bump product version to 4.1.6.2
[LibreOffice.git] / svx / source / table / accessiblecell.cxx
blob61e7dfceb58986d2402ab21ef4a189c2b368ba15
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <accessiblecell.hxx>
23 #include "svx/DescriptionGenerator.hxx"
25 #include <com/sun/star/accessibility/AccessibleRole.hpp>
26 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
28 #include <vcl/svapp.hxx>
30 #include <unotools/accessiblestatesethelper.hxx>
32 #include <editeng/outlobj.hxx>
33 #include <svx/unoshtxt.hxx>
34 #include <svx/svdotext.hxx>
36 using namespace ::sdr::table;
37 using namespace ::com::sun::star;
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::accessibility;
40 using namespace ::com::sun::star::lang;
41 using namespace ::com::sun::star::container;
43 namespace accessibility {
45 // --------------------------------------------------------------------
46 // AccessibleCell
47 // --------------------------------------------------------------------
49 AccessibleCell::AccessibleCell( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible>& rxParent, const sdr::table::CellRef& rCell, sal_Int32 nIndex, const AccessibleShapeTreeInfo& rShapeTreeInfo )
50 : AccessibleCellBase( rxParent, AccessibleRole::TABLE_CELL )
51 , maShapeTreeInfo( rShapeTreeInfo )
52 , mnIndexInParent( nIndex )
53 , mpText( NULL )
54 , mxCell( rCell )
58 // --------------------------------------------------------------------
60 AccessibleCell::~AccessibleCell (void)
62 DBG_ASSERT( mpText == 0, "svx::AccessibleCell::~AccessibleCell(), not disposed!?" );
65 // --------------------------------------------------------------------
67 void AccessibleCell::Init (void)
69 SdrView* pView = maShapeTreeInfo.GetSdrView();
70 const Window* pWindow = maShapeTreeInfo.GetWindow ();
71 if( (pView != NULL) && (pWindow != NULL) && mxCell.is())
73 OutlinerParaObject* pOutlinerParaObject = mxCell->GetEditOutlinerParaObject(); // Get the OutlinerParaObject if text edit is active
75 bool bOwnParaObject = pOutlinerParaObject != 0;
77 if( !pOutlinerParaObject )
78 pOutlinerParaObject = mxCell->GetOutlinerParaObject();
80 // create AccessibleTextHelper to handle this shape's text
81 if( pOutlinerParaObject )
83 // non-empty text -> use full-fledged edit source right away
84 SAL_WNODEPRECATED_DECLARATIONS_PUSH
85 ::std::auto_ptr<SvxEditSource> pEditSource( new SvxTextEditSource( mxCell->GetObject(), mxCell.get(), *pView, *pWindow) );
86 SAL_WNODEPRECATED_DECLARATIONS_POP
87 mpText = new AccessibleTextHelper( pEditSource );
88 mpText->SetEventSource(this);
91 if( bOwnParaObject)
92 delete pOutlinerParaObject;
96 // --------------------------------------------------------------------
98 sal_Bool AccessibleCell::SetState (sal_Int16 aState)
100 sal_Bool bStateHasChanged = sal_False;
102 if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
104 // Offer FOCUSED state to edit engine and detect whether the state
105 // changes.
106 sal_Bool bIsFocused = mpText->HaveFocus ();
107 mpText->SetFocus (sal_True);
108 bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
110 else
111 bStateHasChanged = AccessibleContextBase::SetState (aState);
113 return bStateHasChanged;
116 // --------------------------------------------------------------------
118 sal_Bool AccessibleCell::ResetState (sal_Int16 aState)
120 sal_Bool bStateHasChanged = sal_False;
122 if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
124 // Try to remove FOCUSED state from the edit engine and detect
125 // whether the state changes.
126 sal_Bool bIsFocused = mpText->HaveFocus ();
127 mpText->SetFocus (sal_False);
128 bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
130 else
131 bStateHasChanged = AccessibleContextBase::ResetState (aState);
133 return bStateHasChanged;
136 //-----------------------------------------------------------------------------
138 bool AccessibleCell::operator== (const AccessibleCell& rAccessibleCell)
140 return this == &rAccessibleCell;
143 //-----------------------------------------------------------------------------
144 // XInterface
145 //-----------------------------------------------------------------------------
147 Any SAL_CALL AccessibleCell::queryInterface( const Type& aType ) throw (RuntimeException)
149 return AccessibleCellBase::queryInterface( aType );
152 //-----------------------------------------------------------------------------
154 void SAL_CALL AccessibleCell::acquire( ) throw ()
156 AccessibleCellBase::acquire();
159 //-----------------------------------------------------------------------------
161 void SAL_CALL AccessibleCell::release( ) throw ()
163 AccessibleCellBase::release();
166 // --------------------------------------------------------------------
167 // XAccessibleContext
168 // --------------------------------------------------------------------
170 /** The children of this cell come from the paragraphs of text.
172 sal_Int32 SAL_CALL AccessibleCell::getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException)
174 SolarMutexGuard aSolarGuard;
175 ThrowIfDisposed ();
176 return mpText != NULL ? mpText->GetChildCount () : 0;
179 // --------------------------------------------------------------------
181 /** Forward the request to the shape. Return the requested shape or throw
182 an exception for a wrong index.
184 Reference<XAccessible> SAL_CALL AccessibleCell::getAccessibleChild (sal_Int32 nIndex) throw (IndexOutOfBoundsException, RuntimeException)
186 SolarMutexGuard aSolarGuard;
187 ThrowIfDisposed ();
189 // todo: does GetChild throw IndexOutOfBoundsException?
190 return mpText->GetChild (nIndex);
193 // --------------------------------------------------------------------
195 /** Return a copy of the state set.
196 Possible states are:
197 ENABLED
198 SHOWING
199 VISIBLE
201 Reference<XAccessibleStateSet> SAL_CALL AccessibleCell::getAccessibleStateSet (void) throw (RuntimeException)
203 SolarMutexGuard aSolarGuard;
204 ::osl::MutexGuard aGuard (maMutex);
205 Reference<XAccessibleStateSet> xStateSet;
207 if (rBHelper.bDisposed || mpText == NULL)
209 // Return a minimal state set that only contains the DEFUNC state.
210 xStateSet = AccessibleContextBase::getAccessibleStateSet ();
212 else
214 ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
216 if(pStateSet)
218 // Merge current FOCUSED state from edit engine.
219 if (mpText != NULL)
221 if (mpText->HaveFocus())
222 pStateSet->AddState (AccessibleStateType::FOCUSED);
223 else
224 pStateSet->RemoveState (AccessibleStateType::FOCUSED);
227 // Create a copy of the state set that may be modified by the
228 // caller without affecting the current state set.
229 xStateSet = Reference<XAccessibleStateSet>(new ::utl::AccessibleStateSetHelper (*pStateSet));
233 return xStateSet;
236 // --------------------------------------------------------------------
237 // XAccessibleComponent
238 // --------------------------------------------------------------------
240 sal_Bool SAL_CALL AccessibleCell::containsPoint( const ::com::sun::star::awt::Point& aPoint) throw (::com::sun::star::uno::RuntimeException)
242 return AccessibleComponentBase::containsPoint( aPoint );
245 /** The implementation below is at the moment straightforward. It iterates
246 over all children (and thereby instances all children which have not
247 been already instatiated) until a child covering the specifed point is
248 found.
249 This leaves room for improvement. For instance, first iterate only over
250 the already instantiated children and only if no match is found
251 instantiate the remaining ones.
253 Reference<XAccessible > SAL_CALL AccessibleCell::getAccessibleAtPoint ( const ::com::sun::star::awt::Point& aPoint) throw(RuntimeException)
255 SolarMutexGuard aSolarGuard;
256 ::osl::MutexGuard aGuard (maMutex);
258 sal_Int32 nChildCount = getAccessibleChildCount ();
259 for (sal_Int32 i=0; i<nChildCount; ++i)
261 Reference<XAccessible> xChild (getAccessibleChild (i));
262 if (xChild.is())
264 Reference<XAccessibleComponent> xChildComponent (xChild->getAccessibleContext(), uno::UNO_QUERY);
265 if (xChildComponent.is())
267 awt::Rectangle aBBox (xChildComponent->getBounds());
268 if ( (aPoint.X >= aBBox.X)
269 && (aPoint.Y >= aBBox.Y)
270 && (aPoint.X < aBBox.X+aBBox.Width)
271 && (aPoint.Y < aBBox.Y+aBBox.Height) )
272 return xChild;
277 // Have not found a child under the given point. Returning empty
278 // reference to indicate this.
279 return uno::Reference<XAccessible>();
282 // --------------------------------------------------------------------
284 ::com::sun::star::awt::Rectangle SAL_CALL AccessibleCell::getBounds(void) throw(RuntimeException)
286 SolarMutexGuard aSolarGuard;
287 ::osl::MutexGuard aGuard (maMutex);
289 ThrowIfDisposed ();
290 ::com::sun::star::awt::Rectangle aBoundingBox;
291 if( mxCell.is() )
293 // Get the cell's bounding box in internal coordinates (in 100th of mm)
294 const ::Rectangle aCellRect( mxCell->getCellRect() );
296 // Transform coordinates from internal to pixel.
297 if (maShapeTreeInfo.GetViewForwarder() == NULL)
298 throw uno::RuntimeException (OUString("AccessibleCell has no valid view forwarder"),static_cast<uno::XWeak*>(this));
300 ::Size aPixelSize( maShapeTreeInfo.GetViewForwarder()->LogicToPixel(::Size(aCellRect.GetWidth(), aCellRect.GetHeight())) );
301 ::Point aPixelPosition( maShapeTreeInfo.GetViewForwarder()->LogicToPixel( aCellRect.TopLeft() ));
303 // Clip the shape's bounding box with the bounding box of its parent.
304 Reference<XAccessibleComponent> xParentComponent ( getAccessibleParent(), uno::UNO_QUERY);
305 if (xParentComponent.is())
307 // Make the coordinates relative to the parent.
308 awt::Point aParentLocation (xParentComponent->getLocationOnScreen());
309 int x = aPixelPosition.getX() - aParentLocation.X;
310 int y = aPixelPosition.getY() - aParentLocation.Y;
312 // Clip with parent (with coordinates relative to itself).
313 ::Rectangle aBBox ( x, y, x + aPixelSize.getWidth(), y + aPixelSize.getHeight());
314 awt::Size aParentSize (xParentComponent->getSize());
315 ::Rectangle aParentBBox (0,0, aParentSize.Width, aParentSize.Height);
316 aBBox = aBBox.GetIntersection (aParentBBox);
317 aBoundingBox = awt::Rectangle ( aBBox.getX(), aBBox.getY(), aBBox.getWidth(), aBBox.getHeight());
319 else
321 OSL_TRACE ("parent does not support component");
322 aBoundingBox = awt::Rectangle (aPixelPosition.getX(), aPixelPosition.getY(),aPixelSize.getWidth(), aPixelSize.getHeight());
326 return aBoundingBox;
329 // --------------------------------------------------------------------
331 ::com::sun::star::awt::Point SAL_CALL AccessibleCell::getLocation(void) throw (RuntimeException)
333 ThrowIfDisposed ();
334 ::com::sun::star::awt::Rectangle aBoundingBox(getBounds());
335 return ::com::sun::star::awt::Point(aBoundingBox.X, aBoundingBox.Y);
338 // --------------------------------------------------------------------
340 ::com::sun::star::awt::Point SAL_CALL AccessibleCell::getLocationOnScreen(void) throw(RuntimeException)
342 ThrowIfDisposed ();
344 // Get relative position...
345 ::com::sun::star::awt::Point aLocation(getLocation ());
347 // ... and add absolute position of the parent.
348 Reference<XAccessibleComponent> xParentComponent( getAccessibleParent(), uno::UNO_QUERY);
349 if(xParentComponent.is())
351 ::com::sun::star::awt::Point aParentLocation(xParentComponent->getLocationOnScreen());
352 aLocation.X += aParentLocation.X;
353 aLocation.Y += aParentLocation.Y;
355 else
357 OSL_TRACE ("getLocation: parent does not support XAccessibleComponent");
360 return aLocation;
363 // --------------------------------------------------------------------
365 awt::Size SAL_CALL AccessibleCell::getSize (void) throw (RuntimeException)
367 ThrowIfDisposed ();
368 awt::Rectangle aBoundingBox (getBounds());
369 return awt::Size (aBoundingBox.Width, aBoundingBox.Height);
372 // --------------------------------------------------------------------
374 void SAL_CALL AccessibleCell::addFocusListener ( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener) throw (::com::sun::star::uno::RuntimeException)
376 AccessibleComponentBase::addFocusListener( xListener );
379 // --------------------------------------------------------------------
381 void SAL_CALL AccessibleCell::removeFocusListener (const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
383 AccessibleComponentBase::removeFocusListener( xListener );
386 // --------------------------------------------------------------------
388 void SAL_CALL AccessibleCell::grabFocus (void) throw (::com::sun::star::uno::RuntimeException)
390 AccessibleComponentBase::grabFocus();
393 // --------------------------------------------------------------------
395 sal_Int32 SAL_CALL AccessibleCell::getForeground(void) throw (RuntimeException)
397 ThrowIfDisposed ();
398 sal_Int32 nColor (0x0ffffffL);
400 // todo
401 return nColor;
404 // --------------------------------------------------------------------
406 sal_Int32 SAL_CALL AccessibleCell::getBackground (void) throw (RuntimeException)
408 ThrowIfDisposed ();
409 sal_Int32 nColor (0L);
411 // todo
412 return nColor;
415 // --------------------------------------------------------------------
416 // XAccessibleExtendedComponent
417 // --------------------------------------------------------------------
419 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFont > SAL_CALL AccessibleCell::getFont (void) throw (::com::sun::star::uno::RuntimeException)
421 //todo
422 return AccessibleComponentBase::getFont();
425 // --------------------------------------------------------------------
427 OUString SAL_CALL AccessibleCell::getTitledBorderText (void) throw (::com::sun::star::uno::RuntimeException)
429 return AccessibleComponentBase::getTitledBorderText();
432 // --------------------------------------------------------------------
434 OUString SAL_CALL AccessibleCell::getToolTipText (void) throw (::com::sun::star::uno::RuntimeException)
436 return AccessibleComponentBase::getToolTipText();
439 // --------------------------------------------------------------------
440 // XAccessibleEventBroadcaster
441 // --------------------------------------------------------------------
443 void SAL_CALL AccessibleCell::addAccessibleEventListener( const Reference<XAccessibleEventListener >& rxListener) throw (RuntimeException)
445 SolarMutexGuard aSolarGuard;
446 ::osl::MutexGuard aGuard (maMutex);
447 if (rBHelper.bDisposed || rBHelper.bInDispose)
449 Reference<XInterface> xSource( static_cast<XComponent *>(this) );
450 lang::EventObject aEventObj(xSource);
451 rxListener->disposing(aEventObj);
453 else
455 AccessibleContextBase::addAccessibleEventListener (rxListener);
456 if (mpText != NULL)
457 mpText->AddEventListener (rxListener);
461 // --------------------------------------------------------------------
463 void SAL_CALL AccessibleCell::removeAccessibleEventListener( const Reference<XAccessibleEventListener >& rxListener) throw (RuntimeException)
465 SolarMutexGuard aSolarGuard;
466 AccessibleContextBase::removeAccessibleEventListener(rxListener);
467 if (mpText != NULL)
468 mpText->RemoveEventListener (rxListener);
471 // --------------------------------------------------------------------
472 // XServiceInfo
473 // --------------------------------------------------------------------
475 OUString SAL_CALL AccessibleCell::getImplementationName(void) throw (RuntimeException)
477 return OUString("AccessibleCell");
480 // --------------------------------------------------------------------
482 Sequence<OUString> SAL_CALL AccessibleCell::getSupportedServiceNames(void) throw (RuntimeException)
484 ThrowIfDisposed ();
486 // Get list of supported service names from base class...
487 uno::Sequence<OUString> aServiceNames = AccessibleContextBase::getSupportedServiceNames();
488 sal_Int32 nCount (aServiceNames.getLength());
490 // ...and add additional names.
491 aServiceNames.realloc (nCount + 1);
492 static const OUString sAdditionalServiceName ("com.sun.star.drawing.AccessibleCell");
493 aServiceNames[nCount] = sAdditionalServiceName;
495 return aServiceNames;
498 // --------------------------------------------------------------------
499 // IAccessibleViewForwarderListener
500 // --------------------------------------------------------------------
502 void AccessibleCell::ViewForwarderChanged (ChangeType /*aChangeType*/, const IAccessibleViewForwarder* /*pViewForwarder*/)
504 // Inform all listeners that the graphical representation (i.e. size
505 // and/or position) of the shape has changed.
506 CommitChange(AccessibleEventId::VISIBLE_DATA_CHANGED, Any(), Any());
508 // update our children that our screen position might have changed
509 if( mpText )
510 mpText->UpdateChildren();
513 // --------------------------------------------------------------------
514 // protected
515 // --------------------------------------------------------------------
517 void AccessibleCell::disposing (void)
519 SolarMutexGuard aSolarGuard;
520 ::osl::MutexGuard aGuard (maMutex);
522 // Make sure to send an event that this object looses the focus in the
523 // case that it has the focus.
524 ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
525 if (pStateSet != NULL)
526 pStateSet->RemoveState(AccessibleStateType::FOCUSED);
528 if (mpText != NULL)
530 mpText->Dispose();
531 delete mpText;
532 mpText = NULL;
535 // Cleanup. Remove references to objects to allow them to be
536 // destroyed.
537 mxCell.clear();
538 maShapeTreeInfo = AccessibleShapeTreeInfo();
540 // Call base classes.
541 AccessibleContextBase::dispose ();
544 sal_Int32 SAL_CALL AccessibleCell::getAccessibleIndexInParent (void) throw (RuntimeException)
546 ThrowIfDisposed ();
547 return mnIndexInParent;
550 OUString SAL_CALL AccessibleCell::getAccessibleName (void) throw (::com::sun::star::uno::RuntimeException)
552 ThrowIfDisposed ();
553 SolarMutexGuard aSolarGuard;
555 if( mxCell.is() )
556 return mxCell->getName();
558 return AccessibleCellBase::getAccessibleName();
561 } // end of namespace accessibility
563 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */