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_sc.hxx"
30 #include "AccessibleDataPilotControl.hxx"
31 #include "unoguard.hxx"
32 #include "fieldwnd.hxx"
33 
34 #include <com/sun/star/accessibility/AccessibleRole.hpp>
35 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
36 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
37 
38 #include <unotools/accessiblestatesethelper.hxx>
39 #include <rtl/uuid.h>
40 #include <tools/gen.hxx>
41 #include <toolkit/helper/convert.hxx>
42 #include <tools/debug.hxx>
43 
44 using namespace	::com::sun::star;
45 using namespace	::com::sun::star::accessibility;
46 
47 class ScAccessibleDataPilotButton
48 	:	public ScAccessibleContextBase
49 {
50 public:
51 	//=====  internal  ========================================================
52 	ScAccessibleDataPilotButton(
53         const ::com::sun::star::uno::Reference<
54         ::com::sun::star::accessibility::XAccessible>& rxParent,
55         ScPivotFieldWindow* pFieldWindow,
56         sal_Int32 nIndex);
57 
58 	virtual void Init();
59 
60     using ScAccessibleContextBase::disposing;
61     virtual void SAL_CALL disposing();
62 
63     void SetIndex(sal_Int32 nIndex) { mnIndex = nIndex; }
64     void NameChanged();
65     void SetFocused();
66     void ResetFocused();
67 protected:
68 	virtual ~ScAccessibleDataPilotButton(void);
69 public:
70 	///=====  XAccessibleComponent  ============================================
71 
72     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
73 		SAL_CALL getAccessibleAtPoint(
74 		const ::com::sun::star::awt::Point& rPoint )
75 		throw (::com::sun::star::uno::RuntimeException);
76 
77     virtual sal_Bool SAL_CALL isVisible(  )
78 		throw (::com::sun::star::uno::RuntimeException);
79 
80     virtual void SAL_CALL grabFocus(  )
81 		throw (::com::sun::star::uno::RuntimeException);
82 
83     virtual sal_Int32 SAL_CALL getForeground(  )
84         throw (::com::sun::star::uno::RuntimeException);
85 
86     virtual sal_Int32 SAL_CALL getBackground(  )
87         throw (::com::sun::star::uno::RuntimeException);
88 
89     ///=====  XAccessibleContext  ==============================================
90 
91     ///	Return the number of currently visible children.
92     virtual sal_Int32 SAL_CALL
93     	getAccessibleChildCount(void) throw (::com::sun::star::uno::RuntimeException);
94 
95     ///	Return the specified child or NULL if index is invalid.
96     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
97     	getAccessibleChild(sal_Int32 nIndex)
98         throw (::com::sun::star::uno::RuntimeException,
99 				::com::sun::star::lang::IndexOutOfBoundsException);
100 
101     ///	Return this objects index among the parents children.
102 	virtual	sal_Int32 SAL_CALL
103     	getAccessibleIndexInParent(void)
104         throw (::com::sun::star::uno::RuntimeException);
105 
106     ///	Return the set of current states.
107 	virtual ::com::sun::star::uno::Reference<
108             ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
109     	getAccessibleStateSet(void)
110         throw (::com::sun::star::uno::RuntimeException);
111 
112 	///=====  XServiceInfo  ====================================================
113 
114     /**	Returns an identifier for the implementation of this object.
115     */
116 	virtual ::rtl::OUString SAL_CALL
117     	getImplementationName(void)
118         throw (::com::sun::star::uno::RuntimeException);
119 
120 	///=====  XTypeProvider  ===================================================
121 
122 	/**	Returns a implementation id.
123     */
124     virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL
125         getImplementationId(void)
126         throw (::com::sun::star::uno::RuntimeException);
127 
128 protected:
129     ///	Return this object's description.
130 	virtual ::rtl::OUString SAL_CALL
131     	createAccessibleDescription(void)
132         throw (::com::sun::star::uno::RuntimeException);
133 
134     ///	Return the object's current name.
135 	virtual ::rtl::OUString SAL_CALL
136     	createAccessibleName(void)
137         throw (::com::sun::star::uno::RuntimeException);
138 
139     ///	Return the object's current bounding box relative to the desktop.
140 	virtual Rectangle GetBoundingBoxOnScreen(void) const
141 		throw (::com::sun::star::uno::RuntimeException);
142 
143 	///	Return the object's current bounding box relative to the parent object.
144 	virtual Rectangle GetBoundingBox(void) const
145 		throw (::com::sun::star::uno::RuntimeException);
146 
147 private:
148     ScPivotFieldWindow* mpFieldWindow;
149     sal_Int32        mnIndex;
150 };
151 
152 	//=====  internal  ========================================================
153 ScAccessibleDataPilotControl::ScAccessibleDataPilotControl(
154         const uno::Reference<XAccessible>& rxParent,
155         ScPivotFieldWindow* pFieldWindow)
156         :
157     ScAccessibleContextBase(rxParent, AccessibleRole::GROUP_BOX),
158     mpFieldWindow(pFieldWindow)
159 {
160     if (mpFieldWindow)
161         maChildren.resize(mpFieldWindow->GetFieldCount());
162 }
163 
164 ScAccessibleDataPilotControl::~ScAccessibleDataPilotControl(void)
165 {
166 	if (!IsDefunc() && !rBHelper.bInDispose)
167 	{
168 		// increment refcount to prevent double call off dtor
169 		osl_incrementInterlockedCount( &m_refCount );
170 		// call dispose to inform object wich have a weak reference to this object
171 		dispose();
172 	}
173 }
174 
175 void ScAccessibleDataPilotControl::Init()
176 {
177 }
178 
179 void SAL_CALL ScAccessibleDataPilotControl::disposing()
180 {
181     ScUnoGuard aGuard;
182     mpFieldWindow = NULL;
183 
184     ScAccessibleContextBase::disposing();
185 }
186 
187 void ScAccessibleDataPilotControl::AddField(sal_Int32 nNewIndex)
188 {
189     sal_Bool bAdded(sal_False);
190     if (static_cast<size_t>(nNewIndex) == maChildren.size())
191     {
192         maChildren.push_back(AccessibleWeak());
193         bAdded = sal_True;
194     }
195     else if (static_cast<size_t>(nNewIndex) < maChildren.size())
196     {
197         ::std::vector < AccessibleWeak >::iterator aItr = maChildren.begin() + nNewIndex;
198         maChildren.insert(aItr, AccessibleWeak());
199 
200         ::std::vector < AccessibleWeak >::iterator aEndItr = maChildren.end();
201         aItr = maChildren.begin() + nNewIndex + 1;
202         uno::Reference< XAccessible > xTempAcc;
203         sal_Int32 nIndex = nNewIndex + 1;
204         while (aItr != aEndItr)
205         {
206             xTempAcc = aItr->xWeakAcc;
207             if (xTempAcc.is() && aItr->pAcc)
208                 aItr->pAcc->SetIndex(nIndex);
209             ++nIndex;
210             ++aItr;
211         }
212         bAdded = sal_True;
213     }
214     else
215     {
216         DBG_ERRORFILE("did not recognize a child count change");
217     }
218 
219     if (bAdded)
220     {
221 		AccessibleEventObject aEvent;
222 		aEvent.EventId = AccessibleEventId::CHILD;
223 		aEvent.Source = uno::Reference< XAccessibleContext >(this);
224 		aEvent.NewValue <<= getAccessibleChild(nNewIndex);
225 
226 		CommitChange(aEvent); // new child - event
227     }
228 }
229 
230 void ScAccessibleDataPilotControl::RemoveField(sal_Int32 nOldIndex)
231 {
232     sal_Bool bRemoved(sal_False);
233     uno::Reference< XAccessible > xTempAcc;
234     ScAccessibleDataPilotButton* pField = NULL;
235     if (static_cast<size_t>(nOldIndex) < maChildren.size())
236     {
237         xTempAcc = getAccessibleChild(nOldIndex);
238         pField = maChildren[nOldIndex].pAcc;
239 
240         ::std::vector < AccessibleWeak >::iterator aItr = maChildren.begin() + nOldIndex;
241         aItr = maChildren.erase(aItr);
242 
243         ::std::vector < AccessibleWeak >::iterator aEndItr = maChildren.end();
244         uno::Reference< XAccessible > xItrAcc;
245         while (aItr != aEndItr)
246         {
247             xItrAcc = aItr->xWeakAcc;
248             if (xItrAcc.is() && aItr->pAcc)
249                 aItr->pAcc->SetIndex(nOldIndex);
250             ++nOldIndex;
251             ++aItr;
252         }
253         bRemoved = sal_True;
254     }
255     else
256     {
257         DBG_ERRORFILE("did not recognize a child count change");
258     }
259 
260     if (bRemoved)
261     {
262 		AccessibleEventObject aEvent;
263 		aEvent.EventId = AccessibleEventId::CHILD;
264 		aEvent.Source = uno::Reference< XAccessibleContext >(this);
265 		aEvent.NewValue <<= xTempAcc;
266 
267 		CommitChange(aEvent); // gone child - event
268 
269         if (pField)
270             pField->dispose();
271     }
272 }
273 
274 void ScAccessibleDataPilotControl::FieldFocusChange(sal_Int32 nOldIndex, sal_Int32 nNewIndex)
275 {
276     DBG_ASSERT(static_cast<size_t>(nOldIndex) < maChildren.size() &&
277                 static_cast<size_t>(nNewIndex) < maChildren.size(), "did not recognize a child count change");
278 
279     uno::Reference < XAccessible > xTempAcc = maChildren[nOldIndex].xWeakAcc;
280     if (xTempAcc.is() && maChildren[nOldIndex].pAcc)
281         maChildren[nOldIndex].pAcc->ResetFocused();
282 
283     xTempAcc = maChildren[nNewIndex].xWeakAcc;
284     if (xTempAcc.is() && maChildren[nNewIndex].pAcc)
285         maChildren[nNewIndex].pAcc->SetFocused();
286 }
287 
288 void ScAccessibleDataPilotControl::FieldNameChange(sal_Int32 nIndex)
289 {
290     DBG_ASSERT(static_cast<size_t>(nIndex) < maChildren.size(), "did not recognize a child count change");
291 
292     uno::Reference < XAccessible > xTempAcc = maChildren[nIndex].xWeakAcc;
293     if (xTempAcc.is() && maChildren[nIndex].pAcc)
294         maChildren[nIndex].pAcc->ChangeName();
295 }
296 
297 void ScAccessibleDataPilotControl::GotFocus()
298 {
299     if (mpFieldWindow)
300     {
301         DBG_ASSERT(mpFieldWindow->GetFieldCount() == maChildren.size(), "did not recognize a child count change");
302 
303         sal_Int32 nIndex(mpFieldWindow->GetSelectedIndex());
304         uno::Reference < XAccessible > xTempAcc = maChildren[nIndex].xWeakAcc;
305         if (xTempAcc.is() && maChildren[nIndex].pAcc)
306             maChildren[nIndex].pAcc->SetFocused();
307     }
308 }
309 
310 void ScAccessibleDataPilotControl::LostFocus()
311 {
312     if (mpFieldWindow)
313     {
314         DBG_ASSERT(mpFieldWindow->GetFieldCount() == maChildren.size(), "did not recognize a child count change");
315 
316         sal_Int32 nIndex(mpFieldWindow->GetSelectedIndex());
317         uno::Reference < XAccessible > xTempAcc = maChildren[nIndex].xWeakAcc;
318         if (xTempAcc.is() && maChildren[nIndex].pAcc)
319             maChildren[nIndex].pAcc->ResetFocused();
320     }
321 }
322 
323 	///=====  XAccessibleComponent  ============================================
324 
325 uno::Reference< XAccessible > SAL_CALL ScAccessibleDataPilotControl::getAccessibleAtPoint(
326 		const awt::Point& rPoint )
327 		throw (uno::RuntimeException)
328 {
329     uno::Reference<XAccessible> xAcc;
330     if (containsPoint(rPoint))
331     {
332         ScUnoGuard aGuard;
333         IsObjectValid();
334         if (mpFieldWindow)
335         {
336             Point aAbsPoint(VCLPoint(rPoint));
337             Point aControlEdge(GetBoundingBoxOnScreen().TopLeft());
338             Point aRelPoint(aAbsPoint - aControlEdge);
339             size_t nChildIndex = mpFieldWindow->GetFieldIndex( aRelPoint );
340             if( nChildIndex != PIVOTFIELD_INVALID )
341                 xAcc = getAccessibleChild(static_cast< long >( nChildIndex ));
342         }
343     }
344     return xAcc;
345 }
346 
347 sal_Bool SAL_CALL ScAccessibleDataPilotControl::isVisible(  )
348         throw (uno::RuntimeException)
349 {
350     return sal_True;
351 }
352 
353 void SAL_CALL ScAccessibleDataPilotControl::grabFocus(  )
354 		throw (uno::RuntimeException)
355 {
356     ScUnoGuard aGuard;
357     IsObjectValid();
358     if (mpFieldWindow)
359         mpFieldWindow->GrabFocus();
360 }
361 
362 sal_Int32 SAL_CALL ScAccessibleDataPilotControl::getForeground(  )
363     throw (uno::RuntimeException)
364 {
365     ScUnoGuard aGuard;
366     IsObjectValid();
367     sal_Int32 nColor(0);
368     if (mpFieldWindow)
369     {
370         nColor = mpFieldWindow->GetSettings().GetStyleSettings().GetWindowTextColor().GetColor();
371     }
372     return nColor;
373 }
374 
375 sal_Int32 SAL_CALL ScAccessibleDataPilotControl::getBackground(  )
376     throw (uno::RuntimeException)
377 {
378     ScUnoGuard aGuard;
379     IsObjectValid();
380     sal_Int32 nColor(0);
381     if (mpFieldWindow)
382     {
383         const StyleSettings& rStyleSett = mpFieldWindow->GetSettings().GetStyleSettings();
384         nColor = (mpFieldWindow->GetType() == PIVOTFIELDTYPE_SELECT) ? rStyleSett.GetFaceColor().GetColor() : rStyleSett.GetWindowColor().GetColor();
385     }
386     return nColor;
387 }
388 
389 	///=====  XAccessibleContext  ==============================================
390 
391 sal_Int32 SAL_CALL ScAccessibleDataPilotControl::getAccessibleChildCount(void)
392         throw (uno::RuntimeException)
393 {
394     ScUnoGuard aGuard;
395     IsObjectValid();
396     if (mpFieldWindow)
397         return mpFieldWindow->GetFieldCount();
398     else
399         return 0;
400 }
401 
402 uno::Reference< XAccessible> SAL_CALL ScAccessibleDataPilotControl::getAccessibleChild(sal_Int32 nIndex)
403         throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
404 {
405     ScUnoGuard aGuard;
406     IsObjectValid();
407     uno::Reference<XAccessible> xAcc;
408     if (mpFieldWindow)
409     {
410         if (nIndex < 0 || static_cast< size_t >( nIndex ) >= mpFieldWindow->GetFieldCount())
411             throw lang::IndexOutOfBoundsException();
412 
413         DBG_ASSERT(mpFieldWindow->GetFieldCount() == maChildren.size(), "did not recognize a child count change");
414 
415         uno::Reference < XAccessible > xTempAcc = maChildren[nIndex].xWeakAcc;
416         if (!xTempAcc.is())
417         {
418             maChildren[nIndex].pAcc = new ScAccessibleDataPilotButton(this, mpFieldWindow, nIndex);
419             xTempAcc = maChildren[nIndex].pAcc;
420             maChildren[nIndex].xWeakAcc = xTempAcc;
421         }
422 
423         xAcc = xTempAcc;
424     }
425     return xAcc;
426 }
427 
428 uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessibleDataPilotControl::getAccessibleStateSet(void)
429         throw (uno::RuntimeException)
430 {
431 	ScUnoGuard aGuard;
432     IsObjectValid();
433 
434 	utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
435 
436     if (IsDefunc())
437         pStateSet->AddState(AccessibleStateType::DEFUNC);
438     else
439     {
440         pStateSet->AddState(AccessibleStateType::ENABLED);
441         pStateSet->AddState(AccessibleStateType::OPAQUE);
442         if (isShowing())
443             pStateSet->AddState(AccessibleStateType::SHOWING);
444         if (isVisible())
445             pStateSet->AddState(AccessibleStateType::VISIBLE);
446     }
447 
448     return pStateSet;
449 }
450 
451 	///=====  XServiceInfo  ====================================================
452 
453 ::rtl::OUString SAL_CALL ScAccessibleDataPilotControl::getImplementationName(void)
454         throw (uno::RuntimeException)
455 {
456     return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDataPilotControl"));
457 }
458 
459 	///=====  XTypeProvider  ===================================================
460 
461 uno::Sequence<sal_Int8> SAL_CALL ScAccessibleDataPilotControl::getImplementationId(void)
462         throw (uno::RuntimeException)
463 {
464     ScUnoGuard aGuard;
465     IsObjectValid();
466 	static uno::Sequence<sal_Int8> aId;
467 	if (aId.getLength() == 0)
468 	{
469 		aId.realloc (16);
470 		rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
471 	}
472 	return aId;
473 }
474 
475 	//=====  internal  ========================================================
476 
477 ::rtl::OUString SAL_CALL ScAccessibleDataPilotControl::createAccessibleDescription(void)
478         throw (uno::RuntimeException)
479 {
480     ScUnoGuard aGuard;
481     IsObjectValid();
482     if (mpFieldWindow)
483         return mpFieldWindow->GetDescription();
484 
485     return rtl::OUString();
486 }
487 
488 ::rtl::OUString SAL_CALL ScAccessibleDataPilotControl::createAccessibleName(void)
489         throw (uno::RuntimeException)
490 {
491     ScUnoGuard aGuard;
492     IsObjectValid();
493     if (mpFieldWindow)
494         return mpFieldWindow->GetName();
495 
496     return rtl::OUString();
497 }
498 
499 Rectangle ScAccessibleDataPilotControl::GetBoundingBoxOnScreen(void) const
500 		throw (uno::RuntimeException)
501 {
502 	if (mpFieldWindow)
503 		return mpFieldWindow->GetWindowExtentsRelative(NULL);
504     else
505 	    return Rectangle();
506 }
507 
508 Rectangle ScAccessibleDataPilotControl::GetBoundingBox(void) const
509 		throw (uno::RuntimeException)
510 {
511     if (mpFieldWindow)
512         return mpFieldWindow->GetWindowExtentsRelative(mpFieldWindow->GetAccessibleParentWindow());
513     else
514         return Rectangle();
515 }
516 
517 
518 //===============================================================================
519 
520 ScAccessibleDataPilotButton::ScAccessibleDataPilotButton(
521         const ::com::sun::star::uno::Reference<
522         ::com::sun::star::accessibility::XAccessible>& rxParent,
523         ScPivotFieldWindow* pFieldWindow,
524         sal_Int32 nIndex)
525     : ScAccessibleContextBase(rxParent, AccessibleRole::PUSH_BUTTON),
526     mpFieldWindow(pFieldWindow),
527     mnIndex(nIndex)
528 {
529 }
530 
531 ScAccessibleDataPilotButton::~ScAccessibleDataPilotButton(void)
532 {
533 	if (!IsDefunc() && !rBHelper.bInDispose)
534 	{
535 		// increment refcount to prevent double call off dtor
536 		osl_incrementInterlockedCount( &m_refCount );
537 		// call dispose to inform object wich have a weak reference to this object
538 		dispose();
539 	}
540 }
541 
542 void ScAccessibleDataPilotButton::Init()
543 {
544 }
545 
546 void SAL_CALL ScAccessibleDataPilotButton::disposing()
547 {
548     ScUnoGuard aGuard;
549     mpFieldWindow = NULL;
550 
551     ScAccessibleContextBase::disposing();
552 }
553 
554 void ScAccessibleDataPilotButton::SetFocused()
555 {
556 	CommitFocusGained();
557 }
558 
559 void ScAccessibleDataPilotButton::ResetFocused()
560 {
561 	CommitFocusLost();
562 }
563 
564 	///=====  XAccessibleComponent  ============================================
565 
566 uno::Reference< XAccessible > SAL_CALL ScAccessibleDataPilotButton::getAccessibleAtPoint(
567         const ::com::sun::star::awt::Point& /* rPoint */ )
568 		throw (::com::sun::star::uno::RuntimeException)
569 {
570     return NULL;
571 }
572 
573 sal_Bool SAL_CALL ScAccessibleDataPilotButton::isVisible(  )
574 		throw (::com::sun::star::uno::RuntimeException)
575 {
576     return sal_True;
577 }
578 
579 void SAL_CALL ScAccessibleDataPilotButton::grabFocus(  )
580 		throw (::com::sun::star::uno::RuntimeException)
581 {
582     ScUnoGuard aGuard;
583     IsObjectValid();
584     if (mpFieldWindow)
585     {
586         mpFieldWindow->GrabFocusAndSelect(getAccessibleIndexInParent());
587     }
588 }
589 
590 sal_Int32 SAL_CALL ScAccessibleDataPilotButton::getForeground(  )
591 throw (uno::RuntimeException)
592 {
593     ScUnoGuard aGuard;
594     IsObjectValid();
595     sal_Int32 nColor(0);
596     if (mpFieldWindow)
597     {
598         nColor = mpFieldWindow->GetSettings().GetStyleSettings().GetButtonTextColor().GetColor();
599     }
600     return nColor;
601 }
602 
603 sal_Int32 SAL_CALL ScAccessibleDataPilotButton::getBackground(  )
604 throw (uno::RuntimeException)
605 {
606     ScUnoGuard aGuard;
607     IsObjectValid();
608     sal_Int32 nColor(0);
609     if (mpFieldWindow)
610     {
611         nColor = mpFieldWindow->GetSettings().GetStyleSettings().GetFaceColor().GetColor();
612     }
613     return nColor;
614 }
615 
616 	///=====  XAccessibleContext  ==============================================
617 
618 sal_Int32 SAL_CALL ScAccessibleDataPilotButton::getAccessibleChildCount(void)
619     throw (::com::sun::star::uno::RuntimeException)
620 {
621     return 0;
622 }
623 
624 uno::Reference< XAccessible> SAL_CALL ScAccessibleDataPilotButton::getAccessibleChild(sal_Int32 /* nIndex */)
625         throw (::com::sun::star::uno::RuntimeException,
626 				::com::sun::star::lang::IndexOutOfBoundsException)
627 {
628     throw lang::IndexOutOfBoundsException();
629 }
630 
631 sal_Int32 SAL_CALL ScAccessibleDataPilotButton::getAccessibleIndexInParent(void)
632         throw (::com::sun::star::uno::RuntimeException)
633 {
634     ScUnoGuard aGuard;
635     IsObjectValid();
636     return mnIndex;
637 }
638 
639 uno::Reference<XAccessibleStateSet> SAL_CALL ScAccessibleDataPilotButton::getAccessibleStateSet(void)
640         throw (::com::sun::star::uno::RuntimeException)
641 {
642 	ScUnoGuard aGuard;
643     IsObjectValid();
644 
645 	utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
646 
647     if (IsDefunc())
648         pStateSet->AddState(AccessibleStateType::DEFUNC);
649     else
650     {
651         pStateSet->AddState(AccessibleStateType::ENABLED);
652         pStateSet->AddState(AccessibleStateType::OPAQUE);
653         pStateSet->AddState(AccessibleStateType::FOCUSABLE);
654         if (mpFieldWindow && (sal::static_int_cast<sal_Int32>(mpFieldWindow->GetSelectedIndex()) == mnIndex))
655             pStateSet->AddState(AccessibleStateType::FOCUSED);
656         if (isShowing())
657             pStateSet->AddState(AccessibleStateType::SHOWING);
658         if (isVisible())
659             pStateSet->AddState(AccessibleStateType::VISIBLE);
660     }
661 
662     return pStateSet;
663 }
664 
665 	///=====  XServiceInfo  ====================================================
666 
667 ::rtl::OUString SAL_CALL ScAccessibleDataPilotButton::getImplementationName(void)
668         throw (::com::sun::star::uno::RuntimeException)
669 {
670     return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDataPilotButton"));
671 }
672 
673 	///=====  XTypeProvider  ===================================================
674 
675 uno::Sequence<sal_Int8> SAL_CALL ScAccessibleDataPilotButton::getImplementationId(void)
676         throw (::com::sun::star::uno::RuntimeException)
677 {
678     ScUnoGuard aGuard;
679     IsObjectValid();
680 	static uno::Sequence<sal_Int8> aId;
681 	if (aId.getLength() == 0)
682 	{
683 		aId.realloc (16);
684 		rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
685 	}
686 	return aId;
687 }
688 
689 ::rtl::OUString SAL_CALL ScAccessibleDataPilotButton::createAccessibleDescription(void)
690         throw (::com::sun::star::uno::RuntimeException)
691 {
692     return rtl::OUString();
693 }
694 
695 ::rtl::OUString SAL_CALL ScAccessibleDataPilotButton::createAccessibleName(void)
696         throw (::com::sun::star::uno::RuntimeException)
697 {
698     ScUnoGuard aGuard;
699     IsObjectValid();
700     if (mpFieldWindow)
701         return mpFieldWindow->GetFieldText(getAccessibleIndexInParent());
702 
703     return rtl::OUString();
704 }
705 
706 Rectangle ScAccessibleDataPilotButton::GetBoundingBoxOnScreen(void) const
707 		throw (::com::sun::star::uno::RuntimeException)
708 {
709     Rectangle aRect(GetBoundingBox());
710 
711     if (mpFieldWindow)
712     {
713         Point aParentPos(mpFieldWindow->GetWindowExtentsRelative(NULL).TopLeft());
714         aRect.Move(aParentPos.getX(), aParentPos.getY());
715     }
716 
717     return aRect;
718 }
719 
720 Rectangle ScAccessibleDataPilotButton::GetBoundingBox(void) const
721 		throw (::com::sun::star::uno::RuntimeException)
722 {
723     if (mpFieldWindow)
724         return Rectangle (mpFieldWindow->GetFieldPosition(const_cast<ScAccessibleDataPilotButton*> (this)->getAccessibleIndexInParent()), mpFieldWindow->GetFieldSize());
725     else
726         return Rectangle();
727 }
728