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

Generated by: LCOV version 1.10