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