LCOV - code coverage report
Current view: top level - accessibility/source/extended - AccessibleToolPanelDeck.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1 125 0.8 %
Date: 2014-11-03 Functions: 2 29 6.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 "accessibility/extended/AccessibleToolPanelDeck.hxx"
      21             : 
      22             : #include <com/sun/star/accessibility/AccessibleRole.hpp>
      23             : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
      24             : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
      25             : #include <com/sun/star/lang/DisposedException.hpp>
      26             : 
      27             : #include <svtools/toolpanel/toolpaneldeck.hxx>
      28             : #include <toolkit/awt/vclxwindow.hxx>
      29             : #include <toolkit/helper/vclunohelper.hxx>
      30             : #include <vcl/svapp.hxx>
      31             : #include <osl/mutex.hxx>
      32             : #include <unotools/accessiblestatesethelper.hxx>
      33             : #include <tools/diagnose_ex.h>
      34             : 
      35             : #include <boost/noncopyable.hpp>
      36             : 
      37             : 
      38             : namespace accessibility
      39             : {
      40             :     using ::com::sun::star::uno::Reference;
      41             :     using ::com::sun::star::uno::XInterface;
      42             :     using ::com::sun::star::uno::UNO_QUERY;
      43             :     using ::com::sun::star::uno::UNO_QUERY_THROW;
      44             :     using ::com::sun::star::uno::UNO_SET_THROW;
      45             :     using ::com::sun::star::uno::Exception;
      46             :     using ::com::sun::star::uno::RuntimeException;
      47             :     using ::com::sun::star::uno::Any;
      48             :     using ::com::sun::star::uno::makeAny;
      49             :     using ::com::sun::star::uno::Sequence;
      50             :     using ::com::sun::star::uno::Type;
      51             :     using ::com::sun::star::accessibility::XAccessible;
      52             :     using ::com::sun::star::accessibility::XAccessibleContext;
      53             :     using ::com::sun::star::lang::DisposedException;
      54             :     using ::com::sun::star::lang::IndexOutOfBoundsException;
      55             :     using ::com::sun::star::lang::Locale;
      56             :     using ::com::sun::star::accessibility::XAccessibleRelationSet;
      57             :     using ::com::sun::star::accessibility::XAccessibleStateSet;
      58             :     using ::com::sun::star::accessibility::IllegalAccessibleComponentStateException;
      59             :     using ::com::sun::star::awt::XFont;
      60             : 
      61             :     namespace AccessibleRole = ::com::sun::star::accessibility::AccessibleRole;
      62             :     namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId;
      63             :     namespace AccessibleStateType = ::com::sun::star::accessibility::AccessibleStateType;
      64             : 
      65             :     typedef ::com::sun::star::awt::Point        UnoPoint;
      66             : 
      67             :     // AccessibleToolPanelDeck_Impl - declaration
      68             :     class AccessibleToolPanelDeck_Impl  :public ::boost::noncopyable
      69             :                                         ,public ::svt::IToolPanelDeckListener
      70             :     {
      71             :     public:
      72             :         AccessibleToolPanelDeck_Impl(
      73             :             AccessibleToolPanelDeck& i_rAntiImpl,
      74             :             const Reference< XAccessible >& i_rAccessibleParent,
      75             :             ::svt::ToolPanelDeck& i_rPanelDeck
      76             :         );
      77             : 
      78             :         void    checkDisposed();
      79           0 :         bool    isDisposed() const { return m_pPanelDeck == NULL; }
      80             :         void    dispose();
      81             : 
      82             :         virtual ~AccessibleToolPanelDeck_Impl();
      83             : 
      84             :         Reference< XAccessible >    getOwnAccessible() const;
      85             :         Reference< XAccessible >    getActivePanelAccessible();
      86             : 
      87             :     protected:
      88             :         // IToolPanelDeckListener
      89             :         virtual void PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition ) SAL_OVERRIDE;
      90             :         virtual void PanelRemoved( const size_t i_nPosition ) SAL_OVERRIDE;
      91             :         virtual void ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive ) SAL_OVERRIDE;
      92             :         virtual void LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter ) SAL_OVERRIDE;
      93             :         virtual void Dying() SAL_OVERRIDE;
      94             : 
      95             :     public:
      96             :         AccessibleToolPanelDeck&    m_rAntiImpl;
      97             :         Reference< XAccessible >    m_xAccessibleParent;
      98             :         ::svt::ToolPanelDeck*       m_pPanelDeck;
      99             : 
     100             :         Reference< XAccessible >        m_xActivePanelAccessible;
     101             :     };
     102             : 
     103             :     // MethodGuard
     104             :     namespace
     105             :     {
     106             :         class MethodGuard
     107             :         {
     108             :         public:
     109           0 :             MethodGuard( AccessibleToolPanelDeck_Impl& i_rImpl )
     110           0 :                 :m_aGuard()
     111             :             {
     112           0 :                 i_rImpl.checkDisposed();
     113           0 :             }
     114           0 :             ~MethodGuard()
     115           0 :             {
     116           0 :             }
     117             : 
     118             :         private:
     119             :             SolarMutexGuard  m_aGuard;
     120             :         };
     121             :     }
     122             : 
     123             :     // AccessibleToolPanelDeck_Impl - implementation
     124           0 :     AccessibleToolPanelDeck_Impl::AccessibleToolPanelDeck_Impl( AccessibleToolPanelDeck& i_rAntiImpl, const Reference< XAccessible >& i_rAccessibleParent,
     125             :             ::svt::ToolPanelDeck& i_rPanelDeck )
     126             :         :m_rAntiImpl( i_rAntiImpl )
     127             :         ,m_xAccessibleParent( i_rAccessibleParent )
     128             :         ,m_pPanelDeck( &i_rPanelDeck )
     129           0 :         ,m_xActivePanelAccessible()
     130             :     {
     131           0 :         m_pPanelDeck->AddListener( *this );
     132           0 :     }
     133             : 
     134           0 :     AccessibleToolPanelDeck_Impl::~AccessibleToolPanelDeck_Impl()
     135             :     {
     136           0 :         if ( !isDisposed() )
     137           0 :             dispose();
     138           0 :     }
     139             : 
     140           0 :     void AccessibleToolPanelDeck_Impl::dispose()
     141             :     {
     142           0 :         ENSURE_OR_RETURN_VOID( !isDisposed(), "disposed twice" );
     143           0 :         m_pPanelDeck->RemoveListener( *this );
     144           0 :         m_pPanelDeck = NULL;
     145           0 :         m_xAccessibleParent.clear();
     146             :     }
     147             : 
     148           0 :     void AccessibleToolPanelDeck_Impl::checkDisposed()
     149             :     {
     150           0 :         if ( isDisposed() )
     151           0 :             throw DisposedException( OUString(), *&m_rAntiImpl );
     152           0 :     }
     153             : 
     154           0 :     Reference< XAccessible > AccessibleToolPanelDeck_Impl::getOwnAccessible() const
     155             :     {
     156           0 :         Reference< XAccessible > xOwnAccessible( static_cast< XAccessible* >( m_rAntiImpl.GetVCLXWindow() ) );
     157             :         OSL_ENSURE( xOwnAccessible->getAccessibleContext() == Reference< XAccessibleContext >( &m_rAntiImpl ),
     158             :             "AccessibleToolPanelDeck_Impl::getOwnAccessible: could not retrieve proper XAccessible for /myself!" );
     159           0 :         return xOwnAccessible;
     160             :     }
     161             : 
     162           0 :     Reference< XAccessible > AccessibleToolPanelDeck_Impl::getActivePanelAccessible()
     163             :     {
     164           0 :         ENSURE_OR_RETURN( !isDisposed(), "AccessibleToolPanelDeck_Impl::getActivePanelAccessible: already disposed!", NULL );
     165             : 
     166           0 :         if ( !m_xActivePanelAccessible.is() )
     167             :         {
     168           0 :             ::boost::optional< size_t > aActivePanel( m_pPanelDeck->GetActivePanel() );
     169           0 :             ENSURE_OR_RETURN( !!aActivePanel, "AccessibleToolPanelDeck_Impl::getActivePanelAccessible: this should not be called without an active panel!", NULL );
     170           0 :             ::svt::PToolPanel pActivePanel( m_pPanelDeck->GetPanel( *aActivePanel ) );
     171           0 :             ENSURE_OR_RETURN( pActivePanel.get() != NULL, "AccessibleToolPanelDeck_Impl::getActivePanelAccessible: no active panel!", NULL );
     172           0 :             m_xActivePanelAccessible = pActivePanel->CreatePanelAccessible( getOwnAccessible() );
     173           0 :             OSL_ENSURE( m_xActivePanelAccessible.is(), "AccessibleToolPanelDeck_Impl::getActivePanelAccessible: illegal accessible returned by the panel!" );
     174             :         }
     175             : 
     176           0 :         return m_xActivePanelAccessible;
     177             :     }
     178             : 
     179           0 :     void AccessibleToolPanelDeck_Impl::PanelInserted( const ::svt::PToolPanel& i_pPanel, const size_t i_nPosition )
     180             :     {
     181             :         (void)i_pPanel;
     182             :         (void)i_nPosition;
     183           0 :     }
     184             : 
     185           0 :     void AccessibleToolPanelDeck_Impl::PanelRemoved( const size_t i_nPosition )
     186             :     {
     187             :         (void)i_nPosition;
     188           0 :     }
     189             : 
     190           0 :     void AccessibleToolPanelDeck_Impl::ActivePanelChanged( const ::boost::optional< size_t >& i_rOldActive, const ::boost::optional< size_t >& i_rNewActive )
     191             :     {
     192           0 :         if ( !!i_rOldActive )
     193             :         {
     194           0 :             if ( !m_xActivePanelAccessible.is() )
     195             :             {
     196             :                 // again, this might in theory happen if the XAccessible for the active panel has never before been requested.
     197             :                 // In this case, just say that all our children are invalid, so they all must be re-requested.
     198           0 :                 m_rAntiImpl.NotifyAccessibleEvent( AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any() );
     199             :             }
     200             :             else
     201             :             {
     202           0 :                 m_rAntiImpl.NotifyAccessibleEvent( AccessibleEventId::CHILD, makeAny( m_xActivePanelAccessible ), Any() );
     203             :             }
     204             :         }
     205             : 
     206           0 :         m_xActivePanelAccessible.clear();
     207             : 
     208           0 :         if ( !!i_rNewActive )
     209             :         {
     210           0 :             m_rAntiImpl.NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), makeAny( getActivePanelAccessible() ) );
     211             :         }
     212           0 :     }
     213             : 
     214           0 :     void AccessibleToolPanelDeck_Impl::LayouterChanged( const ::svt::PDeckLayouter& i_rNewLayouter )
     215             :     {
     216           0 :         MethodGuard aGuard( *this );
     217             : 
     218             :         (void)i_rNewLayouter;
     219           0 :         m_rAntiImpl.NotifyAccessibleEvent( AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any() );
     220           0 :     }
     221             : 
     222           0 :     void AccessibleToolPanelDeck_Impl::Dying()
     223             :     {
     224             :         // the tool panel deck is dying, so dispose ourself
     225           0 :         m_rAntiImpl.dispose();
     226           0 :     }
     227             : 
     228             :     // AccessibleToolPanelDeck
     229           0 :     AccessibleToolPanelDeck::AccessibleToolPanelDeck( const Reference< XAccessible >& i_rAccessibleParent,
     230             :             ::svt::ToolPanelDeck& i_rPanelDeck )
     231             :         :AccessibleToolPanelDeck_Base( i_rPanelDeck.GetWindowPeer() )
     232           0 :         ,m_pImpl( new AccessibleToolPanelDeck_Impl( *this, i_rAccessibleParent, i_rPanelDeck ) )
     233             :     {
     234           0 :     }
     235             : 
     236           0 :     AccessibleToolPanelDeck::~AccessibleToolPanelDeck()
     237             :     {
     238           0 :     }
     239             : 
     240           0 :     sal_Int32 SAL_CALL AccessibleToolPanelDeck::getAccessibleChildCount(  ) throw (RuntimeException, std::exception)
     241             :     {
     242           0 :         MethodGuard aGuard( *m_pImpl );
     243             : 
     244           0 :         sal_Int32 nChildCount( m_pImpl->m_pPanelDeck->GetLayouter()->GetAccessibleChildCount() );
     245             : 
     246           0 :         ::boost::optional< size_t > aActivePanel( m_pImpl->m_pPanelDeck->GetActivePanel() );
     247           0 :         if ( !!aActivePanel )
     248           0 :             return ++nChildCount;
     249             : 
     250           0 :         return nChildCount;
     251             :     }
     252             : 
     253           0 :     Reference< XAccessible > SAL_CALL AccessibleToolPanelDeck::getAccessibleChild( sal_Int32 i_nIndex ) throw (IndexOutOfBoundsException, RuntimeException, std::exception)
     254             :     {
     255           0 :         MethodGuard aGuard( *m_pImpl );
     256             : 
     257           0 :         const sal_Int32 nChildCount( getAccessibleChildCount() );
     258           0 :         if ( ( i_nIndex < 0 ) || ( i_nIndex >= nChildCount ) )
     259           0 :             throw IndexOutOfBoundsException( OUString(), *this );
     260             : 
     261             :         // first "n" children are provided by the layouter
     262           0 :         const size_t nLayouterCount( m_pImpl->m_pPanelDeck->GetLayouter()->GetAccessibleChildCount() );
     263           0 :         if ( size_t( i_nIndex ) < nLayouterCount )
     264           0 :             return m_pImpl->m_pPanelDeck->GetLayouter()->GetAccessibleChild(
     265             :                 size_t( i_nIndex ),
     266             :                 m_pImpl->getOwnAccessible()
     267           0 :             );
     268             : 
     269             :         // the last child is the XAccessible of the active panel
     270           0 :         return m_pImpl->getActivePanelAccessible();
     271             :     }
     272             : 
     273           0 :     Reference< XAccessible > SAL_CALL AccessibleToolPanelDeck::getAccessibleParent(  ) throw (RuntimeException, std::exception)
     274             :     {
     275           0 :         MethodGuard aGuard( *m_pImpl );
     276           0 :         const Reference< XAccessible > xParent = implGetForeignControlledParent();
     277           0 :         if ( xParent.is() )
     278           0 :             return xParent;
     279           0 :         return m_pImpl->m_xAccessibleParent;
     280             :     }
     281             : 
     282           0 :     sal_Int16 SAL_CALL AccessibleToolPanelDeck::getAccessibleRole(  ) throw (RuntimeException, std::exception)
     283             :     {
     284           0 :         MethodGuard aGuard( *m_pImpl );
     285           0 :         return AccessibleRole::PANEL;
     286             :     }
     287             : 
     288           0 :     Reference< XAccessible > SAL_CALL AccessibleToolPanelDeck::getAccessibleAtPoint( const UnoPoint& i_rPoint ) throw (RuntimeException, std::exception)
     289             :     {
     290           0 :         MethodGuard aGuard( *m_pImpl );
     291             : 
     292           0 :         const ::Point aRequestedPoint( VCLUnoHelper::ConvertToVCLPoint( i_rPoint ) );
     293             :         // check the panel window itself
     294           0 :         const vcl::Window& rActivePanelAnchor( m_pImpl->m_pPanelDeck->GetPanelWindowAnchor() );
     295           0 :         const Rectangle aPanelAnchorArea( rActivePanelAnchor.GetPosPixel(), rActivePanelAnchor.GetOutputSizePixel() );
     296           0 :         if ( aPanelAnchorArea.IsInside( aRequestedPoint ) )
     297             :             // note that this assumes that the Window which actually implements the concrete panel covers
     298             :             // the complete area of its "anchor" Window. But this is ensured by the ToolPanelDeck implementation.
     299           0 :             return m_pImpl->getActivePanelAccessible();
     300             : 
     301             :         // check the XAccessible instances provided by the layouter
     302             :         try
     303             :         {
     304           0 :             const ::svt::PDeckLayouter pLayouter( m_pImpl->m_pPanelDeck->GetLayouter() );
     305           0 :             ENSURE_OR_THROW( pLayouter.get() != NULL, "invalid layouter" );
     306             : 
     307           0 :             const size_t nLayouterChildren = pLayouter->GetAccessibleChildCount();
     308           0 :             for ( size_t i=0; i<nLayouterChildren; ++i )
     309             :             {
     310           0 :                 const Reference< XAccessible > xLayoutItemAccessible( pLayouter->GetAccessibleChild( i, m_pImpl->getOwnAccessible() ), UNO_SET_THROW );
     311           0 :                 const Reference< XAccessibleComponent > xLayoutItemComponent( xLayoutItemAccessible->getAccessibleContext(), UNO_QUERY_THROW );
     312           0 :                 const ::Rectangle aLayoutItemBounds( VCLUnoHelper::ConvertToVCLRect( xLayoutItemComponent->getBounds() ) );
     313           0 :                 if ( aLayoutItemBounds.IsInside( aRequestedPoint ) )
     314           0 :                     return xLayoutItemAccessible;
     315           0 :             }
     316             :         }
     317           0 :         catch( const Exception& )
     318             :         {
     319             :             DBG_UNHANDLED_EXCEPTION();
     320             :         }
     321             : 
     322           0 :         return NULL;
     323             :     }
     324             : 
     325           0 :     void SAL_CALL AccessibleToolPanelDeck::grabFocus(  ) throw (RuntimeException, std::exception)
     326             :     {
     327           0 :         MethodGuard aGuard( *m_pImpl );
     328           0 :         m_pImpl->m_pPanelDeck->GrabFocus();
     329           0 :     }
     330             : 
     331           0 :     void SAL_CALL AccessibleToolPanelDeck::disposing()
     332             :     {
     333           0 :         AccessibleToolPanelDeck_Base::disposing();
     334           0 :         m_pImpl->dispose();
     335           0 :     }
     336             : 
     337           0 :     Reference< XAccessible > AccessibleToolPanelDeck::GetChildAccessible( const VclWindowEvent& i_rVclWindowEvent )
     338             :     {
     339             :         // don't let the base class generate any A11Y events from VclWindowEvent, we completely manage those
     340             :         // A11Y events ourself
     341             :         (void)i_rVclWindowEvent;
     342           0 :         return NULL;
     343             :     }
     344             : 
     345           0 :     void AccessibleToolPanelDeck::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& i_rStateSet )
     346             :     {
     347           0 :         AccessibleToolPanelDeck_Base::FillAccessibleStateSet( i_rStateSet );
     348           0 :         if ( m_pImpl->isDisposed() )
     349             :         {
     350           0 :             i_rStateSet.AddState( AccessibleStateType::DEFUNC );
     351             :         }
     352             :         else
     353             :         {
     354           0 :             i_rStateSet.AddState( AccessibleStateType::FOCUSABLE );
     355             :         }
     356           0 :     }
     357          60 : } // namespace accessibility
     358             : 
     359             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10