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_sd.hxx"
26 #include "AccessiblePageShape.hxx"
27 #include <svx/AccessibleShapeInfo.hxx>
28 
29 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLE_ROLE_HPP_
30 #include <com/sun/star/accessibility/AccessibleRole.hpp>
31 #endif
32 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLE_STATE_TYPE_HPP_
33 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
34 #endif
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/container/XChild.hpp>
37 #include <com/sun/star/drawing/XShapes.hpp>
38 #include <com/sun/star/drawing/XShapeDescriptor.hpp>
39 #include <com/sun/star/drawing/XMasterPageTarget.hpp>
40 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
41 
42 using namespace ::com::sun::star;
43 using namespace ::com::sun::star::uno;
44 using namespace	::com::sun::star::accessibility;
45 using ::com::sun::star::uno::Reference;
46 using ::rtl::OUString;
47 
48 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
49 
50 namespace accessibility {
51 
52 //=====  internal  ============================================================
53 
54 AccessiblePageShape::AccessiblePageShape (
55     const uno::Reference<drawing::XDrawPage>& rxPage,
56     const uno::Reference<XAccessible>& rxParent,
57     const AccessibleShapeTreeInfo& rShapeTreeInfo,
58     long nIndex)
59     : AccessibleShape (AccessibleShapeInfo (NULL, rxParent, nIndex), rShapeTreeInfo),
60       mxPage (rxPage)
61 {
62     // The main part of the initialization is done in the init method which
63     // has to be called from this constructor's caller.
64 }
65 
66 
67 
68 
69 AccessiblePageShape::~AccessiblePageShape (void)
70 {
71     OSL_TRACE ("~AccessiblePageShape");
72 }
73 
74 
75 
76 
77 void AccessiblePageShape::Init (void)
78 {
79     AccessibleShape::Init ();
80 }
81 
82 
83 
84 
85 //=====  XAccessibleContext  ==================================================
86 
87 sal_Int32 SAL_CALL
88    	AccessiblePageShape::getAccessibleChildCount (void)
89     throw ()
90 {
91     return 0;
92 }
93 
94 
95 
96 
97 /** Forward the request to the shape.  Return the requested shape or throw
98     an exception for a wrong index.
99 */
100 uno::Reference<XAccessible> SAL_CALL
101     AccessiblePageShape::getAccessibleChild( sal_Int32 )
102     throw (::com::sun::star::uno::RuntimeException)
103 {
104     throw lang::IndexOutOfBoundsException (
105         ::rtl::OUString::createFromAscii ("page shape has no children"),
106         static_cast<uno::XWeak*>(this));
107 }
108 
109 
110 
111 
112 //=====  XAccessibleComponent  ================================================
113 
114 awt::Rectangle SAL_CALL AccessiblePageShape::getBounds (void)
115     throw (::com::sun::star::uno::RuntimeException)
116 {
117     ThrowIfDisposed ();
118 
119     awt::Rectangle aBoundingBox;
120 
121     if (maShapeTreeInfo.GetViewForwarder() != NULL)
122     {
123         uno::Reference<beans::XPropertySet> xSet (mxPage, uno::UNO_QUERY);
124         if (xSet.is())
125         {
126             uno::Any aValue;
127             awt::Point aPosition;
128             awt::Size aSize;
129 
130             aValue = xSet->getPropertyValue (
131                 ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("BorderLeft")));
132             aValue >>= aBoundingBox.X;
133             aValue = xSet->getPropertyValue (
134                 ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("BorderTop")));
135             aValue >>= aBoundingBox.Y;
136 
137             aValue = xSet->getPropertyValue (
138                 ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("Width")));
139             aValue >>= aBoundingBox.Width;
140             aValue = xSet->getPropertyValue (
141                 ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("Height")));
142             aValue >>= aBoundingBox.Height;
143         }
144 
145         // Transform coordinates from internal to pixel.
146         ::Size aPixelSize = maShapeTreeInfo.GetViewForwarder()->LogicToPixel (
147             ::Size (aBoundingBox.Width, aBoundingBox.Height));
148         ::Point aPixelPosition = maShapeTreeInfo.GetViewForwarder()->LogicToPixel (
149             ::Point (aBoundingBox.X, aBoundingBox.Y));
150 
151         // Clip the shape's bounding box with the bounding box of its parent.
152         Reference<XAccessibleComponent> xParentComponent (
153             getAccessibleParent(), uno::UNO_QUERY);
154         if (xParentComponent.is())
155         {
156             // Make the coordinates relative to the parent.
157             awt::Point aParentLocation (xParentComponent->getLocationOnScreen());
158             int x = aPixelPosition.getX() - aParentLocation.X;
159             int y = aPixelPosition.getY() - aParentLocation.Y;
160 
161 
162             // Clip with parent (with coordinates relative to itself).
163             ::Rectangle aBBox (
164                 x, y, x + aPixelSize.getWidth(), y + aPixelSize.getHeight());
165             awt::Size aParentSize (xParentComponent->getSize());
166             ::Rectangle aParentBBox (0,0, aParentSize.Width, aParentSize.Height);
167             aBBox = aBBox.GetIntersection (aParentBBox);
168             aBoundingBox = awt::Rectangle (
169                 aBBox.getX(),
170                 aBBox.getY(),
171                 aBBox.getWidth(),
172                 aBBox.getHeight());
173         }
174         else
175             aBoundingBox = awt::Rectangle (
176                 aPixelPosition.getX(), aPixelPosition.getY(),
177                 aPixelSize.getWidth(), aPixelSize.getHeight());
178     }
179 
180     return aBoundingBox;
181 }
182 
183 
184 
185 
186 sal_Int32 SAL_CALL AccessiblePageShape::getForeground (void)
187     throw (::com::sun::star::uno::RuntimeException)
188 {
189     ThrowIfDisposed ();
190     sal_Int32 nColor (0x0ffffffL);
191 
192     try
193     {
194         uno::Reference<beans::XPropertySet> aSet (mxPage, uno::UNO_QUERY);
195         if (aSet.is())
196         {
197             uno::Any aColor;
198             aColor = aSet->getPropertyValue (::rtl::OUString::createFromAscii ("LineColor"));
199             aColor >>= nColor;
200         }
201     }
202     catch (::com::sun::star::beans::UnknownPropertyException)
203     {
204         // Ignore exception and return default color.
205     }
206     return nColor;
207 }
208 
209 
210 
211 
212 /** Extract the background color from the Background property of eithe the
213     draw page or its master page.
214 */
215 sal_Int32 SAL_CALL AccessiblePageShape::getBackground (void)
216     throw (::com::sun::star::uno::RuntimeException)
217 {
218     ThrowIfDisposed ();
219     sal_Int32 nColor (0x01020ffL);
220 
221     try
222     {
223         uno::Reference<beans::XPropertySet> xSet (mxPage, uno::UNO_QUERY);
224         if (xSet.is())
225         {
226             uno::Any aBGSet;
227             aBGSet = xSet->getPropertyValue (
228                 ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("Background")));
229             Reference<beans::XPropertySet> xBGSet (aBGSet, uno::UNO_QUERY);
230             if ( ! xBGSet.is())
231             {
232                 // Draw page has no Background property.  Try the master
233                 // page instead.
234                 Reference<drawing::XMasterPageTarget> xTarget (mxPage, uno::UNO_QUERY);
235                 if (xTarget.is())
236                 {
237                     xSet = Reference<beans::XPropertySet> (xTarget->getMasterPage(),
238                         uno::UNO_QUERY);
239                     aBGSet = xSet->getPropertyValue (
240                         ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("Background")));
241                     xBGSet = Reference<beans::XPropertySet> (aBGSet, uno::UNO_QUERY);
242                 }
243             }
244             // Fetch the fill color.  Has to be extended to cope with
245             // gradients, hashes, and bitmaps.
246             if (xBGSet.is())
247             {
248                 uno::Any aColor;
249                 aColor = xBGSet->getPropertyValue (::rtl::OUString::createFromAscii ("FillColor"));
250                 aColor >>= nColor;
251             }
252             else
253                 OSL_TRACE ("no Background property in page");
254         }
255     }
256     catch (::com::sun::star::beans::UnknownPropertyException)
257     {
258         OSL_TRACE ("caught excption due to unknown property");
259         // Ignore exception and return default color.
260     }
261     return nColor;
262 }
263 
264 
265 
266 
267 //=====  XServiceInfo  ========================================================
268 
269 ::rtl::OUString SAL_CALL
270     AccessiblePageShape::getImplementationName (void)
271     throw (::com::sun::star::uno::RuntimeException)
272 {
273     ThrowIfDisposed ();
274 	return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessiblePageShape"));
275 }
276 
277 
278 
279 
280 ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
281     AccessiblePageShape::getSupportedServiceNames (void)
282     throw (::com::sun::star::uno::RuntimeException)
283 {
284     ThrowIfDisposed ();
285     return AccessibleShape::getSupportedServiceNames();
286 }
287 
288 
289 
290 
291 //=====  lang::XEventListener  ================================================
292 
293 void SAL_CALL
294     AccessiblePageShape::disposing (const ::com::sun::star::lang::EventObject& aEvent)
295     throw (::com::sun::star::uno::RuntimeException)
296 {
297     ThrowIfDisposed ();
298     AccessibleShape::disposing (aEvent);
299 }
300 
301 
302 
303 
304 //=====  XComponent  ==========================================================
305 
306 void AccessiblePageShape::dispose (void)
307     throw (::com::sun::star::uno::RuntimeException)
308 {
309     OSL_TRACE ("AccessiblePageShape::dispose");
310 
311     // Unregister listeners.
312     Reference<lang::XComponent> xComponent (mxShape, uno::UNO_QUERY);
313     if (xComponent.is())
314         xComponent->removeEventListener (this);
315 
316     // Cleanup.
317     mxShape = NULL;
318 
319     // Call base classes.
320     AccessibleContextBase::dispose ();
321 }
322 
323 
324 
325 
326 //=====  protected internal  ==================================================
327 
328 ::rtl::OUString
329     AccessiblePageShape::CreateAccessibleBaseName (void)
330     throw (::com::sun::star::uno::RuntimeException)
331 {
332     return ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("PageShape"));
333 }
334 
335 
336 
337 
338 ::rtl::OUString
339     AccessiblePageShape::CreateAccessibleName (void)
340     throw (::com::sun::star::uno::RuntimeException)
341 {
342     Reference<beans::XPropertySet> xPageProperties (mxPage, UNO_QUERY);
343 
344     // Get name of the current slide.
345     OUString sCurrentSlideName;
346     try
347     {
348         if (xPageProperties.is())
349         {
350             xPageProperties->getPropertyValue(A2S("LinkDisplayName")) >>= sCurrentSlideName;
351         }
352     }
353     catch (beans::UnknownPropertyException&)
354     {
355     }
356 
357     return CreateAccessibleBaseName()+A2S(": ")+sCurrentSlideName;
358 }
359 
360 
361 
362 
363 ::rtl::OUString
364     AccessiblePageShape::CreateAccessibleDescription (void)
365     throw (::com::sun::star::uno::RuntimeException)
366 {
367     return ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("Page Shape"));
368 }
369 
370 
371 } // end of namespace accessibility
372 
373 
374