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