Files
libreoffice/svx/source/table/accessiblecell.cxx
Release Engineers 262b6f4b50 CWS-TOOLING: integrate CWS impress168
2009-04-24 11:26:33 +0200 wg  r271204 : i101157
2009-04-24 10:17:59 +0200 wg  r271200 : i101157
2009-04-23 15:50:12 +0200 wg  r271178 : i101157
2009-04-23 15:16:58 +0200 wg  r271176 : i101157
2009-04-23 13:04:41 +0200 wg  r271158 : i101157
2009-04-22 15:39:32 +0200 wg  r271123 : i101157
2009-04-22 14:27:24 +0200 wg  r271111 : i101157
2009-04-22 14:14:02 +0200 wg  r271109 : i101157
2009-04-17 14:34:19 +0200 wg  r270946 : i101157
2009-04-17 13:49:15 +0200 wg  r270939 : i101157
2009-03-31 14:54:52 +0200 sj  r270281 : CWS-TOOLING: rebase CWS impress168 to trunk@270033 (milestone: DEV300:m45)
2009-03-26 16:56:44 +0100 sj  r270089 : removed invalid file names
2009-03-24 14:02:54 +0100 sj  r269944 : CWS-TOOLING: rebase CWS impress168 to trunk@269781 (milestone: DEV300:m44)
2009-03-06 16:32:14 +0100 sj  r269020 : #i99970# importing customshapes without group object, taking care of the correct text alignment
2009-02-27 13:53:24 +0100 sj  r268591 : #158501,158483# fixed positioning problem of 3d customshapes
2009-02-19 16:02:00 +0100 sj  r268292 : #76543# fixed interactive hyperlink program action with relativ url
2009-02-18 15:36:52 +0100 sj  r268233 : #158503# added import of circular gradients for ellipse shapes
2009-02-16 19:51:54 +0100 sj  r267836 : #i99146# calculating correct text bounds
2009-02-12 13:59:46 +0100 sj  r267654 : #i96179# fixed bullet problem
2009-02-10 17:26:41 +0100 sj  r267566 : #158476# fixed import of the ribbon shape
2009-02-10 17:10:27 +0100 cl  r267561 : #i95364# fixed type detection of linked images
2009-02-09 18:31:59 +0100 cl  r267531 : #i98352# removed assertion
2009-02-09 18:31:17 +0100 cl  r267530 : #i98355# fixed alien attribute import for sd in binfilter
2009-02-09 18:30:53 +0100 cl  r267529 : #i98355# fixed alien attribute import for sd in binfilter
2009-02-09 09:52:15 +0100 cl  r267501 : #i98573# fixed build error
2009-02-06 17:02:21 +0100 sj  r267476 : #i96179# fixed bullet problem
2009-02-06 14:58:39 +0100 cl  r267466 : #i14832# fixed page count field for handout printing
2009-02-06 10:23:01 +0100 cl  r267447 : #i98573# fixed GetEditOutlinerParaObject() memory leak
2009-02-05 18:03:34 +0100 cl  r267435 : #i98573# fixed GetEditOutlinerParaObject() memory leak
2009-02-05 18:03:08 +0100 cl  r267434 : #i85481# added XMultiPropertyStates to text implementations
2009-02-05 18:02:54 +0100 cl  r267433 : #i85481# added XMultiPropertyStates to text implementations
2009-02-05 18:02:42 +0100 cl  r267432 : #i85481# added XMultiPropertyStates to text implementations
2009-02-04 18:54:46 +0100 sj  r267400 : #i33630# fixed arrow size of word import
2009-02-04 15:40:16 +0100 cl  r267389 : #i58702# fixed tiled bitmap fill for vcl canvas
2009-02-04 15:39:07 +0100 cl  r267388 : #i58702# fixed tiled bitmap fill for vcl canvas
2009-02-04 14:23:27 +0100 cl  r267382 : #i98573# fixed memory leaks caused by wron usage of GetEditOutlinerParaObject()
2009-02-04 14:22:34 +0100 cl  r267381 : #i98573# fixed memory leaks caused by wron usage of GetEditOutlinerParaObject()
2009-02-04 12:51:50 +0100 cl  r267371 : #i14832# added Page Count field to impress
2009-02-04 12:41:31 +0100 cl  r267368 : #i14832# added Page Count field to impress
2009-05-06 21:51:02 +00:00

577 lines
20 KiB
C++

/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: accessiblecell.cxx,v $
* $Revision: 1.5 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"
#include <accessiblecell.hxx>
#include "DescriptionGenerator.hxx"
#include <com/sun/star/accessibility/AccessibleRole.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <vcl/svapp.hxx>
#include <unotools/accessiblestatesethelper.hxx>
#include <svx/outlobj.hxx>
#include <svx/unoshtxt.hxx>
#include <svx/svdotext.hxx>
using ::rtl::OUString;
using namespace ::sdr::table;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::accessibility;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::container;
namespace accessibility {
// --------------------------------------------------------------------
// AccessibleCell
// --------------------------------------------------------------------
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 )
: AccessibleCellBase( rxParent, AccessibleRole::TABLE_CELL )
, maShapeTreeInfo( rShapeTreeInfo )
, mnIndexInParent( nIndex )
, mpText( NULL )
, mxCell( rCell )
{
}
// --------------------------------------------------------------------
AccessibleCell::~AccessibleCell (void)
{
DBG_ASSERT( mpText == 0, "svx::AccessibleCell::~AccessibleCell(), not disposed!?" );
}
// --------------------------------------------------------------------
void AccessibleCell::Init (void)
{
SdrView* pView = maShapeTreeInfo.GetSdrView();
const Window* pWindow = maShapeTreeInfo.GetWindow ();
if( (pView != NULL) && (pWindow != NULL) && mxCell.is())
{
OutlinerParaObject* pOutlinerParaObject = mxCell->GetEditOutlinerParaObject(); // Get the OutlinerParaObject if text edit is active
bool bOwnParaObject = pOutlinerParaObject != 0;
if( !pOutlinerParaObject )
pOutlinerParaObject = mxCell->GetOutlinerParaObject();
// create AccessibleTextHelper to handle this shape's text
if( pOutlinerParaObject )
{
// non-empty text -> use full-fledged edit source right away
::std::auto_ptr<SvxEditSource> pEditSource( new SvxTextEditSource( mxCell->GetObject(), mxCell.get(), *pView, *pWindow) );
mpText = new AccessibleTextHelper( pEditSource );
mpText->SetEventSource(this);
}
if( bOwnParaObject)
delete pOutlinerParaObject;
}
}
// --------------------------------------------------------------------
sal_Bool AccessibleCell::SetState (sal_Int16 aState)
{
sal_Bool bStateHasChanged = sal_False;
if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
{
// Offer FOCUSED state to edit engine and detect whether the state
// changes.
sal_Bool bIsFocused = mpText->HaveFocus ();
mpText->SetFocus (sal_True);
bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
}
else
bStateHasChanged = AccessibleContextBase::SetState (aState);
return bStateHasChanged;
}
// --------------------------------------------------------------------
sal_Bool AccessibleCell::ResetState (sal_Int16 aState)
{
sal_Bool bStateHasChanged = sal_False;
if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
{
// Try to remove FOCUSED state from the edit engine and detect
// whether the state changes.
sal_Bool bIsFocused = mpText->HaveFocus ();
mpText->SetFocus (sal_False);
bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
}
else
bStateHasChanged = AccessibleContextBase::ResetState (aState);
return bStateHasChanged;
}
// --------------------------------------------------------------------
sal_Bool AccessibleCell::GetState (sal_Int16 aState)
{
if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
{
// Just delegate the call to the edit engine. The state is not
// merged into the state set.
return mpText->HaveFocus();
}
else
return AccessibleContextBase::GetState (aState);
}
//-----------------------------------------------------------------------------
bool AccessibleCell::operator== (const AccessibleCell& rAccessibleCell)
{
return this == &rAccessibleCell;
}
//-----------------------------------------------------------------------------
// XInterface
//-----------------------------------------------------------------------------
Any SAL_CALL AccessibleCell::queryInterface( const Type& aType ) throw (RuntimeException)
{
return AccessibleCellBase::queryInterface( aType );
}
//-----------------------------------------------------------------------------
void SAL_CALL AccessibleCell::acquire( ) throw ()
{
AccessibleCellBase::acquire();
}
//-----------------------------------------------------------------------------
void SAL_CALL AccessibleCell::release( ) throw ()
{
AccessibleCellBase::release();
}
// --------------------------------------------------------------------
// XAccessibleContext
// --------------------------------------------------------------------
/** The children of this cell come from the paragraphs of text.
*/
sal_Int32 SAL_CALL AccessibleCell::getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException)
{
::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
ThrowIfDisposed ();
return mpText != NULL ? mpText->GetChildCount () : 0;
}
// --------------------------------------------------------------------
/** Forward the request to the shape. Return the requested shape or throw
an exception for a wrong index.
*/
Reference<XAccessible> SAL_CALL AccessibleCell::getAccessibleChild (sal_Int32 nIndex) throw (IndexOutOfBoundsException, RuntimeException)
{
::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
ThrowIfDisposed ();
// todo: does GetChild throw IndexOutOfBoundsException?
return mpText->GetChild (nIndex);
}
// --------------------------------------------------------------------
/** Return a copy of the state set.
Possible states are:
ENABLED
SHOWING
VISIBLE
*/
Reference<XAccessibleStateSet> SAL_CALL AccessibleCell::getAccessibleStateSet (void) throw (RuntimeException)
{
::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
::osl::MutexGuard aGuard (maMutex);
Reference<XAccessibleStateSet> xStateSet;
if (rBHelper.bDisposed || mpText == NULL)
{
// Return a minimal state set that only contains the DEFUNC state.
xStateSet = AccessibleContextBase::getAccessibleStateSet ();
}
else
{
::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
if(pStateSet)
{
// Merge current FOCUSED state from edit engine.
if (mpText != NULL)
{
if (mpText->HaveFocus())
pStateSet->AddState (AccessibleStateType::FOCUSED);
else
pStateSet->RemoveState (AccessibleStateType::FOCUSED);
}
// Create a copy of the state set that may be modified by the
// caller without affecting the current state set.
xStateSet = Reference<XAccessibleStateSet>(new ::utl::AccessibleStateSetHelper (*pStateSet));
}
}
return xStateSet;
}
// --------------------------------------------------------------------
// XAccessibleComponent
// --------------------------------------------------------------------
sal_Bool SAL_CALL AccessibleCell::containsPoint( const ::com::sun::star::awt::Point& aPoint) throw (::com::sun::star::uno::RuntimeException)
{
return AccessibleComponentBase::containsPoint( aPoint );
}
/** The implementation below is at the moment straightforward. It iterates
over all children (and thereby instances all children which have not
been already instatiated) until a child covering the specifed point is
found.
This leaves room for improvement. For instance, first iterate only over
the already instantiated children and only if no match is found
instantiate the remaining ones.
*/
Reference<XAccessible > SAL_CALL AccessibleCell::getAccessibleAtPoint ( const ::com::sun::star::awt::Point& aPoint) throw(RuntimeException)
{
::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
::osl::MutexGuard aGuard (maMutex);
sal_Int32 nChildCount = getAccessibleChildCount ();
for (sal_Int32 i=0; i<nChildCount; ++i)
{
Reference<XAccessible> xChild (getAccessibleChild (i));
if (xChild.is())
{
Reference<XAccessibleComponent> xChildComponent (xChild->getAccessibleContext(), uno::UNO_QUERY);
if (xChildComponent.is())
{
awt::Rectangle aBBox (xChildComponent->getBounds());
if ( (aPoint.X >= aBBox.X)
&& (aPoint.Y >= aBBox.Y)
&& (aPoint.X < aBBox.X+aBBox.Width)
&& (aPoint.Y < aBBox.Y+aBBox.Height) )
return xChild;
}
}
}
// Have not found a child under the given point. Returning empty
// reference to indicate this.
return uno::Reference<XAccessible>();
}
// --------------------------------------------------------------------
::com::sun::star::awt::Rectangle SAL_CALL AccessibleCell::getBounds(void) throw(RuntimeException)
{
::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
::osl::MutexGuard aGuard (maMutex);
ThrowIfDisposed ();
::com::sun::star::awt::Rectangle aBoundingBox;
if( mxCell.is() )
{
// Get the cell's bounding box in internal coordinates (in 100th of mm)
const ::Rectangle aCellRect( mxCell->getCellRect() );
// Transform coordinates from internal to pixel.
if (maShapeTreeInfo.GetViewForwarder() == NULL)
throw uno::RuntimeException (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleCell has no valid view forwarder")),static_cast<uno::XWeak*>(this));
::Size aPixelSize( maShapeTreeInfo.GetViewForwarder()->LogicToPixel(::Size(aCellRect.GetWidth(), aCellRect.GetHeight())) );
::Point aPixelPosition( maShapeTreeInfo.GetViewForwarder()->LogicToPixel( aCellRect.TopLeft() ));
// Clip the shape's bounding box with the bounding box of its parent.
Reference<XAccessibleComponent> xParentComponent ( getAccessibleParent(), uno::UNO_QUERY);
if (xParentComponent.is())
{
// Make the coordinates relative to the parent.
awt::Point aParentLocation (xParentComponent->getLocationOnScreen());
int x = aPixelPosition.getX() - aParentLocation.X;
int y = aPixelPosition.getY() - aParentLocation.Y;
// Clip with parent (with coordinates relative to itself).
::Rectangle aBBox ( x, y, x + aPixelSize.getWidth(), y + aPixelSize.getHeight());
awt::Size aParentSize (xParentComponent->getSize());
::Rectangle aParentBBox (0,0, aParentSize.Width, aParentSize.Height);
aBBox = aBBox.GetIntersection (aParentBBox);
aBoundingBox = awt::Rectangle ( aBBox.getX(), aBBox.getY(), aBBox.getWidth(), aBBox.getHeight());
}
else
{
OSL_TRACE ("parent does not support component");
aBoundingBox = awt::Rectangle (aPixelPosition.getX(), aPixelPosition.getY(),aPixelSize.getWidth(), aPixelSize.getHeight());
}
}
return aBoundingBox;
}
// --------------------------------------------------------------------
::com::sun::star::awt::Point SAL_CALL AccessibleCell::getLocation(void) throw (RuntimeException)
{
ThrowIfDisposed ();
::com::sun::star::awt::Rectangle aBoundingBox(getBounds());
return ::com::sun::star::awt::Point(aBoundingBox.X, aBoundingBox.Y);
}
// --------------------------------------------------------------------
::com::sun::star::awt::Point SAL_CALL AccessibleCell::getLocationOnScreen(void) throw(RuntimeException)
{
ThrowIfDisposed ();
// Get relative position...
::com::sun::star::awt::Point aLocation(getLocation ());
// ... and add absolute position of the parent.
Reference<XAccessibleComponent> xParentComponent( getAccessibleParent(), uno::UNO_QUERY);
if(xParentComponent.is())
{
::com::sun::star::awt::Point aParentLocation(xParentComponent->getLocationOnScreen());
aLocation.X += aParentLocation.X;
aLocation.Y += aParentLocation.Y;
}
else
{
OSL_TRACE ("getLocation: parent does not support XAccessibleComponent");
}
return aLocation;
}
// --------------------------------------------------------------------
awt::Size SAL_CALL AccessibleCell::getSize (void) throw (RuntimeException)
{
ThrowIfDisposed ();
awt::Rectangle aBoundingBox (getBounds());
return awt::Size (aBoundingBox.Width, aBoundingBox.Height);
}
// --------------------------------------------------------------------
void SAL_CALL AccessibleCell::addFocusListener ( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener) throw (::com::sun::star::uno::RuntimeException)
{
AccessibleComponentBase::addFocusListener( xListener );
}
// --------------------------------------------------------------------
void SAL_CALL AccessibleCell::removeFocusListener (const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
{
AccessibleComponentBase::removeFocusListener( xListener );
}
// --------------------------------------------------------------------
void SAL_CALL AccessibleCell::grabFocus (void) throw (::com::sun::star::uno::RuntimeException)
{
AccessibleComponentBase::grabFocus();
}
// --------------------------------------------------------------------
sal_Int32 SAL_CALL AccessibleCell::getForeground(void) throw (RuntimeException)
{
ThrowIfDisposed ();
sal_Int32 nColor (0x0ffffffL);
// todo
return nColor;
}
// --------------------------------------------------------------------
sal_Int32 SAL_CALL AccessibleCell::getBackground (void) throw (RuntimeException)
{
ThrowIfDisposed ();
sal_Int32 nColor (0L);
// todo
return nColor;
}
// --------------------------------------------------------------------
// XAccessibleExtendedComponent
// --------------------------------------------------------------------
::com::sun::star::uno::Reference< ::com::sun::star::awt::XFont > SAL_CALL AccessibleCell::getFont (void) throw (::com::sun::star::uno::RuntimeException)
{
//todo
return AccessibleComponentBase::getFont();
}
// --------------------------------------------------------------------
::rtl::OUString SAL_CALL AccessibleCell::getTitledBorderText (void) throw (::com::sun::star::uno::RuntimeException)
{
return AccessibleComponentBase::getTitledBorderText();
}
// --------------------------------------------------------------------
::rtl::OUString SAL_CALL AccessibleCell::getToolTipText (void) throw (::com::sun::star::uno::RuntimeException)
{
return AccessibleComponentBase::getToolTipText();
}
// --------------------------------------------------------------------
// XAccessibleEventBroadcaster
// --------------------------------------------------------------------
void SAL_CALL AccessibleCell::addEventListener( const Reference<XAccessibleEventListener >& rxListener) throw (RuntimeException)
{
::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
::osl::MutexGuard aGuard (maMutex);
if (rBHelper.bDisposed || rBHelper.bInDispose)
{
Reference<XInterface> xSource( static_cast<XComponent *>(this) );
lang::EventObject aEventObj(xSource);
rxListener->disposing(aEventObj);
}
else
{
AccessibleContextBase::addEventListener (rxListener);
if (mpText != NULL)
mpText->AddEventListener (rxListener);
}
}
// --------------------------------------------------------------------
void SAL_CALL AccessibleCell::removeEventListener( const Reference<XAccessibleEventListener >& rxListener) throw (RuntimeException)
{
::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
AccessibleContextBase::removeEventListener(rxListener);
if (mpText != NULL)
mpText->RemoveEventListener (rxListener);
}
// --------------------------------------------------------------------
// XServiceInfo
// --------------------------------------------------------------------
OUString SAL_CALL AccessibleCell::getImplementationName(void) throw (RuntimeException)
{
return OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleCell"));
}
// --------------------------------------------------------------------
Sequence<OUString> SAL_CALL AccessibleCell::getSupportedServiceNames(void) throw (RuntimeException)
{
ThrowIfDisposed ();
// Get list of supported service names from base class...
uno::Sequence<OUString> aServiceNames = AccessibleContextBase::getSupportedServiceNames();
sal_Int32 nCount (aServiceNames.getLength());
// ...and add additional names.
aServiceNames.realloc (nCount + 1);
static const OUString sAdditionalServiceName (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.AccessibleCell"));
aServiceNames[nCount] = sAdditionalServiceName;
return aServiceNames;
}
// --------------------------------------------------------------------
// IAccessibleViewForwarderListener
// --------------------------------------------------------------------
void AccessibleCell::ViewForwarderChanged (ChangeType /*aChangeType*/, const IAccessibleViewForwarder* /*pViewForwarder*/)
{
// Inform all listeners that the graphical representation (i.e. size
// and/or position) of the shape has changed.
CommitChange(AccessibleEventId::VISIBLE_DATA_CHANGED, Any(), Any());
// update our children that our screen position might have changed
if( mpText )
mpText->UpdateChildren();
}
// --------------------------------------------------------------------
// protected
// --------------------------------------------------------------------
void AccessibleCell::disposing (void)
{
::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
::osl::MutexGuard aGuard (maMutex);
// Make sure to send an event that this object looses the focus in the
// case that it has the focus.
::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
if (pStateSet != NULL)
pStateSet->RemoveState(AccessibleStateType::FOCUSED);
if (mpText != NULL)
{
mpText->Dispose();
delete mpText;
mpText = NULL;
}
// Cleanup. Remove references to objects to allow them to be
// destroyed.
mxCell.clear();
maShapeTreeInfo = AccessibleShapeTreeInfo();
// Call base classes.
AccessibleContextBase::dispose ();
}
sal_Int32 SAL_CALL AccessibleCell::getAccessibleIndexInParent (void) throw (RuntimeException)
{
ThrowIfDisposed ();
return mnIndexInParent;
}
} // end of namespace accessibility