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

Generated by: LCOV version 1.11