1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #include "stdafx.h"
23 #include "UAccCOM2.h"
24 #include "EnumVariant.h"
25 #include "MAccessible.h"
26 
27 #include "act.hxx"
28 
29 /////////////////////////////////////////////////////////////////////////////
30 // CEnumVariant
31 
32 
33 
34 /**
35    * enumarate method,get next element
36    * @param  cElements The number of elements to be returned.
37    * @param  pvar      An array of at least size celt in which the elements are to be returned.
38    * @param  pcElementFetched Pointer to the number of elements returned in rgVar, or Null��
39    * @return Result.
40    */
Next(ULONG cElements,VARIANT __RPC_FAR * pvar,ULONG __RPC_FAR * pcElementFetched)41 HRESULT STDMETHODCALLTYPE CEnumVariant::Next(ULONG cElements,VARIANT __RPC_FAR *pvar,ULONG __RPC_FAR *pcElementFetched)
42 {
43     long l1;
44     ULONG l2;
45 
46     if (pvar == NULL)
47         return E_INVALIDARG;
48 
49 	CHECK_ENABLE_INF
50     if (pcElementFetched != NULL)
51         *pcElementFetched = 0;
52 
53     // Retrieve the next cElements.
54     for (l1=m_lCurrent, l2=0; l1<m_pXAccessibleSelection->getSelectedAccessibleChildCount() &&
55             l2<cElements; l1++, l2++)
56     {
57         Reference< XAccessible > pRXAcc = m_pXAccessibleSelection->getSelectedAccessibleChild(l1);
58         IAccessible* pChild = NULL;
59         BOOL isGet = CMAccessible::get_IAccessibleFromXAccessible((long)pRXAcc.get(),&pChild);
60         if(isGet)
61         {
62             pvar[l2].vt = VT_I4;
63             ((IMAccessible*)pChild)->Get_XAccChildID(&pvar[l2].lVal);
64         }
65         else if(pRXAcc.is())
66         {
67             if(CMAccessible::g_pAgent)
68                 CMAccessible::g_pAgent->InsertAccObj(pRXAcc.get(),pUNOInterface,NULL);
69             BOOL isGet = CMAccessible::get_IAccessibleFromXAccessible((long)pRXAcc.get(),&pChild);
70             if(isGet)
71             {
72                 pvar[l2].vt = VT_I4;
73                 ((IMAccessible*)pChild)->Get_XAccChildID(&pvar[l2].lVal);
74             }
75         }
76     }
77     // Set count of elements retrieved.
78     if (pcElementFetched != NULL)
79         *pcElementFetched = l2;
80     m_lCurrent = l1;
81 
82     return (l2 < cElements) ? S_FALSE : NOERROR;
83 }
84 
85 /**
86    * skip the elements in the given range when enumarate elements
87    * @param  cElements The number of elements to skip.
88    * @return Result.
89    */
Skip(ULONG cElements)90 HRESULT STDMETHODCALLTYPE CEnumVariant::Skip(ULONG cElements)
91 {
92 	CHECK_ENABLE_INF
93     m_lCurrent += cElements;
94     if (m_lCurrent > (long)(m_lLBound+m_pXAccessibleSelection->getSelectedAccessibleChildCount()))
95     {
96         m_lCurrent =  m_lLBound+m_pXAccessibleSelection->getSelectedAccessibleChildCount();
97         return E_FAIL;
98     }
99     else
100         return NOERROR;
101 }
102 
103 
104 /**
105    * reset the enumaration position to initial value
106    * @param
107    * @return Result.
108    */
Reset(void)109 HRESULT STDMETHODCALLTYPE CEnumVariant::Reset( void)
110 {
111     m_lCurrent = m_lLBound;
112     return NOERROR;
113 }
114 
115 
116 /**
117    *create a new IEnumVariant object,
118    *copy current enumaration container and its state to
119    *the new object
120    *AT will use the copy object to get elements
121    * @param ppenum On return, pointer to the location of the clone enumerator��
122    * @return Result.
123    */
Clone(IEnumVARIANT __RPC_FAR * __RPC_FAR * ppenum)124 HRESULT STDMETHODCALLTYPE CEnumVariant::Clone(IEnumVARIANT __RPC_FAR *__RPC_FAR *ppenum)
125 {
126     CEnumVariant * penum = NULL;
127     HRESULT hr;
128     if (ppenum == NULL)
129         return E_INVALIDARG;
130 
131     *ppenum = NULL;
132 
133     hr = Create(&penum);
134     if( hr == S_OK )
135     {
136         penum->PutSelection((long)pUNOInterface);
137         *ppenum = penum;
138     }
139     else
140     {
141         if (penum)
142             penum->Release();
143     }
144     return hr;
145 }
146 
147 /**
148    *Static public method to create a CLSID_EnumVariant com object.
149    * @param ppenum Pointer to accept com object.
150    * @return Result.
151    */
Create(CEnumVariant __RPC_FAR * __RPC_FAR * ppenum)152 HRESULT STDMETHODCALLTYPE CEnumVariant::Create(CEnumVariant __RPC_FAR *__RPC_FAR *ppenum)
153 {
154 	ActivateActContext();
155 	HRESULT hr = CoCreateInstance(CLSID_EnumVariant,NULL,
156                                  CLSCTX_SERVER,IID_IEnumVariant,(void **)ppenum);
157 	DeactivateActContext();
158 	if (S_OK != hr)
159     {
160         return E_FAIL;
161     }
162 
163     return S_OK;
164 }
165 
166 /**
167    *Return count of elements in current container
168    * @param.
169    * @return count of elements in current container.
170    */
GetCountOfElements()171 long CEnumVariant::GetCountOfElements()
172 {
173 	CHECK_ENABLE_INF_ZERO
174 
175     if(m_pXAccessibleSelection.is())
176         return m_pXAccessibleSelection->getSelectedAccessibleChildCount();
177     return 0;
178 }
179 
180 /**
181    * Set member m_pXAccessibleSelection to NULL and m_lCurrent to m_lLBound.
182    * @param.
183    * @return Result
184    */
ClearEnumeration()185 STDMETHODIMP CEnumVariant::ClearEnumeration()
186 {
187     pUNOInterface = NULL;
188     m_pXAccessibleSelection = NULL;
189     m_lCurrent = m_lLBound;
190     return S_OK;
191 }
192 
193 /**
194    *Static method to fetch XAccessibleSelection
195    * @param pXAcc XAccessible interface.
196    * @return XAccessibleSelection interface.
197    */
GetXAccessibleSelection(XAccessible * pXAcc)198 static Reference<XAccessibleSelection> GetXAccessibleSelection(XAccessible* pXAcc)
199 {
200     XAccessibleSelection* pSelection = NULL;
201     Reference< XAccessibleContext > pRContext;
202 
203     if( pXAcc == NULL)
204         return NULL;
205 
206     pRContext = pXAcc->getAccessibleContext();
207     if( !pRContext.is() )
208         return NULL;
209 
210     Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY);
211     if( !pRSelection.is() )
212         return NULL;
213 
214     return pRSelection;
215 }
216 
217 /**
218    * Put valid UNO XAccessible interface.
219    * @param pXSelection XAccessible interface.
220    * @return Result..
221    */
PutSelection(long pXSelection)222 STDMETHODIMP CEnumVariant::PutSelection(long pXSelection)
223 {
224     pUNOInterface = (XAccessible*)pXSelection;
225     m_pXAccessibleSelection = GetXAccessibleSelection(pUNOInterface);
226     return S_OK;
227 }
228