xref: /trunk/main/unotools/source/accessibility/accessiblerelationsethelper.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_unotools.hxx"
30 
31 
32 #include "unotools/accessiblerelationsethelper.hxx"
33 #include <rtl/uuid.h>
34 #include <vector>
35 #include <comphelper/sequence.hxx>
36 
37 using namespace ::utl;
38 using namespace ::rtl;
39 using namespace ::com::sun::star;
40 using namespace ::com::sun::star::accessibility;
41 
42 class AccessibleRelationSetHelperImpl
43 {
44 public:
45     AccessibleRelationSetHelperImpl();
46     AccessibleRelationSetHelperImpl(const AccessibleRelationSetHelperImpl& rImpl);
47     ~AccessibleRelationSetHelperImpl();
48 
49     sal_Int32 getRelationCount(  )
50         throw (uno::RuntimeException);
51     AccessibleRelation getRelation( sal_Int32 nIndex )
52             throw (lang::IndexOutOfBoundsException,
53                     uno::RuntimeException);
54     sal_Bool containsRelation( sal_Int16 aRelationType )
55         throw (uno::RuntimeException);
56     AccessibleRelation getRelationByType( sal_Int16 aRelationType )
57             throw (uno::RuntimeException);
58     void AddRelation(const AccessibleRelation& rRelation)
59             throw (uno::RuntimeException);
60 
61 private:
62     std::vector<AccessibleRelation> maRelations;
63 };
64 
65 AccessibleRelationSetHelperImpl::AccessibleRelationSetHelperImpl()
66 {
67 }
68 
69 AccessibleRelationSetHelperImpl::AccessibleRelationSetHelperImpl(const AccessibleRelationSetHelperImpl& rImpl)
70     : maRelations(rImpl.maRelations)
71 {
72 }
73 
74 AccessibleRelationSetHelperImpl::~AccessibleRelationSetHelperImpl()
75 {
76 }
77 
78 sal_Int32 AccessibleRelationSetHelperImpl::getRelationCount(  )
79     throw (uno::RuntimeException)
80 {
81     return maRelations.size();
82 }
83 
84 AccessibleRelation AccessibleRelationSetHelperImpl::getRelation( sal_Int32 nIndex )
85     throw (lang::IndexOutOfBoundsException,
86             uno::RuntimeException)
87 {
88     if ((nIndex < 0) || (static_cast<sal_uInt32>(nIndex) >= maRelations.size()))
89         throw lang::IndexOutOfBoundsException();
90     return maRelations[nIndex];
91 }
92 
93 sal_Bool AccessibleRelationSetHelperImpl::containsRelation( sal_Int16 aRelationType )
94     throw (uno::RuntimeException)
95 {
96     AccessibleRelation defaultRelation; // default is INVALID
97     AccessibleRelation relationByType = getRelationByType(aRelationType);
98     return relationByType.RelationType != defaultRelation.RelationType;
99 }
100 
101 AccessibleRelation AccessibleRelationSetHelperImpl::getRelationByType( sal_Int16 aRelationType )
102     throw (uno::RuntimeException)
103 {
104     sal_Int32 nCount(getRelationCount());
105     sal_Int32 i(0);
106     sal_Bool bFound(sal_False);
107     while ((i < nCount) && !bFound)
108     {
109         if (maRelations[i].RelationType == aRelationType)
110             return maRelations[i];
111         else
112             i++;
113     }
114     return AccessibleRelation();
115 }
116 
117 void AccessibleRelationSetHelperImpl::AddRelation(const AccessibleRelation& rRelation)
118     throw (uno::RuntimeException)
119 {
120     sal_Int32 nCount(getRelationCount());
121     sal_Int32 i(0);
122     sal_Bool bFound(sal_False);
123     while ((i < nCount) && !bFound)
124     {
125         if (maRelations[i].RelationType == rRelation.RelationType)
126             bFound = sal_True;
127         else
128             i++;
129     }
130     if (bFound)
131         maRelations[i].TargetSet = comphelper::concatSequences(maRelations[i].TargetSet, rRelation.TargetSet);
132     else
133         maRelations.push_back(rRelation);
134 }
135 
136 //=====  internal  ============================================================
137 
138 AccessibleRelationSetHelper::AccessibleRelationSetHelper ()
139     : mpHelperImpl(NULL)
140 {
141     mpHelperImpl = new AccessibleRelationSetHelperImpl();
142 }
143 
144 AccessibleRelationSetHelper::AccessibleRelationSetHelper (const AccessibleRelationSetHelper& rHelper)
145     : cppu::WeakImplHelper1<XAccessibleRelationSet>()
146     , mpHelperImpl(NULL)
147 {
148     if (rHelper.mpHelperImpl)
149         mpHelperImpl = new AccessibleRelationSetHelperImpl(*rHelper.mpHelperImpl);
150     else
151         mpHelperImpl = new AccessibleRelationSetHelperImpl();
152 }
153 
154 AccessibleRelationSetHelper::~AccessibleRelationSetHelper(void)
155 {
156     delete mpHelperImpl;
157 }
158 
159 //=====  XAccessibleRelationSet  ==============================================
160 
161     /** Returns the number of relations in this relation set.
162 
163         @return
164             Returns the number of relations or zero if there are none.
165     */
166 sal_Int32 SAL_CALL
167     AccessibleRelationSetHelper::getRelationCount(  )
168         throw (uno::RuntimeException)
169 {
170     ::vos::OGuard aGuard (maMutex);
171     return mpHelperImpl->getRelationCount();
172 }
173 
174     /** Returns the relation of this relation set that is specified by
175         the given index.
176 
177         @param nIndex
178             This index specifies the relatio to return.
179 
180         @return
181             For a valid index, i.e. inside the range 0 to the number of
182             relations minus one, the returned value is the requested
183             relation.  If the index is invalid then the returned relation
184             has the type INVALID.
185 
186     */
187  AccessibleRelation SAL_CALL
188         AccessibleRelationSetHelper::getRelation( sal_Int32 nIndex )
189             throw (lang::IndexOutOfBoundsException,
190                     uno::RuntimeException)
191 {
192     ::vos::OGuard aGuard (maMutex);
193     return mpHelperImpl->getRelation(nIndex);
194 }
195 
196     /** Tests whether the relation set contains a relation matching the
197         specified key.
198 
199         @param aRelationType
200             The type of relation to look for in this set of relations.  This
201             has to be one of the constants of
202             <type>AccessibleRelationType</type>.
203 
204         @return
205             Returns <TRUE/> if there is a (at least one) relation of the
206             given type and <FALSE/> if there is no such relation in the set.
207     */
208 sal_Bool SAL_CALL
209     AccessibleRelationSetHelper::containsRelation( sal_Int16 aRelationType )
210         throw (uno::RuntimeException)
211 {
212     ::vos::OGuard aGuard (maMutex);
213     return mpHelperImpl->containsRelation(aRelationType);
214 }
215 
216     /** Retrieve and return the relation with the given relation type.
217 
218         @param aRelationType
219             The type of the relation to return.  This has to be one of the
220             constants of <type>AccessibleRelationType</type>.
221 
222         @return
223             If a relation with the given type could be found than (a copy
224             of) this relation is returned.  Otherwise a relation with the
225             type INVALID is returned.
226     */
227 AccessibleRelation SAL_CALL
228         AccessibleRelationSetHelper::getRelationByType( sal_Int16 aRelationType )
229             throw (uno::RuntimeException)
230 {
231     ::vos::OGuard aGuard (maMutex);
232     return mpHelperImpl->getRelationByType(aRelationType);
233 }
234 
235 void AccessibleRelationSetHelper::AddRelation(const AccessibleRelation& rRelation)
236             throw (uno::RuntimeException)
237 {
238     ::vos::OGuard aGuard (maMutex);
239     mpHelperImpl->AddRelation(rRelation);
240 }
241 
242 //=====  XTypeProvider  =======================================================
243 
244 uno::Sequence< ::com::sun::star::uno::Type>
245     AccessibleRelationSetHelper::getTypes (void)
246     throw (::com::sun::star::uno::RuntimeException)
247 {
248     ::vos::OGuard aGuard (maMutex);
249     const ::com::sun::star::uno::Type aTypeList[] = {
250         ::getCppuType((const uno::Reference<
251             XAccessibleRelationSet>*)0),
252         ::getCppuType((const uno::Reference<
253             lang::XTypeProvider>*)0)
254         };
255     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>
256         aTypeSequence (aTypeList, 2);
257     return aTypeSequence;
258 }
259 
260 uno::Sequence<sal_Int8> SAL_CALL
261     AccessibleRelationSetHelper::getImplementationId (void)
262     throw (::com::sun::star::uno::RuntimeException)
263 {
264     ::vos::OGuard aGuard (maMutex);
265     static uno::Sequence<sal_Int8> aId;
266     if (aId.getLength() == 0)
267     {
268         aId.realloc (16);
269         rtl_createUuid ((sal_uInt8 *)aId.getArray(), 0, sal_True);
270     }
271     return aId;
272 }
273