summaryrefslogtreecommitdiff
path: root/winaccessibility/source/service
diff options
context:
space:
mode:
authorSteve Yin <steve_y@apache.org>2013-11-14 08:18:05 +0000
committerMichael Meeks <michael.meeks@collabora.com>2013-11-19 10:02:22 +0000
commita18bdb3bc05e761704cc345a66a9d642bc4f4a0a (patch)
tree534b0f54f06d684e4496370f6fff38a15bfeb9ac /winaccessibility/source/service
parentf0d9beb80f926a05bc7dd87801c6daa7bc268cec (diff)
Integrate branch of IAccessible2
Just the winaccessibility directory initially. Change-Id: Ia21abb8d7088646ad6c1f83b3a03e7add716b0c0
Diffstat (limited to 'winaccessibility/source/service')
-rw-r--r--winaccessibility/source/service/AccComponentEventListener.cxx336
-rw-r--r--winaccessibility/source/service/AccContainerEventListener.cxx573
-rw-r--r--winaccessibility/source/service/AccDescendantManagerEventListener.cxx226
-rw-r--r--winaccessibility/source/service/AccDialogEventListener.cxx150
-rw-r--r--winaccessibility/source/service/AccEventListener.cxx309
-rw-r--r--winaccessibility/source/service/AccFrameEventListener.cxx173
-rw-r--r--winaccessibility/source/service/AccListEventListener.cxx123
-rw-r--r--winaccessibility/source/service/AccMenuEventListener.cxx151
-rw-r--r--winaccessibility/source/service/AccObject.cxx1109
-rw-r--r--winaccessibility/source/service/AccObjectContainerEventListener.cxx72
-rw-r--r--winaccessibility/source/service/AccObjectManagerAgent.cxx386
-rw-r--r--winaccessibility/source/service/AccObjectWinManager.cxx1321
-rw-r--r--winaccessibility/source/service/AccParagraphEventListener.cxx145
-rw-r--r--winaccessibility/source/service/AccResource.cxx85
-rw-r--r--winaccessibility/source/service/AccTableEventListener.cxx146
-rw-r--r--winaccessibility/source/service/AccTextComponentEventListener.cxx65
-rw-r--r--winaccessibility/source/service/AccTopWindowListener.cxx321
-rw-r--r--winaccessibility/source/service/AccTreeEventListener.cxx87
-rw-r--r--winaccessibility/source/service/AccWindowEventListener.cxx152
-rw-r--r--winaccessibility/source/service/ResIDGenerator.cxx54
-rw-r--r--winaccessibility/source/service/checkmt.cxx36
-rw-r--r--winaccessibility/source/service/checkmt.hxx28
-rw-r--r--winaccessibility/source/service/exports.dxp2
-rw-r--r--winaccessibility/source/service/msaaservice_impl.cxx289
-rw-r--r--winaccessibility/source/service/winaccessibility.component27
25 files changed, 6366 insertions, 0 deletions
diff --git a/winaccessibility/source/service/AccComponentEventListener.cxx b/winaccessibility/source/service/AccComponentEventListener.cxx
new file mode 100644
index 000000000000..0f0343619766
--- /dev/null
+++ b/winaccessibility/source/service/AccComponentEventListener.cxx
@@ -0,0 +1,336 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#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 "AccComponentEventListener.hxx"
+#include "AccObjectManagerAgent.hxx"
+#include "unomsaaevent.hxx"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccComponentEventListener::AccComponentEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
+ :AccEventListener(pAcc, Agent)
+{
+}
+
+AccComponentEventListener::~AccComponentEventListener()
+{
+}
+
+/**
+ * Uno's event notifier when event is captured
+ *
+ * @param AccessibleEventObject the event object which contains information about event
+ */
+void AccComponentEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ 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:
+ handleSelectionChangedEvent();
+ 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 oldValue, Any newValue)
+{
+ pAgent->UpdateValue(pAccessible);
+ pAgent->NotifyAccEvent(UM_EVENT_OBJECT_VALUECHANGE, pAccessible);
+}
+
+/**
+ * handle the NAME_CHANGED event
+ */
+void AccComponentEventListener::handleActionChangedEvent()
+{
+ pAgent->UpdateAction(pAccessible);
+ pAgent->NotifyAccEvent(UM_EVENT_OBJECT_DEFACTIONCHANGE, pAccessible);
+}
+
+/**
+ * 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 oldValue, Any newValue)
+{
+ pAgent->UpdateValue(pAccessible, newValue);
+ pAgent->NotifyAccEvent(UM_EVENT_OBJECT_VALUECHANGE, pAccessible);
+}
+
+/**
+ * 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 oldValue, Any newValue)
+{
+ pAgent->NotifyAccEvent(UM_EVENT_OBJECT_CARETCHANGE, pAccessible);
+}
+
+/**
+ * handle the VISIBLE_DATA_CHANGED event
+ */
+void AccComponentEventListener::handleVisibleDataChangedEvent()
+{
+ AccEventListener::handleVisibleDataChangedEvent();
+}
+
+/**
+ * handle the BOUNDRECT_CHANGED event
+ */
+void AccComponentEventListener::handleBoundrectChangedEvent()
+{
+ AccEventListener::handleBoundrectChangedEvent();
+}
+
+/**
+ * set the new state and fire the MSAA event
+ *
+ * @param state new state id
+ * @param enable true if state is set, false if state is unset
+ */
+void AccComponentEventListener::setComponentState(short state, bool enable )
+{
+ // only the following state can be fired state event.
+ switch (state)
+ {
+ case AccessibleStateType::CHECKED:
+ case AccessibleStateType::PRESSED:
+ case AccessibleStateType::SELECTED:
+ case AccessibleStateType::ARMED:
+ case AccessibleStateType::INDETERMINATE:
+ case AccessibleStateType::SHOWING:
+ fireStatePropertyChange(state, enable);
+ break;
+ case AccessibleStateType::VISIBLE:
+ if (getRole() == AccessibleRole::MENU_ITEM)
+ {
+ if(enable)
+ {
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::VISIBLE);
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::FOCUSABLE);
+ }
+ else
+ {
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::VISIBLE);
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::FOCUSABLE);
+ }
+ }
+ else
+ {
+ fireStatePropertyChange(state, enable);
+ }
+ break;
+ break;
+ case AccessibleStateType::FOCUSED:
+ fireStateFocusdChange(enable);
+ break;
+ case AccessibleStateType::ENABLED:
+ if(enable)
+ {
+ pAgent->UpdateState(pAccessible);
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::DEFUNC);
+ // 8. label should have no FOCUSABLE state state, Firefox has READONLY state, we can also have.
+ if( getRole() != AccessibleRole::LABEL
+ && getRole() != AccessibleRole::SCROLL_BAR) //IAccessibility2 Implementation 2009
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::FOCUSABLE);
+ }
+ else
+ {
+ pAgent->UpdateState(pAccessible);
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::DEFUNC);
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::FOCUSABLE);
+ }
+ break;
+ case AccessibleStateType::ACTIVE:
+ // Only frames should be active
+ // no msaa state mapping
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * fire the MSAA state changed event
+ *
+ * @param state the state id
+ * @param set true if state is set, false if state is unset
+ */
+void AccComponentEventListener::fireStatePropertyChange(short state, bool set)
+{
+ if( set)
+ {
+ // new value
+ switch(state)
+ {
+ case AccessibleStateType::CHECKED:
+ case AccessibleStateType::INDETERMINATE:
+ pAgent->IncreaseState( pAccessible, state);
+ pAgent->UpdateAction( pAccessible );
+
+ if(!pAgent->IsSpecialToolboItem(pAccessible))
+ {
+ pAgent->NotifyAccEvent(UM_EVENT_STATE_CHECKED, pAccessible);
+ }
+ break;
+ case AccessibleStateType::PRESSED:
+ pAgent->IncreaseState( pAccessible, state);
+ pAgent->NotifyAccEvent(UM_EVENT_STATE_PRESSED, pAccessible);
+ break;
+ case AccessibleStateType::SELECTED:
+ pAgent->IncreaseState( pAccessible, state);
+ break;
+ case AccessibleStateType::ARMED:
+ pAgent->IncreaseState( pAccessible, state);
+ pAgent->NotifyAccEvent(UM_EVENT_STATE_ARMED, pAccessible);
+ break;
+ case AccessibleStateType::SHOWING:
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::DEFUNC);
+ // UNO !SHOWING == MSAA OFFSCREEN
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::SHOWING );
+ break;
+ case AccessibleStateType::VISIBLE:
+ // UNO !VISIBLE == MSAA INVISIBLE
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::VISIBLE );
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ // old value
+ switch(state)
+ {
+ case AccessibleStateType::CHECKED:
+ case AccessibleStateType::INDETERMINATE:
+ pAgent->DecreaseState( pAccessible, state );
+ pAgent->UpdateAction( pAccessible );
+
+ if(!pAgent->IsSpecialToolboItem(pAccessible))
+ {
+ pAgent->NotifyAccEvent(UM_EVENT_STATE_CHECKED, pAccessible);
+ }
+ break;
+ case AccessibleStateType::PRESSED:
+ pAgent->DecreaseState( pAccessible, state );
+ pAgent->NotifyAccEvent(UM_EVENT_STATE_PRESSED, pAccessible);
+ break;
+ case AccessibleStateType::SELECTED:
+ pAgent->DecreaseState( pAccessible, state );
+ //if the state is unset, no need to send MSAA SELECTION event
+ //pAgent->NotifyAccEvent(UM_EVENT_STATE_SELECTED, pAccessible);
+ break;
+ case AccessibleStateType::ARMED:
+ {
+ pAgent->DecreaseState( pAccessible, state);
+ //if the state is unset, no need to send MSAA MENU event
+ //pAgent->NotifyAccEvent(UM_EVENT_STATE_ARMED, pAccessible);
+ }
+ break;
+ case AccessibleStateType::SHOWING:
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::DEFUNC);
+ // UNO !SHOWING == MSAA OFFSCREEN
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::SHOWING );
+ break;
+ case AccessibleStateType::VISIBLE:
+ // UNO !VISIBLE == MSAA INVISIBLE
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::VISIBLE );
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+/**
+ * handle the focused event
+ *
+ * @param enable true if get focus, false if lose focus
+ */
+void AccComponentEventListener::fireStateFocusdChange(bool enable)
+{
+ if(enable)
+ {
+ if(getParentRole() != AccessibleRole::COMBO_BOX )
+ pAgent->NotifyAccEvent(UM_EVENT_STATE_FOCUSED, pAccessible);
+ }
+ else
+ {
+ //if lose focus, no need to send MSAA FOCUS event
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::FOCUSED);
+ }
+}
+
+void AccComponentEventListener::handleSelectionChangedEvent()
+{
+ pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED, pAccessible);
+}
+
+//add TEXT_SELECTION_CHANGED event
+void AccComponentEventListener::handleTextSelectionChangedEvent()
+{
+ pAgent->NotifyAccEvent(UM_EVENT_TEXT_SELECTION_CHANGED, pAccessible);
+}
diff --git a/winaccessibility/source/service/AccContainerEventListener.cxx b/winaccessibility/source/service/AccContainerEventListener.cxx
new file mode 100644
index 000000000000..f0a96c475947
--- /dev/null
+++ b/winaccessibility/source/service/AccContainerEventListener.cxx
@@ -0,0 +1,573 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#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 "AccContainerEventListener.hxx"
+#include "AccObjectManagerAgent.hxx"
+#include "unomsaaevent.hxx"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccContainerEventListener::AccContainerEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
+ :AccEventListener(pAcc, Agent)
+{
+}
+
+AccContainerEventListener::~AccContainerEventListener()
+{
+}
+
+/**
+ * Uno's event notifier when event is captured
+ *
+ * @param AccessibleEventObject the event object which contains information about event
+ */
+void AccContainerEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ short role = getRole();
+ switch (aEvent.EventId)
+ {
+ case AccessibleEventId::CHILD:
+ handleChildChangedEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ case AccessibleEventId::SELECTION_CHANGED:
+ handleSelectionChangedEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ case AccessibleEventId::INVALIDATE_ALL_CHILDREN:
+ handleAllChildrenChangedEvent();
+ break;
+ case AccessibleEventId::TEXT_CHANGED:
+ handleTextChangedEvent(aEvent.OldValue, aEvent.NewValue);
+ 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;
+ }
+}
+
+/**
+ * handle the VISIBLE_DATA_CHANGED event
+ */
+void AccContainerEventListener::handleVisibleDataChangedEvent()
+{
+ AccEventListener::handleVisibleDataChangedEvent();
+}
+
+/**
+ * handle the BOUNDRECT_CHANGED event
+ */
+void AccContainerEventListener::handleBoundrectChangedEvent()
+{
+ AccEventListener::handleBoundrectChangedEvent();
+}
+
+void AccContainerEventListener::handleStateChangedEvent(Any oldValue, Any newValue)
+{
+ short State;
+ if( newValue >>= State)
+ {
+ setComponentState( State,true);
+ }
+ else if (oldValue >>= State)
+ {
+ setComponentState( State,false);
+ }
+
+}
+
+/**
+ * handle the CHILD event
+ * @param oldValue the child to be deleted
+ * @param newValue the child to be added
+ */
+void AccContainerEventListener::handleChildChangedEvent(Any oldValue, Any newValue)
+{
+ Reference< XAccessible > xChild;
+ if( newValue >>= xChild)
+ {
+ //create a new child
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ //add this child
+
+ if(pAgent->InsertAccObj( pAcc,pAccessible))
+ {
+ //add all oldValue's existing children
+ pAgent->InsertChildrenAccObj(pAcc);
+ pAgent->NotifyAccEvent(UM_EVENT_CHILD_ADDED, pAcc);
+ }
+ }
+ else
+ {}
+ }
+ else if (oldValue >>= xChild)
+ {
+ //delete a existing child
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ pAgent->NotifyAccEvent(UM_EVENT_CHILD_REMOVED, pAcc);
+ //delete all oldValue's existing children
+ pAgent->DeleteChildrenAccObj( pAcc );
+ //delete this child
+ pAgent->DeleteAccObj( pAcc );
+
+ }
+ else
+ {}
+ }
+
+}
+
+/**
+ * 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(UM_EVENT_SELECTION_CHANGED,newValue))
+ {
+ return ;
+ }
+
+ //menu bar does not process selection change event,just same as word behavior
+ if(getRole()!=AccessibleRole::MENU_BAR)
+ pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED, pAccessible);
+}
+
+/**
+ * handle the INVALIDATE_ALL_CHILDREN event
+ */
+void AccContainerEventListener::handleAllChildrenChangedEvent()
+{
+ //TODO: update all the children
+ if( pAccessible )
+ {
+ //delete all oldValue's existing children
+ pAgent->DeleteChildrenAccObj( pAccessible );
+ //add all oldValue's existing children
+ pAgent->InsertChildrenAccObj( pAccessible );
+ pAgent->NotifyAccEvent(UM_EVENT_OBJECT_REORDER , pAccessible);
+ }
+}
+
+/**
+ * handle the TEXT_CHANGED event
+ */
+void AccContainerEventListener::handleTextChangedEvent(Any oldValue, Any newValue)
+{
+ pAgent->UpdateValue(pAccessible, newValue);
+ pAgent->NotifyAccEvent(UM_EVENT_OBJECT_TEXTCHANGE, pAccessible);
+}
+
+/**
+ * set the new state and fire the MSAA event
+ * @param state new state id
+ * @param enable true if state is set, false if state is unset
+ */
+void AccContainerEventListener::setComponentState(short state, bool enable )
+{
+ // only the following state can be fired state event.
+
+ switch (state)
+ {
+ case AccessibleStateType::SELECTED:
+ case AccessibleStateType::BUSY:
+ case AccessibleStateType::INDETERMINATE:
+ case AccessibleStateType::OFFSCREEN:
+ case AccessibleStateType::FOCUSABLE:
+ case AccessibleStateType::SHOWING:
+ case AccessibleStateType::VISIBLE:
+ fireStatePropertyChange(state, enable);
+ break;
+ case AccessibleStateType::FOCUSED:
+ fireStateFocusdChange(enable);
+ break;
+ case AccessibleStateType::ENABLED:
+ if(enable)
+ {
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::DEFUNC);
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::FOCUSABLE);
+ pAgent->UpdateState(pAccessible);
+
+ UpdateAllChildrenState(pAccessible);
+ }
+ else
+ {
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::DEFUNC);
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::FOCUSABLE);
+ pAgent->UpdateState(pAccessible);
+
+ UpdateAllChildrenState(pAccessible);
+ }
+ break;
+ case AccessibleStateType::ACTIVE:
+ // Only frames should be active
+ // no msaa state mapping
+ //for PAGE_TAB_LIST, there will be ACTIVE state, then it should be converted to FOCUSED event.
+ if(getRole() == AccessibleRole::PAGE_TAB_LIST)
+ {
+ if (!enable) /* get the active state */
+ {
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::FOCUSED);
+ }
+
+ else /* lose the active state */
+ {
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::FOCUSED);
+ }
+ }
+ break;
+
+ case AccessibleStateType::EXPANDED:
+ case AccessibleStateType::COLLAPSE:
+ case AccessibleStateType::CHECKED:
+ {
+ pAgent->UpdateState(pAccessible);
+ pAgent->NotifyAccEvent(UM_EVENT_STATE_BUSY, pAccessible);
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+/**
+ * fire the MSAA state changed event
+ * @param state the state id
+ * @param set true if state is set, false if state is unset
+ */
+void AccContainerEventListener::fireStatePropertyChange(short state, bool set)
+{
+ if( set )
+ {
+ // new value
+ switch(state)
+ {
+ case AccessibleStateType::SELECTED:
+ pAgent->IncreaseState( pAccessible, state);
+ break;
+ case AccessibleStateType::INDETERMINATE:
+ case AccessibleStateType::BUSY:
+ case AccessibleStateType::FOCUSABLE:
+ case AccessibleStateType::OFFSCREEN:
+ pAgent->IncreaseState( pAccessible, state);
+ pAgent->NotifyAccEvent(UM_EVENT_STATE_BUSY, pAccessible);
+ break;
+ case AccessibleStateType::SHOWING:
+ // UNO !SHOWING == MSAA OFFSCREEN
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::SHOWING );
+ break;
+ case AccessibleStateType::VISIBLE:
+ // UNO !VISIBLE == MSAA INVISIBLE
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::VISIBLE );
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ // old value
+ switch(state)
+ {
+ case AccessibleStateType::SELECTED:
+ pAgent->DecreaseState( pAccessible, state );
+ break;
+ case AccessibleStateType::BUSY:
+ case AccessibleStateType::INDETERMINATE:
+ case AccessibleStateType::FOCUSABLE:
+ case AccessibleStateType::OFFSCREEN:
+ pAgent->DecreaseState( pAccessible, state);
+ pAgent->NotifyAccEvent(UM_EVENT_STATE_BUSY, pAccessible);
+ break;
+ case AccessibleStateType::SHOWING:
+ // UNO !SHOWING == MSAA OFFSCREEN
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::SHOWING );
+ break;
+ case AccessibleStateType::VISIBLE:
+ // UNO !VISIBLE == MSAA INVISIBLE
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::VISIBLE );
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/**
+ * handle the focused event
+ * @param enable true if get focus, false if lose focus
+ */
+void AccContainerEventListener::fireStateFocusdChange(bool enable)
+{
+ if(enable)
+ {
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::FOCUSED);
+ //if the acc role is MENU_BAR, MSAA UM_EVENT_MENU_START event should be sent
+ //if the acc role is POPUP_MENU, MSAA UM_EVENT_MENUPOPUPSTART event should be sent
+ short role = getRole();
+ if(role == AccessibleRole::MENU_BAR)
+ {
+ pAgent->NotifyAccEvent(UM_EVENT_MENU_START, pAccessible);
+ }
+ else if (role == AccessibleRole::POPUP_MENU)
+ pAgent->NotifyAccEvent(UM_EVENT_MENUPOPUPSTART, pAccessible);
+ //Disable the focused event on option_pane and Panel.
+ //only disable option_pane for toolbar has panel to get focus
+ else if (role == AccessibleRole::PANEL || role == AccessibleRole::OPTION_PANE )
+ {
+ //don't send focused event on PANEL & OPTION_PANE if the parent is not toolbar
+ short parentRole = getParentRole();
+ if (parentRole == AccessibleRole::TOOL_BAR
+ || parentRole == AccessibleRole::SCROLL_PANE // sidebar
+ || parentRole == AccessibleRole::PANEL) // sidebar
+ pAgent->NotifyAccEvent(UM_EVENT_STATE_FOCUSED, pAccessible);
+ }
+ //to update ComboBox's description
+ else if (role == AccessibleRole::COMBO_BOX )
+ {
+ pAgent->UpdateDescription(pAccessible);
+ //for editable combobox, send focus event on only edit control,
+ bool bSendFocusOnCombobox = true;
+ //send focused event to the first text child
+ Reference<XAccessibleContext> mxContext(pAccessible->getAccessibleContext(),UNO_QUERY);
+ if(mxContext.is())
+ {
+ Reference<XAccessible> mxChild = mxContext->getAccessibleChild(0);
+ if(mxChild.is())
+ {
+ Reference<XAccessibleContext> mxChildContext(mxChild->getAccessibleContext(),UNO_QUERY);
+ short childrole = mxChildContext->getAccessibleRole();
+ if (childrole == AccessibleRole::TEXT)
+ {
+ if (IsEditable(mxChildContext))
+ {
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::FOCUSED);
+ pAgent->IncreaseState( mxChild.get(), AccessibleStateType::FOCUSED);
+ pAgent->NotifyAccEvent(UM_EVENT_STATE_FOCUSED, mxChild.get());
+ bSendFocusOnCombobox = false;
+ }
+ }
+ }
+ }
+ if (bSendFocusOnCombobox)
+ pAgent->NotifyAccEvent(UM_EVENT_STATE_FOCUSED, pAccessible);
+ }
+ else
+ pAgent->NotifyAccEvent(UM_EVENT_STATE_FOCUSED, pAccessible);
+ }
+ else
+ {
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::FOCUSED);
+ //if the acc role is MENU_BAR, MSAA UM_EVENT_MENU_END event should be sent
+ //if the acc role is POPUP_MENU, MSAA UM_EVENT_MENUPOPUPEND event should be sent
+ if(getRole() == AccessibleRole::MENU_BAR)
+ {
+ pAgent->NotifyAccEvent(UM_EVENT_MENU_END, pAccessible);
+ }
+ else if (getRole() == AccessibleRole::POPUP_MENU)
+ {
+ pAgent->NotifyAccEvent(UM_EVENT_MENUPOPUPEND, pAccessible);
+ }
+ }
+}
+
+/**
+ * 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 oldValue, Any newValue)
+{
+ pAgent->UpdateValue(pAccessible);
+ pAgent->NotifyAccEvent(UM_EVENT_OBJECT_VALUECHANGE, pAccessible);
+}
+
+bool AccContainerEventListener::IsEditable(Reference<XAccessibleContext> xContext)
+{
+ bool ret = false;
+ Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet();
+ if( !pRState.is() )
+ return false;
+
+ Sequence<short> pStates = pRState->getStates();
+ int count = pStates.getLength();
+ for( int iIndex = 0;iIndex < count;iIndex++ )
+ {
+ if(pStates[iIndex] == AccessibleStateType::EDITABLE)
+ return true;
+ }
+ return ret;
+}
+
+bool AccContainerEventListener::NotifyChildEvent(short nWinEvent,const Any &Value)
+{
+ Reference< XAccessible > xChild;
+ if(Value >>= xChild )
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ pAgent->NotifyAccEvent(nWinEvent, pAcc);
+ return true;
+ }
+ }
+ return false;
+}
+
+void AccContainerEventListener::handleSelectionChangedAddEvent(const Any& /*oldValue*/, const Any& newValue)
+{
+ if(NotifyChildEvent(UM_EVENT_SELECTION_CHANGED_ADD,newValue))
+ {
+ return ;
+ }
+ pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED_ADD,pAccessible);
+}
+void AccContainerEventListener::handleSelectionChangedRemoveEvent(const Any& /*oldValue*/, const Any& newValue)
+{
+ if(NotifyChildEvent(UM_EVENT_SELECTION_CHANGED_REMOVE,newValue))
+ {
+ return ;
+ }
+ pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED_REMOVE,pAccessible);
+}
+void AccContainerEventListener::handleSelectionChangedWithinEvent(const Any& /*oldValue*/, const Any& newValue)
+{
+ if(NotifyChildEvent(UM_EVENT_SELECTION_CHANGED_WITHIN,newValue))
+ {
+ return ;
+ }
+ pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED_WITHIN,pAccessible);
+}
+
+void SAL_CALL AccContainerEventListener::UpdateAllChildrenState( com::sun::star::accessibility::XAccessible* pXAccessible )
+{
+ Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pXAccessible->getAccessibleContext(),UNO_QUERY);
+ if(!xContext.is())
+ {
+ return;
+ }
+ com::sun::star::accessibility::XAccessibleContext* pAccessibleContext = xContext.get();
+ if(pAccessibleContext == NULL)
+ {
+ return;
+ }
+
+ if (pAgent && pAgent->IsStateManageDescendant(pXAccessible))
+ {
+ return;
+ }
+
+ int count = pAccessibleContext->getAccessibleChildCount();
+ for (int i=0;i<count;i++)
+ {
+ Reference<com::sun::star::accessibility::XAccessible> mxAccessible
+ = pAccessibleContext->getAccessibleChild(i);
+
+ com::sun::star::accessibility::XAccessible* mpAccessible = mxAccessible.get();
+ if(mpAccessible != NULL)
+ {
+ pAgent->UpdateState(mpAccessible);
+ UpdateAllChildrenState(mpAccessible);
+ }
+ }
+}
+
+
+void AccContainerEventListener::handlePageChangedEvent(const Any& /*oldValue*/, const Any& /*newValue*/)
+{
+ pAgent->NotifyAccEvent(UM_EVENT_OBJECT_PAGECHANGED, pAccessible);
+}
+
+void AccContainerEventListener::handleSectionChangedEvent(const Any& /*oldValue*/, const Any& /*newValue*/ )
+{
+ pAgent->NotifyAccEvent(UM_EVENT_SECTION_CHANGED, pAccessible);
+}
+
+void AccContainerEventListener::handleColumnChangedEvent(const Any& /*oldValue*/, const Any& /*newValue*/)
+{
+ pAgent->NotifyAccEvent(UM_EVENT_COLUMN_CHANGED, pAccessible);
+}
+
+//IAccessibility2 Implementation 2009-----
+void AccContainerEventListener::handleNameChangedEvent( Any name )
+{
+ if (getRole() == AccessibleRole::COMBO_BOX)
+ {
+ Reference<XAccessibleContext> mxContext(pAccessible->getAccessibleContext(),UNO_QUERY);
+ if(mxContext.is())
+ {
+ Reference<XAccessible> mxChild = mxContext->getAccessibleChild(0);
+ if(mxChild.is())
+ {
+ Reference<XAccessibleContext> mxChildContext(mxChild->getAccessibleContext(),UNO_QUERY);
+ short childrole = mxChildContext->getAccessibleRole();
+ if (childrole == AccessibleRole::TEXT)
+ {
+ pAgent->UpdateAccName(mxChild.get(), name);
+ }
+ }
+ }
+ }
+ AccEventListener::handleNameChangedEvent(name);
+}
+//-----IAccessibility2 Implementation 2009
diff --git a/winaccessibility/source/service/AccDescendantManagerEventListener.cxx b/winaccessibility/source/service/AccDescendantManagerEventListener.cxx
new file mode 100644
index 000000000000..97bd1b221655
--- /dev/null
+++ b/winaccessibility/source/service/AccDescendantManagerEventListener.cxx
@@ -0,0 +1,226 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#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 "AccDescendantManagerEventListener.hxx"
+#include "AccObjectManagerAgent.hxx"
+#include "unomsaaevent.hxx"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccDescendantManagerEventListener::AccDescendantManagerEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
+ :AccComponentEventListener(pAcc, Agent),
+ pActiveDescendant(NULL)
+{
+}
+
+AccDescendantManagerEventListener::~AccDescendantManagerEventListener()
+{
+}
+
+/**
+ * Uno's event notifier when event is captured
+ * @param AccessibleEventObject the event object which contains information about event
+ */
+void AccDescendantManagerEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ switch (aEvent.EventId)
+ {
+ case AccessibleEventId::SELECTION_CHANGED:
+ handleSelectionChangedEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ case AccessibleEventId::CHILD:
+ handleChildChangedEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ case AccessibleEventId::ACTIVE_DESCENDANT_CHANGED_NOFOCUS:
+ handleChildChangedNoFocusEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ case AccessibleEventId::SELECTION_CHANGED_ADD:
+ handleSelectionChangedAddEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ case AccessibleEventId::SELECTION_CHANGED_REMOVE:
+ handleSelectionChangedRemoveEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ case AccessibleEventId::SELECTION_CHANGED_WITHIN:
+ handleSelectionChangedWithinEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ default:
+ AccComponentEventListener::notifyEvent(aEvent);
+ break;
+ }
+}
+
+/**
+ * handle the CHILD event
+ * @param oldValue the child to be deleted
+ * @param newValue the child to be added
+ */
+void AccDescendantManagerEventListener::handleChildChangedEvent(Any oldValue, Any newValue)
+{
+
+ Reference< XAccessible > xChild;
+ if( newValue >>= xChild)
+ {
+ //create a new child
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ pAgent->InsertAccObj( pAcc,pAccessible);
+ pAgent->InsertChildrenAccObj(pAcc);
+
+ pAgent->NotifyAccEvent(UM_EVENT_CHILD_ADDED, pAcc);
+
+ }
+ else
+ {}
+ }
+
+ if (oldValue >>= xChild)
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+
+ pAgent->NotifyAccEvent(UM_EVENT_CHILD_REMOVED, pAcc);
+ pAgent->DeleteChildrenAccObj( pAcc );
+ pAgent->DeleteAccObj( pAcc );
+ }
+ else
+ {}
+ }
+
+}
+
+/**
+ * handle the SELECTION_CHANGED event
+ */
+void AccDescendantManagerEventListener::handleSelectionChangedEvent(Any oldValue, Any newValue)
+{
+ bool bSend =false;
+ Reference< XAccessible > xChild;
+ if(newValue >>= xChild )
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ //if the Role is the SC cell ,don't add the selected state.
+ if (pAgent->GetRole(pAcc) != AccessibleRole::TABLE_CELL)
+ {
+ pAgent->IncreaseState( pAcc, AccessibleStateType::SELECTED);
+ }
+
+ pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED, pAcc);
+ bSend=true;
+ }
+ }
+ if(oldValue >>= xChild )
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ pAgent->DecreaseState( pAcc, AccessibleStateType::SELECTED);
+ }
+ }
+ if (!bSend)
+ {
+ pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED, pAccessible);
+ }
+}
+
+
+void AccDescendantManagerEventListener::handleChildChangedNoFocusEvent(Any oldValue, Any newValue)
+{
+ Reference< XAccessible > xChild;
+ if(newValue >>= xChild )
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+
+ pAgent->InsertAccObj(pAcc,pAccessible);
+ pAgent->InsertChildrenAccObj(pAcc);
+
+ pActiveDescendant= pAcc;
+ }
+ }
+ if (oldValue >>= xChild)
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ pAgent->DeleteChildrenAccObj( pAcc );
+ pAgent->DeleteAccObj( pAcc );
+ }
+ }
+}
+
+bool AccDescendantManagerEventListener::NotifyChildEvent(short nWinEvent,const Any &Value)
+{
+ Reference< XAccessible > xChild;
+ if(Value >>= xChild )
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ pAgent->NotifyAccEvent(nWinEvent, pAcc);
+
+ if (pAgent && pAgent->IsStateManageDescendant(pAccessible) && ( nWinEvent == UM_EVENT_SELECTION_CHANGED_REMOVE) )
+ {
+ pAgent->DeleteAccObj( pAcc );
+ }
+ return true;
+ }
+ }
+ return false;
+}
+void AccDescendantManagerEventListener::handleSelectionChangedAddEvent(const Any& /*oldValue*/, const Any &newValue)
+{
+ if(NotifyChildEvent(UM_EVENT_SELECTION_CHANGED_ADD,newValue))
+ {
+ return ;
+ }
+ pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED_ADD,pAccessible);
+}
+void AccDescendantManagerEventListener::handleSelectionChangedRemoveEvent(const Any& /*oldValue*/, const Any &newValue)
+{
+ if(NotifyChildEvent(UM_EVENT_SELECTION_CHANGED_REMOVE,newValue))
+ {
+ return ;
+ }
+ pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED_REMOVE,pAccessible);
+}
+
+void AccDescendantManagerEventListener::handleSelectionChangedWithinEvent(const Any& /*oldValue*/, const Any &newValue)
+{
+ if(NotifyChildEvent(UM_EVENT_SELECTION_CHANGED_WITHIN,newValue))
+ {
+ return ;
+ }
+ pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED_WITHIN,pAccessible);
+}
+
diff --git a/winaccessibility/source/service/AccDialogEventListener.cxx b/winaccessibility/source/service/AccDialogEventListener.cxx
new file mode 100644
index 000000000000..6f78bf7d69a2
--- /dev/null
+++ b/winaccessibility/source/service/AccDialogEventListener.cxx
@@ -0,0 +1,150 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#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 "AccDialogEventListener.hxx"
+#include "AccObjectManagerAgent.hxx"
+#include "unomsaaevent.hxx"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccDialogEventListener::AccDialogEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
+ :AccEventListener(pAcc, Agent)
+{}
+AccDialogEventListener::~AccDialogEventListener()
+{
+}
+
+/**
+ * Uno's event notifier when event is captured
+ * @param AccessibleEventObject the event object which contains information about event
+ */
+void AccDialogEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ switch (aEvent.EventId)
+ {
+ case AccessibleEventId::CHILD:
+ handleChildChangedEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ case AccessibleEventId::VISIBLE_DATA_CHANGED:
+ handleVisibleDataChangedEvent();
+ break;
+ case AccessibleEventId::BOUNDRECT_CHANGED:
+ handleBoundrectChangedEvent();
+ break;
+ default:
+ AccEventListener::notifyEvent(aEvent);
+ break;
+ }
+}
+
+/**
+ * handle the VISIBLE_DATA_CHANGED event
+ */
+void AccDialogEventListener::handleVisibleDataChangedEvent()
+{
+ AccEventListener::handleVisibleDataChangedEvent();
+}
+
+/**
+ * handle the BOUNDRECT_CHANGED event
+ */
+void AccDialogEventListener::handleBoundrectChangedEvent()
+{
+ AccEventListener::handleBoundrectChangedEvent();
+}
+
+/**
+ * handle the CHILD event
+ * @param oldValue the child to be deleted
+ * @param newValue the child to be added
+ */
+void AccDialogEventListener::handleChildChangedEvent(Any oldValue, Any newValue)
+{
+ Reference< XAccessible > xChild;
+ if( newValue >>= xChild)
+ {
+ //create a new child
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ //add this child
+ pAgent->InsertAccObj( pAcc,pAccessible);
+ //add all oldValue's existing children
+ pAgent->InsertChildrenAccObj(pAcc);
+ pAgent->NotifyAccEvent(UM_EVENT_CHILD_ADDED, pAcc);
+ }
+ else
+ {}
+ }
+ else if (oldValue >>= xChild)
+ {
+ //delete a existing child
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ pAgent->NotifyAccEvent(UM_EVENT_CHILD_REMOVED, pAcc);
+ //delete all oldValue's existing children
+ pAgent->DeleteChildrenAccObj( pAcc );
+ //delete this child
+ pAgent->DeleteAccObj( pAcc );
+ }
+ else
+ {}
+ }
+
+}
+
+/**
+ * set the new state and fire the MSAA event
+ * @param state new state id
+ * @param enable true if state is set, false if state is unset
+ */
+void AccDialogEventListener::setComponentState(short state, bool enable )
+{
+ // only the following state can be fired state event.
+ switch (state)
+ {
+ case AccessibleStateType::ICONIFIED:
+ // no msaa state mapping
+ break;
+ case AccessibleStateType::VISIBLE:
+ // UNO !VISIBLE == MSAA INVISIBLE
+ if( enable )
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::VISIBLE );
+ else
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::VISIBLE );
+ break;
+ case AccessibleStateType::ACTIVE:
+ // Only frames should be active
+ // no msaa state mapping
+ break;
+ default:
+ break;
+ }
+}
diff --git a/winaccessibility/source/service/AccEventListener.cxx b/winaccessibility/source/service/AccEventListener.cxx
new file mode 100644
index 000000000000..1925b8746cd0
--- /dev/null
+++ b/winaccessibility/source/service/AccEventListener.cxx
@@ -0,0 +1,309 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#include <cppuhelper/bootstrap.hxx>
+#include <com/sun/star/bridge/XUnoUrlResolver.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <toolkit/awt/Vclxwindow.hxx>
+
+#ifndef _SV_SYSDATA_HXX
+#if defined( WIN ) || defined( WNT ) || defined( OS2 )
+typedef sal_Int32 HWND;
+#endif
+#endif
+#include "AccEventListener.hxx"
+#include "AccObjectManagerAgent.hxx"
+#include "unomsaaevent.hxx"
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
+#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
+
+#include <stdio.h>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+using namespace rtl;
+using namespace cppu;
+
+AccEventListener::AccEventListener(com::sun::star::accessibility::XAccessible* pAcc,
+ AccObjectManagerAgent* Agent)
+ :pAccessible(pAcc),
+ pAgent(Agent),
+ m_isDisposed(false),
+ m_refcount(0)
+{}
+
+AccEventListener::~AccEventListener()
+{
+}
+
+/**
+ * Uno's event notifier when event is captured
+ * @param AccessibleEventObject the event object which contains information about event
+ */
+void AccEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent )
+throw (::com::sun::star::uno::RuntimeException)
+{
+
+ switch (aEvent.EventId)
+ {
+ case AccessibleEventId::NAME_CHANGED:
+ handleNameChangedEvent(aEvent.NewValue);
+ break;
+ case AccessibleEventId::DESCRIPTION_CHANGED:
+ handleDescriptionChangedEvent(aEvent.NewValue);
+ break;
+ case AccessibleEventId::STATE_CHANGED:
+ handleStateChangedEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * handle the NAME_CHANGED event
+ * @param name the new name with changed.
+ */
+void AccEventListener::handleNameChangedEvent(Any name)
+{
+ if ( pAgent->IsTopWinAcc( pAccessible ) )
+ {
+ XAccessible* pAccDoc = pAgent->GetAccDocByAccTopWin( pAccessible );
+ if ( pAccDoc )
+ {
+ pAgent->UpdateAccName(pAccDoc);
+ pAgent->NotifyAccEvent(UM_EVENT_OBJECT_NAMECHANGE, pAccDoc);
+ }
+ }
+
+ pAgent->UpdateAccName(pAccessible, name);
+ pAgent->NotifyAccEvent(UM_EVENT_OBJECT_NAMECHANGE, pAccessible);
+}
+
+/**
+ * handle the DESCRIPTION_CHANGED event
+ * @param desc the new description
+ */
+void AccEventListener::handleDescriptionChangedEvent(Any desc)
+{
+ pAgent->UpdateDescription(pAccessible, desc);
+ pAgent->NotifyAccEvent(UM_EVENT_OBJECT_DESCRIPTIONCHANGE, pAccessible);
+}
+
+/**
+ * handle the BOUNDRECT_CHANGED event
+ */
+void AccEventListener::handleBoundrectChangedEvent()
+{
+ pAgent->UpdateLocation(pAccessible);
+ pAgent->NotifyAccEvent(UM_EVENT_BOUNDRECT_CHANGED, pAccessible);
+}
+
+/**
+ * handle the VISIBLE_DATA_CHANGED event
+ */
+void AccEventListener::handleVisibleDataChangedEvent()
+{
+ pAgent->UpdateValue(pAccessible);
+ pAgent->NotifyAccEvent(UM_EVENT_VISIBLE_DATA_CHANGED, pAccessible);
+}
+
+/**
+ * handle the STATE_CHANGED event
+ * @param oldValue the old state of the source of event
+ * @param newValue the new state of the source of event
+ */
+void AccEventListener::handleStateChangedEvent(Any oldValue, Any newValue)
+{
+ short newV, oldV;
+ if( newValue >>= newV)
+ {
+ setComponentState(newV, true);
+ }
+ else if (oldValue >>= oldV)
+ {
+ setComponentState(oldV, false);
+ }
+}
+
+/**
+ * set the new state and fire the MSAA event
+ * @param state new state id
+ * @param enable true if state is set, false if state is unset
+ */
+void AccEventListener::setComponentState(short state, bool enable )
+{
+ switch (state)
+ {
+ case AccessibleStateType::FOCUSED:
+ fireStateFocusdChange(enable);
+ break;
+ default:
+ fireStatePropertyChange(state, enable);
+ break;
+ }
+}
+
+/**
+ * handle the focused event
+ * @param enable true if get focus, false if lose focus
+ */
+void AccEventListener::fireStateFocusdChange(bool enable)
+{
+ if(enable)
+ {
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::FOCUSED);
+ pAgent->NotifyAccEvent(UM_EVENT_STATE_FOCUSED, pAccessible);
+ }
+ else
+ {
+ // no focus lost event in MSAA
+ }
+}
+
+
+/**
+ * fire the MSAA state changed event
+ * @param state the state id
+ * @param set true if state is set, false if state is unset
+ */
+void AccEventListener::fireStatePropertyChange(short state, bool set )
+{
+ if( set )
+ {
+ //get new state
+ }
+ else
+ {
+ //lose old state
+ }
+}
+
+/**
+ * get the role of accessible object which is observed
+ */
+short AccEventListener::getRole()
+{
+ Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
+ if(xContext.is())
+ {
+ return xContext->getAccessibleRole();
+ }
+ return -1;
+}
+
+/**
+ * get the role of accessible parent object which is observed
+ */
+short AccEventListener::getParentRole()
+{
+ if(pAccessible)
+ {
+ return pAgent->GetParentRole(pAccessible);
+ }
+ return -1;
+}
+/**
+ * remove the listener from accessible object
+ */
+void AccEventListener::removeMeFromBroadcaster()
+{
+ try
+ {
+ vos::OGuard aGuard(aRemoveMutex);
+ if(m_isDisposed)
+ return;
+ //get accessible context
+ Reference< XAccessibleContext > pRContext;
+ XAccessibleContext* pContext =NULL;
+
+ if( pAccessible == NULL)
+ {
+ return;
+ }
+ pRContext = pAccessible->getAccessibleContext();
+ if( !pRContext.is() )
+ {
+ return;
+ }
+
+ //get broadcaster from accessible component
+ Reference<XAccessibleComponent> xComponent(pRContext,UNO_QUERY);
+ if(!xComponent.is())
+ {
+ return;
+ }
+ Reference<XAccessibleEventBroadcaster> broadcaster(xComponent,UNO_QUERY);
+ XAccessibleEventBroadcaster* pBroadcaster = broadcaster.get();
+ if (pBroadcaster != NULL)
+ {
+ //remove the lister from accessible object
+ pBroadcaster->removeEventListener(this);
+ m_isDisposed = true;
+ pAgent->NotifyDestroy(pAccessible);
+ }
+ }
+ catch(...)
+ {
+ return;
+ }
+
+}
+
+/**
+ * this method is invoked before listener is disposed
+ */
+void AccEventListener::disposing( const ::com::sun::star::lang::EventObject& Source )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ removeMeFromBroadcaster();
+}
+
+//need to investigate further
+::com::sun::star::uno::Any SAL_CALL AccEventListener::queryInterface( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::uno::RuntimeException)
+{
+ if(aType.equals(::getCppuType( (Reference< com::sun::star::accessibility::XAccessibleEventListener> const *)0 ) ))
+ {
+ Reference< com::sun::star::accessibility::XAccessibleEventListener> xEventListener( static_cast< com::sun::star::accessibility::XAccessibleEventListener* >(this));
+ return makeAny(xEventListener);
+ }
+
+ return Any();
+}
+
+void AccEventListener::acquire( ) throw ()
+{
+ ::osl_incrementInterlockedCount( &m_refcount );
+}
+
+void AccEventListener::release() throw ()
+{
+ // thread-safe decrementation of reference count
+ if (0 == ::osl_decrementInterlockedCount( &m_refcount ))
+ {
+ delete this; // shutdown this object
+ }
+}
diff --git a/winaccessibility/source/service/AccFrameEventListener.cxx b/winaccessibility/source/service/AccFrameEventListener.cxx
new file mode 100644
index 000000000000..bec7cac44005
--- /dev/null
+++ b/winaccessibility/source/service/AccFrameEventListener.cxx
@@ -0,0 +1,173 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#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 "AccFrameEventListener.hxx"
+#include "AccObjectManagerAgent.hxx"
+#include "unomsaaevent.hxx"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+#include <vcl/window.hxx>
+#include <toolkit/awt/Vclxwindow.hxx>
+
+#ifndef _SV_SYSDATA_HXX
+#if defined( WIN ) || defined( WNT ) || defined( OS2 )
+typedef sal_Int32 HWND;
+typedef sal_Int32 HMENU;
+typedef sal_Int32 HDC;
+typedef void *PVOID;
+typedef PVOID HANDLE;
+typedef HANDLE HFONT;
+#endif
+#include <vcl/sysdata.hxx>
+#endif
+
+
+AccFrameEventListener::AccFrameEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
+ :AccEventListener(pAcc, Agent)
+{
+}
+
+AccFrameEventListener::~AccFrameEventListener()
+{
+}
+
+/**
+ * Uno's event notifier when event is captured
+ * @param AccessibleEventObject the event object which contains information about event
+ */
+void AccFrameEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ switch (aEvent.EventId)
+ {
+ case AccessibleEventId::CHILD:
+ handleChildChangedEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ case AccessibleEventId::VISIBLE_DATA_CHANGED:
+ handleVisibleDataChangedEvent();
+ break;
+ case AccessibleEventId::BOUNDRECT_CHANGED:
+ handleBoundrectChangedEvent();
+ break;
+ default:
+ AccEventListener::notifyEvent(aEvent);
+ break;
+ }
+}
+
+/**
+ * handle the VISIBLE_DATA_CHANGED event
+ */
+void AccFrameEventListener::handleVisibleDataChangedEvent()
+{
+ AccEventListener::handleVisibleDataChangedEvent();
+}
+
+/**
+ * handle the BOUNDRECT_CHANGED event
+ */
+void AccFrameEventListener::handleBoundrectChangedEvent()
+{
+ AccEventListener::handleBoundrectChangedEvent();
+}
+
+/**
+ * handle the CHILD event
+ * @param oldValue the child to be deleted
+ * @param newValue the child to be added
+ */
+void AccFrameEventListener::handleChildChangedEvent(Any oldValue, Any newValue)
+{
+ Reference< XAccessible > xChild;
+ if( newValue >>= xChild)
+ {
+ //create a new child
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+
+ VCLXWindow* pvclwindow = (VCLXWindow*)pAccessible;
+ Window* window = pvclwindow->GetWindow();
+ const SystemEnvData* systemdata=window->GetSystemData();
+
+ //add this child
+ pAgent->InsertAccObj( pAcc,pAccessible,(HWND)systemdata->hWnd);
+ //add all oldValue's existing children
+ pAgent->InsertChildrenAccObj(pAcc);
+ pAgent->NotifyAccEvent(UM_EVENT_CHILD_ADDED, pAcc);
+ }
+ else
+ {}
+ }
+ else if (oldValue >>= xChild)
+ {
+ //delete a existing child
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ pAgent->NotifyAccEvent(UM_EVENT_CHILD_REMOVED, pAcc);
+ //delete all oldValue's existing children
+ pAgent->DeleteChildrenAccObj( pAcc );
+ //delete this child
+ pAgent->DeleteAccObj( pAcc );
+ }
+ else
+ {}
+ }
+
+}
+
+/**
+ * set the new state and fire the MSAA event
+ * @param state new state id
+ * @param enable true if state is set, false if state is unset
+ */
+void AccFrameEventListener::setComponentState(short state, bool enable )
+{
+ // only the following state can be fired state event.
+ switch (state)
+ {
+ case AccessibleStateType::ICONIFIED:
+ // no msaa state
+ break;
+ case AccessibleStateType::VISIBLE:
+ // UNO !VISIBLE == MSAA INVISIBLE
+ if( enable )
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::VISIBLE );
+ else
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::VISIBLE );
+ break;
+ case AccessibleStateType::ACTIVE:
+ // Only frames should be active
+ // no msaa state mapping
+ break;
+ default:
+ break;
+ }
+}
diff --git a/winaccessibility/source/service/AccListEventListener.cxx b/winaccessibility/source/service/AccListEventListener.cxx
new file mode 100644
index 000000000000..4b79a76155fc
--- /dev/null
+++ b/winaccessibility/source/service/AccListEventListener.cxx
@@ -0,0 +1,123 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#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 "AccListEventListener.hxx"
+#include "AccObjectManagerAgent.hxx"
+#include "unomsaaevent.hxx"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccListEventListener::AccListEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
+ :AccDescendantManagerEventListener(pAcc, Agent),
+ shouldDeleteChild(true)
+{
+}
+
+AccListEventListener::~AccListEventListener()
+{
+}
+
+/**
+ * Uno's event notifier when event is captured
+ * @param AccessibleEventObject the event object which contains information about event
+ */
+void AccListEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException)
+{
+ 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 save 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
+ sal_Bool bHasCache = pAgent->InsertAccObj(pAcc,pAccessible);
+ if (!bHasCache)
+ {
+ pAgent->UpdateState(pAcc);
+ }
+
+ pAgent->IncreaseState( pAcc, AccessibleStateType::FOCUSED);
+
+ pAgent->NotifyAccEvent(UM_EVENT_ACTIVE_DESCENDANT_CHANGED, pAcc);
+ pActiveDescendant= pAcc;
+ }
+ }
+ if (oldValue >>= xChild)
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ pAgent->DeleteAccObj( pAcc );
+ }
+ }
+}
+
+/**
+ * handle the VALUE_CHANGED event
+ *
+ * @param oldValue the old value of the source of event
+ * @param newValue the new value of the source of event
+ */
+void AccListEventListener::handleValueChangedEvent(Any oldValue, Any newValue)
+{
+ //to enable value changed event
+ if(getParentRole() == AccessibleRole::COMBO_BOX)
+ {
+ XAccessible* pParentAcc = pAgent->GetParentXAccessible(pAccessible);
+ pAgent->UpdateValue(pParentAcc);
+ pAgent->NotifyAccEvent(UM_EVENT_OBJECT_VALUECHANGE, pParentAcc);
+ }
+}
diff --git a/winaccessibility/source/service/AccMenuEventListener.cxx b/winaccessibility/source/service/AccMenuEventListener.cxx
new file mode 100644
index 000000000000..342d5335de85
--- /dev/null
+++ b/winaccessibility/source/service/AccMenuEventListener.cxx
@@ -0,0 +1,151 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#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 "AccMenuEventListener.hxx"
+#include "AccObjectManagerAgent.hxx"
+#include "unomsaaevent.hxx"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccMenuEventListener::AccMenuEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
+ :AccComponentEventListener(pAcc, Agent)
+{}
+AccMenuEventListener::~AccMenuEventListener()
+{
+}
+
+/**
+ * Uno's event notifier when event is captured
+ * @param AccessibleEventObject the event object which contains information about event
+ */
+void AccMenuEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ switch (aEvent.EventId)
+ {
+ case AccessibleEventId::CHILD:
+ handleChildChangedEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ case AccessibleEventId::SELECTION_CHANGED:
+ //don't need to process anything,just same as word behavior
+ //handleSelectionChangedEvent();
+ break;
+ default:
+ AccComponentEventListener::notifyEvent(aEvent);
+ break;
+ }
+}
+
+/**
+ * handle the CHILD event
+ * @param oldValue the child to be deleted
+ * @param newValue the child to be added
+ */
+void AccMenuEventListener::handleChildChangedEvent(Any oldValue, Any newValue)
+{
+
+ Reference< XAccessible > xChild;
+ if( newValue >>= xChild)
+ {
+ //create a new child
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ //add this child
+ pAgent->InsertAccObj( pAcc,pAccessible);
+ //add all oldValue's existing children
+ pAgent->InsertChildrenAccObj(pAcc);
+ pAgent->NotifyAccEvent(UM_EVENT_CHILD_ADDED, pAcc);
+ }
+ else
+ {}
+ }
+ else if (oldValue >>= xChild)
+ {
+ //delete an existing child
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ pAgent->NotifyAccEvent(UM_EVENT_CHILD_REMOVED, pAcc);
+ //delete all oldValue's existing children
+ pAgent->DeleteChildrenAccObj( pAcc );
+ //delete this child
+ pAgent->DeleteAccObj( pAcc );
+ }
+ else
+ {}
+ }
+
+}
+
+/**
+ * handle the SELECTION_CHANGED event
+ */
+void AccMenuEventListener::handleSelectionChangedEvent()
+{
+ pAgent->NotifyAccEvent(UM_EVENT_SELECTION_CHANGED, pAccessible);
+}
+
+/**
+ * handle the Menu_popup event
+ */
+void AccMenuEventListener::fireStatePropertyChange(short state, bool set)
+{
+ if( set )
+ {
+ // new value
+ switch(state)
+ {
+ //for sub menu is popup, there is a menu selected event.
+ case AccessibleStateType::SELECTED:
+ pAgent->IncreaseState( pAccessible, state);
+
+ pAgent->UpdateChildState(pAccessible);
+ break;
+ default:
+ AccComponentEventListener::fireStatePropertyChange(state, set
+ );
+ break;
+ }
+ }
+ else
+ {
+ switch(state)
+ {
+ //for sub menu is popup, there is a menu selected event.
+ case AccessibleStateType::SELECTED:
+ pAgent->DecreaseState( pAccessible, state );
+
+ break;
+ default:
+ AccComponentEventListener::fireStatePropertyChange(state, set
+ );
+ break;
+ }
+ }
+}
diff --git a/winaccessibility/source/service/AccObject.cxx b/winaccessibility/source/service/AccObject.cxx
new file mode 100644
index 000000000000..c73ce4a7f0d2
--- /dev/null
+++ b/winaccessibility/source/service/AccObject.cxx
@@ -0,0 +1,1109 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#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 <stdlib.h>
+#include <memory.h>
+#include <stdio.h>
+#include <memory.h>
+#include <algorithm>
+#include <assert.h>
+
+#include "AccObject.hxx"
+#include "AccEventListener.hxx"
+#include "UAccCOM_i.c"
+#include "AccResource.hxx"
+
+#include "act.hxx"
+
+using namespace std;
+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;
+
+
+/**
+ * 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* listener) :
+ m_pIMAcc (NULL),
+ m_resID (NULL),
+ m_pParantID (NULL),
+ m_pParentObj(NULL),
+ m_accListener (listener),
+ m_bShouldDestroy(sal_False),
+ m_xAccRef( pAcc )
+{
+ sal_Bool bRet = ImplInitilizeCreateObj();
+
+ m_xAccContextRef = m_xAccRef->getAccessibleContext();
+ m_xAccActionRef = Reference< XAccessibleAction > (m_xAccContextRef,UNO_QUERY);
+ m_accRole = m_xAccContextRef -> getAccessibleRole();
+ if( m_pIMAcc )
+ {
+ m_pIMAcc->SetXAccessible((long) m_xAccRef.get());
+ m_pIMAcc->Put_XAccAgent((long)pAgent);
+ m_pIMAcc->SetDefaultAction((long)m_xAccActionRef.get());
+ }
+}
+/**
+ * Destructor.
+ * @param
+ * @return
+ */
+AccObject::~AccObject()
+{
+ m_pIMAcc = NULL;
+ m_xAccRef = NULL;
+ m_xAccActionRef = NULL;
+ m_xAccContextRef = NULL;
+}
+
+
+
+/**
+ * Insert a child element.
+ * @param pChild Child element that should be inserted into child list.
+ * @param pos Insert postion.
+ * @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
+ {
+ std::vector<AccObject*>::iterator 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 postion.
+ * @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(NULL);
+ }
+}
+
+/**
+ * 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.
+ */
+sal_Bool AccObject::ImplInitilizeCreateObj()
+{
+ ActivateActContext();
+ HRESULT hr = CoCreateInstance( CLSID_MAccessible, NULL, CLSCTX_ALL ,
+ IID_IMAccessible,
+ (void **)&m_pIMAcc);
+ DeactivateActContext();
+
+ if ( S_OK != hr )
+ {
+ return sal_False;
+ }
+
+ return sal_True;
+}
+
+/**
+ * Update name property to com object.
+ * @param
+ * @return
+ */
+void AccObject::UpdateName( )
+{
+ if (!m_pIMAcc)
+ {
+ return;
+ }
+
+ if( ( TEXT_FRAME == m_accRole ) && ( m_pParentObj !=NULL )&& ( SCROLL_PANE == m_pParentObj -> m_accRole ) )
+ m_pIMAcc->Put_XAccName( m_pParentObj->m_xAccContextRef->getAccessibleName().getStr() );
+ //IAccessibility2 Implementation 2009-----
+ if ( PARAGRAPH == m_accRole)
+ {
+ ::rtl::OUString emptyStr = ::rtl::OUString::createFromAscii("");
+ m_pIMAcc->Put_XAccName(emptyStr.getStr());
+ }
+ //-----IAccessibility2 Implementation 2009
+ else
+ m_pIMAcc->Put_XAccName(m_xAccContextRef->getAccessibleName().getStr());
+
+ return ;
+}
+/**
+ * Update description property to com object.
+ * no content for update description
+ * @param
+ * @return
+ */
+void AccObject::UpdateDescription()
+{
+ if (!m_pIMAcc)
+ {
+ return;
+ }
+
+ m_pIMAcc->Put_XAccDescription(m_xAccContextRef->getAccessibleDescription().getStr());
+ return ;
+}
+
+/**
+ * Update default action property to com object.
+ * @param
+ * @return
+ */
+void AccObject::UpdateAction()
+{
+ m_xAccActionRef = Reference< XAccessibleAction > (m_xAccContextRef,UNO_QUERY);
+
+ if( m_xAccActionRef.is() && m_pIMAcc )
+ {
+ if( m_xAccActionRef->getAccessibleActionCount() > 0 )
+ {
+ UpdateDefaultAction( );
+ m_pIMAcc->SetDefaultAction((long)m_xAccActionRef.get());
+ }
+ }
+}
+
+/**
+ * Update value property to com object.
+ * @param
+ * @return
+ */
+void AccObject::UpdateValue()
+{
+ if( NULL == m_pIMAcc || !m_xAccContextRef.is() )
+ {
+ assert(false);
+ return ;
+ }
+
+ Reference< XAccessibleValue > pRValue(m_xAccContextRef.get(),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( m_xAccActionRef->getAccessibleActionDescription((sal_Int32)0).getStr() );
+ return;
+ }
+}
+
+/**
+ * Set value property via pAny.
+ * @param pAny New value.
+ * @return
+ */
+void AccObject::SetValue( Any pAny )
+{
+ unsigned short pUNumberString[100];
+ memset( pUNumberString, 0 , sizeof( pUNumberString) );
+
+ if( NULL == m_pIMAcc || !m_xAccContextRef.is() )
+ {
+ assert(false);
+ return ;
+ }
+ Reference< XAccessibleText > pRText(m_xAccContextRef,UNO_QUERY);
+ ::rtl::OUString val;
+ int index = 0 ;
+ 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:
+
+ if(pRText.get())
+ {
+ val = pRText->getText();
+ }
+ m_pIMAcc->Put_XAccValue( val.getStr() );
+ break;
+ case TREE_ITEM:
+ //IAccessibility2 Implementation 2009-----
+ //case CHECK_BOX: //Commented by Li Xing to disable the value for general checkbox
+ case COMBO_BOX:
+ case TABLE_CELL:
+ case NOTE:
+ case SCROLL_BAR:
+ m_pIMAcc->Put_XAccValue( GetMAccessibleValueFromAny(pAny).getStr() );
+ break ;
+ // Added by Li Xing, only the checkbox in tree should have the value.
+ case CHECK_BOX:
+ if( ( m_pParentObj !=NULL ) && (TREE == m_pParentObj->m_accRole || TREE_ITEM == m_pParentObj->m_accRole ))
+ m_pIMAcc->Put_XAccValue( GetMAccessibleValueFromAny(pAny).getStr() );
+ //-----IAccessibility2 Implementation 2009
+ break;
+ default:
+ break;
+ }
+
+ return;
+
+
+}
+::rtl::OUString AccObject::GetMAccessibleValueFromAny(Any pAny)
+{
+ ::rtl::OUString strValue;
+
+ if(NULL == m_pIMAcc)
+ return strValue;
+
+ if(pAny.getValueType() == getCppuType( (sal_uInt16 *)0 ) )
+ {
+ sal_uInt16 val;
+ if (pAny >>= val)
+ {
+ strValue=::rtl::OUString::valueOf((sal_Int32)val);
+
+ }
+ }
+ else if(pAny.getValueType() == getCppuType( (::rtl::OUString *)0 ) )
+ {
+
+ pAny >>= strValue ;
+
+ }
+ else if(pAny.getValueType() == getCppuType( (Sequence< ::rtl::OUString > *)0 ) )
+ {
+ Sequence< ::rtl::OUString > val;
+ if (pAny >>= val)
+ {
+
+ int count = val.getLength();
+
+ for( int iIndex = 0;iIndex < count;iIndex++ )
+ {
+ strValue += val[iIndex];
+ }
+
+ }
+ }
+ else if(pAny.getValueType() == getCppuType( (double *)0 ) )
+ {
+ double val;
+ if (pAny >>= val)
+ {
+ strValue=::rtl::OUString::valueOf(val);
+ }
+ }
+ else if(pAny.getValueType() == getCppuType( (sal_Int32 *)0 ) )
+ {
+ sal_Int32 val;
+ if (pAny >>= val)
+ {
+ strValue=::rtl::OUString::valueOf(val);
+ }
+ }
+ else if (pAny.getValueType() == getCppuType( (com::sun::star::accessibility::TextSegment *)0 ) )
+ {
+ com::sun::star::accessibility::TextSegment val;
+ if (pAny >>= val)
+ {
+ ::rtl::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( NULL == m_pIMAcc )
+ return ;
+
+ m_pIMAcc->Put_XAccName( GetMAccessibleValueFromAny(pAny).getStr() );
+
+}
+
+/**
+ * Set description property via pAny.
+ * @param pAny New accessible description.
+ * @return
+ */
+void AccObject::SetDescription( Any pAny )
+{
+ if( NULL == m_pIMAcc )
+ return ;
+ m_pIMAcc->Put_XAccDescription( GetMAccessibleValueFromAny(pAny).getStr() );
+}
+
+/**
+ * Set role property via pAny
+ * @param Role New accessible role.
+ * @return
+ */
+void AccObject::SetRole( short Role )
+{
+ if( NULL == m_pIMAcc )
+ return ;
+ m_pIMAcc->Put_XAccRole( Role );
+}
+
+/**
+* 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 = sal_True;
+ sal_Bool isExpandable = sal_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( NULL == 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 !=NULL ) && (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( NULL == 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 NULL;
+}
+/**
+ * update action desciption desc
+ * @param
+ * @return
+ */
+void AccObject::UpdateActionDesc()
+{
+ if (!m_pIMAcc)
+ {
+ return;
+ }
+
+ ::rtl::OUString pXString = m_xAccContextRef->getAccessibleDescription();
+ m_pIMAcc->Put_XAccDescription(pXString.getStr());
+ 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))
+ {
+ pXString = m_xAccActionRef->getAccessibleActionDescription( 0 );
+ //Solution:If string length is more than zero,action will will be set.
+ if( pXString.getLength() > 0)
+ m_pIMAcc->Put_ActionDescription( pXString.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 );
+ short iRoleIndex = pContext->getAccessibleRole();
+ if (( 0 <= iRoleIndex) && ( iRoleIndex <= (sizeof(ROLE_TABLE)/(sizeof(short)*2))))
+ {
+ 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(0L);
+
+ if ( m_accRole == POPUP_MENU )
+ {
+ return;
+ }
+
+ Sequence<short> pStates = pRState->getStates();
+ int count = pStates.getLength();
+
+ sal_Bool isEnable = sal_False;
+ sal_Bool isShowing = sal_False;
+ sal_Bool isEditable = sal_False;
+ sal_Bool isVisible = sal_False;
+ sal_Bool isFocusable = sal_False;
+
+ for( int iIndex = 0;iIndex < count;iIndex++ )
+ {
+ if( pStates[iIndex] == ENABLED )
+ isEnable = sal_True;
+ else if( pStates[iIndex] == SHOWING)
+ isShowing = sal_True;
+ else if( pStates[iIndex] == VISIBLE)
+ isVisible = sal_True;
+ else if( pStates[iIndex] == EDITABLE )
+ isEditable = sal_True;
+ else if (pStates[iIndex] == FOCUSABLE)
+ isFocusable = sal_True;
+ IncreaseState( pStates[iIndex]);
+ }
+ sal_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;
+
+ if( m_pIMAcc )
+ {
+ switch(m_accRole)
+ {
+ case LABEL:
+ 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 == STATUS_BAR || Role == TOOL_TIP))
+ {
+ if( SEPARATOR == Role )
+ {
+ if( ( m_pParentObj != NULL ) && ( 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 );
+ sal_Bool isDecreaseFocusable = sal_False;
+ 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 != NULL )&& (TOOL_BAR == m_pParentObj->m_accRole ) )
+ IncreaseState( FOCUSABLE );
+ else
+ DecreaseState( FOCUSABLE );
+ }
+ else
+ DecreaseState( FOCUSABLE );
+ }
+ else if( isShowing || isVisible )
+ {
+ IncreaseState( FOCUSABLE );
+ }
+ }
+
+ if( m_pIMAcc )
+ {
+ 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() )
+ {
+ ::com::sun::star::awt::Point pCPoint = pRComponent->getLocationOnScreen();
+ ::com::sun::star::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.
+ */
+sal_Bool AccObject:: UpdateAccessibleInfoFromUnoToMSAA ( )
+{
+ if( NULL == m_pIMAcc || !m_xAccContextRef.is() )
+ {
+ assert(false);
+ return sal_False;
+ }
+
+ UpdateName();
+
+ UpdateValue();
+
+ UpdateActionDesc();
+
+ UpdateRole();
+
+ UpdateLocation();
+
+ UpdateState();
+
+ return sal_True;
+}
+
+/*
+ * Add a child selected element.
+ * @param pAccObj Child object pointer.
+ * @return
+ */
+void AccObject::AddSelect( long index, AccObject* accObj)
+{
+ m_selectionList.insert(IAccSelectionList::value_type(index,accObj));
+}
+
+IAccSelectionList& AccObject::GetSelection()
+{
+ return m_selectionList;
+}
+
+
+/**
+ * Set self to focus object in parant 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 parant 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 = sal_False;
+ *isExpandable = sal_False;
+
+ if( !m_xAccContextRef.is() )
+ {
+ return;
+ }
+ Reference< XAccessibleStateSet > pRState = m_xAccContextRef->getAccessibleStateSet();
+ if( !pRState.is() )
+ {
+ return;
+ }
+
+ Sequence<short> pStates = pRState->getStates();
+ int count = pStates.getLength();
+
+ for( int iIndex = 0;iIndex < count;iIndex++ )
+ {
+ if( EXPANDED == pStates[iIndex] )
+ {
+ *isExpanded = sal_True;
+ }
+ else if( EXPANDABLE == pStates[iIndex] )
+ {
+ *isExpandable = sal_True;
+ }
+ }
+}
+
+void AccObject::NotifyDestroy(sal_Bool ifDelete)
+{
+ m_bShouldDestroy=ifDelete;
+ if(m_pIMAcc)
+ m_pIMAcc->NotifyDestroy(m_bShouldDestroy);
+}
+
+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(NULL);
+ }
+ }
+}
+//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 > AccObject::GetXAccessible()
+{
+ return m_xAccRef;
+}
+
+void AccObject::SetParentHWND(HWND hWnd)
+{
+ m_pParantID = hWnd;
+}
+void AccObject::SetListener( AccEventListener* Listener )
+{
+ m_accListener = Listener;
+}
+AccEventListener* AccObject::getListener()
+{
+ return m_accListener;
+}
+
+long AccObject::GetResID()
+{
+ return m_resID;
+}
+
+HWND AccObject::GetParentHWND()
+{
+ return m_pParantID;
+}
+
+AccObject* AccObject::GetParentObj()
+{
+ return m_pParentObj;
+}
+sal_Bool AccObject::ifShouldDestroy()
+{
+ return m_bShouldDestroy;
+}
diff --git a/winaccessibility/source/service/AccObjectContainerEventListener.cxx b/winaccessibility/source/service/AccObjectContainerEventListener.cxx
new file mode 100644
index 000000000000..8aea67670426
--- /dev/null
+++ b/winaccessibility/source/service/AccObjectContainerEventListener.cxx
@@ -0,0 +1,72 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// AccObjectContainerEventListener.cpp: implementation of the AccContainerEventListener class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
+
+#include "AccObjectContainerEventListener.hxx"
+#include "AccObjectManagerAgent.hxx"
+#include "unomsaaevent.hxx"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccObjectContainerEventListener::AccObjectContainerEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
+ :AccContainerEventListener(pAcc, Agent)
+{}
+AccObjectContainerEventListener::~AccObjectContainerEventListener()
+{
+}
+
+/**
+ * handle the STATE_CHANGED event
+ */
+void AccObjectContainerEventListener::handleStateChangedEvent(Any oldValue, Any newValue)
+{
+ //set the accessible name before process for there is no NAME_CHANGED event when change
+ //the text in drawing objects.
+ short newV;
+ if( newValue >>= newV)
+ {
+ if (newV == AccessibleStateType::FOCUSED)
+ {
+ pAgent->UpdateAccName(pAccessible);
+
+ pAgent->UpdateDescription(pAccessible);
+ }
+ }
+ AccContainerEventListener::handleStateChangedEvent(oldValue, newValue);
+}
+/**
+ * handle the VISIBLE_DATA_CHANGED event
+ * For SHAPES, the visiable_data_changed event should be mapped to LOCATION_CHANGED event
+ */
+void AccObjectContainerEventListener::handleVisibleDataChangedEvent()
+{
+ AccContainerEventListener::handleBoundrectChangedEvent();
+}
diff --git a/winaccessibility/source/service/AccObjectManagerAgent.cxx b/winaccessibility/source/service/AccObjectManagerAgent.cxx
new file mode 100644
index 000000000000..1b29480dd04b
--- /dev/null
+++ b/winaccessibility/source/service/AccObjectManagerAgent.cxx
@@ -0,0 +1,386 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#include "AccObjectManagerAgent.hxx"
+#include "AccObjectWinManager.hxx"
+
+#include "UAccCOM2.h"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+/**
+ * Construction/Destruction.
+ * @param
+ * @return
+ */
+AccObjectManagerAgent::AccObjectManagerAgent():
+ pWinManager(NULL)
+{
+ if( pWinManager == NULL )
+ {
+ pWinManager = AccObjectWinManager::CreateAccObjectWinManagerInstance(this);
+ }
+}
+
+AccObjectManagerAgent::~AccObjectManagerAgent()
+{
+ delete pWinManager;
+ pWinManager = NULL;
+}
+
+/**
+ * Interface of updating MSAA name when UNO name_changed event occurs.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @return
+ */
+void AccObjectManagerAgent::UpdateAccName( XAccessible* pXAcc )
+{
+ if( pWinManager )
+ pWinManager->UpdateAccName( pXAcc );
+}
+
+/**
+ * Interface of updating MSAA name when UNO action changed event occurs.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @return
+ */
+void AccObjectManagerAgent::UpdateAction( XAccessible* pXAcc )
+{
+ if( pWinManager )
+ pWinManager->UpdateAction( pXAcc );
+}
+
+/**
+ * Interface of updating MSAA value when UNO value_changed event occurs.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @param pAny New value.
+ * @return
+ */
+void AccObjectManagerAgent::UpdateValue( XAccessible* pXAcc, Any pAny )
+{
+ if( pWinManager )
+ pWinManager->SetValue( pXAcc, pAny );
+}
+
+/**
+ * Interface of updating MSAA value when UNO value_changed event occurs.If we can not
+ * find new value,we'll get new value from pXAcc to update com value.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @return
+ */
+void AccObjectManagerAgent::UpdateValue( XAccessible* pXAcc )
+{
+ if( pWinManager )
+ pWinManager->UpdateValue( pXAcc );
+}
+
+/**
+ * Interface of updating MSAA name when UNO name_changed event occurs.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @param newName New UNO accessible name.
+ * @return
+ */
+void AccObjectManagerAgent::UpdateAccName( XAccessible* pXAcc, Any newName)
+{
+ if( pWinManager )
+ pWinManager->SetAccName( pXAcc, newName );
+}
+
+
+/**
+ * Interface of updating MSAA location when UNO location_changed event occurs.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @param pXAcc Uno The top position of new location.
+ * @param pXAcc Uno The left position of new location.
+ * @param pXAcc Uno The width of new location.
+ * @param pXAcc Uno The width of new location.
+ * @return
+ */
+void AccObjectManagerAgent::UpdateLocation( XAccessible* /* pXAcc */, long /*top*/, long /*left*/, long /*width*/, long /*height*/ )
+{
+#ifdef _IMPL_WIN
+ if( pWinManager )
+ pWinManager->SetLocation( pXAcc, top, left, width, height );
+#endif
+}
+
+/**
+ * Interface of updating MSAA name when UNO description_changed event occurs.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @param newDesc New UNO accessible description.
+ * @return
+ */
+void AccObjectManagerAgent::UpdateDescription( XAccessible* pXAcc, Any newDesc )
+{
+ if( pWinManager )
+ pWinManager->SetDescription( pXAcc, newDesc );
+}
+
+/**
+ * When a new UNO XAccessible object is found by listener,we'll create a corresponding
+ * com object and insert it to our manager list.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @param pWnd The top window handle containing control.
+ * @return If the method is correctly processed.
+ */
+unsigned char AccObjectManagerAgent::InsertAccObj( XAccessible* pXAcc,XAccessible* pParentXAcc,long pWnd)
+{
+ if( pWinManager )
+ return (unsigned char)pWinManager->InsertAccObj( pXAcc, pParentXAcc,HWND((void*)pWnd) );
+
+ return sal_False;
+}
+
+/**
+ * save the pair <topwindowhandle, XAccessible>
+ * @param hWnd, top window handle
+ * @param pXAcc XAccessible interface for top window
+ * @return void
+ */
+void AccObjectManagerAgent::SaveTopWindowHandle(long hWnd, com::sun::star::accessibility::XAccessible* pXAcc)
+{
+ if( pWinManager )
+ pWinManager->SaveTopWindowHandle( HWND((void*)hWnd), pXAcc );
+}
+
+
+/**
+ * When a UNO XAccessible object's new children are found by listener,we'll create
+ * corresponding com objects and insert them to our manager list.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @param pWnd The top window handle containing control.
+ * @return If the method is correctly processed.
+ */
+unsigned char AccObjectManagerAgent::InsertChildrenAccObj( XAccessible* pXAcc,
+ long pWnd)
+{
+ if( pWinManager )
+ return (unsigned char)pWinManager->InsertChildrenAccObj( pXAcc, HWND((void*)pWnd) );
+
+ return sal_False;
+}
+
+/**
+ * When a new UNO XAccessible object is destroied,we'll delete its corresponding
+ * com object and remove it from our manager list.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @return
+ */
+void AccObjectManagerAgent::DeleteAccObj( XAccessible* pXAcc )
+{
+ if( pWinManager )
+ pWinManager->DeleteAccObj( pXAcc );
+}
+
+/**
+ * When new UNO children XAccessible objects are destroyed,we'll delete their
+ * corresponding com objects and remove them from our manager list.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @return
+ */
+void AccObjectManagerAgent::DeleteChildrenAccObj( XAccessible* pXAcc )
+{
+ if( pWinManager )
+ pWinManager->DeleteChildrenAccObj( pXAcc );
+}
+
+/**
+ * Interface of decreasing MSAA state when some UNO state is decreased.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @param pState The lost state of control.
+ * @return
+ */
+void AccObjectManagerAgent::DecreaseState( XAccessible* pXAcc,unsigned short pState )
+{
+ if(pWinManager)
+ {
+ pWinManager->DecreaseState( pXAcc, pState );
+ }
+}
+
+/**
+ * Interface of increasing MSAA name when some UNO state is increased.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @param pState The new state of control.
+ * @return
+ */
+void AccObjectManagerAgent::IncreaseState( XAccessible* pXAcc,unsigned short pState )
+{
+ if(pWinManager)
+ {
+ pWinManager->IncreaseState( pXAcc, pState );
+ }
+}
+
+void AccObjectManagerAgent::UpdateState( com::sun::star::accessibility::XAccessible* pXAcc )
+{
+ if(pWinManager)
+ pWinManager->UpdateState(pXAcc);
+}
+
+/**
+ * Interface of notify MSAA event when some UNO event occured.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @param pEvent UNO event ID.
+ * @return If the method is correctly processed.
+ */
+unsigned char AccObjectManagerAgent::NotifyAccEvent( short pEvent,XAccessible* pXAcc )
+{
+ if(pWinManager)
+ return (unsigned char)pWinManager->NotifyAccEvent(pXAcc,pEvent);
+
+ return sal_False;
+}
+
+/**
+ * Judge whether a XAccessible object is a container object.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @return If the method is correctly processed.
+ */
+unsigned short AccObjectManagerAgent::IsContainer( XAccessible* pXAcc )
+{
+ if(pWinManager)
+ return (unsigned char)pWinManager->IsContainer(pXAcc);
+
+ return sal_False;
+}
+
+/**
+ * Return com object interface by querying XAccessible interface.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @return Com interface.
+ */
+IMAccessible* AccObjectManagerAgent::GetIMAccByXAcc(XAccessible* pXAcc)
+{
+ if(pWinManager)
+ return pWinManager->GetIMAccByXAcc(pXAcc);
+
+ return NULL;
+}
+
+/**
+ * Notify manger when a XAccessible object is destroying.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @return.
+ */
+void AccObjectManagerAgent::NotifyDestroy(XAccessible* pXAcc)
+{
+ if(pWinManager)
+ pWinManager->NotifyDestroy(pXAcc);
+}
+
+/**
+ * Return com object interface by querying child id.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @return Com interface.
+ */
+void AccObjectManagerAgent::GetIAccessibleFromResID(long childID,IMAccessible** pIMAcc)
+{
+ if(pWinManager)
+ *pIMAcc = pWinManager->GetIAccessibleFromResID(childID);
+}
+
+/**
+ * Return object interface by querying interface.
+ * @param pXAcc Uno XAccessible interface of control.
+ * @return Com interface.
+ */
+unsigned char AccObjectManagerAgent::GetIAccessibleFromXAccessible(XAccessible* pXAcc, IAccessible** ppXI)
+{
+ if(pWinManager)
+ {
+ *ppXI = (IAccessible*)pWinManager->GetIMAccByXAcc(pXAcc);
+ if(*ppXI)
+ return sal_True;
+ }
+ return sal_False;
+}
+
+XAccessible* AccObjectManagerAgent::GetParentXAccessible( XAccessible* pXAcc )
+{
+ if(pWinManager)
+ return pWinManager->GetParentXAccessible( pXAcc );
+
+ return NULL;
+}
+
+short AccObjectManagerAgent::GetParentRole( XAccessible* pXAcc )
+{
+ if(pWinManager)
+ return pWinManager->GetParentRole( pXAcc );
+
+ return -1;
+}
+
+void AccObjectManagerAgent::UpdateDescription( XAccessible* pXAcc )
+{
+ if(pWinManager)
+ pWinManager->UpdateDescription( pXAcc );
+}
+
+void AccObjectManagerAgent::UpdateChildState(com::sun::star::accessibility::XAccessible* pXAcc)
+{
+ if(pWinManager)
+ pWinManager->UpdateChildState( pXAcc );
+}
+
+
+bool AccObjectManagerAgent::IsSpecialToolboItem(com::sun::star::accessibility::XAccessible* pXAcc)
+{
+ if(pWinManager)
+ return pWinManager->IsSpecialToolboItem( pXAcc );
+
+ return false;
+}
+
+short AccObjectManagerAgent::GetRole(com::sun::star::accessibility::XAccessible* pXAcc)
+{
+ if(pWinManager)
+ return pWinManager->GetRole( pXAcc );
+
+ return -1;
+}
+
+XAccessible* AccObjectManagerAgent::GetAccDocByAccTopWin( XAccessible* pXAcc )
+{
+ if (pWinManager)
+ {
+ return pWinManager->GetAccDocByAccTopWin( pXAcc );
+ }
+ return NULL;
+}
+bool AccObjectManagerAgent::IsTopWinAcc( com::sun::star::accessibility::XAccessible* pXAcc )
+{
+ if (pWinManager)
+ {
+ return pWinManager->IsTopWinAcc( pXAcc );
+ }
+ return NULL;
+}
+
+bool AccObjectManagerAgent::IsStateManageDescendant(com::sun::star::accessibility::XAccessible* pXAcc)
+{
+ if(pWinManager)
+ return pWinManager->IsStateManageDescendant( pXAcc );
+
+ return sal_False;
+}
diff --git a/winaccessibility/source/service/AccObjectWinManager.cxx b/winaccessibility/source/service/AccObjectWinManager.cxx
new file mode 100644
index 000000000000..08ed3efd2b43
--- /dev/null
+++ b/winaccessibility/source/service/AccObjectWinManager.cxx
@@ -0,0 +1,1321 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#include <cassert>
+
+#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/AccessibleStateType.hpp>
+
+#include <oleacc.h>
+#ifndef _SV_AccObjectWinManager_HXX
+#include "AccObjectWinManager.hxx"
+#endif
+#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"
+#include "checkmt.hxx"
+
+#define CHILDID_SELF 0
+
+
+using namespace std;
+using namespace com::sun::star::accessibility;
+using namespace com::sun::star::uno;
+
+AccObjectWinManager* g_acc_manager = NULL;
+AccObjectWinManager* AccObjectWinManager::me = NULL;
+
+/**
+ * Implementation of interface XMSAAService's method getAccObjectPtr() that return the
+ * corresponding com interface with the MS event.
+ *
+ * @param
+ * @return Com interface.
+ */
+long GetMSComPtr(long hWnd, long lParam, long wParam)
+{
+ if( g_acc_manager )
+ return (long)g_acc_manager->Get_ToATInterface(HWND((void*)hWnd),lParam,wParam );
+ return NULL;
+}
+
+/**
+ * constructor
+ * @param Agent The agent kept in all listeners,it's the sole interface by which
+ * listener communicate with windows manager.
+ * pEventAccObj The present event accobject.
+ * oldFocus Last focused object.
+ * isSelectionChanged flag that identifies if there is selection changed.
+ * selectionChildObj Selected object.
+ * dChildID Chile resource ID.
+ * hAcc TopWindowHWND
+ * @return
+ */
+AccObjectWinManager::AccObjectWinManager( AccObjectManagerAgent* Agent ):
+ pAgent( Agent ),
+ oldFocus( NULL )
+{
+}
+
+/**
+ * Public method to produce manager
+ * @param Agent The agent kept in all listeners,it's the sole interface by which
+ * listener communicate with windows manager.
+ * @return
+ */
+AccObjectWinManager* AccObjectWinManager::CreateAccObjectWinManagerInstance( AccObjectManagerAgent* Agent )
+{
+ if( me == NULL )
+ {
+ me = new AccObjectWinManager( Agent );
+ g_acc_manager = me;
+ return me;
+ }
+
+ return me;
+}
+
+
+/**
+ * Destructor,clear all resource.
+ * @param
+ * @return
+ */
+AccObjectWinManager::~AccObjectWinManager()
+{
+ XIdAccList.clear();
+ HwndXAcc.clear();
+ XResIdAccList.clear();
+ XHWNDDocList.clear();
+#ifdef ACC_DEBUG
+
+ fclose( pFile );
+#endif
+}
+
+
+/**
+ * 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.
+ */
+
+long AccObjectWinManager::Get_ToATInterface( HWND hWnd, long lParam, long wParam)
+{
+ vos::OGuard localGuard(maATInterfaceMutex);//
+
+ IMAccessible* pRetIMAcc = NULL;
+
+ if(lParam == OBJID_CLIENT )
+ {
+ AccObject* topWindowAccObj = GetTopWindowAccObj(hWnd);
+ if(topWindowAccObj)
+ {
+ pRetIMAcc = topWindowAccObj->GetIMAccessible();
+ if(pRetIMAcc)
+ pRetIMAcc->AddRef();//increase COM reference count
+ }
+ }
+
+ if ( pRetIMAcc && lParam == OBJID_CLIENT )
+ {
+ IAccessible* pTemp = dynamic_cast<IAccessible*>( pRetIMAcc );
+ HRESULT result = LresultFromObject(IID_IAccessible, wParam, pTemp);
+ pTemp->Release();
+ return result;
+ }
+ return 0;
+}
+
+/**
+ * Search AccObject by XAccessible pointer from our container.
+ * @param pXAcc XAccessible interface.
+ * @return Pointer of accObject that is found.
+ */
+AccObject* AccObjectWinManager::GetAccObjByXAcc( XAccessible* pXAcc)
+{
+ if( pXAcc == NULL)
+ return NULL;
+
+ XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( (void*)pXAcc );
+ if ( pIndTemp == XIdAccList.end() )
+ return NULL;
+
+ return &(pIndTemp->second);
+}
+
+/**
+ * Search XAccessible by AccObject pointer from our container.
+ * @param pAccObj AccObject pointer.
+ * @return Pointer of XAccessible Interface.
+ */
+XAccessible* AccObjectWinManager::GetXAccByAccObj(AccObject* pAccObj)
+{
+ XIdToAccObjHash::iterator iter = XIdAccList.begin();
+ while(iter!=XIdAccList.end())
+ {
+ AccObject* tmp = &(iter->second);
+ if(tmp== pAccObj)
+ return (XAccessible*)(iter->first);
+ iter++;
+ }
+ return NULL;
+}
+
+/**
+ * get acc object of top window by its handle
+ * @param hWnd, top window handle
+ * @return pointer to AccObject
+ */
+AccObject* AccObjectWinManager::GetTopWindowAccObj(HWND hWnd)
+{
+ XHWNDToXAccHash::iterator iterResult =HwndXAcc.find(hWnd);
+ if(iterResult == HwndXAcc.end())
+ return NULL;
+ XAccessible* pXAcc = (XAccessible*)(iterResult->second);
+ return GetAccObjByXAcc(pXAcc);
+}
+
+/**
+ * Simulate MSAA event via XAccessible interface and event type.
+ * @param pXAcc XAccessible interface.
+ * @param state Customize Interface
+ * @return The terminate result that identifies if the call is successful.
+ */
+sal_Bool AccObjectWinManager::NotifyAccEvent(XAccessible* pXAcc,short state)
+{
+ vos::OGuard aGuard(aNotifyMutex);
+
+ if (!IsInMainThread())
+ {
+ return sal_False;
+ }
+
+ Reference< XAccessibleContext > pRContext;
+
+ if( pXAcc == NULL)
+ return sal_False;
+
+
+ pRContext = pXAcc->getAccessibleContext();
+ if( !pRContext.is() )
+ return sal_False;
+
+
+ AccObject* selfAccObj= GetAccObjByXAcc(pXAcc);
+
+ if(selfAccObj==NULL)
+ return sal_False;
+
+ int selectNum =0;
+
+ long dChildID = selfAccObj->GetResID();
+ HWND hAcc = selfAccObj->GetParentHWND();
+
+ switch(state)
+ {
+ case UM_EVENT_STATE_FOCUSED:
+ {
+ UpdateAccFocus(pXAcc);
+ if( selfAccObj )
+ selfAccObj->UpdateDefaultAction( );
+ UpdateValue(pXAcc);
+ NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ }
+ case UM_EVENT_STATE_BUSY:
+ NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_STATE_CHECKED:
+ NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_STATE_PRESSED:
+ NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+
+ //Removed fire out selected event
+ //case UM_EVENT_STATE_SELECTED:
+ // NotifyWinEvent( EVENT_OBJECT_STATECHANGE,hAcc, OBJID_CLIENT,dChildID );
+ // break;
+ case UM_EVENT_STATE_ARMED:
+ UpdateAccFocus(pXAcc);
+ NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_MENU_START:
+ NotifyWinEvent( EVENT_SYSTEM_MENUSTART,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_MENU_END:
+ NotifyWinEvent( EVENT_SYSTEM_MENUEND,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_MENUPOPUPSTART:
+ NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPSTART,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_MENUPOPUPEND:
+ NotifyWinEvent( EVENT_SYSTEM_MENUPOPUPEND,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_SELECTION_CHANGED:
+ NotifyWinEvent( EVENT_OBJECT_SELECTION,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_SELECTION_CHANGED_ADD:
+ NotifyWinEvent( EVENT_OBJECT_SELECTIONADD,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_SELECTION_CHANGED_REMOVE:
+ NotifyWinEvent( EVENT_OBJECT_SELECTIONREMOVE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_SELECTION_CHANGED_WITHIN:
+ NotifyWinEvent( EVENT_OBJECT_SELECTIONWITHIN,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_VALUECHANGE:
+ UpdateValue(pXAcc);
+ NotifyWinEvent( EVENT_OBJECT_VALUECHANGE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_NAMECHANGE:
+ NotifyWinEvent( EVENT_OBJECT_NAMECHANGE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_DESCRIPTIONCHANGE:
+ NotifyWinEvent( EVENT_OBJECT_DESCRIPTIONCHANGE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_DEFACTIONCHANGE:
+ NotifyWinEvent( IA2_EVENT_ACTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_CARETCHANGE:
+ NotifyWinEvent( IA2_EVENT_TEXT_CARET_MOVED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_TEXTCHANGE:
+ NotifyWinEvent( IA2_EVENT_TEXT_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_ACTIVE_DESCENDANT_CHANGED:
+ UpdateAccFocus(pXAcc);
+ NotifyWinEvent( EVENT_OBJECT_FOCUS,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_BOUNDRECT_CHANGED:
+ NotifyWinEvent( EVENT_OBJECT_LOCATIONCHANGE,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_VISIBLE_DATA_CHANGED:
+ NotifyWinEvent( IA2_EVENT_VISIBLE_DATA_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_SHOW :
+ NotifyWinEvent( EVENT_OBJECT_SHOW,hAcc, OBJID_CLIENT,dChildID );
+ NotifyWinEvent( EVENT_SYSTEM_FOREGROUND,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TABLE_CAPTION_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TABLE_CAPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TABLE_COLUMN_HEADER_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TABLE_COLUMN_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TABLE_MODEL_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TABLE_MODEL_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TABLE_ROW_HEADER_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TABLE_ROW_HEADER_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TABLE_SUMMARY_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TABLE_SUMMARY_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TABLE_ROW_DESCRIPTION_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TABLE_ROW_DESCRIPTION_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_REORDER:
+ NotifyWinEvent( EVENT_OBJECT_REORDER,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_PAGE_CHANGED:
+ NotifyWinEvent( IA2_EVENT_PAGE_CHANGED,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_CHILD_REMOVED:
+ NotifyWinEvent( EVENT_OBJECT_DESTROY,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_CHILD_ADDED:
+ NotifyWinEvent( EVENT_OBJECT_CREATE ,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_OBJECT_PAGECHANGED:
+ NotifyWinEvent( IA2_EVENT_PAGE_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_TEXT_SELECTION_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TEXT_SELECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_SECTION_CHANGED:
+ NotifyWinEvent( IA2_EVENT_SECTION_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ case UM_EVENT_COLUMN_CHANGED:
+ NotifyWinEvent( IA2_EVENT_TEXT_COLUMN_CHANGED ,hAcc, OBJID_CLIENT,dChildID );
+ break;
+ default:
+ break;
+ }
+
+ return sal_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 ==NULL )
+ return NULL;
+ if(pObj->GetParentObj())
+ {
+ pObj = pObj->GetParentObj();
+ return pObj->GetXAccessible().get();
+ }
+ return NULL;
+}
+
+/**
+ * Get Parent role by XAccessible interface.
+ * @param pXAcc XAccessible interface.
+ * @return Parent role.
+ */
+short AccObjectWinManager::GetParentRole( XAccessible* pXAcc )
+{
+ AccObject* pObj= GetAccObjByXAcc(pXAcc);
+ if( pObj ==NULL )
+ return -1;
+ if(pObj->GetParentObj())
+ {
+ pObj = pObj->GetParentObj();
+ if(pObj->GetXAccessible().is())
+ {
+ XAccessible* pXAcc = pObj->GetXAccessible().get();
+ Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext();
+ if(pRContext.is())
+ return pRContext->getAccessibleRole();
+ }
+ }
+ return -1;
+}
+
+/**
+ * Update focus objcet by new focused XAccessible interface.
+ * @param newFocus New XAccessible interface that gets focus.
+ * @return
+ */
+void AccObjectWinManager::UpdateAccFocus(XAccessible* newFocus)
+{
+ AccObject* pAccObjNew = GetAccObjByXAcc(newFocus);
+ if(pAccObjNew)
+ {
+ AccObject* pAccObjOld = GetAccObjByXAcc(oldFocus);
+ oldFocus = newFocus;
+ pAccObjNew->setFocus();
+ //if old == new, the pAccObjNew will be without focused state
+ if (pAccObjOld && pAccObjOld != pAccObjNew)
+ pAccObjOld->unsetFocus();
+ }
+}
+
+/**
+ * Update selected objcet by new focused XAccessible interface.
+ * @param pXAcc XAccessible interface that has selected child changed.
+ * @return Selected children count.
+ */
+int AccObjectWinManager::UpdateAccSelection(XAccessible* pXAcc)
+{
+ XAccessibleSelection* pSelection = NULL;
+ Reference< XAccessibleContext > pRContext;
+
+ if( pXAcc == NULL)
+ return sal_False;
+
+ pRContext = pXAcc->getAccessibleContext();
+ if( !pRContext.is() )
+ return sal_False;
+
+ Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY);
+ if( !pRSelection.is() )
+ return sal_False;
+
+ AccObject* pAccObj = GetAccObjByXAcc(pXAcc);
+ if(pAccObj==NULL)
+ return sal_False;
+
+ Reference<XAccessible> pRChild = NULL;
+ AccObject* pAccChildObj = NULL;
+ int selectNum= pRSelection->getSelectedAccessibleChildCount();
+
+ IAccSelectionList oldSelection = pAccObj->GetSelection();
+
+ if(selectNum > 4)//for selected.
+ return selectNum;
+ if(selectNum == 1 && oldSelection.size() == 0)
+ return 1;
+
+ for (int i=0;i<selectNum;i++)
+ {
+ pRChild = pRSelection->getSelectedAccessibleChild(i);
+ if(!pRChild.is())
+ {
+ continue;
+ }
+ Reference<XAccessibleContext> pRChildContext = pRChild->getAccessibleContext();
+ if(!pRChildContext.is())
+ {
+ continue;
+ }
+ long index = pRChildContext->getAccessibleIndexInParent();
+ IAccSelectionList::iterator temp = oldSelection.find(index);
+ if ( temp != oldSelection.end() )
+ {
+ oldSelection.erase(index);
+ continue;
+ }
+
+ pAccChildObj = NULL;
+ pAccChildObj = GetAccObjByXAcc(pRChild.get());
+ if(!pAccChildObj)
+ {
+ InsertAccObj(pRChild.get(), pXAcc,pAccObj->GetParentHWND());
+ pAccChildObj = GetAccObjByXAcc(pRChild.get());
+ }
+
+ pAccObj->AddSelect(index, pAccChildObj);
+
+ if(pAccChildObj != NULL)
+ NotifyWinEvent(EVENT_OBJECT_SELECTIONADD,pAccObj->GetParentHWND(), OBJID_CLIENT,pAccChildObj->GetResID());
+ }
+
+ IAccSelectionList::iterator iter = oldSelection.begin();
+ while(iter!=oldSelection.end())
+ {
+ pAccObj->GetSelection().erase(iter->first);
+ pAccChildObj = (AccObject*)(iter->second);
+ if(pAccChildObj != NULL)
+ NotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE,pAccObj->GetParentHWND(), OBJID_CLIENT,pAccChildObj->GetResID());
+ iter++;
+ }
+ return 0;
+
+}
+
+/**
+ * Delete child element from children list.
+ * @param pObj Child element that should be removed from parant 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* pXAcc )
+{
+ XHWNDToXAccHash::iterator iter = HwndXAcc.begin();
+ while(iter!=HwndXAcc.end())
+ {
+ if(iter->second == pXAcc )
+ {
+ HwndXAcc.erase(iter);
+ return;
+ }
+ iter++;
+ }
+}
+
+/**
+ * Delete Delete all children with the tree root of XAccessible pointer
+ * @param pXAcc Tree root XAccessible interface.
+ * @return
+ */
+void AccObjectWinManager::DeleteChildrenAccObj(XAccessible* pXAcc)
+{
+ vos::OGuard aGuard( aDeleteMutex );
+ AccObject* currentObj=NULL;
+ AccObject* childObj=NULL;
+ XAccessible* pTmpXAcc=NULL;
+
+ currentObj = GetAccObjByXAcc( pXAcc);
+ if(currentObj)
+ {
+ childObj = currentObj->NextChild();
+ while(childObj)
+ {
+ pTmpXAcc = GetXAccByAccObj(childObj);
+ if(pTmpXAcc)
+ {
+ DeleteChildrenAccObj(pTmpXAcc);
+ DeleteAccObj(pTmpXAcc);
+ }
+ childObj = currentObj->NextChild();
+ }
+ }
+}
+
+/**
+ * Delete Delete Acc object self.
+ * @param pXAcc The XAccessible interface.
+ * @return
+ */
+void AccObjectWinManager::DeleteAccObj( XAccessible* pXAcc )
+{
+ vos::OGuard aGuard( aDeleteMutex );
+ if( pXAcc == NULL )
+ return;
+ XIdToAccObjHash::iterator temp = XIdAccList.find(pXAcc);
+ if( temp != XIdAccList.end() )
+ {
+ ResIdGen.SetSub( temp->second.GetResID() );
+ }
+ else
+ {
+ return;
+ }
+
+ AccObject& accObj = temp->second;
+ DeleteAccChildNode( &accObj );
+ DeleteAccListener( &accObj );
+ if( accObj.GetIMAccessible() )
+ {
+ accObj.GetIMAccessible()->Release();
+ }
+ XIdAccList.erase( pXAcc );
+ XResIdAccList.erase( accObj.GetResID() );
+ DeleteFromHwndXAcc(pXAcc);
+}
+
+/**
+ * Delete listener that inspects some XAccessible object
+ * @param pAccObj Accobject pointer.
+ * @return
+ */
+void AccObjectWinManager::DeleteAccListener( AccObject* pAccObj )
+{
+ AccEventListener* listener = pAccObj->getListener();
+ if( listener==NULL )
+ return;
+ listener->removeMeFromBroadcaster();
+ pAccObj->SetListener(NULL);
+}
+
+/**
+ * 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.
+ */
+sal_Bool AccObjectWinManager::InsertChildrenAccObj( com::sun::star::accessibility::XAccessible* pXAcc,
+ HWND pWnd)
+{
+ if(!IsContainer(pXAcc))
+ return sal_False;
+
+ Reference< XAccessibleContext > pRContext;
+
+ if( pXAcc == NULL)
+ return sal_False;
+ pRContext = pXAcc->getAccessibleContext();
+ if( !pRContext.is() )
+ return sal_False;
+
+ short role = pRContext->getAccessibleRole();
+
+ if(com::sun::star::accessibility::AccessibleRole::DOCUMENT == role )
+ {
+ if(IsStateManageDescendant(pXAcc))
+ {
+ return sal_True;
+ }
+ }
+
+ int count = pRContext->getAccessibleChildCount();
+ for (int i=0;i<count;i++)
+ {
+ Reference<XAccessible> mxAccessible
+ = pRContext->getAccessibleChild(i);
+ XAccessible* mpAccessible = mxAccessible.get();
+ if(mpAccessible != NULL)
+ {
+ InsertAccObj( mpAccessible,pXAcc,pWnd );
+ InsertChildrenAccObj(mpAccessible,pWnd);
+ }
+ }
+
+ return sal_True;
+}
+
+/**
+ * Insert child object.
+ * @param pCurObj The child object
+ * @param pParentObj The parant 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 parant object
+ * @param pWnd Top window handle.
+ * @return
+ */
+sal_Bool AccObjectWinManager::InsertAccObj( XAccessible* pXAcc,XAccessible* pParentXAcc,HWND pWnd )
+{
+ XIdToAccObjHash::iterator itXacc = XIdAccList.find( (void*)pXAcc );
+ if (itXacc != XIdAccList.end() )
+ {
+ short nCurRole =GetRole(pXAcc);
+ if (AccessibleRole::SHAPE == nCurRole)
+ {
+ AccObject &objXacc = itXacc->second;
+ AccObject *pObjParent = objXacc.GetParentObj();
+ if (pObjParent &&
+ pObjParent->GetXAccessible().is() &&
+ pObjParent->GetXAccessible().get() != pParentXAcc)
+ {
+ XIdToAccObjHash::iterator itXaccParent = XIdAccList.find( (void*)pParentXAcc );
+ if(itXaccParent != XIdAccList.end())
+ {
+ objXacc.SetParentObj(&(itXaccParent->second));
+ }
+ }
+ }
+ return sal_False;
+ }
+
+
+ Reference< XAccessibleContext > pRContext;
+
+ if( pXAcc == NULL)
+ return sal_False;
+
+ pRContext = pXAcc->getAccessibleContext();
+ if( !pRContext.is() )
+ return sal_False;
+
+ if( pWnd == NULL )
+ {
+ if(pParentXAcc)
+ {
+ AccObject* pObj = GetAccObjByXAcc(pParentXAcc);
+ if(pObj)
+ pWnd = pObj->GetParentHWND();
+ }
+ if( pWnd == NULL )
+ return sal_False;
+ }
+
+ AccObject pObj( pXAcc,pAgent );
+ if( pObj.GetIMAccessible() == NULL )
+ return sal_False;
+ pObj.SetResID( this->ImpleGenerateResID());
+ pObj.SetParentHWND( pWnd );
+
+ //for file name support
+ if ( pObj.GetRole() == DOCUMENT )
+ {
+ XHWNDToDocumentHash::iterator aIter = XHWNDDocList.find( (long)pWnd );
+ if ( aIter != XHWNDDocList.end() )
+ {
+ XHWNDDocList.erase( aIter );
+ }
+ XHWNDDocList.insert( XHWNDToDocumentHash::value_type( (long)pWnd, pXAcc ) );
+
+ }
+ //end of file name
+
+ AccEventListener* listener = createAccEventListener(pXAcc, pAgent);
+ if(listener==NULL)
+ return sal_False;
+ Reference<XAccessibleComponent> xComponent(pRContext,UNO_QUERY);
+ Reference<XAccessibleEventBroadcaster> broadcaster(xComponent,UNO_QUERY);
+ if (broadcaster.is())
+ {
+ Reference <XAccessibleEventListener> pp (
+ static_cast< XAccessibleEventListener* >(listener),UNO_QUERY );
+ if(pp.is())
+ {
+ broadcaster->addEventListener(pp);
+ }
+ else
+ {
+ delete listener;
+ return sal_False;
+ }
+ }
+ else
+ return sal_False;
+
+ XIdAccList.insert( XIdToAccObjHash::value_type( (void*)pXAcc, pObj ));
+ XIdToAccObjHash::iterator pIndTemp = XIdAccList.find( (void*)pXAcc );
+ XResIdAccList.insert(XResIdToAccObjHash::value_type(pObj.GetResID(),&(pIndTemp->second)));
+
+ AccObject* pCurObj = GetAccObjByXAcc(pXAcc);
+ if( pCurObj )
+ {
+ pCurObj->SetListener( listener );
+ if(listener != NULL)
+ listener->acquire();
+ }
+
+ AccObject* pParentObj = GetAccObjByXAcc(pParentXAcc);
+ InsertAccChildNode(pCurObj,pParentObj,pWnd);
+ if( pCurObj )
+ pCurObj->UpdateAccessibleInfoFromUnoToMSAA();
+ return sal_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, com::sun::star::accessibility::XAccessible* pXAcc)
+{
+ HwndXAcc.insert( XHWNDToXAccHash::value_type( hWnd,(void*)pXAcc ) );
+}
+
+
+/**
+ * create the corresponding listener.
+ * @param pXAcc XAccessible interface.
+ * @param Agent The agent kept in all listeners,it's the sole interface by which
+ * listener communicate with windows manager.
+ * @return
+ */
+AccEventListener* AccObjectWinManager::createAccEventListener(XAccessible* pXAcc, AccObjectManagerAgent* /* Agent */ )
+{
+ AccEventListener* listener = NULL;
+ Reference<XAccessibleContext> xContext(pXAcc->getAccessibleContext(),UNO_QUERY);
+ if(xContext.is())
+ {
+ switch( xContext->getAccessibleRole() )
+ {
+ case /*AccessibleRole::*/DIALOG:
+ listener = new AccDialogEventListener(pXAcc,pAgent);
+ break;
+ case /*AccessibleRole::*/FRAME:
+ listener = new AccFrameEventListener(pXAcc,pAgent);
+ break;
+ case /*AccessibleRole::*/WINDOW:
+ listener = new AccWindowEventListener(pXAcc,pAgent);
+ break;
+ case /*AccessibleRole::*/ROOT_PANE:
+ listener = new AccFrameEventListener(pXAcc,pAgent);
+ break;
+ //Container
+ case /*AccessibleRole::*/CANVAS:
+ case /*AccessibleRole::*/COMBO_BOX:
+ case /*AccessibleRole::*/DOCUMENT:
+ 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:
+ listener = new AccContainerEventListener(pXAcc,pAgent);
+ break;
+ case /*AccessibleRole::*/PARAGRAPH:
+ case /*AccessibleRole::*/HEADING:
+ listener = new AccParagraphEventListener(pXAcc,pAgent);
+ break;
+ //Component
+ case /*AccessibleRole::*/CHECK_BOX:
+ case /*AccessibleRole::*/ICON:
+ case /*AccessibleRole::*/LABEL:
+ 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 DATE_EDITOR:
+ listener = new AccComponentEventListener(pXAcc,pAgent);
+ break;
+ //text component
+ case /*AccessibleRole::*/TEXT:
+ listener = new AccTextComponentEventListener(pXAcc,pAgent);
+ break;
+ //menu
+ case /*AccessibleRole::*/MENU:
+ listener = new AccMenuEventListener(pXAcc,pAgent);
+ break;
+ //object container
+ case /*AccessibleRole::*/SHAPE:
+
+ case /*AccessibleRole::*/EMBEDDED_OBJECT:
+ case /*AccessibleRole::*/GRAPHIC:
+ case /*AccessibleRole::*/TEXT_FRAME:
+ listener = new AccObjectContainerEventListener(pXAcc,pAgent);
+ break;
+ //descendmanager
+ case /*AccessibleRole::*/LIST:
+ listener = new AccListEventListener(pXAcc,pAgent);
+ break;
+ case /*AccessibleRole::*/TREE:
+ listener = new AccTreeEventListener(pXAcc,pAgent);
+ break;
+ //special
+ case /*AccessibleRole::*/COLUMN_HEADER:
+ case /*AccessibleRole::*/TABLE:
+ listener = new AccTableEventListener(pXAcc,pAgent);
+ break;
+ default:
+ listener = new AccContainerEventListener(pXAcc,pAgent);
+ break;
+ }
+ }
+
+ return listener;
+}
+
+/**
+ * state is a combination integer, each bit of which represents a single state,
+ * such as focused,1 for the state on,0 for the state off. Here call COM interface
+ * to modify the state value, including DecreaseState.
+ * @param pXAcc XAccessible interface.
+ * @param pState Changed state.
+ * @return
+ */
+void AccObjectWinManager::DecreaseState( XAccessible* pXAcc,unsigned short pState )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->DecreaseState( pState );
+}
+
+/**
+ * state is a combination integer, each bit of which represents a single state,such as focused,1 for
+ * the state on,0 for the state off. Here call COM interface to modify the state value, including
+ * IncreaseState.
+ * @param pXAcc XAccessible interface.
+ * @param pState Changed state.
+ * @return
+ */
+void AccObjectWinManager::IncreaseState( XAccessible* pXAcc,unsigned short pState )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->IncreaseState( pState );
+}
+
+void AccObjectWinManager::UpdateState( com::sun::star::accessibility::XAccessible* pXAcc )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->UpdateState( );
+}
+
+/**
+ * Set corresponding com object's accessible name via XAccessilbe 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();
+}
+
+void AccObjectWinManager::UpdateDescription( XAccessible* pXAcc )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if ( pAccObj )
+ pAccObj->UpdateDescription();
+}
+
+/**
+ * Set corresponding com object's accessible location via XAccessilbe interface and new
+ * location.
+ * @param pXAcc XAccessible interface.
+ * @return
+ */
+void AccObjectWinManager::SetLocation( XAccessible* pXAcc, long /*top*/, long /*left*/, long /*width*/, long /*height*/ )
+{
+ AccObject* pObj = GetAccObjByXAcc( pXAcc );
+ //get the location from XComponent.
+ Reference< XAccessibleContext > pRContext = pXAcc->getAccessibleContext();
+ if( pObj )
+ pObj->UpdateLocation();
+}
+
+/**
+ * Set corresponding com object's value via XAccessilbe 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 XAccessilbe 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 XAccessilbe 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 );
+}
+
+/**
+ * Set corresponding com object's description via XAccessilbe interface and new description.
+ * @param pXAcc XAccessible interface.
+ * @param newDesc new description
+ * @return
+ */
+void AccObjectWinManager::SetDescription( XAccessible* pXAcc, Any newDesc )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->SetDescription( newDesc );
+}
+
+/**
+ * Set corresponding com object's role via XAccessilbe interface and new role.
+ * @param pXAcc XAccessible interface.
+ * @param Role new role
+ * @return
+ */
+void AccObjectWinManager::SetRole( XAccessible* pXAcc, long Role )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if( pAccObj )
+ pAccObj->SetRole( (short)Role );
+}
+
+/**
+ * Judge if a XAccessible object is a container object.
+ * @param pAccessible XAccessible interface.
+ * @return If XAccessible object is container.
+ */
+sal_Bool AccObjectWinManager::IsContainer(XAccessible* pAccessible)
+{
+ try
+ {
+ if(pAccessible)
+ {
+ Reference<XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
+ 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::*/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 sal_True;
+ break;
+ case /*AccessibleRole::*/COLUMN_HEADER:
+ case /*AccessibleRole::*/TABLE:
+ if(!IsStateManageDescendant(pAccessible))
+ return sal_True;
+ break;
+ case /*AccessibleRole::*/MENU:
+ return sal_True;
+ break;
+ default:
+ return sal_False;
+ }
+ }
+ }
+ }
+ catch(...)
+ {
+ return sal_False;
+ }
+ return sal_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(),UNO_QUERY);
+ if(xContext.is())
+ {
+ Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet();
+ if( !pRState.is() )
+ return sal_False;
+
+ Sequence<short> pStates = pRState->getStates();
+ int count = pStates.getLength();
+ for( int iIndex = 0;iIndex < count;iIndex++ )
+ {
+ if(pStates[iIndex] == /*AccessibleStateType::*/MANAGES_DESCENDANTS)
+ return sal_True;
+ }
+ }
+ }
+ return sal_False;
+}
+
+/**
+ * Query and get IAccessible interface by XAccessible interface from list.
+ * @param pXAcc XAccessible interface.
+ * @return Com accobject interface.
+ */
+IMAccessible* AccObjectWinManager::GetIMAccByXAcc(XAccessible* pXAcc)
+{
+ AccObject* pAccObj = GetAccObjByXAcc(pXAcc);
+ if(pAccObj)
+ {
+ return pAccObj->GetIMAccessible();
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+/**
+ * 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 NULL;
+
+ AccObject* pObj = pIndTemp->second;
+
+ if(pObj->GetIMAccessible())
+ return pObj->GetIMAccessible();
+ return NULL;
+}
+/**
+ * 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(sal_True);
+ }
+}
+
+
+void AccObjectWinManager::UpdateChildState(com::sun::star::accessibility::XAccessible* pAccSubMenu)
+{
+ Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccSubMenu,UNO_QUERY);
+ if (!xContext.is())
+ {
+ return;
+ }
+ sal_Int32 nCount = xContext->getAccessibleChildCount();
+ for (sal_Int32 i = 0 ; i < nCount ; ++i)
+ {
+ Reference<com::sun::star::accessibility::XAccessible> xChild = xContext->getAccessibleChild(i);
+ if (xChild.is())
+ {
+ AccObject *pObj = GetAccObjByXAcc(xChild.get());
+ if (pObj)
+ {
+ pObj->UpdateState();
+ }
+ }
+ }
+}
+
+
+bool AccObjectWinManager::IsSpecialToolboItem(com::sun::star::accessibility::XAccessible* pXAcc)
+{
+ if (pXAcc && oldFocus != pXAcc)
+ {
+ if(GetParentRole(pXAcc) == TOOL_BAR)
+ {
+ Reference< XAccessibleContext > pRContext(pXAcc->getAccessibleContext());
+ if (pRContext.is())
+ {
+ if(pRContext->getAccessibleRole() == TOGGLE_BUTTON)
+ {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+short AccObjectWinManager::GetRole(com::sun::star::accessibility::XAccessible* pXAcc)
+{
+ assert(pXAcc != NULL);
+ Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pXAcc->getAccessibleContext(),UNO_QUERY);
+ if(xContext.is())
+ {
+ return xContext->getAccessibleRole();
+ }
+ return -1;
+}
+
+XAccessible* AccObjectWinManager::GetAccDocByHWND( long pWnd )
+{
+ XHWNDToDocumentHash::iterator aIter;
+ aIter = XHWNDDocList.find( pWnd );
+ if ( aIter != XHWNDDocList.end() )
+ {
+ return aIter->second;
+ }
+
+ return NULL;
+}
+
+XAccessible* AccObjectWinManager::GetAccDocByAccTopWin( XAccessible* pXAcc )
+{
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ long pWnd = (long)( pAccObj->GetParentHWND() );
+ return GetAccDocByHWND( pWnd );
+}
+
+bool AccObjectWinManager::IsTopWinAcc( com::sun::star::accessibility::XAccessible* pXAcc )
+{
+ bool bRet = false;
+ AccObject* pAccObj = GetAccObjByXAcc( pXAcc );
+ if ( pAccObj )
+ {
+ bRet = ( pAccObj->GetParentObj() == NULL );
+ }
+ return bRet;
+} \ No newline at end of file
diff --git a/winaccessibility/source/service/AccParagraphEventListener.cxx b/winaccessibility/source/service/AccParagraphEventListener.cxx
new file mode 100644
index 000000000000..fbbc8753b986
--- /dev/null
+++ b/winaccessibility/source/service/AccParagraphEventListener.cxx
@@ -0,0 +1,145 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#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 "AccParagraphEventListener.hxx"
+#include "AccObjectManagerAgent.hxx"
+#include "unomsaaevent.hxx"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccParagraphEventListener::AccParagraphEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
+ :AccContainerEventListener(pAcc, Agent)
+{}
+AccParagraphEventListener::~AccParagraphEventListener()
+{
+}
+
+/**
+ * Uno's event notifier when event is captured
+ * @param AccessibleEventObject the event object which contains information about event
+ */
+void AccParagraphEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ switch (aEvent.EventId)
+ {
+ case AccessibleEventId::CARET_CHANGED:
+ handleCaretChangedEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ case AccessibleEventId::VISIBLE_DATA_CHANGED:
+ handleVisibleDataChangedEvent();
+ break;
+ case AccessibleEventId::BOUNDRECT_CHANGED:
+ handleBoundrectChangedEvent();
+ break;
+ //Added for paragraph selected state.
+ case AccessibleEventId::STATE_CHANGED:
+ {
+ short State;
+ if( (aEvent.NewValue >>= State) && (State == AccessibleStateType::SELECTED) )
+ {
+ pAgent->IncreaseState( pAccessible, State);
+ break;
+ }
+ else if( (aEvent.OldValue >>= State) && (State == AccessibleStateType::SELECTED) )
+ {
+ pAgent->DecreaseState( pAccessible, 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 oldValue, Any newValue)
+{
+ pAgent->UpdateLocation(pAccessible);
+ pAgent->NotifyAccEvent(UM_EVENT_OBJECT_CARETCHANGE, pAccessible);
+}
+
+/**
+ * handle the VISIBLE_DATA_CHANGED event
+ */
+void AccParagraphEventListener::handleVisibleDataChangedEvent()
+{
+ AccEventListener::handleVisibleDataChangedEvent();
+}
+
+/**
+ * handle the BOUNDRECT_CHANGED event
+ */
+void AccParagraphEventListener::handleBoundrectChangedEvent()
+{
+ AccEventListener::handleBoundrectChangedEvent();
+}
+
+/**
+ * set the new state and fire the MSAA event
+ * @param state new state id
+ * @param enable true if state is set, false if state is unset
+ */
+void AccParagraphEventListener::setComponentState(short state, bool enable )
+{
+ // only the following state can be fired state event.
+ switch (state)
+ {
+ case AccessibleStateType::EDITABLE:
+ // no msaa state
+ break;
+ case AccessibleStateType::MULTI_LINE:
+ // no msaa state mapping
+ break;
+ case AccessibleStateType::SINGLE_LINE:
+ // no msaa state mapping
+ break;
+ default:
+ AccContainerEventListener::setComponentState(state, enable);
+ break;
+ }
+}
+
+void AccParagraphEventListener::handleTextSelectionChangedEvent()
+{
+ pAgent->NotifyAccEvent(UM_EVENT_TEXT_SELECTION_CHANGED, pAccessible);
+}
+
diff --git a/winaccessibility/source/service/AccResource.cxx b/winaccessibility/source/service/AccResource.cxx
new file mode 100644
index 000000000000..374da6baf0af
--- /dev/null
+++ b/winaccessibility/source/service/AccResource.cxx
@@ -0,0 +1,85 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#include "AccResource.hxx"
+
+#include <tools/simplerm.hxx>
+
+// ---- needed as long as we have no contexts for components ---
+#include <vcl/svapp.hxx>
+
+//2009.04. Comment the following code because the acc resource is not necessary now. Can open them if necessary
+//#ifndef _TOOLS_INTN_HXX
+//#include <tools/intn.hxx>
+//#endif
+//#ifndef _SOLAR_HRC
+//#include <svtools/solar.hrc>
+//#endif
+
+//.........................................................................
+
+//==================================================================
+//= ResourceManager
+//==================================================================
+SimpleResMgr* ResourceManager::m_pImpl = NULL;
+
+//------------------------------------------------------------------
+ResourceManager::EnsureDelete::~EnsureDelete()
+{
+ delete ResourceManager::m_pImpl;
+}
+
+//------------------------------------------------------------------
+void ResourceManager::ensureImplExists()
+{
+ //Comment the following code because the acc resource is not necessary now. Can open them if necessary
+ /*
+ if (m_pImpl)
+ return;
+
+ LanguageType nType = Application::GetSettings().GetUILanguage();
+
+ ByteString sFileName("winaccessibility");
+ sFileName += ByteString::CreateFromInt32( (sal_Int32)SOLARUPD );
+
+ m_pImpl = SimpleResMgr::Create(sFileName.GetBuffer(), nType);
+
+ if (m_pImpl)
+ {
+ // no that we have a impl class make sure it's deleted on unloading the library
+ static ResourceManager::EnsureDelete s_aDeleteTheImplClas;
+ }
+ */
+}
+
+//------------------------------------------------------------------
+::rtl::OUString ResourceManager::loadString(sal_uInt16 _nResId)
+{
+ ::rtl::OUString sReturn;
+
+ ensureImplExists();
+ if (m_pImpl)
+ sReturn = m_pImpl->ReadString(_nResId);
+
+ return sReturn;
+}
+
+
diff --git a/winaccessibility/source/service/AccTableEventListener.cxx b/winaccessibility/source/service/AccTableEventListener.cxx
new file mode 100644
index 000000000000..4042a5412dae
--- /dev/null
+++ b/winaccessibility/source/service/AccTableEventListener.cxx
@@ -0,0 +1,146 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#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 "AccTableEventListener.hxx"
+#include "AccObjectManagerAgent.hxx"
+#include "unomsaaevent.hxx"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccTableEventListener::AccTableEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
+ :AccDescendantManagerEventListener(pAcc, Agent)
+{}
+AccTableEventListener::~AccTableEventListener()
+{
+}
+
+/**
+ * Uno's event notifier when event is captured
+ * @param AccessibleEventObject the event object which contains information about event
+ */
+void AccTableEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent )
+throw (::com::sun::star::uno::RuntimeException)
+{
+ switch (aEvent.EventId)
+ {
+ case AccessibleEventId::ACTIVE_DESCENDANT_CHANGED:
+ handleActiveDescendantChangedEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+
+ case AccessibleEventId::TABLE_CAPTION_CHANGED:
+ {
+
+ pAgent->NotifyAccEvent(UM_EVENT_TABLE_CAPTION_CHANGED, pAccessible);
+ break;
+ }
+ case AccessibleEventId::TABLE_COLUMN_DESCRIPTION_CHANGED:
+ {
+
+ pAgent->NotifyAccEvent(UM_EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED, pAccessible);
+ break;
+ }
+ case AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED:
+ {
+
+ pAgent->NotifyAccEvent(UM_EVENT_TABLE_COLUMN_HEADER_CHANGED, pAccessible);
+ break;
+ }
+ case AccessibleEventId::TABLE_ROW_HEADER_CHANGED:
+ {
+
+ pAgent->NotifyAccEvent(UM_EVENT_TABLE_ROW_HEADER_CHANGED, pAccessible);
+ break;
+ }
+ case AccessibleEventId::TABLE_MODEL_CHANGED:
+ {
+
+ handleTableModelChangeEvent(aEvent.NewValue);
+ break;
+ }
+ case AccessibleEventId::TABLE_SUMMARY_CHANGED:
+ {
+
+ pAgent->NotifyAccEvent(UM_EVENT_TABLE_SUMMARY_CHANGED, pAccessible);
+ break;
+ }
+ case AccessibleEventId::TABLE_ROW_DESCRIPTION_CHANGED:
+ {
+
+ pAgent->NotifyAccEvent(UM_EVENT_TABLE_ROW_DESCRIPTION_CHANGED, pAccessible);
+ break;
+ }
+ default:
+ AccDescendantManagerEventListener::notifyEvent(aEvent);
+ break;
+ }
+}
+
+/**
+ * handle the ACTIVE_DESCENDANT_CHANGED event
+ * @param oldValue the child to lose active
+ * @param newValue the child to get active
+ */
+void AccTableEventListener::handleActiveDescendantChangedEvent(Any oldValue, Any newValue)
+{
+ Reference< XAccessible > xChild;
+ if(newValue >>= xChild )
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ pAgent->InsertAccObj(pAcc,pAccessible);
+ pAgent->NotifyAccEvent(UM_EVENT_ACTIVE_DESCENDANT_CHANGED, pAcc);
+ }
+ }
+ else if (oldValue >>= xChild)
+ {
+ //delete an existing child
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ pAgent->DeleteAccObj( pAcc );
+ }
+ }
+
+}
+void AccTableEventListener::handleTableModelChangeEvent(Any newValue)
+{
+ AccessibleTableModelChange aModelChange;
+ if (newValue >>= aModelChange)
+ {
+ if( pAccessible )
+ {
+ //delete all oldValue's existing children
+ pAgent->DeleteChildrenAccObj( pAccessible );
+ //add all oldValue's existing children
+ pAgent->InsertChildrenAccObj( pAccessible );
+ }
+ pAgent->NotifyAccEvent(UM_EVENT_TABLE_MODEL_CHANGED, pAccessible);
+ }
+}
diff --git a/winaccessibility/source/service/AccTextComponentEventListener.cxx b/winaccessibility/source/service/AccTextComponentEventListener.cxx
new file mode 100644
index 000000000000..2d8254b144da
--- /dev/null
+++ b/winaccessibility/source/service/AccTextComponentEventListener.cxx
@@ -0,0 +1,65 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#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 "AccTextComponentEventListener.hxx"
+#include "AccObjectManagerAgent.hxx"
+#include "unomsaaevent.hxx"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccTextComponentEventListener::AccTextComponentEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
+ :AccComponentEventListener(pAcc, Agent)
+{}
+AccTextComponentEventListener::~AccTextComponentEventListener()
+{
+}
+
+/**
+ * set the new state and fire the MSAA event
+ * @param state new state id
+ * @param enable true if state is set, false if state is unset
+ */
+void AccTextComponentEventListener::setComponentState(short state, bool enable )
+{
+ // only the following state can be fired state event.
+ switch (state)
+ {
+ case AccessibleStateType::EDITABLE:
+ // no msaa state mapping
+ break;
+ case AccessibleStateType::MULTI_LINE:
+ // no msaa state mapping
+ break;
+ case AccessibleStateType::SINGLE_LINE:
+ // no msaa state mapping
+ break;
+ default:
+ AccComponentEventListener::setComponentState(state, enable);
+ break;
+ }
+}
diff --git a/winaccessibility/source/service/AccTopWindowListener.cxx b/winaccessibility/source/service/AccTopWindowListener.cxx
new file mode 100644
index 000000000000..2cf92bcdb757
--- /dev/null
+++ b/winaccessibility/source/service/AccTopWindowListener.cxx
@@ -0,0 +1,321 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#include <cppuhelper/bootstrap.hxx>
+#include <com/sun/star/bridge/XUnoUrlResolver.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <vcl/window.hxx>
+#include <toolkit/awt/Vclxwindow.hxx>
+
+#ifndef _SV_SYSDATA_HXX
+#if defined( WIN ) || defined( WNT ) || defined( OS2 )
+typedef sal_Int32 HWND;
+typedef sal_Int32 HMENU;
+typedef sal_Int32 HDC;
+typedef void *PVOID;
+typedef PVOID HANDLE;
+typedef HANDLE HFONT;
+#endif
+#include <vcl/sysdata.hxx>
+#endif
+
+#include "AccTopWindowListener.hxx"
+#include "unomsaaevent.hxx"
+
+#include <com/sun/star/awt/XExtendedToolkit.hpp>
+#include <com/sun/star/uno/XInterface.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>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::bridge;
+using namespace com::sun::star::awt;
+using namespace rtl;
+using namespace cppu;
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+AccTopWindowListener* g_pTop = NULL;
+//when proccess exit, call FreeTopWindowListener() in svmain
+void FreeTopWindowListener()
+{
+ if( g_pTop )
+ {
+ g_pTop->release();
+ g_pTop = NULL;
+ }
+}
+
+/**
+ * As a global method to invoke the handleWindowOpened() method
+ */
+void handleWindowOpened_impl(long pAcc)
+{
+ if( g_pTop && pAcc != NULL )
+ g_pTop->handleWindowOpened( (com::sun::star::accessibility::XAccessible*)((void*)pAcc) );
+}
+
+/**
+ * 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( com::sun::star::accessibility::XAccessible* pAccessible )
+{
+ //get SystemData from window
+ VCLXWindow* pvclwindow = (VCLXWindow*)pAccessible;
+ Window* window = pvclwindow->GetWindow();
+ // The SalFrame of window may be destructed at this time
+ const SystemEnvData* systemdata = NULL;
+ try
+ {
+ systemdata = window->GetSystemData();
+ }
+ catch(...)
+ {
+ systemdata = NULL;
+ }
+ Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
+ if(!xContext.is())
+ {
+ return;
+ }
+ com::sun::star::accessibility::XAccessibleContext* pAccessibleContext = xContext.get();
+ //Only AccessibleContext exist, add all listeners
+ if(pAccessibleContext != NULL && systemdata != NULL)
+ {
+ accManagerAgent.SaveTopWindowHandle((HWND)systemdata->hWnd, pAccessible);
+
+ AddAllListeners(pAccessible,NULL,(HWND)systemdata->hWnd);
+
+ if( window->GetStyle() & WB_MOVEABLE )
+ accManagerAgent.IncreaseState( pAccessible, -1 /* U_MOVEBLE */ );
+
+ short role = pAccessibleContext->getAccessibleRole();
+
+
+ if (role == com::sun::star::accessibility::AccessibleRole::POPUP_MENU ||
+ role == com::sun::star::accessibility::AccessibleRole::MENU )
+ {
+ accManagerAgent.NotifyAccEvent(UM_EVENT_MENUPOPUPSTART, pAccessible);
+ }
+
+ if (role == com::sun::star::accessibility::AccessibleRole::FRAME ||
+ role == com::sun::star::accessibility::AccessibleRole::DIALOG ||
+ role == com::sun::star::accessibility::AccessibleRole::WINDOW ||
+ role == com::sun::star::accessibility::AccessibleRole::ALERT)
+ {
+ accManagerAgent.NotifyAccEvent(UM_EVENT_SHOW, pAccessible);
+ }
+ }
+}
+
+AccTopWindowListener::AccTopWindowListener():
+ accManagerAgent(),
+ m_refcount(1)
+{
+}
+
+AccTopWindowListener::~AccTopWindowListener()
+{
+}
+
+/**
+ * It is invoked when a new window is opened, the source of this EventObject is the window
+ */
+void AccTopWindowListener::windowOpened( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException)
+{
+ if ( !e.Source.is())
+ {
+ return;
+ }
+
+ Reference< com::sun::star::accessibility::XAccessible > xAccessible ( e.Source, UNO_QUERY );
+ com::sun::star::accessibility::XAccessible* pAccessible = xAccessible.get();
+ if ( pAccessible == NULL)
+ {
+ return;
+ }
+
+ 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(com::sun::star::accessibility::XAccessible* pAccessible, com::sun::star::accessibility::XAccessible* pParentXAcc, HWND pWND)
+{
+ Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
+ if(!xContext.is())
+ {
+ return;
+ }
+ com::sun::star::accessibility::XAccessibleContext* pAccessibleContext = xContext.get();
+ if(pAccessibleContext == NULL)
+ {
+ return;
+ }
+
+ accManagerAgent.InsertAccObj( pAccessible, pParentXAcc,pWND );
+
+ if (!accManagerAgent.IsContainer(pAccessible))
+ {
+ return;
+ }
+
+
+ short role = pAccessibleContext->getAccessibleRole();
+ if(com::sun::star::accessibility::AccessibleRole::DOCUMENT == role )
+ {
+ if(accManagerAgent.IsStateManageDescendant(pAccessible))
+ {
+ return ;
+ }
+ }
+
+
+ int count = pAccessibleContext->getAccessibleChildCount();
+ for (int i=0;i<count;i++)
+ {
+ Reference<com::sun::star::accessibility::XAccessible> mxAccessible
+ = pAccessibleContext->getAccessibleChild(i);
+
+ com::sun::star::accessibility::XAccessible* mpAccessible = mxAccessible.get();
+ if(mpAccessible != NULL)
+ {
+ Reference<com::sun::star::accessibility::XAccessibleContext> mxAccessibleContext
+ = mpAccessible->getAccessibleContext();
+ com::sun::star::accessibility::XAccessibleContext* mpContext = mxAccessibleContext.get();
+ if(mpContext != NULL)
+ {
+ //fprintf(output, "go on add child's children event listener\n");
+ AddAllListeners(mpAccessible,pAccessible,pWND);
+ }
+ }
+ }
+}
+
+void AccTopWindowListener::windowClosing( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+/**
+ * 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 ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException)
+{
+ if ( !e.Source.is())
+ {
+ return;
+ }
+ Reference< com::sun::star::accessibility::XAccessible > xAccessible ( e.Source, UNO_QUERY );
+ com::sun::star::accessibility::XAccessible* pAccessible = xAccessible.get();
+ if ( pAccessible == NULL)
+ {
+ return;
+ }
+
+
+ VCLXWindow* pvclwindow = (VCLXWindow*)pAccessible;
+ Window* window = pvclwindow->GetWindow();
+ const SystemEnvData* systemdata=window->GetSystemData();
+
+ Reference<com::sun::star::accessibility::XAccessibleContext> xContext(pAccessible->getAccessibleContext(),UNO_QUERY);
+ if(!xContext.is())
+ {
+ return;
+ }
+ com::sun::star::accessibility::XAccessibleContext* pAccessibleContext = xContext.get();
+
+ short role = -1;
+ if(pAccessibleContext != NULL)
+ {
+ role = pAccessibleContext->getAccessibleRole();
+
+ if (role == com::sun::star::accessibility::AccessibleRole::POPUP_MENU ||
+ role == com::sun::star::accessibility::AccessibleRole::MENU)
+ {
+ accManagerAgent.NotifyAccEvent(UM_EVENT_MENUPOPUPEND, pAccessible);
+ }
+ }
+
+
+ accManagerAgent.DeleteChildrenAccObj( pAccessible );
+ if( role != com::sun::star::accessibility::AccessibleRole::POPUP_MENU )
+ accManagerAgent.DeleteAccObj( pAccessible );
+
+}
+
+void AccTopWindowListener::windowMinimized( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+void AccTopWindowListener::windowNormalized( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+void AccTopWindowListener::windowActivated( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+void AccTopWindowListener::windowDeactivated( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+void AccTopWindowListener::disposing( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException)
+{
+}
+
+//need to investigate further
+::com::sun::star::uno::Any SAL_CALL AccTopWindowListener::queryInterface( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::uno::RuntimeException)
+{
+ if (aType.equals( ::getCppuType( (Reference< com::sun::star::awt::XTopWindowListener> const *)0 ) ))
+ {
+ Reference< com::sun::star::awt::XTopWindowListener> xTopListener( static_cast< com::sun::star::awt::XTopWindowListener* >(this));
+ return makeAny(xTopListener);
+ }
+ return Any();
+}
+
+void AccTopWindowListener::acquire( ) throw ()
+{
+ ::osl_incrementInterlockedCount( &m_refcount );
+}
+
+void AccTopWindowListener::release() throw ()
+{
+ // thread-safe decrementation of reference count
+ if (0 == ::osl_decrementInterlockedCount( &m_refcount ))
+ {
+ delete this; // shutdown this object
+ }
+}
diff --git a/winaccessibility/source/service/AccTreeEventListener.cxx b/winaccessibility/source/service/AccTreeEventListener.cxx
new file mode 100644
index 000000000000..6cde4e5979e0
--- /dev/null
+++ b/winaccessibility/source/service/AccTreeEventListener.cxx
@@ -0,0 +1,87 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#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 "AccTreeEventListener.hxx"
+#include "AccObjectManagerAgent.hxx"
+#include "unomsaaevent.hxx"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccTreeEventListener::AccTreeEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
+ :AccDescendantManagerEventListener(pAcc, Agent)
+{}
+AccTreeEventListener::~AccTreeEventListener()
+{
+}
+
+/**
+ * Uno's event notifier when event is captured
+ * @param AccessibleEventObject the event object which contains information about event
+ */
+void AccTreeEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException)
+{
+ switch (aEvent.EventId)
+ {
+ case AccessibleEventId::ACTIVE_DESCENDANT_CHANGED:
+ handleActiveDescendantChangedEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ default:
+ AccDescendantManagerEventListener::notifyEvent(aEvent);
+ break;
+ }
+}
+
+/**
+ * handle the ACTIVE_DESCENDANT_CHANGED event
+ * @param oldValue the child to lose active
+ * @param newValue the child to get active
+ */
+void AccTreeEventListener::handleActiveDescendantChangedEvent(Any oldValue, Any newValue)
+{
+ Reference< XAccessible > xChild;
+ if(newValue >>= xChild )
+ {
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ pAgent->InsertAccObj(pAcc,pAccessible);
+ pAgent->NotifyAccEvent(UM_EVENT_ACTIVE_DESCENDANT_CHANGED, pAcc);
+ pActiveDescendant = pAcc;
+ }
+ }
+ if (oldValue >>= xChild)
+ {
+ //delete an existing child
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ pAgent->DeleteAccObj( pAcc );
+ }
+ }
+
+}
diff --git a/winaccessibility/source/service/AccWindowEventListener.cxx b/winaccessibility/source/service/AccWindowEventListener.cxx
new file mode 100644
index 000000000000..7f9e3ba99494
--- /dev/null
+++ b/winaccessibility/source/service/AccWindowEventListener.cxx
@@ -0,0 +1,152 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#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 "AccWindowEventListener.hxx"
+#include "AccObjectManagerAgent.hxx"
+#include "unomsaaevent.hxx"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::accessibility;
+
+AccWindowEventListener::AccWindowEventListener(com::sun::star::accessibility::XAccessible* pAcc, AccObjectManagerAgent* Agent)
+ :AccEventListener(pAcc, Agent)
+{}
+AccWindowEventListener::~AccWindowEventListener()
+{
+}
+
+/**
+ * Uno's event notifier when event is captured
+ * @param AccessibleEventObject: the event object which contains information about event
+ */
+void AccWindowEventListener::notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException)
+{
+ switch (aEvent.EventId)
+ {
+ case AccessibleEventId::CHILD:
+ handleChildChangedEvent(aEvent.OldValue, aEvent.NewValue);
+ break;
+ case AccessibleEventId::VISIBLE_DATA_CHANGED:
+ handleVisibleDataChangedEvent();
+ break;
+ case AccessibleEventId::BOUNDRECT_CHANGED:
+ handleBoundrectChangedEvent();
+ break;
+ default:
+ AccEventListener::notifyEvent(aEvent);
+ break;
+ }
+}
+
+/**
+ * handle the VISIBLE_DATA_CHANGED event
+ */
+void AccWindowEventListener::handleVisibleDataChangedEvent()
+{
+ AccEventListener::handleVisibleDataChangedEvent();
+}
+
+/**
+ * handle the BOUNDRECT_CHANGED event
+ */
+void AccWindowEventListener::handleBoundrectChangedEvent()
+{
+ AccEventListener::handleBoundrectChangedEvent();
+}
+
+/**
+ * handle the CHILD event
+ * @param oldValue the child to be deleted
+ * @param newValue the child to be added
+ */
+void AccWindowEventListener::handleChildChangedEvent(Any oldValue, Any newValue)
+{
+ Reference< XAccessible > xChild;
+ if( newValue >>= xChild)
+ {
+ //create a new child
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ //add this child
+ pAgent->InsertAccObj( pAcc,pAccessible);
+ //add all oldValue's existing children
+ pAgent->InsertChildrenAccObj(pAcc);
+ pAgent->NotifyAccEvent(UM_EVENT_CHILD_ADDED, pAcc);
+ }
+ else
+ {}
+ }
+ else if (oldValue >>= xChild)
+ {
+ //delete a existing child
+ if(xChild.is())
+ {
+ XAccessible* pAcc = xChild.get();
+ pAgent->NotifyAccEvent(UM_EVENT_CHILD_REMOVED, pAcc);
+ pAgent->DeleteChildrenAccObj( pAcc );
+ //delete this child
+ pAgent->DeleteAccObj( pAcc );
+ }
+ else
+ {}
+ }
+}
+
+/**
+ * set the new state and fire the MSAA event
+ * @param state new state id
+ * @param enable true if state is set, false if state is unset
+ */
+void AccWindowEventListener::setComponentState(short state, bool enable )
+{
+ // only the following state can be fired state event.
+ switch (state)
+ {
+ case AccessibleStateType::ICONIFIED:
+ // no msaa state
+ break;
+ case AccessibleStateType::VISIBLE:
+ // UNO !VISIBLE == MSAA INVISIBLE
+ if( enable )
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::VISIBLE );
+ else
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::VISIBLE );
+ break;
+ case AccessibleStateType::SHOWING:
+ // UNO !SHOWING == MSAA OFFSCREEN
+ if( enable )
+ {
+ pAgent->IncreaseState( pAccessible, AccessibleStateType::SHOWING );
+ }
+ else
+ pAgent->DecreaseState( pAccessible, AccessibleStateType::SHOWING );
+ break;
+ default:
+ break;
+ }
+}
diff --git a/winaccessibility/source/service/ResIDGenerator.cxx b/winaccessibility/source/service/ResIDGenerator.cxx
new file mode 100644
index 000000000000..26e1bac4c5f0
--- /dev/null
+++ b/winaccessibility/source/service/ResIDGenerator.cxx
@@ -0,0 +1,54 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#include "ResIDGenerator.hxx"
+
+/**
+ * Destructor
+ *
+ * @param
+ * @return
+ */
+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 ++max.
+ * Add the obsolete IDs by calling SetSub method
+ *
+ * @param
+ * @return new resource ID.
+ */
+long ResIDGenerator::GenerateNewResID()
+{
+ if (max == LONG_MAX)
+ {
+ if (!subList.empty())
+ {
+ long nRes = *(subList.begin());
+ subList.pop_front();
+ return nRes;
+ }
+ }
+ return -(++max);
+}
diff --git a/winaccessibility/source/service/checkmt.cxx b/winaccessibility/source/service/checkmt.cxx
new file mode 100644
index 000000000000..258a6f61489a
--- /dev/null
+++ b/winaccessibility/source/service/checkmt.cxx
@@ -0,0 +1,36 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#include "checkmt.hxx"
+#include <vcl/svapp.hxx>
+
+bool IsInMainThread()
+{
+ if( Application::GetMainThreadIdentifier() == ::vos::OThread::getCurrentIdentifier())
+ return true;
+ else
+ return false;
+}
+
+vos::IMutex& GetSolarMutex()
+{
+ return Application::GetSolarMutex();
+}
diff --git a/winaccessibility/source/service/checkmt.hxx b/winaccessibility/source/service/checkmt.hxx
new file mode 100644
index 000000000000..6374bd93f6c4
--- /dev/null
+++ b/winaccessibility/source/service/checkmt.hxx
@@ -0,0 +1,28 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#pragma once
+
+#include <vos/mutex.hxx>
+
+bool IsInMainThread();
+
+vos::IMutex& GetSolarMutex();
diff --git a/winaccessibility/source/service/exports.dxp b/winaccessibility/source/service/exports.dxp
new file mode 100644
index 000000000000..f0e1c69934bc
--- /dev/null
+++ b/winaccessibility/source/service/exports.dxp
@@ -0,0 +1,2 @@
+component_getImplementationEnvironment
+component_getFactory
diff --git a/winaccessibility/source/service/msaaservice_impl.cxx b/winaccessibility/source/service/msaaservice_impl.cxx
new file mode 100644
index 000000000000..3148c9713914
--- /dev/null
+++ b/winaccessibility/source/service/msaaservice_impl.cxx
@@ -0,0 +1,289 @@
+/**************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implementationentry.hxx>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/accessibility/XMSAAService.hpp>
+
+#include <com/sun/star/awt/XExtendedToolkit.hpp>
+#include <vcl/svapp.hxx>
+
+using namespace ::rtl; // for OUString
+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;
+
+typedef sal_Int32 HWND;
+
+#include "AccTopWindowListener.hxx"
+#include "g_msacc.hxx"
+
+extern void FreeTopWindowListener();
+extern long GetMSComPtr(long hWnd, long lParam, long wParam);
+extern void handleWindowOpened_impl( long pAcc);
+
+
+namespace my_sc_impl
+{
+
+extern Sequence< OUString > SAL_CALL getSupportedServiceNames_MSAAServiceImpl();
+extern OUString SAL_CALL getImplementationName_MSAAServiceImpl();
+extern Reference< XInterface > SAL_CALL create_MSAAServiceImpl(
+ Reference< XComponentContext > const & xContext )
+ SAL_THROW( () );
+/**
+ * Method that returns the service name.
+ * @param
+ * @return Name sequence.
+ */
+static Sequence< OUString > getSupportedServiceNames_MSAAServiceImpl()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ // MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(1);
+ seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.MSAAService"));
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+/**
+ * Method that returns the service name.
+ * @param
+ * @return Name sequence.
+ */
+static OUString getImplementationName_MSAAServiceImpl()
+{
+ static OUString *pImplName = 0;
+ if( ! pImplName )
+ {
+ // MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pImplName )
+ {
+ static OUString implName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.my_sc_implementation.MSAAService") );
+ pImplName = &implName;
+ }
+ }
+ return *pImplName;
+}
+
+class MSAAServiceImpl : public ::cppu::WeakImplHelper3<
+ XMSAAService, lang::XServiceInfo, lang::XInitialization >
+{
+ OUString m_arg;
+public:
+ // focus on three given interfaces,
+ // no need to implement XInterface, XTypeProvider, XWeak
+ MSAAServiceImpl ();
+ virtual ~MSAAServiceImpl( void );
+ // XInitialization will be called upon createInstanceWithArguments[AndContext]()
+ virtual void SAL_CALL initialize( Sequence< Any > const & args )
+ throw (Exception);
+ // XMSAAService
+ virtual sal_Int32 SAL_CALL getAccObjectPtr (long hWnd, long lParam, long wParam)
+ throw (RuntimeException);
+ virtual void SAL_CALL handleWindowOpened(sal_Int32)
+ throw (RuntimeException);
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName()
+ throw (RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )
+ throw (RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
+ throw (RuntimeException);
+};
+
+/**
+ * Implemention of XInitialization.
+ * @param
+ * @return.
+ */
+void MSAAServiceImpl::initialize( Sequence< Any > const & args ) throw (Exception)
+{
+ if (1 != args.getLength())
+ {
+ throw lang::IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("give a string instanciating this component!") ),
+ (::cppu::OWeakObject *)this, // resolve to XInterface reference
+ 0 ); // argument pos
+ }
+ if (! (args[ 0 ] >>= m_arg))
+ {
+ throw lang::IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no string given as argument!") ),
+ (::cppu::OWeakObject *)this, // resolve to XInterface reference
+ 0 ); // argument pos
+ }
+}
+
+/**
+ * Implemention of getAccObjectPtr.
+ * @param
+ * @return Com interface.
+ */
+sal_Int32 MSAAServiceImpl::getAccObjectPtr ( long hWnd, long lParam, long wParam) throw (RuntimeException)
+{
+ return GetMSComPtr(hWnd, lParam, wParam);
+}
+
+/**
+ * Implemention of handleWindowOpened,the method will be invoked when a top window
+ * opened and AT starts up.
+ * @param
+ * @return
+ */
+void MSAAServiceImpl::handleWindowOpened( sal_Int32 pAcc)
+{
+ handleWindowOpened_impl(pAcc);
+}
+
+/**
+ * Implemention of XServiceInfo.
+ * @param
+ * @return Implementataion name.
+ */
+OUString MSAAServiceImpl::getImplementationName() throw (RuntimeException)
+{
+ // unique implementation name
+ return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.my_sc_impl.MSAAService") );
+}
+
+/**
+ * Implemention of XServiceInfo,return support service name.
+ * @param Service name.
+ * @return If the service name is supported.
+ */
+sal_Bool MSAAServiceImpl::supportsService( OUString const & serviceName ) throw (RuntimeException)
+{
+ // this object only supports one service, so the test is simple
+ return serviceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.accessibility.MSAAService") );
+}
+
+/**
+ * Implemention of XServiceInfo,return all service names.
+ * @param.
+ * @return service name sequence.
+ */
+Sequence< OUString > MSAAServiceImpl::getSupportedServiceNames() throw (RuntimeException)
+{
+ return getSupportedServiceNames_MSAAServiceImpl();
+}
+
+/**
+ * Static method that can create an entity of our MSAA Service
+ * @param xContext No use here.
+ * @return The object interface.
+ */
+Reference< XInterface > SAL_CALL create_MSAAServiceImpl( Reference< XComponentContext > const & /*xContext*/ ) SAL_THROW( () )
+{
+ MSAAServiceImpl* xxx = new MSAAServiceImpl();
+ //return static_cast< lang::XTypeProvider * >( xxx );
+ Reference< XMSAAService > p( xxx );
+ return p;
+}
+
+/**
+ * Constructor.
+ * @param
+ * @return
+ */
+MSAAServiceImpl::MSAAServiceImpl()
+{
+ Reference< XExtendedToolkit > xToolkit =
+ Reference< XExtendedToolkit >(Application::GetVCLToolkit(), UNO_QUERY);
+
+ if(xToolkit.is())
+ {
+ AccTopWindowListener *accListener;
+ accListener = new AccTopWindowListener();
+ g_pTop = accListener;
+ Reference< XTopWindowListener> x(accListener);
+ xToolkit->addTopWindowListener(x);
+ }
+}
+
+/**
+ * Static method that can create an entity of our MSAA Service
+ * @param Destructor
+ * @return
+ */
+MSAAServiceImpl::~MSAAServiceImpl()
+{
+
+ // 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).
+ FreeTopWindowListener();
+
+
+}
+
+}
+
+/* shared lib exports implemented without helpers in service_impl1.cxx */
+namespace my_sc_impl
+{
+static struct ::cppu::ImplementationEntry s_component_entries [] =
+ {
+ {
+ create_MSAAServiceImpl, getImplementationName_MSAAServiceImpl,
+ getSupportedServiceNames_MSAAServiceImpl, ::cppu::createSingleComponentFactory,
+ 0, 0
+ },
+ {
+ create_MSAAServiceImpl, getImplementationName_MSAAServiceImpl,
+ getSupportedServiceNames_MSAAServiceImpl, ::cppu::createSingleComponentFactory,
+ 0, 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+ };
+}
+
+extern "C"
+{
+ void SAL_CALL component_getImplementationEnvironment(
+ sal_Char const ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+ {
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+ }
+ void * SAL_CALL component_getFactory(
+ sal_Char const * implName, lang::XMultiServiceFactory * xMgr,
+ registry::XRegistryKey * xRegistry )
+ {
+ return ::cppu::component_getFactoryHelper(
+ implName, xMgr, xRegistry, ::my_sc_impl::s_component_entries );
+ }
+}
diff --git a/winaccessibility/source/service/winaccessibility.component b/winaccessibility/source/service/winaccessibility.component
new file mode 100644
index 000000000000..d2dfe39573ed
--- /dev/null
+++ b/winaccessibility/source/service/winaccessibility.component
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--**********************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+**********************************************************************-->
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.accessibility.my_sc_implementation.MSAAService">
+ <service name="com.sun.star.accessibility.MSAAService"/>
+ </implementation>
+</component>