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 "AccRelation.h"
32 #include <com/sun/star/accessibility/XAccessible.hpp>
33 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
34 #include "MAccessible.h"
35 
36 using namespace com::sun::star::accessibility;
37 using namespace com::sun::star::uno;
38 
39 /**
40    * Get relation type.
41    * @param relationType Variant to get relation type.
42    * @return Result.
43 */
44 STDMETHODIMP CAccRelation::get_relationType(BSTR * relationType)
45 {
46 
47 	CHECK_ENABLE_INF
48 
49     ENTER_PROTECTED_BLOCK
50 
51     if (relationType == NULL)
52         return E_INVALIDARG;
53 
54     int type = relation.RelationType;
55     SAFE_SYSFREESTRING(*relationType);
56 
57     *relationType = getRelationTypeBSTR(type);
58     return S_OK;
59 
60     LEAVE_PROTECTED_BLOCK
61 }
62 
63 // Gets what the type of localized relation is.
64 STDMETHODIMP CAccRelation::get_localizedRelationType(BSTR *)
65 {
66 
67 
68     ENTER_PROTECTED_BLOCK
69 
70     return S_OK;
71 
72     LEAVE_PROTECTED_BLOCK
73 }
74 
75 /**
76    * Get targets length.
77    * @param nTargets Variant to get targets length.
78    * @return Result.
79 */
80 STDMETHODIMP CAccRelation::get_nTargets(long * nTargets)
81 {
82 
83 
84     ENTER_PROTECTED_BLOCK
85 
86 	CHECK_ENABLE_INF
87     if (nTargets == NULL)
88         return E_INVALIDARG;
89 
90     Sequence< Reference< XInterface > > xTargets = relation.TargetSet;
91     *nTargets = xTargets.getLength();
92     return S_OK;
93 
94     LEAVE_PROTECTED_BLOCK
95 }
96 
97 /**
98    * Get special target.
99    * @param targetIndex target index.
100    * @param target      Variant to get special target.
101    * @return Result.
102 */
103 STDMETHODIMP CAccRelation::get_target(long targetIndex, IUnknown * * target)
104 {
105 
106 	CHECK_ENABLE_INF
107 
108     ENTER_PROTECTED_BLOCK
109 
110     if (target == NULL)
111         return E_FAIL;
112 
113     Sequence< Reference< XInterface > > xTargets = relation.TargetSet;
114     int nCount = xTargets.getLength();
115     if( targetIndex >= nCount )
116         return E_FAIL;
117 
118     Reference<XInterface> pRAcc = xTargets[targetIndex];
119     IAccessible* pRet = NULL;
120 
121     BOOL isGet = CMAccessible::get_IAccessibleFromXAccessible((long)pRAcc.get(),&pRet);
122     if(isGet)
123     {
124         *target = /*(IAccessible2 *)*/(IUnknown*)pRet;
125         pRet->AddRef();
126         return S_OK;
127     }
128 
129     return E_FAIL;
130 
131     LEAVE_PROTECTED_BLOCK
132 }
133 
134 /**
135    * Get special targets.
136    * @param maxTargets Special targets count.
137    * @param target Variant to get special target.
138    * @param nTargets Variant to accept actual target length.
139    * @return Result.
140 */
141 STDMETHODIMP CAccRelation::get_targets(long, IUnknown * * target, long * nTargets)
142 {
143 
144 	CHECK_ENABLE_INF
145 
146     ENTER_PROTECTED_BLOCK
147 
148     // #CHECK#
149     if(target == NULL)
150         return E_INVALIDARG;
151     if (nTargets == NULL)
152         return E_INVALIDARG;
153 
154     Sequence< Reference< XInterface > > xTargets = relation.TargetSet;
155     int nCount = xTargets.getLength();
156 
157     *target = (IUnknown*)::CoTaskMemAlloc(nCount*sizeof(IUnknown));
158 
159     // #CHECK Memory Allocation#
160     if(*target == NULL)
161     {
162         return E_FAIL;
163     }
164 
165     for(int i=0; i<nCount ; i++)
166     {
167         IUnknown* pAcc = NULL;
168         HRESULT hr = get_target(i,&pAcc);
169         if(SUCCEEDED(hr))
170             target[i] = pAcc;
171     }
172 
173     *nTargets = nCount;
174     return S_OK;
175 
176     LEAVE_PROTECTED_BLOCK
177 }
178 
179 /**
180    * Put UNO interface.
181    * @param pXSubInterface AccessibleRelation pointer.
182    * @return Result.
183 */
184 STDMETHODIMP CAccRelation::put_XSubInterface(long pXSubInterface)
185 {
186 
187     relation = *((AccessibleRelation*)pXSubInterface);
188     return S_OK;
189 }
190 
191 /**
192    * Get relation type string by type.
193    * @param type Relation type.
194    * @return relation type string.
195 */
196 BSTR CAccRelation::getRelationTypeBSTR(int type)
197 {
198     static struct TYPE_BSTR_MAP
199     {
200         LPCTSTR string;
201         int type;
202     }
203     map[] =
204         {
205             {_T("INVALID")				,	0},
206             {IA2_RELATION_FLOWS_FROM	,	1},
207             {IA2_RELATION_FLOWS_TO		,	2},
208             {IA2_RELATION_CONTROLLED_BY	,	3},
209             {IA2_RELATION_CONTROLLER_FOR,	4},
210             {IA2_RELATION_LABEL_FOR		,	5},
211             {IA2_RELATION_LABELED_BY	,	6},
212             {IA2_RELATION_MEMBER_OF		,	7},
213             {IA2_RELATION_SUBWINDOW_OF	,	8},
214 			{IA2_RELATION_NODE_CHILD_OF,	9},
215             {IA2_RELATION_DESCRIBED_BY	,	10},
216         };
217 
218     USES_CONVERSION;
219 
220     return (type >= 0 && type <= 10) ? T2BSTR(map[type].string) : _T("");
221 }
222