diff options
author | Kohei Yoshida <kohei@openoffice.org> | 2009-08-20 04:28:30 +0000 |
---|---|---|
committer | Kohei Yoshida <kohei@openoffice.org> | 2009-08-20 04:28:30 +0000 |
commit | 9c22409f2648758e69a9de4ae49c2ba9bab24a3b (patch) | |
tree | 4c2e057064284b29475ed1b3fd2fe6057a2a096f | |
parent | 8802d45ff2523326cef7bf62cee92cd3809ada86 (diff) |
My first cut on implementing accessibility for the new datapilot field popup window. This is still work-in-progress, with
lots of debug statements everywhere.
-rw-r--r-- | sc/inc/AccessibleFilterMenu.hxx | 191 | ||||
-rw-r--r-- | sc/inc/AccessibleFilterMenuItem.hxx | 111 | ||||
-rw-r--r-- | sc/inc/AccessibleFilterTopWindow.hxx | 80 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleContextBase.cxx | 5 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleFilterMenu.cxx | 532 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx | 309 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx | 98 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/makefile.mk | 6 | ||||
-rw-r--r-- | sc/source/ui/cctrl/dpcontrol.cxx | 229 | ||||
-rw-r--r-- | sc/source/ui/inc/AccessibleContextBase.hxx | 2 | ||||
-rw-r--r-- | sc/source/ui/inc/dpcontrol.hxx | 49 | ||||
-rw-r--r-- | sc/source/ui/view/gridwin2.cxx | 3 |
12 files changed, 1591 insertions, 24 deletions
diff --git a/sc/inc/AccessibleFilterMenu.hxx b/sc/inc/AccessibleFilterMenu.hxx new file mode 100644 index 000000000000..1489f3bbdca1 --- /dev/null +++ b/sc/inc/AccessibleFilterMenu.hxx @@ -0,0 +1,191 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibleDataPilotControl.hxx,v $ + * $Revision: 1.6 $ + * + * 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 SC_ACCESSIBLEFILTERMENU_HXX +#define SC_ACCESSIBLEFILTERMENU_HXX + +#include "AccessibleContextBase.hxx" +#include "cppuhelper/implbase2.hxx" + +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <com/sun/star/accessibility/XAccessibleStateSet.hpp> +#include <com/sun/star/accessibility/XAccessibleText.hpp> +#include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp> +#include <com/sun/star/accessibility/TextSegment.hpp> + +#include <vector> +#include <set> + +namespace com { namespace sun { namespace star { + namespace accessibility { + struct AccessibleEventObject; + } +}}} + +class ScDocument; +class ScMenuFloatingWindow; + +typedef ::cppu::ImplHelper2< + ::com::sun::star::accessibility::XAccessibleStateSet, + ::com::sun::star::accessibility::XAccessibleSelection > ScAccessibleFilterMenu_BASE; + +class ScAccessibleFilterMenu : + public ScAccessibleContextBase, + public ScAccessibleFilterMenu_BASE +{ +public: + struct MenuItem + { + ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible > mxAccessible; + bool mbSelected; + + MenuItem(); + }; + + ScAccessibleFilterMenu( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible>& rxParent, + ScMenuFloatingWindow* pWin, const ::rtl::OUString& rName, ScDocument* pDoc); + virtual ~ScAccessibleFilterMenu(); + + // XAccessibleComponent + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& rPoint ) + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL isVisible() + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL grabFocus() + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getForeground() + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getBackground() + throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleContext + + virtual ::rtl::OUString SAL_CALL getAccessibleName() + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getAccessibleChildCount() + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL + getAccessibleChild(sal_Int32 nIndex) + throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException); + + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL + getAccessibleStateSet() + throw (::com::sun::star::uno::RuntimeException); + + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleEventBroadcaster + + virtual void SAL_CALL + addEventListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessibleEventListener>& xListener) + throw (com::sun::star::uno::RuntimeException); + + // Remove an existing event listener. + virtual void SAL_CALL + removeEventListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessibleEventListener>& xListener) + throw (com::sun::star::uno::RuntimeException); + + // XAccessibleStateSet + + virtual ::sal_Bool SAL_CALL isEmpty() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL contains(sal_Int16 nState) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL containsAll(const ::com::sun::star::uno::Sequence< ::sal_Int16 >& aStateSet) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence<sal_Int16> SAL_CALL getStates() throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleSelection + + virtual void SAL_CALL selectAccessibleChild( ::sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isAccessibleChildSelected( ::sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL clearAccessibleSelection( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL selectAllAccessibleChildren( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getSelectedAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL + getSelectedAccessibleChild(sal_Int32 nChildIndex) + throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL deselectAccessibleChild( ::sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + // XInterface + + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( + ::com::sun::star::uno::Type const & rType ) + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL acquire() throw (); + virtual void SAL_CALL release() throw (); + + // XTypeProvider + + virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() + throw (::com::sun::star::uno::RuntimeException); + + // non-UNO methods + + void selectMenuItem(size_t nIndex, bool bSelect); + void appendMenuItem(const ::rtl::OUString& rName, bool bEnabled, size_t nMenuPos); + + void setEnabled(bool bEnabled); + +private: + bool isFocused(); + bool isSelected(); + + void updateStates(); + +private: + ::std::vector<MenuItem> maMenuItems; + ::std::set<sal_Int16> maStates; + + ScMenuFloatingWindow* mpWindow; + ScDocument* mpDoc; + + bool mbEnabled:1; + bool mbSelected:1; +}; + +#endif diff --git a/sc/inc/AccessibleFilterMenuItem.hxx b/sc/inc/AccessibleFilterMenuItem.hxx new file mode 100644 index 000000000000..740cfd4e30c9 --- /dev/null +++ b/sc/inc/AccessibleFilterMenuItem.hxx @@ -0,0 +1,111 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibleDataPilotControl.hxx,v $ + * $Revision: 1.6 $ + * + * 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 SC_ACCESSIBLEFILTERMENUITEM_HXX +#define SC_ACCESSIBLEFILTERMENUITEM_HXX + +#include "AccessibleContextBase.hxx" +#include "cppuhelper/implbase2.hxx" + +#include <com/sun/star/accessibility/XAccessibleAction.hpp> +#include <com/sun/star/accessibility/XAccessibleStateSet.hpp> + +class ScMenuFloatingWindow; + +typedef ::cppu::ImplHelper2< + ::com::sun::star::accessibility::XAccessibleAction, + ::com::sun::star::accessibility::XAccessibleStateSet > ScAccessibleFilterMenuItem_BASE; + +class ScAccessibleFilterMenuItem : + public ScAccessibleContextBase, + public ScAccessibleFilterMenuItem_BASE +{ +public: + explicit ScAccessibleFilterMenuItem( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const ::rtl::OUString& rName, size_t nMenuPos); + + virtual ~ScAccessibleFilterMenuItem(); + + // XAccessibleContext + + virtual sal_Int32 SAL_CALL getAccessibleChildCount() + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL + getAccessibleChild(sal_Int32 nIndex) + throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException); + + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL + getAccessibleStateSet() + throw (::com::sun::star::uno::RuntimeException); + + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleStateSet + + virtual ::sal_Bool SAL_CALL isEmpty() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL contains(sal_Int16 nState) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL containsAll(const ::com::sun::star::uno::Sequence< ::sal_Int16 >& aStateSet) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence<sal_Int16> SAL_CALL getStates() throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleAction + + virtual ::sal_Int32 SAL_CALL getAccessibleActionCount( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL doAccessibleAction( ::sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getAccessibleActionDescription( ::sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleKeyBinding > SAL_CALL getAccessibleActionKeyBinding( ::sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( + ::com::sun::star::uno::Type const & rType ) + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL acquire() throw (); + virtual void SAL_CALL release() throw (); + + // Non-UNO Methods + + void select(); + void unselect(); + bool isSelected() const; + + void setEnabled(bool bEnabled); + +private: + ScMenuFloatingWindow* mpWindow; + ::rtl::OUString maName; + size_t mnMenuPos; + bool mbSelected:1; + bool mbEnabled:1; +}; + +#endif diff --git a/sc/inc/AccessibleFilterTopWindow.hxx b/sc/inc/AccessibleFilterTopWindow.hxx new file mode 100644 index 000000000000..7b7ad0c880f0 --- /dev/null +++ b/sc/inc/AccessibleFilterTopWindow.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibleDataPilotControl.hxx,v $ + * $Revision: 1.6 $ + * + * 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 SC_ACCESSIBLEFILTERTOPWINDOW_HXX +#define SC_ACCESSIBLEFILTERTOPWINDOW_HXX + +#include "AccessibleContextBase.hxx" +#include "cppuhelper/implbase1.hxx" + +class ScDPFieldPopupWindow; +class ScDocument; + +class ScAccessibleFilterTopWindow : public ScAccessibleContextBase +{ +public: + ScAccessibleFilterTopWindow( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible>& rxParent, + ScDPFieldPopupWindow* pWin, const ::rtl::OUString& rName, ScDocument* pDoc); + virtual ~ScAccessibleFilterTopWindow(); + + // XAccessibleContext + + virtual sal_Int32 SAL_CALL getAccessibleChildCount() + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL + getAccessibleChild(sal_Int32 nIndex) + throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException); + + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw (::com::sun::star::uno::RuntimeException); + + // Non-UNO Methods + + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + getAccessibleChildMenu(); + + void setAccessibleChildListBox( + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& rAccessible); + +private: + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + mxAccessibleMenu; + + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > + mxAccessibleListBox; + + ScDPFieldPopupWindow* mpWindow; + ScDocument* mpDoc; +}; + +#endif diff --git a/sc/source/ui/Accessibility/AccessibleContextBase.cxx b/sc/source/ui/Accessibility/AccessibleContextBase.cxx index 8774ef74f86d..16d80402abac 100644 --- a/sc/source/ui/Accessibility/AccessibleContextBase.cxx +++ b/sc/source/ui/Accessibility/AccessibleContextBase.cxx @@ -628,3 +628,8 @@ void ScAccessibleContextBase::IsObjectValid() const if (rBHelper.bDisposed || rBHelper.bInDispose) throw lang::DisposedException(); } + +void ScAccessibleContextBase::SetRole(sal_Int16 nRole) +{ + maRole = nRole; +} diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx new file mode 100644 index 000000000000..2ab7722807da --- /dev/null +++ b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx @@ -0,0 +1,532 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibleDataPilotControl.hxx,v $ + * $Revision: 1.6 $ + * + * 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_sc.hxx" +#include "AccessibleFilterMenu.hxx" +#include "AccessibleFilterMenuItem.hxx" +#include "unoguard.hxx" +#include "global.hxx" +#include "document.hxx" +#include "docpool.hxx" + +#include "tools/gen.hxx" +#include "svx/unoedsrc.hxx" +#include "svx/editdata.hxx" +#include "svx/outliner.hxx" +#include "svtools/itemset.hxx" +#include "vcl/unohelp.hxx" +#include "dpcontrol.hxx" + +#include <vector> + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleStateSet.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::accessibility::AccessibleStateType; + +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::lang::IndexOutOfBoundsException; +using ::com::sun::star::lang::IllegalArgumentException; +using ::com::sun::star::uno::RuntimeException; +using ::rtl::OUString; +using ::std::for_each; +using ::std::vector; +using ::std::set; + +#include <stdio.h> +#include <string> +#include <sys/time.h> + +namespace { + +class StackPrinter +{ +public: + explicit StackPrinter(const char* msg) : + msMsg(msg) + { + fprintf(stdout, "%s: --begin\n", msMsg.c_str()); + mfStartTime = getTime(); + } + + ~StackPrinter() + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); + } + + void printTime(int line) const + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); + } + +private: + double getTime() const + { + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; + } + + ::std::string msMsg; + double mfStartTime; +}; + +} + +// ============================================================================ + +namespace { + +class SelectMenuItem : public ::std::unary_function<void, ScAccessibleFilterMenu::MenuItem> +{ +public: + explicit SelectMenuItem(bool bSelect) : mbSelect(bSelect) {} + + void operator() (ScAccessibleFilterMenu::MenuItem& rItem) const + { + rItem.mbSelected = mbSelect; + ScAccessibleFilterMenuItem* p = static_cast<ScAccessibleFilterMenuItem*>(rItem.mxAccessible.get()); + if (mbSelect) + p->select(); + else + p->unselect(); + } +private: + bool mbSelect; +}; + +class AddRemoveEventListener : public ::std::unary_function<void, ScAccessibleFilterMenu::MenuItem> +{ +public: + explicit AddRemoveEventListener(const Reference<XAccessibleEventListener>& rListener, bool bAdd) : + mxListener(rListener), mbAdd(bAdd) {} + + void operator() (ScAccessibleFilterMenu::MenuItem& rItem) const + { + if (!rItem.mxAccessible.is()) + return; + + Reference<XAccessibleEventBroadcaster> xBc(rItem.mxAccessible, UNO_QUERY); + if (xBc.is()) + { + if (mbAdd) + xBc->addEventListener(mxListener); + else + xBc->removeEventListener(mxListener); + } + } +private: + Reference<XAccessibleEventListener> mxListener; + bool mbAdd; +}; + +class CountSelectedMenuItem : public ::std::unary_function<void, ScAccessibleFilterMenu::MenuItem> +{ +public: + explicit CountSelectedMenuItem() : mnCount(0) {} + + CountSelectedMenuItem(const CountSelectedMenuItem& r) : + mnCount(r.mnCount) {} + + void operator() (ScAccessibleFilterMenu::MenuItem& rItem) + { +// if (rItem.mbSelected) +// ++mnCount; +// + ScAccessibleFilterMenuItem* p = static_cast<ScAccessibleFilterMenuItem*>(rItem.mxAccessible.get()); +// fprintf(stdout, "CountSelectedMenuItem::(): name = '%s' selected = %d\n", +// rtl::OUStringToOString(p->getAccessibleName(), RTL_TEXTENCODING_UTF8).getStr(), p->isSelected()); + if (p->isSelected()) + ++mnCount; + } + + size_t getCount() const { return mnCount; } + +private: + size_t mnCount; +}; + +} + +// ============================================================================ + +ScAccessibleFilterMenu::MenuItem::MenuItem() : + mbSelected(false) +{ +} + +// ============================================================================ + +ScAccessibleFilterMenu::ScAccessibleFilterMenu(const Reference<XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, ScDocument* pDoc) : + ScAccessibleContextBase(rxParent, AccessibleRole::MENU), + mpWindow(pWin), + mpDoc(pDoc), + mbEnabled(true), + mbSelected(false) +{ + fprintf(stdout, "ScAccessibleFilterMenu::ScAccessibleFilterMenu: ctor (%p)\n", this); + SetName(rName); +// SetDescription(OUString::createFromAscii("parent filter menu description")); +} + +ScAccessibleFilterMenu::~ScAccessibleFilterMenu() +{ + fprintf(stdout, "ScAccessibleFilterMenu::~ScAccessibleFilterMenu: dtor (%p)\n", this); +} + +// XAccessibleComponent + +Reference<XAccessible> ScAccessibleFilterMenu::getAccessibleAtPoint( const ::com::sun::star::awt::Point& rPoint ) + throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::getAccessibleAtPoint: point = (%ld,%ld)\n", rPoint.X, rPoint.Y); + return this; +} + +sal_Bool ScAccessibleFilterMenu::isVisible() throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::isVisible: called\n"); + return true; +} + +void ScAccessibleFilterMenu::grabFocus() + throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::grabFocus: called\n"); +} + +sal_Int32 ScAccessibleFilterMenu::getForeground() + throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::getForeground: called\n"); + return 0; +} + +sal_Int32 ScAccessibleFilterMenu::getBackground() + throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::getBackground: called\n"); + return 0; +} + +// XAccessibleContext + +OUString ScAccessibleFilterMenu::getAccessibleName() throw (RuntimeException) +{ + return ScAccessibleContextBase::getAccessibleName(); +} + +sal_Int32 ScAccessibleFilterMenu::getAccessibleChildCount() + throw (RuntimeException) +{ + return maMenuItems.size(); +} + +Reference<XAccessible> ScAccessibleFilterMenu::getAccessibleChild(sal_Int32 nIndex) + throw (RuntimeException, IndexOutOfBoundsException) +{ + if (maMenuItems.size() <= nIndex) + throw IndexOutOfBoundsException(); + + return maMenuItems[nIndex].mxAccessible; +} + +Reference<XAccessibleStateSet> ScAccessibleFilterMenu::getAccessibleStateSet() + throw (RuntimeException) +{ + updateStates(); + return this; +} + +OUString ScAccessibleFilterMenu::getImplementationName() + throw (RuntimeException) +{ + return OUString::createFromAscii("ScAccessibleFilterMenu - implementation name"); +} + +// XAccessibleEventBroadcaster + +void ScAccessibleFilterMenu::addEventListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessibleEventListener>& xListener) + throw (com::sun::star::uno::RuntimeException) +{ + ScAccessibleContextBase::addEventListener(xListener); + for_each(maMenuItems.begin(), maMenuItems.end(), AddRemoveEventListener(xListener, true)); +} + +void ScAccessibleFilterMenu::removeEventListener( + const ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessibleEventListener>& xListener) + throw (com::sun::star::uno::RuntimeException) +{ + ScAccessibleContextBase::removeEventListener(xListener); + for_each(maMenuItems.begin(), maMenuItems.end(), AddRemoveEventListener(xListener, false)); +} + +// XAccessibleStateSet + +sal_Bool ScAccessibleFilterMenu::isEmpty() throw (RuntimeException) +{ + updateStates(); + return maStates.empty(); +} + +sal_Bool ScAccessibleFilterMenu::contains(sal_Int16 nState) throw (RuntimeException) +{ + updateStates(); + return maStates.count(nState) > 0; +} + +sal_Bool ScAccessibleFilterMenu::containsAll(const Sequence<sal_Int16>& aStateSet) + throw (RuntimeException) +{ + updateStates(); + sal_Int32 n = aStateSet.getLength(); + for (sal_Int32 i = 0; i < n; ++i) + { + if (!maStates.count(aStateSet[i])) + // This state is not set. + return false; + } + // All specified states are set. + return true; +} + +Sequence<sal_Int16> ScAccessibleFilterMenu::getStates() throw (RuntimeException) +{ + StackPrinter __stack_printer__("ScAccessibleFilterMenu::getStates"); + updateStates(); + Sequence<sal_Int16> aSeq(0); + set<sal_Int16>::const_iterator itr = maStates.begin(), itrEnd = maStates.end(); + for (size_t i = 0; itr != itrEnd; ++itr, ++i) + { + aSeq.realloc(i+1); + aSeq[i] = *itr; + } + if (maStates.count(FOCUSED)) + fprintf(stdout, "ScAccessibleFilterMenu::getStates: focused\n"); + else + fprintf(stdout, "ScAccessibleFilterMenu::getStates: not focused\n"); + return aSeq; +} + +// XAccessibleSelection + +void ScAccessibleFilterMenu::selectAccessibleChild(sal_Int32 nChildIndex) + throw (IndexOutOfBoundsException, RuntimeException) +{ + StackPrinter __stack_printer__("********** ScAccessibleFilterMenu::selectAccessibleChild **********"); + fprintf(stdout, "ScAccessibleFilterMenu::selectAccessibleChild: index = %ld\n", nChildIndex); + if (nChildIndex >= maMenuItems.size()) + throw IndexOutOfBoundsException(); + + maMenuItems[nChildIndex].mbSelected = true; + mpWindow->setSelectedMenuItem(nChildIndex, false, false); +} + +sal_Bool ScAccessibleFilterMenu::isAccessibleChildSelected(sal_Int32 nChildIndex) + throw (IndexOutOfBoundsException, RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::isAccessibleChildSelected: index = %ld\n", nChildIndex); + if (nChildIndex >= maMenuItems.size()) + throw IndexOutOfBoundsException(); + + return maMenuItems[nChildIndex].mbSelected; +} + +void ScAccessibleFilterMenu::clearAccessibleSelection() throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::clearAccessibleSelection: called\n"); + for_each(maMenuItems.begin(), maMenuItems.end(), SelectMenuItem(false)); + mpWindow->clearSelectedMenuItem(false); +} + +void ScAccessibleFilterMenu::selectAllAccessibleChildren() throw (RuntimeException) +{ + // not suported - this is a menu, you can't select all menu items. + +// fprintf(stdout, "ScAccessibleFilterMenu::selectAllAccessibleChildren: called\n"); +// for_each(maMenuItems.begin(), maMenuItems.end(), SelectMenuItem(true)); +} + +sal_Int32 ScAccessibleFilterMenu::getSelectedAccessibleChildCount() throw (RuntimeException) +{ + sal_Int32 n = for_each(maMenuItems.begin(), maMenuItems.end(), CountSelectedMenuItem()).getCount(); + fprintf(stdout, "ScAccessibleFilterMenu::getSelectedAccessibleChildCount: count = %ld\n", n); + return n; +} + +Reference<XAccessible> ScAccessibleFilterMenu::getSelectedAccessibleChild(sal_Int32 nChildIndex) + throw (IndexOutOfBoundsException, RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::getSelectedAccessibleChild: index = %ld\n", nChildIndex); + if (static_cast<size_t>(nChildIndex) >= maMenuItems.size()) + throw IndexOutOfBoundsException(); + + return maMenuItems[nChildIndex].mxAccessible; +} + +void ScAccessibleFilterMenu::deselectAccessibleChild(sal_Int32 nChildIndex) throw (IndexOutOfBoundsException, RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenu::deselectAccessibleChild: index = %ld\n", nChildIndex); + if (static_cast<size_t>(nChildIndex) >= maMenuItems.size()) + throw IndexOutOfBoundsException(); + + maMenuItems[nChildIndex].mbSelected = false; + ScAccessibleFilterMenuItem* p = static_cast<ScAccessibleFilterMenuItem*>( + maMenuItems[nChildIndex].mxAccessible.get()); + p->unselect(); + + mpWindow->selectMenuItem(nChildIndex, false, false, false); +} + +// XInterface + +uno::Any SAL_CALL ScAccessibleFilterMenu::queryInterface( uno::Type const & rType ) + throw (RuntimeException) +{ + Any any = ScAccessibleContextBase::queryInterface(rType); + if (any.hasValue()) + return any; + + return ScAccessibleFilterMenu_BASE::queryInterface(rType); +} + +void SAL_CALL ScAccessibleFilterMenu::acquire() throw () +{ + ScAccessibleContextBase::acquire(); +} + +void SAL_CALL ScAccessibleFilterMenu::release() throw () +{ + ScAccessibleContextBase::release(); +} + +// XTypeProvider + +Sequence<sal_Int8> ScAccessibleFilterMenu::getImplementationId() + throw (RuntimeException) +{ + Sequence<sal_Int8> aId(16); + return aId; +} + +void ScAccessibleFilterMenu::selectMenuItem(size_t nIndex, bool bSelect) +{ + StackPrinter __stack_printer__("ScAccessibleFilterMenu::selectMenuItem"); + fprintf(stdout, "ScAccessibleFilterMenu::selectMenuItem: index = %d select = %d\n", nIndex, bSelect); + if (maMenuItems.size() <= nIndex) + return; + + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; + CommitChange(aEvent); + + maMenuItems[nIndex].mbSelected = bSelect; + ScAccessibleFilterMenuItem* p = static_cast<ScAccessibleFilterMenuItem*>( + maMenuItems[nIndex].mxAccessible.get()); + if (bSelect) + p->select(); + else + p->unselect(); + + isSelected(); +// aEvent.EventId = AccessibleEventId::STATE_CHANGED; +// CommitChange(aEvent); +} + +void ScAccessibleFilterMenu::appendMenuItem(const OUString& rName, bool bEnabled, size_t nMenuPos) +{ + // Check weather this menu item is a sub menu or a regular menu item. + ScMenuFloatingWindow* pSubMenu = mpWindow->getSubMenuWindow(nMenuPos); + MenuItem aItem; + if (pSubMenu) + { + aItem.mxAccessible = pSubMenu->CreateAccessible(); + ScAccessibleFilterMenu* p = static_cast<ScAccessibleFilterMenu*>( + aItem.mxAccessible.get()); + p->setEnabled(bEnabled); + } + else + { + aItem.mxAccessible.set(new ScAccessibleFilterMenuItem(this, mpWindow, rName, nMenuPos)); + ScAccessibleFilterMenuItem* p = static_cast<ScAccessibleFilterMenuItem*>( + aItem.mxAccessible.get()); + p->setEnabled(bEnabled); + } + maMenuItems.push_back(aItem); +} + +void ScAccessibleFilterMenu::setEnabled(bool bEnabled) +{ + mbEnabled = bEnabled; +} + +bool ScAccessibleFilterMenu::isFocused() +{ + return true; +// return isSelected(); +} + +bool ScAccessibleFilterMenu::isSelected() +{ + // Check to see if any of the child menu items is selected. + size_t nSelectCount = for_each(maMenuItems.begin(), maMenuItems.end(), CountSelectedMenuItem()).getCount(); +// fprintf(stdout, "ScAccessibleFilterMenu::isSelected: selected count = %d\n", nSelectCount); + return nSelectCount == 0; +} + +void ScAccessibleFilterMenu::updateStates() +{ + maStates.clear(); + maStates.insert(ENABLED); + maStates.insert(FOCUSABLE); + maStates.insert(SELECTABLE); + maStates.insert(SENSITIVE); + maStates.insert(OPAQUE); + + if (isFocused()) + maStates.insert(FOCUSED); + if (isSelected()) + maStates.insert(SELECTED); +} diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx new file mode 100644 index 000000000000..2e151b67b600 --- /dev/null +++ b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx @@ -0,0 +1,309 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibleDataPilotControl.hxx,v $ + * $Revision: 1.6 $ + * + * 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_sc.hxx" +#include "AccessibleFilterMenuItem.hxx" +#include "dpcontrol.hxx" + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleStateSet.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleEventObject.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/TextSegment.hpp> + +#include <vector> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; + +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::lang::IndexOutOfBoundsException; +using ::com::sun::star::uno::RuntimeException; +using ::rtl::OUString; +using ::std::vector; + +#include <stdio.h> +#include <string> +#include <sys/time.h> + +namespace { + +class StackPrinter +{ +public: + explicit StackPrinter(const char* msg) : + msMsg(msg) + { + fprintf(stdout, "%s: --begin\n", msMsg.c_str()); + mfStartTime = getTime(); + } + + ~StackPrinter() + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); + } + + void printTime(int line) const + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); + } + +private: + double getTime() const + { + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; + } + + ::std::string msMsg; + double mfStartTime; +}; + +} + +ScAccessibleFilterMenuItem::ScAccessibleFilterMenuItem( + const Reference<XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos) : + ScAccessibleContextBase(rxParent, AccessibleRole::MENU_ITEM), + mpWindow(pWin), + maName(rName), + mnMenuPos(nMenuPos), + mbSelected(false), + mbEnabled(true) +{ + SetName(rName); +} + +ScAccessibleFilterMenuItem::~ScAccessibleFilterMenuItem() +{ +} + +sal_Int32 ScAccessibleFilterMenuItem::getAccessibleChildCount() + throw (RuntimeException) +{ + return 0; +} + +Reference<XAccessible> ScAccessibleFilterMenuItem::getAccessibleChild(sal_Int32 nIndex) + throw (RuntimeException, IndexOutOfBoundsException) +{ + throw IndexOutOfBoundsException(); + return Reference<XAccessible>(); +} + +Reference<XAccessibleStateSet> ScAccessibleFilterMenuItem::getAccessibleStateSet() + throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenuItem::getAccessibleStateSet: called\n"); + return this; +} + +OUString ScAccessibleFilterMenuItem::getImplementationName() + throw (RuntimeException) +{ + return OUString::createFromAscii("ScAccessibleFilterMenuItem - implementation name"); +} + +// XAccessibleStateSet + +sal_Bool ScAccessibleFilterMenuItem::isEmpty() throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenuItem::isEmpty: called\n"); + return (mbEnabled || mbSelected); +} + +sal_Bool ScAccessibleFilterMenuItem::contains(sal_Int16 nState) throw (RuntimeException) +{ + using namespace ::com::sun::star::accessibility::AccessibleStateType; + fprintf(stdout, "ScAccessibleFilterMenuItem::contains: state = %d\n", nState); + if (mbEnabled) + { + switch (nState) + { + case ENABLED: + case FOCUSABLE: + case SELECTABLE: + case SENSITIVE: + return true; + } + } + + if (mbSelected) + { + switch (nState) + { + case FOCUSED: + case SELECTED: + return true; + } + } + return false; +} + +sal_Bool ScAccessibleFilterMenuItem::containsAll(const Sequence<sal_Int16>& aStateSet) + throw (RuntimeException) +{ + using namespace ::com::sun::star::accessibility::AccessibleStateType; + fprintf(stdout, "ScAccessibleFilterMenuItem::containsAll: called\n"); + sal_Int32 n = aStateSet.getLength(); + for (sal_Int32 i = 0; i < n; ++i) + { + sal_Int16 nState = aStateSet[i]; + if (mbEnabled) + { + switch (nState) + { + case ENABLED: + case FOCUSABLE: + case SELECTABLE: + case SENSITIVE: + continue; + } + } + if (mbSelected) + { + switch (nState) + { + case FOCUSED: + case SELECTED: + continue; + } + } + return false; + } + return true; +} + +Sequence<sal_Int16> ScAccessibleFilterMenuItem::getStates() throw (RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenuItem::getStates: name = '%s' enabled = %d selected = %d\n", + rtl::OUStringToOString(getAccessibleName(), RTL_TEXTENCODING_UTF8).getStr(), + mbEnabled, mbSelected); + using namespace ::com::sun::star::accessibility::AccessibleStateType; + vector<sal_Int16> aStates; + if (mbEnabled) + { + aStates.push_back(ENABLED); + aStates.push_back(FOCUSABLE); + aStates.push_back(SELECTABLE); + aStates.push_back(SENSITIVE); + } + + if (mbSelected) + { + aStates.push_back(FOCUSED); + aStates.push_back(SELECTED); + } + + size_t n = aStates.size(); + Sequence<sal_Int16> aSeq(aStates.size()); + for (size_t i = 0; i < n; ++i) + aSeq[i] = aStates[i]; + + return aSeq; +} + +// XAccessibleAction + +sal_Int32 ScAccessibleFilterMenuItem::getAccessibleActionCount() throw (RuntimeException) +{ + return 1; +} + +sal_Bool ScAccessibleFilterMenuItem::doAccessibleAction(sal_Int32 nIndex) + throw (IndexOutOfBoundsException, RuntimeException) +{ + fprintf(stdout, "ScAccessibleFilterMenuItem::doAccessibleAction: called\n"); + return false; +} + +OUString ScAccessibleFilterMenuItem::getAccessibleActionDescription(sal_Int32 nIndex) + throw (IndexOutOfBoundsException, RuntimeException) +{ + return OUString::createFromAscii("Add some action here..."); +} + +Reference<XAccessibleKeyBinding> ScAccessibleFilterMenuItem::getAccessibleActionKeyBinding( + sal_Int32 nIndex) throw (IndexOutOfBoundsException, RuntimeException) +{ + return Reference<XAccessibleKeyBinding>(); +} + +Any SAL_CALL ScAccessibleFilterMenuItem::queryInterface( uno::Type const & rType ) + throw (RuntimeException) +{ + Any any = ScAccessibleContextBase::queryInterface(rType); + if (any.hasValue()) + return any; + + return ScAccessibleFilterMenuItem_BASE::queryInterface(rType); +} + +void SAL_CALL ScAccessibleFilterMenuItem::acquire() throw () +{ + ScAccessibleContextBase::acquire(); +} + +void SAL_CALL ScAccessibleFilterMenuItem::release() throw () +{ + ScAccessibleContextBase::release(); +} + +void ScAccessibleFilterMenuItem::select() +{ + mbSelected = true; + CommitFocusGained(); +} + +void ScAccessibleFilterMenuItem::unselect() +{ + mbSelected = false; + CommitFocusLost(); +} + +bool ScAccessibleFilterMenuItem::isSelected() const +{ + return mbSelected; +} + +void ScAccessibleFilterMenuItem::setEnabled(bool bEnabled) +{ + mbEnabled = bEnabled; +} + diff --git a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx new file mode 100644 index 000000000000..f0256b0abe9f --- /dev/null +++ b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx @@ -0,0 +1,98 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: AccessibleDataPilotControl.hxx,v $ + * $Revision: 1.6 $ + * + * 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_sc.hxx" +#include "AccessibleFilterTopWindow.hxx" +#include "AccessibleFilterMenu.hxx" +#include "dpcontrol.hxx" + +#include <com/sun/star/accessibility/AccessibleRole.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using ::com::sun::star::lang::IndexOutOfBoundsException; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::RuntimeException; +using ::rtl::OUString; + +ScAccessibleFilterTopWindow::ScAccessibleFilterTopWindow( + const Reference<XAccessible>& rxParent, ScDPFieldPopupWindow* pWin, const OUString& rName, ScDocument* pDoc) : + ScAccessibleContextBase(rxParent, AccessibleRole::PANEL), + mpWindow(pWin), + mpDoc(pDoc) +{ + SetName(rName); +} + +ScAccessibleFilterTopWindow::~ScAccessibleFilterTopWindow() +{ +} + +// XAccessibleContext + +sal_Int32 ScAccessibleFilterTopWindow::getAccessibleChildCount() throw (RuntimeException) +{ + return 2; +} + +Reference<XAccessible> ScAccessibleFilterTopWindow::getAccessibleChild( + sal_Int32 nIndex) throw (RuntimeException, IndexOutOfBoundsException) +{ + if (nIndex >= 2) + throw IndexOutOfBoundsException(); + + if (nIndex == 0) + return getAccessibleChildMenu(); + + if (nIndex == 1) + return mxAccessibleListBox; + + return Reference<XAccessible>(); +} + +OUString ScAccessibleFilterTopWindow::getImplementationName() throw (RuntimeException) +{ + return OUString::createFromAscii("ScAccessibleFilterTopWindow"); +} + +Reference<XAccessible> ScAccessibleFilterTopWindow::getAccessibleChildMenu() +{ + if (!mxAccessibleMenu.is()) + mxAccessibleMenu.set(new ScAccessibleFilterMenu(this, mpWindow, getAccessibleName(), mpDoc)); + return mxAccessibleMenu; +} + +void ScAccessibleFilterTopWindow::setAccessibleChildListBox(const Reference<XAccessible>& rAccessible) +{ + mxAccessibleListBox = rAccessible; +} + diff --git a/sc/source/ui/Accessibility/makefile.mk b/sc/source/ui/Accessibility/makefile.mk index dfa5ac94b63f..0bde79f1f159 100644 --- a/sc/source/ui/Accessibility/makefile.mk +++ b/sc/source/ui/Accessibility/makefile.mk @@ -53,6 +53,9 @@ SLOFILES = \ $(SLO)$/AccessibleDocumentBase.obj \ $(SLO)$/AccessibleCellBase.obj \ $(SLO)$/AccessibleDocumentPagePreview.obj \ + $(SLO)$/AccessibleFilterMenu.obj \ + $(SLO)$/AccessibleFilterMenuItem.obj \ + $(SLO)$/AccessibleFilterTopWindow.obj \ $(SLO)$/AccessiblePreviewTable.obj \ $(SLO)$/AccessiblePreviewCell.obj \ $(SLO)$/AccessiblePreviewHeaderCell.obj \ @@ -73,6 +76,9 @@ EXCEPTIONSFILES= \ $(SLO)$/AccessibleDocumentBase.obj \ $(SLO)$/AccessibleCellBase.obj \ $(SLO)$/AccessibleDocumentPagePreview.obj \ + $(SLO)$/AccessibleFilterMenu.obj \ + $(SLO)$/AccessibleFilterMenuItem.obj \ + $(SLO)$/AccessibleFilterTopWindow.obj \ $(SLO)$/AccessiblePreviewTable.obj \ $(SLO)$/AccessiblePreviewCell.obj \ $(SLO)$/AccessiblePreviewHeaderCell.obj \ diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index 0060a9341ec3..df8658eb1f6b 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -41,14 +41,86 @@ #include "vcl/wintypes.hxx" #include "vcl/decoview.hxx" #include "strload.hxx" +#include "global.hxx" + +#include "AccessibleFilterMenu.hxx" +#include "AccessibleFilterTopWindow.hxx" + +#include <com/sun/star/accessibility/XAccessible.hpp> #define MENU_NOT_SELECTED 999 +using ::com::sun::star::uno::Reference; +using ::com::sun::star::accessibility::XAccessible; using ::rtl::OUString; using ::rtl::OUStringHash; using ::std::vector; using ::std::hash_map; using ::std::auto_ptr; +//using ::std::for_each; + + +#include <stdio.h> +#include <string> +#include <sys/time.h> + +namespace { + +class StackPrinter +{ +public: + explicit StackPrinter(const char* msg) : + msMsg(msg) + { + fprintf(stdout, "%s: --begin\n", msMsg.c_str()); + mfStartTime = getTime(); + } + + ~StackPrinter() + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); + } + + void printTime(int line) const + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); + } + +private: + double getTime() const + { + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; + } + + ::std::string msMsg; + double mfStartTime; +}; + +} + +//namespace { +// +//class AppendAccessibleMenuItems : public ::std::unary_function<ScMenuFloatingWindow::MenuItem, void> +//{ +//public: +// explicit AppendAccessibleMenuItems(ScAccessibleFilterMenu* pAccMenu) : +// mnPos(0), mpAccMenu(pAccMenu) {} +// +// void operator() (const ScMenuFloatingWindow::MenuItem& rItem) +// { +// mpAccMenu->appendMenuItem(rItem.maText, rItem.mbEnabled, mnPos++); +// } +// +//private: +// size_t mnPos; +// ScAccessibleFilterMenu* mpAccMenu; +//}; +// +//} ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX, const Fraction* pZoomY) : mpOutDev(pOutDev), @@ -272,16 +344,19 @@ IMPL_LINK( ScMenuFloatingWindow::SubMenuItem, TimeoutHdl, void*, EMPTYARG ) // ---------------------------------------------------------------------------- -ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent) : +ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc) : FloatingWindow(pParent, (WB_SYSTEMFLOATWIN|WB_SYSTEMWINDOW|WB_NOBORDER)), maOpenTimer(this), maCloseTimer(this), + maName(OUString::createFromAscii("ScMenuFloatingWindow")), mnSelectedMenu(MENU_NOT_SELECTED), mnClickedMenu(MENU_NOT_SELECTED), + mpDoc(pDoc), mpParentMenu(dynamic_cast<ScMenuFloatingWindow*>(pParent)), mpActiveSubMenu(NULL), mbActionFired(false) { + fprintf(stdout, "***** ScMenuFloatingWindow::ScMenuFloatingWindow: ctor (%p) parent = %p\n", this, pParent); // TODO: How do we get the right font to use here ? const sal_uInt16 nPopupFontHeight = 12; const StyleSettings& rStyle = GetSettings().GetStyleSettings(); @@ -289,6 +364,7 @@ ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent) : maLabelFont.SetHeight(nPopupFontHeight); SetFont(maLabelFont); + SetText(OUString::createFromAscii("ScMenuFloatingWindow")); SetPopupModeEndHdl( LINK(this, ScMenuFloatingWindow, EndPopupHdl) ); } @@ -404,6 +480,30 @@ void ScMenuFloatingWindow::Paint(const Rectangle& /*rRect*/) drawAllMenuItems(); } +Reference<XAccessible> ScMenuFloatingWindow::CreateAccessible() +{ + if (!mxAccessible.is()) + { + StackPrinter __stack_printer__("ScMenuFloatingWindow::CreateAccessible (create new)"); + Reference<XAccessible> xAccParent = mpParentMenu ? + mpParentMenu->GetAccessible() : GetAccessibleParentWindow()->GetAccessible(); + + mxAccessible.set(new ScAccessibleFilterMenu(xAccParent, this, maName, getDoc())); + ScAccessibleFilterMenu* p = static_cast<ScAccessibleFilterMenu*>( + mxAccessible.get()); + +// for_each(maMenuItems.begin(), maMenuItems.end(), AppendAccessibleMenuItems(p)); + vector<MenuItem>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end(); + for (itr = itrBeg; itr != itrEnd; ++itr) + { + size_t nPos = ::std::distance(itrBeg, itr); + p->appendMenuItem(itr->maText, itr->mbEnabled, nPos); + } + } + + return mxAccessible; +} + void ScMenuFloatingWindow::addMenuItem(const OUString& rText, bool bEnabled, Action* pAction) { MenuItem aItem; @@ -418,7 +518,8 @@ ScMenuFloatingWindow* ScMenuFloatingWindow::addSubMenuItem(const OUString& rText MenuItem aItem; aItem.maText = rText; aItem.mbEnabled = bEnabled; - aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this)); + aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this, mpDoc)); + aItem.mpSubMenuWin->setName(rText); maMenuItems.push_back(aItem); return aItem.mpSubMenuWin.get(); } @@ -430,7 +531,7 @@ void ScMenuFloatingWindow::drawMenuItem(size_t nPos) Point aPos; Size aSize; - getMenuItemPosSize(aPos, aSize, nPos); + getMenuItemPosSize(nPos, aPos, aSize); DecorationView aDecoView(this); long nXOffset = 5; @@ -476,17 +577,19 @@ void ScMenuFloatingWindow::executeMenu(size_t nPos) EndPopupMode(); } -void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer) +void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bNotifyAccessible) { + StackPrinter __stack_printer__("******************** ScMenuFloatingWindow::setSelectedMenuItem ********************"); + fprintf(stdout, "ScMenuFloatingWindow::setSelectedMenuItem: pos = %d\n", nPos); if (mnSelectedMenu != nPos) { - selectMenuItem(mnSelectedMenu, false, bSubMenuTimer); - selectMenuItem(nPos, true, bSubMenuTimer); + selectMenuItem(mnSelectedMenu, false, bSubMenuTimer, bNotifyAccessible); + selectMenuItem(nPos, true, bSubMenuTimer, bNotifyAccessible); mnSelectedMenu = nPos; } } -size_t ScMenuFloatingWindow::getSelectedMenuItem() const +size_t ScMenuFloatingWindow::getSelectedMenuPos() const { return mnSelectedMenu; } @@ -563,7 +666,7 @@ void ScMenuFloatingWindow::launchSubMenu(bool bSetMenuPos) { Point aPos; Size aSize; - getMenuItemPosSize(aPos, aSize, maOpenTimer.mnMenuPos); + getMenuItemPosSize(maOpenTimer.mnMenuPos, aPos, aSize); ScMenuFloatingWindow* pSubMenu = maOpenTimer.mpSubMenu; if (!pSubMenu) @@ -588,6 +691,21 @@ void ScMenuFloatingWindow::endSubMenu() } } +void ScMenuFloatingWindow::fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const +{ + vector<MenuItem>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end(); + for (itr = itrBeg; itr != itrEnd; ++itr) + { + size_t nPos = ::std::distance(itrBeg, itr); + pAccMenu->appendMenuItem(itr->maText, itr->mbEnabled, nPos); + } +} + +ScDocument* ScMenuFloatingWindow::getDoc() +{ + return mpDoc; +} + void ScMenuFloatingWindow::notify(NotificationType eType) { switch (eType) @@ -608,8 +726,9 @@ void ScMenuFloatingWindow::notify(NotificationType eType) void ScMenuFloatingWindow::resetMenu(bool bSetMenuPos) { - mnSelectedMenu = bSetMenuPos ? 0 : MENU_NOT_SELECTED; resizeToFitMenuItems(); + if (bSetMenuPos) + setSelectedMenuItem(0, false, true); } void ScMenuFloatingWindow::resizeToFitMenuItems() @@ -625,14 +744,15 @@ void ScMenuFloatingWindow::resizeToFitMenuItems() size_t nLastPos = maMenuItems.size()-1; Point aPos; Size aSize; - getMenuItemPosSize(aPos, aSize, nLastPos); + getMenuItemPosSize(nLastPos, aPos, aSize); aPos.X() += nTextWidth + 15; aPos.Y() += aSize.Height() + 5; SetOutputSizePixel(Size(aPos.X(), aPos.Y())); } -void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer) +void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer, bool bNotifyAccessible) { + fprintf(stdout, "ScMenuFloatingWindow::selectMenuItem: pos = %d selected = %d\n", nPos, bSelected); if (nPos >= maMenuItems.size() || nPos == MENU_NOT_SELECTED) { queueCloseSubMenu(); @@ -663,6 +783,64 @@ void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSub queueCloseSubMenu(); } } + + if (bNotifyAccessible && mxAccessible.is()) + { + ScAccessibleFilterMenu* p = static_cast<ScAccessibleFilterMenu*>(mxAccessible.get()); + p->selectMenuItem(nPos, bSelected); + } +} + +void ScMenuFloatingWindow::clearSelectedMenuItem(bool bNotifyAccessible) +{ + selectMenuItem(mnSelectedMenu, false, false, bNotifyAccessible); + + if (bNotifyAccessible && mxAccessible.is()) + { + ScAccessibleFilterMenu* p = static_cast<ScAccessibleFilterMenu*>(mxAccessible.get()); + p->selectMenuItem(mnSelectedMenu, false); + } + + mnSelectedMenu = MENU_NOT_SELECTED; +} + +ScMenuFloatingWindow* ScMenuFloatingWindow::getSubMenuWindow(size_t nPos) const +{ + if (maMenuItems.size() <= nPos) + return NULL; + + return maMenuItems[nPos].mpSubMenuWin.get(); +} + +size_t ScMenuFloatingWindow::getMenuItemCount() const +{ + return maMenuItems.size(); +} + +OUString ScMenuFloatingWindow::getMenuItemName(size_t nPos) const +{ + if (maMenuItems.size() <= nPos) + return ScGlobal::GetEmptyString(); + + return maMenuItems[nPos].maText; +} + +bool ScMenuFloatingWindow::isMenuItemEnabled(size_t nPos) const +{ + if (maMenuItems.size() <= nPos) + return false; + + return maMenuItems[nPos].mbEnabled; +} + +void ScMenuFloatingWindow::setName(const OUString& rName) +{ + maName = rName; +} + +const OUString& ScMenuFloatingWindow::getName() const +{ + return maName; } void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected) @@ -674,7 +852,7 @@ void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected) Point aPos; Size aSize; - getMenuItemPosSize(aPos, aSize, nPos); + getMenuItemPosSize(nPos, aPos, aSize); Region aRegion(Rectangle(aPos,aSize)); if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL)) @@ -717,7 +895,7 @@ void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected) drawMenuItem(nPos); } -void ScMenuFloatingWindow::getMenuItemPosSize(Point& rPos, Size& rSize, size_t nPos) const +void ScMenuFloatingWindow::getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const { const sal_uInt16 nLeftMargin = 5; const sal_uInt16 nTopMargin = 5; @@ -740,7 +918,7 @@ size_t ScMenuFloatingWindow::getEnclosingMenuItem(const Point& rPos) const { Point aPos; Size aSize; - getMenuItemPosSize(aPos, aSize, i); + getMenuItemPosSize(i, aPos, aSize); Rectangle aRect(aPos, aSize); if (aRect.IsInside(rPos)) return i; @@ -776,8 +954,8 @@ void ScDPFieldPopupWindow::CancelButton::Click() // ---------------------------------------------------------------------------- -ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent) : - ScMenuFloatingWindow(pParent), +ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent, ScDocument* pDoc) : + ScMenuFloatingWindow(pParent, pDoc), maChecks(this, 0), maChkToggleAll(this, 0), maBtnSelectSingle (this, 0), @@ -1019,7 +1197,7 @@ void ScDPFieldPopupWindow::MouseMove(const MouseEvent& rMEvt) { ScMenuFloatingWindow::MouseMove(rMEvt); - size_t nSelectedMenu = getSelectedMenuItem(); + size_t nSelectedMenu = getSelectedMenuPos(); if (nSelectedMenu == MENU_NOT_SELECTED) queueCloseSubMenu(); } @@ -1047,6 +1225,23 @@ void ScDPFieldPopupWindow::Paint(const Rectangle& rRect) DrawRect(Rectangle(aPos,aSize)); } +Reference<XAccessible> ScDPFieldPopupWindow::CreateAccessible() +{ + if (!mxAccessible.is()) + { + mxAccessible.set(new ScAccessibleFilterTopWindow( + GetAccessibleParentWindow()->GetAccessible(), this, getName(), getDoc())); + ScAccessibleFilterTopWindow* pAccTop = static_cast<ScAccessibleFilterTopWindow*>(mxAccessible.get()); + Reference<XAccessible> xAccMenu = pAccTop->getAccessibleChildMenu(); + ScAccessibleFilterMenu* pAccMenu = static_cast<ScAccessibleFilterMenu*>(xAccMenu.get()); + fillMenuItemsToAccessible(pAccMenu); + + pAccTop->setAccessibleChildListBox(maChecks.CreateAccessible()); + } + + return mxAccessible; +} + void ScDPFieldPopupWindow::setMemberSize(size_t n) { maMembers.reserve(n); diff --git a/sc/source/ui/inc/AccessibleContextBase.hxx b/sc/source/ui/inc/AccessibleContextBase.hxx index 8d312a0d13d9..c1ff5afcf52f 100644 --- a/sc/source/ui/inc/AccessibleContextBase.hxx +++ b/sc/source/ui/inc/AccessibleContextBase.hxx @@ -319,6 +319,8 @@ protected: /// Use this method to set initial Description without notification void SetDescription(const rtl::OUString& rDesc) { msDescription = rDesc; } + void SetRole(sal_Int16 nRole); + /// Reference to the parent object. ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> mxParent; diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 0074add2be25..72a7dc7a6970 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -44,11 +44,21 @@ #include <memory> #include <hash_map> +namespace com { namespace sun { namespace star { + + namespace accessibility { + class XAccessible; + } + +}}} + class OutputDevice; class Point; class Size; class StyleSettings; class Window; +class ScDocument; +class ScAccessibleFilterMenu; /** * This class takes care of physically drawing field button controls inside @@ -103,7 +113,7 @@ public: virtual void execute() = 0; }; - explicit ScMenuFloatingWindow(Window* pParent); + explicit ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc); virtual ~ScMenuFloatingWindow(); virtual void MouseMove(const MouseEvent& rMEvt); @@ -111,23 +121,42 @@ public: virtual void MouseButtonUp(const MouseEvent& rMEvt); virtual void KeyInput(const KeyEvent& rKEvt); virtual void Paint(const Rectangle& rRect); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible(); void addMenuItem(const ::rtl::OUString& rText, bool bEnabled, Action* pAction); ScMenuFloatingWindow* addSubMenuItem(const ::rtl::OUString& rText, bool bEnabled); + void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer = true, bool bNotifyAccessible = true); + void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer, bool bNotifyAccessible); + void clearSelectedMenuItem(bool bNotifyAccessible); + ScMenuFloatingWindow* getSubMenuWindow(size_t nPos) const; + size_t getMenuItemCount() const; + ::rtl::OUString getMenuItemName(size_t nPos) const; + bool isMenuItemEnabled(size_t nPos) const; + + void setName(const ::rtl::OUString& rName); + const ::rtl::OUString& getName() const; protected: + void drawMenuItem(size_t nPos); void drawAllMenuItems(); const Font& getLabelFont() const; void executeMenu(size_t nPos); - void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer = true); - size_t getSelectedMenuItem() const; + size_t getSelectedMenuPos() const; void queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu); void queueCloseSubMenu(); void launchSubMenu(bool bSetMenuPos); void endSubMenu(); + void fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const; + + ScDocument* getDoc(); + +protected: + ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible > mxAccessible; + private: struct SubMenuItem; void handleMenuTimeout(SubMenuItem* pTimer); @@ -137,15 +166,15 @@ private: void resetMenu(bool bSetMenuPos); void resizeToFitMenuItems(); - void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer); void highlightMenuItem(size_t nPos, bool bSelected); - void getMenuItemPosSize(Point& rPos, Size& rSize, size_t nPos) const; + void getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const; size_t getEnclosingMenuItem(const Point& rPos) const; DECL_LINK( EndPopupHdl, void* ); private: + struct MenuItem { ::rtl::OUString maText; @@ -178,9 +207,16 @@ private: Font maLabelFont; + // Name of this menu window, taken from the menu item of the parent window + // that launches it (if this is a sub menu). If this is a top-level menu + // window, then this name can be anything. + ::rtl::OUString maName; + size_t mnSelectedMenu; size_t mnClickedMenu; + ScDocument* mpDoc; + ScMenuFloatingWindow* mpParentMenu; ScMenuFloatingWindow* mpActiveSubMenu; @@ -202,11 +238,12 @@ public: */ struct ExtendedData {}; - explicit ScDPFieldPopupWindow(Window* pParent); + explicit ScDPFieldPopupWindow(Window* pParent, ScDocument* pDoc); virtual ~ScDPFieldPopupWindow(); virtual void MouseMove(const MouseEvent& rMEvt); virtual void Paint(const Rectangle& rRect); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible(); void setMemberSize(size_t n); void addMember(const ::rtl::OUString& rName, bool bVisible); diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index 8bafb474bff3..5a01a642ac24 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -911,7 +911,8 @@ void ScGridWindow::DPLaunchFieldPopupMenu( const ScDPLabelData& rLabelData = *pDPData->maDPParam.maLabelArray[pDPData->mnDim]; - mpDPFieldPopup.reset(new ScDPFieldPopupWindow(this)); + mpDPFieldPopup.reset(new ScDPFieldPopupWindow(this, pViewData->GetDocument())); + mpDPFieldPopup->setName(OUString::createFromAscii("DataPilot field member popup")); mpDPFieldPopup->setExtendedData(pDPData.release()); mpDPFieldPopup->setOKAction(new DPFieldPopupOKAction(this)); { |