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