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