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