[Libreoffice-commits] core.git: framework/inc framework/source include/sfx2 sfx2/source

Michael Stahl mstahl at redhat.com
Tue Jul 14 02:57:23 PDT 2015


 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 <mstahl at 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()));


More information about the Libreoffice-commits mailing list