LCOV - code coverage report
Current view: top level - libreoffice/toolkit/source/awt - vclxaccessiblecomponent.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 391 0.0 %
Date: 2012-12-27 Functions: 0 42 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/accessibility/AccessibleRole.hpp>
      21             : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
      22             : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
      23             : #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
      24             : #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
      25             : #include <toolkit/awt/vclxaccessiblecomponent.hxx>
      26             : #include <toolkit/helper/externallock.hxx>
      27             : #include <toolkit/awt/vclxwindow.hxx>
      28             : #include <toolkit/helper/convert.hxx>
      29             : #include <toolkit/awt/vclxfont.hxx>
      30             : #include <vcl/dialog.hxx>
      31             : #include <vcl/window.hxx>
      32             : #include <tools/debug.hxx>
      33             : #include <unotools/accessiblestatesethelper.hxx>
      34             : #include <unotools/accessiblerelationsethelper.hxx>
      35             : #include <vcl/svapp.hxx>
      36             : #include <vcl/menu.hxx>
      37             : 
      38             : #ifndef VCLEVENT_WINDOW_FRAMETITLECHANGED
      39             : #define VCLEVENT_WINDOW_FRAMETITLECHANGED   1018    // pData = XubString* = oldTitle
      40             : #endif
      41             : 
      42             : using namespace ::com::sun::star;
      43             : using namespace ::comphelper;
      44             : 
      45             : 
      46             : DBG_NAME(VCLXAccessibleComponent)
      47             : 
      48             : 
      49             : //  ----------------------------------------------------
      50             : //  class VCLXAccessibleComponent
      51             : //  ----------------------------------------------------
      52           0 : VCLXAccessibleComponent::VCLXAccessibleComponent( VCLXWindow* pVCLXindow )
      53             :     : AccessibleExtendedComponentHelper_BASE( new VCLExternalSolarLock() )
      54           0 :     , OAccessibleImplementationAccess( )
      55             : {
      56             :     DBG_CTOR( VCLXAccessibleComponent, 0 );
      57           0 :     mpVCLXindow = pVCLXindow;
      58           0 :     mxWindow = pVCLXindow;
      59             : 
      60           0 :     m_pSolarLock = static_cast< VCLExternalSolarLock* >( getExternalLock( ) );
      61             : 
      62             :     DBG_ASSERT( pVCLXindow->GetWindow(), "VCLXAccessibleComponent - no window!" );
      63           0 :     if ( pVCLXindow->GetWindow() )
      64             :     {
      65           0 :       pVCLXindow->GetWindow()->AddEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
      66           0 :       pVCLXindow->GetWindow()->AddChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
      67             :     }
      68             : 
      69             :     // announce the XAccessible of our creator to the base class
      70           0 :     lateInit( pVCLXindow );
      71           0 : }
      72             : 
      73           0 : VCLXAccessibleComponent::~VCLXAccessibleComponent()
      74             : {
      75             :     DBG_DTOR( VCLXAccessibleComponent, 0 );
      76             : 
      77           0 :     ensureDisposed();
      78             : 
      79           0 :     if ( mpVCLXindow && mpVCLXindow->GetWindow() )
      80             :     {
      81           0 :         mpVCLXindow->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
      82           0 :         mpVCLXindow->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
      83             :     }
      84             : 
      85           0 :     delete m_pSolarLock;
      86           0 :     m_pSolarLock = NULL;
      87             :     // This is not completely safe. If we assume that the base class dtor calls some method which
      88             :     // uses this lock, the we crash. However, as the base class' dtor does not have a chance to call _out_
      89             :     // virtual methods, this is no problem as long as the base class is safe, i.e. does not use the external
      90             :     // lock from within it's dtor. At the moment, we _know_ the base class is safe in this respect, so
      91             :     // let's assume it keeps this way.
      92             :     // @see OAccessibleContextHelper::OAccessibleContextHelper( IMutex* )
      93           0 : }
      94             : 
      95           0 : IMPLEMENT_FORWARD_XINTERFACE3( VCLXAccessibleComponent, AccessibleExtendedComponentHelper_BASE, OAccessibleImplementationAccess, VCLXAccessibleComponent_BASE )
      96           0 : IMPLEMENT_FORWARD_XTYPEPROVIDER3( VCLXAccessibleComponent, AccessibleExtendedComponentHelper_BASE, OAccessibleImplementationAccess, VCLXAccessibleComponent_BASE )
      97             : 
      98           0 : ::rtl::OUString VCLXAccessibleComponent::getImplementationName() throw (uno::RuntimeException)
      99             : {
     100           0 :     return ::rtl::OUString("com.sun.star.comp.toolkit.AccessibleWindow");
     101             : }
     102             : 
     103           0 : sal_Bool VCLXAccessibleComponent::supportsService( const ::rtl::OUString& rServiceName ) throw (uno::RuntimeException)
     104             : {
     105           0 :     uno::Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
     106           0 :     const ::rtl::OUString* pNames = aNames.getConstArray();
     107           0 :     const ::rtl::OUString* pEnd = pNames + aNames.getLength();
     108           0 :     for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
     109             :         ;
     110             : 
     111           0 :     return pNames != pEnd;
     112             : }
     113             : 
     114           0 : uno::Sequence< ::rtl::OUString > VCLXAccessibleComponent::getSupportedServiceNames() throw (uno::RuntimeException)
     115             : {
     116           0 :     uno::Sequence< ::rtl::OUString > aNames(1);
     117           0 :     aNames[0] = ::rtl::OUString("com.sun.star.awt.AccessibleWindow");
     118           0 :     return aNames;
     119             : }
     120             : 
     121           0 : IMPL_LINK( VCLXAccessibleComponent, WindowEventListener, VclSimpleEvent*, pEvent )
     122             : {
     123             :     DBG_CHKTHIS(VCLXAccessibleComponent,0);
     124             : 
     125             :     DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
     126             : 
     127             :         /* Ignore VCLEVENT_WINDOW_ENDPOPUPMODE, because the UNO accessibility wrapper
     128             :          * might have been destroyed by the previous VCLEventListener (if no AT tool
     129             :          * is running), e.g. sub-toolbars in impress.
     130             :          */
     131           0 :     if ( pEvent && pEvent->ISA( VclWindowEvent ) && mxWindow.is() /* #122218# */ && (pEvent->GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE) )
     132             :     {
     133             :         DBG_ASSERT( ((VclWindowEvent*)pEvent)->GetWindow(), "Window???" );
     134           0 :         if( !((VclWindowEvent*)pEvent)->GetWindow()->IsAccessibilityEventsSuppressed() || ( pEvent->GetId() == VCLEVENT_OBJECT_DYING ) )
     135             :         {
     136           0 :             ProcessWindowEvent( *(VclWindowEvent*)pEvent );
     137             :         }
     138             :     }
     139           0 :     return 0;
     140             : }
     141             : 
     142           0 : IMPL_LINK( VCLXAccessibleComponent, WindowChildEventListener, VclSimpleEvent*, pEvent )
     143             : {
     144             :     DBG_CHKTHIS(VCLXAccessibleComponent,0);
     145             : 
     146             :     DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
     147           0 :     if ( pEvent && pEvent->ISA( VclWindowEvent ) && mxWindow.is() /* #i68079# */ )
     148             :     {
     149             :         DBG_ASSERT( ((VclWindowEvent*)pEvent)->GetWindow(), "Window???" );
     150           0 :         if( !((VclWindowEvent*)pEvent)->GetWindow()->IsAccessibilityEventsSuppressed() )
     151             :         {
     152             :             // #103087# to prevent an early release of the component
     153           0 :             uno::Reference< accessibility::XAccessibleContext > xTmp = this;
     154             : 
     155           0 :             ProcessWindowChildEvent( *(VclWindowEvent*)pEvent );
     156             :         }
     157             :     }
     158           0 :     return 0;
     159             : }
     160             : 
     161           0 : uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::GetChildAccessible( const VclWindowEvent& rVclWindowEvent )
     162             : {
     163             :     // checks if the data in the window event is our direct child
     164             :     // and returns its accessible
     165             : 
     166             :     // MT: Change this later, normaly a show/hide event shouldn't have the Window* in pData.
     167           0 :     Window* pChildWindow = (Window *) rVclWindowEvent.GetData();
     168           0 :     if( pChildWindow && GetWindow() == pChildWindow->GetAccessibleParentWindow() )
     169           0 :         return pChildWindow->GetAccessible( rVclWindowEvent.GetId() == VCLEVENT_WINDOW_SHOW );
     170             :     else
     171           0 :         return uno::Reference< accessibility::XAccessible > ();
     172             : }
     173             : 
     174           0 : void VCLXAccessibleComponent::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent )
     175             : {
     176           0 :     uno::Any aOldValue, aNewValue;
     177           0 :     uno::Reference< accessibility::XAccessible > xAcc;
     178             : 
     179           0 :     switch ( rVclWindowEvent.GetId() )
     180             :     {
     181             :         case VCLEVENT_WINDOW_SHOW:  // send create on show for direct accessible children
     182             :         {
     183           0 :             xAcc = GetChildAccessible( rVclWindowEvent );
     184           0 :             if( xAcc.is() )
     185             :             {
     186           0 :                 aNewValue <<= xAcc;
     187           0 :                 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
     188             :             }
     189             :         }
     190           0 :         break;
     191             :         case VCLEVENT_WINDOW_HIDE:  // send destroy on hide for direct accessible children
     192             :         {
     193           0 :             xAcc = GetChildAccessible( rVclWindowEvent );
     194           0 :             if( xAcc.is() )
     195             :             {
     196           0 :                 aOldValue <<= xAcc;
     197           0 :                 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
     198             :             }
     199             :         }
     200           0 :         break;
     201           0 :     }
     202           0 : }
     203             : 
     204           0 : void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
     205             : {
     206           0 :     uno::Any aOldValue, aNewValue;
     207             : 
     208           0 :     Window* pAccWindow = rVclWindowEvent.GetWindow();
     209             :     DBG_ASSERT( pAccWindow, "VCLXAccessibleComponent::ProcessWindowEvent - Window?" );
     210             : 
     211           0 :     switch ( rVclWindowEvent.GetId() )
     212             :     {
     213             :         case VCLEVENT_OBJECT_DYING:
     214             :         {
     215           0 :             pAccWindow->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
     216           0 :             pAccWindow->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
     217           0 :             mxWindow.clear();
     218           0 :             mpVCLXindow = NULL;
     219             :         }
     220           0 :         break;
     221             :         //
     222             :         // dont handle CHILDCREATED events here
     223             :         // they are handled separately as child events, see ProcessWindowChildEvent above
     224             :         //
     225             :         /*
     226             :         case VCLEVENT_WINDOW_CHILDCREATED:
     227             :         {
     228             :             Window* pWindow = (Window*) rVclWindowEvent.GetData();
     229             :             DBG_ASSERT( pWindow, "VCLEVENT_WINDOW_CHILDCREATED - Window=?" );
     230             :             aNewValue <<= pWindow->GetAccessible();
     231             :             NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
     232             :         }
     233             :         break;
     234             :         */
     235             :         case VCLEVENT_WINDOW_CHILDDESTROYED:
     236             :         {
     237           0 :             Window* pWindow = (Window*) rVclWindowEvent.GetData();
     238             :             DBG_ASSERT( pWindow, "VCLEVENT_WINDOW_CHILDDESTROYED - Window=?" );
     239           0 :             if ( pWindow->GetAccessible( sal_False ).is() )
     240             :             {
     241           0 :                 aOldValue <<= pWindow->GetAccessible( sal_False );
     242           0 :                 NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
     243             :             }
     244             :         }
     245           0 :         break;
     246             : 
     247             :         //
     248             :         // show and hide will be handled as child events only and are
     249             :         // responsible for sending create/destroy events, see ProcessWindowChildEvent above
     250             :         //
     251             :         /*
     252             :         case VCLEVENT_WINDOW_SHOW:
     253             :         {
     254             :             aNewValue <<= accessibility::AccessibleStateType::VISIBLE;
     255             :             NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     256             : 
     257             :             aNewValue <<= accessibility::AccessibleStateType::SHOWING;
     258             :             NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     259             : 
     260             :             aNewValue.clear();
     261             :             aOldValue <<= accessibility::AccessibleStateType::INVALID;
     262             :             NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     263             :         }
     264             :         break;
     265             :         case VCLEVENT_WINDOW_HIDE:
     266             :         {
     267             :             aOldValue <<= accessibility::AccessibleStateType::VISIBLE;
     268             :             NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     269             : 
     270             :             aOldValue <<= accessibility::AccessibleStateType::SHOWING;
     271             :             NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     272             : 
     273             :             aOldValue.clear();
     274             :             aNewValue <<= accessibility::AccessibleStateType::INVALID;
     275             :             NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     276             :         }
     277             :         break;
     278             :         */
     279             :         case VCLEVENT_WINDOW_ACTIVATE:
     280             :         {
     281             :             // avoid notification if a child frame is already active
     282             :             // only one frame may be active at a given time
     283           0 :             if ( !pAccWindow->HasActiveChildFrame() &&
     284           0 :                  ( getAccessibleRole() == accessibility::AccessibleRole::FRAME ||
     285           0 :                    getAccessibleRole() == accessibility::AccessibleRole::ALERT ||
     286           0 :                    getAccessibleRole() == accessibility::AccessibleRole::DIALOG ) )  // #i18891#
     287             :             {
     288           0 :                 aNewValue <<= accessibility::AccessibleStateType::ACTIVE;
     289           0 :                 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     290             :             }
     291             :         }
     292           0 :         break;
     293             :         case VCLEVENT_WINDOW_DEACTIVATE:
     294             :         {
     295           0 :             if ( getAccessibleRole() == accessibility::AccessibleRole::FRAME ||
     296           0 :                  getAccessibleRole() == accessibility::AccessibleRole::ALERT ||
     297           0 :                  getAccessibleRole() == accessibility::AccessibleRole::DIALOG )  // #i18891#
     298             :             {
     299           0 :                 aOldValue <<= accessibility::AccessibleStateType::ACTIVE;
     300           0 :                 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     301             :             }
     302             :         }
     303           0 :         break;
     304             :         case VCLEVENT_WINDOW_GETFOCUS:
     305             :         case VCLEVENT_CONTROL_GETFOCUS:
     306             :         {
     307           0 :             if( (pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VCLEVENT_CONTROL_GETFOCUS) ||
     308           0 :                 (!pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VCLEVENT_WINDOW_GETFOCUS) )
     309             :             {
     310             :                 // if multiple listeners were registered it is possible that the
     311             :                 // focus was changed during event processing (eg SfxTopWindow )
     312             :                 // #106082# allow ChildPathFocus only for CompoundControls, for windows the focus must be in the window itself
     313           0 :                 if( (pAccWindow->IsCompoundControl() && pAccWindow->HasChildPathFocus()) ||
     314           0 :                     (!pAccWindow->IsCompoundControl() && pAccWindow->HasFocus()) )
     315             :                 {
     316           0 :                     aNewValue <<= accessibility::AccessibleStateType::FOCUSED;
     317           0 :                     NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     318             :                 }
     319             :             }
     320             :         }
     321           0 :         break;
     322             :         case VCLEVENT_WINDOW_LOSEFOCUS:
     323             :         case VCLEVENT_CONTROL_LOSEFOCUS:
     324             :         {
     325           0 :             if( (pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VCLEVENT_CONTROL_LOSEFOCUS) ||
     326           0 :                 (!pAccWindow->IsCompoundControl() && rVclWindowEvent.GetId() == VCLEVENT_WINDOW_LOSEFOCUS) )
     327             :             {
     328           0 :                 aOldValue <<= accessibility::AccessibleStateType::FOCUSED;
     329           0 :                 NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     330             :             }
     331             :         }
     332           0 :         break;
     333             :         case VCLEVENT_WINDOW_FRAMETITLECHANGED:
     334             :         {
     335           0 :             ::rtl::OUString aOldName( *((::rtl::OUString*) rVclWindowEvent.GetData()) );
     336           0 :             ::rtl::OUString aNewName( getAccessibleName() );
     337           0 :             aOldValue <<= aOldName;
     338           0 :             aNewValue <<= aNewName;
     339           0 :             NotifyAccessibleEvent( accessibility::AccessibleEventId::NAME_CHANGED, aOldValue, aNewValue );
     340             :         }
     341           0 :         break;
     342             :         case VCLEVENT_WINDOW_ENABLED:
     343             :         {
     344           0 :             aNewValue <<= accessibility::AccessibleStateType::ENABLED;
     345           0 :             NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     346           0 :             aNewValue <<= accessibility::AccessibleStateType::SENSITIVE;
     347           0 :             NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     348             :         }
     349           0 :         break;
     350             :         case VCLEVENT_WINDOW_DISABLED:
     351             :         {
     352           0 :             aOldValue <<= accessibility::AccessibleStateType::SENSITIVE;
     353           0 :             NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     354             : 
     355           0 :             aOldValue <<= accessibility::AccessibleStateType::ENABLED;
     356           0 :             NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     357             :         }
     358           0 :         break;
     359             :         case VCLEVENT_WINDOW_MOVE:
     360             :         case VCLEVENT_WINDOW_RESIZE:
     361             :         {
     362           0 :             NotifyAccessibleEvent( accessibility::AccessibleEventId::BOUNDRECT_CHANGED, aOldValue, aNewValue );
     363             :         }
     364           0 :         break;
     365             :         case VCLEVENT_WINDOW_MENUBARADDED:
     366             :         {
     367           0 :             MenuBar* pMenuBar = (MenuBar*) rVclWindowEvent.GetData();
     368           0 :             if ( pMenuBar )
     369             :             {
     370           0 :                 uno::Reference< accessibility::XAccessible > xChild( pMenuBar->GetAccessible() );
     371           0 :                 if ( xChild.is() )
     372             :                 {
     373           0 :                     aNewValue <<= xChild;
     374           0 :                     NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
     375           0 :                 }
     376             :             }
     377             :         }
     378           0 :         break;
     379             :         case VCLEVENT_WINDOW_MENUBARREMOVED:
     380             :         {
     381           0 :             MenuBar* pMenuBar = (MenuBar*) rVclWindowEvent.GetData();
     382           0 :             if ( pMenuBar )
     383             :             {
     384           0 :                 uno::Reference< accessibility::XAccessible > xChild( pMenuBar->GetAccessible() );
     385           0 :                 if ( xChild.is() )
     386             :                 {
     387           0 :                     aOldValue <<= xChild;
     388           0 :                     NotifyAccessibleEvent( accessibility::AccessibleEventId::CHILD, aOldValue, aNewValue );
     389           0 :                 }
     390             :             }
     391             :         }
     392           0 :         break;
     393             :         case VCLEVENT_WINDOW_MINIMIZE:
     394             :         {
     395           0 :             aNewValue <<= accessibility::AccessibleStateType::ICONIFIED;
     396           0 :             NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     397             :         }
     398           0 :         break;
     399             :         case VCLEVENT_WINDOW_NORMALIZE:
     400             :         {
     401           0 :             aOldValue <<= accessibility::AccessibleStateType::ICONIFIED;
     402           0 :             NotifyAccessibleEvent( accessibility::AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
     403             :         }
     404           0 :         break;
     405             :         default:
     406             :         {
     407             :         }
     408           0 :         break;
     409           0 :     }
     410           0 : }
     411             : 
     412           0 : void VCLXAccessibleComponent::disposing()
     413             : {
     414           0 :     if ( mpVCLXindow && mpVCLXindow->GetWindow() )
     415             :     {
     416           0 :         mpVCLXindow->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
     417           0 :         mpVCLXindow->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
     418             :     }
     419             : 
     420           0 :     AccessibleExtendedComponentHelper_BASE::disposing();
     421             : 
     422           0 :     mxWindow.clear();
     423           0 :     mpVCLXindow = NULL;
     424           0 : }
     425             : 
     426           0 : Window* VCLXAccessibleComponent::GetWindow() const
     427             : {
     428           0 :     return GetVCLXWindow() ? GetVCLXWindow()->GetWindow() : NULL;
     429             : }
     430             : 
     431           0 : void VCLXAccessibleComponent::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet )
     432             : {
     433           0 :     Window* pWindow = GetWindow();
     434           0 :     if ( pWindow )
     435             :     {
     436           0 :         Window *pLabeledBy = pWindow->GetAccessibleRelationLabeledBy();
     437           0 :         if ( pLabeledBy && pLabeledBy != pWindow )
     438             :         {
     439           0 :             uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
     440           0 :             aSequence[0] = pLabeledBy->GetAccessible();
     441           0 :             rRelationSet.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY, aSequence ) );
     442             :         }
     443             : 
     444           0 :         Window* pLabelFor = pWindow->GetAccessibleRelationLabelFor();
     445           0 :         if ( pLabelFor && pLabelFor != pWindow )
     446             :         {
     447           0 :             uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
     448           0 :             aSequence[0] = pLabelFor->GetAccessible();
     449           0 :             rRelationSet.AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABEL_FOR, aSequence ) );
     450             :         }
     451             :     }
     452           0 : }
     453             : 
     454           0 : void VCLXAccessibleComponent::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
     455             : {
     456           0 :     Window* pWindow = GetWindow();
     457           0 :     if ( pWindow )
     458             :     {
     459           0 :         if ( pWindow->IsVisible() )
     460             :         {
     461           0 :             rStateSet.AddState( accessibility::AccessibleStateType::VISIBLE );
     462           0 :             rStateSet.AddState( accessibility::AccessibleStateType::SHOWING );
     463             :         }
     464             :         else
     465             :         {
     466           0 :             rStateSet.AddState( accessibility::AccessibleStateType::INVALID );
     467             :         }
     468             : 
     469           0 :         if ( pWindow->IsEnabled() )
     470             :         {
     471           0 :             rStateSet.AddState( accessibility::AccessibleStateType::ENABLED );
     472           0 :             rStateSet.AddState( accessibility::AccessibleStateType::SENSITIVE );
     473             :         }
     474             : 
     475           0 :         if ( pWindow->HasChildPathFocus() &&
     476           0 :              ( getAccessibleRole() == accessibility::AccessibleRole::FRAME ||
     477           0 :                getAccessibleRole() == accessibility::AccessibleRole::ALERT ||
     478           0 :                getAccessibleRole() == accessibility::AccessibleRole::DIALOG ) )  // #i18891#
     479           0 :             rStateSet.AddState( accessibility::AccessibleStateType::ACTIVE );
     480             : 
     481             :         // #104290# MT: This way, a ComboBox doesn't get state FOCUSED.
     482             :         // I also don't understand
     483             :         // a) why WINDOW_FIRSTCHILD is used here (which btw is a border window in the case of a combo box)
     484             :         // b) why HasFocus() is nout "enough" for a compound control
     485             :         /*
     486             :         Window* pChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
     487             :         if ( ( !pWindow->IsCompoundControl() && pWindow->HasFocus() ) ||
     488             :              ( pWindow->IsCompoundControl() && pChild && pChild->HasFocus() ) )
     489             :             rStateSet.AddState( accessibility::AccessibleStateType::FOCUSED );
     490             :         */
     491           0 :         if ( pWindow->HasFocus() || ( pWindow->IsCompoundControl() && pWindow->HasChildPathFocus() ) )
     492           0 :             rStateSet.AddState( accessibility::AccessibleStateType::FOCUSED );
     493             : 
     494           0 :         if ( pWindow->IsWait() )
     495           0 :             rStateSet.AddState( accessibility::AccessibleStateType::BUSY );
     496             : 
     497           0 :         if ( pWindow->GetStyle() & WB_SIZEABLE )
     498           0 :             rStateSet.AddState( accessibility::AccessibleStateType::RESIZABLE );
     499             : 
     500           0 :         if( pWindow->IsDialog() )
     501             :         {
     502           0 :             Dialog *pDlg = static_cast< Dialog* >( pWindow );
     503           0 :             if( pDlg->IsInExecute() )
     504           0 :                 rStateSet.AddState( accessibility::AccessibleStateType::MODAL );
     505             :         }
     506             :     }
     507             :     else
     508             :     {
     509           0 :         rStateSet.AddState( accessibility::AccessibleStateType::DEFUNC );
     510             :     }
     511             : 
     512             : /*
     513             : 
     514             : MUST BE SET FROM DERIVED CLASSES:
     515             : 
     516             : CHECKED
     517             : COLLAPSED
     518             : EXPANDED
     519             : EXPANDABLE
     520             : EDITABLE
     521             : FOCUSABLE
     522             : HORIZONTAL
     523             : VERTICAL
     524             : ICONIFIED
     525             : MULTILINE
     526             : MULTI_SELECTABLE
     527             : PRESSED
     528             : SELECTABLE
     529             : SELECTED
     530             : SINGLE_LINE
     531             : TRANSIENT
     532             : 
     533             :     */
     534           0 : }
     535             : 
     536             : 
     537             : // accessibility::XAccessibleContext
     538           0 : sal_Int32 VCLXAccessibleComponent::getAccessibleChildCount() throw (uno::RuntimeException)
     539             : {
     540           0 :     OExternalLockGuard aGuard( this );
     541             : 
     542           0 :     sal_Int32 nChildren = 0;
     543           0 :     if ( GetWindow() )
     544           0 :         nChildren = GetWindow()->GetAccessibleChildWindowCount();
     545             : 
     546           0 :     return nChildren;
     547             : }
     548             : 
     549           0 : uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
     550             : {
     551           0 :     OExternalLockGuard aGuard( this );
     552             : 
     553           0 :     if ( i >= getAccessibleChildCount() )
     554           0 :         throw lang::IndexOutOfBoundsException();
     555             : 
     556           0 :     uno::Reference< accessibility::XAccessible > xAcc;
     557           0 :     if ( GetWindow() )
     558             :     {
     559           0 :         Window* pChild = GetWindow()->GetAccessibleChildWindow( (sal_uInt16)i );
     560           0 :         if ( pChild )
     561           0 :             xAcc = pChild->GetAccessible();
     562             :     }
     563             : 
     564           0 :     return xAcc;
     565             : }
     566             : 
     567           0 : uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getVclParent() const
     568             : {
     569           0 :     uno::Reference< accessibility::XAccessible > xAcc;
     570           0 :     if ( GetWindow() )
     571             :     {
     572           0 :         Window* pParent = GetWindow()->GetAccessibleParentWindow();
     573           0 :         if ( pParent )
     574           0 :             xAcc = pParent->GetAccessible();
     575             :     }
     576           0 :     return xAcc;
     577             : }
     578             : 
     579           0 : uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getAccessibleParent(  ) throw (uno::RuntimeException)
     580             : {
     581           0 :     OExternalLockGuard aGuard( this );
     582             : 
     583           0 :     uno::Reference< accessibility::XAccessible > xAcc( implGetForeignControlledParent() );
     584           0 :     if ( !xAcc.is() )
     585             :         // we do _not_ have a foreign-controlled parent -> default to our VCL parent
     586           0 :         xAcc = getVclParent();
     587             : 
     588           0 :     return xAcc;
     589             : }
     590             : 
     591           0 : sal_Int32 VCLXAccessibleComponent::getAccessibleIndexInParent(  ) throw (uno::RuntimeException)
     592             : {
     593           0 :     OExternalLockGuard aGuard( this );
     594             : 
     595           0 :     sal_Int32 nIndex = -1;
     596             : 
     597           0 :     uno::Reference< accessibility::XAccessible > xAcc( implGetForeignControlledParent() );
     598           0 :     if ( xAcc.is() )
     599             :     {   // we _do_ have a foreign-controlled parent -> use the base class' implementation,
     600             :         // which goes the UNO way
     601           0 :         nIndex = AccessibleExtendedComponentHelper_BASE::getAccessibleIndexInParent( );
     602             :     }
     603             :     else
     604             :     {
     605           0 :         if ( GetWindow() )
     606             :         {
     607           0 :             Window* pParent = GetWindow()->GetAccessibleParentWindow();
     608           0 :             if ( pParent )
     609             :             {
     610             :                 /*
     611             :                 for ( sal_uInt16 n = pParent->GetAccessibleChildWindowCount(); n; )
     612             :                 {
     613             :                     Window* pChild = pParent->GetAccessibleChildWindow( --n );
     614             :                     if ( pChild == GetWindow() )
     615             :                     {
     616             :                         nIndex = n;
     617             :                         break;
     618             :                     }
     619             :                 }
     620             :                 */
     621             :                 //  Iterate over all the parent's children and search for this object.
     622             :                 // this should be compatible with the code in SVX
     623           0 :                 uno::Reference< accessibility::XAccessible > xParentAcc( pParent->GetAccessible() );
     624           0 :                 if ( xParentAcc.is() )
     625             :                 {
     626           0 :                     uno::Reference< accessibility::XAccessibleContext > xParentContext ( xParentAcc->getAccessibleContext() );
     627           0 :                     if ( xParentContext.is() )
     628             :                     {
     629           0 :                         sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
     630           0 :                         for ( sal_Int32 i=0; i<nChildCount; i++ )
     631             :                         {
     632           0 :                             uno::Reference< accessibility::XAccessible > xChild( xParentContext->getAccessibleChild(i) );
     633           0 :                             if ( xChild.is() )
     634             :                             {
     635           0 :                                 uno::Reference< accessibility::XAccessibleContext > xChildContext = xChild->getAccessibleContext();
     636           0 :                                 if ( xChildContext == (accessibility::XAccessibleContext*) this )
     637             :                                 {
     638           0 :                                     nIndex = i;
     639             :                                     break;
     640           0 :                                 }
     641             :                             }
     642           0 :                         }
     643           0 :                     }
     644           0 :                 }
     645             :             }
     646             :         }
     647             :     }
     648           0 :     return nIndex;
     649             : }
     650             : 
     651           0 : sal_Int16 VCLXAccessibleComponent::getAccessibleRole(  ) throw (uno::RuntimeException)
     652             : {
     653           0 :     OExternalLockGuard aGuard( this );
     654             : 
     655           0 :     sal_Int16 nRole = 0;
     656             : 
     657           0 :     if ( GetWindow() )
     658           0 :         nRole = GetWindow()->GetAccessibleRole();
     659             : 
     660           0 :     return nRole;
     661             : }
     662             : 
     663           0 : ::rtl::OUString VCLXAccessibleComponent::getAccessibleDescription(  ) throw (uno::RuntimeException)
     664             : {
     665           0 :     OExternalLockGuard aGuard( this );
     666             : 
     667           0 :     ::rtl::OUString aDescription;
     668             : 
     669           0 :     if ( GetWindow() )
     670           0 :         aDescription = GetWindow()->GetAccessibleDescription();
     671             : 
     672           0 :     return aDescription;
     673             : }
     674             : 
     675           0 : ::rtl::OUString VCLXAccessibleComponent::getAccessibleName(  ) throw (uno::RuntimeException)
     676             : {
     677           0 :     OExternalLockGuard aGuard( this );
     678             : 
     679           0 :     ::rtl::OUString aName;
     680           0 :     if ( GetWindow() )
     681             :     {
     682           0 :         aName = GetWindow()->GetAccessibleName();
     683             : #if OSL_DEBUG_LEVEL > 1
     684             :         aName += rtl::OUString(" (Type = ");
     685             :         aName += rtl::OUString::valueOf(static_cast<sal_Int32>(GetWindow()->GetType()));
     686             :         aName += rtl::OUString( ")");
     687             : #endif
     688             :     }
     689           0 :     return aName;
     690             : }
     691             : 
     692           0 : uno::Reference< accessibility::XAccessibleRelationSet > VCLXAccessibleComponent::getAccessibleRelationSet(  ) throw (uno::RuntimeException)
     693             : {
     694           0 :     OExternalLockGuard aGuard( this );
     695             : 
     696           0 :     utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper;
     697           0 :     uno::Reference< accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper;
     698           0 :     FillAccessibleRelationSet( *pRelationSetHelper );
     699           0 :     return xSet;
     700             : }
     701             : 
     702           0 : uno::Reference< accessibility::XAccessibleStateSet > VCLXAccessibleComponent::getAccessibleStateSet(  ) throw (uno::RuntimeException)
     703             : {
     704           0 :     OExternalLockGuard aGuard( this );
     705             : 
     706           0 :     utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
     707           0 :     uno::Reference< accessibility::XAccessibleStateSet > xSet = pStateSetHelper;
     708           0 :     FillAccessibleStateSet( *pStateSetHelper );
     709           0 :     return xSet;
     710             : }
     711             : 
     712           0 : lang::Locale VCLXAccessibleComponent::getLocale() throw (accessibility::IllegalAccessibleComponentStateException, uno::RuntimeException)
     713             : {
     714           0 :     OExternalLockGuard aGuard( this );
     715             : 
     716           0 :     return Application::GetSettings().GetLanguageTag().getLocale();
     717             : }
     718             : 
     719           0 : uno::Reference< accessibility::XAccessible > VCLXAccessibleComponent::getAccessibleAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException)
     720             : {
     721           0 :     OExternalLockGuard aGuard( this );
     722             : 
     723           0 :     uno::Reference< accessibility::XAccessible > xChild;
     724           0 :     for ( sal_uInt32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
     725             :     {
     726           0 :         uno::Reference< accessibility::XAccessible > xAcc = getAccessibleChild( i );
     727           0 :         if ( xAcc.is() )
     728             :         {
     729           0 :             uno::Reference< accessibility::XAccessibleComponent > xComp( xAcc->getAccessibleContext(), uno::UNO_QUERY );
     730           0 :             if ( xComp.is() )
     731             :             {
     732           0 :                 Rectangle aRect = VCLRectangle( xComp->getBounds() );
     733           0 :                 Point aPos = VCLPoint( rPoint );
     734           0 :                 if ( aRect.IsInside( aPos ) )
     735             :                 {
     736           0 :                     xChild = xAcc;
     737             :                     break;
     738             :                 }
     739           0 :             }
     740             :         }
     741           0 :     }
     742             : 
     743           0 :     return xChild;
     744             : }
     745             : 
     746             : // accessibility::XAccessibleComponent
     747           0 : awt::Rectangle VCLXAccessibleComponent::implGetBounds() throw (uno::RuntimeException)
     748             : {
     749           0 :     awt::Rectangle aBounds ( 0, 0, 0, 0 );
     750             : 
     751           0 :     Window* pWindow = GetWindow();
     752           0 :     if ( pWindow )
     753             :     {
     754           0 :         Rectangle aRect = pWindow->GetWindowExtentsRelative( NULL );
     755           0 :         aBounds = AWTRectangle( aRect );
     756           0 :         Window* pParent = pWindow->GetAccessibleParentWindow();
     757           0 :         if ( pParent )
     758             :         {
     759           0 :             Rectangle aParentRect = pParent->GetWindowExtentsRelative( NULL );
     760           0 :             awt::Point aParentScreenLoc = AWTPoint( aParentRect.TopLeft() );
     761           0 :             aBounds.X -= aParentScreenLoc.X;
     762           0 :             aBounds.Y -= aParentScreenLoc.Y;
     763             :         }
     764             :     }
     765             : 
     766           0 :     uno::Reference< accessibility::XAccessible > xParent( implGetForeignControlledParent() );
     767           0 :     if ( xParent.is() )
     768             :     {   // hmm, we can't rely on our VCL coordinates, as in the Accessibility Hierarchy, somebody gave
     769             :         // us a parent which is different from our VCL parent
     770             :         // (actually, we did not check if it's really different ...)
     771             : 
     772             :         // the screen location of the foreign parent
     773           0 :         uno::Reference< accessibility::XAccessibleComponent > xParentComponent( xParent->getAccessibleContext(), uno::UNO_QUERY );
     774             :         DBG_ASSERT( xParentComponent.is(), "VCLXAccessibleComponent::implGetBounds: invalid (foreign) parent component!" );
     775             : 
     776           0 :         awt::Point aScreenLocForeign( 0, 0 );
     777           0 :         if ( xParentComponent.is() )
     778           0 :             aScreenLocForeign = xParentComponent->getLocationOnScreen();
     779             : 
     780             :         // the screen location of the VCL parent
     781           0 :         xParent = getVclParent();
     782           0 :         if ( xParent.is() )
     783           0 :             xParentComponent = xParentComponent.query( xParent->getAccessibleContext() );
     784             : 
     785           0 :         awt::Point aScreenLocVCL( 0, 0 );
     786           0 :         if ( xParentComponent.is() )
     787           0 :             aScreenLocVCL = xParentComponent->getLocationOnScreen();
     788             : 
     789             :         // the difference between them
     790           0 :         awt::Size aOffset( aScreenLocVCL.X - aScreenLocForeign.X, aScreenLocVCL.Y - aScreenLocForeign.Y );
     791             :         // move the bounds
     792           0 :         aBounds.X += aOffset.Width;
     793           0 :         aBounds.Y += aOffset.Height;
     794             :     }
     795             : 
     796           0 :     return aBounds;
     797             : }
     798             : 
     799           0 : awt::Point VCLXAccessibleComponent::getLocationOnScreen(  ) throw (uno::RuntimeException)
     800             : {
     801           0 :     OExternalLockGuard aGuard( this );
     802             : 
     803           0 :     awt::Point aPos;
     804           0 :     if ( GetWindow() )
     805             :     {
     806           0 :         Rectangle aRect = GetWindow()->GetWindowExtentsRelative( NULL );
     807           0 :         aPos.X = aRect.Left();
     808           0 :         aPos.Y = aRect.Top();
     809             :     }
     810             : 
     811           0 :     return aPos;
     812             : }
     813             : 
     814           0 : void VCLXAccessibleComponent::grabFocus(  ) throw (uno::RuntimeException)
     815             : {
     816           0 :     OExternalLockGuard aGuard( this );
     817             : 
     818           0 :     uno::Reference< accessibility::XAccessibleStateSet > xStates = getAccessibleStateSet();
     819           0 :     if ( mxWindow.is() && xStates.is() && xStates->contains( accessibility::AccessibleStateType::FOCUSABLE ) )
     820           0 :         mxWindow->setFocus();
     821           0 : }
     822             : 
     823           0 : sal_Int32 SAL_CALL VCLXAccessibleComponent::getForeground(  ) throw (uno::RuntimeException)
     824             : {
     825           0 :     OExternalLockGuard aGuard( this );
     826             : 
     827           0 :     sal_Int32 nColor = 0;
     828           0 :     Window* pWindow = GetWindow();
     829           0 :     if ( pWindow )
     830             :     {
     831           0 :         if ( pWindow->IsControlForeground() )
     832           0 :             nColor = pWindow->GetControlForeground().GetColor();
     833             :         else
     834             :         {
     835           0 :             Font aFont;
     836           0 :             if ( pWindow->IsControlFont() )
     837           0 :                 aFont = pWindow->GetControlFont();
     838             :             else
     839           0 :                 aFont = pWindow->GetFont();
     840           0 :             nColor = aFont.GetColor().GetColor();
     841             :         }
     842             :     }
     843             : 
     844           0 :     return nColor;
     845             : }
     846             : 
     847           0 : sal_Int32 SAL_CALL VCLXAccessibleComponent::getBackground(  ) throw (uno::RuntimeException)
     848             : {
     849           0 :     OExternalLockGuard aGuard( this );
     850             : 
     851           0 :     sal_Int32 nColor = 0;
     852           0 :     Window* pWindow = GetWindow();
     853           0 :     if ( pWindow )
     854             :     {
     855           0 :         if ( pWindow->IsControlBackground() )
     856           0 :             nColor = pWindow->GetControlBackground().GetColor();
     857             :         else
     858           0 :             nColor = pWindow->GetBackground().GetColor().GetColor();
     859             :     }
     860             : 
     861           0 :     return nColor;
     862             : }
     863             : 
     864             : // XAccessibleExtendedComponent
     865             : 
     866           0 : uno::Reference< awt::XFont > SAL_CALL VCLXAccessibleComponent::getFont(  ) throw (uno::RuntimeException)
     867             : {
     868           0 :     OExternalLockGuard aGuard( this );
     869             : 
     870           0 :     uno::Reference< awt::XFont > xFont;
     871           0 :     Window* pWindow = GetWindow();
     872           0 :     if ( pWindow )
     873             :     {
     874           0 :         uno::Reference< awt::XDevice > xDev( pWindow->GetComponentInterface(), uno::UNO_QUERY );
     875           0 :         if ( xDev.is() )
     876             :         {
     877           0 :             Font aFont;
     878           0 :             if ( pWindow->IsControlFont() )
     879           0 :                 aFont = pWindow->GetControlFont();
     880             :             else
     881           0 :                 aFont = pWindow->GetFont();
     882           0 :             VCLXFont* pVCLXFont = new VCLXFont;
     883           0 :             pVCLXFont->Init( *xDev.get(), aFont );
     884           0 :             xFont = pVCLXFont;
     885           0 :         }
     886             :     }
     887             : 
     888           0 :     return xFont;
     889             : }
     890             : 
     891           0 : ::rtl::OUString SAL_CALL VCLXAccessibleComponent::getTitledBorderText(  ) throw (uno::RuntimeException)
     892             : {
     893           0 :     OExternalLockGuard aGuard( this );
     894             : 
     895           0 :     ::rtl::OUString sRet;
     896           0 :     if ( GetWindow() )
     897           0 :         sRet = GetWindow()->GetText();
     898             : 
     899           0 :     return sRet;
     900             : }
     901             : 
     902           0 : ::rtl::OUString SAL_CALL VCLXAccessibleComponent::getToolTipText(  ) throw (uno::RuntimeException)
     903             : {
     904           0 :     OExternalLockGuard aGuard( this );
     905             : 
     906           0 :     ::rtl::OUString sRet;
     907           0 :     if ( GetWindow() )
     908           0 :         sRet = GetWindow()->GetQuickHelpText();
     909             : 
     910           0 :     return sRet;
     911             : }
     912             : 
     913             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10