xref: /AOO41X/main/accessibility/source/standard/vclxaccessiblestatusbar.cxx (revision ddde725d65c83fe3ba1186d46f6e3e08f12ba47e)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_accessibility.hxx"
30 #include <accessibility/standard/vclxaccessiblestatusbar.hxx>
31 #include <accessibility/standard/vclxaccessiblestatusbaritem.hxx>
32 #include <toolkit/helper/convert.hxx>
33 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
34 #include <vcl/status.hxx>
35 
36 
37 using namespace ::com::sun::star;
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::lang;
40 using namespace ::com::sun::star::accessibility;
41 using namespace ::comphelper;
42 
43 
44 //  ----------------------------------------------------
45 //  class VCLXAccessibleStatusBar
46 //  ----------------------------------------------------
47 
48 VCLXAccessibleStatusBar::VCLXAccessibleStatusBar( VCLXWindow* pVCLXWindow )
49     :VCLXAccessibleComponent( pVCLXWindow )
50 {
51     m_pStatusBar = static_cast< StatusBar* >( GetWindow() );
52 
53     if ( m_pStatusBar )
54         m_aAccessibleChildren.assign( m_pStatusBar->GetItemCount(), Reference< XAccessible >() );
55 }
56 
57 // -----------------------------------------------------------------------------
58 
59 VCLXAccessibleStatusBar::~VCLXAccessibleStatusBar()
60 {
61 }
62 
63 // -----------------------------------------------------------------------------
64 
65 void VCLXAccessibleStatusBar::UpdateShowing( sal_Int32 i, sal_Bool bShowing )
66 {
67     if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() )
68     {
69         Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
70         if ( xChild.is() )
71         {
72             VCLXAccessibleStatusBarItem* pVCLXAccessibleStatusBarItem = static_cast< VCLXAccessibleStatusBarItem* >( xChild.get() );
73             if ( pVCLXAccessibleStatusBarItem )
74                 pVCLXAccessibleStatusBarItem->SetShowing( bShowing );
75         }
76     }
77 }
78 
79 // -----------------------------------------------------------------------------
80 
81 void VCLXAccessibleStatusBar::UpdateItemName( sal_Int32 i )
82 {
83     if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() )
84     {
85         Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
86         if ( xChild.is() )
87         {
88             VCLXAccessibleStatusBarItem* pVCLXAccessibleStatusBarItem = static_cast< VCLXAccessibleStatusBarItem* >( xChild.get() );
89             if ( pVCLXAccessibleStatusBarItem )
90             {
91                 ::rtl::OUString sItemName = pVCLXAccessibleStatusBarItem->GetItemName();
92                 pVCLXAccessibleStatusBarItem->SetItemName( sItemName );
93             }
94         }
95     }
96 }
97 
98 // -----------------------------------------------------------------------------
99 
100 void VCLXAccessibleStatusBar::UpdateItemText( sal_Int32 i )
101 {
102     if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() )
103     {
104         Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
105         if ( xChild.is() )
106         {
107             VCLXAccessibleStatusBarItem* pVCLXAccessibleStatusBarItem = static_cast< VCLXAccessibleStatusBarItem* >( xChild.get() );
108             if ( pVCLXAccessibleStatusBarItem )
109             {
110                 ::rtl::OUString sItemText = pVCLXAccessibleStatusBarItem->GetItemText();
111                 pVCLXAccessibleStatusBarItem->SetItemText( sItemText );
112             }
113         }
114     }
115 }
116 
117 // -----------------------------------------------------------------------------
118 
119 void VCLXAccessibleStatusBar::InsertChild( sal_Int32 i )
120 {
121     if ( i >= 0 && i <= (sal_Int32)m_aAccessibleChildren.size() )
122     {
123         // insert entry in child list
124         m_aAccessibleChildren.insert( m_aAccessibleChildren.begin() + i, Reference< XAccessible >() );
125 
126         // send accessible child event
127         Reference< XAccessible > xChild( getAccessibleChild( i ) );
128         if ( xChild.is() )
129         {
130             Any aOldValue, aNewValue;
131             aNewValue <<= xChild;
132             NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
133         }
134     }
135 }
136 
137 // -----------------------------------------------------------------------------
138 
139 void VCLXAccessibleStatusBar::RemoveChild( sal_Int32 i )
140 {
141     if ( i >= 0 && i < (sal_Int32)m_aAccessibleChildren.size() )
142     {
143         // get the accessible of the removed page
144         Reference< XAccessible > xChild( m_aAccessibleChildren[i] );
145 
146         // remove entry in child list
147         m_aAccessibleChildren.erase( m_aAccessibleChildren.begin() + i );
148 
149         // send accessible child event
150         if ( xChild.is() )
151         {
152             Any aOldValue, aNewValue;
153             aOldValue <<= xChild;
154             NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
155 
156             Reference< XComponent > xComponent( xChild, UNO_QUERY );
157             if ( xComponent.is() )
158                 xComponent->dispose();
159         }
160     }
161 }
162 
163 // -----------------------------------------------------------------------------
164 
165 void VCLXAccessibleStatusBar::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
166 {
167     switch ( rVclWindowEvent.GetId() )
168     {
169         case VCLEVENT_STATUSBAR_ITEMADDED:
170         {
171             if ( m_pStatusBar )
172             {
173                 sal_uInt16 nItemId = (sal_uInt16)(sal_IntPtr) rVclWindowEvent.GetData();
174                 sal_uInt16 nItemPos = m_pStatusBar->GetItemPos( nItemId );
175                 InsertChild( nItemPos );
176             }
177         }
178         break;
179         case VCLEVENT_STATUSBAR_ITEMREMOVED:
180         {
181             if ( m_pStatusBar )
182             {
183                 sal_uInt16 nItemId = (sal_uInt16)(sal_IntPtr) rVclWindowEvent.GetData();
184                 for ( sal_Int32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
185                 {
186                     Reference< XAccessible > xChild( getAccessibleChild( i ) );
187                     if ( xChild.is() )
188                     {
189                         VCLXAccessibleStatusBarItem* pVCLXAccessibleStatusBarItem = static_cast< VCLXAccessibleStatusBarItem* >( xChild.get() );
190                         if ( pVCLXAccessibleStatusBarItem && pVCLXAccessibleStatusBarItem->GetItemId() == nItemId )
191                         {
192                             RemoveChild( i );
193                             break;
194                         }
195                     }
196                 }
197             }
198         }
199         break;
200         case VCLEVENT_STATUSBAR_ALLITEMSREMOVED:
201         {
202             for ( sal_Int32 i = m_aAccessibleChildren.size() - 1; i >= 0; --i )
203                 RemoveChild( i );
204         }
205         break;
206         case VCLEVENT_STATUSBAR_SHOWITEM:
207         case VCLEVENT_STATUSBAR_HIDEITEM:
208         {
209             if ( m_pStatusBar )
210             {
211                 sal_uInt16 nItemId = (sal_uInt16)(sal_IntPtr) rVclWindowEvent.GetData();
212                 sal_uInt16 nItemPos = m_pStatusBar->GetItemPos( nItemId );
213                 UpdateShowing( nItemPos, rVclWindowEvent.GetId() == VCLEVENT_STATUSBAR_SHOWITEM );
214             }
215         }
216         break;
217         case VCLEVENT_STATUSBAR_SHOWALLITEMS:
218         case VCLEVENT_STATUSBAR_HIDEALLITEMS:
219         {
220             for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i )
221                 UpdateShowing( i, rVclWindowEvent.GetId() == VCLEVENT_STATUSBAR_SHOWALLITEMS );
222         }
223         break;
224         case VCLEVENT_STATUSBAR_NAMECHANGED:
225         {
226             if ( m_pStatusBar )
227             {
228                 sal_uInt16 nItemId = (sal_uInt16)(sal_IntPtr) rVclWindowEvent.GetData();
229                 sal_uInt16 nItemPos = m_pStatusBar->GetItemPos( nItemId );
230                 UpdateItemName( nItemPos );
231             }
232         }
233         break;
234         case VCLEVENT_STATUSBAR_DRAWITEM:
235         {
236             if ( m_pStatusBar )
237             {
238                 sal_uInt16 nItemId = (sal_uInt16)(sal_IntPtr) rVclWindowEvent.GetData();
239                 sal_uInt16 nItemPos = m_pStatusBar->GetItemPos( nItemId );
240                 UpdateItemText( nItemPos );
241             }
242         }
243         break;
244         case VCLEVENT_OBJECT_DYING:
245         {
246             if ( m_pStatusBar )
247             {
248                 m_pStatusBar = NULL;
249 
250                 // dispose all children
251                 for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i )
252                 {
253                     Reference< XComponent > xComponent( m_aAccessibleChildren[i], UNO_QUERY );
254                     if ( xComponent.is() )
255                         xComponent->dispose();
256                 }
257                 m_aAccessibleChildren.clear();
258             }
259 
260             VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent );
261         }
262         break;
263         default:
264             VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent );
265    }
266 }
267 
268 // -----------------------------------------------------------------------------
269 // XComponent
270 // -----------------------------------------------------------------------------
271 
272 void VCLXAccessibleStatusBar::disposing()
273 {
274     VCLXAccessibleComponent::disposing();
275 
276     if ( m_pStatusBar )
277     {
278         m_pStatusBar = NULL;
279 
280         // dispose all children
281         for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i )
282         {
283             Reference< XComponent > xComponent( m_aAccessibleChildren[i], UNO_QUERY );
284             if ( xComponent.is() )
285                 xComponent->dispose();
286         }
287         m_aAccessibleChildren.clear();
288     }
289 }
290 
291 // -----------------------------------------------------------------------------
292 // XServiceInfo
293 // -----------------------------------------------------------------------------
294 
295 ::rtl::OUString VCLXAccessibleStatusBar::getImplementationName() throw (RuntimeException)
296 {
297     return ::rtl::OUString::createFromAscii( "com.sun.star.comp.toolkit.AccessibleStatusBar" );
298 }
299 
300 // -----------------------------------------------------------------------------
301 
302 Sequence< ::rtl::OUString > VCLXAccessibleStatusBar::getSupportedServiceNames() throw (RuntimeException)
303 {
304     Sequence< ::rtl::OUString > aNames(1);
305     aNames[0] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.AccessibleStatusBar" );
306     return aNames;
307 }
308 
309 // -----------------------------------------------------------------------------
310 // XAccessibleContext
311 // -----------------------------------------------------------------------------
312 
313 sal_Int32 VCLXAccessibleStatusBar::getAccessibleChildCount() throw (RuntimeException)
314 {
315     OExternalLockGuard aGuard( this );
316 
317     return m_aAccessibleChildren.size();
318 }
319 
320 // -----------------------------------------------------------------------------
321 
322 Reference< XAccessible > VCLXAccessibleStatusBar::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException)
323 {
324     OExternalLockGuard aGuard( this );
325 
326     if ( i < 0 || i >= getAccessibleChildCount() )
327         throw IndexOutOfBoundsException();
328 
329     Reference< XAccessible > xChild = m_aAccessibleChildren[i];
330     if ( !xChild.is() )
331     {
332         if ( m_pStatusBar )
333         {
334             sal_uInt16 nItemId = m_pStatusBar->GetItemId( (sal_uInt16)i );
335 
336             xChild = new VCLXAccessibleStatusBarItem( m_pStatusBar, nItemId );
337 
338             // insert into status bar item list
339             m_aAccessibleChildren[i] = xChild;
340         }
341     }
342 
343     return xChild;
344 }
345 
346 // -----------------------------------------------------------------------------
347 // XAccessibleComponent
348 // -----------------------------------------------------------------------------
349 
350 Reference< XAccessible > VCLXAccessibleStatusBar::getAccessibleAtPoint( const awt::Point& rPoint ) throw (RuntimeException)
351 {
352     OExternalLockGuard aGuard( this );
353 
354     Reference< XAccessible > xChild;
355     if ( m_pStatusBar )
356     {
357         sal_uInt16 nItemId = m_pStatusBar->GetItemId( VCLPoint( rPoint ) );
358         sal_Int32 nItemPos = m_pStatusBar->GetItemPos( nItemId );
359         if ( nItemPos >= 0 && nItemPos < (sal_Int32)m_aAccessibleChildren.size() )
360             xChild = getAccessibleChild( nItemPos );
361     }
362 
363     return xChild;
364 }
365 
366 // -----------------------------------------------------------------------------
367