summaryrefslogtreecommitdiffstats
path: root/winaccessibility/source/service/AccObject.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--winaccessibility/source/service/AccObject.cxx1128
1 files changed, 1128 insertions, 0 deletions
diff --git a/winaccessibility/source/service/AccObject.cxx b/winaccessibility/source/service/AccObject.cxx
new file mode 100644
index 000000000..d2862577f
--- /dev/null
+++ b/winaccessibility/source/service/AccObject.cxx
@@ -0,0 +1,1128 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/XAccessibleValue.hpp>
+#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
+#include <com/sun/star/accessibility/XAccessibleText.hpp>
+
+#include <o3tl/char16_t2wchar_t.hxx>
+#include <o3tl/safeint.hxx>
+
+#include <stdlib.h>
+#include <memory.h>
+#include <stdio.h>
+#include <algorithm>
+#include <assert.h>
+
+#include <AccObject.hxx>
+#include <AccEventListener.hxx>
+
+#if defined __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wextra-tokens"
+ // "#endif !_MIDL_USE_GUIDDEF_" in midl-generated code
+#endif
+#include <UAccCOM_i.c>
+#if defined __clang__
+#pragma clang diagnostic pop
+#endif
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::accessibility::AccessibleRole;
+using namespace com::sun::star::accessibility::AccessibleStateType;
+
+//Role mapping table,left side is UNO role, right side is MSAA role
+const short ROLE_TABLE[][2] =
+ {
+ {UNKNOWN, IA2_ROLE_UNKNOWN},
+ {ALERT , ROLE_SYSTEM_DIALOG},
+ {COLUMN_HEADER , ROLE_SYSTEM_COLUMNHEADER},
+ //{CANVAS , ROLE_SYSTEM_CLIENT},
+ {CANVAS , IA2_ROLE_CANVAS},
+ {CHECK_BOX , ROLE_SYSTEM_CHECKBUTTON},
+ {CHECK_MENU_ITEM , IA2_ROLE_CHECK_MENU_ITEM},
+ {COLOR_CHOOSER, IA2_ROLE_COLOR_CHOOSER},
+ {COMBO_BOX , ROLE_SYSTEM_COMBOBOX},
+ {DATE_EDITOR , IA2_ROLE_DATE_EDITOR},
+ {DESKTOP_ICON , IA2_ROLE_DESKTOP_ICON},
+ {DESKTOP_PANE, IA2_ROLE_DESKTOP_PANE},
+ {DIRECTORY_PANE, IA2_ROLE_DIRECTORY_PANE},
+ {DIALOG, ROLE_SYSTEM_DIALOG},
+ {DOCUMENT, ROLE_SYSTEM_DOCUMENT},
+ {EMBEDDED_OBJECT , IA2_ROLE_EMBEDDED_OBJECT },
+ {END_NOTE , IA2_ROLE_ENDNOTE },
+ {FILE_CHOOSER , IA2_ROLE_FILE_CHOOSER },
+ {FILLER, ROLE_SYSTEM_WHITESPACE},
+ {FONT_CHOOSER, IA2_ROLE_FONT_CHOOSER},
+ {FOOTER, IA2_ROLE_FOOTER},
+ {FOOTNOTE, IA2_ROLE_FOOTNOTE},
+ //{FRAME, IA2_ROLE_FRAME},
+ {FRAME, ROLE_SYSTEM_DIALOG},
+ {GLASS_PANE , IA2_ROLE_GLASS_PANE},
+ {GRAPHIC , ROLE_SYSTEM_GRAPHIC},
+ {GROUP_BOX, ROLE_SYSTEM_GROUPING},
+ {HEADER , IA2_ROLE_HEADER},
+ {HEADING , IA2_ROLE_HEADING},
+ {HYPER_LINK , ROLE_SYSTEM_TEXT},
+ {ICON , IA2_ROLE_ICON},
+ {INTERNAL_FRAME, IA2_ROLE_INTERNAL_FRAME},
+ {LABEL, ROLE_SYSTEM_STATICTEXT},
+ {LAYERED_PANE , IA2_ROLE_LAYERED_PANE},
+ {LIST , ROLE_SYSTEM_LIST},
+ {LIST_ITEM , ROLE_SYSTEM_LISTITEM},
+ //{MENU , ROLE_SYSTEM_MENUPOPUP},
+ {MENU, ROLE_SYSTEM_MENUITEM},
+ {MENU_BAR, ROLE_SYSTEM_MENUBAR},
+ {MENU_ITEM, ROLE_SYSTEM_MENUITEM},
+ {OPTION_PANE , IA2_ROLE_OPTION_PANE},
+ {PAGE_TAB, ROLE_SYSTEM_PAGETAB},
+ {PAGE_TAB_LIST, ROLE_SYSTEM_PAGETABLIST},
+ {PANEL, IA2_ROLE_OPTION_PANE},
+ {PARAGRAPH, IA2_ROLE_PARAGRAPH},
+ {PASSWORD_TEXT, ROLE_SYSTEM_TEXT},
+ {POPUP_MENU, ROLE_SYSTEM_MENUPOPUP},
+ {PUSH_BUTTON, ROLE_SYSTEM_PUSHBUTTON},
+ {PROGRESS_BAR, ROLE_SYSTEM_PROGRESSBAR},
+ {RADIO_BUTTON, ROLE_SYSTEM_RADIOBUTTON},
+ {RADIO_MENU_ITEM, IA2_ROLE_RADIO_MENU_ITEM},
+ {ROW_HEADER , ROLE_SYSTEM_ROWHEADER},
+ {ROOT_PANE, IA2_ROLE_ROOT_PANE},
+ {SCROLL_BAR , ROLE_SYSTEM_SCROLLBAR},
+ {SCROLL_PANE , IA2_ROLE_SCROLL_PANE},
+ {SHAPE, IA2_ROLE_SHAPE},
+ {SEPARATOR , ROLE_SYSTEM_SEPARATOR},
+ {SLIDER , ROLE_SYSTEM_SLIDER},
+ {SPIN_BOX , ROLE_SYSTEM_SPINBUTTON},
+ {SPLIT_PANE, IA2_ROLE_SPLIT_PANE},
+ {STATUS_BAR, ROLE_SYSTEM_STATUSBAR},
+ {TABLE, ROLE_SYSTEM_TABLE},
+ {TABLE_CELL , ROLE_SYSTEM_CELL},
+ {TEXT, ROLE_SYSTEM_TEXT},
+ {TEXT_FRAME , IA2_ROLE_TEXT_FRAME},
+ //for change toggle button to push button for jaws
+ {TOGGLE_BUTTON, ROLE_SYSTEM_PUSHBUTTON},
+
+ {TOOL_BAR, ROLE_SYSTEM_TOOLBAR},
+ {TOOL_TIP, ROLE_SYSTEM_TOOLTIP},
+ {TREE , ROLE_SYSTEM_OUTLINE},
+ {VIEW_PORT , IA2_ROLE_VIEW_PORT},
+ {WINDOW, ROLE_SYSTEM_WINDOW},
+ {BUTTON_DROPDOWN, ROLE_SYSTEM_BUTTONDROPDOWN},
+ {BUTTON_MENU, ROLE_SYSTEM_BUTTONMENU},
+ {CAPTION, IA2_ROLE_CAPTION},
+ {CHART, IA2_ROLE_SHAPE},
+ {EDIT_BAR, IA2_ROLE_EDITBAR},
+ {FORM, IA2_ROLE_FORM},
+ {IMAGE_MAP , IA2_ROLE_IMAGE_MAP},
+ {NOTE, IA2_ROLE_NOTE},
+ {PAGE, IA2_ROLE_PAGE},
+ {RULER , IA2_ROLE_RULER},
+ {SECTION, IA2_ROLE_SECTION},
+ {TREE_ITEM , ROLE_SYSTEM_OUTLINEITEM},
+ {TREE_TABLE, ROLE_SYSTEM_OUTLINE},
+ {COMMENT, IA2_ROLE_TEXT_FRAME },
+ {COMMENT_END, IA2_ROLE_TEXT_FRAME },
+ {DOCUMENT_PRESENTATION, ROLE_SYSTEM_DOCUMENT },
+ {DOCUMENT_SPREADSHEET, ROLE_SYSTEM_DOCUMENT },
+ {DOCUMENT_TEXT, ROLE_SYSTEM_DOCUMENT },
+ {STATIC, ROLE_SYSTEM_STATICTEXT }
+ };
+
+
+/**
+ * Constructor.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @param Agent The agent kept in all listeners,it's the sole interface by which
+ * listener communicate with windows manager.
+ * @param listener listener that registers in UNO system.
+ * @return.
+ */
+AccObject::AccObject(XAccessible* pAcc, AccObjectManagerAgent* pAgent,
+ AccEventListener* pListener) :
+ m_resID (0),
+ m_pParantID (nullptr),
+ m_pIMAcc (nullptr),
+ m_pParentObj(nullptr),
+ m_pListener (pListener),
+ m_xAccRef( pAcc )
+{
+ ImplInitializeCreateObj();
+
+ m_xAccContextRef = m_xAccRef->getAccessibleContext();
+ m_xAccActionRef.set(m_xAccContextRef,UNO_QUERY);
+ m_accRole = m_xAccContextRef -> getAccessibleRole();
+ if( m_pIMAcc )
+ {
+ m_pIMAcc->SetXAccessible(reinterpret_cast<hyper>(m_xAccRef.get()));
+ m_pIMAcc->Put_XAccAgent(reinterpret_cast<hyper>(pAgent));
+ m_pIMAcc->SetDefaultAction(reinterpret_cast<hyper>(m_xAccActionRef.get()));
+ }
+}
+/**
+ * Destructor.
+ * @param
+ * @return
+ */
+AccObject::~AccObject()
+{
+ m_pIMAcc = nullptr;
+ m_xAccRef = nullptr;
+ m_xAccActionRef = nullptr;
+ m_xAccContextRef = nullptr;
+}
+
+
+/**
+ * Insert a child element.
+ * @param pChild Child element that should be inserted into child list.
+ * @param pos Insert position.
+ * @return
+ */
+void AccObject::InsertChild( AccObject* pChild,short pos )
+{
+
+ std::vector<AccObject*>::iterator iter;
+ iter = std::find(m_childrenList.begin(),m_childrenList.end(),pChild);
+ if(iter!=m_childrenList.end())
+ return;
+ if(LAST_CHILD==pos)
+ {
+ m_childrenList.push_back(pChild);
+ }
+ else
+ {
+ iter=m_childrenList.begin()+pos;
+ m_childrenList.insert(iter,pChild);
+ }
+
+ pChild->SetParentObj(this);
+}
+
+/**
+ * Delete a child element
+ * @param pChild Child element that should be inserted into child list.
+ * @param pos Insert position.
+ * @return
+ */
+void AccObject::DeleteChild( AccObject* pChild )
+{
+ std::vector<AccObject*>::iterator iter;
+ iter = std::find(m_childrenList.begin(),m_childrenList.end(),pChild);
+ if(iter!=m_childrenList.end())
+ {
+ m_childrenList.erase(iter);
+ if(m_pIMAcc)
+ pChild->SetParentObj(nullptr);
+ }
+}
+
+/**
+ * In order to windows API WindowFromAccessibleObject, we sometimes to set a pure
+ * top window accessible object created by windows system as top ancestor.
+ * @param.
+ * @return
+ */
+void AccObject::UpdateValidWindow()
+{
+ if(m_pIMAcc)
+ m_pIMAcc->Put_XAccWindowHandle(m_pParantID);
+}
+
+/**
+ * Translate all UNO basic information into MSAA com information.
+ * @param
+ * @return If the method is correctly processed.
+ */
+void AccObject::ImplInitializeCreateObj()
+{
+ m_pIMAcc = UAccCOMCreateInstance();
+
+ assert(m_pIMAcc);
+}
+
+/**
+ * Update name property to com object.
+ * @param
+ * @return
+ */
+void AccObject::UpdateName( )
+{
+ if (!m_pIMAcc)
+ {
+ return;
+ }
+
+ if( ( TEXT_FRAME == m_accRole ) && ( m_pParentObj !=nullptr )&& ( SCROLL_PANE == m_pParentObj -> m_accRole ) )
+ m_pIMAcc->Put_XAccName( o3tl::toW(m_pParentObj->m_xAccContextRef->getAccessibleName().getStr()) );
+ //IAccessibility2 Implementation 2009-----
+ if ( PARAGRAPH == m_accRole)
+ {
+ m_pIMAcc->Put_XAccName(L"");
+ }
+ //-----IAccessibility2 Implementation 2009
+ else
+ m_pIMAcc->Put_XAccName(o3tl::toW(m_xAccContextRef->getAccessibleName().getStr()));
+
+ return ;
+}
+
+/**
+ * Update default action property to com object.
+ * @param
+ * @return
+ */
+void AccObject::UpdateAction()
+{
+ m_xAccActionRef.set(m_xAccContextRef,UNO_QUERY);
+
+ if( m_xAccActionRef.is() && m_pIMAcc )
+ {
+ if( m_xAccActionRef->getAccessibleActionCount() > 0 )
+ {
+ UpdateDefaultAction( );
+ m_pIMAcc->SetDefaultAction(
+ reinterpret_cast<hyper>(m_xAccActionRef.get()));
+ }
+ }
+}
+
+/**
+ * Update value property to com object.
+ * @param
+ * @return
+ */
+void AccObject::UpdateValue()
+{
+ if( nullptr == m_pIMAcc || !m_xAccContextRef.is() )
+ {
+ assert(false);
+ return ;
+ }
+
+ Reference< XAccessibleValue > pRValue(m_xAccContextRef,UNO_QUERY);
+ Any pAny;
+ if( pRValue.is() )
+ {
+ pAny = pRValue->getCurrentValue();
+ }
+
+ SetValue( pAny );
+}
+
+/**
+ * Set special default action description string via UNO role.
+ * @param Role UNO role
+ * @return
+ */
+void AccObject::UpdateDefaultAction( )
+{
+ if(!m_xAccActionRef.is())
+ return ;
+
+ switch(m_accRole)
+ {
+ case PUSH_BUTTON:
+ case TOGGLE_BUTTON:
+ case RADIO_BUTTON:
+ case MENU_ITEM:
+ case RADIO_MENU_ITEM:
+ case CHECK_MENU_ITEM:
+ case LIST_ITEM:
+ case CHECK_BOX:
+ case TREE_ITEM:
+ case BUTTON_DROPDOWN:
+ m_pIMAcc->Put_ActionDescription( o3tl::toW(m_xAccActionRef->getAccessibleActionDescription(sal_Int32(0)).getStr()) );
+ return;
+ }
+}
+
+/**
+ * Set value property via pAny.
+ * @param pAny New value.
+ * @return
+ */
+void AccObject::SetValue( Any pAny )
+{
+ if( nullptr == m_pIMAcc || !m_xAccContextRef.is() )
+ {
+ assert(false);
+ return ;
+ }
+ Reference< XAccessibleText > pRText(m_xAccContextRef,UNO_QUERY);
+ OUString val;
+ switch(m_accRole)
+ {
+ case SPIN_BOX:
+ // 3. date editor's msaa value should be the same as spinbox
+ case DATE_EDITOR:
+ case TEXT:
+ case PARAGRAPH:
+ case HEADING:
+ case TABLE_CELL:
+
+ if(pRText)
+ {
+ val = pRText->getText();
+ }
+ m_pIMAcc->Put_XAccValue( o3tl::toW(val.getStr()) );
+ break;
+ case TREE_ITEM:
+ //case CHECK_BOX: //Commented by Li Xing to disable the value for general checkbox
+ case COMBO_BOX:
+ case NOTE:
+ case SCROLL_BAR:
+ m_pIMAcc->Put_XAccValue( o3tl::toW(GetMAccessibleValueFromAny(pAny).getStr()) );
+ break ;
+ // Added by Li Xing, only the checkbox in tree should have the value.
+ case CHECK_BOX:
+ if( ( m_pParentObj !=nullptr ) && (TREE == m_pParentObj->m_accRole || TREE_ITEM == m_pParentObj->m_accRole ))
+ m_pIMAcc->Put_XAccValue( o3tl::toW(GetMAccessibleValueFromAny(pAny).getStr()) );
+ break;
+ default:
+ break;
+ }
+
+ return;
+}
+
+OUString AccObject::GetMAccessibleValueFromAny(Any pAny)
+{
+ OUString strValue;
+
+ if(nullptr == m_pIMAcc)
+ return strValue;
+
+ if(pAny.getValueType() == cppu::UnoType<cppu::UnoUnsignedShortType>::get() )
+ {
+ sal_uInt16 val;
+ if (pAny >>= val)
+ {
+ strValue=OUString::number(val);
+
+ }
+ }
+ else if(pAny.getValueType() == cppu::UnoType<OUString>::get())
+ {
+
+ pAny >>= strValue ;
+
+ }
+ else if(pAny.getValueType() == cppu::UnoType<Sequence< OUString >>::get())
+ {
+ Sequence< OUString > val;
+ if (pAny >>= val)
+ {
+ for (const OUString& rElem : val)
+ strValue += rElem;
+ }
+ }
+ else if(pAny.getValueType() == cppu::UnoType<double>::get())
+ {
+ double val;
+ if (pAny >>= val)
+ {
+ strValue=OUString::number(val);
+ }
+ }
+ else if(pAny.getValueType() == cppu::UnoType<sal_Int32>::get())
+ {
+ sal_Int32 val;
+ if (pAny >>= val)
+ {
+ strValue=OUString::number(val);
+ }
+ }
+ else if (pAny.getValueType() == cppu::UnoType<css::accessibility::TextSegment>::get())
+ {
+ css::accessibility::TextSegment val;
+ if (pAny >>= val)
+ {
+ OUString realVal(val.SegmentText);
+ strValue = realVal;
+
+ }
+ }
+
+ return strValue;
+}
+/**
+ * Set name property via pAny.
+ * @param pAny New accessible name.
+ * @return
+ */
+void AccObject::SetName( Any pAny)
+{
+ if( nullptr == m_pIMAcc )
+ return ;
+
+ m_pIMAcc->Put_XAccName( o3tl::toW(GetMAccessibleValueFromAny(pAny).getStr()) );
+
+}
+
+/**
+* Get role property via pAny
+* @param
+* @return accessible role
+*/
+short AccObject::GetRole() const
+{
+ return m_accRole;
+}
+
+/**
+ * Get MSAA state from UNO state
+ * @Role xState UNO state.
+ * @return
+ */
+DWORD AccObject::GetMSAAStateFromUNO(short xState)
+{
+ DWORD IState = UNO_MSAA_UNMAPPING;
+
+ if( !m_xAccContextRef.is() )
+ {
+ assert(false);
+ return IState;
+ }
+ short Role = m_accRole;
+
+ switch( xState )
+ {
+ case BUSY:
+ IState = STATE_SYSTEM_BUSY;
+ break;
+ case CHECKED:
+ if( Role == PUSH_BUTTON || Role == TOGGLE_BUTTON )
+ {
+ IState = STATE_SYSTEM_PRESSED;
+ }
+ else
+ IState = STATE_SYSTEM_CHECKED;
+ break;
+ case DEFUNC:
+ IState = STATE_SYSTEM_UNAVAILABLE;
+ break;
+ case EXPANDED:
+ IState = STATE_SYSTEM_EXPANDED;
+ break;
+ case FOCUSABLE:
+ IState = STATE_SYSTEM_FOCUSABLE;
+ break;
+ case FOCUSED:
+ IState = STATE_SYSTEM_FOCUSED;
+ break;
+ case INDETERMINATE:
+ IState = STATE_SYSTEM_MIXED;
+ break;
+ case MULTI_SELECTABLE:
+ IState = STATE_SYSTEM_MULTISELECTABLE;
+ break;
+ case PRESSED:
+ IState = STATE_SYSTEM_PRESSED;
+ break;
+ case RESIZABLE:
+ IState = STATE_SYSTEM_SIZEABLE;
+ break;
+ case SELECTABLE:
+ if( m_accRole == MENU || m_accRole == MENU_ITEM)
+ {
+ IState = UNO_MSAA_UNMAPPING;
+ }
+ else
+ {
+ IState = STATE_SYSTEM_SELECTABLE;
+ }
+ break;
+ case SELECTED:
+ if( m_accRole == MENU || m_accRole == MENU_ITEM )
+ {
+ IState = UNO_MSAA_UNMAPPING;
+ }
+ else
+ {
+ IState = STATE_SYSTEM_SELECTED;
+ }
+ break;
+ case ARMED:
+ IState = STATE_SYSTEM_FOCUSED;
+ break;
+ case EXPANDABLE:
+ {
+ sal_Bool isExpanded = true;
+ sal_Bool isExpandable = true;
+ if( Role == PUSH_BUTTON || Role == TOGGLE_BUTTON || BUTTON_DROPDOWN == Role )
+ {
+ IState = STATE_SYSTEM_HASPOPUP;
+ }
+ else
+ {
+ GetExpandedState(&isExpandable,&isExpanded);
+ if(!isExpanded)
+ IState = STATE_SYSTEM_COLLAPSED;
+ }
+ }
+ break;
+ //Remove the SENSITIVE state mapping. There is no corresponding MSAA state.
+ //case SENSITIVE:
+ // IState = STATE_SYSTEM_PROTECTED;
+ case EDITABLE:
+ if( m_pIMAcc )
+ {
+ m_pIMAcc->DecreaseState( STATE_SYSTEM_READONLY );
+ }
+ break;
+ case OFFSCREEN:
+ IState = STATE_SYSTEM_OFFSCREEN;
+ break;
+ case MOVEABLE:
+ IState = STATE_SYSTEM_MOVEABLE;
+ break;
+ case COLLAPSE:
+ IState = STATE_SYSTEM_COLLAPSED;
+ break;
+ case DEFAULT:
+ IState = STATE_SYSTEM_DEFAULT;
+ break;
+ default:
+ break;
+ }
+
+ return IState;
+}
+
+/**
+ * Decrease state of com object
+ * @param xState The lost state.
+ * @return
+ */
+void AccObject::DecreaseState( short xState )
+{
+ if( nullptr == m_pIMAcc )
+ {
+ return;
+ }
+
+ if( xState == FOCUSABLE)
+ {
+ short Role = m_accRole ;
+ if(Role == MENU_ITEM
+ || Role == RADIO_MENU_ITEM
+ || Role == CHECK_MENU_ITEM)
+ return;
+ else
+ {
+ if (Role == TOGGLE_BUTTON || Role == PUSH_BUTTON || BUTTON_DROPDOWN == Role)
+ {
+ if( ( m_pParentObj !=nullptr ) && (TOOL_BAR == m_pParentObj->m_accRole ) )
+ return;
+ }
+ }
+ }
+
+ else if( xState == AccessibleStateType::VISIBLE )
+ {
+ m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE );
+ }
+ else if( xState == AccessibleStateType::SHOWING )
+ {
+ m_pIMAcc->IncreaseState( STATE_SYSTEM_OFFSCREEN );
+ }
+
+ DWORD msState = GetMSAAStateFromUNO(xState);
+ if(msState!=UNO_MSAA_UNMAPPING)
+ m_pIMAcc->DecreaseState(msState);
+}
+
+/**
+ * Increase state of com object
+ * @param xState The new state.
+ * @return
+ */
+void AccObject::IncreaseState( short xState )
+{
+ if( nullptr == m_pIMAcc )
+ {
+ assert(false);
+ return;
+ }
+
+
+ if( xState == AccessibleStateType::VISIBLE )
+ {
+ m_pIMAcc->DecreaseState( STATE_SYSTEM_INVISIBLE );
+ }
+ else if( xState == AccessibleStateType::SHOWING )
+ {
+ m_pIMAcc->DecreaseState( STATE_SYSTEM_OFFSCREEN );
+ }
+
+
+ DWORD msState = GetMSAAStateFromUNO(xState);
+ if(msState!=UNO_MSAA_UNMAPPING)
+ m_pIMAcc->IncreaseState( msState );
+}
+
+/**
+ * Get next child element
+ * @param
+ * @return AccObject Object interface.
+ */
+AccObject* AccObject::NextChild()
+{
+ IAccChildList::iterator pInd = m_childrenList.begin();
+ if( pInd != m_childrenList.end() )
+ return *pInd;
+ return nullptr;
+}
+/**
+ * update action description desc
+ * @param
+ * @return
+ */
+void AccObject::UpdateActionDesc()
+{
+ if (!m_pIMAcc)
+ return;
+
+ long Role = m_accRole;
+
+ if( Role == PUSH_BUTTON || Role == RADIO_BUTTON || Role == MENU_ITEM ||
+ Role == LIST_ITEM || Role == CHECK_BOX || Role == TREE_ITEM ||
+ Role == CHECK_MENU_ITEM || Role == RADIO_MENU_ITEM )
+ {
+ UpdateDefaultAction( );
+ }
+ else
+ {
+
+ if( m_xAccActionRef.is() )
+ {
+ if( m_xAccActionRef->getAccessibleActionCount() > 0 )
+ {
+ if (!(Role == SPIN_BOX || Role == COMBO_BOX || Role == DATE_EDITOR ||
+ Role == EDIT_BAR || Role == PASSWORD_TEXT || Role == TEXT))
+ {
+ const OUString sActionDesc = m_xAccActionRef->getAccessibleActionDescription(0);
+ // if string is non-empty, action is set.
+ if (!sActionDesc.isEmpty())
+ m_pIMAcc->Put_ActionDescription(o3tl::toW(sActionDesc.getStr()));
+ }
+ }
+ }
+ }
+
+}
+/**
+ * update role information from uno to com
+ * @param
+ * @return
+ */
+void AccObject::UpdateRole()
+{
+ if (!m_pIMAcc)
+ {
+ return;
+ }
+
+ XAccessibleContext* pContext = m_xAccContextRef.get();
+ m_pIMAcc->Put_XAccRole( ROLE_SYSTEM_WINDOW );
+ sal_Int16 iRoleIndex = pContext->getAccessibleRole();
+ if ((0 <= iRoleIndex) && (o3tl::make_unsigned(iRoleIndex) < SAL_N_ELEMENTS(ROLE_TABLE)))
+ {
+ short iIA2Role = ROLE_TABLE[iRoleIndex][1] ;
+ m_pIMAcc->Put_XAccRole( iIA2Role );
+ }
+
+}
+/**
+ * update state information from uno to com
+ * @param
+ * @return
+ */
+void AccObject::UpdateState()
+{
+ if (!m_pIMAcc)
+ {
+ return;
+ }
+
+ XAccessibleContext* pContext = m_xAccContextRef.get();
+ Reference< XAccessibleStateSet > pRState = pContext->getAccessibleStateSet();
+ if( !pRState.is() )
+ {
+ assert(false);
+ return ;
+ }
+
+ m_pIMAcc->SetState(0);
+
+ if ( m_accRole == POPUP_MENU )
+ {
+ return;
+ }
+
+ bool isEnable = false;
+ bool isShowing = false;
+ bool isEditable = false;
+ bool isVisible = false;
+ bool isFocusable = false;
+
+ for (const sal_Int16 nState : pRState->getStates())
+ {
+ if (nState == ENABLED)
+ isEnable = true;
+ else if (nState == SHOWING)
+ isShowing = true;
+ else if (nState == VISIBLE)
+ isVisible = true;
+ else if (nState == EDITABLE)
+ isEditable = true;
+ else if (nState == FOCUSABLE)
+ isFocusable = true;
+ IncreaseState(nState);
+ }
+ bool bIsMenuItem = m_accRole == MENU_ITEM || m_accRole == RADIO_MENU_ITEM || m_accRole == CHECK_MENU_ITEM;
+
+ if(bIsMenuItem)
+ {
+ if(!(isShowing && isVisible) )
+ {
+ m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE );
+ m_pIMAcc->DecreaseState( STATE_SYSTEM_FOCUSABLE );
+ }
+ }
+ else
+ {
+ if(!(isShowing || isVisible) )
+ m_pIMAcc->IncreaseState( STATE_SYSTEM_INVISIBLE );
+ }
+
+ short Role = m_accRole;
+
+ switch(m_accRole)
+ {
+ case LABEL:
+ case STATIC:
+ m_pIMAcc->IncreaseState( STATE_SYSTEM_READONLY );
+ break;
+ case TEXT:
+ // 2. editable combobox -> readonly ------ bridge
+ case EMBEDDED_OBJECT:
+ case END_NOTE:
+ case FOOTER:
+ case FOOTNOTE:
+ case GRAPHIC:
+ case HEADER:
+ case HEADING:
+
+ //Image Map
+ case PARAGRAPH:
+ case PASSWORD_TEXT:
+ case SHAPE:
+ case SPIN_BOX:
+ case TABLE:
+ case TABLE_CELL:
+ case TEXT_FRAME:
+ case DATE_EDITOR:
+ case DOCUMENT:
+ case COLUMN_HEADER:
+ {
+ if(!isEditable)
+ m_pIMAcc->IncreaseState( STATE_SYSTEM_READONLY );
+ }
+ break;
+ default:
+ break;
+ }
+
+ if( isEnable )
+ {
+
+ if(!(Role == FILLER || Role == END_NOTE || Role == FOOTER || Role == FOOTNOTE || Role == GROUP_BOX || Role == RULER
+ || Role == HEADER || Role == ICON || Role == INTERNAL_FRAME || Role == LABEL || Role == LAYERED_PANE
+ || Role == SCROLL_BAR || Role == SCROLL_PANE || Role == SPLIT_PANE || Role == STATIC || Role == STATUS_BAR
+ || Role == TOOL_TIP))
+ {
+ if( SEPARATOR == Role )
+ {
+ if( ( m_pParentObj != nullptr ) && ( MENU == m_pParentObj->m_accRole || POPUP_MENU == m_pParentObj->m_accRole ))
+ IncreaseState( FOCUSABLE );
+ }
+
+ else if (TABLE_CELL == Role || TABLE == Role || PANEL == Role || OPTION_PANE == Role ||
+ COLUMN_HEADER == Role)
+ {
+ if (isFocusable)
+ IncreaseState( FOCUSABLE );
+ }
+ else
+ {
+ if(bIsMenuItem)
+ {
+ if ( isShowing && isVisible)
+ {
+ IncreaseState( FOCUSABLE );
+ }
+ }
+ else
+ {
+ IncreaseState( FOCUSABLE );
+ }
+ }
+ }
+ }
+ else
+ {
+ m_pIMAcc->IncreaseState( STATE_SYSTEM_UNAVAILABLE );
+ if( !((Role == MENU_ITEM) ||
+ (Role == RADIO_MENU_ITEM) ||
+ (Role == CHECK_MENU_ITEM)) )
+ {
+ if ( Role == TOGGLE_BUTTON || Role == PUSH_BUTTON || BUTTON_DROPDOWN == Role)
+ {
+ if(( m_pParentObj != nullptr )&& (TOOL_BAR == m_pParentObj->m_accRole ) )
+ IncreaseState( FOCUSABLE );
+ else
+ DecreaseState( FOCUSABLE );
+ }
+ else
+ DecreaseState( FOCUSABLE );
+ }
+ else if( isShowing || isVisible )
+ {
+ IncreaseState( FOCUSABLE );
+ }
+ }
+
+ switch(m_accRole)
+ {
+ case POPUP_MENU:
+ case MENU:
+ if( pContext->getAccessibleChildCount() > 0 )
+ m_pIMAcc->IncreaseState( STATE_SYSTEM_HASPOPUP );
+ break;
+ case PASSWORD_TEXT:
+ m_pIMAcc->IncreaseState( STATE_SYSTEM_PROTECTED );
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * update location information from uno to com
+ * @param
+ * @return
+ */
+void AccObject::UpdateLocation()
+{
+ if (!m_pIMAcc)
+ {
+ return;
+ }
+ XAccessibleContext* pContext = m_xAccContextRef.get();
+
+ Reference< XAccessibleComponent > pRComponent(pContext,UNO_QUERY);
+ if( pRComponent.is() )
+ {
+ css::awt::Point pCPoint = pRComponent->getLocationOnScreen();
+ css::awt::Size pCSize = pRComponent->getSize();
+ Location tempLocation;
+ tempLocation.m_dLeft = pCPoint.X;
+ tempLocation.m_dTop = pCPoint.Y;
+ tempLocation.m_dWidth = pCSize.Width;
+ tempLocation.m_dHeight = pCSize.Height;
+ m_pIMAcc->Put_XAccLocation( tempLocation );
+ }
+
+}
+
+
+/**
+ * Public method to mapping information between MSAA and UNO.
+ * @param
+ * @return If the method is correctly processed.
+ */
+bool AccObject::UpdateAccessibleInfoFromUnoToMSAA()
+{
+ if( nullptr == m_pIMAcc || !m_xAccContextRef.is() )
+ {
+ assert(false);
+ return false;
+ }
+
+ UpdateName();
+
+ UpdateValue();
+
+ UpdateActionDesc();
+
+ UpdateRole();
+
+ UpdateLocation();
+
+ UpdateState();
+
+ return true;
+}
+
+/*
+ * Add a child selected element.
+ * @param pAccObj Child object pointer.
+ * @return
+ */
+void AccObject::AddSelect( long index, AccObject* accObj)
+{
+ m_selectionList.emplace(index,accObj);
+}
+
+IAccSelectionList& AccObject::GetSelection()
+{
+ return m_selectionList;
+}
+
+
+/**
+ * Set self to focus object in parent child list
+ * @param
+ * @return
+ */
+void AccObject::setFocus()
+{
+ if(m_pIMAcc)
+ {
+ IncreaseState(FOCUSED);
+ m_pIMAcc->Put_XAccFocus(CHILDID_SELF);
+
+ UpdateRole();
+ }
+}
+
+/**
+ * Unset self from focus object in parent child list.
+ * @param
+ * @return
+ */
+void AccObject::unsetFocus()
+{
+ if(m_pIMAcc)
+ {
+ DecreaseState( FOCUSED );
+ m_pIMAcc->Put_XAccFocus(UACC_NO_FOCUS);
+ }
+}
+
+void AccObject::GetExpandedState( sal_Bool* isExpandable, sal_Bool* isExpanded)
+{
+ *isExpanded = false;
+ *isExpandable = false;
+
+ if( !m_xAccContextRef.is() )
+ {
+ return;
+ }
+ Reference< XAccessibleStateSet > pRState = m_xAccContextRef->getAccessibleStateSet();
+ if( !pRState.is() )
+ {
+ return;
+ }
+
+ for (sal_Int16 nState : pRState->getStates())
+ {
+ if (nState == EXPANDED)
+ *isExpanded = true;
+ else if (nState == EXPANDABLE)
+ *isExpandable = true;
+ }
+}
+
+void AccObject::NotifyDestroy()
+{
+ if(m_pIMAcc)
+ m_pIMAcc->NotifyDestroy();
+}
+
+void AccObject::SetParentObj(AccObject* pParentAccObj)
+{
+ m_pParentObj = pParentAccObj;
+
+ if(m_pIMAcc)
+ {
+ if(m_pParentObj)
+ {
+ m_pIMAcc->Put_XAccParent(m_pParentObj->GetIMAccessible());
+ }
+ else
+ {
+ m_pIMAcc->Put_XAccParent(nullptr);
+ }
+ }
+}
+//ResID means ChildID in MSAA
+void AccObject::SetResID(long id)
+{
+ m_resID = id;
+ if(m_pIMAcc)
+ m_pIMAcc->Put_XAccChildID(m_resID);
+}
+//return COM interface in acc object
+IMAccessible* AccObject::GetIMAccessible()
+{
+ return m_pIMAcc;
+}
+
+Reference<XAccessible> const& AccObject::GetXAccessible()
+{
+ return m_xAccRef;
+}
+
+void AccObject::SetParentHWND(HWND hWnd)
+{
+ m_pParantID = hWnd;
+}
+
+void AccObject::SetListener(rtl::Reference<AccEventListener> const& pListener)
+{
+ m_pListener = pListener;
+}
+
+AccEventListener* AccObject::getListener()
+{
+ return m_pListener.get();
+}
+
+long AccObject::GetResID()
+{
+ return m_resID;
+}
+
+HWND AccObject::GetParentHWND()
+{
+ return m_pParantID;
+}
+
+AccObject* AccObject::GetParentObj()
+{
+ return m_pParentObj;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */