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