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
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26
27 #include <svx/ShapeTypeHandler.hxx>
28 #include <svx/SvxShapeTypes.hxx>
29 #include <svx/AccessibleShapeInfo.hxx>
30 #include <com/sun/star/drawing/XShapeDescriptor.hpp>
31 #include <vos/mutex.hxx>
32 #include <vcl/svapp.hxx>
33 #include <svx/dialmgr.hxx>
34
35 #include <svx/unoshape.hxx>
36 #include <svx/svdoashp.hxx>
37 #include "svx/unoapi.hxx"
38
39 #include "svx/svdstr.hrc"
40
41 using namespace ::rtl;
42 using namespace ::com::sun::star;
43 using namespace ::com::sun::star::accessibility;
44
45 namespace accessibility {
46
47 // Pointer to the shape type handler singleton.
48 ShapeTypeHandler* ShapeTypeHandler::instance = NULL;
49
50
51 // Create an empty reference to an accessible object.
52 AccessibleShape*
CreateEmptyShapeReference(const AccessibleShapeInfo &,const AccessibleShapeTreeInfo &,ShapeTypeId)53 CreateEmptyShapeReference (
54 const AccessibleShapeInfo& /*rShapeInfo*/,
55 const AccessibleShapeTreeInfo& /*rShapeTreeInfo*/,
56 ShapeTypeId /*nId*/)
57 {
58 return NULL;
59 }
60
61
62
63
Instance(void)64 ShapeTypeHandler& ShapeTypeHandler::Instance (void)
65 {
66 // Using double check pattern to make sure that exactly one instance of
67 // the shape type handler is instantiated.
68 if (instance == NULL)
69 {
70 ::vos::OGuard aGuard (::Application::GetSolarMutex());
71 if (instance == NULL)
72 {
73 // Create the single instance of the shape type handler.
74 instance = new ShapeTypeHandler;
75
76 // Register the basic SVX shape types.
77 RegisterDrawShapeTypes ();
78 }
79 }
80
81 return *instance;
82 }
83
84
85
86
87 /** The given service name is first transformed into a slot id that
88 identifies the place of the type descriptor. From that descriptor the
89 shape type id is returned.
90 */
GetTypeId(const OUString & aServiceName) const91 ShapeTypeId ShapeTypeHandler::GetTypeId (const OUString& aServiceName) const
92 {
93 tServiceNameToSlotId::iterator I (maServiceNameToSlotId.find (aServiceName));
94 if (I != maServiceNameToSlotId.end())
95 {
96 // long nSlotId = maServiceNameToSlotId[aServiceName];
97 return maShapeTypeDescriptorList[I->second].mnShapeTypeId;
98 }
99 else
100 return -1;
101 }
102
103
104
105 /** Extract the specified shape's service name and forward the request to
106 the appropriate method.
107 */
GetTypeId(const uno::Reference<drawing::XShape> & rxShape) const108 ShapeTypeId ShapeTypeHandler::GetTypeId (const uno::Reference<drawing::XShape>& rxShape) const
109 {
110 uno::Reference<drawing::XShapeDescriptor> xDescriptor (rxShape, uno::UNO_QUERY);
111 if (xDescriptor.is())
112 return GetTypeId (xDescriptor->getShapeType());
113 else
114 return -1;
115 }
116
117
118
119
GetServiceName(ShapeTypeId aTypeId) const120 const OUString& ShapeTypeHandler::GetServiceName (ShapeTypeId aTypeId) const
121 {
122 return maShapeTypeDescriptorList[aTypeId].msServiceName;
123 }
124
125
126
127
128 /** This factory method determines the type descriptor for the type of the
129 given shape, then calls the descriptor's create function, and finally
130 initializes the new object.
131 */
132 AccessibleShape*
CreateAccessibleObject(const AccessibleShapeInfo & rShapeInfo,const AccessibleShapeTreeInfo & rShapeTreeInfo) const133 ShapeTypeHandler::CreateAccessibleObject (
134 const AccessibleShapeInfo& rShapeInfo,
135 const AccessibleShapeTreeInfo& rShapeTreeInfo) const
136 {
137 ShapeTypeId nSlotId (GetSlotId (rShapeInfo.mxShape));
138 AccessibleShape* pShape =
139 maShapeTypeDescriptorList[nSlotId].maCreateFunction (
140 rShapeInfo,
141 rShapeTreeInfo,
142 maShapeTypeDescriptorList[nSlotId].mnShapeTypeId);
143 return pShape;
144 }
145
146
147
148
149 /** Create the single instance of this class and initialize its list of
150 type descriptors with an entry of an unknown type.
151 */
ShapeTypeHandler(void)152 ShapeTypeHandler::ShapeTypeHandler (void)
153 : maShapeTypeDescriptorList (1)
154 {
155 // Make sure that at least the UNKNOWN entry is present.
156 // Resize the list, if necessary, so that the new type can be inserted.
157 maShapeTypeDescriptorList[0].mnShapeTypeId = UNKNOWN_SHAPE_TYPE;
158 maShapeTypeDescriptorList[0].msServiceName =
159 OUString::createFromAscii ("UNKNOWN_SHAPE_TYPE");
160 maShapeTypeDescriptorList[0].maCreateFunction = CreateEmptyShapeReference;
161 maServiceNameToSlotId[maShapeTypeDescriptorList[0].msServiceName] = 0;
162 }
163
164
165
166
~ShapeTypeHandler(void)167 ShapeTypeHandler::~ShapeTypeHandler (void)
168 {
169 // Because this class is a singleton and the only instance, whose
170 // destructor has just been called, is pointed to from instance,
171 // we reset the static variable instance, so that further calls to
172 // getInstance do not return an undefined object but create a new
173 // singleton.
174 instance = NULL;
175 }
176
177
178
179
AddShapeTypeList(int nDescriptorCount,ShapeTypeDescriptor aDescriptorList[])180 bool ShapeTypeHandler::AddShapeTypeList (int nDescriptorCount,
181 ShapeTypeDescriptor aDescriptorList[])
182 {
183 ::vos::OGuard aGuard (::Application::GetSolarMutex());
184
185 // Determine first id of new type descriptor(s).
186 int nFirstId = maShapeTypeDescriptorList.size();
187
188 // Resize the list, if necessary, so that the types can be inserted.
189 maShapeTypeDescriptorList.resize (nFirstId + nDescriptorCount);
190
191 for (int i=0; i<nDescriptorCount; i++)
192 {
193 #if OSL_DEBUG_LEVEL > 0
194 ShapeTypeId nId (aDescriptorList[i].mnShapeTypeId);
195 (void)nId;
196 #endif
197
198 // Fill Type descriptor.
199 maShapeTypeDescriptorList[nFirstId+i].mnShapeTypeId = aDescriptorList[i].mnShapeTypeId;
200 maShapeTypeDescriptorList[nFirstId+i].msServiceName = aDescriptorList[i].msServiceName;
201 maShapeTypeDescriptorList[nFirstId+i].maCreateFunction = aDescriptorList[i].maCreateFunction;
202
203 // Update inverse mapping from service name to the descriptor's position.
204 maServiceNameToSlotId[aDescriptorList[i].msServiceName] = nFirstId+i;
205 }
206
207 return true;
208 }
209
210
211
212
213 #include <tools/string.hxx>
GetSlotId(const OUString & aServiceName) const214 long ShapeTypeHandler::GetSlotId (const OUString& aServiceName) const
215 {
216 tServiceNameToSlotId::iterator I (maServiceNameToSlotId.find (aServiceName));
217 if (I != maServiceNameToSlotId.end())
218 return I->second;
219 else
220 return 0;
221 }
222
223
224
225
226 // Extract the given shape's service name and forward request to appropriate
227 // method.
GetSlotId(const uno::Reference<drawing::XShape> & rxShape) const228 long ShapeTypeHandler::GetSlotId (const uno::Reference<drawing::XShape>& rxShape) const
229 {
230 uno::Reference<drawing::XShapeDescriptor> xDescriptor (rxShape, uno::UNO_QUERY);
231 if (xDescriptor.is())
232 return GetSlotId (xDescriptor->getShapeType());
233 else
234 return 0;
235 }
236
237 /// get the accessible base name for an object
238 ::rtl::OUString
CreateAccessibleBaseName(const uno::Reference<drawing::XShape> & rxShape)239 ShapeTypeHandler::CreateAccessibleBaseName (const uno::Reference<drawing::XShape>& rxShape)
240 throw (::com::sun::star::uno::RuntimeException)
241 {
242 sal_Int32 nResourceId;
243 OUString sName;
244
245 switch (ShapeTypeHandler::Instance().GetTypeId (rxShape))
246 {
247 // case DRAWING_3D_POLYGON: was removed in original code in
248 // AccessibleShape::CreateAccessibleBaseName. See issue 11190 for details.
249 // Id can be removed from SvxShapeTypes.hxx as well.
250 case DRAWING_3D_CUBE:
251 nResourceId = STR_ObjNameSingulCube3d;
252 break;
253 case DRAWING_3D_EXTRUDE:
254 nResourceId = STR_ObjNameSingulExtrude3d;
255 break;
256 case DRAWING_3D_LATHE:
257 nResourceId = STR_ObjNameSingulLathe3d;
258 break;
259 case DRAWING_3D_SCENE:
260 nResourceId = STR_ObjNameSingulScene3d;
261 break;
262 case DRAWING_3D_SPHERE:
263 nResourceId = STR_ObjNameSingulSphere3d;
264 break;
265 case DRAWING_CAPTION:
266 nResourceId = STR_ObjNameSingulCAPTION;
267 break;
268 case DRAWING_CLOSED_BEZIER:
269 nResourceId = STR_ObjNameSingulPATHFILL;
270 break;
271 case DRAWING_CLOSED_FREEHAND:
272 nResourceId = STR_ObjNameSingulFREEFILL;
273 break;
274 case DRAWING_CONNECTOR:
275 nResourceId = STR_ObjNameSingulEDGE;
276 break;
277 case DRAWING_CONTROL:
278 nResourceId = STR_ObjNameSingulUno;
279 break;
280 case DRAWING_ELLIPSE:
281 nResourceId = STR_ObjNameSingulCIRCE;
282 break;
283 case DRAWING_GROUP:
284 nResourceId = STR_ObjNameSingulGRUP;
285 break;
286 case DRAWING_LINE:
287 nResourceId = STR_ObjNameSingulLINE;
288 break;
289 case DRAWING_MEASURE:
290 nResourceId = STR_ObjNameSingulMEASURE;
291 break;
292 case DRAWING_OPEN_BEZIER:
293 nResourceId = STR_ObjNameSingulPATHLINE;
294 break;
295 case DRAWING_OPEN_FREEHAND:
296 nResourceId = STR_ObjNameSingulFREELINE;
297 break;
298 case DRAWING_PAGE:
299 nResourceId = STR_ObjNameSingulPAGE;
300 break;
301 case DRAWING_POLY_LINE:
302 nResourceId = STR_ObjNameSingulPLIN;
303 break;
304 case DRAWING_POLY_LINE_PATH:
305 nResourceId = STR_ObjNameSingulPLIN;
306 break;
307 case DRAWING_POLY_POLYGON:
308 nResourceId = STR_ObjNameSingulPOLY;
309 break;
310 case DRAWING_POLY_POLYGON_PATH:
311 nResourceId = STR_ObjNameSingulPOLY;
312 break;
313 case DRAWING_RECTANGLE:
314 nResourceId = STR_ObjNameSingulRECT;
315 break;
316 case DRAWING_CUSTOM:
317 {
318 nResourceId = STR_ObjNameSingulCUSTOMSHAPE;
319
320 SvxShape* pShape = SvxShape::getImplementation( rxShape );
321 if (pShape)
322 {
323 SdrObject *pSdrObj = pShape->GetSdrObject();
324 if (pSdrObj)
325 {
326 String aTmp;
327 pSdrObj->TakeObjNameSingul( aTmp );
328
329 if(pSdrObj->ISA(SdrObjCustomShape))
330 {
331 SdrObjCustomShape* pCustomShape = (SdrObjCustomShape*)pSdrObj;
332 if(pCustomShape)
333 if (pCustomShape->IsTextPath())
334 nResourceId = STR_ObjNameSingulFONTWORK;
335 else
336 {
337 nResourceId = -1;
338 sName = pCustomShape->GetCustomShapeName();
339 }
340 }
341 }
342 }
343 break;
344 }
345 case DRAWING_TEXT:
346 nResourceId = STR_ObjNameSingulTEXT;
347 break;
348 default:
349 nResourceId = -1;
350 sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("UnknownAccessibleShape"));
351 uno::Reference<drawing::XShapeDescriptor> xDescriptor (rxShape, uno::UNO_QUERY);
352 if (xDescriptor.is())
353 sName += ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM(": "))
354 + xDescriptor->getShapeType();
355 break;
356 }
357
358 if (nResourceId != -1)
359 {
360 ::vos::OGuard aGuard (::Application::GetSolarMutex());
361 sName = OUString (SVX_RESSTR((unsigned short)nResourceId));
362 }
363
364 return sName;
365 }
366
367 } // end of namespace accessibility
368