summaryrefslogtreecommitdiff
path: root/sfx2
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2019-08-20 17:03:13 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2019-08-23 15:11:27 +0200
commitec940941e0bd7db15c5cf7d43df82226e0d849dc (patch)
treea876a500dfa6a32bc8b284b3b07525480ba60765 /sfx2
parent1d524bc7a331e8381e88cfd1b6dea4678ad32514 (diff)
tdf#119388 add new UNO listener/broadcaster
so that we only need to fire each event to the exact shape that wants it, instead of spamming all the shapes. Takes deleting a column from 20s to 10s for me. Note that none of the broadcasters are calling disposing(EventObject), so I did not make XShapeEventListener extend lang::XEventListener. If a memory leak regression points at this commit, possibly I missed something. Change-Id: I2b8db08247d3e0203d41faf77491368168994e4d Reviewed-on: https://gerrit.libreoffice.org/77857 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'sfx2')
-rw-r--r--sfx2/source/doc/sfxbasemodel.cxx44
1 files changed, 43 insertions, 1 deletions
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 )