diff options
Diffstat (limited to '')
98 files changed, 24435 insertions, 0 deletions
diff --git a/winaccessibility/CustomTarget_ia2_idl.mk b/winaccessibility/CustomTarget_ia2_idl.mk new file mode 100644 index 000000000..40a985153 --- /dev/null +++ b/winaccessibility/CustomTarget_ia2_idl.mk @@ -0,0 +1,42 @@ +# -*- 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_CustomTarget_CustomTarget,winaccessibility/ia2/idl)) + +wina11y_COMIDLDIR := $(call gb_CustomTarget_get_workdir,winaccessibility/ia2/idl) +wina11y_SOURCE := $(SRCDIR)/winaccessibility/source/UAccCOMIDL + +# We cannot depend on *.tlb because they only produced by IDL compiler +# if idl contains 'library' statement. +$(call gb_CustomTarget_get_target,winaccessibility/ia2/idl) : \ + $(wina11y_COMIDLDIR)/AccessibleKeyBinding.h \ + $(wina11y_COMIDLDIR)/AccessibleKeyStroke.h \ + $(wina11y_COMIDLDIR)/Charset.h \ + $(wina11y_COMIDLDIR)/UAccCOM.h \ + $(wina11y_COMIDLDIR)/defines.h \ + $(wina11y_COMIDLDIR)/ia2_api_all.h + +$(wina11y_COMIDLDIR)/%.h : $(wina11y_SOURCE)/%.idl \ + | $(wina11y_COMIDLDIR)/.dir + $(call gb_Output_announce,$(subst $(WORKDIR)/,,$@),$(true),IDL,1) + $(call gb_Trace_StartRange,$(subst $(WORKDIR)/,,$@),IDL) + $(call gb_Helper_abbreviate_dirs, \ + midl.exe \ + -tlb $(wina11y_COMIDLDIR)/$*.tlb \ + -h $(wina11y_COMIDLDIR)/$*.h \ + -iid $(wina11y_COMIDLDIR)/$*_i.c \ + -dlldata $(wina11y_COMIDLDIR)/dlldata.c \ + -proxy $(wina11y_COMIDLDIR)/$*_p.c \ + -Oicf \ + $(SOLARINC) \ + -I $(wina11y_SOURCE) \ + $<) + $(call gb_Trace_EndRange,$(subst $(WORKDIR)/,,$@),IDL) + +# vim:set shiftwidth=4 tabstop=4 noexpandtab: diff --git a/winaccessibility/Library_uacccom.mk b/winaccessibility/Library_uacccom.mk new file mode 100644 index 000000000..8c3d3c159 --- /dev/null +++ b/winaccessibility/Library_uacccom.mk @@ -0,0 +1,83 @@ +# -*- 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,UAccCOM)) + +$(eval $(call gb_Library_use_custom_headers,UAccCOM,winaccessibility/ia2/idl)) + +$(eval $(call gb_Library_set_include,UAccCOM,\ + $$(INCLUDE) \ + -I$(SRCDIR)/winaccessibility/inc \ + $(foreach i,$(ATL_INCLUDE), -I$(i)) \ +)) + +$(eval $(call gb_Library_add_defs,UAccCOM,\ + -DUACCCOM_DLLIMPLEMENTATION \ +)) + +$(eval $(call gb_Library_use_sdk_api,UAccCOM)) + +$(eval $(call gb_Library_add_nativeres,UAccCOM,UAccCOM)) + +$(eval $(call gb_Library_add_exception_objects,UAccCOM,\ + winaccessibility/source/UAccCOM/AccAction \ + winaccessibility/source/UAccCOM/AccActionBase \ + winaccessibility/source/UAccCOM/AccComponent \ + winaccessibility/source/UAccCOM/AccComponentBase \ + winaccessibility/source/UAccCOM/AccEditableText \ + winaccessibility/source/UAccCOM/AccHyperLink \ + winaccessibility/source/UAccCOM/AccHypertext \ + winaccessibility/source/UAccCOM/AccImage \ + winaccessibility/source/UAccCOM/AccRelation \ + winaccessibility/source/UAccCOM/AccTable \ + winaccessibility/source/UAccCOM/AccTableCell \ + winaccessibility/source/UAccCOM/AccText \ + winaccessibility/source/UAccCOM/AccTextBase \ + winaccessibility/source/UAccCOM/AccValue \ + winaccessibility/source/UAccCOM/EnumVariant \ + winaccessibility/source/UAccCOM/MAccessible \ + winaccessibility/source/UAccCOM/StdAfx \ + winaccessibility/source/UAccCOM/UAccCOM \ + winaccessibility/source/UAccCOM/UNOXWrapper \ +)) + +$(eval $(call gb_Library_add_ldflags,UAccCOM,\ + /DEF:$(SRCDIR)/winaccessibility/source/UAccCOM/UAccCOM.def \ +)) + +$(eval $(call gb_Library_use_libraries,UAccCOM,\ + vcl \ + comphelper \ + cppu \ + sal \ +)) + +$(eval $(call gb_Library_use_externals,UAccCOM,\ + boost_headers \ +)) + +$(eval $(call gb_Library_use_system_win32_libs,UAccCOM,\ + oleacc \ + advapi32 \ + delayimp \ + kernel32 \ + ole32 \ + oleaut32 \ + shlwapi \ + user32 \ + uuid \ +)) + +$(eval $(call gb_Library_add_libs,UAccCOM,\ + $(ATL_LIB)/atls.lib \ +)) + +# vim:set noet sw=4 ts=4: diff --git a/winaccessibility/Library_winaccessibility.mk b/winaccessibility/Library_winaccessibility.mk new file mode 100644 index 000000000..4b182a996 --- /dev/null +++ b/winaccessibility/Library_winaccessibility.mk @@ -0,0 +1,82 @@ +# -*- 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,winaccessibility)) + +$(eval $(call gb_Library_use_custom_headers,winaccessibility,winaccessibility/ia2/idl)) + +$(eval $(call gb_Library_set_include,winaccessibility,\ + $$(INCLUDE) \ + -I$(SRCDIR)/winaccessibility/inc \ + $(foreach i,$(ATL_INCLUDE), -I$(i)) \ +)) + +$(eval $(call gb_Library_use_sdk_api,winaccessibility)) + +$(eval $(call gb_Library_set_componentfile,winaccessibility,winaccessibility/source/service/winaccessibility,services)) + +$(eval $(call gb_Library_use_common_precompiled_header,winaccessibility)) + +$(eval $(call gb_Library_add_exception_objects,winaccessibility,\ + winaccessibility/source/service/AccObject \ + winaccessibility/source/service/ResIDGenerator \ + winaccessibility/source/service/AccObjectWinManager \ + winaccessibility/source/service/AccObjectManagerAgent \ + winaccessibility/source/service/AccEventListener \ + winaccessibility/source/service/AccComponentEventListener \ + winaccessibility/source/service/AccContainerEventListener \ + winaccessibility/source/service/AccDialogEventListener \ + winaccessibility/source/service/AccFrameEventListener \ + winaccessibility/source/service/AccWindowEventListener \ + winaccessibility/source/service/AccMenuEventListener \ + winaccessibility/source/service/AccTextComponentEventListener \ + winaccessibility/source/service/AccObjectContainerEventListener \ + winaccessibility/source/service/AccParagraphEventListener \ + winaccessibility/source/service/AccDescendantManagerEventListener \ + winaccessibility/source/service/AccListEventListener \ + winaccessibility/source/service/AccTableEventListener \ + winaccessibility/source/service/AccTreeEventListener \ + winaccessibility/source/service/AccTopWindowListener \ + winaccessibility/source/service/msaaservice_impl \ +)) + +$(eval $(call gb_Library_use_externals,winaccessibility,\ + boost_headers \ +)) + +$(eval $(call gb_Library_use_libraries,winaccessibility,\ + UAccCOM \ + comphelper \ + cppu \ + cppuhelper \ + vcl \ + sal \ + tk \ + tl \ +)) + +$(eval $(call gb_Library_use_system_win32_libs,winaccessibility,\ + oleacc \ + advapi32 \ + delayimp \ + kernel32 \ + ole32 \ + oleaut32 \ + shlwapi \ + user32 \ + uuid \ + gdi32 \ + shell32 \ + imm32 \ + winspool \ +)) + +# vim:set noet sw=4 ts=4: diff --git a/winaccessibility/Makefile b/winaccessibility/Makefile new file mode 100644 index 000000000..0997e6284 --- /dev/null +++ b/winaccessibility/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/winaccessibility/Module_winaccessibility.mk b/winaccessibility/Module_winaccessibility.mk new file mode 100644 index 000000000..2421164b3 --- /dev/null +++ b/winaccessibility/Module_winaccessibility.mk @@ -0,0 +1,23 @@ +# -*- 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,winaccessibility)) + +ifeq ($(OS),WNT) +ifeq ($(COM),MSC) +$(eval $(call gb_Module_add_targets,winaccessibility,\ + WinResTarget_uacccom \ + CustomTarget_ia2_idl \ + Library_uacccom \ + Library_winaccessibility \ +)) +endif # COM=MSC +endif # WNT + +# vim:set shiftwidth=4 softtabstop=4 noexpandtab: diff --git a/winaccessibility/README.md b/winaccessibility/README.md new file mode 100644 index 000000000..6abf34a37 --- /dev/null +++ b/winaccessibility/README.md @@ -0,0 +1,62 @@ +# Windows Accessibility Bridge + +This code provides a bridge between our internal Accessibility +interfaces (implemented on all visible 'things' in the suite: eg. +windows, buttons, entry boxes etc.) - and the Windows `MSAA` / +`IAccessible2` COM interfaces that are familiar to windows users and +Accessible Technologies (ATs) such as the NVDA screen reader. + +The code breaks into three bits: + ++ `source/service/` + + the UNO service providing the accessibility bridge. + It essentially listens to events from the LibreOffice + core and creates and synchronises COM peers for our + internal accessibility objects when events arrive. + ++ `source/UAccCom/` + + COM implementations of the `MSAA` / `IAccessible2` interfaces + to provide native peers for the accessibility code. + ++ `source/UAccCOMIDL/` + + COM Interface Definition Language (IDL) for UAccCom. + +Here is one way of visualising the code / control flow + + VCL <-> UNO toolkit <-> UNO a11y <-> win a11y <-> COM / IAccessible2 + + vcl/ <-> toolkit/ <-> accessibility/ <-> winaccessibility/ <-> UAccCom/ + +## Threading + +It's possible that the UNO components are called from threads other +than the main thread, so they have to be synchronized. It would be nice +to put the component into a UNO apartment (and the COM components into STA) +but UNO would spawn a new thread for it so it's not possible. +The COM components also call into the same global `AccObjectWinManager` +as the UNO components do so both have to be synchronized in the same way. + +So we use the `SolarMutex` for all synchronization since anything else +would be rather difficult to make work. Unfortunately there is a +pre-existing problem in vcl with Win32 Window creation and destruction +on non-main threads where a synchronous `SendMessage` is used while +the `SolarMutex` is locked that can cause deadlocks if the main thread is +waiting on the `SolarMutex` itself at that time and thus not handing the +Win32 message; this is easy to trigger with `JunitTests` but hopefully +not by actual end users. + +## Debugging / Playing with winaccessibility + +If NVDA is running when soffice starts, IA2 should be automatically enabled +and work as expected. In order to use 'accprobe' to debug +it is necessary to override the check for whether an AT (like NVDA) is +running; to do that use: + + SAL_FORCE_IACCESSIBLE2=1 soffice.exe -writer + +Then you can use accprobe to introspect the accessibility hierarchy +remotely, checkout: + +<http://accessibility.linuxfoundation.org/a11yweb/util/accprobe/> + +But often it's more useful to look at NVDA's text output window. diff --git a/winaccessibility/WinResTarget_uacccom.mk b/winaccessibility/WinResTarget_uacccom.mk new file mode 100644 index 000000000..13de1d505 --- /dev/null +++ b/winaccessibility/WinResTarget_uacccom.mk @@ -0,0 +1,31 @@ +# -*- 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_WinResTarget_WinResTarget,UAccCOM)) + +$(eval $(call gb_WinResTarget_use_custom_headers,UAccCOM,\ + winaccessibility/ia2/idl \ +)) + +ifneq ($(ENABLE_DBGUTIL),TRUE) +$(eval $(call gb_WinResTarget_add_defs,UAccCOM,\ + -DPRODUCT \ +)) +endif + +$(eval $(call gb_WinResTarget_set_include,UAccCOM,\ + $$(INCLUDE) \ + $(foreach i,$(ATL_INCLUDE), -I$(i)) \ +)) + +$(eval $(call gb_WinResTarget_set_rcfile,UAccCOM,winaccessibility/source/UAccCOM/UAccCOM)) + +# vim:set noet sw=4 ts=4: diff --git a/winaccessibility/inc/AccComponentEventListener.hxx b/winaccessibility/inc/AccComponentEventListener.hxx new file mode 100644 index 000000000..6c2683f8b --- /dev/null +++ b/winaccessibility/inc/AccComponentEventListener.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 <stdio.h> +#include "AccEventListener.hxx" +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> + +/** + * AccComponentEventListener is inherited from AccEventListener. It handles the events + * generated by component controls. The accessible roles are: CHECK_BOX, ICON, LABEL, + * MENU_ITEM, PUSH_BUTTON, RADIO_BUTTON, SCROLL_BAR, SEPARATOR, TOGGLE_BUTTON, TOOL_TIP, SPIN_BOX. + * It defines the procedure of specific event handling related with components and provides + * the detailed support for some related methods. + */ +class AccComponentEventListener : public AccEventListener +{ +private: + static FILE *output, *output2, *output3, *outacc; //used for debugging +public: + AccComponentEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent); + virtual ~AccComponentEventListener() override; + + // XAccessibleEventListener + virtual void SAL_CALL + notifyEvent(const css::accessibility::AccessibleEventObject& aEvent) override; + + //for value changed event + virtual void HandleValueChangedEvent(css::uno::Any oldValue, css::uno::Any newValue); + + //for action changed event + virtual void HandleActionChangedEvent(); + + //for text changed event + virtual void HandleTextChangedEvent(css::uno::Any oldValue, css::uno::Any newValue); + + //for caret changed event + virtual void HandleCaretChangedEvent(css::uno::Any oldValue, css::uno::Any newValue); + + virtual void SetComponentState(short state, bool enable) override; + virtual void FireStatePropertyChange(short state, bool set) override; + virtual void FireStateFocusedChange(bool enable) override; + + void HandleSelectionChangedEventNoArgs(); + + //add TEXT_SELECTION_CHANGED event + void HandleTextSelectionChangedEvent(); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccContainerEventListener.hxx b/winaccessibility/inc/AccContainerEventListener.hxx new file mode 100644 index 000000000..c880374fb --- /dev/null +++ b/winaccessibility/inc/AccContainerEventListener.hxx @@ -0,0 +1,99 @@ +/* -*- 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 + +enum class UnoMSAAEvent; + +#include <stdio.h> +#include "AccEventListener.hxx" +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> + + +/** + * AccContainerEventListener is inherited from AccEventListener. It handles the events + * generated by container controls. The accessible roles are: CANVAS, COMBO_BOX, DOCUMENT, + * EMBEDDED_OBJECT, END_NOTE, FILLER, FOOTNOTE, FOOTER, GRAPHIC, HEADER, LAYERED_PANE, + * MENU_BAR, POPUP_MENU, OPTION_PANE, PAGE_TAB, PAGE_TAB_LIST, PANEL, SCROLL_PANE, SPLIT_PANE, + * STATUS_BAR, TABLE_CELL, TEXT_FRAME, TOOL_BAR, VIEW_PORT. + * It defines the procedure of specific event handling related with containsers and provides + * the detailed support for some related methods. + */ +class AccContainerEventListener: public AccEventListener +{ +public: + AccContainerEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent); + virtual ~AccContainerEventListener() override; + + //AccessibleEventListener + virtual void SAL_CALL notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) override; + + //for child changed event + virtual void HandleChildChangedEvent( + css::uno::Any oldValue, css::uno::Any newValue); + + //for selection changed event + virtual void HandleSelectionChangedEvent( + const css::uno::Any &oldValue, const css::uno::Any &newValue); + + //for all children changed event + virtual void HandleAllChildrenChangedEvent(); + + //for text changed event + virtual void HandleTextChangedEvent( + css::uno::Any oldValue, css::uno::Any newValue); + virtual void HandleStateChangedEvent( + css::uno::Any oldValue, css::uno::Any newValue) override; + + //for value changed event + virtual void HandleValueChangedEvent( + css::uno::Any oldValue, css::uno::Any newValue); + + //state changed + virtual void SetComponentState(short state, bool enable) override; + virtual void FireStatePropertyChange(short state, bool set) override; + virtual void FireStateFocusedChange(bool enable) override; + virtual bool IsEditable(css::uno::Reference<css::accessibility::XAccessibleContext> const & xContext); + + // update all children's state + void UpdateAllChildrenState( css::accessibility::XAccessible* pXAccessible); + + bool NotifyChildEvent(UnoMSAAEvent eWinEvent, const css::uno::Any& Value); + + virtual void HandleSelectionChangedAddEvent( + const css::uno::Any &oldValue, const css::uno::Any &newValue); + virtual void HandleSelectionChangedRemoveEvent( + const css::uno::Any &oldValue, const css::uno::Any &newValue); + virtual void HandleSelectionChangedWithinEvent( + const css::uno::Any &oldValue, const css::uno::Any &newValue); + + virtual void HandlePageChangedEvent( + const css::uno::Any &oldValue, const css::uno::Any &newValue); + + virtual void HandleSectionChangedEvent( + const css::uno::Any &oldValue, const css::uno::Any &newValue); + virtual void HandleColumnChangedEvent( + const css::uno::Any &oldValue, const css::uno::Any &newValue); + + //for name changed event + virtual void HandleNameChangedEvent(css::uno::Any name) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccDescendantManagerEventListener.hxx b/winaccessibility/inc/AccDescendantManagerEventListener.hxx new file mode 100644 index 000000000..669143a03 --- /dev/null +++ b/winaccessibility/inc/AccDescendantManagerEventListener.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 + +enum class UnoMSAAEvent; + +#include <stdio.h> +#include <vector> +#include "AccComponentEventListener.hxx" +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> + +/** + * AccDescendantManagerEventListener is inherited from AccComponentEventListener. It handles + * the events generated by active descendant controls. They are: TREE, LIST, and TABLE. + * It defines the procedure of specific event handling related with active descendant components + * and provides the detailed support for some related methods. + */ +class AccDescendantManagerEventListener: public AccComponentEventListener +{ +private: + std::vector<com::sun::star::accessibility::XAccessible*> m_aUnselectedChildrenForDeletion; + +public: + AccDescendantManagerEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent); + virtual ~AccDescendantManagerEventListener() override; + + // XAccessibleEventListener + virtual void SAL_CALL notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) override; + + //for selection changed event + virtual void HandleSelectionChangedEvent( + css::uno::Any oldValue, css::uno::Any newValue); + + //for child changed event + virtual void HandleChildChangedEvent( + css::uno::Any oldValue, css::uno::Any newValue); + + virtual void HandleChildChangedNoFocusEvent( + css::uno::Any oldValue, css::uno::Any newValue); + + bool NotifyChildEvent(UnoMSAAEvent eWinEvent, const css::uno::Any& Value); + + virtual void HandleSelectionChangedAddEvent( + const css::uno::Any &oldValue, const css::uno::Any &newValue); + virtual void HandleSelectionChangedRemoveEvent( + const css::uno::Any &oldValue, const css::uno::Any &newValue); + virtual void HandleSelectionChangedWithinEvent( + const css::uno::Any &oldValue, const css::uno::Any &newValue); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccDialogEventListener.hxx b/winaccessibility/inc/AccDialogEventListener.hxx new file mode 100644 index 000000000..b8394f712 --- /dev/null +++ b/winaccessibility/inc/AccDialogEventListener.hxx @@ -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 . + */ + +#pragma once + +#include <stdio.h> +#include "AccEventListener.hxx" +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> + +/** + * AccDialogEventListener is inherited from AccEventListener. It handles the events + * generated by Dialogs. The accessible role is: DIALOG. + * It defines the procedure of specific event handling related with dialogs and provides + * the detailed support for some related methods. + */ +class AccDialogEventListener : public AccEventListener +{ +public: + AccDialogEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent); + virtual ~AccDialogEventListener() override; + + //AccessibleEventListener + virtual void SAL_CALL + notifyEvent(const css::accessibility::AccessibleEventObject& aEvent) override; + + //for child changed event + virtual void HandleChildChangedEvent(css::uno::Any oldValue, css::uno::Any newValue); + + //state changed + virtual void SetComponentState(short state, bool enable) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccEventListener.hxx b/winaccessibility/inc/AccEventListener.hxx new file mode 100644 index 000000000..4e29e9f50 --- /dev/null +++ b/winaccessibility/inc/AccEventListener.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/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> + +#include <cppuhelper/implbase.hxx> + +class AccObjectManagerAgent; + +/** + * AccEventListener is the general event listener for all controls. It defines the + * procedure of all the event handling and provides the basic support for some simple + * methods. + */ +class AccEventListener : public ::cppu::WeakImplHelper<css::accessibility::XAccessibleEventListener> +{ +protected: + //accessible owner's pointer + css::uno::Reference<css::accessibility::XAccessible> m_xAccessible; + //agent pointer for objects' manager + AccObjectManagerAgent* pAgent; + +public: + AccEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent); + virtual ~AccEventListener() override; + + // XEventListener + virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override; + + // XAccessibleEventListener + virtual void SAL_CALL + notifyEvent(const css::accessibility::AccessibleEventObject& aEvent) override; + + //for name changed event + virtual void HandleNameChangedEvent(css::uno::Any name); + + //for description changed event + virtual void HandleDescriptionChangedEvent(); + + //for state changed event + virtual void HandleStateChangedEvent(css::uno::Any oldValue, css::uno::Any newValue); + virtual void SetComponentState(short state, bool enable); + virtual void FireStatePropertyChange(short state, bool set); + virtual void FireStateFocusedChange(bool enable); + + //for bound rect changed event + virtual void HandleBoundrectChangedEvent(); + + //for visible data changed event + virtual void HandleVisibleDataChangedEvent(); + + // get the accessible role of m_xAccessible + virtual short GetRole(); + //get the accessible parent's role + virtual short GetParentRole(); + + void RemoveMeFromBroadcaster(); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccFrameEventListener.hxx b/winaccessibility/inc/AccFrameEventListener.hxx new file mode 100644 index 000000000..43f4fe393 --- /dev/null +++ b/winaccessibility/inc/AccFrameEventListener.hxx @@ -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 . + */ + +#pragma once + +#include <stdio.h> +#include "AccEventListener.hxx" +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> + +/** + * AccFrameEventListener is inherited from AccEventListener. It handles the events + * generated by Dialogs. The accessible roles are: FRAME and ROOT_PANE. + * It defines the procedure of specific event handling related with frames and provides + * the detailed support for some related methods. + */ +class AccFrameEventListener : public AccEventListener +{ +public: + AccFrameEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent); + virtual ~AccFrameEventListener() override; + + // XAccessibleEventListener + virtual void SAL_CALL + notifyEvent(const css::accessibility::AccessibleEventObject& aEvent) override; + + //for child changed event + virtual void HandleChildChangedEvent(css::uno::Any oldValue, css::uno::Any newValue); + + //state changed + virtual void SetComponentState(short state, bool enable) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccListEventListener.hxx b/winaccessibility/inc/AccListEventListener.hxx new file mode 100644 index 000000000..bd75a977c --- /dev/null +++ b/winaccessibility/inc/AccListEventListener.hxx @@ -0,0 +1,49 @@ +/* -*- 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 <stdio.h> +#include "AccDescendantManagerEventListener.hxx" +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> + +/** + * AccListEventListener is inherited from AccDescendantManagerEventListener. It handles + * the events generated by tree controls. The accessible role is: LIST. + * It defines the procedure of specific event handling related with list components + * and provides the detailed support for some related methods. + */ +class AccListEventListener : public AccDescendantManagerEventListener +{ +public: + AccListEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent); + virtual ~AccListEventListener() override; + + // XAccessibleEventListener + virtual void SAL_CALL + notifyEvent(const css::accessibility::AccessibleEventObject& aEvent) override; + + //for active descendant changed event + virtual void HandleActiveDescendantChangedEvent(css::uno::Any oldValue, css::uno::Any newValue); + //for value changed event + virtual void HandleValueChangedEvent(css::uno::Any oldValue, css::uno::Any newValue) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccMenuEventListener.hxx b/winaccessibility/inc/AccMenuEventListener.hxx new file mode 100644 index 000000000..c0efc33fc --- /dev/null +++ b/winaccessibility/inc/AccMenuEventListener.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 <stdio.h> +#include "AccComponentEventListener.hxx" +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> + +/** + * AccMenuEventListener is inherited from AccComponentEventListener. It handles the events + * generated by container controls. The accessible role is: MENU + * It defines the procedure of specific event handling related with menus and provides + * the detailed support for some related methods. + */ +class AccMenuEventListener : public AccComponentEventListener +{ +public: + AccMenuEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent); + virtual ~AccMenuEventListener() override; + + //AccessibleEventListener + virtual void SAL_CALL + notifyEvent(const css::accessibility::AccessibleEventObject& aEvent) override; + + //for child changed event + virtual void HandleChildChangedEvent(css::uno::Any oldValue, css::uno::Any newValue); + + //for selection changed event + virtual void HandleSelectionChangedEventNoArgs(); + + //for state changed event + virtual void FireStatePropertyChange(short state, bool set) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccObject.hxx b/winaccessibility/inc/AccObject.hxx new file mode 100644 index 000000000..a255f3626 --- /dev/null +++ b/winaccessibility/inc/AccObject.hxx @@ -0,0 +1,135 @@ +/* -*- 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 <vector> +#include <map> +#if !defined WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> +#include <oleacc.h> + +#include <rtl/ref.hxx> + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <com/sun/star/accessibility/XAccessibleAction.hpp> + +#include "accHelper.hxx" + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +class AccEventListener; +class AccObjectManagerAgent; +class AccObject; + +typedef std::map<const long, AccObject*> IAccSelectionList; +typedef std::vector<AccObject *> IAccChildList; + + +class AccObject +{ +private: + + short m_accRole; + long m_resID; + HWND m_pParantID; + IMAccessible* m_pIMAcc; + AccObject* m_pParentObj; + IAccChildList m_childrenList; + ::rtl::Reference<AccEventListener> m_pListener; + IAccSelectionList m_selectionList; + + css::uno::Reference < css::accessibility::XAccessible > m_xAccRef; + css::uno::Reference < css::accessibility::XAccessibleAction > m_xAccActionRef; + css::uno::Reference < css::accessibility::XAccessibleContext > m_xAccContextRef; + + void ImplInitializeCreateObj();//create COM object + + void UpdateActionDesc(); + void UpdateRole(); + + DWORD GetMSAAStateFromUNO(short xState);//translate state from UNO to MSAA value + css::accessibility::XAccessibleSelection* GetXAccessibleSelection(); + void GetExpandedState(sal_Bool* isExpandable, sal_Bool* isExpanded); + OUString GetMAccessibleValueFromAny(css::uno::Any pAny); + +public: + + AccObject ( css::accessibility::XAccessible* pXAcc = nullptr,AccObjectManagerAgent* pAgent = nullptr ,AccEventListener* accListener=nullptr); + virtual ~AccObject(); + + bool UpdateAccessibleInfoFromUnoToMSAA( ); //implement accessible information mapping + void UpdateDefaultAction(); + + IMAccessible* GetIMAccessible(); //return COM interface in acc object + css::uno::Reference<css::accessibility::XAccessible> const& GetXAccessible(); + + void SetResID(long id);//ResID means ChildID in MSAA + long GetResID(); + + + void SetParentHWND(HWND hWnd);//need to set top window handle when send event to AT + HWND GetParentHWND(); + + void SetListener(::rtl::Reference<AccEventListener> const& pListener); + AccEventListener* getListener(); + + void SetParentObj(AccObject* pParentAccObj); + AccObject* GetParentObj(); + + void InsertChild( AccObject* pChild,short pos = LAST_CHILD); + void DeleteChild( AccObject* pChild ); + AccObject* NextChild(); + + void NotifyDestroy(); + + void DecreaseState(short xState );//call COM interface DecreaseState method + void IncreaseState( short xState );//call COM interface IncreaseState method + + void SetName( css::uno::Any newName); + void SetValue( css::uno::Any pAny ); + + short GetRole() const; + + void UpdateState(); + void UpdateName(); + void UpdateValue(); + void UpdateAction(); + void UpdateValidWindow(); + void UpdateLocation(); + + void setFocus(); + void unsetFocus(); + + void AddSelect(long index, AccObject* accObj); + IAccSelectionList& GetSelection(); + void setLocalizedResourceString(); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccObjectContainerEventListener.hxx b/winaccessibility/inc/AccObjectContainerEventListener.hxx new file mode 100644 index 000000000..41baf99b4 --- /dev/null +++ b/winaccessibility/inc/AccObjectContainerEventListener.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 <stdio.h> +#include "AccContainerEventListener.hxx" +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> + + +/** + * AccObjectContainerEventListener is inherited from AccContainerEventListener. It handles the events + * generated by container controls. The accessible role is: SHAPE + * It defines the procedure of specific event handling related with shapes and provides + * the detailed support for some related methods. + */ +class AccObjectContainerEventListener: public AccContainerEventListener +{ +public: + AccObjectContainerEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent); + virtual ~AccObjectContainerEventListener() override; + + virtual void HandleStateChangedEvent( + css::uno::Any oldValue, css::uno::Any newValue) override; + + //for visible data changed event, for shapes, the visibledatachanged should be mapped to LOCATION_CHANGED + virtual void HandleVisibleDataChangedEvent() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccObjectManagerAgent.hxx b/winaccessibility/inc/AccObjectManagerAgent.hxx new file mode 100644 index 000000000..d91f33ef1 --- /dev/null +++ b/winaccessibility/inc/AccObjectManagerAgent.hxx @@ -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 . + */ + +#pragma once + +#include <memory> + +#include <prewin.h> +#include <Windows.h> +#include <postwin.h> + +#include <com/sun/star/accessibility/XAccessible.hpp> + +struct IMAccessible; +struct IAccessible; +class AccObjectWinManager; +enum class UnoMSAAEvent; + +/**************************************************************** +AccObjectManagerAgent is used for managing AccObjects, which encapsulates +platform differences,and call AccObjectWinManager for Windows platform. To do for +Linux platform +*****************************************************************/ +class AccObjectManagerAgent +{ +private: + + std::unique_ptr<AccObjectWinManager> pWinManager; + +public: + + AccObjectManagerAgent(); + virtual ~AccObjectManagerAgent(); + + virtual bool InsertAccObj(css::accessibility::XAccessible* pXAcc, + css::accessibility::XAccessible* pParentXAcc, + HWND hWnd = nullptr); + virtual void GetIAccessibleFromResID(long childID,IMAccessible**); + virtual bool GetIAccessibleFromXAccessible(css::accessibility::XAccessible* pXAcc, IAccessible** ppIA); + + virtual void DeleteAccObj( css::accessibility::XAccessible* pXAcc ); + virtual IMAccessible* GetIMAccByXAcc(css::accessibility::XAccessible* pXAcc); + + bool NotifyAccEvent(UnoMSAAEvent eEvent, css::accessibility::XAccessible* pXAcc = nullptr); + + bool InsertChildrenAccObj(css::accessibility::XAccessible* pXAcc, + HWND hWnd = nullptr); + void DeleteChildrenAccObj( css::accessibility::XAccessible* pXAcc ); + + void DecreaseState( css::accessibility::XAccessible* pXAcc,unsigned short pState ); + void IncreaseState( css::accessibility::XAccessible* pXAcc,unsigned short pState ); + void UpdateState( css::accessibility::XAccessible* pXAcc ); + + static void UpdateLocation( css::accessibility::XAccessible* pXAcc, + long Top = 0,long left = 0,long width = 0,long height = 0 ); + void UpdateAction( css::accessibility::XAccessible* pXAcc ); + + void UpdateValue( css::accessibility::XAccessible* pXAcc ); + void UpdateValue( css::accessibility::XAccessible* pXAcc, css::uno::Any ); + + void UpdateAccName( css::accessibility::XAccessible* pXAcc, css::uno::Any newName); + void UpdateAccName( css::accessibility::XAccessible* pXAcc); + + void NotifyDestroy(css::accessibility::XAccessible* pXAcc); + + css::accessibility::XAccessible* GetParentXAccessible( css::accessibility::XAccessible* pXAcc ); + short GetParentRole(css::accessibility::XAccessible* pXAcc ); + bool IsContainer(css::accessibility::XAccessible* pXAcc); + + void SaveTopWindowHandle(HWND hWnd, css::accessibility::XAccessible* pXAcc); + + void UpdateChildState(css::accessibility::XAccessible* pXAcc); + + bool IsSpecialToolbarItem(css::accessibility::XAccessible* pXAcc); + + short GetRole(css::accessibility::XAccessible* pXAcc); + + css::accessibility::XAccessible* GetAccDocByAccTopWin( css::accessibility::XAccessible* pXAcc ); + bool IsTopWinAcc( css::accessibility::XAccessible* pXAcc ); + + bool IsStateManageDescendant(css::accessibility::XAccessible* pXAcc); + + sal_Int64 Get_ToATInterface(sal_Int64 hWnd, sal_Int64 lParam, sal_Int64 wParam); + +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccObjectWinManager.hxx b/winaccessibility/inc/AccObjectWinManager.hxx new file mode 100644 index 000000000..342d2278d --- /dev/null +++ b/winaccessibility/inc/AccObjectWinManager.hxx @@ -0,0 +1,153 @@ +/* -*- 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> +#if !defined WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> +#include <rtl/ref.hxx> +#include "ResIDGenerator.hxx" + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +namespace com::sun::star::accessibility { +class XAccessible; +} +class ResIDGenerator; +class AccObjectManagerAgent; +class AccEventListener; +class AccObject; +enum class UnoMSAAEvent; + +/******************************************************************* +AccObjectWinManager complete the functions: +1. Insert, delete,query,update Acc objects +2. Create, delete,fire AccEventLister, the lifecycle of AccEventListener is as same as + Acc Object + 3.Return COM interface for AT,by the call back in salframe + 4.Pass accessible information to Acc objects + *******************************************************************/ +class AccObjectWinManager +{ + friend class AccObjectManagerAgent; + +private: + typedef std::map<com::sun::star::accessibility::XAccessible*, AccObject> XIdToAccObjHash; + typedef std::map<HWND, com::sun::star::accessibility::XAccessible*> XHWNDToXAccHash; + typedef std::map<const long, AccObject*> XResIdToAccObjHash; + + typedef std::map<const HWND, css::accessibility::XAccessible* > + XHWNDToDocumentHash; + + //XAccessible to AccObject + XIdToAccObjHash XIdAccList; + + //HWND to All XAccessible pointer + XHWNDToXAccHash HwndXAcc; + + //id_Child to AccObject + XResIdToAccObjHash XResIdAccList; + + //for file name support + XHWNDToDocumentHash XHWNDDocList; + + css::accessibility::XAccessible* oldFocus; + + AccObjectManagerAgent* pAgent; + ResIDGenerator ResIdGen; + + AccObjectWinManager(AccObjectManagerAgent* Agent=nullptr); + +private: + long ImpleGenerateResID(); + AccObject* GetAccObjByXAcc( css::accessibility::XAccessible* pXAcc); + + AccObject* GetTopWindowAccObj(HWND hWnd); + + css::accessibility::XAccessible* GetAccDocByHWND(HWND hWnd); + + static void DeleteAccListener( AccObject* pAccObj ); + static void InsertAccChildNode(AccObject* pCurObj,AccObject* pParentObj,HWND pWnd); + static void DeleteAccChildNode(AccObject* pChild); + void DeleteFromHwndXAcc(css::accessibility::XAccessible const * pXAcc ); + int UpdateAccSelection(css::accessibility::XAccessible* pXAcc); + + ::rtl::Reference<AccEventListener> CreateAccEventListener( + css::accessibility::XAccessible* pXAcc); +public: + virtual ~AccObjectWinManager(); + bool InsertAccObj( css::accessibility::XAccessible* pXAcc,css::accessibility::XAccessible* pParentXAcc,HWND pWnd); + bool InsertChildrenAccObj( css::accessibility::XAccessible* pXAcc,HWND pWnd=nullptr); + void DeleteAccObj( css::accessibility::XAccessible* pXAcc ); + void DeleteChildrenAccObj(css::accessibility::XAccessible* pAccObj); + + bool NotifyAccEvent(css::accessibility::XAccessible* pXAcc, UnoMSAAEvent eEvent); + + LRESULT Get_ToATInterface(HWND hWnd, long lParam, WPARAM wParam); + + void DecreaseState( css::accessibility::XAccessible* pXAcc,unsigned short pState ); + void IncreaseState( css::accessibility::XAccessible* pXAcc,unsigned short pState ); + void UpdateState( css::accessibility::XAccessible* pXAcc ); + void SetLocation( css::accessibility::XAccessible* pXAcc, + long Top = 0,long left = 0,long width = 0,long height = 0); + + void SetValue( css::accessibility::XAccessible* pXAcc, css::uno::Any pAny ); + void UpdateValue( css::accessibility::XAccessible* pXAcc ); + + void SetAccName( css::accessibility::XAccessible* pXAcc, css::uno::Any newName); + void UpdateAccName( css::accessibility::XAccessible* pXAcc ); + + void UpdateAccFocus( css::accessibility::XAccessible* newFocus ); + void UpdateAction( css::accessibility::XAccessible* pXAcc ); + + static bool IsContainer( css::accessibility::XAccessible* pAccessible ); + + IMAccessible* GetIMAccByXAcc( css::accessibility::XAccessible* pXAcc ); + IMAccessible* GetIAccessibleFromResID(long resID); + + void NotifyDestroy( css::accessibility::XAccessible* pXAcc ); + css::accessibility::XAccessible* GetParentXAccessible( css::accessibility::XAccessible* pXAcc ); + short GetParentRole( css::accessibility::XAccessible* pXAcc ); + + void SaveTopWindowHandle(HWND hWnd, css::accessibility::XAccessible* pXAcc); + + void UpdateChildState(css::accessibility::XAccessible* pXAcc); + + bool IsSpecialToolbarItem(css::accessibility::XAccessible* pXAcc); + + static short GetRole(css::accessibility::XAccessible* pXAcc); + + css::accessibility::XAccessible* GetAccDocByAccTopWin( css::accessibility::XAccessible* pXAcc ); + bool IsTopWinAcc( css::accessibility::XAccessible* pXAcc ); + + static bool IsStateManageDescendant(css::accessibility::XAccessible* pAccessible); + +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccParagraphEventListener.hxx b/winaccessibility/inc/AccParagraphEventListener.hxx new file mode 100644 index 000000000..7204839e3 --- /dev/null +++ b/winaccessibility/inc/AccParagraphEventListener.hxx @@ -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 . + */ + +#pragma once + +#include <stdio.h> +#include "AccContainerEventListener.hxx" +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> + +/** + * AccParagraphEventListener is inherited from AccContainerEventListener. It handles the events + * generated by container controls. The accessible roles are: PARAGRAPH and HEADING. + * It defines the procedure of specific event handling related with text containsers and provides + * the detailed support for some related methods. + */ +class AccParagraphEventListener : public AccContainerEventListener +{ +public: + AccParagraphEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent); + virtual ~AccParagraphEventListener() override; + + //AccessibleEventListener + virtual void SAL_CALL + notifyEvent(const css::accessibility::AccessibleEventObject& aEvent) override; + + //for caret changed event + virtual void HandleCaretChangedEvent(css::uno::Any oldValue, css::uno::Any newValue); + + virtual void SetComponentState(short state, bool enable) override; + + //add TEXT_SELECTION_CHANGED event + void HandleTextSelectionChangedEvent(); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccTableEventListener.hxx b/winaccessibility/inc/AccTableEventListener.hxx new file mode 100644 index 000000000..01871e35e --- /dev/null +++ b/winaccessibility/inc/AccTableEventListener.hxx @@ -0,0 +1,49 @@ +/* -*- 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 <stdio.h> +#include "AccDescendantManagerEventListener.hxx" +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> + +/** + * AccTableEventListener is inherited from AccDescendantManagerEventListener. It handles + * the events generated by tree controls. The accessible role is: TABLE. + * It defines the procedure of specific event handling related with table components + * and provides the detailed support for some related methods. + */ +class AccTableEventListener : public AccDescendantManagerEventListener +{ +public: + AccTableEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent); + virtual ~AccTableEventListener() override; + + // XAccessibleEventListener + virtual void SAL_CALL + notifyEvent(const css::accessibility::AccessibleEventObject& aEvent) override; + + //for active descendant changed event + virtual void HandleActiveDescendantChangedEvent(css::uno::Any oldValue, css::uno::Any newValue); + + void HandleTableModelChangeEvent(css::uno::Any newValue); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccTextComponentEventListener.hxx b/winaccessibility/inc/AccTextComponentEventListener.hxx new file mode 100644 index 000000000..f1e49097e --- /dev/null +++ b/winaccessibility/inc/AccTextComponentEventListener.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 <stdio.h> +#include "AccComponentEventListener.hxx" +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> + +/** + * AccTextComponentEventListener is inherited from AccComponentEventListener. It handles the events + * generated by container controls. The accessible role is: TEXT + * It defines the procedure of specific event handling related with text components and provides + * the detailed support for some related methods. + */ +class AccTextComponentEventListener : public AccComponentEventListener +{ +public: + AccTextComponentEventListener(css::accessibility::XAccessible* pAcc, + AccObjectManagerAgent* Agent); + virtual ~AccTextComponentEventListener() override; + + virtual void SetComponentState(short state, bool enable) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccTopWindowListener.hxx b/winaccessibility/inc/AccTopWindowListener.hxx new file mode 100644 index 000000000..c88ce5085 --- /dev/null +++ b/winaccessibility/inc/AccTopWindowListener.hxx @@ -0,0 +1,66 @@ +/* -*- 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/awt/XTopWindowListener.hpp> +#include <com/sun/star/awt/XExtendedToolkit.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> + +#include <cppuhelper/implbase.hxx> + +#include "AccObjectManagerAgent.hxx" + +/** + * AccEventListener is the general event listener for all top windows. The top windows defined + * in UNO are: FRAME, WINDOW, DIALOG, MENU, TOOLTIP. + * It implements the methods of XTopWindowListener and the most important method is windowOpened(). + * In this method, all the accessible objects (including COM object and Uno objects) are created and + * cached into bridge managers, and they are monitored by listeners for later accessible event handling. + */ +class AccTopWindowListener : public ::cppu::WeakImplHelper<css::awt::XTopWindowListener> +{ +private: + AccObjectManagerAgent accManagerAgent; + +public: + AccTopWindowListener(); + virtual ~AccTopWindowListener() override; + + // XTopWindowListener + virtual void SAL_CALL windowOpened(const css::lang::EventObject& e) override; + virtual void SAL_CALL windowClosing(const css::lang::EventObject& e) override; + virtual void SAL_CALL windowClosed(const css::lang::EventObject& e) override; + virtual void SAL_CALL windowMinimized(const css::lang::EventObject& e) override; + virtual void SAL_CALL windowNormalized(const css::lang::EventObject& e) override; + virtual void SAL_CALL windowActivated(const css::lang::EventObject& e) override; + virtual void SAL_CALL windowDeactivated(const css::lang::EventObject& e) override; + + // XEventListener + virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override; + + virtual void AddAllListeners(css::accessibility::XAccessible* pAccessible, + css::accessibility::XAccessible* pParentXAcc, HWND pWND); + //for On-Demand load. + virtual void HandleWindowOpened(css::accessibility::XAccessible* pAccessible); + + sal_Int64 GetMSComPtr(sal_Int64 hWnd, sal_Int64 lParam, sal_Int64 wParam); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccTreeEventListener.hxx b/winaccessibility/inc/AccTreeEventListener.hxx new file mode 100644 index 000000000..bb3574bf0 --- /dev/null +++ b/winaccessibility/inc/AccTreeEventListener.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 <stdio.h> +#include "AccDescendantManagerEventListener.hxx" +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> + +/** + * AccTreeEventListener is inherited from AccDescendantManagerEventListener. It handles + * the events generated by tree controls. The accessible role is: TREE. + * It defines the procedure of specific event handling related with tree components + * and provides the detailed support for some related methods. + */ +class AccTreeEventListener : public AccDescendantManagerEventListener +{ +public: + AccTreeEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent); + virtual ~AccTreeEventListener() override; + + // XAccessibleEventListener + virtual void SAL_CALL + notifyEvent(const css::accessibility::AccessibleEventObject& aEvent) override; + + //for active descendant changed event + virtual void HandleActiveDescendantChangedEvent(css::uno::Any oldValue, css::uno::Any newValue); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/AccWindowEventListener.hxx b/winaccessibility/inc/AccWindowEventListener.hxx new file mode 100644 index 000000000..a4995e343 --- /dev/null +++ b/winaccessibility/inc/AccWindowEventListener.hxx @@ -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 . + */ + +#pragma once + +#include <stdio.h> +#include "AccEventListener.hxx" +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> + +/** + * AccWindowEventListener is inherited from AccEventListener. It handles the events + * generated by Dialogs. The accessible role is: WINDOW. + * It defines the procedure of specific event handling related with windows and provides + * the detailed support for some related methods. + */ +class AccWindowEventListener : public AccEventListener +{ +public: + AccWindowEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent); + virtual ~AccWindowEventListener() override; + + // XAccessibleEventListener + virtual void SAL_CALL + notifyEvent(const css::accessibility::AccessibleEventObject& aEvent) override; + + //for child changed event + virtual void HandleChildChangedEvent(css::uno::Any oldValue, css::uno::Any newValue); + + //state changed + virtual void SetComponentState(short state, bool enable) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/ResIDGenerator.hxx b/winaccessibility/inc/ResIDGenerator.hxx new file mode 100644 index 000000000..400f58a2e --- /dev/null +++ b/winaccessibility/inc/ResIDGenerator.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 <deque> + +//ResID i.e. MSAA child ID, +//this class is responsible for generating a child ID +// +// In IAccessible2, negative child IDs are commonly used to +// indicate unique resource IDs. +class ResIDGenerator +{ +private: + long m_nMin; + std::deque<long> subList; + +public: + ResIDGenerator() + : m_nMin(-1) + { + } + ~ResIDGenerator(); + long GenerateNewResID(); + void SetSub(long number) { subList.push_back(number); }; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/UAccCOMdllapi.h b/winaccessibility/inc/UAccCOMdllapi.h new file mode 100644 index 000000000..50f705c6d --- /dev/null +++ b/winaccessibility/inc/UAccCOMdllapi.h @@ -0,0 +1,20 @@ +/* -*- 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/. + */ + +#pragma once + +#include <sal/types.h> + +#if defined(UACCCOM_DLLIMPLEMENTATION) +#define UACCCOM_DLLPUBLIC SAL_DLLPUBLIC_EXPORT +#else +#define UACCCOM_DLLPUBLIC SAL_DLLPUBLIC_IMPORT +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/accHelper.hxx b/winaccessibility/inc/accHelper.hxx new file mode 100644 index 000000000..4e2d941c4 --- /dev/null +++ b/winaccessibility/inc/accHelper.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 "UAccCOMdllapi.h" + +enum DIRECTION +{ + FIRST_CHILD = 0, + LAST_CHILD = -1, + BEFORE_CHILD = 1, + AFTER_CHILD = 2 +}; + +#define UNO_MSAA_UNMAPPING 0x00000000 + +struct IMAccessible; +UACCCOM_DLLPUBLIC IMAccessible* UAccCOMCreateInstance(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/inc/unomsaaevent.hxx b/winaccessibility/inc/unomsaaevent.hxx new file mode 100644 index 000000000..e8d77d7cd --- /dev/null +++ b/winaccessibility/inc/unomsaaevent.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 + +enum class UnoMSAAEvent +{ + STATE_FOCUSED, + STATE_CHECKED, + STATE_ARMED, + STATE_PRESSED, + STATE_SELECTED, + STATE_SHOWING, + MENU_START, + MENU_END, + MENUPOPUPSTART, + MENUPOPUPEND, + SELECTION_CHANGED, + INVALIDATE_ALL_CHILDREN, + OBJECT_VALUECHANGE, + OBJECT_NAMECHANGE, + OBJECT_DESCRIPTIONCHANGE, + OBJECT_DEFACTIONCHANGE, + OBJECT_CARETCHANGE, + OBJECT_TEXTCHANGE, + ACTIVE_DESCENDANT_CHANGED, + BOUNDRECT_CHANGED, + VISIBLE_DATA_CHANGED, + SHOW, + STATE_BUSY, + TABLE_CAPTION_CHANGED, + TABLE_COLUMN_DESCRIPTION_CHANGED, + TABLE_COLUMN_HEADER_CHANGED, + TABLE_MODEL_CHANGED, + TABLE_ROW_HEADER_CHANGED, + TABLE_SUMMARY_CHANGED, + OBJECT_REORDER, + PAGE_CHANGED, + CHILD_ADDED, + CHILD_REMOVED, + TABLE_ROW_DESCRIPTION_CHANGED, + SELECTION_CHANGED_ADD, + SELECTION_CHANGED_REMOVE, + SELECTION_CHANGED_WITHIN, + OBJECT_PAGECHANGED, + TEXT_SELECTION_CHANGED, + SECTION_CHANGED, + COLUMN_CHANGED +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccAction.cxx b/winaccessibility/source/UAccCOM/AccAction.cxx new file mode 100644 index 000000000..97bfc4f40 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccAction.cxx @@ -0,0 +1,118 @@ +/* -*- 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 . + */ + +/** + * AccAction.cpp : Implementation of CAccAction + */ +#include "stdafx.h" +#include "AccAction.h" + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +using namespace com::sun::star::accessibility; +using namespace com::sun::star::uno; + +/** + * Returns the number of action. + * + * @param nActions the number of action. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccAction::nActions(/*[out,retval]*/long* nActions) +{ + + return CAccActionBase::nActions(nActions); +} + +/** + * Performs specified action on the object. + * + * @param actionIndex the index of action. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccAction::doAction(/* [in] */ long actionIndex) +{ + + return CAccActionBase::doAction(actionIndex); +} + +/** + * Gets description of specified action. + * + * @param actionIndex the index of action. + * @param description the description string of the specified action. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccAction::get_description(long actionIndex,BSTR __RPC_FAR *description) +{ + + return CAccActionBase::get_description(actionIndex, description); +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccAction::get_name( long actionIndex, BSTR __RPC_FAR *name) +{ + + return CAccActionBase::get_name(actionIndex, name); +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccAction::get_localizedName( long actionIndex, BSTR __RPC_FAR *localizedName) +{ + + return CAccActionBase::get_localizedName(actionIndex, localizedName); +} + +/** + * Returns key binding object (if any) associated with specified action + * key binding is string. + * e.g. "alt+d" (like IAccessible::get_accKeyboardShortcut). + * + * @param actionIndex the index of action. + * @param nMaxBinding the max number of key binding. + * @param keyBinding the key binding array. + * @param nBinding the actual number of key binding returned. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccAction::get_keyBinding( + /* [in] */ long actionIndex, + /* [in] */ long nMaxBinding, + /* [length_is][length_is][size_is][size_is][out] */ BSTR __RPC_FAR *__RPC_FAR *keyBinding, + /* [retval][out] */ long __RPC_FAR *nBinding) +{ + + return CAccActionBase::get_keyBinding(actionIndex, nMaxBinding, keyBinding, nBinding); +} + +/** + * Put UNO interface. + * @param pXSubInterface XAccessibleHyperlink interface. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccAction::put_XSubInterface(hyper pXSubInterface) +{ + + + pRXAct = reinterpret_cast<XAccessibleAction*>(pXSubInterface); + + return S_OK; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccAction.h b/winaccessibility/source/UAccCOM/AccAction.h new file mode 100644 index 000000000..7fcff0810 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccAction.h @@ -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 "Resource.h" // main symbols +#include "AccActionBase.h" + +/** + * CAccAction implements IAccessibleAction interface. + */ +class ATL_NO_VTABLE CAccAction : + public CComObjectRoot, + public CComCoClass<CAccAction, &CLSID_AccAction>, + public IAccessibleAction, + public CAccActionBase +{ +public: + CAccAction() + { + + } + + DECLARE_NO_REGISTRY() + + BEGIN_COM_MAP(CAccAction) + COM_INTERFACE_ENTRY(IAccessibleAction) + COM_INTERFACE_ENTRY(IUNOXWrapper) + COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_) +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + END_COM_MAP() +#if defined __clang__ +#pragma clang diagnostic pop +#endif + + static HRESULT WINAPI SmartQI_(void* pv, + REFIID iid, void** ppvObject, DWORD_PTR) + { + return static_cast<CAccAction*>(pv)->SmartQI(iid,ppvObject); + } + + HRESULT SmartQI(REFIID iid, void** ppvObject) + { + if( m_pOuterUnknown ) + return OuterQueryInterface(iid,ppvObject); + return E_FAIL; + } + + // IAccessibleAction +public: + // IAccessibleAction + + // Returns the number of action. + STDMETHOD(nActions)(/*[out,retval]*/long* nActions) override; + + // Performs specified action on the object. + STDMETHOD(doAction)(/* [in] */ long actionIndex) override; + + // Gets description of specified action. + STDMETHOD(get_description)(long actionIndex,BSTR __RPC_FAR *description) override; + + // added , 2006/06/28, for driver 07/11 + // get the action name + STDMETHOD(get_name)( long actionIndex, BSTR __RPC_FAR *name) override; + + // get the localized action name + STDMETHOD(get_localizedName)( long actionIndex, BSTR __RPC_FAR *localizedName) override; + + // Returns key binding object (if any) associated with specified action + // key binding is string. + // e.g. "alt+d" (like IAccessible::get_accKeyboardShortcut). + STDMETHOD(get_keyBinding)( + /* [in] */ long actionIndex, + /* [in] */ long nMaxBinding, + /* [length_is][length_is][size_is][size_is][out] */ BSTR __RPC_FAR *__RPC_FAR *keyBinding, + /* [retval][out] */ long __RPC_FAR *nBinding) override; + + // Override of IUNOXWrapper. + STDMETHOD(put_XSubInterface)(hyper pXSubInterface) override; + +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccActionBase.cxx b/winaccessibility/source/UAccCOM/AccActionBase.cxx new file mode 100644 index 000000000..cd68f3032 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccActionBase.cxx @@ -0,0 +1,221 @@ +/* -*- 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 . + */ + + +// AccActionBase.cpp: implementation of the CAccActionBase class. + +#include "stdafx.h" + +#include "AccActionBase.h" +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> + +#include <vcl/svapp.hxx> +#include <o3tl/char16_t2wchar_t.hxx> +#include <comphelper/AccessibleImplementationHelper.hxx> + +#include "AccessibleKeyStroke.h" + +#include "acccommon.h" + +using namespace com::sun::star::accessibility::AccessibleRole; +using namespace com::sun::star::accessibility; +using namespace com::sun::star::uno; +using namespace com::sun::star::awt; + + +// Construction/Destruction + + +CAccActionBase::CAccActionBase() +{} + +CAccActionBase::~CAccActionBase() +{} + +/** + * Returns the number of action. + * + * @param nActions the number of action. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccActionBase::nActions(/*[out,retval]*/long* nActions) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if( pRXAct.is() && nActions != nullptr ) + { + *nActions = GetXInterface()->getAccessibleActionCount(); + return S_OK; + } + *nActions = 0; + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Performs specified action on the object. + * + * @param actionIndex the index of action. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccActionBase::doAction(/* [in] */ long actionIndex) +{ + SolarMutexGuard g; + + try { + + if( pRXAct.is() ) + { + return GetXInterface()->doAccessibleAction( actionIndex )?S_OK:E_FAIL; + } + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** + * Gets description of specified action. + * + * @param actionIndex the index of action. + * @param description the description string of the specified action. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccActionBase::get_description(long actionIndex,BSTR __RPC_FAR *description) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(description == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXAct.is()) + return E_FAIL; + + OUString ouStr = GetXInterface()->getAccessibleActionDescription(actionIndex); + // #CHECK# + + SysFreeString(*description); + *description = SysAllocString(o3tl::toW(ouStr.getStr())); + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccActionBase::get_name( long, BSTR __RPC_FAR *) +{ + return E_NOTIMPL; +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccActionBase::get_localizedName( long, BSTR __RPC_FAR *) +{ + return E_NOTIMPL; +} + +/** + * Returns key binding object (if any) associated with specified action + * key binding is string. + * e.g. "alt+d" (like IAccessible::get_accKeyboardShortcut). + * + * @param actionIndex the index of action. + * @param nMaxBinding the max number of key binding. + * @param keyBinding the key binding array. + * @param nBinding the actual number of key binding returned. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccActionBase::get_keyBinding( + /* [in] */ long actionIndex, + /* [in] */ long, + /* [length_is][length_is][size_is][size_is][out] */ BSTR __RPC_FAR *__RPC_FAR *keyBinding, + /* [retval][out] */ long __RPC_FAR *nBinding) +{ + SolarMutexGuard g; + + try { + + if( !keyBinding || !nBinding) + return E_INVALIDARG; + + if( !pRXAct.is() ) + return E_FAIL; + + Reference< XAccessibleKeyBinding > binding = GetXInterface()->getAccessibleActionKeyBinding(actionIndex); + if( !binding.is() ) + return E_FAIL; + + sal_Int32 nCount = binding->getAccessibleKeyBindingCount(); + + *keyBinding = static_cast<BSTR*>(::CoTaskMemAlloc(nCount*sizeof(BSTR))); + + // #CHECK Memory Allocation# + if(*keyBinding == nullptr) + return E_FAIL; + + for( sal_Int32 index = 0;index < nCount;index++ ) + { + auto const wString = comphelper::GetkeyBindingStrByXkeyBinding( + binding->getAccessibleKeyBinding(index)); + + (*keyBinding)[index] = SysAllocString(o3tl::toW(wString.getStr())); + } + + *nBinding = nCount; + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Override of IUNOXWrapper. + * + * @param pXInterface the pointer of UNO interface. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccActionBase::put_XInterface(hyper pXInterface) +{ + // internal IUNOXWrapper - no mutex meeded + + try { + + CUNOXWrapper::put_XInterface(pXInterface); + + //special query. + if(pUNOInterface == nullptr) + return E_FAIL; + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + if( !pRContext.is() ) + return E_FAIL; + + Reference<XAccessibleAction> pRXI(pRContext,UNO_QUERY); + if( !pRXI.is() ) + pRXAct = nullptr; + else + pRXAct = pRXI.get(); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccActionBase.h b/winaccessibility/source/UAccCOM/AccActionBase.h new file mode 100644 index 000000000..26d3e7d05 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccActionBase.h @@ -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 . + */ + +// AccActionBase.h: interface for the CAccActionBase class. + +#pragma once + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include "UNOXWrapper.h" + +class ATL_NO_VTABLE CAccActionBase : public CUNOXWrapper +{ +public: + CAccActionBase(); + virtual ~CAccActionBase(); + + // IAccessibleAction +public: + // IAccessibleAction + + // Returns the number of action. + STDMETHOD(nActions)(/*[out,retval]*/ long* nActions); + + // Performs specified action on the object. + STDMETHOD(doAction)(/* [in] */ long actionIndex); + + // Gets description of specified action. + STDMETHOD(get_description)(long actionIndex, BSTR __RPC_FAR* description); + + // added , 2006/06/28, for driver 07/11 + // get the action name + STDMETHOD(get_name)(long actionIndex, BSTR __RPC_FAR* name); + + // get the localized action Name + STDMETHOD(get_localizedName)(long actionIndex, BSTR __RPC_FAR* localizedName); + + // Returns key binding object (if any) associated with specified action + // key binding is string. + // e.g. "alt+d" (like IAccessible::get_accKeyboardShortcut). + STDMETHOD(get_keyBinding) + ( + /* [in] */ long actionIndex, + /* [in] */ long nMaxBinding, + /* [length_is][length_is][size_is][size_is][out] */ BSTR __RPC_FAR* __RPC_FAR* keyBinding, + /* [retval][out] */ long __RPC_FAR* nBinding); + + // Override of IUNOXWrapper. + STDMETHOD(put_XInterface)(hyper pXInterface) override; + +protected: + css::uno::Reference<css::accessibility::XAccessibleAction> pRXAct; + +private: + css::accessibility::XAccessibleAction* GetXInterface() { return pRXAct.get(); } +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccComponent.cxx b/winaccessibility/source/UAccCOM/AccComponent.cxx new file mode 100644 index 000000000..2ca64cd7d --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccComponent.cxx @@ -0,0 +1,66 @@ +/* -*- 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 . + */ + +/** + * AccComponent.cpp : Implementation of CUAccCOMApp and DLL registration. + */ +#include "stdafx.h" +#include "AccComponent.h" + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +/** + * Returns the location of the upper left corner of the object's bounding + * box relative to the parent. + * + * @param Location the upper left corner of the object's bounding box. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponent::get_locationInParent(long* x, long* y) +{ + return CAccComponentBase::get_locationInParent(x, y); +} + +/** + * Returns the foreground color of this object. + * + * @param Color the color of foreground. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponent::get_foreground(IA2Color* foreground) +{ + return CAccComponentBase::get_foreground(foreground); +} + +/** + * Returns the background color of this object. + * + * @param Color the color of background. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponent::get_background(IA2Color* background) +{ + return CAccComponentBase::get_background(background); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccComponent.h b/winaccessibility/source/UAccCOM/AccComponent.h new file mode 100644 index 000000000..9a620a523 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccComponent.h @@ -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 "Resource.h" // main symbols + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleComponent.hpp> +#include "UNOXWrapper.h" +#include "AccComponentBase.h" + + +/** + * CAccComponent implements IAccessibleComponent interface. + */ +class ATL_NO_VTABLE CAccComponent : + public CComObjectRoot, + public CComCoClass<CAccComponent,&CLSID_AccComponent>, + public IAccessibleComponent, + public CAccComponentBase +{ +public: + CAccComponent() + { + } + + BEGIN_COM_MAP(CAccComponent) + COM_INTERFACE_ENTRY(IAccessibleComponent) + COM_INTERFACE_ENTRY(IUNOXWrapper) + COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_) +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + END_COM_MAP() +#if defined __clang__ +#pragma clang diagnostic pop +#endif + + static HRESULT WINAPI SmartQI_(void* pv, + REFIID iid, void** ppvObject, DWORD_PTR) + { + return static_cast<CAccComponent*>(pv)->SmartQI(iid,ppvObject); + } + + HRESULT SmartQI(REFIID iid, void** ppvObject) + { + if( m_pOuterUnknown ) + return OuterQueryInterface(iid,ppvObject); + return E_FAIL; + } + + DECLARE_NO_REGISTRY() + +public: + // IAccessibleComponent + + // Returns the location of the upper left corner of the object's bounding + // box relative to the parent. + STDMETHOD(get_locationInParent)(long *x, long *y) override; + + // Returns the foreground color of this object. + STDMETHOD(get_foreground)(IA2Color * foreground) override; + + // Returns the background color of this object. + STDMETHOD(get_background)(IA2Color * background) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccComponentBase.cxx b/winaccessibility/source/UAccCOM/AccComponentBase.cxx new file mode 100644 index 000000000..ed44c2c93 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccComponentBase.cxx @@ -0,0 +1,214 @@ +/* -*- 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 "stdafx.h" +#include "AccComponentBase.h" +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <vcl/svapp.hxx> +#include "MAccessible.h" + +using namespace com::sun::star::accessibility; +using namespace com::sun::star::uno; + +// Construction/Destruction + +CAccComponentBase::CAccComponentBase() {} + +CAccComponentBase::~CAccComponentBase() {} + +/** + * Returns the location of the upper left corner of the object's bounding + * box relative to the parent. + * + * @param Location the upper left corner of the object's bounding box. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponentBase::get_locationInParent(long* x, long* y) +{ + SolarMutexGuard g; + + try + { + if (x == nullptr || y == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if (!pRXComp.is()) + return E_FAIL; + + const css::awt::Point& pt = GetXInterface()->getLocation(); + *x = pt.X; + *y = pt.Y; + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +/** + * Returns the location of the upper left corner of the object's bounding + * box in screen. + * + * @param Location the upper left corner of the object's bounding + * box in screen coordinates. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponentBase::get_locationOnScreen(long* x, long* y) +{ + SolarMutexGuard g; + + try + { + if (x == nullptr || y == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if (!pRXComp.is()) + return E_FAIL; + + const css::awt::Point& pt = GetXInterface()->getLocationOnScreen(); + *x = pt.X; + *y = pt.Y; + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +/** + * Grabs the focus to this object. + * + * @param success the boolean result to be returned. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponentBase::grabFocus(boolean* success) +{ + SolarMutexGuard g; + + try + { + if (success == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if (!pRXComp.is()) + { + return E_FAIL; + } + GetXInterface()->grabFocus(); + *success = TRUE; + + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +/** + * Returns the foreground color of this object. + * + * @param Color the color of foreground. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponentBase::get_foreground(IA2Color* foreground) +{ + SolarMutexGuard g; + + try + { + if (foreground == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if (!pRXComp.is()) + { + return E_FAIL; + } + *foreground = static_cast<long>(GetXInterface()->getForeground()); + + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +/** + * Returns the background color of this object. + * + * @param Color the color of background. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponentBase::get_background(IA2Color* background) +{ + SolarMutexGuard g; + + try + { + if (background == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if (!pRXComp.is()) + { + return E_FAIL; + } + *background = static_cast<long>(GetXInterface()->getBackground()); + + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +/** + * Override of IUNOXWrapper. + * + * @param pXInterface the pointer of UNO interface. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccComponentBase::put_XInterface(hyper pXInterface) +{ + // internal IUNOXWrapper - no mutex meeded + + try + { + CUNOXWrapper::put_XInterface(pXInterface); + //special query. + if (pUNOInterface == nullptr) + return E_FAIL; + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + if (!pRContext.is()) + { + return E_FAIL; + } + Reference<XAccessibleComponent> pRXI(pRContext, UNO_QUERY); + if (!pRXI.is()) + pRXComp = nullptr; + else + pRXComp = pRXI.get(); + + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccComponentBase.h b/winaccessibility/source/UAccCOM/AccComponentBase.h new file mode 100644 index 000000000..83770ba2d --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccComponentBase.h @@ -0,0 +1,63 @@ +/* -*- 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 . + */ + +// AccComponentBase.h: interface for the CAccComponentBase class. + +#pragma once + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/accessibility/XAccessibleComponent.hpp> +#include "UNOXWrapper.h" + +class ATL_NO_VTABLE CAccComponentBase : public CUNOXWrapper +{ +public: + CAccComponentBase(); + virtual ~CAccComponentBase(); + // IAccessibleComponent +public: + // IAccessibleComponent + + // Returns the location of the upper left corner of the object's bounding + // box relative to the parent. + STDMETHOD(get_locationInParent)(long* x, long* y); + + // Returns the location of the upper left corner of the object's bounding + // box in screen. + STDMETHOD(get_locationOnScreen)(long* x, long* y); + + // Grabs the focus to this object. + STDMETHOD(grabFocus)(boolean* success); + + // Returns the foreground color of this object. + STDMETHOD(get_foreground)(IA2Color* foreground); + + // Returns the background color of this object. + STDMETHOD(get_background)(IA2Color* background); + + // Override of IUNOXWrapper. + STDMETHOD(put_XInterface)(hyper pXInterface) override; + +protected: + css::uno::Reference<css::accessibility::XAccessibleComponent> pRXComp; + + css::accessibility::XAccessibleComponent* GetXInterface() { return pRXComp.get(); } +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccEditableText.cxx b/winaccessibility/source/UAccCOM/AccEditableText.cxx new file mode 100644 index 000000000..2bfd84366 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccEditableText.cxx @@ -0,0 +1,505 @@ +/* -*- 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 . + */ + +/** + * AccEditableText.cpp : Implementation of CUAccCOMApp and DLL registration. + */ +#include "stdafx.h" +#include "AccEditableText.h" + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +#include <vcl/svapp.hxx> +#include <o3tl/char16_t2wchar_t.hxx> + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleText.hpp> +#include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/style/LineSpacing.hpp> +#include <com/sun/star/style/TabStop.hpp> +#include <vector> + +using namespace com::sun::star::accessibility; +using namespace com::sun::star::uno; +using namespace com::sun::star::awt; +using namespace com::sun::star::beans; + +/** + * Copy a range of text to the clipboard. + * + * @param startOffset the start offset of copying. + * @param endOffset the end offset of copying. + * @param success the boolean result to be returned. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::copyText(long startOffset, long endOffset) +{ + SolarMutexGuard g; + + try { + + // #CHECK XInterface# + if(!pRXEdtTxt.is()) + { + return E_FAIL; + } + + if ( GetXInterface()->copyText( startOffset, endOffset ) ) + return S_OK; + + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** + * Deletes a range of text. + * + * @param startOffset the start offset of deleting. + * @param endOffset the end offset of deleting. + * @param success the boolean result to be returned. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::deleteText(long startOffset, long endOffset) +{ + SolarMutexGuard g; + + try { + + if( !pRXEdtTxt.is() ) + return E_FAIL; + + if( GetXInterface()->deleteText( startOffset, endOffset ) ) + return S_OK; + + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** + * Inserts text at a specified offset. + * + * @param offset the offset of inserting. + * @param text the text to be inserted. + * @param success the boolean result to be returned. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::insertText(long offset, BSTR * text) +{ + SolarMutexGuard g; + + try { + + if (text == nullptr) + return E_INVALIDARG; + + if( !pRXEdtTxt.is() ) + return E_FAIL; + + OUString ouStr(o3tl::toU(*text)); + + if( GetXInterface()->insertText( ouStr, offset ) ) + return S_OK; + + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** + * Cuts a range of text to the clipboard. + * + * @param startOffset the start offset of cutting. + * @param endOffset the end offset of cutting. + * @param success the boolean result to be returned. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::cutText(long startOffset, long endOffset) +{ + SolarMutexGuard g; + + try { + + if( !pRXEdtTxt.is() ) + return E_FAIL; + + if( GetXInterface()->cutText( startOffset, endOffset ) ) + return S_OK; + + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** + * Pastes text from clipboard at specified offset. + * + * @param offset the offset of pasting. + * @param success the boolean result to be returned. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::pasteText(long offset) +{ + SolarMutexGuard g; + + try { + + if( !pRXEdtTxt.is() ) + return E_FAIL; + + if( GetXInterface()->pasteText( offset ) ) + return S_OK; + + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** + * Replaces range of text with new text. + * + * @param startOffset the start offset of replacing. + * @param endOffset the end offset of replacing. + * @param text the replacing text. + * @param success the boolean result to be returned. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::replaceText(long startOffset, long endOffset, BSTR * text) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if (text == nullptr) + return E_INVALIDARG; + if( !pRXEdtTxt.is() ) + return E_FAIL; + + OUString ouStr(o3tl::toU(*text)); + + if( GetXInterface()->replaceText( startOffset,endOffset, ouStr) ) + return S_OK; + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** + * Sets attributes of range of text. + * + * @param startOffset the start offset. + * @param endOffset the end offset. + * @param attributes the attribute text. + * @param success the boolean result to be returned. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::setAttributes(long startOffset, long endOffset, BSTR * attributes) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if (attributes == nullptr) + return E_INVALIDARG; + if( !pRXEdtTxt.is() ) + return E_FAIL; + + OUString ouStr(o3tl::toU(*attributes)); + + std::vector< OUString > vecAttr; + for (sal_Int32 nIndex {0}; nIndex >= 0; ) + vecAttr.push_back(ouStr.getToken(0, ';', nIndex)); + + Sequence< PropertyValue > beanSeq(vecAttr.size()); + auto beanSeqRange = asNonConstRange(beanSeq); + for(std::vector<OUString>::size_type i = 0; i < vecAttr.size(); i ++) + { + OUString attr = vecAttr[i]; + sal_Int32 nPos = attr.indexOf(':'); + if(nPos > -1) + { + OUString attrName = attr.copy(0, nPos); + OUString attrValue = attr.copy(nPos + 1); + beanSeqRange[i].Name = attrName; + get_AnyFromOLECHAR(attrName, attrValue, beanSeqRange[i].Value); + } + } + + if( GetXInterface()->setAttributes( startOffset,endOffset, beanSeq) ) + return S_OK; + + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** + * Convert attributes string to Any type. + * + * @param ouName the string of attribute name. + * @param ouValue the string of attribute value. + * @param rAny the Any object to be returned. + */ +void CAccEditableText::get_AnyFromOLECHAR(std::u16string_view ouName, const OUString &ouValue, Any &rAny) +{ + if(ouName == u"CharBackColor" || + ouName == u"CharColor" || + ouName == u"ParaAdjust" || + ouName == u"ParaFirstLineIndent" || + ouName == u"ParaLeftMargin" || + ouName == u"ParaRightMargin" || + ouName == u"ParaTopMargin" || + ouName == u"ParaBottomMargin" || + ouName == u"CharFontPitch" ) + { + // Convert to int. + // NOTE: CharFontPitch is not implemented in java file. + sal_Int32 nValue = ouValue.toInt32(); + rAny.setValue(&nValue, cppu::UnoType<sal_Int32>::get()); + } + else if(ouName == u"CharShadowed" || + ouName == u"CharContoured" ) + { + // Convert to boolean. + rAny <<= ouValue.toBoolean(); + } + else if(ouName == u"CharEscapement" || + ouName == u"CharStrikeout" || + ouName == u"CharUnderline" || + ouName == u"CharFontPitch" ) + { + // Convert to short. + short nValue = static_cast<short>(ouValue.toInt32()); + rAny.setValue(&nValue, cppu::UnoType<short>::get()); + } + else if(ouName == u"CharHeight" || + ouName == u"CharWeight" ) + { + // Convert to float. + float fValue = ouValue.toFloat(); + rAny.setValue(&fValue, cppu::UnoType<float>::get()); + } + else if(ouName == u"CharFontName" ) + { + // Convert to string. + rAny.setValue(&ouValue, cppu::UnoType<OUString>::get()); + } + else if(ouName == u"CharPosture" ) + { + // Convert to FontSlant. + css::awt::FontSlant fontSlant = static_cast<css::awt::FontSlant>(ouValue.toInt32()); + rAny.setValue(&fontSlant, cppu::UnoType<css::awt::FontSlant>::get()); + } + else if(ouName == u"ParaTabStops" ) + { + + // Convert to the Sequence with TabStop element. + std::vector< css::style::TabStop > vecTabStop; + css::style::TabStop tabStop; + OUString ouSubValue; + sal_Int32 pos = 0, posComma = 0; + + do + { + // Position. + pos = ouValue.indexOf("Position=", pos); + if(pos != -1) + { + posComma = ouValue.indexOf(',', pos + 9); // 9 = length of "Position=". + if(posComma != -1) + { + ouSubValue = ouValue.copy(pos + 9, posComma - pos - 9); + tabStop.Position = ouSubValue.toInt32(); + pos = posComma + 1; + + // TabAlign. + pos = ouValue.indexOf("TabAlign=", pos); + if(pos != -1) + { + posComma = ouValue.indexOf(',', pos + 9); // 9 = length of "TabAlign=". + if(posComma != -1) + { + ouSubValue = ouValue.copy(pos + 9, posComma - pos - 9); + tabStop.Alignment = static_cast<css::style::TabAlign>(ouSubValue.toInt32()); + pos = posComma + 1; + + // DecimalChar. + pos = ouValue.indexOf("DecimalChar=", pos); + if(pos != -1) + { + posComma = ouValue.indexOf(',', pos + 11); // 11 = length of "TabAlign=". + if(posComma != -1) + { + ouSubValue = ouValue.copy(pos + 11, posComma - pos - 11); + tabStop.DecimalChar = ouSubValue.toChar(); + pos = posComma + 1; + + // FillChar. + pos = ouValue.indexOf("FillChar=", pos); + if(pos != -1) + { + posComma = ouValue.indexOf(',', pos + 9); // 9 = length of "TabAlign=". + if(posComma != -1) + { + ouSubValue = ouValue.copy(pos + 9, posComma - pos - 9); + tabStop.DecimalChar = ouSubValue.toChar(); + pos = posComma + 1; + + // Complete TabStop element. + vecTabStop.push_back(tabStop); + } + else + break; // No match comma. + } + else + break; // No match FillChar. + } + else + break; // No match comma. + } + else + break; // No match DecimalChar. + } + else + break; // No match comma. + } + else + break; // No match TabAlign. + } + else + break; // No match comma. + } + else + break; // No match Position. + } + while(pos < ouValue.getLength()); + + + // Dump into Sequence. + int iSeqLen = vecTabStop.empty() ? 1 : vecTabStop.size(); + Sequence< css::style::TabStop > seqTabStop(iSeqLen); + auto pseqTabStop = seqTabStop.getArray(); + + if (!vecTabStop.empty()) + { + // Dump every element. + for(int i = 0; i < iSeqLen; i ++) + { + pseqTabStop[i] = vecTabStop[i]; + } + } + else + { + // Create default value. + pseqTabStop[0].Position = 0; + pseqTabStop[0].Alignment = css::style::TabAlign_DEFAULT; + pseqTabStop[0].DecimalChar = '.'; + pseqTabStop[0].FillChar = ' '; + } + + // Assign to Any object. + rAny.setValue(&seqTabStop, cppu::UnoType<Sequence< css::style::TabStop >>::get()); + } + else if(ouName == u"ParaLineSpacing" ) + { + // Parse value string. + css::style::LineSpacing lineSpacing; + OUString ouSubValue; + sal_Int32 pos = 0, posComma = 0; + + pos = ouValue.indexOf("Mode=", pos); + if(pos != -1) + { + posComma = ouValue.indexOf(',', pos + 5); // 5 = length of "Mode=". + if(posComma != -1) + { + ouSubValue = ouValue.copy(pos + 5, posComma - pos - 5); + lineSpacing.Mode = static_cast<sal_Int16>(ouSubValue.toInt32()); + pos = posComma + 1; + + pos = ouValue.indexOf("Height=", pos); + if(pos != -1) + { + ouSubValue = ouValue.copy(pos + 7); + lineSpacing.Height = static_cast<sal_Int16>(ouSubValue.toInt32()); + } + else + { + lineSpacing.Height = sal_Int16(100); // Default height. + } + } + else + { + lineSpacing.Height = sal_Int16(100); // Default height. + } + } + else + { + // Default Mode and Height. + lineSpacing.Mode = sal_Int16(0); + lineSpacing.Height = sal_Int16(100); // Default height. + } + + // Convert to Any object. + rAny.setValue(&lineSpacing, cppu::UnoType<css::style::LineSpacing>::get()); + } + else + { + // Do nothing. + sal_Int32 nDefault = 0; + rAny.setValue(&nDefault, cppu::UnoType<sal_Int32>::get()); + } +} + +/** + * Override of IUNOXWrapper. + * + * @param pXInterface the pointer of UNO interface. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccEditableText::put_XInterface(hyper pXInterface) +{ + // internal IUNOXWrapper - no mutex meeded + + try { + + CUNOXWrapper::put_XInterface(pXInterface); + //special query. + if(pUNOInterface == nullptr) + return E_FAIL; + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + if( !pRContext.is() ) + { + return E_FAIL; + } + Reference<XAccessibleEditableText> pRXI(pRContext,UNO_QUERY); + if( !pRXI.is() ) + pRXEdtTxt = nullptr; + else + pRXEdtTxt = pRXI.get(); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccEditableText.h b/winaccessibility/source/UAccCOM/AccEditableText.h new file mode 100644 index 000000000..244dc626b --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccEditableText.h @@ -0,0 +1,118 @@ +/* -*- 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 <string_view> + +#include "Resource.h" +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/accessibility/XAccessibleEditableText.hpp> +#include "UNOXWrapper.h" + +/** + * CAccEditableText implements IAccessibleEditableText interface. + */ +class CAccEditableText : + public CComObjectRoot, + public CComCoClass<CAccEditableText,&CLSID_AccEditableText>, + public IAccessibleEditableText, + public CUNOXWrapper +{ +public: + CAccEditableText() + { + + } + virtual ~CAccEditableText() + { + + } + + BEGIN_COM_MAP(CAccEditableText) + COM_INTERFACE_ENTRY(IAccessibleEditableText) + COM_INTERFACE_ENTRY(IUNOXWrapper) + COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_) +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + END_COM_MAP() +#if defined __clang__ +#pragma clang diagnostic pop +#endif + + static HRESULT WINAPI SmartQI_(void* pv, + REFIID iid, void** ppvObject, DWORD_PTR) + { + return static_cast<CAccEditableText*>(pv)->SmartQI(iid,ppvObject); + } + + HRESULT SmartQI(REFIID iid, void** ppvObject) + { + if( m_pOuterUnknown ) + return OuterQueryInterface(iid,ppvObject); + return E_FAIL; + } + + DECLARE_NO_REGISTRY() + +public: + // IAccessibleEditableText + + // Copies a range of text to the clipboard. + STDMETHOD(copyText)(long startOffset, long endOffset) override; + + // Deletes a range of text. + STDMETHOD(deleteText)(long startOffset, long endOffset) override; + + // Inserts text at a specified offset. + STDMETHOD(insertText)(long offset, BSTR * text) override; + + // Cuts a range of text to the clipboard. + STDMETHOD(cutText)(long startOffset, long endOffset) override; + + // Pastes text from clipboard at specified offset. + STDMETHOD(pasteText)(long offset) override; + + // Replaces range of text with new text. + STDMETHOD(replaceText)(long startOffset, long endOffset, BSTR * text) override; + + + // Sets attributes of range of text. + STDMETHOD(setAttributes)(long startOffset, long endOffset, BSTR * attributes) override; + + // Override of IUNOXWrapper. + STDMETHOD(put_XInterface)(hyper pXInterface) override; + +private: + + css::uno::Reference<css::accessibility::XAccessibleEditableText> pRXEdtTxt; + + static void get_AnyFromOLECHAR(std::u16string_view ouName, const OUString &ouValue, css::uno::Any &rAny); + + css::accessibility::XAccessibleEditableText* GetXInterface() + { + return pRXEdtTxt.get(); + } +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccHyperLink.cxx b/winaccessibility/source/UAccCOM/AccHyperLink.cxx new file mode 100644 index 000000000..6857540c3 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccHyperLink.cxx @@ -0,0 +1,300 @@ +/* -*- 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 "stdafx.h" +#include "AccHyperLink.h" + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +#include <vcl/svapp.hxx> + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include "MAccessible.h" + +using namespace com::sun::star::accessibility; +using namespace com::sun::star::uno; +using namespace com::sun::star::awt; + +/** + * Returns the number of action. + * + * @param nActions the number of action. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::nActions(/*[out,retval]*/long* nActions) +{ + + return CAccActionBase::nActions(nActions); +} + +/** + * Performs specified action on the object. + * + * @param actionIndex the index of action. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::doAction(/* [in] */ long actionIndex) +{ + + return CAccActionBase::doAction(actionIndex); +} + +/** + * Gets description of specified action. + * + * @param actionIndex the index of action. + * @param description the description string of the specified action. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_description(long actionIndex,BSTR __RPC_FAR *description) +{ + + return CAccActionBase::get_description(actionIndex, description); +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_name( long actionIndex, BSTR __RPC_FAR *name) +{ + + return CAccActionBase::get_name(actionIndex, name); +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_localizedName( long actionIndex, BSTR __RPC_FAR *localizedName) +{ + + return CAccActionBase::get_name(actionIndex, localizedName); +} + +/** + * Returns key binding object (if any) associated with specified action + * key binding is string. + * e.g. "alt+d" (like IAccessible::get_accKeyboardShortcut). + * + * @param actionIndex the index of action. + * @param nMaxBinding the max number of key binding. + * @param keyBinding the key binding array. + * @param nBinding the actual number of key binding returned. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_keyBinding( + /* [in] */ long actionIndex, + /* [in] */ long nMaxBinding, + /* [length_is][length_is][size_is][size_is][out] */ BSTR __RPC_FAR *__RPC_FAR *keyBinding, + /* [retval][out] */ long __RPC_FAR *nBinding) +{ + + return CAccActionBase::get_keyBinding(actionIndex, nMaxBinding, keyBinding, nBinding); +} + +/** + * get an object + * @param + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_anchor(/* [in] */ long index, + /* [retval][out] */ VARIANT __RPC_FAR *anchor) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(anchor == nullptr) + { + return E_INVALIDARG; + } + // #CHECK XInterface# + if(!pRXLink.is()) + { + return E_FAIL; + } + // Get Any type value via pRXLink. + css::uno::Any anyVal = GetXInterface()->getAccessibleActionAnchor(index); + // Convert Any to VARIANT. + CMAccessible::ConvertAnyToVariant(anyVal, anchor); + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * get an object + * @param + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_anchorTarget(/* [in] */ long index, + /* [retval][out] */ VARIANT __RPC_FAR *anchorTarget) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(anchorTarget == nullptr) + { + return E_INVALIDARG; + } + // #CHECK XInterface# + if(!pRXLink.is()) + { + return E_FAIL; + } + // Get Any type value via pRXLink. + css::uno::Any anyVal = GetXInterface()->getAccessibleActionObject(index); + // Convert Any to VARIANT. + CMAccessible::ConvertAnyToVariant(anyVal, anchorTarget); + + return S_OK; + + } catch(...) { return E_FAIL; } +} + + +/** + * Get start index. + * @param index Variant to get start index. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_startIndex(/* [retval][out] */ long __RPC_FAR *index) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(index == nullptr) + { + return E_INVALIDARG; + } + *index = GetXInterface()->getStartIndex(); + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Get start index. + * @param index Variant to get end index. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_endIndex(/* [retval][out] */ long __RPC_FAR *index) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(index == nullptr) + { + return E_INVALIDARG; + } + // #CHECK XInterface# + if(!pRXLink.is()) + { + return E_FAIL; + } + *index = GetXInterface()->getEndIndex(); + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Judge if the hyperlink is valid. + * @param valid Variant to get validity. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::get_valid(/* [retval][out] */ boolean __RPC_FAR *valid) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(valid == nullptr) + { + return E_INVALIDARG; + } + // #CHECK XInterface# + if(!pRXLink.is()) + { + return E_FAIL; + } + *valid = GetXInterface()->isValid(); + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Put UNO interface. + * @param pXInterface XAccessibleContext interface. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::put_XInterface(hyper pXInterface) +{ + // internal IUNOXWrapper - no mutex meeded + + try { + + CAccActionBase::put_XInterface(pXInterface); + //special query. + if(pUNOInterface != nullptr) + { + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + if( !pRContext.is() ) + { + return E_FAIL; + } + Reference<XAccessibleHyperlink> pRXI(pRContext,UNO_QUERY); + if( !pRXI.is() ) + { + pRXLink = nullptr; + } + else + pRXLink = pRXI.get(); + } + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Put UNO interface. + * @param pXSubInterface XAccessibleHyperlink interface. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHyperLink::put_XSubInterface(hyper pXSubInterface) +{ + // internal IUNOXWrapper - no mutex meeded + + pRXLink = reinterpret_cast<XAccessibleHyperlink*>(pXSubInterface); + pRXAct = reinterpret_cast<XAccessibleAction*>(pXSubInterface); + + return S_OK; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccHyperLink.h b/winaccessibility/source/UAccCOM/AccHyperLink.h new file mode 100644 index 000000000..42d65a833 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccHyperLink.h @@ -0,0 +1,136 @@ +/* -*- 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 "Resource.h" // main symbols + +#include <com/sun/star/accessibility/XAccessibleHyperlink.hpp> +#include "AccActionBase.h" +#include "UNOXWrapper.h" + +/** + * CAccHyperLink implements IAccessibleHyperlink interface. + */ +class ATL_NO_VTABLE CAccHyperLink : + public CComObjectRoot, + public CComCoClass<CAccHyperLink,&CLSID_AccHyperLink>, + public IAccessibleHyperlink, + public CAccActionBase +{ +public: + CAccHyperLink() + { + } + + BEGIN_COM_MAP(CAccHyperLink) + COM_INTERFACE_ENTRY(IAccessibleAction) + COM_INTERFACE_ENTRY(IAccessibleHyperlink) + COM_INTERFACE_ENTRY(IUNOXWrapper) +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + END_COM_MAP() +#if defined __clang__ +#pragma clang diagnostic pop +#endif + + DECLARE_NO_REGISTRY() + + static HRESULT WINAPI SmartQI_(void* pv, + REFIID iid, void** ppvObject, DWORD_PTR) + { + return static_cast<CAccHyperLink*>(pv)->SmartQI(iid,ppvObject); + } + + HRESULT SmartQI(REFIID iid, void** ppvObject) + { + if( m_pOuterUnknown ) + return OuterQueryInterface(iid,ppvObject); + return E_FAIL; + } + + // IAccessibleHyperlink +public: + // IAccessibleAction + + // Returns the number of action. + STDMETHOD(nActions)(/*[out,retval]*/long* nActions) override; + + // Performs specified action on the object. + STDMETHOD(doAction)(/* [in] */ long actionIndex) override; + + // get the action name + STDMETHOD(get_name)( long actionIndex, BSTR __RPC_FAR *name) override; + + // get the localized action name + STDMETHOD(get_localizedName)( long actionIndex, BSTR __RPC_FAR *localizedName) override; + + // Gets description of specified action. + STDMETHOD(get_description)(long actionIndex,BSTR __RPC_FAR *description) override; + + // Returns key binding object (if any) associated with specified action + // key binding is string. + // e.g. "alt+d" (like IAccessible::get_accKeyboardShortcut). + STDMETHOD(get_keyBinding)( + /* [in] */ long actionIndex, + /* [in] */ long nMaxBinding, + /* [length_is][length_is][size_is][size_is][out] */ BSTR __RPC_FAR *__RPC_FAR *keyBinding, + /* [retval][out] */ long __RPC_FAR *nBinding) override; + + // IAccessibleHyperlink + + // get an object, e.g. BSTR or image object, that is overloaded with link behavior + STDMETHOD(get_anchor)(/* [in] */ long index, + /* [retval][out] */ VARIANT __RPC_FAR *anchor) override; + + // get an object representing the target of the link, usually a BSTR of the URI + STDMETHOD(get_anchorTarget)(/* [in] */ long index, + /* [retval][out] */ VARIANT __RPC_FAR *anchorTarget) override; + + // Returns the index at which the textual representation of the + // hyperlink (group) starts. + STDMETHOD(get_startIndex)(/* [retval][out] */ long __RPC_FAR *index) override; + + // Returns the index at which the textual representation of the + // hyperlink (group) ends. + STDMETHOD(get_endIndex)(/* [retval][out] */ long __RPC_FAR *index) override; + + // Returns whether the document referenced by this links is still valid. + STDMETHOD(get_valid)(/* [retval][out] */ boolean __RPC_FAR *valid) override; + + // Override of IUNOXWrapper. + STDMETHOD(put_XInterface)(hyper pXInterface) override; + + // Override of IUNOXWrapper. + STDMETHOD(put_XSubInterface)(hyper pXSubInterface) override; + +private: + + css::uno::Reference<css::accessibility::XAccessibleHyperlink> pRXLink; + + css::accessibility::XAccessibleHyperlink* GetXInterface() + { + return pRXLink.get(); + } + +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccHypertext.cxx b/winaccessibility/source/UAccCOM/AccHypertext.cxx new file mode 100644 index 000000000..722f13b5c --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccHypertext.cxx @@ -0,0 +1,401 @@ +/* -*- 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 "stdafx.h" +#include "AccHypertext.h" +#include "AccHyperLink.h" +#include "acccommon.h" + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +#include <vcl/svapp.hxx> + + +using namespace com::sun::star::accessibility; +using namespace com::sun::star::uno; + + +/** + * Get special selection. + * @param startOffset Start selection offset. + * @param endOffset End selection offset. + * @param success Variant to accept the result of if the method call is successful. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::addSelection(long startOffset, long endOffset) +{ + + return CAccTextBase::get_addSelection(startOffset, endOffset); +} + + +/** + * Get special attributes. + * @param offset Offset. + * @param startOffset Variant to accept start offset. + * @param endOffset Variant to accept end offset. + * @param textAttributes Variant to accept attributes. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_attributes(long offset, long * startOffset, long * endOffset, BSTR * textAttributes) +{ + + return CAccTextBase::get_attributes(offset, startOffset, endOffset, textAttributes); +} + +/** + * Get caret position. + * @param offset Variant to accept caret offset. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_caretOffset(long * offset) +{ + + return CAccTextBase::get_caretOffset(offset); +} + +/** + * Get character extents. + * @param offset Offset. + * @param x Variant to accept x position. + * @param y Variant to accept y position. + * @param width Variant to accept width. + * @param Height Variant to accept height. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_characterExtents(long offset, IA2CoordinateType coordType, long * x, long * y, long * width, long * height) +{ + + return CAccTextBase::get_characterExtents(offset, coordType, x, y, width, height); +} + +/** + * Get selections count. + * @param nSelections Variant to accept selections count. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_nSelections(long * nSelections) +{ + + return CAccTextBase::get_nSelections(nSelections); +} + +/** + * Get offset of some special point. + * @param x X position of one point. + * @param x Y position of one point. + * @param coordType Type. + * @param offset Variant to accept offset. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_offsetAtPoint(long x, long y, IA2CoordinateType coordType, long * offset) +{ + return CAccTextBase::get_offsetAtPoint(x, y, coordType, offset); +} + +/** + * Get selection range. + * @param selection selection count. + * @param startOffset Variant to accept the start offset of special selection. + * @param endOffset Variant to accept the end offset of special selection. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_selection(long selection, long * startOffset, long * endOffset) +{ + + return CAccTextBase::get_selection(selection, startOffset, endOffset); +} + +/** + * Get special text. + * @param startOffset Start position of special range. + * @param endOffset End position of special range. + * @param text Variant to accept the text of special range. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_text(long startOffset, long endOffset, BSTR * text) +{ + + return CAccTextBase::get_text(startOffset, endOffset, text); +} + +/** + * Get special text before some position. + * @param offset Special position. + * @param boundaryType Boundary type. + * @param startOffset Variant to accept the start offset. + * @param endOffset Variant to accept the end offset. + * @param text Variant to accept the special text. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_textBeforeOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) +{ + + return CAccTextBase::get_textBeforeOffset(offset, boundaryType, + startOffset, endOffset, text); +} + +/** + * Get special text after some position. + * @param offset Special position. + * @param boundaryType Boundary type. + * @param startOffset Variant to accept the start offset. + * @param endOffset Variant to accept the end offset. + * @param text Variant to accept the special text. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_textAfterOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) +{ + + return CAccTextBase::get_textAfterOffset(offset, boundaryType, + startOffset, endOffset, text); +} + +/** + * Get special text at some position. + * @param offset Special position. + * @param boundaryType Boundary type. + * @param startOffset Variant to accept the start offset. + * @param endOffset Variant to accept the end offset. + * @param text Variant to accept the special text. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_textAtOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) +{ + + return CAccTextBase::get_textAtOffset(offset, boundaryType, + startOffset, endOffset, text); +} + +/** + * Remove selection. + * @param selectionIndex Special selection index + * @param success Variant to accept the method called result. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::removeSelection(long selectionIndex) +{ + + return CAccTextBase::removeSelection(selectionIndex); +} + +/** + * Set caret position. + * @param offset Special position. + * @param success Variant to accept the method called result. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::setCaretOffset(long offset) +{ + + return CAccTextBase::setCaretOffset(offset); +} + +/** + * Set special selection. + * @param selectionIndex Special selection index. + * @param startOffset start position. + * @param endOffset end position. + * @param success Variant to accept the method called result. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::setSelection(long selectionIndex, long startOffset, long endOffset) +{ + + return CAccTextBase::setSelection(selectionIndex, startOffset, + endOffset); +} + +/** + * Get characters count. + * @param nCharacters Variant to accept the characters count. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_nCharacters(long * nCharacters) +{ + + return CAccTextBase::get_nCharacters(nCharacters); +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_newText( IA2TextSegment *newText) +{ + return CAccTextBase::get_newText(newText); +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_oldText( IA2TextSegment *oldText) +{ + return CAccTextBase::get_oldText(oldText); +} + +/** + * Scroll to special sub-string . + * @param startIndex Start index of sub string. + * @param endIndex End index of sub string. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::scrollSubstringToPoint(long startIndex, long endIndex,enum IA2CoordinateType coordinateType, long x, long y ) +{ + + return CAccTextBase::scrollSubstringToPoint(startIndex, endIndex, coordinateType, x, y); +} +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::scrollSubstringTo(long startIndex, long endIndex,enum IA2ScrollType scrollType) +{ + + return CAccTextBase::scrollSubstringTo(startIndex, endIndex,scrollType); +} + +/** + * Get hyperlink count. + * @param hyperlinkCount Variant to accept hyperlink count. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_nHyperlinks(long *hyperlinkCount) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(hyperlinkCount == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if(!pHyperText.is()) + { + return E_FAIL; + } + + *hyperlinkCount = pHyperText->getHyperLinkCount(); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Get special hyperlink. + * @param index Special hyperlink index. + * @param hyperlink Variant to accept special hyperlink via index. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_hyperlink(long index,IAccessibleHyperlink **hyperlink) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(hyperlink == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if(!pHyperText.is()) + { + return E_FAIL; + } + + Reference<XAccessibleHyperlink> pRLink = pHyperText->getHyperLink(index); + if(!pRLink.is()) + { + *hyperlink = nullptr; + return E_FAIL; + } + + IAccessibleHyperlink* plink = nullptr; + HRESULT hr = createInstance<CAccHyperLink>(IID_IAccessibleHyperlink, &plink); + if( SUCCEEDED(hr) ) + { + IUNOXWrapper* wrapper = nullptr; + plink->QueryInterface(IID_IUNOXWrapper, reinterpret_cast<void**>(&wrapper)); + if(wrapper) + { + wrapper->put_XSubInterface(reinterpret_cast<hyper>(pRLink.get())); + wrapper->Release(); + } + *hyperlink = plink; + return S_OK; + } + + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** + * Returns the index of the hyperlink that is associated with this character index. + * @param charIndex Special char index. + * @param hyperlinkIndex Variant to accept special hyperlink index. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::get_hyperlinkIndex(long charIndex, long *hyperlinkIndex) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(hyperlinkIndex == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if(!pHyperText.is()) + { + return E_FAIL; + } + + *hyperlinkIndex = pHyperText->getHyperLinkIndex(charIndex); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Put UNO interface. + * @param pXInterface UNO interface. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccHypertext::put_XInterface(hyper pXInterface) +{ + // internal IUNOXWrapper - no mutex meeded + + try { + + CAccTextBase::put_XInterface(pXInterface); + //special query. + if(pUNOInterface == nullptr) + return E_FAIL; + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + if( !pRContext.is() ) + { + return E_FAIL; + } + Reference<XAccessibleHypertext> pRXI(pRContext,UNO_QUERY); + if( !pRXI.is() ) + pHyperText = nullptr; + else + pHyperText = pRXI.get(); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccHypertext.h b/winaccessibility/source/UAccCOM/AccHypertext.h new file mode 100644 index 000000000..3a6dccfb1 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccHypertext.h @@ -0,0 +1,153 @@ +/* -*- 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 "Resource.h" // main symbols + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleHypertext.hpp> +#include "AccTextBase.h" + +/** + * CAccHypertext implements IAccessibleHypertext interface. + */ +class ATL_NO_VTABLE CAccHypertext : + public CComObjectRoot, + public CComCoClass<CAccHypertext,&CLSID_AccHypertext>, + public IAccessibleHypertext, + public CAccTextBase +{ +public: + CAccHypertext() + { + } + + BEGIN_COM_MAP(CAccHypertext) + COM_INTERFACE_ENTRY(IAccessibleText) + COM_INTERFACE_ENTRY(IAccessibleHypertext) + COM_INTERFACE_ENTRY(IUNOXWrapper) + COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_) +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + END_COM_MAP() +#if defined __clang__ +#pragma clang diagnostic pop +#endif + + static HRESULT WINAPI SmartQI_(void* pv, + REFIID iid, void** ppvObject, DWORD_PTR) + { + return static_cast<CAccHypertext*>(pv)->SmartQI(iid,ppvObject); + } + + HRESULT SmartQI(REFIID iid, void** ppvObject) + { + if( m_pOuterUnknown ) + return OuterQueryInterface(iid,ppvObject); + return E_FAIL; + } + + DECLARE_NO_REGISTRY() + +public: + // IAccessibleText + + // Adds a text selection. + STDMETHOD(addSelection)(long startOffset, long endOffset) override;//, unsigned char * success) + + // Gets text attributes. + STDMETHOD(get_attributes)(long offset, long * startOffset, long * endOffset, BSTR * textAttributes) override; + + // Gets caret offset. + STDMETHOD(get_caretOffset)(long * offset) override; + + // Gets bounding rect containing the glyph(s) representing the character + // at the specified text offset + STDMETHOD(get_characterExtents)(long offset, IA2CoordinateType coordType, long * x, long * y, long * width, long * height) override; + + // Gets number of active non-contiguous selections. + STDMETHOD(get_nSelections)(long * nSelections) override; + + // Gets bounding rect for the glyph at a certain point. + STDMETHOD(get_offsetAtPoint)(long x, long y, IA2CoordinateType coordType, long * offset) override; + + // Gets character offsets of N-th active text selection. + STDMETHOD(get_selection)(long selection, long * startOffset, long * endOffset) override; + + // Gets a range of text by offset NOTE: returned string may be longer + // than endOffset-startOffset bytes if text contains multi-byte characters. + STDMETHOD(get_text)(long startOffset, long endOffset, BSTR * text) override; + + // Gets a specified amount of text that ends before a specified offset. + STDMETHOD(get_textBeforeOffset)(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) override; + + // Gets a specified amount of text that spans the specified offset. + STDMETHOD(get_textAfterOffset)(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) override; + + // Gets a specified amount of text that starts after a specified offset. + STDMETHOD(get_textAtOffset)(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) override; + + // Unselects a range of text. + STDMETHOD(removeSelection)(long selectionIndex) override; + + // Moves text caret. + STDMETHOD(setCaretOffset)(long offset) override; + + // Changes the bounds of an existing selection. + STDMETHOD(setSelection)(long selectionIndex, long startOffset, long endOffset) override; + + // Gets total number of characters. + // NOTE: this may be different than the total number of bytes required + // to store the text, if the text contains multi-byte characters. + STDMETHOD(get_nCharacters)(long * nCharacters) override; + + // Makes specific part of string visible on screen. + STDMETHOD(scrollSubstringTo)(long startIndex, long endIndex,enum IA2ScrollType scrollType) override; + + STDMETHOD(scrollSubstringToPoint)(long startIndex, long endIndex,enum IA2CoordinateType coordinateType, long x, long y ) override; + + STDMETHOD(get_newText)( IA2TextSegment *newText) override; + + STDMETHOD(get_oldText)( IA2TextSegment *oldText) override; + + //IAccessibleHypertext + + // Gets the number of hyperlink. + STDMETHOD(get_nHyperlinks)(long *hyperlinkCount) override; + + // Gets the hyperlink object via specified index. + STDMETHOD(get_hyperlink)(long index,IAccessibleHyperlink **hyperlink) override; + + // Returns the index of the hyperlink that is associated with this + // character index. + STDMETHOD(get_hyperlinkIndex)(long charIndex, long *hyperlinkIndex) override; + + // Override of IUNOXWrapper. + STDMETHOD(put_XInterface)(hyper pXInterface) override; + +private: + + css::uno::Reference<css::accessibility::XAccessibleHypertext> pHyperText; + +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccImage.cxx b/winaccessibility/source/UAccCOM/AccImage.cxx new file mode 100644 index 000000000..666524a71 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccImage.cxx @@ -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 . + */ + +#include "stdafx.h" +#include "AccImage.h" + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +#include <vcl/svapp.hxx> +#include <o3tl/char16_t2wchar_t.hxx> + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> + +using namespace css::accessibility; +using namespace css::uno; + +/** + * Get description. + * @param description Variant to get description. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccImage::get_description(BSTR* description) +{ + SolarMutexGuard g; + + try + { + // #CHECK# + if (description == nullptr) + return E_INVALIDARG; + if (!pRXImg.is()) + return E_FAIL; + + OUString ouStr = GetXInterface()->getAccessibleImageDescription(); + SysFreeString(*description); + *description = SysAllocString(o3tl::toW(ouStr.getStr())); + + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccImage::get_imagePosition( + /* [in] */ enum IA2CoordinateType, + /* [out] */ long __RPC_FAR*, + /* [retval][out] */ long __RPC_FAR*) +{ + return E_NOTIMPL; +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccImage::get_imageSize( + /* [out] */ long __RPC_FAR*, + /* [retval][out] */ long __RPC_FAR*) +{ + return E_NOTIMPL; +} + +/** + * Put UNO interface. + * @param pXInterface UNO interface. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccImage::put_XInterface(hyper pXInterface) +{ + // internal IUNOXWrapper - no mutex meeded + + try + { + CUNOXWrapper::put_XInterface(pXInterface); + //special query. + if (pUNOInterface == nullptr) + return E_FAIL; + + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + if (!pRContext.is()) + { + return E_FAIL; + } + Reference<XAccessibleImage> pRXI(pRContext, UNO_QUERY); + if (!pRXI.is()) + pRXImg = nullptr; + else + pRXImg = pRXI.get(); + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccImage.h b/winaccessibility/source/UAccCOM/AccImage.h new file mode 100644 index 000000000..4e0708a18 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccImage.h @@ -0,0 +1,99 @@ +/* -*- 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 "Resource.h" // main symbols + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/accessibility/XAccessibleImage.hpp> +#include "UNOXWrapper.h" + +/** + * CAccImage implements IAccessibleImage interface. + */ +class ATL_NO_VTABLE CAccImage : + public CComObjectRoot, + public CComCoClass<CAccImage,&CLSID_AccImage>, + public IAccessibleImage, + public CUNOXWrapper +{ +public: + CAccImage() + { + } + virtual ~CAccImage() + { + } + BEGIN_COM_MAP(CAccImage) + COM_INTERFACE_ENTRY(IAccessibleImage) + COM_INTERFACE_ENTRY(IUNOXWrapper) + COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_) +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + END_COM_MAP() +#if defined __clang__ +#pragma clang diagnostic pop +#endif + + static HRESULT WINAPI SmartQI_(void* pv, + REFIID iid, void** ppvObject, DWORD_PTR) + { + return static_cast<CAccImage*>(pv)->SmartQI(iid,ppvObject); + } + + HRESULT SmartQI(REFIID iid, void** ppvObject) + { + if( m_pOuterUnknown ) + return OuterQueryInterface(iid,ppvObject); + return E_FAIL; + } + + DECLARE_NO_REGISTRY() + +public: + // IAccessibleImage + + // Gets the description of the image. + STDMETHOD(get_description)(BSTR * description) override; + + STDMETHOD(get_imagePosition)( enum IA2CoordinateType coordinateType, + long __RPC_FAR *x, + long __RPC_FAR *y) override; + + STDMETHOD(get_imageSize)( + long __RPC_FAR *height, + long __RPC_FAR *width) override; + + // Override of IUNOXWrapper. + STDMETHOD(put_XInterface)(hyper pXInterface) override; + +private: + + css::uno::Reference<css::accessibility::XAccessibleImage> pRXImg; + + css::accessibility::XAccessibleImage* GetXInterface() + { + return pRXImg.get(); + } +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccRelation.cxx b/winaccessibility/source/UAccCOM/AccRelation.cxx new file mode 100644 index 000000000..543a5b1ae --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccRelation.cxx @@ -0,0 +1,217 @@ +/* -*- 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 "stdafx.h" +#include "AccRelation.h" + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +#include <vcl/svapp.hxx> + +#include <com/sun/star/accessibility/AccessibleRelationType.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include "MAccessible.h" + +using namespace com::sun::star::accessibility; +using namespace com::sun::star::uno; + +/** + * Get relation type. + * @param relationType Variant to get relation type. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccRelation::get_relationType(BSTR * relationType) +{ + SolarMutexGuard g; + + try { + + if (relationType == nullptr) + return E_INVALIDARG; + + int type = relation.RelationType; + SysFreeString(*relationType); + + *relationType = getRelationTypeBSTR(type); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +// Gets what the type of localized relation is. +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccRelation::get_localizedRelationType(BSTR *) +{ + + + try { + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Get targets length. + * @param nTargets Variant to get targets length. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccRelation::get_nTargets(long * nTargets) +{ + SolarMutexGuard g; + + try { + + if (nTargets == nullptr) + return E_INVALIDARG; + + Sequence< Reference< XInterface > > xTargets = relation.TargetSet; + *nTargets = xTargets.getLength(); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Get special target. + * @param targetIndex target index. + * @param target Variant to get special target. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccRelation::get_target(long targetIndex, IUnknown * * target) +{ + SolarMutexGuard g; + + try { + + if (target == nullptr) + return E_FAIL; + + Sequence< Reference< XInterface > > xTargets = relation.TargetSet; + int nCount = xTargets.getLength(); + if( targetIndex >= nCount ) + return E_FAIL; + + Reference<XAccessible> xRAcc(xTargets[targetIndex], UNO_QUERY); + IAccessible* pRet = nullptr; + + bool isGet = CMAccessible::get_IAccessibleFromXAccessible(xRAcc.get(), &pRet); + if(isGet) + { + *target = /*(IAccessible2 *)*/pRet; + pRet->AddRef(); + return S_OK; + } + + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** + * Get special targets. + * @param maxTargets Special targets count. + * @param target Variant to get special target. + * @param nTargets Variant to accept actual target length. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccRelation::get_targets(long, IUnknown * * target, long * nTargets) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(target == nullptr) + return E_INVALIDARG; + if (nTargets == nullptr) + return E_INVALIDARG; + + Sequence< Reference< XInterface > > xTargets = relation.TargetSet; + int nCount = xTargets.getLength(); + + *target = static_cast<IUnknown*>(::CoTaskMemAlloc(nCount*sizeof(IUnknown))); + + // #CHECK Memory Allocation# + if(*target == nullptr) + { + return E_FAIL; + } + + for(int i=0; i<nCount ; i++) + { + IUnknown* pAcc = nullptr; + HRESULT hr = get_target(i,&pAcc); + if(SUCCEEDED(hr)) + target[i] = pAcc; + } + + *nTargets = nCount; + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Put UNO interface. + * @param pXSubInterface AccessibleRelation pointer. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccRelation::put_XSubInterface(hyper pXSubInterface) +{ + // internal IUNOXWrapper - no mutex meeded + + relation = *reinterpret_cast<AccessibleRelation*>(pXSubInterface); + return S_OK; +} + +/** + * Get relation type string by type. + * @param type Relation type. + * @return relation type string. +*/ +BSTR CAccRelation::getRelationTypeBSTR(int type) +{ + static LPCWSTR map[] = + { + L"INVALID", // AccessibleRelationType::INVALID + IA2_RELATION_FLOWS_FROM, // AccessibleRelationType::CONTENT_FLOWS_FROM + IA2_RELATION_FLOWS_TO, // AccessibleRelationType::CONTENT_FLOWS_TO + IA2_RELATION_CONTROLLED_BY, // AccessibleRelationType::CONTROLLED_BY + IA2_RELATION_CONTROLLER_FOR, // AccessibleRelationType::CONTROLLER_FOR + IA2_RELATION_LABEL_FOR, // AccessibleRelationType::LABEL_FOR + IA2_RELATION_LABELED_BY, // AccessibleRelationType::LABELED_BY + IA2_RELATION_MEMBER_OF, // AccessibleRelationType::MEMBER_OF + IA2_RELATION_SUBWINDOW_OF, // AccessibleRelationType::SUB_WINDOW_OF + IA2_RELATION_NODE_CHILD_OF, // AccessibleRelationType::NODE_CHILD_OF + IA2_RELATION_DESCRIBED_BY // AccessibleRelationType::DESCRIBED_BY + }; + + return ::SysAllocString( (type >= AccessibleRelationType::INVALID && type <= AccessibleRelationType::DESCRIBED_BY) + ? map[type] : L""); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccRelation.h b/winaccessibility/source/UAccCOM/AccRelation.h new file mode 100644 index 000000000..df258f709 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccRelation.h @@ -0,0 +1,91 @@ +/* -*- 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 "Resource.h" // main symbols + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/accessibility/XAccessibleRelationSet.hpp> +#include "UNOXWrapper.h" + +/** + * CAccRelation implements IAccessibleRelation interface. + */ +class ATL_NO_VTABLE CAccRelation : + public CComObjectRoot, + public CComCoClass<CAccRelation, &CLSID_AccRelation>, + public IAccessibleRelation, + public CUNOXWrapper +{ +public: + CAccRelation() + { + } + virtual ~CAccRelation() + { + } + + DECLARE_NO_REGISTRY() + + DECLARE_PROTECT_FINAL_CONSTRUCT() + + BEGIN_COM_MAP(CAccRelation) + COM_INTERFACE_ENTRY(IAccessibleRelation) + COM_INTERFACE_ENTRY(IUNOXWrapper) +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + END_COM_MAP() +#if defined __clang__ +#pragma clang diagnostic pop +#endif + + // IAccessibleRelation +public: + // IAccessibleRelation + + // Gets what the type of relation is. + STDMETHOD(get_relationType)(BSTR * relationType) override; + + // Gets what the type of localized relation is. + STDMETHOD(get_localizedRelationType)(BSTR * relationType) override; + + // Gets how many targets this relation have. + STDMETHOD(get_nTargets)(long * nTargets) override; + + // Gets one accessible relation target. + STDMETHOD(get_target)(long targetIndex, IUnknown * * target) override; + + // Gets multiple accessible relation targets. + STDMETHOD(get_targets)(long maxTargets, IUnknown * * target, long * nTargets) override; + + // Override of IUNOXWrapper. + STDMETHOD(put_XSubInterface)(hyper pXSubInterface) override; + + //static OLECHAR* getRelationTypeOLECHAR(int type); + static BSTR getRelationTypeBSTR(int type); + +private: + + css::accessibility::AccessibleRelation relation; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccTable.cxx b/winaccessibility/source/UAccCOM/AccTable.cxx new file mode 100644 index 000000000..63f9edf7e --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccTable.cxx @@ -0,0 +1,1095 @@ +/* -*- 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 . + */ + +/** + * AccTable.cpp : Implementation of CAccTable. + */ +#include "stdafx.h" +#include "AccTable.h" + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +#include <vcl/svapp.hxx> +#include <o3tl/char16_t2wchar_t.hxx> + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include "MAccessible.h" + +#include <com/sun/star/accessibility/XAccessibleTableSelection.hpp> + +using namespace com::sun::star::accessibility; +using namespace com::sun::star::uno; +/** + * Gets accessible table cell. + * + * @param row the row of the specified cell. + * @param column the column of the specified cell. + * @param accessible the accessible object of the cell. + */ + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_accessibleAt(long row, long column, IUnknown * * accessible) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(accessible == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + Reference<XAccessible> pRAcc = pRXTable->getAccessibleCellAt(row, column); + + if(!pRAcc.is()) + { + *accessible = nullptr; + return E_FAIL; + } + + IAccessible* pRet = nullptr; + + bool isTRUE = CMAccessible::get_IAccessibleFromXAccessible(pRAcc.get(), &pRet); + if(isTRUE) + { + *accessible = pRet; + pRet->AddRef(); + return S_OK; + } + else if(pRAcc.is()) + { + Reference<XAccessible> pxTable(pRXTable, UNO_QUERY); + + CMAccessible::g_pAgent->InsertAccObj(pRAcc.get(),pxTable.get()); + isTRUE = CMAccessible::get_IAccessibleFromXAccessible(pRAcc.get(), &pRet); + + if(isTRUE) + { + *accessible = pRet; + pRet->AddRef(); + return S_OK; + } + } + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_cellAt(long row, long column, IUnknown * * cell) +{ + return get_accessibleAt(row, column, cell); +} + +/** + * Gets accessible table caption. + * + * @param accessible the accessible object of table caption. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_caption(IUnknown * *) +{ + return E_NOTIMPL; +} + +/** + * Gets accessible column description (as string). + * + * @param column the column index. + * @param description the description of the specified column. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_columnDescription(long column, BSTR * description) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(description == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + const OUString& ouStr = pRXTable->getAccessibleColumnDescription(column); + // #CHECK# + + SysFreeString(*description); + *description = SysAllocString(o3tl::toW(ouStr.getStr())); + if (*description==nullptr) + return E_FAIL; + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Gets number of columns spanned by table cell. + * + * @param row the row of the specified cell. + * @param column the column of the specified cell. + * @param spanColumns the column span of the specified cell. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_columnExtentAt(long row, long column, long * nColumnsSpanned) +{ + SolarMutexGuard g; + + try { + + // Check pointer. + if(nColumnsSpanned == nullptr) + return E_INVALIDARG; + + if(!pRXTable.is()) + return E_FAIL; + + *nColumnsSpanned = pRXTable->getAccessibleColumnExtentAt(row, column); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Gets accessible column header. + * + * @param column the column index. + * @param accessible the accessible object of the specified column. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_columnHeader(IAccessibleTable __RPC_FAR *__RPC_FAR *accessibleTable, long *startingRowIndex) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(accessibleTable == nullptr || startingRowIndex == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + Reference<XAccessibleTable> pRColumnHeaderTable = pRXTable->getAccessibleColumnHeaders(); + if(!pRColumnHeaderTable.is()) + { + *accessibleTable = nullptr; + return E_FAIL; + } + + Reference<XAccessible> pRXColumnHeader(pRColumnHeaderTable,UNO_QUERY); + + if(!pRXColumnHeader.is()) + { + *accessibleTable = nullptr; + return E_FAIL; + } + *startingRowIndex = 0 ; + + IMAccessible* pIMacc = nullptr; + HRESULT hr = createInstance<CMAccessible>(IID_IMAccessible, &pIMacc); + if (!SUCCEEDED(hr)) + { + return E_FAIL; + } + pIMacc->SetXAccessible( + reinterpret_cast<hyper>(pRXColumnHeader.get())); + pIMacc->QueryInterface(IID_IAccessibleTable,reinterpret_cast<void **>(accessibleTable)); + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Gets total number of columns in table. + * + * @param columnCount the number of columns in table. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_nColumns(long * columnCount) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(columnCount == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + *columnCount = pRXTable->getAccessibleColumnCount(); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Gets total number of rows in table. + * + * @param rowCount the number of rows in table. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_nRows(long * rowCount) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(rowCount == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + *rowCount = pRXTable->getAccessibleRowCount(); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Gets total number of selected columns. + * + * @param columnCount the number of selected columns. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_nSelectedColumns(long * columnCount) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(columnCount == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + Sequence<long> pSelected = pRXTable->getSelectedAccessibleColumns(); + *columnCount = pSelected.getLength(); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Gets total number of selected rows. + * + * @param rowCount the number of selected rows. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_nSelectedRows(long * rowCount) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(rowCount == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + Sequence<long> pSelected = pRXTable->getSelectedAccessibleRows(); + *rowCount = pSelected.getLength(); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Gets accessible row description (as string). + * + * @param row the row index. + * @param description the description of the specified row. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_rowDescription(long row, BSTR * description) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(description == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + const OUString& ouStr = pRXTable->getAccessibleRowDescription(row); + // #CHECK# + + SysFreeString(*description); + *description = SysAllocString(o3tl::toW(ouStr.getStr())); + if (*description==nullptr) + return E_FAIL; + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Gets number of rows spanned by a table cell. + * + * @param row the row of the specified cell. + * @param column the column of the specified cell. + * @param spanRows the row span of the specified cell. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_rowExtentAt(long row, long column, long * nRowsSpanned) +{ + SolarMutexGuard g; + + try { + + // Check pointer. + if(nRowsSpanned == nullptr) + return E_INVALIDARG; + + if(!pRXTable.is()) + return E_FAIL; + + *nRowsSpanned= pRXTable->getAccessibleRowExtentAt(row, column); + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Gets accessible row header. + * + * @param row the row index. + * @param accessible the accessible object of the row header. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_rowHeader(IAccessibleTable __RPC_FAR *__RPC_FAR *accessibleTable, long *startingColumnIndex) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(accessibleTable == nullptr || startingColumnIndex == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + Reference<XAccessibleTable> pRRowHeaderTable = pRXTable->getAccessibleRowHeaders(); + if(!pRRowHeaderTable.is()) + { + *accessibleTable = nullptr; + return E_FAIL; + } + + Reference<XAccessible> pRXRowHeader(pRRowHeaderTable,UNO_QUERY); + + if(!pRXRowHeader.is()) + { + *accessibleTable = nullptr; + return E_FAIL; + } + *startingColumnIndex = 0 ; + + IMAccessible* pIMacc = nullptr; + HRESULT hr = createInstance<CMAccessible>(IID_IMAccessible, &pIMacc); + if (!SUCCEEDED(hr)) + { + return E_FAIL; + } + pIMacc->SetXAccessible( + reinterpret_cast<hyper>(pRXRowHeader.get())); + pIMacc->QueryInterface(IID_IAccessibleTable,reinterpret_cast<void **>(accessibleTable)); + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Gets list of row indexes currently selected (0-based). + * + * @param accessible the accessible object array of the selected rows. + * @param nRows the actual size of the accessible object array. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_selectedRows(long** rows, long* nRows) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(rows == nullptr || nRows == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + Sequence<long> pSelected = pRXTable->getSelectedAccessibleRows(); + long count = pSelected.getLength() ; + *nRows = count; + + *rows = static_cast<long*>(CoTaskMemAlloc(count * sizeof(long))); + // #CHECK Memory Allocation# + if(*rows == nullptr) + { + return E_FAIL; + } + for(int i=0; i<count; i++) + (*rows)[i] = pSelected[i]; + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Gets list of row indexes currently selected (0-based). + * + * @param maxRows This parameter is ignored. + * @param accessible the accessible object array of the selected rows. + * @param nRows the actual size of the accessible object array. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_selectedRows(long, long ** rows, long * nRows) +{ + return get_selectedRows(rows, nRows); +} + +/** + * Gets list of column indexes currently selected (0-based). + * + * @param accessible the accessible object array of the selected columns. + * @param numColumns the actual size of accessible object array. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_selectedColumns(long ** columns, long * numColumns) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(columns == nullptr || numColumns == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + Sequence<long> pSelected = pRXTable->getSelectedAccessibleColumns(); + long count = pSelected.getLength() ; + *numColumns = count; + + *columns = static_cast<long*>(CoTaskMemAlloc(count * sizeof(long))); + // #CHECK Memory Allocation# + if(*columns == nullptr) + { + return E_FAIL; + } + for(int i=0; i<count; i++) + (*columns)[i] = pSelected[i]; + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Gets list of column indexes currently selected (0-based). + * + * @param maxColumns This parameter is ignored + * @param accessible the accessible object array of the selected columns. + * @param numColumns the actual size of accessible object array. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_selectedColumns(long, long ** columns, long * numColumns) +{ + return get_selectedColumns(columns, numColumns); +} + +/** + * Gets accessible table summary. + * + * @param accessible the accessible object of the summary. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_summary(IUnknown * * accessible) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(accessible == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + Reference<XAccessible> pRAcc = pRXTable->getAccessibleSummary(); + + IAccessible* pRet = nullptr; + CMAccessible::get_IAccessibleFromXAccessible(pRAcc.get(), &pRet); + + if(pRet) + { + *accessible = pRet; + pRet->AddRef(); + return S_OK; + } + + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** + * Determines if table column is selected. + * + * @param column the column index. + * @param isSelected the result. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_isColumnSelected(long column, boolean * isSelected) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(isSelected == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + *isSelected = pRXTable->isAccessibleColumnSelected(column); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Determines if table row is selected. + * + * @param row the row index. + * @param isSelected the result. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_isRowSelected(long row, boolean * isSelected) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(isSelected == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + *isSelected = pRXTable->isAccessibleRowSelected(row); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Determines if table cell is selected. + * + * @param row the row index. + * @param column the column index. + * @param isSelected the result. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_isSelected(long row, long column, boolean * isSelected) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(isSelected == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + *isSelected = pRXTable->isAccessibleSelected(row, column); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Selects a row and unselect all previously selected rows. + * + * @param row the row index. + * @param success the result. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::selectRow(long row) +{ + SolarMutexGuard g; + + try { + + // Check XAccessibleTable reference. + if(!pRXTable.is()) + return E_FAIL; + + Reference<XAccessibleTableSelection> pRTableExtent(pRXTable, UNO_QUERY); + if(pRTableExtent.is()) + { + pRTableExtent->selectRow(row); + return S_OK; + } + else + { + // Get XAccessibleSelection. + Reference<XAccessibleSelection> pRSelection(pRXTable, UNO_QUERY); + if(!pRSelection.is()) + return E_FAIL; + + // Select row. + long lCol, lColumnCount; + lColumnCount = pRXTable->getAccessibleColumnCount(); + for(lCol = 0; lCol < lColumnCount; lCol ++) + { + long lChildIndex = pRXTable->getAccessibleIndex(row, lCol); + pRSelection->selectAccessibleChild(lChildIndex); + } + + return S_OK; + } + + } catch(...) { return E_FAIL; } +} + +/** + * Selects a column and unselect all previously selected columns. + * + * @param column the column index. + * @param success the result. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::selectColumn(long column) +{ + SolarMutexGuard g; + + try { + + // Check XAccessibleTable reference. + if(!pRXTable.is()) + return E_FAIL; + + Reference<XAccessibleTableSelection> pRTableExtent(pRXTable, UNO_QUERY); + if(pRTableExtent.is()) + { + pRTableExtent->selectColumn(column); + return S_OK; + } + else + { + // Get XAccessibleSelection. + Reference<XAccessibleSelection> pRSelection(pRXTable, UNO_QUERY); + if(!pRSelection.is()) + return E_FAIL; + + // Select column. + long lRow, lRowCount; + lRowCount = pRXTable->getAccessibleRowCount(); + for(lRow = 0; lRow < lRowCount; lRow ++) + { + long lChildIndex = pRXTable->getAccessibleIndex(lRow, column); + pRSelection->selectAccessibleChild(lChildIndex); + } + + return S_OK; + } + // End of added. + + } catch(...) { return E_FAIL; } +} + +/** + * Unselects one row, leaving other selected rows selected (if any). + * + * @param row the row index. + * @param success the result. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::unselectRow(long row) +{ + SolarMutexGuard g; + + try { + + // Check XAccessibleTable reference. + if(!pRXTable.is()) + return E_FAIL; + + Reference<XAccessibleTableSelection> pRTableExtent(pRXTable, UNO_QUERY); + if(pRTableExtent.is()) + { + if(pRTableExtent->unselectRow(row)) + return S_OK; + else + return E_FAIL; + } + else + { + // Get XAccessibleSelection. + Reference<XAccessibleSelection> pRSelection(pRXTable, UNO_QUERY); + if(!pRSelection.is()) + return E_FAIL; + + // Select column. + long lColumn, lColumnCount; + lColumnCount = pRXTable->getAccessibleColumnCount(); + for(lColumn = 0; lColumn < lColumnCount; lColumn ++) + { + long lChildIndex = pRXTable->getAccessibleIndex(row, lColumn); + pRSelection->deselectAccessibleChild(lChildIndex); + } + + return S_OK; + } + // End of added. + + } catch(...) { return E_FAIL; } +} + +/** + * Unselects one column, leaving other selected columns selected (if any). + * + * @param column the column index. + * @param success the result. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::unselectColumn(long column) +{ + SolarMutexGuard g; + + try { + + // Check XAccessibleTable reference. + if(!pRXTable.is()) + return E_FAIL; + + Reference<XAccessibleTableSelection> pRTableExtent(pRXTable, UNO_QUERY); + if(pRTableExtent.is()) + { + if(pRTableExtent->unselectColumn(column)) + return S_OK; + else + return E_FAIL; + } + else + { + // Get XAccessibleSelection. + Reference<XAccessibleSelection> pRSelection(pRXTable, UNO_QUERY); + if(!pRSelection.is()) + return E_FAIL; + + // Unselect columns. + long lRow, lRowCount; + lRowCount = pRXTable->getAccessibleRowCount(); + + for(lRow = 0; lRow < lRowCount; lRow ++) + { + long lChildIndex = pRXTable->getAccessibleIndex(lRow, column); + pRSelection->deselectAccessibleChild(lChildIndex); + } + return S_OK; + } + + } catch(...) { return E_FAIL; } +} + +/** + * Override of IUNOXWrapper. + * + * @param pXInterface the pointer of UNO interface. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::put_XInterface(hyper pXInterface) +{ + // internal IUNOXWrapper - no mutex meeded + + try { + + CUNOXWrapper::put_XInterface(pXInterface); + //special query. + if(pUNOInterface == nullptr) + return E_INVALIDARG; + + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + if( !pRContext.is() ) + return E_FAIL; + + Reference<XAccessibleTable> pRXI(pRContext,UNO_QUERY); + if( !pRXI.is() ) + pRXTable = nullptr; + else + pRXTable = pRXI.get(); + return S_OK; + + } catch(...) { return E_FAIL; } +} + + +/** + * Gets columnIndex of childIndex. + * + * @param childIndex childIndex + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_columnIndex(long childIndex, long * columnIndex) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(columnIndex == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + *columnIndex = pRXTable->getAccessibleColumn(childIndex); + return S_OK; + + } catch(...) { return E_FAIL; } +} +/** + * Gets rowIndex of childIndex. + * + * @param childIndex childIndex + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_rowIndex(long childIndex, long * rowIndex) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(rowIndex == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + *rowIndex = pRXTable->getAccessibleRow(childIndex); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Gets childIndex of childIndex. + * + * @param childIndex childIndex + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_childIndex(long RowIndex , long columnIndex, long * childIndex ) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(childIndex == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + *childIndex = pRXTable->getAccessibleIndex(RowIndex, columnIndex); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_rowColumnExtentsAtIndex(long, + long *, + long *, + long *, + long *, + boolean *) +{ + return E_NOTIMPL; +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_modelChange(IA2TableModelChange *) +{ + return E_NOTIMPL; +} + +// @brief Returns the total number of selected children +// @param [out] childCount +// Number of children currently selected +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_nSelectedChildren(long *childCount) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(childCount == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + Reference<XAccessibleSelection> pRSelection(pRXTable, UNO_QUERY); + if(!pRSelection.is()) + return E_FAIL; + + *childCount = pRSelection->getSelectedAccessibleChildCount(); + return S_OK; + + } catch(...) { return E_FAIL; } +} + + + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_nSelectedCells(long *cellCount) +{ + return get_nSelectedChildren(cellCount); +} + +// @brief Returns a list of child indexes currently selected (0-based). +// @param [in] maxChildren +// Max children requested (possibly from IAccessibleTable::nSelectedChildren) +// @param [out] children +// array of indexes of selected children (each index is 0-based) +// @param [out] nChildren +// Length of array (not more than maxChildren) +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_selectedChildren(long, long **children, long *nChildren) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if(children == nullptr || nChildren == nullptr) + return E_INVALIDARG; + + // #CHECK XInterface# + if(!pRXTable.is()) + return E_FAIL; + + Reference<XAccessibleSelection> pRSelection(pRXTable, UNO_QUERY); + if(!pRSelection.is()) + return E_FAIL; + + long childCount = pRSelection->getSelectedAccessibleChildCount() ; + + *nChildren = childCount; + + *children = static_cast<long*>(CoTaskMemAlloc(childCount * sizeof(long))); + + for( long i = 0; i< childCount; i++) + { + Reference<XAccessible> pRAcc = pRSelection->getSelectedAccessibleChild(i); + if(pRAcc.is()) + { + Reference<XAccessibleContext> pRContext(pRAcc, UNO_QUERY); + if( !pRContext.is() ) + return E_FAIL; + + long childIndex = pRContext->getAccessibleIndexInParent(); + (*children)[i] = childIndex; + } + } + + return S_OK; + + } catch(...) { return E_FAIL; } + +} + +/** + * @brief Returns a list of accessibles currently selected. + * @param cells Pointer to an array of references to selected accessibles. + * The array is allocated by the server with CoTaskMemAlloc and + * freed by the client with CoTaskMemFree. + * @param nSelectedCells The number of accessibles returned; the size of the returned array. + * @return S_FALSE if there are none, [out] values are NULL and 0 respectively, otherwise S_OK + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTable::get_selectedCells(IUnknown * * * cells, long *nSelectedCells) +{ + SolarMutexGuard g; + + try { + + if (cells == nullptr || nSelectedCells == nullptr) + return E_INVALIDARG; + + if (!pRXTable.is()) + return E_FAIL; + + Reference<XAccessibleSelection> xSelection(pRXTable, UNO_QUERY); + if (!xSelection.is()) + return E_FAIL; + + const long nSelected = xSelection->getSelectedAccessibleChildCount(); + *nSelectedCells = nSelected; + + *cells = static_cast<IUnknown**>(CoTaskMemAlloc(nSelected * sizeof(IUnknown*))); + + for (long i = 0; i < nSelected; i++) + { + Reference<XAccessible> xAcc = xSelection->getSelectedAccessibleChild(i); + assert(xAcc.is()); + + IAccessible* pIAccessible; + bool bOK = CMAccessible::get_IAccessibleFromXAccessible(xAcc.get(), &pIAccessible); + + if (!bOK) + { + Reference<XAccessible> xTable(pRXTable, UNO_QUERY); + CMAccessible::g_pAgent->InsertAccObj(xAcc.get(), xTable.get()); + bOK = CMAccessible::get_IAccessibleFromXAccessible(xAcc.get(), &pIAccessible); + } + + assert(bOK && "Couldn't retrieve IAccessible object"); + + pIAccessible->AddRef(); + (*cells)[i] = pIAccessible; + } + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccTable.h b/winaccessibility/source/UAccCOM/AccTable.h new file mode 100644 index 000000000..d5805c3c0 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccTable.h @@ -0,0 +1,184 @@ +/* -*- 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 "Resource.h" // main symbols + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/accessibility/XAccessibleTable.hpp> +#include "UNOXWrapper.h" + +/** + * CAccTable implements the IAccessibleTable and IAccessibleTable2 interfaces. + */ +class ATL_NO_VTABLE CAccTable : + public CComObjectRoot, + public CComCoClass<CAccTable, &CLSID_AccTable>, + public IAccessibleTable, + public IAccessibleTable2, + public CUNOXWrapper + +{ +public: + CAccTable() + { + } + virtual ~CAccTable() + { + } + + BEGIN_COM_MAP(CAccTable) + COM_INTERFACE_ENTRY(IAccessibleTable) + COM_INTERFACE_ENTRY(IAccessibleTable2) + COM_INTERFACE_ENTRY(IUNOXWrapper) + COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_) +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + END_COM_MAP() +#if defined __clang__ +#pragma clang diagnostic pop +#endif + + static HRESULT WINAPI SmartQI_(void* pv, + REFIID iid, void** ppvObject, DWORD_PTR) + { + return static_cast<CAccTable*>(pv)->SmartQI(iid,ppvObject); + } + + HRESULT SmartQI(REFIID iid, void** ppvObject) + { + if( m_pOuterUnknown ) + return OuterQueryInterface(iid,ppvObject); + return E_FAIL; + } + + DECLARE_NO_REGISTRY() + +public: + // IAccessibleTable and IAccessibleTable2 + + // Gets accessible table cell (IAccessibleTable version). + STDMETHOD(get_accessibleAt)(long row, long column, IUnknown * * accessible) override; + + // Gets accessible table cell (IAccessibleTable2 version). + STDMETHOD(get_cellAt)(long row, long column, IUnknown * * cell) override; + + // Gets accessible table caption. + STDMETHOD(get_caption)(IUnknown * * accessible) override; + + // Gets accessible column description (as string). + STDMETHOD(get_columnDescription)(long column, BSTR * description) override; + + // Gets number of columns spanned by table cell. + STDMETHOD(get_columnExtentAt)(long row, long column, long * nColumnsSpanned) override; + + // Gets accessible column header. + STDMETHOD(get_columnHeader)(IAccessibleTable __RPC_FAR *__RPC_FAR *accessibleTable, long *startingRowIndex) override; + + // Gets total number of columns in table. + STDMETHOD(get_nColumns)(long * columnCount) override; + + // Gets total number of rows in table. + STDMETHOD(get_nRows)(long * rowCount) override; + + // Gets total number of selected columns. + STDMETHOD(get_nSelectedColumns)(long * columnCount) override; + + // Gets total number of selected rows. + STDMETHOD(get_nSelectedRows)(long * rowCount) override; + + // Gets accessible row description (as string). + STDMETHOD(get_rowDescription)(long row, BSTR * description) override; + + // Gets number of rows spanned by a table cell. + STDMETHOD(get_rowExtentAt)(long row, long column, long * nRowsSpanned) override; + + // Gets accessible row header. + STDMETHOD(get_rowHeader)(IAccessibleTable __RPC_FAR *__RPC_FAR *accessibleTable, long *startingColumnIndex) override; + + // Gets list of row indexes currently selected (0-based). + STDMETHOD(get_selectedRows)(long **rows, long * nRows) override; + STDMETHOD(get_selectedRows)(long maxRows, long **rows, long * nRows) override; + + // Gets list of column indexes currently selected (0-based). + STDMETHOD(get_selectedColumns)(long **columns, long * numColumns) override; + STDMETHOD(get_selectedColumns)(long maxColumns, long **columns, long * numColumns) override; + + // Gets accessible table summary. + STDMETHOD(get_summary)(IUnknown * * accessible) override; + + // Determines if table column is selected. + STDMETHOD(get_isColumnSelected)(long column, boolean * isSelected) override; + + // Determines if table row is selected. + STDMETHOD(get_isRowSelected)(long row, boolean * isSelected) override; + + // Determines if table cell is selected. + STDMETHOD(get_isSelected)(long row, long column, boolean * isSelected) override; + + // Selects a row and unselect all previously selected rows. + STDMETHOD(selectRow)(long row ) override; + + + // Selects a column and unselect all previously selected columns. + + STDMETHOD(selectColumn)(long column) override; + + // Unselects one row, leaving other selected rows selected (if any). + STDMETHOD(unselectRow)(long row) override; + + // Unselects one column, leaving other selected columns selected (if any). + STDMETHOD(unselectColumn)(long column) override; + + //get Column index + STDMETHOD(get_columnIndex)(long childIndex, long * columnIndex) override; + + STDMETHOD(get_rowIndex)(long childIndex, long * rowIndex) override; + + STDMETHOD(get_childIndex)(long rowIndex,long columnIndex, long * childIndex) override; + + // get total number of selected cells + STDMETHOD(get_nSelectedChildren)(long *childCount) override; + STDMETHOD(get_nSelectedCells)(long *childCount) override; + + STDMETHOD(get_selectedChildren)(long maxChildren, long **children, long *nChildren) override; + + // Returns a list of accessibles currently selected + STDMETHOD(get_selectedCells)(IUnknown * * * cells, long *nSelectedCells) override; + + STDMETHOD(get_rowColumnExtentsAtIndex)( long index, + long *row, + long *column, + long *rowExtents, + long *columnExtents, + boolean *isSelected) override; + + STDMETHOD(get_modelChange)(IA2TableModelChange *modelChange) override; + + // Override of IUNOXWrapper. + STDMETHOD(put_XInterface)(hyper pXInterface) override; + +private: + css::uno::Reference<css::accessibility::XAccessibleTable> pRXTable; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccTableCell.cxx b/winaccessibility/source/UAccCOM/AccTableCell.cxx new file mode 100644 index 000000000..90c450735 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccTableCell.cxx @@ -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 . + */ + +#include "AccTableCell.h" + +#include <vcl/svapp.hxx> +#include <com/sun/star/accessibility/XAccessible.hpp> + +using namespace com::sun::star::accessibility; +using namespace com::sun::star::uno; + +CAccTableCell::CAccTableCell() + : m_nIndexInParent(0) +{ +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::put_XInterface(hyper pXInterface) +{ + // internal IUNOXWrapper - no mutex meeded + + try + { + CUNOXWrapper::put_XInterface(pXInterface); + if (pUNOInterface == nullptr) + return E_INVALIDARG; + + Reference<XAccessibleContext> xContext = pUNOInterface->getAccessibleContext(); + if (!xContext.is()) + return E_FAIL; + + // retrieve reference to table (parent of the cell) + Reference<XAccessibleContext> xParentContext + = xContext->getAccessibleParent()->getAccessibleContext(); + Reference<XAccessibleTable> xTable(xParentContext, UNO_QUERY); + + if (!xTable.is()) + { + m_xTable.clear(); + return E_FAIL; + } + + m_xTable = xTable; + m_nIndexInParent = xContext->getAccessibleIndexInParent(); + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_columnExtent(long* pColumnsSpanned) +{ + SolarMutexGuard g; + + try + { + if (pColumnsSpanned == nullptr) + return E_INVALIDARG; + + if (!m_xTable.is()) + return E_FAIL; + + long nRow = 0, nColumn = 0; + get_rowIndex(&nRow); + get_columnIndex(&nColumn); + + *pColumnsSpanned = m_xTable->getAccessibleColumnExtentAt(nRow, nColumn); + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_columnIndex(long* pColumnIndex) +{ + SolarMutexGuard g; + + try + { + if (pColumnIndex == nullptr) + return E_INVALIDARG; + + if (!m_xTable.is()) + return E_FAIL; + + *pColumnIndex = m_xTable->getAccessibleColumn(m_nIndexInParent); + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_rowExtent(long* pRowsSpanned) +{ + SolarMutexGuard g; + + try + { + if (pRowsSpanned == nullptr) + return E_INVALIDARG; + + if (!m_xTable.is()) + return E_FAIL; + + long nRow = 0, nColumn = 0; + get_rowIndex(&nRow); + get_columnIndex(&nColumn); + + *pRowsSpanned = m_xTable->getAccessibleRowExtentAt(nRow, nColumn); + + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_rowIndex(long* pRowIndex) +{ + SolarMutexGuard g; + + try + { + if (pRowIndex == nullptr) + return E_INVALIDARG; + + if (!m_xTable.is()) + return E_FAIL; + + *pRowIndex = m_xTable->getAccessibleRow(m_nIndexInParent); + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_isSelected(boolean* pIsSelected) +{ + SolarMutexGuard g; + + try + { + if (pIsSelected == nullptr) + return E_INVALIDARG; + + if (!m_xTable.is()) + return E_FAIL; + + long nRow = 0, nColumn = 0; + get_rowIndex(&nRow); + get_columnIndex(&nColumn); + + *pIsSelected = m_xTable->isAccessibleSelected(nRow, nColumn); + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccTableCell.h b/winaccessibility/source/UAccCOM/AccTableCell.h new file mode 100644 index 000000000..2c7d1a79a --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccTableCell.h @@ -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 "Resource.h" + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/accessibility/XAccessibleTable.hpp> +#include "UNOXWrapper.h" + +/** + * CAccTableCell implements the IAccessibleTableCell interface. + */ +class ATL_NO_VTABLE CAccTableCell : public CComObjectRoot, + public CComCoClass<CAccTableCell, &CLSID_AccTableCell>, + public IAccessibleTableCell, + public CUNOXWrapper + +{ +public: + CAccTableCell(); + virtual ~CAccTableCell() {} + + BEGIN_COM_MAP(CAccTableCell) + COM_INTERFACE_ENTRY(IAccessibleTableCell) + COM_INTERFACE_ENTRY(IUNOXWrapper) + COM_INTERFACE_ENTRY_FUNC_BLIND(0, SmartQI_) +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + END_COM_MAP() +#if defined __clang__ +#pragma clang diagnostic pop +#endif + + static HRESULT WINAPI SmartQI_(void* pv, REFIID iid, void** ppvObject, DWORD_PTR) + { + return static_cast<CAccTableCell*>(pv)->SmartQI(iid, ppvObject); + } + + HRESULT SmartQI(REFIID iid, void** ppvObject) + { + if (m_pOuterUnknown) + return OuterQueryInterface(iid, ppvObject); + return E_FAIL; + } + + DECLARE_NO_REGISTRY() + +public: + STDMETHOD(put_XInterface)(hyper pXInterface) override; + + // IAccessibleTableCell interfaces + STDMETHOD(get_columnExtent)(long*) override; + STDMETHOD(get_columnHeaderCells)(IUnknown***, long*) override { return E_FAIL; } + STDMETHOD(get_columnIndex)(long*) override; + STDMETHOD(get_rowExtent)(long*) override; + STDMETHOD(get_rowHeaderCells)(IUnknown***, long*) override { return E_FAIL; } + STDMETHOD(get_rowIndex)(long*) override; + STDMETHOD(get_isSelected)(boolean*) override; + STDMETHOD(get_rowColumnExtents)(long*, long*, long*, long*, boolean*) { return E_FAIL; } + STDMETHOD(get_table)(IUnknown**) { return E_FAIL; } + +private: + css::uno::Reference<css::accessibility::XAccessibleTable> m_xTable; + sal_Int32 m_nIndexInParent; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccText.cxx b/winaccessibility/source/UAccCOM/AccText.cxx new file mode 100644 index 000000000..fc6c39285 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccText.cxx @@ -0,0 +1,267 @@ +/* -*- 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 "stdafx.h" +#include "AccText.h" + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +using namespace com::sun::star::accessibility; +using namespace com::sun::star::uno; + +/** + * Get special selection. + * @param startOffset Start selection offset. + * @param endOffset End selection offset. + * @param success Variant to accept the result of if the method call is successful. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::addSelection(long startOffset, long endOffset)//, unsigned char * success) +{ + + return CAccTextBase::get_addSelection(startOffset, endOffset);//, success); +} + +/** + * Get special attributes. + * @param offset Offset. + * @param startOffset Variant to accept start offset. + * @param endOffset Variant to accept end offset. + * @param textAttributes Variant to accept attributes. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_attributes(long offset, long * startOffset, long * endOffset, BSTR * textAttributes) +{ + + return CAccTextBase::get_attributes(offset, startOffset, endOffset, textAttributes); +} + +/** + * Get caret position. + * @param offset Variant to accept caret offset. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_caretOffset(long * offset) +{ + + return CAccTextBase::get_caretOffset(offset); +} + +/** + * Get character extents. + * @param offset Offset. + * @param x Variant to accept x position. + * @param y Variant to accept y position. + * @param width Variant to accept width. + * @param Height Variant to accept height. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_characterExtents(long offset, IA2CoordinateType coordType, long * x, long * y, long * width, long * height) +{ + + return CAccTextBase::get_characterExtents(offset, coordType, x, y, width, height); +} + +/** + * Get selections count. + * @param nSelections Variant to accept selections count. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_nSelections(long * nSelections) +{ + + return CAccTextBase::get_nSelections(nSelections); +} + +/** + * Get offset of some special point. + * @param x X position of one point. + * @param x Y position of one point. + * @param coordType Type. + * @param offset Variant to accept offset. + * @return Result. +*/ + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_offsetAtPoint(long x, long y, IA2CoordinateType coordType, long * offset) +{ + + return CAccTextBase::get_offsetAtPoint(x, y, coordType, offset); +} + +/** + * Get selection range. + * @param selection selection count. + * @param startOffset Variant to accept the start offset of special selection. + * @param endOffset Variant to accept the end offset of special selection. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_selection(long selection, long * startOffset, long * endOffset) +{ + + return CAccTextBase::get_selection(selection, startOffset, endOffset); +} + +/** + * Get special text. + * @param startOffset Start position of special range. + * @param endOffset End position of special range. + * @param text Variant to accept the text of special range. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_text(long startOffset, long endOffset, BSTR * text) +{ + + return CAccTextBase::get_text(startOffset, endOffset, text); +} + +/** + * Get special text before some position. + * @param offset Special position. + * @param boundaryType Boundary type. + * @param startOffset Variant to accept the start offset. + * @param endOffset Variant to accept the end offset. + * @param text Variant to accept the special text. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_textBeforeOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) +{ + + return CAccTextBase::get_textBeforeOffset(offset, boundaryType, + startOffset, endOffset, text); +} + +/** + * Get special text after some position. + * @param offset Special position. + * @param boundaryType Boundary type. + * @param startOffset Variant to accept the start offset. + * @param endOffset Variant to accept the end offset. + * @param text Variant to accept the special text. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_textAfterOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) +{ + + return CAccTextBase::get_textAfterOffset(offset, boundaryType, + startOffset, endOffset, text); +} + +/** + * Get special text at some position. + * @param offset Special position. + * @param boundaryType Boundary type. + * @param startOffset Variant to accept the start offset. + * @param endOffset Variant to accept the end offset. + * @param text Variant to accept the special text. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_textAtOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) +{ + + return CAccTextBase::get_textAtOffset(offset, boundaryType, + startOffset, endOffset, text); +} + +/** + * Remove selection. + * @param selectionIndex Special selection index + * @param success Variant to accept the method called result. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::removeSelection(long selectionIndex)//, unsigned char * success) +{ + + return CAccTextBase::removeSelection(selectionIndex);//, success); +} + +/** + * Set caret position. + * @param offset Special position. + * @param success Variant to accept the method called result. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::setCaretOffset(long offset) +{ + + return CAccTextBase::setCaretOffset(offset); +} + +/** + * Set special selection. + * @param selectionIndex Special selection index. + * @param startOffset start position. + * @param endOffset end position. + * @param success Variant to accept the method called result. + * @return Result. +*/ + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::setSelection(long selectionIndex, long startOffset, long endOffset) +{ + + return CAccTextBase::setSelection(selectionIndex, startOffset, + endOffset); +} + +/** + * Get characters count. + * @param nCharacters Variant to accept the characters count. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_nCharacters(long * nCharacters) +{ + + return CAccTextBase::get_nCharacters(nCharacters); +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_newText( IA2TextSegment *newText) +{ + return CAccTextBase::get_newText(newText); +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::get_oldText( IA2TextSegment *oldText) +{ + return CAccTextBase::get_oldText(oldText); +} + +/** + * Scroll to special sub-string . + * @param startIndex Start index of sub string. + * @param endIndex End index of sub string. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::scrollSubstringToPoint(long startIndex, long endIndex,enum IA2CoordinateType coordinateType, long x, long y ) +{ + + return CAccTextBase::scrollSubstringToPoint(startIndex, endIndex, coordinateType, x, y); +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccText::scrollSubstringTo(long startIndex, long endIndex,enum IA2ScrollType scrollType) +{ + + return CAccTextBase::scrollSubstringTo(startIndex, endIndex,scrollType); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccText.h b/winaccessibility/source/UAccCOM/AccText.h new file mode 100644 index 000000000..eba821aae --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccText.h @@ -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 "Resource.h" // main symbols + +#include "AccTextBase.h" + +/** + * CAccText implements IAccessibleText interface. + */ +class ATL_NO_VTABLE CAccText : + public CComObjectRoot, + public CComCoClass<CAccText,&CLSID_AccText>, + public IAccessibleText, + public CAccTextBase +{ +public: + CAccText() + { + } + + BEGIN_COM_MAP(CAccText) + COM_INTERFACE_ENTRY(IAccessibleText) + COM_INTERFACE_ENTRY(IUNOXWrapper) + COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_) +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + END_COM_MAP() +#if defined __clang__ +#pragma clang diagnostic pop +#endif + + static HRESULT WINAPI SmartQI_(void* pv, + REFIID iid, void** ppvObject, DWORD_PTR) + { + return static_cast<CAccText*>(pv)->SmartQI(iid,ppvObject); + } + + HRESULT SmartQI(REFIID iid, void** ppvObject) + { + if( m_pOuterUnknown ) + return OuterQueryInterface(iid,ppvObject); + return E_FAIL; + } + + DECLARE_NO_REGISTRY() + +public: + // IAccessibleText + + // Adds a text selection. + STDMETHOD(addSelection)(long startOffset, long endOffset) override;//, unsigned char * success); + + // Gets text attributes. + STDMETHOD(get_attributes)(long offset, long * startOffset, long * endOffset, BSTR * textAttributes) override; + + // Gets caret offset. + STDMETHOD(get_caretOffset)(long * offset) override; + + // Gets bounding rect containing the glyph(s) representing the character + // at the specified text offset + STDMETHOD(get_characterExtents)(long offset, IA2CoordinateType coordType, long * x, long * y, long * width, long * height) override; + + // Gets number of active non-contiguous selections. + STDMETHOD(get_nSelections)(long * nSelections) override; + + // Gets bounding rect for the glyph at a certain point. + STDMETHOD(get_offsetAtPoint)(long x, long y, IA2CoordinateType coordType, long * offset) override; + + // Gets character offsets of N-th active text selection. + STDMETHOD(get_selection)(long selection, long * startOffset, long * endOffset) override; + + // Gets a range of text by offset NOTE: returned string may be longer + // than endOffset-startOffset bytes if text contains multi-byte characters. + STDMETHOD(get_text)(long startOffset, long endOffset, BSTR * text) override; + + // Gets a specified amount of text that ends before a specified offset. + STDMETHOD(get_textBeforeOffset)(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) override; + + // Gets a specified amount of text that spans the specified offset. + STDMETHOD(get_textAfterOffset)(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) override; + + // Gets a specified amount of text that starts after a specified offset. + STDMETHOD(get_textAtOffset)(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) override; + + // Unselects a range of text. + STDMETHOD(removeSelection)(long selectionIndex) override;//, unsigned char * success); + + // Moves text caret. + STDMETHOD(setCaretOffset)(long offset) override;//, unsigned char * success); + + // Changes the bounds of an existing selection. + STDMETHOD(setSelection)(long selectionIndex, long startOffset, long endOffset) override;//, unsigned char * success); + + // Gets total number of characters. + // NOTE: this may be different than the total number of bytes required + // to store the text, if the text contains multi-byte characters. + STDMETHOD(get_nCharacters)(long * nCharacters) override; + + // Makes specific part of string visible on screen. + STDMETHOD(scrollSubstringTo)(long startIndex, long endIndex,enum IA2ScrollType scrollType) override; + STDMETHOD(scrollSubstringToPoint)(long startIndex, long endIndex,enum IA2CoordinateType coordinateType, long x, long y ) override; + + STDMETHOD(get_newText)( IA2TextSegment *newText) override; + + STDMETHOD(get_oldText)( IA2TextSegment *oldText) override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccTextBase.cxx b/winaccessibility/source/UAccCOM/AccTextBase.cxx new file mode 100644 index 000000000..a1f371a47 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccTextBase.cxx @@ -0,0 +1,911 @@ +/* -*- 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 . + */ + + +// AccTextBase.cpp: implementation of the CAccTextBase class. + +#include "stdafx.h" + +#include "AccTextBase.h" + +#include <rtl/ustrbuf.hxx> +#include <sal/log.hxx> +#include <vcl/svapp.hxx> +#include <o3tl/char16_t2wchar_t.hxx> + +#include <com/sun/star/accessibility/AccessibleScrollType.hpp> +#include <com/sun/star/accessibility/AccessibleTextType.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/XAccessibleTextSelection.hpp> +#include "MAccessible.h" + +using namespace css::accessibility; +using namespace css::uno; + +namespace +{ +sal_Int16 lcl_matchIA2TextBoundaryType(IA2TextBoundaryType boundaryType) +{ + switch (boundaryType) + { + case IA2_TEXT_BOUNDARY_CHAR: + return com::sun::star::accessibility::AccessibleTextType::CHARACTER; + case IA2_TEXT_BOUNDARY_WORD: + return com::sun::star::accessibility::AccessibleTextType::WORD; + case IA2_TEXT_BOUNDARY_SENTENCE: + return com::sun::star::accessibility::AccessibleTextType::SENTENCE; + case IA2_TEXT_BOUNDARY_PARAGRAPH: + return com::sun::star::accessibility::AccessibleTextType::PARAGRAPH; + case IA2_TEXT_BOUNDARY_LINE: + return com::sun::star::accessibility::AccessibleTextType::LINE; + case IA2_TEXT_BOUNDARY_ALL: + // assert here, better handle it directly at call site + assert(false + && "No match for IA2_TEXT_BOUNDARY_ALL, handle at call site."); + break; + default: + break; + } + + SAL_WARN("iacc2", "Unmatched text boundary type: " << boundaryType); + return -1; +} +} + + +// Construction/Destruction + + +static OUString ReplaceFourChar(OUString const & oldOUString); + +CAccTextBase::CAccTextBase() +{} + +CAccTextBase::~CAccTextBase() +{} + + +/** + * Get special selection. + * @param startOffset Start selection offset. + * @param endOffset End selection offset. + * @param success Variant to accept the result of if the method call is successful. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_addSelection(long startOffset, long endOffset) +{ + SolarMutexGuard g; + + try { + + // #CHECK XInterface# + if(pUNOInterface == nullptr) + return E_FAIL; + + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + + Reference< XAccessibleTextSelection > pRExtension(pRContext,UNO_QUERY); + + if( pRExtension.is() ) + { + pRExtension->addSelection(0, startOffset, endOffset); + return S_OK; + } + else + { + GetXInterface()->setSelection(startOffset, endOffset); + return S_OK; + } + + } catch(...) { return E_FAIL; } +} + +/** + * Get special attributes. + * @param offset Offset. + * @param startOffset Variant to accept start offset. + * @param endOffset Variant to accept end offset. + * @param textAttributes Variant to accept attributes. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_attributes(long offset, long * startOffset, long * endOffset, BSTR * textAttributes) +{ + SolarMutexGuard g; + + try { + + if (startOffset == nullptr || endOffset == nullptr || textAttributes == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if(!pRXText.is()) + { + return E_FAIL; + } + + if( offset < 0 || offset > GetXInterface()->getCharacterCount() ) + return E_FAIL; + + OUStringBuffer strAttrs("Version:1;"); + + Sequence< css::beans::PropertyValue > pValues = GetXInterface()->getCharacterAttributes(offset, Sequence< OUString >()); + int nCount = pValues.getLength(); + + sal_Int16 numberingLevel = 0; + OUString numberingPrefix; + Any anyNumRule; + bool bHaveNumberingPrefixAttr = false; + bool bHaveNumberingLevel = false; + bool bHaveNumberingRules = false; + for(int i =0; i<nCount; i++) + { + + const css::beans::PropertyValue &pValue = pValues[i]; + if(pValue.Name == "NumberingLevel") + { + if (pValue.Value != Any()) + pValue.Value >>= numberingLevel; + else + numberingLevel = -1; + bHaveNumberingLevel = true; + continue; + } + if(pValue.Name == "NumberingPrefix") + { + pValue.Value >>=numberingPrefix; + bHaveNumberingPrefixAttr = true; + continue; + } + if(pValue.Name == "NumberingRules") + { + bHaveNumberingRules = true; + anyNumRule = pValue.Value; + continue; + } + if (bHaveNumberingLevel && bHaveNumberingRules && bHaveNumberingPrefixAttr) + { + strAttrs.append(';'); + numberingPrefix = ReplaceFourChar(numberingPrefix); + strAttrs.append(CMAccessible::get_String4Numbering(anyNumRule,numberingLevel,numberingPrefix)); + bHaveNumberingLevel = false; + bHaveNumberingRules = false; + } + if( (bHaveNumberingPrefixAttr && i > 1 ) || + (!bHaveNumberingPrefixAttr && i > 0 ) ) //element 0 is NumberingPrefix, not write alone + { + strAttrs.append(';'); + } + strAttrs.append(pValue.Name); + strAttrs.append(':'); + + if (pValue.Name == "CharBackColor" || + pValue.Name == "CharColor" || + pValue.Name == "CharUnderlineColor" ) + { + unsigned long nColor; + pValue.Value >>= nColor; + strAttrs.append('#'); + OUString const hex = OUString::number(nColor, 16).toAsciiUpperCase(); + for (sal_Int32 j = hex.getLength(); j < 8; ++j) { + strAttrs.append('0'); + } + strAttrs.append(hex); + } + else + { + strAttrs.append(CMAccessible::get_StringFromAny(pValue.Value)); + } + } + strAttrs.append(';'); + // #CHECK# + if(*textAttributes) + SysFreeString(*textAttributes); + *textAttributes = SysAllocString(o3tl::toW(strAttrs.makeStringAndClear().getStr())); + + if( offset < GetXInterface()->getCharacterCount() ) + { + TextSegment textSeg = GetXInterface()->getTextAtIndex(offset, AccessibleTextType::ATTRIBUTE_RUN); + *startOffset = textSeg.SegmentStart; + *endOffset = textSeg.SegmentEnd; + } + else + { + *startOffset = offset; + *endOffset = offset; + } + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Get caret position. + * @param offset Variant to accept caret offset. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_caretOffset(long * offset) +{ + SolarMutexGuard g; + + try { + + if (offset == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if(!pRXText.is()) + { + *offset = 0; + return S_OK; + } + + *offset = GetXInterface()->getCaretPosition(); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Get character count. + * @param nCharacters Variant to accept character count. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_characterCount(long * nCharacters) +{ + SolarMutexGuard g; + + try { + + if (nCharacters == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if(!pRXText.is()) + { + *nCharacters = 0; + return S_OK; + } + + *nCharacters = GetXInterface()->getCharacterCount(); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Get character extents. + * @param offset Offset. + * @param x Variant to accept x position. + * @param y Variant to accept y position. + * @param width Variant to accept width. + * @param Height Variant to accept height. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_characterExtents(long offset, IA2CoordinateType coordType, long * x, long * y, long * width, long * height) +{ + SolarMutexGuard g; + + try { + + if (x == nullptr || height == nullptr || y == nullptr || width == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if(!pRXText.is()) + return E_FAIL; + + if(offset < 0 || offset > GetXInterface()->getCharacterCount() ) + return E_FAIL; + + css::awt::Rectangle rectangle; + rectangle = GetXInterface()->getCharacterBounds(offset); + + //IA2Point aPoint; + css::awt::Point aPoint; + + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + if( !pRContext.is() ) + { + return E_FAIL; + } + Reference<XAccessibleComponent> pRComp(pRContext,UNO_QUERY); + if( pRComp.is() ) + { + if(coordType == IA2_COORDTYPE_SCREEN_RELATIVE) + { + css::awt::Point pt = pRComp->getLocationOnScreen(); + aPoint.X = pt.X; + aPoint.Y = pt.Y; + } + else if(coordType == IA2_COORDTYPE_PARENT_RELATIVE) + { + css::awt::Point pt = pRComp->getLocation(); + aPoint.X = pt.X; + aPoint.Y = pt.Y; + } + } + rectangle.X = rectangle.X + aPoint.X; + rectangle.Y = rectangle.Y + aPoint.Y; + + *x = rectangle.X; + *y = rectangle.Y; + + // GetXInterface()->getCharacterBounds() have different implement in different acc component + // But we need return the width/height == 1 for every component when offset == text length. + // So we ignore the return result of GetXInterface()->getCharacterBounds() when offset == text length. + if( offset == GetXInterface()->getCharacterCount() ) + { + *width = 1; + *height = 1; + } + else + { + *width = rectangle.Width; + *height = rectangle.Height; + } + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Get selections count. + * @param nSelections Variant to accept selections count. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_nSelections(long * nSelections) +{ + SolarMutexGuard g; + + try { + + if (nSelections == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if(pUNOInterface == nullptr) + { + *nSelections = 0; + return S_OK; + } + + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + + Reference< XAccessibleTextSelection > pRExtension(pRContext,UNO_QUERY); + + if( pRExtension.is() ) + { + *nSelections = pRExtension->getSelectedPortionCount(); + return S_OK; + } + + long iLength = GetXInterface()->getSelectedText().getLength(); + if( iLength> 0) + { + *nSelections = 1; + return S_OK; + } + + *nSelections = 0; + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Get offset of some special point. + * @param x X position of one point. + * @param x Y position of one point. + * @param coordType Type. + * @param offset Variant to accept offset. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_offsetAtPoint(long x, long y, IA2CoordinateType, long * offset) +{ + SolarMutexGuard g; + + try { + + if (offset == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if(!pRXText.is()) + return E_FAIL; + + css::awt::Point point; + point.X = x; + point.Y = y; + *offset = GetXInterface()->getIndexAtPoint(point); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Get selection range. + * @param selection selection count. + * @param startOffset Variant to accept the start offset of special selection. + * @param endOffset Variant to accept the end offset of special selection. + * @return Result. +*/ + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_selection(long selectionIndex, long * startOffset, long * endOffset) +{ + SolarMutexGuard g; + + try { + + if (startOffset == nullptr || endOffset == nullptr ) + return E_INVALIDARG; + // #CHECK XInterface# + if(pUNOInterface == nullptr ) + return E_FAIL; + + long nSelection = 0; + get_nSelections(&nSelection); + + if(selectionIndex >= nSelection || selectionIndex < 0 ) + return E_FAIL; + + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + + Reference< XAccessibleTextSelection > pRExtension(pRContext,UNO_QUERY); + + if( pRExtension.is() ) + { + *startOffset = pRExtension->getSeletedPositionStart(selectionIndex); + *endOffset = pRExtension->getSeletedPositionEnd(selectionIndex); + return S_OK; + } + else if(GetXInterface()->getSelectionEnd() > -1) + { + *startOffset = GetXInterface()->getSelectionStart(); + *endOffset = GetXInterface()->getSelectionEnd(); + return S_OK; + } + + *startOffset = 0; + *endOffset = 0; + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** + * Get special text. + * @param startOffset Start position of special range. + * @param endOffset End position of special range. + * @param text Variant to accept the text of special range. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_text(long startOffset, long endOffset, BSTR * text) +{ + SolarMutexGuard g; + + try { + + if (text == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if(!pRXText.is()) + return E_FAIL; + + if (endOffset < -1 || endOffset < startOffset ) + { + return E_FAIL; + } + + OUString ouStr; + if (endOffset == -1 ) + { + long nLen=0; + if(SUCCEEDED(get_characterCount(&nLen))) + { + ouStr = GetXInterface()->getTextRange( 0, nLen ); + } + } + else + { + ouStr = GetXInterface()->getTextRange( startOffset, endOffset ); + } + + SysFreeString(*text); + *text = SysAllocString(o3tl::toW(ouStr.getStr())); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Get special text before some position. + * @param offset Special position. + * @param boundaryType Boundary type. + * @param startOffset Variant to accept the start offset. + * @param endOffset Variant to accept the end offset. + * @param text Variant to accept the special text. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_textBeforeOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) +{ + SolarMutexGuard g; + + try { + + // #CHECK# + if (startOffset == nullptr || endOffset == nullptr || text == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if(!pRXText.is()) + return E_FAIL; + + if (boundaryType == IA2_TEXT_BOUNDARY_ALL) + { + long nChar; + get_nCharacters( &nChar ); + *startOffset = 0; + *endOffset = nChar; + return get_text(0, nChar, text); + } + + const sal_Int16 nUnoBoundaryType = lcl_matchIA2TextBoundaryType(boundaryType); + if (nUnoBoundaryType < 0) + return E_FAIL; + + TextSegment segment = GetXInterface()->getTextBeforeIndex(offset, nUnoBoundaryType); + OUString ouStr = segment.SegmentText; + SysFreeString(*text); + *text = SysAllocString(o3tl::toW(ouStr.getStr())); + *startOffset = segment.SegmentStart; + *endOffset = segment.SegmentEnd; + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Get special text after some position. + * @param offset Special position. + * @param boundaryType Boundary type. + * @param startOffset Variant to accept the start offset. + * @param endOffset Variant to accept the end offset. + * @param text Variant to accept the special text. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_textAfterOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) +{ + SolarMutexGuard g; + + try { + + if (startOffset == nullptr || endOffset == nullptr || text == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if(!pRXText.is()) + return E_FAIL; + + if (boundaryType == IA2_TEXT_BOUNDARY_ALL) + { + long nChar; + get_nCharacters( &nChar ); + *startOffset = 0; + *endOffset = nChar; + return get_text(0, nChar, text); + } + + const sal_Int16 nUnoBoundaryType = lcl_matchIA2TextBoundaryType(boundaryType); + if (nUnoBoundaryType < 0) + return E_FAIL; + + TextSegment segment = GetXInterface()->getTextBehindIndex(offset, nUnoBoundaryType); + OUString ouStr = segment.SegmentText; + SysFreeString(*text); + *text = SysAllocString(o3tl::toW(ouStr.getStr())); + *startOffset = segment.SegmentStart; + *endOffset = segment.SegmentEnd; + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Get special text at some position. + * @param offset Special position. + * @param boundaryType Boundary type. + * @param startOffset Variant to accept the start offset. + * @param endOffset Variant to accept the end offset. + * @param text Variant to accept the special text. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_textAtOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text) +{ + SolarMutexGuard g; + + try { + + if (startOffset == nullptr || text == nullptr ||endOffset == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if(!pRXText.is()) + return E_FAIL; + + if (boundaryType == IA2_TEXT_BOUNDARY_ALL) + { + long nChar; + get_nCharacters( &nChar ); + *startOffset = 0; + *endOffset = nChar; + return get_text(0, nChar, text); + } + + const sal_Int16 nUnoBoundaryType = lcl_matchIA2TextBoundaryType(boundaryType); + if (nUnoBoundaryType < 0) + return E_FAIL; + + TextSegment segment = GetXInterface()->getTextAtIndex(offset, nUnoBoundaryType); + OUString ouStr = segment.SegmentText; + SysFreeString(*text); + *text = SysAllocString(o3tl::toW(ouStr.getStr())); + *startOffset = segment.SegmentStart; + *endOffset = segment.SegmentEnd; + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Remove selection. + * @param selectionIndex Special selection index + * @param success Variant to accept the method called result. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::removeSelection(long selectionIndex) +{ + SolarMutexGuard g; + + try { + + // #CHECK XInterface# + if(pUNOInterface == nullptr) + { + return E_FAIL; + } + + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + + Reference< XAccessibleTextSelection > pRExtension(pRContext,UNO_QUERY); + + if( pRExtension.is() ) + { + pRExtension->removeSelection(selectionIndex); + return S_OK; + } + else + { + GetXInterface()->setSelection(0, 0); + return S_OK; + } + + } catch(...) { return E_FAIL; } +} + +/** + * Set caret position. + * @param offset Special position. + * @param success Variant to accept the method called result. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::setCaretOffset(long offset) +{ + SolarMutexGuard g; + + try { + + // #CHECK XInterface# + if(!pRXText.is()) + return E_FAIL; + + GetXInterface()->setCaretPosition( offset); + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Set special selection. + * @param selectionIndex Special selection index. + * @param startOffset start position. + * @param endOffset end position. + * @param success Variant to accept the method called result. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::setSelection(long, long startOffset, long endOffset) +{ + SolarMutexGuard g; + + try { + + // #CHECK XInterface# + if(!pRXText.is()) + { + return E_FAIL; + } + + GetXInterface()->setSelection( startOffset, endOffset ); + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** + * Get characters count. + * @param nCharacters Variant to accept the characters count. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_nCharacters(long * nCharacters) +{ + SolarMutexGuard g; + + try { + + if (nCharacters == nullptr) + return E_INVALIDARG; + // #CHECK XInterface# + if(!pRXText.is()) + { + *nCharacters = 0; + return S_OK; + } + + *nCharacters = GetXInterface()->getCharacterCount(); + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +// added by qiuhd, 2006/07/03, for direver 07/11 +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_newText( IA2TextSegment *) +{ + return E_NOTIMPL; +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::get_oldText( IA2TextSegment *) +{ + return E_NOTIMPL; +} + +/** + * Scroll to special sub-string . + * @param startIndex Start index of sub string. + * @param endIndex End index of sub string. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::scrollSubstringToPoint(long, long, IA2CoordinateType, long, long ) +{ + return E_NOTIMPL; +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::scrollSubstringTo(long startIndex, long endIndex, IA2ScrollType type) +{ + SolarMutexGuard g; + + try { + + // #CHECK XInterface# + if(!pRXText.is()) + return E_FAIL; + + AccessibleScrollType lUnoType; + + switch(type) + { + case IA2_SCROLL_TYPE_TOP_LEFT: + lUnoType = AccessibleScrollType_SCROLL_TOP_LEFT; + break; + case IA2_SCROLL_TYPE_BOTTOM_RIGHT: + lUnoType = AccessibleScrollType_SCROLL_BOTTOM_RIGHT; + break; + case IA2_SCROLL_TYPE_TOP_EDGE: + lUnoType = AccessibleScrollType_SCROLL_TOP_EDGE; + break; + case IA2_SCROLL_TYPE_BOTTOM_EDGE: + lUnoType = AccessibleScrollType_SCROLL_BOTTOM_EDGE; + break; + case IA2_SCROLL_TYPE_LEFT_EDGE: + lUnoType = AccessibleScrollType_SCROLL_LEFT_EDGE; + break; + case IA2_SCROLL_TYPE_RIGHT_EDGE: + lUnoType = AccessibleScrollType_SCROLL_RIGHT_EDGE; + break; + case IA2_SCROLL_TYPE_ANYWHERE: + lUnoType = AccessibleScrollType_SCROLL_ANYWHERE; + break; + default: + return E_NOTIMPL; + } + + if( GetXInterface()->scrollSubstringTo(startIndex, endIndex, lUnoType) ) + return S_OK; + + return E_NOTIMPL; + + } catch(...) { return E_FAIL; } +} + +/** + * Put UNO interface. + * @param pXInterface UNO interface. + * @return Result. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTextBase::put_XInterface(hyper pXInterface) +{ + // internal IUNOXWrapper - no mutex meeded + + try { + + CUNOXWrapper::put_XInterface(pXInterface); + //special query. + if(pUNOInterface == nullptr) + return E_FAIL; + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + if( !pRContext.is() ) + { + return E_FAIL; + } + Reference<XAccessibleText> pRXI(pRContext,UNO_QUERY); + if( !pRXI.is() ) + pRXText = nullptr; + else + pRXText = pRXI; + return S_OK; + + } catch(...) { return E_FAIL; } +} + +static OUString ReplaceOneChar(OUString const & oldOUString, sal_Unicode replacedChar, std::u16string_view replaceStr) +{ + auto s = oldOUString; + int iReplace = s.lastIndexOf(replacedChar); + if (iReplace > -1) + { + for(;iReplace>-1;) + { + s = s.replaceAt(iReplace,1, replaceStr); + iReplace=s.lastIndexOf(replacedChar,iReplace); + } + } + return s; +} + +static OUString ReplaceFourChar(OUString const & oldOUString) +{ + auto s = oldOUString; + s = ReplaceOneChar(s, '\\', u"\\\\"); + s = ReplaceOneChar(s, ';', u"\\;"); + s = ReplaceOneChar(s, '=', u"\\="); + s = ReplaceOneChar(s, ',', u"\\,"); + s = ReplaceOneChar(s, ':', u"\\:"); + return s; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccTextBase.h b/winaccessibility/source/UAccCOM/AccTextBase.h new file mode 100644 index 000000000..66f008756 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccTextBase.h @@ -0,0 +1,113 @@ +/* -*- 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 . + */ + +// AccTextBase.h: interface for the CAccTextBase class. + +#pragma once + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/accessibility/XAccessibleText.hpp> +#include "UNOXWrapper.h" + +class ATL_NO_VTABLE CAccTextBase : public CUNOXWrapper +{ +public: + CAccTextBase(); + virtual ~CAccTextBase(); + + // IAccessibleText +public: + // IAccessibleText + + // Adds a text selection. + STDMETHOD(get_addSelection)(long startOffset, long endOffset); + + // Gets text attributes. + STDMETHOD(get_attributes) + (long offset, long* startOffset, long* endOffset, BSTR* textAttributes); + + // Gets caret offset. + STDMETHOD(get_caretOffset)(long* offset); + + // Gets total number of characters. + STDMETHOD(get_characterCount)(long* nCharacters); + + // Gets bounding rect containing the glyph(s) representing the character + // at the specified text offset + STDMETHOD(get_characterExtents) + (long offset, IA2CoordinateType coordType, long* x, long* y, long* width, long* height); + + // Gets number of active non-contiguous selections. + STDMETHOD(get_nSelections)(long* nSelections); + + // Gets bounding rect for the glyph at a certain point. + STDMETHOD(get_offsetAtPoint)(long x, long y, IA2CoordinateType coordType, long* offset); + + // Gets character offsets of N-th active text selection. + STDMETHOD(get_selection)(long selectionIndex, long* startOffset, long* endOffset); + + // Gets a range of text by offset NOTE: returned string may be longer + // than endOffset-startOffset bytes if text contains multi-byte characters. + STDMETHOD(get_text)(long startOffset, long endOffset, BSTR* text); + + // Gets a specified amount of text that ends before a specified offset. + STDMETHOD(get_textBeforeOffset) + (long offset, IA2TextBoundaryType boundaryType, long* startOffset, long* endOffset, BSTR* text); + + // Gets a specified amount of text that spans the specified offset. + STDMETHOD(get_textAfterOffset) + (long offset, IA2TextBoundaryType boundaryType, long* startOffset, long* endOffset, BSTR* text); + + // Gets a specified amount of text that starts after a specified offset. + STDMETHOD(get_textAtOffset) + (long offset, IA2TextBoundaryType boundaryType, long* startOffset, long* endOffset, BSTR* text); + + // Unselects a range of text. + STDMETHOD(removeSelection)(long selectionIndex); + + // Moves text caret. + STDMETHOD(setCaretOffset)(long offset); + + // Changes the bounds of an existing selection. + STDMETHOD(setSelection)(long selectionIndex, long startOffset, long endOffset); + + // Gets total number of characters. + // NOTE: this may be different than the total number of bytes required + // to store the text, if the text contains multi-byte characters. + STDMETHOD(get_nCharacters)(long* nCharacters); + + STDMETHOD(get_newText)(IA2TextSegment* newText); + + STDMETHOD(get_oldText)(IA2TextSegment* oldText); + + // Makes specific part of string visible on screen. + STDMETHOD(scrollSubstringTo)(long startIndex, long endIndex, enum IA2ScrollType scrollType); + STDMETHOD(scrollSubstringToPoint) + (long startIndex, long endIndex, enum IA2CoordinateType coordinateType, long x, long y); + + // Override of IUNOXWrapper. + STDMETHOD(put_XInterface)(hyper pXInterface) override; + +private: + css::uno::Reference<css::accessibility::XAccessibleText> pRXText; + + css::accessibility::XAccessibleText* GetXInterface() { return pRXText.get(); } +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccValue.cxx b/winaccessibility/source/UAccCOM/AccValue.cxx new file mode 100644 index 000000000..c18440e65 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccValue.cxx @@ -0,0 +1,245 @@ +/* -*- 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 "stdafx.h" +#include "AccValue.h" +#include "MAccessible.h" + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +#include <vcl/svapp.hxx> + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> + +using namespace com::sun::star::accessibility; +using namespace com::sun::star::uno; + +/** + * Get current value. + * @param currentValue Variant that accepts current value. + * @return Result. + */ + +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccValue::get_currentValue(VARIANT* currentValue) +{ + SolarMutexGuard g; + + try + { + if (currentValue == nullptr) + return E_INVALIDARG; + if (!pRXVal.is()) + return E_FAIL; + + // Get Any type value from UNO. + css::uno::Any anyVal = GetXInterface()->getCurrentValue(); + // Convert Any to VARIANT. + CMAccessible::ConvertAnyToVariant(anyVal, currentValue); + + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +/** + * Set current value. + * @param Value New value should be set. + * @param success If the method is successfully called. + * @return Result. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccValue::setCurrentValue(VARIANT value) +{ + SolarMutexGuard g; + + try + { + if (!pRXVal.is()) + return E_FAIL; + + HRESULT hRet = S_OK; + css::uno::Any anyVal; + + // Set value according to value type. + switch (value.vt) + { + case VT_UI1: + { + anyVal <<= sal_Unicode(value.bVal); + } + break; + + case VT_BOOL: + { + css::uno::Type typeInfo(TypeClass_BOOLEAN, "bool"); + anyVal.setValue(&value.boolVal, typeInfo); + } + break; + + case VT_I2: + { + css::uno::Type typeInfo(TypeClass_SHORT, "short"); + anyVal.setValue(&value.iVal, typeInfo); + } + break; + + case VT_I4: + { + css::uno::Type typeInfo(TypeClass_LONG, "long"); + anyVal.setValue(&value.lVal, typeInfo); + } + break; + + case VT_R4: + { + css::uno::Type typeInfo(TypeClass_FLOAT, "float"); + anyVal.setValue(&value.fltVal, typeInfo); + } + break; + + case VT_R8: + { + css::uno::Type typeInfo(TypeClass_DOUBLE, "double"); + anyVal.setValue(&value.dblVal, typeInfo); + } + break; + + default: + { + // Unsupported type conversion. + hRet = E_FAIL; + } + break; + } + + if (hRet == S_OK) + { + hRet = pRXVal->setCurrentValue(anyVal) ? S_OK : E_FAIL; + } + + return hRet; + } + catch (...) + { + return E_FAIL; + } +} + +/** + * Get maximum value. + * @param maximumValue Variant that accepts maximum value. + * @return Result. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccValue::get_maximumValue(VARIANT* maximumValue) +{ + SolarMutexGuard g; + + try + { + if (maximumValue == nullptr) + return E_INVALIDARG; + if (!pRXVal.is()) + return E_FAIL; + + // Get Any type value from UNO. + css::uno::Any anyVal = GetXInterface()->getMaximumValue(); + // Convert Any to VARIANT. + CMAccessible::ConvertAnyToVariant(anyVal, maximumValue); + + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +/** + * Get minimum value. + * @param minimumValue Variant that accepts minimum value. + * @return Result. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccValue::get_minimumValue(VARIANT* minimumValue) +{ + SolarMutexGuard g; + + try + { + if (minimumValue == nullptr) + return E_FAIL; + if (!pRXVal.is()) + return E_FAIL; + + // Get Any type value from UNO. + css::uno::Any anyVal = GetXInterface()->getMinimumValue(); + // Convert Any to VARIANT. + CMAccessible::ConvertAnyToVariant(anyVal, minimumValue); + + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +/** + * Put valid UNO interface into com class. + * @param pXInterface UNO interface. + * @return Result. + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CAccValue::put_XInterface(hyper pXInterface) +{ + // internal IUNOXWrapper - no mutex meeded + + try + { + CUNOXWrapper::put_XInterface(pXInterface); + //special query. + if (pUNOInterface == nullptr) + return E_FAIL; + Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); + if (!pRContext.is()) + { + return E_FAIL; + } + Reference<XAccessibleValue> pRXI(pRContext, UNO_QUERY); + if (!pRXI.is()) + pRXVal = nullptr; + else + pRXVal = pRXI.get(); + return S_OK; + } + catch (...) + { + return E_FAIL; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccValue.h b/winaccessibility/source/UAccCOM/AccValue.h new file mode 100644 index 000000000..056eeb261 --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccValue.h @@ -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 "Resource.h" // main symbols + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/accessibility/XAccessibleValue.hpp> +#include "UNOXWrapper.h" + +/** + * CAccValue implements IAccessibleValue interface. + */ +class CAccValue : + public CComObjectRoot, + public CComCoClass<CAccValue,&CLSID_AccValue>, + public IAccessibleValue, + public CUNOXWrapper +{ +public: + CAccValue() + { + } + virtual ~CAccValue() + { + } + + BEGIN_COM_MAP(CAccValue) + COM_INTERFACE_ENTRY(IAccessibleValue) + COM_INTERFACE_ENTRY(IUNOXWrapper) + COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_) +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + END_COM_MAP() +#if defined __clang__ +#pragma clang diagnostic pop +#endif + + static HRESULT WINAPI SmartQI_(void* pv, + REFIID iid, void** ppvObject, DWORD_PTR) + { + return static_cast<CAccValue*>(pv)->SmartQI(iid,ppvObject); + } + + HRESULT SmartQI(REFIID iid, void** ppvObject) + { + if( m_pOuterUnknown ) + return OuterQueryInterface(iid,ppvObject); + return E_FAIL; + } + + DECLARE_NO_REGISTRY() + +public: + // IAccessibleValue + + // Returns the value of this object as a number. + STDMETHOD(get_currentValue)(VARIANT *currentValue) override; + + // Sets the value of this object to the given number. + STDMETHOD(setCurrentValue)(VARIANT value) override; + + // Returns the maximal value that can be represented by this object. + STDMETHOD(get_maximumValue)(VARIANT *maximumValue) override; + + // Returns the minimal value that can be represented by this object. + STDMETHOD(get_minimumValue)(VARIANT *minimumValue) override; + + // Override of IUNOXWrapper. + STDMETHOD(put_XInterface)(hyper pXInterface) override; + +private: + + css::uno::Reference<css::accessibility::XAccessibleValue> pRXVal; + + css::accessibility::XAccessibleValue* GetXInterface() + { + return pRXVal.get(); + } + +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/AccessibleKeyStroke.h b/winaccessibility/source/UAccCOM/AccessibleKeyStroke.h new file mode 100644 index 000000000..db3903cbd --- /dev/null +++ b/winaccessibility/source/UAccCOM/AccessibleKeyStroke.h @@ -0,0 +1,152 @@ +/* -*- 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 + +struct ACCESSIBLE_KEYSTROKE +{ + short modifiers; + short keyCode; + char keyChar; + short keyFunc; +}; + +const short MODIFIER_SHIFT = 1; +const short MODIFIER_CTRL = 2; +const short MODIFIER_ALT = 4; + +const short KEYCODE_NUM0 = 256; +const short KEYCODE_NUM1 = 257; +const short KEYCODE_NUM2 = 258; +const short KEYCODE_NUM3 = 259; +const short KEYCODE_NUM4 = 260; +const short KEYCODE_NUM5 = 261; +const short KEYCODE_NUM6 = 262; +const short KEYCODE_NUM7 = 263; +const short KEYCODE_NUM8 = 264; +const short KEYCODE_NUM9 = 265; +const short KEYCODE_A = 512; +const short KEYCODE_B = 513; +const short KEYCODE_C = 514; +const short KEYCODE_D = 515; +const short KEYCODE_E = 516; +const short KEYCODE_F = 517; +const short KEYCODE_G = 518; +const short KEYCODE_H = 519; +const short KEYCODE_I = 520; +const short KEYCODE_J = 521; +const short KEYCODE_K = 522; +const short KEYCODE_L = 523; +const short KEYCODE_M = 524; +const short KEYCODE_N = 525; +const short KEYCODE_O = 526; +const short KEYCODE_P = 527; +const short KEYCODE_Q = 528; +const short KEYCODE_R = 529; +const short KEYCODE_S = 530; +const short KEYCODE_T = 531; +const short KEYCODE_U = 532; +const short KEYCODE_V = 533; +const short KEYCODE_W = 534; +const short KEYCODE_X = 535; +const short KEYCODE_Y = 536; +const short KEYCODE_Z = 537; +const short KEYCODE_F1 = 768; +const short KEYCODE_F2 = 769; +const short KEYCODE_F3 = 770; +const short KEYCODE_F4 = 771; +const short KEYCODE_F5 = 772; +const short KEYCODE_F6 = 773; +const short KEYCODE_F7 = 774; +const short KEYCODE_F8 = 775; +const short KEYCODE_F9 = 776; +const short KEYCODE_F10 = 777; +const short KEYCODE_F11 = 778; +const short KEYCODE_F12 = 779; +const short KEYCODE_F13 = 780; +const short KEYCODE_F14 = 781; +const short KEYCODE_F15 = 782; +const short KEYCODE_F16 = 783; +const short KEYCODE_F17 = 784; +const short KEYCODE_F18 = 785; +const short KEYCODE_F19 = 786; +const short KEYCODE_F20 = 787; +const short KEYCODE_F21 = 788; +const short KEYCODE_F22 = 789; +const short KEYCODE_F23 = 790; +const short KEYCODE_F24 = 791; +const short KEYCODE_F25 = 792; +const short KEYCODE_F26 = 793; +const short KEYCODE_DOWN = 1024; +const short KEYCODE_UP = 1025; +const short KEYCODE_LEFT = 1026; +const short KEYCODE_RIGHT = 1027; +const short KEYCODE_HOME = 1028; +const short KEYCODE_END = 1029; +const short KEYCODE_PAGEUP = 1030; +const short KEYCODE_PAGEDOWN = 1031; +const short KEYCODE_RETURN = 1280; +const short KEYCODE_ESCAPE = 1281; +const short KEYCODE_TAB = 1282; +const short KEYCODE_BACKSPACE = 1283; +const short KEYCODE_SPACE = 1284; +const short KEYCODE_INSERT = 1285; +const short KEYCODE_DELETE = 1286; +const short KEYCODE_ADD = 1287; +const short KEYCODE_SUBTRACT = 1288; +const short KEYCODE_MULTIPLY = 1289; +const short KEYCODE_DIVIDE = 1290; +const short KEYCODE_POINT = 1291; +const short KEYCODE_COMMA = 1292; +const short KEYCODE_LESS = 1293; +const short KEYCODE_GREATER = 1294; +const short KEYCODE_EQUAL = 1295; +const short KEYCODE_OPEN = 1296; +const short KEYCODE_CUT = 1297; +const short KEYCODE_COPY = 1298; +const short KEYCODE_PASTE = 1299; +const short KEYCODE_UNDO = 1300; +const short KEYCODE_REPEAT = 1301; +const short KEYCODE_FIND = 1302; +const short KEYCODE_PROPERTIES = 1303; +const short KEYCODE_FRONT = 1304; +const short KEYCODE_CONTEXTMENU = 1305; +const short KEYCODE_HELP = 1306; + +const short SHORTCUT_DONTKNOW = 0; +const short NEW = 1; +const short OPEN = 2; +const short SAVE = 3; +const short SAVEAS = 4; +const short PRINT = 5; +const short CLOSE = 6; +const short QUIT = 7; +const short CUT = 8; +const short COPY = 9; +const short PASTE = 10; +const short UNDO = 11; +const short REDO = 12; +const short UNODELETE = 13; +const short REPEAT = 14; +const short FIND = 15; +const short FINDBACKWARD = 16; +const short PROPERTIES = 17; +const short FRONT = 18; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/EnumVariant.cxx b/winaccessibility/source/UAccCOM/EnumVariant.cxx new file mode 100644 index 000000000..26cd75b25 --- /dev/null +++ b/winaccessibility/source/UAccCOM/EnumVariant.cxx @@ -0,0 +1,245 @@ +/* -*- 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 "stdafx.h" +#include "EnumVariant.h" +#include "MAccessible.h" + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +#include <vcl/svapp.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; + + +// CEnumVariant + + +/** + * enumerate method,get next element + * @param cElements The number of elements to be returned. + * @param pvar An array of at least size celt in which the elements are to be returned. + * @param pcElementFetched Pointer to the number of elements returned in rgVar, or Null + * @return Result. + */ +HRESULT STDMETHODCALLTYPE CEnumVariant::Next(ULONG cElements,VARIANT __RPC_FAR *pvar,ULONG __RPC_FAR *pcElementFetched) +{ + SolarMutexGuard g; + + long l1; + ULONG l2; + + if (pvar == nullptr) + return E_INVALIDARG; + + if (pcElementFetched != nullptr) + *pcElementFetched = 0; + + // Retrieve the next cElements. + for (l1=m_lCurrent, l2=0; l1<m_pXAccessibleSelection->getSelectedAccessibleChildCount() && + l2<cElements; l1++, l2++) + { + Reference< XAccessible > pRXAcc = m_pXAccessibleSelection->getSelectedAccessibleChild(l1); + IAccessible* pChild = nullptr; + bool isGet = CMAccessible::get_IAccessibleFromXAccessible(pRXAcc.get(), + &pChild); + if(isGet) + { + pvar[l2].vt = VT_DISPATCH; + pvar[l2].pdispVal = pChild; + pChild->AddRef(); + } + else if(pRXAcc.is()) + { + if(CMAccessible::g_pAgent) + CMAccessible::g_pAgent->InsertAccObj(pRXAcc.get(),pUNOInterface); + isGet = CMAccessible::get_IAccessibleFromXAccessible( + pRXAcc.get(), &pChild); + if(isGet) + { + pvar[l2].vt = VT_DISPATCH; + pvar[l2].pdispVal = pChild; + pChild->AddRef(); + } + } + } + // Set count of elements retrieved. + if (pcElementFetched != nullptr) + *pcElementFetched = l2; + m_lCurrent = l1; + + return (l2 < cElements) ? S_FALSE : NOERROR; +} + +/** + * skip the elements in the given range when enumerate elements + * @param cElements The number of elements to skip. + * @return Result. + */ +HRESULT STDMETHODCALLTYPE CEnumVariant::Skip(ULONG cElements) +{ + SolarMutexGuard g; + + m_lCurrent += cElements; + if (m_lCurrent > static_cast<long>(m_lLBound+m_pXAccessibleSelection->getSelectedAccessibleChildCount())) + { + m_lCurrent = m_lLBound+m_pXAccessibleSelection->getSelectedAccessibleChildCount(); + return E_FAIL; + } + else + return NOERROR; +} + + +/** + * reset the enumaration position to initial value + * @param + * @return Result. + */ +HRESULT STDMETHODCALLTYPE CEnumVariant::Reset() +{ + SolarMutexGuard g; + + m_lCurrent = m_lLBound; + return NOERROR; +} + + +/** + *create a new IEnumVariant object, + *copy current enumaration container and its state to + *the new object + *AT will use the copy object to get elements + * @param ppenum On return, pointer to the location of the clone enumerator + * @return Result. + */ +HRESULT STDMETHODCALLTYPE CEnumVariant::Clone(IEnumVARIANT __RPC_FAR *__RPC_FAR *ppenum) +{ + SolarMutexGuard g; + + CEnumVariant * penum = nullptr; + HRESULT hr; + if (ppenum == nullptr) + return E_INVALIDARG; + + *ppenum = nullptr; + + hr = Create(&penum); + if( hr == S_OK ) + { + penum->PutSelection(reinterpret_cast<hyper>(pUNOInterface)); + *ppenum = penum; + } + else + { + if (penum) + penum->Release(); + } + return hr; +} + +/** + *Static public method to create a CLSID_EnumVariant com object. + * @param ppenum Pointer to accept com object. + * @return Result. + */ +HRESULT STDMETHODCALLTYPE CEnumVariant::Create(CEnumVariant __RPC_FAR *__RPC_FAR *ppenum) +{ + SolarMutexGuard g; + + HRESULT hr = createInstance<CEnumVariant>(IID_IEnumVariant, ppenum); + if (S_OK != hr) + { + return E_FAIL; + } + + return S_OK; +} + +/** + *Return count of elements in current container + * @param. + * @return count of elements in current container. + */ +long CEnumVariant::GetCountOfElements() +{ + if(m_pXAccessibleSelection.is()) + return m_pXAccessibleSelection->getSelectedAccessibleChildCount(); + return 0; +} + +/** + * Set member m_pXAccessibleSelection to NULL and m_lCurrent to m_lLBound. + * @param. + * @return Result + */ +COM_DECLSPEC_NOTHROW STDMETHODIMP CEnumVariant::ClearEnumeration() +{ + // internal IEnumVariant - no mutex meeded + + pUNOInterface = nullptr; + m_pXAccessibleSelection = nullptr; + m_lCurrent = m_lLBound; + return S_OK; +} + +/** + *Static method to fetch XAccessibleSelection + * @param pXAcc XAccessible interface. + * @return XAccessibleSelection interface. + */ +static Reference<XAccessibleSelection> GetXAccessibleSelection(XAccessible* pXAcc) +{ + if( pXAcc == nullptr) + return nullptr; + + Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext(); + if( !pRContext.is() ) + return nullptr; + + Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY); + if( !pRSelection.is() ) + return nullptr; + + return pRSelection; +} + +/** + * Put valid UNO XAccessible interface. + * @param pXSelection XAccessible interface. + * @return Result... + */ +STDMETHODIMP CEnumVariant::PutSelection(hyper pXSelection) +{ + // internal IEnumVariant - no mutex meeded + + pUNOInterface = reinterpret_cast<XAccessible*>(pXSelection); + m_pXAccessibleSelection = GetXAccessibleSelection(pUNOInterface); + return S_OK; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/EnumVariant.h b/winaccessibility/source/UAccCOM/EnumVariant.h new file mode 100644 index 000000000..d82bd771f --- /dev/null +++ b/winaccessibility/source/UAccCOM/EnumVariant.h @@ -0,0 +1,109 @@ +/* -*- 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 "Resource.h" // main symbols +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <AccObjectManagerAgent.hxx> + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +/** + * CEnumVariant implements IEnumVARIANT interface. + */ +class ATL_NO_VTABLE CEnumVariant : + public CComObjectRootEx<CComMultiThreadModel>, + public CComCoClass<CEnumVariant, &CLSID_EnumVariant>, + public IDispatchImpl<IEnumVariant, &IID_IEnumVariant, &LIBID_UACCCOMLib> +{ +public: + CEnumVariant() + :m_lLBound(0), + pUNOInterface(nullptr) + { + m_lCurrent = m_lLBound; + } + + virtual ~CEnumVariant() {}; + + DECLARE_NO_REGISTRY() + + DECLARE_PROTECT_FINAL_CONSTRUCT() + + BEGIN_COM_MAP(CEnumVariant) + COM_INTERFACE_ENTRY(IEnumVariant) + COM_INTERFACE_ENTRY(IEnumVARIANT) +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + END_COM_MAP() +#if defined __clang__ +#pragma clang diagnostic pop +#endif + + // IEnumVariant +public: + + STDMETHOD(ClearEnumeration)() override; + + // IEnumVARIANT + + + HRESULT STDMETHODCALLTYPE Next(ULONG cElements,VARIANT __RPC_FAR *pvar,ULONG __RPC_FAR *pcElementFetched) override; + + + HRESULT STDMETHODCALLTYPE Skip(ULONG cElements) override; + + + HRESULT STDMETHODCALLTYPE Reset( void) override; + + + HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT __RPC_FAR *__RPC_FAR *ppenum) override; + + // IEnumVariant + + + HRESULT STDMETHODCALLTYPE PutSelection(hyper pXSelection) override; + + + static HRESULT STDMETHODCALLTYPE Create(CEnumVariant __RPC_FAR *__RPC_FAR *ppenum); + + + long GetCountOfElements(); + +private: + + long m_lCurrent; + long m_lLBound; + css::accessibility::XAccessible* pUNOInterface; + css::uno::Reference<css::accessibility::XAccessibleSelection> + m_pXAccessibleSelection; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/MAccessible.cxx b/winaccessibility/source/UAccCOM/MAccessible.cxx new file mode 100644 index 000000000..848960ff7 --- /dev/null +++ b/winaccessibility/source/UAccCOM/MAccessible.cxx @@ -0,0 +1,3162 @@ +/* -*- 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 "MAccessible.h" + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +#include <algorithm> +#include <cstddef> + +#include "AccAction.h" +#include "AccRelation.h" +#include "AccComponent.h" +#include "AccText.h" +#include "AccEditableText.h" +#include "AccImage.h" +#include "AccTable.h" +#include "AccTableCell.h" +#include "AccValue.h" +#include "AccHypertext.h" +#include "AccHyperLink.h" + +#include <rtl/ustrbuf.hxx> +#include <vcl/svapp.hxx> +#include <o3tl/char16_t2wchar_t.hxx> +#include <comphelper/AccessibleImplementationHelper.hxx> + +#include <com/sun/star/accessibility/XAccessibleText.hpp> +#include <com/sun/star/accessibility/XAccessibleEditableText.hpp> +#include <com/sun/star/accessibility/XAccessibleImage.hpp> +#include <com/sun/star/accessibility/XAccessibleTable.hpp> +#include <com/sun/star/accessibility/XAccessibleExtendedComponent.hpp> +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp> +#include <com/sun/star/accessibility/XAccessibleHypertext.hpp> +#include <com/sun/star/accessibility/XAccessibleHyperlink.hpp> +#include <com/sun/star/accessibility/XAccessibleRelationSet.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/XAccessibleGroupPosition.hpp> +#include <com/sun/star/accessibility/XAccessibleValue.hpp> +#include <com/sun/star/accessibility/XAccessibleExtendedAttributes.hpp> +#include <com/sun/star/style/LineSpacing.hpp> +#include <com/sun/star/style/TabStop.hpp> +#include <com/sun/star/container/XIndexReplace.hpp> + + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; +using namespace com::sun::star::accessibility::AccessibleStateType; + +namespace { + +enum class XInterfaceType { + XI_COMPONENT, + XI_TEXT, + XI_TABLE, + XI_TABLECELL, + XI_EDITABLETEXT, + XI_IMAGE, + XI_SELECTION, + XI_EXTENDEDCOMP, + XI_VALUE, + XI_KEYBINDING, + XI_ACTION, + XI_HYPERTEXT, + XI_HYPERLINK, + XI_ATTRIBUTE +}; + +template <class Interface> +bool queryXInterface(XAccessible* pXAcc, XInterface** ppXI) +{ + if (!pXAcc) + return false; + + Reference<XAccessibleContext> pRContext = pXAcc->getAccessibleContext(); + if (!pRContext.is()) + return false; + + Reference<Interface> pRXI(pRContext, UNO_QUERY); + if (!pRXI.is()) + return false; + + *ppXI = pRXI.get(); + return true; +} + +// Since there's no specific XInterface for table cells, this +// method checks that the accessible's parent is a table +// (implements XAccessibleTable) and pXAcc's context implements +// XAccessibleComponent. +bool queryTableCell(XAccessible* pXAcc, XInterface** ppXI) +{ + XInterface* pXInterface = nullptr; + + const bool bSupportsInterface = queryXInterface<XAccessibleComponent>(pXAcc, &pXInterface); + if (!bSupportsInterface) + return false; + + // check whether parent is a table (its accessible context implements XAccessibleTable) + XInterface* pParentXInterface = nullptr; + Reference<XAccessible> xParentAcc = pXAcc->getAccessibleContext()->getAccessibleParent(); + const bool bParentIsTable = queryXInterface<XAccessibleTable>(xParentAcc.get(), &pParentXInterface); + + if (!bParentIsTable) + return false; + + *ppXI = pXInterface; + return true; +} + +} + +// IA2 states mapping, and name +// maintenance the consistency, change one array, change the three all +long const IA2_STATES[] = +{ + IA2_STATE_ACTIVE, // = 0x1; + IA2_STATE_ARMED, // = 0x2; + IA2_STATE_DEFUNCT, // = 0x4; + IA2_STATE_EDITABLE, // = 0x8; + IA2_STATE_HORIZONTAL, // = 0x10; + IA2_STATE_ICONIFIED, // = 0x20; + IA2_STATE_INVALID_ENTRY, // = 0x80; + IA2_STATE_MANAGES_DESCENDANTS, // = 0x100; + IA2_STATE_MODAL, // = 0x200; + IA2_STATE_MULTI_LINE, // = 0x400; + IA2_STATE_OPAQUE, // = 0x800; + IA2_STATE_REQUIRED, // = 0x2000; + IA2_STATE_SELECTABLE_TEXT, // = 0x3000; + IA2_STATE_SINGLE_LINE, // = 0x4000; + IA2_STATE_STALE, // = 0x8000; + IA2_STATE_SUPPORTS_AUTOCOMPLETION, // = 0x10000; + IA2_STATE_TRANSIENT, //= 0x20000; + IA2_STATE_VERTICAL // = 0x40000; +}; +/* + +<=== map ===> + +*/ +short const UNO_STATES[] = +{ + ACTIVE, // = (sal_Int16)1; + ARMED, // = (sal_Int16)2; + DEFUNC, // = (sal_Int16)5; + EDITABLE, // = (sal_Int16)6; + HORIZONTAL, // = (sal_Int16)12; + ICONIFIED, // = (sal_Int16)13; + -1, //IA2_STATE_INVALID_ENTRY + MANAGES_DESCENDANTS, // = (sal_Int16)15; + MODAL, // = (sal_Int16)16; + MULTI_LINE, // = (sal_Int16)17; + OPAQUE, // = (sal_Int16)19; + -1, //IA2_STATE_REQUIRED + -1, //IA2_STATE_SELECTABLE_TEXT + SINGLE_LINE, // = (sal_Int16)26; + STALE, // = (sal_Int16)27; + -1, //IA2_STATE_SUPPORTS_AUTOCOMPLETION + TRANSIENT, //IA2_STATE_TRANSIENT + VERTICAL // = (sal_Int16)29; +}; + +using namespace com::sun::star::accessibility::AccessibleRole; + + +AccObjectManagerAgent* CMAccessible::g_pAgent = nullptr; + +CMAccessible::CMAccessible(): +m_pszName(nullptr), +m_pszValue(nullptr), +m_pszActionDescription(nullptr), +m_iRole(0x00), +m_dState(0x00), +m_pIParent(nullptr), +m_dChildID(0x00), +m_dFocusChildID(UACC_NO_FOCUS), +m_hwnd(nullptr), +m_isDestroy(false) +{ + m_sLocation.m_dLeft=0; + m_sLocation.m_dTop = 0; + m_sLocation.m_dWidth=0; + m_sLocation.m_dHeight=0; + CEnumVariant::Create(&m_pEnumVar); + m_containedObjects.clear(); +} + +CMAccessible::~CMAccessible() +{ + SolarMutexGuard g; + + if(m_pszName!=nullptr) + { + SysFreeString(std::exchange(m_pszName, nullptr)); + } + if(m_pszValue!=nullptr) + { + SysFreeString(std::exchange(m_pszValue, nullptr)); + } + + if(m_pszActionDescription!=nullptr) + { + SysFreeString(std::exchange(m_pszActionDescription, nullptr)); + } + + if(m_pIParent) + { + m_pIParent->Release(); + m_pIParent=nullptr; + } + m_pEnumVar->Release(); + m_containedObjects.clear(); +} + +/** +* Returns the Parent IAccessible interface pointer to AT. +* It should add reference, and the client should release the component. +* It should return E_FAIL when the parent point is null. +* @param ppdispParent [in,out] used to return the parent interface point. +* when the point is null, should return null. +* @return S_OK if successful and E_FAIL if the m_pIParent is NULL. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accParent(IDispatch **ppdispParent) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(ppdispParent == nullptr) + { + return E_INVALIDARG; + } + + if(m_pIParent) + { + *ppdispParent = m_pIParent; + (*ppdispParent)->AddRef(); + return S_OK; + } + else if(m_hwnd) + { + HRESULT hr = AccessibleObjectFromWindow(m_hwnd, OBJID_WINDOW, IID_IAccessible, reinterpret_cast<void**>(ppdispParent)); + if (!SUCCEEDED(hr) || !*ppdispParent) + { + return S_FALSE; + } + return S_OK; + } + return S_FALSE; + + } catch(...) { return E_FAIL; } +} + +/** +* Returns child count of current COM object. +* @param pcountChildren [in,out] used to return the children count. +* @return S_OK if successful. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accChildCount(long *pcountChildren) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pcountChildren == nullptr) + { + return E_INVALIDARG; + } + + if (!m_xAccessible.is()) + return S_FALSE; + + Reference<XAccessibleContext> const pRContext = + m_xAccessible->getAccessibleContext(); + if( pRContext.is() ) + { + *pcountChildren = pRContext->getAccessibleChildCount(); + } + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** +* Returns child interface pointer for AT according to input child ID. +* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, +* the child ID specify child index from 0 to children count, 0 stands for object self. +* @param ppdispChild, [in,out] use to return the child interface point. +* @return S_OK if successful and S_FALSE if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accChild(VARIANT varChild, IDispatch **ppdispChild) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(ppdispChild == nullptr) + { + return E_INVALIDARG; + } + if(varChild.vt==VT_I4) + { + //get child interface pointer due to child ID + if(varChild.lVal==CHILDID_SELF) + { + AddRef(); + *ppdispChild = this; + return S_OK; + } + *ppdispChild = GetChildInterface(varChild.lVal); + if((*ppdispChild) == nullptr) + return E_FAIL; + (*ppdispChild)->AddRef(); + return S_OK; + } + return S_FALSE; + + } catch(...) { return E_FAIL; } +} + +/** +* Returns the accessible name of the current COM object self or its one child to AT. +* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, +* the child ID specify child index from 0 to children count, 0 stands for object self. +* @param pszName, [in,out] use to return the name of the proper object. +* @return S_OK if successful and S_FALSE if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accName(VARIANT varChild, BSTR *pszName) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pszName == nullptr) + { + return E_INVALIDARG; + } + if(varChild.vt==VT_I4) + { + if(varChild.lVal==CHILDID_SELF) + { + SysFreeString(*pszName); + *pszName = SysAllocString(m_pszName); + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->get_accName(varChild,pszName); + } + return S_FALSE; + + } catch(...) { return E_FAIL; } +} + +/** +* Returns the accessible value of the current COM object self or its one child to AT. +* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, +* the child ID specify child index from 0 to children count, 0 stands for object self. +* @param pszValue, [in,out] use to return the value of the proper object. +* @return S_OK if successful and S_FALSE if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accValue(VARIANT varChild, BSTR *pszValue) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if( pszValue == nullptr ) + { + return E_INVALIDARG; + } + if( varChild.vt==VT_I4 ) + { + if(varChild.lVal==CHILDID_SELF) + { + if(m_dState & STATE_SYSTEM_PROTECTED) + return E_ACCESSDENIED; + + if ( m_pszValue !=nullptr && wcslen(m_pszValue) == 0 ) + return S_OK; + + SysFreeString(*pszValue); + *pszValue = SysAllocString(m_pszValue); + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->get_accValue(varChild,pszValue); + } + return S_FALSE; + + } catch(...) { return E_FAIL; } +} + +/** +* Returns the accessible description of the current COM object self or its one child to AT. +* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, +* the child ID specify child index from 0 to children count, 0 stands for object self. +* @param pszDescription, [in,out] use to return the description of the proper object. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accDescription(VARIANT varChild, BSTR *pszDescription) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pszDescription == nullptr) + { + return E_INVALIDARG; + } + if(varChild.vt==VT_I4) + { + if(varChild.lVal==CHILDID_SELF) + { + if (!m_xAccessible.is()) + return S_FALSE; + + Reference<XAccessibleContext> xContext = m_xAccessible->getAccessibleContext(); + if (!xContext.is()) + return S_FALSE; + + const OUString sDescription = xContext->getAccessibleDescription(); + SysFreeString(*pszDescription); + *pszDescription = SysAllocString(o3tl::toW(sDescription.getStr())); + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->get_accDescription(varChild,pszDescription); + } + return S_FALSE; + + } catch(...) { return E_FAIL; } +} + +/** +* Returns the accessible role of the current COM object self or its one child to AT. +* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, +* the child ID specify child index from 0 to children count, 0 stands for object self. +* @param pvarRole, [in,out] use to return the role of the proper object. +* @return S_OK if successful and S_FALSE if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accRole(VARIANT varChild, VARIANT *pvarRole) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pvarRole == nullptr) + { + return E_INVALIDARG; + } + if(varChild.vt == VT_I4) + { + + if(varChild.lVal == CHILDID_SELF) + { + VariantInit(pvarRole); + pvarRole->vt = VT_I4; + + if (m_iRole < IA2_ROLE_CAPTION) + pvarRole->lVal = m_iRole; + else + pvarRole->lVal = ROLE_SYSTEM_CLIENT; + + return S_OK; + } + + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->get_accRole(varChild,pvarRole); + } + return S_FALSE; + + } catch(...) { return E_FAIL; } +} + +/** +* Returns the accessible state of the current COM object self or its one child to AT. +* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, +* the child ID specify child index from 0 to children count, 0 stands for object self. +* @param pvarState, [in,out] use to return the state of the proper object. +* @return S_OK if successful and S_FALSE if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accState(VARIANT varChild, VARIANT *pvarState) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pvarState == nullptr) + { + return E_INVALIDARG; + } + if(varChild.vt==VT_I4) + { + if(varChild.lVal == CHILDID_SELF) + { + if (m_xAccessible.is()) + { + Reference<XAccessibleContext> const pContext = + m_xAccessible->getAccessibleContext(); + if(pContext.is()) + { + // add the STATE_SYSTEM_LINKED state + Reference< XAccessibleHypertext > pRHypertext(pContext,UNO_QUERY); + if(pRHypertext.is()) + { + if( pRHypertext->getHyperLinkCount() > 0 ) + m_dState |= STATE_SYSTEM_LINKED; + else + m_dState &= ~STATE_SYSTEM_LINKED; + } + else + m_dState &= ~STATE_SYSTEM_LINKED; + } + } + + VariantInit(pvarState); + pvarState->vt = VT_I4; + pvarState->lVal = m_dState; + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->get_accState(varChild,pvarState); + } + return S_FALSE; + + } catch(...) { return E_FAIL; } +} + +/** +* Returns the accessible helpString of the current COM object self or its one child to AT. +* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, +* the child ID specify child index from 0 to children count, 0 stands for object self. +* @param pszHelp, [in,out] use to return the helpString of the proper object. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accHelp(VARIANT, BSTR *) +{ + return E_NOTIMPL; +} + +/** +* Returns the accessible HelpTopic of the current COM object self or its one child to AT. +* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, +* the child ID specify child index from 0 to children count, 0 stands for object self. +* @param pszHelpFile, [in,out] use to return the HelpTopic of the proper object. +* @param pidTopic, use to return the HelpTopic ID of the proper object. +* @return S_OK if successful and E_FAIL if failure. +* Not implemented yet +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accHelpTopic(BSTR *, VARIANT, long *) +{ + return E_NOTIMPL; +} + +static bool GetMnemonicChar( const OUString& aStr, sal_Unicode* wStr) +{ + for (sal_Int32 i = 0;; i += 2) { + i = aStr.indexOf('~', i); + if (i == -1 || i == aStr.getLength() - 1) { + return false; + } + auto c = aStr[i + 1]; + if (c != '~') { + *wStr = c; + return true; + } + } +} + +/** +* Returns the accessible keyboard shortcut of the current COM object self or its one child to AT. +* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, +* the child ID specify child index from 0 to children count, 0 stands for object self. +* @param pszKeyboardShortcut, [in,out] use to return the kbshortcut of the proper object. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accKeyboardShortcut(VARIANT varChild, BSTR *pszKeyboardShortcut) +{ + SolarMutexGuard g; + + try { + + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pszKeyboardShortcut == nullptr) + { + return E_INVALIDARG; + } + + if(varChild.vt==VT_I4) + { + if(varChild.lVal == CHILDID_SELF) + { + if (m_xAccessible.is()) + { + Reference<XAccessibleContext> const pRContext = + m_xAccessible->getAccessibleContext(); + if( !pRContext.is() ) + return S_FALSE; + + Reference<XAccessibleAction> pRXI(pRContext,UNO_QUERY); + + OUString wString; + + if( pRXI.is() && pRXI->getAccessibleActionCount() >= 1) + { + Reference< XAccessibleKeyBinding > binding = pRXI->getAccessibleActionKeyBinding(0); + if( binding.is() ) + { + long nCount = binding->getAccessibleKeyBindingCount(); + if(nCount >= 1) + { + wString = comphelper::GetkeyBindingStrByXkeyBinding( binding->getAccessibleKeyBinding(0) ); + } + } + } + if(wString.isEmpty()) + { + Reference<XAccessibleRelationSet> pRrelationSet = pRContext->getAccessibleRelationSet(); + if(!pRrelationSet.is()) + { + return S_FALSE; + } + + long nRelCount = pRrelationSet->getRelationCount(); + + // Modified by Steve Yin, for SODC_1552 + if( /*nRelCount <= 0 &&*/ m_iRole == ROLE_SYSTEM_TEXT ) + { + VARIANT varParentRole; + VariantInit( &varParentRole ); + + if (m_pIParent + && SUCCEEDED(m_pIParent->get_accRole(varChild, &varParentRole)) + && varParentRole.lVal == ROLE_SYSTEM_COMBOBOX) // edit in comboBox + { + m_pIParent->get_accKeyboardShortcut(varChild, pszKeyboardShortcut); + return S_OK; + } + } + + AccessibleRelation *paccRelation = nullptr; + AccessibleRelation accRelation; + for(int i=0; i<nRelCount ; i++) + { + if( pRrelationSet->getRelation(i).RelationType == 6 ) + { + accRelation = pRrelationSet->getRelation(i); + paccRelation = &accRelation; + } + } + + if(paccRelation == nullptr) + return S_FALSE; + + Sequence< Reference< XInterface > > xTargets = paccRelation->TargetSet; + Reference<XInterface> pRAcc = xTargets[0]; + + XAccessible* pXAcc = static_cast<XAccessible*>(pRAcc.get()); + + Reference<XAccessibleContext> pRLebelContext = pXAcc->getAccessibleContext(); + if(!pRLebelContext.is()) + return S_FALSE; + + pRrelationSet = pRLebelContext->getAccessibleRelationSet(); + nRelCount = pRrelationSet->getRelationCount(); + + paccRelation = nullptr; + for(int j=0; j<nRelCount ; j++) + { + if( pRrelationSet->getRelation(j).RelationType == 5 ) + { + accRelation = pRrelationSet->getRelation(j); + paccRelation = &accRelation; + } + } + + if(paccRelation) + { + xTargets = paccRelation->TargetSet; + pRAcc = xTargets[0]; + if (m_xAccessible.get() != static_cast<XAccessible*>(pRAcc.get())) + return S_FALSE; + } + + Reference<XAccessibleExtendedComponent> pRXIE(pRLebelContext,UNO_QUERY); + if(!pRXIE.is()) + return S_FALSE; + + OUString ouStr = pRXIE->getTitledBorderText(); + sal_Unicode key; + if(GetMnemonicChar(ouStr, &key)) + { + wString = "Alt+" + OUStringChar(key); + } + else + return S_FALSE; + } + + SysFreeString(*pszKeyboardShortcut); + *pszKeyboardShortcut = SysAllocString(o3tl::toW(wString.getStr())); + + return S_OK; + } + else + { + return S_FALSE; + } + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + + return pChild->get_accKeyboardShortcut(varChild,pszKeyboardShortcut); + } + return S_FALSE; + + } catch(...) { return E_FAIL; } +} + +/** +* Returns the current focused child to AT. +* @param pvarChild, [in,out] vt member of pvarChild must be VT_I4,and lVal member stores the child ID, +* the child ID specify child index from 0 to children count, 0 stands for object self. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accFocus(VARIANT *pvarChild) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pvarChild == nullptr) + { + return E_INVALIDARG; + } + if( m_dFocusChildID==UACC_NO_FOCUS ) + { + pvarChild->vt = VT_EMPTY;//no focus on the object and its children + return S_OK; + } + //if the descendant of current object has focus indicated by m_dFocusChildID, return the IDispatch of this focused object + else + { + IMAccessible* pIMAcc = nullptr; + g_pAgent->GetIAccessibleFromResID(m_dFocusChildID,&pIMAcc); + if (pIMAcc == nullptr) + { + return E_FAIL; + } + pIMAcc->AddRef(); + pvarChild->vt = VT_DISPATCH; + pvarChild->pdispVal = pIMAcc; + + } + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** +* Returns the selection of the current COM object to AT. +* @param pvarChildren,[in,out] +* if selection num is 0,return VT_EMPTY for vt, +* if selection num is 1,return VT_I4 for vt,and child index for lVal +* if selection num >1,return VT_UNKNOWN for vt, and IEnumVariant* for punkVal +* @return S_OK if successful and S_FALSE if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_accSelection(VARIANT *pvarChildren) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pvarChildren == nullptr) + { + return E_INVALIDARG; + } + switch(m_pEnumVar->GetCountOfElements()) + { + case 0: + pvarChildren->vt = VT_EMPTY; + break; + case 1: + VARIANT varTmp[1]; + ULONG count; + VariantInit(&varTmp[0]); + m_pEnumVar->Next(1,varTmp,&count); + if(count!=1) + return S_FALSE; + pvarChildren->vt = VT_DISPATCH; + pvarChildren->pdispVal = varTmp[0].pdispVal; + pvarChildren->pdispVal->AddRef(); + VariantClear(&varTmp[0]); + m_pEnumVar->Reset(); + break; + default: + pvarChildren->vt = VT_UNKNOWN; + IEnumVARIANT* pClone; + m_pEnumVar->Clone(&pClone); + pClone->Reset(); + pvarChildren->punkVal = pClone; + break; + } + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** +* Returns the location of the current COM object self or its one child to AT. +* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, +* the child ID specify child index from 0 to children count, 0 stands for object self. +* @param pxLeft, [in,out] use to return the x-coordination of the proper object. +* @param pyTop, [in,out] use to return the y-coordination of the proper object. +* @param pcxWidth, [in,out] use to return the x-coordination width of the proper object. +* @param pcyHeight, [in,out] use to return the y-coordination height of the proper object. +* @return S_OK if successful and S_FALSE if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varChild) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pxLeft == nullptr || pyTop == nullptr || pcxWidth == nullptr || pcyHeight == nullptr) + { + return E_INVALIDARG; + } + + if(varChild.vt==VT_I4) + { + if(varChild.lVal==CHILDID_SELF) + { + + if (m_xAccessible.is()) + { + Reference<XAccessibleContext> const pRContext = + m_xAccessible->getAccessibleContext(); + if( !pRContext.is() ) + return S_FALSE; + Reference< XAccessibleComponent > pRComponent(pRContext,UNO_QUERY); + if( !pRComponent.is() ) + return S_FALSE; + + css::awt::Point pCPoint = pRComponent->getLocationOnScreen(); + css::awt::Size pCSize = pRComponent->getSize(); + *pxLeft = pCPoint.X; + *pyTop = pCPoint.Y; + *pcxWidth = pCSize.Width; + *pcyHeight = pCSize.Height; + return S_OK; + } + else + { + *pxLeft = m_sLocation.m_dLeft; + *pyTop = m_sLocation.m_dTop; + *pcxWidth = m_sLocation.m_dWidth; + *pcyHeight = m_sLocation.m_dHeight; + return S_OK; + } + } + + } + return S_FALSE; + + } catch(...) { return E_FAIL; } +} + +/** +* Returns the current focused child to AT. +* @param navDir, the direction flag of the navigation. +* @param varStart, the start child id of this navigation action. +* @param pvarEndUpAt, [in,out] the end up child of this navigation action. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEndUpAt) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pvarEndUpAt == nullptr) + { + return E_INVALIDARG; + } + HRESULT ret = E_FAIL; + switch (navDir) + { + case NAVDIR_FIRSTCHILD: + ret = GetFirstChild(varStart,pvarEndUpAt); + break; + case NAVDIR_LASTCHILD: + ret = GetLastChild(varStart,pvarEndUpAt); + break; + case NAVDIR_NEXT: + ret = GetNextSibling(varStart,pvarEndUpAt); + break; + case NAVDIR_PREVIOUS: + ret = GetPreSibling(varStart,pvarEndUpAt); + break; + case NAVDIR_DOWN://do not implement temporarily + break; + case NAVDIR_UP://do not implement temporarily + break; + case NAVDIR_LEFT://do not implement temporarily + break; + case NAVDIR_RIGHT://do not implement temporarily + break; + default: + break; + } + return ret; + + } catch(...) { return E_FAIL; } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::accHitTest(long xLeft, long yTop, VARIANT *pvarChild) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pvarChild == nullptr) + { + return E_INVALIDARG; + } + long x, y, w, h; + VARIANT varSelf; + VariantInit(&varSelf); + varSelf.vt = VT_I4; + varSelf.lVal = CHILDID_SELF; + accLocation(&x,&y,&w,&h,varSelf); + if( (x < xLeft && (x + w) >xLeft) && (y < yTop && (y + h) >yTop) ) + { + int i, nCount; + pvarChild->vt = VT_EMPTY; + Reference< XAccessibleContext > pRContext = GetContextByXAcc(m_xAccessible.get()); + nCount = pRContext->getAccessibleChildCount(); + if(nCount > 256) + return E_FAIL; + IMAccessible* child = nullptr; + for( i = 0; i<nCount; i++) + { + + child = GetChildInterface(i + 1); + if(child && child->accHitTest(xLeft,yTop,pvarChild) == S_OK) + break; + } + + if(pvarChild->vt == VT_DISPATCH) + return S_OK; + + if( i < nCount) + { + pvarChild->vt = VT_DISPATCH; + pvarChild->pdispVal = child; + child->AddRef(); + } + else + { + pvarChild->vt = VT_I4; + pvarChild->lVal = CHILDID_SELF; + } + return S_OK; + } + return S_FALSE; + + } catch(...) { return E_FAIL; } +} + +/** +* Get The other Interface from CMAccessible. +* @param guidService, must be IID_IAccessible here. +* @param riid, the IID interface . +* @return S_OK if successful and S_FALSE if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::QueryService(REFGUID guidService, REFIID riid, void** ppvObject) +{ + if( InlineIsEqualGUID(guidService, IID_IAccessible) ) + return QueryInterface(riid, ppvObject); + return S_FALSE; +} + +/** +* Set the accessible name of the current COM object self or its one child from UNO. +* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, +* the child ID specify child index from 0 to children count, 0 stands for object self. +* @param szName, the name used to set the name of the proper object. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::put_accName(VARIANT varChild, BSTR szName) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + if(varChild.vt==VT_I4) + { + if(varChild.lVal==CHILDID_SELF) + { + SysFreeString(m_pszName); + m_pszName=SysAllocString(szName); + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->put_accName(varChild,szName); + } + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** +* Set the accessible value of the current COM object self or its one child from UNO. +* @param varChild, vt member of varChild must be VT_I4,and lVal member stores the child ID, +* the child ID specify child index from 0 to children count, 0 stands for object self. +* @param szValue, the value used to set the value of the proper object. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::put_accValue(VARIANT varChild, BSTR szValue) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + if(varChild.vt==VT_I4) + { + if(varChild.lVal==CHILDID_SELF) + { + SysFreeString(m_pszValue); + m_pszValue=SysAllocString(szValue); + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->put_accValue(varChild,szValue); + } + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** +* Set the accessible name of the current COM object self from UNO. +* @param pszName, the name value used to set the name of the current object. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccName(const OLECHAR __RPC_FAR *pszName) +{ + // internal IMAccessible - no mutex meeded + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pszName == nullptr) + { + return E_INVALIDARG; + } + + SysFreeString(m_pszName); + m_pszName = SysAllocString(pszName); + if(m_pszName==nullptr) + return E_FAIL; + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** +* Set the accessible role of the current COM object self from UNO. +* @param pRole, the role value used to set the role of the current object. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccRole(unsigned short pRole) +{ + // internal IMAccessible - no mutex meeded + + m_iRole = pRole; + return S_OK; +} + +/** +* Add one state into the current state set for the current COM object from UNO. +* @param pXSate, the state used to set the name of the current object. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::DecreaseState(DWORD pXSate) +{ + // internal IMAccessible - no mutex meeded + + m_dState &= (~pXSate); + return S_OK; +} + +/** +* Delete one state into the current state set for the current COM object from UNO. +* @param pXSate, the state used to set the name of the current object. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::IncreaseState(DWORD pXSate) +{ + // internal IMAccessible - no mutex meeded + + m_dState |= pXSate; + return S_OK; +} + +/** +* Set state into the current state set for the current COM object from UNO. +* @param pXSate, the state used to set the name of the current object. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::SetState(DWORD pXSate) +{ + // internal IMAccessible - no mutex meeded + + m_dState = pXSate; + return S_OK; +} + +/** +* Set the accessible value of the current COM object self from UNO. +* @param pszAccValue, the name used to set the value of the current object. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccValue(const OLECHAR __RPC_FAR *pszAccValue) +{ + // internal IMAccessible - no mutex meeded + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pszAccValue == nullptr) + { + return E_INVALIDARG; + } + SysFreeString(m_pszValue); + m_pszValue = SysAllocString(pszAccValue); + if(m_pszValue==nullptr) + return E_FAIL; + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** +* Set the HWND value of the current COM object self from UNO. It should set the parent IAccessible +* Object through the method AccessibleObjectFromWindow(...). +* @param hwnd, the HWND used to set the value of the current object. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccWindowHandle(HWND hwnd) +{ + // internal IMAccessible - no mutex meeded + + try { + if (m_isDestroy) return S_FALSE; + m_hwnd = hwnd; + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** +* Set accessible focus by specifying child ID +* @param dChildID, the child id identifies the focus child. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccFocus(long dChildID) +{ + // internal IMAccessible - no mutex meeded + + try { + if (m_isDestroy) return S_FALSE; + + if(dChildID==CHILDID_SELF) + { + if(m_pIParent) + { + m_pIParent->Put_XAccFocus(m_dChildID); + } + } + else + { + m_dFocusChildID = dChildID; + //traverse all ancestors to set the focused child ID so that when the get_accFocus is called on + //any of the ancestors, this id can be used to get the IAccessible of focused object. + if(m_pIParent) + { + m_pIParent->Put_XAccFocus(dChildID); + } + } + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** +*Set accessible object location for the current COM object +* @param sLocation, the location of the current object. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccLocation(const Location sLocation) +{ + // internal IMAccessible - no mutex meeded + + this->m_sLocation = sLocation; + return S_OK; +} + +/** +* Set accessible parent object for the current COM object if +* the current object is a child of some COM object +* @param pIParent, the parent of the current object. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccParent(IMAccessible __RPC_FAR *pIParent) +{ + // internal IMAccessible - no mutex meeded + + this->m_pIParent = pIParent; + + if(pIParent) + m_pIParent->AddRef(); + + return S_OK; +} + +/** +* Set unique child id to COM +* @param dChildID, the id of the current object. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccChildID(long dChildID) +{ + // internal IMAccessible - no mutex meeded + + this->m_dChildID = dChildID; + return S_OK; +} + +/** +* Set AccObjectManagerAgent object pointer to COM +* @param pAgent, the AccObjectManagerAgent point. +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccAgent(hyper pAgent) +{ + // internal IMAccessible - no mutex meeded + + g_pAgent = reinterpret_cast<AccObjectManagerAgent*>(pAgent); + return S_OK; +} + +/** +* When a UNO control disposing, it disposes its listeners, +* then notify AccObject in bridge management, then notify +* COM that the XAccessible is invalid, so set m_xAccessible as NULL +* @return S_OK if successful and E_FAIL if failure. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::NotifyDestroy() +{ + // internal IMAccessible - no mutex meeded + + m_isDestroy = true; + m_xAccessible.clear(); + return S_OK; +} + +/** +*private methods that help implement public functions +*/ + +/** +* Return child interface pointer by child ID,note: need to call AddRef() +* @param lChildID, specify child index,which AT(such as Inspect32) gives. +* @return IMAccessible*, pointer to the corresponding child object. +*/ +IMAccessible* CMAccessible::GetChildInterface(long dChildID)//for test +{ + if(dChildID<0) + { + if(g_pAgent) + { + IMAccessible* pIMAcc = nullptr; + g_pAgent->GetIAccessibleFromResID(dChildID,&pIMAcc); + return pIMAcc; + } + return nullptr; + } + else + { + if (!m_xAccessible.is()) + return nullptr; + + Reference<XAccessibleContext> const pRContext = + m_xAccessible->getAccessibleContext(); + if( !pRContext.is() ) + return nullptr; + + if(dChildID<1 || dChildID>pRContext->getAccessibleChildCount()) + return nullptr; + + IAccessible* pChild = nullptr; + Reference< XAccessible > pXChild = pRContext->getAccessibleChild(dChildID-1); + bool isGet = get_IAccessibleFromXAccessible(pXChild.get(), &pChild); + + if(!isGet) + { + g_pAgent->InsertAccObj(pXChild.get(), m_xAccessible.get(), m_hwnd); + isGet = get_IAccessibleFromXAccessible(pXChild.get(), &pChild); + } + + if(isGet) + { + IMAccessible* pIMAcc = static_cast<IMAccessible*>(pChild); + return pIMAcc; + } + } + + return nullptr; +} + +/** +* for descendantmanager circumstance,provide child interface when navigate +* @param varCur, the current child. +* @param flags, the navigation direction. +* @return IMAccessible*, the child of the end up node. +*/ +IMAccessible* CMAccessible::GetNavigateChildForDM(VARIANT varCur, short flags) +{ + + XAccessibleContext* pXContext = GetContextByXAcc(m_xAccessible.get()); + if(pXContext==nullptr) + { + return nullptr; + } + + int count = pXContext->getAccessibleChildCount(); + if(count<1) + { + return nullptr; + } + + IMAccessible* pCurChild = nullptr; + union { + XAccessible* pChildXAcc; + hyper nHyper = 0; + }; + Reference<XAccessible> pRChildXAcc; + XAccessibleContext* pChildContext = nullptr; + int index = 0,delta=0; + switch(flags) + { + case DM_FIRSTCHILD: + pRChildXAcc = pXContext->getAccessibleChild(0); + break; + case DM_LASTCHILD: + pRChildXAcc = pXContext->getAccessibleChild(count-1); + break; + case DM_NEXTCHILD: + case DM_PREVCHILD: + pCurChild = GetChildInterface(varCur.lVal); + if(pCurChild==nullptr) + { + return nullptr; + } + pCurChild->GetUNOInterface(&nHyper); + if(pChildXAcc==nullptr) + { + return nullptr; + } + pChildContext = GetContextByXAcc(pChildXAcc); + if(pChildContext == nullptr) + { + return nullptr; + } + delta = (flags==DM_NEXTCHILD)?1:-1; + //currently, getAccessibleIndexInParent is error in UNO for + //some kind of List,such as ValueSet, the index will be less 1 than + //what should be, need to fix UNO code + index = pChildContext->getAccessibleIndexInParent()+delta; + if((index>=0)&&(index<=count-1)) + { + pRChildXAcc = pXContext->getAccessibleChild(index); + } + break; + default: + break; + } + + if(!pRChildXAcc.is()) + { + return nullptr; + } + pChildXAcc = pRChildXAcc.get(); + g_pAgent->InsertAccObj(pChildXAcc, m_xAccessible.get()); + return g_pAgent->GetIMAccByXAcc(pChildXAcc); +} + +/** +*the following 4 private methods are for accNavigate implementation +*/ + +/** +* Return first child for parent container, process differently according +* to whether it is descendant manage +* @param varStart, the start child id of this navigation action. +* @param pvarEndUpAt, [in,out] the end up child of this navigation action. +* @return S_OK if successful and E_FAIL if failure. +*/ +HRESULT CMAccessible::GetFirstChild(VARIANT varStart,VARIANT* pvarEndUpAt) +{ + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pvarEndUpAt == nullptr) + { + return E_INVALIDARG; + } + if(varStart.vt != VT_I4) + { + pvarEndUpAt->vt = VT_EMPTY; + return E_INVALIDARG; + } + + pvarEndUpAt->pdispVal = GetNavigateChildForDM(varStart, DM_FIRSTCHILD); + if(pvarEndUpAt->pdispVal) + { + pvarEndUpAt->pdispVal->AddRef(); + pvarEndUpAt->vt = VT_DISPATCH; + return S_OK; + } + + pvarEndUpAt->vt = VT_EMPTY; + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** +* Return last child for parent container, process differently according +* to whether it is descendant manage +* @param varStart, the start child id of this navigation action. +* @param pvarEndUpAt, [in,out] the end up child of this navigation action. +* @return S_OK if successful and E_FAIL if failure. +*/ +HRESULT CMAccessible::GetLastChild(VARIANT varStart,VARIANT* pvarEndUpAt) +{ + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pvarEndUpAt == nullptr) + { + return E_INVALIDARG; + } + if(varStart.vt != VT_I4) + { + pvarEndUpAt->vt = VT_EMPTY; + return E_INVALIDARG; + } + + pvarEndUpAt->pdispVal = GetNavigateChildForDM(varStart, DM_LASTCHILD); + if(pvarEndUpAt->pdispVal) + { + pvarEndUpAt->pdispVal->AddRef(); + pvarEndUpAt->vt = VT_DISPATCH; + return S_OK; + } + pvarEndUpAt->vt = VT_EMPTY; + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** +* The method GetNextSibling is general, whatever it is descendant manage or not +* Get the next sibling object. +* @param varStart, the start child id of this navigation action. +* @param pvarEndUpAt, [in,out] the end up child of this navigation action. +* @return S_OK if successful and E_FAIL if failure. +*/ +HRESULT CMAccessible::GetNextSibling(VARIANT varStart,VARIANT* pvarEndUpAt) +{ + + try { + if (m_isDestroy) return S_FALSE; + if(varStart.vt != VT_I4) + { + pvarEndUpAt->vt = VT_EMPTY; + return E_INVALIDARG; + } + + Reference<XAccessibleContext> const pRContext = + GetContextByXAcc(m_xAccessible.get()); + if(pRContext.is()) + { + varStart.iVal = sal_Int16(pRContext->getAccessibleIndexInParent() + 2); + if(m_pIParent) + if( m_pIParent->get_accChild(varStart,&pvarEndUpAt->pdispVal) == S_OK) + { + pvarEndUpAt->vt = VT_DISPATCH; + return S_OK; + } + } + pvarEndUpAt->vt = VT_EMPTY; + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** +*the method GetPreSibling is general, whatever it is descendant manage or not +* @param varStart, the start child id of this navigation action. +* @param pvarEndUpAt, [in,out] the end up child of this navigation action. +* @return S_OK if successful and E_FAIL if failure. +*/ +HRESULT CMAccessible::GetPreSibling(VARIANT varStart,VARIANT* pvarEndUpAt) +{ + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pvarEndUpAt == nullptr) + { + return E_INVALIDARG; + } + if(varStart.vt != VT_I4) + { + pvarEndUpAt->vt = VT_EMPTY; + return E_INVALIDARG; + } + + Reference<XAccessibleContext> const pRContext = + GetContextByXAcc(m_xAccessible.get()); + if(pRContext.is()) + { + varStart.iVal = sal_Int16(pRContext->getAccessibleIndexInParent()); + if(m_pIParent && varStart.iVal > 0) + if( m_pIParent->get_accChild(varStart,&pvarEndUpAt->pdispVal) == S_OK) + { + pvarEndUpAt->vt = VT_DISPATCH; + return S_OK; + } + } + pvarEndUpAt->vt = VT_EMPTY; + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +/** +* For IAccessible2 implementation methods +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_nRelations( long __RPC_FAR *nRelations) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + + // #CHECK# + if(nRelations == nullptr) + { + return E_INVALIDARG; + } + + *nRelations = 0; + + if (!m_xContext.is()) + return E_FAIL; + Reference<XAccessibleRelationSet> pRrelationSet = + m_xContext->getAccessibleRelationSet(); + if(!pRrelationSet.is()) + { + *nRelations = 0; + return S_OK; + } + + *nRelations = pRrelationSet->getRelationCount(); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_relation( long relationIndex, IAccessibleRelation __RPC_FAR *__RPC_FAR *relation) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(relation == nullptr) + { + return E_INVALIDARG; + } + + if (!m_xContext.is()) + return E_FAIL; + + + long nMax = 0; + get_nRelations(&nMax); + + *relation = static_cast<IAccessibleRelation*>(::CoTaskMemAlloc(sizeof(IAccessibleRelation))); + + // #CHECK Memory Allocation# + if(*relation == nullptr) + { + return E_FAIL; + } + + if( relationIndex < nMax ) + { + Reference<XAccessibleRelationSet> const pRrelationSet = + m_xContext->getAccessibleRelationSet(); + if(!pRrelationSet.is()) + { + + return E_FAIL; + } + + IAccessibleRelation* pRelation = nullptr; + HRESULT hr = createInstance<CAccRelation>(IID_IAccessibleRelation, + &pRelation); + if(SUCCEEDED(hr)) + { + IUNOXWrapper* wrapper = nullptr; + hr = pRelation->QueryInterface(IID_IUNOXWrapper, reinterpret_cast<void**>(&wrapper)); + if(SUCCEEDED(hr)) + { + AccessibleRelation accRelation = pRrelationSet->getRelation(relationIndex); + wrapper->put_XSubInterface( + reinterpret_cast<hyper>(&accRelation)); + wrapper->Release(); + *relation = pRelation; + return S_OK; + } + + } + } + + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_relations( long, IAccessibleRelation __RPC_FAR *__RPC_FAR *relation, long __RPC_FAR *nRelations) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + + // #CHECK# + if(relation == nullptr || nRelations == nullptr) + { + return E_INVALIDARG; + } + // #CHECK XInterface# + + if (!m_xContext.is()) + return E_FAIL; + + Reference<XAccessibleRelationSet> const pRrelationSet = + m_xContext->getAccessibleRelationSet(); + if(!pRrelationSet.is()) + { + *nRelations = 0; + return S_OK; + } + + long nCount = pRrelationSet->getRelationCount(); + + *relation = static_cast<IAccessibleRelation*>(::CoTaskMemAlloc(nCount*sizeof(IAccessibleRelation))); + + // #CHECK Memory Allocation# + if(*relation == nullptr) + { + return E_FAIL; + } + + for(int i=0; i<nCount ; i++) + { + IAccessibleRelation* pRelation = nullptr; + HRESULT hr = createInstance<CAccRelation>(IID_IAccessibleRelation, + &pRelation); + if(SUCCEEDED(hr)) + { + IUNOXWrapper* wrapper = nullptr; + hr = pRelation->QueryInterface(IID_IUNOXWrapper, reinterpret_cast<void**>(&wrapper)); + if(SUCCEEDED(hr)) + { + AccessibleRelation accRelation = pRrelationSet->getRelation(i); + wrapper->put_XSubInterface( + reinterpret_cast<hyper>(&accRelation)); + wrapper->Release(); + } + relation[i] = pRelation; + } + } + + *nRelations = nCount; + return S_OK; + + } catch(...) { return E_FAIL; } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::role(long __RPC_FAR *role) +{ + SolarMutexGuard g; + + try { + + (*role) = m_iRole; + + return S_OK; + + } catch(...) { return E_FAIL; } +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_nActions(long __RPC_FAR *nActions) +{ + SolarMutexGuard g; + + try + { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(nActions == nullptr) + { + return E_INVALIDARG; + } + *nActions = 0; + IAccessibleAction* pAcc = nullptr; + HRESULT hr = QueryInterface(IID_IAccessibleAction, reinterpret_cast<void**>(&pAcc)); + if( hr == S_OK ) + { + pAcc->nActions(nActions); + pAcc->Release(); + } + + return S_OK; + } + catch(...) + { + *nActions = 0; + return S_OK; + } +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::scrollToPoint(enum IA2CoordinateType, long, long) +{ + return E_NOTIMPL; +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::scrollTo(enum IA2ScrollType) +{ + return E_NOTIMPL; +} + +static XAccessible* getTheParentOfMember(XAccessible* pXAcc) +{ + // #CHECK# + if(pXAcc == nullptr) + { + return nullptr; + } + Reference<XAccessibleContext> pRContext = pXAcc->getAccessibleContext(); + Reference<XAccessibleRelationSet> pRrelationSet = pRContext->getAccessibleRelationSet(); + sal_Int32 nRelations = pRrelationSet->getRelationCount(); + for(sal_Int32 i=0 ; i<nRelations ; i++) + { + AccessibleRelation accRelation = pRrelationSet->getRelation(i); + if(accRelation.RelationType == 7) + { + Sequence< Reference< XInterface > > xTargets = accRelation.TargetSet; + return static_cast<XAccessible*>(xTargets[0].get()); + } + } + return nullptr; +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_groupPosition(long __RPC_FAR *groupLevel,long __RPC_FAR *similarItemsInGroup,long __RPC_FAR *positionInGroup) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(groupLevel == nullptr || similarItemsInGroup == nullptr || positionInGroup == nullptr) + { + return E_INVALIDARG; + } + + if (!m_xAccessible.is()) + return E_FAIL; + + Reference<XAccessibleContext> const pRContext = + m_xAccessible->getAccessibleContext(); + if(!pRContext.is()) + return E_FAIL; + long Role = pRContext->getAccessibleRole(); + + *groupLevel = 0; + *similarItemsInGroup = 0; + *positionInGroup = 0; + + if (Role != AccessibleRole::DOCUMENT && Role != AccessibleRole::DOCUMENT_PRESENTATION && + Role != AccessibleRole::DOCUMENT_SPREADSHEET && Role != AccessibleRole::DOCUMENT_TEXT) + { + Reference< XAccessibleGroupPosition > xGroupPosition( pRContext, UNO_QUERY ); + if ( xGroupPosition.is() ) + { + Sequence< sal_Int32 > rSeq = xGroupPosition->getGroupPosition( Any( pRContext ) ); + if (rSeq.getLength() >= 3) + { + *groupLevel = rSeq[0]; + *similarItemsInGroup = rSeq[1]; + *positionInGroup = rSeq[2]; + return S_OK; + } + return S_OK; + } + } + + Reference< XAccessible> pParentAcc = pRContext->getAccessibleParent(); + if( !pParentAcc.is() ) + { + return S_OK; + } + + Reference<XAccessibleContext> pRParentContext = pParentAcc->getAccessibleContext(); + + if( Role == RADIO_BUTTON ) + { + int index = 0; + int number = 0; + Reference<XAccessibleRelationSet> pRrelationSet = pRContext->getAccessibleRelationSet(); + long nRel = pRrelationSet->getRelationCount(); + for(int i=0 ; i<nRel ; i++) + { + AccessibleRelation accRelation = pRrelationSet->getRelation(i); + if(accRelation.RelationType == 7) + { + Sequence< Reference< XInterface > > xTargets = accRelation.TargetSet; + + Reference<XInterface> pRAcc = xTargets[0]; + for(int j=0; j<pRParentContext->getAccessibleChildCount(); j++) + { + if( getTheParentOfMember(pRParentContext->getAccessibleChild(j).get()) + == static_cast<XAccessible*>(pRAcc.get()) && + pRParentContext->getAccessibleChild(j)->getAccessibleContext()->getAccessibleRole() == RADIO_BUTTON) + number++; + if (pRParentContext->getAccessibleChild(j).get() == m_xAccessible.get()) + index = number; + } + } + } + *groupLevel = 1; + *similarItemsInGroup = number; + *positionInGroup = index; + return S_OK; + } + + else if ( COMBO_BOX == Role ) + { + *groupLevel = 1; + *similarItemsInGroup = 0; + *positionInGroup = -1; + + long nCount = pRContext->getAccessibleChildCount(); + if( 2 != nCount) + { + return S_OK; + } + Reference<XAccessible> xList=pRContext->getAccessibleChild(1); + if (!xList.is()) + { + return S_OK; + } + Reference<XAccessibleContext> xListContext(xList,UNO_QUERY); + if (!xListContext.is()) + { + return S_OK; + } + Reference<XAccessibleSelection> xListSel(xList,UNO_QUERY); + if (!xListSel.is()) + { + return S_OK; + } + *similarItemsInGroup = xListContext->getAccessibleChildCount(); + if (*similarItemsInGroup > 0 ) + { + try + { + Reference<XAccessible> xChild = xListSel->getSelectedAccessibleChild(0); + if (xChild.is()) + { + Reference<XAccessibleContext> xChildContext(xChild,UNO_QUERY); + if (xChildContext.is()) + { + *positionInGroup=xChildContext->getAccessibleIndexInParent() + 1 ; + return S_OK; + } + } + } + catch(...) + {} + } + return S_OK; + } + else if ( PAGE_TAB == Role ) + { + *groupLevel = 1; + *similarItemsInGroup = pRParentContext->getAccessibleChildCount(); + + if (*similarItemsInGroup > 0 ) + { + *positionInGroup=pRContext->getAccessibleIndexInParent() + 1 ; + } + else + { + *positionInGroup = -1; + } + return S_OK; + } + + int level = 0; + bool isFound = false; + while( pParentAcc.is() && !isFound) + { + level++; + pRParentContext = pParentAcc->getAccessibleContext(); + Role = pRParentContext->getAccessibleRole(); + if( (Role == TREE) || (Role == LIST) ) + isFound = true; + pParentAcc = pRParentContext->getAccessibleParent(); + } + + if( isFound ) + { + Reference< XAccessible> pTempAcc = pRContext->getAccessibleParent(); + pRParentContext = pTempAcc->getAccessibleContext(); + *groupLevel = level; + *similarItemsInGroup = pRParentContext->getAccessibleChildCount(); + *positionInGroup = pRContext->getAccessibleIndexInParent() + 1; + } + else + { + *groupLevel = 0; + *similarItemsInGroup = 0; + *positionInGroup = 0; + } + return S_OK; + + } catch(...) { return E_FAIL; } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_extendedStates(long, BSTR __RPC_FAR *__RPC_FAR *, long __RPC_FAR *) +{ + return E_NOTIMPL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_uniqueID(long __RPC_FAR *uniqueID) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(uniqueID == nullptr) + { + return E_INVALIDARG; + } + *uniqueID = m_dChildID; + return S_OK; + + } catch(...) { return E_FAIL; } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_windowHandle(HWND __RPC_FAR *windowHandle) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(windowHandle == nullptr) + { + return E_INVALIDARG; + } + + HWND nHwnd = m_hwnd; + IAccessible* pParent = m_pIParent; + while((nHwnd==nullptr) && pParent) + { + if (CMAccessible* pChild = dynamic_cast<CMAccessible*>(pParent)) + { + pParent = pChild->m_pIParent; + nHwnd = pChild->m_hwnd; + } + else + pParent = nullptr; + } + + *windowHandle = nHwnd; + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** +* Get XAccessibleContext directly from UNO by the stored XAccessible pointer +* @param pXAcc, UNO XAccessible object point. +* @return XAccessibleContext*, the context of the pXAcc. +*/ +XAccessibleContext* CMAccessible::GetContextByXAcc( XAccessible* pXAcc ) +{ + Reference< XAccessibleContext > pRContext; + if( pXAcc == nullptr) + return nullptr; + + pRContext = pXAcc->getAccessibleContext(); + if( !pRContext.is() ) + return nullptr; + return pRContext.get(); +} + +/** +* Return the member variable m_pXAccessibleSelection, instead of +* get XAccessibleSelection according to XAccessibleContext because if so,it will +* depend on the UNO implementation code,so when COM is created, put XAccessibleSelection +* by bridge management system +* @return XAccessibleSelection*, the selection of the current object. +*/ +Reference< XAccessibleSelection > CMAccessible::GetSelection() +{ + if (!m_xAccessible.is()) + return nullptr; + Reference<XAccessibleContext> const pRContext = + m_xAccessible->getAccessibleContext(); + if(pRContext.is()) + { + Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY); + return pRSelection; + } + return nullptr; +} + +/** +* Select one XAccessible item, for accSelect implementation +* @param pItem, the item should be selected. +* @return S_OK if successful. +*/ +HRESULT CMAccessible::SelectChild(XAccessible* pItem) +{ + + try { + if (m_isDestroy) return S_FALSE; + XAccessibleContext* pParentContext = GetContextByXAcc(m_xAccessible.get()); + XAccessibleContext* pContext = GetContextByXAcc( pItem ); + if( pParentContext == nullptr || pContext == nullptr ) + return E_FAIL; + + Reference< XAccessibleSelection > pRSelection = GetSelection(); + if( !pRSelection.is() ) + return E_FAIL; + long Index = pContext->getAccessibleIndexInParent(); + pRSelection->selectAccessibleChild( Index ); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** +* Deselect one XAccessible item, for accSelect implementation +* @param pItem, the item should be deselected. +* @return S_OK if successful. +*/ +HRESULT CMAccessible::DeSelectChild(XAccessible* pItem) +{ + + try { + if (m_isDestroy) return S_FALSE; + XAccessibleContext* pParentContext = GetContextByXAcc(m_xAccessible.get()); + ; + XAccessibleContext* pContext = GetContextByXAcc( pItem ); + if( pParentContext == nullptr || pContext == nullptr ) + return E_INVALIDARG; + + Reference< XAccessibleSelection > pRSelection = GetSelection(); + if( !pRSelection.is() ) + return E_FAIL; + long Index = pContext->getAccessibleIndexInParent(); + pRSelection->deselectAccessibleChild( Index ); + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** +* Select multiple XAccessible items,for implementation of accSelect +* @param pItem, the items should be selected. +* @param size, the size of the items. +* @return S_OK if successful. +*/ +HRESULT CMAccessible::SelectMultipleChidren( XAccessible** pItem,int size ) +{ + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pItem == nullptr) + { + return E_INVALIDARG; + } + for(int index = 0;index < size;index++) + { + SelectChild( pItem[index] ); + } + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** +* Deselect multiple XAccessible items,for implementation of accSelect +* @param pItem, the items should be selected. +* @param size, the size of the items. +* @return S_OK if successful. +*/ +HRESULT CMAccessible::DeSelectMultipleChildren( XAccessible** pItem,int size ) +{ + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pItem == nullptr) + { + return E_INVALIDARG; + } + for(int index = 0;index < size;index++) + { + DeSelectChild( pItem[index] ); + } + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** +* When COM is created, UNO set XAccessible pointer to it +* in order to COM can operate UNO information +* @param pXAcc, the XAccessible object of current object. +* @return S_OK if successful. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::SetXAccessible(hyper pXAcc) +{ + // internal IMAccessible - no mutex meeded + + m_xAccessible = reinterpret_cast<XAccessible*>(pXAcc); + m_pEnumVar->PutSelection(/*XAccessibleSelection*/ + reinterpret_cast<hyper>(m_xAccessible.get())); + + m_xContext = m_xAccessible->getAccessibleContext(); + + return S_OK; +} + +/** +* accSelect method has many optional flags, needs to process comprehensively +* Mozilla and Microsoft do not implement SELFLAG_EXTENDSELECTION flag. +* The implementation of this flag is a little trouble-shooting,so we also +* do not implement it now +* @param flagsSelect, the selection flag of the select action. +* @param varChild, the child object pointer of current action. +* @return S_OK if successful. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::accSelect(long flagsSelect, VARIANT varChild) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + if( (flagsSelect&SELFLAG_ADDSELECTION) && + (SELFLAG_REMOVESELECTION&flagsSelect) ) + return E_INVALIDARG; + + if ( (flagsSelect&SELFLAG_TAKESELECTION) && + ( + (flagsSelect&SELFLAG_ADDSELECTION) || + (flagsSelect&SELFLAG_REMOVESELECTION) || + (flagsSelect&SELFLAG_EXTENDSELECTION ) + ) + ) + return E_INVALIDARG; + + if ( varChild.vt != VT_I4 ) + return E_INVALIDARG; + + IMAccessible* pSelectAcc; + if( varChild.lVal == CHILDID_SELF ) + { + pSelectAcc = this; + pSelectAcc->AddRef(); + } + else + { + pSelectAcc = GetChildInterface(varChild.lVal); + } + + if( pSelectAcc == nullptr ) + return E_INVALIDARG; + + if( flagsSelect&SELFLAG_TAKEFOCUS ) + { + union { + XAccessible* pTempUNO; + hyper nHyper = 0; + }; + pSelectAcc->GetUNOInterface(&nHyper); + + if( pTempUNO == nullptr ) + return 0; + + Reference<XAccessibleContext> pRContext = pTempUNO->getAccessibleContext(); + Reference< XAccessibleComponent > pRComponent(pRContext,UNO_QUERY); + Reference< XAccessible > pRParentXAcc = pRContext->getAccessibleParent(); + Reference< XAccessibleContext > pRParentContext = pRParentXAcc->getAccessibleContext(); + Reference< XAccessibleComponent > pRParentComponent(pRParentContext,UNO_QUERY); + Reference< XAccessibleSelection > pRParentSelection(pRParentContext,UNO_QUERY); + + + pRComponent->grabFocus(); + + if( flagsSelect & SELFLAG_TAKESELECTION ) + { + pRParentSelection->clearAccessibleSelection(); + pRParentSelection->selectAccessibleChild( pRContext->getAccessibleIndexInParent() ); + } + + if( flagsSelect & SELFLAG_ADDSELECTION ) + { + pRParentSelection->selectAccessibleChild( pRContext->getAccessibleIndexInParent() ); + } + + if( flagsSelect & SELFLAG_REMOVESELECTION ) + { + pRParentSelection->deselectAccessibleChild( pRContext->getAccessibleIndexInParent() ); + } + + if( flagsSelect & SELFLAG_EXTENDSELECTION ) + { + long indexInParrent = pRContext->getAccessibleIndexInParent(); + + if( pRParentSelection->isAccessibleChildSelected( indexInParrent + 1 ) || + pRParentSelection->isAccessibleChildSelected( indexInParrent - 1 ) ) + { + pRParentSelection->selectAccessibleChild( indexInParrent ); + } + } + + } + + pSelectAcc->Release(); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +/** +* Return XAccessible interface pointer when needed +* @param pXAcc, [in, out] the Uno interface of the current object. +* @return S_OK if successful. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::GetUNOInterface(hyper * pXAcc) +{ + // internal IMAccessible - no mutex meeded + + if(pXAcc == nullptr) + return E_INVALIDARG; + + *pXAcc = reinterpret_cast<hyper>(m_xAccessible.get()); + return S_OK; +} + +/** +* Helper method for Implementation of get_accDefaultAction +* @param pAction, the default action point of the current object. +* @return S_OK if successful. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::SetDefaultAction(hyper pAction) +{ + // internal IMAccessible - no mutex meeded + + m_xAction = reinterpret_cast<XAccessibleAction*>(pAction); + return S_OK; +} + +/** +* This method is called when AT open some UI elements initially +* the UI element takes the default action defined here +* @param varChild, the child id of the defaultaction. +* @param pszDefaultAction,[in/out] the description of the current action. +* @return S_OK if successful. +*/ +COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE CMAccessible::get_accDefaultAction(VARIANT varChild, BSTR *pszDefaultAction) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(pszDefaultAction == nullptr) + { + return E_INVALIDARG; + } + if(varChild.vt==VT_I4) + { + if(varChild.lVal==CHILDID_SELF) + { + if (!m_xAction.is()) + return DISP_E_MEMBERNOTFOUND; + SysFreeString(*pszDefaultAction); + *pszDefaultAction = SysAllocString(m_pszActionDescription); + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->get_accDefaultAction(varChild,pszDefaultAction); + } + return S_FALSE; + + } catch(...) { return E_FAIL; } +} + +/** +* AT call this method to operate application +* @param varChild, the child id of the action object. +* @return S_OK if successful. +*/ +COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE CMAccessible::accDoDefaultAction(VARIANT varChild) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + if( varChild.vt != VT_I4 ) + return E_INVALIDARG; + if (!m_xAction.is()) + return E_FAIL; + if (m_xAction->getAccessibleActionCount() == 0) + return E_FAIL; + + if(varChild.lVal==CHILDID_SELF) + { + if (m_xAction->getAccessibleActionCount() > 0) + m_xAction->doAccessibleAction(0); + return S_OK; + } + + long lVal = varChild.lVal; + varChild.lVal = CHILDID_SELF; + IMAccessible *pChild = this->GetChildInterface(lVal); + if(!pChild) + return E_FAIL; + return pChild->accDoDefaultAction( varChild ); + + } catch(...) { return E_FAIL; } +} + +/** +* UNO set description information for action to COM. +* @param szAction, the action description of the current object. +* @return S_OK if successful. +*/ +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_ActionDescription( const OLECHAR* szAction) +{ + // internal IMAccessible - no mutex meeded + + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(szAction == nullptr) + { + return E_INVALIDARG; + } + SysFreeString(m_pszActionDescription ); + m_pszActionDescription = SysAllocString( szAction ); + return S_OK; + + } catch(...) { return E_FAIL; } +} + +bool CMAccessible::GetXInterfaceFromXAccessible(XAccessible* pXAcc, XInterface** ppXI, XInterfaceType eType) +{ + switch(eType) + { + case XInterfaceType::XI_COMPONENT: + return queryXInterface<XAccessibleComponent>(pXAcc, ppXI); + case XInterfaceType::XI_TEXT: + return queryXInterface<XAccessibleText>(pXAcc, ppXI); + case XInterfaceType::XI_EDITABLETEXT: + return queryXInterface<XAccessibleEditableText>(pXAcc, ppXI); + case XInterfaceType::XI_TABLE: + return queryXInterface<XAccessibleTable>(pXAcc, ppXI); + case XInterfaceType::XI_TABLECELL: + // needs specific handling, since there's no XInterface for table cells + return queryTableCell(pXAcc, ppXI); + case XInterfaceType::XI_SELECTION: + return queryXInterface<XAccessibleSelection>(pXAcc, ppXI); + case XInterfaceType::XI_EXTENDEDCOMP: + return queryXInterface<XAccessibleExtendedComponent>(pXAcc, ppXI); + case XInterfaceType::XI_KEYBINDING: + return queryXInterface<XAccessibleKeyBinding>(pXAcc, ppXI); + case XInterfaceType::XI_ACTION: + return queryXInterface<XAccessibleAction>(pXAcc, ppXI); + case XInterfaceType::XI_VALUE: + return queryXInterface<XAccessibleValue>(pXAcc, ppXI); + case XInterfaceType::XI_HYPERTEXT: + return queryXInterface<XAccessibleHypertext>(pXAcc, ppXI); + case XInterfaceType::XI_HYPERLINK: + return queryXInterface<XAccessibleHyperlink>(pXAcc, ppXI); + case XInterfaceType::XI_IMAGE: + return queryXInterface<XAccessibleImage>(pXAcc, ppXI); + default: + return false; + } +} + +template<typename T> static HRESULT +createAggInstance(CMAccessible &rOuter, void ** ppvObject) +{ + // Note: CComAggObject has special handling for IUnknown - must + // query for that when creating it! Otherwise we get a T member of it + // which will redirect QueryInterface back to CMAccessible infinitely. + // (CComAggObject has its own ref-count too which is not a problem + // since it is inserted in m_containedObjects.) + return CComCreator< CComAggObject<T> >::CreateInstance( + rOuter.GetControllingUnknown(), IID_IUnknown, ppvObject); +} + +typedef HRESULT (AggCreatorFunc)(CMAccessible &, void **); + +namespace { + +struct AggMapEntry +{ + const IID* piid; + AggCreatorFunc* pfnCreateInstance; + const XInterfaceType eXInterfaceType; +}; + +} + +static AggMapEntry g_CMAccessible_AggMap[] = { + { &IID_IAccessibleComponent, &createAggInstance<CAccComponent>, XInterfaceType::XI_COMPONENT }, + { &IID_IAccessibleText, &createAggInstance<CAccText>, XInterfaceType::XI_TEXT }, + { &IID_IAccessibleEditableText, &createAggInstance<CAccEditableText>, XInterfaceType::XI_EDITABLETEXT }, + { &IID_IAccessibleImage, &createAggInstance<CAccImage>, XInterfaceType::XI_IMAGE }, + { &IID_IAccessibleTable, &createAggInstance<CAccTable>, XInterfaceType::XI_TABLE }, + { &IID_IAccessibleTable2, &createAggInstance<CAccTable>, XInterfaceType::XI_TABLE }, + { &IID_IAccessibleTableCell, &createAggInstance<CAccTableCell>, XInterfaceType::XI_TABLECELL }, + { &IID_IAccessibleAction, &createAggInstance<CAccAction>, XInterfaceType::XI_ACTION }, + { &IID_IAccessibleValue, &createAggInstance<CAccValue>, XInterfaceType::XI_VALUE }, + { &IID_IAccessibleHypertext, &createAggInstance<CAccHypertext>, XInterfaceType::XI_HYPERTEXT }, + { &IID_IAccessibleHyperlink, &createAggInstance<CAccHyperLink>, XInterfaceType::XI_HYPERLINK } +}; + + +HRESULT WINAPI CMAccessible::SmartQI(void* /*pv*/, REFIID iid, void** ppvObject) +{ + try { + + if (m_isDestroy) return S_FALSE; + if (InlineIsEqualGUID(iid,IID_IAccIdentity) || + InlineIsEqualGUID(iid,IID_IStdMarshalInfo) || + InlineIsEqualGUID(iid,IID_IMarshal) || + InlineIsEqualGUID(iid,IID_IExternalConnection)|| + InlineIsEqualGUID(iid,IID_IOleWindow)) + { + return E_FAIL; + } + + for (const AggMapEntry& rEntry : g_CMAccessible_AggMap) + { + if (InlineIsEqualGUID(iid, *rEntry.piid)) + { + SolarMutexGuard g; + + XInterface* pXI = nullptr; + bool bFound = GetXInterfaceFromXAccessible(m_xAccessible.get(), + &pXI, rEntry.eXInterfaceType); + if(!bFound) + { + return E_FAIL; + } + + XGUIDToComObjHash::iterator pIndTemp = m_containedObjects.find( iid ); + if ( pIndTemp != m_containedObjects.end() ) + { + return pIndTemp->second.p->QueryInterface( iid, ppvObject ); + } + else + { + HRESULT hr = rEntry.pfnCreateInstance(*this, ppvObject); + assert(hr == S_OK); + if(hr == S_OK) + { + m_containedObjects.emplace(*rEntry.piid, static_cast<IUnknown*>(*ppvObject)); + IUNOXWrapper* wrapper = nullptr; + static_cast<IUnknown*>(*ppvObject)->QueryInterface(IID_IUNOXWrapper, reinterpret_cast<void**>(&wrapper)); + if(wrapper) + { + wrapper->put_XInterface( + reinterpret_cast<hyper>(m_xAccessible.get())); + wrapper->Release(); + } + return S_OK; + } + } + return E_FAIL; + } + } + return E_FAIL; + + } catch(...) { return E_FAIL; } +} + +bool CMAccessible::get_IAccessibleFromXAccessible(XAccessible* pXAcc, IAccessible** ppIA) +{ + try + { + // #CHECK# + if(ppIA == nullptr) + { + return false; + } + bool isGet = false; + if(g_pAgent) + isGet = g_pAgent->GetIAccessibleFromXAccessible(pXAcc, ppIA); + + return isGet; + } + catch(...) + { + return false; + } +} + +OUString CMAccessible::get_StringFromAny(Any const & pAny) +{ + switch(pAny.getValueTypeClass()) + { + case TypeClass_CHAR: + { + sal_Int8 val; + pAny >>= val; + return OUString::number(val); + } + case TypeClass_BOOLEAN: + { + bool val; + pAny >>= val; + return OUString::number(int(val)); + } + case TypeClass_BYTE: + { + sal_Int8 val; + pAny >>= val; + return OUString::number(val); + } + case TypeClass_SHORT: + { + sal_Int16 val; + pAny >>= val; + return OUString::number(val); + } + case TypeClass_UNSIGNED_SHORT: + { + sal_uInt16 val; + pAny >>= val; + return OUString::number(val); + } + case TypeClass_LONG: + { + sal_Int32 val; + pAny >>= val; + return OUString::number(val); + } + case TypeClass_UNSIGNED_LONG: + { + sal_uInt32 val; + pAny >>= val; + return OUString::number(val); + } + case TypeClass_FLOAT: + { + float val; + pAny >>= val; + return OUString::number(val); + } + case TypeClass_DOUBLE: + { + double val; + pAny >>= val; + return OUString::number(val); + } + case TypeClass_STRING: + { + OUString val; + pAny >>= val; + return val; + } + case TypeClass_SEQUENCE: + { + if(pAny.getValueType() == cppu::UnoType<Sequence< OUString >>::get()) + { + Sequence < OUString > val; + pAny >>= val; + + OUStringBuffer pString; + + for (const OUString& rElem : val) + pString.append(rElem); + + return pString.makeStringAndClear(); + } + else if (pAny.getValueType() == cppu::UnoType<Sequence< css::style::TabStop >>::get()) + { + Sequence < css::style::TabStop > val; + pAny >>= val; + + OUStringBuffer buf; + for (const css::style::TabStop& rSingleVal : val) + { + buf.append("Position="); + buf.append(rSingleVal.Position); + buf.append(",TabAlign="); + buf.append(sal_Int32(rSingleVal.Alignment)); + buf.append(","); + + buf.append("DecimalChar="); + if (rSingleVal.DecimalChar==';' || rSingleVal.DecimalChar == ':' || rSingleVal.DecimalChar == ',' || + rSingleVal.DecimalChar == '=' || rSingleVal.DecimalChar == '\\') + buf.append('\\'); + buf.append(rSingleVal.DecimalChar); + buf.append(","); + + buf.append("FillChar="); + if (rSingleVal.FillChar==';' || rSingleVal.FillChar == ':' || rSingleVal.FillChar == ',' || + rSingleVal.FillChar == '=' || rSingleVal.FillChar == '\\') + buf.append('\\'); + buf.append(rSingleVal.FillChar); + buf.append(","); + } + return buf.makeStringAndClear(); + } + break; + } + case TypeClass_ENUM: + { + if (pAny.getValueType() == cppu::UnoType<css::awt::FontSlant>::get()) + { + css::awt::FontSlant val; + pAny >>= val; + return OUString::number(sal_Int32(val)); + } + break; + } + case TypeClass_STRUCT: + { + if (pAny.getValueType() == cppu::UnoType<css::style::LineSpacing>::get()) + { + css::style::LineSpacing val; + pAny >>= val; + return "Mode=" + OUString::number(val.Mode) + ",Height=" + + OUString::number(val.Height) + ","; + } + else if (pAny.getValueType() == cppu::UnoType<css::accessibility::TextSegment>::get()) + { + css::accessibility::TextSegment val; + pAny >>= val; + return val.SegmentText; + } + break; + } + case TypeClass_VOID: + case TypeClass_HYPER: + case TypeClass_UNSIGNED_HYPER: + case TypeClass_TYPE: + case TypeClass_ANY: + case TypeClass_TYPEDEF: + case TypeClass_EXCEPTION: + case TypeClass_INTERFACE: + case TypeClass_SERVICE: + case TypeClass_MODULE: + case TypeClass_INTERFACE_METHOD: + case TypeClass_INTERFACE_ATTRIBUTE: + case TypeClass_UNKNOWN: + case TypeClass_PROPERTY: + case TypeClass_CONSTANT: + case TypeClass_CONSTANTS: + case TypeClass_SINGLETON: + break; + default: + break; + } + return OUString(); +} + +OUString CMAccessible::get_String4Numbering(const Any& pAny, sal_Int16 numberingLevel,std::u16string_view numberingPrefix) +{ + Reference< css::container::XIndexReplace > pXIndex; + if((pAny>>=pXIndex) && (numberingLevel !=-1))//numbering level is -1,means invalid value + { + Any aAny = pXIndex->getByIndex(numberingLevel); + Sequence< css::beans::PropertyValue > aProps; + aAny >>= aProps; + OUStringBuffer buf("Numbering:NumberingLevel="); + buf.append(sal_Int32(numberingLevel)); + buf.append(','); + for (const css::beans::PropertyValue& rProp : aProps) + { + if( (rProp.Name == "BulletChar" ) || + (rProp.Name == "NumberingType" )) + { + buf.append(rProp.Name); + buf.append('='); + auto const pTemp = CMAccessible::get_StringFromAny(rProp.Value); + buf.append(pTemp); + buf.append(','); + + if (rProp.Name == "NumberingType" && !numberingPrefix.empty()) + { + buf.append("NumberingPrefix="); + buf.append(numberingPrefix); + } + } + } + return buf.makeStringAndClear(); + } + + //Because now have three types numbering level: + //1.real numbering list,numbering level>=0 and numbering Rule !=NULL; + //2.common paragraph, numbering level >=0, and numbering Rule == NULL; + //3.TOC paragraph, numbering level >0, and numbering Rule ==NULL; + // IAText:numberinglevel base on 0, but TOC's level base on 1, + // so NumberingLevel value will be decreased 1 in bridge code. + else if(numberingLevel >0) + { + return "Numbering:NumberingLevel=" + OUString::number(numberingLevel-1) + ",NumberingType=4,NumberingPrefix=,"; + } + else + { + return "Numbering:"; + } +} + +void CMAccessible::ConvertAnyToVariant(const css::uno::Any &rAnyVal, VARIANT *pvData) +{ + if(rAnyVal.hasValue()) + { + // Clear VARIANT variable. + VariantClear(pvData); + + // Set value according to value type. + switch(rAnyVal.getValueTypeClass()) + { + case TypeClass_CHAR: + pvData->vt = VT_UI1; + memcpy(&pvData->bVal, rAnyVal.getValue(), sizeof(char)); + break; + + case TypeClass_BOOLEAN: + { + bool bBoolean(false); + rAnyVal >>= bBoolean; + pvData->vt = VT_BOOL; + pvData->boolVal = VARIANT_BOOL(bBoolean); // boolVal is a VARIANT_BOOL, a 16bit field + break; + } + case TypeClass_BYTE: + pvData->vt = VT_UI1; + memcpy(&pvData->bVal, rAnyVal.getValue(), sizeof(sal_Int8)); + break; + + case TypeClass_SHORT: + pvData->vt = VT_I2; + memcpy(&pvData->iVal, rAnyVal.getValue(), sizeof(sal_Int16)); + break; + + case TypeClass_UNSIGNED_SHORT: + pvData->vt = VT_I2; + memcpy(&pvData->iVal, rAnyVal.getValue(), sizeof(sal_uInt16)); + break; + + case TypeClass_LONG: + pvData->vt = VT_I4; + memcpy(&pvData->lVal, rAnyVal.getValue(), sizeof(sal_Int32)); + break; + + case TypeClass_UNSIGNED_LONG: + pvData->vt = VT_I4; + memcpy(&pvData->lVal, rAnyVal.getValue(), sizeof(sal_uInt32)); + break; + + case TypeClass_FLOAT: + pvData->vt = VT_R4; + memcpy(&pvData->fltVal, rAnyVal.getValue(), sizeof(float)); + break; + + case TypeClass_DOUBLE: + pvData->vt = VT_R8; + memcpy(&pvData->dblVal, rAnyVal.getValue(), sizeof(double)); + break; + + case TypeClass_STRING: + { + pvData->vt = VT_BSTR; + OUString val; + rAnyVal >>= val; + pvData->bstrVal = SysAllocString(o3tl::toW(val.getStr())); + break; + } + + case TypeClass_VOID: + case TypeClass_HYPER: + case TypeClass_UNSIGNED_HYPER: + case TypeClass_TYPE: + case TypeClass_ANY: + case TypeClass_ENUM: + case TypeClass_TYPEDEF: + case TypeClass_STRUCT: + case TypeClass_EXCEPTION: + case TypeClass_SEQUENCE: + case TypeClass_INTERFACE: + { + Reference< XAccessible > pXAcc; + if(rAnyVal >>= pXAcc) + { + if(pXAcc.is()) + { + IAccessible* pIAcc = nullptr; + get_IAccessibleFromXAccessible(pXAcc.get(), &pIAcc); + if(pIAcc == nullptr) + { + Reference< XAccessibleContext > pXAccContext = pXAcc->getAccessibleContext(); + g_pAgent->InsertAccObj(pXAcc.get(),pXAccContext->getAccessibleParent().get()); + get_IAccessibleFromXAccessible(pXAcc.get(), &pIAcc); + } + if(pIAcc) + { + pIAcc->AddRef(); + + pvData->vt = VT_UNKNOWN; + pvData->pdispVal = pIAcc; + break; + } + } + } + [[fallthrough]]; + } + case TypeClass_SERVICE: + case TypeClass_MODULE: + case TypeClass_INTERFACE_METHOD: + case TypeClass_INTERFACE_ATTRIBUTE: + case TypeClass_UNKNOWN: + case TypeClass_PROPERTY: + case TypeClass_CONSTANT: + case TypeClass_CONSTANTS: + case TypeClass_SINGLETON: + case TypeClass::TypeClass_MAKE_FIXED_SIZE: + // Output the type string, if there is other uno value type. + pvData->vt = VT_BSTR; + pvData->bstrVal = SysAllocString(o3tl::toW(rAnyVal.getValueTypeName().getStr())); + break; + + default: + break; + } + } + else + { + VariantClear(pvData); + } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_states(AccessibleStates __RPC_FAR *states) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + + if (!m_xContext.is()) + return E_FAIL; + + Reference<XAccessibleStateSet> const pRStateSet = + m_xContext->getAccessibleStateSet(); + if(!pRStateSet.is()) + { + return S_OK; + } + Sequence<short> pStates = pRStateSet->getStates(); + + + long count = pStates.getLength() ; + *states = 0x0; + for( int i = 0; i < count; i++ ) + { + for( std::size_t j = 0; j < SAL_N_ELEMENTS(UNO_STATES); j++ ) + { + if( pStates[i] == UNO_STATES[j] ) + { + *states |= IA2_STATES[j]; + break; + } + } + } + return S_OK; + + + } catch(...) { return E_FAIL; } +} + +// return the UNO roles +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_extendedRole(BSTR __RPC_FAR *) +{ + return E_NOTIMPL; +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_localizedExtendedRole(BSTR __RPC_FAR *) +{ + return E_NOTIMPL; +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_nExtendedStates(long __RPC_FAR *) +{ + return E_NOTIMPL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_localizedExtendedStates(long, BSTR __RPC_FAR *__RPC_FAR *, long __RPC_FAR *) +{ + return E_NOTIMPL; +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_indexInParent(long __RPC_FAR *accParentIndex) +{ + try { + if (m_isDestroy) return S_FALSE; + // #CHECK# + if(accParentIndex == nullptr) + return E_INVALIDARG; + + if (!m_xContext.is()) + return E_FAIL; + + *accParentIndex = m_xContext->getAccessibleIndexInParent(); + return S_OK; + + + } catch(...) { return E_FAIL; } +} +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_locale( IA2Locale __RPC_FAR *locale ) +{ + try { + if (m_isDestroy) return S_FALSE; + if(locale == nullptr) + return E_INVALIDARG; + + if (!m_xContext.is()) + return E_FAIL; + + css::lang::Locale unoLoc = m_xContext->getLocale(); + locale->language = SysAllocString(o3tl::toW(unoLoc.Language.getStr())); + locale->country = SysAllocString(o3tl::toW(unoLoc.Country.getStr())); + locale->variant = SysAllocString(o3tl::toW(unoLoc.Variant.getStr())); + + return S_OK; + + } catch(...) { return E_FAIL; } +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_appName(BSTR __RPC_FAR *name) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + if(name == nullptr) + return E_INVALIDARG; + + *name = SysAllocString(OLESTR("Hannover")); + return S_OK; + } catch(...) { return E_FAIL; } +} +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_appVersion(BSTR __RPC_FAR *version) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + if(version == nullptr) + return E_INVALIDARG; + *version=SysAllocString(OLESTR("3.0")); + return S_OK; + } catch(...) { return E_FAIL; } +} +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_toolkitName(BSTR __RPC_FAR *name) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + if(name == nullptr) + return E_INVALIDARG; + *name = SysAllocString(OLESTR(" ")); + return S_OK; + } catch(...) { return E_FAIL; } +} +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_toolkitVersion(BSTR __RPC_FAR *version) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + if(version == nullptr) + return E_INVALIDARG; + *version = SysAllocString(OLESTR(" ")); + return S_OK; + } catch(...) { return E_FAIL; } +} + + +COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_attributes(/*[out]*/ BSTR *pAttr) +{ + SolarMutexGuard g; + + try { + if (m_isDestroy) return S_FALSE; + + if (!m_xAccessible.is()) + return E_FAIL; + + Reference<XAccessibleContext> pRContext = m_xAccessible->getAccessibleContext(); + if( !pRContext.is() ) + { + return E_FAIL; + } + Reference<XAccessibleExtendedAttributes> pRXI(pRContext,UNO_QUERY); + if( !pRXI.is() ) + return E_FAIL; + else + { + css::uno::Reference<css::accessibility::XAccessibleExtendedAttributes> pRXAttr; + pRXAttr = pRXI.get(); + css::uno::Any anyVal = pRXAttr->getExtendedAttributes(); + + OUString val; + anyVal >>= val; + + if(*pAttr) + SysFreeString(*pAttr); + *pAttr = SysAllocString(o3tl::toW(val.getStr())); + + return S_OK; + } + } catch(...) { return E_FAIL; } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/MAccessible.h b/winaccessibility/source/UAccCOM/MAccessible.h new file mode 100644 index 000000000..5d18d74ab --- /dev/null +++ b/winaccessibility/source/UAccCOM/MAccessible.h @@ -0,0 +1,242 @@ +/* -*- 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 "stdafx.h" +#include "Resource.h" // main symbols +#include <map> +#include <string_view> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <AccObjectManagerAgent.hxx> +#include "EnumVariant.h" +#include "acccommon.h" +#include <rtl/ustring.hxx> + +namespace { +enum class XInterfaceType; +} + +/** + *This class implements IMAccessible interface, which inherits from IAccessible2, and + *in turn inherits from IAccessible. So its methods include the methods defined only in + *IAccessible, plus the methods defined only in IAccessible2, plus the methods defined + *only in IMAccessible. + */ +class ATL_NO_VTABLE CMAccessible : + public CComObjectRoot, + public CComCoClass<CMAccessible, &CLSID_MAccessible>, + public IDispatchImpl<IMAccessible, &IID_IMAccessible, &LIBID_UACCCOMLib>, + public IServiceProvider, + public IAccessibleApplication +{ + typedef ::std::map<const GUID, CComPtr<IUnknown>, ltComp> XGUIDToComObjHash; + +public: + CMAccessible(); + virtual ~CMAccessible(); + + DECLARE_NO_REGISTRY() + + DECLARE_GET_CONTROLLING_UNKNOWN() + + DECLARE_PROTECT_FINAL_CONSTRUCT() + + BEGIN_COM_MAP(CMAccessible) + COM_INTERFACE_ENTRY(IMAccessible) + COM_INTERFACE_ENTRY(IAccessible) + COM_INTERFACE_ENTRY(IAccessible2) + COM_INTERFACE_ENTRY(IDispatch) + COM_INTERFACE_ENTRY(IAccessibleApplication) + COM_INTERFACE_ENTRY(IServiceProvider) + COM_INTERFACE_ENTRY_FUNC_BLIND(0,SmartQI_) +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + END_COM_MAP() +#if defined __clang__ +#pragma clang diagnostic pop +#endif + + // IMAccessible + STDMETHOD(put_accValue)(VARIANT varChild,BSTR szValue) override; + STDMETHOD(put_accName)(VARIANT varChild,BSTR szName) override; + STDMETHOD(accDoDefaultAction)(VARIANT varChild) override; + STDMETHOD(accHitTest)(long xLeft,long yTop,VARIANT *pvarChild) override; + STDMETHOD(accNavigate)(long navDir,VARIANT varStart,VARIANT *pvarEndUpAt) override; + STDMETHOD(accLocation)(long *pxLeft,long *pyTop,long *pcxWidth,long *pcyHeight,VARIANT varChild) override; + STDMETHOD(accSelect)(long flagsSelect,VARIANT varChild) override; + STDMETHOD(get_accDefaultAction)( VARIANT varChild,BSTR *pszDefaultAction) override; + STDMETHOD(get_accSelection)(VARIANT *pvarChildren) override; + STDMETHOD(get_accFocus)(VARIANT *pvarChild) override; + STDMETHOD(get_accKeyboardShortcut)( VARIANT varChild,BSTR *pszKeyboardShortcut) override; + STDMETHOD(get_accHelpTopic)(BSTR *pszHelpFile,VARIANT varChild,long *pidTopic) override; + STDMETHOD(get_accHelp)(VARIANT varChild,BSTR *pszHelp) override; + STDMETHOD(get_accState)(VARIANT varChild,VARIANT *pvarState) override; + STDMETHOD(get_accRole)(VARIANT varChild,VARIANT *pvarRole) override; + STDMETHOD(get_accDescription)(VARIANT varChild,BSTR *pszDescription) override; + STDMETHOD(get_accValue)( VARIANT varChild,BSTR *pszValue) override; + STDMETHOD(get_accName)(VARIANT varChild,BSTR *pszName) override; + STDMETHOD(get_accChild)(VARIANT varChild,IDispatch **ppdispChild) override; + STDMETHOD(get_accChildCount)(long *pcountChildren) override; + STDMETHOD(get_accParent)( IDispatch **ppdispParent) override; + + // methods which are defined only in the IAccessible2 + // These methods only declare here, and their implementation bodies are empty now. + STDMETHOD(get_nRelations)( long __RPC_FAR *nRelations) override; + STDMETHOD(get_relation)( long relationIndex, IAccessibleRelation __RPC_FAR *__RPC_FAR *relation) override; + STDMETHOD(get_relations)( long maxRelations, IAccessibleRelation __RPC_FAR *__RPC_FAR *relation, long __RPC_FAR *nRelations) override; + STDMETHOD(role)(long __RPC_FAR *role) override; + STDMETHOD(get_nActions)(long __RPC_FAR *nActions); + STDMETHOD(scrollTo)(enum IA2ScrollType scrollType) override; + STDMETHOD(scrollToPoint)(enum IA2CoordinateType coordinateType, long x, long y) override; + STDMETHOD(get_groupPosition)(long __RPC_FAR *groupLevel,long __RPC_FAR *similarItemsInGroup,long __RPC_FAR *positionInGroup) override; + STDMETHOD(get_states)( AccessibleStates __RPC_FAR *states ) override; + STDMETHOD(get_extendedRole)( BSTR __RPC_FAR *extendedRole ) override; + STDMETHOD(get_localizedExtendedRole)( BSTR __RPC_FAR *localizedExtendedRole ) override; + STDMETHOD(get_nExtendedStates)( long __RPC_FAR *nExtendedStates) override; + STDMETHOD(get_extendedStates)( long maxExtendedStates, BSTR __RPC_FAR *__RPC_FAR *extendedStates, long __RPC_FAR *nExtendedStates) override; + STDMETHOD(get_localizedExtendedStates)(long maxLocalizedExtendedStates,BSTR __RPC_FAR *__RPC_FAR *localizedExtendedStates,long __RPC_FAR *nLocalizedExtendedStates) override; + STDMETHOD(get_uniqueID)(long __RPC_FAR *uniqueID) override; + STDMETHOD(get_windowHandle)(HWND __RPC_FAR *windowHandle) override; + STDMETHOD(get_indexInParent)( long __RPC_FAR *accParentIndex ) override; + STDMETHOD(get_locale)( IA2Locale __RPC_FAR *locale ) override; + STDMETHOD(get_attributes)(/*[out]*/ BSTR *pAttr) override; + + //IServiceProvider. + STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void** ppvObject) override; + + //IAccessibleApplication + STDMETHOD(get_appName)(BSTR __RPC_FAR *name) override; + STDMETHOD(get_appVersion)(BSTR __RPC_FAR *version) override; + STDMETHOD(get_toolkitName)(BSTR __RPC_FAR *name) override; + STDMETHOD(get_toolkitVersion)(BSTR __RPC_FAR *version) override; + + // methods which are defined only in IMAccessible + // These methods are provided for UNO management system. + // The UNO management system use these methods to put Accessibility + // information to COM. + STDMETHOD(Put_XAccName)(const OLECHAR __RPC_FAR *pszName) override; + STDMETHOD(Put_XAccRole)(unsigned short pRole) override; + STDMETHOD(DecreaseState)(DWORD pXSate) override; + STDMETHOD(IncreaseState)(DWORD pXSate) override; + STDMETHOD(SetState)(DWORD pXSate) override; + STDMETHOD(Put_XAccValue)(const OLECHAR __RPC_FAR *pszAccValue) override; + STDMETHOD(Put_XAccLocation)(const Location sLocation) override; + STDMETHOD(Put_XAccFocus)(long dChildID) override; + STDMETHOD(Put_XAccParent)(IMAccessible __RPC_FAR *pIParent) override; + STDMETHOD(Put_XAccWindowHandle)(HWND hwnd) override; + STDMETHOD(Put_XAccChildID)(long dChildID) override; + STDMETHOD(Put_XAccAgent)(hyper pAgent) override; + STDMETHOD(NotifyDestroy)() override; + STDMETHOD(Put_ActionDescription)( const OLECHAR* szAction) override; + STDMETHOD(SetDefaultAction)(hyper pAction) override; + STDMETHOD(GetUNOInterface)(hyper*) override; + STDMETHOD(SetXAccessible)(hyper) override; + +private: + BSTR m_pszName; + BSTR m_pszValue; + BSTR m_pszActionDescription; + unsigned short m_iRole; + DWORD m_dState; + IMAccessible* m_pIParent; + Location m_sLocation; + + // identify a COM object/Acc object uniquely + long m_dChildID; + // specify the focus child ID in object self and its direct children + + long m_dFocusChildID; + // parent window handle,will be used in the future application, its value comes from UNO + + HWND m_hwnd; + + // the COM class which implements IEnumVARIANT interface,currently only used in + // the implementation of get_accSelection + CEnumVariant* m_pEnumVar; + + // specify if the XAccessible is invalid + bool m_isDestroy; + + css::uno::Reference<css::accessibility::XAccessible> m_xAccessible; + // initially m_xAction and m_xContext are the same object + // but they may be different once AccObject::UpdateAction() is called? + css::uno::Reference<css::accessibility::XAccessibleAction> m_xAction; + css::uno::Reference<css::accessibility::XAccessibleContext> m_xContext; + +private: + + // the helper methods in order to implement the above public methods + IMAccessible* GetChildInterface(long dChildIndex);//notice here the parameter is child index,not child id + IMAccessible* GetNavigateChildForDM(VARIANT varCur,short flags);//for descendant manage + HRESULT GetFirstChild(VARIANT varStart,VARIANT* pvarEndUpAt);//for accNavigate implementation + HRESULT GetLastChild(VARIANT varStart,VARIANT* pvarEndUpAt);//for accNavigate implementation + HRESULT GetNextSibling(VARIANT varStart,VARIANT* pvarEndUpAt);//for accNavigate implementation + HRESULT GetPreSibling(VARIANT varStart,VARIANT* pvarEndUpAt);//for accNavigate implementation + + // the following private methods are used to implement accSelect method + HRESULT SelectChild(css::accessibility::XAccessible* pItem); + HRESULT DeSelectChild(css::accessibility::XAccessible* pItem); + HRESULT SelectMultipleChidren(css::accessibility::XAccessible** pItem, + int size); + HRESULT DeSelectMultipleChildren(css::accessibility::XAccessible** pItem, + int size); + static css::accessibility::XAccessibleContext* GetContextByXAcc( + css::accessibility::XAccessible* pXAcc); + css::uno::Reference<css::accessibility::XAccessibleSelection> GetSelection(); + // end accSelect implementation methods + static bool GetXInterfaceFromXAccessible(css::accessibility::XAccessible*, + css::uno::XInterface**, XInterfaceType); + HRESULT WINAPI SmartQI(void* pv, REFIID iid, void** ppvObject); + +public: + // AccObjectManagerAgent is a management object in UNO, here keep its pointer for + // the implementation of accNavigate when descendant manage happens for List,Tree, or Table + // AccObjectManagerAgent and the following UNO objects XAccessible,XAccessibleSelection, + // XAccessibleAction are all used to operate UNO accessibility information directly when + // implement some specific MSAA methods,such as accSelection,accNavigate + static AccObjectManagerAgent* g_pAgent; + + static bool get_IAccessibleFromXAccessible( + css::accessibility::XAccessible * pXAcc, IAccessible** ppIA); + XGUIDToComObjHash m_containedObjects; + + static HRESULT WINAPI SmartQI_(void* pv, + REFIID iid, void** ppvObject, DWORD_PTR) + { + return static_cast<CMAccessible*>(pv)->SmartQI(pv,iid,ppvObject); + } + + static OUString get_StringFromAny(css::uno::Any const & pAny); + + static OUString get_String4Numbering(const css::uno::Any& pAny, + sal_Int16 numberingLevel, std::u16string_view numberingPrefix); + + // Helper function for data conversion. + static void ConvertAnyToVariant(const css::uno::Any &rAnyVal, + VARIANT *pvData); +}; + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/Resource.h b/winaccessibility/source/UAccCOM/Resource.h new file mode 100644 index 000000000..d8abe9bcc --- /dev/null +++ b/winaccessibility/source/UAccCOM/Resource.h @@ -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 . + */ + +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by UAccCOM.rc + + +#define IDS_PROJNAME 100 + +// Next default values for new objects + +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 203 +#define _APS_NEXT_COMMAND_VALUE 32768 +#define _APS_NEXT_CONTROL_VALUE 201 +#define _APS_NEXT_SYMED_VALUE 137 +#endif +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/StdAfx.cxx b/winaccessibility/source/UAccCOM/StdAfx.cxx new file mode 100644 index 000000000..71ebbdb6b --- /dev/null +++ b/winaccessibility/source/UAccCOM/StdAfx.cxx @@ -0,0 +1,26 @@ +/* -*- 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 "stdafx.h" + +#ifdef _ATL_STATIC_REGISTRY +#include <statreg.h> +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/UAccCOM.cxx b/winaccessibility/source/UAccCOM/UAccCOM.cxx new file mode 100644 index 000000000..944db5c94 --- /dev/null +++ b/winaccessibility/source/UAccCOM/UAccCOM.cxx @@ -0,0 +1,117 @@ +/* -*- 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 "stdafx.h" +#include "Resource.h" +#include <initguid.h> +#include <accHelper.hxx> + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored \ + "-Wextra-tokens" // "#endif !_MIDL_USE_GUIDDEF_" in midl-generated code +#endif +#include <UAccCOM_i.c> +#include <ia2_api_all_i.c> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +#include "MAccessible.h" +#include "EnumVariant.h" +#include "UNOXWrapper.h" +#include "AccComponent.h" +#include "AccRelation.h" +#include "AccAction.h" +#include "AccText.h" +#include "AccEditableText.h" +#include "AccImage.h" +#include "AccValue.h" +#include "AccTable.h" +#include "AccTableCell.h" +#include "AccHyperLink.h" +#include "AccHypertext.h" + +CComModule _Module; + +BEGIN_OBJECT_MAP(ObjectMap) +OBJECT_ENTRY(CLSID_MAccessible, CMAccessible) +OBJECT_ENTRY(CLSID_EnumVariant, CEnumVariant) +OBJECT_ENTRY(CLSID_AccComponent, CAccComponent) +OBJECT_ENTRY(CLSID_AccRelation, CAccRelation) +OBJECT_ENTRY(CLSID_AccAction, CAccAction) +OBJECT_ENTRY(CLSID_AccText, CAccText) +OBJECT_ENTRY(CLSID_AccEditableText, CAccEditableText) +OBJECT_ENTRY(CLSID_AccImage, CAccImage) +OBJECT_ENTRY(CLSID_AccValue, CAccValue) +OBJECT_ENTRY(CLSID_AccTable, CAccTable) +OBJECT_ENTRY(CLSID_AccTableCell, CAccTableCell) +OBJECT_ENTRY(CLSID_AccHyperLink, CAccHyperLink) +OBJECT_ENTRY(CLSID_AccHypertext, CAccHypertext) +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-field-initializers" +#endif +END_OBJECT_MAP() +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +// DLL Entry Point + +extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + _Module.Init(ObjectMap, hInstance, &LIBID_UACCCOMLib); + DisableThreadLibraryCalls(hInstance); + } + else if (dwReason == DLL_PROCESS_DETACH) + _Module.Term(); + return TRUE; // ok +} + +// Used to determine whether the DLL can be unloaded by OLE + +STDAPI DllCanUnloadNow() { return (_Module.GetLockCount() == 0) ? S_OK : E_FAIL; } + +// Returns a class factory to create an object of the requested type + +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) +{ + return _Module.GetClassObject(rclsid, riid, ppv); +} + +IMAccessible* UAccCOMCreateInstance() +{ + IMAccessible* pIMA = nullptr; + HRESULT hr = createInstance<CMAccessible>(IID_IMAccessible, &pIMA); + return (S_OK == hr) ? pIMA : nullptr; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/UAccCOM.def b/winaccessibility/source/UAccCOM/UAccCOM.def new file mode 100644 index 000000000..45baa527b --- /dev/null +++ b/winaccessibility/source/UAccCOM/UAccCOM.def @@ -0,0 +1,5 @@ +LIBRARY "UAccCOM.DLL" + +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE diff --git a/winaccessibility/source/UAccCOM/UAccCOM.rc b/winaccessibility/source/UAccCOM/UAccCOM.rc new file mode 100644 index 000000000..d81746ed3 --- /dev/null +++ b/winaccessibility/source/UAccCOM/UAccCOM.rc @@ -0,0 +1,90 @@ +/* + * 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 . + */ + +//Microsoft Developer Studio generated resource script. + +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS + + +// Generated from the TEXTINCLUDE 2 resource. + +#include "winres.h" + + +#undef APSTUDIO_READONLY_SYMBOLS + + +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED + + +// TEXTINCLUDE + + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "1 TYPELIB ""UAccCOM.tlb""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +// String Table + + +STRINGTABLE DISCARDABLE +BEGIN + IDS_PROJNAME "UAccCOM" +END + +#endif // English (U.S.) resources + + + + +#ifndef APSTUDIO_INVOKED + + +// Generated from the TEXTINCLUDE 3 resource. + +1 TYPELIB "UAccCOM.tlb" + + +#endif // not APSTUDIO_INVOKED + diff --git a/winaccessibility/source/UAccCOM/UNOXWrapper.cxx b/winaccessibility/source/UAccCOM/UNOXWrapper.cxx new file mode 100644 index 000000000..c009a005e --- /dev/null +++ b/winaccessibility/source/UAccCOM/UNOXWrapper.cxx @@ -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 . + */ + +#include "UNOXWrapper.h" + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +using namespace ::com::sun::star; + +// CUNOXWrapper + +COM_DECLSPEC_NOTHROW STDMETHODIMP CUNOXWrapper::put_XInterface(hyper nXInterface) +{ + pUNOInterface = reinterpret_cast<accessibility::XAccessible*>(nXInterface); + return S_OK; +} + +COM_DECLSPEC_NOTHROW STDMETHODIMP CUNOXWrapper::put_XSubInterface(hyper) { return S_OK; } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/UNOXWrapper.h b/winaccessibility/source/UAccCOM/UNOXWrapper.h new file mode 100644 index 000000000..42983f88a --- /dev/null +++ b/winaccessibility/source/UAccCOM/UNOXWrapper.h @@ -0,0 +1,58 @@ +/* -*- 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 "stdafx.h" +#include "Resource.h" // main symbols + +#include <com/sun/star/accessibility/XAccessible.hpp> + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +/** + * CUNOXWrapper implements IUNOXWrapper interface. + */ +class ATL_NO_VTABLE CUNOXWrapper : public IUNOXWrapper +{ +protected: + css::accessibility::XAccessible* pUNOInterface; + +public: + CUNOXWrapper() + : pUNOInterface(nullptr) + { + } + + // IUNOXWrapper + STDMETHOD(put_XInterface)(hyper pXInterface) override; + STDMETHOD(put_XSubInterface)(hyper) override; + +protected: + ~CUNOXWrapper() {} +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/acccommon.h b/winaccessibility/source/UAccCOM/acccommon.h new file mode 100644 index 000000000..d2dffc5e6 --- /dev/null +++ b/winaccessibility/source/UAccCOM/acccommon.h @@ -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 + +//for MAccessible.cxx +struct ltComp +{ + bool operator()(REFGUID rguid1, REFGUID rguid2) const + { + if(reinterpret_cast<LONG const *>(&rguid1)[0] < reinterpret_cast<LONG const *>(&rguid2)[0]) + return true; + else if(reinterpret_cast<LONG const *>(&rguid1)[0] > reinterpret_cast<LONG const *>(&rguid2)[0]) + return false; + if(reinterpret_cast<LONG const *>(&rguid1)[1] < reinterpret_cast<LONG const *>(&rguid2)[1]) + return true; + else if(reinterpret_cast<LONG const *>(&rguid1)[1] > reinterpret_cast<LONG const *>(&rguid2)[1]) + return false; + if(reinterpret_cast<LONG const *>(&rguid1)[2] < reinterpret_cast<LONG const *>(&rguid2)[2]) + return true; + else if(reinterpret_cast<LONG const *>(&rguid1)[2] > reinterpret_cast<LONG const *>(&rguid2)[2]) + return false; + if(reinterpret_cast<LONG const *>(&rguid1)[3] < reinterpret_cast<LONG const *>(&rguid2)[3]) + return true; + else if(reinterpret_cast<LONG const *>(&rguid1)[3] > reinterpret_cast<LONG const *>(&rguid2)[3]) + return false; + return false; + } +}; + +enum DM_NIR { + DM_FIRSTCHILD = 0x00, + DM_LASTCHILD = 0x01, + DM_NEXTCHILD = 0x02, + DM_PREVCHILD = 0x03 +}; + + +#define SELECT_STR L"Select" +#define PRESS_STR L"Press" +#define UNCHECK_STR L"UnCheck" +#define CHECK_STR L"Check" +//End + +template<typename T, typename Ifc> HRESULT +createInstance(REFIID iid, Ifc ** ppIfc) +{ + return + CComCreator< CComObject<T> >::CreateInstance(nullptr, iid, reinterpret_cast<void**>(ppIfc)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOM/stdafx.h b/winaccessibility/source/UAccCOM/stdafx.h new file mode 100644 index 000000000..53044645f --- /dev/null +++ b/winaccessibility/source/UAccCOM/stdafx.h @@ -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 . + */ + +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, +// but are changed infrequently + +#pragma once + +#pragma once + +// this turns off ATL's locking in the COM component implementations +// (we don't need it since we use SolarMutex instead) +#define _ATL_APARTMENT_THREADED + +#include <prewin.h> +#if !defined WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wall" +#pragma clang diagnostic ignored "-Wattributes" +#pragma clang diagnostic ignored "-Wdelete-incomplete" +#pragma clang diagnostic ignored "-Wextra" +#pragma clang diagnostic ignored "-Wint-to-pointer-cast" +#pragma clang diagnostic ignored "-Winvalid-noreturn" +#pragma clang diagnostic ignored "-Wmicrosoft" +#pragma clang diagnostic ignored "-Wnon-pod-varargs" +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <atlbase.h> +// You may derive a class from CComModule and use it if you want to override +// something, but do not change the name of _Module +extern CComModule _Module; +#include <atlcom.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif +#include <postwin.h> +#undef OPAQUE + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOMIDL/AccessibleKeyBinding.idl b/winaccessibility/source/UAccCOMIDL/AccessibleKeyBinding.idl new file mode 100644 index 000000000..91d17de05 --- /dev/null +++ b/winaccessibility/source/UAccCOMIDL/AccessibleKeyBinding.idl @@ -0,0 +1,60 @@ +/* -*- 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 . + */ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; +import "AccessibleKeyStroke.idl"; + +[object, uuid(6B1923AC-3E9A-4336-99E1-A69EA4E946E9)] +interface IAccessibleKeyBinding : IUnknown +{ + // get number of key bindings for this object + [propget] HRESULT nKeyBindings + ( + [out, retval] long *nKeyBindings + ); + + // get length of keystroke sequence for specified key binding + [propget] HRESULT keyStrokeSequenceLength + ( + [in] long keyBindingIndex, + [out] long *sequenceLength + ); + + // The returned sequence of key strokes describes one method + // to invoke the associated action (the one from which you + // obtained the object at which you called this method) by + // pressing keys. The keys specified by each of the returned + // key strokes have to be pressed at the same time (the + // Control-key and the A-key for example). The keys of one key + // stroke have to be released before pressing those of the next. + // The order of the key strokes in the sequence define the order + // in which to press them. + [propget] HRESULT keyBinding + ( + [in] long keyBindingIndex, + [in] long keyStrokeSequenceLength, + [out, size_is(,keyStrokeSequenceLength), length_is(,*actualKeyStrokeSequenceLength)] + ACCESSIBLE_KEYSTROKE **keyStroke, + [out, retval] long *actualKeyStrokeSequenceLength + ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOMIDL/AccessibleKeyStroke.idl b/winaccessibility/source/UAccCOMIDL/AccessibleKeyStroke.idl new file mode 100644 index 000000000..5166014f6 --- /dev/null +++ b/winaccessibility/source/UAccCOMIDL/AccessibleKeyStroke.idl @@ -0,0 +1,149 @@ +/* -*- 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 . + */ + +typedef struct _ACCESSIBLE_KEYSTROKE { + short modifiers; + short keyCode; + char keyChar; + short keyFunc; +} ACCESSIBLE_KEYSTROKE; + +const short MODIFIER_SHIFT = 1; +const short MODIFIER_CTRL = 2; +const short MODIFIER_ALT = 4; + +const short KEYCODE_NUM0 = 256; +const short KEYCODE_NUM1 = 257; +const short KEYCODE_NUM2 = 258; +const short KEYCODE_NUM3 = 259; +const short KEYCODE_NUM4 = 260; +const short KEYCODE_NUM5 = 261; +const short KEYCODE_NUM6 = 262; +const short KEYCODE_NUM7 = 263; +const short KEYCODE_NUM8 = 264; +const short KEYCODE_NUM9 = 265; +const short KEYCODE_A = 512; +const short KEYCODE_B = 513; +const short KEYCODE_C = 514; +const short KEYCODE_D = 515; +const short KEYCODE_E = 516; +const short KEYCODE_F = 517; +const short KEYCODE_G = 518; +const short KEYCODE_H = 519; +const short KEYCODE_I = 520; +const short KEYCODE_J = 521; +const short KEYCODE_K = 522; +const short KEYCODE_L = 523; +const short KEYCODE_M = 524; +const short KEYCODE_N = 525; +const short KEYCODE_O = 526; +const short KEYCODE_P = 527; +const short KEYCODE_Q = 528; +const short KEYCODE_R = 529; +const short KEYCODE_S = 530; +const short KEYCODE_T = 531; +const short KEYCODE_U = 532; +const short KEYCODE_V = 533; +const short KEYCODE_W = 534; +const short KEYCODE_X = 535; +const short KEYCODE_Y = 536; +const short KEYCODE_Z = 537; +const short KEYCODE_F1 = 768; +const short KEYCODE_F2 = 769; +const short KEYCODE_F3 = 770; +const short KEYCODE_F4 = 771; +const short KEYCODE_F5 = 772; +const short KEYCODE_F6 = 773; +const short KEYCODE_F7 = 774; +const short KEYCODE_F8 = 775; +const short KEYCODE_F9 = 776; +const short KEYCODE_F10 = 777; +const short KEYCODE_F11 = 778; +const short KEYCODE_F12 = 779; +const short KEYCODE_F13 = 780; +const short KEYCODE_F14 = 781; +const short KEYCODE_F15 = 782; +const short KEYCODE_F16 = 783; +const short KEYCODE_F17 = 784; +const short KEYCODE_F18 = 785; +const short KEYCODE_F19 = 786; +const short KEYCODE_F20 = 787; +const short KEYCODE_F21 = 788; +const short KEYCODE_F22 = 789; +const short KEYCODE_F23 = 790; +const short KEYCODE_F24 = 791; +const short KEYCODE_F25 = 792; +const short KEYCODE_F26 = 793; +const short KEYCODE_DOWN = 1024; +const short KEYCODE_UP = 1025; +const short KEYCODE_LEFT = 1026; +const short KEYCODE_RIGHT = 1027; +const short KEYCODE_HOME = 1028; +const short KEYCODE_END = 1029; +const short KEYCODE_PAGEUP = 1030; +const short KEYCODE_PAGEDOWN = 1031; +const short KEYCODE_RETURN = 1280; +const short KEYCODE_ESCAPE = 1281; +const short KEYCODE_TAB = 1282; +const short KEYCODE_BACKSPACE = 1283; +const short KEYCODE_SPACE = 1284; +const short KEYCODE_INSERT = 1285; +const short KEYCODE_DELETE = 1286; +const short KEYCODE_ADD = 1287; +const short KEYCODE_SUBTRACT = 1288; +const short KEYCODE_MULTIPLY = 1289; +const short KEYCODE_DIVIDE = 1290; +const short KEYCODE_POINT = 1291; +const short KEYCODE_COMMA = 1292; +const short KEYCODE_LESS = 1293; +const short KEYCODE_GREATER = 1294; +const short KEYCODE_EQUAL = 1295; +const short KEYCODE_OPEN = 1296; +const short KEYCODE_CUT = 1297; +const short KEYCODE_COPY = 1298; +const short KEYCODE_PASTE = 1299; +const short KEYCODE_UNDO = 1300; +const short KEYCODE_REPEAT = 1301; +const short KEYCODE_FIND = 1302; +const short KEYCODE_PROPERTIES = 1303; +const short KEYCODE_FRONT = 1304; +const short KEYCODE_CONTEXTMENU = 1305; +const short KEYCODE_HELP = 1306; + +const short SHORTCUT_DONTKNOW = 0; +const short NEW = 1; +const short OPEN = 2; +const short SAVE = 3; +const short SAVEAS = 4; +const short PRINT = 5; +const short CLOSE = 6; +const short QUIT = 7; +const short CUT = 8; +const short COPY = 9; +const short PASTE = 10; +const short UNDO = 11; +const short REDO = 12; +const short UNODELETE = 13; +const short REPEAT = 14; +const short FIND = 15; +const short FINDBACKWARD = 16; +const short PROPERTIES = 17; +const short FRONT = 18; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOMIDL/Charset.idl b/winaccessibility/source/UAccCOMIDL/Charset.idl new file mode 100644 index 000000000..d5bf7ecd2 --- /dev/null +++ b/winaccessibility/source/UAccCOMIDL/Charset.idl @@ -0,0 +1,33 @@ +/* -*- 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 . + */ + + +const short CHARSET_DONTKNOW = 0; +const short ANSI = 1; +const short MAC = 2; +const short IBMPC_437 = 3; +const short IBMPC_850 = 4; +const short IBMPC_860 = 5; +const short IBMPC_861 = 6; +const short IBMPC_863 = 7; +const short IBMPC_865 = 8; +const short CHARSET_SYSTEM = 9; +const short SYMBOL = 10; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOMIDL/UAccCOM.idl b/winaccessibility/source/UAccCOMIDL/UAccCOM.idl new file mode 100644 index 000000000..f48b66ddd --- /dev/null +++ b/winaccessibility/source/UAccCOMIDL/UAccCOM.idl @@ -0,0 +1,213 @@ +/* -*- 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 . + */ + +import "oaidl.idl"; +import "ocidl.idl"; + +import "ia2_api_all.idl"; +import "defines.idl"; + + [ + object, + uuid(D00F5EB7-588A-487F-A6F6-0B5D7D1815AA), + dual, + helpstring("IMAccessible Interface"), + pointer_default(unique) + ] + interface IMAccessible : IAccessible2 + { + [id(1), helpstring("method Put_XAccName")] HRESULT Put_XAccName(const OLECHAR* pszName); + [id(2), helpstring("method Put_XAccRole")] HRESULT Put_XAccRole(unsigned short pRole); + [id(3), helpstring("method DecreaseState")] HRESULT DecreaseState(DWORD pXSate); + [id(4), helpstring("method IncreaseState")] HRESULT IncreaseState(DWORD pXSate); + [id(6), helpstring("method Put_XAccValue")] HRESULT Put_XAccValue(const OLECHAR* pszAccValue); + [id(7), helpstring("method SetState")] HRESULT SetState(DWORD pXSate); + [id(8), helpstring("method Put_XAccLocation")] HRESULT Put_XAccLocation(const Location sLocation); + [id(9), helpstring("method Put_XAccFocus")] HRESULT Put_XAccFocus(long dChildID); + [id(10), helpstring("method Put_XAccParent")] HRESULT Put_XAccParent(IMAccessible* pIParent); + [id(13), helpstring("method Put_XAccWindowHandle")] HRESULT Put_XAccWindowHandle(HWND hwnd); + [id(14), helpstring("method Put_XAccChildID")] HRESULT Put_XAccChildID(long dChildID); + [id(19), helpstring("method SetXAccessible")] HRESULT SetXAccessible(hyper XAccessible); + [id(20), helpstring("method GetUNOInterface")] HRESULT GetUNOInterface(hyper* UNOInterface); + [id(23), helpstring("method SetDefaultAction")] HRESULT SetDefaultAction(hyper pAction); + [id(24), helpstring("method Put_ActionDescription")] HRESULT Put_ActionDescription( const OLECHAR* szAction); + [id(25), helpstring("method Put_XAccAgent")] HRESULT Put_XAccAgent(hyper pAgent); + [id(26), helpstring("method NotifyDestroy")] HRESULT NotifyDestroy(); + }; + [ + object, + uuid(951299EE-1841-4249-9E07-812C0739E489), + dual, + helpstring("IEnumVariant Interface"), + pointer_default(unique) + ] + interface IEnumVariant : IEnumVARIANT + { + [id(1), helpstring("method ClearEnumeration")] HRESULT ClearEnumeration(); + [id(2), helpstring("method PutSelection")] HRESULT PutSelection(hyper pXSelection); + }; + [ + object, + uuid(6641185C-E099-4C45-B753-3FBC0EE40646), + dual, + helpstring("IUNOXWrapper Interface"), + pointer_default(unique) + ] + interface IUNOXWrapper : IUnknown + { + [id(1), helpstring("method put_XInterface")] HRESULT put_XInterface(hyper pXInterface); + [id(2), helpstring("method put_XSubInterface")] HRESULT put_XSubInterface(hyper pXSubInterface); + }; + +[ + uuid(19ECB1B0-9376-4FF9-B580-223FC9C200B8), + version(1.0), + helpstring("UAccCOM 1.0 Type Library") +] +library UACCCOMLib +{ + importlib("stdole32.tlb"); + importlib("stdole2.tlb"); + importlib("oleacc.dll"); + + [ + uuid(CF8DF8BA-44FE-4B10-BD2E-8C8CB322485F), + helpstring("MAccessible Class") + ] + coclass MAccessible + { + [default] interface IMAccessible; + }; + [ + uuid(152884E0-268B-4481-9AE7-1B372D3AA97F), + helpstring("EnumVariant Class") + ] + coclass EnumVariant + { + [default] interface IEnumVariant; + }; + [ + uuid(AA360FB0-BC98-41C1-A885-BB921F5ED601), + helpstring("UNOXWrapper Class") + ] + coclass UNOXWrapper + { + [default] interface IUNOXWrapper; + }; + + [ + uuid(9FD9BA47-70AF-4160-99F1-526F2B9F111B), + helpstring("AccComponent Class") + ] + coclass AccComponent + { + [default] interface IAccessibleComponent; + }; + + [ + uuid(8745CF0C-3104-4BAE-B7D0-D7B1717C006E), + helpstring("AccRelation Class") + ] + coclass AccRelation + { + [default] interface IAccessibleRelation; + }; + [ + uuid(AA49F20E-BB4E-400D-A5B0-6F5B7B770227), + helpstring("AccAction Class") + ] + coclass AccAction + { + [default] interface IAccessibleAction; + }; + + [ + uuid(6D8AB08B-CCE9-471E-8A41-35773D5263F5), + helpstring("AccText Class") + ] + coclass AccText + { + [default] interface IAccessibleText; + }; + + [ + uuid(79CE1450-1F61-48E2-BF76-C07BD10105E2), + helpstring("AccEditableText Class") + ] + coclass AccEditableText + { + [default] interface IAccessibleEditableText; + }; + + [ + uuid(CC55D71B-1828-4EE0-89E2-C3749CF9C9AB), + helpstring("AccHypertext Class") + ] + coclass AccHypertext + { + [default] interface IAccessibletext; + }; + + + [ + uuid(73A45800-7A62-432C-A1A6-BF8852994331), + helpstring("AccImage Class") + ] + coclass AccImage + { + [default] interface IAccessibleImage; + }; + + [ + uuid(730A561B-1AF6-49E1-9C04-9A2F48CD8512), + helpstring("AccValue Class") + ] + coclass AccValue + { + [default] interface IAccessibleValue; + }; + [ + uuid(92BAA62D-535A-4EAB-9ABB-BFA60B7A6DB6), + helpstring("AccTable Class") + ] + coclass AccTable + { + [default] interface IAccessibleTable; + }; + [ + uuid(77948F17-05C8-4DAA-93D4-BCCD16ADC660), + helpstring("AccTableCell Class") + ] + coclass AccTableCell + { + [default] interface IAccessibleTableCell; + }; + + [ + uuid(519A64CD-F6A6-4793-BE50-4E36C4C593EF), + helpstring("AccHyperLink Class") + ] + coclass AccHyperLink + { + [default] interface IAccessibleAction; + }; + +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOMIDL/defines.idl b/winaccessibility/source/UAccCOMIDL/defines.idl new file mode 100644 index 000000000..2902b4f92 --- /dev/null +++ b/winaccessibility/source/UAccCOMIDL/defines.idl @@ -0,0 +1,40 @@ +/* -*- 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 . + */ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + +interface IMAccessible; + +const long UACC_NO_FOCUS=0xFFFF; + +typedef struct { + long m_dChildID;//identify a unique child node + IMAccessible* m_pIMAccessible; +}AccChildNode; + +typedef struct Location { + long m_dLeft; + long m_dTop; + long m_dWidth; + long m_dHeight; +}Location; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/UAccCOMIDL/ia2_api_all.idl b/winaccessibility/source/UAccCOMIDL/ia2_api_all.idl new file mode 100644 index 000000000..95a3a42db --- /dev/null +++ b/winaccessibility/source/UAccCOMIDL/ia2_api_all.idl @@ -0,0 +1,5476 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * File Name (api_all_headers.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2013 Linux Foundation + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + +import "objidl.idl"; +import "oaidl.idl"; +import "oleacc.idl"; + +/************************************************************************* + * + * File Name (IA2CommonTypes.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2013 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + /** These constants control the scrolling of an object or substring into a window. + + This enum is used in IAccessible2::scrollTo and IAccessibleText::scrollSubstringTo. +*/ +enum IA2ScrollType { + + /** Scroll the top left corner of the object or substring such that the top left + corner (and as much as possible of the rest of the object or substring) is within + the top level window. In cases where the entire object or substring fits within + the top level window, the placement of the object or substring is dependent on + the application. For example, the object or substring may be scrolled to the + closest edge, the furthest edge, or midway between those two edges. In cases + where there is a hierarchy of nested scrollable controls, more than one control + may have to be scrolled. + */ + IA2_SCROLL_TYPE_TOP_LEFT, + + /** Scroll the bottom right corner of the object or substring such that the bottom right + corner (and as much as possible of the rest of the object or substring) is within + the top level window. In cases where the entire object or substring fits within + the top level window, the placement of the object or substring is dependent on + the application. For example, the object or substring may be scrolled to the + closest edge, the furthest edge, or midway between those two edges. In cases + where there is a hierarchy of nested scrollable controls, more than one control + may have to be scrolled. + */ + IA2_SCROLL_TYPE_BOTTOM_RIGHT, + + /** Scroll the top edge of the object or substring such that the top edge + (and as much as possible of the rest of the object or substring) is within the + top level window. In cases where the entire object or substring fits within + the top level window, the placement of the object or substring is dependent on + the application. For example, the object or substring may be scrolled to the + closest edge, the furthest edge, or midway between those two edges. In cases + where there is a hierarchy of nested scrollable controls, more than one control + may have to be scrolled. + */ + IA2_SCROLL_TYPE_TOP_EDGE, + + /** Scroll the bottom edge of the object or substring such that the bottom edge + (and as much as possible of the rest of the object or substring) is within the + top level window. In cases where the entire object or substring fits within + the top level window, the placement of the object or substring is dependent on + the application. For example, the object or substring may be scrolled to the + closest edge, the furthest edge, or midway between those two edges. In cases + where there is a hierarchy of nested scrollable controls, more than one control + may have to be scrolled. + */ + IA2_SCROLL_TYPE_BOTTOM_EDGE, + + /** Scroll the left edge of the object or substring such that the left edge + (and as much as possible of the rest of the object or substring) is within the + top level window. In cases where the entire object or substring fits within + the top level window, the placement of the object or substring is dependent on + the application. For example, the object or substring may be scrolled to the + closest edge, the furthest edge, or midway between those two edges. In cases + where there is a hierarchy of nested scrollable controls, more than one control + may have to be scrolled. + */ + IA2_SCROLL_TYPE_LEFT_EDGE, + + /** Scroll the right edge of the object or substring such that the right edge + (and as much as possible of the rest of the object or substring) is within the + top level window. In cases where the entire object or substring fits within + the top level window, the placement of the object or substring is dependent on + the application. For example, the object or substring may be scrolled to the + closest edge, the furthest edge, or midway between those two edges. In cases + where there is a hierarchy of nested scrollable controls, more than one control + may have to be scrolled. + */ + IA2_SCROLL_TYPE_RIGHT_EDGE, + + /** Scroll the object or substring such that as much as possible of the + object or substring is within the top level window. The placement of + the object is dependent on the application. For example, the object or + substring may be scrolled to closest edge, the furthest edge, or midway + between those two edges. + */ + IA2_SCROLL_TYPE_ANYWHERE +}; + +/** These constants define which coordinate system a point is located in. + + This enum is used in IAccessible2::scrollToPoint, IAccessibleImage::imagePosition, + IAccessibleText::characterExtents, and IAccessibleText::offsetAtPoint, and + IAccessibleText::scrollSubstringToPoint. +*/ +enum IA2CoordinateType { + + /// The coordinates are relative to the screen. + IA2_COORDTYPE_SCREEN_RELATIVE, + + /** The coordinates are relative to the upper left corner of the bounding box + of the immediate parent. + */ + IA2_COORDTYPE_PARENT_RELATIVE + +}; + +/** Special offsets for use in IAccessibleText and IAccessibleEditableText methods + + Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for more information. +*/ +enum IA2TextSpecialOffsets { + IA2_TEXT_OFFSET_LENGTH = -1, /**< This offset is equivalent to the length of the string. It eliminates + the need to call IAccessibleText::nCharacters. */ + IA2_TEXT_OFFSET_CARET = -2 /**< This offset signifies that the text related to the physical location + of the caret should be used. */ +}; + +/** These constants specify the kind of change made to a table. + + This enum is used in the IA2TableModelChange struct which in turn is used by + IAccessibleTable::modelChange and IAccessibleTable2::modelChange. +*/ +enum IA2TableModelChangeType { + IA2_TABLE_MODEL_CHANGE_INSERT, // = 0; + IA2_TABLE_MODEL_CHANGE_DELETE, + IA2_TABLE_MODEL_CHANGE_UPDATE +}; + +/** A structure defining the type of and extents of changes made to a table + + IAccessibleTable::modelChange and IAccessibleTable2::modelChange return this struct. + In the case of an insertion or change the row and column offsets define the boundaries + of the inserted or changed subtable after the operation. In the case of a deletion + the row and column offsets define the boundaries of the subtable being removed before + the removal. +*/ +typedef struct IA2TableModelChange { + enum IA2TableModelChangeType type; // insert, delete, update + long firstRow; ///< 0 based, inclusive + long lastRow; ///< 0 based, inclusive + long firstColumn; ///< 0 based, inclusive + long lastColumn; ///< 0 based, inclusive +} IA2TableModelChange; +/************************************************************************* + * + * File Name (AccessibleRelation.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2013 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + +/** @defgroup grpRelations Relations + Use the following constants to compare against the BSTRs returned by + IAccessibleRelation::relationType. +*/ +///@{ + +/** The target object is the containing application object. */ +const WCHAR *const IA2_RELATION_CONTAINING_APPLICATION = L"containingApplication"; + +/** The target object is the containing document object. The target object implements + the IAccessibleDocument interface. +*/ +const WCHAR *const IA2_RELATION_CONTAINING_DOCUMENT = L"containingDocument"; + +/** The target object is the containing tab pane object. */ +const WCHAR *const IA2_RELATION_CONTAINING_TAB_PANE = L"containingTabPane"; + +/** The target object is the containing window object. */ +const WCHAR *const IA2_RELATION_CONTAINING_WINDOW = L"containingWindow"; + +/** Some attribute of this object is affected by a target object. */ +const WCHAR *const IA2_RELATION_CONTROLLED_BY = L"controlledBy"; + +/** This object is interactive and controls some attribute of a target object. */ +const WCHAR *const IA2_RELATION_CONTROLLER_FOR = L"controllerFor"; + +/** This object is described by the target object. */ +const WCHAR *const IA2_RELATION_DESCRIBED_BY = L"describedBy"; + +/** This object is describes the target object. */ +const WCHAR *const IA2_RELATION_DESCRIPTION_FOR = L"descriptionFor"; + +/** This object is embedded by a target object. */ +const WCHAR *const IA2_RELATION_EMBEDDED_BY = L"embeddedBy"; + +/** This object embeds a target object. This relation can be used on the + OBJID_CLIENT accessible for a top level window to show where the content + areas are. +*/ +const WCHAR *const IA2_RELATION_EMBEDS = L"embeds"; + +/** Content flows to this object from a target object. + This relation and IA2_RELATION_FLOWS_TO are useful to tie text and non-text + objects together in order to allow assistive technology to follow the + intended reading order. +*/ +const WCHAR *const IA2_RELATION_FLOWS_FROM = L"flowsFrom"; + +/** Content flows from this object to a target object. */ +const WCHAR *const IA2_RELATION_FLOWS_TO = L"flowsTo"; + +/** This object is label for a target object. */ +const WCHAR *const IA2_RELATION_LABEL_FOR = L"labelFor"; + +/** This object is labelled by a target object. Note that the double L spelling + which follows is preferred. Please use it instead. This single L version may + be removed in a later version. +*/ +const WCHAR *const IA2_RELATION_LABELED_BY = L"labelledBy"; + +/** This object is labelled by a target object. */ +const WCHAR *const IA2_RELATION_LABELLED_BY = L"labelledBy"; + +/** This object is a member of a group of one or more objects. When + there is more than one object in the group each member may have one and the + same target, e.g. a grouping object. It is also possible that each member has + multiple additional targets, e.g. one for every other member in the group. +*/ +const WCHAR *const IA2_RELATION_MEMBER_OF = L"memberOf"; + +/** The target object is the next object in the tab order. */ +const WCHAR *const IA2_RELATION_NEXT_TABBABLE = L"nextTabbable"; + +/** This object is a logical child of a target object. This relation is the reciprocal + of the IA2_RELATION_NODE_PARENT_OF relation. In some cases an application's accessible + tree is such that objects can be in a logical parent-child relationship which is + different from the hierarchy of the accessible tree. */ +const WCHAR *const IA2_RELATION_NODE_CHILD_OF = L"nodeChildOf"; + +/** This object is a logical parent of a target object. This relation is the reciprocal + of the IA2_RELATION_NODE_CHILD_OF relation. In some cases an application's accessible + tree is such that objects can be in a logical parent-child relationship which is + different from the hierarchy of the accessible tree. */ +const WCHAR *const IA2_RELATION_NODE_PARENT_OF = L"nodeParentOf"; + +/** This object is a parent window of the target object. */ +const WCHAR *const IA2_RELATION_PARENT_WINDOW_OF = L"parentWindowOf"; + +/** This object is a transient component related to the target object. + When this object is activated the target object doesn't lose focus. +*/ +const WCHAR *const IA2_RELATION_POPUP_FOR = L"popupFor"; + +/** The target object is the previous object in the tab order. */ +const WCHAR *const IA2_RELATION_PREVIOUS_TABBABLE = L"previousTabbable"; + +/** This object is a sub window of a target object. */ +const WCHAR *const IA2_RELATION_SUBWINDOW_OF = L"subwindowOf"; + +///@} + +/** This interface gives access to an object's set of relations. +*/ +[object, uuid(7CDF86EE-C3DA-496a-BDA4-281B336E1FDC)] +interface IAccessibleRelation : IUnknown +{ + /** @brief Returns the type of the relation. + @param [out] relationType + The strings returned are defined @ref grpRelations "in this section of the documentation". + @retval S_OK + */ + [propget] HRESULT relationType + ( + [out, retval] BSTR *relationType + ); + + /** @brief Returns a localized version of the relation type. + @param [out] localizedRelationType + @retval S_OK + */ + [propget] HRESULT localizedRelationType + ( + [out, retval] BSTR *localizedRelationType + ); + + /** @brief Returns the number of targets for this relation. + @param [out] nTargets + @retval S_OK + */ + [propget] HRESULT nTargets + ( + [out, retval] long *nTargets + ); + + /** @brief Returns one accessible relation target. + @param [in] targetIndex + 0 based index + @param [out] target + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + @note Use QueryInterface to get IAccessible2. + */ + [propget] HRESULT target + ( + [in] long targetIndex, + [out, retval] IUnknown **target + ); + + /** @brief Returns multiple accessible relation targets + @param [in] maxTargets + maximum size of the array allocated by the client + @param [out] targets + The array of target objects. Note that this array is to be allocated by the + client and freed when no longer needed. Refer to @ref _arrayConsideration + "Special Consideration when using Arrays" for more details. You will need to use + QueryInterface on the IUnknown to get the IAccessible2. + @param [out] nTargets + actual number of targets in the returned array (not more than maxTargets) + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, e.g. a negative value + */ + [propget] HRESULT targets + ( + [in] long maxTargets, + [out, size_is(maxTargets), length_is(*nTargets)] + IUnknown **targets, + [out, retval] long *nTargets + ); + +} +/************************************************************************* + * + * File Name (AccessibleAction.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2013 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + +/** This enum defines values which are predefined actions for use when implementing + support for media. + + This enum is used when specifying an action for IAccessibleAction::doAction. +*/ + +enum IA2Actions { + IA2_ACTION_OPEN = -1, /**< Used to inform the server that the client will + signal via IA2_ACTION_COMPLETE when it has consumed + the content provided by the object. This action + allows the object's server to wait for all clients + to signal their readiness for additional content. + Any form of content generation that requires + synchronization with an AT would require use of this + action. One example is the generation of text describing + visual content not obvious from a video's sound track. + In this scenario the Text to Speech or Braille output + may take more time than the related length of silence + in the video's sound track. */ + IA2_ACTION_COMPLETE = -2, /**< Used by the client to inform the server that it has + consumed the most recent content provided by this object. */ + IA2_ACTION_CLOSE = -3 /**< Used to inform the server that the client no longer + requires synchronization. */ +}; + +/** @brief This interface gives access to actions that can be executed + for accessible objects. + + Every accessible object that can be manipulated via the native GUI beyond the + methods available either in the MSAA IAccessible interface or in the set of + IAccessible2 interfaces (other than this IAccessibleAction interface) should + support the IAccessibleAction interface in order to provide Assistive Technology + access to all the actions that can be performed by the object. Each action can + be performed or queried for a name, description or associated key bindings. + Actions are needed more for ATs that assist the mobility impaired, such as + on-screen keyboards and voice command software. By providing actions directly, + the AT can present them to the user without the user having to perform the extra + steps to navigate a context menu. + + The first action should be equivalent to the MSAA default action. If there is + only one action, %IAccessibleAction should also be implemented. +*/ +[object, uuid(B70D9F59-3B5A-4dba-AB9E-22012F607DF5)] +interface IAccessibleAction : IUnknown +{ + + /** @brief Returns the number of accessible actions available in this object. + + If there are more than one, the first one is considered the + "default" action of the object. + @param [out] nActions + The returned value of the number of actions is zero if there are + no actions. + @retval S_OK + @note This method is missing a [propget] prefix in the IDL. The result is the + method is named nActions in generated C++ code instead of get_nActions. + */ + HRESULT nActions + ( + [out,retval] long* nActions + ); + + /** @brief Performs the specified Action on the object. + @param [in] actionIndex + 0 based index specifying the action to perform. If it lies outside + the valid range no action is performed. + @retval S_OK + @retval S_FALSE if action could not be performed + @retval E_INVALIDARG if bad [in] passed + @note If implementing support for media, refer to the predefined constants in the ::IA2Actions enum. + */ + HRESULT doAction + ( + [in] long actionIndex + ); + + /** @brief Returns a description of the specified action of the object. + @param [in] actionIndex + 0 based index specifying which action's description to return. + If it lies outside the valid range an empty string is returned. + @param [out] description + The returned value is a localized string of the specified action. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT description + ( + [in] long actionIndex, + [out, retval] BSTR *description + ); + + /** @brief Returns an array of BSTRs describing one or more key bindings, if + there are any, associated with the specified action. + + The returned strings are the localized human readable key sequences to be + used to activate each action, e.g. "Ctrl+Shift+D". Since these key + sequences are to be used when the object has focus, they are like + mnemonics (access keys), and not like shortcut (accelerator) keys. + + There is no need to implement this method for single action controls since + that would be redundant with the standard MSAA programming practice of + getting the mnemonic from get_accKeyboardShortcut. + + An AT such as an On Screen Keyboard might not expose these bindings but + provide alternative means of activation. + + Note: the client allocates and passes in an array of pointers. The server + allocates the BSTRs and passes back one or more pointers to these BSTRs into + the array of pointers allocated by the client. The client is responsible + for deallocating the BSTRs. + + @param [in] actionIndex + 0 based index specifying which action's key bindings should be returned. + @param [in] nMaxBindings + This parameter is ignored. Refer to @ref _arrayConsideration + "Special Consideration when using Arrays" for more details. + @param [out] keyBindings + An array of BSTRs, allocated by the server, one for each key binding. + The client must free it with CoTaskMemFree. + @param [out] nBindings + The number of key bindings returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are no key bindings, [out] values are NULL and 0 respectively + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT keyBinding + ( + [in] long actionIndex, + [in] long nMaxBindings, + [out, size_is(,nMaxBindings), length_is(,*nBindings)] BSTR **keyBindings, + [out, retval] long *nBindings + ); + + /** @brief Returns the non-localized name of specified action. + @param [in] actionIndex + 0 based index specifying which action's non-localized name should be returned. + @param [out] name + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT name + ( + [in] long actionIndex, + [out, retval] BSTR *name + ); + + /** @brief Returns the localized name of specified action. + @param [in] actionIndex + 0 based index specifying which action's localized name should be returned. + @param [out] localizedName + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT localizedName + ( + [in] long actionIndex, + [out, retval] BSTR *localizedName + ); + +} +/************************************************************************* + * + * File Name (AccessibleRole.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2013 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + +/** Collection of roles + + This enumerator defines an extended set of accessible roles of objects implementing + the %IAccessible2 interface. These roles are in addition to the MSAA roles obtained + through the MSAA get_accRole method. Examples are 'footnote', 'heading', and + 'label'. You obtain an object's %IAccessible2 roles by calling IAccessible2::role. +*/ +enum IA2Role { + + /** Unknown role. The object contains some Accessible information, but its + role is not known. + */ + IA2_ROLE_UNKNOWN = 0, + + /** An object that can be drawn into and to manage events from the objects + drawn into it. Also refer to ::IA2_ROLE_FRAME, + ::IA2_ROLE_GLASS_PANE, and ::IA2_ROLE_LAYERED_PANE. + */ + IA2_ROLE_CANVAS = 0x401, + + /// A caption describing another object. + IA2_ROLE_CAPTION, + + /// Used for check buttons that are menu items. + IA2_ROLE_CHECK_MENU_ITEM, + + /// A specialized dialog that lets the user choose a color. + IA2_ROLE_COLOR_CHOOSER, + + /// A date editor. + IA2_ROLE_DATE_EDITOR, + + /** An iconified internal frame in an ::IA2_ROLE_DESKTOP_PANE. + Also refer to ::IA2_ROLE_INTERNAL_FRAME. + */ + IA2_ROLE_DESKTOP_ICON, + + /** A desktop pane. A pane that supports internal frames and iconified + versions of those internal frames. Also refer to ::IA2_ROLE_INTERNAL_FRAME. + */ + IA2_ROLE_DESKTOP_PANE, + + /** A directory pane. A pane that allows the user to navigate through + and select the contents of a directory. May be used by a file chooser. + Also refer to ::IA2_ROLE_FILE_CHOOSER. + */ + IA2_ROLE_DIRECTORY_PANE, + + /** An editable text object in a toolbar. <b>Deprecated.</b> + The edit bar role was meant for a text area in a tool bar. However, to detect + a text area in a tool bar the AT can query the parent. + */ + IA2_ROLE_EDITBAR, + + /// Embedded (OLE) object. + IA2_ROLE_EMBEDDED_OBJECT, + + /// Text that is used as an endnote (footnote at the end of a chapter or section). + IA2_ROLE_ENDNOTE, + + /** A file chooser. A specialized dialog that displays the files in the + directory and lets the user select a file, browse a different directory, + or specify a filename. May use the directory pane to show the contents of + a directory. + Also refer to ::IA2_ROLE_DIRECTORY_PANE. + */ + IA2_ROLE_FILE_CHOOSER, + + /** A font chooser. A font chooser is a component that lets the user pick + various attributes for fonts. + */ + IA2_ROLE_FONT_CHOOSER, + + /** Footer of a document page. + Also refer to ::IA2_ROLE_HEADER. + */ + IA2_ROLE_FOOTER, + + /// Text that is used as a footnote. Also refer to ::IA2_ROLE_ENDNOTE. + IA2_ROLE_FOOTNOTE, + + /** A container of form controls. An example of the use of this role is to + represent an HTML FORM tag. + */ + IA2_ROLE_FORM, + + /** Frame role. A top level window with a title bar, border, menu bar, etc. + It is often used as the primary window for an application. Also refer to + ::IA2_ROLE_CANVAS and the MSAA roles of dialog and window. + */ + IA2_ROLE_FRAME, + + /** A glass pane. A pane that is guaranteed to be painted on top of all panes + beneath it. Also refer to ::IA2_ROLE_CANVAS, ::IA2_ROLE_INTERNAL_FRAME, and + ::IA2_ROLE_ROOT_PANE. + */ + IA2_ROLE_GLASS_PANE, + + /** Header of a document page. + Also refer to ::IA2_ROLE_FOOTER. + */ + IA2_ROLE_HEADER, + + /// Heading. Use the IAccessible2::attributes level attribute to determine the heading level. + IA2_ROLE_HEADING, + + /// A small fixed size picture, typically used to decorate components. + IA2_ROLE_ICON, + + /** An image map object. Usually a graphic with multiple hotspots, where + each hotspot can be activated resulting in the loading of another document + or section of a document. + */ + IA2_ROLE_IMAGE_MAP, + + /** An object which is used to allow input of characters not found on a keyboard, + such as the input of Chinese characters on a Western keyboard. + */ + IA2_ROLE_INPUT_METHOD_WINDOW, + + /** An internal frame. A frame-like object that is clipped by a desktop pane. + The desktop pane, internal frame, and desktop icon objects are often used to + create multiple document interfaces within an application. + Also refer to ::IA2_ROLE_DESKTOP_ICON, ::IA2_ROLE_DESKTOP_PANE, and ::IA2_ROLE_FRAME. + */ + IA2_ROLE_INTERNAL_FRAME, + + /// An object used to present an icon or short string in an interface. + IA2_ROLE_LABEL, + + /** A layered pane. A specialized pane that allows its children to be drawn + in layers, providing a form of stacking order. This is usually the pane that + holds the menu bar as well as the pane that contains most of the visual + components in a window. + Also refer to ::IA2_ROLE_CANVAS, ::IA2_ROLE_GLASS_PANE, and ::IA2_ROLE_ROOT_PANE. + */ + IA2_ROLE_LAYERED_PANE, + + /** A section whose content is parenthetic or ancillary to the main content + of the resource. + */ + IA2_ROLE_NOTE, + + /** A specialized pane whose primary use is inside a dialog. + Also refer to MSAA's dialog role. + */ + IA2_ROLE_OPTION_PANE, + + /** An object representing a page of document content. It is used in documents + which are accessed by the user on a page by page basis. + */ + IA2_ROLE_PAGE, + + /// A paragraph of text. + IA2_ROLE_PARAGRAPH, + + /** A radio button that is a menu item. + Also refer to MSAA's button and menu item roles. + */ + IA2_ROLE_RADIO_MENU_ITEM, + + /** An object which is redundant with another object in the accessible hierarchy. + ATs typically ignore objects with this role. + */ + IA2_ROLE_REDUNDANT_OBJECT, + + /** A root pane. A specialized pane that has a glass pane and a layered pane + as its children. + Also refer to ::IA2_ROLE_GLASS_PANE and ::IA2_ROLE_LAYERED_PANE + */ + IA2_ROLE_ROOT_PANE, + + /** A ruler such as those used in word processors. + */ + IA2_ROLE_RULER, + + /** A scroll pane. An object that allows a user to incrementally view a large + amount of information. Its children can include scroll bars and a viewport. + Also refer to ::IA2_ROLE_VIEW_PORT and MSAA's scroll bar role. + */ + IA2_ROLE_SCROLL_PANE, + + /** A container of document content. An example of the use of this role is to + represent an HTML DIV tag. A section may be used as a region. A region is a + group of elements that together form a perceivable unit. A region does not + necessarily follow the logical structure of the content, but follows the + perceivable structure of the page. A region may have an attribute in the set + of IAccessible2::attributes which indicates that it is "live". A live region + is content that is likely to change in response to a timed change, a user + event, or some other programmed logic or event. + */ + IA2_ROLE_SECTION, + + /// Object with graphical representation used to represent content on draw pages. + IA2_ROLE_SHAPE, + + /** A split pane. A specialized panel that presents two other panels at the + same time. Between the two panels is a divider the user can manipulate to make + one panel larger and the other panel smaller. + */ + IA2_ROLE_SPLIT_PANE, + + /** An object that forms part of a menu system but which can be "undocked" + from or "torn off" the menu system to exist as a separate window. + */ + IA2_ROLE_TEAR_OFF_MENU, + + /// An object used as a terminal emulator. + IA2_ROLE_TERMINAL, + + /// Collection of objects that constitute a logical text entity. + IA2_ROLE_TEXT_FRAME, + + /** A toggle button. A specialized push button that can be checked or unchecked, + but does not provide a separate indicator for the current state. + Also refer to MSAA's roles of push button, check box, and radio button. + <BR><B>Note:</B> IA2_ROLE_TOGGLE_BUTTON should not be used. Instead, use MSAA's + ROLE_SYSTEM_PUSHBUTTON and STATE_SYSTEM_PRESSED. + */ + IA2_ROLE_TOGGLE_BUTTON, + + /** A viewport. An object usually used in a scroll pane. It represents the + portion of the entire data that the user can see. As the user manipulates + the scroll bars, the contents of the viewport can change. + Also refer to ::IA2_ROLE_SCROLL_PANE. + */ + IA2_ROLE_VIEW_PORT, + + /** An object containing content which is complementary to the main content of + a document, but remains meaningful when separated from the main content. There + are various types of content that would appropriately have this role. For example, + in the case where content is delivered via a web portal to a web browser, this may + include but not be limited to show times, current weather, related articles, or + stocks to watch. The complementary role indicates that contained content is relevant + to the main content. If the complementary content is completely separable main + content, it may be appropriate to use a more general role. + */ + IA2_ROLE_COMPLEMENTARY_CONTENT + +}; +/************************************************************************* + * + * File Name (AccessibleStates.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2010 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + +typedef long AccessibleStates; + +/** %IAccessible2 specific state bit constants + + This enum defines the state bits returned by IAccessible2::states. The + %IAccessible2 state bits are in addition to those returned by MSAA. +*/ +enum IA2States { + +/** Indicates a window is currently the active window, or is an active subelement + within a container or table. + + This state can be used to indicate the current active item in a container, even + if the container itself is not currently active. In other words this would indicate + the item that will get focus if you tab to the container. + + This information is important for knowing what to report for trees and potentially + other containers in a virtual buffer. + + Also, see ::IA2_STATE_MANAGES_DESCENDANTS for more information. +*/ +IA2_STATE_ACTIVE = 0x1, + +/** Indicates that the object is armed. + + Used to indicate that the control is "pressed" and will be invoked when the + actuator, e.g. a mouse button, is "released". An AT which either monitors the + mouse or synthesizes mouse events might need to know that, and possibly a talking + interface would even let the user know about it. It could also potentially be + useful to on screen keyboards or test tools since the information does indicate + something about the state of the interface, for example, code operating asynchronously + might need to wait for the armed state to change before doing something else. + +*/ +IA2_STATE_ARMED = 0x2, + +/** Indicates the user interface object corresponding to this object no longer exists. */ +IA2_STATE_DEFUNCT = 0x4, + +/** An object with this state has a caret and implements the IAccessibleText interface. + + Such fields may be read-only, so STATE_SYSTEM_READONLY is valid in combination + with IA2_STATE_EDITABLE. + +*/ +IA2_STATE_EDITABLE = 0x8, + +/** Indicates the orientation of this object is horizontal. */ +IA2_STATE_HORIZONTAL = 0x10, + +/** Indicates this object is minimized and is represented only by an icon. */ +IA2_STATE_ICONIFIED = 0x20, + +/** Indicates an input validation failure. */ +IA2_STATE_INVALID_ENTRY = 0x40, + +/** Indicates that this object manages its children. + + Note: Due to the fact that MSAA's WinEvents don't allow the active child index + to be passed on the IA2_EVENT_ACTIVE_DESCENDANT_CHANGED event, the manages + descendants scheme can't be used. Instead the active child object has to fire + MSAA's EVENT_OBJECT_FOCUS. In a future release a new event mechanism may be + added to provide for event specific data to be passed with the event. At that + time the IA2_EVENT_ACTIVE_DECENDENT_CHANGED event and + IA2_STATE_MANAGES_DESCENDANTS state would be useful. +*/ +IA2_STATE_MANAGES_DESCENDANTS = 0x80, + +/** Indicates that an object is modal. + + Modal objects have the behavior that something must be done with the object + before the user can interact with an object in a different window. +*/ +IA2_STATE_MODAL = 0x100, + +/** Indicates this text object can contain multiple lines of text. */ +IA2_STATE_MULTI_LINE = 0x200, + +/** Indicates this object paints every pixel within its rectangular region. */ +IA2_STATE_OPAQUE = 0x400, + +/** Indicates that user interaction is required. + + An example of when this state is used is when a field in a form must be filled + before a form can be processed. +*/ +IA2_STATE_REQUIRED = 0x800, + +/** Indicates an object which supports text selection. + + Note: This is different than MSAA STATE_SYSTEM_SELECTABLE. +*/ +IA2_STATE_SELECTABLE_TEXT = 0x1000, + +/** Indicates that this text object can contain only a single line of text. */ +IA2_STATE_SINGLE_LINE = 0x2000, + +/** Indicates that the accessible object is stale. + + This state is used when the accessible object no longer accurately + represents the state of the object which it is representing such as when an + object is transient or when an object has been or is in the process of being + destroyed or when the object's index in its parent has changed. +*/ +IA2_STATE_STALE = 0x4000, + +/** Indicates that the object implements autocompletion. + + This state indicates that a text control will respond to the input of + one ore more characters and cause a sub-item to become selected. The + selection may also result in events fired on the parent object. +*/ +IA2_STATE_SUPPORTS_AUTOCOMPLETION = 0x8000, + +/** Indicates this object is transient. + + An object has this state when its parent object has the state ::IA2_STATE_MANAGES_DESCENDANTS. + For example, a list item object may be managed by its parent list object and may only + exist as long as the object is actually rendered. Similarly a table cell's accessible + object may exist only while the cell has focus. However, from the perspective of an + assistive technology a transient object behaves like a non-transient object. As a + result it is likely that this state is not of use to an assistive technology, but it + is provided in case an assistive technology determines that knowledge of the transient + nature of the object is useful and also for harmony with the Linux accessibility API. + + Also, see ::IA2_STATE_MANAGES_DESCENDANTS for more information. + */ +IA2_STATE_TRANSIENT = 0x10000, + +/** Indicates the orientation of this object is vertical. */ +IA2_STATE_VERTICAL = 0x20000, + +/** Indicates this object is checkable. + + The standard checkable objects are check boxes, radio buttons, check box menu + items, radio menu items, and toggle buttons. Since assistive technology will + determine that these objects are checkable via the object's role the checkable + state is not required. However, this state is necessary in those cases where + an object has a role which is not one of the previously mentioned roles. An + example is a table cell which indicates whether or not an email has an attachment, + whether or not a mail is considered spam, and whether or not an email has been read. + */ +IA2_STATE_CHECKABLE = 0x40000, + +/** Indicates this object is pinned. + + This state indicates that an object is fixed at a certain location. One example + is a browser tab that when pinned cannot be moved until unpinned. Another example + is a movable or floating object that when pinned remains in its pinned location + until being unpinned. + */ +IA2_STATE_PINNED = 0x80000 + +}; +/************************************************************************* + * + * File Name (Accessible2.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2013 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + +/** @mainpage + + @section _interfaces Interfaces + IAccessible2\n + IAccessible2_2\n + IAccessibleAction\n + IAccessibleApplication\n + IAccessibleComponent\n + IAccessibleDocument\n + IAccessibleEditableText\n + IAccessibleHypertext\n + IAccessibleHypertext2\n + IAccessibleHyperlink\n + IAccessibleImage\n + IAccessibleRelation\n + IAccessibleTable [Deprecated]\n + IAccessibleTable2\n + IAccessibleTableCell\n + IAccessibleText\n + IAccessibleText2\n + IAccessibleValue + + @section _structs Structs + IA2Locale\n + IA2TableModelChange\n + IA2TextSegment + + @section _enums Enums + ::IA2Actions values are predefined actions for use when implementing support for HTML5 media.\n + ::IA2CoordinateType values define the requested coordinate type (screen or parent window).\n + ::IA2EventID values identify events.\n + ::IA2Role values defines roles which are in addition to the existing MSAA roles.\n + ::IA2ScrollType values define where to place an object or substring on the screen.\n + ::IA2States values define states which are in addition to the existing MSAA states.\n + ::IA2TableModelChangeType values describe the kinds of changes made to a table (insert, delete, update).\n + ::IA2TextBoundaryType values define the requested text unit (character, word, sentence, line, paragraph).\n + ::IA2TextSpecialOffsets values define special offsets for use in the text interfaces. + + @section _constants Constants + @ref grpRelations + + @section _misc Miscellaneous + @ref _licensePage "BSD License"\n + @ref _generalInfo "General Information"\n + + @page _licensePage BSD License + %IAccessible2 IDL Specification + + Copyright (c) 2007, 2013 Linux Foundation\n + Copyright (c) 2006 IBM Corporation\n + Copyright (c) 2000, 2006 Sun Microsystems, Inc.\n + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + 3. Neither the name of the Linux Foundation nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + This BSD License conforms to the Open Source Initiative "Simplified + BSD License" as published at: + http://www.opensource.org/licenses/bsd-license.php + + %IAccessible2 is a trademark of the Linux Foundation. The %IAccessible2 + mark may be used in accordance with the + <a href="http://www.linuxfoundation.org/collaborate/workgroups/accessibility/trademark-policy"> + Linux Foundation Trademark Policy</a> to indicate compliance with the %IAccessible2 specification. + + @page _generalInfo General Information + The following information is applicable to two or more interfaces. + + @ref _errors\n + @ref _memory\n + @ref _arrayConsideration\n + @ref _indexes\n + @ref _enumBase\n + @ref _specialOffsets\n + @ref _discoveringInterfaces\n + @ref _changingInterfaces\n + @ref _applicationInfo\n + @ref _childIDs\n + @ref _variants\n + @ref _iaaction-iahyperlink\n + @ref _trademark + + @section _errors Error Handling + HRESULT values are defined by the Microsoft® Win32® API. For more information, refer to + <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa378137%28v=vs.85%29.aspx"> + Interpreting HRESULT Values</a> in MSDN®. + + Note that the S_FALSE return value is considered a non-error value and the + SUCCEEDED macro will return TRUE. S_FALSE is used when there is no failure + but there was nothing valid to return, e.g. in IAccessible2::attributes when + there are no attributes. When S_FALSE is returned [out] pointer types should + be NULL and [out] longs should generally be 0, but sometimes -1 is used such + as IAccessible2::indexInParent, IAccessibleText::caretOffset, and + IAccessibleHypertext::hyperlinkIndex. + + Note that for BSTR [out] variables common COM practice is that the server does + the SysAllocString and the client does the SysFreeString. Also note that when + NULL is returned there is no need for the client to call SysFreeString. Please + refer to the documentation for each method for more details regarding error handling. + + @section _memory Memory Management + The following memory management issues should be considered: + @li Although [out] BSTR variables are declared by the client, their space is + allocated by the server. They need to be freed with SysFreeString by the + client at end of life; the same is true when BSTRs are used in structs or + arrays which are passed to the server. + @li If there is no valid [out] BSTR to return, the server should return S_FALSE and + assign NULL to the output, e.g. *theOutBSTR = NULL;. + @li COM interfaces need to be referenced with AddRef when used and dereferenced + with Release at end of life. + @li Single [out] longs, HWNDs, booleans, and structs are declared by the caller + and passed by reference. The marshaller does all the memory management. + + The following articles may be helpful for understanding memory management issues: + @li An article by Don Box in a + <a href="http://www.microsoft.com/msj/1196/activex1196.aspx">Q & A section</a> + of the November 1996 edition of the Microsoft Systems Journal. + @li A posting to a CodeGuru forum, + <a href="http://www.codeguru.com/forum/showthread.php?t=364511">Windows SDK + String: What are the rules for BSTR allocation and deallocation?</a> + + @subsection _arrayConsideration Special Consideration when using Arrays + There are several methods which return arrays. In the case of IAccessible2::relations + and IAccessibleRelation::targets the client must allocate and free the arrays. + + For the remaining methods which return arrays, the server must allocate the array + and the client must free the array when no longer needed. These methods are + IAccessible2::extendedStates, IAccessible2::localizedExtendedStates, + IAccessible2_2::relationTargetsOfType, IAccessibleAction::keyBinding, + IAccessibleHypertext2::hyperlinks, IAccessibleTable::selectedChildren, + IAccessibleTable::selectedColumns, IAccessibleTable::selectedRows, + IAccessibleTable2::selectedCells, IAccessibleTable2::selectedColumns, + IAccessibleTable2::selectedRows, IAccessibleTableCell::columnHeaderCells, + and IAccessibleTableCell::rowHeaderCells. + For those methods, the server must allocate both the top level array and any storage + associated with it, e.g. for BSTRs. The server must allocate the arrays with + CoTaskMemAlloc and any BSTRs with SysAllocString. The client must use CoTaskMemFree + to free the array and any BSTRs must be freed with SysFreeString. + + Also, the IDL for IAccessible2::extendedStates, IAccessible2::localizedExtendedStates, + IAccessibleAction::keyBinding, IAccessibleTable::selectedChildren, + IAccessibleTable::selectedColumns, and IAccessibleTable::selectedRows includes an + extraneous [in] parameter for the caller to specify the max size of the array. + This parameter will be ignored by the COM server. + + @section _indexes Zero and One Based Indexes + Unless otherwise specified all offsets and indexes are 0 based. + + @section _enumBase Enum Base + Note that enums start at 0. + + @section _specialOffsets Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods + IAccessibleText and IAccessibleEditableText can use one or more of the following + special offset values. They are defined in the ::IA2TextSpecialOffsets enum. + @li Using ::IA2_TEXT_OFFSET_LENGTH (-1) as an offset in any of the IAccessibleText or + IAccessibleEditableText methods is the same as specifying the length of the string. + @li Using ::IA2_TEXT_OFFSET_CARET (-2) as an offset for IAccessibleText::textBeforeOffset, + IAccessibleText::textAtOffset, and IAccessibleText::textAfterOffset indicates that the + text related to the physical location of the caret should be used. This is needed for + applications that consider the character offset of the end of one line (as reached by + pressing the End key) the same as the offset of the first character on the next line. + Since the same offset is associated with two different lines a special means is needed + to fetch text from the line where the caret is physically located. + + @section _discoveringInterfaces Discovery of Interfaces + In general AT (Assistive Technology) should try IAccessible2 interfaces, followed by using + the MSAA (Microsoft® Active Accessibility®) interfaces. (In cases where the an application + is known to have custom interfaces which provide information not supplied by IAccessible2 + or MSAA, then those custom interfaces can be used.) The AT can then, by default, support + unknown IAccessible2/MSAA applications, without the application developers having to request + AT vendors for support on an individual application by application basis. + + When you have a reference to an IAccessible and require a reference to an IAccessible2 use + QueryService as follows: + @code + // pAcc is a reference to the accessible object's IAccessible interface. + IServiceProvider *pService = NULL; + hr = pAcc->QueryInterface(IID_IServiceProvider, (void **)&pService); + if(SUCCEEDED(hr)) { + IAccessible2 *pIA2 = NULL; + hr = pService->QueryService(IID_IAccessible, IID_IAccessible2, (void**)&pIA2); + if (SUCCEEDED(hr) && pIA2) { + // The control supports IAccessible2. + // pIA2 is the reference to the accessible object's IAccessible2 interface. + } + } + @endcode + + @section _changingInterfaces Changing between Accessible Interfaces + Note that developers must always implement MSAA's IAccessible and, if needed, some + of the interfaces in the set of IAccessible2 interfaces. Although the IAccessible2 + IDL is coded such that IAccessible2 is a subclass of MSAA's IAccessible, none of + MSAA's IAccessible methods are redefined by IAccessible2. + + QueryService must be used to switch from a reference to an MSAA IAccessible interface + to another interface. This has been + <a href="http://www.atia.org/files/public/Introducing_IAccessibleEx.doc"> + documented</a> and the pertinent facts have been extracted below: + + @par + Why use QueryService instead of just using QueryInterface to get IAccessibleEx + directly? The reason is that since MSAA 2.0, clients don't talk to a server's + IAccessible interface directly; instead they talk to an intermediate MSAA-provided + wrapper that calls through to the original IAccessible. This wrapper provides services + such as implementing IDispatch, supplying information from MSAA 2.0's Dynamic Annotation + service, and scaling locations when running on Windows Vista with DPI scaling enabled. + QueryService is the supported way to expose additional interfaces from an existing + IAccessible and was originally used by MSHTML to expose IHTMLElement objects corresponding + to IAccessibles. QueryService is often more convenient for servers to implement than + QueryInterface because it does not have the same requirements for preserving object + identity or symmetry/transitivity as QueryInterface, so QueryService allows servers to + easily implement the interface on the same object or a separate object. The latter is + often hard to do with QueryInterface unless the original object supports aggregation. + + Two related references in MSDN® are: + @li <a href="http://msdn.microsoft.com/en-us/library/ms696078(VS.85).aspx"> + "Using QueryService to expose a native object model interface for an IAccessible object"</a> + @li <a href="http://msdn.microsoft.com/en-us/library/ms528415.aspx#acc_obj"> + "Accessing the Internet Explorer Object Associated with an Accessible Object"</a> + + Based on this information from Microsoft, QueryService must be used to switch back and forth + between a reference to an MSAA IAccessible interface and any of the IAccessible2 interfaces. + + Regarding switching between any of the IAccessible2 interfaces, applications implementing + IAccessible2 should implement the IAccessible2 interfaces on a single object since ATs + will be using QueryInterface to switch between the IAccessible2 interfaces. Implementing + the IAccessible2 interfaces on separate objects would require the use of QueryService. + There is one exception, IAccessibleApplication can be implemented on a separate object so + its common code doesn't have to be included in each accessible object. ATs should use + QueryService to access IAccessibleApplication. + + @section _applicationInfo Access to Information about the Application + Servers implementing IAccessible2 should provide access to the IAccessibleApplication + interface via QueryService from any object so that ATs can easily determine specific + information about the application such as its name or version. + + @section _childIDs Child IDs + The IAccessible2 interfaces do not support child IDs, i.e. simple child elements. + Full accessible objects must be created for each object that supports IAccessible2. + Therefore MSAA's get_accChild should never return a child ID (other than CHILDID_SELF) + for an object that implements any of the IAccessible2 interfaces. + + Microsoft's UI Automation specification has the same limitation and this was resolved + in the UI Automation Express specification by adding IAccessibleEx::GetObjectForChild + and IAccessibleEx::GetIAccessiblePair. These methods allow mapping back and forth + between an IAccessibleEx and an {IAccessible, Child ID} pair. A future version of + IAccessible2 may include similar methods to map back and forth between an IAccessible2 + and an {IAccessible, Child ID} pair. + + @section _variants VARIANTs + Some methods return a VARIANT. Implementers need to make sure that the return type is + specified, i.e. VT_I4, VT_IDISPATCH, etc. The methods that return VARIANTs are + IAccessibleHyperlink::anchor, IAccessibleHyperlink::anchorTarget, IAccessibleValue::currentValue, + IAccessibleValue::maximumValue, IAccessibleValue::minimumValue. + + @section _iaaction-iahyperlink IAccessibleHyperlink as subclass of IAccessibleAction + In this version of the IDL, IAccessibleHyperlink is a subclass of IAccessibleAction. + However, there is no practical need for that inheritance and in some cases, such as + an image map of smart tags, it doesn't make sense because such an image map doesn't + have actionable objects; it's the secondary smart tags that are actionable. As a + result, implementations should not rely on the inheritance as it may be removed in + a later version of the IDL. + + @section _trademark Trademark Attribution + The names of actual companies and products mentioned herein may be the trademarks of + their respective owners. In particular, Active Accessibility, Microsoft, MSDN, and Win32 + are trademarks of the Microsoft group of companies in the U.S.A. and/or other countries. + +**/ + + + + + + + + +/** A structure defining the locale of an accessible object. + +IAccessible2::locale returns this struct. +*/ +typedef struct IA2Locale { + BSTR language; ///< ISO 639-1 Alpha-2 two character language code + BSTR country; ///< ISO 3166-1 Alpha-2 two character country code + BSTR variant; ///< Application specific variant of the locale +} IA2Locale; + +/** @brief This interface exposes the primary set of information about an + IAccessible2 enabled accessible object. + + This interface must always be provided for objects that support some + portion of the collection of the %IAccessible2 interfaces. + + Please refer to @ref _changingInterfaces "Changing between Accessible Interfaces" + for special considerations related to use of the MSAA IAccessible interface and + the set of %IAccessible2 interfaces. + */ +[object, uuid(E89F726E-C4F4-4c19-BB19-B647D7FA8478)] +interface IAccessible2 : IAccessible +{ + + /** @brief Returns the number of accessible relations for this object. + @param [out] nRelations + @retval S_OK + */ + [propget] HRESULT nRelations + ( + [out, retval] long *nRelations + ); + + /** @brief Returns one accessible relation for this object. + @param [in] relationIndex + 0 based + @param [out] relation + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT relation + ( + [in] long relationIndex, + [out, retval] IAccessibleRelation **relation + ); + + /** @brief Returns multiple accessible relations for this object. + @param [in] maxRelations + maximum size of the array allocated by the client + @param [out] relations + The array of accessible relation objects. Note that this array is to be + allocated by the client and freed when no longer needed. Refer to @ref + _arrayConsideration "Special Consideration when using Arrays" for more details. + @param [out] nRelations + actual number of relations in the returned array (not more than maxRelations) + @retval S_OK + @retval S_FALSE if there are no relations, nRelations is set to 0 + @note As a performant alternative, client code should consider using IAccessible2_2::relationTargetsOfType. + */ + [propget] HRESULT relations + ( + [in] long maxRelations, + [out, size_is(maxRelations), length_is(*nRelations)] + IAccessibleRelation **relations, + [out, retval] long *nRelations + ); + + /** @brief Returns the role of an %IAccessible2 object. + @param [out] role + The role of an %IAccessible2 object. + @retval S_OK + @note + @li For convenience MSAA roles are also passed through this method so the + AT doesn't have to also fetch roles through MSAA's get_accRole. + @li %IAccessible2 roles should not be passed through MSAA's get_accRole. + @li For compatibility with non IAccessible2 enabled ATs, IAccessible2 + applications should also add support to get_accRole to return the closest + MSAA role or ROLE_SYSTEM_CLIENT (the MSAA defined default role) if there + is not a good match. + @li This method is missing a [propget] prefix in the IDL. The result is the + method is named role in generated C++ code instead of get_role. + */ + HRESULT role + ( + [out, retval] long *role + ); + + /** @brief Makes an object visible on the screen. + @param [in] scrollType + Defines where the object should be placed on the screen. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT scrollTo + ( + [in] enum IA2ScrollType scrollType + ); + + /** @brief Moves the top left of an object to a specified location. + + @param [in] coordinateType + Specifies whether the coordinates are relative to the screen or the parent object. + @param [in] x + Defines the x coordinate. + @param [in] y + Defines the y coordinate. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT scrollToPoint + ( + [in] enum IA2CoordinateType coordinateType, + [in] long x, + [in] long y + ); + + /** @brief Returns grouping information. + + Used for tree items, list items, tab panel labels, radio buttons, etc. + Also used for collections of non-text objects. + + @param [out] groupLevel + 1 based, 0 indicates that this value is not applicable + @param [out] similarItemsInGroup + 1 based, 0 indicates that this value is not applicable + @param [out] positionInGroup + 1 based, 0 indicates that this value is not applicable. This is an index + into the objects in the current group, not an index into all the objects + at the same group level. + @retval S_OK if at least one value is valid + @retval S_FALSE if no values are valid, [out] values are 0s + @note This method is meant to describe the nature of an object's containment + structure. It's exposed by trees, tree grids, nested lists, nested menus, + but not headings, which uses the level object attribute. It is also exposed + by radio buttons (with groupLevel == 0). + @note This is normally not implemented on a combo box to describe the nature + of its contents. Normally an AT will get that information from its child list + object. However, in some cases when non-edit combo boxes are not able to be structured + such that the list is a child of the combo box, this method is implemented on + the combo box itself. ATs can use this interface if a child list is not found. + */ + [propget] HRESULT groupPosition + ( + [out] long *groupLevel, + [out] long *similarItemsInGroup, + [out, retval] long *positionInGroup + ); + + /** @brief Returns the bit strip containing any IAccessible2 states. + + The IAccessible2 states are in addition to the MSAA states and are defined in + the IA2States enum. + + @param [out] states + @retval S_OK + */ + [propget] HRESULT states + ( + [out, retval] AccessibleStates *states + ); + + /** @brief Returns the extended role. + + An extended role is a role which is dynamically generated by the application. + It is not predefined by the %IAccessible2 specification. + + @param [out] extendedRole + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT extendedRole + ( + [out, retval] BSTR *extendedRole + ); + + /** @brief Returns the localized extended role. + @param [out] localizedExtendedRole + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT localizedExtendedRole + ( + [out, retval] BSTR *localizedExtendedRole + ); + + /** @brief Returns the number of extended states. + @param [out] nExtendedStates + @retval S_OK + */ + [propget] HRESULT nExtendedStates + ( + [out, retval] long *nExtendedStates + ); + + /** @brief Returns the extended states (array of strings). + + An extended state is a state which is dynamically generated by the application. + It is not predefined by the %IAccessible2 specification. + + @param [in] maxExtendedStates + This parameter is ignored. Refer to @ref _arrayConsideration + "Special Consideration when using Arrays" for more details. + @param [out] extendedStates + This array is allocated by the server. The client must free it with CoTaskMemFree. + @param [out] nExtendedStates + The number of extended states returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are no states, [out] values are NULL and 0 respectively + */ + [propget] HRESULT extendedStates + ( + [in] long maxExtendedStates, + [out, size_is(,maxExtendedStates), length_is(,*nExtendedStates)] BSTR **extendedStates, + [out, retval] long *nExtendedStates + ); + + /** @brief Returns the localized extended states (array of strings). + + @param [in] maxLocalizedExtendedStates + This parameter is ignored. Refer to @ref _arrayConsideration + "Special Consideration when using Arrays" for more details. + @param [out] localizedExtendedStates + This array is allocated by the server. The client must free it with CoTaskMemFree. + @param [out] nLocalizedExtendedStates + The number of localized extended states returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are no states, [out] values are NULL and 0 respectively + */ + [propget] HRESULT localizedExtendedStates + ( + [in] long maxLocalizedExtendedStates, + [out, size_is(,maxLocalizedExtendedStates), length_is(,*nLocalizedExtendedStates)] BSTR **localizedExtendedStates, + [out, retval] long *nLocalizedExtendedStates + ); + + /** @brief Returns the unique ID. + + The uniqueID is an identifier for this object, is unique within the + current window, and remains the same for the lifetime of the accessible + object. + + The uniqueID is not related to: + - the MSAA objectID which is used by the server to disambiguate between + IAccessibles per HWND or + - the MSAA childID which is used to disambiguate between children being + managed by an IAccessible. + + This value is provided so the AT can have access to a unique runtime persistent + identifier even when not handling an event for the object. + + An example of when this value is useful is if the AT wants to build a cache. + The AT could cache the uniqueIDs in addition to other data being cached. + When an event is fired the AT could map the uniqueID to its internal model. + Thus, if there's a REORDER/SHOW/HIDE event the AT knows which part of the + internal structure has been invalidated and can refetch just that part. + + This value can also be used by an AT to determine when the current control + has changed. If the role is the same for two controls that are adjacent in + the tab order, this can be used to detect the new control. + + Another use of this value by an AT is to identify when a grouping object has + changed, e.g. when moving from a radio button in one group to a radio button in a + different group. + + One means of implementing this would be to create a factory with a 32 bit number + generator and a reuse pool. The number generator would emit numbers starting + at 1. Each time an object's life cycle ended, its number would be saved into a + reuse pool. The number generator would be used whenever the reuse pool was empty. + + Another way to create a unique ID is to generate it from a pointer value, e.g. an + object's address. That would be unique because no two active objects can use the + same allocated memory space. + + @param [out] uniqueID + @retval S_OK + */ + [propget] HRESULT uniqueID + ( + [out, retval] long *uniqueID + ); + + /** @brief Returns the window handle for the parent window which contains this object. + + This is the same window handle which will be passed for any events that occur on the + object, but is cached in the accessible object for use when it would be helpful to + access the window handle in cases where an event isn't fired on this object. + + A use case is when a screen reader is grabbing an entire web page on a page load. + Without the availability of windowHandle, the AT would have to get the window handle + by using WindowFromAccessibleObject on each IAccessible, which is slow because it's + implemented by oleacc.dll as a loop which crawls up the ancestor chain and looks for + a ROLE_WINDOW object, mapping that back to a window handle. + + @param [out] windowHandle + @retval S_OK + */ + [propget] HRESULT windowHandle + ( + [out, retval] HWND *windowHandle + ); + + /** @brief Returns the index of this object in its parent object. + @param [out] indexInParent + 0 based; -1 indicates there is no parent; the upper bound is the value + returned by the parent's IAccessible::get_accChildCount. + @retval S_OK + @retval S_FALSE if no parent, [out] value is -1 + */ + [propget] HRESULT indexInParent + ( + [out, retval] long *indexInParent + ); + + /** @brief Returns the IA2Locale of the accessible object. + @param [out] locale + @retval S_OK + */ + [propget] HRESULT locale + ( + [out, retval] IA2Locale *locale + ); + + /** @brief Returns the attributes specific to this object, such as a cell's formula. + @param [out] attributes + @retval S_OK + @retval S_FALSE returned if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT attributes + ( + [out, retval] BSTR *attributes + ); + +} + +/************************************************************************* + * + * File Name (Accessible2_2.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2013 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + + +/** @brief This interface exposes the primary set of information about an + IAccessible2 enabled accessible object. + + This interface must always be provided for objects that support some + portion of the collection of the %IAccessible2 interfaces. + + Please refer to @ref _changingInterfaces "Changing between Accessible Interfaces" + for special considerations related to use of the MSAA IAccessible interface and + the set of %IAccessible2 interfaces. + */ +[object, uuid(6C9430E9-299D-4E6F-BD01-A82A1E88D3FF)] +interface IAccessible2_2 : IAccessible2 +{ + /** @brief Returns the attribute value of a specified attribute specific to this object. + @param [in] name + @param [out] attribute + @retval S_OK + @retval S_FALSE returned if there is nothing to return, [out] value is NULL. + @retval E_INVALIDARG if bad [in] passed. + @note The output value is a VARIANT. Typically it will be a VT_BSTR, but there + are some cases where it will be a VT_I4 or VT_BOOL. Refer to the <a href= + "http://www.linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2/objectattributesIAccessible2"> + Object Attributes specification</a> for more information. + */ + [propget] HRESULT attribute + ( + [in] BSTR name, + [out, retval] VARIANT *attribute + ); + + /** @brief Returns the deepest hypertext accessible in the subtree of this object, and the caret offset within it. + @param [out] accessible + @param [out] caretOffset + @retval S_OK + @retval S_FALSE returned if there is no caret in any of the objects in the subtree, [out] accessible is NULL and [out] caretOffset is -1. + */ + [propget] HRESULT accessibleWithCaret + ( + [out] IUnknown **accessible, + [out, retval] long *caretOffset + ); + + /** @brief Returns relation targets for a specified target type. + @param [in] type + The requested @ref grpRelations "relation type". + @param [in] maxTargets + The number of targets requested. 0 indicates that all targets should be returned. + @param [out] targets + This array is allocated by the server. The client must free it with CoTaskMemFree. + @param [out] nTargets + The number of targets returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are no targets, [out] values are NULL and 0 respectively. + @retval E_INVALIDARG if bad [in] passed. + */ + [propget] HRESULT relationTargetsOfType + ( + [in] BSTR type, + [in] long maxTargets, + [out, size_is(,*nTargets)] IUnknown ***targets, + [out, retval] long *nTargets + ); + +} + +/************************************************************************* + * + * File Name (AccessibleComponent.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2010 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + +/** A value specifying a color in ARGB format, where each 8 bit color component +specifies alpha, red, green, and blue respectively. The alpha value is optional. +*/ +typedef long IA2Color; + +/** @brief This interface is implemented by any object that can be rendered + on the screen. + + This interface provides the standard mechanism for an assistive technology + to retrieve information concerning the graphical representation of an object. + Coordinates used by the functions of this interface are specified in + different coordinate systems. Their scale is the same and is equal to + that of the screen coordinate system. In other words all coordinates + are measured in pixels. They differ in their respective origin: + <ul> + <li>The screen coordinate system has its origin in the upper left + corner of the current screen.</li> + <li>The origin of the parent coordinate system is the upper left corner + of the parent's bounding box. With no parent the screen coordinate + system is used instead.</li> + </ul> +*/ +[object, uuid(1546D4B0-4C98-4bda-89AE-9A64748BDDE4)] +interface IAccessibleComponent : IUnknown +{ + + /** @brief Returns the location of the upper left corner of the object's + bounding box relative to the immediate parent object. + + The coordinates of the bounding box are given relative to the parent's + coordinate system. The coordinates of the returned position are relative + to this object's parent or relative to the screen on which this object + is rendered if it has no parent. If the object is not on any screen + the returned position is (0,0). + + @param [out] x + @param [out] y + @retval S_OK + */ + [propget] HRESULT locationInParent + ( + [out] long *x, + [out, retval] long *y + ); + + /** @brief Returns the foreground color of this object. + @param [out] foreground + The returned color is the foreground color of this object or, if + that is not supported, the default foreground color. + @retval S_OK + */ + [propget] HRESULT foreground + ( + [out, retval] IA2Color *foreground + ); + + /** @brief Returns the background color of this object. + @param [out] background + The returned color is the background color of this object or, if + that is not supported, the default background color. + @retval S_OK + */ + [propget] HRESULT background + ( + [out, retval] IA2Color *background + ); +} +/************************************************************************* + * + * File Name (AccessibleValue.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2010 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + +/** @brief This interface gives access to a single numerical value. + + The %IAccessibleValue interface represents a single numerical value and should + be implemented by any class that supports numerical value like progress bars + and spin boxes. This interface lets you access the value and its upper and + lower bounds. +*/ +[object, uuid(35855B5B-C566-4fd0-A7B1-E65465600394)] +interface IAccessibleValue : IUnknown +{ + + /** @brief Returns the value of this object as a number. + + The exact return type is implementation dependent. Typical types are long and + double. + @param [out] currentValue + Returns the current value represented by this object. See the section about + @ref _variants "VARIANTs" for additional information. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is a VARIANT with vt = VT_EMPTY + */ + [propget] HRESULT currentValue + ( + [out, retval] VARIANT *currentValue + ); + + /** @brief Sets the value of this object to the given number. + + The argument is clipped to the valid interval whose upper and lower + bounds are returned by the methods IAccessibleValue::maximumValue and + IAccessibleValue::minimumValue, i.e. if it is lower than the minimum + value the new value will be the minimum and if it is greater than the + maximum then the new value will be the maximum. + + @param [in] value + The new value represented by this object. The set of admissible types for + this argument is implementation dependent. + @retval S_OK + */ + HRESULT setCurrentValue + ( + [in] VARIANT value + ); + + /** @brief Returns the maximal value that can be represented by this object. + + The type of the returned value is implementation dependent. It does not have + to be the same type as that returned by method IAccessibleValue::currentValue. + + @param [out] maximumValue + Returns the maximal value in an implementation dependent type. If this object + has no upper bound then an empty object is returned. See the section about + @ref _variants "VARIANTs" for additional information. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is a VARIANT with vt = VT_EMPTY + */ + [propget] HRESULT maximumValue + ( + [out, retval] VARIANT *maximumValue + ); + + /** @brief Returns the minimal value that can be represented by this object. + + The type of the returned value is implementation dependent. It does not have + to be the same type as that returned by method IAccessibleValue::currentValue. + + @param [out] minimumValue + Returns the minimal value in an implementation dependent type. If this object + has no lower bound then an empty object is returned. See the section about + @ref _variants "VARIANTs" for additional information. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is a VARIANT with vt = VT_EMPTY + */ + [propget] HRESULT minimumValue + ( + [out, retval] VARIANT *minimumValue + ); + +}; +/************************************************************************* + * + * File Name (AccessibleText.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2013 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + + +/** A structure containing a substring and the start and end offsets in the enclosing string. + + IAccessibleText::newText and IAccessibleText::oldText return this struct. +*/ +typedef struct IA2TextSegment { + BSTR text; ///< A copy of a segment of text taken from an enclosing paragraph. + long start; ///< Index of the first character of the segment in the enclosing text. + long end; ///< Index of the character following the last character of the segment in the enclosing text. +} IA2TextSegment; + +/** This enum defines values which specify a text boundary type. + + IA2_TEXT_BOUNDARY_SENTENCE is optional. When a method doesn't implement this + method it must return S_FALSE. Typically this feature would not be implemented + by an application. However, if the application developer was not satisfied with + how screen readers have handled the reading of sentences this boundary type + could be implemented and screen readers could use the application's version of a + sentence rather than the screen reader's. + + The rest of the boundary types must be supported. + + This enum is used in IAccessibleText::textBeforeOffset, IAccessibleText::textAtOffset, + and IAccessibleText::textAfterOffset. +*/ + +enum IA2TextBoundaryType { + IA2_TEXT_BOUNDARY_CHAR, /**< Typically, a single character is returned. In some cases more than + one character is returned, for example, when a document contains field + data such as a field containing a date, time, or footnote reference. + In this case the caret can move over several characters in one movement + of the caret. Note that after the caret moves, the caret offset changes + by the number of characters in the field, e.g. by 8 characters in the + following date: 03/26/07. */ + IA2_TEXT_BOUNDARY_WORD, /**< The range provided matches the range observed when the application + processes the Ctrl + left arrow and Ctrl + right arrow key sequences. + Typically this is from the start of one word to the start of the next, but + various applications are inconsistent in the handling of the end of a line. */ + IA2_TEXT_BOUNDARY_SENTENCE, ///< Range is from start of one sentence to the start of another sentence. + IA2_TEXT_BOUNDARY_PARAGRAPH, ///< Range is from start of one paragraph to the start of another paragraph. + IA2_TEXT_BOUNDARY_LINE, /**< Range is from start of one line to the start of another line. This + often means that an end-of-line character will appear at the end of the + range. However in the case of some applications an end-of-line character + indicates the end of a paragraph and the lines composing the paragraph, + other than the last line, do not contain an end of line character. */ + IA2_TEXT_BOUNDARY_ALL ///< Using this value will cause all text to be returned. +}; + +/** @brief This interface gives read-only access to text. + + The %IAccessibleText interface should be implemented by all components + that present textual information on the display like buttons, + text entry fields, or text portions of the document window. The interface + provides access to the text's content, attributes, and spatial location. + However, text can not be modified with this interface. That is the task + of the IAccessibleEditableText interface. + + The text length, i.e. the number of characters in the text, is + returned by IAccessibleText::nCharacters. All methods that operate + on particular characters (e.g. IAccessibleText::textAtOffset) use character + indices from 0 to length-1. All methods that operate on character positions + (e.g. IAccessibleText::text) use indices from 0 to length. + + Please note that accessible text does not necessarily support selection. + In this case it should behave as if there where no selection. An empty + selection is used for example to express the current cursor position. + + Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleText methods. + + E_FAIL is returned in the following cases + @li endOffset < startOffset + @li endoffset > length +*/ +[object, uuid(24FD2FFB-3AAD-4a08-8335-A3AD89C0FB4B)] +interface IAccessibleText : IUnknown +{ + + /** @brief Adds a text selection + @param [in] startOffset + Starting offset ( 0 based). + @param [in] endOffset + Offset of first character after new selection (0 based). + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + @note Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleText methods. + */ + HRESULT addSelection + ( + [in] long startOffset, + [in] long endOffset + ); + + /** @brief Returns text attributes. + @param [in] offset + Text offset (0 based). Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleText methods. + @param [out] startOffset + The starting offset of the character range over which all text attributes match + those of offset. (0 based) + @param [out] endOffset + The offset of the first character past the character range over which all text + attributes match those of offset. (0 based) + @param [out] textAttributes + A string of attributes describing the text. The attributes are described in the + <a href="http://www.linuxfoundation.org/en/Accessibility/IAccessible2/TextAttributes"> + text attributes specification</a> on the %IAccessible2 web site. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] values are 0s and NULL respectively + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT attributes + ( + [in] long offset, + [out] long *startOffset, + [out] long *endOffset, + [out, retval] BSTR *textAttributes + ); + + /** @brief Returns the position of the caret. + + Returns the 0-based offset of the caret within the text. If the text is + implemented as a tree of text objects with embed characters in higher levels + representing substrings of child text objects and the caret is in one of the + child text objects, then the offset in the higher level text object would be + at the embed character representing child text object that contains the caret. + + For example, if the string "one two three" is implemented as a two text objects, + with a top level text object containing an embed character "one ? three" and a + child text object containing "two" and if the caret is in the descendant object + just before the 'o' in "two", then: + <ul> + <li>the caretOffset for the "one ? three" object would be 4, matching the embed character</li> + <li>the caretOffset for "two" would be 2, matching the "o"</li> + </ul> + The caret position/offset is that of the character logically following it, e.g. + to the right of it in a left to right language, or to the left of it in a right + to left language. + @param [out] offset + The returned offset is relative to the text represented by this object. + @retval S_OK + @retval S_FALSE if the caret is not currently active on this object, i.e. the + caret is located on some other object. The returned offset value will be -1. + @note S_FALSE (and an offset of -1) will not be returned if the caret is somewhere + in the text object or one of its descendants. + */ + [propget] HRESULT caretOffset + ( + [out, retval] long *offset + ); + + + /** @brief Returns the bounding box of the specified position. + + The virtual character after the last character of the represented + text, i.e. the one at position length is a special case. It represents the + current input position and will therefore typically be queried by AT more + often than other positions. Because it does not represent an existing character + its bounding box is defined in relation to preceding characters. It should be + roughly equivalent to the bounding box of some character when inserted at the + end of the text. Its height typically being the maximal height of all the + characters in the text or the height of the preceding character, its width being + at least one pixel so that the bounding box is not degenerate. + + Note that the index 'length' is not always valid. Whether it is or not is + implementation dependent. It typically is when text is editable or otherwise + when on the screen the caret can be placed behind the text. You can be sure + that the index is valid after you have received a ::IA2_EVENT_TEXT_CARET_MOVED + event for this index. + @param [in] offset + Index of the character for which to return its bounding box. The valid range + is 0..length. Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleText methods. + @param [in] coordType + Specifies if the coordinates are relative to the screen or to the parent window. + @param [out] x + X coordinate of the top left corner of the bounding box of the referenced character. + @param [out] y + Y coordinate of the top left corner of the bounding box of the referenced character. + @param [out] width + Width of the bounding box of the referenced character. + @param [out] height + Height of the bounding box of the referenced character. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT characterExtents + ( + [in] long offset, + [in] enum IA2CoordinateType coordType, + [out] long *x, + [out] long *y, + [out] long *width, + [out, retval] long *height + ); + + + /** @brief Returns the number of active non-contiguous selections + @param [out] nSelections + @retval S_OK + */ + [propget] HRESULT nSelections + ( + [out, retval] long *nSelections + ); + + /** @brief Returns the text position for the specified screen position. + + Given a point return the zero-based index of the character under that + point. The same functionality could be achieved by using the bounding + boxes for each character as returned by IAccessibleText::characterExtents. + The method IAccessibleText::offsetAtPoint, however, can be implemented + more efficiently. + + @param [in] x + The position's x value for which to look up the index of the character that + is rendered on to the display at that point. + @param [in] y + The position's y value for which to look up the index of the character that + is rendered on to the display at that point. + @param [in] coordType + Screen coordinates or window coordinates. + @param [out] offset + Index of the character under the given point or -1 if the point + is invalid or there is no character under the point. + @retval S_OK + @retval S_FALSE if nothing to return, [out] value is -1 + + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT offsetAtPoint + ( + [in] long x, + [in] long y, + [in] enum IA2CoordinateType coordType, + [out, retval] long *offset + ); + + /** @brief Returns the character offsets of Nth active text selection + + Returns the 0-based starting and ending offsets of the Nth selection. If the + text is implemented as a tree of text objects with embed characters in higher + levels representing substrings of child text objects, consider the following. + If the starting selection offset is in one of the child text objects, then the + starting offset in the higher level text object would be at the embed character + representing the child text object that contains the starting selection offset. + If the ending selection offset is in one of the child text objects, then the + ending offset in the higher level text object would be just after the embed + character representing the child text object that contains the ending selection + offset. + + For example, if the string "one two three" is implemented as a two text objects, + with a top level text object containing an embed character "one ? three" and a + child text object containing "two" and if the selection is the string "two" then: + <ul> + <li>the startOffset for the "one ? three" object would be 4, matching the embed character and the endOffset would be 5.</li> + <li>the startOffset for the "two" object would be 0, and the endOffset would be 3</li> + </ul> + Selection offsets are that of the character logically following it, e.g. + to the right of it in a left to right language or to the left of it in a right to left language. + @param [in] selectionIndex + Index of selection (0 based). + @param [out] startOffset + 0 based offset of first selected character + @param [out] endOffset + 0 based offset of one past the last selected character. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT selection + ( + [in] long selectionIndex, + [out] long *startOffset, + [out, retval] long *endOffset + ); + + /** @brief Returns the substring between the two given indices. + + The substring starts with the character at startOffset (inclusive) and up to + the character at endOffset (exclusive), if startOffset is less or equal + endOffset. If endOffset is lower than startOffset, the result is the same + as a call with the two arguments being exchanged. + + The whole text can be requested by passing the indices zero and + IAccessibleText::nCharacters. If both indices have the same value, an empty + string is returned. + @param [in] startOffset + Index of the first character to include in the returned string. The valid range + is 0..length. + @param [in] endOffset + Index of the last character to exclude in the returned string. The valid range + is 0..length. + @param [out] text + Returns the substring starting with the character at startOffset (inclusive) + and up to the character at endOffset (exclusive), if startOffset is less than + or equal to endOffset. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + @note + @li The returned string may be longer than endOffset-startOffset bytes if text + contains multi-byte characters. + @li Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleText methods. + */ + [propget] HRESULT text + ( + [in] long startOffset, + [in] long endOffset, + [out, retval] BSTR *text + ); + + /** @brief Returns a text portion before the given position. + + Returns the substring of the specified text type that is located before the + given character and does not include it. The result of this method should be + same as a result for IAccessibleText::textAtOffset with a suitably decreased + index value. + + For example, if text type is ::IA2_TEXT_BOUNDARY_WORD, then the complete + word that is closest to and located before offset is returned. + + If the index is valid, but no text is found, S_FALSE is returned along without + values of 0, 0, and a NULL pointer. This would happen for boundary types other + than character when the text consists entirely of whitespace. + + @param [in] offset + Index of the character for which to return the text part before it. The index + character will not be part of the returned string. The valid range is 0..length. + Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleText methods. + @param [in] boundaryType + The type of the text portion to return. See ::IA2TextBoundaryType for the + complete list. + @param [out] startOffset + 0 based offset of first character. + @param [out] endOffset + 0 based offset of one past the last character. + @param [out] text + Returns the requested text portion. This portion may be empty or invalid when + no appropriate text portion is found or text type is invalid. + @retval S_OK + @retval S_FALSE if the requested boundary type is not implemented, such as + ::IA2_TEXT_BOUNDARY_SENTENCE, or if there is nothing to return; + [out] values are 0s and NULL respectively + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT textBeforeOffset + ( + [in] long offset, + [in] enum IA2TextBoundaryType boundaryType, + [out] long *startOffset, + [out] long *endOffset, + [out, retval] BSTR *text + ); + + /** @brief Returns a text portion after the given position. + + Returns the substring of the specified text type that is located after the + given character and does not include it. The result of this method should be + same as a result for IAccessibleText::textAtOffset with a suitably increased + index value. + + For example, if text type is ::IA2_TEXT_BOUNDARY_WORD, then the complete + word that is closest to and located after offset is returned. + + If the index is valid, but no text is found, S_FALSE is returned along without + values of 0, 0, and a NULL pointer. This would happen for boundary types other + than character when the text consists entirely of whitespace. + + @param [in] offset + Index of the character for which to return the text part after it. The index + character will not be part of the returned string. The valid range is 0..length. + Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleText methods. + @param [in] boundaryType + The type of the text portion to return. See ::IA2TextBoundaryType for the complete + list. + @param [out] startOffset + 0 based offset of first character. + @param [out] endOffset + 0 based offset of one past the last character. + @param [out] text + Returns the requested text portion. This portion may be empty or invalid when + no appropriate text portion is found or text type is invalid. + @retval S_OK + @retval S_FALSE if the requested boundary type is not implemented, such as + ::IA2_TEXT_BOUNDARY_SENTENCE, or if there is nothing to return; + [out] values are 0s and NULL respectively + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT textAfterOffset + ( + [in] long offset, + [in] enum IA2TextBoundaryType boundaryType, + [out] long *startOffset, + [out] long *endOffset, + [out, retval] BSTR *text + ); + + /** @brief Returns a text portion that spans the given position. + + Returns the substring defined by the specified boundary type at the specified + offset. Refer to IA2TextBoundaryType for more details. + + For the word boundary type the returned string will contain the word at the + offset if the offset is inside a word and will contain the word before the + offset if the offset is not inside a word. All offsets from the first to the + last characters of a word are considered inside the word. Boundary types of + sentence and paragraph should exhibit similar behavior. + + If the index is valid, but no text is found, S_FALSE is returned along without + values of 0, 0, and a NULL pointer. This would happen for boundary types other + than character when the text consists entirely of whitespace. + + @param [in] offset + Index of the character for which to return the text part it belongs to. The valid + range is 0..length. + Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleText methods. + @param [in] boundaryType + The type of the text portion to return. See ::IA2TextBoundaryType for the complete + list. + @param [out] startOffset + 0 based offset of first character. + @param [out] endOffset + 0 based offset of one past the last character. + @param [out] text + Returns the requested text portion. This portion may be empty or invalid when + no appropriate text portion is found or text type is invalid. + @retval S_OK + @retval S_FALSE if the requested boundary type is not implemented, such as + ::IA2_TEXT_BOUNDARY_SENTENCE, or if there is nothing to return; + [out] values are 0s and NULL respectively + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT textAtOffset + ( + [in] long offset, + [in] enum IA2TextBoundaryType boundaryType, + [out] long *startOffset, + [out] long *endOffset, + [out, retval] BSTR *text + ); + + /** @brief Unselects a range of text. + @param [in] selectionIndex + Index of selection to remove (0 based). + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT removeSelection + ( + [in] long selectionIndex + ); + + /** @brief Sets the position of the caret. + + The caret position/offset is that of the character logically following it, + e.g. to the right of it in a left to right language. + + Setting the caret position may or may not alter the current selection. A + change of the selection is notified to the accessibility event listeners with + an ::IA2_EVENT_TEXT_SELECTION_CHANGED event. + + When the new caret position differs from the old one (which, of course, is the + standard case) this is notified to the accessibility event listeners with an + ::IA2_EVENT_TEXT_CARET_MOVED event. + @param [in] offset + The new index of the caret. This caret is actually placed to the left side of + the character with that index. An index of 0 places the caret so that the next + insertion goes before the first character. An index of IAccessibleText::nCharacters + leads to insertion after the last character. Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleText methods. + @retval S_OK + @retval E_FAIL if the caret cannot be set + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT setCaretOffset + ( + [in] long offset + ); + + /** @brief Changes the bounds of an existing selection. + @param [in] selectionIndex + Index of selection to change (0 based) + @param [in] startOffset + New starting offset (0 based) + @param [in] endOffset + New ending offset (0 based) - the offset of the character just past the last character of the selection. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + @note Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleText methods. + */ + HRESULT setSelection + ( + [in] long selectionIndex, + [in] long startOffset, + [in] long endOffset + ); + + /** @brief Returns total number of characters. + + Note that this may be different than the total number of bytes required to store the + text, if the text contains multi-byte characters. + @param [out] nCharacters + @retval S_OK + */ + [propget] HRESULT nCharacters + ( + [out, retval] long *nCharacters + ); + + /** @brief Makes a specific part of string visible on screen. + @param [in] startIndex + 0 based character offset. + @param [in] endIndex + 0 based character offset - the offset of the character just past the last character of the string. + @param [in] scrollType + Defines where the object should be placed on the screen. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + @note Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleText methods. + */ + HRESULT scrollSubstringTo + ( + [in] long startIndex, + [in] long endIndex, + [in] enum IA2ScrollType scrollType + ); + + /** @brief Moves the top left of a substring to a specified location. + + @param [in] startIndex + 0 based character offset. + @param [in] endIndex + 0 based character offset - the offset of the character just past the last character of the string. + @param [in] coordinateType + Specifies whether the coordinates are relative to the screen or the parent object. + @param [in] x + Defines the x coordinate. + @param [in] y + Defines the y coordinate. + @retval S_OK + @retval S_FALSE if the object is already at the specified location. + @retval E_INVALIDARG if bad [in] passed + @note Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleText methods. + */ + HRESULT scrollSubstringToPoint + ( + [in] long startIndex, + [in] long endIndex, + [in] enum IA2CoordinateType coordinateType, + [in] long x, + [in] long y + ); + + /** @brief Returns any inserted text. + + Provided for use by the ::IA2_EVENT_TEXT_INSERTED and ::IA2_EVENT_TEXT_UPDATED + event handlers. + + This data is only guaranteed to be valid while the thread notifying the event + continues. Once the handler has returned, the validity of the data depends on + how the server manages the life cycle of its objects. Also, note that the server + may have different life cycle management strategies for controls depending on + whether or not a control manages its children. Lists, trees, and tables can have + a large number of children and thus it's possible that the child objects for those + controls would only be created as needed. Servers should document their life cycle + strategy as this will be of interest to assistive technology or script engines + accessing data out of process or from other threads. Servers only need to save the + last inserted block of text and a scope of the entire application is adequate. + + @param [out] newText + The text that was just inserted. + @retval S_OK + @retval S_FALSE If there is nothing to return, the values of IA2TextSegment + struct are set as follows: text = NULL, start = 0, end = 0. + + */ + [propget] HRESULT newText + ( + [out, retval] IA2TextSegment *newText + ); + + /** @brief Returns any removed text. + + Provided for use by the IA2_EVENT_TEXT_REMOVED/UPDATED event handlers. + + This data is only guaranteed to be valid while the thread notifying the event + continues. Once the handler has returned, the validity of the data depends on + how the server manages the life cycle of its objects. Also, note that the server + may have different life cycle management strategies for controls depending on + whether or not a control manages its children. Lists, trees, and tables can have + a large number of children and thus it's possible that the child objects for those + controls would only be created as needed. Servers should document their life cycle + strategy as this will be of interest to assistive technology or script engines + accessing data out of process or from other threads. Servers only need to save the + last removed block of text and a scope of the entire application is adequate. + + @param [out] oldText + The text that was just removed. + @retval S_OK + @retval S_FALSE If there is nothing to return, the values of IA2TextSegment + struct are set as follows: text = NULL, start = 0, end = 0. + */ + [propget] HRESULT oldText + ( + [out, retval] IA2TextSegment *oldText + ); + +} +/************************************************************************* + * + * File Name (AccessibleText2.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2013 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + + + +/** @brief This interface gives read-only access to text. + + The %IAccessibleText2 interface extends the functionality of the + %IAccessibleText interface. +*/ +[object, uuid(9690A9CC-5C80-4DF5-852E-2D5AE4189A54)] +interface IAccessibleText2 : IAccessibleText +{ + + /** @brief Returns the range and of the specified set of attributes. + + Return the range (start and end offsets) and text attributes that correspond + to the given attributes filter at the given offset. + + @param [in] offset + The offset at which to search for the attributes specified in the filter. + @param [in] filter + The requested attribute names. The filter format is "attribute1, attribute2". + @param [out] startOffset + The starting (0-based) offset of the text containing the specified attributes. + @param [out] endOffset + The (0-based) offset one past the last character of the text containing the + specified attributes. + @param [out] attributeValues + The values of the requested attributes. + @retval S_OK + @retval S_FALSE if nothing to return, [out] values are -1, -1, NULL respectively. + @retval E_INVALIDARG if bad [in] passed. + */ + [propget] HRESULT attributeRange + ( + [in] long offset, + [in] BSTR filter, + [out] long *startOffset, + [out] long *endOffset, + [out, retval] BSTR *attributeValues + ); + +} +/************************************************************************* + * + * File Name (AccessibleEditableText.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2012 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + + +/** @brief This interface provides clipboard capability to text objects. + + This interface is typically used in conjunction with the IAccessibleText + interface and complements that interface with the additional capability of + clipboard operations. Note that even a read only text object can support + the copy capability so this interface is not limited to editable objects. + + The substrings used with this interface are specified as follows: + If startOffset is less than endOffset, the substring starts with the + character at startOffset and ends with the character just before endOffset. + If endOffset is lower than startOffset, the result is the same as a call + with the two arguments exchanged. The whole text can be defined by passing + the indices zero and IAccessibleText::nCharacters. If both indices have the + same value, an empty string is defined. + + Refer to the @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about a special offset constant that can be used in %IAccessibleEditableText methods. +*/ +[object, uuid(A59AA09A-7011-4b65-939D-32B1FB5547E3)] +interface IAccessibleEditableText : IUnknown +{ + + /** @brief Copies the text range into the clipboard. + + The selection is set to the specified offsets and then selection is copied into + the system clipboard. + + @param [in] startOffset + Start index of the text to moved into the clipboard. + The valid range is 0..length. + @param [in] endOffset + End index of the text to moved into the clipboard. + The valid range is 0..length. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + @note Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleEditableText + methods. + @deprecated This function is available via the application's GUI. + */ + HRESULT copyText + ( + [in] long startOffset, + [in] long endOffset + ); + + /** @brief Deletes a range of text. + + The text between and including the two given indices is deleted + from the text represented by this object. + + @param [in] startOffset + Start index of the text to be deleted. + The valid range is 0..length. + @param [in] endOffset + End index of the text to be deleted. + The valid range is 0..length. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + @note Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleEditableText + methods. + */ + HRESULT deleteText + ( + [in] long startOffset, + [in] long endOffset + ); + + /** @brief Inserts text at the specified position. + + The specified string is inserted at the given index into the text + represented by this object. + + @param [in] offset + Index at which to insert the text. + The valid range is 0..length. + Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleEditableText + methods. + @param [in] text + Text that is inserted. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT insertText + ( + [in] long offset, + [in] BSTR *text + ); + + /** @brief Deletes a range of text and copies it to the clipboard. + + The selection is set to the specified offsets, the selection is then copied into + the system clipboard, and then the selection is deleted. + + @param [in] startOffset + Start index of the text to be deleted. + The valid range is 0..length. + @param [in] endOffset + End index of the text to be deleted. + The valid range is 0..length. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + @note Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleEditableText + methods. + @deprecated This function is available via the application's GUI. + */ + HRESULT cutText + ( + [in] long startOffset, + [in] long endOffset + ); + + /** @brief Pastes content from the clipboard. + + Any existing selection is removed, the clipboard content is then pasted into + this object's text at the given offset. This method is similar to the insertText + method. If the index is not valid the system clipboard content is not inserted. The + behavior is the same as when Ctrl+V is used, i.e. the pasted contents are not + necessarily plain text. + + @param [in] offset + Index at which to insert the content from the system clipboard into + the text represented by this object. + The valid range is 0..length. + Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleEditableText + methods. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + @deprecated This function is available via the application's GUI. + */ + HRESULT pasteText + ( + [in] long offset + ); + + /** @brief Replaces text. + + The text between the two given indices is replaced by the specified + replacement string. This method is equivalent to calling first + IAccessibleEditableText::deleteText with the two indices and then + calling IAccessibleEditableText::insertText with the replacement text + at the start index. + + @param [in] startOffset + Start index of the text to be replaced. + The valid range is 0..length. + @param [in] endOffset + End index of the text to be replaced. + The valid range is 0..length. + @param [in] text + The Text that replaces the text between the given indices. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + @note Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleEditableText + methods. + */ + HRESULT replaceText + ( + [in] long startOffset, + [in] long endOffset, + [in] BSTR *text + ); + + /** @brief Replaces the attributes of a text range by the given set of attributes. + + Sets the attributes for the text between the two given indices. The old + attributes are replaced by the new list of attributes. + + @param [in] startOffset + Start index of the text whose attributes are modified. + The valid range is 0..length. + @param [in] endOffset + End index of the text whose attributes are modified. + The valid range is 0..length. + @param [in] attributes + Set of attributes that replaces the old list of attributes of + the specified text portion. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + @note Refer to @ref _specialOffsets + "Special Offsets for use in the IAccessibleText and IAccessibleEditableText Methods" + for information about special offsets that can be used in %IAccessibleEditableText + methods. + */ + HRESULT setAttributes + ( + [in] long startOffset, + [in] long endOffset, + [in] BSTR *attributes + ); +} + +/************************************************************************* + * + * File Name (AccessibleHyperlink.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2010 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + + +/** @brief This interface represents hyperlinks. + + This interface represents a hyperlink associated with a single substring + of text or single non-text object. Non-text objects can have either a + single link or a collection of links such as when the non-text object is + an image map. + + Linked objects and anchors are implementation dependent. This interface is derived + from IAccessibleAction. IAccessibleAction::nActions is one greater than the + maximum value for the indices used with the methods of this interface. + + Furthermore, the object that implements this interface has to be connected + implicitly or explicitly with an object that implements IAccessibleText. + IAccessibleHyperlink::startIndex and IAccessibleHyperlink::endIndex are + indices with respect to the text exposed by IAccessibleText. + + This interface provides access to a single object which can have multiple actions. + An example is an image map which is an image with multiple links each of which is + associated with a separate non-overlapping area of the image. This interface could + also be applied to other kinds of objects with multiple actions such as "smart tags" + which are objects, typically strings, which have multiple actions such as + "Activate URI", "Bookmark URI", etc. + + An interesting use case is an image map where each area is associated with multiple + actions, e.g. an image map of smart tags. In this case you would have to implement + two levels of accessible hyperlinks. The first level hyperlinks would only implement + anchor and anchorTarget. The anchors would all reference the image object. The + anchorTargets would reference the second level accessible hyperlink objects. None + of the IAccessibleAction methods would be implemented on the first level hyperlink + objects. The second level hyperlink objects would implement the IAccessibleAction + methods. Their anchors would also reference the image object and their anchorTargets + would reference URLs or the objects that would be activated. + + This use case demonstrates that in some cases there is no need for IAccessibleHyperlink + to derive from IAccessibleAction. As a result it may be removed in a later version of + the IDL and it is suggested that implementations should not rely on the inheritance. + +*/ +[object, uuid(01C20F2B-3DD2-400f-949F-AD00BDAB1D41)] +interface IAccessibleHyperlink : IAccessibleAction +{ + + /** @brief Returns an object that represents the link anchor, as appropriate + for the link at the specified index. + @param [in] index + A 0 based index identifies the anchor when, as in the case of an image map, + there is more than one link represented by this object. The valid maximal + index is indicated by IAccessibleAction::nActions. + @param [out] anchor + This is an implementation dependent value. For example, for a text link this + method could return the substring of the containing string where the substring + is overridden with link behavior, and for an image link this method could return + an IUnknown VARIANT for IAccessibleImage. See the section about + @ref _variants "VARIANTs" for additional information. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT anchor + ( + [in] long index, + [out, retval] VARIANT *anchor + ); + + /** @brief Returns an object representing the target of the link, as appropriate + for the link at the specified index. + @param [in] index + A 0 based index identifies the anchor when, as in the case of an image map, + there is more than one link represented by this object. The valid maximal + index is indicated by IAccessibleAction::nActions. + @param [out] anchorTarget + This is an implementation dependent value. For example this method could + return a BSTR VARIANT of the URI. Alternatively this method could return an + IUnknown VARIANT of a COM interface representing a target object to be + activated when the link is activated. See the section about + @ref _variants "VARIANTs" for additional information. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT anchorTarget + ( + [in] long index, + [out, retval] VARIANT *anchorTarget + ); + + /** @brief Returns the 0 based character offset at which the textual representation of the hyperlink starts. + + The returned value is related to the IAccessibleText interface of the object that + owns this hyperlink. + @param [out] index + @retval S_OK + */ + [propget] HRESULT startIndex + ( + [out, retval] long *index + ); + + /** @brief Returns the 0 based character offset at which the textual representation of the hyperlink ends. + + The returned value is related to the IAccessibleText interface of the object that + owns this hyperlink. The character at the index is not part of the hypertext. + @param [out] index + @retval S_OK + */ + [propget] HRESULT endIndex + ( + [out, retval] long *index + ); + + /** @brief Returns whether the target object referenced by this link is still valid. + + This is a volatile state that may change without sending an appropriate event. + Returns TRUE if the referenced target is still valid and FALSE otherwise. + + This has also been used to indicate whether or not the URI of the anchorTarget + is malformed. + + @param [out] valid + If false, one or more of the object's links are invalid. + If true, all of the object's links are valid. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is FALSE + @note This method is not being used, is deprecated, and should not be implemented or + used. It is likely that this method will be removed in a later version of the IDL. + */ + [propget] HRESULT valid + ( + [out, retval] boolean *valid + ); +} +/************************************************************************* + * + * File Name (AccessibleHypertext.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2010 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + + + +/** @brief This interface exposes information about hypertext in a document. + + The %IAccessibleHypertext interface is the main interface to expose + hyperlinks in a document, typically a text document, that are used + to reference other documents. A typical implementation is to implement + this interface on the smallest text object such as a paragraph of text. +*/ +[object, uuid(6B4F8BBF-F1F2-418a-B35E-A195BC4103B9)] +interface IAccessibleHypertext : IAccessibleText +{ + + /** @brief Returns the number of links and link groups contained within this hypertext + paragraph. + @param [out] hyperlinkCount + The number of links and link groups within this hypertext paragraph. + Returns 0 if there is no link. + @retval S_OK + */ + [propget] HRESULT nHyperlinks + ( + [out, retval] long *hyperlinkCount + ); + + /** @brief Returns the specified link. + + The returned IAccessibleHyperlink object encapsulates the hyperlink and + provides several kinds of information describing it. + @param [in] index + This 0 based index specifies the hyperlink to return. + @param [out] hyperlink + If the given index is valid, i.e. lies in the interval from 0 to the number + of links minus one, a reference to the specified hyperlink object is returned. + If the index is invalid then a NULL pointer is returned. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT hyperlink + ( + [in] long index, + [out, retval] IAccessibleHyperlink **hyperlink + ); + + /** @brief Returns the index of the hyperlink that is associated with this character index. + + This is the case when a link spans the given character index. + @param [in] charIndex + A 0 based index of the character for which to return the link index. If + IAccessibleText is used to represent the text containing the link, then the + character index is only valid if it is greater than or equal to zero and + lower than the number of characters in the text. + @param [out] hyperlinkIndex + Returns the 0 based index of the hyperlink that is associated with this + character index, or -1 if charIndex is not on a link. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is -1 + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT hyperlinkIndex + ( + [in] long charIndex, + [out, retval] long *hyperlinkIndex + ); + +} +/************************************************************************* + * + * File Name (AccessibleHypertext2.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2013 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + + + +/** @brief This interface exposes information about hypertext in a document. + + The %IAccessibleHypertext2 interface extends the functionality of the + %IAccessibleHypertext interface. +*/ +[object, uuid(CF64D89F-8287-4B44-8501-A827453A6077)] +interface IAccessibleHypertext2 : IAccessibleHypertext +{ + + /** @brief Returns the links for this object. + + The returned IAccessibleHyperlink objects encapsulate the hyperlink and + provides several kinds of information describing it. + + @param [out] hyperlinks + This array is allocated by the server. The client must free it with CoTaskMemFree. + @param [out] nHyperlinks + The number of links returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are no links, [out] values are NULL and 0 respectively + */ + [propget] HRESULT hyperlinks + ( + [out, size_is(,*nHyperlinks)] IAccessibleHyperlink ***hyperlinks, + [out, retval] long *nHyperlinks + ); + +} +/************************************************************************* + * + * File Name (AccessibleTable.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2013 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + + + +/** @brief This interface gives access to a two-dimensional table. + + Typically all accessible objects that represent cells or cell-clusters of a table + will be at the same time children of the table. In this case IAccessible2::indexInParent + will return the child index which then can be used when calling IAccessibleTable::rowIndex + and IAccessibleTable::columnIndex. + + However, in some cases that kind of implementation will not be possible. When + the table cells are not direct children of a table, the object representing + the cell can define a "table-cell-index" object attribute identifying the 0 + based table cell index. This object attribute is obtained by parsing the + attribute string returned by IAccessible2::attributes. The "table-cell-index" + attribute can be used just like a child index of the typical case. ATs should + first test for the presence of the "table-cell-index" attribute and if it is not + present then IAccessible2::indexInParent can be used as in the typical case + where cells are direct children of the table. + + The range of valid coordinates for this interface are implementation dependent. + However, that range includes at least the intervals from the first row + or column with the index 0 up to the last (but not including) used row or column + as returned by IAccessibleTable::nRows and IAccessibleTable::nColumns. + + Note that newer implementations are now using IAccessibleTable2 and IAccessibleTableCell + rather than this interface. +*/ +[object, uuid(35AD8070-C20C-4fb4-B094-F4F7275DD469)] +interface IAccessibleTable : IUnknown +{ + + /** @brief Returns the accessible object at the specified row and column in + the table. This object could be an IAccessible or an IAccessible2. + @param [in] row + The 0 based row index for which to retrieve the cell. + @param [in] column + The 0 based column index for which to retrieve the cell. + @param [out] accessible + If both row and column index are valid then the corresponding accessible + object is returned that represents the requested cell regardless of whether + the cell is currently visible (on the screen). + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT accessibleAt + ( + [in] long row, + [in] long column, + [out, retval] IUnknown **accessible + ); + + /** @brief Returns the caption for the table. The returned object could be + an IAccessible or an IAccessible2. + @param [out] accessible + If the table has a caption then a reference to it is returned, else a NULL + pointer is returned. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT caption + ( + [out, retval] IUnknown **accessible + ); + + /** @brief Translates the given row and column indexes into the corresponding cell index. + @param [in] rowIndex + 0 based row index for the cell. + @param [in] columnIndex + 0 based column index for the cell. + @param [out] cellIndex + Returns the 0 based index of the cell at the specified row and column indexes. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is 0 + @note The returned value is not necessarily a child index of the immediate parent. + In cases where the table cells are not direct children of the table the index + is actually the cell index, i.e. conceptually it's an index into a one dimensional + array of cells laid out in row order. + */ + [propget] HRESULT childIndex + ( + [in] long rowIndex, + [in] long columnIndex, + [out, retval] long *cellIndex + ); + + /** @brief Returns the description text of the specified column in the table. + @param [in] column + The 0 based index of the column for which to retrieve the description. + @param [out] description + Returns the description text of the specified column in the table if such a + description exists. Otherwise a NULL pointer is returned. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT columnDescription + ( + [in] long column, + [out, retval] BSTR *description + ); + + /** @brief Returns the number of columns occupied by the accessible object + at the specified row and column in the table. + + The result is greater than 1 if the specified cell spans multiple columns. + @param [in] row + 0 based row index of the accessible for which to return the column extent. + @param [in] column + 0 based column index of the accessible for which to return the column extent. + @param [out] nColumnsSpanned + Returns the 1 based column extent of the specified cell. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is 0 + */ + [propget] HRESULT columnExtentAt + ( + [in] long row, + [in] long column, + [out, retval] long *nColumnsSpanned + ); + + /** @brief Returns the column headers as an %IAccessibleTable object. + + Content and size of the returned table are implementation dependent. + @param [out] accessibleTable + The column header + @param [out] startingRowIndex + The 0 based row index where the header starts, usually 0. + @retval S_OK + @retval S_FALSE if there is no header, [out] values are NULL and 0 respectively + */ + [propget] HRESULT columnHeader + ( + [out] IAccessibleTable **accessibleTable, + [out, retval] long *startingRowIndex + ); + + /** @brief Translates the given cell index into the corresponding column index. + @param [in] cellIndex + 0 based index of the cell in the parent or closest ancestor table. Typically this + is the value returned from IAccessible2::indexInParent, but in the case where the + table cells are not direct children of the table this is the cell index specified + by the "table-cell-index" object attribute obtained from parsing the attributes + string returned by calling IAccessible2::attributes on the cell object. + @param [out] columnIndex + Returns the 0 based column index of the cell of the specified child or the index of + the first column if the child spans multiple columns. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is 0 + */ + [propget] HRESULT columnIndex + ( + [in] long cellIndex, + [out, retval] long *columnIndex + ); + + /** @brief Returns the total number of columns in table + @param [out] columnCount + Number of columns in table (including columns outside the current viewport) + @retval S_OK + */ + [propget] HRESULT nColumns + ( + [out, retval] long *columnCount + ); + + /** @brief Returns the total number of rows in table + @param [out] rowCount + Number of rows in table (including rows outside the current viewport) + @retval S_OK + */ + [propget] HRESULT nRows + ( + [out, retval] long *rowCount + ); + + /** @brief Returns the total number of selected cells + @param [out] cellCount + Number of cells currently selected + @retval S_OK + */ + [propget] HRESULT nSelectedChildren + ( + [out, retval] long *cellCount + ); + + /** @brief Returns the total number of selected columns + @param [out] columnCount + Number of columns currently selected + @retval S_OK + */ + [propget] HRESULT nSelectedColumns + ( + [out, retval] long *columnCount + ); + + /** @brief Returns the total number of selected rows + @param [out] rowCount + Number of rows currently selected + @retval S_OK + */ + [propget] HRESULT nSelectedRows + ( + [out, retval] long *rowCount + ); + + /** @brief Returns the description text of the specified row in the table. + @param [in] row + The 0 based index of the row for which to retrieve the description. + @param [out] description + Returns the description text of the specified row in the table if such a + description exists. Otherwise a NULL pointer is returned. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed, [out] value is NULL + */ + [propget] HRESULT rowDescription + ( + [in] long row, + [out, retval] BSTR *description + ); + + /** @brief Returns the number of rows occupied by the accessible object + at the specified row and column in the table. + + The result is greater than 1 if the specified cell spans multiple rows. + @param [in] row + 0 based row index of the accessible for which to return the row extent. + @param [in] column + 0 based column index of the accessible for which to return the row extent. + @param [out] nRowsSpanned + Returns the row extent of the specified cell. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is 0 + */ + [propget] HRESULT rowExtentAt + ( + [in] long row, + [in] long column, + [out, retval] long *nRowsSpanned + ); + + /** @brief Returns the row headers as an %IAccessibleTable object. + + Content and size of the returned table are implementation dependent. + @param [out] accessibleTable + The row header. + @param [out] startingColumnIndex + The 0 based column index where the header starts, usually 0. + @retval S_OK + @retval S_FALSE if there is no header, [out] values are NULL and 0 respectively + */ + [propget] HRESULT rowHeader + ( + [out] IAccessibleTable **accessibleTable, + [out, retval] long *startingColumnIndex + ); + + /** @brief Translates the given cell index into a row index. + @param [in] cellIndex + 0 based index of the cell in the parent or closest ancestor table. Typically this + is the value returned from IAccessible2::indexInParent, but in the case where the + table cells are not direct children of the table this is the cell index specified + by the "table-cell-index" object attribute obtained from parsing the attributes + string returned by calling IAccessible2::attributes on the cell object. + @param [out] rowIndex + 0 based row index + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is 0 + */ + [propget] HRESULT rowIndex + ( + [in] long cellIndex, + [out, retval] long *rowIndex + ); + + /** @brief Returns a list of cell indexes currently selected (0 based). + @param [in] maxChildren + This parameter is ignored. Refer to @ref _arrayConsideration + "Special Consideration when using Arrays" for more details. + @param [out] children + An array of cell indexes of selected cells (each index is 0 based), + allocated by the server. The client must free it with CoTaskMemFree. + @param [out] nChildren + The number of cell indexes returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are none, [out] values are NULL and 0 respectively + */ + [propget] HRESULT selectedChildren + ( + [in] long maxChildren, + [out, size_is(,maxChildren), length_is(,*nChildren)] long **children, + [out, retval] long *nChildren + ); + + /** @brief Returns a list of column indexes currently selected (0 based). + @param [in] maxColumns + This parameter is ignored. Refer to @ref _arrayConsideration + "Special Consideration when using Arrays" for more details. + @param [out] columns + An array of column indexes of selected columns (each index is 0 based), allocated + by the server. The client must free it with CoTaskMemFree. + @param [out] nColumns + The number of column indexes returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are none, [out] values are NULL and 0 respectively + */ + [propget] HRESULT selectedColumns + ( + [in] long maxColumns, + [out, size_is(,maxColumns), length_is(,*nColumns)] long **columns, + [out, retval] long *nColumns + ); + + /** @brief Returns a list of row indexes currently selected (0 based). + @param [in] maxRows + This parameter is ignored. Refer to @ref _arrayConsideration + "Special Consideration when using Arrays" for more details. + @param [out] rows + An array of row indexes of selected rows (each index is 0 based), allocated + by the server. The client must free it with CoTaskMemFree. + @param [out] nRows + The number of row indexes returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are none, [out] values are NULL and 0 respectively + */ + [propget] HRESULT selectedRows + ( + [in] long maxRows, + [out, size_is(,maxRows), length_is(,*nRows)] long **rows, + [out, retval] long *nRows + ); + + /** @brief Returns the summary description of the table. The returned object could be + an IAccessible or an IAccessible2. + @param [out] accessible + Returns a reference to an implementation dependent accessible object + representing the table's summary or a NULL pointer if the table + does not support a summary. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT summary + ( + [out, retval] IUnknown **accessible + ); + + /** @brief Returns a boolean value indicating whether the specified column is + completely selected. + @param [in] column + 0 based index of the column for which to determine whether it is selected. + @param [out] isSelected + Returns TRUE if the specified column is selected completely and FALSE otherwise. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is FALSE + */ + [propget] HRESULT isColumnSelected + ( + [in] long column, + [out, retval] boolean *isSelected + ); + + /** @brief Returns a boolean value indicating whether the specified row is completely + selected. + @param [in] row + 0 based index of the row for which to determine whether it is selected. + @param [out] isSelected + Returns TRUE if the specified row is selected completely and FALSE otherwise. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is FALSE + */ + [propget] HRESULT isRowSelected + ( + [in] long row, + [out, retval] boolean *isSelected + ); + + /** @brief Returns a boolean value indicating whether the specified cell is selected. + @param [in] row + 0 based index of the row for the cell to determine whether it is selected. + @param [in] column + 0 based index of the column for the cell to determine whether it is selected. + @param [out] isSelected + Returns TRUE if the specified cell is selected and FALSE otherwise. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] value is FALSE + */ + [propget] HRESULT isSelected + ( + [in] long row, + [in] long column, + [out, retval] boolean *isSelected + ); + + /** @brief Selects a row and unselects all previously selected rows. + @param [in] row + 0 based index of the row to be selected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT selectRow + ( + [in] long row + ); + + /** @brief Selects a column and unselects all previously selected columns. + @param [in] column + 0 based index of the column to be selected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT selectColumn + ( + [in] long column + ); + + /** @brief Unselects one row, leaving other selected rows selected (if any). + @param [in] row + 0 based index of the row to be unselected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT unselectRow + ( + [in] long row + ); + + /** @brief Unselects one column, leaving other selected columns selected (if any). + @param [in] column + 0 based index of the column to be unselected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT unselectColumn + ( + [in] long column + ); + + /** @brief Given a cell index, gets the row and column indexes and extents of a cell + and whether or not it is selected. + + This is a convenience function. It is not mandatory to implement it. + @param [in] index + 0 based index of this cell in the table. + @param [out] row + 0 based row index. + @param [out] column + 0 based column index. + @param [out] rowExtents + Number of cells spanned by this cell in this row. + @param [out] columnExtents + Number of cells spanned by this cell in this column. + @param [out] isSelected + Indicates if the specified cell is selected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed, [out] values are 0s and FALSE respectively + */ + [propget] HRESULT rowColumnExtentsAtIndex + ( + [in] long index, + [out] long *row, + [out] long *column, + [out] long *rowExtents, + [out] long *columnExtents, + [out, retval] boolean *isSelected + ); + + /** @brief Returns the type and extents describing how a table changed. + + Provided for use by the IA2_EVENT_TABLE_MODEL_CHANGED event handler. + + This data is only guaranteed to be valid while the thread notifying the event + continues. Once the handler has returned, the validity of the data depends on + how the server manages the life cycle of its objects. Also, note that the server + may have different life cycle management strategies for controls depending on + whether or not a control manages its children. Lists, trees, and tables can have + a large number of children and thus it's possible that the child objects for those + controls would only be created as needed. Servers should document their life cycle + strategy as this will be of interest to assistive technology or script engines + accessing data out of process or from other threads. Servers only need to save the + most recent row and column values associated with the change and a scope of the + entire application is adequate. + + @param [out] modelChange + A struct of (type(insert, delete, update), firstRow, lastRow, firstColumn, lastColumn). + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT modelChange + ( + [out, retval] IA2TableModelChange *modelChange + ); + +} +/************************************************************************* + * + * File Name (AccessibleTable2.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2012 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + + + +/** @brief This interface gives access to a two-dimensional table. + + Please also refer to the IAccessibleTableCell interface. + + If you want to support older applications you should also support the + IAccessibleTable interface. +*/ +[object, uuid(6167f295-06f0-4cdd-a1fa-02e25153d869)] +interface IAccessibleTable2 : IUnknown +{ + + /** @brief Returns the accessible object at the specified row and column in + the table. This object could be an IAccessible or an IAccessible2. + @param [in] row + The 0 based row index for which to retrieve the cell. + @param [in] column + The 0 based column index for which to retrieve the cell. + @param [out] cell + If both row and column index are valid then the corresponding accessible + object is returned that represents the requested cell regardless of whether + the cell is currently visible (on the screen). + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT cellAt + ( + [in] long row, + [in] long column, + [out, retval] IUnknown **cell + ); + + /** @brief Returns the caption for the table. The returned object could be + an IAccessible or an IAccessible2. + @param [out] accessible + If the table has a caption then a reference to it is returned, else a NULL + pointer is returned. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @deprecated use a describedBy relation + */ + [propget] HRESULT caption + ( + [out, retval] IUnknown **accessible + ); + + /** @brief Returns the description text of the specified column in the table. + @param [in] column + The 0 based index of the column for which to retrieve the description. + @param [out] description + Returns the description text of the specified column in the table if such a + description exists. Otherwise a NULL pointer is returned. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT columnDescription + ( + [in] long column, + [out, retval] BSTR *description + ); + + + /** @brief Returns the total number of columns in table + @param [out] columnCount + Number of columns in table (including columns outside the current viewport) + @retval S_OK + */ + [propget] HRESULT nColumns + ( + [out, retval] long *columnCount + ); + + /** @brief Returns the total number of rows in table + @param [out] rowCount + Number of rows in table (including rows outside the current viewport) + @retval S_OK + */ + [propget] HRESULT nRows + ( + [out, retval] long *rowCount + ); + + /** @brief Returns the total number of selected cells + @param [out] cellCount + Number of cells currently selected + @retval S_OK + */ + [propget] HRESULT nSelectedCells + ( + [out, retval] long *cellCount + ); + + /** @brief Returns the total number of selected columns + @param [out] columnCount + Number of columns currently selected + @retval S_OK + */ + [propget] HRESULT nSelectedColumns + ( + [out, retval] long *columnCount + ); + + /** @brief Returns the total number of selected rows + @param [out] rowCount + Number of rows currently selected + @retval S_OK + */ + [propget] HRESULT nSelectedRows + ( + [out, retval] long *rowCount + ); + + /** @brief Returns the description text of the specified row in the table. + @param [in] row + The 0 based index of the row for which to retrieve the description. + @param [out] description + Returns the description text of the specified row in the table if such a + description exists. Otherwise a NULL pointer is returned. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT rowDescription + ( + [in] long row, + [out, retval] BSTR *description + ); + + /** @brief Returns a list of accessibles currently selected. + @param [out] cells + Pointer to an array of references to selected accessibles. The array is + allocated by the server with CoTaskMemAlloc and freed by the client with + CoTaskMemFree. + @param [out] nSelectedCells + The number of accessibles returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are none, [out] values are NULL and 0 respectively + */ + [propget] HRESULT selectedCells + ( + [out, size_is(,*nSelectedCells)] IUnknown ***cells, + [out, retval] long *nSelectedCells + ); + + /** @brief Returns a list of column indexes currently selected (0 based). + @param [out] selectedColumns + A pointer to an array of column indexes of selected columns (each index is + 0 based). The array is allocated by the server with CoTaskMemAlloc and + freed by the client with CoTaskMemFree. + @param [out] nColumns + The number of column indexes returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are none, [out] values are NULL and 0 respectively + */ + [propget] HRESULT selectedColumns + ( + [out, size_is(,*nColumns)] long **selectedColumns, + [out, retval] long *nColumns + ); + + /** @brief Returns a list of row indexes currently selected (0 based). + @param [out] selectedRows + An array of row indexes of selected rows (each index is 0 based). The array + is allocated by the server with CoTaskMemAlloc and freed by the client with + CoTaskMemFree. + @param [out] nRows + The number of row indexes returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there are none, [out] values are NULL and 0 respectively + */ + [propget] HRESULT selectedRows + ( + [out, size_is(,*nRows)] long **selectedRows, + [out, retval] long *nRows + ); + + /** @brief Returns the summary description of the table. The returned object could be + an IAccessible or an IAccessible2. + @param [out] accessible + Returns a reference to an implementation dependent accessible object + representing the table's summary or a NULL pointer if the table + does not support a summary. + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + @deprecated Use the labeledBy relation + */ + [propget] HRESULT summary + ( + [out, retval] IUnknown **accessible + ); + + /** @brief Returns a boolean value indicating whether the specified column is + completely selected. + @param [in] column + 0 based index of the column for which to determine whether it is selected. + @param [out] isSelected + Returns TRUE if the specified column is selected completely and FALSE otherwise. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT isColumnSelected + ( + [in] long column, + [out, retval] boolean *isSelected + ); + + /** @brief Returns a boolean value indicating whether the specified row is completely + selected. + @param [in] row + 0 based index of the row for which to determine whether it is selected. + @param [out] isSelected + Returns TRUE if the specified row is selected completely and FALSE otherwise. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + [propget] HRESULT isRowSelected + ( + [in] long row, + [out, retval] boolean *isSelected + ); + + /** @brief Selects a row and unselects all previously selected rows. + + The behavior should mimic that of the application, but for those applications + which do not have a means in the GUI to select a full row of cells the behavior + should be as follows: First any selected rows in the table are unselected. Then + the entire row of cells for the specified row is selected. If any of the + cells in the selected row span additional rows, the cells in those rows + are also selected. + @param [in] row + 0 based index of the row to be selected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT selectRow + ( + [in] long row + ); + + /** @brief Selects a column and unselects all previously selected columns. + + The behavior should mimic that of the application, but for those applications + which do not have a means in the GUI to select a full column of cells the behavior + should be as follows: First any selected columns in the table are unselected. Then + the entire column of cells for the specified column is selected. If any of the + cells in the selected column span additional columns, the cells in those columns + are also selected. + @param [in] column + 0 based index of the column to be selected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT selectColumn + ( + [in] long column + ); + + /** @brief Unselects one row, leaving other selected rows selected (if any). + + The behavior should mimic that of the application, but for those applications + which do not have a means in the GUI to unselect a full row of cells the + behavior should be as follows: The entire row of cells for the specified + row is unselected. If any of the cells in the selected row span additional + rows, the cells in those rows are also unselected. + @param [in] row + 0 based index of the row to be unselected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT unselectRow + ( + [in] long row + ); + + /** @brief Unselects one column, leaving other selected columns selected (if any). + + The behavior should mimic that of the application, but for those applications + which do not have a means in the GUI to unselect a full column of cells the + behavior should be as follows: The entire column of cells for the specified + column is unselected. If any of the cells in the selected column span additional + columns, the cells in those columns are also unselected. + @param [in] column + 0 based index of the column to be unselected. + @retval S_OK + @retval E_INVALIDARG if bad [in] passed + */ + HRESULT unselectColumn + ( + [in] long column + ); + + /** @brief Returns the type and extents describing how a table changed. + + Provided for use by the IA2_EVENT_TABLE_MODEL_CHANGED event handler. + + This data is only guaranteed to be valid while the thread notifying the event + continues. Once the handler has returned, the validity of the data depends on + how the server manages the life cycle of its objects. Also, note that the server + may have different life cycle management strategies for controls depending on + whether or not a control manages its children. Lists, trees, and tables can have + a large number of children and thus it's possible that the child objects for those + controls would only be created as needed. Servers should document their life cycle + strategy as this will be of interest to assistive technology or script engines + accessing data out of process or from other threads. Servers only need to save the + most recent row and column values associated with the change and a scope of the + entire application is adequate. + + @param [out] modelChange + A struct of (type(insert, delete, update), firstRow, lastRow, firstColumn, lastColumn). + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT modelChange + ( + [out, retval] IA2TableModelChange *modelChange + ); + +} +/************************************************************************* + * + * File Name (AccessibleTableCell.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2013 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + + +/** @brief This interface gives access to the cells of a two-dimensional table. + + Please also refer to the IAccessibleTable2 interface. + +*/ +[object, uuid(594116B1-C99F-4847-AD06-0A7A86ECE645)] +interface IAccessibleTableCell : IUnknown +{ + + /** @brief Returns the number of columns occupied by this cell accessible. + + The result is greater than 1 if the specified cell spans multiple columns. + @param [out] nColumnsSpanned + Returns the 1 based column extent of the specified cell. + @retval S_OK + */ + [propget] HRESULT columnExtent + ( + [out, retval] long *nColumnsSpanned + ); + + /** @brief Returns the column headers as an array of cell accessibles. + + @param [out] cellAccessibles + Pointer to an array of references to cell accessibles. The array is allocated + by the server. The client must free it with CoTaskMemFree. + @param [out] nColumnHeaderCells + The number of accessibles returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there is no header, [out] values are NULL and 0 respectively + */ + [propget] HRESULT columnHeaderCells + ( + [out, size_is(,*nColumnHeaderCells)] IUnknown ***cellAccessibles, + [out, retval] long *nColumnHeaderCells + ); + + /** @brief Translates this cell accessible into the corresponding column index. + + @param [out] columnIndex + Returns the 0 based column index of the cell of the specified cell or the index of + the first column if the cell spans multiple columns. + @retval S_OK + */ + [propget] HRESULT columnIndex + ( + [out, retval] long *columnIndex + ); + + /** @brief Returns the number of rows occupied by this cell accessible. + + @param [out] nRowsSpanned + Returns the row extent of the specified cell. + @retval S_OK + */ + [propget] HRESULT rowExtent + ( + [out, retval] long *nRowsSpanned + ); + + /** @brief Returns the row headers as an array of cell accessibles. + + @param [out] cellAccessibles + Pointer to an array of references to cell accessibles. The array is allocated + by the server. The client must free it with CoTaskMemFree. + @param [out] nRowHeaderCells + The number of accessibles returned; the size of the returned array. + @retval S_OK + @retval S_FALSE if there is no header, [out] values are NULL and 0 respectively + */ + [propget] HRESULT rowHeaderCells + ( + [out, size_is(,*nRowHeaderCells)] IUnknown ***cellAccessibles, + [out, retval] long *nRowHeaderCells + ); + + /** @brief Translates this cell accessible into the corresponding row index. + + @param [out] rowIndex + Returns the 0 based row index of the specified cell or the index of + the first row if the cell spans multiple rows. + @retval S_OK + */ + [propget] HRESULT rowIndex + ( + [out, retval] long *rowIndex + ); + + /** @brief Returns a boolean value indicating whether this cell is selected. + + @param [out] isSelected + Returns TRUE if the specified cell is selected and FALSE otherwise. + @retval S_OK + */ + [propget] HRESULT isSelected + ( + [out, retval] boolean *isSelected + ); + + /** @brief Gets the row and column indexes and extents of this cell accessible + and whether or not it is selected. + + This is a convenience function. It is not mandatory to implement it. + @param [out] row + 0 based row index. + @param [out] column + 0 based column index. + @param [out] rowExtents + Number of cells spanned by this cell in this row. + @param [out] columnExtents + Number of cells spanned by this cell in this column. + @param [out] isSelected + Indicates if the specified cell is selected. + @retval S_OK + */ + [propget] HRESULT rowColumnExtents + ( + [out] long *row, + [out] long *column, + [out] long *rowExtents, + [out] long *columnExtents, + [out, retval] boolean *isSelected + ); + + /** @brief Returns a reference to the accessible of the containing table. + + @param [out] table + Returns a reference to the IUnknown of the containing table. + @retval S_OK + */ + [propget] HRESULT table + ( + [out, retval] IUnknown **table + ); + +} +/************************************************************************* + * + * File Name (AccessibleImage.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2010 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + + +/** @brief This interface represents images and icons. + + This interface is used for a representation of images like icons on buttons. + %IAccessibleImage only needs to be implemented in certain situations. Some + examples are: + <ol> + <li>The accessible name and description are not enough to fully + describe the image, e.g. when the accessible description is used to define the + behavior of an actionable image and the image itself conveys semantically + significant information. + <li>The user can edit the content that includes an + image and therefore the user needs to be able to review the image's position. + </ol> +*/ +[object, uuid(FE5ABB3D-615E-4f7b-909F-5F0EDA9E8DDE)] +interface IAccessibleImage : IUnknown +{ + /** @brief Returns the localized description of the image. + @param [out] description + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT description + ( + [out, retval] BSTR *description + ); + + /** @brief Returns the coordinates of the image. + @param [in] coordinateType + Specifies whether the returned coordinates should be relative to the screen or the parent object. + @param [out] x + @param [out] y + @retval S_OK + */ + [propget] HRESULT imagePosition + ( + [in] enum IA2CoordinateType coordinateType, + [out] long *x, + [out, retval] long *y + ); + + /** @brief Returns the size of the image in units specified by parent's coordinate system. + @param [out] height + @param [out] width + @retval S_OK + */ + + [propget] HRESULT imageSize + ( + [out] long *height, + [out, retval] long *width + ); +} +/************************************************************************* + * + * File Name (AccessibleEventID.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2010 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + +/** %IAccessible2 specific event constants + + This enum defines the event IDs fired by %IAccessible2 objects. The event IDs + are in addition to those used by MSAA. +*/ +enum IA2EventID { + + /** The change of the number or attributes of actions of an accessible + object is signaled by events of this type. + */ + IA2_EVENT_ACTION_CHANGED = 0x101, + + /** <b>Deprecated.</b> The active descendant of a component has changed. + + Note: This event constant is misspelled and thus is deprecated and will be + removed in a later version. Please use the correctly spelled version which + follows. + */ + IA2_EVENT_ACTIVE_DECENDENT_CHANGED, + + /** The active descendant of a component has changed. The active descendant + is used in objects with transient children. + + Note: Due to the fact that MSAA's WinEvents don't allow the active child index + to be passed on the IA2_EVENT_ACTIVE_DESCENDANT_CHANGED event the manages + descendants scheme can't be used. Instead the active child object has to fire + MSAA's EVENT_OBJECT_FOCUS. In a future release a new event mechanism may be + added to provide for event specific data to be passed with the event. At that + time the IA2_EVENT_ACTIVE_DECENDENT_CHANGED event and + IA2_STATE_MANAGES_DESCENDANTS state would be useful. + */ + IA2_EVENT_ACTIVE_DESCENDANT_CHANGED = IA2_EVENT_ACTIVE_DECENDENT_CHANGED, + + /** The document wide attributes of the document object have changed. + */ + IA2_EVENT_DOCUMENT_ATTRIBUTE_CHANGED, + + /** The contents of the document have changed. + */ + IA2_EVENT_DOCUMENT_CONTENT_CHANGED, + + /** The loading of the document has completed. + */ + IA2_EVENT_DOCUMENT_LOAD_COMPLETE, + + /** The loading of the document was interrupted. + */ + IA2_EVENT_DOCUMENT_LOAD_STOPPED, + + /** The document contents are being reloaded. + */ + IA2_EVENT_DOCUMENT_RELOAD, + + /** The ending index of this link within the containing string has changed. + */ + IA2_EVENT_HYPERLINK_END_INDEX_CHANGED, + + /** The number of anchors associated with this hyperlink object has changed. + */ + IA2_EVENT_HYPERLINK_NUMBER_OF_ANCHORS_CHANGED, + + /** The hyperlink selected state changed from selected to unselected or + from unselected to selected. + */ + IA2_EVENT_HYPERLINK_SELECTED_LINK_CHANGED, + + /** One of the links associated with the hypertext object has been activated. + */ + IA2_EVENT_HYPERTEXT_LINK_ACTIVATED, + + /** One of the links associated with the hypertext object has been selected. + */ + IA2_EVENT_HYPERTEXT_LINK_SELECTED, + + /** The starting index of this link within the containing string has changed. + */ + IA2_EVENT_HYPERLINK_START_INDEX_CHANGED, + + /** Focus has changed from one hypertext object to another, or focus moved + from a non-hypertext object to a hypertext object, or focus moved from a + hypertext object to a non-hypertext object. + */ + IA2_EVENT_HYPERTEXT_CHANGED, + + /** The number of hyperlinks associated with a hypertext object changed + */ + IA2_EVENT_HYPERTEXT_NLINKS_CHANGED, + + /** An object's attributes changed. + Also see ::IA2_EVENT_TEXT_ATTRIBUTE_CHANGED. + */ + IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED, + + /** A slide changed in a presentation document or a page boundary was + crossed in a word processing document. + */ + IA2_EVENT_PAGE_CHANGED, + + /** The caret moved from one section to the next. + */ + IA2_EVENT_SECTION_CHANGED, + + /** A table caption changed. + */ + IA2_EVENT_TABLE_CAPTION_CHANGED, + + /** A table's column description changed. + */ + IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED, + + /** A table's column header changed. + */ + IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED, + + /** A table's data changed. + */ + IA2_EVENT_TABLE_MODEL_CHANGED, + + /** A table's row description changed. + */ + IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED, + + /** A table's row header changed. + */ + IA2_EVENT_TABLE_ROW_HEADER_CHANGED, + + /** A table's summary changed. + */ + IA2_EVENT_TABLE_SUMMARY_CHANGED, + + /** A text object's attributes changed. + Also see ::IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED. + */ + IA2_EVENT_TEXT_ATTRIBUTE_CHANGED, + + /** The caret has moved to a new position. + */ + IA2_EVENT_TEXT_CARET_MOVED, + + /** <b>Deprecated.</b> This event is equivalent to ::IA2_EVENT_TEXT_UPDATED. + */ + IA2_EVENT_TEXT_CHANGED, + + /** The caret moved from one column to the next. + */ + IA2_EVENT_TEXT_COLUMN_CHANGED, + + /** Text was inserted. + */ + IA2_EVENT_TEXT_INSERTED, + + /** Text was removed. + */ + IA2_EVENT_TEXT_REMOVED, + + /** This event indicates general text changes, i.e. changes to text that are + exposed through the IAccessibleText interface. For compatibility with ATK/AT-SPI + which does not have an equivalent event, servers can alternatively fire + ::IA2_EVENT_TEXT_REMOVED and ::IA2_EVENT_TEXT_INSERTED. + */ + IA2_EVENT_TEXT_UPDATED, + + /** The text selection changed. Later versions of Microsoft development environments + have an equivalent event identified, EVENT_OBJECT_TEXTSELECTIONCHANGED. Servers + should use that if it is available and use IA2_EVENT_TEXT_SELECTION_CHANGED otherwise. + Clients should be prepared to respond to either event. + + */ + IA2_EVENT_TEXT_SELECTION_CHANGED, + + /** A visible data event indicates the change of the visual appearance + of an accessible object. This includes for example most of the + attributes available via the IAccessibleComponent interface. + */ + IA2_EVENT_VISIBLE_DATA_CHANGED + +}; +/************************************************************************* + * + * File Name (AccessibleApplication.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2010 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + + +/** @brief This interface gives access to the application's name and version information. + + This interface provides the AT with the information it needs to differentiate + this application from other applications, from other versions of this + application, or from other versions of this application running on different + versions of an accessibility bridge or accessibility toolkit. + + Servers implementing IAccessible2 should provide access to the %IAccessibleApplication + interface via QueryService from any object so that ATs can easily determine specific + information about the application such as its name or version. +*/ +[object, uuid(D49DED83-5B25-43F4-9B95-93B44595979E)] +interface IAccessibleApplication : IUnknown +{ + + /** @brief Returns the application name. + @param [out] name + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT appName + ( + [out, retval] BSTR *name + ); + + /** @brief Returns the application version. + @param [out] version + The version string must not contain levels when it is know beforehand that + this information will never require a change in a client's behavior. + For example, use "3.6.0" rather than "3.6.0.v201005131500". + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT appVersion + ( + [out, retval] BSTR *version + ); + + /** @brief Returns the toolkit/bridge name. + @param [out] name + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT toolkitName + ( + [out, retval] BSTR *name + ); + + /** @brief Returns the toolkit/bridge version. + @param [out] version + The version string must not contain levels when it is know beforehand that + this information will never require a change in a client's behavior. + For example, use "3.6.0" rather than "3.6.0.v201005131500". + @retval S_OK + @retval S_FALSE if there is nothing to return, [out] value is NULL + */ + [propget] HRESULT toolkitVersion + ( + [out, retval] BSTR *version + ); + +} + +/************************************************************************* + * + * File Name (AccessibleDocument.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2013 Linux Foundation + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + + + + + +/** @brief This interface represents documents. + + This interface is used for a representation of documents. +*/ +[object, uuid(C48C7FCF-4AB5-4056-AFA6-902D6E1D1149)] +interface IAccessibleDocument : IUnknown +{ + /** @brief Returns the most recently used anchor target within a document. + + A document's most recently targeted in-page anchor is returned. A typical use + of this method is to fetch the anchor target within an HTML document. In this + case anchor targets are those which have been defined with the <a> tag. + + @param [out] accessible + @retval S_OK + @retval S_FALSE if there are no existing valid anchor targets, [out] value is NULL. + */ + [propget] HRESULT anchorTarget + ( + [out, retval] IUnknown **accessible + ); + +} +/************************************************************************* + * + * File Name (IA2TypeLibrary.idl) + * + * IAccessible2 IDL Specification + * + * Copyright (c) 2007, 2012 Linux Foundation + * Copyright (c) 2006 IBM Corporation + * Copyright (c) 2000, 2006 Sun Microsystems, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the Linux Foundation nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This BSD License conforms to the Open Source Initiative "Simplified + * BSD License" as published at: + * http://www.opensource.org/licenses/bsd-license.php + * + * IAccessible2 is a trademark of the Linux Foundation. The IAccessible2 + * mark may be used in accordance with the Linux Foundation Trademark + * Policy to indicate compliance with the IAccessible2 specification. + * + ************************************************************************/ + +// This is not a standalone file. It is to be appended to the end of the +// merged IDL file. + +cpp_quote("") +cpp_quote("// Type Library Definitions") +cpp_quote("") + +[ + uuid(CE3F726E-D1D3-44FE-B995-FF1DB3B48B2B), + helpstring("IAccessible2 Type Library"), + version(1.3), + hidden +] + +library IAccessible2Lib +{ + importlib ("stdole2.tlb"); + importlib ("oleacc.dll"); + interface IAccessible2; + interface IAccessible2_2; + interface IAccessibleAction; + interface IAccessibleApplication; + interface IAccessibleComponent; + interface IAccessibleDocument; + interface IAccessibleEditableText; + interface IAccessibleHyperlink; + interface IAccessibleHypertext; + interface IAccessibleHypertext2; + interface IAccessibleImage; + interface IAccessibleRelation; + interface IAccessibleTable; + interface IAccessibleTable2; + interface IAccessibleTableCell; + interface IAccessibleText; + interface IAccessibleText2; + interface IAccessibleValue; + enum IA2CoordinateType; + enum IA2EventID; + enum IA2Role; + enum IA2ScrollType; + enum IA2States; + enum IA2TableModelChangeType; + enum IA2TextBoundaryType; + enum IA2TextSpecialOffsets; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccComponentEventListener.cxx b/winaccessibility/source/service/AccComponentEventListener.cxx new file mode 100644 index 000000000..f2a649a05 --- /dev/null +++ b/winaccessibility/source/service/AccComponentEventListener.cxx @@ -0,0 +1,325 @@ +/* -*- 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/XAccessible.hpp> +#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/accessibility/XAccessibleEventBroadcaster.hpp> + +#include <vcl/svapp.hxx> + +#include <AccComponentEventListener.hxx> +#include <AccObjectManagerAgent.hxx> +#include <unomsaaevent.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; + +AccComponentEventListener::AccComponentEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent) + :AccEventListener(pAcc, Agent) +{ +} + +AccComponentEventListener::~AccComponentEventListener() +{ +} + +/** + * Uno's event notifier when event is captured + * + * @param AccessibleEventObject the event object which contains information about event + */ +void AccComponentEventListener::notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) +{ + SolarMutexGuard g; + + switch (aEvent.EventId) + { + case AccessibleEventId::VALUE_CHANGED: + HandleValueChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::ACTION_CHANGED: + HandleActionChangedEvent(); + break; + case AccessibleEventId::TEXT_CHANGED: + HandleTextChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::CARET_CHANGED: + HandleCaretChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::VISIBLE_DATA_CHANGED: + HandleVisibleDataChangedEvent(); + break; + case AccessibleEventId::BOUNDRECT_CHANGED: + HandleBoundrectChangedEvent(); + break; + case AccessibleEventId::SELECTION_CHANGED: + HandleSelectionChangedEventNoArgs(); + break; + //to add TEXT_SELECTION_CHANGED event + case AccessibleEventId::TEXT_SELECTION_CHANGED: + HandleTextSelectionChangedEvent(); + break; + //End + default: + AccEventListener::notifyEvent(aEvent); + break; + } +} + +/** + * handle the VALUE_CHANGED event + * + * @param oldValue the old value of the source of event + * @param newValue the new value of the source of event + */ +void AccComponentEventListener::HandleValueChangedEvent(Any, Any) +{ + pAgent->UpdateValue(m_xAccessible.get()); + pAgent->NotifyAccEvent(UnoMSAAEvent::OBJECT_VALUECHANGE, m_xAccessible.get()); +} + +/** + * handle the NAME_CHANGED event + */ +void AccComponentEventListener::HandleActionChangedEvent() +{ + pAgent->UpdateAction(m_xAccessible.get()); + pAgent->NotifyAccEvent(UnoMSAAEvent::OBJECT_DEFACTIONCHANGE, m_xAccessible.get()); +} + +/** + * handle the TEXT_CHANGED event + * + * @param oldValue the old value of the source of event + * @param newValue the new value of the source of event + */ +void AccComponentEventListener::HandleTextChangedEvent(Any, Any newValue) +{ + pAgent->UpdateValue(m_xAccessible.get(), newValue); + pAgent->NotifyAccEvent(UnoMSAAEvent::OBJECT_VALUECHANGE, m_xAccessible.get()); +} + +/** + * handle the CARET_CHANGED event + * + * @param oldValue the old value of the source of event + * @param newValue the new value of the source of event + */ +void AccComponentEventListener::HandleCaretChangedEvent(Any, Any) +{ + pAgent->NotifyAccEvent(UnoMSAAEvent::OBJECT_CARETCHANGE, m_xAccessible.get()); +} + +/** + * set the new state and fire the MSAA event + * + * @param state new state id + * @param enable true if state is set, false if state is unset + */ +void AccComponentEventListener::SetComponentState(short state, bool enable) +{ + // only the following state can be fired state event. + switch (state) + { + case AccessibleStateType::CHECKED: + case AccessibleStateType::PRESSED: + case AccessibleStateType::SELECTED: + case AccessibleStateType::ARMED: + case AccessibleStateType::INDETERMINATE: + case AccessibleStateType::SHOWING: + FireStatePropertyChange(state, enable); + break; + case AccessibleStateType::VISIBLE: + if (GetRole() == AccessibleRole::MENU_ITEM) + { + if(enable) + { + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE); + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSABLE); + } + else + { + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE); + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSABLE); + } + } + else + { + FireStatePropertyChange(state, enable); + } + break; + case AccessibleStateType::FOCUSED: + FireStateFocusedChange(enable); + break; + case AccessibleStateType::ENABLED: + if(enable) + { + pAgent->UpdateState(m_xAccessible.get()); + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::DEFUNC); + // 8. label should have no FOCUSABLE state, Firefox has READONLY state, we can also have. + if ( GetRole() != AccessibleRole::LABEL + && GetRole() != AccessibleRole::STATIC + && GetRole() != AccessibleRole::SCROLL_BAR) + { + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSABLE); + } + } + else + { + pAgent->UpdateState(m_xAccessible.get()); + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::DEFUNC); + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSABLE); + } + break; + case AccessibleStateType::ACTIVE: + // Only frames should be active + // no msaa state mapping + break; + default: + break; + } +} + +/** + * fire the MSAA state changed event + * + * @param state the state id + * @param set true if state is set, false if state is unset + */ +void AccComponentEventListener::FireStatePropertyChange(short state, bool set) +{ + if( set) + { + // new value + switch(state) + { + case AccessibleStateType::CHECKED: + case AccessibleStateType::INDETERMINATE: + pAgent->IncreaseState(m_xAccessible.get(), state); + pAgent->UpdateAction(m_xAccessible.get()); + + if (!pAgent->IsSpecialToolbarItem(m_xAccessible.get())) + { + pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_CHECKED, m_xAccessible.get()); + } + break; + case AccessibleStateType::PRESSED: + pAgent->IncreaseState(m_xAccessible.get(), state); + pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_PRESSED, m_xAccessible.get()); + break; + case AccessibleStateType::SELECTED: + pAgent->IncreaseState(m_xAccessible.get(), state); + break; + case AccessibleStateType::ARMED: + pAgent->IncreaseState(m_xAccessible.get(), state); + pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_ARMED, m_xAccessible.get()); + break; + case AccessibleStateType::SHOWING: + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::DEFUNC); + // UNO !SHOWING == MSAA OFFSCREEN + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::SHOWING ); + break; + case AccessibleStateType::VISIBLE: + // UNO !VISIBLE == MSAA INVISIBLE + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE ); + break; + default: + break; + } + } + else + { + // old value + switch(state) + { + case AccessibleStateType::CHECKED: + case AccessibleStateType::INDETERMINATE: + pAgent->DecreaseState(m_xAccessible.get(), state); + pAgent->UpdateAction(m_xAccessible.get()); + + if (!pAgent->IsSpecialToolbarItem(m_xAccessible.get())) + { + pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_CHECKED, m_xAccessible.get()); + } + break; + case AccessibleStateType::PRESSED: + pAgent->DecreaseState(m_xAccessible.get(), state); + pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_PRESSED, m_xAccessible.get()); + break; + case AccessibleStateType::SELECTED: + pAgent->DecreaseState(m_xAccessible.get(), state); + //if the state is unset, no need to send MSAA SELECTION event + //pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_SELECTED, m_xAccessible.get()); + break; + case AccessibleStateType::ARMED: + { + pAgent->DecreaseState(m_xAccessible.get(), state); + //if the state is unset, no need to send MSAA MENU event + //pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_ARMED, m_xAccessible.get()); + } + break; + case AccessibleStateType::SHOWING: + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::DEFUNC); + // UNO !SHOWING == MSAA OFFSCREEN + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::SHOWING); + break; + case AccessibleStateType::VISIBLE: + // UNO !VISIBLE == MSAA INVISIBLE + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE); + break; + + default: + break; + } + } +} + +/** + * handle the focused event + * + * @param enable true if get focus, false if lose focus + */ +void AccComponentEventListener::FireStateFocusedChange(bool enable) +{ + if(enable) + { + if (GetParentRole() != AccessibleRole::COMBO_BOX) + pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_FOCUSED, m_xAccessible.get()); + } + else + { + //if lose focus, no need to send MSAA FOCUS event + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSED); + } +} + +void AccComponentEventListener::HandleSelectionChangedEventNoArgs() +{ + pAgent->NotifyAccEvent(UnoMSAAEvent::SELECTION_CHANGED, m_xAccessible.get()); +} + +//add TEXT_SELECTION_CHANGED event +void AccComponentEventListener::HandleTextSelectionChangedEvent() +{ + pAgent->NotifyAccEvent(UnoMSAAEvent::TEXT_SELECTION_CHANGED, m_xAccessible.get()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccContainerEventListener.cxx b/winaccessibility/source/service/AccContainerEventListener.cxx new file mode 100644 index 000000000..aa7a016e2 --- /dev/null +++ b/winaccessibility/source/service/AccContainerEventListener.cxx @@ -0,0 +1,552 @@ +/* -*- 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/XAccessible.hpp> +#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/accessibility/XAccessibleEventBroadcaster.hpp> + +#include <vcl/svapp.hxx> + +#include <AccContainerEventListener.hxx> +#include <AccObjectManagerAgent.hxx> +#include <unomsaaevent.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; + +AccContainerEventListener::AccContainerEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent) + :AccEventListener(pAcc, Agent) +{ +} + +AccContainerEventListener::~AccContainerEventListener() +{ +} + +/** + * Uno's event notifier when event is captured + * + * @param AccessibleEventObject the event object which contains information about event + */ +void AccContainerEventListener::notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) +{ + SolarMutexGuard g; + + switch (aEvent.EventId) + { + case AccessibleEventId::CHILD: + HandleChildChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::SELECTION_CHANGED: + HandleSelectionChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::INVALIDATE_ALL_CHILDREN: + HandleAllChildrenChangedEvent(); + break; + case AccessibleEventId::TEXT_CHANGED: + HandleTextChangedEvent(aEvent.OldValue, aEvent.NewValue); + [[fallthrough]]; //TODO ??? + case AccessibleEventId::VISIBLE_DATA_CHANGED: + HandleVisibleDataChangedEvent(); + break; + case AccessibleEventId::BOUNDRECT_CHANGED: + HandleBoundrectChangedEvent(); + break; + case AccessibleEventId::STATE_CHANGED: + HandleStateChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::VALUE_CHANGED: + HandleValueChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::SELECTION_CHANGED_ADD: + HandleSelectionChangedAddEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::SELECTION_CHANGED_REMOVE: + HandleSelectionChangedRemoveEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::SELECTION_CHANGED_WITHIN: + HandleSelectionChangedWithinEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::PAGE_CHANGED: + HandlePageChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::SECTION_CHANGED: + HandleSectionChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::COLUMN_CHANGED: + HandleColumnChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + default: + AccEventListener::notifyEvent(aEvent); + break; + } +} + +void AccContainerEventListener::HandleStateChangedEvent(Any oldValue, Any newValue) +{ + short State; + if( newValue >>= State) + { + SetComponentState(State, true); + } + else if (oldValue >>= State) + { + SetComponentState(State, false); + } + +} + +/** + * handle the CHILD event + * @param oldValue the child to be deleted + * @param newValue the child to be added + */ +void AccContainerEventListener::HandleChildChangedEvent(Any oldValue, Any newValue) +{ + Reference< XAccessible > xChild; + if( newValue >>= xChild) + { + //create a new child + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + //add this child + + if (pAgent->InsertAccObj(pAcc, m_xAccessible.get())) + { + //add all oldValue's existing children + pAgent->InsertChildrenAccObj(pAcc); + pAgent->NotifyAccEvent(UnoMSAAEvent::CHILD_ADDED, pAcc); + } + } + } + else if (oldValue >>= xChild) + { + //delete an existing child + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + pAgent->NotifyAccEvent(UnoMSAAEvent::CHILD_REMOVED, pAcc); + //delete all oldValue's existing children + pAgent->DeleteChildrenAccObj( pAcc ); + //delete this child + pAgent->DeleteAccObj( pAcc ); + + } + } + +} + +/** + * handle the SELECTION_CHANGED event + * @param oldValue the old value of the source of event + * @param newValue the new value of the source of event + */ +void AccContainerEventListener::HandleSelectionChangedEvent(const Any& /*oldValue*/, const Any& newValue) +{ + if (NotifyChildEvent(UnoMSAAEvent::SELECTION_CHANGED, newValue)) + { + return ; + } + + //menu bar does not process selection change event,just same as word behavior + if (GetRole()!=AccessibleRole::MENU_BAR) + pAgent->NotifyAccEvent(UnoMSAAEvent::SELECTION_CHANGED, m_xAccessible.get()); +} + +/** + * handle the INVALIDATE_ALL_CHILDREN event + */ +void AccContainerEventListener::HandleAllChildrenChangedEvent() +{ + //TODO: update all the children + if (m_xAccessible.is()) + { + //delete all oldValue's existing children + pAgent->DeleteChildrenAccObj(m_xAccessible.get()); + //add all oldValue's existing children + pAgent->InsertChildrenAccObj(m_xAccessible.get()); + pAgent->NotifyAccEvent(UnoMSAAEvent::OBJECT_REORDER, m_xAccessible.get()); + } +} + +/** + * handle the TEXT_CHANGED event + */ +void AccContainerEventListener::HandleTextChangedEvent(Any, Any newValue) +{ + pAgent->UpdateValue(m_xAccessible.get(), newValue); + pAgent->NotifyAccEvent(UnoMSAAEvent::OBJECT_TEXTCHANGE, m_xAccessible.get()); +} + +/** + * set the new state and fire the MSAA event + * @param state new state id + * @param enable true if state is set, false if state is unset + */ +void AccContainerEventListener::SetComponentState(short state, bool enable ) +{ + // only the following state can be fired state event. + + switch (state) + { + case AccessibleStateType::SELECTED: + case AccessibleStateType::BUSY: + case AccessibleStateType::INDETERMINATE: + case AccessibleStateType::OFFSCREEN: + case AccessibleStateType::FOCUSABLE: + case AccessibleStateType::SHOWING: + case AccessibleStateType::VISIBLE: + FireStatePropertyChange(state, enable); + break; + case AccessibleStateType::FOCUSED: + FireStateFocusedChange(enable); + break; + case AccessibleStateType::ENABLED: + if(enable) + { + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::DEFUNC); + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSABLE); + pAgent->UpdateState(m_xAccessible.get()); + + UpdateAllChildrenState(m_xAccessible.get()); + } + else + { + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::DEFUNC); + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSABLE); + pAgent->UpdateState(m_xAccessible.get()); + + UpdateAllChildrenState(m_xAccessible.get()); + } + break; + case AccessibleStateType::ACTIVE: + // Only frames should be active + // no msaa state mapping + //for PAGE_TAB_LIST, there will be ACTIVE state, then it should be converted to FOCUSED event. + if (GetRole() == AccessibleRole::PAGE_TAB_LIST) + { + if (!enable) /* get the active state */ + { + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSED); + } + + else /* lose the active state */ + { + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSED); + } + } + break; + + case AccessibleStateType::EXPANDED: + case AccessibleStateType::COLLAPSE: + case AccessibleStateType::CHECKED: + { + pAgent->UpdateState(m_xAccessible.get()); + pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_BUSY, m_xAccessible.get()); + break; + } + + default: + break; + } +} + +/** + * fire the MSAA state changed event + * @param state the state id + * @param set true if state is set, false if state is unset + */ +void AccContainerEventListener::FireStatePropertyChange(short state, bool set) +{ + if( set ) + { + // new value + switch(state) + { + case AccessibleStateType::SELECTED: + pAgent->IncreaseState(m_xAccessible.get(), state); + break; + case AccessibleStateType::INDETERMINATE: + case AccessibleStateType::BUSY: + case AccessibleStateType::FOCUSABLE: + case AccessibleStateType::OFFSCREEN: + pAgent->IncreaseState(m_xAccessible.get(), state); + pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_BUSY, m_xAccessible.get()); + break; + case AccessibleStateType::SHOWING: + // UNO !SHOWING == MSAA OFFSCREEN + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::SHOWING); + break; + case AccessibleStateType::VISIBLE: + // UNO !VISIBLE == MSAA INVISIBLE + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE); + break; + default: + break; + } + } + else + { + // old value + switch(state) + { + case AccessibleStateType::SELECTED: + pAgent->DecreaseState(m_xAccessible.get(), state); + break; + case AccessibleStateType::BUSY: + case AccessibleStateType::INDETERMINATE: + case AccessibleStateType::FOCUSABLE: + case AccessibleStateType::OFFSCREEN: + pAgent->DecreaseState(m_xAccessible.get(), state); + pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_BUSY, m_xAccessible.get()); + break; + case AccessibleStateType::SHOWING: + // UNO !SHOWING == MSAA OFFSCREEN + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::SHOWING); + break; + case AccessibleStateType::VISIBLE: + // UNO !VISIBLE == MSAA INVISIBLE + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE); + break; + default: + break; + } + } +} + +/** + * handle the focused event + * @param enable true if get focus, false if lose focus + */ +void AccContainerEventListener::FireStateFocusedChange(bool enable) +{ + if(enable) + { + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSED); + // if the acc role is MENU_BAR, UnoMSAAEvent::MENU_START event should be sent + // if the acc role is POPUP_MENU, UnoMSAAEvent::MENUPOPUPSTART event should be sent + short role = GetRole(); + if(role == AccessibleRole::MENU_BAR) + { + pAgent->NotifyAccEvent(UnoMSAAEvent::MENU_START, m_xAccessible.get()); + } + else if (role == AccessibleRole::POPUP_MENU) + pAgent->NotifyAccEvent(UnoMSAAEvent::MENUPOPUPSTART, m_xAccessible.get()); + //Disable the focused event on option_pane and Panel. + //only disable option_pane for toolbar has panel to get focus + else if (role == AccessibleRole::PANEL || role == AccessibleRole::OPTION_PANE ) + { + //don't send focused event on PANEL & OPTION_PANE if the parent is not toolbar + short parentRole = GetParentRole(); + if (parentRole == AccessibleRole::TOOL_BAR + || parentRole == AccessibleRole::SCROLL_PANE // sidebar + || parentRole == AccessibleRole::PANEL) // sidebar + pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_FOCUSED, m_xAccessible.get()); + } + else if (role == AccessibleRole::COMBO_BOX ) + { + //for editable combobox, send focus event on only edit control, + bool bSendFocusOnCombobox = true; + //send focused event to the first text child + Reference<XAccessibleContext> mxContext = m_xAccessible->getAccessibleContext(); + if(mxContext.is()) + { + Reference<XAccessible> mxChild = mxContext->getAccessibleChild(0); + if(mxChild.is()) + { + Reference<XAccessibleContext> mxChildContext = mxChild->getAccessibleContext(); + short childrole = mxChildContext->getAccessibleRole(); + if (childrole == AccessibleRole::TEXT) + { + if (IsEditable(mxChildContext)) + { + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSED); + pAgent->IncreaseState( mxChild.get(), AccessibleStateType::FOCUSED); + pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_FOCUSED, mxChild.get()); + bSendFocusOnCombobox = false; + } + } + } + } + if (bSendFocusOnCombobox) + pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_FOCUSED, m_xAccessible.get()); + } + else + pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_FOCUSED, m_xAccessible.get()); + } + else + { + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSED); + // if the acc role is MENU_BAR, UnoMSAAEvent::MENU_END event should be sent + // if the acc role is POPUP_MENU, UnoMSAAEvent::MENUPOPUPEND event should be sent + if (GetRole() == AccessibleRole::MENU_BAR) + { + pAgent->NotifyAccEvent(UnoMSAAEvent::MENU_END, m_xAccessible.get()); + } + else if (GetRole() == AccessibleRole::POPUP_MENU) + { + pAgent->NotifyAccEvent(UnoMSAAEvent::MENUPOPUPEND, m_xAccessible.get()); + } + } +} + +/** + * handle the VALUE_CHANGED event + * + * @param oldValue the old value of the source of event + * @param newValue the new value of the source of event + */ +void AccContainerEventListener::HandleValueChangedEvent(Any, Any) +{ + pAgent->UpdateValue(m_xAccessible.get()); + pAgent->NotifyAccEvent(UnoMSAAEvent::OBJECT_VALUECHANGE, m_xAccessible.get()); +} + +bool AccContainerEventListener::IsEditable(Reference<XAccessibleContext> const & xContext) +{ + Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet(); + if( !pRState.is() ) + return false; + + Sequence<short> pStates = pRState->getStates(); + int count = pStates.getLength(); + for( int iIndex = 0;iIndex < count;iIndex++ ) + { + if(pStates[iIndex] == AccessibleStateType::EDITABLE) + return true; + } + return false; +} + +bool AccContainerEventListener::NotifyChildEvent(UnoMSAAEvent eWinEvent, const Any& Value) +{ + Reference< XAccessible > xChild; + if(Value >>= xChild ) + { + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + pAgent->NotifyAccEvent(eWinEvent, pAcc); + return true; + } + } + return false; +} + +void AccContainerEventListener::HandleSelectionChangedAddEvent(const Any& /*oldValue*/, const Any& newValue) +{ + if (NotifyChildEvent(UnoMSAAEvent::SELECTION_CHANGED_ADD, newValue)) + { + return ; + } + pAgent->NotifyAccEvent(UnoMSAAEvent::SELECTION_CHANGED_ADD, m_xAccessible.get()); +} + +void AccContainerEventListener::HandleSelectionChangedRemoveEvent(const Any& /*oldValue*/, const Any& newValue) +{ + if (NotifyChildEvent(UnoMSAAEvent::SELECTION_CHANGED_REMOVE, newValue)) + { + return ; + } + pAgent->NotifyAccEvent(UnoMSAAEvent::SELECTION_CHANGED_REMOVE, m_xAccessible.get()); +} + +void AccContainerEventListener::HandleSelectionChangedWithinEvent(const Any& /*oldValue*/, const Any& newValue) +{ + if (NotifyChildEvent(UnoMSAAEvent::SELECTION_CHANGED_WITHIN, newValue)) + { + return ; + } + pAgent->NotifyAccEvent(UnoMSAAEvent::SELECTION_CHANGED_WITHIN, m_xAccessible.get()); +} + +void AccContainerEventListener::UpdateAllChildrenState(XAccessible* pXAccessible) +{ + Reference<css::accessibility::XAccessibleContext> xContext = pXAccessible->getAccessibleContext(); + if(!xContext.is()) + { + return; + } + css::accessibility::XAccessibleContext* pAccessibleContext = xContext.get(); + if(pAccessibleContext == nullptr) + { + return; + } + + if (pAgent && pAgent->IsStateManageDescendant(pXAccessible)) + { + return; + } + + int count = pAccessibleContext->getAccessibleChildCount(); + for (int i=0;i<count;i++) + { + Reference<css::accessibility::XAccessible> mxAccessible + = pAccessibleContext->getAccessibleChild(i); + + css::accessibility::XAccessible* mpAccessible = mxAccessible.get(); + if(mpAccessible != nullptr) + { + pAgent->UpdateState(mpAccessible); + UpdateAllChildrenState(mpAccessible); + } + } +} + +void AccContainerEventListener::HandlePageChangedEvent(const Any& /*oldValue*/, const Any& /*newValue*/) +{ + pAgent->NotifyAccEvent(UnoMSAAEvent::OBJECT_PAGECHANGED, m_xAccessible.get()); +} + +void AccContainerEventListener::HandleSectionChangedEvent(const Any& /*oldValue*/, const Any& /*newValue*/ ) +{ + pAgent->NotifyAccEvent(UnoMSAAEvent::SECTION_CHANGED, m_xAccessible.get()); +} + +void AccContainerEventListener::HandleColumnChangedEvent(const Any& /*oldValue*/, const Any& /*newValue*/) +{ + pAgent->NotifyAccEvent(UnoMSAAEvent::COLUMN_CHANGED, m_xAccessible.get()); +} + +void AccContainerEventListener::HandleNameChangedEvent( Any name ) +{ + if (GetRole() == AccessibleRole::COMBO_BOX) + { + Reference<XAccessibleContext> mxContext(m_xAccessible->getAccessibleContext()); + if(mxContext.is()) + { + Reference<XAccessible> mxChild = mxContext->getAccessibleChild(0); + if(mxChild.is()) + { + Reference<XAccessibleContext> mxChildContext = mxChild->getAccessibleContext(); + short childrole = mxChildContext->getAccessibleRole(); + if (childrole == AccessibleRole::TEXT) + { + pAgent->UpdateAccName(mxChild.get(), name); + } + } + } + } + AccEventListener::HandleNameChangedEvent(name); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccDescendantManagerEventListener.cxx b/winaccessibility/source/service/AccDescendantManagerEventListener.cxx new file mode 100644 index 000000000..c38f19e32 --- /dev/null +++ b/winaccessibility/source/service/AccDescendantManagerEventListener.cxx @@ -0,0 +1,237 @@ +/* -*- 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/XAccessible.hpp> +#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/accessibility/XAccessibleEventBroadcaster.hpp> + +#include <vcl/svapp.hxx> + +#include <AccDescendantManagerEventListener.hxx> +#include <AccObjectManagerAgent.hxx> +#include <unomsaaevent.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; + +AccDescendantManagerEventListener::AccDescendantManagerEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent) + : AccComponentEventListener(pAcc, Agent) +{ +} + +AccDescendantManagerEventListener::~AccDescendantManagerEventListener() +{ +} + +/** + * Uno's event notifier when event is captured + * @param AccessibleEventObject the event object which contains information about event + */ +void AccDescendantManagerEventListener::notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) +{ + SolarMutexGuard g; + + switch (aEvent.EventId) + { + case AccessibleEventId::SELECTION_CHANGED: + HandleSelectionChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::CHILD: + HandleChildChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS: + HandleChildChangedNoFocusEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::SELECTION_CHANGED_ADD: + HandleSelectionChangedAddEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::SELECTION_CHANGED_REMOVE: + HandleSelectionChangedRemoveEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::SELECTION_CHANGED_WITHIN: + HandleSelectionChangedWithinEvent(aEvent.OldValue, aEvent.NewValue); + break; + default: + AccComponentEventListener::notifyEvent(aEvent); + break; + } +} + +/** + * handle the CHILD event + * @param oldValue the child to be deleted + * @param newValue the child to be added + */ +void AccDescendantManagerEventListener::HandleChildChangedEvent(Any oldValue, Any newValue) +{ + + Reference< XAccessible > xChild; + if( newValue >>= xChild) + { + //create a new child + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + pAgent->InsertAccObj(pAcc, m_xAccessible.get()); + pAgent->InsertChildrenAccObj(pAcc); + + pAgent->NotifyAccEvent(UnoMSAAEvent::CHILD_ADDED, pAcc); + + } + } + + if (oldValue >>= xChild) + { + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + + pAgent->NotifyAccEvent(UnoMSAAEvent::CHILD_REMOVED, pAcc); + pAgent->DeleteChildrenAccObj( pAcc ); + pAgent->DeleteAccObj( pAcc ); + } + } + +} + +/** + * handle the SELECTION_CHANGED event + */ +void AccDescendantManagerEventListener::HandleSelectionChangedEvent(Any oldValue, Any newValue) +{ + bool bSend =false; + Reference< XAccessible > xChild; + if(newValue >>= xChild ) + { + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + //if the Role is the SC cell ,don't add the selected state. + if (pAgent->GetRole(pAcc) != AccessibleRole::TABLE_CELL) + { + pAgent->IncreaseState( pAcc, AccessibleStateType::SELECTED); + } + + pAgent->NotifyAccEvent(UnoMSAAEvent::SELECTION_CHANGED, pAcc); + bSend=true; + } + } + if(oldValue >>= xChild ) + { + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + pAgent->DecreaseState( pAcc, AccessibleStateType::SELECTED); + } + } + if (!bSend) + { + pAgent->NotifyAccEvent(UnoMSAAEvent::SELECTION_CHANGED, m_xAccessible.get()); + } +} + + +void AccDescendantManagerEventListener::HandleChildChangedNoFocusEvent(Any oldValue, Any newValue) +{ + Reference< XAccessible > xChild; + if(newValue >>= xChild ) + { + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + + pAgent->InsertAccObj(pAcc, m_xAccessible.get()); + pAgent->InsertChildrenAccObj(pAcc); + } + } + if (oldValue >>= xChild) + { + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + pAgent->DeleteChildrenAccObj( pAcc ); + pAgent->DeleteAccObj( pAcc ); + } + } +} + +bool AccDescendantManagerEventListener::NotifyChildEvent(UnoMSAAEvent eWinEvent, const Any& Value) +{ + Reference< XAccessible > xChild; + if(Value >>= xChild ) + { + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + pAgent->NotifyAccEvent(eWinEvent, pAcc); + + if (pAgent->IsStateManageDescendant(m_xAccessible.get())) + { + if (eWinEvent == UnoMSAAEvent::SELECTION_CHANGED_REMOVE) + { + // The object has just been sent in a SELECTION_CHANGED_REMOVE event + // and accessibility tools may query for the object and call methods on + // it as a response to this. + // Therefore, don't delete the object yet, but remember it for deletion + // once the next event of a different type occurs. + m_aUnselectedChildrenForDeletion.push_back(pAcc); + } + else + { + // handle any pending deletions for objects previously removed from selection + for (XAccessible* pAcc2 : m_aUnselectedChildrenForDeletion) + pAgent->DeleteAccObj(pAcc2); + m_aUnselectedChildrenForDeletion.clear(); + } + } + return true; + } + } + return false; +} +void AccDescendantManagerEventListener::HandleSelectionChangedAddEvent(const Any& /*oldValue*/, const Any &newValue) +{ + if (NotifyChildEvent(UnoMSAAEvent::SELECTION_CHANGED_ADD, newValue)) + { + return ; + } + pAgent->NotifyAccEvent(UnoMSAAEvent::SELECTION_CHANGED_ADD, m_xAccessible.get()); +} + +void AccDescendantManagerEventListener::HandleSelectionChangedRemoveEvent(const Any& /*oldValue*/, const Any &newValue) +{ + if (NotifyChildEvent(UnoMSAAEvent::SELECTION_CHANGED_REMOVE, newValue)) + { + return ; + } + pAgent->NotifyAccEvent(UnoMSAAEvent::SELECTION_CHANGED_REMOVE, m_xAccessible.get()); +} + +void AccDescendantManagerEventListener::HandleSelectionChangedWithinEvent(const Any& /*oldValue*/, const Any &newValue) +{ + if (NotifyChildEvent(UnoMSAAEvent::SELECTION_CHANGED_WITHIN, newValue)) + { + return ; + } + pAgent->NotifyAccEvent(UnoMSAAEvent::SELECTION_CHANGED_WITHIN, m_xAccessible.get()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccDialogEventListener.cxx b/winaccessibility/source/service/AccDialogEventListener.cxx new file mode 100644 index 000000000..865a039a7 --- /dev/null +++ b/winaccessibility/source/service/AccDialogEventListener.cxx @@ -0,0 +1,133 @@ +/* -*- 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/XAccessible.hpp> +#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/accessibility/XAccessibleEventBroadcaster.hpp> + +#include <vcl/svapp.hxx> + +#include <AccDialogEventListener.hxx> +#include <AccObjectManagerAgent.hxx> +#include <unomsaaevent.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; + +AccDialogEventListener::AccDialogEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent) + :AccEventListener(pAcc, Agent) +{} +AccDialogEventListener::~AccDialogEventListener() +{ +} + +/** + * Uno's event notifier when event is captured + * @param AccessibleEventObject the event object which contains information about event + */ +void AccDialogEventListener::notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) +{ + SolarMutexGuard g; + + switch (aEvent.EventId) + { + case AccessibleEventId::CHILD: + HandleChildChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::VISIBLE_DATA_CHANGED: + HandleVisibleDataChangedEvent(); + break; + case AccessibleEventId::BOUNDRECT_CHANGED: + HandleBoundrectChangedEvent(); + break; + default: + AccEventListener::notifyEvent(aEvent); + break; + } +} + +/** + * handle the CHILD event + * @param oldValue the child to be deleted + * @param newValue the child to be added + */ +void AccDialogEventListener::HandleChildChangedEvent(Any oldValue, Any newValue) +{ + Reference< XAccessible > xChild; + if( newValue >>= xChild) + { + //create a new child + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + //add this child + pAgent->InsertAccObj(pAcc, m_xAccessible.get()); + //add all oldValue's existing children + pAgent->InsertChildrenAccObj(pAcc); + pAgent->NotifyAccEvent(UnoMSAAEvent::CHILD_ADDED, pAcc); + } + } + else if (oldValue >>= xChild) + { + //delete an existing child + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + pAgent->NotifyAccEvent(UnoMSAAEvent::CHILD_REMOVED, pAcc); + //delete all oldValue's existing children + pAgent->DeleteChildrenAccObj( pAcc ); + //delete this child + pAgent->DeleteAccObj( pAcc ); + } + } + +} + +/** + * set the new state and fire the MSAA event + * @param state new state id + * @param enable true if state is set, false if state is unset + */ +void AccDialogEventListener::SetComponentState(short state, bool enable) +{ + // only the following state can be fired state event. + switch (state) + { + case AccessibleStateType::ICONIFIED: + // no msaa state mapping + break; + case AccessibleStateType::VISIBLE: + // UNO !VISIBLE == MSAA INVISIBLE + if( enable ) + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE); + else + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE); + break; + case AccessibleStateType::ACTIVE: + // Only frames should be active + // no msaa state mapping + break; + default: + break; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccEventListener.cxx b/winaccessibility/source/service/AccEventListener.cxx new file mode 100644 index 000000000..fd8636099 --- /dev/null +++ b/winaccessibility/source/service/AccEventListener.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 <cppuhelper/bootstrap.hxx> +#include <com/sun/star/bridge/XUnoUrlResolver.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include <vcl/svapp.hxx> + +#include <AccEventListener.hxx> +#include <AccObjectManagerAgent.hxx> +#include <unomsaaevent.hxx> + +#include <com/sun/star/accessibility/XAccessible.hpp> +#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/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/accessibility/XAccessibleComponent.hpp> + +#include <stdio.h> + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; +using namespace cppu; + +AccEventListener::AccEventListener(css::accessibility::XAccessible* pAcc, + AccObjectManagerAgent* Agent) + : m_xAccessible(pAcc) + , pAgent(Agent) +{ +} + +AccEventListener::~AccEventListener() {} + +/** + * Uno's event notifier when event is captured + * @param AccessibleEventObject the event object which contains information about event + */ +void AccEventListener::notifyEvent(const css::accessibility::AccessibleEventObject& aEvent) +{ + SolarMutexGuard g; + + switch (aEvent.EventId) + { + case AccessibleEventId::NAME_CHANGED: + HandleNameChangedEvent(aEvent.NewValue); + break; + case AccessibleEventId::DESCRIPTION_CHANGED: + HandleDescriptionChangedEvent(); + break; + case AccessibleEventId::STATE_CHANGED: + HandleStateChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + default: + break; + } +} + +/** + * handle the NAME_CHANGED event + * @param name the new name with changed. + */ +void AccEventListener::HandleNameChangedEvent(Any name) +{ + if (pAgent->IsTopWinAcc(m_xAccessible.get())) + { + XAccessible* pAccDoc = pAgent->GetAccDocByAccTopWin(m_xAccessible.get()); + if (pAccDoc) + { + pAgent->UpdateAccName(pAccDoc); + pAgent->NotifyAccEvent(UnoMSAAEvent::OBJECT_NAMECHANGE, pAccDoc); + } + } + + pAgent->UpdateAccName(m_xAccessible.get(), name); + pAgent->NotifyAccEvent(UnoMSAAEvent::OBJECT_NAMECHANGE, m_xAccessible.get()); +} + +/** + * handle the DESCRIPTION_CHANGED event + */ +void AccEventListener::HandleDescriptionChangedEvent() +{ + pAgent->NotifyAccEvent(UnoMSAAEvent::OBJECT_DESCRIPTIONCHANGE, m_xAccessible.get()); +} + +/** + * handle the BOUNDRECT_CHANGED event + */ +void AccEventListener::HandleBoundrectChangedEvent() +{ + AccObjectManagerAgent::UpdateLocation(m_xAccessible.get()); + pAgent->NotifyAccEvent(UnoMSAAEvent::BOUNDRECT_CHANGED, m_xAccessible.get()); +} + +/** + * handle the VISIBLE_DATA_CHANGED event + */ +void AccEventListener::HandleVisibleDataChangedEvent() +{ + pAgent->UpdateValue(m_xAccessible.get()); + pAgent->NotifyAccEvent(UnoMSAAEvent::VISIBLE_DATA_CHANGED, m_xAccessible.get()); +} + +/** + * handle the STATE_CHANGED event + * @param oldValue the old state of the source of event + * @param newValue the new state of the source of event + */ +void AccEventListener::HandleStateChangedEvent(Any oldValue, Any newValue) +{ + short newV, oldV; + if (newValue >>= newV) + { + SetComponentState(newV, true); + } + else if (oldValue >>= oldV) + { + SetComponentState(oldV, false); + } +} + +/** + * set the new state and fire the MSAA event + * @param state new state id + * @param enable true if state is set, false if state is unset + */ +void AccEventListener::SetComponentState(short state, bool enable) +{ + switch (state) + { + case AccessibleStateType::FOCUSED: + FireStateFocusedChange(enable); + break; + default: + FireStatePropertyChange(state, enable); + break; + } +} + +/** + * handle the focused event + * @param enable true if get focus, false if lose focus + */ +void AccEventListener::FireStateFocusedChange(bool enable) +{ + if (enable) + { + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSED); + pAgent->NotifyAccEvent(UnoMSAAEvent::STATE_FOCUSED, m_xAccessible.get()); + } + else + { + // no focus lost event in MSAA + } +} + +/** + * fire the MSAA state changed event + * @param state the state id + * @param set true if state is set, false if state is unset + */ +void AccEventListener::FireStatePropertyChange(short /*state*/, bool set) +{ + if (set) + { + //get new state + } + else + { + //lose old state + } +} + +/** + * get the role of accessible object which is observed + */ +short AccEventListener::GetRole() +{ + css::uno::Reference<css::accessibility::XAccessibleContext> const xContext( + m_xAccessible->getAccessibleContext()); + if (xContext.is()) + { + return xContext->getAccessibleRole(); + } + return -1; +} + +/** + * get the role of accessible parent object which is observed + */ +short AccEventListener::GetParentRole() +{ + if (m_xAccessible.is()) + { + return pAgent->GetParentRole(m_xAccessible.get()); + } + return -1; +} +/** + * remove the listener from accessible object + */ +void AccEventListener::RemoveMeFromBroadcaster() +{ + try + { + if (!m_xAccessible.is()) + { + return; + } + try + { + css::uno::Reference<XAccessibleEventBroadcaster> const xBroadcaster( + m_xAccessible->getAccessibleContext(), UNO_QUERY); + if (xBroadcaster.is()) + { + //remove the lister from accessible object + xBroadcaster->removeAccessibleEventListener(this); + } + } + catch (Exception const&) + { // may throw if it's already disposed - ignore that + } + pAgent->NotifyDestroy(m_xAccessible.get()); + m_xAccessible.clear(); // release cyclic reference + } + catch (...) + { + return; + } +} + +/** + * this method is invoked before listener is disposed + */ +void AccEventListener::disposing(const css::lang::EventObject& /*Source*/) +{ + SolarMutexGuard g; + + RemoveMeFromBroadcaster(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccFrameEventListener.cxx b/winaccessibility/source/service/AccFrameEventListener.cxx new file mode 100644 index 000000000..bae97a1ca --- /dev/null +++ b/winaccessibility/source/service/AccFrameEventListener.cxx @@ -0,0 +1,145 @@ +/* -*- 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/XAccessible.hpp> +#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/accessibility/XAccessibleEventBroadcaster.hpp> + +#include <vcl/svapp.hxx> + +#include <AccFrameEventListener.hxx> +#include <AccObjectManagerAgent.hxx> +#include <unomsaaevent.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; + +#include <vcl/window.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <vcl/sysdata.hxx> + +AccFrameEventListener::AccFrameEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent) + :AccEventListener(pAcc, Agent) +{ +} + +AccFrameEventListener::~AccFrameEventListener() +{ +} + +/** + * Uno's event notifier when event is captured + * @param AccessibleEventObject the event object which contains information about event + */ +void AccFrameEventListener::notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) +{ + SolarMutexGuard g; + + switch (aEvent.EventId) + { + case AccessibleEventId::CHILD: + HandleChildChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::VISIBLE_DATA_CHANGED: + HandleVisibleDataChangedEvent(); + break; + case AccessibleEventId::BOUNDRECT_CHANGED: + HandleBoundrectChangedEvent(); + break; + default: + AccEventListener::notifyEvent(aEvent); + break; + } +} + +/** + * handle the CHILD event + * @param oldValue the child to be deleted + * @param newValue the child to be added + */ +void AccFrameEventListener::HandleChildChangedEvent(Any oldValue, Any newValue) +{ + Reference< XAccessible > xChild; + if( newValue >>= xChild) + { + //create a new child + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + + VCLXWindow* pvclwindow = dynamic_cast<VCLXWindow*>(m_xAccessible.get()); + assert(pvclwindow); + const SystemEnvData* systemdata + = pvclwindow->GetWindow()->GetSystemData(); + + //add this child + pAgent->InsertAccObj(pAcc, m_xAccessible.get(), systemdata->hWnd); + //add all oldValue's existing children + pAgent->InsertChildrenAccObj(pAcc); + pAgent->NotifyAccEvent(UnoMSAAEvent::CHILD_ADDED, pAcc); + } + } + else if (oldValue >>= xChild) + { + //delete an existing child + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + pAgent->NotifyAccEvent(UnoMSAAEvent::CHILD_REMOVED, pAcc); + //delete all oldValue's existing children + pAgent->DeleteChildrenAccObj( pAcc ); + //delete this child + pAgent->DeleteAccObj( pAcc ); + } + } + +} + +/** + * set the new state and fire the MSAA event + * @param state new state id + * @param enable true if state is set, false if state is unset + */ +void AccFrameEventListener::SetComponentState(short state, bool enable ) +{ + // only the following state can be fired state event. + switch (state) + { + case AccessibleStateType::ICONIFIED: + // no msaa state + break; + case AccessibleStateType::VISIBLE: + // UNO !VISIBLE == MSAA INVISIBLE + if( enable ) + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE); + else + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE); + break; + case AccessibleStateType::ACTIVE: + // Only frames should be active + // no msaa state mapping + break; + default: + break; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccListEventListener.cxx b/winaccessibility/source/service/AccListEventListener.cxx new file mode 100644 index 000000000..b4ecb9f77 --- /dev/null +++ b/winaccessibility/source/service/AccListEventListener.cxx @@ -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 . + */ + +#include <com/sun/star/accessibility/XAccessible.hpp> +#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/accessibility/XAccessibleEventBroadcaster.hpp> + +#include <vcl/svapp.hxx> + +#include <AccListEventListener.hxx> +#include <AccObjectManagerAgent.hxx> +#include <unomsaaevent.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; + +AccListEventListener::AccListEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent) + :AccDescendantManagerEventListener(pAcc, Agent) +{ +} + +AccListEventListener::~AccListEventListener() +{ +} + +/** + * Uno's event notifier when event is captured + * @param AccessibleEventObject the event object which contains information about event + */ +void AccListEventListener::notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) +{ + SolarMutexGuard g; + + switch (aEvent.EventId) + { + case AccessibleEventId::ACTIVE_DESCENDANT_CHANGED: + HandleActiveDescendantChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::INVALIDATE_ALL_CHILDREN: + // Since List items a transient a child events are mostly used + // to attach/detach listeners, it is safe to ignore it here + //TODO: investigate again + break; + case AccessibleEventId::VALUE_CHANGED: + HandleValueChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + default: + AccDescendantManagerEventListener::notifyEvent(aEvent); + break; + } +} + +/** + * handle the ACTIVE_DESCENDANT_CHANGED event + * @param oldValue the child to lose active + * @param newValue the child to get active + */ +void AccListEventListener::HandleActiveDescendantChangedEvent(Any oldValue, Any newValue) +{ + Reference< XAccessible > xChild; + + if(newValue >>= xChild ) + { + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + + // Valueset has cache the child item xacc,Update state if no insert obj + bool bHasCache = pAgent->InsertAccObj(pAcc, m_xAccessible.get()); + if (!bHasCache) + { + pAgent->UpdateState(pAcc); + } + + pAgent->IncreaseState( pAcc, AccessibleStateType::FOCUSED); + + pAgent->NotifyAccEvent(UnoMSAAEvent::ACTIVE_DESCENDANT_CHANGED, pAcc); + } + } + if (oldValue >>= xChild) + { + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + pAgent->DeleteAccObj( pAcc ); + } + } +} + +/** + * handle the VALUE_CHANGED event + * + * @param oldValue the old value of the source of event + * @param newValue the new value of the source of event + */ +void AccListEventListener::HandleValueChangedEvent(Any, Any) +{ + //to enable value changed event + if (GetParentRole() == AccessibleRole::COMBO_BOX) + { + XAccessible* pParentAcc = + pAgent->GetParentXAccessible(m_xAccessible.get()); + pAgent->UpdateValue(pParentAcc); + pAgent->NotifyAccEvent(UnoMSAAEvent::OBJECT_VALUECHANGE, pParentAcc); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccMenuEventListener.cxx b/winaccessibility/source/service/AccMenuEventListener.cxx new file mode 100644 index 000000000..05d78b9b0 --- /dev/null +++ b/winaccessibility/source/service/AccMenuEventListener.cxx @@ -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 . + */ + +#include <com/sun/star/accessibility/XAccessible.hpp> +#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/accessibility/XAccessibleEventBroadcaster.hpp> + +#include <vcl/svapp.hxx> + +#include <AccMenuEventListener.hxx> +#include <AccObjectManagerAgent.hxx> +#include <unomsaaevent.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; + +AccMenuEventListener::AccMenuEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent) + :AccComponentEventListener(pAcc, Agent) +{} +AccMenuEventListener::~AccMenuEventListener() +{ +} + +/** + * Uno's event notifier when event is captured + * @param AccessibleEventObject the event object which contains information about event + */ +void AccMenuEventListener::notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) +{ + SolarMutexGuard g; + + switch (aEvent.EventId) + { + case AccessibleEventId::CHILD: + HandleChildChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::SELECTION_CHANGED: + //don't need to process anything,just same as word behavior + //handleSelectionChangedEvent(); + break; + default: + AccComponentEventListener::notifyEvent(aEvent); + break; + } +} + +/** + * handle the CHILD event + * @param oldValue the child to be deleted + * @param newValue the child to be added + */ +void AccMenuEventListener::HandleChildChangedEvent(Any oldValue, Any newValue) +{ + + Reference< XAccessible > xChild; + if( newValue >>= xChild) + { + //create a new child + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + //add this child + pAgent->InsertAccObj(pAcc, m_xAccessible.get()); + //add all oldValue's existing children + pAgent->InsertChildrenAccObj(pAcc); + pAgent->NotifyAccEvent(UnoMSAAEvent::CHILD_ADDED, pAcc); + } + } + else if (oldValue >>= xChild) + { + //delete an existing child + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + pAgent->NotifyAccEvent(UnoMSAAEvent::CHILD_REMOVED, pAcc); + //delete all oldValue's existing children + pAgent->DeleteChildrenAccObj( pAcc ); + //delete this child + pAgent->DeleteAccObj( pAcc ); + } + } + +} + +/** + * handle the SELECTION_CHANGED event + */ +void AccMenuEventListener::HandleSelectionChangedEventNoArgs() +{ + pAgent->NotifyAccEvent(UnoMSAAEvent::SELECTION_CHANGED, m_xAccessible.get()); +} + +/** + * handle the Menu_popup event + */ +void AccMenuEventListener::FireStatePropertyChange(short state, bool set) +{ + if( set ) + { + // new value + switch(state) + { + //for sub menu is popup, there is a menu selected event. + case AccessibleStateType::SELECTED: + pAgent->IncreaseState(m_xAccessible.get(), state); + pAgent->UpdateChildState(m_xAccessible.get()); + break; + default: + AccComponentEventListener::FireStatePropertyChange(state, set); + break; + } + } + else + { + switch(state) + { + //for sub menu is popup, there is a menu selected event. + case AccessibleStateType::SELECTED: + pAgent->DecreaseState(m_xAccessible.get(), state); + + break; + default: + AccComponentEventListener::FireStatePropertyChange(state, set); + break; + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccObject.cxx b/winaccessibility/source/service/AccObject.cxx new file mode 100644 index 000000000..d2862577f --- /dev/null +++ b/winaccessibility/source/service/AccObject.cxx @@ -0,0 +1,1128 @@ +/* -*- 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/uno/Sequence.h> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/XAccessibleValue.hpp> +#include <com/sun/star/accessibility/XAccessibleComponent.hpp> +#include <com/sun/star/accessibility/XAccessibleText.hpp> + +#include <o3tl/char16_t2wchar_t.hxx> +#include <o3tl/safeint.hxx> + +#include <stdlib.h> +#include <memory.h> +#include <stdio.h> +#include <algorithm> +#include <assert.h> + +#include <AccObject.hxx> +#include <AccEventListener.hxx> + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wextra-tokens" + // "#endif !_MIDL_USE_GUIDDEF_" in midl-generated code +#endif +#include <UAccCOM_i.c> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; +using namespace com::sun::star::accessibility::AccessibleRole; +using namespace com::sun::star::accessibility::AccessibleStateType; + +//Role mapping table,left side is UNO role, right side is MSAA role +const short ROLE_TABLE[][2] = + { + {UNKNOWN, IA2_ROLE_UNKNOWN}, + {ALERT , ROLE_SYSTEM_DIALOG}, + {COLUMN_HEADER , ROLE_SYSTEM_COLUMNHEADER}, + //{CANVAS , ROLE_SYSTEM_CLIENT}, + {CANVAS , IA2_ROLE_CANVAS}, + {CHECK_BOX , ROLE_SYSTEM_CHECKBUTTON}, + {CHECK_MENU_ITEM , IA2_ROLE_CHECK_MENU_ITEM}, + {COLOR_CHOOSER, IA2_ROLE_COLOR_CHOOSER}, + {COMBO_BOX , ROLE_SYSTEM_COMBOBOX}, + {DATE_EDITOR , IA2_ROLE_DATE_EDITOR}, + {DESKTOP_ICON , IA2_ROLE_DESKTOP_ICON}, + {DESKTOP_PANE, IA2_ROLE_DESKTOP_PANE}, + {DIRECTORY_PANE, IA2_ROLE_DIRECTORY_PANE}, + {DIALOG, ROLE_SYSTEM_DIALOG}, + {DOCUMENT, ROLE_SYSTEM_DOCUMENT}, + {EMBEDDED_OBJECT , IA2_ROLE_EMBEDDED_OBJECT }, + {END_NOTE , IA2_ROLE_ENDNOTE }, + {FILE_CHOOSER , IA2_ROLE_FILE_CHOOSER }, + {FILLER, ROLE_SYSTEM_WHITESPACE}, + {FONT_CHOOSER, IA2_ROLE_FONT_CHOOSER}, + {FOOTER, IA2_ROLE_FOOTER}, + {FOOTNOTE, IA2_ROLE_FOOTNOTE}, + //{FRAME, IA2_ROLE_FRAME}, + {FRAME, ROLE_SYSTEM_DIALOG}, + {GLASS_PANE , IA2_ROLE_GLASS_PANE}, + {GRAPHIC , ROLE_SYSTEM_GRAPHIC}, + {GROUP_BOX, ROLE_SYSTEM_GROUPING}, + {HEADER , IA2_ROLE_HEADER}, + {HEADING , IA2_ROLE_HEADING}, + {HYPER_LINK , ROLE_SYSTEM_TEXT}, + {ICON , IA2_ROLE_ICON}, + {INTERNAL_FRAME, IA2_ROLE_INTERNAL_FRAME}, + {LABEL, ROLE_SYSTEM_STATICTEXT}, + {LAYERED_PANE , IA2_ROLE_LAYERED_PANE}, + {LIST , ROLE_SYSTEM_LIST}, + {LIST_ITEM , ROLE_SYSTEM_LISTITEM}, + //{MENU , ROLE_SYSTEM_MENUPOPUP}, + {MENU, ROLE_SYSTEM_MENUITEM}, + {MENU_BAR, ROLE_SYSTEM_MENUBAR}, + {MENU_ITEM, ROLE_SYSTEM_MENUITEM}, + {OPTION_PANE , IA2_ROLE_OPTION_PANE}, + {PAGE_TAB, ROLE_SYSTEM_PAGETAB}, + {PAGE_TAB_LIST, ROLE_SYSTEM_PAGETABLIST}, + {PANEL, IA2_ROLE_OPTION_PANE}, + {PARAGRAPH, IA2_ROLE_PARAGRAPH}, + {PASSWORD_TEXT, ROLE_SYSTEM_TEXT}, + {POPUP_MENU, ROLE_SYSTEM_MENUPOPUP}, + {PUSH_BUTTON, ROLE_SYSTEM_PUSHBUTTON}, + {PROGRESS_BAR, ROLE_SYSTEM_PROGRESSBAR}, + {RADIO_BUTTON, ROLE_SYSTEM_RADIOBUTTON}, + {RADIO_MENU_ITEM, IA2_ROLE_RADIO_MENU_ITEM}, + {ROW_HEADER , ROLE_SYSTEM_ROWHEADER}, + {ROOT_PANE, IA2_ROLE_ROOT_PANE}, + {SCROLL_BAR , ROLE_SYSTEM_SCROLLBAR}, + {SCROLL_PANE , IA2_ROLE_SCROLL_PANE}, + {SHAPE, IA2_ROLE_SHAPE}, + {SEPARATOR , ROLE_SYSTEM_SEPARATOR}, + {SLIDER , ROLE_SYSTEM_SLIDER}, + {SPIN_BOX , ROLE_SYSTEM_SPINBUTTON}, + {SPLIT_PANE, IA2_ROLE_SPLIT_PANE}, + {STATUS_BAR, ROLE_SYSTEM_STATUSBAR}, + {TABLE, ROLE_SYSTEM_TABLE}, + {TABLE_CELL , ROLE_SYSTEM_CELL}, + {TEXT, ROLE_SYSTEM_TEXT}, + {TEXT_FRAME , IA2_ROLE_TEXT_FRAME}, + //for change toggle button to push button for jaws + {TOGGLE_BUTTON, ROLE_SYSTEM_PUSHBUTTON}, + + {TOOL_BAR, ROLE_SYSTEM_TOOLBAR}, + {TOOL_TIP, ROLE_SYSTEM_TOOLTIP}, + {TREE , ROLE_SYSTEM_OUTLINE}, + {VIEW_PORT , IA2_ROLE_VIEW_PORT}, + {WINDOW, ROLE_SYSTEM_WINDOW}, + {BUTTON_DROPDOWN, ROLE_SYSTEM_BUTTONDROPDOWN}, + {BUTTON_MENU, ROLE_SYSTEM_BUTTONMENU}, + {CAPTION, IA2_ROLE_CAPTION}, + {CHART, IA2_ROLE_SHAPE}, + {EDIT_BAR, IA2_ROLE_EDITBAR}, + {FORM, IA2_ROLE_FORM}, + {IMAGE_MAP , IA2_ROLE_IMAGE_MAP}, + {NOTE, IA2_ROLE_NOTE}, + {PAGE, IA2_ROLE_PAGE}, + {RULER , IA2_ROLE_RULER}, + {SECTION, IA2_ROLE_SECTION}, + {TREE_ITEM , ROLE_SYSTEM_OUTLINEITEM}, + {TREE_TABLE, ROLE_SYSTEM_OUTLINE}, + {COMMENT, IA2_ROLE_TEXT_FRAME }, + {COMMENT_END, IA2_ROLE_TEXT_FRAME }, + {DOCUMENT_PRESENTATION, ROLE_SYSTEM_DOCUMENT }, + {DOCUMENT_SPREADSHEET, ROLE_SYSTEM_DOCUMENT }, + {DOCUMENT_TEXT, ROLE_SYSTEM_DOCUMENT }, + {STATIC, ROLE_SYSTEM_STATICTEXT } + }; + + +/** + * Constructor. + * @param pXAcc Uno XAccessible interface of control. + * @param Agent The agent kept in all listeners,it's the sole interface by which + * listener communicate with windows manager. + * @param listener listener that registers in UNO system. + * @return. + */ +AccObject::AccObject(XAccessible* pAcc, AccObjectManagerAgent* pAgent, + AccEventListener* pListener) : + m_resID (0), + m_pParantID (nullptr), + m_pIMAcc (nullptr), + m_pParentObj(nullptr), + m_pListener (pListener), + m_xAccRef( pAcc ) +{ + ImplInitializeCreateObj(); + + m_xAccContextRef = m_xAccRef->getAccessibleContext(); + m_xAccActionRef.set(m_xAccContextRef,UNO_QUERY); + m_accRole = m_xAccContextRef -> getAccessibleRole(); + if( m_pIMAcc ) + { + m_pIMAcc->SetXAccessible(reinterpret_cast<hyper>(m_xAccRef.get())); + m_pIMAcc->Put_XAccAgent(reinterpret_cast<hyper>(pAgent)); + m_pIMAcc->SetDefaultAction(reinterpret_cast<hyper>(m_xAccActionRef.get())); + } +} +/** + * Destructor. + * @param + * @return + */ +AccObject::~AccObject() +{ + m_pIMAcc = nullptr; + m_xAccRef = nullptr; + m_xAccActionRef = nullptr; + m_xAccContextRef = nullptr; +} + + +/** + * Insert a child element. + * @param pChild Child element that should be inserted into child list. + * @param pos Insert position. + * @return + */ +void AccObject::InsertChild( AccObject* pChild,short pos ) +{ + + std::vector<AccObject*>::iterator iter; + iter = std::find(m_childrenList.begin(),m_childrenList.end(),pChild); + if(iter!=m_childrenList.end()) + return; + if(LAST_CHILD==pos) + { + m_childrenList.push_back(pChild); + } + else + { + iter=m_childrenList.begin()+pos; + m_childrenList.insert(iter,pChild); + } + + pChild->SetParentObj(this); +} + +/** + * Delete a child element + * @param pChild Child element that should be inserted into child list. + * @param pos Insert position. + * @return + */ +void AccObject::DeleteChild( AccObject* pChild ) +{ + std::vector<AccObject*>::iterator iter; + iter = std::find(m_childrenList.begin(),m_childrenList.end(),pChild); + if(iter!=m_childrenList.end()) + { + m_childrenList.erase(iter); + if(m_pIMAcc) + pChild->SetParentObj(nullptr); + } +} + +/** + * In order to windows API WindowFromAccessibleObject, we sometimes to set a pure + * top window accessible object created by windows system as top ancestor. + * @param. + * @return + */ +void AccObject::UpdateValidWindow() +{ + if(m_pIMAcc) + m_pIMAcc->Put_XAccWindowHandle(m_pParantID); +} + +/** + * Translate all UNO basic information into MSAA com information. + * @param + * @return If the method is correctly processed. + */ +void AccObject::ImplInitializeCreateObj() +{ + m_pIMAcc = UAccCOMCreateInstance(); + + assert(m_pIMAcc); +} + +/** + * Update name property to com object. + * @param + * @return + */ +void AccObject::UpdateName( ) +{ + if (!m_pIMAcc) + { + return; + } + + if( ( TEXT_FRAME == m_accRole ) && ( m_pParentObj !=nullptr )&& ( SCROLL_PANE == m_pParentObj -> m_accRole ) ) + m_pIMAcc->Put_XAccName( o3tl::toW(m_pParentObj->m_xAccContextRef->getAccessibleName().getStr()) ); + //IAccessibility2 Implementation 2009----- + if ( PARAGRAPH == m_accRole) + { + m_pIMAcc->Put_XAccName(L""); + } + //-----IAccessibility2 Implementation 2009 + else + m_pIMAcc->Put_XAccName(o3tl::toW(m_xAccContextRef->getAccessibleName().getStr())); + + return ; +} + +/** + * Update default action property to com object. + * @param + * @return + */ +void AccObject::UpdateAction() +{ + m_xAccActionRef.set(m_xAccContextRef,UNO_QUERY); + + if( m_xAccActionRef.is() && m_pIMAcc ) + { + if( m_xAccActionRef->getAccessibleActionCount() > 0 ) + { + UpdateDefaultAction( ); + m_pIMAcc->SetDefaultAction( + reinterpret_cast<hyper>(m_xAccActionRef.get())); + } + } +} + +/** + * Update value property to com object. + * @param + * @return + */ +void AccObject::UpdateValue() +{ + if( nullptr == m_pIMAcc || !m_xAccContextRef.is() ) + { + assert(false); + return ; + } + + Reference< XAccessibleValue > pRValue(m_xAccContextRef,UNO_QUERY); + Any pAny; + if( pRValue.is() ) + { + pAny = pRValue->getCurrentValue(); + } + + SetValue( pAny ); +} + +/** + * Set special default action description string via UNO role. + * @param Role UNO role + * @return + */ +void AccObject::UpdateDefaultAction( ) +{ + if(!m_xAccActionRef.is()) + return ; + + switch(m_accRole) + { + case PUSH_BUTTON: + case TOGGLE_BUTTON: + case RADIO_BUTTON: + case MENU_ITEM: + case RADIO_MENU_ITEM: + case CHECK_MENU_ITEM: + case LIST_ITEM: + case CHECK_BOX: + case TREE_ITEM: + case BUTTON_DROPDOWN: + m_pIMAcc->Put_ActionDescription( o3tl::toW(m_xAccActionRef->getAccessibleActionDescription(sal_Int32(0)).getStr()) ); + return; + } +} + +/** + * Set value property via pAny. + * @param pAny New value. + * @return + */ +void AccObject::SetValue( Any pAny ) +{ + if( nullptr == m_pIMAcc || !m_xAccContextRef.is() ) + { + assert(false); + return ; + } + Reference< XAccessibleText > pRText(m_xAccContextRef,UNO_QUERY); + OUString val; + switch(m_accRole) + { + case SPIN_BOX: + // 3. date editor's msaa value should be the same as spinbox + case DATE_EDITOR: + case TEXT: + case PARAGRAPH: + case HEADING: + case TABLE_CELL: + + if(pRText) + { + val = pRText->getText(); + } + m_pIMAcc->Put_XAccValue( o3tl::toW(val.getStr()) ); + break; + case TREE_ITEM: + //case CHECK_BOX: //Commented by Li Xing to disable the value for general checkbox + case COMBO_BOX: + case NOTE: + case SCROLL_BAR: + m_pIMAcc->Put_XAccValue( o3tl::toW(GetMAccessibleValueFromAny(pAny).getStr()) ); + break ; + // Added by Li Xing, only the checkbox in tree should have the value. + case CHECK_BOX: + if( ( m_pParentObj !=nullptr ) && (TREE == m_pParentObj->m_accRole || TREE_ITEM == m_pParentObj->m_accRole )) + m_pIMAcc->Put_XAccValue( o3tl::toW(GetMAccessibleValueFromAny(pAny).getStr()) ); + break; + default: + break; + } + + return; +} + +OUString AccObject::GetMAccessibleValueFromAny(Any pAny) +{ + OUString strValue; + + if(nullptr == m_pIMAcc) + return strValue; + + if(pAny.getValueType() == cppu::UnoType<cppu::UnoUnsignedShortType>::get() ) + { + sal_uInt16 val; + if (pAny >>= val) + { + strValue=OUString::number(val); + + } + } + else if(pAny.getValueType() == cppu::UnoType<OUString>::get()) + { + + pAny >>= strValue ; + + } + else if(pAny.getValueType() == cppu::UnoType<Sequence< OUString >>::get()) + { + Sequence< OUString > val; + if (pAny >>= val) + { + for (const OUString& rElem : val) + strValue += rElem; + } + } + else if(pAny.getValueType() == cppu::UnoType<double>::get()) + { + double val; + if (pAny >>= val) + { + strValue=OUString::number(val); + } + } + else if(pAny.getValueType() == cppu::UnoType<sal_Int32>::get()) + { + sal_Int32 val; + if (pAny >>= val) + { + strValue=OUString::number(val); + } + } + else if (pAny.getValueType() == cppu::UnoType<css::accessibility::TextSegment>::get()) + { + css::accessibility::TextSegment val; + if (pAny >>= val) + { + OUString realVal(val.SegmentText); + strValue = realVal; + + } + } + + return strValue; +} +/** + * Set name property via pAny. + * @param pAny New accessible name. + * @return + */ +void AccObject::SetName( Any pAny) +{ + if( nullptr == m_pIMAcc ) + return ; + + m_pIMAcc->Put_XAccName( o3tl::toW(GetMAccessibleValueFromAny(pAny).getStr()) ); + +} + +/** +* Get role property via pAny +* @param +* @return accessible role +*/ +short AccObject::GetRole() const +{ + return m_accRole; +} + +/** + * Get MSAA state from UNO state + * @Role xState UNO state. + * @return + */ +DWORD AccObject::GetMSAAStateFromUNO(short xState) +{ + DWORD IState = UNO_MSAA_UNMAPPING; + + if( !m_xAccContextRef.is() ) + { + assert(false); + return IState; + } + short Role = m_accRole; + + switch( xState ) + { + case BUSY: + IState = STATE_SYSTEM_BUSY; + break; + case CHECKED: + if( Role == PUSH_BUTTON || Role == TOGGLE_BUTTON ) + { + IState = STATE_SYSTEM_PRESSED; + } + else + IState = STATE_SYSTEM_CHECKED; + break; + case DEFUNC: + IState = STATE_SYSTEM_UNAVAILABLE; + break; + case EXPANDED: + IState = STATE_SYSTEM_EXPANDED; + break; + case FOCUSABLE: + IState = STATE_SYSTEM_FOCUSABLE; + break; + case FOCUSED: + IState = STATE_SYSTEM_FOCUSED; + break; + case INDETERMINATE: + IState = STATE_SYSTEM_MIXED; + break; + case MULTI_SELECTABLE: + IState = STATE_SYSTEM_MULTISELECTABLE; + break; + case PRESSED: + IState = STATE_SYSTEM_PRESSED; + break; + case RESIZABLE: + IState = STATE_SYSTEM_SIZEABLE; + break; + case SELECTABLE: + if( m_accRole == MENU || m_accRole == MENU_ITEM) + { + IState = UNO_MSAA_UNMAPPING; + } + else + { + IState = STATE_SYSTEM_SELECTABLE; + } + break; + case SELECTED: + if( m_accRole == MENU || m_accRole == MENU_ITEM ) + { + IState = UNO_MSAA_UNMAPPING; + } + else + { + IState = STATE_SYSTEM_SELECTED; + } + break; + case ARMED: + IState = STATE_SYSTEM_FOCUSED; + break; + case EXPANDABLE: + { + sal_Bool isExpanded = true; + sal_Bool isExpandable = true; + if( Role == PUSH_BUTTON || Role == TOGGLE_BUTTON || BUTTON_DROPDOWN == Role ) + { + IState = STATE_SYSTEM_HASPOPUP; + } + else + { + GetExpandedState(&isExpandable,&isExpanded); + if(!isExpanded) + IState = STATE_SYSTEM_COLLAPSED; + } + } + break; + //Remove the SENSITIVE state mapping. There is no corresponding MSAA state. + //case SENSITIVE: + // IState = STATE_SYSTEM_PROTECTED; + case EDITABLE: + if( m_pIMAcc ) + { + m_pIMAcc->DecreaseState( STATE_SYSTEM_READONLY ); + } + break; + case OFFSCREEN: + IState = STATE_SYSTEM_OFFSCREEN; + break; + case MOVEABLE: + IState = STATE_SYSTEM_MOVEABLE; + break; + case COLLAPSE: + IState = STATE_SYSTEM_COLLAPSED; + break; + case DEFAULT: + IState = STATE_SYSTEM_DEFAULT; + break; + default: + break; + } + + return IState; +} + +/** + * Decrease state of com object + * @param xState The lost state. + * @return + */ +void AccObject::DecreaseState( short xState ) +{ + if( nullptr == m_pIMAcc ) + { + return; + } + + if( xState == FOCUSABLE) + { + short Role = m_accRole ; + if(Role == MENU_ITEM + || Role == RADIO_MENU_ITEM + || Role == CHECK_MENU_ITEM) + return; + else + { + if (Role == TOGGLE_BUTTON || Role == PUSH_BUTTON || BUTTON_DROPDOWN == Role) + { + if( ( m_pParentObj !=nullptr ) && (TOOL_BAR == m_pParentObj->m_accRole ) ) + return; + } + } + } + + else if( xState == AccessibleStateType::VISIBLE ) + { + m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE ); + } + else if( xState == AccessibleStateType::SHOWING ) + { + m_pIMAcc->IncreaseState( STATE_SYSTEM_OFFSCREEN ); + } + + DWORD msState = GetMSAAStateFromUNO(xState); + if(msState!=UNO_MSAA_UNMAPPING) + m_pIMAcc->DecreaseState(msState); +} + +/** + * Increase state of com object + * @param xState The new state. + * @return + */ +void AccObject::IncreaseState( short xState ) +{ + if( nullptr == m_pIMAcc ) + { + assert(false); + return; + } + + + if( xState == AccessibleStateType::VISIBLE ) + { + m_pIMAcc->DecreaseState( STATE_SYSTEM_INVISIBLE ); + } + else if( xState == AccessibleStateType::SHOWING ) + { + m_pIMAcc->DecreaseState( STATE_SYSTEM_OFFSCREEN ); + } + + + DWORD msState = GetMSAAStateFromUNO(xState); + if(msState!=UNO_MSAA_UNMAPPING) + m_pIMAcc->IncreaseState( msState ); +} + +/** + * Get next child element + * @param + * @return AccObject Object interface. + */ +AccObject* AccObject::NextChild() +{ + IAccChildList::iterator pInd = m_childrenList.begin(); + if( pInd != m_childrenList.end() ) + return *pInd; + return nullptr; +} +/** + * update action description desc + * @param + * @return + */ +void AccObject::UpdateActionDesc() +{ + if (!m_pIMAcc) + return; + + long Role = m_accRole; + + if( Role == PUSH_BUTTON || Role == RADIO_BUTTON || Role == MENU_ITEM || + Role == LIST_ITEM || Role == CHECK_BOX || Role == TREE_ITEM || + Role == CHECK_MENU_ITEM || Role == RADIO_MENU_ITEM ) + { + UpdateDefaultAction( ); + } + else + { + + if( m_xAccActionRef.is() ) + { + if( m_xAccActionRef->getAccessibleActionCount() > 0 ) + { + if (!(Role == SPIN_BOX || Role == COMBO_BOX || Role == DATE_EDITOR || + Role == EDIT_BAR || Role == PASSWORD_TEXT || Role == TEXT)) + { + const OUString sActionDesc = m_xAccActionRef->getAccessibleActionDescription(0); + // if string is non-empty, action is set. + if (!sActionDesc.isEmpty()) + m_pIMAcc->Put_ActionDescription(o3tl::toW(sActionDesc.getStr())); + } + } + } + } + +} +/** + * update role information from uno to com + * @param + * @return + */ +void AccObject::UpdateRole() +{ + if (!m_pIMAcc) + { + return; + } + + XAccessibleContext* pContext = m_xAccContextRef.get(); + m_pIMAcc->Put_XAccRole( ROLE_SYSTEM_WINDOW ); + sal_Int16 iRoleIndex = pContext->getAccessibleRole(); + if ((0 <= iRoleIndex) && (o3tl::make_unsigned(iRoleIndex) < SAL_N_ELEMENTS(ROLE_TABLE))) + { + short iIA2Role = ROLE_TABLE[iRoleIndex][1] ; + m_pIMAcc->Put_XAccRole( iIA2Role ); + } + +} +/** + * update state information from uno to com + * @param + * @return + */ +void AccObject::UpdateState() +{ + if (!m_pIMAcc) + { + return; + } + + XAccessibleContext* pContext = m_xAccContextRef.get(); + Reference< XAccessibleStateSet > pRState = pContext->getAccessibleStateSet(); + if( !pRState.is() ) + { + assert(false); + return ; + } + + m_pIMAcc->SetState(0); + + if ( m_accRole == POPUP_MENU ) + { + return; + } + + bool isEnable = false; + bool isShowing = false; + bool isEditable = false; + bool isVisible = false; + bool isFocusable = false; + + for (const sal_Int16 nState : pRState->getStates()) + { + if (nState == ENABLED) + isEnable = true; + else if (nState == SHOWING) + isShowing = true; + else if (nState == VISIBLE) + isVisible = true; + else if (nState == EDITABLE) + isEditable = true; + else if (nState == FOCUSABLE) + isFocusable = true; + IncreaseState(nState); + } + bool bIsMenuItem = m_accRole == MENU_ITEM || m_accRole == RADIO_MENU_ITEM || m_accRole == CHECK_MENU_ITEM; + + if(bIsMenuItem) + { + if(!(isShowing && isVisible) ) + { + m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE ); + m_pIMAcc->DecreaseState( STATE_SYSTEM_FOCUSABLE ); + } + } + else + { + if(!(isShowing || isVisible) ) + m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE ); + } + + short Role = m_accRole; + + switch(m_accRole) + { + case LABEL: + case STATIC: + m_pIMAcc->IncreaseState( STATE_SYSTEM_READONLY ); + break; + case TEXT: + // 2. editable combobox -> readonly ------ bridge + case EMBEDDED_OBJECT: + case END_NOTE: + case FOOTER: + case FOOTNOTE: + case GRAPHIC: + case HEADER: + case HEADING: + + //Image Map + case PARAGRAPH: + case PASSWORD_TEXT: + case SHAPE: + case SPIN_BOX: + case TABLE: + case TABLE_CELL: + case TEXT_FRAME: + case DATE_EDITOR: + case DOCUMENT: + case COLUMN_HEADER: + { + if(!isEditable) + m_pIMAcc->IncreaseState( STATE_SYSTEM_READONLY ); + } + break; + default: + break; + } + + if( isEnable ) + { + + if(!(Role == FILLER || Role == END_NOTE || Role == FOOTER || Role == FOOTNOTE || Role == GROUP_BOX || Role == RULER + || Role == HEADER || Role == ICON || Role == INTERNAL_FRAME || Role == LABEL || Role == LAYERED_PANE + || Role == SCROLL_BAR || Role == SCROLL_PANE || Role == SPLIT_PANE || Role == STATIC || Role == STATUS_BAR + || Role == TOOL_TIP)) + { + if( SEPARATOR == Role ) + { + if( ( m_pParentObj != nullptr ) && ( MENU == m_pParentObj->m_accRole || POPUP_MENU == m_pParentObj->m_accRole )) + IncreaseState( FOCUSABLE ); + } + + else if (TABLE_CELL == Role || TABLE == Role || PANEL == Role || OPTION_PANE == Role || + COLUMN_HEADER == Role) + { + if (isFocusable) + IncreaseState( FOCUSABLE ); + } + else + { + if(bIsMenuItem) + { + if ( isShowing && isVisible) + { + IncreaseState( FOCUSABLE ); + } + } + else + { + IncreaseState( FOCUSABLE ); + } + } + } + } + else + { + m_pIMAcc->IncreaseState( STATE_SYSTEM_UNAVAILABLE ); + if( !((Role == MENU_ITEM) || + (Role == RADIO_MENU_ITEM) || + (Role == CHECK_MENU_ITEM)) ) + { + if ( Role == TOGGLE_BUTTON || Role == PUSH_BUTTON || BUTTON_DROPDOWN == Role) + { + if(( m_pParentObj != nullptr )&& (TOOL_BAR == m_pParentObj->m_accRole ) ) + IncreaseState( FOCUSABLE ); + else + DecreaseState( FOCUSABLE ); + } + else + DecreaseState( FOCUSABLE ); + } + else if( isShowing || isVisible ) + { + IncreaseState( FOCUSABLE ); + } + } + + switch(m_accRole) + { + case POPUP_MENU: + case MENU: + if( pContext->getAccessibleChildCount() > 0 ) + m_pIMAcc->IncreaseState( STATE_SYSTEM_HASPOPUP ); + break; + case PASSWORD_TEXT: + m_pIMAcc->IncreaseState( STATE_SYSTEM_PROTECTED ); + break; + default: + break; + } +} + +/** + * update location information from uno to com + * @param + * @return + */ +void AccObject::UpdateLocation() +{ + if (!m_pIMAcc) + { + return; + } + XAccessibleContext* pContext = m_xAccContextRef.get(); + + Reference< XAccessibleComponent > pRComponent(pContext,UNO_QUERY); + if( pRComponent.is() ) + { + css::awt::Point pCPoint = pRComponent->getLocationOnScreen(); + css::awt::Size pCSize = pRComponent->getSize(); + Location tempLocation; + tempLocation.m_dLeft = pCPoint.X; + tempLocation.m_dTop = pCPoint.Y; + tempLocation.m_dWidth = pCSize.Width; + tempLocation.m_dHeight = pCSize.Height; + m_pIMAcc->Put_XAccLocation( tempLocation ); + } + +} + + +/** + * Public method to mapping information between MSAA and UNO. + * @param + * @return If the method is correctly processed. + */ +bool AccObject::UpdateAccessibleInfoFromUnoToMSAA() +{ + if( nullptr == m_pIMAcc || !m_xAccContextRef.is() ) + { + assert(false); + return false; + } + + UpdateName(); + + UpdateValue(); + + UpdateActionDesc(); + + UpdateRole(); + + UpdateLocation(); + + UpdateState(); + + return true; +} + +/* + * Add a child selected element. + * @param pAccObj Child object pointer. + * @return + */ +void AccObject::AddSelect( long index, AccObject* accObj) +{ + m_selectionList.emplace(index,accObj); +} + +IAccSelectionList& AccObject::GetSelection() +{ + return m_selectionList; +} + + +/** + * Set self to focus object in parent child list + * @param + * @return + */ +void AccObject::setFocus() +{ + if(m_pIMAcc) + { + IncreaseState(FOCUSED); + m_pIMAcc->Put_XAccFocus(CHILDID_SELF); + + UpdateRole(); + } +} + +/** + * Unset self from focus object in parent child list. + * @param + * @return + */ +void AccObject::unsetFocus() +{ + if(m_pIMAcc) + { + DecreaseState( FOCUSED ); + m_pIMAcc->Put_XAccFocus(UACC_NO_FOCUS); + } +} + +void AccObject::GetExpandedState( sal_Bool* isExpandable, sal_Bool* isExpanded) +{ + *isExpanded = false; + *isExpandable = false; + + if( !m_xAccContextRef.is() ) + { + return; + } + Reference< XAccessibleStateSet > pRState = m_xAccContextRef->getAccessibleStateSet(); + if( !pRState.is() ) + { + return; + } + + for (sal_Int16 nState : pRState->getStates()) + { + if (nState == EXPANDED) + *isExpanded = true; + else if (nState == EXPANDABLE) + *isExpandable = true; + } +} + +void AccObject::NotifyDestroy() +{ + if(m_pIMAcc) + m_pIMAcc->NotifyDestroy(); +} + +void AccObject::SetParentObj(AccObject* pParentAccObj) +{ + m_pParentObj = pParentAccObj; + + if(m_pIMAcc) + { + if(m_pParentObj) + { + m_pIMAcc->Put_XAccParent(m_pParentObj->GetIMAccessible()); + } + else + { + m_pIMAcc->Put_XAccParent(nullptr); + } + } +} +//ResID means ChildID in MSAA +void AccObject::SetResID(long id) +{ + m_resID = id; + if(m_pIMAcc) + m_pIMAcc->Put_XAccChildID(m_resID); +} +//return COM interface in acc object +IMAccessible* AccObject::GetIMAccessible() +{ + return m_pIMAcc; +} + +Reference<XAccessible> const& AccObject::GetXAccessible() +{ + return m_xAccRef; +} + +void AccObject::SetParentHWND(HWND hWnd) +{ + m_pParantID = hWnd; +} + +void AccObject::SetListener(rtl::Reference<AccEventListener> const& pListener) +{ + m_pListener = pListener; +} + +AccEventListener* AccObject::getListener() +{ + return m_pListener.get(); +} + +long AccObject::GetResID() +{ + return m_resID; +} + +HWND AccObject::GetParentHWND() +{ + return m_pParantID; +} + +AccObject* AccObject::GetParentObj() +{ + return m_pParentObj; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccObjectContainerEventListener.cxx b/winaccessibility/source/service/AccObjectContainerEventListener.cxx new file mode 100644 index 000000000..429e99734 --- /dev/null +++ b/winaccessibility/source/service/AccObjectContainerEventListener.cxx @@ -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 . + */ + +// AccObjectContainerEventListener.cpp: implementation of the AccContainerEventListener class. + +#include <com/sun/star/accessibility/XAccessible.hpp> +#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/accessibility/XAccessibleEventBroadcaster.hpp> + +#include <AccObjectContainerEventListener.hxx> +#include <AccObjectManagerAgent.hxx> +#include <unomsaaevent.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; + +AccObjectContainerEventListener::AccObjectContainerEventListener( + css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent) + : AccContainerEventListener(pAcc, Agent) +{ +} +AccObjectContainerEventListener::~AccObjectContainerEventListener() {} + +/** + * handle the STATE_CHANGED event + */ +void AccObjectContainerEventListener::HandleStateChangedEvent(Any oldValue, Any newValue) +{ + //set the accessible name before process for there is no NAME_CHANGED event when change + //the text in drawing objects. + short newV; + if (newValue >>= newV) + { + if (newV == AccessibleStateType::FOCUSED) + { + pAgent->UpdateAccName(m_xAccessible.get()); + } + } + AccContainerEventListener::HandleStateChangedEvent(oldValue, newValue); +} +/** + * handle the VISIBLE_DATA_CHANGED event + * For SHAPES, the visible_data_changed event should be mapped to LOCATION_CHANGED event + */ +void AccObjectContainerEventListener::HandleVisibleDataChangedEvent() +{ + AccContainerEventListener::HandleBoundrectChangedEvent(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccObjectManagerAgent.cxx b/winaccessibility/source/service/AccObjectManagerAgent.cxx new file mode 100644 index 000000000..b67a2294e --- /dev/null +++ b/winaccessibility/source/service/AccObjectManagerAgent.cxx @@ -0,0 +1,384 @@ +/* -*- 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 <AccObjectManagerAgent.hxx> +#include <AccObjectWinManager.hxx> + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnon-virtual-dtor" +#endif +#include <UAccCOM.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; + +/** + * Construction/Destruction. + * @param + * @return + */ +AccObjectManagerAgent::AccObjectManagerAgent() + : pWinManager(new AccObjectWinManager(this)) +{ +} + +AccObjectManagerAgent::~AccObjectManagerAgent() +{ +} + +/** + * Interface of updating MSAA name when UNO name_changed event occurs. + * @param pXAcc Uno XAccessible interface of control. + * @return + */ +void AccObjectManagerAgent::UpdateAccName( XAccessible* pXAcc ) +{ + if( pWinManager ) + pWinManager->UpdateAccName( pXAcc ); +} + +/** + * Interface of updating MSAA name when UNO action changed event occurs. + * @param pXAcc Uno XAccessible interface of control. + * @return + */ +void AccObjectManagerAgent::UpdateAction( XAccessible* pXAcc ) +{ + if( pWinManager ) + pWinManager->UpdateAction( pXAcc ); +} + +/** + * Interface of updating MSAA value when UNO value_changed event occurs. + * @param pXAcc Uno XAccessible interface of control. + * @param pAny New value. + * @return + */ +void AccObjectManagerAgent::UpdateValue( XAccessible* pXAcc, Any pAny ) +{ + if( pWinManager ) + pWinManager->SetValue( pXAcc, pAny ); +} + +/** + * Interface of updating MSAA value when UNO value_changed event occurs. If we can not + * find new value, we'll get new value from pXAcc to update com value. + * @param pXAcc Uno XAccessible interface of control. + * @return + */ +void AccObjectManagerAgent::UpdateValue( XAccessible* pXAcc ) +{ + if( pWinManager ) + pWinManager->UpdateValue( pXAcc ); +} + +/** + * Interface of updating MSAA name when UNO name_changed event occurs. + * @param pXAcc Uno XAccessible interface of control. + * @param newName New UNO accessible name. + * @return + */ +void AccObjectManagerAgent::UpdateAccName( XAccessible* pXAcc, Any newName) +{ + if( pWinManager ) + pWinManager->SetAccName( pXAcc, newName ); +} + + +/** + * Interface of updating MSAA location when UNO location_changed event occurs. + * @param pXAcc Uno XAccessible interface of control. + * @param pXAcc Uno The top position of new location. + * @param pXAcc Uno The left position of new location. + * @param pXAcc Uno The width of new location. + * @param pXAcc Uno The width of new location. + * @return + */ +void AccObjectManagerAgent::UpdateLocation( XAccessible* /* pXAcc */, long /*top*/, long /*left*/, long /*width*/, long /*height*/ ) +{ +#ifdef _IMPL_WIN + if( pWinManager ) + pWinManager->SetLocation( pXAcc, top, left, width, height ); +#endif +} + +/** + * When a new UNO XAccessible object is found by listener, we create a corresponding + * com object and insert it to our manager list. + * @param pXAcc Uno XAccessible interface of control. + * @param pWnd The top window handle containing control. + * @return If the method is correctly processed. + */ +bool AccObjectManagerAgent::InsertAccObj( + XAccessible* pXAcc, XAccessible* pParentXAcc, HWND hWnd) +{ + if( pWinManager ) + return pWinManager->InsertAccObj(pXAcc, pParentXAcc, hWnd); + + return false; +} + +/** + * save the pair <topwindowhandle, XAccessible> + * @param hWnd, top window handle + * @param pXAcc XAccessible interface for top window + * @return void + */ +void +AccObjectManagerAgent::SaveTopWindowHandle(HWND hWnd, XAccessible* pXAcc) +{ + if( pWinManager ) + pWinManager->SaveTopWindowHandle(hWnd, pXAcc); +} + + +/** + * When a UNO XAccessible object's new children are found by listener, we create + * corresponding com objects and insert them to our manager list. + * @param pXAcc Uno XAccessible interface of control. + * @param pWnd The top window handle containing control. + * @return If the method is correctly processed. + */ +bool +AccObjectManagerAgent::InsertChildrenAccObj(XAccessible* pXAcc, HWND hWnd) +{ + if( pWinManager ) + return pWinManager->InsertChildrenAccObj(pXAcc, hWnd); + + return false; +} + +/** + * When a new UNO XAccessible object is destroyed, we delete its corresponding + * com object and remove it from our manager list. + * @param pXAcc Uno XAccessible interface of control. + * @return + */ +void AccObjectManagerAgent::DeleteAccObj( XAccessible* pXAcc ) +{ + if( pWinManager ) + pWinManager->DeleteAccObj( pXAcc ); +} + +/** + * When new UNO children XAccessible objects are destroyed, we delete their + * corresponding com objects and remove them from our manager list. + * @param pXAcc Uno XAccessible interface of control. + * @return + */ +void AccObjectManagerAgent::DeleteChildrenAccObj( XAccessible* pXAcc ) +{ + if( pWinManager ) + pWinManager->DeleteChildrenAccObj( pXAcc ); +} + +/** + * Interface of decreasing MSAA state when some UNO state is decreased. + * @param pXAcc Uno XAccessible interface of control. + * @param pState The lost state of control. + * @return + */ +void AccObjectManagerAgent::DecreaseState( XAccessible* pXAcc,unsigned short pState ) +{ + if(pWinManager) + { + pWinManager->DecreaseState( pXAcc, pState ); + } +} + +/** + * Interface of increasing MSAA name when some UNO state is increased. + * @param pXAcc Uno XAccessible interface of control. + * @param pState The new state of control. + * @return + */ +void AccObjectManagerAgent::IncreaseState( XAccessible* pXAcc,unsigned short pState ) +{ + if(pWinManager) + { + pWinManager->IncreaseState( pXAcc, pState ); + } +} + +void AccObjectManagerAgent::UpdateState( css::accessibility::XAccessible* pXAcc ) +{ + if(pWinManager) + pWinManager->UpdateState(pXAcc); +} + +/** + * Interface of notify MSAA event when some UNO event occurred. + * @param pXAcc Uno XAccessible interface of control. + * @param eEvent event type. + * @return If the method is correctly processed. + */ +bool AccObjectManagerAgent::NotifyAccEvent(UnoMSAAEvent eEvent, XAccessible* pXAcc) +{ + if(pWinManager) + return pWinManager->NotifyAccEvent(pXAcc, eEvent); + + return false; +} + +/** + * Judge whether a XAccessible object is a container object. + * @param pXAcc Uno XAccessible interface of control. + * @return If the method is correctly processed. + */ +bool AccObjectManagerAgent::IsContainer( XAccessible* pXAcc ) +{ + if(pWinManager) + return AccObjectWinManager::IsContainer(pXAcc); + + return false; +} + +/** + * Return com object interface by querying XAccessible interface. + * @param pXAcc Uno XAccessible interface of control. + * @return Com interface. + */ +IMAccessible* AccObjectManagerAgent::GetIMAccByXAcc(XAccessible* pXAcc) +{ + if(pWinManager) + return pWinManager->GetIMAccByXAcc(pXAcc); + + return nullptr; +} + +/** + * Notify manager when a XAccessible object is destroying. + * @param pXAcc Uno XAccessible interface of control. + * @return. + */ +void AccObjectManagerAgent::NotifyDestroy(XAccessible* pXAcc) +{ + if(pWinManager) + pWinManager->NotifyDestroy(pXAcc); +} + +/** + * Return com object interface by querying child id. + * @param pXAcc Uno XAccessible interface of control. + * @return Com interface. + */ +void AccObjectManagerAgent::GetIAccessibleFromResID(long childID,IMAccessible** pIMAcc) +{ + if(pWinManager) + *pIMAcc = pWinManager->GetIAccessibleFromResID(childID); +} + +/** + * Return object interface by querying interface. + * @param pXAcc Uno XAccessible interface of control. + * @return Com interface. + */ +bool AccObjectManagerAgent::GetIAccessibleFromXAccessible( + XAccessible* pXAcc, IAccessible** ppXI) +{ + if(pWinManager) + { + *ppXI = pWinManager->GetIMAccByXAcc(pXAcc); + if(*ppXI) + return true; + } + return false; +} + +XAccessible* AccObjectManagerAgent::GetParentXAccessible( XAccessible* pXAcc ) +{ + if(pWinManager) + return pWinManager->GetParentXAccessible( pXAcc ); + + return nullptr; +} + +short AccObjectManagerAgent::GetParentRole( XAccessible* pXAcc ) +{ + if(pWinManager) + return pWinManager->GetParentRole( pXAcc ); + + return -1; +} + +void AccObjectManagerAgent::UpdateChildState(XAccessible* pXAcc) +{ + if(pWinManager) + pWinManager->UpdateChildState( pXAcc ); +} + + +bool AccObjectManagerAgent::IsSpecialToolbarItem(XAccessible* pXAcc) +{ + if(pWinManager) + return pWinManager->IsSpecialToolbarItem(pXAcc); + + return false; +} + +short AccObjectManagerAgent::GetRole(XAccessible* pXAcc) +{ + if(pWinManager) + return AccObjectWinManager::GetRole( pXAcc ); + + return -1; +} + +XAccessible* AccObjectManagerAgent::GetAccDocByAccTopWin( XAccessible* pXAcc ) +{ + if (pWinManager) + { + return pWinManager->GetAccDocByAccTopWin( pXAcc ); + } + return nullptr; +} +bool AccObjectManagerAgent::IsTopWinAcc(XAccessible* pXAcc) +{ + if (pWinManager) + { + return pWinManager->IsTopWinAcc( pXAcc ); + } + return false; +} + +bool AccObjectManagerAgent::IsStateManageDescendant(XAccessible* pXAcc) +{ + if(pWinManager) + return AccObjectWinManager::IsStateManageDescendant( pXAcc ); + + return false; +} + +/** + * Implementation of interface XMSAAService's method getAccObjectPtr() + * that returns the corresponding COM interface with the MS event. + * @return Com interface. + */ +sal_Int64 AccObjectManagerAgent::Get_ToATInterface( + sal_Int64 hWnd, sal_Int64 lParam, sal_Int64 wParam) +{ + return static_cast<sal_Int64>(pWinManager->Get_ToATInterface( + static_cast<HWND>(reinterpret_cast<void*>(hWnd)), lParam, wParam)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccObjectWinManager.cxx b/winaccessibility/source/service/AccObjectWinManager.cxx new file mode 100644 index 000000000..bcde1ccf4 --- /dev/null +++ b/winaccessibility/source/service/AccObjectWinManager.cxx @@ -0,0 +1,1202 @@ +/* -*- 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 <cassert> + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/accessibility/XAccessibleEventListener.hpp> +#include <com/sun/star/accessibility/XAccessibleComponent.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> + +#include <oleacc.h> +#include <AccObjectWinManager.hxx> +#include <AccEventListener.hxx> +#include <AccComponentEventListener.hxx> +#include <AccContainerEventListener.hxx> +#include <AccDialogEventListener.hxx> +#include <AccWindowEventListener.hxx> +#include <AccFrameEventListener.hxx> +#include <AccMenuEventListener.hxx> +#include <AccObjectContainerEventListener.hxx> +#include <AccParagraphEventListener.hxx> +#include <AccTextComponentEventListener.hxx> +#include <AccListEventListener.hxx> +#include <AccTreeEventListener.hxx> +#include <AccTableEventListener.hxx> +#include <AccObject.hxx> +#include <unomsaaevent.hxx> + + +using namespace com::sun::star::accessibility; +using namespace com::sun::star::uno; + +/** + * constructor + * @param Agent The agent kept in all listeners,it's the sole interface by which + * listener communicate with windows manager. + * pEventAccObj The present event accobject. + * oldFocus Last focused object. + * isSelectionChanged flag that identifies if there is selection changed. + * selectionChildObj Selected object. + * dChildID Chile resource ID. + * hAcc TopWindowHWND + * @return + */ +AccObjectWinManager::AccObjectWinManager( AccObjectManagerAgent* Agent ): + oldFocus( nullptr ), + pAgent( Agent ) +{ +} + +/** + * Destructor,clear all resource. + * @param + * @return + */ +AccObjectWinManager::~AccObjectWinManager() +{ + XIdAccList.clear(); + HwndXAcc.clear(); + XResIdAccList.clear(); + XHWNDDocList.clear(); +} + + +/** + * Get valid com object interface when notifying some MSAA event + * @param pWND The top window handle that contains that event control. + * @param wParam Windows system interface. + * @return Com interface with event. + */ + +LRESULT +AccObjectWinManager::Get_ToATInterface(HWND hWnd, long lParam, WPARAM wParam) +{ + IMAccessible* pRetIMAcc = nullptr; + + if(lParam == OBJID_CLIENT ) + { + AccObject* topWindowAccObj = GetTopWindowAccObj(hWnd); + if(topWindowAccObj) + { + pRetIMAcc = topWindowAccObj->GetIMAccessible(); + if(pRetIMAcc) + pRetIMAcc->AddRef();//increase COM reference count + } + } + + if ( pRetIMAcc && lParam == OBJID_CLIENT ) + { + LRESULT result = LresultFromObject(IID_IAccessible, wParam, pRetIMAcc); + pRetIMAcc->Release(); + return result; + } + return 0; +} + +/** + * Search AccObject by XAccessible pointer from our container. + * @param pXAcc XAccessible interface. + * @return Pointer of accObject that is found. + */ +AccObject* AccObjectWinManager::GetAccObjByXAcc( XAccessible* pXAcc) +{ + if( pXAcc == nullptr) + return nullptr; + + XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( pXAcc ); + if ( pIndTemp == XIdAccList.end() ) + return nullptr; + + return &(pIndTemp->second); +} + +/** + * get acc object of top window by its handle + * @param hWnd, top window handle + * @return pointer to AccObject + */ +AccObject* AccObjectWinManager::GetTopWindowAccObj(HWND hWnd) +{ + XHWNDToXAccHash::iterator iterResult =HwndXAcc.find(hWnd); + if(iterResult == HwndXAcc.end()) + return nullptr; + XAccessible* pXAcc = iterResult->second; + return GetAccObjByXAcc(pXAcc); +} + +/** + * Simulate MSAA event via XAccessible interface and event type. + * @param pXAcc XAccessible interface. + * @param eEvent event type + * @return The terminate result that identifies if the call is successful. + */ +bool AccObjectWinManager::NotifyAccEvent(XAccessible* pXAcc, UnoMSAAEvent eEvent) +{ + Reference< XAccessibleContext > pRContext; + + if( pXAcc == nullptr) + return false; + + + pRContext = pXAcc->getAccessibleContext(); + if( !pRContext.is() ) + return false; + + + AccObject* selfAccObj= GetAccObjByXAcc(pXAcc); + + if(selfAccObj==nullptr) + return false; + + long dChildID = selfAccObj->GetResID(); + HWND hAcc = selfAccObj->GetParentHWND(); + + switch(eEvent) + { + case UnoMSAAEvent::STATE_FOCUSED: + { + UpdateAccFocus(pXAcc); + selfAccObj->UpdateDefaultAction( ); + UpdateValue(pXAcc); + NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID ); + break; + } + case UnoMSAAEvent::STATE_BUSY: + NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::STATE_CHECKED: + NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::STATE_PRESSED: + NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID ); + break; + + //Removed fire out selected event + //case UnoMSAAEvent::STATE_SELECTED: + // NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID ); + // break; + case UnoMSAAEvent::STATE_ARMED: + UpdateAccFocus(pXAcc); + NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::MENU_START: + NotifyWinEvent( EVENT_SYSTEM_MENUSTART,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::MENU_END: + NotifyWinEvent( EVENT_SYSTEM_MENUEND,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::MENUPOPUPSTART: + NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPSTART,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::MENUPOPUPEND: + NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPEND,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::SELECTION_CHANGED: + NotifyWinEvent( EVENT_OBJECT_SELECTION,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::SELECTION_CHANGED_ADD: + NotifyWinEvent( EVENT_OBJECT_SELECTIONADD,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::SELECTION_CHANGED_REMOVE: + NotifyWinEvent( EVENT_OBJECT_SELECTIONREMOVE,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::SELECTION_CHANGED_WITHIN: + NotifyWinEvent( EVENT_OBJECT_SELECTIONWITHIN,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::OBJECT_VALUECHANGE: + UpdateValue(pXAcc); + NotifyWinEvent( EVENT_OBJECT_VALUECHANGE,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::OBJECT_NAMECHANGE: + NotifyWinEvent( EVENT_OBJECT_NAMECHANGE,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::OBJECT_DESCRIPTIONCHANGE: + NotifyWinEvent( EVENT_OBJECT_DESCRIPTIONCHANGE,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::OBJECT_DEFACTIONCHANGE: + NotifyWinEvent( IA2_EVENT_ACTION_CHANGED,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::OBJECT_CARETCHANGE: + NotifyWinEvent( IA2_EVENT_TEXT_CARET_MOVED,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::OBJECT_TEXTCHANGE: + NotifyWinEvent( IA2_EVENT_TEXT_CHANGED,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::ACTIVE_DESCENDANT_CHANGED: + UpdateAccFocus(pXAcc); + NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::BOUNDRECT_CHANGED: + NotifyWinEvent( EVENT_OBJECT_LOCATIONCHANGE,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::VISIBLE_DATA_CHANGED: + NotifyWinEvent( IA2_EVENT_VISIBLE_DATA_CHANGED,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::SHOW : + NotifyWinEvent( EVENT_OBJECT_SHOW,hAcc, OBJID_CLIENT,dChildID ); + NotifyWinEvent( EVENT_SYSTEM_FOREGROUND,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::TABLE_CAPTION_CHANGED: + NotifyWinEvent( IA2_EVENT_TABLE_CAPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::TABLE_COLUMN_DESCRIPTION_CHANGED: + NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::TABLE_COLUMN_HEADER_CHANGED: + NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::TABLE_MODEL_CHANGED: + NotifyWinEvent( IA2_EVENT_TABLE_MODEL_CHANGED,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::TABLE_ROW_HEADER_CHANGED: + NotifyWinEvent( IA2_EVENT_TABLE_ROW_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::TABLE_SUMMARY_CHANGED: + NotifyWinEvent( IA2_EVENT_TABLE_SUMMARY_CHANGED,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::TABLE_ROW_DESCRIPTION_CHANGED: + NotifyWinEvent( IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::OBJECT_REORDER: + NotifyWinEvent( EVENT_OBJECT_REORDER,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::PAGE_CHANGED: + NotifyWinEvent( IA2_EVENT_PAGE_CHANGED,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::CHILD_REMOVED: + NotifyWinEvent( EVENT_OBJECT_DESTROY,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::CHILD_ADDED: + NotifyWinEvent( EVENT_OBJECT_CREATE ,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::OBJECT_PAGECHANGED: + NotifyWinEvent( IA2_EVENT_PAGE_CHANGED ,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::TEXT_SELECTION_CHANGED: + NotifyWinEvent( IA2_EVENT_TEXT_SELECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::SECTION_CHANGED: + NotifyWinEvent( IA2_EVENT_SECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID ); + break; + case UnoMSAAEvent::COLUMN_CHANGED: + NotifyWinEvent( IA2_EVENT_TEXT_COLUMN_CHANGED ,hAcc, OBJID_CLIENT,dChildID ); + break; + default: + break; + } + + return true; +} + +/** + * Get Parent XAccessible interface by XAccessible interface. + * @param pXAcc XAccessible interface. + * @return Parent XAccessible interface. + */ +XAccessible* AccObjectWinManager::GetParentXAccessible( XAccessible* pXAcc ) +{ + AccObject* pObj= GetAccObjByXAcc(pXAcc); + if( pObj ==nullptr ) + return nullptr; + if(pObj->GetParentObj()) + { + pObj = pObj->GetParentObj(); + return pObj->GetXAccessible().get(); + } + return nullptr; +} + +/** + * Get Parent role by XAccessible interface. + * @param pXAcc XAccessible interface. + * @return Parent role. + */ +short AccObjectWinManager::GetParentRole( XAccessible* pXAcc ) +{ + AccObject* pObj= GetAccObjByXAcc(pXAcc); + if( pObj ==nullptr ) + return -1; + if(pObj->GetParentObj()) + { + pObj = pObj->GetParentObj(); + if(pObj->GetXAccessible().is()) + { + Reference< XAccessibleContext > pRContext = pObj->GetXAccessible()->getAccessibleContext(); + if(pRContext.is()) + return pRContext->getAccessibleRole(); + } + } + return -1; +} + +/** + * Update focus object by new focused XAccessible interface. + * @param newFocus New XAccessible interface that gets focus. + * @return + */ +void AccObjectWinManager::UpdateAccFocus(XAccessible* newFocus) +{ + AccObject* pAccObjNew = GetAccObjByXAcc(newFocus); + if(pAccObjNew) + { + AccObject* pAccObjOld = GetAccObjByXAcc(oldFocus); + oldFocus = newFocus; + pAccObjNew->setFocus(); + //if old == new, the pAccObjNew will be without focused state + if (pAccObjOld && pAccObjOld != pAccObjNew) + pAccObjOld->unsetFocus(); + } +} + +/** + * Update selected object by new focused XAccessible interface. + * @param pXAcc XAccessible interface that has selected child changed. + * @return Selected children count. + */ +int AccObjectWinManager::UpdateAccSelection(XAccessible* pXAcc) +{ + Reference< XAccessibleContext > pRContext; + + if( pXAcc == nullptr) + return 0; + + pRContext = pXAcc->getAccessibleContext(); + if( !pRContext.is() ) + return 0; + + Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY); + if( !pRSelection.is() ) + return 0; + + AccObject* pAccObj = GetAccObjByXAcc(pXAcc); + if(pAccObj==nullptr) + return 0; + + Reference<XAccessible> pRChild; + AccObject* pAccChildObj = nullptr; + int selectNum= pRSelection->getSelectedAccessibleChildCount(); + + IAccSelectionList oldSelection = pAccObj->GetSelection(); + + if(selectNum > 4)//for selected. + return selectNum; + if(selectNum == 1 && oldSelection.size() == 0) + return 1; + + for (int i=0;i<selectNum;i++) + { + pRChild = pRSelection->getSelectedAccessibleChild(i); + if(!pRChild.is()) + { + continue; + } + Reference<XAccessibleContext> pRChildContext = pRChild->getAccessibleContext(); + if(!pRChildContext.is()) + { + continue; + } + long index = pRChildContext->getAccessibleIndexInParent(); + IAccSelectionList::iterator temp = oldSelection.find(index); + if ( temp != oldSelection.end() ) + { + oldSelection.erase(index); + continue; + } + + pAccChildObj = GetAccObjByXAcc(pRChild.get()); + if(!pAccChildObj) + { + InsertAccObj(pRChild.get(), pXAcc,pAccObj->GetParentHWND()); + pAccChildObj = GetAccObjByXAcc(pRChild.get()); + } + + pAccObj->AddSelect(index, pAccChildObj); + + if(pAccChildObj != nullptr) + NotifyWinEvent(EVENT_OBJECT_SELECTIONADD,pAccObj->GetParentHWND(), OBJID_CLIENT,pAccChildObj->GetResID()); + } + + for (const auto& rEntry : oldSelection) + { + pAccObj->GetSelection().erase(rEntry.first); + pAccChildObj = rEntry.second; + if(pAccChildObj != nullptr) + NotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE,pAccObj->GetParentHWND(), OBJID_CLIENT,pAccChildObj->GetResID()); + } + return 0; + +} + +/** + * Delete child element from children list. + * @param pObj Child element that should be removed from parent child list. + * @return + */ +void AccObjectWinManager::DeleteAccChildNode( AccObject* pObj ) +{ + AccObject *parentAccObj = pObj->GetParentObj(); + if( parentAccObj ) + parentAccObj->DeleteChild( pObj ); +} + +/** + * Delete XAccessible items in top window handle hashtable + * @param pXAcc XAccessible interface. + * @return + */ +void AccObjectWinManager::DeleteFromHwndXAcc(XAccessible const * pXAcc ) +{ + auto iter = std::find_if(HwndXAcc.begin(), HwndXAcc.end(), + [&pXAcc](XHWNDToXAccHash::value_type& rEntry) { return rEntry.second == pXAcc; }); + if (iter != HwndXAcc.end()) + HwndXAcc.erase(iter); +} + +/** + * Delete all children with the tree root of XAccessible pointer + * @param pXAcc Tree root XAccessible interface. + * @return + */ +void AccObjectWinManager::DeleteChildrenAccObj(XAccessible* pXAcc) +{ + AccObject* currentObj=nullptr; + AccObject* childObj=nullptr; + + currentObj = GetAccObjByXAcc( pXAcc); + if(currentObj) + { + childObj = currentObj->NextChild(); + while(childObj) + { + XAccessible *const pTmpXAcc = childObj->GetXAccessible().get(); + if(pTmpXAcc) + { + DeleteChildrenAccObj(pTmpXAcc); + DeleteAccObj(pTmpXAcc); + } + childObj = currentObj->NextChild(); + } + } +} + +/** + * Delete Acc object self. + * @param pXAcc The XAccessible interface. + * @return + */ +void AccObjectWinManager::DeleteAccObj( XAccessible* pXAcc ) +{ + if( pXAcc == nullptr ) + return; + XIdToAccObjHash::iterator temp = XIdAccList.find(pXAcc); + if( temp != XIdAccList.end() ) + { + ResIdGen.SetSub( temp->second.GetResID() ); + } + else + { + return; + } + + AccObject& accObj = temp->second; + DeleteAccChildNode( &accObj ); + DeleteAccListener( &accObj ); + if( accObj.GetIMAccessible() ) + { + accObj.GetIMAccessible()->Release(); + } + size_t i = XResIdAccList.erase(accObj.GetResID()); + assert(i != 0); + (void) i; + DeleteFromHwndXAcc(pXAcc); + if (accObj.GetRole() == AccessibleRole::DOCUMENT || + accObj.GetRole() == AccessibleRole::DOCUMENT_PRESENTATION || + accObj.GetRole() == AccessibleRole::DOCUMENT_SPREADSHEET || + accObj.GetRole() == AccessibleRole::DOCUMENT_TEXT) + { + XHWNDDocList.erase(accObj.GetParentHWND()); + } + XIdAccList.erase(pXAcc); // note: this invalidates accObj so do it last! +} + +/** + * Delete listener that inspects some XAccessible object + * @param pAccObj Accobject pointer. + * @return + */ +void AccObjectWinManager::DeleteAccListener( AccObject* pAccObj ) +{ + AccEventListener* listener = pAccObj->getListener(); + if( listener==nullptr ) + return; + listener->RemoveMeFromBroadcaster(); + pAccObj->SetListener(nullptr); +} + +/** + * Generate a child ID, which is used for AT + * @param + * @return New resource ID. + */ +inline long AccObjectWinManager::ImpleGenerateResID() +{ + return ResIdGen.GenerateNewResID(); +} + +/** + * Insert all children of the current acc object + * @param pXAcc XAccessible interface + * @param pWnd Top Window handle + * @return The calling result. + */ +bool AccObjectWinManager::InsertChildrenAccObj( css::accessibility::XAccessible* pXAcc, + HWND pWnd) +{ + if(!IsContainer(pXAcc)) + return false; + + Reference< XAccessibleContext > pRContext; + + if( pXAcc == nullptr) + return false; + pRContext = pXAcc->getAccessibleContext(); + if( !pRContext.is() ) + return false; + + short role = pRContext->getAccessibleRole(); + + if(css::accessibility::AccessibleRole::DOCUMENT == role || + css::accessibility::AccessibleRole::DOCUMENT_PRESENTATION == role || + css::accessibility::AccessibleRole::DOCUMENT_SPREADSHEET == role || + css::accessibility::AccessibleRole::DOCUMENT_TEXT == role) + { + if(IsStateManageDescendant(pXAcc)) + { + return true; + } + } + + int count = pRContext->getAccessibleChildCount(); + for (int i=0;i<count;i++) + { + Reference<XAccessible> mxAccessible + = pRContext->getAccessibleChild(i); + XAccessible* mpAccessible = mxAccessible.get(); + if(mpAccessible != nullptr) + { + InsertAccObj( mpAccessible,pXAcc,pWnd ); + InsertChildrenAccObj(mpAccessible,pWnd); + } + } + + return true; +} + +/** + * Insert child object. + * @param pCurObj The child object + * @param pParentObj The parent object + * @param pWnd Top window handle. + * @return + */ +void AccObjectWinManager::InsertAccChildNode( AccObject* pCurObj, AccObject* pParentObj, HWND /* pWnd */ ) +{ + if(pCurObj) + { + if(pParentObj) + { + pParentObj->InsertChild(pCurObj); + } + else + { + pCurObj->UpdateValidWindow(); + } + } +} + +/** + * Insert child object. + * @param pCurObj The child object + * @param pParentObj The parent object + * @param pWnd Top window handle. + * @return + */ +bool AccObjectWinManager::InsertAccObj( XAccessible* pXAcc,XAccessible* pParentXAcc,HWND pWnd ) +{ + XIdToAccObjHash::iterator itXacc = XIdAccList.find( pXAcc ); + if (itXacc != XIdAccList.end() ) + { + short nCurRole =GetRole(pXAcc); + if (AccessibleRole::SHAPE == nCurRole) + { + AccObject &objXacc = itXacc->second; + AccObject *pObjParent = objXacc.GetParentObj(); + if (pObjParent && + pObjParent->GetXAccessible().is() && + pObjParent->GetXAccessible().get() != pParentXAcc) + { + XIdToAccObjHash::iterator itXaccParent = XIdAccList.find( pParentXAcc ); + if(itXaccParent != XIdAccList.end()) + { + objXacc.SetParentObj(&(itXaccParent->second)); + } + } + } + return false; + } + + + Reference< XAccessibleContext > pRContext; + + if( pXAcc == nullptr) + return false; + + pRContext = pXAcc->getAccessibleContext(); + if( !pRContext.is() ) + return false; + + if( pWnd == nullptr ) + { + if(pParentXAcc) + { + AccObject* pObj = GetAccObjByXAcc(pParentXAcc); + if(pObj) + pWnd = pObj->GetParentHWND(); + } + if( pWnd == nullptr ) + return false; + } + + AccObject pObj( pXAcc,pAgent ); + if( pObj.GetIMAccessible() == nullptr ) + return false; + pObj.SetResID( this->ImpleGenerateResID()); + pObj.SetParentHWND( pWnd ); + + //for file name support + if (pObj.GetRole() == AccessibleRole::DOCUMENT || + pObj.GetRole() == AccessibleRole::DOCUMENT_PRESENTATION || + pObj.GetRole() == AccessibleRole::DOCUMENT_SPREADSHEET || + pObj.GetRole() == AccessibleRole::DOCUMENT_TEXT) + { + XHWNDToDocumentHash::iterator aIter = XHWNDDocList.find(pWnd); + if ( aIter != XHWNDDocList.end() ) + { + XHWNDDocList.erase( aIter ); + } + XHWNDDocList.emplace( pWnd, pXAcc ); + } + //end of file name + + ::rtl::Reference<AccEventListener> const pListener = + CreateAccEventListener(pXAcc); + if (!pListener.is()) + return false; + Reference<XAccessibleComponent> xComponent(pRContext,UNO_QUERY); + Reference<XAccessibleEventBroadcaster> broadcaster(xComponent,UNO_QUERY); + if (broadcaster.is()) + { + Reference<XAccessibleEventListener> const xListener(pListener); + broadcaster->addAccessibleEventListener(xListener); + } + else + return false; + + XIdAccList.emplace(pXAcc, pObj); + XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( pXAcc ); + XResIdAccList.emplace(pObj.GetResID(),&(pIndTemp->second)); + + AccObject* pCurObj = GetAccObjByXAcc(pXAcc); + if( pCurObj ) + { + pCurObj->SetListener(pListener); + } + + AccObject* pParentObj = GetAccObjByXAcc(pParentXAcc); + InsertAccChildNode(pCurObj,pParentObj,pWnd); + if( pCurObj ) + pCurObj->UpdateAccessibleInfoFromUnoToMSAA(); + return true; +} + + +/** + * save the pair <topwindowhandle, XAccessible> + * @param hWnd, top window handle + * @param pXAcc XAccessible interface for top window + * @return void + */ +void AccObjectWinManager::SaveTopWindowHandle(HWND hWnd, css::accessibility::XAccessible* pXAcc) +{ + HwndXAcc.emplace(hWnd,pXAcc); +} + + +/** Create the corresponding listener. + * @param pXAcc XAccessible interface. + */ +::rtl::Reference<AccEventListener> +AccObjectWinManager::CreateAccEventListener(XAccessible* pXAcc) +{ + ::rtl::Reference<AccEventListener> pRet; + Reference<XAccessibleContext> xContext = pXAcc->getAccessibleContext(); + if(xContext.is()) + { + switch( xContext->getAccessibleRole() ) + { + case AccessibleRole::DIALOG: + pRet = new AccDialogEventListener(pXAcc,pAgent); + break; + case AccessibleRole::FRAME: + pRet = new AccFrameEventListener(pXAcc,pAgent); + break; + case AccessibleRole::WINDOW: + pRet = new AccWindowEventListener(pXAcc,pAgent); + break; + case AccessibleRole::ROOT_PANE: + pRet = new AccFrameEventListener(pXAcc,pAgent); + break; + //Container + case AccessibleRole::CANVAS: + case AccessibleRole::COMBO_BOX: + case AccessibleRole::DOCUMENT: + case AccessibleRole::DOCUMENT_PRESENTATION: + case AccessibleRole::DOCUMENT_SPREADSHEET: + case AccessibleRole::DOCUMENT_TEXT: + case AccessibleRole::END_NOTE: + case AccessibleRole::FILLER: + case AccessibleRole::FOOTNOTE: + case AccessibleRole::FOOTER: + case AccessibleRole::HEADER: + case AccessibleRole::LAYERED_PANE: + case AccessibleRole::MENU_BAR: + case AccessibleRole::POPUP_MENU: + case AccessibleRole::OPTION_PANE: + case AccessibleRole::PAGE_TAB: + case AccessibleRole::PAGE_TAB_LIST: + case AccessibleRole::PANEL: + case AccessibleRole::SCROLL_PANE: + case AccessibleRole::SPLIT_PANE: + case AccessibleRole::STATUS_BAR: + case AccessibleRole::TABLE_CELL: + case AccessibleRole::TOOL_BAR: + case AccessibleRole::VIEW_PORT: + pRet = new AccContainerEventListener(pXAcc,pAgent); + break; + case AccessibleRole::PARAGRAPH: + case AccessibleRole::HEADING: + pRet = new AccParagraphEventListener(pXAcc,pAgent); + break; + //Component + case AccessibleRole::CHECK_BOX: + case AccessibleRole::ICON: + case AccessibleRole::LABEL: + case AccessibleRole::STATIC: + case AccessibleRole::MENU_ITEM: + case AccessibleRole::CHECK_MENU_ITEM: + case AccessibleRole::RADIO_MENU_ITEM: + case AccessibleRole::PUSH_BUTTON: + case AccessibleRole::RADIO_BUTTON: + case AccessibleRole::SCROLL_BAR: + case AccessibleRole::SEPARATOR: + case AccessibleRole::TOGGLE_BUTTON: + case AccessibleRole::BUTTON_DROPDOWN: + case AccessibleRole::TOOL_TIP: + case AccessibleRole::SPIN_BOX: + case AccessibleRole::DATE_EDITOR: + pRet = new AccComponentEventListener(pXAcc,pAgent); + break; + //text component + case AccessibleRole::TEXT: + pRet = new AccTextComponentEventListener(pXAcc,pAgent); + break; + //menu + case AccessibleRole::MENU: + pRet = new AccMenuEventListener(pXAcc,pAgent); + break; + //object container + case AccessibleRole::SHAPE: + + case AccessibleRole::EMBEDDED_OBJECT: + case AccessibleRole::GRAPHIC: + case AccessibleRole::TEXT_FRAME: + pRet = new AccObjectContainerEventListener(pXAcc,pAgent); + break; + //descendmanager + case AccessibleRole::LIST: + pRet = new AccListEventListener(pXAcc,pAgent); + break; + case AccessibleRole::TREE: + pRet = new AccTreeEventListener(pXAcc,pAgent); + break; + //special + case AccessibleRole::COLUMN_HEADER: + case AccessibleRole::TABLE: + pRet = new AccTableEventListener(pXAcc,pAgent); + break; + default: + pRet = new AccContainerEventListener(pXAcc,pAgent); + break; + } + } + return pRet; +} + +/** + * state is a combination integer, each bit of which represents a single state, + * such as focused,1 for the state on,0 for the state off. Here call COM interface + * to modify the state value, including DecreaseState. + * @param pXAcc XAccessible interface. + * @param pState Changed state. + * @return + */ +void AccObjectWinManager::DecreaseState( XAccessible* pXAcc,unsigned short pState ) +{ + AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); + if( pAccObj ) + pAccObj->DecreaseState( pState ); +} + +/** + * state is a combination integer, each bit of which represents a single state,such as focused,1 for + * the state on,0 for the state off. Here call COM interface to modify the state value, including + * IncreaseState. + * @param pXAcc XAccessible interface. + * @param pState Changed state. + * @return + */ +void AccObjectWinManager::IncreaseState( XAccessible* pXAcc,unsigned short pState ) +{ + AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); + if( pAccObj ) + pAccObj->IncreaseState( pState ); +} + +void AccObjectWinManager::UpdateState( css::accessibility::XAccessible* pXAcc ) +{ + AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); + if( pAccObj ) + pAccObj->UpdateState( ); +} + +/** + * Set corresponding com object's accessible name via XAccessible interface and new + * name + * @param pXAcc XAccessible interface. + * @return + */ +void AccObjectWinManager::UpdateAccName( XAccessible* pXAcc ) +{ + AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); + if( pAccObj ) + pAccObj->UpdateName(); +} + +void AccObjectWinManager::UpdateAction( XAccessible* pXAcc ) +{ + AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); + if( pAccObj ) + pAccObj->UpdateAction(); +} + +/** + * Set corresponding com object's accessible location via XAccessible interface and new + * location. + * @param pXAcc XAccessible interface. + * @return + */ +void AccObjectWinManager::SetLocation( XAccessible* pXAcc, long /*top*/, long /*left*/, long /*width*/, long /*height*/ ) +{ + AccObject* pObj = GetAccObjByXAcc( pXAcc ); + //get the location from XComponent. + Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext(); + if( pObj ) + pObj->UpdateLocation(); +} + +/** + * Set corresponding com object's value via XAccessible interface and new value. + * @param pXAcc XAccessible interface. + * @param pAny new value. + * @return + */ +void AccObjectWinManager::SetValue( XAccessible* pXAcc, Any pAny ) +{ + AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); + if( pAccObj ) + pAccObj->SetValue( pAny ); +} + +/** + * Set corresponding com object's value via XAccessible interface. + * @param pXAcc XAccessible interface. + * @return + */ +void AccObjectWinManager::UpdateValue( XAccessible* pXAcc ) +{ + AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); + if( pAccObj ) + pAccObj->UpdateValue(); +} + +/** + * Set corresponding com object's name via XAccessible interface and new name. + * @param pXAcc XAccessible interface. + * @param newName new name + * @return + */ +void AccObjectWinManager::SetAccName( XAccessible* pXAcc, Any newName) +{ + AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); + if( pAccObj ) + pAccObj->SetName( newName ); +} + +/** + * Judge if a XAccessible object is a container object. + * @param pAccessible XAccessible interface. + * @return If XAccessible object is container. + */ +bool AccObjectWinManager::IsContainer(XAccessible* pAccessible) +{ + try + { + if(pAccessible) + { + Reference<XAccessibleContext> xContext = pAccessible->getAccessibleContext(); + if(xContext.is()) + { + switch( xContext->getAccessibleRole() ) + { + case AccessibleRole::DIALOG: + case AccessibleRole::FRAME: + case AccessibleRole::WINDOW: + case AccessibleRole::ROOT_PANE: + case AccessibleRole::CANVAS: + case AccessibleRole::COMBO_BOX: + case AccessibleRole::DOCUMENT: + case AccessibleRole::DOCUMENT_PRESENTATION: + case AccessibleRole::DOCUMENT_SPREADSHEET: + case AccessibleRole::DOCUMENT_TEXT: + case AccessibleRole::EMBEDDED_OBJECT: + case AccessibleRole::END_NOTE: + case AccessibleRole::FILLER: + case AccessibleRole::FOOTNOTE: + case AccessibleRole::FOOTER: + case AccessibleRole::GRAPHIC: + case AccessibleRole::GROUP_BOX: + case AccessibleRole::HEADER: + case AccessibleRole::LAYERED_PANE: + case AccessibleRole::MENU_BAR: + case AccessibleRole::POPUP_MENU: + case AccessibleRole::OPTION_PANE: + case AccessibleRole::PAGE_TAB: + case AccessibleRole::PAGE_TAB_LIST: + case AccessibleRole::PANEL: + case AccessibleRole::SCROLL_PANE: + case AccessibleRole::SPLIT_PANE: + case AccessibleRole::STATUS_BAR: + case AccessibleRole::TABLE_CELL: + case AccessibleRole::TEXT_FRAME: + case AccessibleRole::TOOL_BAR: + case AccessibleRole::VIEW_PORT: + case AccessibleRole::SHAPE: + return true; + case AccessibleRole::COLUMN_HEADER: + case AccessibleRole::TABLE: + if(!IsStateManageDescendant(pAccessible)) + return true; + break; + case AccessibleRole::MENU: + return true; + default: + return false; + } + } + } + } + catch(...) + { + return false; + } + return false; +} + +/** + * Judge if a XAccessible object has ManageDescendant event. + * @param pAccessible XAccessible interface. + * @return If XAccessible object is managedescendant. + */ +bool AccObjectWinManager::IsStateManageDescendant(XAccessible* pAccessible) +{ + if(pAccessible) + { + Reference<XAccessibleContext> xContext = pAccessible->getAccessibleContext(); + if(xContext.is()) + { + Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet(); + if( !pRState.is() ) + return false; + + for (sal_Int16 nState : pRState->getStates()) + { + if (nState == AccessibleStateType::MANAGES_DESCENDANTS) + return true; + } + } + } + return false; +} + +/** + * Query and get IAccessible interface by XAccessible interface from list. + * @param pXAcc XAccessible interface. + * @return Com accobject interface. + */ +IMAccessible* AccObjectWinManager::GetIMAccByXAcc(XAccessible* pXAcc) +{ + AccObject* pAccObj = GetAccObjByXAcc(pXAcc); + if(pAccObj) + { + return pAccObj->GetIMAccessible(); + } + else + { + return nullptr; + } +} + +/** + * Query and get IAccessible interface by child id from list. + * @param resID, childID. + * @return Com accobject interface. + */ +IMAccessible * AccObjectWinManager::GetIAccessibleFromResID(long resID) +{ + XResIdToAccObjHash::iterator pIndTemp = XResIdAccList.find( resID ); + if ( pIndTemp == XResIdAccList.end() ) + return nullptr; + + AccObject* pObj = pIndTemp->second; + + if(pObj->GetIMAccessible()) + return pObj->GetIMAccessible(); + return nullptr; +} +/** + * Notify some object will be destroyed. + * @param pXAcc XAccessible interface. + * @return Com accobject interface. + */ +void AccObjectWinManager::NotifyDestroy(XAccessible* pXAcc) +{ + AccObject* accObj = GetAccObjByXAcc(pXAcc); + if(accObj) + { + accObj->NotifyDestroy(); + } +} + + +void AccObjectWinManager::UpdateChildState(css::accessibility::XAccessible* pAccSubMenu) +{ + Reference<css::accessibility::XAccessibleContext> xContext(pAccSubMenu,UNO_QUERY); + if (!xContext.is()) + { + return; + } + sal_Int32 nCount = xContext->getAccessibleChildCount(); + for (sal_Int32 i = 0 ; i < nCount ; ++i) + { + Reference<css::accessibility::XAccessible> xChild = xContext->getAccessibleChild(i); + if (xChild.is()) + { + AccObject *pObj = GetAccObjByXAcc(xChild.get()); + if (pObj) + { + pObj->UpdateState(); + } + } + } +} + + +bool AccObjectWinManager::IsSpecialToolbarItem(css::accessibility::XAccessible* pXAcc) +{ + if (pXAcc && oldFocus != pXAcc) + { + if (GetParentRole(pXAcc) == AccessibleRole::TOOL_BAR) + { + Reference< XAccessibleContext > pRContext(pXAcc->getAccessibleContext()); + if (pRContext.is()) + { + if (pRContext->getAccessibleRole() == AccessibleRole::TOGGLE_BUTTON) + { + return true; + } + } + } + } + return false; +} + +short AccObjectWinManager::GetRole(css::accessibility::XAccessible* pXAcc) +{ + assert(pXAcc != nullptr); + Reference<css::accessibility::XAccessibleContext> xContext = pXAcc->getAccessibleContext(); + if(xContext.is()) + { + return xContext->getAccessibleRole(); + } + return -1; +} + +XAccessible* AccObjectWinManager::GetAccDocByHWND(HWND pWnd) +{ + XHWNDToDocumentHash::iterator aIter; + aIter = XHWNDDocList.find( pWnd ); + if ( aIter != XHWNDDocList.end() ) + { + return aIter->second; + } + + return nullptr; +} + +XAccessible* AccObjectWinManager::GetAccDocByAccTopWin( XAccessible* pXAcc ) +{ + AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); + HWND hWnd = pAccObj->GetParentHWND(); + return GetAccDocByHWND(hWnd); +} + +bool AccObjectWinManager::IsTopWinAcc( css::accessibility::XAccessible* pXAcc ) +{ + bool bRet = false; + AccObject* pAccObj = GetAccObjByXAcc( pXAcc ); + if ( pAccObj ) + { + bRet = ( pAccObj->GetParentObj() == nullptr ); + } + return bRet; +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccParagraphEventListener.cxx b/winaccessibility/source/service/AccParagraphEventListener.cxx new file mode 100644 index 000000000..66783030c --- /dev/null +++ b/winaccessibility/source/service/AccParagraphEventListener.cxx @@ -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 . + */ + +#include <com/sun/star/accessibility/XAccessible.hpp> +#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/accessibility/XAccessibleEventBroadcaster.hpp> + +#include <vcl/svapp.hxx> + +#include <AccParagraphEventListener.hxx> +#include <AccObjectManagerAgent.hxx> +#include <unomsaaevent.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; + +AccParagraphEventListener::AccParagraphEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent) + :AccContainerEventListener(pAcc, Agent) +{} +AccParagraphEventListener::~AccParagraphEventListener() +{ +} + +/** + * Uno's event notifier when event is captured + * @param AccessibleEventObject the event object which contains information about event + */ +void AccParagraphEventListener::notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) +{ + SolarMutexGuard g; + + switch (aEvent.EventId) + { + case AccessibleEventId::CARET_CHANGED: + HandleCaretChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::VISIBLE_DATA_CHANGED: + HandleVisibleDataChangedEvent(); + break; + case AccessibleEventId::BOUNDRECT_CHANGED: + HandleBoundrectChangedEvent(); + break; + //Added for paragraph selected state. + case AccessibleEventId::STATE_CHANGED: + { + short State; + if( (aEvent.NewValue >>= State) && (State == AccessibleStateType::SELECTED) ) + { + pAgent->IncreaseState(m_xAccessible.get(), State); + break; + } + else if( (aEvent.OldValue >>= State) && (State == AccessibleStateType::SELECTED) ) + { + pAgent->DecreaseState(m_xAccessible.get(), State); + break; + } + + AccContainerEventListener::notifyEvent(aEvent); + break; + } + + case AccessibleEventId::TEXT_SELECTION_CHANGED: + HandleTextSelectionChangedEvent(); + break; + + default: + AccContainerEventListener::notifyEvent(aEvent); + break; + } +} + +/** + * handle the CARET_CHANGED event + * @param oldValue in UNO, this parameter is always NULL + * @param newValue in UNO, this parameter is always NULL + */ +void AccParagraphEventListener::HandleCaretChangedEvent(Any, Any) +{ + AccObjectManagerAgent::UpdateLocation(m_xAccessible.get()); + pAgent->NotifyAccEvent(UnoMSAAEvent::OBJECT_CARETCHANGE, m_xAccessible.get()); +} + +/** + * set the new state and fire the MSAA event + * @param state new state id + * @param enable true if state is set, false if state is unset + */ +void AccParagraphEventListener::SetComponentState(short state, bool enable ) +{ + // only the following state can be fired state event. + switch (state) + { + case AccessibleStateType::EDITABLE: + // no msaa state + break; + case AccessibleStateType::MULTI_LINE: + // no msaa state mapping + break; + case AccessibleStateType::SINGLE_LINE: + // no msaa state mapping + break; + default: + AccContainerEventListener::SetComponentState(state, enable); + break; + } +} + +void AccParagraphEventListener::HandleTextSelectionChangedEvent() +{ + pAgent->NotifyAccEvent(UnoMSAAEvent::TEXT_SELECTION_CHANGED, m_xAccessible.get()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccTableEventListener.cxx b/winaccessibility/source/service/AccTableEventListener.cxx new file mode 100644 index 000000000..96345cc86 --- /dev/null +++ b/winaccessibility/source/service/AccTableEventListener.cxx @@ -0,0 +1,142 @@ +/* -*- 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/XAccessible.hpp> +#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/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp> + +#include <vcl/svapp.hxx> + +#include <AccTableEventListener.hxx> +#include <AccObjectManagerAgent.hxx> +#include <unomsaaevent.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; + +AccTableEventListener::AccTableEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent) + :AccDescendantManagerEventListener(pAcc, Agent) +{} +AccTableEventListener::~AccTableEventListener() +{ +} + +/** + * Uno's event notifier when event is captured + * @param AccessibleEventObject the event object which contains information about event + */ +void AccTableEventListener::notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) +{ + SolarMutexGuard g; + + switch (aEvent.EventId) + { + case AccessibleEventId::ACTIVE_DESCENDANT_CHANGED: + HandleActiveDescendantChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + + case AccessibleEventId::TABLE_CAPTION_CHANGED: + { + pAgent->NotifyAccEvent(UnoMSAAEvent::TABLE_CAPTION_CHANGED, m_xAccessible.get()); + break; + } + case AccessibleEventId::TABLE_COLUMN_DESCRIPTION_CHANGED: + { + pAgent->NotifyAccEvent(UnoMSAAEvent::TABLE_COLUMN_DESCRIPTION_CHANGED, m_xAccessible.get()); + break; + } + case AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED: + { + pAgent->NotifyAccEvent(UnoMSAAEvent::TABLE_COLUMN_HEADER_CHANGED, m_xAccessible.get()); + break; + } + case AccessibleEventId::TABLE_ROW_HEADER_CHANGED: + { + pAgent->NotifyAccEvent(UnoMSAAEvent::TABLE_ROW_HEADER_CHANGED, m_xAccessible.get()); + break; + } + case AccessibleEventId::TABLE_MODEL_CHANGED: + { + HandleTableModelChangeEvent(aEvent.NewValue); + break; + } + case AccessibleEventId::TABLE_SUMMARY_CHANGED: + { + pAgent->NotifyAccEvent(UnoMSAAEvent::TABLE_SUMMARY_CHANGED, m_xAccessible.get()); + break; + } + case AccessibleEventId::TABLE_ROW_DESCRIPTION_CHANGED: + { + pAgent->NotifyAccEvent(UnoMSAAEvent::TABLE_ROW_DESCRIPTION_CHANGED, m_xAccessible.get()); + break; + } + default: + AccDescendantManagerEventListener::notifyEvent(aEvent); + break; + } +} + +/** + * handle the ACTIVE_DESCENDANT_CHANGED event + * @param oldValue the child to lose active + * @param newValue the child to get active + */ +void AccTableEventListener::HandleActiveDescendantChangedEvent(Any oldValue, Any newValue) +{ + Reference< XAccessible > xChild; + if(newValue >>= xChild ) + { + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + pAgent->InsertAccObj(pAcc, m_xAccessible.get()); + pAgent->NotifyAccEvent(UnoMSAAEvent::ACTIVE_DESCENDANT_CHANGED, pAcc); + } + } + else if (oldValue >>= xChild) + { + //delete an existing child + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + pAgent->DeleteAccObj( pAcc ); + } + } + +} +void AccTableEventListener::HandleTableModelChangeEvent(Any newValue) +{ + AccessibleTableModelChange aModelChange; + if (newValue >>= aModelChange) + { + if (m_xAccessible.is()) + { + //delete all oldValue's existing children + pAgent->DeleteChildrenAccObj(m_xAccessible.get()); + //add all oldValue's existing children + pAgent->InsertChildrenAccObj(m_xAccessible.get()); + } + pAgent->NotifyAccEvent(UnoMSAAEvent::TABLE_MODEL_CHANGED, m_xAccessible.get()); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccTextComponentEventListener.cxx b/winaccessibility/source/service/AccTextComponentEventListener.cxx new file mode 100644 index 000000000..1a185b0d8 --- /dev/null +++ b/winaccessibility/source/service/AccTextComponentEventListener.cxx @@ -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 . + */ + +#include <com/sun/star/accessibility/XAccessible.hpp> +#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/accessibility/XAccessibleEventBroadcaster.hpp> + +#include <vcl/svapp.hxx> + +#include <AccTextComponentEventListener.hxx> +#include <AccObjectManagerAgent.hxx> +#include <unomsaaevent.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; + +AccTextComponentEventListener::AccTextComponentEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent) + :AccComponentEventListener(pAcc, Agent) +{} +AccTextComponentEventListener::~AccTextComponentEventListener() +{ +} + +/** + * set the new state and fire the MSAA event + * @param state new state id + * @param enable true if state is set, false if state is unset + */ +void AccTextComponentEventListener::SetComponentState(short state, bool enable ) +{ + // only the following state can be fired state event. + switch (state) + { + case AccessibleStateType::EDITABLE: + // no msaa state mapping + break; + case AccessibleStateType::MULTI_LINE: + // no msaa state mapping + break; + case AccessibleStateType::SINGLE_LINE: + // no msaa state mapping + break; + default: + AccComponentEventListener::SetComponentState(state, enable); + break; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccTopWindowListener.cxx b/winaccessibility/source/service/AccTopWindowListener.cxx new file mode 100644 index 000000000..a828c36c0 --- /dev/null +++ b/winaccessibility/source/service/AccTopWindowListener.cxx @@ -0,0 +1,254 @@ +/* -*- 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/log.hxx> +#include <vcl/window.hxx> +#include <toolkit/awt/vclxaccessiblecomponent.hxx> +#include <toolkit/awt/vclxwindow.hxx> + +#include <vcl/sysdata.hxx> +#include <vcl/svapp.hxx> + +#include <AccTopWindowListener.hxx> +#include <unomsaaevent.hxx> + +#include <com/sun/star/accessibility/AccessibleRole.hpp> + +using namespace com::sun::star::uno; + +/** + * For the new opened window, generate all the UNO accessible's object, COM object and add + * accessible listener to monitor all these objects. + * @param pAccessible the accessible of the new opened window + */ +void AccTopWindowListener::HandleWindowOpened( css::accessibility::XAccessible* pAccessible ) +{ + //get SystemData from window + VclPtr<vcl::Window> window; + if (auto pvclwindow = dynamic_cast<VCLXWindow*>(pAccessible)) + window = pvclwindow->GetWindow(); + else if (auto pvclxcomponent = dynamic_cast<VCLXAccessibleComponent*>(pAccessible)) + window = pvclxcomponent->GetWindow(); + assert(window); + // The SalFrame of window may be destructed at this time + const SystemEnvData* systemdata = nullptr; + try + { + systemdata = window->GetSystemData(); + } + catch(...) + { + systemdata = nullptr; + } + Reference<css::accessibility::XAccessibleContext> xContext = pAccessible->getAccessibleContext(); + if(!xContext.is()) + return; + + css::accessibility::XAccessibleContext* pAccessibleContext = xContext.get(); + //Only AccessibleContext exist, add all listeners + if(pAccessibleContext != nullptr && systemdata != nullptr) + { + accManagerAgent.SaveTopWindowHandle(systemdata->hWnd, pAccessible); + + AddAllListeners(pAccessible,nullptr,systemdata->hWnd); + + if( window->GetStyle() & WB_MOVEABLE ) + accManagerAgent.IncreaseState( pAccessible, static_cast<unsigned short>(-1) /* U_MOVEBLE */ ); + + short role = pAccessibleContext->getAccessibleRole(); + + if (role == css::accessibility::AccessibleRole::POPUP_MENU || + role == css::accessibility::AccessibleRole::MENU ) + { + accManagerAgent.NotifyAccEvent(UnoMSAAEvent::MENUPOPUPSTART, pAccessible); + } + + if (role == css::accessibility::AccessibleRole::FRAME || + role == css::accessibility::AccessibleRole::DIALOG || + role == css::accessibility::AccessibleRole::WINDOW || + role == css::accessibility::AccessibleRole::ALERT) + { + accManagerAgent.NotifyAccEvent(UnoMSAAEvent::SHOW, pAccessible); + } + } +} + +AccTopWindowListener::AccTopWindowListener() + : accManagerAgent() +{ +} + +AccTopWindowListener::~AccTopWindowListener() +{ +} + +/** + * It is invoked when a new window is opened, the source of this EventObject is the window + */ +void AccTopWindowListener::windowOpened( const css::lang::EventObject& e ) +{ + SAL_INFO( "iacc2", "windowOpened triggered" ); + + if ( !e.Source.is()) + return; + + Reference< css::accessibility::XAccessible > xAccessible ( e.Source, UNO_QUERY ); + css::accessibility::XAccessible* pAccessible = xAccessible.get(); + if ( !pAccessible ) + return; + + SolarMutexGuard g; + + HandleWindowOpened( pAccessible ); +} + +/** + * Add the accessible event listener to object and all its children objects. + * @param pAccessible the accessible object + * @param pParentXAcc the parent of current accessible object + * @param pWND the handle of top window which current object resides + */ +void AccTopWindowListener::AddAllListeners(css::accessibility::XAccessible* pAccessible, css::accessibility::XAccessible* pParentXAcc, HWND pWND) +{ + Reference<css::accessibility::XAccessibleContext> xContext = pAccessible->getAccessibleContext(); + if(!xContext.is()) + { + return; + } + css::accessibility::XAccessibleContext* pAccessibleContext = xContext.get(); + if(pAccessibleContext == nullptr) + { + return; + } + + accManagerAgent.InsertAccObj(pAccessible, pParentXAcc, pWND); + + if (!accManagerAgent.IsContainer(pAccessible)) + { + return; + } + + + short role = pAccessibleContext->getAccessibleRole(); + if(css::accessibility::AccessibleRole::DOCUMENT == role || + css::accessibility::AccessibleRole::DOCUMENT_PRESENTATION == role || + css::accessibility::AccessibleRole::DOCUMENT_SPREADSHEET == role || + css::accessibility::AccessibleRole::DOCUMENT_TEXT == role) + { + if(accManagerAgent.IsStateManageDescendant(pAccessible)) + { + return ; + } + } + + + int count = pAccessibleContext->getAccessibleChildCount(); + for (int i=0;i<count;i++) + { + Reference<css::accessibility::XAccessible> mxAccessible + = pAccessibleContext->getAccessibleChild(i); + + css::accessibility::XAccessible* mpAccessible = mxAccessible.get(); + if(mpAccessible != nullptr) + { + Reference<css::accessibility::XAccessibleContext> mxAccessibleContext + = mpAccessible->getAccessibleContext(); + css::accessibility::XAccessibleContext* mpContext = mxAccessibleContext.get(); + if(mpContext != nullptr) + AddAllListeners( mpAccessible, pAccessible, pWND); + } + } +} + +void AccTopWindowListener::windowClosing( const css::lang::EventObject& ) +{ + SAL_INFO( "iacc2", "windowClosing triggered" ); +} + +/** + * Invoke this method when the top window is closed, remove all the objects and its children + * from current manager's cache, and remove the COM object and the accessible event listener + * assigned to the accessible objects. + */ +void AccTopWindowListener::windowClosed( const css::lang::EventObject& e ) +{ + SAL_INFO( "iacc2", "windowClosed triggered" ); + + if ( !e.Source.is()) + return; + + Reference< css::accessibility::XAccessible > xAccessible ( e.Source, UNO_QUERY ); + css::accessibility::XAccessible* pAccessible = xAccessible.get(); + if ( pAccessible == nullptr) + return; + + Reference<css::accessibility::XAccessibleContext> xContext = pAccessible->getAccessibleContext(); + if(!xContext.is()) + { + return; + } + css::accessibility::XAccessibleContext* pAccessibleContext = xContext.get(); + + short role = -1; + if(pAccessibleContext != nullptr) + { + role = pAccessibleContext->getAccessibleRole(); + + if (role == css::accessibility::AccessibleRole::POPUP_MENU || + role == css::accessibility::AccessibleRole::MENU) + { + accManagerAgent.NotifyAccEvent(UnoMSAAEvent::MENUPOPUPEND, pAccessible); + } + } + + + accManagerAgent.DeleteChildrenAccObj( pAccessible ); + if( role != css::accessibility::AccessibleRole::POPUP_MENU ) + accManagerAgent.DeleteAccObj( pAccessible ); + +} + +void AccTopWindowListener::windowMinimized( const css::lang::EventObject& ) +{ +} + +void AccTopWindowListener::windowNormalized( const css::lang::EventObject& ) +{ +} + +void AccTopWindowListener::windowActivated( const css::lang::EventObject& ) +{ +} + +void AccTopWindowListener::windowDeactivated( const css::lang::EventObject& ) +{ +} + +void AccTopWindowListener::disposing( const css::lang::EventObject& ) +{ +} + +sal_Int64 AccTopWindowListener::GetMSComPtr( + sal_Int64 hWnd, sal_Int64 lParam, sal_Int64 wParam) +{ + return accManagerAgent.Get_ToATInterface(hWnd, lParam, wParam); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccTreeEventListener.cxx b/winaccessibility/source/service/AccTreeEventListener.cxx new file mode 100644 index 000000000..ee3be70ac --- /dev/null +++ b/winaccessibility/source/service/AccTreeEventListener.cxx @@ -0,0 +1,90 @@ +/* -*- 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/XAccessible.hpp> +#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/accessibility/XAccessibleEventBroadcaster.hpp> + +#include <vcl/svapp.hxx> + +#include <AccTreeEventListener.hxx> +#include <AccObjectManagerAgent.hxx> +#include <unomsaaevent.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; + +AccTreeEventListener::AccTreeEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent) + :AccDescendantManagerEventListener(pAcc, Agent) +{} +AccTreeEventListener::~AccTreeEventListener() +{ +} + +/** + * Uno's event notifier when event is captured + * @param AccessibleEventObject the event object which contains information about event + */ +void AccTreeEventListener::notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) +{ + SolarMutexGuard g; + + switch (aEvent.EventId) + { + case AccessibleEventId::ACTIVE_DESCENDANT_CHANGED: + HandleActiveDescendantChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + default: + AccDescendantManagerEventListener::notifyEvent(aEvent); + break; + } +} + +/** + * handle the ACTIVE_DESCENDANT_CHANGED event + * @param oldValue the child to lose active + * @param newValue the child to get active + */ +void AccTreeEventListener::HandleActiveDescendantChangedEvent(Any oldValue, Any newValue) +{ + Reference< XAccessible > xChild; + if(newValue >>= xChild ) + { + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + pAgent->InsertAccObj(pAcc, m_xAccessible.get()); + pAgent->NotifyAccEvent(UnoMSAAEvent::ACTIVE_DESCENDANT_CHANGED, pAcc); + } + } + if (oldValue >>= xChild) + { + //delete an existing child + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + pAgent->DeleteAccObj( pAcc ); + } + } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccWindowEventListener.cxx b/winaccessibility/source/service/AccWindowEventListener.cxx new file mode 100644 index 000000000..fbc719a81 --- /dev/null +++ b/winaccessibility/source/service/AccWindowEventListener.cxx @@ -0,0 +1,136 @@ +/* -*- 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/XAccessible.hpp> +#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/accessibility/XAccessibleEventBroadcaster.hpp> + +#include <vcl/svapp.hxx> + +#include <AccWindowEventListener.hxx> +#include <AccObjectManagerAgent.hxx> +#include <unomsaaevent.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::accessibility; + +AccWindowEventListener::AccWindowEventListener(css::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent) + :AccEventListener(pAcc, Agent) +{} +AccWindowEventListener::~AccWindowEventListener() +{ +} + +/** + * Uno's event notifier when event is captured + * @param AccessibleEventObject: the event object which contains information about event + */ +void AccWindowEventListener::notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) +{ + SolarMutexGuard g; + + switch (aEvent.EventId) + { + case AccessibleEventId::CHILD: + HandleChildChangedEvent(aEvent.OldValue, aEvent.NewValue); + break; + case AccessibleEventId::VISIBLE_DATA_CHANGED: + HandleVisibleDataChangedEvent(); + break; + case AccessibleEventId::BOUNDRECT_CHANGED: + HandleBoundrectChangedEvent(); + break; + default: + AccEventListener::notifyEvent(aEvent); + break; + } +} + +/** + * handle the CHILD event + * @param oldValue the child to be deleted + * @param newValue the child to be added + */ +void AccWindowEventListener::HandleChildChangedEvent(Any oldValue, Any newValue) +{ + Reference< XAccessible > xChild; + if( newValue >>= xChild) + { + //create a new child + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + //add this child + pAgent->InsertAccObj(pAcc, m_xAccessible.get()); + //add all oldValue's existing children + pAgent->InsertChildrenAccObj(pAcc); + pAgent->NotifyAccEvent(UnoMSAAEvent::CHILD_ADDED, pAcc); + } + } + else if (oldValue >>= xChild) + { + //delete an existing child + if(xChild.is()) + { + XAccessible* pAcc = xChild.get(); + pAgent->NotifyAccEvent(UnoMSAAEvent::CHILD_REMOVED, pAcc); + pAgent->DeleteChildrenAccObj( pAcc ); + //delete this child + pAgent->DeleteAccObj( pAcc ); + } + } +} + +/** + * set the new state and fire the MSAA event + * @param state new state id + * @param enable true if state is set, false if state is unset + */ +void AccWindowEventListener::SetComponentState(short state, bool enable ) +{ + // only the following state can be fired state event. + switch (state) + { + case AccessibleStateType::ICONIFIED: + // no msaa state + break; + case AccessibleStateType::VISIBLE: + // UNO !VISIBLE == MSAA INVISIBLE + if( enable ) + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE); + else + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE); + break; + case AccessibleStateType::SHOWING: + // UNO !SHOWING == MSAA OFFSCREEN + if( enable ) + { + pAgent->IncreaseState(m_xAccessible.get(), AccessibleStateType::SHOWING); + } + else + pAgent->DecreaseState(m_xAccessible.get(), AccessibleStateType::SHOWING); + break; + default: + break; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/ResIDGenerator.cxx b/winaccessibility/source/service/ResIDGenerator.cxx new file mode 100644 index 000000000..749838030 --- /dev/null +++ b/winaccessibility/source/service/ResIDGenerator.cxx @@ -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 . + */ + +#include <ResIDGenerator.hxx> + +#include <cassert> + +ResIDGenerator::~ResIDGenerator() {} + +/** + * SubList stores those IDs that were ever generated and deleted, the method + * return the ID from subList first if subList is not empty, else return m_nMin--. + * Add the obsolete IDs by calling SetSub method + * + * @param + * @return new resource ID. + */ +long ResIDGenerator::GenerateNewResID() +{ + if (!subList.empty()) + { + long nRes = *(subList.begin()); + subList.pop_front(); + return nRes; + } + assert(m_nMin > LONG_MIN); + return m_nMin--; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/msaaservice_impl.cxx b/winaccessibility/source/service/msaaservice_impl.cxx new file mode 100644 index 000000000..13f10a6d7 --- /dev/null +++ b/winaccessibility/source/service/msaaservice_impl.cxx @@ -0,0 +1,275 @@ +/* -*- 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 <rtl/ref.hxx> +#include <sal/log.hxx> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implementationentry.hxx> +#include <cppuhelper/supportsservice.hxx> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/accessibility/XMSAAService.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> + +#include <com/sun/star/awt/XExtendedToolkit.hpp> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> + +#include <prewin.h> +#include <postwin.h> + +using namespace ::com::sun::star; // for odk interfaces +using namespace ::com::sun::star::uno; // for basic types +using namespace ::com::sun::star::accessibility; + +using namespace ::com::sun::star::awt; + +#include <AccTopWindowListener.hxx> + +namespace my_sc_impl +{ + +namespace { + +class MSAAServiceImpl : public ::cppu::WeakImplHelper< + XMSAAService, lang::XServiceInfo > +{ +private: + rtl::Reference<AccTopWindowListener> m_pTopWindowListener; + +public: + MSAAServiceImpl (); + + // XComponent - as used by VCL to lifecycle manage this bridge. + virtual void SAL_CALL dispose() override; + virtual void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener >& ) override + { /* dummy */ } + virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& ) override + { /* dummy */ } + + // XMSAAService + virtual sal_Int64 SAL_CALL getAccObjectPtr( + sal_Int64 hWnd, sal_Int64 lParam, sal_Int64 wParam) override; + virtual void SAL_CALL handleWindowOpened(sal_Int64) override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName ) override; + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override; +}; + +} + +/** + * Implementation of getAccObjectPtr. + * @param + * @return Com interface. + */ +sal_Int64 MSAAServiceImpl::getAccObjectPtr( + sal_Int64 hWnd, sal_Int64 lParam, sal_Int64 wParam) +{ + SolarMutexGuard g; + + if (!m_pTopWindowListener.is()) + { + return 0; + } + return m_pTopWindowListener->GetMSComPtr(hWnd, lParam, wParam); +} + +/** + * Implementation of handleWindowOpened, the method will be invoked when a + * top window is opened and AT starts up. + * @param + * @return + */ +void MSAAServiceImpl::handleWindowOpened(sal_Int64 nAcc) +{ + SolarMutexGuard g; + + SAL_INFO( "iacc2", "Window opened " << nAcc ); + + if (m_pTopWindowListener.is() && nAcc) + { + m_pTopWindowListener->HandleWindowOpened( + static_cast<css::accessibility::XAccessible*>( + reinterpret_cast<void*>(nAcc))); + } +} + +OUString MSAAServiceImpl::getImplementationName() +{ + return "com.sun.star.accessibility.my_sc_implementation.MSAAService"; +} + +/** + * Implementation of XServiceInfo, return support service name. + * @param Service name. + * @return If the service name is supported. + */ +sal_Bool MSAAServiceImpl::supportsService( OUString const & serviceName ) +{ + return cppu::supportsService(this, serviceName); +} + +/** + * Implementation of XServiceInfo, return all service names. + * @param. + * @return service name sequence. + */ +Sequence< OUString > MSAAServiceImpl::getSupportedServiceNames() +{ + return { "com.sun.star.accessibility.MSAAService" }; +} + +static void AccessBridgeHandleExistingWindow(const Reference< XMSAAService > &xAccMgr, + vcl::Window *pWindow, bool bShow) +{ + if ( pWindow ) + { + css::uno::Reference< css::accessibility::XAccessible > xAccessible; + + SAL_INFO( "iacc2", "Decide whether to register existing window with IAccessible2" ); + + // Test for combo box - drop down floating windows first + vcl::Window * pParentWindow = pWindow->GetParent(); + + if ( pParentWindow ) + { + try + { + // The parent window of a combo box floating window should have the role COMBO_BOX + css::uno::Reference< css::accessibility::XAccessible > xParentAccessible(pParentWindow->GetAccessible()); + if ( xParentAccessible.is() ) + { + css::uno::Reference< css::accessibility::XAccessibleContext > xParentAC( xParentAccessible->getAccessibleContext() ); + if ( xParentAC.is() && (css::accessibility::AccessibleRole::COMBO_BOX == xParentAC->getAccessibleRole()) ) + { + // O.k. - this is a combo box floating window corresponding to the child of role LIST of the parent. + // Let's not rely on a specific child order, just search for the child with the role LIST + sal_Int32 nCount = xParentAC->getAccessibleChildCount(); + for ( sal_Int32 n = 0; (n < nCount) && !xAccessible.is(); n++) + { + css::uno::Reference< css::accessibility::XAccessible > xChild = xParentAC->getAccessibleChild(n); + if ( xChild.is() ) + { + css::uno::Reference< css::accessibility::XAccessibleContext > xChildAC = xChild->getAccessibleContext(); + if ( xChildAC.is() && (css::accessibility::AccessibleRole::LIST == xChildAC->getAccessibleRole()) ) + { + xAccessible = xChild; + } + } + } + } + } + } + catch (css::uno::RuntimeException const&) + { + // Ignore show events that throw DisposedExceptions in getAccessibleContext(), + // but keep revoking these windows in hide(s). + if (bShow) + return; + } + } + + // We have to rely on the fact that Window::GetAccessible()->getAccessibleContext() returns a valid XAccessibleContext + // also for other menus than menubar or toplevel popup window. Otherwise we had to traverse the hierarchy to find the + // context object to this menu floater. This makes the call to Window->IsMenuFloatingWindow() obsolete. + if ( ! xAccessible.is() ) + xAccessible = pWindow->GetAccessible(); + + assert( xAccMgr.is() ); + if ( xAccessible.is() ) + { + xAccMgr->handleWindowOpened( + reinterpret_cast<sal_Int64>(xAccessible.get())); + SAL_INFO( "iacc2", "Decide whether to register existing window with IAccessible2" ); + } + } +} + +/* + * Setup and notify the OS of Accessible peers for all existing windows. + */ +static void AccessBridgeUpdateOldTopWindows( const Reference< XMSAAService > &xAccMgr ) +{ + sal_uInt16 nTopWindowCount = static_cast<sal_uInt16>(Application::GetTopWindowCount()); + + for ( sal_uInt16 i = 0; i < nTopWindowCount; i++ ) + { + vcl::Window* pTopWindow = Application::GetTopWindow( i ); + css::uno::Reference< css::accessibility::XAccessible > xAccessible = pTopWindow->GetAccessible(); + if ( xAccessible.is() ) + { + css::uno::Reference< css::accessibility::XAccessibleContext > xAC( xAccessible->getAccessibleContext() ); + if ( xAC.is()) + { + if ( !xAC->getAccessibleName().isEmpty() ) + AccessBridgeHandleExistingWindow( xAccMgr, pTopWindow, true ); + } + } + } +} + +MSAAServiceImpl::MSAAServiceImpl() +{ + Reference< XExtendedToolkit > xToolkit(Application::GetVCLToolkit(), UNO_QUERY); + + if( xToolkit.is() ) + { + m_pTopWindowListener.set(new AccTopWindowListener()); + Reference<XTopWindowListener> const xRef(m_pTopWindowListener); + xToolkit->addTopWindowListener( xRef ); + SAL_INFO( "iacc2", "successfully connected to the toolkit event hose" ); + } + else + SAL_WARN( "iacc2", "No VCL toolkit interface to listen to for events"); +} + +void MSAAServiceImpl::dispose() +{ + SolarMutexGuard g; + + // As all folders and streams contain references to their parents, + // we must remove these references so that they will be deleted when + // the hash_map of the root folder is cleared, releasing all subfolders + // and substreams which in turn release theirs, etc. When xRootFolder is + // released when this destructor completes, the folder tree should be + // deleted fully (and automagically). + m_pTopWindowListener.clear(); +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +winaccessibility_MSAAServiceImpl_get_implementation( + css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&) +{ + Reference< XMSAAService > xAccMgr( new MSAAServiceImpl() ); + + AccessBridgeUpdateOldTopWindows( xAccMgr ); + + SAL_INFO("iacc2", "Created new IAccessible2 service impl."); + + xAccMgr->acquire(); + return xAccMgr.get(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/winaccessibility.component b/winaccessibility/source/service/winaccessibility.component new file mode 100644 index 000000000..fe26e40e2 --- /dev/null +++ b/winaccessibility/source/service/winaccessibility.component @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * 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 . + --> +<component loader="com.sun.star.loader.SharedLibrary" environment="@CPPU_ENV@" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.accessibility.my_sc_implementation.MSAAService" + constructor="winaccessibility_MSAAServiceImpl_get_implementation"> + <service name="com.sun.star.accessibility.MSAAService"/> + </implementation> +</component> |