summaryrefslogtreecommitdiffstats
path: root/winaccessibility
diff options
context:
space:
mode:
Diffstat (limited to 'winaccessibility')
-rw-r--r--winaccessibility/CustomTarget_ia2_idl.mk60
-rw-r--r--winaccessibility/Library_uacccom.mk84
-rw-r--r--winaccessibility/Library_winaccessibility.mk81
-rw-r--r--winaccessibility/Makefile14
-rw-r--r--winaccessibility/Module_winaccessibility.mk23
-rw-r--r--winaccessibility/README.md62
-rw-r--r--winaccessibility/WinResTarget_uacccom.mk31
-rw-r--r--winaccessibility/inc/AccComponentEventListener.hxx68
-rw-r--r--winaccessibility/inc/AccContainerEventListener.hxx95
-rw-r--r--winaccessibility/inc/AccDescendantManagerEventListener.hxx65
-rw-r--r--winaccessibility/inc/AccDialogEventListener.hxx47
-rw-r--r--winaccessibility/inc/AccEventListener.hxx79
-rw-r--r--winaccessibility/inc/AccFrameEventListener.hxx50
-rw-r--r--winaccessibility/inc/AccListEventListener.hxx49
-rw-r--r--winaccessibility/inc/AccMenuEventListener.hxx50
-rw-r--r--winaccessibility/inc/AccObject.hxx123
-rw-r--r--winaccessibility/inc/AccObjectContainerEventListener.hxx47
-rw-r--r--winaccessibility/inc/AccObjectWinManager.hxx146
-rw-r--r--winaccessibility/inc/AccParagraphEventListener.hxx52
-rw-r--r--winaccessibility/inc/AccTableEventListener.hxx49
-rw-r--r--winaccessibility/inc/AccTextComponentEventListener.hxx43
-rw-r--r--winaccessibility/inc/AccTopWindowListener.hxx66
-rw-r--r--winaccessibility/inc/AccTreeEventListener.hxx47
-rw-r--r--winaccessibility/inc/AccWindowEventListener.hxx47
-rw-r--r--winaccessibility/inc/ResIDGenerator.hxx45
-rw-r--r--winaccessibility/inc/UAccCOMdllapi.h20
-rw-r--r--winaccessibility/inc/accHelper.hxx37
-rw-r--r--winaccessibility/inc/unomsaaevent.hxx67
-rw-r--r--winaccessibility/source/UAccCOM/AccAction.cxx110
-rw-r--r--winaccessibility/source/UAccCOM/AccAction.h102
-rw-r--r--winaccessibility/source/UAccCOM/AccActionBase.cxx215
-rw-r--r--winaccessibility/source/UAccCOM/AccActionBase.h71
-rw-r--r--winaccessibility/source/UAccCOM/AccComponent.cxx58
-rw-r--r--winaccessibility/source/UAccCOM/AccComponent.h87
-rw-r--r--winaccessibility/source/UAccCOM/AccComponentBase.cxx214
-rw-r--r--winaccessibility/source/UAccCOM/AccComponentBase.h63
-rw-r--r--winaccessibility/source/UAccCOM/AccEditableText.cxx494
-rw-r--r--winaccessibility/source/UAccCOM/AccEditableText.h118
-rw-r--r--winaccessibility/source/UAccCOM/AccHyperLink.cxx287
-rw-r--r--winaccessibility/source/UAccCOM/AccHyperLink.h136
-rw-r--r--winaccessibility/source/UAccCOM/AccHypertext.cxx390
-rw-r--r--winaccessibility/source/UAccCOM/AccHypertext.h153
-rw-r--r--winaccessibility/source/UAccCOM/AccImage.cxx110
-rw-r--r--winaccessibility/source/UAccCOM/AccImage.h99
-rw-r--r--winaccessibility/source/UAccCOM/AccRelation.cxx206
-rw-r--r--winaccessibility/source/UAccCOM/AccRelation.h91
-rw-r--r--winaccessibility/source/UAccCOM/AccTable.cxx1078
-rw-r--r--winaccessibility/source/UAccCOM/AccTable.h184
-rw-r--r--winaccessibility/source/UAccCOM/AccTableCell.cxx311
-rw-r--r--winaccessibility/source/UAccCOM/AccTableCell.h87
-rw-r--r--winaccessibility/source/UAccCOM/AccText.cxx259
-rw-r--r--winaccessibility/source/UAccCOM/AccText.h129
-rw-r--r--winaccessibility/source/UAccCOM/AccTextBase.cxx810
-rw-r--r--winaccessibility/source/UAccCOM/AccTextBase.h111
-rw-r--r--winaccessibility/source/UAccCOM/AccValue.cxx237
-rw-r--r--winaccessibility/source/UAccCOM/AccValue.h102
-rw-r--r--winaccessibility/source/UAccCOM/AccessibleKeyStroke.h152
-rw-r--r--winaccessibility/source/UAccCOM/EnumVariant.cxx258
-rw-r--r--winaccessibility/source/UAccCOM/EnumVariant.h98
-rw-r--r--winaccessibility/source/UAccCOM/MAccessible.cxx2767
-rw-r--r--winaccessibility/source/UAccCOM/MAccessible.h225
-rw-r--r--winaccessibility/source/UAccCOM/Resource.h38
-rw-r--r--winaccessibility/source/UAccCOM/StdAfx.cxx26
-rw-r--r--winaccessibility/source/UAccCOM/UAccCOM.cxx109
-rw-r--r--winaccessibility/source/UAccCOM/UAccCOM.def5
-rw-r--r--winaccessibility/source/UAccCOM/UAccCOM.rc90
-rw-r--r--winaccessibility/source/UAccCOM/UNOXWrapper.cxx35
-rw-r--r--winaccessibility/source/UAccCOM/UNOXWrapper.h50
-rw-r--r--winaccessibility/source/UAccCOM/acccommon.h68
-rw-r--r--winaccessibility/source/UAccCOM/stdafx.h64
-rw-r--r--winaccessibility/source/UAccCOMIDL/UAccCOM.idl212
-rw-r--r--winaccessibility/source/UAccCOMIDL/defines.idl28
-rw-r--r--winaccessibility/source/service/AccComponentEventListener.cxx327
-rw-r--r--winaccessibility/source/service/AccContainerEventListener.cxx498
-rw-r--r--winaccessibility/source/service/AccDescendantManagerEventListener.cxx198
-rw-r--r--winaccessibility/source/service/AccDialogEventListener.cxx93
-rw-r--r--winaccessibility/source/service/AccEventListener.cxx296
-rw-r--r--winaccessibility/source/service/AccFrameEventListener.cxx128
-rw-r--r--winaccessibility/source/service/AccListEventListener.cxx126
-rw-r--r--winaccessibility/source/service/AccMenuEventListener.cxx106
-rw-r--r--winaccessibility/source/service/AccObject.cxx1164
-rw-r--r--winaccessibility/source/service/AccObjectContainerEventListener.cxx68
-rw-r--r--winaccessibility/source/service/AccObjectWinManager.cxx1125
-rw-r--r--winaccessibility/source/service/AccParagraphEventListener.cxx130
-rw-r--r--winaccessibility/source/service/AccTableEventListener.cxx142
-rw-r--r--winaccessibility/source/service/AccTextComponentEventListener.cxx67
-rw-r--r--winaccessibility/source/service/AccTopWindowListener.cxx253
-rw-r--r--winaccessibility/source/service/AccTreeEventListener.cxx90
-rw-r--r--winaccessibility/source/service/AccWindowEventListener.cxx98
-rw-r--r--winaccessibility/source/service/ResIDGenerator.cxx46
-rw-r--r--winaccessibility/source/service/msaaservice_impl.cxx275
-rw-r--r--winaccessibility/source/service/winaccessibility.component25
92 files changed, 17439 insertions, 0 deletions
diff --git a/winaccessibility/CustomTarget_ia2_idl.mk b/winaccessibility/CustomTarget_ia2_idl.mk
new file mode 100644
index 0000000000..364e6b6257
--- /dev/null
+++ b/winaccessibility/CustomTarget_ia2_idl.mk
@@ -0,0 +1,60 @@
+# -*- 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))
+
+iaccessible2_DIR := $(call gb_UnpackedTarball_get_dir,IAccessible2)
+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)/UAccCOM.h \
+ $(wina11y_COMIDLDIR)/defines.h \
+ $(wina11y_COMIDLDIR)/ia2_api_all.h
+
+$(wina11y_COMIDLDIR)/ia2_api_all.h: $(call gb_ExternalProject_get_target,IAccessible2) \
+ | $(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)/ia2_api_all.tlb \
+ -h $(wina11y_COMIDLDIR)/ia2_api_all.h \
+ -iid $(wina11y_COMIDLDIR)/ia2_api_all_i.c \
+ -dlldata $(wina11y_COMIDLDIR)/dlldata.c \
+ -proxy $(wina11y_COMIDLDIR)/ia2_api_all_p.c \
+ -Oicf \
+ $(SOLARINC) \
+ -I $(wina11y_SOURCE) \
+ -I $(iaccessible2_DIR) \
+ $(iaccessible2_DIR)/ia2_api_all.idl)
+ $(call gb_Trace_EndRange,$(subst $(WORKDIR)/,,$@),IDL)
+
+$(wina11y_COMIDLDIR)/%.h : $(wina11y_SOURCE)/%.idl \
+ $(call gb_ExternalProject_get_target,IAccessible2) \
+ | $(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) \
+ -I $(iaccessible2_DIR) \
+ $<)
+ $(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 0000000000..0fb07814b2
--- /dev/null
+++ b/winaccessibility/Library_uacccom.mk
@@ -0,0 +1,84 @@
+# -*- 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 \
+ utl \
+))
+
+$(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 0000000000..fd4325845e
--- /dev/null
+++ b/winaccessibility/Library_winaccessibility.mk
@@ -0,0 +1,81 @@
+# -*- 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/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 0000000000..0997e62848
--- /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 0000000000..2421164b34
--- /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 0000000000..6abf34a37e
--- /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 0000000000..13de1d505b
--- /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 0000000000..72666b2a56
--- /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, AccObjectWinManager* pManager);
+ 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(sal_Int64 state, bool enable) override;
+ virtual void FireStatePropertyChange(sal_Int64 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 0000000000..e6d284e75a
--- /dev/null
+++ b/winaccessibility/inc/AccContainerEventListener.hxx
@@ -0,0 +1,95 @@
+/* -*- 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 containers and provides
+ * the detailed support for some related methods.
+ */
+class AccContainerEventListener: public AccEventListener
+{
+public:
+ AccContainerEventListener(css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager);
+ virtual ~AccContainerEventListener() override;
+
+ //AccessibleEventListener
+ virtual void SAL_CALL notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) override;
+
+ //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(sal_Int64 state, bool enable) override;
+ virtual void FireStatePropertyChange(sal_Int64 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 0000000000..f910c2e644
--- /dev/null
+++ b/winaccessibility/inc/AccDescendantManagerEventListener.hxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+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, AccObjectWinManager* pManager);
+ 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);
+
+ 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 0000000000..8f47fa94ab
--- /dev/null
+++ b/winaccessibility/inc/AccDialogEventListener.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 "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, AccObjectWinManager* pManager);
+ virtual ~AccDialogEventListener() override;
+
+ //AccessibleEventListener
+ virtual void SAL_CALL
+ notifyEvent(const css::accessibility::AccessibleEventObject& aEvent) override;
+
+ //state changed
+ virtual void SetComponentState(sal_Int64 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 0000000000..e9dd0e64be
--- /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 AccObjectWinManager;
+
+/**
+ * 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;
+ // pointer for object's manager
+ AccObjectWinManager* m_pObjManager;
+
+public:
+ AccEventListener(css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager);
+ 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);
+
+ virtual void HandleChildChangedEvent(css::uno::Any oldValue, css::uno::Any newValue);
+ virtual void HandleDescriptionChangedEvent();
+
+ //for state changed event
+ virtual void HandleStateChangedEvent(css::uno::Any oldValue, css::uno::Any newValue);
+ virtual void SetComponentState(sal_Int64 state, bool enable);
+ virtual void FireStatePropertyChange(sal_Int64 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(bool isNotifyDestroy);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/winaccessibility/inc/AccFrameEventListener.hxx b/winaccessibility/inc/AccFrameEventListener.hxx
new file mode 100644
index 0000000000..b575b57f50
--- /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, AccObjectWinManager* pManager);
+ 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) override;
+
+ //state changed
+ virtual void SetComponentState(sal_Int64 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 0000000000..eb9911308d
--- /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, AccObjectWinManager* pManager);
+ 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 0000000000..fbe4eb2900
--- /dev/null
+++ b/winaccessibility/inc/AccMenuEventListener.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 "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, AccObjectWinManager* pManager);
+ virtual ~AccMenuEventListener() override;
+
+ //AccessibleEventListener
+ virtual void SAL_CALL
+ notifyEvent(const css::accessibility::AccessibleEventObject& aEvent) override;
+
+ //for selection changed event
+ virtual void HandleSelectionChangedEventNoArgs();
+
+ //for state changed event
+ virtual void FireStatePropertyChange(sal_Int64 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 0000000000..65c8f57773
--- /dev/null
+++ b/winaccessibility/inc/AccObject.hxx
@@ -0,0 +1,123 @@
+/* -*- 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"
+#include <UAccCOM.h>
+
+class AccEventListener;
+class AccObjectWinManager;
+class AccObject;
+
+typedef std::vector<AccObject *> IAccChildList;
+
+
+class AccObject
+{
+private:
+
+ short m_accRole;
+ long m_resID;
+ HWND m_pParantID;
+ IMAccessible* const m_pIMAcc; // AccObjectManager::GetTopWindowIMAccessible relies on this being const
+ AccObject* m_pParentObj;
+ IAccChildList m_childrenList;
+ ::rtl::Reference<AccEventListener> m_pListener;
+
+ 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(sal_Int64 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, AccObjectWinManager* pManager = 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();
+
+ ::rtl::Reference<AccEventListener> 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( sal_Int64 xState );//call COM interface DecreaseState method
+ void IncreaseState( sal_Int64 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 setFocus();
+ void unsetFocus();
+
+ 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 0000000000..37ab738068
--- /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, AccObjectWinManager* pManager);
+ 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/AccObjectWinManager.hxx b/winaccessibility/inc/AccObjectWinManager.hxx
new file mode 100644
index 0000000000..024a58fc86
--- /dev/null
+++ b/winaccessibility/inc/AccObjectWinManager.hxx
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <map>
+#include <mutex>
+
+#if !defined WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include <prewin.h>
+#include <windows.h>
+#include <postwin.h>
+#include <rtl/ref.hxx>
+#include "ResIDGenerator.hxx"
+#include <UAccCOM.h>
+
+namespace com::sun::star::accessibility {
+class XAccessible;
+}
+class ResIDGenerator;
+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
+{
+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;
+
+ // guard any access to XIdAccList and HwndXAcc
+ std::recursive_mutex m_Mutex;
+
+ //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;
+
+ ResIDGenerator ResIdGen;
+
+private:
+ long ImpleGenerateResID();
+ AccObject* GetAccObjByXAcc( css::accessibility::XAccessible* pXAcc);
+
+ IMAccessible* GetTopWindowIMAccessible(HWND hWnd);
+
+ css::accessibility::XAccessible* GetAccDocByHWND(HWND hWnd);
+
+ static rtl::Reference<AccEventListener> DeleteAccListener(AccObject* pAccObj);
+ static void InsertAccChildNode(AccObject* pCurObj,AccObject* pParentObj,HWND pWnd);
+ static void DeleteAccChildNode(AccObject* pChild);
+ void DeleteFromHwndXAcc(css::accessibility::XAccessible const * pXAcc );
+
+ ::rtl::Reference<AccEventListener> CreateAccEventListener(
+ css::accessibility::XAccessible* pXAcc);
+public:
+ AccObjectWinManager();
+ virtual ~AccObjectWinManager();
+ virtual bool InsertAccObj(css::accessibility::XAccessible* pXAcc,
+ css::accessibility::XAccessible* pParentXAcc,
+ HWND pWnd = nullptr);
+ 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);
+
+ sal_Int64 Get_ToATInterface(sal_Int64 nHWnd, long lParam, WPARAM wParam);
+
+ void DecreaseState(css::accessibility::XAccessible* pXAcc, sal_Int64 nState);
+ void IncreaseState(css::accessibility::XAccessible* pXAcc, sal_Int64 nState);
+ void UpdateState( css::accessibility::XAccessible* pXAcc );
+
+ 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 );
+
+ virtual IMAccessible* GetIAccessibleFromXAccessible(css::accessibility::XAccessible* pXAcc);
+ virtual 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 0000000000..d2f5457e1b
--- /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, HEADING and BLOCK_QUOTE.
+ * It defines the procedure of specific event handling related with text containers and provides
+ * the detailed support for some related methods.
+ */
+class AccParagraphEventListener : public AccContainerEventListener
+{
+public:
+ AccParagraphEventListener(css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager);
+ 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(sal_Int64 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 0000000000..ee0738f21a
--- /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, AccObjectWinManager* pManager);
+ 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 0000000000..d4b78bcd30
--- /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,
+ AccObjectWinManager* pManager);
+ virtual ~AccTextComponentEventListener() override;
+
+ virtual void SetComponentState(sal_Int64 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 0000000000..d48ad035dd
--- /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 "AccObjectWinManager.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:
+ AccObjectWinManager m_aAccObjectManager;
+
+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 0000000000..cb6551db44
--- /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, AccObjectWinManager* pManager);
+ 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 0000000000..595f340990
--- /dev/null
+++ b/winaccessibility/inc/AccWindowEventListener.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 "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, AccObjectWinManager* pManager);
+ virtual ~AccWindowEventListener() override;
+
+ // XAccessibleEventListener
+ virtual void SAL_CALL
+ notifyEvent(const css::accessibility::AccessibleEventObject& aEvent) override;
+
+ //state changed
+ virtual void SetComponentState(sal_Int64 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 0000000000..400f58a2e6
--- /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 0000000000..50f705c6da
--- /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 0000000000..4e2d941c41
--- /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 0000000000..e8d77d7cdc
--- /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 0000000000..094e102519
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccAction.cxx
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/**
+ * AccAction.cpp : Implementation of CAccAction
+ */
+#include "stdafx.h"
+#include <UAccCOM.h>
+#include "AccAction.h"
+
+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 0000000000..7fcff08105
--- /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 0000000000..0fb2d7bbce
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccActionBase.cxx
@@ -0,0 +1,215 @@
+/* -*- 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 "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 {
+
+ if( pRXAct.is() && nActions != nullptr )
+ {
+ *nActions = pRXAct->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 pRXAct->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 {
+
+ if(description == nullptr)
+ return E_INVALIDARG;
+
+ if(!pRXAct.is())
+ return E_FAIL;
+
+ OUString ouStr = pRXAct->getAccessibleActionDescription(actionIndex);
+
+ 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 = pRXAct->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 0000000000..9bf2c70b4b
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccActionBase.h
@@ -0,0 +1,71 @@
+/* -*- 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;
+};
+
+/* 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 0000000000..e1e7af6abf
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccComponent.cxx
@@ -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 .
+ */
+
+/**
+ * AccComponent.cpp : Implementation of CUAccCOMApp and DLL registration.
+ */
+#include "stdafx.h"
+#include <UAccCOM.h>
+#include "AccComponent.h"
+
+/**
+ * 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 0000000000..9a620a5231
--- /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 0000000000..1cd6cdc1c8
--- /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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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 0000000000..83770ba2d2
--- /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 0000000000..212546e12e
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccEditableText.cxx
@@ -0,0 +1,494 @@
+/* -*- 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 <UAccCOM.h>
+#include "AccEditableText.h"
+
+#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 {
+
+ 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 {
+
+ 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 {
+
+ 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 0000000000..244dc626bb
--- /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 0000000000..40a5280c2c
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccHyperLink.cxx
@@ -0,0 +1,287 @@
+/* -*- 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 <UAccCOM.h>
+#include "AccHyperLink.h"
+
+#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 {
+
+ if(anchor == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ 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 {
+
+ if(anchorTarget == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ 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 {
+
+ 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 {
+
+ if(index == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ 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 {
+
+ if(valid == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ 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 0000000000..42d65a8335
--- /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 0000000000..c1f81c8884
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccHypertext.cxx
@@ -0,0 +1,390 @@
+/* -*- 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 <UAccCOM.h>
+#include "AccHypertext.h"
+#include "AccHyperLink.h"
+#include "acccommon.h"
+
+#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 {
+
+ if(hyperlinkCount == nullptr)
+ return E_INVALIDARG;
+
+ 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 {
+
+ if(hyperlink == nullptr)
+ return E_INVALIDARG;
+
+ 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 {
+
+ if(hyperlinkIndex == nullptr)
+ return E_INVALIDARG;
+
+ 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 0000000000..3a6dccfb12
--- /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 0000000000..7dbfcc339c
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccImage.cxx
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "stdafx.h"
+#include <UAccCOM.h>
+#include "AccImage.h"
+
+#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
+ {
+ 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 0000000000..4e0708a180
--- /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 0000000000..b866d3f0ba
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccRelation.cxx
@@ -0,0 +1,206 @@
+/* -*- 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 <UAccCOM.h>
+#include "AccRelation.h"
+
+#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 = CMAccessible::get_IAccessibleFromXAccessible(xRAcc.get());
+ if (pRet)
+ {
+ *target = 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 {
+
+ 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 0000000000..df258f709d
--- /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 0000000000..a158cf7066
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccTable.cxx
@@ -0,0 +1,1078 @@
+/* -*- 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 <UAccCOM.h>
+#include "AccTable.h"
+
+#include <sal/log.hxx>
+#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 {
+
+ if(accessible == nullptr)
+ return E_INVALIDARG;
+
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Reference<XAccessible> pRAcc = pRXTable->getAccessibleCellAt(row, column);
+
+ if(!pRAcc.is())
+ {
+ *accessible = nullptr;
+ return E_FAIL;
+ }
+
+ IAccessible* pRet = CMAccessible::get_IAccessibleFromXAccessible(pRAcc.get());
+ if (pRet)
+ {
+ *accessible = pRet;
+ pRet->AddRef();
+ return S_OK;
+ }
+ else if(pRAcc.is())
+ {
+ Reference<XAccessible> pxTable(pRXTable, UNO_QUERY);
+
+ CMAccessible::g_pAccObjectManager->InsertAccObj(pRAcc.get(),pxTable.get());
+ pRet = CMAccessible::get_IAccessibleFromXAccessible(pRAcc.get());
+
+ if (pRet)
+ {
+ *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 {
+
+ if(description == nullptr)
+ return E_INVALIDARG;
+
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ const OUString& ouStr = pRXTable->getAccessibleColumnDescription(column);
+
+ 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 {
+
+ if(accessibleTable == nullptr || startingRowIndex == nullptr)
+ return E_INVALIDARG;
+
+ 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 {
+
+ if(columnCount == nullptr)
+ return E_INVALIDARG;
+
+ 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 {
+
+ if(rowCount == nullptr)
+ return E_INVALIDARG;
+
+ 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 {
+
+ if(columnCount == nullptr)
+ return E_INVALIDARG;
+
+ 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 {
+
+ if(rowCount == nullptr)
+ return E_INVALIDARG;
+
+ 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 {
+
+ if(description == nullptr)
+ return E_INVALIDARG;
+
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ const OUString& ouStr = pRXTable->getAccessibleRowDescription(row);
+
+ 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 {
+
+ if(accessibleTable == nullptr || startingColumnIndex == nullptr)
+ return E_INVALIDARG;
+
+ 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 {
+
+ if(rows == nullptr || nRows == nullptr)
+ return E_INVALIDARG;
+
+ 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 {
+
+ if(columns == nullptr || numColumns == nullptr)
+ return E_INVALIDARG;
+
+ 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 {
+
+ if(accessible == nullptr)
+ return E_INVALIDARG;
+
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Reference<XAccessible> pRAcc = pRXTable->getAccessibleSummary();
+
+ IAccessible* pRet = CMAccessible::get_IAccessibleFromXAccessible(pRAcc.get());
+
+ 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 {
+
+ if(isSelected == nullptr)
+ return E_INVALIDARG;
+
+ 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 {
+
+ if(isSelected == nullptr)
+ return E_INVALIDARG;
+
+ 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 {
+
+ if(isSelected == nullptr)
+ return E_INVALIDARG;
+
+ 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 ++)
+ {
+ sal_Int64 nChildIndex = pRXTable->getAccessibleIndex(row, lCol);
+ pRSelection->selectAccessibleChild(nChildIndex);
+ }
+
+ 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 ++)
+ {
+ sal_Int64 nChildIndex = pRXTable->getAccessibleIndex(lRow, column);
+ pRSelection->selectAccessibleChild(nChildIndex);
+ }
+
+ 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 ++)
+ {
+ sal_Int64 nChildIndex = pRXTable->getAccessibleIndex(row, lColumn);
+ pRSelection->deselectAccessibleChild(nChildIndex);
+ }
+
+ 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 ++)
+ {
+ sal_Int64 nChildIndex = pRXTable->getAccessibleIndex(lRow, column);
+ pRSelection->deselectAccessibleChild(nChildIndex);
+ }
+ 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 {
+
+ if(columnIndex == nullptr)
+ return E_INVALIDARG;
+
+ 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 {
+
+ if(rowIndex == nullptr)
+ return E_INVALIDARG;
+
+ 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 {
+
+ if(childIndex == nullptr)
+ return E_INVALIDARG;
+
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ sal_Int64 nIndex = pRXTable->getAccessibleIndex(RowIndex, columnIndex);
+ if (nIndex > std::numeric_limits<long>::max())
+ {
+ // use -2 when the child index is too large to fit into 32 bit to neither use the
+ // valid index of another child nor -1, which is more commonly used to indicate that
+ // a child is no more inside of a parent or invalid otherwise
+ SAL_WARN("vcl.qt", "CAccTable::get_childIndex: Child index exceeds maximum long value, "
+ "returning -2.");
+ nIndex = -2;
+ }
+ *childIndex = nIndex;
+ 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 {
+
+ if(childCount == nullptr)
+ return E_INVALIDARG;
+
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Reference<XAccessibleSelection> pRSelection(pRXTable, UNO_QUERY);
+ if(!pRSelection.is())
+ return E_FAIL;
+
+ sal_Int64 nSelected = pRSelection->getSelectedAccessibleChildCount();
+ if (nSelected > std::numeric_limits<long>::max())
+ {
+ SAL_WARN("iacc2", "CAccTable::get_nSelectedChildren: Selected item count exceeds maximum long value, "
+ "using max long.");
+ nSelected = std::numeric_limits<long>::max();
+ }
+ *childCount = nSelected;
+ 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 {
+
+ if(children == nullptr || nChildren == nullptr)
+ return E_INVALIDARG;
+
+ if(!pRXTable.is())
+ return E_FAIL;
+
+ Reference<XAccessibleSelection> pRSelection(pRXTable, UNO_QUERY);
+ if(!pRSelection.is())
+ return E_FAIL;
+
+ sal_Int64 nChildCount = pRSelection->getSelectedAccessibleChildCount();
+ if (nChildCount > std::numeric_limits<long>::max())
+ {
+ SAL_WARN("iacc2", "CAccTable::get_selectedChildren: Selected child count exceeds maximum long value, "
+ "using max long.");
+ nChildCount = std::numeric_limits<long>::max();
+ }
+
+ *nChildren = nChildCount;
+ *children = static_cast<long*>(CoTaskMemAlloc(nChildCount * sizeof(long)));
+
+ for( sal_Int64 i = 0; i< nChildCount; i++)
+ {
+ Reference<XAccessible> pRAcc = pRSelection->getSelectedAccessibleChild(i);
+ if(pRAcc.is())
+ {
+ Reference<XAccessibleContext> pRContext(pRAcc, UNO_QUERY);
+ if( !pRContext.is() )
+ return E_FAIL;
+
+
+ sal_Int64 nChildIndex = pRContext->getAccessibleIndexInParent();
+ if (nChildIndex > std::numeric_limits<long>::max())
+ {
+ SAL_WARN("iacc2", "CAccTable::get_selectedChildren: Child index exceeds maximum long value, "
+ "using max long.");
+ nChildIndex = std::numeric_limits<long>::max();
+ }
+ (*children)[i] = nChildIndex;
+ }
+ }
+
+ 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;
+
+ sal_Int64 nSelected = xSelection->getSelectedAccessibleChildCount();
+ if (nSelected > std::numeric_limits<long>::max())
+ {
+ SAL_WARN("iacc2", "CAccTable::get_selectedCells: Selected cell count exceeds maximum long value, "
+ "using max long.");
+ nSelected = std::numeric_limits<long>::max();
+ }
+ *nSelectedCells = nSelected;
+
+ *cells = static_cast<IUnknown**>(CoTaskMemAlloc(nSelected * sizeof(IUnknown*)));
+
+ for (sal_Int64 i = 0; i < nSelected; i++)
+ {
+ Reference<XAccessible> xAcc = xSelection->getSelectedAccessibleChild(i);
+ assert(xAcc.is());
+
+ IAccessible* pIAccessible = CMAccessible::get_IAccessibleFromXAccessible(xAcc.get());
+
+ if (!pIAccessible)
+ {
+ Reference<XAccessible> xTable(pRXTable, UNO_QUERY);
+ CMAccessible::g_pAccObjectManager->InsertAccObj(xAcc.get(), xTable.get());
+ pIAccessible = CMAccessible::get_IAccessibleFromXAccessible(xAcc.get());
+ }
+
+ assert(pIAccessible && "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 0000000000..d5805c3c0b
--- /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 0000000000..95725c2a40
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccTableCell.cxx
@@ -0,0 +1,311 @@
+/* -*- 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 "MAccessible.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_columnHeaderCells(IUnknown*** cellAccessibles,
+ long* pColumnHeaderCellCount)
+{
+ SolarMutexGuard g;
+
+ if (!cellAccessibles || !pColumnHeaderCellCount)
+ return E_INVALIDARG;
+
+ if (!m_xTable.is())
+ return E_FAIL;
+
+ Reference<XAccessibleTable> xHeaders = m_xTable->getAccessibleColumnHeaders();
+ if (!xHeaders.is())
+ return E_FAIL;
+
+ const sal_Int32 nCount = xHeaders->getAccessibleRowCount();
+ *pColumnHeaderCellCount = nCount;
+ *cellAccessibles = static_cast<IUnknown**>(CoTaskMemAlloc(nCount * sizeof(IUnknown*)));
+ sal_Int32 nCol = 0;
+ get_columnIndex(&nCol);
+ for (sal_Int32 nRow = 0; nRow < nCount; nRow++)
+ {
+ Reference<XAccessible> xCell = xHeaders->getAccessibleCellAt(nRow, nCol);
+ assert(xCell.is());
+
+ IAccessible* pIAccessible = CMAccessible::get_IAccessibleFromXAccessible(xCell.get());
+ if (!pIAccessible)
+ {
+ Reference<XAccessible> xTableAcc(m_xTable, UNO_QUERY);
+ CMAccessible::g_pAccObjectManager->InsertAccObj(xCell.get(), xTableAcc.get());
+ pIAccessible = CMAccessible::get_IAccessibleFromXAccessible(xCell.get());
+ }
+ assert(pIAccessible && "Couldn't retrieve IAccessible object for cell.");
+
+ pIAccessible->AddRef();
+ (*cellAccessibles)[nRow] = pIAccessible;
+ }
+ return S_OK;
+}
+
+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_rowHeaderCells(IUnknown*** cellAccessibles,
+ long* pRowHeaderCellCount)
+{
+ SolarMutexGuard g;
+
+ if (!cellAccessibles || !pRowHeaderCellCount)
+ return E_INVALIDARG;
+
+ if (!m_xTable.is())
+ return E_FAIL;
+
+ Reference<XAccessibleTable> xHeaders = m_xTable->getAccessibleRowHeaders();
+ if (!xHeaders.is())
+ return E_FAIL;
+
+ const sal_Int32 nCount = xHeaders->getAccessibleColumnCount();
+ *pRowHeaderCellCount = nCount;
+ *cellAccessibles = static_cast<IUnknown**>(CoTaskMemAlloc(nCount * sizeof(IUnknown*)));
+ sal_Int32 nRow = 0;
+ get_rowIndex(&nRow);
+ for (sal_Int32 nCol = 0; nCol < nCount; nCol++)
+ {
+ Reference<XAccessible> xCell = xHeaders->getAccessibleCellAt(nRow, nCol);
+ assert(xCell.is());
+
+ IAccessible* pIAccessible = CMAccessible::get_IAccessibleFromXAccessible(xCell.get());
+ if (!pIAccessible)
+ {
+ Reference<XAccessible> xTableAcc(m_xTable, UNO_QUERY);
+ CMAccessible::g_pAccObjectManager->InsertAccObj(xCell.get(), xTableAcc.get());
+ pIAccessible = CMAccessible::get_IAccessibleFromXAccessible(xCell.get());
+ }
+ assert(pIAccessible && "Couldn't retrieve IAccessible object for cell.");
+
+ pIAccessible->AddRef();
+ (*cellAccessibles)[nCol] = pIAccessible;
+ }
+ return S_OK;
+}
+
+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;
+ }
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_rowColumnExtents(long* pRow, long* pColumn,
+ long* pRowExtents,
+ long* pColumnExtents,
+ boolean* pIsSelected)
+{
+ SolarMutexGuard g;
+
+ if (!pRow || !pColumn || !pRowExtents || !pColumnExtents || !pIsSelected)
+ return E_INVALIDARG;
+
+ if (get_rowIndex(pRow) != S_OK)
+ return E_FAIL;
+ if (get_columnIndex(pColumn) != S_OK)
+ return E_FAIL;
+ if (get_rowExtent(pRowExtents) != S_OK)
+ return E_FAIL;
+ if (get_columnExtent(pColumnExtents) != S_OK)
+ return E_FAIL;
+ if (get_isSelected(pIsSelected) != S_OK)
+ return E_FAIL;
+ return S_OK;
+}
+
+COM_DECLSPEC_NOTHROW STDMETHODIMP CAccTableCell::get_table(IUnknown** ppTable)
+{
+ if (!ppTable)
+ return E_INVALIDARG;
+
+ if (!m_xTable.is())
+ return E_FAIL;
+
+ Reference<XAccessible> xAcc(m_xTable, UNO_QUERY);
+ if (!xAcc.is())
+ return E_FAIL;
+
+ IAccessible* pRet = CMAccessible::get_IAccessibleFromXAccessible(xAcc.get());
+ if (!pRet)
+ return E_FAIL;
+
+ *ppTable = pRet;
+ pRet->AddRef();
+ return S_OK;
+}
+
+/* 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 0000000000..95250d53ad
--- /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;
+ STDMETHOD(get_columnIndex)(long*) override;
+ STDMETHOD(get_rowExtent)(long*) override;
+ STDMETHOD(get_rowHeaderCells)(IUnknown***, long*) override;
+ STDMETHOD(get_rowIndex)(long*) override;
+ STDMETHOD(get_isSelected)(boolean*) override;
+ STDMETHOD(get_rowColumnExtents)(long*, long*, long*, long*, boolean*) override;
+ STDMETHOD(get_table)(IUnknown**) override;
+
+private:
+ css::uno::Reference<css::accessibility::XAccessibleTable> m_xTable;
+ sal_Int64 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 0000000000..0cddc52a8f
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccText.cxx
@@ -0,0 +1,259 @@
+/* -*- 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 <UAccCOM.h>
+#include "AccText.h"
+
+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 0000000000..eba821aae8
--- /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 0000000000..a50cee9dd4
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccTextBase.cxx
@@ -0,0 +1,810 @@
+/* -*- 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/accessibility/AccessibleTextAttributeHelper.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
+
+
+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 {
+
+ 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
+ {
+ pRXText->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;
+
+ if(!pRXText.is())
+ {
+ return E_FAIL;
+ }
+
+ if (offset < 0 || offset > pRXText->getCharacterCount() )
+ return E_FAIL;
+
+
+ const OUString sAttrs = AccessibleTextAttributeHelper::GetIAccessible2TextAttributes(pRXText,
+ IA2AttributeType::TextAttributes,
+ offset, *startOffset, *endOffset);
+
+ if(*textAttributes)
+ SysFreeString(*textAttributes);
+ *textAttributes = SysAllocString(o3tl::toW(sAttrs.getStr()));
+
+ 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;
+
+ if(!pRXText.is())
+ {
+ *offset = 0;
+ return S_OK;
+ }
+
+ *offset = pRXText->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;
+
+ if(!pRXText.is())
+ {
+ *nCharacters = 0;
+ return S_OK;
+ }
+
+ *nCharacters = pRXText->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;
+
+ if(!pRXText.is())
+ return E_FAIL;
+
+ if (offset < 0 || offset > pRXText->getCharacterCount())
+ return E_FAIL;
+
+ css::awt::Rectangle rectangle;
+ rectangle = pRXText->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;
+
+ // pRXText->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 pRXText->getCharacterBounds() when offset == text length.
+ if (offset == pRXText->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;
+
+ 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 = pRXText->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 coordType, long * offset)
+{
+ SolarMutexGuard g;
+
+ try {
+
+ if (offset == nullptr)
+ return E_INVALIDARG;
+
+ if(!pRXText.is())
+ return E_FAIL;
+
+ css::awt::Point point;
+ point.X = x;
+ point.Y = y;
+
+ if (coordType == IA2_COORDTYPE_SCREEN_RELATIVE)
+ {
+ // convert from screen to local coordinates
+ Reference<XAccessibleContext> xContext = pUNOInterface->getAccessibleContext();
+ Reference<XAccessibleComponent> xComponent(xContext, UNO_QUERY);
+ if (!xComponent.is())
+ return S_FALSE;
+
+ css::awt::Point aObjectPos = xComponent->getLocationOnScreen();
+ point.X -= aObjectPos.X;
+ point.Y -= aObjectPos.Y;
+ }
+
+ *offset = pRXText->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;
+
+ 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 (pRXText->getSelectionEnd() > -1)
+ {
+ *startOffset = pRXText->getSelectionStart();
+ *endOffset = pRXText->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;
+
+ 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 = pRXText->getTextRange(0, nLen);
+ }
+ }
+ else
+ {
+ ouStr = pRXText->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 {
+
+ if (startOffset == nullptr || endOffset == nullptr || text == nullptr)
+ return E_INVALIDARG;
+
+ 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 = pRXText->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;
+
+ 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 = pRXText->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;
+
+ 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 = pRXText->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 {
+
+ 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
+ {
+ pRXText->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 {
+
+ if(!pRXText.is())
+ return E_FAIL;
+
+ pRXText->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 {
+
+ if(!pRXText.is())
+ {
+ return E_FAIL;
+ }
+
+ pRXText->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;
+
+ if(!pRXText.is())
+ {
+ *nCharacters = 0;
+ return S_OK;
+ }
+
+ *nCharacters = pRXText->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 {
+
+ 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 (pRXText->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);
+ pRXText = pRXI;
+ return S_OK;
+
+ } catch(...) { return E_FAIL; }
+}
+
+/* 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 0000000000..50d50cb077
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccTextBase.h
@@ -0,0 +1,111 @@
+/* -*- 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;
+};
+
+/* 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 0000000000..8465fb5718
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/AccValue.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 "stdafx.h"
+#include <UAccCOM.h>
+#include "AccValue.h"
+#include "MAccessible.h"
+
+#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 0000000000..056eeb2619
--- /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 0000000000..db3903cbd6
--- /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 0000000000..698461ac7a
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/EnumVariant.cxx
@@ -0,0 +1,258 @@
+/* -*- 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 <UAccCOM.h>
+#include "EnumVariant.h"
+#include "MAccessible.h"
+
+#include <sal/log.hxx>
+#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;
+
+ ULONG l2;
+
+ if (pvar == nullptr)
+ return E_INVALIDARG;
+
+ if (pcElementFetched != nullptr)
+ *pcElementFetched = 0;
+
+ sal_Int64 nChildCount = m_pXAccessibleSelection->getSelectedAccessibleChildCount();
+ if (nChildCount > std::numeric_limits<long>::max())
+ {
+ SAL_WARN("iacc2", "CEnumVariant::Next: Child count exceeds maximum long value, "
+ "using max long.");
+ nChildCount = std::numeric_limits<long>::max();
+ }
+
+ // Retrieve the next cElements.
+ sal_Int64 l1;
+ for (l1 = m_nCurrent, l2 = 0; l1 < nChildCount && l2 < cElements; l1++, l2++)
+ {
+ Reference< XAccessible > pRXAcc = m_pXAccessibleSelection->getSelectedAccessibleChild(l1);
+ IAccessible* pChild = CMAccessible::get_IAccessibleFromXAccessible(pRXAcc.get());
+ if(pChild)
+ {
+ pvar[l2].vt = VT_DISPATCH;
+ pvar[l2].pdispVal = pChild;
+ pChild->AddRef();
+ }
+ else if(pRXAcc.is())
+ {
+ if (CMAccessible::g_pAccObjectManager)
+ CMAccessible::g_pAccObjectManager->InsertAccObj(pRXAcc.get(),pUNOInterface);
+ pChild = CMAccessible::get_IAccessibleFromXAccessible(pRXAcc.get());
+ if(pChild)
+ {
+ pvar[l2].vt = VT_DISPATCH;
+ pvar[l2].pdispVal = pChild;
+ pChild->AddRef();
+ }
+ }
+ }
+ // Set count of elements retrieved.
+ if (pcElementFetched != nullptr)
+ *pcElementFetched = l2;
+ m_nCurrent = 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_nCurrent += cElements;
+ sal_Int64 nChildCount = m_pXAccessibleSelection->getSelectedAccessibleChildCount();
+ if (nChildCount > std::numeric_limits<long>::max())
+ {
+ SAL_WARN("iacc2", "CEnumVariant::Skip: Child count exceeds maximum long value, "
+ "using max long.");
+ nChildCount = std::numeric_limits<long>::max();
+ }
+ if (m_nCurrent > nChildCount)
+ {
+ m_nCurrent = nChildCount;
+ return E_FAIL;
+ }
+ else
+ return NOERROR;
+}
+
+
+/**
+ * reset the enumeration position to initial value
+ * @param
+ * @return Result.
+ */
+HRESULT STDMETHODCALLTYPE CEnumVariant::Reset()
+{
+ SolarMutexGuard g;
+
+ m_nCurrent = 0;
+ return NOERROR;
+}
+
+
+/**
+ *create a new IEnumVariant object,
+ *copy current enumeration 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())
+ {
+ sal_Int64 nCount = m_pXAccessibleSelection->getSelectedAccessibleChildCount();
+ if (nCount > std::numeric_limits<long>::max())
+ {
+ SAL_WARN("iacc2", "CEnumVariant::GetCountOfElements: Count exceeds maximum long value, "
+ "using max long.");
+ nCount = std::numeric_limits<long>::max();
+ }
+ return nCount;
+ }
+ return 0;
+}
+
+/**
+ * Set member m_pXAccessibleSelection to NULL and m_nCurrent to 0.
+ * @param.
+ * @return Result
+ */
+COM_DECLSPEC_NOTHROW STDMETHODIMP CEnumVariant::ClearEnumeration()
+{
+ // internal IEnumVariant - no mutex meeded
+
+ pUNOInterface = nullptr;
+ m_pXAccessibleSelection = nullptr;
+ m_nCurrent = 0;
+ 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 0000000000..c00e30a6a5
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/EnumVariant.h
@@ -0,0 +1,98 @@
+/* -*- 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 <UAccCOM.h>
+
+/**
+ * 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_nCurrent(0),
+ pUNOInterface(nullptr)
+ {
+ }
+
+ 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:
+
+ sal_Int64 m_nCurrent;
+ 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 0000000000..6c1367185c
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/MAccessible.cxx
@@ -0,0 +1,2767 @@
+/* -*- 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 <UAccCOM.h>
+#include "MAccessible.h"
+
+#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 <sal/log.hxx>
+#include <unotools/configmgr.hxx>
+#include <vcl/accessibility/AccessibleTextAttributeHelper.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;
+
+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;
+}
+
+
+void lcl_addIA2State(AccessibleStates& rStates, sal_Int64 nUnoState, sal_Int16 nRole)
+{
+ switch (nUnoState)
+ {
+ case css::accessibility::AccessibleStateType::ACTIVE:
+ rStates |= IA2_STATE_ACTIVE;
+ break;
+ case css::accessibility::AccessibleStateType::ARMED:
+ rStates |= IA2_STATE_ARMED;
+ break;
+ case css::accessibility::AccessibleStateType::CHECKABLE:
+ // STATE_SYSTEM_PRESSED is used instead of STATE_SYSTEM_CHECKED for these button
+ // roles (s. AccObject::GetMSAAStateFromUNO), so don't set CHECKABLE state for them
+ if (nRole != AccessibleRole::PUSH_BUTTON && nRole != AccessibleRole::TOGGLE_BUTTON)
+ rStates |= IA2_STATE_CHECKABLE;
+ break;
+ case css::accessibility::AccessibleStateType::DEFUNC:
+ rStates |= IA2_STATE_DEFUNCT;
+ break;
+ case css::accessibility::AccessibleStateType::EDITABLE:
+ rStates |= IA2_STATE_EDITABLE;
+ break;
+ case css::accessibility::AccessibleStateType::HORIZONTAL:
+ rStates |= IA2_STATE_HORIZONTAL;
+ break;
+ case css::accessibility::AccessibleStateType::ICONIFIED:
+ rStates |= IA2_STATE_ICONIFIED;
+ break;
+ case css::accessibility::AccessibleStateType::MANAGES_DESCENDANTS:
+ rStates |= IA2_STATE_MANAGES_DESCENDANTS;
+ break;
+ case css::accessibility::AccessibleStateType::MODAL:
+ rStates |= IA2_STATE_MODAL;
+ break;
+ case css::accessibility::AccessibleStateType::MULTI_LINE:
+ rStates |= IA2_STATE_MULTI_LINE;
+ break;
+ case css::accessibility::AccessibleStateType::OPAQUE:
+ rStates |= IA2_STATE_OPAQUE;
+ break;
+ case css::accessibility::AccessibleStateType::SINGLE_LINE:
+ rStates |= IA2_STATE_SINGLE_LINE;
+ break;
+ case css::accessibility::AccessibleStateType::STALE:
+ rStates |= IA2_STATE_STALE;
+ break;
+ case css::accessibility::AccessibleStateType::TRANSIENT:
+ rStates |= IA2_STATE_TRANSIENT;
+ break;
+ case css::accessibility::AccessibleStateType::VERTICAL:
+ rStates |= IA2_STATE_VERTICAL;
+ break;
+ default:
+ // no match
+ break;
+ }
+}
+
+}
+
+AccObjectWinManager* CMAccessible::g_pAccObjectManager = 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)
+{
+ 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;
+
+ 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;
+
+ if(pcountChildren == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ if (!m_xAccessible.is())
+ return S_FALSE;
+
+ Reference<XAccessibleContext> const pRContext =
+ m_xAccessible->getAccessibleContext();
+ if( pRContext.is() )
+ {
+ sal_Int64 nChildCount = pRContext->getAccessibleChildCount();
+ if (nChildCount > std::numeric_limits<long>::max())
+ {
+ SAL_WARN("iacc2", "CMAccessible::get_accChildCount: Child count exceeds maximum long value, "
+ "returning max long.");
+ nChildCount = std::numeric_limits<long>::max();
+ }
+
+ *pcountChildren = nChildCount;
+ }
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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 = g_pAccObjectManager->GetIAccessibleFromResID(m_dFocusChildID);
+ 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;
+
+ 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;
+
+ 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())
+ return S_FALSE;
+
+ 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;
+ }
+ }
+ 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;
+
+ 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;
+
+ if (m_isDestroy)
+ return S_FALSE;
+
+ if (!pvarChild)
+ return E_INVALIDARG;
+
+ try
+ {
+ pvarChild->vt = VT_EMPTY;
+
+ Reference<XAccessibleContext> xContext = GetContextByXAcc(m_xAccessible.get());
+ Reference<XAccessibleComponent> xComponent(xContext, UNO_QUERY);
+ if (!xComponent.is())
+ return S_FALSE;
+
+ // convert from screen to object-local coordinates
+ css::awt::Point aTopLeft = xComponent->getLocationOnScreen();
+ css::awt::Point aPoint(xLeft - aTopLeft.X, yTop - aTopLeft.Y);
+
+ Reference<XAccessible> xAccAtPoint = xComponent->getAccessibleAtPoint(aPoint);
+ if (!xAccAtPoint.is())
+ return S_FALSE;
+
+ IAccessible* pRet = get_IAccessibleFromXAccessible(xAccAtPoint.get());
+ if (!pRet)
+ {
+ g_pAccObjectManager->InsertAccObj(xAccAtPoint.get(), m_xAccessible.get(), m_hwnd);
+ pRet = get_IAccessibleFromXAccessible(xAccAtPoint.get());
+ }
+ if (!pRet)
+ return S_FALSE;
+
+ pvarChild->vt = VT_DISPATCH;
+ pvarChild->pdispVal = pRet;
+ pRet->AddRef();
+
+ return S_OK;
+ } 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;
+}
+
+/**
+* No longer supported according to IAccessible doc.
+* Servers should return E_NOTIMPL
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::put_accName(VARIANT, BSTR)
+{
+ return E_NOTIMPL;
+}
+
+/**
+* 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;
+
+ 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;
+
+ 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 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 AccObjectWinManager object pointer to COM
+* @param pManager, the AccObjectWinManager pointer.
+* @return S_OK if successful and E_FAIL if failure.
+*/
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::Put_XAccObjectManager(hyper pManager)
+{
+ // internal IMAccessible - no mutex meeded
+
+ g_pAccObjectManager = reinterpret_cast<AccObjectWinManager*>(pManager);
+ 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_pAccObjectManager)
+ {
+ IMAccessible* pIMAcc = g_pAccObjectManager->GetIAccessibleFromResID(dChildID);
+ 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;
+
+ Reference< XAccessible > pXChild = pRContext->getAccessibleChild(dChildID-1);
+ IAccessible* pChild = get_IAccessibleFromXAccessible(pXChild.get());
+
+ if(!pChild)
+ {
+ g_pAccObjectManager->InsertAccObj(pXChild.get(), m_xAccessible.get(), m_hwnd);
+ pChild = get_IAccessibleFromXAccessible(pXChild.get());
+ }
+
+ if (pChild)
+ {
+ 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;
+ }
+
+ sal_Int64 count = pXContext->getAccessibleChildCount();
+ if(count<1)
+ {
+ return nullptr;
+ }
+
+ IMAccessible* pCurChild = nullptr;
+ union {
+ XAccessible* pChildXAcc;
+ hyper nHyper = 0;
+ };
+ Reference<XAccessible> pRChildXAcc;
+ XAccessibleContext* pChildContext = nullptr;
+ sal_Int64 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_pAccObjectManager->InsertAccObj(pChildXAcc, m_xAccessible.get());
+ return g_pAccObjectManager->GetIAccessibleFromXAccessible(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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ if(relation == nullptr || nRelations == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ 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;
+
+ 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)
+{
+ 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;
+
+ 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;
+ const sal_Int16 nRole = pRContext->getAccessibleRole();
+
+ *groupLevel = 0;
+ *similarItemsInGroup = 0;
+ *positionInGroup = 0;
+
+ if (nRole != AccessibleRole::DOCUMENT && nRole != AccessibleRole::DOCUMENT_PRESENTATION &&
+ nRole != AccessibleRole::DOCUMENT_SPREADSHEET && nRole != 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 (nRole == AccessibleRole::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];
+ sal_Int64 nChildCount = pRParentContext->getAccessibleChildCount();
+ assert(nChildCount < std::numeric_limits<long>::max());
+ for (sal_Int64 j = 0; j< nChildCount; j++)
+ {
+ if( getTheParentOfMember(pRParentContext->getAccessibleChild(j).get())
+ == static_cast<XAccessible*>(pRAcc.get()) &&
+ pRParentContext->getAccessibleChild(j)->getAccessibleContext()->getAccessibleRole() == AccessibleRole::RADIO_BUTTON)
+ number++;
+ if (pRParentContext->getAccessibleChild(j).get() == m_xAccessible.get())
+ index = number;
+ }
+ }
+ }
+ *groupLevel = 1;
+ *similarItemsInGroup = number;
+ *positionInGroup = index;
+ return S_OK;
+ }
+
+ else if (nRole == AccessibleRole::COMBO_BOX)
+ {
+ *groupLevel = 1;
+ *similarItemsInGroup = 0;
+ *positionInGroup = -1;
+
+ if (pRContext->getAccessibleChildCount() != 2)
+ {
+ 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;
+ }
+ sal_Int64 nChildCount = xListContext->getAccessibleChildCount();
+ assert(nChildCount < std::numeric_limits<long>::max());
+ *similarItemsInGroup = nChildCount;
+ 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 (nRole == AccessibleRole::PAGE_TAB)
+ {
+ *groupLevel = 1;
+ sal_Int64 nChildCount = pRParentContext->getAccessibleChildCount();
+ assert(nChildCount < std::numeric_limits<long>::max());
+ *similarItemsInGroup = nChildCount;
+ 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();
+ const sal_Int16 nParentRole = pRParentContext->getAccessibleRole();
+ if ((nParentRole == AccessibleRole::TREE) || (nParentRole == AccessibleRole::LIST))
+ isFound = true;
+ pParentAcc = pRParentContext->getAccessibleParent();
+ }
+
+ if( isFound )
+ {
+ Reference< XAccessible> pTempAcc = pRContext->getAccessibleParent();
+ pRParentContext = pTempAcc->getAccessibleContext();
+ *groupLevel = level;
+ sal_Int64 nChildCount = pRParentContext->getAccessibleChildCount();
+ assert(nChildCount < std::numeric_limits<long>::max());
+ *similarItemsInGroup = nChildCount;
+ *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;
+
+ 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;
+
+ 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();
+}
+
+/**
+* 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 )
+ {
+ sal_Int64 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;
+
+ 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;
+
+ 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; }
+}
+
+IAccessible* CMAccessible::get_IAccessibleFromXAccessible(XAccessible* pXAcc)
+{
+ try
+ {
+ if (g_pAccObjectManager)
+ return g_pAccObjectManager->GetIAccessibleFromXAccessible(pXAcc);
+ }
+ catch(...)
+ {
+ }
+ return nullptr;
+}
+
+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 = get_IAccessibleFromXAccessible(pXAcc.get());
+ if(pIAcc == nullptr)
+ {
+ Reference< XAccessibleContext > pXAccContext = pXAcc->getAccessibleContext();
+ g_pAccObjectManager->InsertAccObj(pXAcc.get(),pXAccContext->getAccessibleParent().get());
+ pIAcc = get_IAccessibleFromXAccessible(pXAcc.get());
+ }
+ 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;
+
+ sal_Int64 const nRStateSet =
+ m_xContext->getAccessibleStateSet();
+
+ *states = 0x0;
+ for (int i = 0; i < 63; ++i)
+ {
+ sal_Int64 nUnoState = sal_Int64(1) << i;
+ if (nRStateSet & nUnoState)
+ lcl_addIA2State(*states, nUnoState, m_xContext->getAccessibleRole());
+ }
+
+ 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;
+
+ if(accParentIndex == nullptr)
+ return E_INVALIDARG;
+
+ if (!m_xContext.is())
+ return E_FAIL;
+
+ sal_Int64 nIndex = m_xContext->getAccessibleIndexInParent();
+ if (nIndex > std::numeric_limits<long>::max())
+ {
+ SAL_WARN("iacc2", "CMAccessible::get_indexInParent: Child index exceeds maximum long value, "
+ "returning max long.");
+ nIndex = std::numeric_limits<long>::max();
+ }
+ *accParentIndex = nIndex;
+ 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;
+
+ static const OUString sAppName = utl::ConfigManager::getProductName();
+ *name = SysAllocString(o3tl::toW(sAppName.getStr()));
+ 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;
+ static const OUString sVersion = utl::ConfigManager::getProductVersion();
+ *version=SysAllocString(o3tl::toW(sVersion.getStr()));
+ 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("VCL"));
+ return S_OK;
+ } catch(...) { return E_FAIL; }
+}
+COM_DECLSPEC_NOTHROW STDMETHODIMP CMAccessible::get_toolkitVersion(BSTR __RPC_FAR *version)
+{
+ return get_appVersion(version);
+}
+
+
+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;
+ }
+
+ OUString sAttributes;
+ Reference<XAccessibleExtendedAttributes> pRXI(pRContext,UNO_QUERY);
+ if (pRXI.is())
+ {
+ css::uno::Reference<css::accessibility::XAccessibleExtendedAttributes> pRXAttr;
+ pRXAttr = pRXI.get();
+ css::uno::Any anyVal = pRXAttr->getExtendedAttributes();
+
+ OUString val;
+ anyVal >>= val;
+ sAttributes += val;
+ }
+
+ // some text-specific IAccessible2 object attributes (like text alignment
+ // of a paragraph) are handled as text attributes in LibreOffice
+ Reference<XAccessibleText> xText(pRContext, UNO_QUERY);
+ if (xText.is())
+ {
+ sal_Int32 nStartOffset = 0;
+ sal_Int32 nEndOffset = 0;
+ sAttributes += AccessibleTextAttributeHelper::GetIAccessible2TextAttributes(
+ xText, IA2AttributeType::ObjectAttributes, 0, nStartOffset, nEndOffset);
+ }
+
+ if (*pAttr)
+ SysFreeString(*pAttr);
+ *pAttr = SysAllocString(o3tl::toW(sAttributes.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 0000000000..b0196267b7
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/MAccessible.h
@@ -0,0 +1,225 @@
+/* -*- 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 <AccObjectWinManager.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_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_XAccObjectManager)(hyper pManager) 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;
+
+ // 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
+
+ static css::accessibility::XAccessibleContext* GetContextByXAcc(
+ css::accessibility::XAccessible* pXAcc);
+ static bool GetXInterfaceFromXAccessible(css::accessibility::XAccessible*,
+ css::uno::XInterface**, XInterfaceType);
+ HRESULT WINAPI SmartQI(void* pv, REFIID iid, void** ppvObject);
+
+public:
+ // AccObjectWinManager is a management object in UNO, here keep its pointer for
+ // the implementation of accNavigate when descendant manage happens for List,Tree, or Table
+ // AccObjectWinManager 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 AccObjectWinManager* g_pAccObjectManager;
+
+ static IAccessible* get_IAccessibleFromXAccessible(css::accessibility::XAccessible* pXAcc);
+ XGUIDToComObjHash m_containedObjects;
+
+ static HRESULT WINAPI SmartQI_(void* pv,
+ REFIID iid, void** ppvObject, DWORD_PTR)
+ {
+ return static_cast<CMAccessible*>(pv)->SmartQI(pv,iid,ppvObject);
+ }
+
+ // 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 0000000000..d8abe9bcc5
--- /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 0000000000..71ebbdb6b3
--- /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 0000000000..2914e16c36
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/UAccCOM.cxx
@@ -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 .
+ */
+
+#include "stdafx.h"
+#include "Resource.h"
+#include <initguid.h>
+#include <UAccCOM.h>
+#include <accHelper.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>
+#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 0000000000..45baa527b4
--- /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 0000000000..d81746ed3f
--- /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 0000000000..df55dc09a4
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/UNOXWrapper.cxx
@@ -0,0 +1,35 @@
+/* -*- 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 <UAccCOM.h>
+#include "UNOXWrapper.h"
+
+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 0000000000..b319d4e2b6
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/UNOXWrapper.h
@@ -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 "stdafx.h"
+#include "Resource.h" // main symbols
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <UAccCOM.h>
+
+/**
+ * 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 0000000000..d2dffc5e60
--- /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 0000000000..6a68376a8e
--- /dev/null
+++ b/winaccessibility/source/UAccCOM/stdafx.h
@@ -0,0 +1,64 @@
+/* -*- 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"
+#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/UAccCOM.idl b/winaccessibility/source/UAccCOMIDL/UAccCOM.idl
new file mode 100644
index 0000000000..871e5c3084
--- /dev/null
+++ b/winaccessibility/source/UAccCOMIDL/UAccCOM.idl
@@ -0,0 +1,212 @@
+/* -*- 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(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_XAccObjectManager")] HRESULT Put_XAccObjectManager(hyper pManager);
+ [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 0000000000..3ca8c88a04
--- /dev/null
+++ b/winaccessibility/source/UAccCOMIDL/defines.idl
@@ -0,0 +1,28 @@
+/* -*- 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;
+
+/* 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 0000000000..e63317b59e
--- /dev/null
+++ b/winaccessibility/source/service/AccComponentEventListener.cxx
@@ -0,0 +1,327 @@
+/* -*- 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 <AccObjectWinManager.hxx>
+#include <unomsaaevent.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccComponentEventListener::AccComponentEventListener(css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager)
+ :AccEventListener(pAcc, pManager)
+{
+}
+
+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)
+{
+ m_pObjManager->UpdateValue(m_xAccessible.get());
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::OBJECT_VALUECHANGE);
+}
+
+/**
+ * handle the NAME_CHANGED event
+ */
+void AccComponentEventListener::HandleActionChangedEvent()
+{
+ m_pObjManager->UpdateAction(m_xAccessible.get());
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::OBJECT_DEFACTIONCHANGE);
+}
+
+/**
+ * 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)
+{
+ m_pObjManager->SetValue(m_xAccessible.get(), newValue);
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::OBJECT_VALUECHANGE);
+}
+
+/**
+ * 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)
+{
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::OBJECT_CARETCHANGE);
+}
+
+/**
+ * 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(sal_Int64 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)
+ {
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE);
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSABLE);
+ }
+ else
+ {
+ m_pObjManager->DecreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE);
+ m_pObjManager->DecreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSABLE);
+ }
+ }
+ else
+ {
+ FireStatePropertyChange(state, enable);
+ }
+ break;
+ case AccessibleStateType::FOCUSED:
+ FireStateFocusedChange(enable);
+ break;
+ case AccessibleStateType::ENABLED:
+ if(enable)
+ {
+ m_pObjManager->UpdateState(m_xAccessible.get());
+ m_pObjManager->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::NOTIFICATION
+ && GetRole() != AccessibleRole::SCROLL_BAR)
+ {
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSABLE);
+ }
+ }
+ else
+ {
+ m_pObjManager->UpdateState(m_xAccessible.get());
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::DEFUNC);
+ m_pObjManager->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(sal_Int64 state, bool set)
+{
+ if( set)
+ {
+ // new value
+ switch(state)
+ {
+ case AccessibleStateType::CHECKED:
+ case AccessibleStateType::INDETERMINATE:
+ m_pObjManager->IncreaseState(m_xAccessible.get(), state);
+ m_pObjManager->UpdateAction(m_xAccessible.get());
+
+ if (!m_pObjManager->IsSpecialToolbarItem(m_xAccessible.get()))
+ {
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_CHECKED);
+ }
+ break;
+ case AccessibleStateType::PRESSED:
+ m_pObjManager->IncreaseState(m_xAccessible.get(), state);
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_PRESSED);
+ break;
+ case AccessibleStateType::SELECTED:
+ m_pObjManager->IncreaseState(m_xAccessible.get(), state);
+ break;
+ case AccessibleStateType::ARMED:
+ m_pObjManager->IncreaseState(m_xAccessible.get(), state);
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_ARMED);
+ break;
+ case AccessibleStateType::SHOWING:
+ m_pObjManager->DecreaseState(m_xAccessible.get(), AccessibleStateType::DEFUNC);
+ // UNO !SHOWING == MSAA OFFSCREEN
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::SHOWING );
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_SHOWING);
+ break;
+ case AccessibleStateType::VISIBLE:
+ // UNO !VISIBLE == MSAA INVISIBLE
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE );
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ // old value
+ switch(state)
+ {
+ case AccessibleStateType::CHECKED:
+ case AccessibleStateType::INDETERMINATE:
+ m_pObjManager->DecreaseState(m_xAccessible.get(), state);
+ m_pObjManager->UpdateAction(m_xAccessible.get());
+
+ if (!m_pObjManager->IsSpecialToolbarItem(m_xAccessible.get()))
+ {
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_CHECKED);
+ }
+ break;
+ case AccessibleStateType::PRESSED:
+ m_pObjManager->DecreaseState(m_xAccessible.get(), state);
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_PRESSED);
+ break;
+ case AccessibleStateType::SELECTED:
+ m_pObjManager->DecreaseState(m_xAccessible.get(), state);
+ //if the state is unset, no need to send MSAA SELECTION event
+ //m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_SELECTED);
+ break;
+ case AccessibleStateType::ARMED:
+ {
+ m_pObjManager->DecreaseState(m_xAccessible.get(), state);
+ //if the state is unset, no need to send MSAA MENU event
+ //m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_ARMED);
+ }
+ break;
+ case AccessibleStateType::SHOWING:
+ m_pObjManager->DecreaseState(m_xAccessible.get(), AccessibleStateType::DEFUNC);
+ // UNO !SHOWING == MSAA OFFSCREEN
+ m_pObjManager->DecreaseState(m_xAccessible.get(), AccessibleStateType::SHOWING);
+ break;
+ case AccessibleStateType::VISIBLE:
+ // UNO !VISIBLE == MSAA INVISIBLE
+ m_pObjManager->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)
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_FOCUSED);
+ }
+ else
+ {
+ //if lose focus, no need to send MSAA FOCUS event
+ m_pObjManager->DecreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSED);
+ }
+}
+
+void AccComponentEventListener::HandleSelectionChangedEventNoArgs()
+{
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::SELECTION_CHANGED);
+}
+
+//add TEXT_SELECTION_CHANGED event
+void AccComponentEventListener::HandleTextSelectionChangedEvent()
+{
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::TEXT_SELECTION_CHANGED);
+}
+
+/* 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 0000000000..d05b9f5a27
--- /dev/null
+++ b/winaccessibility/source/service/AccContainerEventListener.cxx
@@ -0,0 +1,498 @@
+/* -*- 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 <AccObjectWinManager.hxx>
+#include <unomsaaevent.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccContainerEventListener::AccContainerEventListener(css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager)
+ :AccEventListener(pAcc, pManager)
+{
+}
+
+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::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)
+{
+ sal_Int64 State;
+ if( newValue >>= State)
+ {
+ SetComponentState(State, true);
+ }
+ else if (oldValue >>= State)
+ {
+ SetComponentState(State, false);
+ }
+
+}
+
+/**
+ * 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)
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::SELECTION_CHANGED);
+}
+
+/**
+ * handle the INVALIDATE_ALL_CHILDREN event
+ */
+void AccContainerEventListener::HandleAllChildrenChangedEvent()
+{
+ //TODO: update all the children
+ if (m_xAccessible.is())
+ {
+ //delete all oldValue's existing children
+ m_pObjManager->DeleteChildrenAccObj(m_xAccessible.get());
+ //add all oldValue's existing children
+ m_pObjManager->InsertChildrenAccObj(m_xAccessible.get());
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::OBJECT_REORDER);
+ }
+}
+
+/**
+ * handle the TEXT_CHANGED event
+ */
+void AccContainerEventListener::HandleTextChangedEvent(Any, Any newValue)
+{
+ m_pObjManager->SetValue(m_xAccessible.get(), newValue);
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::OBJECT_TEXTCHANGE);
+}
+
+/**
+ * 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(sal_Int64 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)
+ {
+ m_pObjManager->DecreaseState(m_xAccessible.get(), AccessibleStateType::DEFUNC);
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSABLE);
+ m_pObjManager->UpdateState(m_xAccessible.get());
+
+ UpdateAllChildrenState(m_xAccessible.get());
+ }
+ else
+ {
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::DEFUNC);
+ m_pObjManager->DecreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSABLE);
+ m_pObjManager->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 */
+ {
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSED);
+ }
+
+ else /* lose the active state */
+ {
+ m_pObjManager->DecreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSED);
+ }
+ }
+ break;
+
+ case AccessibleStateType::EXPANDED:
+ case AccessibleStateType::COLLAPSE:
+ case AccessibleStateType::CHECKED:
+ {
+ m_pObjManager->UpdateState(m_xAccessible.get());
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_BUSY);
+ 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(sal_Int64 state, bool set)
+{
+ if( set )
+ {
+ // new value
+ switch(state)
+ {
+ case AccessibleStateType::SELECTED:
+ m_pObjManager->IncreaseState(m_xAccessible.get(), state);
+ break;
+ case AccessibleStateType::INDETERMINATE:
+ case AccessibleStateType::BUSY:
+ case AccessibleStateType::FOCUSABLE:
+ case AccessibleStateType::OFFSCREEN:
+ m_pObjManager->IncreaseState(m_xAccessible.get(), state);
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_BUSY);
+ break;
+ case AccessibleStateType::SHOWING:
+ // UNO !SHOWING == MSAA OFFSCREEN
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::SHOWING);
+ break;
+ case AccessibleStateType::VISIBLE:
+ // UNO !VISIBLE == MSAA INVISIBLE
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ // old value
+ switch(state)
+ {
+ case AccessibleStateType::SELECTED:
+ m_pObjManager->DecreaseState(m_xAccessible.get(), state);
+ break;
+ case AccessibleStateType::BUSY:
+ case AccessibleStateType::INDETERMINATE:
+ case AccessibleStateType::FOCUSABLE:
+ case AccessibleStateType::OFFSCREEN:
+ m_pObjManager->DecreaseState(m_xAccessible.get(), state);
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_BUSY);
+ break;
+ case AccessibleStateType::SHOWING:
+ // UNO !SHOWING == MSAA OFFSCREEN
+ m_pObjManager->DecreaseState(m_xAccessible.get(), AccessibleStateType::SHOWING);
+ break;
+ case AccessibleStateType::VISIBLE:
+ // UNO !VISIBLE == MSAA INVISIBLE
+ m_pObjManager->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)
+ {
+ m_pObjManager->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)
+ {
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::MENU_START);
+ }
+ else if (role == AccessibleRole::POPUP_MENU)
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::MENUPOPUPSTART);
+ //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
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_FOCUSED);
+ }
+ 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))
+ {
+ m_pObjManager->DecreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSED);
+ m_pObjManager->IncreaseState( mxChild.get(), AccessibleStateType::FOCUSED);
+ m_pObjManager->NotifyAccEvent(mxChild.get(), UnoMSAAEvent::STATE_FOCUSED);
+ bSendFocusOnCombobox = false;
+ }
+ }
+ }
+ }
+ if (bSendFocusOnCombobox)
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_FOCUSED);
+ }
+ else
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_FOCUSED);
+ }
+ else
+ {
+ m_pObjManager->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)
+ {
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::MENU_END);
+ }
+ else if (GetRole() == AccessibleRole::POPUP_MENU)
+ {
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::MENUPOPUPEND);
+ }
+ }
+}
+
+/**
+ * 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)
+{
+ m_pObjManager->UpdateValue(m_xAccessible.get());
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::OBJECT_VALUECHANGE);
+}
+
+bool AccContainerEventListener::IsEditable(Reference<XAccessibleContext> const & xContext)
+{
+ sal_Int64 nRState = xContext->getAccessibleStateSet();
+ return nRState & AccessibleStateType::EDITABLE;
+}
+
+bool AccContainerEventListener::NotifyChildEvent(UnoMSAAEvent eWinEvent, const Any& Value)
+{
+ Reference< XAccessible > xChild;
+ if(Value >>= xChild )
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ m_pObjManager->NotifyAccEvent(pAcc, eWinEvent);
+ return true;
+ }
+ }
+ return false;
+}
+
+void AccContainerEventListener::HandleSelectionChangedAddEvent(const Any& /*oldValue*/, const Any& newValue)
+{
+ if (NotifyChildEvent(UnoMSAAEvent::SELECTION_CHANGED_ADD, newValue))
+ {
+ return ;
+ }
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::SELECTION_CHANGED_ADD);
+}
+
+void AccContainerEventListener::HandleSelectionChangedRemoveEvent(const Any& /*oldValue*/, const Any& newValue)
+{
+ if (NotifyChildEvent(UnoMSAAEvent::SELECTION_CHANGED_REMOVE, newValue))
+ {
+ return ;
+ }
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::SELECTION_CHANGED_REMOVE);
+}
+
+void AccContainerEventListener::HandleSelectionChangedWithinEvent(const Any& /*oldValue*/, const Any& newValue)
+{
+ if (NotifyChildEvent(UnoMSAAEvent::SELECTION_CHANGED_WITHIN, newValue))
+ {
+ return ;
+ }
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::SELECTION_CHANGED_WITHIN);
+}
+
+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 (AccObjectWinManager::IsStateManageDescendant(pXAccessible))
+ {
+ return;
+ }
+
+ const sal_Int64 nCount = pAccessibleContext->getAccessibleChildCount();
+ for (sal_Int64 i = 0; i < nCount; i++)
+ {
+ Reference<css::accessibility::XAccessible> mxAccessible
+ = pAccessibleContext->getAccessibleChild(i);
+
+ css::accessibility::XAccessible* mpAccessible = mxAccessible.get();
+ if(mpAccessible != nullptr)
+ {
+ m_pObjManager->UpdateState(mpAccessible);
+ UpdateAllChildrenState(mpAccessible);
+ }
+ }
+}
+
+void AccContainerEventListener::HandlePageChangedEvent(const Any& /*oldValue*/, const Any& /*newValue*/)
+{
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::OBJECT_PAGECHANGED);
+}
+
+void AccContainerEventListener::HandleSectionChangedEvent(const Any& /*oldValue*/, const Any& /*newValue*/ )
+{
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::SECTION_CHANGED);
+}
+
+void AccContainerEventListener::HandleColumnChangedEvent(const Any& /*oldValue*/, const Any& /*newValue*/)
+{
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::COLUMN_CHANGED);
+}
+
+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)
+ {
+ m_pObjManager->SetAccName(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 0000000000..d3fcb2d0fe
--- /dev/null
+++ b/winaccessibility/source/service/AccDescendantManagerEventListener.cxx
@@ -0,0 +1,198 @@
+/* -*- 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 <AccObjectWinManager.hxx>
+#include <unomsaaevent.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccDescendantManagerEventListener::AccDescendantManagerEventListener(css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager)
+ : AccComponentEventListener(pAcc, pManager)
+{
+}
+
+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::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 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();
+ Reference<css::accessibility::XAccessibleContext> xContext = pAcc->getAccessibleContext();
+ //if the Role is the SC cell ,don't add the selected state.
+ if (xContext.is() && xContext->getAccessibleRole() != AccessibleRole::TABLE_CELL)
+ {
+ m_pObjManager->IncreaseState( pAcc, AccessibleStateType::SELECTED);
+ }
+
+ m_pObjManager->NotifyAccEvent(pAcc, UnoMSAAEvent::SELECTION_CHANGED);
+ bSend=true;
+ }
+ }
+ if(oldValue >>= xChild )
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ m_pObjManager->DecreaseState( pAcc, AccessibleStateType::SELECTED);
+ }
+ }
+ if (!bSend)
+ {
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::SELECTION_CHANGED);
+ }
+}
+
+
+void AccDescendantManagerEventListener::HandleChildChangedNoFocusEvent(Any oldValue, Any newValue)
+{
+ Reference< XAccessible > xChild;
+ if(newValue >>= xChild )
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+
+ m_pObjManager->InsertAccObj(pAcc, m_xAccessible.get());
+ m_pObjManager->InsertChildrenAccObj(pAcc);
+ }
+ }
+ if (oldValue >>= xChild)
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ m_pObjManager->DeleteChildrenAccObj( pAcc );
+ m_pObjManager->DeleteAccObj( pAcc );
+ }
+ }
+}
+
+bool AccDescendantManagerEventListener::NotifyChildEvent(UnoMSAAEvent eWinEvent, const Any& Value)
+{
+ Reference< XAccessible > xChild;
+ if(Value >>= xChild )
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ m_pObjManager->NotifyAccEvent(pAcc, eWinEvent);
+
+ if (AccObjectWinManager::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)
+ m_pObjManager->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 ;
+ }
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::SELECTION_CHANGED_ADD);
+}
+
+void AccDescendantManagerEventListener::HandleSelectionChangedRemoveEvent(const Any& /*oldValue*/, const Any &newValue)
+{
+ if (NotifyChildEvent(UnoMSAAEvent::SELECTION_CHANGED_REMOVE, newValue))
+ {
+ return ;
+ }
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::SELECTION_CHANGED_REMOVE);
+}
+
+void AccDescendantManagerEventListener::HandleSelectionChangedWithinEvent(const Any& /*oldValue*/, const Any &newValue)
+{
+ if (NotifyChildEvent(UnoMSAAEvent::SELECTION_CHANGED_WITHIN, newValue))
+ {
+ return ;
+ }
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::SELECTION_CHANGED_WITHIN);
+}
+
+/* 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 0000000000..1236fc458a
--- /dev/null
+++ b/winaccessibility/source/service/AccDialogEventListener.cxx
@@ -0,0 +1,93 @@
+/* -*- 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 <AccObjectWinManager.hxx>
+#include <unomsaaevent.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccDialogEventListener::AccDialogEventListener(css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager)
+ :AccEventListener(pAcc, pManager)
+{}
+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::VISIBLE_DATA_CHANGED:
+ HandleVisibleDataChangedEvent();
+ break;
+ case AccessibleEventId::BOUNDRECT_CHANGED:
+ HandleBoundrectChangedEvent();
+ break;
+ default:
+ AccEventListener::notifyEvent(aEvent);
+ break;
+ }
+}
+
+/**
+ * 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(sal_Int64 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 )
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE);
+ else
+ m_pObjManager->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 0000000000..d8e6223403
--- /dev/null
+++ b/winaccessibility/source/service/AccEventListener.cxx
@@ -0,0 +1,296 @@
+/* -*- 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 <AccObjectWinManager.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,
+ AccObjectWinManager* pManager)
+ : m_xAccessible(pAcc)
+ , m_pObjManager(pManager)
+{
+}
+
+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::CHILD:
+ HandleChildChangedEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ 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 (m_pObjManager->IsTopWinAcc(m_xAccessible.get()))
+ {
+ XAccessible* pAccDoc = m_pObjManager->GetAccDocByAccTopWin(m_xAccessible.get());
+ if (pAccDoc)
+ {
+ m_pObjManager->UpdateAccName(pAccDoc);
+ m_pObjManager->NotifyAccEvent(pAccDoc, UnoMSAAEvent::OBJECT_NAMECHANGE);
+ }
+ }
+
+ m_pObjManager->SetAccName(m_xAccessible.get(), name);
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::OBJECT_NAMECHANGE);
+}
+
+/**
+ * Handle the CHILD event
+ * @param oldValue the child to be deleted
+ * @param newValue the child to be added
+ */
+void AccEventListener::HandleChildChangedEvent(com::sun::star::uno::Any oldValue,
+ com::sun::star::uno::Any newValue)
+{
+ Reference<XAccessible> xChild;
+ if (newValue >>= xChild)
+ {
+ if (xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ m_pObjManager->InsertAccObj(pAcc, m_xAccessible.get());
+ m_pObjManager->InsertChildrenAccObj(pAcc);
+ m_pObjManager->NotifyAccEvent(pAcc, UnoMSAAEvent::CHILD_ADDED);
+ }
+ }
+ else if (oldValue >>= xChild)
+ {
+ if (xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ m_pObjManager->NotifyAccEvent(pAcc, UnoMSAAEvent::CHILD_REMOVED);
+ m_pObjManager->DeleteChildrenAccObj(pAcc);
+ m_pObjManager->DeleteAccObj(pAcc);
+ }
+ }
+}
+
+/**
+ * handle the DESCRIPTION_CHANGED event
+ */
+void AccEventListener::HandleDescriptionChangedEvent()
+{
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::OBJECT_DESCRIPTIONCHANGE);
+}
+
+/**
+ * handle the BOUNDRECT_CHANGED event
+ */
+void AccEventListener::HandleBoundrectChangedEvent()
+{
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::BOUNDRECT_CHANGED);
+}
+
+/**
+ * handle the VISIBLE_DATA_CHANGED event
+ */
+void AccEventListener::HandleVisibleDataChangedEvent()
+{
+ m_pObjManager->UpdateValue(m_xAccessible.get());
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::VISIBLE_DATA_CHANGED);
+}
+
+/**
+ * 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)
+{
+ sal_Int64 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(sal_Int64 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)
+ {
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::FOCUSED);
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::STATE_FOCUSED);
+ }
+ 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(sal_Int64 /*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 m_pObjManager->GetParentRole(m_xAccessible.get());
+ }
+ return -1;
+}
+/**
+ * remove the listener from accessible object
+ */
+void AccEventListener::RemoveMeFromBroadcaster(bool const isNotifyDestroy)
+{
+ 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
+ }
+ if (isNotifyDestroy)
+ {
+ m_pObjManager->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(true);
+}
+
+/* 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 0000000000..55ecf24792
--- /dev/null
+++ b/winaccessibility/source/service/AccFrameEventListener.cxx
@@ -0,0 +1,128 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#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 <AccObjectWinManager.hxx>
+#include <unomsaaevent.hxx>
+
+#include <vcl/window.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <vcl/sysdata.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccFrameEventListener::AccFrameEventListener(css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager)
+ :AccEventListener(pAcc, pManager)
+{
+}
+
+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::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)
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ VCLXWindow* pvclwindow = dynamic_cast<VCLXWindow*>(m_xAccessible.get());
+ assert(pvclwindow);
+ const SystemEnvData* systemdata
+ = pvclwindow->GetWindow()->GetSystemData();
+
+ m_pObjManager->InsertAccObj(pAcc, m_xAccessible.get(), systemdata->hWnd);
+ m_pObjManager->InsertChildrenAccObj(pAcc);
+ m_pObjManager->NotifyAccEvent(pAcc, UnoMSAAEvent::CHILD_ADDED);
+ }
+ }
+ else if (oldValue >>= xChild)
+ {
+ AccEventListener::HandleChildChangedEvent(oldValue, newValue);
+ }
+}
+
+/**
+ * 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(sal_Int64 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 )
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE);
+ else
+ m_pObjManager->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 0000000000..9eaab9fd0c
--- /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 <AccObjectWinManager.hxx>
+#include <unomsaaevent.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccListEventListener::AccListEventListener(css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager)
+ :AccDescendantManagerEventListener(pAcc, pManager)
+{
+}
+
+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 = m_pObjManager->InsertAccObj(pAcc, m_xAccessible.get());
+ if (!bHasCache)
+ {
+ m_pObjManager->UpdateState(pAcc);
+ }
+
+ m_pObjManager->IncreaseState( pAcc, AccessibleStateType::FOCUSED);
+
+ m_pObjManager->NotifyAccEvent(pAcc, UnoMSAAEvent::ACTIVE_DESCENDANT_CHANGED);
+ }
+ }
+ if (oldValue >>= xChild)
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ m_pObjManager->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 =
+ m_pObjManager->GetParentXAccessible(m_xAccessible.get());
+ m_pObjManager->UpdateValue(pParentAcc);
+ m_pObjManager->NotifyAccEvent(pParentAcc, UnoMSAAEvent::OBJECT_VALUECHANGE);
+ }
+}
+
+/* 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 0000000000..25b347ebc8
--- /dev/null
+++ b/winaccessibility/source/service/AccMenuEventListener.cxx
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#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 <AccObjectWinManager.hxx>
+#include <unomsaaevent.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccMenuEventListener::AccMenuEventListener(css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager)
+ :AccComponentEventListener(pAcc, pManager)
+{}
+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::SELECTION_CHANGED:
+ //don't need to process anything,just same as word behavior
+ //handleSelectionChangedEvent();
+ break;
+ default:
+ AccComponentEventListener::notifyEvent(aEvent);
+ break;
+ }
+}
+
+/**
+ * handle the SELECTION_CHANGED event
+ */
+void AccMenuEventListener::HandleSelectionChangedEventNoArgs()
+{
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::SELECTION_CHANGED);
+}
+
+/**
+ * handle the Menu_popup event
+ */
+void AccMenuEventListener::FireStatePropertyChange(sal_Int64 state, bool set)
+{
+ if( set )
+ {
+ // new value
+ switch(state)
+ {
+ //for sub menu is popup, there is a menu selected event.
+ case AccessibleStateType::SELECTED:
+ m_pObjManager->IncreaseState(m_xAccessible.get(), state);
+ m_pObjManager->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:
+ m_pObjManager->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 0000000000..51d04ec18d
--- /dev/null
+++ b/winaccessibility/source/service/AccObject.cxx
@@ -0,0 +1,1164 @@
+/* -*- 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 <sal/log.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;
+
+namespace {
+
+/**
+ * Map a UNO accessible role to an IAccessible2 role.
+ * @param nUnoRole The UNO role (css::accessibility::AccessibleRole).
+ * @return IAccessible2 role.
+ */
+short lcl_mapToIAccessible2Role(sal_Int16 nUnoRole)
+{
+ switch(nUnoRole)
+ {
+ case css::accessibility::AccessibleRole::UNKNOWN:
+ return IA2_ROLE_UNKNOWN;
+ case css::accessibility::AccessibleRole::ALERT:
+ return ROLE_SYSTEM_DIALOG;
+ case css::accessibility::AccessibleRole::BLOCK_QUOTE:
+ return IA2_ROLE_BLOCK_QUOTE;
+ case css::accessibility::AccessibleRole::COLUMN_HEADER:
+ return ROLE_SYSTEM_COLUMNHEADER;
+ case css::accessibility::AccessibleRole::CANVAS:
+ return IA2_ROLE_CANVAS;
+ case css::accessibility::AccessibleRole::CHECK_BOX:
+ return ROLE_SYSTEM_CHECKBUTTON;
+ case css::accessibility::AccessibleRole::CHECK_MENU_ITEM:
+ return IA2_ROLE_CHECK_MENU_ITEM;
+ case css::accessibility::AccessibleRole::COLOR_CHOOSER:
+ return IA2_ROLE_COLOR_CHOOSER;
+ case css::accessibility::AccessibleRole::COMBO_BOX:
+ return ROLE_SYSTEM_COMBOBOX;
+ case css::accessibility::AccessibleRole::DATE_EDITOR:
+ return IA2_ROLE_DATE_EDITOR;
+ case css::accessibility::AccessibleRole::DESKTOP_ICON:
+ return IA2_ROLE_DESKTOP_ICON;
+ case css::accessibility::AccessibleRole::DESKTOP_PANE:
+ return IA2_ROLE_DESKTOP_PANE;
+ case css::accessibility::AccessibleRole::DIRECTORY_PANE:
+ return IA2_ROLE_DIRECTORY_PANE;
+ case css::accessibility::AccessibleRole::DIALOG:
+ return ROLE_SYSTEM_DIALOG;
+ case css::accessibility::AccessibleRole::DOCUMENT:
+ return ROLE_SYSTEM_DOCUMENT;
+ case css::accessibility::AccessibleRole::EMBEDDED_OBJECT:
+ return IA2_ROLE_EMBEDDED_OBJECT;
+ case css::accessibility::AccessibleRole::END_NOTE:
+ return IA2_ROLE_ENDNOTE;
+ case css::accessibility::AccessibleRole::FILE_CHOOSER:
+ return IA2_ROLE_FILE_CHOOSER;
+ case css::accessibility::AccessibleRole::FILLER:
+ return ROLE_SYSTEM_WHITESPACE;
+ case css::accessibility::AccessibleRole::FONT_CHOOSER:
+ return IA2_ROLE_FONT_CHOOSER;
+ case css::accessibility::AccessibleRole::FOOTER:
+ return IA2_ROLE_FOOTER;
+ case css::accessibility::AccessibleRole::FOOTNOTE:
+ return IA2_ROLE_FOOTNOTE;
+ case css::accessibility::AccessibleRole::FRAME:
+ return IA2_ROLE_FRAME;
+ case css::accessibility::AccessibleRole::GLASS_PANE:
+ return IA2_ROLE_GLASS_PANE;
+ case css::accessibility::AccessibleRole::GRAPHIC:
+ return ROLE_SYSTEM_GRAPHIC;
+ case css::accessibility::AccessibleRole::GROUP_BOX:
+ return ROLE_SYSTEM_GROUPING;
+ case css::accessibility::AccessibleRole::HEADER:
+ return IA2_ROLE_HEADER;
+ case css::accessibility::AccessibleRole::HEADING:
+ return IA2_ROLE_HEADING;
+ case css::accessibility::AccessibleRole::HYPER_LINK:
+ return ROLE_SYSTEM_TEXT;
+ case css::accessibility::AccessibleRole::ICON:
+ return IA2_ROLE_ICON;
+ case css::accessibility::AccessibleRole::INTERNAL_FRAME:
+ return IA2_ROLE_INTERNAL_FRAME;
+ case css::accessibility::AccessibleRole::LABEL:
+ return ROLE_SYSTEM_STATICTEXT;
+ case css::accessibility::AccessibleRole::LAYERED_PANE:
+ return IA2_ROLE_LAYERED_PANE;
+ case css::accessibility::AccessibleRole::LIST:
+ return ROLE_SYSTEM_LIST;
+ case css::accessibility::AccessibleRole::LIST_ITEM:
+ return ROLE_SYSTEM_LISTITEM;
+ case css::accessibility::AccessibleRole::MENU:
+ return ROLE_SYSTEM_MENUITEM;
+ case css::accessibility::AccessibleRole::MENU_BAR:
+ return ROLE_SYSTEM_MENUBAR;
+ case css::accessibility::AccessibleRole::MENU_ITEM:
+ return ROLE_SYSTEM_MENUITEM;
+ case css::accessibility::AccessibleRole::OPTION_PANE:
+ return IA2_ROLE_OPTION_PANE;
+ case css::accessibility::AccessibleRole::PAGE_TAB:
+ return ROLE_SYSTEM_PAGETAB;
+ case css::accessibility::AccessibleRole::PAGE_TAB_LIST:
+ return ROLE_SYSTEM_PAGETABLIST;
+ case css::accessibility::AccessibleRole::PANEL:
+ return IA2_ROLE_OPTION_PANE;
+ case css::accessibility::AccessibleRole::PARAGRAPH:
+ return IA2_ROLE_PARAGRAPH;
+ case css::accessibility::AccessibleRole::PASSWORD_TEXT:
+ return ROLE_SYSTEM_TEXT;
+ case css::accessibility::AccessibleRole::POPUP_MENU:
+ return ROLE_SYSTEM_MENUPOPUP;
+ case css::accessibility::AccessibleRole::PUSH_BUTTON:
+ return ROLE_SYSTEM_PUSHBUTTON;
+ case css::accessibility::AccessibleRole::PROGRESS_BAR:
+ return ROLE_SYSTEM_PROGRESSBAR;
+ case css::accessibility::AccessibleRole::RADIO_BUTTON:
+ return ROLE_SYSTEM_RADIOBUTTON;
+ case css::accessibility::AccessibleRole::RADIO_MENU_ITEM:
+ return IA2_ROLE_RADIO_MENU_ITEM;
+ case css::accessibility::AccessibleRole::ROW_HEADER:
+ return ROLE_SYSTEM_ROWHEADER;
+ case css::accessibility::AccessibleRole::ROOT_PANE:
+ return IA2_ROLE_ROOT_PANE;
+ case css::accessibility::AccessibleRole::SCROLL_BAR:
+ return ROLE_SYSTEM_SCROLLBAR;
+ case css::accessibility::AccessibleRole::SCROLL_PANE:
+ return IA2_ROLE_SCROLL_PANE;
+ case css::accessibility::AccessibleRole::SHAPE:
+ return IA2_ROLE_SHAPE;
+ case css::accessibility::AccessibleRole::SEPARATOR:
+ return ROLE_SYSTEM_SEPARATOR;
+ case css::accessibility::AccessibleRole::SLIDER:
+ return ROLE_SYSTEM_SLIDER;
+ case css::accessibility::AccessibleRole::SPIN_BOX:
+ return ROLE_SYSTEM_SPINBUTTON;
+ case css::accessibility::AccessibleRole::SPLIT_PANE:
+ return IA2_ROLE_SPLIT_PANE;
+ case css::accessibility::AccessibleRole::STATUS_BAR:
+ return ROLE_SYSTEM_STATUSBAR;
+ case css::accessibility::AccessibleRole::TABLE:
+ return ROLE_SYSTEM_TABLE;
+ case css::accessibility::AccessibleRole::TABLE_CELL:
+ return ROLE_SYSTEM_CELL;
+ case css::accessibility::AccessibleRole::TEXT:
+ return ROLE_SYSTEM_TEXT;
+ case css::accessibility::AccessibleRole::TEXT_FRAME:
+ return IA2_ROLE_TEXT_FRAME;
+ case css::accessibility::AccessibleRole::TOGGLE_BUTTON:
+ return ROLE_SYSTEM_PUSHBUTTON;
+ case css::accessibility::AccessibleRole::TOOL_BAR:
+ return ROLE_SYSTEM_TOOLBAR;
+ case css::accessibility::AccessibleRole::TOOL_TIP:
+ return ROLE_SYSTEM_TOOLTIP;
+ case css::accessibility::AccessibleRole::TREE:
+ return ROLE_SYSTEM_OUTLINE;
+ case css::accessibility::AccessibleRole::VIEW_PORT:
+ return IA2_ROLE_VIEW_PORT;
+ case css::accessibility::AccessibleRole::WINDOW:
+ return ROLE_SYSTEM_WINDOW;
+ case css::accessibility::AccessibleRole::BUTTON_DROPDOWN:
+ return ROLE_SYSTEM_BUTTONDROPDOWN;
+ case css::accessibility::AccessibleRole::BUTTON_MENU:
+ return ROLE_SYSTEM_BUTTONMENU;
+ case css::accessibility::AccessibleRole::CAPTION:
+ return IA2_ROLE_CAPTION;
+ case css::accessibility::AccessibleRole::CHART:
+ return IA2_ROLE_SHAPE;
+ case css::accessibility::AccessibleRole::EDIT_BAR:
+ return IA2_ROLE_EDITBAR;
+ case css::accessibility::AccessibleRole::FORM:
+ return IA2_ROLE_FORM;
+ case css::accessibility::AccessibleRole::IMAGE_MAP:
+ return IA2_ROLE_IMAGE_MAP;
+ case css::accessibility::AccessibleRole::NOTE:
+ return IA2_ROLE_NOTE;
+ case css::accessibility::AccessibleRole::PAGE:
+ return IA2_ROLE_PAGE;
+ case css::accessibility::AccessibleRole::RULER:
+ return IA2_ROLE_RULER;
+ case css::accessibility::AccessibleRole::SECTION:
+ return IA2_ROLE_SECTION;
+ case css::accessibility::AccessibleRole::TREE_ITEM:
+ return ROLE_SYSTEM_OUTLINEITEM;
+ case css::accessibility::AccessibleRole::TREE_TABLE:
+ return ROLE_SYSTEM_OUTLINE;
+ case css::accessibility::AccessibleRole::COMMENT:
+ return IA2_ROLE_TEXT_FRAME;
+ case css::accessibility::AccessibleRole::COMMENT_END:
+ return IA2_ROLE_TEXT_FRAME;
+ case css::accessibility::AccessibleRole::DOCUMENT_PRESENTATION:
+ return ROLE_SYSTEM_DOCUMENT;
+ case css::accessibility::AccessibleRole::DOCUMENT_SPREADSHEET:
+ return ROLE_SYSTEM_DOCUMENT;
+ case css::accessibility::AccessibleRole::DOCUMENT_TEXT:
+ return ROLE_SYSTEM_DOCUMENT;
+ case css::accessibility::AccessibleRole::STATIC:
+ return ROLE_SYSTEM_STATICTEXT;
+ case css::accessibility::AccessibleRole::NOTIFICATION:
+ return ROLE_SYSTEM_ALERT;
+ default:
+ SAL_WARN("iacc2", "Unmapped role: " << nUnoRole);
+ return IA2_ROLE_UNKNOWN;
+ }
+}
+};
+
+
+/**
+ * Constructor.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @param pManager The accessible object manager kept in all listeners.
+ * @param listener listener that registers in UNO system.
+ * @return.
+ */
+AccObject::AccObject(XAccessible* pAcc, AccObjectWinManager* pManager,
+ AccEventListener* pListener) :
+ m_resID (0),
+ m_pParantID (nullptr),
+ m_pIMAcc (UAccCOMCreateInstance()),
+ 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_XAccObjectManager(reinterpret_cast<hyper>(pManager));
+ m_pIMAcc->SetDefaultAction(reinterpret_cast<hyper>(m_xAccActionRef.get()));
+ }
+}
+/**
+ * Destructor.
+ * @param
+ * @return
+ */
+AccObject::~AccObject()
+{
+ 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()
+{
+ 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 (m_accRole == AccessibleRole::PARAGRAPH || m_accRole == AccessibleRole::BLOCK_QUOTE)
+ {
+ 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 BLOCK_QUOTE:
+ 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 nState UNO state.
+ * @return
+ */
+DWORD AccObject::GetMSAAStateFromUNO(sal_Int64 nState)
+{
+ DWORD IState = UNO_MSAA_UNMAPPING;
+
+ if( !m_xAccContextRef.is() )
+ {
+ assert(false);
+ return IState;
+ }
+
+ switch( nState )
+ {
+ case BUSY:
+ IState = STATE_SYSTEM_BUSY;
+ break;
+ case CHECKED:
+ if (m_accRole == PUSH_BUTTON || m_accRole == 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 (m_accRole == PUSH_BUTTON || m_accRole == TOGGLE_BUTTON || m_accRole == BUTTON_DROPDOWN)
+ {
+ 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( sal_Int64 xState )
+{
+ if( nullptr == m_pIMAcc )
+ {
+ return;
+ }
+
+ if( xState == FOCUSABLE)
+ {
+ if (m_accRole == MENU_ITEM || m_accRole == RADIO_MENU_ITEM || m_accRole == CHECK_MENU_ITEM)
+ return;
+ else
+ {
+ if (m_accRole == TOGGLE_BUTTON || m_accRole == PUSH_BUTTON || m_accRole == BUTTON_DROPDOWN)
+ {
+ 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( sal_Int64 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;
+ }
+
+ const sal_Int16 nUnoRole = m_xAccContextRef->getAccessibleRole();
+ short nIA2Role = lcl_mapToIAccessible2Role(nUnoRole);
+ m_pIMAcc->Put_XAccRole(nIA2Role);
+}
+
+/**
+ * update state information from uno to com
+ * @param
+ * @return
+ */
+void AccObject::UpdateState()
+{
+ if (!m_pIMAcc)
+ {
+ return;
+ }
+
+ XAccessibleContext* pContext = m_xAccContextRef.get();
+ sal_Int64 nRState = pContext->getAccessibleStateSet();
+
+ 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 (int i=0; i<63; ++i)
+ {
+ sal_Int64 nState = sal_Int64(1) << i;
+ if (!(nState & nRState))
+ continue;
+ 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 );
+ }
+
+ switch(m_accRole)
+ {
+ case LABEL:
+ case STATIC:
+ case NOTIFICATION:
+ 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 BLOCK_QUOTE:
+ 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 (!(m_accRole == FILLER || m_accRole == END_NOTE || m_accRole == FOOTER || m_accRole == FOOTNOTE || m_accRole == GROUP_BOX || m_accRole == RULER
+ || m_accRole == HEADER || m_accRole == ICON || m_accRole == INTERNAL_FRAME || m_accRole == LABEL || m_accRole == LAYERED_PANE
+ || m_accRole == SCROLL_BAR || m_accRole == SCROLL_PANE || m_accRole == SPLIT_PANE || m_accRole == STATIC || m_accRole == STATUS_BAR
+ || m_accRole == TOOL_TIP || m_accRole == NOTIFICATION))
+ {
+ if (m_accRole == SEPARATOR)
+ {
+ if( ( m_pParentObj != nullptr ) && ( MENU == m_pParentObj->m_accRole || POPUP_MENU == m_pParentObj->m_accRole ))
+ IncreaseState( FOCUSABLE );
+ }
+
+ else if (m_accRole == TABLE_CELL || m_accRole == TABLE || m_accRole == PANEL || m_accRole == OPTION_PANE ||
+ m_accRole == COLUMN_HEADER)
+ {
+ if (isFocusable)
+ IncreaseState( FOCUSABLE );
+ }
+ else
+ {
+ if(bIsMenuItem)
+ {
+ if ( isShowing && isVisible)
+ {
+ IncreaseState( FOCUSABLE );
+ }
+ }
+ else
+ {
+ IncreaseState( FOCUSABLE );
+ }
+ }
+ }
+ }
+ else
+ {
+ m_pIMAcc->IncreaseState( STATE_SYSTEM_UNAVAILABLE );
+ if( !((m_accRole == MENU_ITEM) ||
+ (m_accRole == RADIO_MENU_ITEM) ||
+ (m_accRole == CHECK_MENU_ITEM)) )
+ {
+ if (m_accRole == TOGGLE_BUTTON || m_accRole == PUSH_BUTTON || m_accRole == BUTTON_DROPDOWN)
+ {
+ 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;
+ }
+}
+
+/**
+ * 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();
+
+ UpdateState();
+
+ return true;
+}
+
+
+/**
+ * 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;
+ }
+ sal_Int64 nRState = m_xAccContextRef->getAccessibleStateSet();
+
+ if (nRState & EXPANDED)
+ *isExpanded = true;
+ if (nRState & 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;
+}
+
+rtl::Reference<AccEventListener> AccObject::SetListener(rtl::Reference<AccEventListener> const& pListener)
+{
+ rtl::Reference<AccEventListener> pRet(m_pListener);
+ m_pListener = pListener;
+ return pRet;
+}
+
+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 0000000000..137b498a2c
--- /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 <AccObjectWinManager.hxx>
+#include <unomsaaevent.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccObjectContainerEventListener::AccObjectContainerEventListener(
+ css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager)
+ : AccContainerEventListener(pAcc, pManager)
+{
+}
+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.
+ sal_Int64 newV;
+ if (newValue >>= newV)
+ {
+ if (newV == AccessibleStateType::FOCUSED)
+ {
+ m_pObjManager->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/AccObjectWinManager.cxx b/winaccessibility/source/service/AccObjectWinManager.cxx
new file mode 100644
index 0000000000..24deb8150c
--- /dev/null
+++ b/winaccessibility/source/service/AccObjectWinManager.cxx
@@ -0,0 +1,1125 @@
+/* -*- 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;
+
+AccObjectWinManager::AccObjectWinManager():
+ oldFocus(nullptr)
+{
+}
+
+/**
+ * Destructor,clear all resource.
+ * @param
+ * @return
+ */
+AccObjectWinManager::~AccObjectWinManager()
+{
+ {
+ std::scoped_lock l(m_Mutex);
+
+ 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.
+ */
+
+sal_Int64
+AccObjectWinManager::Get_ToATInterface(sal_Int64 nHWnd, long lParam, WPARAM wParam)
+{
+ IMAccessible* pRetIMAcc = nullptr;
+
+ if(lParam == OBJID_CLIENT )
+ {
+ HWND hWnd = reinterpret_cast<HWND>(nHWnd);
+ pRetIMAcc = GetTopWindowIMAccessible(hWnd);
+ }
+
+ if ( pRetIMAcc && lParam == OBJID_CLIENT )
+ {
+ LRESULT result = LresultFromObject(IID_IAccessible, wParam, pRetIMAcc);
+ pRetIMAcc->Release();
+ return static_cast<sal_Int64>(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;
+
+ std::scoped_lock l(m_Mutex);
+
+ 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
+ */
+IMAccessible * AccObjectWinManager::GetTopWindowIMAccessible(HWND hWnd)
+{
+ std::scoped_lock l(m_Mutex); // tdf#155794 for HwndXAcc and XIdAccList
+
+ XHWNDToXAccHash::iterator iterResult =HwndXAcc.find(hWnd);
+ if(iterResult == HwndXAcc.end())
+ return nullptr;
+ XAccessible* pXAcc = iterResult->second;
+ AccObject *const pAccObject(GetAccObjByXAcc(pXAcc));
+ if (!pAccObject)
+ {
+ return nullptr;
+ }
+ IMAccessible *const pRet(pAccObject->GetIMAccessible());
+ if (!pRet)
+ {
+ return nullptr;
+ }
+ pRet->AddRef();
+ return pRet;
+}
+
+/**
+ * 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::STATE_SHOWING:
+ // send EVENT_SYSTEM_ALERT when notification gets shown
+ if (pRContext->getAccessibleRole() == AccessibleRole::NOTIFICATION)
+ NotifyWinEvent(EVENT_SYSTEM_ALERT, 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();
+ }
+}
+
+/**
+ * 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 )
+{
+ std::scoped_lock l(m_Mutex);
+
+ 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;
+
+ rtl::Reference<AccEventListener> pListener;
+
+ {
+ std::scoped_lock l(m_Mutex);
+
+ XIdToAccObjHash::iterator temp = XIdAccList.find(pXAcc);
+ if( temp != XIdAccList.end() )
+ {
+ ResIdGen.SetSub( temp->second.GetResID() );
+ }
+ else
+ {
+ return;
+ }
+
+ AccObject& accObj = temp->second;
+ DeleteAccChildNode( &accObj );
+ pListener = DeleteAccListener(&accObj);
+ accObj.NotifyDestroy();
+ 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!
+ }
+ if (pListener)
+ {
+ pListener->RemoveMeFromBroadcaster(false);
+ }
+}
+
+/**
+ * Delete listener that inspects some XAccessible object
+ * @param pAccObj Accobject pointer.
+ * @return
+ */
+rtl::Reference<AccEventListener> AccObjectWinManager::DeleteAccListener( AccObject* pAccObj )
+{
+ return 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;
+ }
+ }
+
+ const sal_Int64 nCount = pRContext->getAccessibleChildCount();
+ for (sal_Int64 i = 0; i < nCount; 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 )
+{
+ Reference< XAccessibleContext > pRContext;
+
+ if( pXAcc == nullptr)
+ return false;
+
+ pRContext = pXAcc->getAccessibleContext();
+ if( !pRContext.is() )
+ return false;
+
+ {
+ short nCurRole = GetRole(pXAcc);
+
+ std::scoped_lock l(m_Mutex);
+
+ XIdToAccObjHash::iterator itXacc = XIdAccList.find( pXAcc );
+ if (itXacc != XIdAccList.end() )
+ {
+ 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;
+ }
+ }
+
+ if( pWnd == nullptr )
+ {
+ if(pParentXAcc)
+ {
+ AccObject* pObj = GetAccObjByXAcc(pParentXAcc);
+ if(pObj)
+ pWnd = pObj->GetParentHWND();
+ }
+ if( pWnd == nullptr )
+ return false;
+ }
+
+ AccObject pObj(pXAcc, this);
+ 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;
+
+ {
+ std::scoped_lock l(m_Mutex);
+
+ 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)
+{
+ std::scoped_lock l(m_Mutex);
+
+ 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, this);
+ break;
+ case AccessibleRole::FRAME:
+ pRet = new AccFrameEventListener(pXAcc, this);
+ break;
+ case AccessibleRole::WINDOW:
+ pRet = new AccWindowEventListener(pXAcc, this);
+ break;
+ case AccessibleRole::ROOT_PANE:
+ pRet = new AccFrameEventListener(pXAcc, this);
+ 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, this);
+ break;
+ case AccessibleRole::BLOCK_QUOTE:
+ case AccessibleRole::PARAGRAPH:
+ case AccessibleRole::HEADING:
+ pRet = new AccParagraphEventListener(pXAcc, this);
+ break;
+ //Component
+ case AccessibleRole::CHECK_BOX:
+ case AccessibleRole::ICON:
+ case AccessibleRole::LABEL:
+ case AccessibleRole::STATIC:
+ case AccessibleRole::NOTIFICATION:
+ 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, this);
+ break;
+ //text component
+ case AccessibleRole::TEXT:
+ pRet = new AccTextComponentEventListener(pXAcc, this);
+ break;
+ //menu
+ case AccessibleRole::MENU:
+ pRet = new AccMenuEventListener(pXAcc, this);
+ break;
+ //object container
+ case AccessibleRole::SHAPE:
+
+ case AccessibleRole::EMBEDDED_OBJECT:
+ case AccessibleRole::GRAPHIC:
+ case AccessibleRole::TEXT_FRAME:
+ pRet = new AccObjectContainerEventListener(pXAcc, this);
+ break;
+ //descendmanager
+ case AccessibleRole::LIST:
+ pRet = new AccListEventListener(pXAcc, this);
+ break;
+ case AccessibleRole::TREE:
+ pRet = new AccTreeEventListener(pXAcc, this);
+ break;
+ //special
+ case AccessibleRole::COLUMN_HEADER:
+ case AccessibleRole::TABLE:
+ pRet = new AccTableEventListener(pXAcc, this);
+ break;
+ default:
+ pRet = new AccContainerEventListener(pXAcc, this);
+ 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, sal_Int64 nState)
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->DecreaseState(nState);
+}
+
+/**
+ * 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, sal_Int64 nState)
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->IncreaseState(nState);
+}
+
+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 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())
+ {
+ sal_Int64 nRState = xContext->getAccessibleStateSet();
+ return nRState & AccessibleStateType::MANAGES_DESCENDANTS;
+ }
+ }
+ return false;
+}
+
+/**
+ * Query and get IAccessible interface by XAccessible interface from list.
+ * @param pXAcc XAccessible interface.
+ * @return Com accobject interface.
+ */
+IMAccessible* AccObjectWinManager::GetIAccessibleFromXAccessible(XAccessible* pXAcc)
+{
+ AccObject* pAccObj = GetAccObjByXAcc(pXAcc);
+ if (pAccObj)
+ return pAccObj->GetIMAccessible();
+
+ 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;
+ }
+ const sal_Int64 nCount = xContext->getAccessibleChildCount();
+ for (sal_Int64 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 0000000000..fe7504901f
--- /dev/null
+++ b/winaccessibility/source/service/AccParagraphEventListener.cxx
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <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 <AccObjectWinManager.hxx>
+#include <unomsaaevent.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccParagraphEventListener::AccParagraphEventListener(css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager)
+ :AccContainerEventListener(pAcc, pManager)
+{}
+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:
+ {
+ sal_Int64 State;
+ if( (aEvent.NewValue >>= State) && (State == AccessibleStateType::SELECTED) )
+ {
+ m_pObjManager->IncreaseState(m_xAccessible.get(), State);
+ break;
+ }
+ else if( (aEvent.OldValue >>= State) && (State == AccessibleStateType::SELECTED) )
+ {
+ m_pObjManager->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)
+{
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::OBJECT_CARETCHANGE);
+}
+
+/**
+ * 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(sal_Int64 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()
+{
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::TEXT_SELECTION_CHANGED);
+}
+
+/* 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 0000000000..ccc67690a6
--- /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 <AccObjectWinManager.hxx>
+#include <unomsaaevent.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccTableEventListener::AccTableEventListener(css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager)
+ :AccDescendantManagerEventListener(pAcc, pManager)
+{}
+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:
+ {
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::TABLE_CAPTION_CHANGED);
+ break;
+ }
+ case AccessibleEventId::TABLE_COLUMN_DESCRIPTION_CHANGED:
+ {
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::TABLE_COLUMN_DESCRIPTION_CHANGED);
+ break;
+ }
+ case AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED:
+ {
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::TABLE_COLUMN_HEADER_CHANGED);
+ break;
+ }
+ case AccessibleEventId::TABLE_ROW_HEADER_CHANGED:
+ {
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::TABLE_ROW_HEADER_CHANGED);
+ break;
+ }
+ case AccessibleEventId::TABLE_MODEL_CHANGED:
+ {
+ HandleTableModelChangeEvent(aEvent.NewValue);
+ break;
+ }
+ case AccessibleEventId::TABLE_SUMMARY_CHANGED:
+ {
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::TABLE_SUMMARY_CHANGED);
+ break;
+ }
+ case AccessibleEventId::TABLE_ROW_DESCRIPTION_CHANGED:
+ {
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::TABLE_ROW_DESCRIPTION_CHANGED);
+ 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();
+ m_pObjManager->InsertAccObj(pAcc, m_xAccessible.get());
+ m_pObjManager->NotifyAccEvent(pAcc, UnoMSAAEvent::ACTIVE_DESCENDANT_CHANGED);
+ }
+ }
+ else if (oldValue >>= xChild)
+ {
+ //delete an existing child
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ m_pObjManager->DeleteAccObj( pAcc );
+ }
+ }
+
+}
+void AccTableEventListener::HandleTableModelChangeEvent(Any newValue)
+{
+ AccessibleTableModelChange aModelChange;
+ if (newValue >>= aModelChange)
+ {
+ if (m_xAccessible.is())
+ {
+ //delete all oldValue's existing children
+ m_pObjManager->DeleteChildrenAccObj(m_xAccessible.get());
+ //add all oldValue's existing children
+ m_pObjManager->InsertChildrenAccObj(m_xAccessible.get());
+ }
+ m_pObjManager->NotifyAccEvent(m_xAccessible.get(), UnoMSAAEvent::TABLE_MODEL_CHANGED);
+ }
+}
+
+/* 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 0000000000..05643016ea
--- /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 <AccObjectWinManager.hxx>
+#include <unomsaaevent.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccTextComponentEventListener::AccTextComponentEventListener(css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager)
+ :AccComponentEventListener(pAcc, pManager)
+{}
+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(sal_Int64 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 0000000000..12cb20f85a
--- /dev/null
+++ b/winaccessibility/source/service/AccTopWindowListener.cxx
@@ -0,0 +1,253 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <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)
+ {
+ m_aAccObjectManager.SaveTopWindowHandle(systemdata->hWnd, pAccessible);
+
+ AddAllListeners(pAccessible,nullptr,systemdata->hWnd);
+
+ if( window->GetStyle() & WB_MOVEABLE )
+ m_aAccObjectManager.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 )
+ {
+ m_aAccObjectManager.NotifyAccEvent(pAccessible, UnoMSAAEvent::MENUPOPUPSTART);
+ }
+
+ if (role == css::accessibility::AccessibleRole::FRAME ||
+ role == css::accessibility::AccessibleRole::DIALOG ||
+ role == css::accessibility::AccessibleRole::WINDOW ||
+ role == css::accessibility::AccessibleRole::ALERT)
+ {
+ m_aAccObjectManager.NotifyAccEvent(pAccessible, UnoMSAAEvent::SHOW);
+ }
+ }
+}
+
+AccTopWindowListener::AccTopWindowListener()
+ : m_aAccObjectManager()
+{
+}
+
+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;
+ }
+
+ m_aAccObjectManager.InsertAccObj(pAccessible, pParentXAcc, pWND);
+
+ if (!AccObjectWinManager::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(AccObjectWinManager::IsStateManageDescendant(pAccessible))
+ {
+ return ;
+ }
+ }
+
+ sal_Int64 nCount = pAccessibleContext->getAccessibleChildCount();
+ for (sal_Int64 i = 0; i < nCount; 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)
+ {
+ m_aAccObjectManager.NotifyAccEvent(pAccessible, UnoMSAAEvent::MENUPOPUPEND);
+ }
+ }
+
+
+ m_aAccObjectManager.DeleteChildrenAccObj( pAccessible );
+ if( role != css::accessibility::AccessibleRole::POPUP_MENU )
+ m_aAccObjectManager.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 m_aAccObjectManager.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 0000000000..b7c80b2d1f
--- /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 <AccObjectWinManager.hxx>
+#include <unomsaaevent.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccTreeEventListener::AccTreeEventListener(css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager)
+ :AccDescendantManagerEventListener(pAcc, pManager)
+{}
+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();
+ m_pObjManager->InsertAccObj(pAcc, m_xAccessible.get());
+ m_pObjManager->NotifyAccEvent(pAcc, UnoMSAAEvent::ACTIVE_DESCENDANT_CHANGED);
+ }
+ }
+ if (oldValue >>= xChild)
+ {
+ //delete an existing child
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ m_pObjManager->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 0000000000..5a96914ea5
--- /dev/null
+++ b/winaccessibility/source/service/AccWindowEventListener.cxx
@@ -0,0 +1,98 @@
+/* -*- 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 <AccObjectWinManager.hxx>
+#include <unomsaaevent.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccWindowEventListener::AccWindowEventListener(css::accessibility::XAccessible* pAcc, AccObjectWinManager* pManager)
+ :AccEventListener(pAcc, pManager)
+{}
+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::VISIBLE_DATA_CHANGED:
+ HandleVisibleDataChangedEvent();
+ break;
+ case AccessibleEventId::BOUNDRECT_CHANGED:
+ HandleBoundrectChangedEvent();
+ break;
+ default:
+ AccEventListener::notifyEvent(aEvent);
+ break;
+ }
+}
+
+/**
+ * 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(sal_Int64 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 )
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE);
+ else
+ m_pObjManager->DecreaseState(m_xAccessible.get(), AccessibleStateType::VISIBLE);
+ break;
+ case AccessibleStateType::SHOWING:
+ // UNO !SHOWING == MSAA OFFSCREEN
+ if( enable )
+ {
+ m_pObjManager->IncreaseState(m_xAccessible.get(), AccessibleStateType::SHOWING);
+ }
+ else
+ m_pObjManager->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 0000000000..7498380300
--- /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 0000000000..3891b6df48
--- /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>
+
+#include <AccTopWindowListener.hxx>
+
+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;
+
+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)
+{
+ // tdf#155794: this must complete without taking SolarMutex
+
+ 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_Int64 nCount = xParentAC->getAccessibleChildCount();
+ for (sal_Int64 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 0000000000..fe26e40e20
--- /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>