diff options
Diffstat (limited to 'winaccessibility/source/service')
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> |