framework/inc/helper/mischelper.hxx | 12 +++ framework/source/fwe/classes/sfxhelperfunctions.cxx | 10 ++ framework/source/fwi/helper/mischelper.cxx | 15 +++ framework/source/services/ContextChangeEventMultiplexer.cxx | 47 +++++++++++- include/sfx2/sidebar/SidebarController.hxx | 9 -- sfx2/source/sidebar/SidebarController.cxx | 27 +----- 6 files changed, 90 insertions(+), 30 deletions(-)
New commits: commit 9be8c4f21200aeec5b334d9536b3b7a0b72c24fa Author: Michael Stahl <mst...@redhat.com> Date: Mon Jul 13 18:54:17 2015 +0200 sfx2: remove the global SidebarController::maSidebarControllerContainer This global was crashing on exit, unsurprising as it contains UNO services that reference VCL objects. It turns out that there is already a UNO singleton framework::ContextChangeEventMultiplexer that effectively contains this mapping already, so try to hook that up without creating a public API of it, which is made quite a bit harder by framework's inexplicable multitude of libraries. Change-Id: I4baf67b42c630191fa8879d650eeb62520c331a5 diff --git a/framework/inc/helper/mischelper.hxx b/framework/inc/helper/mischelper.hxx index 6aa0015..7f45aa6 100644 --- a/framework/inc/helper/mischelper.hxx +++ b/framework/inc/helper/mischelper.hxx @@ -28,6 +28,7 @@ #include <com/sun/star/container/XContainerListener.hpp> #include <com/sun/star/frame/XFrame.hpp> #include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/ui/XContextChangeEventListener.hpp> #include <cppuhelper/implbase1.hxx> @@ -36,6 +37,7 @@ #include <rtl/ustring.hxx> #include <fwidllapi.h> +#include <functional> #include <set> namespace framework @@ -304,6 +306,16 @@ class WeakDocumentEventListener : public ::cppu::WeakImplHelper1<com::sun::star: } }; +FWI_DLLPUBLIC css::uno::Reference<css::ui::XContextChangeEventListener> +GetFirstListenerWith_Impl( + css::uno::Reference<css::uno::XInterface> const& xEventFocus, + std::function<bool (css::uno::Reference<css::ui::XContextChangeEventListener> const&)> const& rPredicate); + +FWI_DLLPUBLIC extern auto (*g_pGetMultiplexerListener)( + css::uno::Reference<css::uno::XInterface> const&, + std::function<bool (css::uno::Reference<css::ui::XContextChangeEventListener> const&)> const&) + -> css::uno::Reference<css::ui::XContextChangeEventListener>; + } // namespace framework #endif // INCLUDED_FRAMEWORK_INC_HELPER_MISCHELPER_HXX diff --git a/framework/source/fwe/classes/sfxhelperfunctions.cxx b/framework/source/fwe/classes/sfxhelperfunctions.cxx index a1f0826..c04105c 100644 --- a/framework/source/fwe/classes/sfxhelperfunctions.cxx +++ b/framework/source/fwe/classes/sfxhelperfunctions.cxx @@ -18,6 +18,8 @@ */ #include <framework/sfxhelperfunctions.hxx> +#include <framework/ContextChangeEventMultiplexerTunnel.hxx> +#include <helper/mischelper.hxx> #include <tools/diagnose_ex.h> @@ -163,6 +165,14 @@ void SAL_CALL ActivateToolPanel( const ::com::sun::star::uno::Reference< ::com:: (*pActivator)( i_rFrame, i_rPanelURL ); } +using namespace ::com::sun::star; +uno::Reference<ui::XContextChangeEventListener> GetFirstListenerWith( + uno::Reference<uno::XInterface> const& xEventFocus, + std::function<bool (uno::Reference<ui::XContextChangeEventListener> const&)> const& rPredicate) +{ + return GetFirstListenerWith_Impl(xEventFocus, rPredicate); +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/fwi/helper/mischelper.cxx b/framework/source/fwi/helper/mischelper.cxx index 5b1e15f..06cc061 100644 --- a/framework/source/fwi/helper/mischelper.cxx +++ b/framework/source/fwi/helper/mischelper.cxx @@ -212,6 +212,21 @@ void FillLangItems( std::set< OUString > &rLangItems, } } +auto (*g_pGetMultiplexerListener)( + uno::Reference<uno::XInterface> const&, + std::function<bool (uno::Reference<ui::XContextChangeEventListener> const&)> const&) + -> uno::Reference<ui::XContextChangeEventListener> = nullptr; + +uno::Reference<ui::XContextChangeEventListener> +GetFirstListenerWith_Impl( + uno::Reference<uno::XInterface> const& xEventFocus, + std::function<bool (uno::Reference<ui::XContextChangeEventListener> const&)> const& rPredicate) +{ + assert(g_pGetMultiplexerListener != nullptr); // should not be called too early, nor too late + return g_pGetMultiplexerListener(xEventFocus, rPredicate); +} + + } // namespace framework /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/services/ContextChangeEventMultiplexer.cxx b/framework/source/services/ContextChangeEventMultiplexer.cxx index 6fe88ee..d672704 100644 --- a/framework/source/services/ContextChangeEventMultiplexer.cxx +++ b/framework/source/services/ContextChangeEventMultiplexer.cxx @@ -17,6 +17,8 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <helper/mischelper.hxx> + #include <com/sun/star/lang/XComponent.hpp> #include <com/sun/star/lang/XEventListener.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> @@ -88,7 +90,6 @@ public: const css::lang::EventObject& rEvent) throw (cssu::RuntimeException, std::exception) SAL_OVERRIDE; -private: typedef ::std::vector<cssu::Reference<css::ui::XContextChangeEventListener> > ListenerContainer; class FocusDescriptor { @@ -362,6 +363,50 @@ struct Singleton: } +namespace framework { + +// right now we assume there's one matching listener +uno::Reference<ui::XContextChangeEventListener> GetFirstListenerWith_ImplImpl( + uno::Reference<uno::XInterface> const& xEventFocus, + std::function<bool (uno::Reference<ui::XContextChangeEventListener> const&)> const& rPredicate) +{ + assert(xEventFocus.is()); // in current usage it's a bug if the XController is null here + uno::Reference<ui::XContextChangeEventListener> xRet; + + ContextChangeEventMultiplexer *const pMultiplexer( + dynamic_cast<ContextChangeEventMultiplexer *>(Singleton::get().instance.get())); + assert(pMultiplexer); + + ContextChangeEventMultiplexer::FocusDescriptor const*const pFocusDescriptor( + pMultiplexer->GetFocusDescriptor(xEventFocus, false)); + if (!pFocusDescriptor) + return xRet; + + for (auto & xListener : pFocusDescriptor->maListeners) + { + if (rPredicate(xListener)) + { + assert(!xRet.is()); // generalize this if it is used for more than 1:1 mapping? + xRet = xListener; + } + } + return xRet; +} + +namespace { + +struct Hook +{ + Hook() { g_pGetMultiplexerListener = &GetFirstListenerWith_ImplImpl; } + ~Hook() { g_pGetMultiplexerListener = nullptr; } +}; + +static Hook g_hook; + +} + +} + extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL org_apache_openoffice_comp_framework_ContextChangeEventMultiplexer_get_implementation( css::uno::XComponentContext *, diff --git a/include/sfx2/sidebar/SidebarController.hxx b/include/sfx2/sidebar/SidebarController.hxx index 063a156..db0a9a1 100644 --- a/include/sfx2/sidebar/SidebarController.hxx +++ b/include/sfx2/sidebar/SidebarController.hxx @@ -21,8 +21,6 @@ #include <sal/config.h> -#include <map> - #include <sfx2/sidebar/AsynchronousCall.hxx> #include <sfx2/sidebar/Context.hxx> #include <sfx2/sidebar/FocusManager.hxx> @@ -43,8 +41,6 @@ #include <boost/optional.hpp> #include <cppuhelper/compbase4.hxx> #include <cppuhelper/basemutex.hxx> -#include <cppuhelper/weakref.hxx> - namespace @@ -161,11 +157,6 @@ public: void notifyDeckTitle(const OUString& targetDeckId); private: - typedef ::std::map< - const css::uno::Reference<css::frame::XController>, - css::uno::WeakReference<SidebarController> - > SidebarControllerContainer; - static SidebarControllerContainer maSidebarControllerContainer; VclPtr<Deck> mpCurrentDeck; VclPtr<SidebarDockingWindow> mpParentWindow; diff --git a/sfx2/source/sidebar/SidebarController.cxx b/sfx2/source/sidebar/SidebarController.cxx index 403a40b..3831023 100644 --- a/sfx2/source/sidebar/SidebarController.cxx +++ b/sfx2/source/sidebar/SidebarController.cxx @@ -35,6 +35,7 @@ #include <sfx2/sfxsids.hrc> #include <sfx2/titledockwin.hxx> #include "sfxlocal.hrc" +#include <framework/ContextChangeEventMultiplexerTunnel.hxx> #include <vcl/floatwin.hxx> #include <vcl/fixed.hxx> #include "splitwin.hxx" @@ -71,8 +72,6 @@ namespace namespace sfx2 { namespace sidebar { -SidebarController::SidebarControllerContainer SidebarController::maSidebarControllerContainer; - namespace { enum MenuId { @@ -150,15 +149,13 @@ SidebarController::~SidebarController() SidebarController* SidebarController::GetSidebarControllerForFrame ( const css::uno::Reference<css::frame::XFrame>& rxFrame) { - SidebarControllerContainer::iterator iEntry (maSidebarControllerContainer.find(rxFrame->getController())); - if (iEntry == maSidebarControllerContainer.end()) - return NULL; - - css::uno::Reference<XInterface> xController (iEntry->second.get()); - if ( ! xController.is()) - return NULL; + uno::Reference<ui::XContextChangeEventListener> const xListener( + framework::GetFirstListenerWith(rxFrame->getController(), + [] (uno::Reference<uno::XInterface> const& xRef) + { return nullptr != dynamic_cast<SidebarController*>(xRef.get()); } + )); - return dynamic_cast<SidebarController*>(xController.get()); + return dynamic_cast<SidebarController*>(xListener.get()); } void SidebarController::registerSidebarForFrame(SidebarController* pController, css::uno::Reference<css::frame::XController> xController) @@ -171,20 +168,10 @@ void SidebarController::registerSidebarForFrame(SidebarController* pController, xMultiplexer->addContextChangeEventListener( static_cast<css::ui::XContextChangeEventListener*>(pController), xController); - - WeakReference<SidebarController> xWeakController (pController); - maSidebarControllerContainer.insert( - SidebarControllerContainer::value_type( - xController, - xWeakController)); } void SidebarController::unregisterSidebarForFrame(SidebarController* pController, css::uno::Reference<css::frame::XController> xController) { - SidebarControllerContainer::iterator iEntry (maSidebarControllerContainer.find(xController)); - if (iEntry != maSidebarControllerContainer.end()) - maSidebarControllerContainer.erase(iEntry); - css::uno::Reference<css::ui::XContextChangeEventMultiplexer> xMultiplexer ( css::ui::ContextChangeEventMultiplexer::get( ::comphelper::getProcessComponentContext())); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits