merge the formfield patch from ooo-build
[ooovba.git] / svx / source / table / accessiblecell.cxx
blob6066023eac2bfce5a7d0dd81a9d4606f3c2018cf
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: accessiblecell.cxx,v $
10 * $Revision: 1.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include <accessiblecell.hxx>
36 #include "DescriptionGenerator.hxx"
38 #include <com/sun/star/accessibility/AccessibleRole.hpp>
39 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
41 #include <vcl/svapp.hxx>
43 #include <unotools/accessiblestatesethelper.hxx>
45 #include <svx/outlobj.hxx>
46 #include <svx/unoshtxt.hxx>
47 #include <svx/svdotext.hxx>
49 using ::rtl::OUString;
50 using namespace ::sdr::table;
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::accessibility;
54 using namespace ::com::sun::star::lang;
55 using namespace ::com::sun::star::container;
57 namespace accessibility {
59 // --------------------------------------------------------------------
60 // AccessibleCell
61 // --------------------------------------------------------------------
63 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 )
64 : AccessibleCellBase( rxParent, AccessibleRole::TABLE_CELL )
65 , maShapeTreeInfo( rShapeTreeInfo )
66 , mnIndexInParent( nIndex )
67 , mpText( NULL )
68 , mxCell( rCell )
72 // --------------------------------------------------------------------
74 AccessibleCell::~AccessibleCell (void)
76 DBG_ASSERT( mpText == 0, "svx::AccessibleCell::~AccessibleCell(), not disposed!?" );
79 // --------------------------------------------------------------------
81 void AccessibleCell::Init (void)
83 SdrView* pView = maShapeTreeInfo.GetSdrView();
84 const Window* pWindow = maShapeTreeInfo.GetWindow ();
85 if( (pView != NULL) && (pWindow != NULL) && mxCell.is())
87 OutlinerParaObject* pOutlinerParaObject = mxCell->GetEditOutlinerParaObject(); // Get the OutlinerParaObject if text edit is active
89 bool bOwnParaObject = pOutlinerParaObject != 0;
91 if( !pOutlinerParaObject )
92 pOutlinerParaObject = mxCell->GetOutlinerParaObject();
94 // create AccessibleTextHelper to handle this shape's text
95 if( pOutlinerParaObject )
97 // non-empty text -> use full-fledged edit source right away
98 ::std::auto_ptr<SvxEditSource> pEditSource( new SvxTextEditSource( mxCell->GetObject(), mxCell.get(), *pView, *pWindow) );
99 mpText = new AccessibleTextHelper( pEditSource );
100 mpText->SetEventSource(this);
103 if( bOwnParaObject)
104 delete pOutlinerParaObject;
108 // --------------------------------------------------------------------
110 sal_Bool AccessibleCell::SetState (sal_Int16 aState)
112 sal_Bool bStateHasChanged = sal_False;
114 if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
116 // Offer FOCUSED state to edit engine and detect whether the state
117 // changes.
118 sal_Bool bIsFocused = mpText->HaveFocus ();
119 mpText->SetFocus (sal_True);
120 bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
122 else
123 bStateHasChanged = AccessibleContextBase::SetState (aState);
125 return bStateHasChanged;
128 // --------------------------------------------------------------------
130 sal_Bool AccessibleCell::ResetState (sal_Int16 aState)
132 sal_Bool bStateHasChanged = sal_False;
134 if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
136 // Try to remove FOCUSED state from the edit engine and detect
137 // whether the state changes.
138 sal_Bool bIsFocused = mpText->HaveFocus ();
139 mpText->SetFocus (sal_False);
140 bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
142 else
143 bStateHasChanged = AccessibleContextBase::ResetState (aState);
145 return bStateHasChanged;
148 // --------------------------------------------------------------------
150 sal_Bool AccessibleCell::GetState (sal_Int16 aState)
152 if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
154 // Just delegate the call to the edit engine. The state is not
155 // merged into the state set.
156 return mpText->HaveFocus();
158 else
159 return AccessibleContextBase::GetState (aState);
162 //-----------------------------------------------------------------------------
164 bool AccessibleCell::operator== (const AccessibleCell& rAccessibleCell)
166 return this == &rAccessibleCell;
169 //-----------------------------------------------------------------------------
170 // XInterface
171 //-----------------------------------------------------------------------------
173 Any SAL_CALL AccessibleCell::queryInterface( const Type& aType ) throw (RuntimeException)
175 return AccessibleCellBase::queryInterface( aType );
178 //-----------------------------------------------------------------------------
180 void SAL_CALL AccessibleCell::acquire( ) throw ()
182 AccessibleCellBase::acquire();
185 //-----------------------------------------------------------------------------
187 void SAL_CALL AccessibleCell::release( ) throw ()
189 AccessibleCellBase::release();
192 // --------------------------------------------------------------------
193 // XAccessibleContext
194 // --------------------------------------------------------------------
196 /** The children of this cell come from the paragraphs of text.
198 sal_Int32 SAL_CALL AccessibleCell::getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException)
200 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
201 ThrowIfDisposed ();
202 return mpText != NULL ? mpText->GetChildCount () : 0;
205 // --------------------------------------------------------------------
207 /** Forward the request to the shape. Return the requested shape or throw
208 an exception for a wrong index.
210 Reference<XAccessible> SAL_CALL AccessibleCell::getAccessibleChild (sal_Int32 nIndex) throw (IndexOutOfBoundsException, RuntimeException)
212 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
213 ThrowIfDisposed ();
215 // todo: does GetChild throw IndexOutOfBoundsException?
216 return mpText->GetChild (nIndex);
219 // --------------------------------------------------------------------
221 /** Return a copy of the state set.
222 Possible states are:
223 ENABLED
224 SHOWING
225 VISIBLE
227 Reference<XAccessibleStateSet> SAL_CALL AccessibleCell::getAccessibleStateSet (void) throw (RuntimeException)
229 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
230 ::osl::MutexGuard aGuard (maMutex);
231 Reference<XAccessibleStateSet> xStateSet;
233 if (rBHelper.bDisposed || mpText == NULL)
235 // Return a minimal state set that only contains the DEFUNC state.
236 xStateSet = AccessibleContextBase::getAccessibleStateSet ();
238 else
240 ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
242 if(pStateSet)
244 // Merge current FOCUSED state from edit engine.
245 if (mpText != NULL)
247 if (mpText->HaveFocus())
248 pStateSet->AddState (AccessibleStateType::FOCUSED);
249 else
250 pStateSet->RemoveState (AccessibleStateType::FOCUSED);
253 // Create a copy of the state set that may be modified by the
254 // caller without affecting the current state set.
255 xStateSet = Reference<XAccessibleStateSet>(new ::utl::AccessibleStateSetHelper (*pStateSet));
259 return xStateSet;
262 // --------------------------------------------------------------------
263 // XAccessibleComponent
264 // --------------------------------------------------------------------
266 sal_Bool SAL_CALL AccessibleCell::containsPoint( const ::com::sun::star::awt::Point& aPoint) throw (::com::sun::star::uno::RuntimeException)
268 return AccessibleComponentBase::containsPoint( aPoint );
271 /** The implementation below is at the moment straightforward. It iterates
272 over all children (and thereby instances all children which have not
273 been already instatiated) until a child covering the specifed point is
274 found.
275 This leaves room for improvement. For instance, first iterate only over
276 the already instantiated children and only if no match is found
277 instantiate the remaining ones.
279 Reference<XAccessible > SAL_CALL AccessibleCell::getAccessibleAtPoint ( const ::com::sun::star::awt::Point& aPoint) throw(RuntimeException)
281 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
282 ::osl::MutexGuard aGuard (maMutex);
284 sal_Int32 nChildCount = getAccessibleChildCount ();
285 for (sal_Int32 i=0; i<nChildCount; ++i)
287 Reference<XAccessible> xChild (getAccessibleChild (i));
288 if (xChild.is())
290 Reference<XAccessibleComponent> xChildComponent (xChild->getAccessibleContext(), uno::UNO_QUERY);
291 if (xChildComponent.is())
293 awt::Rectangle aBBox (xChildComponent->getBounds());
294 if ( (aPoint.X >= aBBox.X)
295 && (aPoint.Y >= aBBox.Y)
296 && (aPoint.X < aBBox.X+aBBox.Width)
297 && (aPoint.Y < aBBox.Y+aBBox.Height) )
298 return xChild;
303 // Have not found a child under the given point. Returning empty
304 // reference to indicate this.
305 return uno::Reference<XAccessible>();
308 // --------------------------------------------------------------------
310 ::com::sun::star::awt::Rectangle SAL_CALL AccessibleCell::getBounds(void) throw(RuntimeException)
312 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
313 ::osl::MutexGuard aGuard (maMutex);
315 ThrowIfDisposed ();
316 ::com::sun::star::awt::Rectangle aBoundingBox;
317 if( mxCell.is() )
319 // Get the cell's bounding box in internal coordinates (in 100th of mm)
320 const ::Rectangle aCellRect( mxCell->getCellRect() );
322 // Transform coordinates from internal to pixel.
323 if (maShapeTreeInfo.GetViewForwarder() == NULL)
324 throw uno::RuntimeException (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleCell has no valid view forwarder")),static_cast<uno::XWeak*>(this));
326 ::Size aPixelSize( maShapeTreeInfo.GetViewForwarder()->LogicToPixel(::Size(aCellRect.GetWidth(), aCellRect.GetHeight())) );
327 ::Point aPixelPosition( maShapeTreeInfo.GetViewForwarder()->LogicToPixel( aCellRect.TopLeft() ));
329 // Clip the shape's bounding box with the bounding box of its parent.
330 Reference<XAccessibleComponent> xParentComponent ( getAccessibleParent(), uno::UNO_QUERY);
331 if (xParentComponent.is())
333 // Make the coordinates relative to the parent.
334 awt::Point aParentLocation (xParentComponent->getLocationOnScreen());
335 int x = aPixelPosition.getX() - aParentLocation.X;
336 int y = aPixelPosition.getY() - aParentLocation.Y;
338 // Clip with parent (with coordinates relative to itself).
339 ::Rectangle aBBox ( x, y, x + aPixelSize.getWidth(), y + aPixelSize.getHeight());
340 awt::Size aParentSize (xParentComponent->getSize());
341 ::Rectangle aParentBBox (0,0, aParentSize.Width, aParentSize.Height);
342 aBBox = aBBox.GetIntersection (aParentBBox);
343 aBoundingBox = awt::Rectangle ( aBBox.getX(), aBBox.getY(), aBBox.getWidth(), aBBox.getHeight());
345 else
347 OSL_TRACE ("parent does not support component");
348 aBoundingBox = awt::Rectangle (aPixelPosition.getX(), aPixelPosition.getY(),aPixelSize.getWidth(), aPixelSize.getHeight());
352 return aBoundingBox;
355 // --------------------------------------------------------------------
357 ::com::sun::star::awt::Point SAL_CALL AccessibleCell::getLocation(void) throw (RuntimeException)
359 ThrowIfDisposed ();
360 ::com::sun::star::awt::Rectangle aBoundingBox(getBounds());
361 return ::com::sun::star::awt::Point(aBoundingBox.X, aBoundingBox.Y);
364 // --------------------------------------------------------------------
366 ::com::sun::star::awt::Point SAL_CALL AccessibleCell::getLocationOnScreen(void) throw(RuntimeException)
368 ThrowIfDisposed ();
370 // Get relative position...
371 ::com::sun::star::awt::Point aLocation(getLocation ());
373 // ... and add absolute position of the parent.
374 Reference<XAccessibleComponent> xParentComponent( getAccessibleParent(), uno::UNO_QUERY);
375 if(xParentComponent.is())
377 ::com::sun::star::awt::Point aParentLocation(xParentComponent->getLocationOnScreen());
378 aLocation.X += aParentLocation.X;
379 aLocation.Y += aParentLocation.Y;
381 else
383 OSL_TRACE ("getLocation: parent does not support XAccessibleComponent");
386 return aLocation;
389 // --------------------------------------------------------------------
391 awt::Size SAL_CALL AccessibleCell::getSize (void) throw (RuntimeException)
393 ThrowIfDisposed ();
394 awt::Rectangle aBoundingBox (getBounds());
395 return awt::Size (aBoundingBox.Width, aBoundingBox.Height);
398 // --------------------------------------------------------------------
400 void SAL_CALL AccessibleCell::addFocusListener ( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener) throw (::com::sun::star::uno::RuntimeException)
402 AccessibleComponentBase::addFocusListener( xListener );
405 // --------------------------------------------------------------------
407 void SAL_CALL AccessibleCell::removeFocusListener (const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
409 AccessibleComponentBase::removeFocusListener( xListener );
412 // --------------------------------------------------------------------
414 void SAL_CALL AccessibleCell::grabFocus (void) throw (::com::sun::star::uno::RuntimeException)
416 AccessibleComponentBase::grabFocus();
419 // --------------------------------------------------------------------
421 sal_Int32 SAL_CALL AccessibleCell::getForeground(void) throw (RuntimeException)
423 ThrowIfDisposed ();
424 sal_Int32 nColor (0x0ffffffL);
426 // todo
427 return nColor;
430 // --------------------------------------------------------------------
432 sal_Int32 SAL_CALL AccessibleCell::getBackground (void) throw (RuntimeException)
434 ThrowIfDisposed ();
435 sal_Int32 nColor (0L);
437 // todo
438 return nColor;
441 // --------------------------------------------------------------------
442 // XAccessibleExtendedComponent
443 // --------------------------------------------------------------------
445 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFont > SAL_CALL AccessibleCell::getFont (void) throw (::com::sun::star::uno::RuntimeException)
447 //todo
448 return AccessibleComponentBase::getFont();
451 // --------------------------------------------------------------------
453 ::rtl::OUString SAL_CALL AccessibleCell::getTitledBorderText (void) throw (::com::sun::star::uno::RuntimeException)
455 return AccessibleComponentBase::getTitledBorderText();
458 // --------------------------------------------------------------------
460 ::rtl::OUString SAL_CALL AccessibleCell::getToolTipText (void) throw (::com::sun::star::uno::RuntimeException)
462 return AccessibleComponentBase::getToolTipText();
465 // --------------------------------------------------------------------
466 // XAccessibleEventBroadcaster
467 // --------------------------------------------------------------------
469 void SAL_CALL AccessibleCell::addEventListener( const Reference<XAccessibleEventListener >& rxListener) throw (RuntimeException)
471 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
472 ::osl::MutexGuard aGuard (maMutex);
473 if (rBHelper.bDisposed || rBHelper.bInDispose)
475 Reference<XInterface> xSource( static_cast<XComponent *>(this) );
476 lang::EventObject aEventObj(xSource);
477 rxListener->disposing(aEventObj);
479 else
481 AccessibleContextBase::addEventListener (rxListener);
482 if (mpText != NULL)
483 mpText->AddEventListener (rxListener);
487 // --------------------------------------------------------------------
489 void SAL_CALL AccessibleCell::removeEventListener( const Reference<XAccessibleEventListener >& rxListener) throw (RuntimeException)
491 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
492 AccessibleContextBase::removeEventListener(rxListener);
493 if (mpText != NULL)
494 mpText->RemoveEventListener (rxListener);
497 // --------------------------------------------------------------------
498 // XServiceInfo
499 // --------------------------------------------------------------------
501 OUString SAL_CALL AccessibleCell::getImplementationName(void) throw (RuntimeException)
503 return OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleCell"));
506 // --------------------------------------------------------------------
508 Sequence<OUString> SAL_CALL AccessibleCell::getSupportedServiceNames(void) throw (RuntimeException)
510 ThrowIfDisposed ();
512 // Get list of supported service names from base class...
513 uno::Sequence<OUString> aServiceNames = AccessibleContextBase::getSupportedServiceNames();
514 sal_Int32 nCount (aServiceNames.getLength());
516 // ...and add additional names.
517 aServiceNames.realloc (nCount + 1);
518 static const OUString sAdditionalServiceName (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.AccessibleCell"));
519 aServiceNames[nCount] = sAdditionalServiceName;
521 return aServiceNames;
524 // --------------------------------------------------------------------
525 // IAccessibleViewForwarderListener
526 // --------------------------------------------------------------------
528 void AccessibleCell::ViewForwarderChanged (ChangeType /*aChangeType*/, const IAccessibleViewForwarder* /*pViewForwarder*/)
530 // Inform all listeners that the graphical representation (i.e. size
531 // and/or position) of the shape has changed.
532 CommitChange(AccessibleEventId::VISIBLE_DATA_CHANGED, Any(), Any());
534 // update our children that our screen position might have changed
535 if( mpText )
536 mpText->UpdateChildren();
539 // --------------------------------------------------------------------
540 // protected
541 // --------------------------------------------------------------------
543 void AccessibleCell::disposing (void)
545 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
546 ::osl::MutexGuard aGuard (maMutex);
548 // Make sure to send an event that this object looses the focus in the
549 // case that it has the focus.
550 ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
551 if (pStateSet != NULL)
552 pStateSet->RemoveState(AccessibleStateType::FOCUSED);
554 if (mpText != NULL)
556 mpText->Dispose();
557 delete mpText;
558 mpText = NULL;
561 // Cleanup. Remove references to objects to allow them to be
562 // destroyed.
563 mxCell.clear();
564 maShapeTreeInfo = AccessibleShapeTreeInfo();
566 // Call base classes.
567 AccessibleContextBase::dispose ();
570 sal_Int32 SAL_CALL AccessibleCell::getAccessibleIndexInParent (void) throw (RuntimeException)
572 ThrowIfDisposed ();
573 return mnIndexInParent;
576 ::rtl::OUString SAL_CALL AccessibleCell::getAccessibleName (void) throw (::com::sun::star::uno::RuntimeException)
578 ThrowIfDisposed ();
579 ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
581 if( mxCell.is() )
582 return mxCell->getName();
584 return AccessibleCellBase::getAccessibleName();
587 } // end of namespace accessibility