1*190118d0SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*190118d0SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*190118d0SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*190118d0SAndrew Rist  * distributed with this work for additional information
6*190118d0SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*190118d0SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*190118d0SAndrew Rist  * "License"); you may not use this file except in compliance
9*190118d0SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*190118d0SAndrew Rist  *
11*190118d0SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*190118d0SAndrew Rist  *
13*190118d0SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*190118d0SAndrew Rist  * software distributed under the License is distributed on an
15*190118d0SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*190118d0SAndrew Rist  * KIND, either express or implied.  See the License for the
17*190118d0SAndrew Rist  * specific language governing permissions and limitations
18*190118d0SAndrew Rist  * under the License.
19*190118d0SAndrew Rist  *
20*190118d0SAndrew Rist  *************************************************************/
21*190118d0SAndrew Rist 
22*190118d0SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_editeng.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <editeng/AccessibleContextBase.hxx>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp>
31cdf0e10cSrcweir #include <com/sun/star/beans/PropertyChangeEvent.hpp>
32cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
33cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp>
34cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include <unotools/accessiblestatesethelper.hxx>
37cdf0e10cSrcweir #include <unotools/accessiblerelationsethelper.hxx>
38cdf0e10cSrcweir #include <comphelper/accessibleeventnotifier.hxx>
39cdf0e10cSrcweir #include <rtl/uuid.h>
40cdf0e10cSrcweir #include <vos/mutex.hxx>
41cdf0e10cSrcweir //#include <vcl/svapp.hxx>
42cdf0e10cSrcweir 
43cdf0e10cSrcweir #include <utility>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir using namespace	::rtl;
46cdf0e10cSrcweir using namespace	::com::sun::star;
47cdf0e10cSrcweir using namespace	::com::sun::star::accessibility;
48cdf0e10cSrcweir using ::com::sun::star::uno::Reference;
49cdf0e10cSrcweir 
50cdf0e10cSrcweir namespace accessibility {
51cdf0e10cSrcweir 
52cdf0e10cSrcweir //=====  internal  ============================================================
53cdf0e10cSrcweir 
54cdf0e10cSrcweir // Define a shortcut for the somewhot longish base class name.
55cdf0e10cSrcweir typedef ::cppu::WeakComponentImplHelper4<
56cdf0e10cSrcweir     ::com::sun::star::accessibility::XAccessible,
57cdf0e10cSrcweir     ::com::sun::star::accessibility::XAccessibleContext,
58cdf0e10cSrcweir     ::com::sun::star::accessibility::XAccessibleEventBroadcaster,
59cdf0e10cSrcweir     ::com::sun::star::lang::XServiceInfo> BaseClass;
60cdf0e10cSrcweir 
AccessibleContextBase(const uno::Reference<XAccessible> & rxParent,const sal_Int16 aRole)61cdf0e10cSrcweir AccessibleContextBase::AccessibleContextBase (
62cdf0e10cSrcweir         const uno::Reference<XAccessible>& rxParent,
63cdf0e10cSrcweir 		const sal_Int16 aRole)
64cdf0e10cSrcweir 	:   BaseClass (MutexOwner::maMutex),
65cdf0e10cSrcweir         mxStateSet (NULL),
66cdf0e10cSrcweir         mxRelationSet (NULL),
67cdf0e10cSrcweir         mxParent(rxParent),
68cdf0e10cSrcweir         msDescription(),
69cdf0e10cSrcweir         meDescriptionOrigin(NotSet),
70cdf0e10cSrcweir         msName(),
71cdf0e10cSrcweir         meNameOrigin(NotSet),
72cdf0e10cSrcweir         mnClientId(0),
73cdf0e10cSrcweir         maRole(aRole)
74cdf0e10cSrcweir {
75cdf0e10cSrcweir     // Create the state set.
76cdf0e10cSrcweir     ::utl::AccessibleStateSetHelper* pStateSet  = new ::utl::AccessibleStateSetHelper ();
77cdf0e10cSrcweir     mxStateSet = pStateSet;
78cdf0e10cSrcweir 
79cdf0e10cSrcweir     // Set some states.  Don't use the SetState method because no events
80cdf0e10cSrcweir     // shall be broadcastet (that is not yet initialized anyway).
81cdf0e10cSrcweir     if (pStateSet != NULL)
82cdf0e10cSrcweir     {
83cdf0e10cSrcweir         pStateSet->AddState (AccessibleStateType::ENABLED);
84cdf0e10cSrcweir         pStateSet->AddState (AccessibleStateType::SENSITIVE);
85cdf0e10cSrcweir         pStateSet->AddState (AccessibleStateType::SHOWING);
86cdf0e10cSrcweir         pStateSet->AddState (AccessibleStateType::VISIBLE);
87cdf0e10cSrcweir         pStateSet->AddState (AccessibleStateType::FOCUSABLE);
88cdf0e10cSrcweir         pStateSet->AddState (AccessibleStateType::SELECTABLE);
89cdf0e10cSrcweir     }
90cdf0e10cSrcweir 
91cdf0e10cSrcweir     // Create the relation set.
92cdf0e10cSrcweir     ::utl::AccessibleRelationSetHelper* pRelationSet = new ::utl::AccessibleRelationSetHelper ();
93cdf0e10cSrcweir     mxRelationSet = pRelationSet;
94cdf0e10cSrcweir }
95cdf0e10cSrcweir 
96cdf0e10cSrcweir 
97cdf0e10cSrcweir 
98cdf0e10cSrcweir 
~AccessibleContextBase(void)99cdf0e10cSrcweir AccessibleContextBase::~AccessibleContextBase(void)
100cdf0e10cSrcweir {
101cdf0e10cSrcweir }
102cdf0e10cSrcweir 
103cdf0e10cSrcweir 
104cdf0e10cSrcweir 
105cdf0e10cSrcweir 
SetState(sal_Int16 aState)106cdf0e10cSrcweir sal_Bool AccessibleContextBase::SetState (sal_Int16 aState)
107cdf0e10cSrcweir {
108cdf0e10cSrcweir     ::osl::ClearableMutexGuard aGuard (maMutex);
109cdf0e10cSrcweir     ::utl::AccessibleStateSetHelper* pStateSet =
110cdf0e10cSrcweir         static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
111cdf0e10cSrcweir     if ((pStateSet != NULL) && !pStateSet->contains(aState))
112cdf0e10cSrcweir     {
113cdf0e10cSrcweir         pStateSet->AddState (aState);
114cdf0e10cSrcweir         // Clear the mutex guard so that it is not locked during calls to
115cdf0e10cSrcweir         // listeners.
116cdf0e10cSrcweir         aGuard.clear();
117cdf0e10cSrcweir 
118cdf0e10cSrcweir         // Send event for all states except the DEFUNC state.
119cdf0e10cSrcweir         if (aState != AccessibleStateType::DEFUNC)
120cdf0e10cSrcweir         {
121cdf0e10cSrcweir             uno::Any aNewValue;
122cdf0e10cSrcweir             aNewValue <<= aState;
123cdf0e10cSrcweir             CommitChange(
124cdf0e10cSrcweir                 AccessibleEventId::STATE_CHANGED,
125cdf0e10cSrcweir                 aNewValue,
126cdf0e10cSrcweir                 uno::Any());
127cdf0e10cSrcweir         }
128cdf0e10cSrcweir         return sal_True;
129cdf0e10cSrcweir     }
130cdf0e10cSrcweir     else
131cdf0e10cSrcweir         return sal_False;
132cdf0e10cSrcweir }
133cdf0e10cSrcweir 
134cdf0e10cSrcweir 
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 
ResetState(sal_Int16 aState)137cdf0e10cSrcweir sal_Bool AccessibleContextBase::ResetState (sal_Int16 aState)
138cdf0e10cSrcweir {
139cdf0e10cSrcweir     ::osl::ClearableMutexGuard aGuard (maMutex);
140cdf0e10cSrcweir     ::utl::AccessibleStateSetHelper* pStateSet =
141cdf0e10cSrcweir         static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
142cdf0e10cSrcweir     if ((pStateSet != NULL) && pStateSet->contains(aState))
143cdf0e10cSrcweir     {
144cdf0e10cSrcweir         pStateSet->RemoveState (aState);
145cdf0e10cSrcweir         // Clear the mutex guard so that it is not locked during calls to listeners.
146cdf0e10cSrcweir         aGuard.clear();
147cdf0e10cSrcweir 
148cdf0e10cSrcweir         uno::Any aOldValue;
149cdf0e10cSrcweir         aOldValue <<= aState;
150cdf0e10cSrcweir         CommitChange(
151cdf0e10cSrcweir             AccessibleEventId::STATE_CHANGED,
152cdf0e10cSrcweir             uno::Any(),
153cdf0e10cSrcweir             aOldValue);
154cdf0e10cSrcweir         return sal_True;
155cdf0e10cSrcweir     }
156cdf0e10cSrcweir     else
157cdf0e10cSrcweir         return sal_False;
158cdf0e10cSrcweir }
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 
162cdf0e10cSrcweir 
GetState(sal_Int16 aState)163cdf0e10cSrcweir sal_Bool AccessibleContextBase::GetState (sal_Int16 aState)
164cdf0e10cSrcweir {
165cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
166cdf0e10cSrcweir     ::utl::AccessibleStateSetHelper* pStateSet =
167cdf0e10cSrcweir         static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
168cdf0e10cSrcweir     if (pStateSet != NULL)
169cdf0e10cSrcweir         return pStateSet->contains(aState);
170cdf0e10cSrcweir     else
171cdf0e10cSrcweir         // If there is no state set then return false as a default value.
172cdf0e10cSrcweir         return sal_False;
173cdf0e10cSrcweir }
174cdf0e10cSrcweir 
175cdf0e10cSrcweir 
176cdf0e10cSrcweir 
177cdf0e10cSrcweir 
SetRelationSet(const uno::Reference<XAccessibleRelationSet> & rxNewRelationSet)178cdf0e10cSrcweir void AccessibleContextBase::SetRelationSet (
179cdf0e10cSrcweir     const uno::Reference<XAccessibleRelationSet>& rxNewRelationSet)
180cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
181cdf0e10cSrcweir {
182cdf0e10cSrcweir     OSL_TRACE ("setting relation set");
183cdf0e10cSrcweir 
184cdf0e10cSrcweir     // Try to emit some meaningfull events indicating differing relations in
185cdf0e10cSrcweir     // both sets.
186cdf0e10cSrcweir     typedef std::pair<short int,short int> RD;
187cdf0e10cSrcweir     const RD aRelationDescriptors[] = {
188cdf0e10cSrcweir         RD(AccessibleRelationType::CONTROLLED_BY, AccessibleEventId::CONTROLLED_BY_RELATION_CHANGED),
189cdf0e10cSrcweir         RD(AccessibleRelationType::CONTROLLER_FOR, AccessibleEventId::CONTROLLER_FOR_RELATION_CHANGED),
190cdf0e10cSrcweir         RD(AccessibleRelationType::LABELED_BY, AccessibleEventId::LABELED_BY_RELATION_CHANGED),
191cdf0e10cSrcweir         RD(AccessibleRelationType::LABEL_FOR, AccessibleEventId::LABEL_FOR_RELATION_CHANGED),
192cdf0e10cSrcweir         RD(AccessibleRelationType::MEMBER_OF, AccessibleEventId::MEMBER_OF_RELATION_CHANGED),
193cdf0e10cSrcweir         RD(AccessibleRelationType::INVALID, -1),
194cdf0e10cSrcweir     };
195cdf0e10cSrcweir     for (int i=0; aRelationDescriptors[i].first!=AccessibleRelationType::INVALID; i++)
196cdf0e10cSrcweir         if (mxRelationSet->containsRelation(aRelationDescriptors[i].first)
197cdf0e10cSrcweir         != rxNewRelationSet->containsRelation(aRelationDescriptors[i].first))
198cdf0e10cSrcweir         CommitChange (aRelationDescriptors[i].second, uno::Any(), uno::Any());
199cdf0e10cSrcweir 
200cdf0e10cSrcweir     mxRelationSet = rxNewRelationSet;
201cdf0e10cSrcweir }
202cdf0e10cSrcweir 
203cdf0e10cSrcweir 
204cdf0e10cSrcweir 
205cdf0e10cSrcweir 
206cdf0e10cSrcweir //=====  XAccessible  =========================================================
207cdf0e10cSrcweir 
208cdf0e10cSrcweir uno::Reference< XAccessibleContext> SAL_CALL
getAccessibleContext(void)209cdf0e10cSrcweir     AccessibleContextBase::getAccessibleContext (void)
210cdf0e10cSrcweir     throw (uno::RuntimeException)
211cdf0e10cSrcweir {
212cdf0e10cSrcweir     ThrowIfDisposed ();
213cdf0e10cSrcweir 	return this;
214cdf0e10cSrcweir }
215cdf0e10cSrcweir 
216cdf0e10cSrcweir 
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 
219cdf0e10cSrcweir //=====  XAccessibleContext  ==================================================
220cdf0e10cSrcweir 
221cdf0e10cSrcweir /** No children.
222cdf0e10cSrcweir */
223cdf0e10cSrcweir sal_Int32 SAL_CALL
getAccessibleChildCount(void)224cdf0e10cSrcweir    	AccessibleContextBase::getAccessibleChildCount (void)
225cdf0e10cSrcweir     throw (uno::RuntimeException)
226cdf0e10cSrcweir {
227cdf0e10cSrcweir     ThrowIfDisposed ();
228cdf0e10cSrcweir     return 0;
229cdf0e10cSrcweir }
230cdf0e10cSrcweir 
231cdf0e10cSrcweir 
232cdf0e10cSrcweir 
233cdf0e10cSrcweir 
234cdf0e10cSrcweir /** Forward the request to the shape.  Return the requested shape or throw
235cdf0e10cSrcweir     an exception for a wrong index.
236cdf0e10cSrcweir */
237cdf0e10cSrcweir uno::Reference<XAccessible> SAL_CALL
getAccessibleChild(sal_Int32 nIndex)238cdf0e10cSrcweir     AccessibleContextBase::getAccessibleChild (sal_Int32 nIndex)
239cdf0e10cSrcweir     throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
240cdf0e10cSrcweir {
241cdf0e10cSrcweir     ThrowIfDisposed ();
242cdf0e10cSrcweir     throw lang::IndexOutOfBoundsException (
243cdf0e10cSrcweir         ::rtl::OUString::createFromAscii ("no child with index " + nIndex),
244cdf0e10cSrcweir 		NULL);
245cdf0e10cSrcweir }
246cdf0e10cSrcweir 
247cdf0e10cSrcweir 
248cdf0e10cSrcweir 
249cdf0e10cSrcweir 
250cdf0e10cSrcweir uno::Reference<XAccessible> SAL_CALL
getAccessibleParent(void)251cdf0e10cSrcweir    	AccessibleContextBase::getAccessibleParent (void)
252cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
253cdf0e10cSrcweir {
254cdf0e10cSrcweir     ThrowIfDisposed ();
255cdf0e10cSrcweir 	return mxParent;
256cdf0e10cSrcweir }
257cdf0e10cSrcweir 
258cdf0e10cSrcweir 
259cdf0e10cSrcweir 
260cdf0e10cSrcweir 
261cdf0e10cSrcweir sal_Int32 SAL_CALL
getAccessibleIndexInParent(void)262cdf0e10cSrcweir    	AccessibleContextBase::getAccessibleIndexInParent (void)
263cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
264cdf0e10cSrcweir {
265cdf0e10cSrcweir     ThrowIfDisposed ();
266cdf0e10cSrcweir 	//	Use a simple but slow solution for now.  Optimize later.
267cdf0e10cSrcweir 
268cdf0e10cSrcweir     //	Iterate over all the parent's children and search for this object.
269cdf0e10cSrcweir     if (mxParent.is())
270cdf0e10cSrcweir     {
271cdf0e10cSrcweir     	uno::Reference<XAccessibleContext> xParentContext (
272cdf0e10cSrcweir         	mxParent->getAccessibleContext());
273cdf0e10cSrcweir         if (xParentContext.is())
274cdf0e10cSrcweir         {
275cdf0e10cSrcweir         	sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
276cdf0e10cSrcweir             for (sal_Int32 i=0; i<nChildCount; i++)
277cdf0e10cSrcweir             {
278cdf0e10cSrcweir             	uno::Reference<XAccessible> xChild (xParentContext->getAccessibleChild (i));
279cdf0e10cSrcweir                 if (xChild.is())
280cdf0e10cSrcweir                 {
281cdf0e10cSrcweir                 	uno::Reference<XAccessibleContext> xChildContext = xChild->getAccessibleContext();
282cdf0e10cSrcweir 	            	if (xChildContext == (XAccessibleContext*)this)
283cdf0e10cSrcweir                     	return i;
284cdf0e10cSrcweir                 }
285cdf0e10cSrcweir             }
286cdf0e10cSrcweir         }
287cdf0e10cSrcweir    }
288cdf0e10cSrcweir 
289cdf0e10cSrcweir    //	Return -1 to indicate that this object's parent does not know about the
290cdf0e10cSrcweir    //	object.
291cdf0e10cSrcweir    return -1;
292cdf0e10cSrcweir }
293cdf0e10cSrcweir 
294cdf0e10cSrcweir 
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 
297cdf0e10cSrcweir sal_Int16 SAL_CALL
getAccessibleRole(void)298cdf0e10cSrcweir 	AccessibleContextBase::getAccessibleRole (void)
299cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
300cdf0e10cSrcweir {
301cdf0e10cSrcweir     ThrowIfDisposed ();
302cdf0e10cSrcweir 	return maRole;
303cdf0e10cSrcweir }
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 
306cdf0e10cSrcweir 
307cdf0e10cSrcweir 
308cdf0e10cSrcweir ::rtl::OUString SAL_CALL
getAccessibleDescription(void)309cdf0e10cSrcweir    	AccessibleContextBase::getAccessibleDescription (void)
310cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
311cdf0e10cSrcweir {
312cdf0e10cSrcweir     ThrowIfDisposed ();
313cdf0e10cSrcweir 
314cdf0e10cSrcweir     return msDescription;
315cdf0e10cSrcweir }
316cdf0e10cSrcweir 
317cdf0e10cSrcweir 
318cdf0e10cSrcweir 
319cdf0e10cSrcweir 
320cdf0e10cSrcweir OUString SAL_CALL
getAccessibleName(void)321cdf0e10cSrcweir    	AccessibleContextBase::getAccessibleName (void)
322cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
323cdf0e10cSrcweir {
324cdf0e10cSrcweir     ThrowIfDisposed ();
325cdf0e10cSrcweir 
326cdf0e10cSrcweir     if (meNameOrigin == NotSet)
327cdf0e10cSrcweir     {
328cdf0e10cSrcweir         // Do not send an event because this is the first time it has been
329cdf0e10cSrcweir         // requested.
330cdf0e10cSrcweir         msName = CreateAccessibleName();
331cdf0e10cSrcweir         meNameOrigin = AutomaticallyCreated;
332cdf0e10cSrcweir     }
333cdf0e10cSrcweir 
334cdf0e10cSrcweir     return msName;
335cdf0e10cSrcweir }
336cdf0e10cSrcweir 
337cdf0e10cSrcweir 
338cdf0e10cSrcweir 
339cdf0e10cSrcweir 
340cdf0e10cSrcweir /**	Return a copy of the relation set.
341cdf0e10cSrcweir */
342cdf0e10cSrcweir uno::Reference<XAccessibleRelationSet> SAL_CALL
getAccessibleRelationSet(void)343cdf0e10cSrcweir    	AccessibleContextBase::getAccessibleRelationSet (void)
344cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
345cdf0e10cSrcweir {
346cdf0e10cSrcweir     ThrowIfDisposed ();
347cdf0e10cSrcweir 
348cdf0e10cSrcweir     // Create a copy of the relation set and return it.
349cdf0e10cSrcweir     ::utl::AccessibleRelationSetHelper* pRelationSet =
350cdf0e10cSrcweir         static_cast< ::utl::AccessibleRelationSetHelper*>(mxRelationSet.get());
351cdf0e10cSrcweir     if (pRelationSet != NULL)
352cdf0e10cSrcweir     {
353cdf0e10cSrcweir         return uno::Reference<XAccessibleRelationSet> (
354cdf0e10cSrcweir             new ::utl::AccessibleRelationSetHelper (*pRelationSet));
355cdf0e10cSrcweir     }
356cdf0e10cSrcweir     else
357cdf0e10cSrcweir         return uno::Reference<XAccessibleRelationSet>(NULL);
358cdf0e10cSrcweir }
359cdf0e10cSrcweir 
360cdf0e10cSrcweir 
361cdf0e10cSrcweir 
362cdf0e10cSrcweir 
363cdf0e10cSrcweir /**	Return a copy of the state set.
364cdf0e10cSrcweir     Possible states are:
365cdf0e10cSrcweir 		ENABLED
366cdf0e10cSrcweir 		SHOWING
367cdf0e10cSrcweir 		VISIBLE
368cdf0e10cSrcweir */
369cdf0e10cSrcweir uno::Reference<XAccessibleStateSet> SAL_CALL
getAccessibleStateSet(void)370cdf0e10cSrcweir     AccessibleContextBase::getAccessibleStateSet (void)
371cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
372cdf0e10cSrcweir {
373cdf0e10cSrcweir     ::utl::AccessibleStateSetHelper* pStateSet = NULL;
374cdf0e10cSrcweir 
375cdf0e10cSrcweir 	if (rBHelper.bDisposed)
376cdf0e10cSrcweir     {
377cdf0e10cSrcweir         // We are already disposed!
378cdf0e10cSrcweir         // Create a new state set that has only set the DEFUNC state.
379cdf0e10cSrcweir         pStateSet = new ::utl::AccessibleStateSetHelper ();
380cdf0e10cSrcweir         if (pStateSet != NULL)
381cdf0e10cSrcweir             pStateSet->AddState (AccessibleStateType::DEFUNC);
382cdf0e10cSrcweir     }
383cdf0e10cSrcweir     else
384cdf0e10cSrcweir     {
385cdf0e10cSrcweir         // Create a copy of the state set and return it.
386cdf0e10cSrcweir         pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
387cdf0e10cSrcweir 
388cdf0e10cSrcweir         // Merge current focused state from edit engine.
389cdf0e10cSrcweir #if 0
390cdf0e10cSrcweir         if (aState == AccessibleStateType::FOCUSED
391cdf0e10cSrcweir             && pStateSet != NULL
392cdf0e10cSrcweir             && mpText != NULL)
393cdf0e10cSrcweir         {
394cdf0e10cSrcweir             if (mpText->GetFocusedState ())
395cdf0e10cSrcweir                 pStateSet->AddState (aState);
396cdf0e10cSrcweir             else
397cdf0e10cSrcweir                 pStateSet->RemoveState (aState);
398cdf0e10cSrcweir         }
399cdf0e10cSrcweir #endif
400cdf0e10cSrcweir         if (pStateSet != NULL)
401cdf0e10cSrcweir             pStateSet = new ::utl::AccessibleStateSetHelper (*pStateSet);
402cdf0e10cSrcweir     }
403cdf0e10cSrcweir 
404cdf0e10cSrcweir     return uno::Reference<XAccessibleStateSet>(pStateSet);
405cdf0e10cSrcweir }
406cdf0e10cSrcweir 
407cdf0e10cSrcweir 
408cdf0e10cSrcweir 
409cdf0e10cSrcweir 
410cdf0e10cSrcweir lang::Locale SAL_CALL
getLocale(void)411cdf0e10cSrcweir    	AccessibleContextBase::getLocale (void)
412cdf0e10cSrcweir 	throw (IllegalAccessibleComponentStateException,
413cdf0e10cSrcweir         ::com::sun::star::uno::RuntimeException)
414cdf0e10cSrcweir {
415cdf0e10cSrcweir     ThrowIfDisposed ();
416cdf0e10cSrcweir     // Delegate request to parent.
417cdf0e10cSrcweir 	if (mxParent.is())
418cdf0e10cSrcweir     {
419cdf0e10cSrcweir     	uno::Reference<XAccessibleContext> xParentContext (
420cdf0e10cSrcweir         	mxParent->getAccessibleContext());
421cdf0e10cSrcweir         if (xParentContext.is())
422cdf0e10cSrcweir 	    	return xParentContext->getLocale ();
423cdf0e10cSrcweir     }
424cdf0e10cSrcweir 
425cdf0e10cSrcweir     //	No locale and no parent.  Therefore throw exception to indicate this
426cdf0e10cSrcweir     //	cluelessness.
427cdf0e10cSrcweir     throw IllegalAccessibleComponentStateException ();
428cdf0e10cSrcweir }
429cdf0e10cSrcweir 
430cdf0e10cSrcweir 
431cdf0e10cSrcweir 
432cdf0e10cSrcweir 
433cdf0e10cSrcweir //=====  XAccessibleEventListener  ============================================
434cdf0e10cSrcweir 
435cdf0e10cSrcweir void SAL_CALL
addEventListener(const uno::Reference<XAccessibleEventListener> & rxListener)436cdf0e10cSrcweir     AccessibleContextBase::addEventListener (
437cdf0e10cSrcweir         const uno::Reference<XAccessibleEventListener >& rxListener)
438cdf0e10cSrcweir     throw (uno::RuntimeException)
439cdf0e10cSrcweir {
440cdf0e10cSrcweir 	if (rxListener.is())
441cdf0e10cSrcweir     {
442cdf0e10cSrcweir 	    if (rBHelper.bDisposed || rBHelper.bInDispose)
443cdf0e10cSrcweir 	    {
444cdf0e10cSrcweir             uno::Reference<uno::XInterface> x ((lang::XComponent *)this, uno::UNO_QUERY);
445cdf0e10cSrcweir 		    rxListener->disposing (lang::EventObject (x));
446cdf0e10cSrcweir 	    }
447cdf0e10cSrcweir 	    else
448cdf0e10cSrcweir 	    {
449cdf0e10cSrcweir 		    if (!mnClientId)
450cdf0e10cSrcweir                 mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
451cdf0e10cSrcweir 		    comphelper::AccessibleEventNotifier::addEventListener( mnClientId, rxListener );
452cdf0e10cSrcweir 	    }
453cdf0e10cSrcweir     }
454cdf0e10cSrcweir }
455cdf0e10cSrcweir 
456cdf0e10cSrcweir 
457cdf0e10cSrcweir 
458cdf0e10cSrcweir 
459cdf0e10cSrcweir void SAL_CALL
removeEventListener(const uno::Reference<XAccessibleEventListener> & rxListener)460cdf0e10cSrcweir     AccessibleContextBase::removeEventListener (
461cdf0e10cSrcweir         const uno::Reference<XAccessibleEventListener >& rxListener )
462cdf0e10cSrcweir     throw (uno::RuntimeException)
463cdf0e10cSrcweir {
464cdf0e10cSrcweir     ThrowIfDisposed ();
465cdf0e10cSrcweir 	if (rxListener.is())
466cdf0e10cSrcweir 	{
467cdf0e10cSrcweir         sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, rxListener );
468cdf0e10cSrcweir 		if ( !nListenerCount )
469cdf0e10cSrcweir 		{
470cdf0e10cSrcweir 			// no listeners anymore
471cdf0e10cSrcweir 			// -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
472cdf0e10cSrcweir 			// and at least to us not firing any events anymore, in case somebody calls
473cdf0e10cSrcweir 			// NotifyAccessibleEvent, again
474cdf0e10cSrcweir 			comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
475cdf0e10cSrcweir 			mnClientId = 0;
476cdf0e10cSrcweir 		}
477cdf0e10cSrcweir 	}
478cdf0e10cSrcweir }
479cdf0e10cSrcweir 
480cdf0e10cSrcweir 
481cdf0e10cSrcweir 
482cdf0e10cSrcweir 
483cdf0e10cSrcweir //=====  XServiceInfo  ========================================================
484cdf0e10cSrcweir 
485cdf0e10cSrcweir ::rtl::OUString SAL_CALL
getImplementationName(void)486cdf0e10cSrcweir    	AccessibleContextBase::getImplementationName (void)
487cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
488cdf0e10cSrcweir {
489cdf0e10cSrcweir     ThrowIfDisposed ();
490cdf0e10cSrcweir 	return OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleContextBase"));
491cdf0e10cSrcweir }
492cdf0e10cSrcweir 
493cdf0e10cSrcweir 
494cdf0e10cSrcweir 
495cdf0e10cSrcweir 
496cdf0e10cSrcweir sal_Bool SAL_CALL
supportsService(const OUString & sServiceName)497cdf0e10cSrcweir  	AccessibleContextBase::supportsService (const OUString& sServiceName)
498cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
499cdf0e10cSrcweir {
500cdf0e10cSrcweir     ThrowIfDisposed ();
501cdf0e10cSrcweir     //  Iterate over all supported service names and return true if on of them
502cdf0e10cSrcweir     //  matches the given name.
503cdf0e10cSrcweir     uno::Sequence< ::rtl::OUString> aSupportedServices (
504cdf0e10cSrcweir         getSupportedServiceNames ());
505cdf0e10cSrcweir     for (int i=0; i<aSupportedServices.getLength(); i++)
506cdf0e10cSrcweir         if (sServiceName == aSupportedServices[i])
507cdf0e10cSrcweir             return sal_True;
508cdf0e10cSrcweir     return sal_False;
509cdf0e10cSrcweir }
510cdf0e10cSrcweir 
511cdf0e10cSrcweir 
512cdf0e10cSrcweir 
513cdf0e10cSrcweir 
514cdf0e10cSrcweir uno::Sequence< ::rtl::OUString> SAL_CALL
getSupportedServiceNames(void)515cdf0e10cSrcweir    	AccessibleContextBase::getSupportedServiceNames (void)
516cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
517cdf0e10cSrcweir {
518cdf0e10cSrcweir     ThrowIfDisposed ();
519cdf0e10cSrcweir 	static const OUString sServiceNames[2] = {
520cdf0e10cSrcweir         OUString(RTL_CONSTASCII_USTRINGPARAM(
521cdf0e10cSrcweir             "com.sun.star.accessibility.Accessible")),
522cdf0e10cSrcweir         OUString(RTL_CONSTASCII_USTRINGPARAM(
523cdf0e10cSrcweir             "com.sun.star.accessibility.AccessibleContext"))
524cdf0e10cSrcweir     };
525cdf0e10cSrcweir 	return uno::Sequence<OUString> (sServiceNames, 2);
526cdf0e10cSrcweir }
527cdf0e10cSrcweir 
528cdf0e10cSrcweir 
529cdf0e10cSrcweir 
530cdf0e10cSrcweir 
531cdf0e10cSrcweir //=====  XTypeProvider  =======================================================
532cdf0e10cSrcweir 
533cdf0e10cSrcweir uno::Sequence< ::com::sun::star::uno::Type>
getTypes(void)534cdf0e10cSrcweir 	AccessibleContextBase::getTypes (void)
535cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
536cdf0e10cSrcweir {
537cdf0e10cSrcweir     ThrowIfDisposed ();
538cdf0e10cSrcweir 
539cdf0e10cSrcweir     // This class supports no interfaces on its own.  Just return those
540cdf0e10cSrcweir     // supported by the base class.
541cdf0e10cSrcweir 	return BaseClass::getTypes();
542cdf0e10cSrcweir }
543cdf0e10cSrcweir 
544cdf0e10cSrcweir 
545cdf0e10cSrcweir 
546cdf0e10cSrcweir 
547cdf0e10cSrcweir uno::Sequence<sal_Int8> SAL_CALL
getImplementationId(void)548cdf0e10cSrcweir 	AccessibleContextBase::getImplementationId (void)
549cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
550cdf0e10cSrcweir {
551cdf0e10cSrcweir     ThrowIfDisposed ();
552cdf0e10cSrcweir 	static uno::Sequence<sal_Int8> aId;
553cdf0e10cSrcweir 	if (aId.getLength() == 0)
554cdf0e10cSrcweir 	{
555cdf0e10cSrcweir         ::osl::MutexGuard aGuard (maMutex);
556cdf0e10cSrcweir 		aId.realloc (16);
557cdf0e10cSrcweir 		rtl_createUuid ((sal_uInt8 *)aId.getArray(), 0, sal_True);
558cdf0e10cSrcweir 	}
559cdf0e10cSrcweir 	return aId;
560cdf0e10cSrcweir }
561cdf0e10cSrcweir 
562cdf0e10cSrcweir 
563cdf0e10cSrcweir 
564cdf0e10cSrcweir 
565cdf0e10cSrcweir //=====  internal  ============================================================
566cdf0e10cSrcweir 
disposing(void)567cdf0e10cSrcweir void SAL_CALL AccessibleContextBase::disposing (void)
568cdf0e10cSrcweir {
569cdf0e10cSrcweir     SetState (AccessibleStateType::DEFUNC);
570cdf0e10cSrcweir 
571cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
572cdf0e10cSrcweir 
573cdf0e10cSrcweir     // Send a disposing to all listeners.
574cdf0e10cSrcweir 	if ( mnClientId )
575cdf0e10cSrcweir 	{
576cdf0e10cSrcweir         comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
577cdf0e10cSrcweir 		mnClientId =  0;
578cdf0e10cSrcweir 	}
579cdf0e10cSrcweir }
580cdf0e10cSrcweir 
581cdf0e10cSrcweir 
582cdf0e10cSrcweir 
583cdf0e10cSrcweir 
SetAccessibleDescription(const::rtl::OUString & rDescription,StringOrigin eDescriptionOrigin)584cdf0e10cSrcweir void AccessibleContextBase::SetAccessibleDescription (
585cdf0e10cSrcweir     const ::rtl::OUString& rDescription,
586cdf0e10cSrcweir     StringOrigin eDescriptionOrigin)
587cdf0e10cSrcweir     throw (uno::RuntimeException)
588cdf0e10cSrcweir {
589cdf0e10cSrcweir     if (eDescriptionOrigin < meDescriptionOrigin
590cdf0e10cSrcweir         || (eDescriptionOrigin == meDescriptionOrigin && msDescription != rDescription))
591cdf0e10cSrcweir 	{
592cdf0e10cSrcweir 		uno::Any aOldValue, aNewValue;
593cdf0e10cSrcweir 		aOldValue <<= msDescription;
594cdf0e10cSrcweir 		aNewValue <<= rDescription;
595cdf0e10cSrcweir 
596cdf0e10cSrcweir 		msDescription = rDescription;
597cdf0e10cSrcweir         meDescriptionOrigin = eDescriptionOrigin;
598cdf0e10cSrcweir 
599cdf0e10cSrcweir         CommitChange(
600cdf0e10cSrcweir             AccessibleEventId::DESCRIPTION_CHANGED,
601cdf0e10cSrcweir             aNewValue,
602cdf0e10cSrcweir             aOldValue);
603cdf0e10cSrcweir 	}
604cdf0e10cSrcweir }
605cdf0e10cSrcweir 
606cdf0e10cSrcweir 
607cdf0e10cSrcweir 
608cdf0e10cSrcweir 
SetAccessibleName(const::rtl::OUString & rName,StringOrigin eNameOrigin)609cdf0e10cSrcweir void AccessibleContextBase::SetAccessibleName (
610cdf0e10cSrcweir     const ::rtl::OUString& rName,
611cdf0e10cSrcweir     StringOrigin eNameOrigin)
612cdf0e10cSrcweir     throw (uno::RuntimeException)
613cdf0e10cSrcweir {
614cdf0e10cSrcweir     if (eNameOrigin < meNameOrigin
615cdf0e10cSrcweir         || (eNameOrigin == meNameOrigin && msName != rName))
616cdf0e10cSrcweir 	{
617cdf0e10cSrcweir 		uno::Any aOldValue, aNewValue;
618cdf0e10cSrcweir 		aOldValue <<= msName;
619cdf0e10cSrcweir 		aNewValue <<= rName;
620cdf0e10cSrcweir 
621cdf0e10cSrcweir 		msName = rName;
622cdf0e10cSrcweir         meNameOrigin = eNameOrigin;
623cdf0e10cSrcweir 
624cdf0e10cSrcweir         CommitChange(
625cdf0e10cSrcweir             AccessibleEventId::NAME_CHANGED,
626cdf0e10cSrcweir             aNewValue,
627cdf0e10cSrcweir             aOldValue);
628cdf0e10cSrcweir 	}
629cdf0e10cSrcweir }
630cdf0e10cSrcweir 
631cdf0e10cSrcweir 
632cdf0e10cSrcweir 
633cdf0e10cSrcweir 
CreateAccessibleDescription(void)634cdf0e10cSrcweir ::rtl::OUString AccessibleContextBase::CreateAccessibleDescription (void)
635cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
636cdf0e10cSrcweir {
637cdf0e10cSrcweir     return ::rtl::OUString::createFromAscii ("Empty Description");
638cdf0e10cSrcweir }
639cdf0e10cSrcweir 
640cdf0e10cSrcweir 
641cdf0e10cSrcweir 
642cdf0e10cSrcweir 
CreateAccessibleName(void)643cdf0e10cSrcweir ::rtl::OUString AccessibleContextBase::CreateAccessibleName (void)
644cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
645cdf0e10cSrcweir {
646cdf0e10cSrcweir     return ::rtl::OUString::createFromAscii ("Empty Name");
647cdf0e10cSrcweir }
648cdf0e10cSrcweir 
649cdf0e10cSrcweir 
650cdf0e10cSrcweir 
651cdf0e10cSrcweir 
CommitChange(sal_Int16 nEventId,const uno::Any & rNewValue,const uno::Any & rOldValue)652cdf0e10cSrcweir void AccessibleContextBase::CommitChange (
653cdf0e10cSrcweir     sal_Int16 nEventId,
654cdf0e10cSrcweir     const uno::Any& rNewValue,
655cdf0e10cSrcweir     const uno::Any& rOldValue)
656cdf0e10cSrcweir {
657cdf0e10cSrcweir     // Do not call FireEvent and do not even create the event object when no
658cdf0e10cSrcweir     // listener has been registered yet.  Creating the event object can
659cdf0e10cSrcweir     // otherwise lead to a crash.  See issue 93419 for details.
660cdf0e10cSrcweir 	if (mnClientId != 0)
661cdf0e10cSrcweir     {
662cdf0e10cSrcweir         AccessibleEventObject aEvent (
663cdf0e10cSrcweir             static_cast<XAccessibleContext*>(this),
664cdf0e10cSrcweir             nEventId,
665cdf0e10cSrcweir             rNewValue,
666cdf0e10cSrcweir             rOldValue);
667cdf0e10cSrcweir 
668cdf0e10cSrcweir         FireEvent (aEvent);
669cdf0e10cSrcweir     }
670cdf0e10cSrcweir }
671cdf0e10cSrcweir 
672cdf0e10cSrcweir 
673cdf0e10cSrcweir 
674cdf0e10cSrcweir 
FireEvent(const AccessibleEventObject & aEvent)675cdf0e10cSrcweir void AccessibleContextBase::FireEvent (const AccessibleEventObject& aEvent)
676cdf0e10cSrcweir {
677cdf0e10cSrcweir 	if (mnClientId)
678cdf0e10cSrcweir 		comphelper::AccessibleEventNotifier::addEvent( mnClientId, aEvent );
679cdf0e10cSrcweir }
680cdf0e10cSrcweir 
681cdf0e10cSrcweir 
682cdf0e10cSrcweir 
683cdf0e10cSrcweir 
ThrowIfDisposed(void)684cdf0e10cSrcweir void AccessibleContextBase::ThrowIfDisposed (void)
685cdf0e10cSrcweir     throw (::com::sun::star::lang::DisposedException)
686cdf0e10cSrcweir {
687cdf0e10cSrcweir 	if (rBHelper.bDisposed || rBHelper.bInDispose)
688cdf0e10cSrcweir 	{
689cdf0e10cSrcweir         OSL_TRACE ("Calling disposed object. Throwing exception:");
690cdf0e10cSrcweir         throw lang::DisposedException (
691cdf0e10cSrcweir             OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")),
692cdf0e10cSrcweir             static_cast<uno::XWeak*>(this));
693cdf0e10cSrcweir     }
694cdf0e10cSrcweir }
695cdf0e10cSrcweir 
696cdf0e10cSrcweir 
697cdf0e10cSrcweir 
IsDisposed(void)698cdf0e10cSrcweir sal_Bool AccessibleContextBase::IsDisposed (void)
699cdf0e10cSrcweir {
700cdf0e10cSrcweir 	return (rBHelper.bDisposed || rBHelper.bInDispose);
701cdf0e10cSrcweir }
702cdf0e10cSrcweir 
703cdf0e10cSrcweir 
704cdf0e10cSrcweir 
SetAccessibleRole(sal_Int16 _nRole)705cdf0e10cSrcweir void AccessibleContextBase::SetAccessibleRole( sal_Int16 _nRole )
706cdf0e10cSrcweir {
707cdf0e10cSrcweir 	maRole = _nRole;
708cdf0e10cSrcweir }
709cdf0e10cSrcweir 
710cdf0e10cSrcweir 
711cdf0e10cSrcweir } // end of namespace accessibility
712