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 <unotools/accessiblestatesethelper.hxx>
21 : #include <vcl/svapp.hxx>
22 : #include <vcl/settings.hxx>
23 : #include <svtools/valueset.hxx>
24 : #include "valueimp.hxx"
25 : #include <comphelper/servicehelper.hxx>
26 : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
27 : #include <com/sun/star/accessibility/AccessibleRole.hpp>
28 : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
29 : #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
30 : #include <unotools/accessiblerelationsethelper.hxx>
31 :
32 : using namespace ::com::sun::star;
33 :
34 :
35 : // - ValueSetItem -
36 :
37 :
38 0 : ValueSetItem::ValueSetItem( ValueSet& rParent )
39 : : mrParent(rParent)
40 : , mnId(0)
41 : , meType(VALUESETITEM_NONE)
42 : , mbVisible(true)
43 : , mpData(NULL)
44 : , mbSelected(false)
45 0 : , mpxAcc(NULL)
46 : {
47 0 : }
48 :
49 :
50 :
51 0 : ValueSetItem::~ValueSetItem()
52 : {
53 0 : if( mpxAcc )
54 : {
55 0 : static_cast< ValueItemAcc* >( mpxAcc->get() )->ParentDestroyed();
56 0 : delete mpxAcc;
57 : }
58 0 : }
59 :
60 :
61 :
62 0 : uno::Reference< accessibility::XAccessible > ValueSetItem::GetAccessible( bool bIsTransientChildrenDisabled )
63 : {
64 0 : if( !mpxAcc )
65 0 : mpxAcc = new uno::Reference< accessibility::XAccessible >( new ValueItemAcc( this, bIsTransientChildrenDisabled ) );
66 :
67 0 : return *mpxAcc;
68 : }
69 :
70 :
71 : // - ValueSetAcc -
72 :
73 :
74 0 : ValueSetAcc::ValueSetAcc( ValueSet* pParent, bool bIsTransientChildrenDisabled ) :
75 : ValueSetAccComponentBase (m_aMutex),
76 : mpParent( pParent ),
77 : mbIsTransientChildrenDisabled( bIsTransientChildrenDisabled ),
78 0 : mbIsFocused(false)
79 : {
80 0 : }
81 :
82 :
83 :
84 0 : ValueSetAcc::~ValueSetAcc()
85 : {
86 0 : }
87 :
88 :
89 :
90 0 : void ValueSetAcc::FireAccessibleEvent( short nEventId, const uno::Any& rOldValue, const uno::Any& rNewValue )
91 : {
92 0 : if( nEventId )
93 : {
94 0 : ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > > aTmpListeners( mxEventListeners );
95 0 : accessibility::AccessibleEventObject aEvtObject;
96 :
97 0 : aEvtObject.EventId = nEventId;
98 0 : aEvtObject.Source = static_cast<uno::XWeak*>(this);
99 0 : aEvtObject.NewValue = rNewValue;
100 0 : aEvtObject.OldValue = rOldValue;
101 :
102 0 : for (::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::const_iterator aIter( aTmpListeners.begin() );
103 0 : aIter != aTmpListeners.end() ; ++aIter)
104 : {
105 : try
106 : {
107 0 : (*aIter)->notifyEvent( aEvtObject );
108 : }
109 0 : catch(const uno::Exception&)
110 : {
111 : }
112 0 : }
113 : }
114 0 : }
115 :
116 : namespace
117 : {
118 : class theValueSetAccUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theValueSetAccUnoTunnelId > {};
119 : }
120 :
121 0 : const uno::Sequence< sal_Int8 >& ValueSetAcc::getUnoTunnelId()
122 : {
123 0 : return theValueSetAccUnoTunnelId::get().getSeq();
124 : }
125 :
126 :
127 :
128 0 : ValueSetAcc* ValueSetAcc::getImplementation( const uno::Reference< uno::XInterface >& rxData )
129 : throw()
130 : {
131 : try
132 : {
133 0 : uno::Reference< lang::XUnoTunnel > xUnoTunnel( rxData, uno::UNO_QUERY );
134 0 : return( xUnoTunnel.is() ? reinterpret_cast<ValueSetAcc*>(sal::static_int_cast<sal_IntPtr>(xUnoTunnel->getSomething( ValueSetAcc::getUnoTunnelId() ))) : NULL );
135 : }
136 0 : catch(const ::com::sun::star::uno::Exception&)
137 : {
138 0 : return NULL;
139 : }
140 : }
141 :
142 :
143 :
144 :
145 0 : void ValueSetAcc::GetFocus (void)
146 : {
147 0 : mbIsFocused = true;
148 :
149 : // Broadcast the state change.
150 0 : ::com::sun::star::uno::Any aOldState, aNewState;
151 0 : aNewState <<= ::com::sun::star::accessibility::AccessibleStateType::FOCUSED;
152 : FireAccessibleEvent(
153 : ::com::sun::star::accessibility::AccessibleEventId::STATE_CHANGED,
154 0 : aOldState, aNewState);
155 0 : }
156 :
157 :
158 :
159 0 : void ValueSetAcc::LoseFocus (void)
160 : {
161 0 : mbIsFocused = false;
162 :
163 : // Broadcast the state change.
164 0 : ::com::sun::star::uno::Any aOldState, aNewState;
165 0 : aOldState <<= ::com::sun::star::accessibility::AccessibleStateType::FOCUSED;
166 : FireAccessibleEvent(
167 : ::com::sun::star::accessibility::AccessibleEventId::STATE_CHANGED,
168 0 : aOldState, aNewState);
169 0 : }
170 :
171 :
172 :
173 0 : uno::Reference< accessibility::XAccessibleContext > SAL_CALL ValueSetAcc::getAccessibleContext()
174 : throw (uno::RuntimeException, std::exception)
175 : {
176 0 : ThrowIfDisposed();
177 0 : return this;
178 : }
179 :
180 :
181 :
182 0 : sal_Int32 SAL_CALL ValueSetAcc::getAccessibleChildCount()
183 : throw (uno::RuntimeException, std::exception)
184 : {
185 0 : const SolarMutexGuard aSolarGuard;
186 0 : ThrowIfDisposed();
187 :
188 0 : sal_Int32 nCount = mpParent->ImplGetVisibleItemCount();
189 0 : if (HasNoneField())
190 0 : nCount += 1;
191 0 : return nCount;
192 : }
193 :
194 :
195 :
196 0 : uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessibleChild( sal_Int32 i )
197 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
198 : {
199 0 : ThrowIfDisposed();
200 0 : const SolarMutexGuard aSolarGuard;
201 0 : uno::Reference< accessibility::XAccessible > xRet;
202 0 : ValueSetItem* pItem = getItem (sal::static_int_cast< sal_uInt16 >(i));
203 :
204 0 : if( pItem )
205 0 : xRet = pItem->GetAccessible( mbIsTransientChildrenDisabled );
206 : else
207 0 : throw lang::IndexOutOfBoundsException();
208 :
209 0 : return xRet;
210 : }
211 :
212 :
213 :
214 0 : uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessibleParent()
215 : throw (uno::RuntimeException, std::exception)
216 : {
217 0 : ThrowIfDisposed();
218 0 : const SolarMutexGuard aSolarGuard;
219 0 : Window* pParent = mpParent->GetParent();
220 0 : uno::Reference< accessibility::XAccessible > xRet;
221 :
222 0 : if( pParent )
223 0 : xRet = pParent->GetAccessible();
224 :
225 0 : return xRet;
226 : }
227 :
228 :
229 :
230 0 : sal_Int32 SAL_CALL ValueSetAcc::getAccessibleIndexInParent()
231 : throw (uno::RuntimeException, std::exception)
232 : {
233 0 : ThrowIfDisposed();
234 0 : const SolarMutexGuard aSolarGuard;
235 0 : Window* pParent = mpParent->GetParent();
236 0 : sal_Int32 nRet = 0;
237 :
238 0 : if( pParent )
239 : {
240 0 : sal_Bool bFound = sal_False;
241 :
242 0 : for( sal_uInt16 i = 0, nCount = pParent->GetChildCount(); ( i < nCount ) && !bFound; i++ )
243 : {
244 0 : if( pParent->GetChild( i ) == mpParent )
245 : {
246 0 : nRet = i;
247 0 : bFound = sal_True;
248 : }
249 : }
250 : }
251 :
252 0 : return nRet;
253 : }
254 :
255 :
256 :
257 0 : sal_Int16 SAL_CALL ValueSetAcc::getAccessibleRole()
258 : throw (uno::RuntimeException, std::exception)
259 : {
260 0 : ThrowIfDisposed();
261 : // #i73746# As the Java Access Bridge (v 2.0.1) uses "managesDescendants"
262 : // always if the role is LIST, we need a different role in this case
263 : return (mbIsTransientChildrenDisabled
264 : ? accessibility::AccessibleRole::PANEL
265 0 : : accessibility::AccessibleRole::LIST );
266 : }
267 :
268 :
269 :
270 0 : OUString SAL_CALL ValueSetAcc::getAccessibleDescription()
271 : throw (uno::RuntimeException, std::exception)
272 : {
273 0 : ThrowIfDisposed();
274 0 : const SolarMutexGuard aSolarGuard;
275 0 : OUString aRet( "ValueSet" );
276 :
277 0 : return aRet;
278 : }
279 :
280 :
281 :
282 0 : OUString SAL_CALL ValueSetAcc::getAccessibleName()
283 : throw (uno::RuntimeException, std::exception)
284 : {
285 0 : ThrowIfDisposed();
286 0 : const SolarMutexGuard aSolarGuard;
287 0 : OUString aRet;
288 :
289 0 : if (mpParent)
290 : {
291 0 : aRet = mpParent->GetAccessibleName();
292 :
293 0 : if ( aRet.isEmpty() )
294 : {
295 0 : Window* pLabel = mpParent->GetAccessibleRelationLabeledBy();
296 0 : if ( pLabel && pLabel != mpParent )
297 0 : aRet = OutputDevice::GetNonMnemonicString( pLabel->GetText() );
298 :
299 0 : if (aRet.isEmpty())
300 0 : aRet = mpParent->GetQuickHelpText();
301 : }
302 : }
303 :
304 0 : return aRet;
305 : }
306 :
307 :
308 :
309 0 : uno::Reference< accessibility::XAccessibleRelationSet > SAL_CALL ValueSetAcc::getAccessibleRelationSet()
310 : throw (uno::RuntimeException, std::exception)
311 : {
312 0 : ThrowIfDisposed();
313 0 : SolarMutexGuard g;
314 0 : uno::Reference< accessibility::XAccessibleRelationSet > xRelSet;
315 0 : Window* pWindow = (Window*)mpParent;
316 0 : if ( pWindow )
317 : {
318 0 : utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper;
319 0 : xRelSet = pRelationSet;
320 :
321 0 : Window *pLabeledBy = pWindow->GetAccessibleRelationLabeledBy();
322 0 : if ( pLabeledBy && pLabeledBy != pWindow )
323 : {
324 0 : uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
325 0 : aSequence[0] = pLabeledBy->GetAccessible();
326 0 : pRelationSet->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY, aSequence ) );
327 : }
328 :
329 0 : Window* pMemberOf = pWindow->GetAccessibleRelationMemberOf();
330 0 : if ( pMemberOf && pMemberOf != pWindow )
331 : {
332 0 : uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
333 0 : aSequence[0] = pMemberOf->GetAccessible();
334 0 : pRelationSet->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) );
335 : }
336 : }
337 0 : return xRelSet;
338 : }
339 :
340 :
341 :
342 0 : uno::Reference< accessibility::XAccessibleStateSet > SAL_CALL ValueSetAcc::getAccessibleStateSet()
343 : throw (uno::RuntimeException, std::exception)
344 : {
345 0 : ThrowIfDisposed();
346 0 : ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper();
347 :
348 : // Set some states.
349 0 : pStateSet->AddState (accessibility::AccessibleStateType::ENABLED);
350 0 : pStateSet->AddState (accessibility::AccessibleStateType::SENSITIVE);
351 0 : pStateSet->AddState (accessibility::AccessibleStateType::SHOWING);
352 0 : pStateSet->AddState (accessibility::AccessibleStateType::VISIBLE);
353 0 : if ( !mbIsTransientChildrenDisabled )
354 0 : pStateSet->AddState (accessibility::AccessibleStateType::MANAGES_DESCENDANTS);
355 0 : pStateSet->AddState (accessibility::AccessibleStateType::FOCUSABLE);
356 0 : if (mbIsFocused)
357 0 : pStateSet->AddState (accessibility::AccessibleStateType::FOCUSED);
358 :
359 0 : return pStateSet;
360 : }
361 :
362 :
363 :
364 0 : lang::Locale SAL_CALL ValueSetAcc::getLocale()
365 : throw (accessibility::IllegalAccessibleComponentStateException, uno::RuntimeException, std::exception)
366 : {
367 0 : ThrowIfDisposed();
368 0 : const SolarMutexGuard aSolarGuard;
369 0 : const OUString aEmptyStr;
370 0 : uno::Reference< accessibility::XAccessible > xParent( getAccessibleParent() );
371 0 : lang::Locale aRet( aEmptyStr, aEmptyStr, aEmptyStr );
372 :
373 0 : if( xParent.is() )
374 : {
375 0 : uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
376 :
377 0 : if( xParentContext.is() )
378 0 : aRet = xParentContext->getLocale ();
379 : }
380 :
381 0 : return aRet;
382 : }
383 :
384 :
385 :
386 0 : void SAL_CALL ValueSetAcc::addAccessibleEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
387 : throw (uno::RuntimeException, std::exception)
388 : {
389 0 : ThrowIfDisposed();
390 0 : ::osl::MutexGuard aGuard (m_aMutex);
391 :
392 0 : if( rxListener.is() )
393 : {
394 0 : ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::const_iterator aIter = mxEventListeners.begin();
395 0 : sal_Bool bFound = sal_False;
396 :
397 0 : while( !bFound && ( aIter != mxEventListeners.end() ) )
398 : {
399 0 : if( *aIter == rxListener )
400 0 : bFound = sal_True;
401 : else
402 0 : ++aIter;
403 : }
404 :
405 0 : if (!bFound)
406 0 : mxEventListeners.push_back( rxListener );
407 0 : }
408 0 : }
409 :
410 :
411 :
412 0 : void SAL_CALL ValueSetAcc::removeAccessibleEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
413 : throw (uno::RuntimeException, std::exception)
414 : {
415 0 : ThrowIfDisposed();
416 0 : ::osl::MutexGuard aGuard (m_aMutex);
417 :
418 0 : if( rxListener.is() )
419 : {
420 : ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::iterator aIter =
421 0 : std::find(mxEventListeners.begin(), mxEventListeners.end(), rxListener);
422 :
423 0 : if (aIter != mxEventListeners.end())
424 0 : mxEventListeners.erase(aIter);
425 0 : }
426 0 : }
427 :
428 :
429 :
430 0 : sal_Bool SAL_CALL ValueSetAcc::containsPoint( const awt::Point& aPoint )
431 : throw (uno::RuntimeException, std::exception)
432 : {
433 0 : ThrowIfDisposed();
434 0 : const awt::Rectangle aRect( getBounds() );
435 0 : const Point aSize( aRect.Width, aRect.Height );
436 0 : const Point aNullPoint, aTestPoint( aPoint.X, aPoint.Y );
437 :
438 0 : return Rectangle( aNullPoint, aSize ).IsInside( aTestPoint );
439 : }
440 :
441 :
442 :
443 0 : uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessibleAtPoint( const awt::Point& aPoint )
444 : throw (uno::RuntimeException, std::exception)
445 : {
446 0 : ThrowIfDisposed();
447 0 : const SolarMutexGuard aSolarGuard;
448 0 : const sal_uInt16 nItemId = mpParent->GetItemId( Point( aPoint.X, aPoint.Y ) );
449 0 : uno::Reference< accessibility::XAccessible > xRet;
450 :
451 0 : if ( nItemId )
452 : {
453 0 : const size_t nItemPos = mpParent->GetItemPos( nItemId );
454 :
455 0 : if( VALUESET_ITEM_NONEITEM != nItemPos )
456 : {
457 0 : ValueSetItem *const pItem = mpParent->mItemList[nItemPos];
458 0 : xRet = pItem->GetAccessible( mbIsTransientChildrenDisabled );
459 : }
460 : }
461 :
462 0 : return xRet;
463 : }
464 :
465 :
466 :
467 0 : awt::Rectangle SAL_CALL ValueSetAcc::getBounds()
468 : throw (uno::RuntimeException, std::exception)
469 : {
470 0 : ThrowIfDisposed();
471 0 : const SolarMutexGuard aSolarGuard;
472 0 : const Point aOutPos( mpParent->GetPosPixel() );
473 0 : const Size aOutSize( mpParent->GetOutputSizePixel() );
474 0 : awt::Rectangle aRet;
475 :
476 0 : aRet.X = aOutPos.X();
477 0 : aRet.Y = aOutPos.Y();
478 0 : aRet.Width = aOutSize.Width();
479 0 : aRet.Height = aOutSize.Height();
480 :
481 0 : return aRet;
482 : }
483 :
484 :
485 :
486 0 : awt::Point SAL_CALL ValueSetAcc::getLocation()
487 : throw (uno::RuntimeException, std::exception)
488 : {
489 0 : ThrowIfDisposed();
490 0 : const awt::Rectangle aRect( getBounds() );
491 0 : awt::Point aRet;
492 :
493 0 : aRet.X = aRect.X;
494 0 : aRet.Y = aRect.Y;
495 :
496 0 : return aRet;
497 : }
498 :
499 :
500 :
501 0 : awt::Point SAL_CALL ValueSetAcc::getLocationOnScreen()
502 : throw (uno::RuntimeException, std::exception)
503 : {
504 0 : ThrowIfDisposed();
505 0 : const SolarMutexGuard aSolarGuard;
506 0 : const Point aScreenPos( mpParent->OutputToAbsoluteScreenPixel( Point() ) );
507 0 : awt::Point aRet;
508 :
509 0 : aRet.X = aScreenPos.X();
510 0 : aRet.Y = aScreenPos.Y();
511 :
512 0 : return aRet;
513 : }
514 :
515 :
516 :
517 0 : awt::Size SAL_CALL ValueSetAcc::getSize()
518 : throw (uno::RuntimeException, std::exception)
519 : {
520 0 : ThrowIfDisposed();
521 0 : const awt::Rectangle aRect( getBounds() );
522 0 : awt::Size aRet;
523 :
524 0 : aRet.Width = aRect.Width;
525 0 : aRet.Height = aRect.Height;
526 :
527 0 : return aRet;
528 : }
529 :
530 :
531 :
532 0 : void SAL_CALL ValueSetAcc::grabFocus()
533 : throw (uno::RuntimeException, std::exception)
534 : {
535 0 : ThrowIfDisposed();
536 0 : const SolarMutexGuard aSolarGuard;
537 0 : mpParent->GrabFocus();
538 0 : }
539 :
540 :
541 :
542 0 : uno::Any SAL_CALL ValueSetAcc::getAccessibleKeyBinding()
543 : throw (uno::RuntimeException)
544 : {
545 0 : ThrowIfDisposed();
546 0 : return uno::Any();
547 : }
548 :
549 :
550 :
551 0 : sal_Int32 SAL_CALL ValueSetAcc::getForeground( )
552 : throw (uno::RuntimeException, std::exception)
553 : {
554 0 : ThrowIfDisposed();
555 0 : sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor().GetColor();
556 0 : return static_cast<sal_Int32>(nColor);
557 : }
558 :
559 :
560 :
561 0 : sal_Int32 SAL_CALL ValueSetAcc::getBackground( )
562 : throw (uno::RuntimeException, std::exception)
563 : {
564 0 : ThrowIfDisposed();
565 0 : sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor();
566 0 : return static_cast<sal_Int32>(nColor);
567 : }
568 :
569 :
570 :
571 0 : void SAL_CALL ValueSetAcc::selectAccessibleChild( sal_Int32 nChildIndex )
572 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
573 : {
574 0 : ThrowIfDisposed();
575 0 : const SolarMutexGuard aSolarGuard;
576 0 : ValueSetItem* pItem = getItem (sal::static_int_cast< sal_uInt16 >(nChildIndex));
577 :
578 0 : if(pItem != NULL)
579 : {
580 0 : mpParent->SelectItem( pItem->mnId );
581 0 : mpParent->Select ();
582 : }
583 : else
584 0 : throw lang::IndexOutOfBoundsException();
585 0 : }
586 :
587 :
588 :
589 0 : sal_Bool SAL_CALL ValueSetAcc::isAccessibleChildSelected( sal_Int32 nChildIndex )
590 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
591 : {
592 0 : ThrowIfDisposed();
593 0 : const SolarMutexGuard aSolarGuard;
594 0 : ValueSetItem* pItem = getItem (sal::static_int_cast< sal_uInt16 >(nChildIndex));
595 0 : sal_Bool bRet = sal_False;
596 :
597 0 : if (pItem != NULL)
598 0 : bRet = mpParent->IsItemSelected( pItem->mnId );
599 : else
600 0 : throw lang::IndexOutOfBoundsException();
601 :
602 0 : return bRet;
603 : }
604 :
605 :
606 :
607 0 : void SAL_CALL ValueSetAcc::clearAccessibleSelection()
608 : throw (uno::RuntimeException, std::exception)
609 : {
610 0 : ThrowIfDisposed();
611 0 : const SolarMutexGuard aSolarGuard;
612 0 : mpParent->SetNoSelection();
613 0 : }
614 :
615 :
616 :
617 0 : void SAL_CALL ValueSetAcc::selectAllAccessibleChildren()
618 : throw (uno::RuntimeException, std::exception)
619 : {
620 0 : ThrowIfDisposed();
621 : // unsupported due to single selection only
622 0 : }
623 :
624 :
625 :
626 0 : sal_Int32 SAL_CALL ValueSetAcc::getSelectedAccessibleChildCount()
627 : throw (uno::RuntimeException, std::exception)
628 : {
629 0 : ThrowIfDisposed();
630 0 : const SolarMutexGuard aSolarGuard;
631 0 : sal_Int32 nRet = 0;
632 :
633 0 : for( sal_uInt16 i = 0, nCount = getItemCount(); i < nCount; i++ )
634 : {
635 0 : ValueSetItem* pItem = getItem (i);
636 :
637 0 : if( pItem && mpParent->IsItemSelected( pItem->mnId ) )
638 0 : ++nRet;
639 : }
640 :
641 0 : return nRet;
642 : }
643 :
644 :
645 :
646 0 : uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
647 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
648 : {
649 0 : ThrowIfDisposed();
650 0 : const SolarMutexGuard aSolarGuard;
651 0 : uno::Reference< accessibility::XAccessible > xRet;
652 :
653 0 : for( sal_uInt16 i = 0, nCount = getItemCount(), nSel = 0; ( i < nCount ) && !xRet.is(); i++ )
654 : {
655 0 : ValueSetItem* pItem = getItem(i);
656 :
657 0 : if( pItem && mpParent->IsItemSelected( pItem->mnId ) && ( nSelectedChildIndex == static_cast< sal_Int32 >( nSel++ ) ) )
658 0 : xRet = pItem->GetAccessible( mbIsTransientChildrenDisabled );
659 : }
660 :
661 0 : return xRet;
662 : }
663 :
664 :
665 :
666 0 : void SAL_CALL ValueSetAcc::deselectAccessibleChild( sal_Int32 nChildIndex )
667 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
668 : {
669 0 : ThrowIfDisposed();
670 0 : const SolarMutexGuard aSolarGuard;
671 : // Because of the single selection we can reset the whole selection when
672 : // the specified child is currently selected.
673 0 : if (isAccessibleChildSelected(nChildIndex))
674 0 : mpParent->SetNoSelection();
675 0 : }
676 :
677 :
678 :
679 0 : sal_Int64 SAL_CALL ValueSetAcc::getSomething( const uno::Sequence< sal_Int8 >& rId ) throw( uno::RuntimeException, std::exception )
680 : {
681 : sal_Int64 nRet;
682 :
683 0 : if( ( rId.getLength() == 16 ) && ( 0 == memcmp( ValueSetAcc::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
684 0 : nRet = reinterpret_cast< sal_Int64 >( this );
685 : else
686 0 : nRet = 0;
687 :
688 0 : return nRet;
689 : }
690 :
691 :
692 :
693 :
694 0 : void SAL_CALL ValueSetAcc::disposing (void)
695 : {
696 0 : ::std::vector<uno::Reference<accessibility::XAccessibleEventListener> > aListenerListCopy;
697 :
698 : {
699 : // Make a copy of the list and clear the original.
700 0 : const SolarMutexGuard aSolarGuard;
701 0 : ::osl::MutexGuard aGuard (m_aMutex);
702 0 : aListenerListCopy = mxEventListeners;
703 0 : mxEventListeners.clear();
704 :
705 : // Reset the pointer to the parent. It has to be the one who has
706 : // disposed us because he is dying.
707 0 : mpParent = NULL;
708 : }
709 :
710 : // Inform all listeners that this objects is disposing.
711 : ::std::vector<uno::Reference<accessibility::XAccessibleEventListener> >::const_iterator
712 0 : aListenerIterator (aListenerListCopy.begin());
713 0 : lang::EventObject aEvent (static_cast<accessibility::XAccessible*>(this));
714 0 : while (aListenerIterator != aListenerListCopy.end())
715 : {
716 : try
717 : {
718 0 : (*aListenerIterator)->disposing (aEvent);
719 : }
720 0 : catch(const uno::Exception&)
721 : {
722 : // Ignore exceptions.
723 : }
724 :
725 0 : ++aListenerIterator;
726 0 : }
727 0 : }
728 :
729 :
730 0 : sal_uInt16 ValueSetAcc::getItemCount (void) const
731 : {
732 0 : sal_uInt16 nCount = mpParent->ImplGetVisibleItemCount();
733 : // When the None-Item is visible then increase the number of items by
734 : // one.
735 0 : if (HasNoneField())
736 0 : nCount += 1;
737 0 : return nCount;
738 : }
739 :
740 :
741 0 : ValueSetItem* ValueSetAcc::getItem (sal_uInt16 nIndex) const
742 : {
743 0 : ValueSetItem* pItem = NULL;
744 :
745 0 : if (HasNoneField())
746 : {
747 0 : if (nIndex == 0)
748 : // When present the first item is the then always visible none field.
749 0 : pItem = mpParent->ImplGetItem (VALUESET_ITEM_NONEITEM);
750 : else
751 : // Shift down the index to compensate for the none field.
752 0 : nIndex -= 1;
753 : }
754 0 : if (pItem == NULL)
755 0 : pItem = mpParent->ImplGetItem (static_cast<sal_uInt16>(nIndex));
756 :
757 0 : return pItem;
758 : }
759 :
760 :
761 :
762 :
763 0 : void ValueSetAcc::ThrowIfDisposed (void)
764 : throw (::com::sun::star::lang::DisposedException)
765 : {
766 0 : if (rBHelper.bDisposed || rBHelper.bInDispose)
767 : {
768 : OSL_TRACE ("Calling disposed object. Throwing exception:");
769 : throw lang::DisposedException (
770 : OUString("object has been already disposed"),
771 0 : static_cast<uno::XWeak*>(this));
772 : }
773 : else
774 : {
775 : DBG_ASSERT (mpParent!=NULL, "ValueSetAcc not disposed but mpParent == NULL");
776 : }
777 0 : }
778 :
779 :
780 :
781 0 : bool ValueSetAcc::HasNoneField (void) const
782 : {
783 : DBG_ASSERT (mpParent!=NULL, "ValueSetAcc::HasNoneField called with mpParent==NULL");
784 0 : return ((mpParent->GetStyle() & WB_NONEFIELD) != 0);
785 : }
786 :
787 :
788 :
789 :
790 :
791 : // - ValueItemAcc -
792 :
793 :
794 0 : ValueItemAcc::ValueItemAcc( ValueSetItem* pParent, bool bIsTransientChildrenDisabled ) :
795 : mpParent( pParent ),
796 0 : mbIsTransientChildrenDisabled( bIsTransientChildrenDisabled )
797 : {
798 0 : }
799 :
800 :
801 :
802 0 : ValueItemAcc::~ValueItemAcc()
803 : {
804 0 : }
805 :
806 :
807 :
808 0 : void ValueItemAcc::FireAccessibleEvent( short nEventId, const uno::Any& rOldValue, const uno::Any& rNewValue )
809 : {
810 0 : if( nEventId )
811 : {
812 0 : ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > > aTmpListeners( mxEventListeners );
813 0 : accessibility::AccessibleEventObject aEvtObject;
814 :
815 0 : aEvtObject.EventId = nEventId;
816 0 : aEvtObject.Source = static_cast<uno::XWeak*>(this);
817 0 : aEvtObject.NewValue = rNewValue;
818 0 : aEvtObject.OldValue = rOldValue;
819 :
820 0 : for (::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::const_iterator aIter( aTmpListeners.begin() );
821 0 : aIter != aTmpListeners.end() ; ++aIter)
822 : {
823 0 : (*aIter)->notifyEvent( aEvtObject );
824 0 : }
825 : }
826 0 : }
827 :
828 :
829 :
830 0 : void ValueItemAcc::ParentDestroyed()
831 : {
832 0 : const ::osl::MutexGuard aGuard( maMutex );
833 0 : mpParent = NULL;
834 0 : }
835 :
836 : namespace
837 : {
838 : class theValueItemAccUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theValueItemAccUnoTunnelId > {};
839 : }
840 :
841 0 : const uno::Sequence< sal_Int8 >& ValueItemAcc::getUnoTunnelId()
842 : {
843 0 : return theValueItemAccUnoTunnelId::get().getSeq();
844 : }
845 :
846 :
847 :
848 0 : ValueItemAcc* ValueItemAcc::getImplementation( const uno::Reference< uno::XInterface >& rxData )
849 : throw()
850 : {
851 : try
852 : {
853 0 : uno::Reference< lang::XUnoTunnel > xUnoTunnel( rxData, uno::UNO_QUERY );
854 0 : return( xUnoTunnel.is() ? reinterpret_cast<ValueItemAcc*>(sal::static_int_cast<sal_IntPtr>(xUnoTunnel->getSomething( ValueItemAcc::getUnoTunnelId() ))) : NULL );
855 : }
856 0 : catch(const ::com::sun::star::uno::Exception&)
857 : {
858 0 : return NULL;
859 : }
860 : }
861 :
862 :
863 :
864 0 : uno::Reference< accessibility::XAccessibleContext > SAL_CALL ValueItemAcc::getAccessibleContext()
865 : throw (uno::RuntimeException, std::exception)
866 : {
867 0 : return this;
868 : }
869 :
870 :
871 :
872 0 : sal_Int32 SAL_CALL ValueItemAcc::getAccessibleChildCount()
873 : throw (uno::RuntimeException, std::exception)
874 : {
875 0 : return 0;
876 : }
877 :
878 :
879 :
880 0 : uno::Reference< accessibility::XAccessible > SAL_CALL ValueItemAcc::getAccessibleChild( sal_Int32 )
881 : throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
882 : {
883 0 : throw lang::IndexOutOfBoundsException();
884 : }
885 :
886 :
887 :
888 0 : uno::Reference< accessibility::XAccessible > SAL_CALL ValueItemAcc::getAccessibleParent()
889 : throw (uno::RuntimeException, std::exception)
890 : {
891 0 : const SolarMutexGuard aSolarGuard;
892 0 : uno::Reference< accessibility::XAccessible > xRet;
893 :
894 0 : if( mpParent )
895 0 : xRet = mpParent->mrParent.GetAccessible();
896 :
897 0 : return xRet;
898 : }
899 :
900 :
901 :
902 0 : sal_Int32 SAL_CALL ValueItemAcc::getAccessibleIndexInParent()
903 : throw (uno::RuntimeException, std::exception)
904 : {
905 0 : const SolarMutexGuard aSolarGuard;
906 : // The index defaults to -1 to indicate the child does not belong to its
907 : // parent.
908 0 : sal_Int32 nIndexInParent = -1;
909 :
910 0 : if( mpParent )
911 : {
912 0 : bool bDone = false;
913 :
914 0 : sal_uInt16 nCount = mpParent->mrParent.ImplGetVisibleItemCount();
915 : ValueSetItem* pItem;
916 0 : for (sal_uInt16 i=0; i<nCount && !bDone; i++)
917 : {
918 : // Guard the retrieval of the i-th child with a try/catch block
919 : // just in case the number of children changes in the mean time.
920 : try
921 : {
922 0 : pItem = mpParent->mrParent.ImplGetItem(i);
923 : }
924 0 : catch (const lang::IndexOutOfBoundsException&)
925 : {
926 0 : pItem = NULL;
927 : }
928 :
929 : // Do not create an accessible object for the test.
930 0 : if (pItem != NULL && pItem->mpxAcc != NULL)
931 0 : if (pItem->GetAccessible( mbIsTransientChildrenDisabled ).get() == this )
932 : {
933 0 : nIndexInParent = i;
934 0 : bDone = true;
935 : }
936 : }
937 : }
938 :
939 : //if this valueset contain a none field(common value is default), then we should increase the real index and set the noitem index value equal 0.
940 0 : if ( mpParent && ( (mpParent->mrParent.GetStyle() & WB_NONEFIELD) != 0 ) )
941 : {
942 0 : ValueSetItem* pFirstItem = mpParent->mrParent.ImplGetItem (VALUESET_ITEM_NONEITEM);
943 0 : if( pFirstItem && pFirstItem ->GetAccessible(mbIsTransientChildrenDisabled).get() == this )
944 0 : nIndexInParent = 0;
945 : else
946 0 : nIndexInParent++;
947 : }
948 0 : return nIndexInParent;
949 : }
950 :
951 :
952 :
953 0 : sal_Int16 SAL_CALL ValueItemAcc::getAccessibleRole()
954 : throw (uno::RuntimeException, std::exception)
955 : {
956 0 : return accessibility::AccessibleRole::LIST_ITEM;
957 : }
958 :
959 :
960 :
961 0 : OUString SAL_CALL ValueItemAcc::getAccessibleDescription()
962 : throw (uno::RuntimeException, std::exception)
963 : {
964 0 : return OUString();
965 : }
966 :
967 :
968 :
969 0 : OUString SAL_CALL ValueItemAcc::getAccessibleName()
970 : throw (uno::RuntimeException, std::exception)
971 : {
972 0 : const SolarMutexGuard aSolarGuard;
973 0 : OUString aRet;
974 :
975 0 : if( mpParent )
976 : {
977 0 : aRet = mpParent->maText;
978 :
979 0 : if( aRet.isEmpty() )
980 : {
981 0 : OUStringBuffer aBuffer("Item ");
982 0 : aBuffer.append(static_cast<sal_Int32>(mpParent->mnId));
983 0 : aRet = aBuffer.makeStringAndClear();
984 : }
985 : }
986 :
987 0 : return aRet;
988 : }
989 :
990 :
991 :
992 0 : uno::Reference< accessibility::XAccessibleRelationSet > SAL_CALL ValueItemAcc::getAccessibleRelationSet()
993 : throw (uno::RuntimeException, std::exception)
994 : {
995 0 : return uno::Reference< accessibility::XAccessibleRelationSet >();
996 : }
997 :
998 :
999 :
1000 0 : uno::Reference< accessibility::XAccessibleStateSet > SAL_CALL ValueItemAcc::getAccessibleStateSet()
1001 : throw (uno::RuntimeException, std::exception)
1002 : {
1003 0 : const SolarMutexGuard aSolarGuard;
1004 0 : ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper;
1005 :
1006 0 : if( mpParent )
1007 : {
1008 0 : pStateSet->AddState (accessibility::AccessibleStateType::ENABLED);
1009 0 : pStateSet->AddState (accessibility::AccessibleStateType::SENSITIVE);
1010 0 : pStateSet->AddState (accessibility::AccessibleStateType::SHOWING);
1011 0 : pStateSet->AddState (accessibility::AccessibleStateType::VISIBLE);
1012 0 : if ( !mbIsTransientChildrenDisabled )
1013 0 : pStateSet->AddState (accessibility::AccessibleStateType::TRANSIENT);
1014 :
1015 : // SELECTABLE
1016 0 : pStateSet->AddState( accessibility::AccessibleStateType::SELECTABLE );
1017 : // pStateSet->AddState( accessibility::AccessibleStateType::FOCUSABLE );
1018 :
1019 : // SELECTED
1020 0 : if( mpParent->mrParent.GetSelectItemId() == mpParent->mnId )
1021 : {
1022 0 : pStateSet->AddState( accessibility::AccessibleStateType::SELECTED );
1023 : // pStateSet->AddState( accessibility::AccessibleStateType::FOCUSED );
1024 : }
1025 : }
1026 :
1027 0 : return pStateSet;
1028 : }
1029 :
1030 :
1031 :
1032 0 : lang::Locale SAL_CALL ValueItemAcc::getLocale()
1033 : throw (accessibility::IllegalAccessibleComponentStateException, uno::RuntimeException, std::exception)
1034 : {
1035 0 : const SolarMutexGuard aSolarGuard;
1036 0 : const OUString aEmptyStr;
1037 0 : uno::Reference< accessibility::XAccessible > xParent( getAccessibleParent() );
1038 0 : lang::Locale aRet( aEmptyStr, aEmptyStr, aEmptyStr );
1039 :
1040 0 : if( xParent.is() )
1041 : {
1042 0 : uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
1043 :
1044 0 : if( xParentContext.is() )
1045 0 : aRet = xParentContext->getLocale();
1046 : }
1047 :
1048 0 : return aRet;
1049 : }
1050 :
1051 :
1052 :
1053 0 : void SAL_CALL ValueItemAcc::addAccessibleEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
1054 : throw (uno::RuntimeException, std::exception)
1055 : {
1056 0 : const ::osl::MutexGuard aGuard( maMutex );
1057 :
1058 0 : if( rxListener.is() )
1059 : {
1060 0 : ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::const_iterator aIter = mxEventListeners.begin();
1061 0 : sal_Bool bFound = sal_False;
1062 :
1063 0 : while( !bFound && ( aIter != mxEventListeners.end() ) )
1064 : {
1065 0 : if( *aIter == rxListener )
1066 0 : bFound = sal_True;
1067 : else
1068 0 : ++aIter;
1069 : }
1070 :
1071 0 : if (!bFound)
1072 0 : mxEventListeners.push_back( rxListener );
1073 0 : }
1074 0 : }
1075 :
1076 :
1077 :
1078 0 : void SAL_CALL ValueItemAcc::removeAccessibleEventListener( const uno::Reference< accessibility::XAccessibleEventListener >& rxListener )
1079 : throw (uno::RuntimeException, std::exception)
1080 : {
1081 0 : const ::osl::MutexGuard aGuard( maMutex );
1082 :
1083 0 : if( rxListener.is() )
1084 : {
1085 : ::std::vector< uno::Reference< accessibility::XAccessibleEventListener > >::iterator aIter =
1086 0 : std::find(mxEventListeners.begin(), mxEventListeners.end(), rxListener);
1087 :
1088 0 : if (aIter != mxEventListeners.end())
1089 0 : mxEventListeners.erase(aIter);
1090 0 : }
1091 0 : }
1092 :
1093 :
1094 :
1095 0 : sal_Bool SAL_CALL ValueItemAcc::containsPoint( const awt::Point& aPoint )
1096 : throw (uno::RuntimeException, std::exception)
1097 : {
1098 0 : const awt::Rectangle aRect( getBounds() );
1099 0 : const Point aSize( aRect.Width, aRect.Height );
1100 0 : const Point aNullPoint, aTestPoint( aPoint.X, aPoint.Y );
1101 :
1102 0 : return Rectangle( aNullPoint, aSize ).IsInside( aTestPoint );
1103 : }
1104 :
1105 :
1106 :
1107 0 : uno::Reference< accessibility::XAccessible > SAL_CALL ValueItemAcc::getAccessibleAtPoint( const awt::Point& )
1108 : throw (uno::RuntimeException, std::exception)
1109 : {
1110 0 : uno::Reference< accessibility::XAccessible > xRet;
1111 0 : return xRet;
1112 : }
1113 :
1114 :
1115 :
1116 0 : awt::Rectangle SAL_CALL ValueItemAcc::getBounds()
1117 : throw (uno::RuntimeException, std::exception)
1118 : {
1119 0 : const SolarMutexGuard aSolarGuard;
1120 0 : awt::Rectangle aRet;
1121 :
1122 0 : if( mpParent )
1123 : {
1124 0 : Rectangle aRect( mpParent->mrParent.GetItemRect(mpParent->mnId) );
1125 0 : Point aOrigin;
1126 0 : Rectangle aParentRect( aOrigin, mpParent->mrParent.GetOutputSizePixel() );
1127 :
1128 0 : aRect.Intersection( aParentRect );
1129 :
1130 0 : aRet.X = aRect.Left();
1131 0 : aRet.Y = aRect.Top();
1132 0 : aRet.Width = aRect.GetWidth();
1133 0 : aRet.Height = aRect.GetHeight();
1134 : }
1135 :
1136 0 : return aRet;
1137 : }
1138 :
1139 :
1140 :
1141 0 : awt::Point SAL_CALL ValueItemAcc::getLocation()
1142 : throw (uno::RuntimeException, std::exception)
1143 : {
1144 0 : const awt::Rectangle aRect( getBounds() );
1145 0 : awt::Point aRet;
1146 :
1147 0 : aRet.X = aRect.X;
1148 0 : aRet.Y = aRect.Y;
1149 :
1150 0 : return aRet;
1151 : }
1152 :
1153 :
1154 :
1155 0 : awt::Point SAL_CALL ValueItemAcc::getLocationOnScreen()
1156 : throw (uno::RuntimeException, std::exception)
1157 : {
1158 0 : const SolarMutexGuard aSolarGuard;
1159 0 : awt::Point aRet;
1160 :
1161 0 : if( mpParent )
1162 : {
1163 0 : const Point aPos = mpParent->mrParent.GetItemRect(mpParent->mnId).TopLeft();
1164 0 : const Point aScreenPos( mpParent->mrParent.OutputToAbsoluteScreenPixel( aPos ) );
1165 :
1166 0 : aRet.X = aScreenPos.X();
1167 0 : aRet.Y = aScreenPos.Y();
1168 : }
1169 :
1170 0 : return aRet;
1171 : }
1172 :
1173 :
1174 :
1175 0 : awt::Size SAL_CALL ValueItemAcc::getSize()
1176 : throw (uno::RuntimeException, std::exception)
1177 : {
1178 0 : const awt::Rectangle aRect( getBounds() );
1179 0 : awt::Size aRet;
1180 :
1181 0 : aRet.Width = aRect.Width;
1182 0 : aRet.Height = aRect.Height;
1183 :
1184 0 : return aRet;
1185 : }
1186 :
1187 :
1188 :
1189 0 : void SAL_CALL ValueItemAcc::grabFocus()
1190 : throw (uno::RuntimeException, std::exception)
1191 : {
1192 : // nothing to do
1193 0 : }
1194 :
1195 :
1196 :
1197 0 : uno::Any SAL_CALL ValueItemAcc::getAccessibleKeyBinding()
1198 : throw (uno::RuntimeException)
1199 : {
1200 0 : return uno::Any();
1201 : }
1202 :
1203 :
1204 :
1205 0 : sal_Int32 SAL_CALL ValueItemAcc::getForeground( )
1206 : throw (uno::RuntimeException, std::exception)
1207 : {
1208 0 : sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor().GetColor();
1209 0 : return static_cast<sal_Int32>(nColor);
1210 : }
1211 :
1212 :
1213 :
1214 0 : sal_Int32 SAL_CALL ValueItemAcc::getBackground( )
1215 : throw (uno::RuntimeException, std::exception)
1216 : {
1217 : sal_uInt32 nColor;
1218 0 : if (mpParent && mpParent->meType == VALUESETITEM_COLOR)
1219 0 : nColor = mpParent->maColor.GetColor();
1220 : else
1221 0 : nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor();
1222 0 : return static_cast<sal_Int32>(nColor);
1223 : }
1224 :
1225 :
1226 :
1227 0 : sal_Int64 SAL_CALL ValueItemAcc::getSomething( const uno::Sequence< sal_Int8 >& rId ) throw( uno::RuntimeException, std::exception )
1228 : {
1229 : sal_Int64 nRet;
1230 :
1231 0 : if( ( rId.getLength() == 16 ) && ( 0 == memcmp( ValueItemAcc::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
1232 0 : nRet = reinterpret_cast< sal_Int64 >( this );
1233 : else
1234 0 : nRet = 0;
1235 :
1236 0 : return nRet;
1237 : }
1238 :
1239 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|