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