diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-08-20 17:03:13 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-08-23 15:11:27 +0200 |
commit | ec940941e0bd7db15c5cf7d43df82226e0d849dc (patch) | |
tree | a876a500dfa6a32bc8b284b3b07525480ba60765 /sfx2 | |
parent | 1d524bc7a331e8381e88cfd1b6dea4678ad32514 (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.cxx | 44 |
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 ) |