1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: AccessibleDataPilotControl.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
33 #include "AccessibleDataPilotControl.hxx"
34 #include "unoguard.hxx"
35 #include "fieldwnd.hxx"
37 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
38 #include <com/sun/star/accessibility/AccessibleRole.hpp>
40 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
41 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
43 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
45 #ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
46 #include <unotools/accessiblestatesethelper.hxx>
49 #include <tools/gen.hxx>
50 #include <toolkit/helper/convert.hxx>
51 #include <tools/debug.hxx>
53 using namespace ::com::sun::star
;
54 using namespace ::com::sun::star::accessibility
;
56 class ScAccessibleDataPilotButton
57 : public ScAccessibleContextBase
60 //===== internal ========================================================
61 ScAccessibleDataPilotButton(
62 const ::com::sun::star::uno::Reference
<
63 ::com::sun::star::accessibility::XAccessible
>& rxParent
,
64 ScDPFieldWindow
* pDPFieldWindow
,
69 using ScAccessibleContextBase::disposing
;
70 virtual void SAL_CALL
disposing();
72 void SetIndex(sal_Int32 nIndex
) { mnIndex
= nIndex
; }
77 virtual ~ScAccessibleDataPilotButton(void);
79 ///===== XAccessibleComponent ============================================
81 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>
82 SAL_CALL
getAccessibleAtPoint(
83 const ::com::sun::star::awt::Point
& rPoint
)
84 throw (::com::sun::star::uno::RuntimeException
);
86 virtual sal_Bool SAL_CALL
isVisible( )
87 throw (::com::sun::star::uno::RuntimeException
);
89 virtual void SAL_CALL
grabFocus( )
90 throw (::com::sun::star::uno::RuntimeException
);
92 virtual sal_Int32 SAL_CALL
getForeground( )
93 throw (::com::sun::star::uno::RuntimeException
);
95 virtual sal_Int32 SAL_CALL
getBackground( )
96 throw (::com::sun::star::uno::RuntimeException
);
98 ///===== XAccessibleContext ==============================================
100 /// Return the number of currently visible children.
101 virtual sal_Int32 SAL_CALL
102 getAccessibleChildCount(void) throw (::com::sun::star::uno::RuntimeException
);
104 /// Return the specified child or NULL if index is invalid.
105 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
> SAL_CALL
106 getAccessibleChild(sal_Int32 nIndex
)
107 throw (::com::sun::star::uno::RuntimeException
,
108 ::com::sun::star::lang::IndexOutOfBoundsException
);
110 /// Return this objects index among the parents children.
111 virtual sal_Int32 SAL_CALL
112 getAccessibleIndexInParent(void)
113 throw (::com::sun::star::uno::RuntimeException
);
115 /// Return the set of current states.
116 virtual ::com::sun::star::uno::Reference
<
117 ::com::sun::star::accessibility::XAccessibleStateSet
> SAL_CALL
118 getAccessibleStateSet(void)
119 throw (::com::sun::star::uno::RuntimeException
);
121 ///===== XServiceInfo ====================================================
123 /** Returns an identifier for the implementation of this object.
125 virtual ::rtl::OUString SAL_CALL
126 getImplementationName(void)
127 throw (::com::sun::star::uno::RuntimeException
);
129 ///===== XTypeProvider ===================================================
131 /** Returns a implementation id.
133 virtual ::com::sun::star::uno::Sequence
<sal_Int8
> SAL_CALL
134 getImplementationId(void)
135 throw (::com::sun::star::uno::RuntimeException
);
138 /// Return this object's description.
139 virtual ::rtl::OUString SAL_CALL
140 createAccessibleDescription(void)
141 throw (::com::sun::star::uno::RuntimeException
);
143 /// Return the object's current name.
144 virtual ::rtl::OUString SAL_CALL
145 createAccessibleName(void)
146 throw (::com::sun::star::uno::RuntimeException
);
148 /// Return the object's current bounding box relative to the desktop.
149 virtual Rectangle
GetBoundingBoxOnScreen(void) const
150 throw (::com::sun::star::uno::RuntimeException
);
152 /// Return the object's current bounding box relative to the parent object.
153 virtual Rectangle
GetBoundingBox(void) const
154 throw (::com::sun::star::uno::RuntimeException
);
157 ScDPFieldWindow
* mpDPFieldWindow
;
161 //===== internal ========================================================
162 ScAccessibleDataPilotControl::ScAccessibleDataPilotControl(
163 const uno::Reference
<XAccessible
>& rxParent
,
164 ScDPFieldWindow
* pDPFieldWindow
)
166 ScAccessibleContextBase(rxParent
, AccessibleRole::GROUP_BOX
),
167 mpDPFieldWindow(pDPFieldWindow
)
170 maChildren
.resize(mpDPFieldWindow
->GetFieldCount());
173 ScAccessibleDataPilotControl::~ScAccessibleDataPilotControl(void)
175 if (!IsDefunc() && !rBHelper
.bInDispose
)
177 // increment refcount to prevent double call off dtor
178 osl_incrementInterlockedCount( &m_refCount
);
179 // call dispose to inform object wich have a weak reference to this object
184 void ScAccessibleDataPilotControl::Init()
188 void SAL_CALL
ScAccessibleDataPilotControl::disposing()
191 mpDPFieldWindow
= NULL
;
193 ScAccessibleContextBase::disposing();
196 void ScAccessibleDataPilotControl::AddField(sal_Int32 nNewIndex
)
198 sal_Bool
bAdded(sal_False
);
199 if (static_cast<sal_uInt32
>(nNewIndex
) == maChildren
.size())
201 maChildren
.push_back(AccessibleWeak());
204 else if (static_cast<sal_uInt32
>(nNewIndex
) < maChildren
.size())
206 ::std::vector
< AccessibleWeak
>::iterator aItr
= maChildren
.begin() + nNewIndex
;
207 maChildren
.insert(aItr
, AccessibleWeak());
209 ::std::vector
< AccessibleWeak
>::iterator aEndItr
= maChildren
.end();
210 aItr
= maChildren
.begin() + nNewIndex
+ 1;
211 uno::Reference
< XAccessible
> xTempAcc
;
212 sal_Int32 nIndex
= nNewIndex
+ 1;
213 while (aItr
!= aEndItr
)
215 xTempAcc
= aItr
->xWeakAcc
;
216 if (xTempAcc
.is() && aItr
->pAcc
)
217 aItr
->pAcc
->SetIndex(nIndex
);
225 DBG_ERRORFILE("did not recognize a child count change");
230 AccessibleEventObject aEvent
;
231 aEvent
.EventId
= AccessibleEventId::CHILD
;
232 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
233 aEvent
.NewValue
<<= getAccessibleChild(nNewIndex
);
235 CommitChange(aEvent
); // new child - event
239 void ScAccessibleDataPilotControl::RemoveField(sal_Int32 nOldIndex
)
241 sal_Bool
bRemoved(sal_False
);
242 uno::Reference
< XAccessible
> xTempAcc
;
243 ScAccessibleDataPilotButton
* pField
= NULL
;
244 if (static_cast<sal_uInt32
>(nOldIndex
) < maChildren
.size())
246 xTempAcc
= getAccessibleChild(nOldIndex
);
247 pField
= maChildren
[nOldIndex
].pAcc
;
249 ::std::vector
< AccessibleWeak
>::iterator aItr
= maChildren
.begin() + nOldIndex
;
250 aItr
= maChildren
.erase(aItr
);
252 ::std::vector
< AccessibleWeak
>::iterator aEndItr
= maChildren
.end();
253 uno::Reference
< XAccessible
> xItrAcc
;
254 while (aItr
!= aEndItr
)
256 xItrAcc
= aItr
->xWeakAcc
;
257 if (xItrAcc
.is() && aItr
->pAcc
)
258 aItr
->pAcc
->SetIndex(nOldIndex
);
266 DBG_ERRORFILE("did not recognize a child count change");
271 AccessibleEventObject aEvent
;
272 aEvent
.EventId
= AccessibleEventId::CHILD
;
273 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
274 aEvent
.NewValue
<<= xTempAcc
;
276 CommitChange(aEvent
); // gone child - event
283 void ScAccessibleDataPilotControl::FieldFocusChange(sal_Int32 nOldIndex
, sal_Int32 nNewIndex
)
285 DBG_ASSERT(static_cast<sal_uInt32
>(nOldIndex
) < maChildren
.size() &&
286 static_cast<sal_uInt32
>(nNewIndex
) < maChildren
.size(), "did not recognize a child count change");
288 uno::Reference
< XAccessible
> xTempAcc
= maChildren
[nOldIndex
].xWeakAcc
;
289 if (xTempAcc
.is() && maChildren
[nOldIndex
].pAcc
)
290 maChildren
[nOldIndex
].pAcc
->ResetFocused();
292 xTempAcc
= maChildren
[nNewIndex
].xWeakAcc
;
293 if (xTempAcc
.is() && maChildren
[nNewIndex
].pAcc
)
294 maChildren
[nNewIndex
].pAcc
->SetFocused();
297 void ScAccessibleDataPilotControl::FieldNameChange(sal_Int32 nIndex
)
299 DBG_ASSERT(static_cast<sal_uInt32
>(nIndex
) < maChildren
.size(), "did not recognize a child count change");
301 uno::Reference
< XAccessible
> xTempAcc
= maChildren
[nIndex
].xWeakAcc
;
302 if (xTempAcc
.is() && maChildren
[nIndex
].pAcc
)
303 maChildren
[nIndex
].pAcc
->ChangeName();
306 void ScAccessibleDataPilotControl::GotFocus()
310 DBG_ASSERT(static_cast<sal_uInt32
>(mpDPFieldWindow
->GetFieldCount()) == maChildren
.size(), "did not recognize a child count change");
312 sal_Int32
nIndex(mpDPFieldWindow
->GetSelectedField());
313 uno::Reference
< XAccessible
> xTempAcc
= maChildren
[nIndex
].xWeakAcc
;
314 if (xTempAcc
.is() && maChildren
[nIndex
].pAcc
)
315 maChildren
[nIndex
].pAcc
->SetFocused();
319 void ScAccessibleDataPilotControl::LostFocus()
323 DBG_ASSERT(static_cast<sal_uInt32
>(mpDPFieldWindow
->GetFieldCount()) == maChildren
.size(), "did not recognize a child count change");
325 sal_Int32
nIndex(mpDPFieldWindow
->GetSelectedField());
326 uno::Reference
< XAccessible
> xTempAcc
= maChildren
[nIndex
].xWeakAcc
;
327 if (xTempAcc
.is() && maChildren
[nIndex
].pAcc
)
328 maChildren
[nIndex
].pAcc
->ResetFocused();
332 ///===== XAccessibleComponent ============================================
334 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleDataPilotControl::getAccessibleAtPoint(
335 const awt::Point
& rPoint
)
336 throw (uno::RuntimeException
)
338 uno::Reference
<XAccessible
> xAcc
;
339 if (containsPoint(rPoint
))
345 Point
aAbsPoint(VCLPoint(rPoint
));
346 Point
aControlEdge(GetBoundingBoxOnScreen().TopLeft());
347 Point
aRelPoint(aAbsPoint
- aControlEdge
);
348 size_t nChildIndex(0);
349 if (mpDPFieldWindow
->GetFieldIndex(aRelPoint
, nChildIndex
))
350 xAcc
= getAccessibleChild(static_cast< long >( nChildIndex
));
356 sal_Bool SAL_CALL
ScAccessibleDataPilotControl::isVisible( )
357 throw (uno::RuntimeException
)
362 void SAL_CALL
ScAccessibleDataPilotControl::grabFocus( )
363 throw (uno::RuntimeException
)
368 mpDPFieldWindow
->GrabFocus();
371 sal_Int32 SAL_CALL
ScAccessibleDataPilotControl::getForeground( )
372 throw (uno::RuntimeException
)
379 nColor
= mpDPFieldWindow
->GetSettings().GetStyleSettings().GetWindowTextColor().GetColor();
384 sal_Int32 SAL_CALL
ScAccessibleDataPilotControl::getBackground( )
385 throw (uno::RuntimeException
)
392 if (mpDPFieldWindow
->GetType() == TYPE_SELECT
)
394 nColor
= mpDPFieldWindow
->GetSettings().GetStyleSettings().GetFaceColor().GetColor();
398 nColor
= mpDPFieldWindow
->GetSettings().GetStyleSettings().GetWindowColor().GetColor();
404 ///===== XAccessibleContext ==============================================
406 sal_Int32 SAL_CALL
ScAccessibleDataPilotControl::getAccessibleChildCount(void)
407 throw (uno::RuntimeException
)
412 return mpDPFieldWindow
->GetFieldCount();
417 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleDataPilotControl::getAccessibleChild(sal_Int32 nIndex
)
418 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
)
422 uno::Reference
<XAccessible
> xAcc
;
425 if (nIndex
< 0 || static_cast< size_t >( nIndex
) >= mpDPFieldWindow
->GetFieldCount())
426 throw lang::IndexOutOfBoundsException();
428 DBG_ASSERT(static_cast<sal_uInt32
>(mpDPFieldWindow
->GetFieldCount()) == maChildren
.size(), "did not recognize a child count change");
430 uno::Reference
< XAccessible
> xTempAcc
= maChildren
[nIndex
].xWeakAcc
;
433 maChildren
[nIndex
].pAcc
= new ScAccessibleDataPilotButton(this, mpDPFieldWindow
, nIndex
);
434 xTempAcc
= maChildren
[nIndex
].pAcc
;
435 maChildren
[nIndex
].xWeakAcc
= xTempAcc
;
443 uno::Reference
<XAccessibleStateSet
> SAL_CALL
ScAccessibleDataPilotControl::getAccessibleStateSet(void)
444 throw (uno::RuntimeException
)
449 utl::AccessibleStateSetHelper
* pStateSet
= new utl::AccessibleStateSetHelper();
452 pStateSet
->AddState(AccessibleStateType::DEFUNC
);
455 pStateSet
->AddState(AccessibleStateType::ENABLED
);
456 pStateSet
->AddState(AccessibleStateType::OPAQUE
);
458 pStateSet
->AddState(AccessibleStateType::SHOWING
);
460 pStateSet
->AddState(AccessibleStateType::VISIBLE
);
466 ///===== XServiceInfo ====================================================
468 ::rtl::OUString SAL_CALL
ScAccessibleDataPilotControl::getImplementationName(void)
469 throw (uno::RuntimeException
)
471 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDataPilotControl"));
474 ///===== XTypeProvider ===================================================
476 uno::Sequence
<sal_Int8
> SAL_CALL
ScAccessibleDataPilotControl::getImplementationId(void)
477 throw (uno::RuntimeException
)
481 static uno::Sequence
<sal_Int8
> aId
;
482 if (aId
.getLength() == 0)
485 rtl_createUuid (reinterpret_cast<sal_uInt8
*>(aId
.getArray()), 0, sal_True
);
490 //===== internal ========================================================
492 ::rtl::OUString SAL_CALL
ScAccessibleDataPilotControl::createAccessibleDescription(void)
493 throw (uno::RuntimeException
)
498 return mpDPFieldWindow
->GetDescription();
500 return rtl::OUString();
503 ::rtl::OUString SAL_CALL
ScAccessibleDataPilotControl::createAccessibleName(void)
504 throw (uno::RuntimeException
)
509 return mpDPFieldWindow
->GetName();
511 return rtl::OUString();
514 Rectangle
ScAccessibleDataPilotControl::GetBoundingBoxOnScreen(void) const
515 throw (uno::RuntimeException
)
518 return mpDPFieldWindow
->GetWindowExtentsRelative(NULL
);
523 Rectangle
ScAccessibleDataPilotControl::GetBoundingBox(void) const
524 throw (uno::RuntimeException
)
527 return mpDPFieldWindow
->GetWindowExtentsRelative(mpDPFieldWindow
->GetAccessibleParentWindow());
533 //===============================================================================
535 ScAccessibleDataPilotButton::ScAccessibleDataPilotButton(
536 const ::com::sun::star::uno::Reference
<
537 ::com::sun::star::accessibility::XAccessible
>& rxParent
,
538 ScDPFieldWindow
* pDPFieldWindow
,
540 : ScAccessibleContextBase(rxParent
, AccessibleRole::PUSH_BUTTON
),
541 mpDPFieldWindow(pDPFieldWindow
),
546 ScAccessibleDataPilotButton::~ScAccessibleDataPilotButton(void)
548 if (!IsDefunc() && !rBHelper
.bInDispose
)
550 // increment refcount to prevent double call off dtor
551 osl_incrementInterlockedCount( &m_refCount
);
552 // call dispose to inform object wich have a weak reference to this object
557 void ScAccessibleDataPilotButton::Init()
561 void SAL_CALL
ScAccessibleDataPilotButton::disposing()
564 mpDPFieldWindow
= NULL
;
566 ScAccessibleContextBase::disposing();
569 void ScAccessibleDataPilotButton::SetFocused()
574 void ScAccessibleDataPilotButton::ResetFocused()
579 ///===== XAccessibleComponent ============================================
581 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleDataPilotButton::getAccessibleAtPoint(
582 const ::com::sun::star::awt::Point
& /* rPoint */ )
583 throw (::com::sun::star::uno::RuntimeException
)
588 sal_Bool SAL_CALL
ScAccessibleDataPilotButton::isVisible( )
589 throw (::com::sun::star::uno::RuntimeException
)
594 void SAL_CALL
ScAccessibleDataPilotButton::grabFocus( )
595 throw (::com::sun::star::uno::RuntimeException
)
601 mpDPFieldWindow
->GrabFocusWithSel(getAccessibleIndexInParent());
605 sal_Int32 SAL_CALL
ScAccessibleDataPilotButton::getForeground( )
606 throw (uno::RuntimeException
)
613 nColor
= mpDPFieldWindow
->GetSettings().GetStyleSettings().GetButtonTextColor().GetColor();
618 sal_Int32 SAL_CALL
ScAccessibleDataPilotButton::getBackground( )
619 throw (uno::RuntimeException
)
626 nColor
= mpDPFieldWindow
->GetSettings().GetStyleSettings().GetFaceColor().GetColor();
631 ///===== XAccessibleContext ==============================================
633 sal_Int32 SAL_CALL
ScAccessibleDataPilotButton::getAccessibleChildCount(void)
634 throw (::com::sun::star::uno::RuntimeException
)
639 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleDataPilotButton::getAccessibleChild(sal_Int32
/* nIndex */)
640 throw (::com::sun::star::uno::RuntimeException
,
641 ::com::sun::star::lang::IndexOutOfBoundsException
)
643 throw lang::IndexOutOfBoundsException();
646 sal_Int32 SAL_CALL
ScAccessibleDataPilotButton::getAccessibleIndexInParent(void)
647 throw (::com::sun::star::uno::RuntimeException
)
654 uno::Reference
<XAccessibleStateSet
> SAL_CALL
ScAccessibleDataPilotButton::getAccessibleStateSet(void)
655 throw (::com::sun::star::uno::RuntimeException
)
660 utl::AccessibleStateSetHelper
* pStateSet
= new utl::AccessibleStateSetHelper();
663 pStateSet
->AddState(AccessibleStateType::DEFUNC
);
666 pStateSet
->AddState(AccessibleStateType::ENABLED
);
667 pStateSet
->AddState(AccessibleStateType::OPAQUE
);
668 pStateSet
->AddState(AccessibleStateType::FOCUSABLE
);
669 if (mpDPFieldWindow
&& (sal::static_int_cast
<sal_Int32
>(mpDPFieldWindow
->GetSelectedField()) == mnIndex
))
670 pStateSet
->AddState(AccessibleStateType::FOCUSED
);
672 pStateSet
->AddState(AccessibleStateType::SHOWING
);
674 pStateSet
->AddState(AccessibleStateType::VISIBLE
);
680 ///===== XServiceInfo ====================================================
682 ::rtl::OUString SAL_CALL
ScAccessibleDataPilotButton::getImplementationName(void)
683 throw (::com::sun::star::uno::RuntimeException
)
685 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDataPilotButton"));
688 ///===== XTypeProvider ===================================================
690 uno::Sequence
<sal_Int8
> SAL_CALL
ScAccessibleDataPilotButton::getImplementationId(void)
691 throw (::com::sun::star::uno::RuntimeException
)
695 static uno::Sequence
<sal_Int8
> aId
;
696 if (aId
.getLength() == 0)
699 rtl_createUuid (reinterpret_cast<sal_uInt8
*>(aId
.getArray()), 0, sal_True
);
704 ::rtl::OUString SAL_CALL
ScAccessibleDataPilotButton::createAccessibleDescription(void)
705 throw (::com::sun::star::uno::RuntimeException
)
707 return rtl::OUString();
710 ::rtl::OUString SAL_CALL
ScAccessibleDataPilotButton::createAccessibleName(void)
711 throw (::com::sun::star::uno::RuntimeException
)
716 return mpDPFieldWindow
->GetFieldText(getAccessibleIndexInParent());
718 return rtl::OUString();
721 Rectangle
ScAccessibleDataPilotButton::GetBoundingBoxOnScreen(void) const
722 throw (::com::sun::star::uno::RuntimeException
)
724 Rectangle
aRect(GetBoundingBox());
728 Point
aParentPos(mpDPFieldWindow
->GetWindowExtentsRelative(NULL
).TopLeft());
729 aRect
.Move(aParentPos
.getX(), aParentPos
.getY());
735 Rectangle
ScAccessibleDataPilotButton::GetBoundingBox(void) const
736 throw (::com::sun::star::uno::RuntimeException
)
739 return Rectangle (mpDPFieldWindow
->GetFieldPosition(const_cast<ScAccessibleDataPilotButton
*> (this)->getAccessibleIndexInParent()), mpDPFieldWindow
->GetFieldSize());