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 #include <svx/AccessibleShape.hxx>
27 #include "svx/DescriptionGenerator.hxx"
28 #include <svx/AccessibleShapeInfo.hxx>
29 #include <com/sun/star/view/XSelectionSupplier.hpp>
30 #include <rtl/uuid.h>
31 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLE_ROLE_HPP_
32 #include <com/sun/star/accessibility/AccessibleRole.hpp>
33 #endif
34 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLETEXTTYPE_HPP_
35 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
36 #endif
37 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLE_STATE_TYPE_HPP_
38 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
39 #endif
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include <com/sun/star/container/XChild.hpp>
42 #include <com/sun/star/drawing/XShapes.hpp>
43 #include <com/sun/star/drawing/XShapeDescriptor.hpp>
44 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
45 #include <com/sun/star/drawing/FillStyle.hpp>
46 #include <com/sun/star/text/XText.hpp>
47 #include <editeng/outlobj.hxx>
48 #include <rtl/ref.hxx>
49 #include <editeng/unoedsrc.hxx>
50 #include <svx/unoshtxt.hxx>
51 #include <svx/svdobj.hxx>
52 #include <svx/svdmodel.hxx>
53 #include "svx/unoapi.hxx"
54 #include <com/sun/star/uno/Exception.hpp>
55 #include <svx/ShapeTypeHandler.hxx>
56 #include <svx/SvxShapeTypes.hxx>
57
58 #ifndef _SVX_ACCESSIBILITY_HRC
59 #include "accessibility.hrc"
60 #endif
61 #include "svx/svdstr.hrc"
62 #include <svx/dialmgr.hxx>
63 #include <vcl/svapp.hxx>
64 #include <unotools/accessiblestatesethelper.hxx>
65 #include <svx/svdview.hxx>
66 #include "AccessibleEmptyEditSource.hxx"
67 #include <svx/svdpage.hxx>
68 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLERELATIONTYPE_HPP_
69 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
70 #endif
71 #ifndef _UTL_ACCESSIBLERELATIONSETHELPER_HXX_
72 #include <unotools/accessiblerelationsethelper.hxx>
73 #endif
74 using namespace ::com::sun::star;
75 using namespace ::com::sun::star::accessibility;
76 using ::com::sun::star::lang::IndexOutOfBoundsException;
77 using ::com::sun::star::uno::RuntimeException;
78 using ::com::sun::star::uno::Reference;
79 using ::rtl::OUString;
80 #include <algorithm>
81
82 // #include <Accessiblehyperlink.hxx>
83 namespace accessibility {
84
85 namespace {
86
GetOptionalProperty(const Reference<beans::XPropertySet> & rxSet,const OUString & rsPropertyName)87 OUString GetOptionalProperty (
88 const Reference<beans::XPropertySet>& rxSet,
89 const OUString& rsPropertyName)
90 {
91 OUString sValue;
92
93 if (rxSet.is())
94 {
95 const Reference<beans::XPropertySetInfo> xInfo (rxSet->getPropertySetInfo());
96 if ( ! xInfo.is() || xInfo->hasPropertyByName(rsPropertyName))
97 {
98 try
99 {
100 rxSet->getPropertyValue(rsPropertyName) >>= sValue;
101 }
102 catch (beans::UnknownPropertyException&)
103 {
104 // This exception should only be thrown when the property
105 // does not exits (of course) and the XPropertySetInfo is
106 // not available.
107 }
108 }
109 }
110 return sValue;
111 }
112
113 } // end of anonymous namespace
114
115
116
117
118 //===== internal ============================================================
119
AccessibleShape(const AccessibleShapeInfo & rShapeInfo,const AccessibleShapeTreeInfo & rShapeTreeInfo)120 AccessibleShape::AccessibleShape (
121 const AccessibleShapeInfo& rShapeInfo,
122 const AccessibleShapeTreeInfo& rShapeTreeInfo)
123 : AccessibleContextBase (rShapeInfo.mxParent,AccessibleRole::SHAPE),
124 mpChildrenManager(NULL),
125 mxShape (rShapeInfo.mxShape),
126 maShapeTreeInfo (rShapeTreeInfo),
127 mnIndex (rShapeInfo.mnIndex),
128 m_nIndexInParent(-1),
129 mpText (NULL),
130 mpParent (rShapeInfo.mpChildrenManager)
131 {
132 m_pShape = GetSdrObjectFromXShape(mxShape);
133 UpdateNameAndDescription();
134 }
AccessibleShape(const::com::sun::star::uno::Reference<::com::sun::star::drawing::XShape> & rxShape,const::com::sun::star::uno::Reference<::com::sun::star::accessibility::XAccessible> & rxParent,const AccessibleShapeTreeInfo & rShapeTreeInfo,sal_Int32 nIndex)135 AccessibleShape::AccessibleShape (
136 const ::com::sun::star::uno::Reference<
137 ::com::sun::star::drawing::XShape>& rxShape,
138 const ::com::sun::star::uno::Reference<
139 ::com::sun::star::accessibility::XAccessible>& rxParent,
140 const AccessibleShapeTreeInfo& rShapeTreeInfo,
141 sal_Int32 nIndex)
142 : AccessibleContextBase (rxParent,AccessibleRole::SHAPE),
143 mpChildrenManager(NULL),
144 mxShape (rxShape),
145 maShapeTreeInfo (rShapeTreeInfo),
146 mnIndex (nIndex),
147 m_nIndexInParent(-1),
148 mpText (NULL),
149 mpParent (NULL)
150 {
151 m_pShape = GetSdrObjectFromXShape(mxShape);
152 }
~AccessibleShape(void)153 AccessibleShape::~AccessibleShape (void)
154 {
155 if (mpChildrenManager != NULL)
156 delete mpChildrenManager;
157 if (mpText != NULL)
158 delete mpText;
159 OSL_TRACE ("~AccessibleShape");
160
161 // Unregistering from the various broadcasters should be unnecessary
162 // since this destructor would not have been called if one of the
163 // broadcasters would still hold a strong reference to this object.
164 }
165
166
167
168
Init(void)169 void AccessibleShape::Init (void)
170 {
171 // Update the OPAQUE and SELECTED shape.
172 UpdateStates ();
173
174 // Create a children manager when this shape has children of its own.
175 Reference<drawing::XShapes> xShapes (mxShape, uno::UNO_QUERY);
176 if (xShapes.is() && xShapes->getCount() > 0)
177 mpChildrenManager = new ChildrenManager (
178 this, xShapes, maShapeTreeInfo, *this);
179 if (mpChildrenManager != NULL)
180 mpChildrenManager->Update();
181
182 // Register at model as document::XEventListener.
183 if (maShapeTreeInfo.GetModelBroadcaster().is())
184 maShapeTreeInfo.GetModelBroadcaster()->addEventListener (
185 static_cast<document::XEventListener*>(this));
186
187 // Beware! Here we leave the paths of the UNO API and descend into the
188 // depths of the core. Necessary for makeing the edit engine
189 // accessible.
190 Reference<text::XText> xText (mxShape, uno::UNO_QUERY);
191 if (xText.is())
192 {
193 SdrView* pView = maShapeTreeInfo.GetSdrView ();
194 const Window* pWindow = maShapeTreeInfo.GetWindow ();
195 if (pView != NULL && pWindow != NULL && mxShape.is())
196 {
197 // #107948# Determine whether shape text is empty
198 SdrObject* pSdrObject = GetSdrObjectFromXShape(mxShape);
199 if( pSdrObject )
200 {
201 SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, pSdrObject );
202 OutlinerParaObject* pOutlinerParaObject = NULL;
203
204 if( pTextObj )
205 pOutlinerParaObject = pTextObj->GetEditOutlinerParaObject(); // Get the OutlinerParaObject if text edit is active
206
207 bool bOwnParaObj = pOutlinerParaObject != NULL;
208
209 if( !pOutlinerParaObject && pSdrObject )
210 pOutlinerParaObject = pSdrObject->GetOutlinerParaObject();
211
212 // create AccessibleTextHelper to handle this shape's text
213 if( !pOutlinerParaObject )
214 {
215 // empty text -> use proxy edit source to delay creation of EditEngine
216 ::std::auto_ptr<SvxEditSource> pEditSource( new AccessibleEmptyEditSource ( *pSdrObject, *pView, *pWindow) );
217 mpText = new AccessibleTextHelper( pEditSource );
218 }
219 else
220 {
221 // non-empty text -> use full-fledged edit source right away
222 ::std::auto_ptr<SvxEditSource> pEditSource( new SvxTextEditSource ( *pSdrObject, 0, *pView, *pWindow) );
223 mpText = new AccessibleTextHelper( pEditSource );
224 }
225
226 if( bOwnParaObj )
227 delete pOutlinerParaObject;
228
229 mpText->SetEventSource(this);
230 }
231 }
232 }
233 }
234
235
236
237
UpdateStates(void)238 void AccessibleShape::UpdateStates (void)
239 {
240 ::utl::AccessibleStateSetHelper* pStateSet =
241 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
242 if (pStateSet == NULL)
243 return;
244
245 // Set the opaque state for certain shape types when their fill style is
246 // solid.
247 bool bShapeIsOpaque = false;
248 switch (ShapeTypeHandler::Instance().GetTypeId (mxShape))
249 {
250 case DRAWING_PAGE:
251 case DRAWING_RECTANGLE:
252 case DRAWING_TEXT:
253 {
254 uno::Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY);
255 if (xSet.is())
256 {
257 try
258 {
259 drawing::FillStyle aFillStyle;
260 bShapeIsOpaque = ( xSet->getPropertyValue (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillStyle"))) >>= aFillStyle)
261 && aFillStyle == drawing::FillStyle_SOLID;
262 }
263 catch (::com::sun::star::beans::UnknownPropertyException&)
264 {
265 // Ignore.
266 }
267 }
268 }
269 }
270 if (bShapeIsOpaque)
271 pStateSet->AddState (AccessibleStateType::OPAQUE);
272 else
273 pStateSet->RemoveState (AccessibleStateType::OPAQUE);
274
275 // Set the selected state.
276 bool bShapeIsSelected = false;
277 // XXX fix_me this has to be done with an extra interface later on
278 if ( m_pShape && maShapeTreeInfo.GetSdrView() )
279 {
280 bShapeIsSelected = maShapeTreeInfo.GetSdrView()->IsObjMarked(m_pShape) == sal_True;
281 }
282
283 if (bShapeIsSelected)
284 pStateSet->AddState (AccessibleStateType::SELECTED);
285 else
286 pStateSet->RemoveState (AccessibleStateType::SELECTED);
287 }
GetStyle()288 ::rtl::OUString AccessibleShape::GetStyle()
289 {
290 return ShapeTypeHandler::CreateAccessibleBaseName( mxShape );
291 }
292
operator ==(const AccessibleShape & rShape)293 bool AccessibleShape::operator== (const AccessibleShape& rShape)
294 {
295 return this==&rShape;
296 }
297
298
299
300
SetState(sal_Int16 aState)301 sal_Bool AccessibleShape::SetState (sal_Int16 aState)
302 {
303 sal_Bool bStateHasChanged = sal_False;
304
305 if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
306 {
307 // Offer FOCUSED state to edit engine and detect whether the state
308 // changes.
309 sal_Bool bIsFocused = mpText->HaveFocus ();
310 mpText->SetFocus (sal_True);
311 bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
312 }
313 else
314 bStateHasChanged = AccessibleContextBase::SetState (aState);
315
316 return bStateHasChanged;
317 }
318
319
320
321
ResetState(sal_Int16 aState)322 sal_Bool AccessibleShape::ResetState (sal_Int16 aState)
323 {
324 sal_Bool bStateHasChanged = sal_False;
325
326 if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
327 {
328 // Try to remove FOCUSED state from the edit engine and detect
329 // whether the state changes.
330 sal_Bool bIsFocused = mpText->HaveFocus ();
331 mpText->SetFocus (sal_False);
332 bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
333 }
334 else
335 bStateHasChanged = AccessibleContextBase::ResetState (aState);
336
337 return bStateHasChanged;
338 }
339
340
341
342
GetState(sal_Int16 aState)343 sal_Bool AccessibleShape::GetState (sal_Int16 aState)
344 {
345 if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
346 {
347 // Just delegate the call to the edit engine. The state is not
348 // merged into the state set.
349 return mpText->HaveFocus();
350 }
351 else
352 return AccessibleContextBase::GetState (aState);
353 }
354 // Solution: OverWrite the parent's getAccessibleName method
getAccessibleName(void)355 ::rtl::OUString SAL_CALL AccessibleShape::getAccessibleName (void)
356 throw (::com::sun::star::uno::RuntimeException)
357 {
358 ThrowIfDisposed ();
359 if( m_pShape && m_pShape->GetTitle().Len() > 0)
360 return CreateAccessibleName() + ::rtl::OUString(' ') + m_pShape->GetTitle();
361 else
362 return CreateAccessibleName();
363 }
364
getAccessibleDescription(void)365 ::rtl::OUString SAL_CALL AccessibleShape::getAccessibleDescription (void)
366 throw (::com::sun::star::uno::RuntimeException)
367 {
368 ThrowIfDisposed ();
369 if( m_pShape && m_pShape->GetDescription().Len() > 0)
370 return m_pShape->GetDescription() ;
371 else
372 return OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
373 }
374 //===== XAccessibleContext ==================================================
375
376 /** The children of this shape come from two sources: The children from
377 group or scene shapes and the paragraphs of text.
378 */
379 sal_Int32 SAL_CALL
getAccessibleChildCount()380 AccessibleShape::getAccessibleChildCount ()
381 throw (::com::sun::star::uno::RuntimeException)
382 {
383 ThrowIfDisposed ();
384 sal_Int32 nChildCount = 0;
385
386 // Add the number of shapes that are children of this shape.
387 if (mpChildrenManager != NULL)
388 nChildCount += mpChildrenManager->GetChildCount ();
389 // Add the number text paragraphs.
390 if (mpText != NULL)
391 nChildCount += mpText->GetChildCount ();
392
393 return nChildCount;
394 }
395
396
397
398
399 /** Forward the request to the shape. Return the requested shape or throw
400 an exception for a wrong index.
401 */
402 uno::Reference<XAccessible> SAL_CALL
getAccessibleChild(sal_Int32 nIndex)403 AccessibleShape::getAccessibleChild (sal_Int32 nIndex)
404 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
405 {
406 ThrowIfDisposed ();
407
408 uno::Reference<XAccessible> xChild;
409
410 // Depending on the index decide whether to delegate this call to the
411 // children manager or the edit engine.
412 if ((mpChildrenManager != NULL)
413 && (nIndex < mpChildrenManager->GetChildCount()))
414 {
415 xChild = mpChildrenManager->GetChild (nIndex);
416 }
417 else if (mpText != NULL)
418 {
419 sal_Int32 nI = nIndex;
420 if (mpChildrenManager != NULL)
421 nI -= mpChildrenManager->GetChildCount();
422 xChild = mpText->GetChild (nI);
423 }
424 else
425 throw lang::IndexOutOfBoundsException (
426 ::rtl::OUString::createFromAscii ("shape has no child with index ")
427 + rtl::OUString::valueOf(nIndex),
428 static_cast<uno::XWeak*>(this));
429
430 return xChild;
431 }
432
433 uno::Reference<XAccessibleRelationSet> SAL_CALL
getAccessibleRelationSet(void)434 AccessibleShape::getAccessibleRelationSet (void)
435 throw (::com::sun::star::uno::RuntimeException)
436 {
437 ::osl::MutexGuard aGuard (maMutex);
438 ::utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper;
439
440 //this mxshape is the captioned shape, only for sw
441 if (pRelationSet != NULL)
442 {
443 uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
444 aSequence[0] = mpParent->GetAccessibleCaption(mxShape);
445 if(aSequence[0].get())
446 {
447 pRelationSet->AddRelation(
448 AccessibleRelation( AccessibleRelationType::DESCRIBED_BY, aSequence ) );
449 }
450 return uno::Reference<XAccessibleRelationSet> (
451 new ::utl::AccessibleRelationSetHelper (*pRelationSet));
452 }
453 else
454 {
455 return uno::Reference<XAccessibleRelationSet>(NULL);
456 }
457 }
458
459 /** Return a copy of the state set.
460 Possible states are:
461 ENABLED
462 SHOWING
463 VISIBLE
464 */
465 uno::Reference<XAccessibleStateSet> SAL_CALL
getAccessibleStateSet(void)466 AccessibleShape::getAccessibleStateSet (void)
467 throw (::com::sun::star::uno::RuntimeException)
468 {
469 ::osl::MutexGuard aGuard (maMutex);
470 Reference<XAccessibleStateSet> xStateSet;
471
472 if (rBHelper.bDisposed || mpText == NULL)
473 // Return a minimal state set that only contains the DEFUNC state.
474 {
475 xStateSet = AccessibleContextBase::getAccessibleStateSet ();
476 ::utl::AccessibleStateSetHelper* pStateSet =
477 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
478 ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent();
479 if( xTempAcc.is() )
480 {
481 ::com::sun::star::uno::Reference<XAccessibleContext>
482 xTempAccContext = xTempAcc->getAccessibleContext();
483 if( xTempAccContext.is() )
484 {
485 ::com::sun::star::uno::Reference<XAccessibleStateSet> rState =
486 xTempAccContext->getAccessibleStateSet();
487 if( rState.is() ) {
488 com::sun::star::uno::Sequence<short> pStates = rState->getStates();
489 int count = pStates.getLength();
490 for( int iIndex = 0;iIndex < count;iIndex++ )
491 {
492 if( pStates[iIndex] == AccessibleStateType::EDITABLE )
493 {
494 pStateSet->AddState (AccessibleStateType::EDITABLE);
495 pStateSet->AddState (AccessibleStateType::RESIZABLE);
496 pStateSet->AddState (AccessibleStateType::MOVEABLE);
497 break;
498 }
499 }
500 }
501 }
502 }
503 xStateSet = Reference<XAccessibleStateSet>(
504 new ::utl::AccessibleStateSetHelper (*pStateSet));
505 }else
506 {
507 ::utl::AccessibleStateSetHelper* pStateSet =
508 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
509
510 if (pStateSet != NULL)
511 {
512 // Merge current FOCUSED state from edit engine.
513 if (mpText != NULL)
514 {
515 if (mpText->HaveFocus())
516 pStateSet->AddState (AccessibleStateType::FOCUSED);
517 else
518 pStateSet->RemoveState (AccessibleStateType::FOCUSED);
519 }
520 //Solution:Just when the document is not read-only,set states EDITABLE,RESIZABLE,MOVEABLE
521 ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent();
522 if( xTempAcc.is() )
523 {
524 ::com::sun::star::uno::Reference<XAccessibleContext>
525 xTempAccContext = xTempAcc->getAccessibleContext();
526 if( xTempAccContext.is() )
527 {
528 ::com::sun::star::uno::Reference<XAccessibleStateSet> rState =
529 xTempAccContext->getAccessibleStateSet();
530 if( rState.is() ) {
531 com::sun::star::uno::Sequence<short> pStates = rState->getStates();
532 int count = pStates.getLength();
533 for( int iIndex = 0;iIndex < count;iIndex++ )
534 {
535 if( pStates[iIndex] == AccessibleStateType::EDITABLE )
536 {
537 pStateSet->AddState (AccessibleStateType::EDITABLE);
538 pStateSet->AddState (AccessibleStateType::RESIZABLE);
539 pStateSet->AddState (AccessibleStateType::MOVEABLE);
540 break;
541 }
542 }
543 }
544 }
545 }
546 // Create a copy of the state set that may be modified by the
547 // caller without affecting the current state set.
548 xStateSet = Reference<XAccessibleStateSet>(
549 new ::utl::AccessibleStateSetHelper (*pStateSet));
550 }
551 }
552 UpdateDocumentAllSelState(xStateSet);
553 return xStateSet;
554 }
555
556
557
558
559 //===== XAccessibleComponent ================================================
560
561 /** The implementation below is at the moment straightforward. It iterates
562 over all children (and thereby instances all children which have not
563 been already instatiated) until a child covering the specifed point is
564 found.
565 This leaves room for improvement. For instance, first iterate only over
566 the already instantiated children and only if no match is found
567 instantiate the remaining ones.
568 */
569 uno::Reference<XAccessible > SAL_CALL
getAccessibleAtPoint(const awt::Point & aPoint)570 AccessibleShape::getAccessibleAtPoint (
571 const awt::Point& aPoint)
572 throw (uno::RuntimeException)
573 {
574 ::osl::MutexGuard aGuard (maMutex);
575
576 sal_Int32 nChildCount = getAccessibleChildCount ();
577 for (sal_Int32 i=0; i<nChildCount; ++i)
578 {
579 Reference<XAccessible> xChild (getAccessibleChild (i));
580 if (xChild.is())
581 {
582 Reference<XAccessibleComponent> xChildComponent (
583 xChild->getAccessibleContext(), uno::UNO_QUERY);
584 if (xChildComponent.is())
585 {
586 awt::Rectangle aBBox (xChildComponent->getBounds());
587 if ( (aPoint.X >= aBBox.X)
588 && (aPoint.Y >= aBBox.Y)
589 && (aPoint.X < aBBox.X+aBBox.Width)
590 && (aPoint.Y < aBBox.Y+aBBox.Height) )
591 return xChild;
592 }
593 }
594 }
595
596 // Have not found a child under the given point. Returning empty
597 // reference to indicate this.
598 return uno::Reference<XAccessible>();
599 }
600
601
602
603
getBounds(void)604 awt::Rectangle SAL_CALL AccessibleShape::getBounds (void)
605 throw (::com::sun::star::uno::RuntimeException)
606 {
607 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
608 ::osl::MutexGuard aGuard (maMutex);
609
610 ThrowIfDisposed ();
611 awt::Rectangle aBoundingBox;
612 if ( mxShape.is() )
613 {
614
615 static const OUString sBoundRectName (
616 RTL_CONSTASCII_USTRINGPARAM("BoundRect"));
617 static const OUString sAnchorPositionName (
618 RTL_CONSTASCII_USTRINGPARAM("AnchorPosition"));
619
620 // Get the shape's bounding box in internal coordinates (in 100th of
621 // mm). Use the property BoundRect. Only if that is not supported ask
622 // the shape for its position and size directly.
623 Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY);
624 Reference<beans::XPropertySetInfo> xSetInfo;
625 bool bFoundBoundRect = false;
626 if (xSet.is())
627 {
628 xSetInfo = xSet->getPropertySetInfo ();
629 if (xSetInfo.is())
630 {
631 if (xSetInfo->hasPropertyByName (sBoundRectName))
632 {
633 try
634 {
635 uno::Any aValue = xSet->getPropertyValue (sBoundRectName);
636 aValue >>= aBoundingBox;
637 bFoundBoundRect = true;
638 }
639 catch (beans::UnknownPropertyException e)
640 {
641 // Handled below (bFoundBoundRect stays false).
642 }
643 }
644 else
645 OSL_TRACE (" no property BoundRect");
646 }
647 }
648
649 // Fallback when there is no BoundRect Property.
650 if ( ! bFoundBoundRect )
651 {
652 awt::Point aPosition (mxShape->getPosition());
653 awt::Size aSize (mxShape->getSize());
654 aBoundingBox = awt::Rectangle (
655 aPosition.X, aPosition.Y,
656 aSize.Width, aSize.Height);
657
658 // While BoundRects have absolute positions, the position returned
659 // by XPosition::getPosition is relative. Get the anchor position
660 // (usually not (0,0) for Writer shapes).
661 if (xSetInfo.is())
662 {
663 if (xSetInfo->hasPropertyByName (sAnchorPositionName))
664 {
665 uno::Any aPos = xSet->getPropertyValue (sAnchorPositionName);
666 awt::Point aAnchorPosition;
667 aPos >>= aAnchorPosition;
668 aBoundingBox.X += aAnchorPosition.X;
669 aBoundingBox.Y += aAnchorPosition.Y;
670 }
671 }
672 }
673
674 // Transform coordinates from internal to pixel.
675 if (maShapeTreeInfo.GetViewForwarder() == NULL)
676 throw uno::RuntimeException (::rtl::OUString (
677 RTL_CONSTASCII_USTRINGPARAM(
678 "AccessibleShape has no valid view forwarder")),
679 static_cast<uno::XWeak*>(this));
680 ::Size aPixelSize = maShapeTreeInfo.GetViewForwarder()->LogicToPixel (
681 ::Size (aBoundingBox.Width, aBoundingBox.Height));
682 ::Point aPixelPosition = maShapeTreeInfo.GetViewForwarder()->LogicToPixel (
683 ::Point (aBoundingBox.X, aBoundingBox.Y));
684
685 // Clip the shape's bounding box with the bounding box of its parent.
686 Reference<XAccessibleComponent> xParentComponent (
687 getAccessibleParent(), uno::UNO_QUERY);
688 if (xParentComponent.is())
689 {
690 // Make the coordinates relative to the parent.
691 awt::Point aParentLocation (xParentComponent->getLocationOnScreen());
692 int x = aPixelPosition.getX() - aParentLocation.X;
693 int y = aPixelPosition.getY() - aParentLocation.Y;
694
695 /* // The following block is a workarround for bug #99889# (property
696 // BoundRect returnes coordinates relative to document window
697 // instead of absolute coordinates for shapes in Writer). Has to
698 // be removed as soon as bug is fixed.
699
700 // Use a non-null anchor position as flag that the shape is in a
701 // Writer document.
702 if (xSetInfo.is())
703 if (xSetInfo->hasPropertyByName (sAnchorPositionName))
704 {
705 uno::Any aPos = xSet->getPropertyValue (sAnchorPositionName);
706 awt::Point aAnchorPosition;
707 aPos >>= aAnchorPosition;
708 if (aAnchorPosition.X > 0)
709 {
710 x = aPixelPosition.getX();
711 y = aPixelPosition.getY();
712 }
713 }
714 // End of workarround.
715 */
716 // Clip with parent (with coordinates relative to itself).
717 ::Rectangle aBBox (
718 x, y, x + aPixelSize.getWidth(), y + aPixelSize.getHeight());
719 awt::Size aParentSize (xParentComponent->getSize());
720 ::Rectangle aParentBBox (0,0, aParentSize.Width, aParentSize.Height);
721 aBBox = aBBox.GetIntersection (aParentBBox);
722 aBoundingBox = awt::Rectangle (
723 aBBox.getX(),
724 aBBox.getY(),
725 aBBox.getWidth(),
726 aBBox.getHeight());
727 }
728 else
729 {
730 OSL_TRACE ("parent does not support component");
731 aBoundingBox = awt::Rectangle (
732 aPixelPosition.getX(), aPixelPosition.getY(),
733 aPixelSize.getWidth(), aPixelSize.getHeight());
734 }
735 }
736
737 return aBoundingBox;
738 }
739
740
741
742
getLocation(void)743 awt::Point SAL_CALL AccessibleShape::getLocation (void)
744 throw (::com::sun::star::uno::RuntimeException)
745 {
746 ThrowIfDisposed ();
747 awt::Rectangle aBoundingBox (getBounds());
748 return awt::Point (aBoundingBox.X, aBoundingBox.Y);
749 }
750
751
752
753
getLocationOnScreen(void)754 awt::Point SAL_CALL AccessibleShape::getLocationOnScreen (void)
755 throw (::com::sun::star::uno::RuntimeException)
756 {
757 ThrowIfDisposed ();
758
759 // Get relative position...
760 awt::Point aLocation (getLocation ());
761
762 // ... and add absolute position of the parent.
763 uno::Reference<XAccessibleComponent> xParentComponent (
764 getAccessibleParent(), uno::UNO_QUERY);
765 if (xParentComponent.is())
766 {
767 awt::Point aParentLocation (xParentComponent->getLocationOnScreen());
768 aLocation.X += aParentLocation.X;
769 aLocation.Y += aParentLocation.Y;
770 }
771 else
772 OSL_TRACE ("getLocation: parent does not support XAccessibleComponent");
773 return aLocation;
774 }
775
776
777
778
getSize(void)779 awt::Size SAL_CALL AccessibleShape::getSize (void)
780 throw (uno::RuntimeException)
781 {
782 ThrowIfDisposed ();
783 awt::Rectangle aBoundingBox (getBounds());
784 return awt::Size (aBoundingBox.Width, aBoundingBox.Height);
785 }
786
787
788
789
getForeground(void)790 sal_Int32 SAL_CALL AccessibleShape::getForeground (void)
791 throw (::com::sun::star::uno::RuntimeException)
792 {
793 ThrowIfDisposed ();
794 sal_Int32 nColor (0x0ffffffL);
795
796 try
797 {
798 uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY);
799 if (aSet.is())
800 {
801 uno::Any aColor;
802 aColor = aSet->getPropertyValue (OUString::createFromAscii ("LineColor"));
803 aColor >>= nColor;
804 }
805 }
806 catch (::com::sun::star::beans::UnknownPropertyException)
807 {
808 // Ignore exception and return default color.
809 }
810 return nColor;
811 }
812
813
814
815
getBackground(void)816 sal_Int32 SAL_CALL AccessibleShape::getBackground (void)
817 throw (::com::sun::star::uno::RuntimeException)
818 {
819 ThrowIfDisposed ();
820 sal_Int32 nColor (0L);
821
822 try
823 {
824 uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY);
825 if (aSet.is())
826 {
827 uno::Any aColor;
828 aColor = aSet->getPropertyValue (OUString::createFromAscii ("FillColor"));
829 aColor >>= nColor;
830 aColor = aSet->getPropertyValue (OUString::createFromAscii ("FillTransparence"));
831 short nTrans=0;
832 aColor >>= nTrans;
833 Color crBk(nColor);
834 if (nTrans == 0 )
835 {
836 crBk.SetTransparency(0xff);
837 }
838 else
839 {
840 nTrans = short(256 - nTrans / 100. * 256);
841 crBk.SetTransparency(sal_uInt8(nTrans));
842 }
843 nColor = crBk.GetColor();
844 }
845 }
846 catch (::com::sun::star::beans::UnknownPropertyException)
847 {
848 // Ignore exception and return default color.
849 }
850 return nColor;
851 }
852
853
854
855
856 //===== XAccessibleEventBroadcaster =========================================
857
addEventListener(const Reference<XAccessibleEventListener> & rxListener)858 void SAL_CALL AccessibleShape::addEventListener (
859 const Reference<XAccessibleEventListener >& rxListener)
860 throw (uno::RuntimeException)
861 {
862 if (rBHelper.bDisposed || rBHelper.bInDispose)
863 {
864 uno::Reference<uno::XInterface> xThis (
865 (lang::XComponent *)this, uno::UNO_QUERY);
866 rxListener->disposing (lang::EventObject (xThis));
867 }
868 else
869 {
870 AccessibleContextBase::addEventListener (rxListener);
871 if (mpText != NULL)
872 mpText->AddEventListener (rxListener);
873 }
874 }
875
876
877
878
removeEventListener(const Reference<XAccessibleEventListener> & rxListener)879 void SAL_CALL AccessibleShape::removeEventListener (
880 const Reference<XAccessibleEventListener >& rxListener)
881 throw (uno::RuntimeException)
882 {
883 AccessibleContextBase::removeEventListener (rxListener);
884 if (mpText != NULL)
885 mpText->RemoveEventListener (rxListener);
886 }
887
888
889
890
891 //===== XInterface ==========================================================
892
893 com::sun::star::uno::Any SAL_CALL
queryInterface(const com::sun::star::uno::Type & rType)894 AccessibleShape::queryInterface (const com::sun::star::uno::Type & rType)
895 throw (::com::sun::star::uno::RuntimeException)
896 {
897 ::com::sun::star::uno::Any aReturn = AccessibleContextBase::queryInterface (rType);
898 if ( ! aReturn.hasValue())
899 aReturn = ::cppu::queryInterface (rType,
900 static_cast<XAccessibleComponent*>(this),
901 static_cast<XAccessibleExtendedComponent*>(this),
902 static_cast< ::com::sun::star::accessibility::XAccessibleSelection* >(this),
903
904 static_cast< ::com::sun::star::accessibility::XAccessibleExtendedAttributes* >(this),
905 static_cast<lang::XEventListener*>(this),
906 static_cast<document::XEventListener*>(this),
907 static_cast<lang::XUnoTunnel*>(this),
908 static_cast<XAccessibleGroupPosition*>(this),
909 static_cast<XAccessibleHypertext*>(this)
910 );
911 return aReturn;
912 }
913
914
915
916
917 void SAL_CALL
acquire(void)918 AccessibleShape::acquire (void)
919 throw ()
920 {
921 AccessibleContextBase::acquire ();
922 }
923
924
925
926
927 void SAL_CALL
release(void)928 AccessibleShape::release (void)
929 throw ()
930 {
931 AccessibleContextBase::release ();
932 }
933 //
934 //===== XAccessibleSelection ============================================
935 //
936
937 //--------------------------------------------------------------------------------
selectAccessibleChild(sal_Int32)938 void SAL_CALL AccessibleShape::selectAccessibleChild( sal_Int32 )
939 throw ( IndexOutOfBoundsException, RuntimeException )
940 {
941 }
942
943 //----------------------------------------------------------------------------------
isAccessibleChildSelected(sal_Int32 nChildIndex)944 sal_Bool SAL_CALL AccessibleShape::isAccessibleChildSelected( sal_Int32 nChildIndex )
945 throw ( IndexOutOfBoundsException,
946 RuntimeException )
947 {
948 uno::Reference<XAccessible> xAcc = getAccessibleChild( nChildIndex );
949 uno::Reference<XAccessibleContext> xContext;
950 if( xAcc.is() )
951 {
952 xContext = xAcc->getAccessibleContext();
953 }
954
955 if( xContext.is() )
956 {
957 if( xContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
958 {
959 uno::Reference< ::com::sun::star::accessibility::XAccessibleText >
960 xText(xAcc, uno::UNO_QUERY);
961 if( xText.is() )
962 {
963 if( xText->getSelectionStart() >= 0 ) return sal_True;
964 }
965 }
966 else if( xContext->getAccessibleRole() == AccessibleRole::SHAPE )
967 {
968 Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet();
969 if( !pRState.is() )
970 return sal_False;
971
972 uno::Sequence<short> pStates = pRState->getStates();
973 int nCount = pStates.getLength();
974 for( int i = 0; i < nCount; i++ )
975 {
976 if(pStates[i] == AccessibleStateType::SELECTED)
977 return sal_True;
978 }
979 return sal_False;
980 }
981 }
982
983 return sal_False;
984 }
985
986 //---------------------------------------------------------------------
clearAccessibleSelection()987 void SAL_CALL AccessibleShape::clearAccessibleSelection( )
988 throw ( RuntimeException )
989 {
990 }
991
992 //-------------------------------------------------------------------------
selectAllAccessibleChildren()993 void SAL_CALL AccessibleShape::selectAllAccessibleChildren( )
994 throw ( RuntimeException )
995 {
996 }
997
998 //----------------------------------------------------------------------------
getSelectedAccessibleChildCount()999 sal_Int32 SAL_CALL AccessibleShape::getSelectedAccessibleChildCount()
1000 throw ( RuntimeException )
1001 {
1002 sal_Int32 nCount = 0;
1003 sal_Int32 TotalCount = getAccessibleChildCount();
1004 for( sal_Int32 i = 0; i < TotalCount; i++ )
1005 if( isAccessibleChildSelected(i) ) nCount++;
1006
1007 return nCount;
1008 }
1009
1010 //--------------------------------------------------------------------------------------
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)1011 Reference<XAccessible> SAL_CALL AccessibleShape::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
1012 throw ( IndexOutOfBoundsException, RuntimeException)
1013 {
1014 if ( nSelectedChildIndex > getSelectedAccessibleChildCount() )
1015 throw IndexOutOfBoundsException();
1016 sal_Int32 i1, i2;
1017 for( i1 = 0, i2 = 0; i1 < getAccessibleChildCount(); i1++ )
1018 if( isAccessibleChildSelected(i1) )
1019 {
1020 if( i2 == nSelectedChildIndex )
1021 return getAccessibleChild( i1 );
1022 i2++;
1023 }
1024 return Reference<XAccessible>();
1025 }
1026
1027 //----------------------------------------------------------------------------------
deselectAccessibleChild(sal_Int32)1028 void SAL_CALL AccessibleShape::deselectAccessibleChild( sal_Int32 )
1029 throw ( IndexOutOfBoundsException,
1030 RuntimeException )
1031 {
1032
1033 }
1034
1035 //===== XAccessibleExtendedAttributes ========================================================
getExtendedAttributes()1036 uno::Any SAL_CALL AccessibleShape::getExtendedAttributes()
1037 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1038 {
1039 uno::Any strRet;
1040 ::rtl::OUString style;
1041 if( getAccessibleRole() != AccessibleRole::SHAPE ) return strRet;
1042 if( m_pShape )
1043 {
1044 //style = ::rtl::OUString::createFromAscii("style=");
1045 style = ::rtl::OUString::createFromAscii("style:");
1046 style += GetStyle();
1047 }
1048 style += ::rtl::OUString::createFromAscii(";");
1049 strRet <<= style;
1050 return strRet;
1051 }
1052 //===== XServiceInfo ========================================================
1053
1054 ::rtl::OUString SAL_CALL
getImplementationName(void)1055 AccessibleShape::getImplementationName (void)
1056 throw (::com::sun::star::uno::RuntimeException)
1057 {
1058 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleShape"));
1059 }
1060
1061
1062
1063
1064 uno::Sequence<OUString> SAL_CALL
getSupportedServiceNames(void)1065 AccessibleShape::getSupportedServiceNames (void)
1066 throw (::com::sun::star::uno::RuntimeException)
1067 {
1068 ThrowIfDisposed ();
1069 // Get list of supported service names from base class...
1070 uno::Sequence<OUString> aServiceNames =
1071 AccessibleContextBase::getSupportedServiceNames();
1072 sal_Int32 nCount (aServiceNames.getLength());
1073
1074 // ...and add additional names.
1075 aServiceNames.realloc (nCount + 1);
1076 static const OUString sAdditionalServiceName (RTL_CONSTASCII_USTRINGPARAM(
1077 "com.sun.star.drawing.AccessibleShape"));
1078 aServiceNames[nCount] = sAdditionalServiceName;
1079
1080 return aServiceNames;
1081 }
1082
1083
1084
1085
1086
1087 //===== XTypeProvider ===================================================
1088
1089 uno::Sequence<uno::Type> SAL_CALL
getTypes(void)1090 AccessibleShape::getTypes (void)
1091 throw (uno::RuntimeException)
1092 {
1093 ThrowIfDisposed ();
1094 // Get list of types from the context base implementation, ...
1095 uno::Sequence<uno::Type> aTypeList (AccessibleContextBase::getTypes());
1096 // ... get list of types from component base implementation, ...
1097 uno::Sequence<uno::Type> aComponentTypeList (AccessibleComponentBase::getTypes());
1098 // ... define local types, ...
1099 const uno::Type aLangEventListenerType =
1100 ::getCppuType((const uno::Reference<lang::XEventListener>*)0);
1101 const uno::Type aDocumentEventListenerType =
1102 ::getCppuType((const uno::Reference<document::XEventListener>*)0);
1103 const uno::Type aUnoTunnelType =
1104 ::getCppuType((const uno::Reference<lang::XUnoTunnel>*)0);
1105 // const uno::Type aStateSetType =
1106 // ::getCppuType((const uno::Reference<XAccessibleStateSet>*)0);
1107
1108 // ... and merge them all into one list.
1109 sal_Int32 nTypeCount (aTypeList.getLength()),
1110 nComponentTypeCount (aComponentTypeList.getLength());
1111 int i;
1112
1113 aTypeList.realloc (nTypeCount + nComponentTypeCount + 3);
1114
1115 for (i=0; i<nComponentTypeCount; i++)
1116 aTypeList[nTypeCount + i] = aComponentTypeList[i];
1117
1118 aTypeList[nTypeCount + i++ ] = aLangEventListenerType;
1119 aTypeList[nTypeCount + i++ ] = aDocumentEventListenerType;
1120 aTypeList[nTypeCount + i ] = aUnoTunnelType;
1121
1122 return aTypeList;
1123 }
1124
1125
1126
1127
1128 //===== lang::XEventListener ================================================
1129
1130 /** Disposing calls are accepted only from the model: Just reset the
1131 reference to the model in the shape tree info. Otherwise this object
1132 remains functional.
1133 */
1134 void SAL_CALL
disposing(const lang::EventObject & aEvent)1135 AccessibleShape::disposing (const lang::EventObject& aEvent)
1136 throw (uno::RuntimeException)
1137 {
1138 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
1139 ::osl::MutexGuard aGuard (maMutex);
1140
1141 try
1142 {
1143 if (aEvent.Source == maShapeTreeInfo.GetModelBroadcaster())
1144 {
1145 // Remove reference to model broadcaster to allow it to pass
1146 // away.
1147 maShapeTreeInfo.SetModelBroadcaster(NULL);
1148 }
1149
1150 }
1151 catch (uno::RuntimeException e)
1152 {
1153 OSL_TRACE ("caught exception while disposing");
1154 }
1155 }
1156
1157
1158
1159
1160 //===== document::XEventListener ============================================
1161
1162 void SAL_CALL
notifyEvent(const document::EventObject & rEventObject)1163 AccessibleShape::notifyEvent (const document::EventObject& rEventObject)
1164 throw (uno::RuntimeException)
1165 {
1166 static const OUString sShapeModified (
1167 RTL_CONSTASCII_USTRINGPARAM("ShapeModified"));
1168
1169 // First check if the event is for us.
1170 uno::Reference<drawing::XShape> xShape (
1171 rEventObject.Source, uno::UNO_QUERY);
1172 if ( xShape.get() == mxShape.get() )
1173 {
1174 if (rEventObject.EventName.equals (sShapeModified))
1175 {
1176 //Need to update text children when receiving ShapeModified hint when exiting edit mode for text box
1177 if (mpText)
1178 mpText->UpdateChildren();
1179
1180
1181 // Some property of a shape has been modified. Send an event
1182 // that indicates a change of the visible data to all listeners.
1183 CommitChange (
1184 AccessibleEventId::VISIBLE_DATA_CHANGED,
1185 uno::Any(),
1186 uno::Any());
1187
1188 // Name and Description may have changed. Update the local
1189 // values accordingly.
1190 UpdateNameAndDescription();
1191 }
1192 }
1193 }
1194
1195
1196
1197
1198 //===== lang::XUnoTunnel ================================================
1199
1200 const uno::Sequence< sal_Int8 >&
getUnoTunnelImplementationId()1201 AccessibleShape::getUnoTunnelImplementationId()
1202 throw()
1203 {
1204 static uno::Sequence< sal_Int8 >* pSeq = 0;
1205
1206 if( !pSeq )
1207 {
1208 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
1209
1210 if( !pSeq )
1211 {
1212 static uno::Sequence< sal_Int8 > aSeq( 16 );
1213 rtl_createUuid( (sal_uInt8*) aSeq.getArray(), 0, sal_True );
1214 pSeq = &aSeq;
1215 }
1216 }
1217
1218 return( *pSeq );
1219 }
1220
1221 //------------------------------------------------------------------------------
1222 AccessibleShape*
getImplementation(const uno::Reference<uno::XInterface> & rxIFace)1223 AccessibleShape::getImplementation( const uno::Reference< uno::XInterface >& rxIFace )
1224 throw()
1225 {
1226 uno::Reference< lang::XUnoTunnel > xTunnel( rxIFace, uno::UNO_QUERY );
1227 AccessibleShape* pReturn = NULL;
1228
1229 if( xTunnel.is() )
1230 pReturn = reinterpret_cast< AccessibleShape* >( xTunnel->getSomething( getUnoTunnelImplementationId() ) );
1231
1232 return( pReturn );
1233 }
1234
1235 //------------------------------------------------------------------------------
1236 sal_Int64 SAL_CALL
getSomething(const uno::Sequence<sal_Int8> & rIdentifier)1237 AccessibleShape::getSomething( const uno::Sequence< sal_Int8 >& rIdentifier )
1238 throw(uno::RuntimeException)
1239 {
1240 sal_Int64 nReturn( 0 );
1241
1242 if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( getUnoTunnelImplementationId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) )
1243 nReturn = reinterpret_cast< sal_Int64 >( this );
1244
1245 return( nReturn );
1246 }
1247
1248 //===== IAccessibleViewForwarderListener ====================================
1249
ViewForwarderChanged(ChangeType aChangeType,const IAccessibleViewForwarder * pViewForwarder)1250 void AccessibleShape::ViewForwarderChanged (ChangeType aChangeType,
1251 const IAccessibleViewForwarder* pViewForwarder)
1252 {
1253 // Inform all listeners that the graphical representation (i.e. size
1254 // and/or position) of the shape has changed.
1255 CommitChange (AccessibleEventId::VISIBLE_DATA_CHANGED,
1256 uno::Any(),
1257 uno::Any());
1258
1259 // Tell children manager of the modified view forwarder.
1260 if (mpChildrenManager != NULL)
1261 mpChildrenManager->ViewForwarderChanged (aChangeType, pViewForwarder);
1262
1263 // update our children that our screen position might have changed
1264 if( mpText )
1265 mpText->UpdateChildren();
1266 }
1267
1268
1269
1270
1271 //===== protected internal ==================================================
1272 /// Set this object's name if is different to the current name.
1273 ::rtl::OUString
CreateAccessibleBaseName(void)1274 AccessibleShape::CreateAccessibleBaseName (void)
1275 throw (::com::sun::star::uno::RuntimeException)
1276 {
1277 return ShapeTypeHandler::CreateAccessibleBaseName( mxShape );
1278 }
1279
1280
1281 ::rtl::OUString
CreateAccessibleName(void)1282 AccessibleShape::CreateAccessibleName (void)
1283 throw (::com::sun::star::uno::RuntimeException)
1284 {
1285 //OUString sName (CreateAccessibleBaseName());
1286 OUString sName;
1287 sName = GetFullAccessibleName(this);
1288 return sName;
1289 }
1290
1291 ::rtl::OUString
GetFullAccessibleName(AccessibleShape * shape)1292 AccessibleShape::GetFullAccessibleName (AccessibleShape *shape)
1293 throw (::com::sun::star::uno::RuntimeException)
1294 {
1295 OUString sName (shape->CreateAccessibleBaseName());
1296 // Append the shape's index to the name to disambiguate between shapes
1297 // of the same type. If such an index where not given to the
1298 // constructor then use the z-order instead. If even that does not exist
1299 // we throw an exception.
1300 //long nIndex = mnIndex;
1301 //if (nIndex == -1)
1302 //{
1303 // try
1304 // {
1305 // uno::Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY);
1306 // if (xSet.is())
1307 // {
1308 // uno::Any aZOrder (xSet->getPropertyValue (::rtl::OUString::createFromAscii ("ZOrder")));
1309 // aZOrder >>= nIndex;
1310
1311 // // Add one to be not zero based.
1312 // nIndex += 1;
1313 // }
1314 // }
1315 // catch (beans::UnknownPropertyException)
1316 // {
1317 // // We throw our own exception that is a bit more informative.
1318 // throw uno::RuntimeException (::rtl::OUString (
1319 // RTL_CONSTASCII_USTRINGPARAM("AccessibleShape has invalid index and no ZOrder property")),
1320 // static_cast<uno::XWeak*>(this));
1321 // }
1322
1323 //}
1324
1325 //// Put a space between name and index because of Gnopernicus otherwise
1326 //// spells the name.
1327 //sName += OUString (RTL_CONSTASCII_USTRINGPARAM(" ")) + OUString::valueOf (nIndex);
1328
1329 //return sName;
1330
1331 XubString nameStr;
1332 if(shape->m_pShape)
1333 nameStr = shape->m_pShape->GetName();
1334 if(nameStr.Len() == 0)
1335 {
1336 sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
1337 }
1338 else
1339 {
1340 sName = nameStr;
1341 }
1342 /*
1343 sal_Int32 nChildCount = shape->getAccessibleChildCount();
1344 if(nChildCount > 0)
1345 {
1346 for (sal_Int32 i=0; i<nChildCount; ++i)
1347 {
1348 Reference<XAccessible> xChild (shape->getAccessibleChild (i));
1349 if (xChild.is())
1350 {
1351 uno::Reference <XAccessibleContext> xChildContext(xChild->getAccessibleContext());
1352 if (xChildContext->getAccessibleRole() == AccessibleRole::PARAGRAPH)
1353 {
1354 uno::Reference<XAccessibleText> xText = uno::Reference<XAccessibleText> ( xChild, uno::UNO_QUERY );
1355 sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " )) + xText->getText();
1356 }
1357 else if (xChildContext->getAccessibleRole() == AccessibleRole::SHAPE)
1358 {
1359 sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " )) + GetFullAccessibleName(static_cast< AccessibleShape*>( xChild.get()));
1360 }
1361 }
1362 }
1363 }
1364 */
1365 //Solution:If the new produced name if not the same with last,notify name changed
1366 // Event
1367 if( aAccName != sName && aAccName.getLength() != 0 )
1368 {
1369 uno::Any aOldValue, aNewValue;
1370 aOldValue <<= aAccName;
1371 aNewValue <<= sName;
1372 CommitChange(
1373 AccessibleEventId::NAME_CHANGED,
1374 aNewValue,
1375 aOldValue);
1376 }
1377 aAccName = sName;
1378 return sName;
1379 }
1380 ::rtl::OUString
CreateAccessibleDescription(void)1381 AccessibleShape::CreateAccessibleDescription (void)
1382 throw (::com::sun::star::uno::RuntimeException)
1383 {
1384 DescriptionGenerator aDG (mxShape);
1385 aDG.Initialize (CreateAccessibleBaseName());
1386 switch (ShapeTypeHandler::Instance().GetTypeId (mxShape))
1387 {
1388 case DRAWING_3D_CUBE:
1389 case DRAWING_3D_EXTRUDE:
1390 case DRAWING_3D_LATHE:
1391 case DRAWING_3D_SPHERE:
1392 aDG.Add3DProperties ();
1393 break;
1394
1395 case DRAWING_3D_SCENE:
1396 case DRAWING_GROUP:
1397 case DRAWING_PAGE:
1398 // No further information is appended.
1399 break;
1400
1401 case DRAWING_CAPTION:
1402 case DRAWING_CLOSED_BEZIER:
1403 case DRAWING_CLOSED_FREEHAND:
1404 case DRAWING_ELLIPSE:
1405 case DRAWING_POLY_POLYGON:
1406 case DRAWING_POLY_POLYGON_PATH:
1407 case DRAWING_RECTANGLE:
1408 aDG.AddLineProperties ();
1409 aDG.AddFillProperties ();
1410 break;
1411
1412 case DRAWING_CONNECTOR:
1413 case DRAWING_LINE:
1414 case DRAWING_MEASURE:
1415 case DRAWING_OPEN_BEZIER:
1416 case DRAWING_OPEN_FREEHAND:
1417 case DRAWING_POLY_LINE:
1418 case DRAWING_POLY_LINE_PATH:
1419 aDG.AddLineProperties ();
1420 break;
1421
1422 case DRAWING_CONTROL:
1423 aDG.AddProperty (OUString::createFromAscii ("ControlBackground"),
1424 DescriptionGenerator::COLOR,
1425 OUString());
1426 aDG.AddProperty (OUString::createFromAscii ("ControlBorder"),
1427 DescriptionGenerator::INTEGER,
1428 OUString());
1429 break;
1430
1431 case DRAWING_TEXT:
1432 aDG.AddTextProperties ();
1433 break;
1434
1435 default:
1436 aDG.Initialize (::rtl::OUString (
1437 RTL_CONSTASCII_USTRINGPARAM("Unknown accessible shape")));
1438 uno::Reference<drawing::XShapeDescriptor> xDescriptor (mxShape, uno::UNO_QUERY);
1439 if (xDescriptor.is())
1440 {
1441 aDG.AppendString (::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("service name=")));
1442 aDG.AppendString (xDescriptor->getShapeType());
1443 }
1444 }
1445
1446 return aDG();
1447 }
1448
1449
1450
1451
GetXShape()1452 uno::Reference< drawing::XShape > AccessibleShape::GetXShape()
1453 {
1454 return( mxShape );
1455 }
1456
1457
1458
1459 // protected
disposing(void)1460 void AccessibleShape::disposing (void)
1461 {
1462 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
1463 ::osl::MutexGuard aGuard (maMutex);
1464
1465 // Make sure to send an event that this object looses the focus in the
1466 // case that it has the focus.
1467 ::utl::AccessibleStateSetHelper* pStateSet =
1468 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
1469 if (pStateSet != NULL)
1470 pStateSet->RemoveState (AccessibleStateType::FOCUSED);
1471
1472 // Unregister from broadcasters.
1473 Reference<lang::XComponent> xComponent (mxShape, uno::UNO_QUERY);
1474 if (xComponent.is())
1475 xComponent->removeEventListener (this);
1476
1477 // Unregister from model.
1478 if (maShapeTreeInfo.GetModelBroadcaster().is())
1479 maShapeTreeInfo.GetModelBroadcaster()->removeEventListener (
1480 static_cast<document::XEventListener*>(this));
1481
1482 // Release the child containers.
1483 if (mpChildrenManager != NULL)
1484 {
1485 delete mpChildrenManager;
1486 mpChildrenManager = NULL;
1487 }
1488 if (mpText != NULL)
1489 {
1490 mpText->Dispose();
1491 delete mpText;
1492 mpText = NULL;
1493 }
1494
1495 // Cleanup. Remove references to objects to allow them to be
1496 // destroyed.
1497 mxShape = NULL;
1498 maShapeTreeInfo = AccessibleShapeTreeInfo();
1499
1500 // Call base classes.
1501 AccessibleContextBase::dispose ();
1502 }
1503
1504 sal_Int32 SAL_CALL
getAccessibleIndexInParent(void)1505 AccessibleShape::getAccessibleIndexInParent (void)
1506 throw (::com::sun::star::uno::RuntimeException)
1507 {
1508 ThrowIfDisposed ();
1509 // Use a simple but slow solution for now. Optimize later.
1510
1511 sal_Int32 nIndex = m_nIndexInParent;
1512 if ( -1 == nIndex )
1513 nIndex = AccessibleContextBase::getAccessibleIndexInParent();
1514 return nIndex;
1515 }
1516
1517
1518
1519
UpdateNameAndDescription(void)1520 void AccessibleShape::UpdateNameAndDescription (void)
1521 {
1522 // Ignore missing title, name, or description. There are fallbacks for
1523 // them.
1524 try
1525 {
1526 Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY_THROW);
1527 OUString sString;
1528
1529 // Get the accessible name.
1530 sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Title")));
1531 if (sString.getLength() > 0)
1532 {
1533 SetAccessibleName(sString, AccessibleContextBase::FromShape);
1534 }
1535 else
1536 {
1537 sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Name")));
1538 if (sString.getLength() > 0)
1539 SetAccessibleName(sString, AccessibleContextBase::FromShape);
1540 }
1541
1542 // Get the accessible description.
1543 sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Description")));
1544 if (sString.getLength() > 0)
1545 SetAccessibleDescription(sString, AccessibleContextBase::FromShape);
1546 }
1547 catch (uno::RuntimeException&)
1548 {
1549 }
1550 }
1551 // Return this object's role.
getAccessibleRole(void)1552 sal_Int16 SAL_CALL AccessibleShape::getAccessibleRole (void)
1553 throw (::com::sun::star::uno::RuntimeException)
1554 {
1555 sal_Int16 nAccessibleRole = AccessibleRole::SHAPE ;
1556 switch (ShapeTypeHandler::Instance().GetTypeId (mxShape))
1557 {
1558 case DRAWING_GRAPHIC_OBJECT:
1559 nAccessibleRole = AccessibleRole::GRAPHIC ; break;
1560 case DRAWING_OLE:
1561 nAccessibleRole = AccessibleRole::EMBEDDED_OBJECT ; break;
1562
1563 default:
1564 nAccessibleRole = AccessibleContextBase::getAccessibleRole();
1565 break;
1566 }
1567
1568 return nAccessibleRole;
1569 }
1570
1571
UpdateDocumentAllSelState(Reference<XAccessibleStateSet> & xStateSet)1572 void AccessibleShape::UpdateDocumentAllSelState(Reference<XAccessibleStateSet> &xStateSet)
1573 {
1574 if (mpParent && mpParent->IsDocumentSelAll())
1575 {
1576 ::utl::AccessibleStateSetHelper* pStateSet =
1577 static_cast< ::utl::AccessibleStateSetHelper*>(xStateSet.get());
1578 pStateSet->AddState (AccessibleStateType::SELECTED);
1579
1580 //uno::Any NewValue;
1581 //NewValue <<= AccessibleStateType::SELECTED;
1582
1583 //CommitChange(AccessibleEventId::STATE_CHANGED,NewValue,uno::Any());
1584 }
1585 }
1586
1587 //sort the drawing objects from up to down, from left to right
1588 struct XShapePosCompareHelper
1589 {
operator ()accessibility::XShapePosCompareHelper1590 bool operator() ( const uno::Reference<drawing::XShape>& xshape1,
1591 const uno::Reference<drawing::XShape>& xshape2 ) const
1592 {
1593 SdrObject* pObj1 = GetSdrObjectFromXShape(xshape1);
1594 SdrObject* pObj2 = GetSdrObjectFromXShape(xshape2);
1595 if(pObj1 && pObj2)
1596 return pObj1->GetOrdNum() < pObj2->GetOrdNum();
1597 else
1598 return 0;
1599 }
1600 };
1601 //end of group position
1602
1603 //===== XAccessibleGroupPosition =========================================
1604 uno::Sequence< sal_Int32 > SAL_CALL
getGroupPosition(const uno::Any &)1605 AccessibleShape::getGroupPosition( const uno::Any& )
1606 throw (uno::RuntimeException)
1607 {
1608 // we will return the:
1609 // [0] group level
1610 // [1] similar items counts in the group
1611 // [2] the position of the object in the group
1612 uno::Sequence< sal_Int32 > aRet( 3 );
1613 aRet[0] = 0;
1614 aRet[1] = 0;
1615 aRet[2] = 0;
1616
1617 ::com::sun::star::uno::Reference<XAccessible> xParent = getAccessibleParent();
1618 if (!xParent.is())
1619 {
1620 return aRet;
1621 }
1622 SdrObject *pObj = GetSdrObjectFromXShape(mxShape);
1623
1624
1625 if(pObj == NULL )
1626 {
1627 return aRet;
1628 }
1629
1630 // Compute object's group level.
1631 sal_Int32 nGroupLevel = 0;
1632 SdrObject * pUper = pObj->GetUpGroup();
1633 while( pUper )
1634 {
1635 ++nGroupLevel;
1636 pUper = pUper->GetUpGroup();
1637 }
1638
1639 ::com::sun::star::uno::Reference<XAccessibleContext> xParentContext = xParent->getAccessibleContext();
1640 if( xParentContext->getAccessibleRole() == AccessibleRole::DOCUMENT)//Document
1641 {
1642 Reference< XAccessibleGroupPosition > xGroupPosition( xParent,uno::UNO_QUERY );
1643 if ( xGroupPosition.is() )
1644 {
1645 aRet = xGroupPosition->getGroupPosition( uno::makeAny( getAccessibleContext() ) );
1646 }
1647 return aRet;
1648 }
1649 if (xParentContext->getAccessibleRole() != AccessibleRole::SHAPE)
1650 {
1651 return aRet;
1652 }
1653
1654 SdrObjList *pGrpList = NULL;
1655 if( pObj->GetUpGroup() )
1656 pGrpList = pObj->GetUpGroup()->GetSubList();
1657 else
1658 return aRet;
1659
1660 std::vector< uno::Reference<drawing::XShape> > vXShapes;
1661 if (pGrpList)
1662 {
1663 const sal_Int32 nObj = pGrpList->GetObjCount();
1664 for(sal_Int32 i = 0 ; i < nObj ; ++i)
1665 {
1666 SdrObject *pSubObj = pGrpList->GetObj(i);
1667 if (pSubObj &&
1668 xParentContext->getAccessibleChild(i)->getAccessibleContext()->getAccessibleRole() != AccessibleRole::GROUP_BOX)
1669 {
1670 vXShapes.push_back( GetXShapeForSdrObject(pSubObj) );
1671 }
1672 }
1673 }
1674
1675 std::sort( vXShapes.begin(), vXShapes.end(), XShapePosCompareHelper() );
1676
1677 //get the index of the selected object in the group
1678 std::vector< uno::Reference<drawing::XShape> >::iterator aIter;
1679 //we start counting position from 1
1680 sal_Int32 nPos = 1;
1681 for ( aIter = vXShapes.begin(); aIter != vXShapes.end(); aIter++, nPos++ )
1682 {
1683 if ( (*aIter).get() == mxShape.get() )
1684 {
1685 sal_Int32* pArray = aRet.getArray();
1686 pArray[0] = nGroupLevel;
1687 pArray[1] = vXShapes.size();
1688 pArray[2] = nPos;
1689 break;
1690 }
1691 }
1692
1693 return aRet;
1694 }
1695
getObjectLink(const uno::Any &)1696 ::rtl::OUString AccessibleShape::getObjectLink( const uno::Any& )
1697 throw (uno::RuntimeException)
1698 {
1699 ::rtl::OUString aRet;
1700
1701 SdrObject *pObj = GetSdrObjectFromXShape(mxShape);
1702 if(pObj == NULL )
1703 {
1704 return aRet;
1705 }
1706 if (maShapeTreeInfo.GetDocumentWindow().is())
1707 {
1708 Reference< XAccessibleGroupPosition > xGroupPosition( maShapeTreeInfo.GetDocumentWindow(), uno::UNO_QUERY );
1709 if (xGroupPosition.is())
1710 {
1711 aRet = xGroupPosition->getObjectLink( uno::makeAny( getAccessibleContext() ) );
1712 }
1713 }
1714 return aRet;
1715 }
1716
1717 //===== XAccesibleHypertext ==================================================
getHyperLinkCount()1718 sal_Int32 SAL_CALL AccessibleShape::getHyperLinkCount()
1719 throw (::com::sun::star::uno::RuntimeException)
1720 {
1721 // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile.
1722 // Code need to be adapted....
1723 return 0;
1724
1725 /*
1726 SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this);
1727 if (pLink->IsValidHyperlink())
1728 return 1;
1729 else
1730 return 0;
1731 */
1732 }
1733 uno::Reference< XAccessibleHyperlink > SAL_CALL
getHyperLink(sal_Int32)1734 AccessibleShape::getHyperLink( sal_Int32 )
1735 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1736 {
1737 uno::Reference< XAccessibleHyperlink > xRet;
1738 // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile.
1739 // Code need to be adapted....
1740 /*
1741 SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this);
1742 if (pLink->IsValidHyperlink())
1743 xRet = pLink;
1744 if( !xRet.is() )
1745 throw ::com::sun::star::lang::IndexOutOfBoundsException();
1746 */
1747 return xRet;
1748 }
getHyperLinkIndex(sal_Int32)1749 sal_Int32 SAL_CALL AccessibleShape::getHyperLinkIndex( sal_Int32 )
1750 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1751 {
1752 sal_Int32 nRet = 0;
1753 return nRet;
1754 }
1755 //===== XAccesibleText ==================================================
getCaretPosition()1756 sal_Int32 SAL_CALL AccessibleShape::getCaretPosition( ) throw (::com::sun::star::uno::RuntimeException){return 0;}
setCaretPosition(sal_Int32)1757 sal_Bool SAL_CALL AccessibleShape::setCaretPosition( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;}
getCharacter(sal_Int32)1758 sal_Unicode SAL_CALL AccessibleShape::getCharacter( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;}
getCharacterAttributes(sal_Int32,const::com::sun::star::uno::Sequence<::rtl::OUString> &)1759 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL AccessibleShape::getCharacterAttributes( sal_Int32, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1760 {
1761 uno::Sequence< ::com::sun::star::beans::PropertyValue > aValues(0);
1762 return aValues;
1763 }
getCharacterBounds(sal_Int32)1764 ::com::sun::star::awt::Rectangle SAL_CALL AccessibleShape::getCharacterBounds( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1765 {
1766 return com::sun::star::awt::Rectangle(0, 0, 0, 0 );
1767 }
getCharacterCount()1768 sal_Int32 SAL_CALL AccessibleShape::getCharacterCount( ) throw (::com::sun::star::uno::RuntimeException){return 0;}
getIndexAtPoint(const::com::sun::star::awt::Point &)1769 sal_Int32 SAL_CALL AccessibleShape::getIndexAtPoint( const ::com::sun::star::awt::Point& ) throw (::com::sun::star::uno::RuntimeException){return 0;}
getSelectedText()1770 ::rtl::OUString SAL_CALL AccessibleShape::getSelectedText( ) throw (::com::sun::star::uno::RuntimeException){return OUString();}
getSelectionStart()1771 sal_Int32 SAL_CALL AccessibleShape::getSelectionStart( ) throw (::com::sun::star::uno::RuntimeException){return 0;}
getSelectionEnd()1772 sal_Int32 SAL_CALL AccessibleShape::getSelectionEnd( ) throw (::com::sun::star::uno::RuntimeException){return 0;}
setSelection(sal_Int32,sal_Int32)1773 sal_Bool SAL_CALL AccessibleShape::setSelection( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return sal_True;}
getText()1774 ::rtl::OUString SAL_CALL AccessibleShape::getText( ) throw (::com::sun::star::uno::RuntimeException){return OUString();}
getTextRange(sal_Int32,sal_Int32)1775 ::rtl::OUString SAL_CALL AccessibleShape::getTextRange( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return OUString();}
getTextAtIndex(sal_Int32,sal_Int16)1776 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleShape::getTextAtIndex( sal_Int32, sal_Int16 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
1777 {
1778 ::com::sun::star::accessibility::TextSegment aResult;
1779 return aResult;
1780 }
getTextBeforeIndex(sal_Int32,sal_Int16)1781 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleShape::getTextBeforeIndex( sal_Int32, sal_Int16 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
1782 {
1783 ::com::sun::star::accessibility::TextSegment aResult;
1784 return aResult;
1785 }
getTextBehindIndex(sal_Int32,sal_Int16)1786 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleShape::getTextBehindIndex( sal_Int32, sal_Int16 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
1787 {
1788 ::com::sun::star::accessibility::TextSegment aResult;
1789 return aResult;
1790 }
copyText(sal_Int32,sal_Int32)1791 sal_Bool SAL_CALL AccessibleShape::copyText( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return sal_True;}
1792
1793 } // end of namespace accessibility
1794