summaryrefslogtreecommitdiff
path: root/winaccessibility/source/service/AccEventListener.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'winaccessibility/source/service/AccEventListener.cxx')
-rw-r--r--winaccessibility/source/service/AccEventListener.cxx309
1 files changed, 309 insertions, 0 deletions
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
+ }
+}