diff options
Diffstat (limited to 'sd/source/ui/accessibility')
17 files changed, 6030 insertions, 0 deletions
diff --git a/sd/source/ui/accessibility/AccessibleDocumentViewBase.cxx b/sd/source/ui/accessibility/AccessibleDocumentViewBase.cxx new file mode 100644 index 000000000000..034a0bc5e863 --- /dev/null +++ b/sd/source/ui/accessibility/AccessibleDocumentViewBase.cxx @@ -0,0 +1,842 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_sd.hxx" +#include "AccessibleDocumentViewBase.hxx" +#include <com/sun/star/drawing/XDrawPage.hpp> +#include <com/sun/star/drawing/XDrawView.hpp> +#include <com/sun/star/drawing/XShapes.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <rtl/ustring.h> +#include<sfx2/viewfrm.hxx> + +#include <svx/AccessibleShape.hxx> + +#include <svx/svdobj.hxx> +#include <svx/svdmodel.hxx> +#include <svx/unoapi.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include "Window.hxx" +#include <vcl/svapp.hxx> + + +#include "ViewShell.hxx" +#include "View.hxx" +#include <memory> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using ::com::sun::star::uno::Reference; + +class SfxViewFrame; + +namespace accessibility { + +//===== internal ============================================================ +AccessibleDocumentViewBase::AccessibleDocumentViewBase ( + ::sd::Window* pSdWindow, + ::sd::ViewShell* pViewShell, + const uno::Reference<frame::XController>& rxController, + const uno::Reference<XAccessible>& rxParent) + : AccessibleContextBase (rxParent, AccessibleRole::DOCUMENT), + mpWindow (pSdWindow), + mxController (rxController), + mxModel (NULL), + maViewForwarder ( + static_cast<SdrPaintView*>(pViewShell->GetView()), + *static_cast<OutputDevice*>(pSdWindow)) +{ + if (mxController.is()) + mxModel = mxController->getModel(); + + // Fill the shape tree info. + maShapeTreeInfo.SetModelBroadcaster ( + uno::Reference<document::XEventBroadcaster>( + mxModel, uno::UNO_QUERY)); + maShapeTreeInfo.SetController (mxController); + maShapeTreeInfo.SetSdrView (pViewShell->GetView()); + maShapeTreeInfo.SetWindow (pSdWindow); + maShapeTreeInfo.SetViewForwarder (&maViewForwarder); + + mxWindow = ::VCLUnoHelper::GetInterface (pSdWindow); +} + + + + +AccessibleDocumentViewBase::~AccessibleDocumentViewBase (void) +{ + // At this place we should be disposed. You may want to add a + // corresponding assertion into the destructor of a derived class. +} + + + + +void AccessibleDocumentViewBase::Init (void) +{ + // Finish the initialization of the shape tree info container. + maShapeTreeInfo.SetDocumentWindow (this); + + // Register as window listener to stay up to date with its size and + // position. + mxWindow->addWindowListener (this); + // Register as focus listener to + mxWindow->addFocusListener (this); + + // Determine the list of shapes on the current page. + uno::Reference<drawing::XShapes> xShapeList; + uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY); + if (xView.is()) + xShapeList = uno::Reference<drawing::XShapes> ( + xView->getCurrentPage(), uno::UNO_QUERY); + + // Register this object as dispose event listener at the model. + if (mxModel.is()) + mxModel->addEventListener ( + static_cast<awt::XWindowListener*>(this)); + + // Register as property change listener at the controller. + uno::Reference<beans::XPropertySet> xSet (mxController, uno::UNO_QUERY); + if (xSet.is()) + xSet->addPropertyChangeListener ( + OUString (RTL_CONSTASCII_USTRINGPARAM("")), + static_cast<beans::XPropertyChangeListener*>(this)); + + // Register this object as dispose event listener at the controller. + if (mxController.is()) + mxController->addEventListener ( + static_cast<awt::XWindowListener*>(this)); + + // Register at VCL Window to be informed of activated and deactivated + // OLE objects. + Window* pWindow = maShapeTreeInfo.GetWindow(); + if (pWindow != NULL) + { + maWindowLink = LINK( + this, AccessibleDocumentViewBase, WindowChildEventListener); + + pWindow->AddChildEventListener (maWindowLink); + + USHORT nCount = pWindow->GetChildCount(); + for (sal_uInt16 i=0; i<nCount; i++) + { + Window* pChildWindow = pWindow->GetChild (i); + if (pChildWindow && + (AccessibleRole::EMBEDDED_OBJECT + ==pChildWindow->GetAccessibleRole())) + { + SetAccessibleOLEObject (pChildWindow->GetAccessible()); + } + } + } +} + + + + +IMPL_LINK(AccessibleDocumentViewBase, WindowChildEventListener, + VclSimpleEvent*, pEvent) +{ + OSL_ASSERT(pEvent!=NULL && pEvent->ISA(VclWindowEvent)); + if (pEvent!=NULL && pEvent->ISA(VclWindowEvent)) + { + VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent); + // DBG_ASSERT( pVclEvent->GetWindow(), "Window???" ); + switch (pWindowEvent->GetId()) + { + case VCLEVENT_OBJECT_DYING: + { + // Window is dying. Unregister from VCL Window. + // This is also attempted in the disposing() method. + Window* pWindow = maShapeTreeInfo.GetWindow(); + Window* pDyingWindow = static_cast<Window*>( + pWindowEvent->GetWindow()); + if (pWindow==pDyingWindow && pWindow!=NULL && maWindowLink.IsSet()) + { + pWindow->RemoveChildEventListener (maWindowLink); + maWindowLink = Link(); + } + } + break; + + case VCLEVENT_WINDOW_SHOW: + { + // A new window has been created. Is it an OLE object? + Window* pChildWindow = static_cast<Window*>( + pWindowEvent->GetData()); + if (pChildWindow!=NULL + && (pChildWindow->GetAccessibleRole() + == AccessibleRole::EMBEDDED_OBJECT)) + { + SetAccessibleOLEObject (pChildWindow->GetAccessible()); + } + } + break; + + case VCLEVENT_WINDOW_HIDE: + { + // A window has been destroyed. Has that been an OLE + // object? + Window* pChildWindow = static_cast<Window*>( + pWindowEvent->GetData()); + if (pChildWindow!=NULL + && (pChildWindow->GetAccessibleRole() + == AccessibleRole::EMBEDDED_OBJECT)) + { + SetAccessibleOLEObject (NULL); + } + } + break; + } + } + + return 0; +} + + + + +//===== IAccessibleViewForwarderListener ==================================== + +void AccessibleDocumentViewBase::ViewForwarderChanged(ChangeType, const IAccessibleViewForwarder* ) +{ + // Empty +} + + + + +//===== XAccessibleContext ================================================== + +Reference<XAccessible> SAL_CALL + AccessibleDocumentViewBase::getAccessibleParent (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed (); + + return AccessibleContextBase::getAccessibleParent(); +} + + + +sal_Int32 SAL_CALL + AccessibleDocumentViewBase::getAccessibleChildCount (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed (); + + if (mxAccessibleOLEObject.is()) + return 1; + else + return 0; +} + + + + +Reference<XAccessible> SAL_CALL + AccessibleDocumentViewBase::getAccessibleChild (sal_Int32 nIndex) + throw (uno::RuntimeException, lang::IndexOutOfBoundsException) +{ + ThrowIfDisposed (); + + ::osl::MutexGuard aGuard (maMutex); + if (mxAccessibleOLEObject.is()) + if (nIndex == 0) + return mxAccessibleOLEObject; + + throw lang::IndexOutOfBoundsException ( + ::rtl::OUString::createFromAscii ("no child with index ") + + rtl::OUString::valueOf(nIndex), + NULL); +} + + + + +//===== XAccessibleComponent ================================================ + +/** Iterate over all children and test whether the specified point lies + within one of their bounding boxes. Return the first child for which + this is true. +*/ +uno::Reference<XAccessible > SAL_CALL + AccessibleDocumentViewBase::getAccessibleAtPoint ( + const awt::Point& aPoint) + throw (uno::RuntimeException) +{ + ThrowIfDisposed (); + + ::osl::MutexGuard aGuard (maMutex); + uno::Reference<XAccessible> xChildAtPosition; + + sal_Int32 nChildCount = getAccessibleChildCount (); + for (sal_Int32 i=nChildCount-1; i>=0; --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) ) + { + xChildAtPosition = xChild; + break; + } + } + } + } + + // Have not found a child under the given point. Returning empty + // reference to indicate this. + return xChildAtPosition; +} + + + + +awt::Rectangle SAL_CALL + AccessibleDocumentViewBase::getBounds (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + + // Transform visible area into screen coordinates. + ::Rectangle aVisibleArea ( + maShapeTreeInfo.GetViewForwarder()->GetVisibleArea()); + ::Point aPixelTopLeft ( + maShapeTreeInfo.GetViewForwarder()->LogicToPixel ( + aVisibleArea.TopLeft())); + ::Point aPixelSize ( + maShapeTreeInfo.GetViewForwarder()->LogicToPixel ( + aVisibleArea.BottomRight()) + - aPixelTopLeft); + + // Prepare to subtract the parent position to transform into relative + // coordinates. + awt::Point aParentPosition; + Reference<XAccessible> xParent = getAccessibleParent (); + if (xParent.is()) + { + Reference<XAccessibleComponent> xParentComponent ( + xParent->getAccessibleContext(), uno::UNO_QUERY); + if (xParentComponent.is()) + aParentPosition = xParentComponent->getLocationOnScreen(); + } + + return awt::Rectangle ( + aPixelTopLeft.X() - aParentPosition.X, + aPixelTopLeft.Y() - aParentPosition.Y, + aPixelSize.X(), + aPixelSize.Y()); +} + + + + +awt::Point SAL_CALL + AccessibleDocumentViewBase::getLocation (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed (); + awt::Rectangle aBoundingBox (getBounds()); + return awt::Point (aBoundingBox.X, aBoundingBox.Y); +} + + + + +awt::Point SAL_CALL + AccessibleDocumentViewBase::getLocationOnScreen (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed (); + ::Point aLogicalPoint (maShapeTreeInfo.GetViewForwarder()->GetVisibleArea().TopLeft()); + ::Point aPixelPoint (maShapeTreeInfo.GetViewForwarder()->LogicToPixel (aLogicalPoint)); + return awt::Point (aPixelPoint.X(), aPixelPoint.Y()); +} + + + + +awt::Size SAL_CALL + AccessibleDocumentViewBase::getSize (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed (); + + // Transform visible area into screen coordinates. + ::Rectangle aVisibleArea ( + maShapeTreeInfo.GetViewForwarder()->GetVisibleArea()); + ::Point aPixelTopLeft ( + maShapeTreeInfo.GetViewForwarder()->LogicToPixel ( + aVisibleArea.TopLeft())); + ::Point aPixelSize ( + maShapeTreeInfo.GetViewForwarder()->LogicToPixel ( + aVisibleArea.BottomRight()) + - aPixelTopLeft); + + return awt::Size (aPixelSize.X(), aPixelSize.Y()); +} + + + + +//===== XInterface ========================================================== + +uno::Any SAL_CALL + AccessibleDocumentViewBase::queryInterface (const uno::Type & rType) + throw (uno::RuntimeException) +{ + uno::Any aReturn = AccessibleContextBase::queryInterface (rType); + if ( ! aReturn.hasValue()) + aReturn = ::cppu::queryInterface (rType, + static_cast<XAccessibleComponent*>(this), + static_cast<XAccessibleSelection*>(this), + static_cast<lang::XEventListener*>( + static_cast<awt::XWindowListener*>(this)), + static_cast<beans::XPropertyChangeListener*>(this), + static_cast<awt::XWindowListener*>(this), + static_cast<awt::XFocusListener*>(this) + ); + return aReturn; +} + + + + +void SAL_CALL + AccessibleDocumentViewBase::acquire (void) + throw () +{ + AccessibleContextBase::acquire (); +} + + + + +void SAL_CALL + AccessibleDocumentViewBase::release (void) + throw () +{ + AccessibleContextBase::release (); +} + + + + +//===== XServiceInfo ======================================================== + +::rtl::OUString SAL_CALL + AccessibleDocumentViewBase::getImplementationName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleDocumentViewBase")); +} + + + + +::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL + AccessibleDocumentViewBase::getSupportedServiceNames (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + return AccessibleContextBase::getSupportedServiceNames (); +} + + + + + +//===== XTypeProvider ======================================================= + +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> SAL_CALL + AccessibleDocumentViewBase::getTypes (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + + // Get list of types from the context base implementation, ... + uno::Sequence<uno::Type> aTypeList (AccessibleContextBase::getTypes()); + // ... get list of types from component base implementation, ... + uno::Sequence<uno::Type> aComponentTypeList (AccessibleComponentBase::getTypes()); + + + // ...and add the additional type for the component, ... + const uno::Type aLangEventListenerType = + ::getCppuType((const uno::Reference<lang::XEventListener>*)0); + const uno::Type aPropertyChangeListenerType = + ::getCppuType((const uno::Reference<beans::XPropertyChangeListener>*)0); + const uno::Type aWindowListenerType = + ::getCppuType((const uno::Reference<awt::XWindowListener>*)0); + const uno::Type aFocusListenerType = + ::getCppuType((const uno::Reference<awt::XFocusListener>*)0); + const uno::Type aEventBroadcaster = + ::getCppuType((const uno::Reference<XAccessibleEventBroadcaster>*)0); + + // ... and merge them all into one list. + sal_Int32 nTypeCount (aTypeList.getLength()), + nComponentTypeCount (aComponentTypeList.getLength()), + i; + + aTypeList.realloc (nTypeCount + nComponentTypeCount + 5); + + for (i=0; i<nComponentTypeCount; i++) + aTypeList[nTypeCount + i] = aComponentTypeList[i]; + + aTypeList[nTypeCount + i++ ] = aLangEventListenerType; + aTypeList[nTypeCount + i++] = aPropertyChangeListenerType; + aTypeList[nTypeCount + i++] = aWindowListenerType; + aTypeList[nTypeCount + i++] = aFocusListenerType; + aTypeList[nTypeCount + i++] = aEventBroadcaster; + + return aTypeList; +} + + + + +void AccessibleDocumentViewBase::impl_dispose() +{ + // Unregister from VCL Window. + Window* pWindow = maShapeTreeInfo.GetWindow(); + if (maWindowLink.IsSet()) + { + if (pWindow) + pWindow->RemoveChildEventListener (maWindowLink); + maWindowLink = Link(); + } + else + { + DBG_ASSERT (pWindow, "AccessibleDocumentViewBase::disposing"); + } + + // Unregister from window. + if (mxWindow.is()) + { + mxWindow->removeWindowListener (this); + mxWindow->removeFocusListener (this); + mxWindow = NULL; + } + + // Unregister form the model. + if (mxModel.is()) + mxModel->removeEventListener ( + static_cast<awt::XWindowListener*>(this)); + + // Unregister from the controller. + if (mxController.is()) + { + uno::Reference<beans::XPropertySet> xSet (mxController, uno::UNO_QUERY); + if (xSet.is()) + xSet->removePropertyChangeListener ( + OUString (RTL_CONSTASCII_USTRINGPARAM("")), + static_cast<beans::XPropertyChangeListener*>(this)); + + mxController->removeEventListener ( + static_cast<awt::XWindowListener*>(this)); + } + + // Propagate change of controller down the shape tree. + maShapeTreeInfo.SetControllerBroadcaster (NULL); + + // Reset the model reference. + mxModel = NULL; + // Reset the model reference. + mxController = NULL; + + maShapeTreeInfo.SetDocumentWindow (NULL); +} + + + + +//===== XEventListener ====================================================== + +void SAL_CALL + AccessibleDocumentViewBase::disposing (const lang::EventObject& rEventObject) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + + // Register this object as dispose event and document::XEventListener + // listener at the model. + + if ( ! rEventObject.Source.is()) + { + // Paranoia. Can this really happen? + } + else if (rEventObject.Source == mxModel || rEventObject.Source == mxController) + { + impl_dispose(); + } +} + +//===== XPropertyChangeListener ============================================= + +void SAL_CALL AccessibleDocumentViewBase::propertyChange (const beans::PropertyChangeEvent& ) + throw (::com::sun::star::uno::RuntimeException) +{ + // Empty +} + + + + +//===== XWindowListener ===================================================== + +void SAL_CALL + AccessibleDocumentViewBase::windowResized (const ::com::sun::star::awt::WindowEvent& ) + throw (::com::sun::star::uno::RuntimeException) +{ + if( IsDisposed() ) + return; + + ViewForwarderChanged ( + IAccessibleViewForwarderListener::VISIBLE_AREA, + &maViewForwarder); +} + + + + +void SAL_CALL + AccessibleDocumentViewBase::windowMoved (const ::com::sun::star::awt::WindowEvent& ) + throw (::com::sun::star::uno::RuntimeException) +{ + if( IsDisposed() ) + return; + + ViewForwarderChanged ( + IAccessibleViewForwarderListener::VISIBLE_AREA, + &maViewForwarder); +} + + + + +void SAL_CALL + AccessibleDocumentViewBase::windowShown (const ::com::sun::star::lang::EventObject& ) + throw (::com::sun::star::uno::RuntimeException) +{ + if( IsDisposed() ) + return; + + ViewForwarderChanged ( + IAccessibleViewForwarderListener::VISIBLE_AREA, + &maViewForwarder); +} + + + + +void SAL_CALL + AccessibleDocumentViewBase::windowHidden (const ::com::sun::star::lang::EventObject& ) + throw (::com::sun::star::uno::RuntimeException) +{ + if( IsDisposed() ) + return; + + ViewForwarderChanged ( + IAccessibleViewForwarderListener::VISIBLE_AREA, + &maViewForwarder); +} + + + + +//===== XFocusListener ================================================== + +void AccessibleDocumentViewBase::focusGained (const ::com::sun::star::awt::FocusEvent& e) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + if (e.Source == mxWindow) + Activated (); +} + +void AccessibleDocumentViewBase::focusLost (const ::com::sun::star::awt::FocusEvent& e) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + if (e.Source == mxWindow) + Deactivated (); +} + + + + +//===== protected internal ================================================== + +// This method is called from the component helper base class while disposing. +void SAL_CALL AccessibleDocumentViewBase::disposing (void) +{ + impl_dispose(); + + AccessibleContextBase::disposing (); +} + + + + +/// Create a name for this view. +::rtl::OUString + AccessibleDocumentViewBase::CreateAccessibleName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString ( + RTL_CONSTASCII_USTRINGPARAM("AccessibleDocumentViewBase")); +} + + + + +/** Create a description for this view. Use the model's description or URL + if a description is not available. +*/ +::rtl::OUString + AccessibleDocumentViewBase::CreateAccessibleDescription (void) + throw (::com::sun::star::uno::RuntimeException) +{ + rtl::OUString sDescription; + + uno::Reference<lang::XServiceInfo> xInfo (mxController, uno::UNO_QUERY); + if (xInfo.is()) + { + OUString sFirstService = xInfo->getSupportedServiceNames()[0]; + if (sFirstService == OUString ( + RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DrawingDocumentDrawView"))) + { + sDescription = OUString (RTL_CONSTASCII_USTRINGPARAM("Draw Document")); + } + else + sDescription = sFirstService; + } + else + sDescription = OUString ( + RTL_CONSTASCII_USTRINGPARAM("Accessible Draw Document")); + return sDescription; +} + + + + +void AccessibleDocumentViewBase::Activated (void) +{ + // Empty. Overwrite to do something usefull. +} + + + + +void AccessibleDocumentViewBase::Deactivated (void) +{ + // Empty. Overwrite to do something usefull. +} + + + + +void AccessibleDocumentViewBase::SetAccessibleOLEObject ( + const Reference <XAccessible>& xOLEObject) +{ + // Send child event about removed accessible OLE object if necessary. + if (mxAccessibleOLEObject != xOLEObject) + if (mxAccessibleOLEObject.is()) + CommitChange ( + AccessibleEventId::CHILD, + uno::Any(), + uno::makeAny (mxAccessibleOLEObject)); + + // Assume that the accessible OLE Object disposes itself correctly. + + { + ::osl::MutexGuard aGuard (maMutex); + mxAccessibleOLEObject = xOLEObject; + } + + // Send child event about new accessible OLE object if necessary. + if (mxAccessibleOLEObject.is()) + CommitChange ( + AccessibleEventId::CHILD, + uno::makeAny (mxAccessibleOLEObject), + uno::Any()); +} + + + + +//===== methods from AccessibleSelectionBase ================================================== + +// return the member maMutex; +::osl::Mutex& + AccessibleDocumentViewBase::implGetMutex() +{ + return( maMutex ); +} + +// return ourself as context in default case +uno::Reference< XAccessibleContext > + AccessibleDocumentViewBase::implGetAccessibleContext() + throw (uno::RuntimeException) +{ + return( this ); +} + +// return sal_False in default case +sal_Bool + AccessibleDocumentViewBase::implIsSelected( sal_Int32 ) + throw (uno::RuntimeException) +{ + return( sal_False ); +} + +// return nothing in default case +void + AccessibleDocumentViewBase::implSelect( sal_Int32, sal_Bool ) + throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ +} + +} // end of namespace accessibility diff --git a/sd/source/ui/accessibility/AccessibleDrawDocumentView.cxx b/sd/source/ui/accessibility/AccessibleDrawDocumentView.cxx new file mode 100644 index 000000000000..dc0088d321f7 --- /dev/null +++ b/sd/source/ui/accessibility/AccessibleDrawDocumentView.cxx @@ -0,0 +1,742 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_sd.hxx" +#include "AccessibleDrawDocumentView.hxx" +#include <com/sun/star/drawing/XDrawPage.hpp> +#include <com/sun/star/drawing/XDrawView.hpp> +#include <com/sun/star/drawing/XDrawPagesSupplier.hpp> +#include <com/sun/star/drawing/XShapes.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <rtl/ustring.h> +#include<sfx2/viewfrm.hxx> + +#include <svx/AccessibleShape.hxx> + +#include <svx/svdobj.hxx> +#include <svx/svdmodel.hxx> +#include <svx/unoapi.hxx> +#include <svx/unoshcol.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include "Window.hxx" +#include <vcl/svapp.hxx> + + +#include "ViewShell.hxx" +#include "View.hxx" +#include <memory> + +#include "accessibility.hrc" +#include "sdresid.hxx" +#include <vos/mutex.hxx> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::accessibility; + +class SfxViewFrame; + +#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) + +namespace accessibility { + + +//===== internal ============================================================ + +AccessibleDrawDocumentView::AccessibleDrawDocumentView ( + ::sd::Window* pSdWindow, + ::sd::ViewShell* pViewShell, + const uno::Reference<frame::XController>& rxController, + const uno::Reference<XAccessible>& rxParent) + : AccessibleDocumentViewBase (pSdWindow, pViewShell, rxController, rxParent), + mpChildrenManager (NULL) +{ + OSL_TRACE ("AccessibleDrawDocumentView"); + UpdateAccessibleName(); +} + + + + +AccessibleDrawDocumentView::~AccessibleDrawDocumentView (void) +{ + OSL_TRACE ("~AccessibleDrawDocumentView"); + DBG_ASSERT (rBHelper.bDisposed || rBHelper.bInDispose, + "~AccessibleDrawDocumentView: object has not been disposed"); +} + + + + +void AccessibleDrawDocumentView::Init (void) +{ + AccessibleDocumentViewBase::Init (); + + // Determine the list of shapes on the current page. + uno::Reference<drawing::XShapes> xShapeList; + uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY); + if (xView.is()) + xShapeList = uno::Reference<drawing::XShapes> ( + xView->getCurrentPage(), uno::UNO_QUERY); + + // Create the children manager. + mpChildrenManager = new ChildrenManager(this, xShapeList, maShapeTreeInfo, *this); + if (mpChildrenManager != NULL) + { + // Create the page shape and initialize it. The shape is acquired + // before initialization and released after transferring ownership + // to the children manager to prevent premature disposing of the + // shape. + AccessiblePageShape* pPage = CreateDrawPageShape(); + if (pPage != NULL) + { + pPage->acquire(); + pPage->Init(); + mpChildrenManager->AddAccessibleShape ( + std::auto_ptr<AccessibleShape>(pPage)); + pPage->release(); + mpChildrenManager->Update (); + } + mpChildrenManager->UpdateSelection (); + } +} + + + + +void AccessibleDrawDocumentView::ViewForwarderChanged (ChangeType aChangeType, + const IAccessibleViewForwarder* pViewForwarder) +{ + AccessibleDocumentViewBase::ViewForwarderChanged (aChangeType, pViewForwarder); + if (mpChildrenManager != NULL) + mpChildrenManager->ViewForwarderChanged (aChangeType, pViewForwarder); +} + + + + +/** The page shape is created on every call at the moment (provided that + every thing goes well). +*/ +AccessiblePageShape* AccessibleDrawDocumentView::CreateDrawPageShape (void) +{ + AccessiblePageShape* pShape = NULL; + + // Create a shape that represents the actual draw page. + uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY); + if (xView.is()) + { + uno::Reference<beans::XPropertySet> xSet ( + uno::Reference<beans::XPropertySet> (xView->getCurrentPage(), uno::UNO_QUERY)); + if (xSet.is()) + { + // Create a rectangle shape that will represent the draw page. + uno::Reference<lang::XMultiServiceFactory> xFactory (mxModel, uno::UNO_QUERY); + uno::Reference<drawing::XShape> xRectangle; + if (xFactory.is()) + xRectangle = uno::Reference<drawing::XShape>(xFactory->createInstance ( + OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.RectangleShape"))), + uno::UNO_QUERY); + + // Set the shape's size and position. + if (xRectangle.is()) + { + uno::Any aValue; + awt::Point aPosition; + awt::Size aSize; + + // Set size and position of the shape to those of the draw + // page. + aValue = xSet->getPropertyValue ( + OUString (RTL_CONSTASCII_USTRINGPARAM("BorderLeft"))); + aValue >>= aPosition.X; + aValue = xSet->getPropertyValue ( + OUString (RTL_CONSTASCII_USTRINGPARAM("BorderTop"))); + aValue >>= aPosition.Y; + xRectangle->setPosition (aPosition); + + aValue = xSet->getPropertyValue ( + OUString (RTL_CONSTASCII_USTRINGPARAM("Width"))); + aValue >>= aSize.Width; + aValue = xSet->getPropertyValue ( + OUString (RTL_CONSTASCII_USTRINGPARAM("Height"))); + aValue >>= aSize.Height; + xRectangle->setSize (aSize); + + // Create the accessible object for the shape and + // initialize it. + pShape = new AccessiblePageShape ( + xView->getCurrentPage(), this, maShapeTreeInfo); + } + } + } + return pShape; +} + + + + +//===== XAccessibleContext ================================================== + +sal_Int32 SAL_CALL + AccessibleDrawDocumentView::getAccessibleChildCount (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed (); + + long mpChildCount = AccessibleDocumentViewBase::getAccessibleChildCount(); + + // Forward request to children manager. + if (mpChildrenManager != NULL) + mpChildCount += mpChildrenManager->GetChildCount (); + + return mpChildCount; +} + + + + +uno::Reference<XAccessible> SAL_CALL + AccessibleDrawDocumentView::getAccessibleChild (sal_Int32 nIndex) + throw (uno::RuntimeException, lang::IndexOutOfBoundsException) +{ + ThrowIfDisposed (); + + ::osl::ClearableMutexGuard aGuard (maMutex); + + // Take care of children of the base class. + sal_Int32 nCount = AccessibleDocumentViewBase::getAccessibleChildCount(); + if (nCount > 0) + { + if (nIndex < nCount) + return AccessibleDocumentViewBase::getAccessibleChild(nIndex); + else + nIndex -= nCount; + } + + // Create a copy of the pointer to the children manager and release the + // mutex before calling any of its methods. + ChildrenManager* pChildrenManager = mpChildrenManager; + aGuard.clear(); + + // Forward request to children manager. + if (pChildrenManager != NULL) + { + return pChildrenManager->GetChild (nIndex); + } + else + throw lang::IndexOutOfBoundsException ( + ::rtl::OUString::createFromAscii ("no accessible child with index ") + + rtl::OUString::valueOf(nIndex), + static_cast<uno::XWeak*>(this)); +} + + + + +//===== XEventListener ====================================================== + +void SAL_CALL + AccessibleDrawDocumentView::disposing (const lang::EventObject& rEventObject) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + + AccessibleDocumentViewBase::disposing (rEventObject); + if (rEventObject.Source == mxModel) + { + ::osl::Guard< ::osl::Mutex> aGuard (::osl::Mutex::getGlobalMutex()); + // maShapeTreeInfo has been modified in base class. + if (mpChildrenManager != NULL) + mpChildrenManager->SetInfo (maShapeTreeInfo); + } +} + + + + +//===== XPropertyChangeListener ============================================= + +void SAL_CALL + AccessibleDrawDocumentView::propertyChange (const beans::PropertyChangeEvent& rEventObject) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + + AccessibleDocumentViewBase::propertyChange (rEventObject); + + OSL_TRACE ("AccessibleDrawDocumentView::propertyChange"); + if (rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("CurrentPage"))) + { + OSL_TRACE (" current page changed"); + + // Update the accessible name to reflect the current slide. + UpdateAccessibleName(); + + // The current page changed. Update the children manager accordingly. + uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY); + if (xView.is() && mpChildrenManager!=NULL) + { + // Inform the children manager to forget all children and give + // him the new ones. + mpChildrenManager->ClearAccessibleShapeList (); + mpChildrenManager->SetShapeList (uno::Reference<drawing::XShapes> ( + xView->getCurrentPage(), uno::UNO_QUERY)); + + // Create the page shape and initialize it. The shape is + // acquired before initialization and released after + // transferring ownership to the children manager to prevent + // premature disposing of the shape. + AccessiblePageShape* pPage = CreateDrawPageShape (); + if (pPage != NULL) + { + pPage->acquire(); + pPage->Init(); + mpChildrenManager->AddAccessibleShape ( + std::auto_ptr<AccessibleShape>(pPage)); + mpChildrenManager->Update (false); + pPage->release(); + } + } + else + OSL_TRACE ("View invalid"); + } + else if (rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("VisibleArea"))) + { + OSL_TRACE (" visible area changed"); + if (mpChildrenManager != NULL) + mpChildrenManager->ViewForwarderChanged ( + IAccessibleViewForwarderListener::VISIBLE_AREA, + &maViewForwarder); + } + else + { + OSL_TRACE (" unhandled"); + } + OSL_TRACE (" done"); +} + + + +//===== XServiceInfo ======================================================== + +::rtl::OUString SAL_CALL + AccessibleDrawDocumentView::getImplementationName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "AccessibleDrawDocumentView")); +} + + + + +::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL + AccessibleDrawDocumentView::getSupportedServiceNames (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed(); + // Get list of supported service names from base class... + uno::Sequence<OUString> aServiceNames = + AccessibleDocumentViewBase::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.AccessibleDrawDocumentView")); + aServiceNames[nCount] = sAdditionalServiceName; + + return aServiceNames; +} + + + + +/// Create a name for this view. +::rtl::OUString + AccessibleDrawDocumentView::CreateAccessibleName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + rtl::OUString sName; + + uno::Reference<lang::XServiceInfo> xInfo (mxController, uno::UNO_QUERY); + if (xInfo.is()) + { + uno::Sequence< ::rtl::OUString > aServices( xInfo->getSupportedServiceNames() ); + OUString sFirstService = aServices[0]; + if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DrawingDocumentDrawView"))) + { + if( aServices.getLength() >= 2 && + aServices[1] == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationView"))) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + sName = String( SdResId(SID_SD_A11Y_I_DRAWVIEW_N) ); + } + else + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + sName = String( SdResId(SID_SD_A11Y_D_DRAWVIEW_N) ); + } + } + else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.NotesView"))) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + sName = String( SdResId(SID_SD_A11Y_I_NOTESVIEW_N) ); + } + else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.HandoutView"))) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + sName = String( SdResId(SID_SD_A11Y_I_HANDOUTVIEW_N) ); + } + else + { + sName = sFirstService; + } + } + else + { + sName = OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleDrawDocumentView")); + } + return sName; +} + + + + +/** Create a description for this view. Use the model's description or URL + if a description is not available. +*/ +::rtl::OUString + AccessibleDrawDocumentView::CreateAccessibleDescription (void) + throw (::com::sun::star::uno::RuntimeException) +{ + rtl::OUString sDescription; + + uno::Reference<lang::XServiceInfo> xInfo (mxController, uno::UNO_QUERY); + if (xInfo.is()) + { + uno::Sequence< ::rtl::OUString > aServices( xInfo->getSupportedServiceNames() ); + OUString sFirstService = aServices[0]; + if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DrawingDocumentDrawView"))) + { + if( aServices.getLength() >= 2 && + aServices[1] == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationView"))) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + sDescription = String( SdResId(SID_SD_A11Y_I_DRAWVIEW_D) ); + } + else + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + sDescription = String( SdResId(SID_SD_A11Y_D_DRAWVIEW_D) ); + } + } + else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.NotesView"))) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + sDescription = String( SdResId(SID_SD_A11Y_I_NOTESVIEW_D) ); + } + else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.HandoutView"))) + { + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + sDescription = String( SdResId(SID_SD_A11Y_I_HANDOUTVIEW_D) ); + } + else + { + sDescription = sFirstService; + } + } + else + { + sDescription = OUString(RTL_CONSTASCII_USTRINGPARAM("Accessible Draw Document")); + } + return sDescription; +} + + + + +/** Return selection state of specified child +*/ +sal_Bool + AccessibleDrawDocumentView::implIsSelected( sal_Int32 nAccessibleChildIndex ) + throw (uno::RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + uno::Reference< view::XSelectionSupplier > xSel( mxController, uno::UNO_QUERY ); + sal_Bool bRet = sal_False; + + OSL_ENSURE( 0 <= nAccessibleChildIndex, "AccessibleDrawDocumentView::implIsSelected: invalid index!" ); + + if( xSel.is() && ( 0 <= nAccessibleChildIndex ) ) + { + uno::Any aAny( xSel->getSelection() ); + uno::Reference< drawing::XShapes > xShapes; + + aAny >>= xShapes; + + if( xShapes.is() ) + { + AccessibleShape* pAcc = AccessibleShape::getImplementation( getAccessibleChild( nAccessibleChildIndex ) ); + + if( pAcc ) + { + uno::Reference< drawing::XShape > xShape( pAcc->GetXShape() ); + + if( xShape.is() ) + { + for( sal_Int32 i = 0, nCount = xShapes->getCount(); ( i < nCount ) && !bRet; ++i ) + if( xShapes->getByIndex( i ) == xShape ) + bRet = sal_True; + } + } + } + } + + return( bRet ); +} + + + + +/** Select or delselect the specified shapes. The corresponding accessible + shapes are notified over the selection change listeners registered with + the XSelectionSupplier of the controller. +*/ +void + AccessibleDrawDocumentView::implSelect( sal_Int32 nAccessibleChildIndex, sal_Bool bSelect ) + throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + uno::Reference< view::XSelectionSupplier > xSel( mxController, uno::UNO_QUERY ); + AccessibleShape* pAccessibleChild; + + if( xSel.is() ) + { + uno::Any aAny; + + if( ACCESSIBLE_SELECTION_CHILD_ALL == nAccessibleChildIndex ) + { + // Select or deselect all children. + + if( !bSelect ) + xSel->select( aAny ); + else + { + uno::Reference< drawing::XShapes > xShapes( new SvxShapeCollection() ); + + for(sal_Int32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i ) + { + AccessibleShape* pAcc = AccessibleShape::getImplementation( getAccessibleChild( i ) ); + + if( pAcc && pAcc->GetXShape().is() ) + { + xShapes->add( pAcc->GetXShape() ); + pAccessibleChild = pAcc; + } + } + + if( xShapes->getCount() ) + { + aAny <<= xShapes; + xSel->select( aAny ); + } + } + } + else if( nAccessibleChildIndex >= 0 ) + { + // Select or deselect only the child with index + // nAccessibleChildIndex. + + AccessibleShape* pAcc = AccessibleShape::getImplementation( + getAccessibleChild( nAccessibleChildIndex )); + pAccessibleChild = pAcc; + + // Add or remove the shape that is made accessible from the + // selection of the controller. + if( pAcc ) + { + uno::Reference< drawing::XShape > xShape( pAcc->GetXShape() ); + + if( xShape.is() ) + { + uno::Reference< drawing::XShapes > xShapes; + sal_Bool bFound = sal_False; + + aAny = xSel->getSelection(); + aAny >>= xShapes; + + // Search shape to be selected in current selection. + if (xShapes.is()) + { + sal_Int32 nCount = xShapes->getCount(); + for (sal_Int32 i=0; ( i < nCount ) && !bFound; ++i ) + if( xShapes->getByIndex( i ) == xShape ) + bFound = sal_True; + } + else + // Create an empty selection to add the shape to. + xShapes = new SvxShapeCollection(); + + // Update the selection. + if( !bFound && bSelect ) + xShapes->add( xShape ); + else if( bFound && !bSelect ) + xShapes->remove( xShape ); + + aAny <<= xShapes; + xSel->select( aAny ); + } + } + } + } +} + + + + +void AccessibleDrawDocumentView::Activated (void) +{ + if (mpChildrenManager != NULL) + { + mpChildrenManager->UpdateSelection(); + // When none of the children has the focus then claim it for the + // view. + if ( ! mpChildrenManager->HasFocus()) + SetState (AccessibleStateType::FOCUSED); + else + ResetState (AccessibleStateType::FOCUSED); + } +} + + + + +void AccessibleDrawDocumentView::Deactivated (void) +{ + if (mpChildrenManager != NULL) + mpChildrenManager->RemoveFocus(); + ResetState (AccessibleStateType::FOCUSED); +} + + + + +void AccessibleDrawDocumentView::impl_dispose (void) +{ + if (mpChildrenManager != NULL) + { + delete mpChildrenManager; + mpChildrenManager = NULL; + } + + AccessibleDocumentViewBase::impl_dispose(); +} + + + +/** This method is called from the component helper base class while + disposing. +*/ +void SAL_CALL AccessibleDrawDocumentView::disposing (void) +{ + + // Release resources. + if (mpChildrenManager != NULL) + { + delete mpChildrenManager; + mpChildrenManager = NULL; + } + + // Forward call to base classes. + AccessibleDocumentViewBase::disposing (); +} + + + + +void AccessibleDrawDocumentView::UpdateAccessibleName (void) +{ + OUString sNewName (CreateAccessibleName()); + sNewName += A2S(": "); + + // Add the number of the current slide. + uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY); + if (xView.is()) + { + uno::Reference<beans::XPropertySet> xProperties (xView->getCurrentPage(), UNO_QUERY); + if (xProperties.is()) + try + { + sal_Int16 nPageNumber (0); + if (xProperties->getPropertyValue(A2S("Number")) >>= nPageNumber) + { + sNewName += OUString::valueOf(sal_Int32(nPageNumber)); + } + } + catch (beans::UnknownPropertyException&) + { + } + } + + // Add the number of pages/slides. + Reference<drawing::XDrawPagesSupplier> xPagesSupplier (mxModel, UNO_QUERY); + if (xPagesSupplier.is()) + { + Reference<container::XIndexAccess> xPages (xPagesSupplier->getDrawPages(), UNO_QUERY); + if (xPages.is()) + { + sNewName += A2S(" / "); + sNewName += OUString::valueOf(xPages->getCount()); + } + } + + SetAccessibleName (sNewName, AutomaticallyCreated); +} + + + + +} // end of namespace accessibility diff --git a/sd/source/ui/accessibility/AccessibleOutlineEditSource.cxx b/sd/source/ui/accessibility/AccessibleOutlineEditSource.cxx new file mode 100644 index 000000000000..6862634df9a0 --- /dev/null +++ b/sd/source/ui/accessibility/AccessibleOutlineEditSource.cxx @@ -0,0 +1,225 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_sd.hxx" +#include <editeng/unoedhlp.hxx> +#include <svx/svdoutl.hxx> + +#ifndef SD_ACCESSIBILITY_ACCESSIBLE_OUTLINE_EDIT_SOURCE_HXX +#include <AccessibleOutlineEditSource.hxx> +#endif +#include "OutlineView.hxx" +#include <svx/sdrpaintwindow.hxx> + +namespace accessibility +{ + + AccessibleOutlineEditSource::AccessibleOutlineEditSource( + SdrOutliner& rOutliner, + SdrView& rView, + OutlinerView& rOutlView, + const ::Window& rViewWindow ) + : mrView( rView ), + mrWindow( rViewWindow ), + mpOutliner( &rOutliner ), + mpOutlinerView( &rOutlView ), + mTextForwarder( rOutliner, NULL ), + mViewForwarder( rOutlView ) + { + // register as listener - need to broadcast state change messages + rOutliner.SetNotifyHdl( LINK(this, AccessibleOutlineEditSource, NotifyHdl) ); + StartListening(rOutliner); + } + + AccessibleOutlineEditSource::~AccessibleOutlineEditSource() + { + if( mpOutliner ) + mpOutliner->SetNotifyHdl( Link() ); + Broadcast( TextHint( SFX_HINT_DYING ) ); + } + + SvxEditSource* AccessibleOutlineEditSource::Clone() const + { + return NULL; + } + + SvxTextForwarder* AccessibleOutlineEditSource::GetTextForwarder() + { + // TODO: maybe suboptimal + if( IsValid() ) + return &mTextForwarder; + else + return NULL; + } + + SvxViewForwarder* AccessibleOutlineEditSource::GetViewForwarder() + { + // TODO: maybe suboptimal + if( IsValid() ) + return this; + else + return NULL; + } + + SvxEditViewForwarder* AccessibleOutlineEditSource::GetEditViewForwarder( sal_Bool ) + { + // TODO: maybe suboptimal + if( IsValid() ) + { + // ignore parameter, we're always in edit mode here + return &mViewForwarder; + } + else + return NULL; + } + + void AccessibleOutlineEditSource::UpdateData() + { + // NOOP, since we're always working on the 'real' outliner, + // i.e. changes are immediately reflected on the screen + } + + SfxBroadcaster& AccessibleOutlineEditSource::GetBroadcaster() const + { + return *( const_cast< AccessibleOutlineEditSource* > (this) ); + } + + BOOL AccessibleOutlineEditSource::IsValid() const + { + if( mpOutliner && mpOutlinerView ) + { + // Our view still on outliner? + ULONG nCurrView, nViews; + + for( nCurrView=0, nViews=mpOutliner->GetViewCount(); nCurrView<nViews; ++nCurrView ) + { + if( mpOutliner->GetView(nCurrView) == mpOutlinerView ) + return sal_True; + } + } + + return sal_False; + } + + Rectangle AccessibleOutlineEditSource::GetVisArea() const + { + if( IsValid() ) + { + SdrPaintWindow* pPaintWindow = mrView.FindPaintWindow(mrWindow); + Rectangle aVisArea; + + if(pPaintWindow) + { + aVisArea = pPaintWindow->GetVisibleArea(); + } + + MapMode aMapMode(mrWindow.GetMapMode()); + aMapMode.SetOrigin(Point()); + return mrWindow.LogicToPixel( aVisArea, aMapMode ); + } + + return Rectangle(); + } + + Point AccessibleOutlineEditSource::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const + { + if( IsValid() && mrView.GetModel() ) + { + Point aPoint( OutputDevice::LogicToLogic( rPoint, rMapMode, + MapMode(mrView.GetModel()->GetScaleUnit()) ) ); + MapMode aMapMode(mrWindow.GetMapMode()); + aMapMode.SetOrigin(Point()); + return mrWindow.LogicToPixel( aPoint, aMapMode ); + } + + return Point(); + } + + Point AccessibleOutlineEditSource::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const + { + if( IsValid() && mrView.GetModel() ) + { + MapMode aMapMode(mrWindow.GetMapMode()); + aMapMode.SetOrigin(Point()); + Point aPoint( mrWindow.PixelToLogic( rPoint, aMapMode ) ); + return OutputDevice::LogicToLogic( aPoint, + MapMode(mrView.GetModel()->GetScaleUnit()), + rMapMode ); + } + + return Point(); + } + + void AccessibleOutlineEditSource::Notify( SfxBroadcaster& rBroadcaster, const SfxHint& rHint ) + { + bool bDispose = false; + + if( &rBroadcaster == mpOutliner ) + { + const SfxSimpleHint* pHint = dynamic_cast< const SfxSimpleHint * >( &rHint ); + if( pHint && (pHint->GetId() == SFX_HINT_DYING) ) + { + bDispose = true; + mpOutliner = NULL; + } + } + else + { + const SdrHint* pSdrHint = dynamic_cast< const SdrHint* >( &rHint ); + + if( pSdrHint && ( pSdrHint->GetKind() == HINT_MODELCLEARED ) ) + { + // model is dying under us, going defunc + bDispose = true; + } + } + + if( bDispose ) + { + if( mpOutliner ) + mpOutliner->SetNotifyHdl( Link() ); + mpOutliner = NULL; + mpOutlinerView = NULL; + Broadcast( TextHint( SFX_HINT_DYING ) ); + } + } + + IMPL_LINK(AccessibleOutlineEditSource, NotifyHdl, EENotify*, aNotify) + { + if( aNotify ) + { + ::std::auto_ptr< SfxHint > aHint( SvxEditSourceHelper::EENotification2Hint( aNotify) ); + + if( aHint.get() ) + Broadcast( *aHint.get() ); + } + + return 0; + } + +} // end of namespace accessibility diff --git a/sd/source/ui/accessibility/AccessibleOutlineView.cxx b/sd/source/ui/accessibility/AccessibleOutlineView.cxx new file mode 100644 index 000000000000..f61e09d743f7 --- /dev/null +++ b/sd/source/ui/accessibility/AccessibleOutlineView.cxx @@ -0,0 +1,288 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_sd.hxx" +#include <com/sun/star/drawing/XDrawPage.hpp> +#include <com/sun/star/drawing/XDrawView.hpp> +#include <com/sun/star/drawing/XShapes.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/frame/XController.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#ifndef _COM_SUN_STAR_ACCESSIBLE_ACCESSIBLEEVENTID_HPP_ +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#endif +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#ifndef _COM_SUN_STAR_LANG_XMULSTISERVICEFACTORY_HPP_ +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#endif +#include <rtl/ustring.h> +#ifndef _SFXFRAME_HXX +#include<sfx2/viewfrm.hxx> +#endif + +#include <svx/AccessibleShape.hxx> + +#include <svx/svdobj.hxx> +#include <svx/svdmodel.hxx> +#include <svx/unoapi.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <vcl/svapp.hxx> +#include "Window.hxx" +#include "ViewShell.hxx" +#include "OutlineViewShell.hxx" +#include "View.hxx" +#include "AccessibleOutlineView.hxx" +#include "AccessibleOutlineEditSource.hxx" + +#include <memory> + +#include "accessibility.hrc" +#include "sdresid.hxx" +#include <vos/mutex.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; + +namespace accessibility { + + +//===== internal ============================================================ + +AccessibleOutlineView::AccessibleOutlineView ( + ::sd::Window* pSdWindow, + ::sd::OutlineViewShell* pViewShell, + const uno::Reference<frame::XController>& rxController, + const uno::Reference<XAccessible>& rxParent) + : AccessibleDocumentViewBase (pSdWindow, pViewShell, rxController, rxParent), + maTextHelper( ::std::auto_ptr< SvxEditSource >( NULL ) ) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + // Beware! Here we leave the paths of the UNO API and descend into the + // depths of the core. Necessary for making the edit engine accessible. + if( pViewShell && pSdWindow ) + { + ::sd::View* pView = pViewShell->GetView(); + + if (pView && pView->ISA(::sd::OutlineView)) + { + OutlinerView* pOutlineView = static_cast< ::sd::OutlineView*>( + pView)->GetViewByWindow( pSdWindow ); + SdrOutliner* pOutliner = + static_cast< ::sd::OutlineView*>(pView)->GetOutliner(); + + if( pOutlineView && pOutliner ) + { + maTextHelper.SetEditSource( ::std::auto_ptr< SvxEditSource >( new AccessibleOutlineEditSource( + *pOutliner, *pView, *pOutlineView, *pSdWindow ) ) ); + } + } + } +} + + +AccessibleOutlineView::~AccessibleOutlineView (void) +{ + OSL_TRACE ("~AccessibleOutlineView"); +} + + +void AccessibleOutlineView::Init (void) +{ + // #105479# Set event source _before_ starting to listen + maTextHelper.SetEventSource(this); + + AccessibleDocumentViewBase::Init (); +} + + +void AccessibleOutlineView::ViewForwarderChanged (ChangeType aChangeType, + const IAccessibleViewForwarder* pViewForwarder) +{ + AccessibleDocumentViewBase::ViewForwarderChanged (aChangeType, pViewForwarder); + + UpdateChildren(); +} + + +//===== XAccessibleContext ================================================== + +sal_Int32 SAL_CALL + AccessibleOutlineView::getAccessibleChildCount (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed (); + + // forward + return maTextHelper.GetChildCount(); +} + + +uno::Reference<XAccessible> SAL_CALL + AccessibleOutlineView::getAccessibleChild (sal_Int32 nIndex) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + // Forward request to children manager. + return maTextHelper.GetChild(nIndex); +} + +//===== XAccessibleEventBroadcaster ======================================== + +void SAL_CALL AccessibleOutlineView::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) +{ + // delegate listener handling to children manager. + if ( ! IsDisposed()) + maTextHelper.AddEventListener(xListener); +} + +void SAL_CALL AccessibleOutlineView::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) +{ + // forward + if ( ! IsDisposed()) + maTextHelper.RemoveEventListener(xListener); +} + +//===== XServiceInfo ======================================================== + +::rtl::OUString SAL_CALL + AccessibleOutlineView::getImplementationName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleOutlineView")); +} + + +//===== XEventListener ====================================================== + +void SAL_CALL + AccessibleOutlineView::disposing (const lang::EventObject& rEventObject) + throw (::com::sun::star::uno::RuntimeException) +{ + AccessibleDocumentViewBase::disposing (rEventObject); +} + +//===== protected internal ================================================== + +void AccessibleOutlineView::FireEvent(const AccessibleEventObject& aEvent ) +{ + // delegate listener handling to children manager. + maTextHelper.FireEvent(aEvent); +} + +void AccessibleOutlineView::Activated (void) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + // delegate listener handling to children manager. + maTextHelper.SetFocus(sal_True); +} + +void AccessibleOutlineView::Deactivated (void) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + // delegate listener handling to children manager. + maTextHelper.SetFocus(sal_False); +} + +void SAL_CALL AccessibleOutlineView::disposing (void) +{ + // dispose children + maTextHelper.Dispose(); + + AccessibleDocumentViewBase::disposing (); +} + +//===== XPropertyChangeListener ============================================= + +void SAL_CALL + AccessibleOutlineView::propertyChange (const beans::PropertyChangeEvent& rEventObject) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + + AccessibleDocumentViewBase::propertyChange (rEventObject); + + OSL_TRACE ("AccessibleOutlineView::propertyChange"); + if (rEventObject.PropertyName == ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("CurrentPage"))) + { + OSL_TRACE (" current page changed"); + + // The current page changed. Update the children accordingly. + UpdateChildren(); + } + else if (rEventObject.PropertyName == ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("VisibleArea"))) + { + OSL_TRACE (" visible area changed"); + + // The visible area changed. Update the children accordingly. + UpdateChildren(); + } + else + { + OSL_TRACE (" unhandled"); + } + OSL_TRACE (" done"); +} + + +/// Create a name for this view. +::rtl::OUString + AccessibleOutlineView::CreateAccessibleName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + return String( SdResId(SID_SD_A11Y_I_OUTLINEVIEW_N) ); +} + + +/** Create a description for this view. Use the model's description or URL + if a description is not available. +*/ +::rtl::OUString + AccessibleOutlineView::CreateAccessibleDescription (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + return String( SdResId(SID_SD_A11Y_I_OUTLINEVIEW_D) ); +} + +void AccessibleOutlineView::UpdateChildren() +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + // Update visible children + maTextHelper.UpdateChildren(); +} + +} // end of namespace accessibility diff --git a/sd/source/ui/accessibility/AccessiblePageShape.cxx b/sd/source/ui/accessibility/AccessiblePageShape.cxx new file mode 100644 index 000000000000..560e0654af60 --- /dev/null +++ b/sd/source/ui/accessibility/AccessiblePageShape.cxx @@ -0,0 +1,377 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_sd.hxx" +#include "AccessiblePageShape.hxx" +#include <svx/AccessibleShapeInfo.hxx> + +#ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLE_ROLE_HPP_ +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#endif +#ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLE_STATE_TYPE_HPP_ +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#endif +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/drawing/XShapes.hpp> +#include <com/sun/star/drawing/XShapeDescriptor.hpp> +#include <com/sun/star/drawing/XMasterPageTarget.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::accessibility; +using ::com::sun::star::uno::Reference; +using ::rtl::OUString; + +#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) + +namespace accessibility { + +//===== internal ============================================================ + +AccessiblePageShape::AccessiblePageShape ( + const uno::Reference<drawing::XDrawPage>& rxPage, + const uno::Reference<XAccessible>& rxParent, + const AccessibleShapeTreeInfo& rShapeTreeInfo, + long nIndex) + : AccessibleShape (AccessibleShapeInfo (NULL, rxParent, nIndex), rShapeTreeInfo), + mxPage (rxPage) +{ + // The main part of the initialization is done in the init method which + // has to be called from this constructor's caller. +} + + + + +AccessiblePageShape::~AccessiblePageShape (void) +{ + OSL_TRACE ("~AccessiblePageShape"); +} + + + + +void AccessiblePageShape::Init (void) +{ + AccessibleShape::Init (); +} + + + + +//===== XAccessibleContext ================================================== + +sal_Int32 SAL_CALL + AccessiblePageShape::getAccessibleChildCount (void) + throw () +{ + return 0; +} + + + + +/** Forward the request to the shape. Return the requested shape or throw + an exception for a wrong index. +*/ +uno::Reference<XAccessible> SAL_CALL + AccessiblePageShape::getAccessibleChild( sal_Int32 ) + throw (::com::sun::star::uno::RuntimeException) +{ + throw lang::IndexOutOfBoundsException ( + ::rtl::OUString::createFromAscii ("page shape has no children"), + static_cast<uno::XWeak*>(this)); +} + + + + +//===== XAccessibleComponent ================================================ + +awt::Rectangle SAL_CALL AccessiblePageShape::getBounds (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + + awt::Rectangle aBoundingBox; + + if (maShapeTreeInfo.GetViewForwarder() != NULL) + { + uno::Reference<beans::XPropertySet> xSet (mxPage, uno::UNO_QUERY); + if (xSet.is()) + { + uno::Any aValue; + awt::Point aPosition; + awt::Size aSize; + + aValue = xSet->getPropertyValue ( + ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("BorderLeft"))); + aValue >>= aBoundingBox.X; + aValue = xSet->getPropertyValue ( + ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("BorderTop"))); + aValue >>= aBoundingBox.Y; + + aValue = xSet->getPropertyValue ( + ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("Width"))); + aValue >>= aBoundingBox.Width; + aValue = xSet->getPropertyValue ( + ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("Height"))); + aValue >>= aBoundingBox.Height; + } + + // Transform coordinates from internal to pixel. + ::Size aPixelSize = maShapeTreeInfo.GetViewForwarder()->LogicToPixel ( + ::Size (aBoundingBox.Width, aBoundingBox.Height)); + ::Point aPixelPosition = maShapeTreeInfo.GetViewForwarder()->LogicToPixel ( + ::Point (aBoundingBox.X, aBoundingBox.Y)); + + // 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 + aBoundingBox = awt::Rectangle ( + aPixelPosition.getX(), aPixelPosition.getY(), + aPixelSize.getWidth(), aPixelSize.getHeight()); + } + + return aBoundingBox; +} + + + + +sal_Int32 SAL_CALL AccessiblePageShape::getForeground (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + sal_Int32 nColor (0x0ffffffL); + + try + { + uno::Reference<beans::XPropertySet> aSet (mxPage, uno::UNO_QUERY); + if (aSet.is()) + { + uno::Any aColor; + aColor = aSet->getPropertyValue (::rtl::OUString::createFromAscii ("LineColor")); + aColor >>= nColor; + } + } + catch (::com::sun::star::beans::UnknownPropertyException) + { + // Ignore exception and return default color. + } + return nColor; +} + + + + +/** Extract the background color from the Background property of eithe the + draw page or its master page. +*/ +sal_Int32 SAL_CALL AccessiblePageShape::getBackground (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + sal_Int32 nColor (0x01020ffL); + + try + { + uno::Reference<beans::XPropertySet> xSet (mxPage, uno::UNO_QUERY); + if (xSet.is()) + { + uno::Any aBGSet; + aBGSet = xSet->getPropertyValue ( + ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("Background"))); + Reference<beans::XPropertySet> xBGSet (aBGSet, uno::UNO_QUERY); + if ( ! xBGSet.is()) + { + // Draw page has no Background property. Try the master + // page instead. + Reference<drawing::XMasterPageTarget> xTarget (mxPage, uno::UNO_QUERY); + if (xTarget.is()) + { + xSet = Reference<beans::XPropertySet> (xTarget->getMasterPage(), + uno::UNO_QUERY); + aBGSet = xSet->getPropertyValue ( + ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("Background"))); + xBGSet = Reference<beans::XPropertySet> (aBGSet, uno::UNO_QUERY); + } + } + // Fetch the fill color. Has to be extended to cope with + // gradients, hashes, and bitmaps. + if (xBGSet.is()) + { + uno::Any aColor; + aColor = xBGSet->getPropertyValue (::rtl::OUString::createFromAscii ("FillColor")); + aColor >>= nColor; + } + else + OSL_TRACE ("no Background property in page"); + } + } + catch (::com::sun::star::beans::UnknownPropertyException) + { + OSL_TRACE ("caught excption due to unknown property"); + // Ignore exception and return default color. + } + return nColor; +} + + + + +//===== XServiceInfo ======================================================== + +::rtl::OUString SAL_CALL + AccessiblePageShape::getImplementationName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessiblePageShape")); +} + + + + +::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL + AccessiblePageShape::getSupportedServiceNames (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + return AccessibleShape::getSupportedServiceNames(); +} + + + + +//===== lang::XEventListener ================================================ + +void SAL_CALL + AccessiblePageShape::disposing (const ::com::sun::star::lang::EventObject& aEvent) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + AccessibleShape::disposing (aEvent); +} + + + + +//===== XComponent ========================================================== + +void AccessiblePageShape::dispose (void) + throw (::com::sun::star::uno::RuntimeException) +{ + OSL_TRACE ("AccessiblePageShape::dispose"); + + // Unregister listeners. + Reference<lang::XComponent> xComponent (mxShape, uno::UNO_QUERY); + if (xComponent.is()) + xComponent->removeEventListener (this); + + // Cleanup. + mxShape = NULL; + + // Call base classes. + AccessibleContextBase::dispose (); +} + + + + +//===== protected internal ================================================== + +::rtl::OUString + AccessiblePageShape::CreateAccessibleBaseName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("PageShape")); +} + + + + +::rtl::OUString + AccessiblePageShape::CreateAccessibleName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + Reference<beans::XPropertySet> xPageProperties (mxPage, UNO_QUERY); + + // Get name of the current slide. + OUString sCurrentSlideName; + try + { + if (xPageProperties.is()) + { + xPageProperties->getPropertyValue(A2S("LinkDisplayName")) >>= sCurrentSlideName; + } + } + catch (beans::UnknownPropertyException&) + { + } + + return CreateAccessibleBaseName()+A2S(": ")+sCurrentSlideName; +} + + + + +::rtl::OUString + AccessiblePageShape::CreateAccessibleDescription (void) + throw (::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("Page Shape")); +} + + +} // end of namespace accessibility + + diff --git a/sd/source/ui/accessibility/AccessiblePresentationGraphicShape.cxx b/sd/source/ui/accessibility/AccessiblePresentationGraphicShape.cxx new file mode 100644 index 000000000000..48db0c894e9c --- /dev/null +++ b/sd/source/ui/accessibility/AccessiblePresentationGraphicShape.cxx @@ -0,0 +1,127 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_sd.hxx" +#include "AccessiblePresentationGraphicShape.hxx" + +#include "SdShapeTypes.hxx" + +#include <svx/DescriptionGenerator.hxx> +#include <rtl/ustring.h> + +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; + +namespace accessibility { + +//===== internal ============================================================ + +AccessiblePresentationGraphicShape::AccessiblePresentationGraphicShape ( + const AccessibleShapeInfo& rShapeInfo, + const AccessibleShapeTreeInfo& rShapeTreeInfo) + : AccessibleGraphicShape (rShapeInfo, rShapeTreeInfo) +{ +} + + + + +AccessiblePresentationGraphicShape::~AccessiblePresentationGraphicShape (void) +{ +} + + + + +//===== XServiceInfo ======================================================== + +::rtl::OUString SAL_CALL + AccessiblePresentationGraphicShape::getImplementationName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessiblePresentationGraphicShape")); +} + + + + +/// Set this object's name if is different to the current name. +::rtl::OUString + AccessiblePresentationGraphicShape::CreateAccessibleBaseName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ::rtl::OUString sName; + + ShapeTypeId nShapeType = ShapeTypeHandler::Instance().GetTypeId (mxShape); + switch (nShapeType) + { + case PRESENTATION_GRAPHIC_OBJECT: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("ImpressGraphicObject")); + break; + default: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("UnknownAccessibleImpressShape")); + uno::Reference<drawing::XShapeDescriptor> xDescriptor (mxShape, uno::UNO_QUERY); + if (xDescriptor.is()) + sName += ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM(": ")) + + xDescriptor->getShapeType(); + } + + return sName; +} + + + + +::rtl::OUString + AccessiblePresentationGraphicShape::CreateAccessibleDescription (void) + throw (::com::sun::star::uno::RuntimeException) +{ + // return createAccessibleName (); + DescriptionGenerator aDG (mxShape); + ShapeTypeId nShapeType = ShapeTypeHandler::Instance().GetTypeId (mxShape); + switch (nShapeType) + { + case PRESENTATION_GRAPHIC_OBJECT: + aDG.Initialize (::rtl::OUString::createFromAscii ("PresentationGraphicShape")); + break; + default: + aDG.Initialize ( + ::rtl::OUString::createFromAscii ("Unknown accessible presentation graphic shape")); + uno::Reference<drawing::XShapeDescriptor> xDescriptor (mxShape, uno::UNO_QUERY); + if (xDescriptor.is()) + { + aDG.AppendString (::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("service name="))); + aDG.AppendString (xDescriptor->getShapeType()); + } + } + + return aDG(); +} + +} // end of namespace accessibility diff --git a/sd/source/ui/accessibility/AccessiblePresentationOLEShape.cxx b/sd/source/ui/accessibility/AccessiblePresentationOLEShape.cxx new file mode 100644 index 000000000000..c62465916983 --- /dev/null +++ b/sd/source/ui/accessibility/AccessiblePresentationOLEShape.cxx @@ -0,0 +1,148 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_sd.hxx" +#include "AccessiblePresentationOLEShape.hxx" + +#include "SdShapeTypes.hxx" + +#include <svx/DescriptionGenerator.hxx> +#include <rtl/ustring.h> + +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; + +namespace accessibility { + +//===== internal ============================================================ + +AccessiblePresentationOLEShape::AccessiblePresentationOLEShape ( + const AccessibleShapeInfo& rShapeInfo, + const AccessibleShapeTreeInfo& rShapeTreeInfo) + : AccessibleOLEShape (rShapeInfo, rShapeTreeInfo) +{ +} + + + + +AccessiblePresentationOLEShape::~AccessiblePresentationOLEShape (void) +{ +} + + + + +//===== XServiceInfo ======================================================== + +::rtl::OUString SAL_CALL + AccessiblePresentationOLEShape::getImplementationName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessiblePresentationOLEShape")); +} + + + + +/// Set this object's name if it is different to the current name. +::rtl::OUString + AccessiblePresentationOLEShape::CreateAccessibleBaseName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ::rtl::OUString sName; + + ShapeTypeId nShapeType = ShapeTypeHandler::Instance().GetTypeId (mxShape); + switch (nShapeType) + { + case PRESENTATION_OLE: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("ImpressOLE")); + break; + case PRESENTATION_CHART: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("ImpressChart")); + break; + case PRESENTATION_TABLE: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("ImpressTable")); + break; + default: + sName = ::rtl::OUString ( + RTL_CONSTASCII_USTRINGPARAM("UnknownAccessibleImpressOLEShape")); + uno::Reference<drawing::XShapeDescriptor> xDescriptor (mxShape, uno::UNO_QUERY); + if (xDescriptor.is()) + sName += ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM(": ")) + + xDescriptor->getShapeType(); + } + + return sName; +} + + + + +::rtl::OUString + AccessiblePresentationOLEShape::CreateAccessibleDescription (void) + throw (::com::sun::star::uno::RuntimeException) +{ + // return createAccessibleName(); + DescriptionGenerator aDG (mxShape); + ShapeTypeId nShapeType = ShapeTypeHandler::Instance().GetTypeId (mxShape); + switch (nShapeType) + { + case PRESENTATION_OLE: + aDG.Initialize (::rtl::OUString::createFromAscii ("PresentationOLEShape")); + //SVX_RESSTR(RID_SVXSTR_A11Y_ST_RECTANGLE)); + aDG.AddProperty (OUString::createFromAscii ("CLSID"), + DescriptionGenerator::STRING); + break; + case PRESENTATION_CHART: + aDG.Initialize (::rtl::OUString::createFromAscii ("PresentationChartShape")); + //SVX_RESSTR(RID_SVXSTR_A11Y_ST_RECTANGLE)); + aDG.AddProperty (OUString::createFromAscii ("CLSID"), + DescriptionGenerator::STRING); + break; + case PRESENTATION_TABLE: + aDG.Initialize (::rtl::OUString::createFromAscii ("PresentationTableShape")); + //SVX_RESSTR(RID_SVXSTR_A11Y_ST_RECTANGLE)); + aDG.AddProperty (OUString::createFromAscii ("CLSID"), + DescriptionGenerator::STRING); + break; + default: + aDG.Initialize (::rtl::OUString::createFromAscii ("Unknown accessible presentation OLE shape")); + uno::Reference<drawing::XShapeDescriptor> xDescriptor (mxShape, uno::UNO_QUERY); + if (xDescriptor.is()) + { + aDG.AppendString (::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("service name="))); + aDG.AppendString (xDescriptor->getShapeType()); + } + } + + return aDG(); +} + +} // end of namespace accessibility diff --git a/sd/source/ui/accessibility/AccessiblePresentationShape.cxx b/sd/source/ui/accessibility/AccessiblePresentationShape.cxx new file mode 100644 index 000000000000..2137d88a9de2 --- /dev/null +++ b/sd/source/ui/accessibility/AccessiblePresentationShape.cxx @@ -0,0 +1,180 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_sd.hxx" +#include "AccessiblePresentationShape.hxx" + +#include "SdShapeTypes.hxx" + +#include <svx/DescriptionGenerator.hxx> +#include <rtl/ustring.h> + +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; + +namespace accessibility { + +//===== internal ============================================================ + +AccessiblePresentationShape::AccessiblePresentationShape ( + const AccessibleShapeInfo& rShapeInfo, + const AccessibleShapeTreeInfo& rShapeTreeInfo) + : AccessibleShape (rShapeInfo, rShapeTreeInfo) +{ +} + + + + +AccessiblePresentationShape::~AccessiblePresentationShape (void) +{ +} + + + + +//===== XServiceInfo ======================================================== + +::rtl::OUString SAL_CALL + AccessiblePresentationShape::getImplementationName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessiblePresentationShape")); +} + + + + +/// Set this object's name if is different to the current name. +::rtl::OUString + AccessiblePresentationShape::CreateAccessibleBaseName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ::rtl::OUString sName; + + ShapeTypeId nShapeType = ShapeTypeHandler::Instance().GetTypeId (mxShape); + switch (nShapeType) + { + case PRESENTATION_TITLE: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("ImpressTitle")); + break; + case PRESENTATION_OUTLINER: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("ImpressOutliner")); + break; + case PRESENTATION_SUBTITLE: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("ImpressSubtitle")); + break; + case PRESENTATION_PAGE: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("ImpressPage")); + break; + case PRESENTATION_NOTES: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("ImpressNotes")); + break; + case PRESENTATION_HANDOUT: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("ImpressHandout")); + break; + case PRESENTATION_HEADER: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("ImpressHeader")); + break; + case PRESENTATION_FOOTER: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("ImpressFooter")); + break; + case PRESENTATION_DATETIME: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("ImpressDateAndTime")); + break; + case PRESENTATION_PAGENUMBER: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("ImpressPageNumber")); + break; + default: + sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("UnknownAccessibleImpressShape")); + uno::Reference<drawing::XShapeDescriptor> xDescriptor (mxShape, uno::UNO_QUERY); + if (xDescriptor.is()) + sName += ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM(": ")) + + xDescriptor->getShapeType(); + } + + return sName; +} + + + + +::rtl::OUString + AccessiblePresentationShape::CreateAccessibleDescription (void) + throw (::com::sun::star::uno::RuntimeException) +{ + // return createAccessibleName (); + DescriptionGenerator aDG (mxShape); + ShapeTypeId nShapeType = ShapeTypeHandler::Instance().GetTypeId (mxShape); + switch (nShapeType) + { + case PRESENTATION_TITLE: + aDG.Initialize (::rtl::OUString::createFromAscii ("PresentationTitleShape")); + break; + case PRESENTATION_OUTLINER: + aDG.Initialize (::rtl::OUString::createFromAscii ("PresentationOutlinerShape")); + break; + case PRESENTATION_SUBTITLE: + aDG.Initialize (::rtl::OUString::createFromAscii ("PresentationSubtitleShape")); + break; + case PRESENTATION_PAGE: + aDG.Initialize (::rtl::OUString::createFromAscii ("PresentationPageShape")); + break; + case PRESENTATION_NOTES: + aDG.Initialize (::rtl::OUString::createFromAscii ("PresentationNotesShape")); + break; + case PRESENTATION_HANDOUT: + aDG.Initialize (::rtl::OUString::createFromAscii ("PresentationHandoutShape")); + break; + case PRESENTATION_HEADER: + aDG.Initialize (::rtl::OUString::createFromAscii ("PresentationHeaderShape")); + break; + case PRESENTATION_FOOTER: + aDG.Initialize (::rtl::OUString::createFromAscii ("PresentationFooterShape")); + break; + case PRESENTATION_DATETIME: + aDG.Initialize (::rtl::OUString::createFromAscii ("PresentationDateAndTimeShape")); + break; + case PRESENTATION_PAGENUMBER: + aDG.Initialize (::rtl::OUString::createFromAscii ("PresentationPageNumberShape")); + break; + default: + aDG.Initialize (::rtl::OUString::createFromAscii ("Unknown accessible presentation shape")); + uno::Reference<drawing::XShapeDescriptor> xDescriptor (mxShape, uno::UNO_QUERY); + if (xDescriptor.is()) + { + aDG.AppendString (::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("service name="))); + aDG.AppendString (xDescriptor->getShapeType()); + } + } + + return aDG(); +} + +} // end of namespace accessibility diff --git a/sd/source/ui/accessibility/AccessibleScrollPanel.cxx b/sd/source/ui/accessibility/AccessibleScrollPanel.cxx new file mode 100644 index 000000000000..ff34c9556bde --- /dev/null +++ b/sd/source/ui/accessibility/AccessibleScrollPanel.cxx @@ -0,0 +1,151 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_sd.hxx" + +#include "AccessibleScrollPanel.hxx" + +#include "taskpane/ScrollPanel.hxx" +#include "taskpane/ControlContainer.hxx" +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <unotools/accessiblestatesethelper.hxx> + +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::uno; +using namespace ::sd::toolpanel; + +namespace accessibility { + +AccessibleScrollPanel::AccessibleScrollPanel ( + ::sd::toolpanel::ScrollPanel& rScrollPanel, + const ::rtl::OUString& rsName, + const ::rtl::OUString& rsDescription) + : AccessibleTreeNode( + rScrollPanel, + rsName, + rsDescription, + AccessibleRole::PANEL) +{ +} + + + + +AccessibleScrollPanel::~AccessibleScrollPanel (void) +{ +} + + + + +//===== XAccessibleContext ================================================== + +sal_Int32 SAL_CALL + AccessibleScrollPanel::getAccessibleChildCount (void) + throw (RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + + sal_Int32 nChildCount (mrTreeNode.GetControlContainer().GetControlCount()); + if (GetScrollPanel().IsVerticalScrollBarVisible()) + ++nChildCount; + if (GetScrollPanel().IsHorizontalScrollBarVisible()) + ++nChildCount; + + return nChildCount; +} + + + + +Reference<XAccessible> SAL_CALL + AccessibleScrollPanel::getAccessibleChild (sal_Int32 nIndex) + throw (lang::IndexOutOfBoundsException, + RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + + Reference<XAccessible> xChild; + + ScrollPanel& rPanel (GetScrollPanel()); + + sal_uInt32 nControlCount (mrTreeNode.GetControlContainer().GetControlCount()); + + // The children of this accessible object include the tree node children + // and the two scroll bars (when they are visible). + if (nIndex < 0) + throw lang::IndexOutOfBoundsException(); + else if ((sal_uInt32)nIndex < nControlCount) + xChild = AccessibleTreeNode::getAccessibleChild(nIndex); + else if ((sal_uInt32)nIndex == nControlCount) + { + if (rPanel.IsVerticalScrollBarVisible()) + xChild = rPanel.GetVerticalScrollBar().GetAccessible(); + else if (rPanel.IsHorizontalScrollBarVisible()) + xChild = rPanel.GetHorizontalScrollBar().GetAccessible(); + } + else if ((sal_uInt32)nIndex == nControlCount+1) + { + if (rPanel.IsVerticalScrollBarVisible() && rPanel.IsHorizontalScrollBarVisible()) + xChild = rPanel.GetHorizontalScrollBar().GetAccessible(); + } + else + throw lang::IndexOutOfBoundsException(); + + return xChild; +} + + + + +//===== XServiceInfo ======================================================== + +OUString SAL_CALL + AccessibleScrollPanel::getImplementationName (void) + throw (RuntimeException) +{ + return OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleScrollPanel")); +} + + + + +ScrollPanel& AccessibleScrollPanel::GetScrollPanel (void) const +{ + return static_cast<ScrollPanel&>(mrTreeNode); +} + +} // end of namespace accessibility diff --git a/sd/source/ui/accessibility/AccessibleSlideSorterObject.cxx b/sd/source/ui/accessibility/AccessibleSlideSorterObject.cxx new file mode 100644 index 000000000000..1f5e99d69f58 --- /dev/null +++ b/sd/source/ui/accessibility/AccessibleSlideSorterObject.cxx @@ -0,0 +1,584 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_sd.hxx" + +#include "AccessibleSlideSorterObject.hxx" + +#include "SlideSorter.hxx" +#include "controller/SlideSorterController.hxx" +#include "controller/SlsPageSelector.hxx" +#include "controller/SlsFocusManager.hxx" +#include "model/SlideSorterModel.hxx" +#include "model/SlsPageDescriptor.hxx" +#include "view/SlideSorterView.hxx" +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <comphelper/accessibleeventnotifier.hxx> +#include <unotools/accessiblestatesethelper.hxx> + +#include "sdpage.hxx" +#include "sdresid.hxx" +#include <vcl/svapp.hxx> + +#include "glob.hrc" + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::accessibility; + + +namespace accessibility { + + +AccessibleSlideSorterObject::AccessibleSlideSorterObject( + const Reference<XAccessible>& rxParent, + ::sd::slidesorter::SlideSorter& rSlideSorter, + sal_uInt16 nPageNumber) + : AccessibleSlideSorterObjectBase(::sd::MutexOwner::maMutex), + mxParent(rxParent), + mnPageNumber(nPageNumber), + mrSlideSorter(rSlideSorter), + mnClientId(0) +{ +} + + + + +AccessibleSlideSorterObject::~AccessibleSlideSorterObject (void) +{ + if ( ! IsDisposed()) + dispose(); +} + + + + +sal_uInt16 AccessibleSlideSorterObject::GetPageNumber (void) const +{ + return mnPageNumber; +} + + + + +void AccessibleSlideSorterObject::FireAccessibleEvent ( + short nEventId, + const uno::Any& rOldValue, + const uno::Any& rNewValue) +{ + if (mnClientId != 0) + { + AccessibleEventObject aEventObject; + + aEventObject.Source = Reference<XWeak>(this); + aEventObject.EventId = nEventId; + aEventObject.NewValue = rNewValue; + aEventObject.OldValue = rOldValue; + + comphelper::AccessibleEventNotifier::addEvent(mnClientId, aEventObject); + } +} + + + + +void SAL_CALL AccessibleSlideSorterObject::disposing (void) +{ + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + + // Send a disposing to all listeners. + if (mnClientId != 0) + { + comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing(mnClientId, *this); + mnClientId = 0; + } +} + + + +//===== XAccessible =========================================================== + +Reference<XAccessibleContext> SAL_CALL + AccessibleSlideSorterObject::getAccessibleContext (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + return this; +} + + + +//===== XAccessibleContext ==================================================== + +sal_Int32 SAL_CALL AccessibleSlideSorterObject::getAccessibleChildCount (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + return 0; +} + + + + +Reference<XAccessible> SAL_CALL AccessibleSlideSorterObject::getAccessibleChild (sal_Int32 ) + throw (lang::IndexOutOfBoundsException, RuntimeException) +{ + ThrowIfDisposed(); + throw lang::IndexOutOfBoundsException(); +} + + + + +Reference<XAccessible> SAL_CALL AccessibleSlideSorterObject::getAccessibleParent (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + return mxParent; +} + + + + +sal_Int32 SAL_CALL AccessibleSlideSorterObject::getAccessibleIndexInParent() + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + sal_Int32 nIndexInParent(-1); + + if (mxParent.is()) + { + Reference<XAccessibleContext> xParentContext (mxParent->getAccessibleContext()); + if (xParentContext.is()) + { + sal_Int32 nChildCount (xParentContext->getAccessibleChildCount()); + for (sal_Int32 i=0; i<nChildCount; ++i) + if (xParentContext->getAccessibleChild(i).get() + == static_cast<XAccessible*>(this)) + { + nIndexInParent = i; + break; + } + } + } + + return nIndexInParent; +} + + + + +sal_Int16 SAL_CALL AccessibleSlideSorterObject::getAccessibleRole (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + static sal_Int16 nRole = AccessibleRole::LIST_ITEM; + return nRole; +} + + + + +::rtl::OUString SAL_CALL AccessibleSlideSorterObject::getAccessibleDescription (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + return String(SdResId(STR_PAGE)); +} + + + + +::rtl::OUString SAL_CALL AccessibleSlideSorterObject::getAccessibleName (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + + SdPage* pPage = GetPage(); + if (pPage != NULL) + return pPage->GetName(); + else + return String(); +} + + + + +Reference<XAccessibleRelationSet> SAL_CALL + AccessibleSlideSorterObject::getAccessibleRelationSet (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + return Reference<XAccessibleRelationSet>(); +} + + + + +Reference<XAccessibleStateSet> SAL_CALL + AccessibleSlideSorterObject::getAccessibleStateSet (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper(); + + if (mxParent.is()) + { + // SELECTABLE + pStateSet->AddState(AccessibleStateType::SELECTABLE); + + // SELECTED + if (mrSlideSorter.GetController().GetPageSelector().IsPageSelected(mnPageNumber)) + pStateSet->AddState(AccessibleStateType::SELECTED); + + // FOCUSABLE + pStateSet->AddState(AccessibleStateType::FOCUSABLE); + + // FOCUSED + if (mrSlideSorter.GetController().GetFocusManager().GetFocusedPageIndex() == mnPageNumber) + if (mrSlideSorter.GetController().GetFocusManager().IsFocusShowing()) + pStateSet->AddState(AccessibleStateType::FOCUSED); + + pStateSet->AddState(AccessibleStateType::ENABLED); + pStateSet->AddState(AccessibleStateType::VISIBLE); + pStateSet->AddState(AccessibleStateType::SHOWING); + pStateSet->AddState(AccessibleStateType::ACTIVE); + } + + return pStateSet; +} + + + + +lang::Locale SAL_CALL AccessibleSlideSorterObject::getLocale (void) + throw (IllegalAccessibleComponentStateException, + RuntimeException) +{ + ThrowIfDisposed(); + // Delegate request to parent. + if (mxParent.is()) + { + Reference<XAccessibleContext> xParentContext (mxParent->getAccessibleContext()); + if (xParentContext.is()) + return xParentContext->getLocale (); + } + + // No locale and no parent. Therefore throw exception to indicate this + // cluelessness. + throw IllegalAccessibleComponentStateException(); +} + + + + + +//===== XAccessibleEventBroadcaster =========================================== + +void SAL_CALL AccessibleSlideSorterObject::addEventListener( + const Reference<XAccessibleEventListener>& rxListener) + throw (RuntimeException) +{ + if (rxListener.is()) + { + const osl::MutexGuard aGuard(maMutex); + + if (IsDisposed()) + { + uno::Reference<uno::XInterface> x ((lang::XComponent *)this, uno::UNO_QUERY); + rxListener->disposing (lang::EventObject (x)); + } + else + { + if (mnClientId == 0) + mnClientId = comphelper::AccessibleEventNotifier::registerClient(); + comphelper::AccessibleEventNotifier::addEventListener(mnClientId, rxListener); + } + } +} + + + + +void SAL_CALL AccessibleSlideSorterObject::removeEventListener( + const Reference<XAccessibleEventListener>& rxListener) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + if (rxListener.is()) + { + const osl::MutexGuard aGuard(maMutex); + + sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, rxListener ); + if ( !nListenerCount ) + { + // no listeners anymore + // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case somebody calls + // NotifyAccessibleEvent, again + comphelper::AccessibleEventNotifier::revokeClient( mnClientId ); + mnClientId = 0; + } + } +} + + + + +//===== XAccessibleComponent ================================================== + +sal_Bool SAL_CALL AccessibleSlideSorterObject::containsPoint(const awt::Point& aPoint) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const awt::Size aSize (getSize()); + return (aPoint.X >= 0) + && (aPoint.X < aSize.Width) + && (aPoint.Y >= 0) + && (aPoint.Y < aSize.Height); +} + + + + +Reference<XAccessible> SAL_CALL + AccessibleSlideSorterObject::getAccessibleAtPoint(const awt::Point& ) + throw (uno::RuntimeException) +{ + return NULL; +} + + + + +awt::Rectangle SAL_CALL AccessibleSlideSorterObject::getBounds (void) + throw (RuntimeException) +{ + ThrowIfDisposed (); + + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + Rectangle aBBox (mrSlideSorter.GetView().GetPageBoundingBox ( + mnPageNumber, + ::sd::slidesorter::view::SlideSorterView::CS_SCREEN, + ::sd::slidesorter::view::SlideSorterView::BBT_INFO)); + + if (mxParent.is()) + { + Reference<XAccessibleComponent> xParentComponent(mxParent->getAccessibleContext(), UNO_QUERY); + if (xParentComponent.is()) + { + awt::Rectangle aParentBBox (xParentComponent->getBounds()); + aBBox.Intersection(Rectangle( + aParentBBox.X, + aParentBBox.Y, + aParentBBox.Width, + aParentBBox.Height)); + } + } + + return awt::Rectangle( + aBBox.Left(), + aBBox.Top(), + aBBox.GetWidth(), + aBBox.GetHeight()); +} + + + + +awt::Point SAL_CALL AccessibleSlideSorterObject::getLocation () + throw (RuntimeException) +{ + ThrowIfDisposed (); + const awt::Rectangle aBBox (getBounds()); + return awt::Point(aBBox.X, aBBox.Y); +} + + + + +awt::Point SAL_CALL AccessibleSlideSorterObject::getLocationOnScreen (void) + throw (RuntimeException) +{ + ThrowIfDisposed (); + + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + awt::Point aLocation (getLocation()); + + if (mxParent.is()) + { + Reference<XAccessibleComponent> xParentComponent(mxParent->getAccessibleContext(),UNO_QUERY); + if (xParentComponent.is()) + { + const awt::Point aParentLocationOnScreen(xParentComponent->getLocationOnScreen()); + aLocation.X += aParentLocationOnScreen.X; + aLocation.Y += aParentLocationOnScreen.Y; + } + } + + return aLocation; +} + + + + +awt::Size SAL_CALL AccessibleSlideSorterObject::getSize (void) + throw (RuntimeException) +{ + ThrowIfDisposed (); + const awt::Rectangle aBBox (getBounds()); + return awt::Size(aBBox.Width,aBBox.Height); +} + + + + +void SAL_CALL AccessibleSlideSorterObject::grabFocus (void) + throw (RuntimeException) +{ + // nothing to do +} + + + + +sal_Int32 SAL_CALL AccessibleSlideSorterObject::getForeground (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + svtools::ColorConfig aColorConfig; + UINT32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor; + return static_cast<sal_Int32>(nColor); +} + + + + +sal_Int32 SAL_CALL AccessibleSlideSorterObject::getBackground (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + UINT32 nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor(); + return static_cast<sal_Int32>(nColor); +} + + + + + +//===== XServiceInfo ======================================================== + +::rtl::OUString SAL_CALL + AccessibleSlideSorterObject::getImplementationName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + return OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleSlideSorterObject")); +} + + + + +sal_Bool SAL_CALL + AccessibleSlideSorterObject::supportsService (const OUString& sServiceName) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + + // Iterate over all supported service names and return true if on of them + // matches the given name. + uno::Sequence< ::rtl::OUString> aSupportedServices ( + getSupportedServiceNames ()); + for (int i=0; i<aSupportedServices.getLength(); i++) + if (sServiceName == aSupportedServices[i]) + return sal_True; + return sal_False; +} + + + + +uno::Sequence< ::rtl::OUString> SAL_CALL + AccessibleSlideSorterObject::getSupportedServiceNames (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + + static const OUString sServiceNames[2] = { + OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.accessibility.Accessible")), + OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.accessibility.AccessibleContext")) + }; + return uno::Sequence<OUString> (sServiceNames, 2); +} + + + + +void AccessibleSlideSorterObject::ThrowIfDisposed (void) + throw (lang::DisposedException) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + OSL_TRACE ("Calling disposed object. Throwing exception:"); + throw lang::DisposedException ( + OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")), + static_cast<uno::XWeak*>(this)); + } +} + + + +sal_Bool AccessibleSlideSorterObject::IsDisposed (void) +{ + return (rBHelper.bDisposed || rBHelper.bInDispose); +} + + + + +SdPage* AccessibleSlideSorterObject::GetPage (void) const +{ + ::sd::slidesorter::model::SharedPageDescriptor pDescriptor( + mrSlideSorter.GetModel().GetPageDescriptor(mnPageNumber)); + if (pDescriptor.get() != NULL) + return pDescriptor->GetPage(); + else + return NULL; +} + + +} // end of namespace ::accessibility diff --git a/sd/source/ui/accessibility/AccessibleSlideSorterView.cxx b/sd/source/ui/accessibility/AccessibleSlideSorterView.cxx new file mode 100644 index 000000000000..10596bd5f793 --- /dev/null +++ b/sd/source/ui/accessibility/AccessibleSlideSorterView.cxx @@ -0,0 +1,1065 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "AccessibleSlideSorterView.hxx" +#include "AccessibleSlideSorterObject.hxx" + +#include "SlideSorter.hxx" +#include "controller/SlideSorterController.hxx" +#include "controller/SlsPageSelector.hxx" +#include "controller/SlsFocusManager.hxx" +#include "controller/SlsSelectionManager.hxx" +#include "view/SlideSorterView.hxx" +#include "model/SlideSorterModel.hxx" +#include "model/SlsPageDescriptor.hxx" +#include "SlideSorterViewShell.hxx" + +#include "ViewShellHint.hxx" +#include "sdpage.hxx" +#include "drawdoc.hxx" + +#include "sdresid.hxx" +#include "accessibility.hrc" +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <comphelper/accessibleeventnotifier.hxx> +#include <unotools/accessiblestatesethelper.hxx> +#include <rtl/ref.hxx> +#include <vcl/svapp.hxx> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::accessibility; + +namespace accessibility { + + +class AccessibleSlideSorterView::Implementation + : public SfxListener +{ +public: + Implementation ( + AccessibleSlideSorterView& rAccessibleSlideSorter, + ::sd::slidesorter::SlideSorter& rSlideSorter, + ::Window* pWindow); + ~Implementation (void); + + void UpdateVisibility (void); + void UpdateChildren (void); + void Clear (void); + sal_Int32 GetVisibleChildCount (void) const; + AccessibleSlideSorterObject* GetAccessibleChild (sal_Int32 nIndex); + AccessibleSlideSorterObject* GetVisibleChild (sal_Int32 nIndex); + + void ConnectListeners (void); + void ReleaseListeners (void); + void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint); + DECL_LINK(WindowEventListener, VclWindowEvent*); + DECL_LINK(SelectionChangeListener, void*); + DECL_LINK(FocusChangeListener, void*); + +private: + AccessibleSlideSorterView& mrAccessibleSlideSorter; + ::sd::slidesorter::SlideSorter& mrSlideSorter; + typedef ::std::vector<rtl::Reference<AccessibleSlideSorterObject> > PageObjectList; + PageObjectList maPageObjects; + sal_Int32 mnFirstVisibleChild; + sal_Int32 mnLastVisibleChild; + bool mbListeningToDocument; + ::Window* mpWindow; + sal_Int32 mnFocusedIndex; + bool mbModelChangeLocked; +}; + + + + +//===== AccessibleSlideSorterView ============================================= + +AccessibleSlideSorterView::AccessibleSlideSorterView( + ::sd::slidesorter::SlideSorter& rSlideSorter, + const Reference<XAccessible>& rxParent, + ::Window* pContentWindow) + : AccessibleSlideSorterViewBase(MutexOwner::maMutex), + mpImpl(new Implementation(*this,rSlideSorter,pContentWindow)), + mrSlideSorter(rSlideSorter), + mxParent(rxParent), + mnClientId(0), + mpContentWindow(pContentWindow) +{ + OSL_TRACE("creating AccessibleSlideSorterView"); +} + + + + +AccessibleSlideSorterView::~AccessibleSlideSorterView (void) +{ + Destroyed (); +} + + + + +void AccessibleSlideSorterView::FireAccessibleEvent ( + short nEventId, + const uno::Any& rOldValue, + const uno::Any& rNewValue ) +{ + if (mnClientId != 0) + { + AccessibleEventObject aEventObject; + + aEventObject.Source = Reference<XWeak>(this); + aEventObject.EventId = nEventId; + aEventObject.NewValue = rNewValue; + aEventObject.OldValue = rOldValue; + + comphelper::AccessibleEventNotifier::addEvent (mnClientId, aEventObject); + } +} + + + + +void SAL_CALL AccessibleSlideSorterView::disposing (void) +{ + if (mnClientId != 0) + { + comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this ); + mnClientId = 0; + } + mpImpl.reset(NULL); +} + + + + +AccessibleSlideSorterObject* AccessibleSlideSorterView::GetAccessibleChildImplementation ( + sal_Int32 nIndex) +{ + AccessibleSlideSorterObject* pResult = NULL; + ::osl::MutexGuard aGuard (maMutex); + + if (nIndex>=0 && nIndex<mpImpl->GetVisibleChildCount()) + pResult = mpImpl->GetVisibleChild(nIndex); + + return pResult; +} + +void AccessibleSlideSorterView::Destroyed (void) +{ + ::osl::MutexGuard aGuard (maMutex); + + // Send a disposing to all listeners. + if (mnClientId != 0) + { + comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this ); + mnClientId = 0; + } +} + +//===== XAccessible ========================================================= + +Reference<XAccessibleContext > SAL_CALL + AccessibleSlideSorterView::getAccessibleContext (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed (); + return this; +} + +//===== XAccessibleContext ================================================== + +sal_Int32 SAL_CALL AccessibleSlideSorterView::getAccessibleChildCount (void) + throw (RuntimeException) +{ + ThrowIfDisposed(); + ::osl::MutexGuard aGuard (maMutex); + return mpImpl->GetVisibleChildCount(); +} + +Reference<XAccessible > SAL_CALL + AccessibleSlideSorterView::getAccessibleChild (sal_Int32 nIndex) + throw (lang::IndexOutOfBoundsException, RuntimeException) +{ + ThrowIfDisposed(); + ::osl::MutexGuard aGuard (maMutex); + + if (nIndex<0 || nIndex>=mpImpl->GetVisibleChildCount()) + throw lang::IndexOutOfBoundsException(); + + return mpImpl->GetVisibleChild(nIndex); +} + +Reference<XAccessible > SAL_CALL AccessibleSlideSorterView::getAccessibleParent (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + Reference<XAccessible> xParent; + + if (mpContentWindow != NULL) + { + ::Window* pParent = mpContentWindow->GetAccessibleParentWindow(); + if (pParent != NULL) + xParent = pParent->GetAccessible(); + } + + return xParent; +} + +sal_Int32 SAL_CALL AccessibleSlideSorterView::getAccessibleIndexInParent (void) + throw (uno::RuntimeException) +{ + OSL_ASSERT(getAccessibleParent().is()); + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + sal_Int32 nIndexInParent(-1); + + + Reference<XAccessibleContext> xParentContext (getAccessibleParent()->getAccessibleContext()); + if (xParentContext.is()) + { + sal_Int32 nChildCount (xParentContext->getAccessibleChildCount()); + for (sal_Int32 i=0; i<nChildCount; ++i) + if (xParentContext->getAccessibleChild(i).get() + == static_cast<XAccessible*>(this)) + { + nIndexInParent = i; + break; + } + } + + return nIndexInParent; +} + + + + +sal_Int16 SAL_CALL AccessibleSlideSorterView::getAccessibleRole (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + static sal_Int16 nRole = AccessibleRole::DOCUMENT; + return nRole; +} + + + + +::rtl::OUString SAL_CALL AccessibleSlideSorterView::getAccessibleDescription (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + ::vos::OGuard aGuard (Application::GetSolarMutex()); + + return String(SdResId(SID_SD_A11Y_I_SLIDEVIEW_D)); +} + + + + +::rtl::OUString SAL_CALL AccessibleSlideSorterView::getAccessibleName (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + ::vos::OGuard aGuard (Application::GetSolarMutex()); + + return String(SdResId(SID_SD_A11Y_I_SLIDEVIEW_N)); +} + + + + +Reference<XAccessibleRelationSet> SAL_CALL + AccessibleSlideSorterView::getAccessibleRelationSet (void) + throw (uno::RuntimeException) +{ + return Reference<XAccessibleRelationSet>(); +} + + + + +Reference<XAccessibleStateSet > SAL_CALL + AccessibleSlideSorterView::getAccessibleStateSet (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper(); + + pStateSet->AddState(AccessibleStateType::FOCUSABLE); + pStateSet->AddState(AccessibleStateType::SELECTABLE); + pStateSet->AddState(AccessibleStateType::ENABLED); + pStateSet->AddState(AccessibleStateType::ACTIVE); + pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE); + pStateSet->AddState(AccessibleStateType::OPAQUE); + if (mpContentWindow!=NULL) + { + if (mpContentWindow->IsVisible()) + pStateSet->AddState(AccessibleStateType::VISIBLE); + if (mpContentWindow->IsReallyVisible()) + pStateSet->AddState(AccessibleStateType::SHOWING); + } + + return pStateSet; +} + + + + +lang::Locale SAL_CALL AccessibleSlideSorterView::getLocale (void) + throw (IllegalAccessibleComponentStateException, + RuntimeException) +{ + ThrowIfDisposed (); + Reference<XAccessibleContext> xParentContext; + Reference<XAccessible> xParent (getAccessibleParent()); + if (xParent.is()) + xParentContext = xParent->getAccessibleContext(); + + if (xParentContext.is()) + return xParentContext->getLocale(); + else + // Strange, no parent! Anyway, return the default locale. + return Application::GetSettings().GetLocale(); +} + + + + +void SAL_CALL AccessibleSlideSorterView::addEventListener( + const Reference<XAccessibleEventListener >& rxListener) + throw (RuntimeException) +{ + if (rxListener.is()) + { + const osl::MutexGuard aGuard(maMutex); + + if (IsDisposed()) + { + uno::Reference<uno::XInterface> x ((lang::XComponent *)this, uno::UNO_QUERY); + rxListener->disposing (lang::EventObject (x)); + } + else + { + if ( ! mnClientId) + mnClientId = comphelper::AccessibleEventNotifier::registerClient(); + comphelper::AccessibleEventNotifier::addEventListener(mnClientId, rxListener); + } + } +} + + + + +void SAL_CALL AccessibleSlideSorterView::removeEventListener( + const Reference<XAccessibleEventListener >& rxListener) + throw (RuntimeException) +{ + ThrowIfDisposed(); + if (rxListener.is()) + { + const osl::MutexGuard aGuard(maMutex); + + if (mnClientId != 0) + { + sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( + mnClientId, rxListener ); + if ( !nListenerCount ) + { + // no listeners anymore -> revoke ourself. This may lead to + // the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case + // somebody calls NotifyAccessibleEvent, again + comphelper::AccessibleEventNotifier::revokeClient( mnClientId ); + mnClientId = 0; + } + } + } +} + + + + +//===== XAccessibleComponent ================================================== + +sal_Bool SAL_CALL AccessibleSlideSorterView::containsPoint (const awt::Point& aPoint) + throw (RuntimeException) +{ + ThrowIfDisposed(); + const awt::Rectangle aBBox (getBounds()); + return (aPoint.X >= 0) + && (aPoint.X < aBBox.Width) + && (aPoint.Y >= 0) + && (aPoint.Y < aBBox.Height); +} + + + + +Reference<XAccessible> SAL_CALL + AccessibleSlideSorterView::getAccessibleAtPoint (const awt::Point& aPoint) + throw (RuntimeException) +{ + ThrowIfDisposed(); + Reference<XAccessible> xAccessible; + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + + const Point aTestPoint (aPoint.X, aPoint.Y); + ::sd::slidesorter::model::SharedPageDescriptor pHitDescriptor ( + mrSlideSorter.GetController().GetPageAt(aTestPoint)); + if (pHitDescriptor.get() != NULL) + xAccessible = mpImpl->GetAccessibleChild( + (pHitDescriptor->GetPage()->GetPageNum()-1)/2); + + return xAccessible; +} + + + + +awt::Rectangle SAL_CALL AccessibleSlideSorterView::getBounds (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + awt::Rectangle aBBox; + + if (mpContentWindow != NULL) + { + const Point aPosition (mpContentWindow->GetPosPixel()); + const Size aSize (mpContentWindow->GetOutputSizePixel()); + + aBBox.X = aPosition.X(); + aBBox.Y = aPosition.Y(); + aBBox.Width = aSize.Width(); + aBBox.Height = aSize.Height(); + } + + return aBBox; +} + + + + +awt::Point SAL_CALL AccessibleSlideSorterView::getLocation (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + awt::Point aLocation; + + if (mpContentWindow != NULL) + { + const Point aPosition (mpContentWindow->GetPosPixel()); + aLocation.X = aPosition.X(); + aLocation.Y = aPosition.Y(); + } + + return aLocation; +} + + + + +/** Calculate the location on screen from the parent's location on screen + and our own relative location. +*/ +awt::Point SAL_CALL AccessibleSlideSorterView::getLocationOnScreen() + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + awt::Point aParentLocationOnScreen; + + Reference<XAccessible> xParent (getAccessibleParent()); + if (xParent.is()) + { + Reference<XAccessibleComponent> xParentComponent ( + xParent->getAccessibleContext(), uno::UNO_QUERY); + if (xParentComponent.is()) + aParentLocationOnScreen = xParentComponent->getLocationOnScreen(); + } + + awt::Point aLocationOnScreen (getLocation()); + aLocationOnScreen.X += aParentLocationOnScreen.X; + aLocationOnScreen.Y += aParentLocationOnScreen.Y; + + return aLocationOnScreen; +} + + + + +awt::Size SAL_CALL AccessibleSlideSorterView::getSize (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + awt::Size aSize; + + if (mpContentWindow != NULL) + { + const Size aOutputSize (mpContentWindow->GetOutputSizePixel()); + aSize.Width = aOutputSize.Width(); + aSize.Height = aOutputSize.Height(); + } + + return aSize; +} + + + + +void SAL_CALL AccessibleSlideSorterView::grabFocus (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + + if (mpContentWindow) + mpContentWindow->GrabFocus(); +} + + + + +sal_Int32 SAL_CALL AccessibleSlideSorterView::getForeground (void) + throw (RuntimeException) +{ + ThrowIfDisposed(); + svtools::ColorConfig aColorConfig; + UINT32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor; + return static_cast<sal_Int32>(nColor); +} + + + + +sal_Int32 SAL_CALL AccessibleSlideSorterView::getBackground (void) + throw (RuntimeException) +{ + ThrowIfDisposed(); + UINT32 nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor(); + return static_cast<sal_Int32>(nColor); +} + + + + +//===== XAccessibleSelection ================================================== + +void SAL_CALL AccessibleSlideSorterView::selectAccessibleChild (sal_Int32 nChildIndex) + throw (lang::IndexOutOfBoundsException, + RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + + AccessibleSlideSorterObject* pChild = mpImpl->GetAccessibleChild(nChildIndex); + if (pChild != NULL) + mrSlideSorter.GetController().GetPageSelector().SelectPage(pChild->GetPageNumber()); + else + throw lang::IndexOutOfBoundsException(); +} + + + + +sal_Bool SAL_CALL AccessibleSlideSorterView::isAccessibleChildSelected (sal_Int32 nChildIndex) + throw (lang::IndexOutOfBoundsException, + RuntimeException) +{ + ThrowIfDisposed(); + sal_Bool bIsSelected = sal_False; + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + + AccessibleSlideSorterObject* pChild = mpImpl->GetAccessibleChild(nChildIndex); + if (pChild != NULL) + bIsSelected = mrSlideSorter.GetController().GetPageSelector().IsPageSelected( + pChild->GetPageNumber()); + else + throw lang::IndexOutOfBoundsException(); + + return bIsSelected; +} + + + + +void SAL_CALL AccessibleSlideSorterView::clearAccessibleSelection (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + + mrSlideSorter.GetController().GetPageSelector().DeselectAllPages(); +} + + + + +void SAL_CALL AccessibleSlideSorterView::selectAllAccessibleChildren (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + + mrSlideSorter.GetController().GetPageSelector().SelectAllPages(); +} + + + + +sal_Int32 SAL_CALL AccessibleSlideSorterView::getSelectedAccessibleChildCount (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed (); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + return mrSlideSorter.GetController().GetPageSelector().GetSelectedPageCount(); +} + + + + +Reference<XAccessible > SAL_CALL + AccessibleSlideSorterView::getSelectedAccessibleChild (sal_Int32 nSelectedChildIndex ) + throw (lang::IndexOutOfBoundsException, uno::RuntimeException) +{ + ThrowIfDisposed (); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + Reference<XAccessible> xChild; + + ::sd::slidesorter::controller::PageSelector& rSelector ( + mrSlideSorter.GetController().GetPageSelector()); + sal_Int32 nPageCount(rSelector.GetPageCount()); + sal_Int32 nSelectedCount = 0; + for (sal_Int32 i=0; i<nPageCount; i++) + if (rSelector.IsPageSelected(i)) + { + if (nSelectedCount == nSelectedChildIndex) + { + xChild = mpImpl->GetAccessibleChild(i); + break; + } + ++nSelectedCount; + } + + + if ( ! xChild.is() ) + throw lang::IndexOutOfBoundsException(); + + return xChild; +} + + + + +void SAL_CALL AccessibleSlideSorterView::deselectAccessibleChild (sal_Int32 nChildIndex) + throw (lang::IndexOutOfBoundsException, + RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + + AccessibleSlideSorterObject* pChild = mpImpl->GetAccessibleChild(nChildIndex); + if (pChild != NULL) + mrSlideSorter.GetController().GetPageSelector().DeselectPage(pChild->GetPageNumber()); + else + throw lang::IndexOutOfBoundsException(); +} + + + + +//===== XServiceInfo ======================================================== + +::rtl::OUString SAL_CALL + AccessibleSlideSorterView::getImplementationName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + return OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleSlideSorterView")); +} + + + + +sal_Bool SAL_CALL + AccessibleSlideSorterView::supportsService (const OUString& sServiceName) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + + // Iterate over all supported service names and return true if on of them + // matches the given name. + uno::Sequence< ::rtl::OUString> aSupportedServices ( + getSupportedServiceNames ()); + for (int i=0; i<aSupportedServices.getLength(); i++) + if (sServiceName == aSupportedServices[i]) + return sal_True; + return sal_False; +} + + + + +uno::Sequence< ::rtl::OUString> SAL_CALL + AccessibleSlideSorterView::getSupportedServiceNames (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + + static const OUString sServiceNames[3] = { + OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.accessibility.Accessible")), + OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.accessibility.AccessibleContext")), + OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.drawing.AccessibleSlideSorterView")) + }; + return uno::Sequence<OUString> (sServiceNames, 3); +} + + + + +void AccessibleSlideSorterView::ThrowIfDisposed (void) + throw (lang::DisposedException) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + OSL_TRACE ("Calling disposed object. Throwing exception:"); + throw lang::DisposedException ( + OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")), + static_cast<uno::XWeak*>(this)); + } +} + + + +sal_Bool AccessibleSlideSorterView::IsDisposed (void) +{ + return (rBHelper.bDisposed || rBHelper.bInDispose); +} + +//===== AccessibleSlideSorterView::Implementation ============================= + +AccessibleSlideSorterView::Implementation::Implementation ( + AccessibleSlideSorterView& rAccessibleSlideSorter, + ::sd::slidesorter::SlideSorter& rSlideSorter, + ::Window* pWindow) + : mrAccessibleSlideSorter(rAccessibleSlideSorter), + mrSlideSorter(rSlideSorter), + maPageObjects(), + mnFirstVisibleChild(0), + mnLastVisibleChild(-1), + mbListeningToDocument(false), + mpWindow(pWindow), + mnFocusedIndex(-1), + mbModelChangeLocked(false) +{ + ConnectListeners(); + UpdateChildren(); + UpdateVisibility(); +} + + + + +AccessibleSlideSorterView::Implementation::~Implementation (void) +{ + ReleaseListeners(); + Clear(); +} + + + + +void AccessibleSlideSorterView::Implementation::UpdateVisibility (void) +{ + ::sd::slidesorter::view::SlideSorterView::PageRange aRange ( + mrSlideSorter.GetView().GetVisiblePageRange()); + mnFirstVisibleChild = aRange.first; + mnLastVisibleChild = aRange.second; +} + + + + +void AccessibleSlideSorterView::Implementation::UpdateChildren (void) +{ + // Clear the list of accessible children and adapt its size. It is + // refilled on demand when later the children are requested. + Clear(); + maPageObjects.resize(mrSlideSorter.GetModel().GetPageCount()); + UpdateVisibility(); +} + + + + +void AccessibleSlideSorterView::Implementation::Clear (void) +{ + PageObjectList::iterator iPageObject; + PageObjectList::iterator iEnd = maPageObjects.end(); + for (iPageObject=maPageObjects.begin(); iPageObject!=iEnd; ++iPageObject) + if (*iPageObject != NULL) + { + Reference<XComponent> xComponent (Reference<XWeak>(iPageObject->get()), UNO_QUERY); + if (xComponent.is()) + xComponent->dispose(); + *iPageObject = NULL; + } + maPageObjects.clear(); +} + + + + +sal_Int32 AccessibleSlideSorterView::Implementation::GetVisibleChildCount (void) const +{ + if (mnFirstVisibleChild <= mnLastVisibleChild) + return mnLastVisibleChild - mnFirstVisibleChild + 1; + else + return 0; +} + + + + +AccessibleSlideSorterObject* AccessibleSlideSorterView::Implementation::GetVisibleChild ( + sal_Int32 nIndex) +{ + assert(nIndex>=0 && nIndex<GetVisibleChildCount()); + + return GetAccessibleChild(nIndex+mnFirstVisibleChild); +} + + + + +AccessibleSlideSorterObject* AccessibleSlideSorterView::Implementation::GetAccessibleChild ( + sal_Int32 nIndex) +{ + OSL_ASSERT(nIndex>=0 && (sal_uInt32)nIndex<maPageObjects.size()); + + AccessibleSlideSorterObject* pChild = NULL; + + if (nIndex>=0 && (sal_uInt32)nIndex<maPageObjects.size()) + { + if (maPageObjects[nIndex] == NULL) + { + ::sd::slidesorter::model::SharedPageDescriptor pDescriptor( + mrSlideSorter.GetModel().GetPageDescriptor(nIndex)); + if (pDescriptor.get() != NULL) + maPageObjects[nIndex] = new AccessibleSlideSorterObject( + &mrAccessibleSlideSorter, + mrSlideSorter, + (pDescriptor->GetPage()->GetPageNum()-1)/2); + } + + pChild = maPageObjects[nIndex].get(); + } + + return pChild; +} + + + + +void AccessibleSlideSorterView::Implementation::ConnectListeners (void) +{ + StartListening (*mrSlideSorter.GetModel().GetDocument()); + if (mrSlideSorter.GetViewShell() != NULL) + StartListening (*mrSlideSorter.GetViewShell()); + mbListeningToDocument = true; + + if (mpWindow != NULL) + mpWindow->AddEventListener( + LINK(this,AccessibleSlideSorterView::Implementation,WindowEventListener)); + + mrSlideSorter.GetController().GetSelectionManager()->AddSelectionChangeListener( + LINK(this,AccessibleSlideSorterView::Implementation,SelectionChangeListener)); + + mrSlideSorter.GetController().GetFocusManager().AddFocusChangeListener( + LINK(this,AccessibleSlideSorterView::Implementation,FocusChangeListener)); +} + + + + +void AccessibleSlideSorterView::Implementation::ReleaseListeners (void) +{ + mrSlideSorter.GetController().GetFocusManager().RemoveFocusChangeListener( + LINK(this,AccessibleSlideSorterView::Implementation,FocusChangeListener)); + + mrSlideSorter.GetController().GetSelectionManager()->RemoveSelectionChangeListener( + LINK(this,AccessibleSlideSorterView::Implementation,SelectionChangeListener)); + + if (mpWindow != NULL) + mpWindow->RemoveEventListener( + LINK(this,AccessibleSlideSorterView::Implementation,WindowEventListener)); + + if (mbListeningToDocument) + { + if (mrSlideSorter.GetViewShell() != NULL) + StartListening(*mrSlideSorter.GetViewShell()); + EndListening (*mrSlideSorter.GetModel().GetDocument()); + mbListeningToDocument = false; + } +} + + + + +void AccessibleSlideSorterView::Implementation::Notify ( + SfxBroadcaster&, + const SfxHint& rHint) +{ + if (rHint.ISA(SdrHint)) + { + SdrHint& rSdrHint (*PTR_CAST(SdrHint,&rHint)); + switch (rSdrHint.GetKind()) + { + case HINT_PAGEORDERCHG: + if ( ! mbModelChangeLocked) + { + UpdateChildren(); + mrAccessibleSlideSorter.FireAccessibleEvent( + AccessibleEventId::INVALIDATE_ALL_CHILDREN, + Any(), + Any()); + } + break; + default: + break; + } + } + else if (rHint.ISA(sd::ViewShellHint)) + { + sd::ViewShellHint& rViewShellHint (*PTR_CAST(sd::ViewShellHint, &rHint)); + switch (rViewShellHint.GetHintId()) + { + case sd::ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_START: + mbModelChangeLocked = true; + break; + + case sd::ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_END: + mbModelChangeLocked = false; + UpdateChildren(); + mrAccessibleSlideSorter.FireAccessibleEvent( + AccessibleEventId::INVALIDATE_ALL_CHILDREN, + Any(), + Any()); + break; + default: + break; + } + } +} + + + + +IMPL_LINK(AccessibleSlideSorterView::Implementation, WindowEventListener, VclWindowEvent*, pEvent) +{ + switch (pEvent->GetId()) + { + case VCLEVENT_WINDOW_MOVE: + case VCLEVENT_WINDOW_RESIZE: + UpdateVisibility(); + mrAccessibleSlideSorter.FireAccessibleEvent( + AccessibleEventId::INVALIDATE_ALL_CHILDREN, + Any(), + Any()); + break; + + case VCLEVENT_WINDOW_GETFOCUS: + case VCLEVENT_WINDOW_LOSEFOCUS: + mrAccessibleSlideSorter.FireAccessibleEvent( + AccessibleEventId::SELECTION_CHANGED, + Any(), + Any()); + break; + default: + break; + } + return 1; +} + + + + +IMPL_LINK(AccessibleSlideSorterView::Implementation, SelectionChangeListener, void*, EMPTYARG ) +{ + mrAccessibleSlideSorter.FireAccessibleEvent( + AccessibleEventId::SELECTION_CHANGED, + Any(), + Any()); + return 1; +} + + + + +IMPL_LINK(AccessibleSlideSorterView::Implementation, FocusChangeListener, void*, EMPTYARG ) +{ + sal_Int32 nNewFocusedIndex ( + mrSlideSorter.GetController().GetFocusManager().GetFocusedPageIndex()); + + if (nNewFocusedIndex != mnFocusedIndex) + { + if (mnFocusedIndex >= 0) + { + AccessibleSlideSorterObject* pObject = GetAccessibleChild(mnFocusedIndex); + if (pObject != NULL) + pObject->FireAccessibleEvent( + AccessibleEventId::STATE_CHANGED, + Any(AccessibleStateType::FOCUSED), + Any()); + } + if (nNewFocusedIndex >= 0) + { + AccessibleSlideSorterObject* pObject = GetAccessibleChild(nNewFocusedIndex); + if (pObject != NULL) + pObject->FireAccessibleEvent( + AccessibleEventId::STATE_CHANGED, + Any(), + Any(AccessibleStateType::FOCUSED)); + } + mnFocusedIndex = nNewFocusedIndex; + } + return 1; +} + + +} // end of namespace ::accessibility diff --git a/sd/source/ui/accessibility/AccessibleTreeNode.cxx b/sd/source/ui/accessibility/AccessibleTreeNode.cxx new file mode 100755 index 000000000000..5c7462581d0b --- /dev/null +++ b/sd/source/ui/accessibility/AccessibleTreeNode.cxx @@ -0,0 +1,722 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_sd.hxx" + +#include "AccessibleTreeNode.hxx" + +#include "taskpane/TaskPaneTreeNode.hxx" +#include "taskpane/ControlContainer.hxx" + +#include "sdresid.hxx" +#include "accessibility.hrc" +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <comphelper/accessibleeventnotifier.hxx> + +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> +#include <svtools/colorcfg.hxx> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::accessibility; +using namespace ::sd::toolpanel; + +namespace accessibility { + + + +//===== AccessibleTreeNode ============================================= + +AccessibleTreeNode::AccessibleTreeNode( + ::sd::toolpanel::TreeNode& rNode, + const OUString& rsName, + const OUString& rsDescription, + sal_Int16 eRole) + : AccessibleTreeNodeBase(MutexOwner::maMutex), + mxParent(NULL), + mrTreeNode(rNode), + mrStateSet(new ::utl::AccessibleStateSetHelper()), + msName(rsName), + msDescription(rsDescription), + meRole(eRole), + mnClientId(0) +{ + ::Window* pWindow = mrTreeNode.GetWindow(); + if (pWindow != NULL) + { + ::Window* pParentWindow = pWindow->GetAccessibleParentWindow(); + if (pParentWindow != NULL && pParentWindow != pWindow) + mxParent = pParentWindow->GetAccessible(); + } + CommonConstructor(); +} + + + + +AccessibleTreeNode::AccessibleTreeNode( + const Reference<XAccessible>& rxParent, + ::sd::toolpanel::TreeNode& rNode, + const OUString& rsName, + const OUString& rsDescription, + const sal_Int16 eRole) + : AccessibleTreeNodeBase(MutexOwner::maMutex), + mxParent(rxParent), + mrTreeNode(rNode), + mrStateSet(new ::utl::AccessibleStateSetHelper()), + msName(rsName), + msDescription(rsDescription), + meRole(eRole), + mnClientId(0) +{ + CommonConstructor(); +} + + + + +void AccessibleTreeNode::CommonConstructor (void) +{ + UpdateStateSet(); + + Link aStateChangeLink (LINK(this,AccessibleTreeNode,StateChangeListener)); + mrTreeNode.AddStateChangeListener(aStateChangeLink); + + if (mrTreeNode.GetWindow() != NULL) + { + Link aWindowEventLink (LINK(this,AccessibleTreeNode,WindowEventListener)); + mrTreeNode.GetWindow()->AddEventListener(aWindowEventLink); + } +} + + + + +AccessibleTreeNode::~AccessibleTreeNode (void) +{ + OSL_ASSERT(IsDisposed()); +} + + + + +void AccessibleTreeNode::FireAccessibleEvent ( + short nEventId, + const uno::Any& rOldValue, + const uno::Any& rNewValue ) +{ + if (mnClientId != 0) + { + AccessibleEventObject aEventObject; + + aEventObject.Source = Reference<XWeak>(this); + aEventObject.EventId = nEventId; + aEventObject.NewValue = rNewValue; + aEventObject.OldValue = rOldValue; + + comphelper::AccessibleEventNotifier::addEvent (mnClientId, aEventObject); + } +} + + + + +void SAL_CALL AccessibleTreeNode::disposing (void) +{ + // We are still listening to the tree node and its window. Both + // probably are by now more or less dead and we must not call them to + // unregister. + + comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this ); + mnClientId = 0; +} + + + + +//===== XAccessible ========================================================= + +Reference<XAccessibleContext > SAL_CALL + AccessibleTreeNode::getAccessibleContext (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed (); + return this; +} + + + + +//===== XAccessibleContext ================================================== + +sal_Int32 SAL_CALL AccessibleTreeNode::getAccessibleChildCount (void) + throw (RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + return mrTreeNode.GetControlContainer().GetControlCount(); +} + + + + +Reference<XAccessible > SAL_CALL + AccessibleTreeNode::getAccessibleChild (sal_Int32 nIndex) + throw (lang::IndexOutOfBoundsException, RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + + if (nIndex<0 || (sal_uInt32)nIndex>=mrTreeNode.GetControlContainer().GetControlCount()) + throw lang::IndexOutOfBoundsException(); + + Reference<XAccessible> xChild; + + ::sd::toolpanel::TreeNode* pNode = mrTreeNode.GetControlContainer().GetControl(nIndex); + if (pNode != NULL) + xChild = pNode->GetAccessibleObject(); + + return xChild; +} + + + + +Reference<XAccessible > SAL_CALL AccessibleTreeNode::getAccessibleParent (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + return mxParent; +} + + + + +sal_Int32 SAL_CALL AccessibleTreeNode::getAccessibleIndexInParent (void) + throw (uno::RuntimeException) +{ + OSL_ASSERT(getAccessibleParent().is()); + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + sal_Int32 nIndexInParent(-1); + + + Reference<XAccessibleContext> xParentContext (getAccessibleParent()->getAccessibleContext()); + if (xParentContext.is()) + { + sal_Int32 nChildCount (xParentContext->getAccessibleChildCount()); + for (sal_Int32 i=0; i<nChildCount; ++i) + if (xParentContext->getAccessibleChild(i).get() + == static_cast<XAccessible*>(this)) + { + nIndexInParent = i; + break; + } + } + + return nIndexInParent; +} + + + + +sal_Int16 SAL_CALL AccessibleTreeNode::getAccessibleRole (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + return meRole; +} + + + + +::rtl::OUString SAL_CALL AccessibleTreeNode::getAccessibleDescription (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + return msDescription; +} + + + + +::rtl::OUString SAL_CALL AccessibleTreeNode::getAccessibleName (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + return msName; +} + + + + +Reference<XAccessibleRelationSet> SAL_CALL + AccessibleTreeNode::getAccessibleRelationSet (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + return Reference<XAccessibleRelationSet>(); +} + + + + +Reference<XAccessibleStateSet > SAL_CALL + AccessibleTreeNode::getAccessibleStateSet (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + return mrStateSet.get(); +} + + + + +void AccessibleTreeNode::UpdateStateSet (void) +{ + if (mrTreeNode.IsExpandable()) + { + UpdateState(AccessibleStateType::EXPANDABLE, true); + UpdateState(AccessibleStateType::EXPANDED, mrTreeNode.IsExpanded()); + } + + UpdateState(AccessibleStateType::FOCUSABLE, true); + + ::Window* pWindow = mrTreeNode.GetWindow(); + if (pWindow != NULL) + { + UpdateState(AccessibleStateType::ENABLED, pWindow->IsEnabled()); + UpdateState(AccessibleStateType::FOCUSED, pWindow->HasFocus()); + UpdateState(AccessibleStateType::VISIBLE, pWindow->IsVisible()); + UpdateState(AccessibleStateType::SHOWING, pWindow->IsReallyVisible()); + } +} + + + + +void AccessibleTreeNode::UpdateState( + sal_Int16 aState, + bool bValue) +{ + if ((mrStateSet->contains(aState)!=sal_False) != bValue) + { + if (bValue) + { + mrStateSet->AddState(aState); + FireAccessibleEvent(AccessibleEventId::STATE_CHANGED, Any(),Any(aState)); + } + else + { + mrStateSet->RemoveState(aState); + FireAccessibleEvent(AccessibleEventId::STATE_CHANGED, Any(aState),Any()); + } + } +} + + + + +lang::Locale SAL_CALL AccessibleTreeNode::getLocale (void) + throw (IllegalAccessibleComponentStateException, + RuntimeException) +{ + ThrowIfDisposed (); + Reference<XAccessibleContext> xParentContext; + Reference<XAccessible> xParent (getAccessibleParent()); + if (xParent.is()) + xParentContext = xParent->getAccessibleContext(); + + if (xParentContext.is()) + return xParentContext->getLocale(); + else + // Strange, no parent! Anyway, return the default locale. + return Application::GetSettings().GetLocale(); +} + + + + +void SAL_CALL AccessibleTreeNode::addEventListener( + const Reference<XAccessibleEventListener >& rxListener) + throw (RuntimeException) +{ + if (rxListener.is()) + { + const osl::MutexGuard aGuard(maMutex); + + if (IsDisposed()) + { + uno::Reference<uno::XInterface> x ((lang::XComponent *)this, uno::UNO_QUERY); + rxListener->disposing (lang::EventObject (x)); + } + else + { + if ( ! mnClientId) + mnClientId = comphelper::AccessibleEventNotifier::registerClient(); + comphelper::AccessibleEventNotifier::addEventListener(mnClientId, rxListener); + } + } +} + + + + +void SAL_CALL AccessibleTreeNode::removeEventListener( + const Reference<XAccessibleEventListener >& rxListener) + throw (RuntimeException) +{ + ThrowIfDisposed(); + if (rxListener.is()) + { + const osl::MutexGuard aGuard(maMutex); + + sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, rxListener ); + if ( !nListenerCount ) + { + // no listeners anymore + // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case somebody calls + // NotifyAccessibleEvent, again + comphelper::AccessibleEventNotifier::revokeClient( mnClientId ); + mnClientId = 0; + } + } +} + + + + +//===== XAccessibleComponent ================================================== + +sal_Bool SAL_CALL AccessibleTreeNode::containsPoint (const awt::Point& aPoint) + throw (RuntimeException) +{ + ThrowIfDisposed(); + const awt::Rectangle aBBox (getBounds()); + return (aPoint.X >= 0) + && (aPoint.X < aBBox.Width) + && (aPoint.Y >= 0) + && (aPoint.Y < aBBox.Height); +} + + + + +Reference<XAccessible> SAL_CALL + AccessibleTreeNode::getAccessibleAtPoint (const awt::Point& aPoint) + throw (RuntimeException) +{ + ThrowIfDisposed(); + Reference<XAccessible> xChildAtPoint; + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + + sal_Int32 nChildCount = getAccessibleChildCount(); + for (sal_Int32 nIndex=0; nIndex<nChildCount; ++nIndex) + { + Reference<XAccessibleComponent> xChildComponent( + getAccessibleChild(nIndex), UNO_QUERY); + if (xChildComponent.is()) + { + awt::Point aChildPoint(aPoint); + awt::Point aChildOrigin(xChildComponent->getLocation()); + aChildPoint.X -= aChildOrigin.X; + aChildPoint.Y -= aChildOrigin.Y; + if (xChildComponent->containsPoint(aChildPoint)) + { + xChildAtPoint = getAccessibleChild(nIndex); + break; + } + } + } + + return xChildAtPoint; +} + + + + +awt::Rectangle SAL_CALL AccessibleTreeNode::getBounds (void) + throw (RuntimeException) +{ + ThrowIfDisposed (); + + awt::Rectangle aBBox; + + ::Window* pWindow = mrTreeNode.GetWindow(); + if (pWindow != NULL) + { + Point aPosition; + if (mxParent.is()) + { + aPosition = pWindow->OutputToAbsoluteScreenPixel(Point(0,0)); + Reference<XAccessibleComponent> xParentComponent ( + mxParent->getAccessibleContext(), UNO_QUERY); + if (xParentComponent.is()) + { + awt::Point aParentPosition (xParentComponent->getLocationOnScreen()); + aPosition.X() -= aParentPosition.X; + aPosition.Y() -= aParentPosition.Y; + } + } + else + aPosition = pWindow->GetPosPixel(); + aBBox.X = aPosition.X(); + aBBox.Y = aPosition.Y(); + + Size aSize (pWindow->GetSizePixel()); + aBBox.Width = aSize.Width(); + aBBox.Height = aSize.Height(); + } + + return aBBox; +} + + + + +awt::Point SAL_CALL AccessibleTreeNode::getLocation (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const awt::Rectangle aBBox (getBounds()); + return awt::Point(aBBox.X,aBBox.Y); +} + + + + +/** Calculate the location on screen from the parent's location on screen + and our own relative location. +*/ +awt::Point SAL_CALL AccessibleTreeNode::getLocationOnScreen() + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + awt::Point aLocationOnScreen; + + ::Window* pWindow = mrTreeNode.GetWindow(); + if (pWindow != NULL) + { + Point aPoint (pWindow->OutputToAbsoluteScreenPixel(Point(0,0))); + aLocationOnScreen.X = aPoint.X(); + aLocationOnScreen.Y = aPoint.Y(); + } + + return aLocationOnScreen; +} + + + + +awt::Size SAL_CALL AccessibleTreeNode::getSize (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const awt::Rectangle aBBox (getBounds()); + return awt::Size(aBBox.Width,aBBox.Height); +} + + + + +void SAL_CALL AccessibleTreeNode::grabFocus (void) + throw (uno::RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard (Application::GetSolarMutex()); + + if (mrTreeNode.GetWindow() != NULL) + mrTreeNode.GetWindow()->GrabFocus(); +} + + + + +sal_Int32 SAL_CALL AccessibleTreeNode::getForeground (void) + throw (RuntimeException) +{ + ThrowIfDisposed(); + svtools::ColorConfig aColorConfig; + UINT32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor; + return static_cast<sal_Int32>(nColor); +} + + + + +sal_Int32 SAL_CALL AccessibleTreeNode::getBackground (void) + throw (RuntimeException) +{ + ThrowIfDisposed(); + UINT32 nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor(); + return static_cast<sal_Int32>(nColor); +} + + + + +//===== XServiceInfo ======================================================== + +::rtl::OUString SAL_CALL + AccessibleTreeNode::getImplementationName (void) + throw (::com::sun::star::uno::RuntimeException) +{ + return OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleTreeNode")); +} + + + + +sal_Bool SAL_CALL + AccessibleTreeNode::supportsService (const OUString& sServiceName) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + + // Iterate over all supported service names and return true if on of them + // matches the given name. + uno::Sequence< ::rtl::OUString> aSupportedServices ( + getSupportedServiceNames ()); + for (int i=0; i<aSupportedServices.getLength(); i++) + if (sServiceName == aSupportedServices[i]) + return sal_True; + return sal_False; +} + + + + +uno::Sequence< ::rtl::OUString> SAL_CALL + AccessibleTreeNode::getSupportedServiceNames (void) + throw (::com::sun::star::uno::RuntimeException) +{ + ThrowIfDisposed (); + static const OUString sServiceNames[2] = { + OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.accessibility.Accessible")), + OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.accessibility.AccessibleContext")), + }; + return uno::Sequence<OUString> (sServiceNames, 2); +} + + + + +void AccessibleTreeNode::ThrowIfDisposed (void) + throw (lang::DisposedException) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + OSL_TRACE ("Calling disposed object. Throwing exception:"); + throw lang::DisposedException ( + OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")), + static_cast<uno::XWeak*>(this)); + } +} + + + +sal_Bool AccessibleTreeNode::IsDisposed (void) +{ + return (rBHelper.bDisposed || rBHelper.bInDispose); +} + + + + +IMPL_LINK(AccessibleTreeNode, StateChangeListener, TreeNodeStateChangeEvent*, pEvent) +{ + OSL_ASSERT(pEvent!=NULL); + OSL_ASSERT(&pEvent->mrSource==&mrTreeNode); + + switch(pEvent->meEventId) + { + case EID_CHILD_ADDED: + if (pEvent->mpChild != NULL) + FireAccessibleEvent(AccessibleEventId::CHILD, + Any(), + Any(pEvent->mpChild->GetAccessibleObject())); + else + FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN,Any(),Any()); + break; + + case EID_ALL_CHILDREN_REMOVED: + FireAccessibleEvent(AccessibleEventId::INVALIDATE_ALL_CHILDREN,Any(),Any()); + break; + + case EID_EXPANSION_STATE_CHANGED: + case EID_FOCUSED_STATE_CHANGED: + case EID_SHOWING_STATE_CHANGED: + UpdateStateSet(); + break; + } + return 1; +} + + + + +IMPL_LINK(AccessibleTreeNode, WindowEventListener, VclWindowEvent*, pEvent) +{ + switch (pEvent->GetId()) + { + case VCLEVENT_WINDOW_HIDE: + // This event may be sent while the window is destroyed so do + // not call UpdateStateSet() which calls back to the window but + // just set the two states VISIBLE and SHOWING to false. + UpdateState(AccessibleStateType::VISIBLE, false); + UpdateState(AccessibleStateType::SHOWING, false); + break; + + case VCLEVENT_WINDOW_SHOW: + case VCLEVENT_WINDOW_DATACHANGED: + UpdateStateSet(); + break; + + case VCLEVENT_WINDOW_MOVE: + case VCLEVENT_WINDOW_RESIZE: + FireAccessibleEvent(AccessibleEventId::BOUNDRECT_CHANGED,Any(),Any()); + break; + + case VCLEVENT_WINDOW_GETFOCUS: + case VCLEVENT_WINDOW_LOSEFOCUS: + UpdateStateSet(); + break; + } + return 1; +} + +} // end of namespace ::accessibility diff --git a/sd/source/ui/accessibility/AccessibleViewForwarder.cxx b/sd/source/ui/accessibility/AccessibleViewForwarder.cxx new file mode 100644 index 000000000000..70734ac23198 --- /dev/null +++ b/sd/source/ui/accessibility/AccessibleViewForwarder.cxx @@ -0,0 +1,193 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_sd.hxx" + +#ifndef _SVX_ACCESSIBILITY_ACCESSIBLE_VIEW_FORWARDER_HXX +#include "AccessibleViewForwarder.hxx" +#endif +#include <svx/svdpntv.hxx> +#include <vcl/outdev.hxx> +#include <svx/sdrpaintwindow.hxx> + +namespace accessibility { + +/** For the time beeing, the implementation of this class will not use the + member mrDevice. Instead the device is retrieved from the view + everytime it is used. This is necessary because the device has to stay + up-to-date with the current view and the class has to stay compatible. + May change in the future. +*/ + +AccessibleViewForwarder::AccessibleViewForwarder (SdrPaintView* pView, USHORT nWindowId) + : mpView (pView), + mnWindowId (nWindowId), + mrDevice (pView->GetPaintWindow((sal_uInt32)nWindowId)->GetOutputDevice()) +{ + OSL_ASSERT (mpView != NULL); + // empty +} + + + + +AccessibleViewForwarder::AccessibleViewForwarder (SdrPaintView* pView, OutputDevice& rDevice) + : mpView (pView), + mnWindowId (0), + mrDevice (rDevice) +{ + // Search the output device to determine its id. + for(sal_uInt32 a(0L); a < mpView->PaintWindowCount(); a++) + { + SdrPaintWindow* pPaintWindow = mpView->GetPaintWindow(a); + OutputDevice& rOutDev = pPaintWindow->GetOutputDevice(); + + if(&rOutDev == &rDevice) + { + mnWindowId = (sal_uInt16)a; + break; + } + } +} + + + + +AccessibleViewForwarder::~AccessibleViewForwarder (void) +{ + // empty +} + + + + +void AccessibleViewForwarder::SetView (SdrPaintView* pView) +{ + mpView = pView; + OSL_ASSERT (mpView != NULL); +} + + + + +sal_Bool AccessibleViewForwarder::IsValid (void) const +{ + return sal_True; +} + + + + +Rectangle AccessibleViewForwarder::GetVisibleArea (void) const +{ + Rectangle aVisibleArea; + + if((sal_uInt32)mnWindowId < mpView->PaintWindowCount()) + { + SdrPaintWindow* pPaintWindow = mpView->GetPaintWindow((sal_uInt32)mnWindowId); + aVisibleArea = pPaintWindow->GetVisibleArea(); + } + + return aVisibleArea; +} + + + + +/** Tansform the given point into pixel coordiantes. After the the pixel + coordiantes of the window origin are added to make the point coordinates + absolute. +*/ +Point AccessibleViewForwarder::LogicToPixel (const Point& rPoint) const +{ + OSL_ASSERT (mpView != NULL); + if((sal_uInt32)mnWindowId < mpView->PaintWindowCount()) + { + SdrPaintWindow* pPaintWindow = mpView->GetPaintWindow((sal_uInt32)mnWindowId); + OutputDevice& rOutDev = pPaintWindow->GetOutputDevice(); + Rectangle aBBox(static_cast<Window&>(rOutDev).GetWindowExtentsRelative(0L)); + return rOutDev.LogicToPixel (rPoint) + aBBox.TopLeft(); + } + else + return Point(); +} + + + + +Size AccessibleViewForwarder::LogicToPixel (const Size& rSize) const +{ + OSL_ASSERT (mpView != NULL); + if((sal_uInt32)mnWindowId < mpView->PaintWindowCount()) + { + SdrPaintWindow* pPaintWindow = mpView->GetPaintWindow((sal_uInt32)mnWindowId); + OutputDevice& rOutDev = pPaintWindow->GetOutputDevice(); + return rOutDev.LogicToPixel (rSize); + } + else + return Size(); +} + + + + +/** First subtract the window origin to make the point coordinates relative + to the window and then transform them into internal coordinates. +*/ +Point AccessibleViewForwarder::PixelToLogic (const Point& rPoint) const +{ + OSL_ASSERT (mpView != NULL); + if((sal_uInt32)mnWindowId < mpView->PaintWindowCount()) + { + SdrPaintWindow* pPaintWindow = mpView->GetPaintWindow((sal_uInt32)mnWindowId); + OutputDevice& rOutDev = pPaintWindow->GetOutputDevice(); + Rectangle aBBox (static_cast<Window&>(rOutDev).GetWindowExtentsRelative(0L)); + return rOutDev.PixelToLogic (rPoint - aBBox.TopLeft()); + } + else + return Point(); +} + + + + +Size AccessibleViewForwarder::PixelToLogic (const Size& rSize) const +{ + OSL_ASSERT (mpView != NULL); + if((sal_uInt32)mnWindowId < mpView->PaintWindowCount()) + { + SdrPaintWindow* pPaintWindow = mpView->GetPaintWindow((sal_uInt32)mnWindowId); + OutputDevice& rOutDev = pPaintWindow->GetOutputDevice(); + return rOutDev.PixelToLogic (rSize); + } + else + return Size(); +} + + +} // end of namespace accessibility diff --git a/sd/source/ui/accessibility/SdShapeTypes.cxx b/sd/source/ui/accessibility/SdShapeTypes.cxx new file mode 100644 index 000000000000..6bd859c570c4 --- /dev/null +++ b/sd/source/ui/accessibility/SdShapeTypes.cxx @@ -0,0 +1,147 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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_sd.hxx" + +#include "SdShapeTypes.hxx" +#include "AccessiblePresentationShape.hxx" +#include "AccessiblePresentationGraphicShape.hxx" +#include "AccessiblePresentationOLEShape.hxx" +#include <rtl/ustring.h> + +namespace accessibility { + +AccessibleShape* + CreateSdAccessibleShape ( + const AccessibleShapeInfo& rShapeInfo, + const AccessibleShapeTreeInfo& rShapeTreeInfo, + ShapeTypeId nId) +{ + switch (nId) + { + case PRESENTATION_TITLE: + case PRESENTATION_OUTLINER: + case PRESENTATION_SUBTITLE: + case PRESENTATION_PAGE: + case PRESENTATION_NOTES: + case PRESENTATION_HANDOUT: + case PRESENTATION_HEADER: + case PRESENTATION_FOOTER: + case PRESENTATION_DATETIME: + case PRESENTATION_PAGENUMBER: + return new AccessiblePresentationShape (rShapeInfo, rShapeTreeInfo); + + case PRESENTATION_GRAPHIC_OBJECT: + return new AccessiblePresentationGraphicShape (rShapeInfo, rShapeTreeInfo); + + case PRESENTATION_OLE: + case PRESENTATION_CHART: + case PRESENTATION_TABLE: + return new AccessiblePresentationOLEShape (rShapeInfo, rShapeTreeInfo); + + default: + return new AccessibleShape (rShapeInfo, rShapeTreeInfo); + } +} + + + + +ShapeTypeDescriptor aSdShapeTypeList[] = { + ShapeTypeDescriptor ( + PRESENTATION_OUTLINER, + ::rtl::OUString::createFromAscii ("com.sun.star.presentation.OutlinerShape"), + CreateSdAccessibleShape ), + ShapeTypeDescriptor ( + PRESENTATION_SUBTITLE, + ::rtl::OUString::createFromAscii ("com.sun.star.presentation.SubtitleShape"), + CreateSdAccessibleShape ), + ShapeTypeDescriptor ( + PRESENTATION_GRAPHIC_OBJECT, + ::rtl::OUString::createFromAscii ("com.sun.star.presentation.GraphicObjectShape"), + CreateSdAccessibleShape ), + ShapeTypeDescriptor ( + PRESENTATION_PAGE, + ::rtl::OUString::createFromAscii ("com.sun.star.presentation.PageShape"), + CreateSdAccessibleShape ), + ShapeTypeDescriptor ( + PRESENTATION_OLE, + ::rtl::OUString::createFromAscii ("com.sun.star.presentation.OLE2Shape"), + CreateSdAccessibleShape ), + ShapeTypeDescriptor ( + PRESENTATION_CHART, + ::rtl::OUString::createFromAscii ("com.sun.star.presentation.ChartShape"), + CreateSdAccessibleShape ), + ShapeTypeDescriptor ( + PRESENTATION_TABLE, + ::rtl::OUString::createFromAscii ("com.sun.star.presentation.TableShape"), + CreateSdAccessibleShape ), + ShapeTypeDescriptor ( + PRESENTATION_NOTES, + ::rtl::OUString::createFromAscii ("com.sun.star.presentation.NotesShape"), + CreateSdAccessibleShape ), + ShapeTypeDescriptor ( + PRESENTATION_TITLE, + ::rtl::OUString::createFromAscii ("com.sun.star.presentation.TitleTextShape"), + CreateSdAccessibleShape ), + ShapeTypeDescriptor ( + PRESENTATION_HANDOUT, + ::rtl::OUString::createFromAscii ("com.sun.star.presentation.HandoutShape"), + CreateSdAccessibleShape ), + ShapeTypeDescriptor ( + PRESENTATION_HEADER, + ::rtl::OUString::createFromAscii ("com.sun.star.presentation.HeaderShape"), + CreateSdAccessibleShape ), + ShapeTypeDescriptor ( + PRESENTATION_FOOTER, + ::rtl::OUString::createFromAscii ("com.sun.star.presentation.FooterShape"), + CreateSdAccessibleShape ), + ShapeTypeDescriptor ( + PRESENTATION_DATETIME, + ::rtl::OUString::createFromAscii ("com.sun.star.presentation.DateTimeShape"), + CreateSdAccessibleShape ), + ShapeTypeDescriptor ( + PRESENTATION_PAGENUMBER, + ::rtl::OUString::createFromAscii ("com.sun.star.presentation.SlideNumberShape"), + CreateSdAccessibleShape ) +}; + + + + +void RegisterImpressShapeTypes (void) +{ + ShapeTypeHandler::Instance().AddShapeTypeList ( + PRESENTATION_PAGENUMBER - PRESENTATION_OUTLINER + 1, + aSdShapeTypeList); +} + + + + +} // end of namespace accessibility diff --git a/sd/source/ui/accessibility/accessibility.hrc b/sd/source/ui/accessibility/accessibility.hrc new file mode 100644 index 000000000000..e55c62abb0a4 --- /dev/null +++ b/sd/source/ui/accessibility/accessibility.hrc @@ -0,0 +1,53 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +#ifndef _SD_ACCESSIBILITY_HRC +#define _SD_ACCESSIBILITY_HRC + +#ifndef _SFX_HRC +#include <sfx2/sfx.hrc> +#endif + +#define SID_SD_A11Y_START (SID_SD_START+600) + +#define SID_SD_A11Y_D_DRAWVIEW_N (SID_SD_A11Y_START + 0) +#define SID_SD_A11Y_D_DRAWVIEW_D (SID_SD_A11Y_START + 1) + +#define SID_SD_A11Y_I_DRAWVIEW_N (SID_SD_A11Y_START + 2) +#define SID_SD_A11Y_I_DRAWVIEW_D (SID_SD_A11Y_START + 3) +#define SID_SD_A11Y_I_OUTLINEVIEW_N (SID_SD_A11Y_START + 4) +#define SID_SD_A11Y_I_OUTLINEVIEW_D (SID_SD_A11Y_START + 5) +#define SID_SD_A11Y_I_SLIDEVIEW_N (SID_SD_A11Y_START + 6) +#define SID_SD_A11Y_I_SLIDEVIEW_D (SID_SD_A11Y_START + 7) +#define SID_SD_A11Y_I_NOTESVIEW_N (SID_SD_A11Y_START + 8) +#define SID_SD_A11Y_I_NOTESVIEW_D (SID_SD_A11Y_START + 9) +#define SID_SD_A11Y_I_HANDOUTVIEW_N (SID_SD_A11Y_START + 10) +#define SID_SD_A11Y_I_HANDOUTVIEW_D (SID_SD_A11Y_START + 11) + + +#endif /* _SD_ACCESSIBILITY_HRC */ + diff --git a/sd/source/ui/accessibility/accessibility.src b/sd/source/ui/accessibility/accessibility.src new file mode 100644 index 000000000000..663d75bd29ff --- /dev/null +++ b/sd/source/ui/accessibility/accessibility.src @@ -0,0 +1,115 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +#include "accessibility.hrc" + +/* Names and descriptions of the Draw/Impress accessibility views + ============================================================== +*/ + +String SID_SD_A11Y_D_DRAWVIEW_N +{ + Text [ en-US ] = "Drawing View"; +}; + +String SID_SD_A11Y_D_DRAWVIEW_D +{ + Text [ en-US ] = "This is where you create and edit drawings."; +}; + +String SID_SD_A11Y_I_DRAWVIEW_N +{ + Text [ en-US ] = "Drawing View"; +}; + +String SID_SD_A11Y_I_DRAWVIEW_D +{ + Text [ en-US ] = "This is where you create and edit slides."; +}; + +String SID_SD_A11Y_I_OUTLINEVIEW_N +{ + Text [ en-US ] = "Outline View"; +}; + +String SID_SD_A11Y_I_OUTLINEVIEW_D +{ + Text [ en-US ] = "This is where you enter or edit text in list form."; +}; + +String SID_SD_A11Y_I_SLIDEVIEW_N +{ + Text [ en-US ] = "Slides View"; +}; + +String SID_SD_A11Y_I_SLIDEVIEW_D +{ + Text [ en-US ] = "This is where you sort slides."; +}; + +String SID_SD_A11Y_I_NOTESVIEW_N +{ + Text [ en-US ] = "Notes View"; +}; + +String SID_SD_A11Y_I_NOTESVIEW_D +{ + Text [ en-US ] = "This is where you enter and view notes."; +}; + +String SID_SD_A11Y_I_HANDOUTVIEW_N +{ + Text [ en-US ] = "Handout View"; +}; + +String SID_SD_A11Y_I_HANDOUTVIEW_D +{ + Text [ en-US ] = "This is where you decide on the layout for handouts."; +}; + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sd/source/ui/accessibility/makefile.mk b/sd/source/ui/accessibility/makefile.mk new file mode 100755 index 000000000000..25d79aa7f8da --- /dev/null +++ b/sd/source/ui/accessibility/makefile.mk @@ -0,0 +1,71 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# 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. +# +#************************************************************************* + + +PRJ=..$/..$/.. + +PROJECTPCH=sd +PROJECTPCHSOURCE=$(PRJ)$/util$/sd +PRJNAME=sd +TARGET=accessibility +ENABLE_EXCEPTIONS=TRUE +AUTOSEG=true +PRJINC=..$/slidesorter + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/AccessibleDocumentViewBase.obj \ + $(SLO)$/AccessibleDrawDocumentView.obj \ + $(SLO)$/AccessibleOutlineView.obj \ + $(SLO)$/AccessiblePresentationShape.obj \ + $(SLO)$/AccessiblePresentationGraphicShape.obj \ + $(SLO)$/AccessiblePresentationOLEShape.obj \ + $(SLO)$/AccessibleViewForwarder.obj \ + $(SLO)$/AccessibleOutlineEditSource.obj \ + $(SLO)$/AccessiblePageShape.obj \ + $(SLO)$/AccessibleScrollPanel.obj \ + $(SLO)$/AccessibleSlideSorterView.obj \ + $(SLO)$/AccessibleSlideSorterObject.obj \ + $(SLO)$/AccessibleTreeNode.obj \ + $(SLO)$/SdShapeTypes.obj + + +EXCEPTIONSFILES= + +SRS2NAME = accessibility +SRC2FILES = accessibility.src + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + |