1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "accessibility/extended/AccessibleToolPanelDeckTabBarItem.hxx"
22 #include <com/sun/star/accessibility/AccessibleRole.hpp>
23 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
24 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
25 #include <com/sun/star/lang/DisposedException.hpp>
27 #include <svtools/toolpanel/toolpaneldeck.hxx>
28 #include <svtools/toolpanel/paneltabbar.hxx>
29 #include <unotools/accessiblestatesethelper.hxx>
30 #include <unotools/accessiblerelationsethelper.hxx>
31 #include <toolkit/helper/externallock.hxx>
32 #include <tools/diagnose_ex.h>
33 #include <vcl/svapp.hxx>
34 #include <osl/mutex.hxx>
36 namespace accessibility
38 typedef ::com::sun::star::awt::Rectangle UnoRectangle
;
39 typedef ::com::sun::star::awt::Point UnoPoint
;
41 using ::com::sun::star::uno::Reference
;
42 using ::com::sun::star::uno::XInterface
;
43 using ::com::sun::star::uno::UNO_QUERY
;
44 using ::com::sun::star::uno::UNO_QUERY_THROW
;
45 using ::com::sun::star::uno::UNO_SET_THROW
;
46 using ::com::sun::star::uno::Exception
;
47 using ::com::sun::star::uno::RuntimeException
;
48 using ::com::sun::star::uno::Any
;
49 using ::com::sun::star::uno::makeAny
;
50 using ::com::sun::star::uno::Sequence
;
51 using ::com::sun::star::uno::Type
;
52 using ::com::sun::star::accessibility::XAccessible
;
53 using ::com::sun::star::lang::DisposedException
;
54 using ::com::sun::star::lang::IndexOutOfBoundsException
;
55 using ::com::sun::star::accessibility::XAccessibleRelationSet
;
56 using ::com::sun::star::accessibility::XAccessibleStateSet
;
57 using ::com::sun::star::accessibility::XAccessibleComponent
;
58 using ::com::sun::star::accessibility::XAccessibleExtendedComponent
;
59 using ::com::sun::star::awt::XFont
;
61 namespace AccessibleRole
= ::com::sun::star::accessibility::AccessibleRole
;
62 namespace AccessibleStateType
= ::com::sun::star::accessibility::AccessibleStateType
;
63 namespace AccessibleEventId
= ::com::sun::star::accessibility::AccessibleEventId
;
65 // AccessibleToolPanelDeckTabBarItem_Impl
66 class AccessibleToolPanelDeckTabBarItem_Impl
: public ::svt::IToolPanelDeckListener
69 AccessibleToolPanelDeckTabBarItem_Impl(
70 AccessibleToolPanelDeckTabBarItem
& i_rAntiImpl
,
71 const Reference
< XAccessible
>& i_rAccessibleParent
,
72 ::svt::IToolPanelDeck
& i_rPanelDeck
,
73 ::svt::PanelTabBar
& i_rTabBar
,
74 const size_t i_nItemPos
76 virtual ~AccessibleToolPanelDeckTabBarItem_Impl();
78 ::svt::PanelTabBar
* getTabBar() const { return m_pTabBar
; }
80 // IToolPanelDeckListener
81 virtual void PanelInserted( const ::svt::PToolPanel
& i_pPanel
, const size_t i_nPosition
) SAL_OVERRIDE
;
82 virtual void PanelRemoved( const size_t i_nPosition
) SAL_OVERRIDE
;
83 virtual void ActivePanelChanged( const ::boost::optional
< size_t >& i_rOldActive
, const ::boost::optional
< size_t >& i_rNewActive
) SAL_OVERRIDE
;
84 virtual void LayouterChanged( const ::svt::PDeckLayouter
& i_rNewLayouter
) SAL_OVERRIDE
;
85 virtual void Dying() SAL_OVERRIDE
;
88 bool isDisposed() const { return m_pPanelDeck
== NULL
; }
89 void checkDisposed() const;
92 const Reference
< XAccessible
>&
93 getAccessibleParent() const { return m_xAccessibleParent
; }
94 size_t getItemPos() const { return m_nItemPos
; }
96 Reference
< XAccessibleComponent
> getParentAccessibleComponent() const;
97 ::svt::IToolPanelDeck
* getPanelDeck() const { return m_pPanelDeck
; }
98 OUString
getPanelDisplayName();
101 void impl_notifyBoundRectChanges();
102 void impl_notifyStateChange( const sal_Int16 i_nLostState
, const sal_Int16 i_nGainedState
);
105 AccessibleToolPanelDeckTabBarItem
& m_rAntiImpl
;
106 Reference
< XAccessible
> m_xAccessibleParent
;
107 ::svt::IToolPanelDeck
* m_pPanelDeck
;
108 VclPtr
< ::svt::PanelTabBar
> m_pTabBar
;
112 // AccessibleToolPanelDeckTabBarItem_Impl
113 AccessibleToolPanelDeckTabBarItem_Impl::AccessibleToolPanelDeckTabBarItem_Impl( AccessibleToolPanelDeckTabBarItem
& i_rAntiImpl
,
114 const Reference
< XAccessible
>& i_rAccessibleParent
, ::svt::IToolPanelDeck
& i_rPanelDeck
, ::svt::PanelTabBar
& i_rTabBar
,
115 const size_t i_nItemPos
)
116 :m_rAntiImpl( i_rAntiImpl
)
117 ,m_xAccessibleParent( i_rAccessibleParent
)
118 ,m_pPanelDeck( &i_rPanelDeck
)
119 ,m_pTabBar( &i_rTabBar
)
120 ,m_nItemPos( i_nItemPos
)
122 m_pPanelDeck
->AddListener( *this );
125 AccessibleToolPanelDeckTabBarItem_Impl::~AccessibleToolPanelDeckTabBarItem_Impl()
129 void AccessibleToolPanelDeckTabBarItem_Impl::checkDisposed() const
132 throw DisposedException( OUString(), *&m_rAntiImpl
);
135 void AccessibleToolPanelDeckTabBarItem_Impl::dispose()
137 ENSURE_OR_RETURN_VOID( !isDisposed(), "AccessibleToolPanelDeckTabBarItem_Impl::dispose: disposed twice!" );
139 m_xAccessibleParent
.clear();
140 m_pPanelDeck
->RemoveListener( *this );
145 Reference
< XAccessibleComponent
> AccessibleToolPanelDeckTabBarItem_Impl::getParentAccessibleComponent() const
147 Reference
< XAccessible
> xAccessibleParent( m_rAntiImpl
.getAccessibleParent(), UNO_QUERY_THROW
);
148 return Reference
< XAccessibleComponent
>( xAccessibleParent
->getAccessibleContext(), UNO_QUERY
);
151 OUString
AccessibleToolPanelDeckTabBarItem_Impl::getPanelDisplayName()
153 const ::svt::PToolPanel
pPanel( m_pPanelDeck
->GetPanel( getItemPos() ) );
154 if ( pPanel
.get() == NULL
)
155 throw DisposedException();
156 return pPanel
->GetDisplayName();
159 void AccessibleToolPanelDeckTabBarItem_Impl::impl_notifyBoundRectChanges()
161 m_rAntiImpl
.NotifyAccessibleEvent( AccessibleEventId::BOUNDRECT_CHANGED
, Any(), Any() );
164 void AccessibleToolPanelDeckTabBarItem_Impl::impl_notifyStateChange( const sal_Int16 i_nLostState
, const sal_Int16 i_nGainedState
)
166 m_rAntiImpl
.NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED
,
167 i_nLostState
> -1 ? makeAny( i_nLostState
) : Any(),
168 i_nGainedState
> -1 ? makeAny( i_nGainedState
) : Any()
172 void AccessibleToolPanelDeckTabBarItem_Impl::PanelInserted( const ::svt::PToolPanel
& i_pPanel
, const size_t i_nPosition
)
175 if ( i_nPosition
<= m_nItemPos
)
177 impl_notifyBoundRectChanges();
180 void AccessibleToolPanelDeckTabBarItem_Impl::PanelRemoved( const size_t i_nPosition
)
182 if ( i_nPosition
== m_nItemPos
)
184 m_rAntiImpl
.dispose();
186 else if ( i_nPosition
< m_nItemPos
)
189 impl_notifyBoundRectChanges();
193 void AccessibleToolPanelDeckTabBarItem_Impl::ActivePanelChanged( const ::boost::optional
< size_t >& i_rOldActive
, const ::boost::optional
< size_t >& i_rNewActive
)
195 if ( m_nItemPos
== i_rOldActive
)
197 impl_notifyStateChange( AccessibleStateType::ACTIVE
, -1 );
198 impl_notifyStateChange( AccessibleStateType::SELECTED
, -1 );
200 else if ( m_nItemPos
== i_rNewActive
)
202 impl_notifyStateChange( -1, AccessibleStateType::ACTIVE
);
203 impl_notifyStateChange( -1, AccessibleStateType::SELECTED
);
207 void AccessibleToolPanelDeckTabBarItem_Impl::LayouterChanged( const ::svt::PDeckLayouter
& i_rNewLayouter
)
209 (void)i_rNewLayouter
;
210 // if the tool panel deck has a new layouter, then the old layouter, and thus all items it was
211 // responsible for, died. So do we.
215 void AccessibleToolPanelDeckTabBarItem_Impl::Dying()
217 // if the tool panel deck is dying, then its layouter dies, so should we.
221 class ItemMethodGuard
224 explicit ItemMethodGuard( AccessibleToolPanelDeckTabBarItem_Impl
& i_rImpl
)
227 i_rImpl
.checkDisposed();
234 SolarMutexGuard m_aGuard
;
237 AccessibleToolPanelDeckTabBarItem::AccessibleToolPanelDeckTabBarItem( const Reference
< XAccessible
>& i_rAccessibleParent
,
238 ::svt::IToolPanelDeck
& i_rPanelDeck
, ::svt::PanelTabBar
& i_rTabBar
, const size_t i_nItemPos
)
239 : ::comphelper::OAccessibleExtendedComponentHelper(
240 new VCLExternalSolarLock
)
241 , m_xImpl(new AccessibleToolPanelDeckTabBarItem_Impl(*this,
242 i_rAccessibleParent
, i_rPanelDeck
, i_rTabBar
, i_nItemPos
))
246 AccessibleToolPanelDeckTabBarItem::~AccessibleToolPanelDeckTabBarItem()
250 sal_Int32 SAL_CALL
AccessibleToolPanelDeckTabBarItem::getAccessibleChildCount( ) throw (RuntimeException
, std::exception
)
255 Reference
< XAccessible
> SAL_CALL
AccessibleToolPanelDeckTabBarItem::getAccessibleChild( sal_Int32 i
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
258 throw IndexOutOfBoundsException( OUString(), *this );
261 Reference
< XAccessible
> SAL_CALL
AccessibleToolPanelDeckTabBarItem::getAccessibleParent( ) throw (RuntimeException
, std::exception
)
263 ItemMethodGuard
aGuard( *m_xImpl
);
264 return m_xImpl
->getAccessibleParent();
267 sal_Int16 SAL_CALL
AccessibleToolPanelDeckTabBarItem::getAccessibleRole( ) throw (RuntimeException
, std::exception
)
269 return AccessibleRole::PAGE_TAB
;
272 OUString SAL_CALL
AccessibleToolPanelDeckTabBarItem::getAccessibleDescription( ) throw (RuntimeException
, std::exception
)
274 ItemMethodGuard
aGuard( *m_xImpl
);
275 return m_xImpl
->getPanelDisplayName();
278 OUString SAL_CALL
AccessibleToolPanelDeckTabBarItem::getAccessibleName( ) throw (RuntimeException
, std::exception
)
280 ItemMethodGuard
aGuard( *m_xImpl
);
281 return m_xImpl
->getPanelDisplayName();
284 Reference
< XAccessibleRelationSet
> SAL_CALL
AccessibleToolPanelDeckTabBarItem::getAccessibleRelationSet( ) throw (RuntimeException
, std::exception
)
286 ItemMethodGuard
aGuard( *m_xImpl
);
287 ::utl::AccessibleRelationSetHelper
* pRelationSet
= new utl::AccessibleRelationSetHelper
;
291 Reference
< XAccessibleStateSet
> SAL_CALL
AccessibleToolPanelDeckTabBarItem::getAccessibleStateSet( ) throw (RuntimeException
, std::exception
)
293 ItemMethodGuard
aGuard( *m_xImpl
);
295 ::utl::AccessibleStateSetHelper
* pStateSet( new ::utl::AccessibleStateSetHelper
);
296 pStateSet
->AddState( AccessibleStateType::FOCUSABLE
);
297 pStateSet
->AddState( AccessibleStateType::SELECTABLE
);
298 pStateSet
->AddState( AccessibleStateType::ICONIFIED
);
300 if ( m_xImpl
->getItemPos() == m_xImpl
->getPanelDeck()->GetActivePanel() )
302 pStateSet
->AddState( AccessibleStateType::ACTIVE
);
303 pStateSet
->AddState( AccessibleStateType::SELECTED
);
306 if ( m_xImpl
->getItemPos() == m_xImpl
->getTabBar()->GetFocusedPanelItem() )
307 pStateSet
->AddState( AccessibleStateType::FOCUSED
);
309 if ( m_xImpl
->getTabBar()->IsEnabled() )
310 pStateSet
->AddState( AccessibleStateType::ENABLED
);
312 if ( m_xImpl
->getTabBar()->IsVisible() )
314 pStateSet
->AddState( AccessibleStateType::SHOWING
);
315 pStateSet
->AddState( AccessibleStateType::VISIBLE
);
321 Reference
< XAccessible
> SAL_CALL
AccessibleToolPanelDeckTabBarItem::getAccessibleAtPoint( const UnoPoint
& i_rLocation
) throw (RuntimeException
, std::exception
)
323 ItemMethodGuard
aGuard( *m_xImpl
);
324 // we do not have children ...
329 void SAL_CALL
AccessibleToolPanelDeckTabBarItem::grabFocus( ) throw (RuntimeException
, std::exception
)
331 ItemMethodGuard
aGuard( *m_xImpl
);
332 m_xImpl
->getTabBar()->FocusPanelItem( m_xImpl
->getItemPos() );
335 ::sal_Int32 SAL_CALL
AccessibleToolPanelDeckTabBarItem::getForeground( ) throw (RuntimeException
, std::exception
)
337 ItemMethodGuard
aGuard( *m_xImpl
);
338 Reference
< XAccessibleComponent
> xParentComponent( m_xImpl
->getParentAccessibleComponent(), UNO_SET_THROW
);
339 return xParentComponent
->getForeground();
342 ::sal_Int32 SAL_CALL
AccessibleToolPanelDeckTabBarItem::getBackground( ) throw (RuntimeException
, std::exception
)
344 ItemMethodGuard
aGuard( *m_xImpl
);
345 Reference
< XAccessibleComponent
> xParentComponent( m_xImpl
->getParentAccessibleComponent(), UNO_SET_THROW
);
346 return xParentComponent
->getBackground();
349 Reference
< XFont
> SAL_CALL
AccessibleToolPanelDeckTabBarItem::getFont( ) throw (RuntimeException
, std::exception
)
351 ItemMethodGuard
aGuard( *m_xImpl
);
352 Reference
< XAccessibleExtendedComponent
> xParentComponent( m_xImpl
->getParentAccessibleComponent(), UNO_QUERY_THROW
);
353 // TODO: strictly, this is not correct: The TabBar implementation of the TabLayouter might use
354 // a different font ...
355 return xParentComponent
->getFont();
358 OUString SAL_CALL
AccessibleToolPanelDeckTabBarItem::getTitledBorderText( ) throw (RuntimeException
, std::exception
)
360 ItemMethodGuard
aGuard( *m_xImpl
);
365 OUString SAL_CALL
AccessibleToolPanelDeckTabBarItem::getToolTipText( ) throw (RuntimeException
, std::exception
)
367 ItemMethodGuard
aGuard( *m_xImpl
);
368 return m_xImpl
->getPanelDisplayName();
371 UnoRectangle
AccessibleToolPanelDeckTabBarItem::implGetBounds() throw (RuntimeException
)
373 ItemMethodGuard
aGuard( *m_xImpl
);
375 const ::Rectangle
aItemScreenRect( m_xImpl
->getTabBar()->GetItemScreenRect( m_xImpl
->getItemPos() ) );
377 Reference
< XAccessibleComponent
> xParentComponent( m_xImpl
->getParentAccessibleComponent(), UNO_SET_THROW
);
378 const UnoPoint
aParentLocation( xParentComponent
->getLocationOnScreen() );
380 aItemScreenRect
.Left() - aParentLocation
.X
,
381 aItemScreenRect
.Top() - aParentLocation
.Y
,
382 aItemScreenRect
.GetWidth(),
383 aItemScreenRect
.GetHeight()
387 void SAL_CALL
AccessibleToolPanelDeckTabBarItem::disposing()
389 ItemMethodGuard
aGuard( *m_xImpl
);
392 } // namespace accessibility
394 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */