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/vclxaccessiblestatusbaritem.hxx>
31 #include <toolkit/helper/externallock.hxx>
32 #include <toolkit/helper/convert.hxx>
33 #include <accessibility/helper/characterattributeshelper.hxx>
34 
35 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
36 #include <com/sun/star/accessibility/AccessibleRole.hpp>
37 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
38 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
39 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
40 
41 #include <unotools/accessiblestatesethelper.hxx>
42 #include <unotools/accessiblerelationsethelper.hxx>
43 #include <vcl/svapp.hxx>
44 #include <vcl/unohelp2.hxx>
45 #include <vcl/status.hxx>
46 #include <vcl/controllayout.hxx>
47 
48 #include <memory>
49 
50 
51 using namespace ::com::sun::star::accessibility;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::lang;
54 using namespace ::com::sun::star::beans;
55 using namespace ::com::sun::star;
56 using namespace ::comphelper;
57 
58 
59 // -----------------------------------------------------------------------------
60 // class VCLXAccessibleStatusBarItem
61 // -----------------------------------------------------------------------------
62 
63 VCLXAccessibleStatusBarItem::VCLXAccessibleStatusBarItem( StatusBar* pStatusBar, sal_uInt16 nItemId )
64 	:AccessibleTextHelper_BASE( new VCLExternalSolarLock() )
65 	,m_pStatusBar( pStatusBar )
66 	,m_nItemId( nItemId )
67 {
68 	m_pExternalLock = static_cast< VCLExternalSolarLock* >( getExternalLock() );
69 
70 	m_sItemName = GetItemName();
71 	m_sItemText = GetItemText();
72 	m_bShowing	= IsShowing();
73 }
74 
75 // -----------------------------------------------------------------------------
76 
77 VCLXAccessibleStatusBarItem::~VCLXAccessibleStatusBarItem()
78 {
79 	delete m_pExternalLock;
80 	m_pExternalLock = NULL;
81 }
82 
83 // -----------------------------------------------------------------------------
84 
85 sal_Bool VCLXAccessibleStatusBarItem::IsShowing()
86 {
87 	sal_Bool bShowing = sal_False;
88 
89 	if ( m_pStatusBar )
90 		bShowing = m_pStatusBar->IsItemVisible( m_nItemId );
91 
92 	return bShowing;
93 }
94 
95 // -----------------------------------------------------------------------------
96 
97 void VCLXAccessibleStatusBarItem::SetShowing( sal_Bool bShowing )
98 {
99 	if ( m_bShowing != bShowing )
100 	{
101 		Any aOldValue, aNewValue;
102 		if ( m_bShowing )
103 			aOldValue <<= AccessibleStateType::SHOWING;
104 		else
105 			aNewValue <<= AccessibleStateType::SHOWING;
106 		m_bShowing = bShowing;
107 		NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
108 	}
109 }
110 
111 // -----------------------------------------------------------------------------
112 
113 void VCLXAccessibleStatusBarItem::SetItemName( const ::rtl::OUString& sItemName )
114 {
115 	if ( !m_sItemName.equals( sItemName ) )
116 	{
117 		Any aOldValue, aNewValue;
118 		aOldValue <<= m_sItemName;
119 		aNewValue <<= sItemName;
120 		m_sItemName = sItemName;
121         NotifyAccessibleEvent( AccessibleEventId::NAME_CHANGED, aOldValue, aNewValue );
122 	}
123 }
124 
125 // -----------------------------------------------------------------------------
126 
127 ::rtl::OUString VCLXAccessibleStatusBarItem::GetItemName()
128 {
129 	::rtl::OUString sName;
130 	if ( m_pStatusBar )
131 		sName = m_pStatusBar->GetAccessibleName( m_nItemId );
132 
133 	return sName;
134 }
135 
136 // -----------------------------------------------------------------------------
137 
138 void VCLXAccessibleStatusBarItem::SetItemText( const ::rtl::OUString& sItemText )
139 {
140 	Any aOldValue, aNewValue;
141     if ( implInitTextChangedEvent( m_sItemText, sItemText, aOldValue, aNewValue ) )
142     {
143         m_sItemText = sItemText;
144 		NotifyAccessibleEvent( AccessibleEventId::TEXT_CHANGED, aOldValue, aNewValue );
145     }
146 }
147 
148 // -----------------------------------------------------------------------------
149 
150 ::rtl::OUString VCLXAccessibleStatusBarItem::GetItemText()
151 {
152 	::rtl::OUString sText;
153 	::vcl::ControlLayoutData aLayoutData;
154 	if ( m_pStatusBar )
155 	{
156 		Rectangle aItemRect = m_pStatusBar->GetItemRect( m_nItemId );
157 		m_pStatusBar->RecordLayoutData( &aLayoutData, aItemRect );
158 		sText = aLayoutData.m_aDisplayText;
159 	}
160 
161 	return sText;
162 }
163 
164 // -----------------------------------------------------------------------------
165 
166 void VCLXAccessibleStatusBarItem::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
167 {
168 	rStateSet.AddState( AccessibleStateType::ENABLED );
169     rStateSet.AddState( AccessibleStateType::SENSITIVE );
170 
171 	rStateSet.AddState( AccessibleStateType::VISIBLE );
172 
173 	if ( IsShowing() )
174 		rStateSet.AddState( AccessibleStateType::SHOWING );
175 }
176 
177 // -----------------------------------------------------------------------------
178 // OCommonAccessibleComponent
179 // -----------------------------------------------------------------------------
180 
181 awt::Rectangle VCLXAccessibleStatusBarItem::implGetBounds() throw (RuntimeException)
182 {
183 	awt::Rectangle aBounds( 0, 0, 0, 0 );
184 
185 	if ( m_pStatusBar )
186 		aBounds = AWTRectangle( m_pStatusBar->GetItemRect( m_nItemId ) );
187 
188 	return aBounds;
189 }
190 
191 // -----------------------------------------------------------------------------
192 // OCommonAccessibleText
193 // -----------------------------------------------------------------------------
194 
195 ::rtl::OUString VCLXAccessibleStatusBarItem::implGetText()
196 {
197 	return GetItemText();
198 }
199 
200 // -----------------------------------------------------------------------------
201 
202 lang::Locale VCLXAccessibleStatusBarItem::implGetLocale()
203 {
204 	return Application::GetSettings().GetLocale();
205 }
206 
207 // -----------------------------------------------------------------------------
208 
209 void VCLXAccessibleStatusBarItem::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
210 {
211 	nStartIndex = 0;
212 	nEndIndex = 0;
213 }
214 
215 // -----------------------------------------------------------------------------
216 // XInterface
217 // -----------------------------------------------------------------------------
218 
219 IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleStatusBarItem, AccessibleTextHelper_BASE, VCLXAccessibleStatusBarItem_BASE )
220 
221 // -----------------------------------------------------------------------------
222 // XTypeProvider
223 // -----------------------------------------------------------------------------
224 
225 IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleStatusBarItem, AccessibleTextHelper_BASE, VCLXAccessibleStatusBarItem_BASE )
226 
227 // -----------------------------------------------------------------------------
228 // XComponent
229 // -----------------------------------------------------------------------------
230 
231 void VCLXAccessibleStatusBarItem::disposing()
232 {
233 	AccessibleTextHelper_BASE::disposing();
234 
235 	m_pStatusBar = NULL;
236 	m_sItemName = ::rtl::OUString();
237 	m_sItemText = ::rtl::OUString();
238 }
239 
240 // -----------------------------------------------------------------------------
241 // XServiceInfo
242 // -----------------------------------------------------------------------------
243 
244 ::rtl::OUString VCLXAccessibleStatusBarItem::getImplementationName() throw (RuntimeException)
245 {
246 	return ::rtl::OUString::createFromAscii( "com.sun.star.comp.toolkit.AccessibleStatusBarItem" );
247 }
248 
249 // -----------------------------------------------------------------------------
250 
251 sal_Bool VCLXAccessibleStatusBarItem::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
252 {
253 	Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
254 	const ::rtl::OUString* pNames = aNames.getConstArray();
255 	const ::rtl::OUString* pEnd = pNames + aNames.getLength();
256 	for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
257 		;
258 
259 	return pNames != pEnd;
260 }
261 
262 // -----------------------------------------------------------------------------
263 
264 Sequence< ::rtl::OUString > VCLXAccessibleStatusBarItem::getSupportedServiceNames() throw (RuntimeException)
265 {
266 	Sequence< ::rtl::OUString > aNames(1);
267 	aNames[0] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.AccessibleStatusBarItem" );
268 	return aNames;
269 }
270 
271 // -----------------------------------------------------------------------------
272 // XAccessible
273 // -----------------------------------------------------------------------------
274 
275 Reference< XAccessibleContext > VCLXAccessibleStatusBarItem::getAccessibleContext(  ) throw (RuntimeException)
276 {
277 	OExternalLockGuard aGuard( this );
278 
279 	return this;
280 }
281 
282 // -----------------------------------------------------------------------------
283 // XAccessibleContext
284 // -----------------------------------------------------------------------------
285 
286 sal_Int32 VCLXAccessibleStatusBarItem::getAccessibleChildCount() throw (RuntimeException)
287 {
288 	OExternalLockGuard aGuard( this );
289 
290 	return 0;
291 }
292 
293 // -----------------------------------------------------------------------------
294 
295 Reference< XAccessible > VCLXAccessibleStatusBarItem::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException)
296 {
297 	OExternalLockGuard aGuard( this );
298 
299 	if ( i < 0 || i >= getAccessibleChildCount() )
300 		throw IndexOutOfBoundsException();
301 
302 	return Reference< XAccessible >();
303 }
304 
305 // -----------------------------------------------------------------------------
306 
307 Reference< XAccessible > VCLXAccessibleStatusBarItem::getAccessibleParent(  ) throw (RuntimeException)
308 {
309 	OExternalLockGuard aGuard( this );
310 
311 	Reference< XAccessible > xParent;
312 	if ( m_pStatusBar )
313 		xParent = m_pStatusBar->GetAccessible();
314 
315 	return xParent;
316 }
317 
318 // -----------------------------------------------------------------------------
319 
320 sal_Int32 VCLXAccessibleStatusBarItem::getAccessibleIndexInParent(  ) throw (RuntimeException)
321 {
322 	OExternalLockGuard aGuard( this );
323 
324 	sal_Int32 nIndexInParent = -1;
325 	if ( m_pStatusBar )
326 		nIndexInParent = m_pStatusBar->GetItemPos( m_nItemId );
327 
328 	return nIndexInParent;
329 }
330 
331 // -----------------------------------------------------------------------------
332 
333 sal_Int16 VCLXAccessibleStatusBarItem::getAccessibleRole(  ) throw (RuntimeException)
334 {
335 	OExternalLockGuard aGuard( this );
336 
337 	return AccessibleRole::LABEL;
338 }
339 
340 // -----------------------------------------------------------------------------
341 
342 ::rtl::OUString VCLXAccessibleStatusBarItem::getAccessibleDescription(	) throw (RuntimeException)
343 {
344 	OExternalLockGuard aGuard( this );
345 
346 	::rtl::OUString sDescription;
347 	if ( m_pStatusBar )
348 		sDescription = m_pStatusBar->GetHelpText( m_nItemId );
349 
350 	return sDescription;
351 }
352 
353 // -----------------------------------------------------------------------------
354 
355 ::rtl::OUString VCLXAccessibleStatusBarItem::getAccessibleName(  ) throw (RuntimeException)
356 {
357 	OExternalLockGuard aGuard( this );
358 
359 	return GetItemName();
360 }
361 
362 // -----------------------------------------------------------------------------
363 
364 Reference< XAccessibleRelationSet > VCLXAccessibleStatusBarItem::getAccessibleRelationSet(  ) throw (RuntimeException)
365 {
366 	OExternalLockGuard aGuard( this );
367 
368     utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper;
369 	Reference< XAccessibleRelationSet > xSet = pRelationSetHelper;
370     return xSet;
371 }
372 
373 // -----------------------------------------------------------------------------
374 
375 Reference< XAccessibleStateSet > VCLXAccessibleStatusBarItem::getAccessibleStateSet(  ) throw (RuntimeException)
376 {
377 	OExternalLockGuard aGuard( this );
378 
379 	utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
380 	Reference< XAccessibleStateSet > xSet = pStateSetHelper;
381 
382 	if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
383 	{
384 		FillAccessibleStateSet( *pStateSetHelper );
385 	}
386 	else
387 	{
388         pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
389 	}
390 
391 	return xSet;
392 }
393 
394 // -----------------------------------------------------------------------------
395 
396 Locale VCLXAccessibleStatusBarItem::getLocale(  ) throw (IllegalAccessibleComponentStateException, RuntimeException)
397 {
398 	OExternalLockGuard aGuard( this );
399 
400 	return Application::GetSettings().GetLocale();
401 }
402 
403 // -----------------------------------------------------------------------------
404 // XAccessibleComponent
405 // -----------------------------------------------------------------------------
406 
407 Reference< XAccessible > VCLXAccessibleStatusBarItem::getAccessibleAtPoint( const awt::Point& ) throw (RuntimeException)
408 {
409 	OExternalLockGuard aGuard( this );
410 
411 	return Reference< XAccessible >();
412 }
413 
414 // -----------------------------------------------------------------------------
415 
416 void VCLXAccessibleStatusBarItem::grabFocus(  ) throw (RuntimeException)
417 {
418 	// no focus for status bar items
419 }
420 
421 // -----------------------------------------------------------------------------
422 
423 sal_Int32 VCLXAccessibleStatusBarItem::getForeground(	) throw (RuntimeException)
424 {
425 	OExternalLockGuard aGuard( this );
426 
427 	sal_Int32 nColor = 0;
428 	Reference< XAccessible > xParent = getAccessibleParent();
429 	if ( xParent.is() )
430 	{
431 		Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
432 		if ( xParentComp.is() )
433 			nColor = xParentComp->getForeground();
434 	}
435 
436 	return nColor;
437 }
438 
439 // -----------------------------------------------------------------------------
440 
441 sal_Int32 VCLXAccessibleStatusBarItem::getBackground(  ) throw (RuntimeException)
442 {
443 	OExternalLockGuard aGuard( this );
444 
445 	sal_Int32 nColor = 0;
446 	Reference< XAccessible > xParent = getAccessibleParent();
447 	if ( xParent.is() )
448 	{
449 		Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
450 		if ( xParentComp.is() )
451 			nColor = xParentComp->getBackground();
452 	}
453 
454 	return nColor;
455 }
456 
457 // -----------------------------------------------------------------------------
458 // XAccessibleExtendedComponent
459 // -----------------------------------------------------------------------------
460 
461 Reference< awt::XFont > VCLXAccessibleStatusBarItem::getFont(  ) throw (RuntimeException)
462 {
463 	OExternalLockGuard aGuard( this );
464 
465 	Reference< awt::XFont > xFont;
466 	Reference< XAccessible > xParent = getAccessibleParent();
467 	if ( xParent.is() )
468 	{
469 		Reference< XAccessibleExtendedComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
470 		if ( xParentComp.is() )
471 			xFont = xParentComp->getFont();
472 	}
473 
474 	return xFont;
475 }
476 
477 // -----------------------------------------------------------------------------
478 
479 ::rtl::OUString VCLXAccessibleStatusBarItem::getTitledBorderText(  ) throw (RuntimeException)
480 {
481 	OExternalLockGuard aGuard( this );
482 
483 	return GetItemText();
484 }
485 
486 // -----------------------------------------------------------------------------
487 
488 ::rtl::OUString VCLXAccessibleStatusBarItem::getToolTipText(  ) throw (RuntimeException)
489 {
490 	OExternalLockGuard aGuard( this );
491 
492 	return ::rtl::OUString();
493 }
494 
495 // -----------------------------------------------------------------------------
496 // XAccessibleText
497 // -----------------------------------------------------------------------------
498 
499 sal_Int32 VCLXAccessibleStatusBarItem::getCaretPosition() throw (RuntimeException)
500 {
501 	OExternalLockGuard aGuard( this );
502 
503 	return -1;
504 }
505 
506 // -----------------------------------------------------------------------------
507 
508 sal_Bool VCLXAccessibleStatusBarItem::setCaretPosition( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
509 {
510 	OExternalLockGuard aGuard( this );
511 
512     if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) )
513         throw IndexOutOfBoundsException();
514 
515 	return sal_False;
516 }
517 
518 // -----------------------------------------------------------------------------
519 
520 Sequence< PropertyValue > VCLXAccessibleStatusBarItem::getCharacterAttributes( sal_Int32 nIndex, const Sequence< ::rtl::OUString >& aRequestedAttributes ) throw (IndexOutOfBoundsException, RuntimeException)
521 {
522 	OExternalLockGuard aGuard( this );
523 
524 	Sequence< PropertyValue > aValues;
525 	::rtl::OUString sText( implGetText() );
526 
527     if ( !implIsValidIndex( nIndex, sText.getLength() ) )
528         throw IndexOutOfBoundsException();
529 
530 	if ( m_pStatusBar )
531 	{
532 		Font aFont = m_pStatusBar->GetFont();
533 		sal_Int32 nBackColor = getBackground();
534 		sal_Int32 nColor = getForeground();
535         ::std::auto_ptr< CharacterAttributesHelper > pHelper( new CharacterAttributesHelper( aFont, nBackColor, nColor ) );
536 		aValues = pHelper->GetCharacterAttributes( aRequestedAttributes );
537 	}
538 
539     return aValues;
540 }
541 
542 // -----------------------------------------------------------------------------
543 
544 awt::Rectangle VCLXAccessibleStatusBarItem::getCharacterBounds( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
545 {
546 	OExternalLockGuard aGuard( this );
547 
548     if ( !implIsValidIndex( nIndex, implGetText().getLength() ) )
549         throw IndexOutOfBoundsException();
550 
551 	awt::Rectangle aBounds( 0, 0, 0, 0 );
552 	if ( m_pStatusBar )
553 	{
554 		::vcl::ControlLayoutData aLayoutData;
555 		Rectangle aItemRect = m_pStatusBar->GetItemRect( m_nItemId );
556 		m_pStatusBar->RecordLayoutData( &aLayoutData, aItemRect );
557 		Rectangle aCharRect = aLayoutData.GetCharacterBounds( nIndex );
558 		aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() );
559 		aBounds = AWTRectangle( aCharRect );
560 	}
561 
562 	return aBounds;
563 }
564 
565 // -----------------------------------------------------------------------------
566 
567 sal_Int32 VCLXAccessibleStatusBarItem::getIndexAtPoint( const awt::Point& aPoint ) throw (RuntimeException)
568 {
569 	OExternalLockGuard aGuard( this );
570 
571 	sal_Int32 nIndex = -1;
572 	if ( m_pStatusBar )
573 	{
574 		::vcl::ControlLayoutData aLayoutData;
575 		Rectangle aItemRect = m_pStatusBar->GetItemRect( m_nItemId );
576 		m_pStatusBar->RecordLayoutData( &aLayoutData, aItemRect );
577 		Point aPnt( VCLPoint( aPoint ) );
578 		aPnt += aItemRect.TopLeft();
579 		nIndex = aLayoutData.GetIndexForPoint( aPnt );
580 	}
581 
582     return nIndex;
583 }
584 
585 // -----------------------------------------------------------------------------
586 
587 sal_Bool VCLXAccessibleStatusBarItem::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
588 {
589 	OExternalLockGuard aGuard( this );
590 
591     if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) )
592         throw IndexOutOfBoundsException();
593 
594 	return sal_False;
595 }
596 
597 // -----------------------------------------------------------------------------
598 
599 sal_Bool VCLXAccessibleStatusBarItem::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
600 {
601 	OExternalLockGuard aGuard( this );
602 
603 	sal_Bool bReturn = sal_False;
604 
605 	if ( m_pStatusBar )
606 	{
607 		Reference< datatransfer::clipboard::XClipboard > xClipboard = m_pStatusBar->GetClipboard();
608 		if ( xClipboard.is() )
609 		{
610 			::rtl::OUString sText( getTextRange( nStartIndex, nEndIndex ) );
611 
612 			::vcl::unohelper::TextDataObject* pDataObj = new ::vcl::unohelper::TextDataObject( sText );
613 			const sal_uInt32 nRef = Application::ReleaseSolarMutex();
614 			xClipboard->setContents( pDataObj, NULL );
615 
616 			Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY );
617 			if( xFlushableClipboard.is() )
618 				xFlushableClipboard->flushClipboard();
619 
620 			Application::AcquireSolarMutex( nRef );
621 
622 			bReturn = sal_True;
623 		}
624 	}
625 
626     return bReturn;
627 }
628 
629 // -----------------------------------------------------------------------------
630