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