xref: /AOO41X/main/sd/source/ui/accessibility/AccessibleTreeNode.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_sd.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "AccessibleTreeNode.hxx"
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include "taskpane/TaskPaneTreeNode.hxx"
34*cdf0e10cSrcweir #include "taskpane/ControlContainer.hxx"
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir #include "sdresid.hxx"
37*cdf0e10cSrcweir #include "accessibility.hrc"
38*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp>
39*cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleEventId.hpp>
40*cdf0e10cSrcweir #include <comphelper/accessibleeventnotifier.hxx>
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #include <vcl/svapp.hxx>
43*cdf0e10cSrcweir #include <vcl/window.hxx>
44*cdf0e10cSrcweir #include <svtools/colorcfg.hxx>
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir using ::rtl::OUString;
47*cdf0e10cSrcweir using namespace ::com::sun::star;
48*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
49*cdf0e10cSrcweir using namespace ::com::sun::star::accessibility;
50*cdf0e10cSrcweir using namespace ::sd::toolpanel;
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir namespace accessibility {
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir //===== AccessibleTreeNode =============================================
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir AccessibleTreeNode::AccessibleTreeNode(
59*cdf0e10cSrcweir     ::sd::toolpanel::TreeNode& rNode,
60*cdf0e10cSrcweir     const OUString& rsName,
61*cdf0e10cSrcweir     const OUString& rsDescription,
62*cdf0e10cSrcweir     sal_Int16 eRole)
63*cdf0e10cSrcweir     : AccessibleTreeNodeBase(MutexOwner::maMutex),
64*cdf0e10cSrcweir 	  mxParent(NULL),
65*cdf0e10cSrcweir       mrTreeNode(rNode),
66*cdf0e10cSrcweir       mrStateSet(new ::utl::AccessibleStateSetHelper()),
67*cdf0e10cSrcweir       msName(rsName),
68*cdf0e10cSrcweir       msDescription(rsDescription),
69*cdf0e10cSrcweir       meRole(eRole),
70*cdf0e10cSrcweir 	  mnClientId(0)
71*cdf0e10cSrcweir {
72*cdf0e10cSrcweir     ::Window* pWindow = mrTreeNode.GetWindow();
73*cdf0e10cSrcweir     if (pWindow != NULL)
74*cdf0e10cSrcweir     {
75*cdf0e10cSrcweir         ::Window* pParentWindow = pWindow->GetAccessibleParentWindow();
76*cdf0e10cSrcweir         if (pParentWindow != NULL && pParentWindow != pWindow)
77*cdf0e10cSrcweir             mxParent = pParentWindow->GetAccessible();
78*cdf0e10cSrcweir     }
79*cdf0e10cSrcweir     CommonConstructor();
80*cdf0e10cSrcweir }
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir void AccessibleTreeNode::CommonConstructor (void)
86*cdf0e10cSrcweir {
87*cdf0e10cSrcweir     UpdateStateSet();
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir     Link aStateChangeLink (LINK(this,AccessibleTreeNode,StateChangeListener));
90*cdf0e10cSrcweir     mrTreeNode.AddStateChangeListener(aStateChangeLink);
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir     if (mrTreeNode.GetWindow() != NULL)
93*cdf0e10cSrcweir     {
94*cdf0e10cSrcweir         Link aWindowEventLink (LINK(this,AccessibleTreeNode,WindowEventListener));
95*cdf0e10cSrcweir         mrTreeNode.GetWindow()->AddEventListener(aWindowEventLink);
96*cdf0e10cSrcweir     }
97*cdf0e10cSrcweir }
98*cdf0e10cSrcweir 
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir AccessibleTreeNode::~AccessibleTreeNode (void)
103*cdf0e10cSrcweir {
104*cdf0e10cSrcweir     OSL_ASSERT(IsDisposed());
105*cdf0e10cSrcweir }
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir void AccessibleTreeNode::FireAccessibleEvent (
111*cdf0e10cSrcweir     short nEventId,
112*cdf0e10cSrcweir     const uno::Any& rOldValue,
113*cdf0e10cSrcweir     const uno::Any& rNewValue )
114*cdf0e10cSrcweir {
115*cdf0e10cSrcweir     if (mnClientId != 0)
116*cdf0e10cSrcweir     {
117*cdf0e10cSrcweir         AccessibleEventObject aEventObject;
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir         aEventObject.Source = Reference<XWeak>(this);
120*cdf0e10cSrcweir         aEventObject.EventId = nEventId;
121*cdf0e10cSrcweir         aEventObject.NewValue = rNewValue;
122*cdf0e10cSrcweir 	    aEventObject.OldValue = rOldValue;
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir 		comphelper::AccessibleEventNotifier::addEvent (mnClientId, aEventObject);
125*cdf0e10cSrcweir     }
126*cdf0e10cSrcweir }
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir 
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir void SAL_CALL AccessibleTreeNode::disposing (void)
132*cdf0e10cSrcweir {
133*cdf0e10cSrcweir     // We are still listening to the tree node and its window.  Both
134*cdf0e10cSrcweir     // probably are by now more or less dead and we must not call them to
135*cdf0e10cSrcweir     // unregister.
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir     if (mnClientId != 0)
138*cdf0e10cSrcweir     {
139*cdf0e10cSrcweir         comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
140*cdf0e10cSrcweir         mnClientId = 0;
141*cdf0e10cSrcweir     }
142*cdf0e10cSrcweir }
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir //=====  XAccessible  =========================================================
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir Reference<XAccessibleContext > SAL_CALL
150*cdf0e10cSrcweir     AccessibleTreeNode::getAccessibleContext (void)
151*cdf0e10cSrcweir     throw (uno::RuntimeException)
152*cdf0e10cSrcweir {
153*cdf0e10cSrcweir     ThrowIfDisposed ();
154*cdf0e10cSrcweir     return this;
155*cdf0e10cSrcweir }
156*cdf0e10cSrcweir 
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir //=====  XAccessibleContext  ==================================================
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir sal_Int32 SAL_CALL AccessibleTreeNode::getAccessibleChildCount (void)
163*cdf0e10cSrcweir     throw (RuntimeException)
164*cdf0e10cSrcweir {
165*cdf0e10cSrcweir     ThrowIfDisposed();
166*cdf0e10cSrcweir     const vos::OGuard aSolarGuard (Application::GetSolarMutex());
167*cdf0e10cSrcweir     return mrTreeNode.GetControlContainer().GetControlCount();
168*cdf0e10cSrcweir }
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir Reference<XAccessible > SAL_CALL
174*cdf0e10cSrcweir     AccessibleTreeNode::getAccessibleChild (sal_Int32 nIndex)
175*cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, RuntimeException)
176*cdf0e10cSrcweir {
177*cdf0e10cSrcweir     ThrowIfDisposed();
178*cdf0e10cSrcweir     const vos::OGuard aSolarGuard (Application::GetSolarMutex());
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir     if (nIndex<0 || (sal_uInt32)nIndex>=mrTreeNode.GetControlContainer().GetControlCount())
181*cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir     Reference<XAccessible> xChild;
184*cdf0e10cSrcweir 
185*cdf0e10cSrcweir     ::sd::toolpanel::TreeNode* pNode = mrTreeNode.GetControlContainer().GetControl(nIndex);
186*cdf0e10cSrcweir     if (pNode != NULL)
187*cdf0e10cSrcweir         xChild = pNode->GetAccessibleObject();
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir     return xChild;
190*cdf0e10cSrcweir }
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir Reference<XAccessible > SAL_CALL AccessibleTreeNode::getAccessibleParent (void)
196*cdf0e10cSrcweir     throw (uno::RuntimeException)
197*cdf0e10cSrcweir {
198*cdf0e10cSrcweir     ThrowIfDisposed();
199*cdf0e10cSrcweir     const vos::OGuard aSolarGuard (Application::GetSolarMutex());
200*cdf0e10cSrcweir     return mxParent;
201*cdf0e10cSrcweir }
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir sal_Int32 SAL_CALL AccessibleTreeNode::getAccessibleIndexInParent (void)
207*cdf0e10cSrcweir     throw (uno::RuntimeException)
208*cdf0e10cSrcweir {
209*cdf0e10cSrcweir     OSL_ASSERT(getAccessibleParent().is());
210*cdf0e10cSrcweir     ThrowIfDisposed();
211*cdf0e10cSrcweir     const vos::OGuard aSolarGuard (Application::GetSolarMutex());
212*cdf0e10cSrcweir     sal_Int32 nIndexInParent(-1);
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir     Reference<XAccessibleContext> xParentContext (getAccessibleParent()->getAccessibleContext());
216*cdf0e10cSrcweir     if (xParentContext.is())
217*cdf0e10cSrcweir     {
218*cdf0e10cSrcweir         sal_Int32 nChildCount (xParentContext->getAccessibleChildCount());
219*cdf0e10cSrcweir         for (sal_Int32 i=0; i<nChildCount; ++i)
220*cdf0e10cSrcweir             if (xParentContext->getAccessibleChild(i).get()
221*cdf0e10cSrcweir                     == static_cast<XAccessible*>(this))
222*cdf0e10cSrcweir             {
223*cdf0e10cSrcweir                 nIndexInParent = i;
224*cdf0e10cSrcweir                 break;
225*cdf0e10cSrcweir             }
226*cdf0e10cSrcweir     }
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir     return nIndexInParent;
229*cdf0e10cSrcweir }
230*cdf0e10cSrcweir 
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir sal_Int16 SAL_CALL AccessibleTreeNode::getAccessibleRole (void)
235*cdf0e10cSrcweir     throw (uno::RuntimeException)
236*cdf0e10cSrcweir {
237*cdf0e10cSrcweir     ThrowIfDisposed();
238*cdf0e10cSrcweir     return meRole;
239*cdf0e10cSrcweir }
240*cdf0e10cSrcweir 
241*cdf0e10cSrcweir 
242*cdf0e10cSrcweir 
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir ::rtl::OUString SAL_CALL AccessibleTreeNode::getAccessibleDescription (void)
245*cdf0e10cSrcweir     throw (uno::RuntimeException)
246*cdf0e10cSrcweir {
247*cdf0e10cSrcweir     ThrowIfDisposed();
248*cdf0e10cSrcweir     return msDescription;
249*cdf0e10cSrcweir }
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir 
254*cdf0e10cSrcweir ::rtl::OUString SAL_CALL AccessibleTreeNode::getAccessibleName (void)
255*cdf0e10cSrcweir     throw (uno::RuntimeException)
256*cdf0e10cSrcweir {
257*cdf0e10cSrcweir     ThrowIfDisposed();
258*cdf0e10cSrcweir     return msName;
259*cdf0e10cSrcweir }
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir Reference<XAccessibleRelationSet> SAL_CALL
265*cdf0e10cSrcweir     AccessibleTreeNode::getAccessibleRelationSet (void)
266*cdf0e10cSrcweir     throw (uno::RuntimeException)
267*cdf0e10cSrcweir {
268*cdf0e10cSrcweir     ThrowIfDisposed();
269*cdf0e10cSrcweir     return Reference<XAccessibleRelationSet>();
270*cdf0e10cSrcweir }
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir 
274*cdf0e10cSrcweir 
275*cdf0e10cSrcweir Reference<XAccessibleStateSet > SAL_CALL
276*cdf0e10cSrcweir     AccessibleTreeNode::getAccessibleStateSet (void)
277*cdf0e10cSrcweir     throw (uno::RuntimeException)
278*cdf0e10cSrcweir {
279*cdf0e10cSrcweir     ThrowIfDisposed();
280*cdf0e10cSrcweir     const vos::OGuard aSolarGuard (Application::GetSolarMutex());
281*cdf0e10cSrcweir     return mrStateSet.get();
282*cdf0e10cSrcweir }
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir void AccessibleTreeNode::UpdateStateSet (void)
288*cdf0e10cSrcweir {
289*cdf0e10cSrcweir     if (mrTreeNode.IsExpandable())
290*cdf0e10cSrcweir     {
291*cdf0e10cSrcweir         UpdateState(AccessibleStateType::EXPANDABLE, true);
292*cdf0e10cSrcweir         UpdateState(AccessibleStateType::EXPANDED, mrTreeNode.IsExpanded());
293*cdf0e10cSrcweir     }
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir     UpdateState(AccessibleStateType::FOCUSABLE, true);
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir     ::Window* pWindow = mrTreeNode.GetWindow();
298*cdf0e10cSrcweir     if (pWindow != NULL)
299*cdf0e10cSrcweir     {
300*cdf0e10cSrcweir         UpdateState(AccessibleStateType::ENABLED, pWindow->IsEnabled());
301*cdf0e10cSrcweir         UpdateState(AccessibleStateType::FOCUSED, pWindow->HasFocus());
302*cdf0e10cSrcweir         UpdateState(AccessibleStateType::VISIBLE, pWindow->IsVisible());
303*cdf0e10cSrcweir         UpdateState(AccessibleStateType::SHOWING, pWindow->IsReallyVisible());
304*cdf0e10cSrcweir     }
305*cdf0e10cSrcweir }
306*cdf0e10cSrcweir 
307*cdf0e10cSrcweir 
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir 
310*cdf0e10cSrcweir void AccessibleTreeNode::UpdateState(
311*cdf0e10cSrcweir     sal_Int16 aState,
312*cdf0e10cSrcweir     bool bValue)
313*cdf0e10cSrcweir {
314*cdf0e10cSrcweir     if ((mrStateSet->contains(aState)!=sal_False) != bValue)
315*cdf0e10cSrcweir     {
316*cdf0e10cSrcweir         if (bValue)
317*cdf0e10cSrcweir         {
318*cdf0e10cSrcweir             mrStateSet->AddState(aState);
319*cdf0e10cSrcweir             FireAccessibleEvent(AccessibleEventId::STATE_CHANGED, Any(),Any(aState));
320*cdf0e10cSrcweir         }
321*cdf0e10cSrcweir         else
322*cdf0e10cSrcweir         {
323*cdf0e10cSrcweir             mrStateSet->RemoveState(aState);
324*cdf0e10cSrcweir             FireAccessibleEvent(AccessibleEventId::STATE_CHANGED, Any(aState),Any());
325*cdf0e10cSrcweir         }
326*cdf0e10cSrcweir     }
327*cdf0e10cSrcweir }
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir 
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir lang::Locale SAL_CALL AccessibleTreeNode::getLocale (void)
333*cdf0e10cSrcweir     throw (IllegalAccessibleComponentStateException,
334*cdf0e10cSrcweir         RuntimeException)
335*cdf0e10cSrcweir {
336*cdf0e10cSrcweir     ThrowIfDisposed ();
337*cdf0e10cSrcweir     Reference<XAccessibleContext> xParentContext;
338*cdf0e10cSrcweir     Reference<XAccessible> xParent (getAccessibleParent());
339*cdf0e10cSrcweir     if (xParent.is())
340*cdf0e10cSrcweir         xParentContext = xParent->getAccessibleContext();
341*cdf0e10cSrcweir 
342*cdf0e10cSrcweir     if (xParentContext.is())
343*cdf0e10cSrcweir         return xParentContext->getLocale();
344*cdf0e10cSrcweir     else
345*cdf0e10cSrcweir         // Strange, no parent!  Anyway, return the default locale.
346*cdf0e10cSrcweir         return Application::GetSettings().GetLocale();
347*cdf0e10cSrcweir }
348*cdf0e10cSrcweir 
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir 
352*cdf0e10cSrcweir void SAL_CALL AccessibleTreeNode::addEventListener(
353*cdf0e10cSrcweir     const Reference<XAccessibleEventListener >& rxListener)
354*cdf0e10cSrcweir     throw (RuntimeException)
355*cdf0e10cSrcweir {
356*cdf0e10cSrcweir 	if (rxListener.is())
357*cdf0e10cSrcweir     {
358*cdf0e10cSrcweir         const osl::MutexGuard aGuard(maMutex);
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir         if (IsDisposed())
361*cdf0e10cSrcweir         {
362*cdf0e10cSrcweir             uno::Reference<uno::XInterface> x ((lang::XComponent *)this, uno::UNO_QUERY);
363*cdf0e10cSrcweir 		    rxListener->disposing (lang::EventObject (x));
364*cdf0e10cSrcweir 	    }
365*cdf0e10cSrcweir         else
366*cdf0e10cSrcweir         {
367*cdf0e10cSrcweir             if (mnClientId == 0)
368*cdf0e10cSrcweir                 mnClientId = comphelper::AccessibleEventNotifier::registerClient();
369*cdf0e10cSrcweir             if (mnClientId != 0)
370*cdf0e10cSrcweir                 comphelper::AccessibleEventNotifier::addEventListener(mnClientId, rxListener);
371*cdf0e10cSrcweir         }
372*cdf0e10cSrcweir     }
373*cdf0e10cSrcweir }
374*cdf0e10cSrcweir 
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir 
377*cdf0e10cSrcweir 
378*cdf0e10cSrcweir void SAL_CALL AccessibleTreeNode::removeEventListener(
379*cdf0e10cSrcweir     const Reference<XAccessibleEventListener >& rxListener)
380*cdf0e10cSrcweir     throw (RuntimeException)
381*cdf0e10cSrcweir {
382*cdf0e10cSrcweir     ThrowIfDisposed();
383*cdf0e10cSrcweir 	if (rxListener.is())
384*cdf0e10cSrcweir 	{
385*cdf0e10cSrcweir         const osl::MutexGuard aGuard(maMutex);
386*cdf0e10cSrcweir 
387*cdf0e10cSrcweir         sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, rxListener );
388*cdf0e10cSrcweir 		if ( !nListenerCount )
389*cdf0e10cSrcweir 		{
390*cdf0e10cSrcweir 			// no listeners anymore
391*cdf0e10cSrcweir 			// -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
392*cdf0e10cSrcweir 			// and at least to us not firing any events anymore, in case somebody calls
393*cdf0e10cSrcweir 			// NotifyAccessibleEvent, again
394*cdf0e10cSrcweir             if (mnClientId != 0)
395*cdf0e10cSrcweir             {
396*cdf0e10cSrcweir                 comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
397*cdf0e10cSrcweir                 mnClientId = 0;
398*cdf0e10cSrcweir             }
399*cdf0e10cSrcweir 		}
400*cdf0e10cSrcweir 	}
401*cdf0e10cSrcweir }
402*cdf0e10cSrcweir 
403*cdf0e10cSrcweir 
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir 
406*cdf0e10cSrcweir //===== XAccessibleComponent ==================================================
407*cdf0e10cSrcweir 
408*cdf0e10cSrcweir sal_Bool SAL_CALL AccessibleTreeNode::containsPoint (const awt::Point& aPoint)
409*cdf0e10cSrcweir     throw (RuntimeException)
410*cdf0e10cSrcweir {
411*cdf0e10cSrcweir     ThrowIfDisposed();
412*cdf0e10cSrcweir     const awt::Rectangle aBBox (getBounds());
413*cdf0e10cSrcweir     return (aPoint.X >= 0)
414*cdf0e10cSrcweir         && (aPoint.X < aBBox.Width)
415*cdf0e10cSrcweir         && (aPoint.Y >= 0)
416*cdf0e10cSrcweir         && (aPoint.Y < aBBox.Height);
417*cdf0e10cSrcweir }
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir 
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir 
422*cdf0e10cSrcweir Reference<XAccessible> SAL_CALL
423*cdf0e10cSrcweir     AccessibleTreeNode::getAccessibleAtPoint (const awt::Point& aPoint)
424*cdf0e10cSrcweir     throw (RuntimeException)
425*cdf0e10cSrcweir {
426*cdf0e10cSrcweir     ThrowIfDisposed();
427*cdf0e10cSrcweir     Reference<XAccessible> xChildAtPoint;
428*cdf0e10cSrcweir     const vos::OGuard aSolarGuard (Application::GetSolarMutex());
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir     sal_Int32 nChildCount = getAccessibleChildCount();
431*cdf0e10cSrcweir     for (sal_Int32 nIndex=0; nIndex<nChildCount; ++nIndex)
432*cdf0e10cSrcweir     {
433*cdf0e10cSrcweir         Reference<XAccessibleComponent> xChildComponent(
434*cdf0e10cSrcweir             getAccessibleChild(nIndex), UNO_QUERY);
435*cdf0e10cSrcweir         if (xChildComponent.is())
436*cdf0e10cSrcweir         {
437*cdf0e10cSrcweir             awt::Point aChildPoint(aPoint);
438*cdf0e10cSrcweir             awt::Point aChildOrigin(xChildComponent->getLocation());
439*cdf0e10cSrcweir             aChildPoint.X -= aChildOrigin.X;
440*cdf0e10cSrcweir             aChildPoint.Y -= aChildOrigin.Y;
441*cdf0e10cSrcweir             if (xChildComponent->containsPoint(aChildPoint))
442*cdf0e10cSrcweir             {
443*cdf0e10cSrcweir                 xChildAtPoint = getAccessibleChild(nIndex);
444*cdf0e10cSrcweir                 break;
445*cdf0e10cSrcweir             }
446*cdf0e10cSrcweir         }
447*cdf0e10cSrcweir     }
448*cdf0e10cSrcweir 
449*cdf0e10cSrcweir     return xChildAtPoint;
450*cdf0e10cSrcweir }
451*cdf0e10cSrcweir 
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir 
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir awt::Rectangle SAL_CALL AccessibleTreeNode::getBounds (void)
456*cdf0e10cSrcweir     throw (RuntimeException)
457*cdf0e10cSrcweir {
458*cdf0e10cSrcweir     ThrowIfDisposed ();
459*cdf0e10cSrcweir 
460*cdf0e10cSrcweir     awt::Rectangle aBBox;
461*cdf0e10cSrcweir 
462*cdf0e10cSrcweir     ::Window* pWindow = mrTreeNode.GetWindow();
463*cdf0e10cSrcweir     if (pWindow != NULL)
464*cdf0e10cSrcweir     {
465*cdf0e10cSrcweir         Point aPosition;
466*cdf0e10cSrcweir         if (mxParent.is())
467*cdf0e10cSrcweir         {
468*cdf0e10cSrcweir             aPosition = pWindow->OutputToAbsoluteScreenPixel(Point(0,0));
469*cdf0e10cSrcweir             Reference<XAccessibleComponent> xParentComponent (
470*cdf0e10cSrcweir                 mxParent->getAccessibleContext(), UNO_QUERY);
471*cdf0e10cSrcweir             if (xParentComponent.is())
472*cdf0e10cSrcweir             {
473*cdf0e10cSrcweir                 awt::Point aParentPosition (xParentComponent->getLocationOnScreen());
474*cdf0e10cSrcweir                 aPosition.X() -= aParentPosition.X;
475*cdf0e10cSrcweir                 aPosition.Y() -= aParentPosition.Y;
476*cdf0e10cSrcweir             }
477*cdf0e10cSrcweir         }
478*cdf0e10cSrcweir         else
479*cdf0e10cSrcweir             aPosition = pWindow->GetPosPixel();
480*cdf0e10cSrcweir         aBBox.X = aPosition.X();
481*cdf0e10cSrcweir         aBBox.Y = aPosition.Y();
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir         Size aSize (pWindow->GetSizePixel());
484*cdf0e10cSrcweir         aBBox.Width = aSize.Width();
485*cdf0e10cSrcweir         aBBox.Height = aSize.Height();
486*cdf0e10cSrcweir     }
487*cdf0e10cSrcweir 
488*cdf0e10cSrcweir     return aBBox;
489*cdf0e10cSrcweir }
490*cdf0e10cSrcweir 
491*cdf0e10cSrcweir 
492*cdf0e10cSrcweir 
493*cdf0e10cSrcweir 
494*cdf0e10cSrcweir awt::Point SAL_CALL AccessibleTreeNode::getLocation (void)
495*cdf0e10cSrcweir     throw (uno::RuntimeException)
496*cdf0e10cSrcweir {
497*cdf0e10cSrcweir     ThrowIfDisposed();
498*cdf0e10cSrcweir     const awt::Rectangle aBBox (getBounds());
499*cdf0e10cSrcweir     return awt::Point(aBBox.X,aBBox.Y);
500*cdf0e10cSrcweir }
501*cdf0e10cSrcweir 
502*cdf0e10cSrcweir 
503*cdf0e10cSrcweir 
504*cdf0e10cSrcweir 
505*cdf0e10cSrcweir /** Calculate the location on screen from the parent's location on screen
506*cdf0e10cSrcweir     and our own relative location.
507*cdf0e10cSrcweir */
508*cdf0e10cSrcweir awt::Point SAL_CALL AccessibleTreeNode::getLocationOnScreen()
509*cdf0e10cSrcweir     throw (uno::RuntimeException)
510*cdf0e10cSrcweir {
511*cdf0e10cSrcweir     ThrowIfDisposed();
512*cdf0e10cSrcweir     const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
513*cdf0e10cSrcweir     awt::Point aLocationOnScreen;
514*cdf0e10cSrcweir 
515*cdf0e10cSrcweir     ::Window* pWindow = mrTreeNode.GetWindow();
516*cdf0e10cSrcweir     if (pWindow != NULL)
517*cdf0e10cSrcweir     {
518*cdf0e10cSrcweir         Point aPoint (pWindow->OutputToAbsoluteScreenPixel(Point(0,0)));
519*cdf0e10cSrcweir         aLocationOnScreen.X = aPoint.X();
520*cdf0e10cSrcweir         aLocationOnScreen.Y = aPoint.Y();
521*cdf0e10cSrcweir     }
522*cdf0e10cSrcweir 
523*cdf0e10cSrcweir     return aLocationOnScreen;
524*cdf0e10cSrcweir }
525*cdf0e10cSrcweir 
526*cdf0e10cSrcweir 
527*cdf0e10cSrcweir 
528*cdf0e10cSrcweir 
529*cdf0e10cSrcweir awt::Size SAL_CALL AccessibleTreeNode::getSize (void)
530*cdf0e10cSrcweir     throw (uno::RuntimeException)
531*cdf0e10cSrcweir {
532*cdf0e10cSrcweir     ThrowIfDisposed();
533*cdf0e10cSrcweir     const awt::Rectangle aBBox (getBounds());
534*cdf0e10cSrcweir     return awt::Size(aBBox.Width,aBBox.Height);
535*cdf0e10cSrcweir }
536*cdf0e10cSrcweir 
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir 
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir void SAL_CALL AccessibleTreeNode::grabFocus (void)
541*cdf0e10cSrcweir     throw (uno::RuntimeException)
542*cdf0e10cSrcweir {
543*cdf0e10cSrcweir     ThrowIfDisposed();
544*cdf0e10cSrcweir     const vos::OGuard aSolarGuard (Application::GetSolarMutex());
545*cdf0e10cSrcweir 
546*cdf0e10cSrcweir     if (mrTreeNode.GetWindow() != NULL)
547*cdf0e10cSrcweir         mrTreeNode.GetWindow()->GrabFocus();
548*cdf0e10cSrcweir }
549*cdf0e10cSrcweir 
550*cdf0e10cSrcweir 
551*cdf0e10cSrcweir 
552*cdf0e10cSrcweir 
553*cdf0e10cSrcweir sal_Int32 SAL_CALL AccessibleTreeNode::getForeground (void)
554*cdf0e10cSrcweir     throw (RuntimeException)
555*cdf0e10cSrcweir {
556*cdf0e10cSrcweir     ThrowIfDisposed();
557*cdf0e10cSrcweir 	svtools::ColorConfig aColorConfig;
558*cdf0e10cSrcweir     sal_uInt32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor;
559*cdf0e10cSrcweir     return static_cast<sal_Int32>(nColor);
560*cdf0e10cSrcweir }
561*cdf0e10cSrcweir 
562*cdf0e10cSrcweir 
563*cdf0e10cSrcweir 
564*cdf0e10cSrcweir 
565*cdf0e10cSrcweir sal_Int32 SAL_CALL AccessibleTreeNode::getBackground (void)
566*cdf0e10cSrcweir     throw (RuntimeException)
567*cdf0e10cSrcweir {
568*cdf0e10cSrcweir     ThrowIfDisposed();
569*cdf0e10cSrcweir     sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor();
570*cdf0e10cSrcweir     return static_cast<sal_Int32>(nColor);
571*cdf0e10cSrcweir }
572*cdf0e10cSrcweir 
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir 
575*cdf0e10cSrcweir 
576*cdf0e10cSrcweir //=====  XServiceInfo  ========================================================
577*cdf0e10cSrcweir 
578*cdf0e10cSrcweir ::rtl::OUString SAL_CALL
579*cdf0e10cSrcweir    	AccessibleTreeNode::getImplementationName (void)
580*cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
581*cdf0e10cSrcweir {
582*cdf0e10cSrcweir 	return OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleTreeNode"));
583*cdf0e10cSrcweir }
584*cdf0e10cSrcweir 
585*cdf0e10cSrcweir 
586*cdf0e10cSrcweir 
587*cdf0e10cSrcweir 
588*cdf0e10cSrcweir sal_Bool SAL_CALL
589*cdf0e10cSrcweir  	AccessibleTreeNode::supportsService (const OUString& sServiceName)
590*cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
591*cdf0e10cSrcweir {
592*cdf0e10cSrcweir     ThrowIfDisposed ();
593*cdf0e10cSrcweir 
594*cdf0e10cSrcweir     //  Iterate over all supported service names and return true if on of them
595*cdf0e10cSrcweir     //  matches the given name.
596*cdf0e10cSrcweir     uno::Sequence< ::rtl::OUString> aSupportedServices (
597*cdf0e10cSrcweir         getSupportedServiceNames ());
598*cdf0e10cSrcweir     for (int i=0; i<aSupportedServices.getLength(); i++)
599*cdf0e10cSrcweir         if (sServiceName == aSupportedServices[i])
600*cdf0e10cSrcweir             return sal_True;
601*cdf0e10cSrcweir     return sal_False;
602*cdf0e10cSrcweir }
603*cdf0e10cSrcweir 
604*cdf0e10cSrcweir 
605*cdf0e10cSrcweir 
606*cdf0e10cSrcweir 
607*cdf0e10cSrcweir uno::Sequence< ::rtl::OUString> SAL_CALL
608*cdf0e10cSrcweir    	AccessibleTreeNode::getSupportedServiceNames (void)
609*cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
610*cdf0e10cSrcweir {
611*cdf0e10cSrcweir     ThrowIfDisposed ();
612*cdf0e10cSrcweir 	static const OUString sServiceNames[2] = {
613*cdf0e10cSrcweir         OUString(RTL_CONSTASCII_USTRINGPARAM(
614*cdf0e10cSrcweir             "com.sun.star.accessibility.Accessible")),
615*cdf0e10cSrcweir         OUString(RTL_CONSTASCII_USTRINGPARAM(
616*cdf0e10cSrcweir             "com.sun.star.accessibility.AccessibleContext")),
617*cdf0e10cSrcweir     };
618*cdf0e10cSrcweir 	return uno::Sequence<OUString> (sServiceNames, 2);
619*cdf0e10cSrcweir }
620*cdf0e10cSrcweir 
621*cdf0e10cSrcweir 
622*cdf0e10cSrcweir 
623*cdf0e10cSrcweir 
624*cdf0e10cSrcweir void AccessibleTreeNode::ThrowIfDisposed (void)
625*cdf0e10cSrcweir     throw (lang::DisposedException)
626*cdf0e10cSrcweir {
627*cdf0e10cSrcweir 	if (rBHelper.bDisposed || rBHelper.bInDispose)
628*cdf0e10cSrcweir 	{
629*cdf0e10cSrcweir         OSL_TRACE ("Calling disposed object. Throwing exception:");
630*cdf0e10cSrcweir         throw lang::DisposedException (
631*cdf0e10cSrcweir             OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")),
632*cdf0e10cSrcweir             static_cast<uno::XWeak*>(this));
633*cdf0e10cSrcweir     }
634*cdf0e10cSrcweir }
635*cdf0e10cSrcweir 
636*cdf0e10cSrcweir 
637*cdf0e10cSrcweir 
638*cdf0e10cSrcweir sal_Bool AccessibleTreeNode::IsDisposed (void)
639*cdf0e10cSrcweir {
640*cdf0e10cSrcweir 	return (rBHelper.bDisposed || rBHelper.bInDispose);
641*cdf0e10cSrcweir }
642*cdf0e10cSrcweir 
643*cdf0e10cSrcweir 
644*cdf0e10cSrcweir 
645*cdf0e10cSrcweir 
646*cdf0e10cSrcweir IMPL_LINK(AccessibleTreeNode, StateChangeListener, TreeNodeStateChangeEvent*, pEvent)
647*cdf0e10cSrcweir {
648*cdf0e10cSrcweir     OSL_ASSERT(pEvent!=NULL);
649*cdf0e10cSrcweir     OSL_ASSERT(&pEvent->mrSource==&mrTreeNode);
650*cdf0e10cSrcweir 
651*cdf0e10cSrcweir     switch(pEvent->meEventId)
652*cdf0e10cSrcweir     {
653*cdf0e10cSrcweir         case EID_CHILD_ADDED:
654*cdf0e10cSrcweir             if (pEvent->mpChild != NULL)
655*cdf0e10cSrcweir                 FireAccessibleEvent(AccessibleEventId::CHILD,
656*cdf0e10cSrcweir                     Any(),
657*cdf0e10cSrcweir                     Any(pEvent->mpChild->GetAccessibleObject()));
658*cdf0e10cSrcweir             else
659*cdf0e10cSrcweir                 FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN,Any(),Any());
660*cdf0e10cSrcweir             break;
661*cdf0e10cSrcweir 
662*cdf0e10cSrcweir         case EID_ALL_CHILDREN_REMOVED:
663*cdf0e10cSrcweir             FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN,Any(),Any());
664*cdf0e10cSrcweir             break;
665*cdf0e10cSrcweir 
666*cdf0e10cSrcweir         case EID_EXPANSION_STATE_CHANGED:
667*cdf0e10cSrcweir         case EID_FOCUSED_STATE_CHANGED:
668*cdf0e10cSrcweir         case EID_SHOWING_STATE_CHANGED:
669*cdf0e10cSrcweir             UpdateStateSet();
670*cdf0e10cSrcweir             break;
671*cdf0e10cSrcweir     }
672*cdf0e10cSrcweir     return 1;
673*cdf0e10cSrcweir }
674*cdf0e10cSrcweir 
675*cdf0e10cSrcweir 
676*cdf0e10cSrcweir 
677*cdf0e10cSrcweir 
678*cdf0e10cSrcweir IMPL_LINK(AccessibleTreeNode, WindowEventListener, VclWindowEvent*, pEvent)
679*cdf0e10cSrcweir {
680*cdf0e10cSrcweir 	switch (pEvent->GetId())
681*cdf0e10cSrcweir     {
682*cdf0e10cSrcweir         case VCLEVENT_WINDOW_HIDE:
683*cdf0e10cSrcweir             // This event may be sent while the window is destroyed so do
684*cdf0e10cSrcweir             // not call UpdateStateSet() which calls back to the window but
685*cdf0e10cSrcweir             // just set the two states VISIBLE and SHOWING to false.
686*cdf0e10cSrcweir             UpdateState(AccessibleStateType::VISIBLE, false);
687*cdf0e10cSrcweir             UpdateState(AccessibleStateType::SHOWING, false);
688*cdf0e10cSrcweir             break;
689*cdf0e10cSrcweir 
690*cdf0e10cSrcweir         case VCLEVENT_WINDOW_SHOW:
691*cdf0e10cSrcweir         case VCLEVENT_WINDOW_DATACHANGED:
692*cdf0e10cSrcweir             UpdateStateSet();
693*cdf0e10cSrcweir             break;
694*cdf0e10cSrcweir 
695*cdf0e10cSrcweir         case VCLEVENT_WINDOW_MOVE:
696*cdf0e10cSrcweir         case VCLEVENT_WINDOW_RESIZE:
697*cdf0e10cSrcweir             FireAccessibleEvent(AccessibleEventId::BOUNDRECT_CHANGED,Any(),Any());
698*cdf0e10cSrcweir             break;
699*cdf0e10cSrcweir 
700*cdf0e10cSrcweir         case VCLEVENT_WINDOW_GETFOCUS:
701*cdf0e10cSrcweir         case VCLEVENT_WINDOW_LOSEFOCUS:
702*cdf0e10cSrcweir             UpdateStateSet();
703*cdf0e10cSrcweir             break;
704*cdf0e10cSrcweir     }
705*cdf0e10cSrcweir     return 1;
706*cdf0e10cSrcweir }
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir } // end of namespace ::accessibility
709