| /************************************************************** |
| * |
| * 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. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_vcl.hxx" |
| |
| #include <com/sun/star/accessibility/XAccessibleContext.hpp> |
| #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> |
| #include <com/sun/star/accessibility/XAccessibleSelection.hpp> |
| #include <com/sun/star/accessibility/AccessibleEventId.hpp> |
| #include <com/sun/star/accessibility/AccessibleStateType.hpp> |
| // --> OD 2009-04-14 #i93269# |
| #include <com/sun/star/accessibility/XAccessibleText.hpp> |
| // <-- |
| #include <cppuhelper/implbase1.hxx> |
| #include <vos/mutex.hxx> |
| #include <rtl/ref.hxx> |
| |
| #include <vcl/svapp.hxx> |
| #include <vcl/window.hxx> |
| #include <vcl/menu.hxx> |
| #include <vcl/toolbox.hxx> |
| |
| #include "atkwrapper.hxx" |
| #include "atkutil.hxx" |
| |
| #include <gtk/gtk.h> |
| |
| #include <set> |
| |
| // #define ENABLE_TRACING |
| |
| #ifdef ENABLE_TRACING |
| #include <stdio.h> |
| #endif |
| |
| using namespace ::com::sun::star; |
| |
| static uno::WeakReference< accessibility::XAccessible > xNextFocusObject; |
| static guint focus_notify_handler = 0; |
| |
| /*****************************************************************************/ |
| |
| extern "C" { |
| |
| static gint |
| atk_wrapper_focus_idle_handler (gpointer data) |
| { |
| vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| focus_notify_handler = 0; |
| |
| uno::Reference< accessibility::XAccessible > xAccessible = xNextFocusObject; |
| if( xAccessible.get() == reinterpret_cast < accessibility::XAccessible * > (data) ) |
| { |
| AtkObject *atk_obj = xAccessible.is() ? atk_object_wrapper_ref( xAccessible ) : NULL; |
| // Gail does not notify focus changes to NULL, so do we .. |
| if( atk_obj ) |
| { |
| #ifdef ENABLE_TRACING |
| fprintf(stderr, "notifying focus event for %p\n", atk_obj); |
| #endif |
| atk_focus_tracker_notify(atk_obj); |
| // --> OD 2009-04-14 #i93269# |
| // emit text_caret_moved event for <XAccessibleText> object, |
| // if cursor is inside the <XAccessibleText> object. |
| // also emit state-changed:focused event under the same condition. |
| { |
| AtkObjectWrapper* wrapper_obj = ATK_OBJECT_WRAPPER (atk_obj); |
| if( wrapper_obj && !wrapper_obj->mpText && wrapper_obj->mpContext ) |
| { |
| uno::Any any = wrapper_obj->mpContext->queryInterface( accessibility::XAccessibleText::static_type(NULL) ); |
| if ( typelib_TypeClass_INTERFACE == any.pType->eTypeClass && |
| any.pReserved != 0 ) |
| { |
| wrapper_obj->mpText = reinterpret_cast< accessibility::XAccessibleText * > (any.pReserved); |
| if ( wrapper_obj->mpText != 0 ) |
| { |
| wrapper_obj->mpText->acquire(); |
| gint caretPos = wrapper_obj->mpText->getCaretPosition(); |
| |
| if ( caretPos != -1 ) |
| { |
| atk_object_notify_state_change( atk_obj, ATK_STATE_FOCUSED, TRUE ); |
| g_signal_emit_by_name( atk_obj, "text_caret_moved", caretPos ); |
| } |
| } |
| } |
| } |
| } |
| // <-- |
| g_object_unref(atk_obj); |
| } |
| } |
| |
| return FALSE; |
| } |
| |
| } // extern "C" |
| |
| /*****************************************************************************/ |
| |
| static void |
| atk_wrapper_focus_tracker_notify_when_idle( const uno::Reference< accessibility::XAccessible > &xAccessible ) |
| { |
| if( focus_notify_handler ) |
| g_source_remove(focus_notify_handler); |
| |
| xNextFocusObject = xAccessible; |
| |
| focus_notify_handler = g_idle_add (atk_wrapper_focus_idle_handler, xAccessible.get()); |
| } |
| |
| /*****************************************************************************/ |
| |
| class DocumentFocusListener : |
| public ::cppu::WeakImplHelper1< accessibility::XAccessibleEventListener > |
| { |
| |
| std::set< uno::Reference< uno::XInterface > > m_aRefList; |
| |
| public: |
| void attachRecursive( |
| const uno::Reference< accessibility::XAccessible >& xAccessible |
| ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException); |
| |
| void attachRecursive( |
| const uno::Reference< accessibility::XAccessible >& xAccessible, |
| const uno::Reference< accessibility::XAccessibleContext >& xContext |
| ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException); |
| |
| void attachRecursive( |
| const uno::Reference< accessibility::XAccessible >& xAccessible, |
| const uno::Reference< accessibility::XAccessibleContext >& xContext, |
| const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet |
| ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException); |
| |
| void detachRecursive( |
| const uno::Reference< accessibility::XAccessible >& xAccessible |
| ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException); |
| |
| void detachRecursive( |
| const uno::Reference< accessibility::XAccessible >& xAccessible, |
| const uno::Reference< accessibility::XAccessibleContext >& xContext |
| ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException); |
| |
| void detachRecursive( |
| const uno::Reference< accessibility::XAccessible >& xAccessible, |
| const uno::Reference< accessibility::XAccessibleContext >& xContext, |
| const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet |
| ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException); |
| |
| static uno::Reference< accessibility::XAccessible > getAccessible(const lang::EventObject& aEvent ) |
| throw (lang::IndexOutOfBoundsException, uno::RuntimeException); |
| |
| // XEventListener |
| virtual void disposing( const lang::EventObject& Source ) throw (uno::RuntimeException); |
| |
| // XAccessibleEventListener |
| virtual void notifyEvent( const accessibility::AccessibleEventObject& aEvent ) throw( uno::RuntimeException ); |
| }; |
| |
| /*****************************************************************************/ |
| |
| void DocumentFocusListener::disposing( const lang::EventObject& aEvent ) |
| throw (uno::RuntimeException) |
| { |
| // fprintf(stderr, "In DocumentFocusListener::disposing (%p)\n", this); |
| // fprintf(stderr, "m_aRefList has %d entries\n", m_aRefList.size()); |
| |
| // Unref the object here, but do not remove as listener since the object |
| // might no longer be in a state that safely allows this. |
| if( aEvent.Source.is() ) |
| m_aRefList.erase(aEvent.Source); |
| |
| // fprintf(stderr, "m_aRefList has %d entries\n", m_aRefList.size()); |
| |
| } |
| |
| /*****************************************************************************/ |
| |
| void DocumentFocusListener::notifyEvent( const accessibility::AccessibleEventObject& aEvent ) |
| throw( uno::RuntimeException ) |
| { |
| try { |
| switch( aEvent.EventId ) |
| { |
| case accessibility::AccessibleEventId::STATE_CHANGED: |
| { |
| sal_Int16 nState = accessibility::AccessibleStateType::INVALID; |
| aEvent.NewValue >>= nState; |
| |
| if( accessibility::AccessibleStateType::FOCUSED == nState ) |
| atk_wrapper_focus_tracker_notify_when_idle( getAccessible(aEvent) ); |
| } |
| break; |
| |
| case accessibility::AccessibleEventId::CHILD: |
| { |
| uno::Reference< accessibility::XAccessible > xChild; |
| if( (aEvent.OldValue >>= xChild) && xChild.is() ) |
| detachRecursive(xChild); |
| |
| if( (aEvent.NewValue >>= xChild) && xChild.is() ) |
| attachRecursive(xChild); |
| } |
| break; |
| |
| case accessibility::AccessibleEventId::INVALIDATE_ALL_CHILDREN: |
| /* { |
| uno::Reference< accessibility::XAccessible > xAccessible( getAccessible(aEvent) ); |
| detachRecursive(xAccessible); |
| attachRecursive(xAccessible); |
| } |
| */ |
| g_warning( "Invalidate all children called\n" ); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| catch( const lang::IndexOutOfBoundsException& e ) |
| { |
| g_warning("Focused object has invalid index in parent"); |
| } |
| } |
| |
| /*****************************************************************************/ |
| |
| uno::Reference< accessibility::XAccessible > DocumentFocusListener::getAccessible(const lang::EventObject& aEvent ) |
| throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| uno::Reference< accessibility::XAccessible > xAccessible(aEvent.Source, uno::UNO_QUERY); |
| |
| if( xAccessible.is() ) |
| return xAccessible; |
| |
| uno::Reference< accessibility::XAccessibleContext > xContext(aEvent.Source, uno::UNO_QUERY); |
| |
| if( xContext.is() ) |
| { |
| uno::Reference< accessibility::XAccessible > xParent( xContext->getAccessibleParent() ); |
| if( xParent.is() ) |
| { |
| uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() ); |
| if( xParentContext.is() ) |
| { |
| return xParentContext->getAccessibleChild( xContext->getAccessibleIndexInParent() ); |
| } |
| } |
| } |
| |
| return uno::Reference< accessibility::XAccessible >(); |
| } |
| |
| /*****************************************************************************/ |
| |
| void DocumentFocusListener::attachRecursive( |
| const uno::Reference< accessibility::XAccessible >& xAccessible |
| ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| uno::Reference< accessibility::XAccessibleContext > xContext = |
| xAccessible->getAccessibleContext(); |
| |
| if( xContext.is() ) |
| attachRecursive(xAccessible, xContext); |
| } |
| |
| /*****************************************************************************/ |
| |
| void DocumentFocusListener::attachRecursive( |
| const uno::Reference< accessibility::XAccessible >& xAccessible, |
| const uno::Reference< accessibility::XAccessibleContext >& xContext |
| ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| uno::Reference< accessibility::XAccessibleStateSet > xStateSet = |
| xContext->getAccessibleStateSet(); |
| |
| if( xStateSet.is() ) |
| attachRecursive(xAccessible, xContext, xStateSet); |
| } |
| |
| /*****************************************************************************/ |
| |
| void DocumentFocusListener::attachRecursive( |
| const uno::Reference< accessibility::XAccessible >& xAccessible, |
| const uno::Reference< accessibility::XAccessibleContext >& xContext, |
| const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet |
| ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| if( xStateSet->contains(accessibility::AccessibleStateType::FOCUSED ) ) |
| atk_wrapper_focus_tracker_notify_when_idle( xAccessible ); |
| |
| uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster = |
| uno::Reference< accessibility::XAccessibleEventBroadcaster >(xContext, uno::UNO_QUERY); |
| |
| // If not already done, add the broadcaster to the list and attach as listener. |
| if( xBroadcaster.is() && m_aRefList.insert(xBroadcaster).second ) |
| { |
| xBroadcaster->addEventListener(static_cast< accessibility::XAccessibleEventListener *>(this)); |
| |
| if( ! xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) ) |
| { |
| sal_Int32 n, nmax = xContext->getAccessibleChildCount(); |
| for( n = 0; n < nmax; n++ ) |
| { |
| uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) ); |
| |
| if( xChild.is() ) |
| attachRecursive(xChild); |
| } |
| } |
| } |
| } |
| |
| /*****************************************************************************/ |
| |
| void DocumentFocusListener::detachRecursive( |
| const uno::Reference< accessibility::XAccessible >& xAccessible |
| ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| uno::Reference< accessibility::XAccessibleContext > xContext = |
| xAccessible->getAccessibleContext(); |
| |
| if( xContext.is() ) |
| detachRecursive(xAccessible, xContext); |
| } |
| |
| /*****************************************************************************/ |
| |
| void DocumentFocusListener::detachRecursive( |
| const uno::Reference< accessibility::XAccessible >& xAccessible, |
| const uno::Reference< accessibility::XAccessibleContext >& xContext |
| ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| uno::Reference< accessibility::XAccessibleStateSet > xStateSet = |
| xContext->getAccessibleStateSet(); |
| |
| if( xStateSet.is() ) |
| detachRecursive(xAccessible, xContext, xStateSet); |
| } |
| |
| /*****************************************************************************/ |
| |
| void DocumentFocusListener::detachRecursive( |
| const uno::Reference< accessibility::XAccessible >&, |
| const uno::Reference< accessibility::XAccessibleContext >& xContext, |
| const uno::Reference< accessibility::XAccessibleStateSet >& xStateSet |
| ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster = |
| uno::Reference< accessibility::XAccessibleEventBroadcaster >(xContext, uno::UNO_QUERY); |
| |
| if( xBroadcaster.is() && 0 < m_aRefList.erase(xBroadcaster) ) |
| { |
| xBroadcaster->removeEventListener(static_cast< accessibility::XAccessibleEventListener *>(this)); |
| |
| if( ! xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS ) ) |
| { |
| sal_Int32 n, nmax = xContext->getAccessibleChildCount(); |
| for( n = 0; n < nmax; n++ ) |
| { |
| uno::Reference< accessibility::XAccessible > xChild( xContext->getAccessibleChild( n ) ); |
| |
| if( xChild.is() ) |
| detachRecursive(xChild); |
| } |
| } |
| } |
| } |
| |
| /*****************************************************************************/ |
| |
| /* |
| * page tabs in gtk are widgets, so we need to simulate focus events for those |
| */ |
| |
| static void handle_tabpage_activated(Window *pWindow) |
| { |
| uno::Reference< accessibility::XAccessible > xAccessible = |
| pWindow->GetAccessible(); |
| |
| if( ! xAccessible.is() ) |
| return; |
| |
| uno::Reference< accessibility::XAccessibleSelection > xSelection( |
| xAccessible->getAccessibleContext(), uno::UNO_QUERY); |
| |
| if( xSelection.is() ) |
| atk_wrapper_focus_tracker_notify_when_idle( xSelection->getSelectedAccessibleChild(0) ); |
| } |
| |
| /*****************************************************************************/ |
| |
| /* |
| * toolbar items in gtk are widgets, so we need to simulate focus events for those |
| */ |
| |
| static void notify_toolbox_item_focus(ToolBox *pToolBox) |
| { |
| uno::Reference< accessibility::XAccessible > xAccessible = |
| pToolBox->GetAccessible(); |
| |
| if( ! xAccessible.is() ) |
| return; |
| |
| uno::Reference< accessibility::XAccessibleContext > xContext = |
| xAccessible->getAccessibleContext(); |
| |
| if( ! xContext.is() ) |
| return; |
| |
| sal_Int32 nPos = pToolBox->GetItemPos( pToolBox->GetHighlightItemId() ); |
| if( nPos != TOOLBOX_ITEM_NOTFOUND ) |
| atk_wrapper_focus_tracker_notify_when_idle( xContext->getAccessibleChild( nPos ) ); |
| } |
| |
| static void handle_toolbox_highlight(Window *pWindow) |
| { |
| ToolBox *pToolBox = static_cast <ToolBox *> (pWindow); |
| |
| // Make sure either the toolbox or its parent toolbox has the focus |
| if ( ! pToolBox->HasFocus() ) |
| { |
| ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() ); |
| if ( ! pToolBoxParent || ! pToolBoxParent->HasFocus() ) |
| return; |
| } |
| |
| notify_toolbox_item_focus(pToolBox); |
| } |
| |
| static void handle_toolbox_highlightoff(Window *pWindow) |
| { |
| ToolBox *pToolBox = static_cast <ToolBox *> (pWindow); |
| ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() ); |
| |
| // Notify when leaving sub toolboxes |
| if( pToolBoxParent && pToolBoxParent->HasFocus() ) |
| notify_toolbox_item_focus( pToolBoxParent ); |
| } |
| |
| /*****************************************************************************/ |
| |
| static void create_wrapper_for_child( |
| const uno::Reference< accessibility::XAccessibleContext >& xContext, |
| sal_Int32 index) |
| { |
| if( xContext.is() ) |
| { |
| uno::Reference< accessibility::XAccessible > xChild(xContext->getAccessibleChild(index)); |
| if( xChild.is() ) |
| { |
| // create the wrapper object - it will survive the unref unless it is a transient object |
| g_object_unref( atk_object_wrapper_ref( xChild ) ); |
| } |
| } |
| } |
| |
| /*****************************************************************************/ |
| |
| static void handle_toolbox_buttonchange(VclWindowEvent const *pEvent) |
| { |
| Window* pWindow = pEvent->GetWindow(); |
| sal_Int32 index = (sal_Int32)(sal_IntPtr) pEvent->GetData(); |
| |
| if( pWindow && pWindow->IsReallyVisible() ) |
| { |
| uno::Reference< accessibility::XAccessible > xAccessible(pWindow->GetAccessible()); |
| if( xAccessible.is() ) |
| { |
| create_wrapper_for_child(xAccessible->getAccessibleContext(), index); |
| } |
| } |
| } |
| |
| /*****************************************************************************/ |
| |
| /* currently not needed anymore... |
| static void create_wrapper_for_children(Window *pWindow) |
| { |
| if( pWindow && pWindow->IsReallyVisible() ) |
| { |
| uno::Reference< accessibility::XAccessible > xAccessible(pWindow->GetAccessible()); |
| if( xAccessible.is() ) |
| { |
| uno::Reference< accessibility::XAccessibleContext > xContext(xAccessible->getAccessibleContext()); |
| if( xContext.is() ) |
| { |
| sal_Int32 nChildren = xContext->getAccessibleChildCount(); |
| for( sal_Int32 i = 0; i < nChildren; ++i ) |
| create_wrapper_for_child(xContext, i); |
| } |
| } |
| } |
| } |
| */ |
| |
| /*****************************************************************************/ |
| |
| static std::set< Window * > g_aWindowList; |
| |
| static void handle_get_focus(::VclWindowEvent const * pEvent) |
| { |
| static rtl::Reference< DocumentFocusListener > aDocumentFocusListener = |
| new DocumentFocusListener(); |
| |
| Window *pWindow = pEvent->GetWindow(); |
| |
| // The menu bar is handled through VCLEVENT_MENU_HIGHLIGHTED |
| if( ! pWindow || !pWindow->IsReallyVisible() || pWindow->GetType() == WINDOW_MENUBARWINDOW ) |
| return; |
| |
| // ToolBoxes are handled through VCLEVENT_TOOLBOX_HIGHLIGHT |
| if( pWindow->GetType() == WINDOW_TOOLBOX ) |
| return; |
| |
| if( pWindow->GetType() == WINDOW_TABCONTROL ) |
| { |
| handle_tabpage_activated( pWindow ); |
| return; |
| } |
| |
| uno::Reference< accessibility::XAccessible > xAccessible = |
| pWindow->GetAccessible(); |
| |
| if( ! xAccessible.is() ) |
| return; |
| |
| uno::Reference< accessibility::XAccessibleContext > xContext = |
| xAccessible->getAccessibleContext(); |
| |
| if( ! xContext.is() ) |
| return; |
| |
| uno::Reference< accessibility::XAccessibleStateSet > xStateSet = |
| xContext->getAccessibleStateSet(); |
| |
| if( ! xStateSet.is() ) |
| return; |
| |
| /* the UNO ToolBox wrapper does not (yet?) support XAccessibleSelection, so we |
| * need to add listeners to the children instead of re-using the tabpage stuff |
| */ |
| if( xStateSet->contains(accessibility::AccessibleStateType::FOCUSED) && |
| ( pWindow->GetType() != WINDOW_TREELISTBOX ) ) |
| { |
| atk_wrapper_focus_tracker_notify_when_idle( xAccessible ); |
| } |
| else |
| { |
| if( g_aWindowList.find(pWindow) == g_aWindowList.end() ) |
| { |
| g_aWindowList.insert(pWindow); |
| try |
| { |
| aDocumentFocusListener->attachRecursive(xAccessible, xContext, xStateSet); |
| } |
| catch( const uno::Exception &e ) |
| { |
| g_warning( "Exception caught processing focus events" ); |
| } |
| } |
| #ifdef ENABLE_TRACING |
| else |
| fprintf(stderr, "Window %p already in the list\n", pWindow ); |
| #endif |
| } |
| } |
| |
| /*****************************************************************************/ |
| |
| static void handle_menu_highlighted(::VclMenuEvent const * pEvent) |
| { |
| try |
| { |
| Menu* pMenu = pEvent->GetMenu(); |
| sal_uInt16 nPos = pEvent->GetItemPos(); |
| |
| if( pMenu && nPos != 0xFFFF) |
| { |
| uno::Reference< accessibility::XAccessible > xAccessible ( pMenu->GetAccessible() ); |
| |
| if( xAccessible.is() ) |
| { |
| uno::Reference< accessibility::XAccessibleContext > xContext ( xAccessible->getAccessibleContext() ); |
| |
| if( xContext.is() ) |
| atk_wrapper_focus_tracker_notify_when_idle( xContext->getAccessibleChild( nPos ) ); |
| } |
| } |
| } |
| catch( const uno::Exception& e ) |
| { |
| g_warning( "Exception caught processing menu highlight events" ); |
| } |
| } |
| |
| /*****************************************************************************/ |
| |
| long WindowEventHandler(void *, ::VclSimpleEvent const * pEvent) |
| { |
| switch (pEvent->GetId()) |
| { |
| case VCLEVENT_WINDOW_SHOW: |
| // fprintf(stderr, "got VCLEVENT_WINDOW_SHOW for %p\n", |
| // static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); |
| break; |
| case VCLEVENT_WINDOW_HIDE: |
| // fprintf(stderr, "got VCLEVENT_WINDOW_HIDE for %p\n", |
| // static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); |
| break; |
| case VCLEVENT_WINDOW_CLOSE: |
| // fprintf(stderr, "got VCLEVENT_WINDOW_CLOSE for %p\n", |
| // static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); |
| break; |
| case VCLEVENT_WINDOW_GETFOCUS: |
| handle_get_focus(static_cast< ::VclWindowEvent const * >(pEvent)); |
| break; |
| case VCLEVENT_WINDOW_LOSEFOCUS: |
| // fprintf(stderr, "got VCLEVENT_WINDOW_LOSEFOCUS for %p\n", |
| // static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); |
| break; |
| case VCLEVENT_WINDOW_MINIMIZE: |
| // fprintf(stderr, "got VCLEVENT_WINDOW_MINIMIZE for %p\n", |
| // static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); |
| break; |
| case VCLEVENT_WINDOW_NORMALIZE: |
| // fprintf(stderr, "got VCLEVENT_WINDOW_NORMALIZE for %p\n", |
| // static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); |
| break; |
| case VCLEVENT_WINDOW_KEYINPUT: |
| case VCLEVENT_WINDOW_KEYUP: |
| case VCLEVENT_WINDOW_COMMAND: |
| case VCLEVENT_WINDOW_MOUSEMOVE: |
| break; |
| /* |
| fprintf(stderr, "got VCLEVENT_WINDOW_COMMAND (%d) for %p\n", |
| static_cast< ::CommandEvent const * > ( |
| static_cast< ::VclWindowEvent const * >(pEvent)->GetData())->GetCommand(), |
| static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); |
| */ |
| case VCLEVENT_MENU_HIGHLIGHT: |
| if (const VclMenuEvent* pMenuEvent = dynamic_cast<const VclMenuEvent*>(pEvent)) |
| { |
| handle_menu_highlighted(pMenuEvent); |
| } |
| else if (const VclAccessibleEvent* pAccEvent = dynamic_cast<const VclAccessibleEvent*>(pEvent)) |
| { |
| uno::Reference< accessibility::XAccessible > xAccessible = pAccEvent->GetAccessible(); |
| if (xAccessible.is()) |
| atk_wrapper_focus_tracker_notify_when_idle(xAccessible); |
| } |
| break; |
| |
| case VCLEVENT_TOOLBOX_HIGHLIGHT: |
| handle_toolbox_highlight(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); |
| break; |
| |
| case VCLEVENT_TOOLBOX_BUTTONSTATECHANGED: |
| handle_toolbox_buttonchange(static_cast< ::VclWindowEvent const * >(pEvent)); |
| break; |
| |
| case VCLEVENT_OBJECT_DYING: |
| g_aWindowList.erase( static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow() ); |
| // fallthrough intentional ! |
| case VCLEVENT_TOOLBOX_HIGHLIGHTOFF: |
| handle_toolbox_highlightoff(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); |
| break; |
| |
| case VCLEVENT_TABPAGE_ACTIVATE: |
| handle_tabpage_activated(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); |
| break; |
| |
| case VCLEVENT_COMBOBOX_SETTEXT: |
| // MT 2010/02: This looks quite strange to me. Stumbled over this when fixing #i104290#. |
| // This kicked in when leaving the combobox in the toolbar, after that the events worked. |
| // I guess this was a try to work around missing combobox events, which didn't do the full job, and shouldn't be necessary anymore. |
| // Fix for #i104290# was done in toolkit/source/awt/vclxaccessiblecomponent, FOCUSED state for compound controls in general. |
| // create_wrapper_for_children(static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow()); |
| break; |
| |
| default: |
| // OSL_TRACE("got event %d \n", pEvent->GetId()); |
| break; |
| } |
| return 0; |
| } |
| |
| static Link g_aEventListenerLink( NULL, (PSTUB) WindowEventHandler ); |
| |
| /*****************************************************************************/ |
| |
| extern "C" { |
| |
| static G_CONST_RETURN gchar * |
| ooo_atk_util_get_toolkit_name (void) |
| { |
| return "VCL"; |
| } |
| |
| /*****************************************************************************/ |
| |
| static G_CONST_RETURN gchar * |
| ooo_atk_util_get_toolkit_version (void) |
| { |
| /* |
| * Version is passed in as a -D flag when this file is |
| * compiled. |
| */ |
| |
| return VERSION; |
| } |
| |
| /*****************************************************************************/ |
| |
| /* |
| * GObject inheritance |
| */ |
| |
| static void |
| ooo_atk_util_class_init (AtkUtilClass *) |
| { |
| AtkUtilClass *atk_class; |
| gpointer data; |
| |
| data = g_type_class_peek (ATK_TYPE_UTIL); |
| atk_class = ATK_UTIL_CLASS (data); |
| |
| atk_class->get_toolkit_name = ooo_atk_util_get_toolkit_name; |
| atk_class->get_toolkit_version = ooo_atk_util_get_toolkit_version; |
| |
| Application::AddEventListener( g_aEventListenerLink ); |
| } |
| |
| } // extern "C" |
| |
| /*****************************************************************************/ |
| |
| GType |
| ooo_atk_util_get_type (void) |
| { |
| static GType type = 0; |
| |
| if (!type) |
| { |
| GType parent_type = g_type_from_name( "GailUtil" ); |
| |
| if( ! parent_type ) |
| { |
| g_warning( "Unknown type: GailUtil" ); |
| parent_type = ATK_TYPE_UTIL; |
| } |
| |
| GTypeQuery type_query; |
| g_type_query( parent_type, &type_query ); |
| |
| static const GTypeInfo typeInfo = |
| { |
| type_query.class_size, |
| (GBaseInitFunc) NULL, |
| (GBaseFinalizeFunc) NULL, |
| (GClassInitFunc) ooo_atk_util_class_init, |
| (GClassFinalizeFunc) NULL, |
| NULL, |
| type_query.instance_size, |
| 0, |
| (GInstanceInitFunc) NULL, |
| NULL |
| } ; |
| |
| type = g_type_register_static (parent_type, "OOoUtil", &typeInfo, (GTypeFlags)0) ; |
| } |
| |
| return type; |
| } |
| |
| |