diff options
-rw-r--r-- | include/sfx2/sfxbasemodel.hxx | 22 | ||||
-rw-r--r-- | include/svx/AccessibleControlShape.hxx | 3 | ||||
-rw-r--r-- | include/svx/AccessibleShape.hxx | 13 | ||||
-rw-r--r-- | include/svx/AccessibleShapeTreeInfo.hxx | 8 | ||||
-rw-r--r-- | offapi/UnoApi_offapi.mk | 2 | ||||
-rw-r--r-- | offapi/com/sun/star/document/XShapeEventBroadcaster.idl | 55 | ||||
-rw-r--r-- | offapi/com/sun/star/document/XShapeEventListener.idl | 49 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/DrawModelBroadcaster.cxx | 36 | ||||
-rw-r--r-- | sc/source/ui/inc/DrawModelBroadcaster.hxx | 9 | ||||
-rw-r--r-- | sd/source/ui/accessibility/AccessibleDocumentViewBase.cxx | 6 | ||||
-rw-r--r-- | sd/source/ui/accessibility/AccessiblePageShape.cxx | 14 | ||||
-rw-r--r-- | sd/source/ui/inc/AccessiblePageShape.hxx | 5 | ||||
-rw-r--r-- | sfx2/source/doc/sfxbasemodel.cxx | 44 | ||||
-rw-r--r-- | svx/source/accessibility/AccessibleShape.cxx | 57 | ||||
-rw-r--r-- | svx/source/accessibility/AccessibleShapeTreeInfo.cxx | 2 | ||||
-rw-r--r-- | svx/source/accessibility/ChildrenManagerImpl.cxx | 2 | ||||
-rw-r--r-- | sw/source/core/access/accmap.cxx | 46 |
17 files changed, 288 insertions, 85 deletions
diff --git a/include/sfx2/sfxbasemodel.hxx b/include/sfx2/sfxbasemodel.hxx index 9dcba7e68542..92c69b5c3bc9 100644 --- a/include/sfx2/sfxbasemodel.hxx +++ b/include/sfx2/sfxbasemodel.hxx @@ -34,6 +34,7 @@ #include <com/sun/star/document/XUndoManagerSupplier.hpp> #include <com/sun/star/rdf/XDocumentMetadataAccess.hpp> #include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/document/XShapeEventBroadcaster.hpp> #include <com/sun/star/document/XDocumentEventBroadcaster.hpp> #include <com/sun/star/document/XEventsSupplier.hpp> #include <com/sun/star/document/XEmbeddedScripts.hpp> @@ -119,7 +120,7 @@ typedef ::cppu::WeakImplHelper < css::container::XChild , css::rdf::XDocumentMetadataAccess , css::document::XDocumentRecovery , css::document::XUndoManagerSupplier - , css::document::XEventBroadcaster + , css::document::XShapeEventBroadcaster , css::document::XDocumentEventBroadcaster , css::lang::XEventListener , css::document::XEventsSupplier @@ -494,24 +495,33 @@ public: virtual css::uno::Reference< css::document::XEmbeddedScripts > SAL_CALL getScriptContainer() override; - // XEventBroadcaster - + // document::XEventBroadcaster /**___________________________________________________________________________________________________ @descr - registers the given XEventListener. */ - virtual void SAL_CALL addEventListener( const css::uno::Reference< css::document::XEventListener >& xListener ) override; /**___________________________________________________________________________________________________ @descr - unregisters the given XEventListener. */ - virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::document::XEventListener >& xListener ) override; - // XDocumentEventBroadcaster + // document::XShapeEventBroadcaster + + /**___________________________________________________________________________________________________ + @descr - registers the given XEventListener. + */ + virtual void SAL_CALL addShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape, const css::uno::Reference< css::document::XShapeEventListener >& xListener ) override; + /**___________________________________________________________________________________________________ + @descr - unregisters the given XEventListener. + */ + virtual void SAL_CALL removeShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape, const css::uno::Reference< css::document::XShapeEventListener >& xListener ) override; + + + // XDocumentEventBroadcaster virtual void SAL_CALL addDocumentEventListener( const css::uno::Reference< css::document::XDocumentEventListener >& Listener ) override; virtual void SAL_CALL removeDocumentEventListener( const css::uno::Reference< css::document::XDocumentEventListener >& Listener ) override; diff --git a/include/svx/AccessibleControlShape.hxx b/include/svx/AccessibleControlShape.hxx index 2ea2f73dd6d7..9b7ff797f96b 100644 --- a/include/svx/AccessibleControlShape.hxx +++ b/include/svx/AccessibleControlShape.hxx @@ -114,9 +114,6 @@ private: //--- XAccessibleEventListener ---------------------------- virtual void SAL_CALL notifyEvent( const css::accessibility::AccessibleEventObject& aEvent ) override; - //--- document::XEventListener ---------------------------- - using AccessibleShape::notifyEvent; - // XVclContainerListener virtual void SAL_CALL elementInserted( const css::container::ContainerEvent& Event ) override; virtual void SAL_CALL elementRemoved( const css::container::ContainerEvent& Event ) override; diff --git a/include/svx/AccessibleShape.hxx b/include/svx/AccessibleShape.hxx index 7d182e58b4c8..a70f95edc086 100644 --- a/include/svx/AccessibleShape.hxx +++ b/include/svx/AccessibleShape.hxx @@ -29,7 +29,7 @@ #include <com/sun/star/awt/Point.hpp> #include <com/sun/star/awt/Rectangle.hpp> #include <com/sun/star/awt/Size.hpp> -#include <com/sun/star/document/XEventListener.hpp> +#include <com/sun/star/document/XShapeEventListener.hpp> #include <com/sun/star/lang/EventObject.hpp> #include <com/sun/star/uno/Any.hxx> #include <com/sun/star/uno/Reference.hxx> @@ -99,7 +99,7 @@ class SVX_DLLPUBLIC AccessibleShape public css::accessibility::XAccessibleGroupPosition, public css::accessibility::XAccessibleHypertext, public IAccessibleViewForwarderListener, - public css::document::XEventListener, + public css::document::XShapeEventListener, public css::lang::XUnoTunnel { public: @@ -312,18 +312,15 @@ public: //===== IAccessibleViewForwarderListener ================================ virtual void ViewForwarderChanged() override; - //===== lang::XEventListener ============================================ - /** Listen for disposing events of the model. The accessible shape remains functional when this happens. */ - virtual void SAL_CALL - disposing (const css::lang::EventObject& Source) override; + void disposing (const css::lang::EventObject& Source); - //===== document::XEventListener ======================================== + //===== document::XShapeEventListener ======================================== virtual void SAL_CALL - notifyEvent (const css::document::EventObject& rEventObject) override; + notifyShapeEvent (const css::document::EventObject& rEventObject) override; //===== XUnoTunnel ======================================================== diff --git a/include/svx/AccessibleShapeTreeInfo.hxx b/include/svx/AccessibleShapeTreeInfo.hxx index 0b5ddf8fae52..82f98759902f 100644 --- a/include/svx/AccessibleShapeTreeInfo.hxx +++ b/include/svx/AccessibleShapeTreeInfo.hxx @@ -26,7 +26,7 @@ namespace com { namespace sun { namespace star { namespace accessibility { class XAccessibleComponent; } - namespace document { class XEventBroadcaster; } + namespace document { class XShapeEventBroadcaster; } namespace frame { class XController; } } } } @@ -89,7 +89,7 @@ public: reference may be passed to unset the broadcaster */ void SetModelBroadcaster (const css::uno::Reference< - css::document::XEventBroadcaster>& rxModelBroadcaster); + css::document::XShapeEventBroadcaster>& rxModelBroadcaster); /** Return the current model broadcaster. @return @@ -97,7 +97,7 @@ public: been set or has been set to an empty reference. */ const css::uno::Reference< - css::document::XEventBroadcaster>& + css::document::XShapeEventBroadcaster>& GetModelBroadcaster() const { return mxModelBroadcaster;} /** Set the view that will be used to construct SvxTextEditSources which @@ -173,7 +173,7 @@ private: This once was named mxControllerBroadcaster. */ css::uno::Reference< - css::document::XEventBroadcaster> mxModelBroadcaster; + css::document::XShapeEventBroadcaster> mxModelBroadcaster; /** This view is necessary to construct an SvxTextEditSource which in turn is used to create an accessible edit engine. diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index 59d7e16772c8..474fc58160fa 100644 --- a/offapi/UnoApi_offapi.mk +++ b/offapi/UnoApi_offapi.mk @@ -2246,6 +2246,8 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/document,\ XOOXMLDocumentPropertiesImporter \ XRedlinesSupplier \ XScriptInvocationContext \ + XShapeEventBroadcaster \ + XShapeEventListener \ XStorageBasedDocument \ XStorageChangeListener \ XTypeDetection \ diff --git a/offapi/com/sun/star/document/XShapeEventBroadcaster.idl b/offapi/com/sun/star/document/XShapeEventBroadcaster.idl new file mode 100644 index 000000000000..52e49ec8e96b --- /dev/null +++ b/offapi/com/sun/star/document/XShapeEventBroadcaster.idl @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef __com_sun_star_document_XShapeEventBroadcaster_idl__ +#define __com_sun_star_document_XShapeEventBroadcaster_idl__ + +#include <com/sun/star/document/XShapeEventListener.idl> +#include <com/sun/star/drawing/XShape.idl> + + +module com { module sun { module star { module document { + +/** + Used to link a listener to a specific shape + + @since LibreOffice 6.4 + */ +interface XShapeEventBroadcaster : com::sun::star::document::XEventBroadcaster +{ + /** registers the given listener + + @param Listener + listener which is interested on such events + */ + void addShapeEventListener( [in] com::sun::star::drawing::XShape Shape, [in] XShapeEventListener Listener ); + + /** unregisters the given listener + + @param Listener + listener which isn't interested on such events any longer + */ + void removeShapeEventListener( [in] com::sun::star::drawing::XShape Shape, [in] XShapeEventListener Listener ); +}; + + +}; }; }; }; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/offapi/com/sun/star/document/XShapeEventListener.idl b/offapi/com/sun/star/document/XShapeEventListener.idl new file mode 100644 index 000000000000..56634d171845 --- /dev/null +++ b/offapi/com/sun/star/document/XShapeEventListener.idl @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef __com_sun_star_document_XShapeEventListener_idl__ +#define __com_sun_star_document_XShapeEventListener_idl__ + +#include <com/sun/star/document/EventObject.idl> + + +module com { module sun { module star { module document { + +/** makes it possible to register listeners, which are called whenever + a document or document content event occurs + + <p>Such events will be broadcasted by a XShapeEventBroadcaster.</p> + + @since LibreOffice 6.4 + */ +interface XShapeEventListener +{ + /** is called whenever a document event (see EventObject) occurs + + @param Event + specifies the event type + */ + void notifyShapeEvent( [in] EventObject Event ); +}; + + +}; }; }; }; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/Accessibility/DrawModelBroadcaster.cxx b/sc/source/ui/Accessibility/DrawModelBroadcaster.cxx index 4cf1567856c5..5b63c9926baf 100644 --- a/sc/source/ui/Accessibility/DrawModelBroadcaster.cxx +++ b/sc/source/ui/Accessibility/DrawModelBroadcaster.cxx @@ -21,6 +21,7 @@ #include <sal/log.hxx> #include <svx/svdmodel.hxx> #include <svx/unomod.hxx> +#include <svx/svdobj.hxx> #include <tools/diagnose_ex.h> using namespace ::com::sun::star; @@ -49,6 +50,30 @@ void SAL_CALL ScDrawModelBroadcaster::removeEventListener( const uno::Reference< maEventListeners.removeInterface( xListener ); } +void SAL_CALL ScDrawModelBroadcaster::addShapeEventListener( + const css::uno::Reference< css::drawing::XShape >& xShape, + const uno::Reference< document::XShapeEventListener >& xListener ) +{ + osl::MutexGuard aGuard(maListenerMutex); + auto rv = maShapeListeners.emplace(xShape, xListener); + assert(rv.second && "duplicate listener?"); + (void)rv; +} + +void SAL_CALL ScDrawModelBroadcaster::removeShapeEventListener( + const css::uno::Reference< css::drawing::XShape >& xShape, + const uno::Reference< document::XShapeEventListener >& xListener ) +{ + osl::MutexGuard aGuard(maListenerMutex); + auto it = maShapeListeners.find(xShape); + if (it != maShapeListeners.end()) + { + assert(it->second == xListener && "removing wrong listener?"); + (void)xListener; + maShapeListeners.erase(it); + } +} + void ScDrawModelBroadcaster::Notify( SfxBroadcaster&, const SfxHint& rHint ) { @@ -73,6 +98,17 @@ void ScDrawModelBroadcaster::Notify( SfxBroadcaster&, TOOLS_WARN_EXCEPTION("sc.ui", "Runtime exception caught while notifying shape"); } } + + // right now, we're only handling the specific event necessary to fix this performance problem + if (pSdrHint->GetKind() == SdrHintKind::ObjectChange) + { + auto pSdrObject = const_cast<SdrObject*>(pSdrHint->GetObject()); + uno::Reference<drawing::XShape> xShape(pSdrObject->getUnoShape(), uno::UNO_QUERY); + osl::MutexGuard aGuard(maListenerMutex); + auto it = maShapeListeners.find(xShape); + if (it != maShapeListeners.end()) + it->second->notifyShapeEvent(aEvent); + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/inc/DrawModelBroadcaster.hxx b/sc/source/ui/inc/DrawModelBroadcaster.hxx index 6a967a075075..0d5966b864fa 100644 --- a/sc/source/ui/inc/DrawModelBroadcaster.hxx +++ b/sc/source/ui/inc/DrawModelBroadcaster.hxx @@ -24,14 +24,17 @@ #include <comphelper/interfacecontainer3.hxx> #include <cppuhelper/implbase.hxx> #include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/document/XShapeEventBroadcaster.hpp> +#include <unordered_map> class SdrModel; class ScDrawModelBroadcaster : public SfxListener, - public ::cppu::WeakImplHelper< css::document::XEventBroadcaster > + public ::cppu::WeakImplHelper< css::document::XShapeEventBroadcaster > { mutable ::osl::Mutex maListenerMutex; ::comphelper::OInterfaceContainerHelper3<css::document::XEventListener> maEventListeners; + std::unordered_map<css::uno::Reference< css::drawing::XShape >, css::uno::Reference< css::document::XShapeEventListener >> maShapeListeners; SdrModel *mpDrawModel; public: @@ -39,8 +42,12 @@ public: ScDrawModelBroadcaster( SdrModel *pDrawModel ); virtual ~ScDrawModelBroadcaster() override; + // css::document::XEventBroadcaster virtual void SAL_CALL addEventListener( const css::uno::Reference< css::document::XEventListener >& xListener ) override; virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::document::XEventListener >& xListener ) override; + // css::document::XShapeEventBroadcaster + virtual void SAL_CALL addShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape, const css::uno::Reference< css::document::XShapeEventListener >& xListener ) override; + virtual void SAL_CALL removeShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape, const css::uno::Reference< css::document::XShapeEventListener >& xListener ) override; virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override; }; diff --git a/sd/source/ui/accessibility/AccessibleDocumentViewBase.cxx b/sd/source/ui/accessibility/AccessibleDocumentViewBase.cxx index 1d2d1016b594..fe808039929e 100644 --- a/sd/source/ui/accessibility/AccessibleDocumentViewBase.cxx +++ b/sd/source/ui/accessibility/AccessibleDocumentViewBase.cxx @@ -20,7 +20,7 @@ #include <AccessibleDocumentViewBase.hxx> #include <com/sun/star/drawing/XDrawView.hpp> #include <com/sun/star/frame/XController.hpp> -#include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/document/XShapeEventBroadcaster.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/accessibility/AccessibleEventId.hpp> #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> @@ -76,8 +76,8 @@ AccessibleDocumentViewBase::AccessibleDocumentViewBase ( // Fill the shape tree info. maShapeTreeInfo.SetModelBroadcaster ( - uno::Reference<document::XEventBroadcaster>( - mxModel, uno::UNO_QUERY)); + uno::Reference<document::XShapeEventBroadcaster>( + mxModel, uno::UNO_QUERY_THROW)); maShapeTreeInfo.SetController (mxController); maShapeTreeInfo.SetSdrView (pViewShell->GetView()); maShapeTreeInfo.SetDevice (pSdWindow); diff --git a/sd/source/ui/accessibility/AccessiblePageShape.cxx b/sd/source/ui/accessibility/AccessiblePageShape.cxx index 5e22d74c1c00..6390ce18e3b5 100644 --- a/sd/source/ui/accessibility/AccessiblePageShape.cxx +++ b/sd/source/ui/accessibility/AccessiblePageShape.cxx @@ -216,24 +216,10 @@ css::uno::Sequence< OUString> SAL_CALL return AccessibleShape::getSupportedServiceNames(); } -//===== lang::XEventListener ================================================ - -void SAL_CALL - AccessiblePageShape::disposing (const css::lang::EventObject& aEvent) -{ - ThrowIfDisposed (); - AccessibleShape::disposing (aEvent); -} - //===== XComponent ========================================================== void AccessiblePageShape::dispose() { - // Unregister listeners. - Reference<lang::XComponent> xComponent (mxShape, uno::UNO_QUERY); - if (xComponent.is()) - xComponent->removeEventListener (this); - // Cleanup. mxShape = nullptr; diff --git a/sd/source/ui/inc/AccessiblePageShape.hxx b/sd/source/ui/inc/AccessiblePageShape.hxx index 71cc0a769be8..ced504f020d3 100644 --- a/sd/source/ui/inc/AccessiblePageShape.hxx +++ b/sd/source/ui/inc/AccessiblePageShape.hxx @@ -95,11 +95,6 @@ public: virtual css::uno::Sequence< OUString> SAL_CALL getSupportedServiceNames() override; - //===== lang::XEventListener ============================================ - - virtual void SAL_CALL - disposing (const css::lang::EventObject& Source) override; - using AccessibleShape::disposing; protected: diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index 5c61dfb047fa..19cfb2dd49f3 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -198,6 +198,8 @@ struct IMPL_SfxBaseModel_DataContainer : public ::sfx2::IModifiableDocument OUString m_sRuntimeUID ; OUString m_aPreusedFilterName ; ::cppu::OMultiTypeInterfaceContainerHelper m_aInterfaceContainer ; + std::unordered_map<css::uno::Reference< css::drawing::XShape >, + css::uno::Reference< css::document::XShapeEventListener >> maShapeListeners; Reference< XInterface > m_xParent ; Reference< frame::XController > m_xCurrent ; Reference< document::XDocumentProperties > m_xDocumentProperties ; @@ -2370,6 +2372,33 @@ void SAL_CALL SfxBaseModel::removeEventListener( const Reference< document::XEve m_pData->m_aInterfaceContainer.removeInterface( cppu::UnoType<document::XEventListener>::get(), aListener ); } +// XShapeEventBroadcaster + +void SAL_CALL SfxBaseModel::addShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape, const Reference< document::XShapeEventListener >& xListener ) +{ + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); + + auto rv = m_pData->maShapeListeners.emplace(xShape, xListener); + assert(rv.second && "duplicate listener?"); + (void)rv; +} + + +// XShapeEventBroadcaster + + +void SAL_CALL SfxBaseModel::removeShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape, const Reference< document::XShapeEventListener >& xListener ) +{ + SfxModelGuard aGuard( *this ); + + auto it = m_pData->maShapeListeners.find(xShape); + if (it != m_pData->maShapeListeners.end()) + { + assert(it->second == xListener && "removing wrong listener?"); + (void)xListener; + m_pData->maShapeListeners.erase(it); + } +} // XDocumentEventBroadcaster @@ -3219,12 +3248,25 @@ void SfxBaseModel::notifyEvent( const document::EventObject& aEvent ) const aIt.remove(); } } + // for right now, we're only doing the event that this particular performance problem needed + if (aEvent.EventName == "ShapeModified") + { + uno::Reference<drawing::XShape> xShape(aEvent.Source, uno::UNO_QUERY); + if (xShape.is()) + { + auto it = m_pData->maShapeListeners.find(xShape); + if (it != m_pData->maShapeListeners.end()) + it->second->notifyShapeEvent(aEvent); + } + } } /** returns true if someone added a XEventListener to this XEventBroadcaster */ bool SfxBaseModel::hasEventListeners() const { - return !impl_isDisposed() && (nullptr != m_pData->m_aInterfaceContainer.getContainer( cppu::UnoType<document::XEventListener>::get()) ); + return !impl_isDisposed() + && ( (nullptr != m_pData->m_aInterfaceContainer.getContainer( cppu::UnoType<document::XEventListener>::get()) ) + || !m_pData->maShapeListeners.empty()); } void SAL_CALL SfxBaseModel::addPrintJobListener( const Reference< view::XPrintJobListener >& xListener ) diff --git a/svx/source/accessibility/AccessibleShape.cxx b/svx/source/accessibility/AccessibleShape.cxx index 779ad7b4fba3..e9966e3c63ef 100644 --- a/svx/source/accessibility/AccessibleShape.cxx +++ b/svx/source/accessibility/AccessibleShape.cxx @@ -30,7 +30,7 @@ #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/document/XEventBroadcaster.hpp> +#include <com/sun/star/document/XShapeEventBroadcaster.hpp> #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> #include <com/sun/star/drawing/FillStyle.hpp> #include <com/sun/star/text/XText.hpp> @@ -141,8 +141,8 @@ void AccessibleShape::Init() // Register at model as document::XEventListener. if (maShapeTreeInfo.GetModelBroadcaster().is()) - maShapeTreeInfo.GetModelBroadcaster()->addEventListener ( - static_cast<document::XEventListener*>(this)); + maShapeTreeInfo.GetModelBroadcaster()->addShapeEventListener(mxShape, + static_cast<document::XShapeEventListener*>(this)); // Beware! Here we leave the paths of the UNO API and descend into the // depths of the core. Necessary for making the edit engine @@ -750,8 +750,7 @@ css::uno::Any SAL_CALL static_cast<XAccessibleExtendedComponent*>(this), static_cast< css::accessibility::XAccessibleSelection* >(this), static_cast< css::accessibility::XAccessibleExtendedAttributes* >(this), - static_cast<lang::XEventListener*>(this), - static_cast<document::XEventListener*>(this), + static_cast<document::XShapeEventListener*>(this), static_cast<lang::XUnoTunnel*>(this), static_cast<XAccessibleGroupPosition*>(this), static_cast<XAccessibleHypertext*>(this) @@ -937,8 +936,7 @@ uno::Sequence<uno::Type> SAL_CALL reference to the model in the shape tree info. Otherwise this object remains functional. */ -void SAL_CALL - AccessibleShape::disposing (const lang::EventObject& aEvent) +void AccessibleShape::disposing (const lang::EventObject& aEvent) { SolarMutexGuard aSolarGuard; ::osl::MutexGuard aGuard (maMutex); @@ -959,33 +957,27 @@ void SAL_CALL } } -// document::XEventListener +// document::XShapeEventListener void SAL_CALL - AccessibleShape::notifyEvent (const document::EventObject& rEventObject) + AccessibleShape::notifyShapeEvent (const document::EventObject& rEventObject) { - // First check if the event is for us. - uno::Reference<drawing::XShape> xShape ( - rEventObject.Source, uno::UNO_QUERY); - if ( xShape.get() == mxShape.get() ) + if (rEventObject.EventName == "ShapeModified") { - if (rEventObject.EventName == "ShapeModified") - { - //Need to update text children when receiving ShapeModified hint when exiting edit mode for text box - if (mpText) - mpText->UpdateChildren(); + //Need to update text children when receiving ShapeModified hint when exiting edit mode for text box + if (mpText) + mpText->UpdateChildren(); - // Some property of a shape has been modified. Send an event - // that indicates a change of the visible data to all listeners. - CommitChange ( - AccessibleEventId::VISIBLE_DATA_CHANGED, - uno::Any(), - uno::Any()); + // Some property of a shape has been modified. Send an event + // that indicates a change of the visible data to all listeners. + CommitChange ( + AccessibleEventId::VISIBLE_DATA_CHANGED, + uno::Any(), + uno::Any()); - // Name and Description may have changed. Update the local - // values accordingly. - UpdateNameAndDescription(); - } + // Name and Description may have changed. Update the local + // values accordingly. + UpdateNameAndDescription(); } } @@ -1071,15 +1063,10 @@ void AccessibleShape::disposing() if (pStateSet != nullptr) pStateSet->RemoveState (AccessibleStateType::FOCUSED); - // Unregister from broadcasters. - Reference<lang::XComponent> xComponent (mxShape, uno::UNO_QUERY); - if (xComponent.is()) - xComponent->removeEventListener (this); - // Unregister from model. if (maShapeTreeInfo.GetModelBroadcaster().is()) - maShapeTreeInfo.GetModelBroadcaster()->removeEventListener ( - static_cast<document::XEventListener*>(this)); + maShapeTreeInfo.GetModelBroadcaster()->removeShapeEventListener(mxShape, + static_cast<document::XShapeEventListener*>(this)); // Release the child containers. if (mpChildrenManager != nullptr) diff --git a/svx/source/accessibility/AccessibleShapeTreeInfo.cxx b/svx/source/accessibility/AccessibleShapeTreeInfo.cxx index 88d24ac1d86f..edc7ef8a9641 100644 --- a/svx/source/accessibility/AccessibleShapeTreeInfo.cxx +++ b/svx/source/accessibility/AccessibleShapeTreeInfo.cxx @@ -86,7 +86,7 @@ void AccessibleShapeTreeInfo::SetDocumentWindow ( } void AccessibleShapeTreeInfo::SetModelBroadcaster ( - const Reference<document::XEventBroadcaster>& rxModelBroadcaster) + const Reference<document::XShapeEventBroadcaster>& rxModelBroadcaster) { mxModelBroadcaster = rxModelBroadcaster; } diff --git a/svx/source/accessibility/ChildrenManagerImpl.cxx b/svx/source/accessibility/ChildrenManagerImpl.cxx index e08a5c2b0a6e..2c0b953dc459 100644 --- a/svx/source/accessibility/ChildrenManagerImpl.cxx +++ b/svx/source/accessibility/ChildrenManagerImpl.cxx @@ -31,7 +31,7 @@ #include <com/sun/star/accessibility/AccessibleStateType.hpp> #include <com/sun/star/accessibility/AccessibleEventId.hpp> #include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/document/XShapeEventBroadcaster.hpp> #include <com/sun/star/frame/XController.hpp> #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> #include <com/sun/star/view/XSelectionSupplier.hpp> diff --git a/sw/source/core/access/accmap.cxx b/sw/source/core/access/accmap.cxx index cb5709c54901..b5f2c615961b 100644 --- a/sw/source/core/access/accmap.cxx +++ b/sw/source/core/access/accmap.cxx @@ -62,7 +62,7 @@ #include <com/sun/star/accessibility/AccessibleStateType.hpp> #include <com/sun/star/accessibility/AccessibleRole.hpp> #include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/document/XShapeEventBroadcaster.hpp> #include <cppuhelper/implbase.hxx> #include <comphelper/interfacecontainer2.hxx> #include <pagepreviewlayout.hxx> @@ -126,10 +126,11 @@ public: }; class SwDrawModellListener_Impl : public SfxListener, - public ::cppu::WeakImplHelper< document::XEventBroadcaster > + public ::cppu::WeakImplHelper< document::XShapeEventBroadcaster > { mutable ::osl::Mutex maListenerMutex; ::comphelper::OInterfaceContainerHelper2 maEventListeners; + std::unordered_map<css::uno::Reference< css::drawing::XShape >, css::uno::Reference< css::document::XShapeEventListener >> maShapeListeners; SdrModel *mpDrawModel; protected: virtual ~SwDrawModellListener_Impl() override; @@ -137,8 +138,12 @@ protected: public: explicit SwDrawModellListener_Impl( SdrModel *pDrawModel ); + // css::document::XEventBroadcaster virtual void SAL_CALL addEventListener( const uno::Reference< document::XEventListener >& xListener ) override; virtual void SAL_CALL removeEventListener( const uno::Reference< document::XEventListener >& xListener ) override; + // css::document::XShapeEventBroadcaster + virtual void SAL_CALL addShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape, const css::uno::Reference< css::document::XShapeEventListener >& xListener ) override; + virtual void SAL_CALL removeShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape, const css::uno::Reference< css::document::XShapeEventListener >& xListener ) override; virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override; void Dispose(); @@ -166,6 +171,30 @@ void SAL_CALL SwDrawModellListener_Impl::removeEventListener( const uno::Referen maEventListeners.removeInterface( xListener ); } +void SAL_CALL SwDrawModellListener_Impl::addShapeEventListener( + const css::uno::Reference< css::drawing::XShape >& xShape, + const uno::Reference< document::XShapeEventListener >& xListener ) +{ + osl::MutexGuard aGuard(maListenerMutex); + auto rv = maShapeListeners.emplace(xShape, xListener); + assert(rv.second && "duplicate listener?"); + (void)rv; +} + +void SAL_CALL SwDrawModellListener_Impl::removeShapeEventListener( + const css::uno::Reference< css::drawing::XShape >& xShape, + const uno::Reference< document::XShapeEventListener >& xListener ) +{ + osl::MutexGuard aGuard(maListenerMutex); + auto it = maShapeListeners.find(xShape); + if (it != maShapeListeners.end()) + { + assert(it->second == xListener); + (void)xListener; + maShapeListeners.erase(it); + } +} + void SwDrawModellListener_Impl::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) { @@ -204,6 +233,17 @@ void SwDrawModellListener_Impl::Notify( SfxBroadcaster& /*rBC*/, TOOLS_WARN_EXCEPTION("sw.a11y", "Runtime exception caught while notifying shape"); } } + + // right now, we're only handling the specific event necessary to fix this performance problem + if (pSdrHint->GetKind() == SdrHintKind::ObjectChange) + { + auto pSdrObject = const_cast<SdrObject*>(pSdrHint->GetObject()); + uno::Reference<drawing::XShape> xShape(pSdrObject->getUnoShape(), uno::UNO_QUERY); + osl::MutexGuard aGuard(maListenerMutex); + auto it = maShapeListeners.find(xShape); + if (it != maShapeListeners.end()) + it->second->notifyShapeEvent(aEvent); + } } void SwDrawModellListener_Impl::Dispose() @@ -247,7 +287,7 @@ public: maInfo.SetSdrView( pMap->GetShell()->GetDrawView() ); maInfo.SetDevice( pMap->GetShell()->GetWin() ); maInfo.SetViewForwarder( pMap ); - uno::Reference < document::XEventBroadcaster > xModelBroadcaster = + uno::Reference < document::XShapeEventBroadcaster > xModelBroadcaster = new SwDrawModellListener_Impl( pMap->GetShell()->getIDocumentDrawModelAccess().GetOrCreateDrawModel() ); maInfo.SetModelBroadcaster( xModelBroadcaster ); |