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 
28 /////////////////////////////////////////////////////////////////////////////
29 // CEnumVariant
30 
31 
32 
33 /**
34    * enumarate method,get next element
35    * @param  cElements The number of elements to be returned.
36    * @param  pvar      An array of at least size celt in which the elements are to be returned.
37    * @param  pcElementFetched Pointer to the number of elements returned in rgVar, or Null��
38    * @return Result.
39    */
40 HRESULT STDMETHODCALLTYPE CEnumVariant::Next(ULONG cElements,VARIANT __RPC_FAR *pvar,ULONG __RPC_FAR *pcElementFetched)
41 {
42     long l1;
43     ULONG l2;
44 
45     if (pvar == NULL)
46         return E_INVALIDARG;
47 
48 	CHECK_ENABLE_INF
49     if (pcElementFetched != NULL)
50         *pcElementFetched = 0;
51 
52     // Retrieve the next cElements.
53     for (l1=m_lCurrent, l2=0; l1<m_pXAccessibleSelection->getSelectedAccessibleChildCount() &&
54             l2<cElements; l1++, l2++)
55     {
56         Reference< XAccessible > pRXAcc = m_pXAccessibleSelection->getSelectedAccessibleChild(l1);
57         IAccessible* pChild = NULL;
58         BOOL isGet = CMAccessible::get_IAccessibleFromXAccessible((long)pRXAcc.get(),&pChild);
59         if(isGet)
60         {
61             pvar[l2].vt = VT_I4;
62             ((IMAccessible*)pChild)->Get_XAccChildID(&pvar[l2].lVal);
63         }
64         else if(pRXAcc.is())
65         {
66             if(CMAccessible::g_pAgent)
67                 CMAccessible::g_pAgent->InsertAccObj(pRXAcc.get(),pUNOInterface,NULL);
68             BOOL isGet = CMAccessible::get_IAccessibleFromXAccessible((long)pRXAcc.get(),&pChild);
69             if(isGet)
70             {
71                 pvar[l2].vt = VT_I4;
72                 ((IMAccessible*)pChild)->Get_XAccChildID(&pvar[l2].lVal);
73             }
74         }
75     }
76     // Set count of elements retrieved.
77     if (pcElementFetched != NULL)
78         *pcElementFetched = l2;
79     m_lCurrent = l1;
80 
81     return (l2 < cElements) ? S_FALSE : NOERROR;
82 }
83 
84 /**
85    * skip the elements in the given range when enumarate elements
86    * @param  cElements The number of elements to skip.
87    * @return Result.
88    */
89 HRESULT STDMETHODCALLTYPE CEnumVariant::Skip(ULONG cElements)
90 {
91 	CHECK_ENABLE_INF
92     m_lCurrent += cElements;
93     if (m_lCurrent > (long)(m_lLBound+m_pXAccessibleSelection->getSelectedAccessibleChildCount()))
94     {
95         m_lCurrent =  m_lLBound+m_pXAccessibleSelection->getSelectedAccessibleChildCount();
96         return E_FAIL;
97     }
98     else
99         return NOERROR;
100 }
101 
102 
103 /**
104    * reset the enumaration position to initial value
105    * @param
106    * @return Result.
107    */
108 HRESULT STDMETHODCALLTYPE CEnumVariant::Reset( void)
109 {
110     m_lCurrent = m_lLBound;
111     return NOERROR;
112 }
113 
114 
115 /**
116    *create a new IEnumVariant object,
117    *copy current enumaration container and its state to
118    *the new object
119    *AT will use the copy object to get elements
120    * @param ppenum On return, pointer to the location of the clone enumerator��
121    * @return Result.
122    */
123 HRESULT STDMETHODCALLTYPE CEnumVariant::Clone(IEnumVARIANT __RPC_FAR *__RPC_FAR *ppenum)
124 {
125     CEnumVariant * penum = NULL;
126     HRESULT hr;
127     if (ppenum == NULL)
128         return E_INVALIDARG;
129 
130     *ppenum = NULL;
131 
132     hr = Create(&penum);
133     if( hr == S_OK )
134     {
135         penum->PutSelection((long)pUNOInterface);
136         *ppenum = penum;
137     }
138     else
139     {
140         if (penum)
141             penum->Release();
142     }
143     return hr;
144 }
145 
146 /**
147    *Static public method to create a CLSID_EnumVariant com object.
148    * @param ppenum Pointer to accept com object.
149    * @return Result.
150    */
151 HRESULT STDMETHODCALLTYPE CEnumVariant::Create(CEnumVariant __RPC_FAR *__RPC_FAR *ppenum)
152 {
153 	HRESULT hr = CoCreateInstance(CLSID_EnumVariant,NULL,
154                                  CLSCTX_SERVER,IID_IEnumVariant,(void **)ppenum);
155 	if (S_OK != hr)
156     {
157         return E_FAIL;
158     }
159 
160     return S_OK;
161 }
162 
163 /**
164    *Return count of elements in current container
165    * @param.
166    * @return count of elements in current container.
167    */
168 long CEnumVariant::GetCountOfElements()
169 {
170 	CHECK_ENABLE_INF_ZERO
171 
172     if(m_pXAccessibleSelection.is())
173         return m_pXAccessibleSelection->getSelectedAccessibleChildCount();
174     return 0;
175 }
176 
177 /**
178    * Set memeber m_pXAccessibleSelection to NULL and m_lCurrent to m_lLBound.
179    * @param.
180    * @return Result
181    */
182 STDMETHODIMP CEnumVariant::ClearEnumeration()
183 {
184     pUNOInterface = NULL;
185     m_pXAccessibleSelection = NULL;
186     m_lCurrent = m_lLBound;
187     return S_OK;
188 }
189 
190 /**
191    *Static method to fetch XAccessibleSelection
192    * @param pXAcc XAccessible interface.
193    * @return XAccessibleSelection interface.
194    */
195 static Reference<XAccessibleSelection> GetXAccessibleSelection(XAccessible* pXAcc)
196 {
197     XAccessibleSelection* pSelection = NULL;
198     Reference< XAccessibleContext > pRContext;
199 
200     if( pXAcc == NULL)
201         return NULL;
202 
203     pRContext = pXAcc->getAccessibleContext();
204     if( !pRContext.is() )
205         return NULL;
206 
207     Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY);
208     if( !pRSelection.is() )
209         return NULL;
210 
211     return pRSelection;
212 }
213 
214 /**
215    * Put valid UNO XAccessible interface.
216    * @param pXSelection XAccessible interface.
217    * @return Result..
218    */
219 STDMETHODIMP CEnumVariant::PutSelection(long pXSelection)
220 {
221     pUNOInterface = (XAccessible*)pXSelection;
222     m_pXAccessibleSelection = GetXAccessibleSelection(pUNOInterface);
223     return S_OK;
224 }
225