1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include "svx/DescriptionGenerator.hxx"
32 #include <com/sun/star/beans/PropertyState.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/beans/XPropertyState.hpp>
35 #include <com/sun/star/container/XChild.hpp>
36 #include <com/sun/star/container/XNameContainer.hpp>
37 #include <com/sun/star/container/XNameAccess.hpp>
38 #include <com/sun/star/container/XNamed.hpp>
39 #include <com/sun/star/drawing/FillStyle.hpp>
40 #include <com/sun/star/drawing/XShapes.hpp>
41 #include <com/sun/star/drawing/XShapeDescriptor.hpp>
42 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
43 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
44 #include <com/sun/star/style/XStyle.hpp>
45 #include <comphelper/processfactory.hxx>
46 #include <vos/mutex.hxx>
47 #include <vcl/svapp.hxx>
48 
49 #include <com/sun/star/uno/Exception.hpp>
50 
51 // Includes for string resources.
52 #ifndef _SVX_ACCESSIBILITY_HRC
53 #include "accessibility.hrc"
54 #endif
55 #include "svx/svdstr.hrc"
56 #include <svx/dialmgr.hxx>
57 #include <tools/string.hxx>
58 
59 #include <svx/xdef.hxx>
60 #include "svx/unoapi.hxx"
61 #include "accessibility.hrc"
62 #include "DGColorNameLookUp.hxx"
63 
64 using namespace ::rtl;
65 using namespace ::com::sun::star;
66 
67 
68 void SvxUnogetInternalNameForItem( const sal_Int16 nWhich, const rtl::OUString& rApiName, String& rInternalName ) throw();
69 
70 namespace accessibility {
71 
72 
73 DescriptionGenerator::DescriptionGenerator (
74     const uno::Reference<drawing::XShape>& xShape)
75     : mxShape (xShape),
76       mxSet (mxShape, uno::UNO_QUERY),
77       mbIsFirstProperty (true)
78 {
79 }
80 
81 
82 
83 
84 DescriptionGenerator::~DescriptionGenerator (void)
85 {
86 }
87 
88 
89 
90 
91 void DescriptionGenerator::Initialize (sal_Int32 nResourceId)
92 {
93     // Get the string from the resource for the specified id.
94     OUString sPrefix;
95     {
96         ::vos::OGuard aGuard (::Application::GetSolarMutex());
97         sPrefix = OUString (SVX_RESSTR (nResourceId));
98     }
99 
100     // Forward the call with the resulting string.
101     Initialize (sPrefix);
102 }
103 
104 
105 
106 
107 void DescriptionGenerator::Initialize (::rtl::OUString sPrefix)
108 {
109     msDescription = sPrefix;
110     if (mxSet.is())
111     {
112         {
113             ::vos::OGuard aGuard (::Application::GetSolarMutex());
114 
115             msDescription.append (sal_Unicode (' '));
116             msDescription.append (OUString (SVX_RESSTR(RID_SVXSTR_A11Y_WITH)));
117             msDescription.append (sal_Unicode (' '));
118 
119             msDescription.append (OUString (SVX_RESSTR (RID_SVXSTR_A11Y_STYLE)));
120             msDescription.append (sal_Unicode ('='));
121         }
122 
123         try
124         {
125             if (mxSet.is())
126             {
127                 uno::Any aValue = mxSet->getPropertyValue (OUString::createFromAscii ("Style"));
128                 uno::Reference<container::XNamed> xStyle (aValue, uno::UNO_QUERY);
129                 if (xStyle.is())
130                     msDescription.append (xStyle->getName());
131             }
132             else
133                 msDescription.append (
134                     OUString::createFromAscii("<no style>"));
135         }
136         catch (::com::sun::star::beans::UnknownPropertyException)
137         {
138             msDescription.append (
139                 OUString::createFromAscii("<unknown>"));
140         }
141     }
142 }
143 
144 
145 
146 
147 ::rtl::OUString DescriptionGenerator::operator() (void)
148 {
149     msDescription.append (sal_Unicode ('.'));
150     return msDescription.makeStringAndClear();
151 }
152 
153 
154 
155 
156 void DescriptionGenerator::AddProperty (
157     const OUString& sPropertyName,
158     PropertyType aType,
159     const sal_Int32 nLocalizedNameId,
160     long nWhichId)
161 {
162     OUString sLocalizedName;
163     {
164         ::vos::OGuard aGuard (::Application::GetSolarMutex());
165         sLocalizedName = SVX_RESSTR (nLocalizedNameId);
166     }
167     AddProperty (sPropertyName, aType, sLocalizedName, nWhichId);
168 }
169 
170 
171 
172 
173 void DescriptionGenerator::AddProperty (const OUString& sPropertyName,
174     PropertyType aType, const OUString& sLocalizedName, long nWhichId)
175 {
176     uno::Reference<beans::XPropertyState> xState (mxShape, uno::UNO_QUERY);
177     if (xState.is()
178         && xState->getPropertyState(sPropertyName)!=beans::PropertyState_DEFAULT_VALUE)
179         if (mxSet.is())
180         {
181             // Append a seperator from previous Properties.
182             if ( ! mbIsFirstProperty)
183                 msDescription.append (sal_Unicode (','));
184             else
185             {
186                 ::vos::OGuard aGuard (::Application::GetSolarMutex());
187 
188                 msDescription.append (sal_Unicode (' '));
189                 msDescription.append (OUString (SVX_RESSTR(RID_SVXSTR_A11Y_AND)));
190                 msDescription.append (sal_Unicode (' '));
191                 mbIsFirstProperty = false;
192             }
193 
194             // Delegate to type specific property handling.
195             switch (aType)
196             {
197                 case COLOR:
198                     AddColor (sPropertyName, sLocalizedName);
199                     break;
200                 case INTEGER:
201                     AddInteger (sPropertyName, sLocalizedName);
202                     break;
203                 case STRING:
204                     AddString (sPropertyName, sLocalizedName, nWhichId);
205                     break;
206                 case FILL_STYLE:
207                     AddFillStyle (sPropertyName, sLocalizedName);
208                     break;
209             }
210         }
211 }
212 
213 
214 
215 
216 void DescriptionGenerator::AppendString (const ::rtl::OUString& sString)
217 {
218     msDescription.append (sString);
219 }
220 
221 
222 
223 
224 void DescriptionGenerator::AddLineProperties (void)
225 {
226     AddProperty (OUString::createFromAscii ("LineColor"),
227         DescriptionGenerator::COLOR,
228         SIP_XA_LINECOLOR);
229     AddProperty (OUString::createFromAscii ("LineDashName"),
230         DescriptionGenerator::STRING,
231         SIP_XA_LINEDASH,
232         XATTR_LINEDASH);
233     AddProperty (OUString::createFromAscii ("LineWidth"),
234         DescriptionGenerator::INTEGER,
235         SIP_XA_LINEWIDTH);
236 }
237 
238 
239 
240 
241 /** The fill style is described by the property "FillStyle".  Depending on
242     its value a hatch-, gradient-, or bitmap name is appended.
243 */
244 void DescriptionGenerator::AddFillProperties (void)
245 {
246     AddProperty (OUString::createFromAscii ("FillStyle"),
247         DescriptionGenerator::FILL_STYLE,
248         SIP_XA_FILLSTYLE);
249 }
250 
251 
252 
253 
254 void DescriptionGenerator::Add3DProperties (void)
255 {
256     AddProperty (OUString::createFromAscii ("D3DMaterialColor"),
257         DescriptionGenerator::COLOR,
258         RID_SVXSTR_A11Y_3D_MATERIAL_COLOR);
259     AddLineProperties ();
260     AddFillProperties ();
261 }
262 
263 
264 
265 
266 void DescriptionGenerator::AddTextProperties (void)
267 {
268     AddProperty (OUString::createFromAscii ("CharColor"),
269         DescriptionGenerator::COLOR);
270     AddFillProperties ();
271 }
272 
273 
274 
275 
276 /** Search for the given color in the global color table.  If found append
277     its name to the description.  Otherwise append its RGB tuple.
278 */
279 void DescriptionGenerator::AddColor (const OUString& sPropertyName,
280     const OUString& sLocalizedName)
281 {
282     msDescription.append (sLocalizedName);
283     msDescription.append (sal_Unicode('='));
284 
285     try
286     {
287 
288         long nValue(0);
289         if (mxSet.is())
290         {
291             uno::Any aValue = mxSet->getPropertyValue (sPropertyName);
292             aValue >>= nValue;
293         }
294 
295         msDescription.append (DGColorNameLookUp::Instance().LookUpColor (nValue));
296     }
297     catch (::com::sun::star::beans::UnknownPropertyException)
298     {
299         msDescription.append (
300             OUString::createFromAscii("<unknown>"));
301     }
302 }
303 
304 
305 
306 
307 void DescriptionGenerator::AddUnknown (const OUString& /*sPropertyName*/,
308     const OUString& sLocalizedName)
309 {
310     //        uno::Any aValue = mxSet->getPropertyValue (sPropertyName);
311     msDescription.append (sLocalizedName);
312 }
313 
314 
315 
316 
317 void DescriptionGenerator::AddInteger (const OUString& sPropertyName,
318     const OUString& sLocalizedName)
319 {
320     msDescription.append (sLocalizedName);
321     msDescription.append (sal_Unicode('='));
322 
323     try
324     {
325         if (mxSet.is())
326         {
327             uno::Any aValue = mxSet->getPropertyValue (sPropertyName);
328             long nValue = 0;
329             aValue >>= nValue;
330             msDescription.append (nValue);
331         }
332     }
333     catch (::com::sun::star::beans::UnknownPropertyException)
334     {
335         msDescription.append (
336             OUString::createFromAscii("<unknown>"));
337     }
338 }
339 
340 
341 
342 
343 void DescriptionGenerator::AddString (const OUString& sPropertyName,
344     const OUString& sLocalizedName, long nWhichId)
345 {
346     msDescription.append (sLocalizedName);
347     msDescription.append (sal_Unicode('='));
348 
349     try
350     {
351         if (mxSet.is())
352         {
353             uno::Any aValue = mxSet->getPropertyValue (sPropertyName);
354             OUString sValue;
355             aValue >>= sValue;
356 
357             if (nWhichId >= 0)
358             {
359                 ::vos::OGuard aGuard (::Application::GetSolarMutex());
360                 String sLocalizedValue;
361                 SvxUnogetInternalNameForItem (sal::static_int_cast<sal_Int16>(nWhichId),
362                                               sValue, sLocalizedValue);
363                 msDescription.append (sLocalizedValue);
364             }
365             else
366                 msDescription.append (sValue);
367         }
368     }
369     catch (::com::sun::star::beans::UnknownPropertyException)
370     {
371         msDescription.append (
372             OUString::createFromAscii("<unknown>"));
373     }
374 }
375 
376 
377 
378 
379 void DescriptionGenerator::AddFillStyle (const OUString& sPropertyName,
380     const OUString& sLocalizedName)
381 {
382     msDescription.append (sLocalizedName);
383     msDescription.append (sal_Unicode('='));
384 
385     try
386     {
387         if (mxSet.is())
388         {
389             uno::Any aValue = mxSet->getPropertyValue (sPropertyName);
390             drawing::FillStyle aFillStyle;
391             aValue >>= aFillStyle;
392 
393             // Get the fill style name from the resource.
394             OUString sFillStyleName;
395             {
396                 ::vos::OGuard aGuard (::Application::GetSolarMutex());
397                 switch (aFillStyle)
398                 {
399                     case drawing::FillStyle_NONE:
400                         sFillStyleName = SVX_RESSTR(RID_SVXSTR_A11Y_FILLSTYLE_NONE);
401                         break;
402                     case drawing::FillStyle_SOLID:
403                         sFillStyleName = SVX_RESSTR(RID_SVXSTR_A11Y_FILLSTYLE_SOLID);
404                         break;
405                     case drawing::FillStyle_GRADIENT:
406                         sFillStyleName = SVX_RESSTR(RID_SVXSTR_A11Y_FILLSTYLE_GRADIENT);
407                         break;
408                     case drawing::FillStyle_HATCH:
409                         sFillStyleName = SVX_RESSTR(RID_SVXSTR_A11Y_FILLSTYLE_HATCH);
410                         break;
411                     case drawing::FillStyle_BITMAP:
412                         sFillStyleName = SVX_RESSTR(RID_SVXSTR_A11Y_FILLSTYLE_BITMAP);
413                         break;
414                     case drawing::FillStyle_MAKE_FIXED_SIZE:
415                         break;
416                 }
417             }
418             msDescription.append (sFillStyleName);
419 
420             // Append the appropriate properties.
421             switch (aFillStyle)
422             {
423                 case drawing::FillStyle_NONE:
424                     break;
425                 case drawing::FillStyle_SOLID:
426                     AddProperty (OUString::createFromAscii ("FillColor"),
427                         COLOR,
428                         SIP_XA_FILLCOLOR);
429                     break;
430                 case drawing::FillStyle_GRADIENT:
431                     AddProperty (OUString::createFromAscii ("FillGradientName"),
432                         STRING,
433                         SIP_XA_FILLGRADIENT,
434                         XATTR_FILLGRADIENT);
435                     break;
436                 case drawing::FillStyle_HATCH:
437                     AddProperty (OUString::createFromAscii ("FillColor"),
438                         COLOR,
439                         SIP_XA_FILLCOLOR);
440                     AddProperty (OUString::createFromAscii ("FillHatchName"),
441                         STRING,
442                         SIP_XA_FILLHATCH,
443                         XATTR_FILLHATCH);
444                     break;
445                 case drawing::FillStyle_BITMAP:
446                     AddProperty (OUString::createFromAscii ("FillBitmapName"),
447                         STRING,
448                         SIP_XA_FILLBITMAP,
449                         XATTR_FILLBITMAP);
450                     break;
451                 case drawing::FillStyle_MAKE_FIXED_SIZE:
452                     break;
453             }
454         }
455     }
456     catch (::com::sun::star::beans::UnknownPropertyException)
457     {
458         msDescription.append (
459             OUString::createFromAscii("<unknown>"));
460     }
461 }
462 
463 
464 
465 
466 void DescriptionGenerator::AddPropertyNames (void)
467 {
468     if (mxSet.is())
469     {
470         uno::Reference<beans::XPropertySetInfo> xInfo (mxSet->getPropertySetInfo());
471         if (xInfo.is())
472         {
473             uno::Sequence<beans::Property> aPropertyList (xInfo->getProperties ());
474             for (int i=0; i<aPropertyList.getLength(); i++)
475             {
476                 msDescription.append (aPropertyList[i].Name);
477                 msDescription.append (sal_Unicode(','));
478             }
479         }
480     }
481 }
482 
483 
484 } // end of namespace accessibility
485