1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include <unotools/accessiblestatesethelper.hxx>
21 #include <tools/debug.hxx>
22
23 // defines how many states the bitfield can contain
24 // it has the size of 64 because I use a uInt64
25 #define BITFIELDSIZE 64
26
27 using namespace ::utl;
28 using namespace ::com::sun::star;
29 using namespace ::com::sun::star::accessibility;
30
31 class AccessibleStateSetHelperImpl
32 {
33 public:
34 AccessibleStateSetHelperImpl();
35 AccessibleStateSetHelperImpl(const AccessibleStateSetHelperImpl& rImpl);
36
37 /// @throws uno::RuntimeException
38 bool IsEmpty () const;
39 /// @throws uno::RuntimeException
40 bool Contains (sal_Int16 aState) const;
41 /// @throws uno::RuntimeException
42 uno::Sequence<sal_Int16> GetStates() const;
43 /// @throws uno::RuntimeException
44 void AddState(sal_Int16 aState);
45 /// @throws uno::RuntimeException
46 void RemoveState(sal_Int16 aState);
47
48 inline void AddStates( const sal_Int64 _nStates );
49
50 private:
51 sal_uInt64 maStates;
52 };
53
AccessibleStateSetHelperImpl()54 AccessibleStateSetHelperImpl::AccessibleStateSetHelperImpl()
55 : maStates(0)
56 {
57 }
58
AccessibleStateSetHelperImpl(const AccessibleStateSetHelperImpl & rImpl)59 AccessibleStateSetHelperImpl::AccessibleStateSetHelperImpl(const AccessibleStateSetHelperImpl& rImpl)
60 : maStates(rImpl.maStates)
61 {
62 }
63
IsEmpty() const64 inline bool AccessibleStateSetHelperImpl::IsEmpty () const
65 {
66 return maStates == 0;
67 }
68
Contains(sal_Int16 aState) const69 inline bool AccessibleStateSetHelperImpl::Contains (sal_Int16 aState) const
70 {
71 DBG_ASSERT(aState < BITFIELDSIZE, "the statesset is too small");
72 sal_uInt64 aTempBitSet(1);
73 aTempBitSet <<= aState;
74 return ((aTempBitSet & maStates) != 0);
75 }
76
GetStates() const77 inline uno::Sequence<sal_Int16> AccessibleStateSetHelperImpl::GetStates() const
78 {
79 uno::Sequence<sal_Int16> aRet(BITFIELDSIZE);
80 sal_Int16* pSeq = aRet.getArray();
81 sal_Int16 nStateCount(0);
82 for (sal_Int16 i = 0; i < BITFIELDSIZE; ++i)
83 if (Contains(i))
84 {
85 *pSeq = i;
86 ++pSeq;
87 ++nStateCount;
88 }
89 aRet.realloc(nStateCount);
90 return aRet;
91 }
92
AddStates(const sal_Int64 _nStates)93 inline void AccessibleStateSetHelperImpl::AddStates( const sal_Int64 _nStates )
94 {
95 maStates |= _nStates;
96 }
97
AddState(sal_Int16 aState)98 inline void AccessibleStateSetHelperImpl::AddState(sal_Int16 aState)
99 {
100 DBG_ASSERT(aState < BITFIELDSIZE, "the statesset is too small");
101 sal_uInt64 aTempBitSet(1);
102 aTempBitSet <<= aState;
103 maStates |= aTempBitSet;
104 }
105
RemoveState(sal_Int16 aState)106 inline void AccessibleStateSetHelperImpl::RemoveState(sal_Int16 aState)
107 {
108 DBG_ASSERT(aState < BITFIELDSIZE, "the statesset is too small");
109 sal_uInt64 aTempBitSet(1);
110 aTempBitSet <<= aState;
111 aTempBitSet = ~aTempBitSet;
112 maStates &= aTempBitSet;
113 }
114
115 //===== internal ============================================================
116
AccessibleStateSetHelper()117 AccessibleStateSetHelper::AccessibleStateSetHelper ()
118 : mpHelperImpl(new AccessibleStateSetHelperImpl)
119 {
120 }
121
AccessibleStateSetHelper(const sal_Int64 _nInitialStates)122 AccessibleStateSetHelper::AccessibleStateSetHelper ( const sal_Int64 _nInitialStates )
123 : mpHelperImpl(new AccessibleStateSetHelperImpl)
124 {
125 mpHelperImpl->AddStates( _nInitialStates );
126 }
127
AccessibleStateSetHelper(const AccessibleStateSetHelper & rHelper)128 AccessibleStateSetHelper::AccessibleStateSetHelper (const AccessibleStateSetHelper& rHelper)
129 : cppu::WeakImplHelper<XAccessibleStateSet>(rHelper)
130 {
131 if (rHelper.mpHelperImpl)
132 mpHelperImpl.reset(new AccessibleStateSetHelperImpl(*rHelper.mpHelperImpl));
133 else
134 mpHelperImpl.reset(new AccessibleStateSetHelperImpl());
135 }
136
~AccessibleStateSetHelper()137 AccessibleStateSetHelper::~AccessibleStateSetHelper()
138 {
139 }
140
141 //===== XAccessibleStateSet ==============================================
142
143 /** Checks whether the current state set is empty.
144
145 @return
146 Returns <TRUE/> if there is no state in this state set and
147 <FALSE/> if there is at least one state set in it.
148 */
isEmpty()149 sal_Bool SAL_CALL AccessibleStateSetHelper::isEmpty ()
150 {
151 osl::MutexGuard aGuard (maMutex);
152 return mpHelperImpl->IsEmpty();
153 }
154
155 /** Checks if the given state is a member of the state set of this
156 object.
157
158 @param aState
159 The state for which to check membership. This has to be one of
160 the constants of <type>AccessibleStateType</type>.
161
162 @return
163 Returns <TRUE/> if the given state is a member of this object's
164 state set and <FALSE/> otherwise.
165 */
contains(sal_Int16 aState)166 sal_Bool SAL_CALL AccessibleStateSetHelper::contains (sal_Int16 aState)
167 {
168 osl::MutexGuard aGuard (maMutex);
169 return mpHelperImpl->Contains(aState);
170 }
171
172 /** Checks if all of the given states are in this object's state
173 set.
174
175 @param aStateSet
176 This sequence of states is interpreted as set and every of its
177 members, duplicates are ignored, is checked for membership in
178 this object's state set. Each state has to be one of the
179 constants of <type>AccessibleStateType</type>.
180
181 @return
182 Returns <TRUE/> if all states of the given state set are members
183 of this object's state set. <FALSE/> is returned if at least
184 one of the states in the given state is not a member of this
185 object's state set.
186 */
containsAll(const uno::Sequence<sal_Int16> & rStateSet)187 sal_Bool SAL_CALL AccessibleStateSetHelper::containsAll
188 (const uno::Sequence<sal_Int16>& rStateSet)
189 {
190 osl::MutexGuard aGuard (maMutex);
191 return std::all_of(rStateSet.begin(), rStateSet.end(),
192 [this](const sal_Int16 nState) { return mpHelperImpl->Contains(nState); });
193 }
194
getStates()195 uno::Sequence<sal_Int16> SAL_CALL AccessibleStateSetHelper::getStates()
196 {
197 osl::MutexGuard aGuard(maMutex);
198 return mpHelperImpl->GetStates();
199 }
200
AddState(sal_Int16 aState)201 void AccessibleStateSetHelper::AddState(sal_Int16 aState)
202 {
203 osl::MutexGuard aGuard (maMutex);
204 mpHelperImpl->AddState(aState);
205 }
206
RemoveState(sal_Int16 aState)207 void AccessibleStateSetHelper::RemoveState(sal_Int16 aState)
208 {
209 osl::MutexGuard aGuard (maMutex);
210 mpHelperImpl->RemoveState(aState);
211 }
212
213 //===== XTypeProvider =======================================================
214
getTypes()215 uno::Sequence< css::uno::Type> AccessibleStateSetHelper::getTypes()
216 {
217 css::uno::Sequence< css::uno::Type> aTypeSequence {
218 cppu::UnoType<XAccessibleStateSet>::get(),
219 cppu::UnoType<lang::XTypeProvider>::get()
220 };
221 return aTypeSequence;
222 }
223
getImplementationId()224 uno::Sequence<sal_Int8> SAL_CALL AccessibleStateSetHelper::getImplementationId()
225 {
226 return css::uno::Sequence<sal_Int8>();
227 }
228
229 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
230