1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright IBM Corporation 2010.
6  * Copyright 2000, 2010 Oracle and/or its affiliates.
7  *
8  * OpenOffice.org - a multi-platform office productivity suite
9  *
10  * This file is part of OpenOffice.org.
11  *
12  * OpenOffice.org is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Lesser General Public License version 3
14  * only, as published by the Free Software Foundation.
15  *
16  * OpenOffice.org is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU Lesser General Public License version 3 for more details
20  * (a copy is included in the LICENSE file that accompanied this code).
21  *
22  * You should have received a copy of the GNU Lesser General Public License
23  * version 3 along with OpenOffice.org.  If not, see
24  * <http://www.openoffice.org/license.html>
25  * for a copy of the LGPLv3 License.
26  *
27  ************************************************************************/
28 
29 #include "stdafx.h"
30 #include "UAccCOM2.h"
31 #include "EnumVariant.h"
32 #include "MAccessible.h"
33 /////////////////////////////////////////////////////////////////////////////
34 // CEnumVariant
35 
36 
37 
38 /**
39    * enumarate method,get next element
40    * @param  cElements The number of elements to be returned.
41    * @param  pvar      An array of at least size celt in which the elements are to be returned.
42    * @param  pcElementFetched Pointer to the number of elements returned in rgVar, or Null��
43    * @return Result.
44    */
45 HRESULT STDMETHODCALLTYPE CEnumVariant::Next(ULONG cElements,VARIANT __RPC_FAR *pvar,ULONG __RPC_FAR *pcElementFetched)
46 {
47     long l1;
48     ULONG l2;
49 
50     if (pvar == NULL)
51         return E_INVALIDARG;
52 
53 	CHECK_ENABLE_INF
54     if (pcElementFetched != NULL)
55         *pcElementFetched = 0;
56 
57     // Retrieve the next cElements.
58     for (l1=m_lCurrent, l2=0; l1<m_pXAccessibleSelection->getSelectedAccessibleChildCount() &&
59             l2<cElements; l1++, l2++)
60     {
61         Reference< XAccessible > pRXAcc = m_pXAccessibleSelection->getSelectedAccessibleChild(l1);
62         IAccessible* pChild = NULL;
63         BOOL isGet = CMAccessible::get_IAccessibleFromXAccessible((long)pRXAcc.get(),&pChild);
64         if(isGet)
65         {
66             pvar[l2].vt = VT_I4;
67             ((IMAccessible*)pChild)->Get_XAccChildID(&pvar[l2].lVal);
68         }
69         else if(pRXAcc.is())
70         {
71             if(CMAccessible::g_pAgent)
72                 CMAccessible::g_pAgent->InsertAccObj(pRXAcc.get(),pUNOInterface,NULL);
73             BOOL isGet = CMAccessible::get_IAccessibleFromXAccessible((long)pRXAcc.get(),&pChild);
74             if(isGet)
75             {
76                 pvar[l2].vt = VT_I4;
77                 ((IMAccessible*)pChild)->Get_XAccChildID(&pvar[l2].lVal);
78             }
79         }
80     }
81     // Set count of elements retrieved.
82     if (pcElementFetched != NULL)
83         *pcElementFetched = l2;
84     m_lCurrent = l1;
85 
86     return (l2 < cElements) ? S_FALSE : NOERROR;
87 }
88 
89 /**
90    * skip the elements in the given range when enumarate elements
91    * @param  cElements The number of elements to skip.
92    * @return Result.
93    */
94 HRESULT STDMETHODCALLTYPE CEnumVariant::Skip(ULONG cElements)
95 {
96 	CHECK_ENABLE_INF
97     m_lCurrent += cElements;
98     if (m_lCurrent > (long)(m_lLBound+m_pXAccessibleSelection->getSelectedAccessibleChildCount()))
99     {
100         m_lCurrent =  m_lLBound+m_pXAccessibleSelection->getSelectedAccessibleChildCount();
101         return E_FAIL;
102     }
103     else
104         return NOERROR;
105 }
106 
107 
108 /**
109    * reset the enumaration position to initial value
110    * @param
111    * @return Result.
112    */
113 HRESULT STDMETHODCALLTYPE CEnumVariant::Reset( void)
114 {
115     m_lCurrent = m_lLBound;
116     return NOERROR;
117 }
118 
119 
120 /**
121    *create a new IEnumVariant object,
122    *copy current enumaration container and its state to
123    *the new object
124    *AT will use the copy object to get elements
125    * @param ppenum On return, pointer to the location of the clone enumerator��
126    * @return Result.
127    */
128 HRESULT STDMETHODCALLTYPE CEnumVariant::Clone(IEnumVARIANT __RPC_FAR *__RPC_FAR *ppenum)
129 {
130     CEnumVariant * penum = NULL;
131     HRESULT hr;
132     if (ppenum == NULL)
133         return E_INVALIDARG;
134 
135     *ppenum = NULL;
136 
137     hr = Create(&penum);
138     if( hr == S_OK )
139     {
140         penum->PutSelection((long)pUNOInterface);
141         *ppenum = penum;
142     }
143     else
144     {
145         if (penum)
146             penum->Release();
147     }
148     return hr;
149 }
150 
151 /**
152    *Static public method to create a CLSID_EnumVariant com object.
153    * @param ppenum Pointer to accept com object.
154    * @return Result.
155    */
156 HRESULT STDMETHODCALLTYPE CEnumVariant::Create(CEnumVariant __RPC_FAR *__RPC_FAR *ppenum)
157 {
158     if (S_OK != CoCreateInstance(CLSID_EnumVariant,NULL,
159                                  CLSCTX_SERVER,IID_IEnumVariant,(void **)ppenum))
160     {
161         return E_FAIL;
162     }
163 
164     return S_OK;
165 }
166 
167 /**
168    *Return count of elements in current container
169    * @param.
170    * @return count of elements in current container.
171    */
172 long CEnumVariant::GetCountOfElements()
173 {
174 	CHECK_ENABLE_INF_ZERO
175 
176     if(m_pXAccessibleSelection.is())
177         return m_pXAccessibleSelection->getSelectedAccessibleChildCount();
178     return 0;
179 }
180 
181 /**
182    * Set memeber m_pXAccessibleSelection to NULL and m_lCurrent to m_lLBound.
183    * @param.
184    * @return Result
185    */
186 STDMETHODIMP CEnumVariant::ClearEnumeration()
187 {
188     pUNOInterface = NULL;
189     m_pXAccessibleSelection = NULL;
190     m_lCurrent = m_lLBound;
191     return S_OK;
192 }
193 
194 /**
195    *Static method to fetch XAccessibleSelection
196    * @param pXAcc XAccessible interface.
197    * @return XAccessibleSelection interface.
198    */
199 static Reference<XAccessibleSelection> GetXAccessibleSelection(XAccessible* pXAcc)
200 {
201     XAccessibleSelection* pSelection = NULL;
202     Reference< XAccessibleContext > pRContext;
203 
204     if( pXAcc == NULL)
205         return NULL;
206 
207     pRContext = pXAcc->getAccessibleContext();
208     if( !pRContext.is() )
209         return NULL;
210 
211     Reference< XAccessibleSelection > pRSelection(pRContext,UNO_QUERY);
212     if( !pRSelection.is() )
213         return NULL;
214 
215     return pRSelection;
216 }
217 
218 /**
219    * Put valid UNO XAccessible interface.
220    * @param pXSelection XAccessible interface.
221    * @return Result..
222    */
223 STDMETHODIMP CEnumVariant::PutSelection(long pXSelection)
224 {
225     pUNOInterface = (XAccessible*)pXSelection;
226     m_pXAccessibleSelection = GetXAccessibleSelection(pUNOInterface);
227     return S_OK;
228 }
229