/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #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); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */