summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sfx2/sfxbasemodel.hxx22
-rw-r--r--include/svx/AccessibleControlShape.hxx3
-rw-r--r--include/svx/AccessibleShape.hxx13
-rw-r--r--include/svx/AccessibleShapeTreeInfo.hxx8
-rw-r--r--offapi/UnoApi_offapi.mk2
-rw-r--r--offapi/com/sun/star/document/XShapeEventBroadcaster.idl55
-rw-r--r--offapi/com/sun/star/document/XShapeEventListener.idl49
-rw-r--r--sc/source/ui/Accessibility/DrawModelBroadcaster.cxx36
-rw-r--r--sc/source/ui/inc/DrawModelBroadcaster.hxx9
-rw-r--r--sd/source/ui/accessibility/AccessibleDocumentViewBase.cxx6
-rw-r--r--sd/source/ui/accessibility/AccessiblePageShape.cxx14
-rw-r--r--sd/source/ui/inc/AccessiblePageShape.hxx5
-rw-r--r--sfx2/source/doc/sfxbasemodel.cxx44
-rw-r--r--svx/source/accessibility/AccessibleShape.cxx57
-rw-r--r--svx/source/accessibility/AccessibleShapeTreeInfo.cxx2
-rw-r--r--svx/source/accessibility/ChildrenManagerImpl.cxx2
-rw-r--r--sw/source/core/access/accmap.cxx46
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 );