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

Markus Mohrhard markus.mohrhard at googlemail.com
Sun Jul 2 02:42:35 UTC 2017


 framework/inc/services/desktop.hxx    |    9 ++++++
 framework/source/services/desktop.cxx |   44 ++++++++++++++++++++++++++++++++++
 include/svtools/transfer.hxx          |    8 +++++-
 svtools/source/misc/transfer.cxx      |   15 +++++++++++
 4 files changed, 75 insertions(+), 1 deletion(-)

New commits:
commit 7250bc4721b334714bb0fa1345211c83330f94b2
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Fri Jun 30 23:23:36 2017 +0200

    notify the clipboard terminate listener before any other terminate listener
    
    Otherwise we may have destroyed a service that is needed to generate
    one of the clipboard formats requested by the system clipboard.
    
    Change-Id: Id05de3ac569e3ed38cd97efc4c48326bc6a8db0b
    Reviewed-on: https://gerrit.libreoffice.org/39429
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/framework/inc/services/desktop.hxx b/framework/inc/services/desktop.hxx
index 2b07a2487d97..a77c816e9d2a 100644
--- a/framework/inc/services/desktop.hxx
+++ b/framework/inc/services/desktop.hxx
@@ -341,6 +341,15 @@ class Desktop : private cppu::BaseMutex,
          */
         void impl_sendCancelTerminationEvent(const TTerminateListenerList& lCalledListener);
 
+        /** calls notifyTermination() on the clipboard listener
+         *
+         * The system clipboard may decide that it wants copies
+         * in several formats of the clipboard content requiring
+         * nearly all the services
+         *
+         */
+        void impl_sendTerminateToClipboard();
+
         /** calls notifyTermination() on every registered termination listener.
          *
          *  Note: Only normal termination listener (registered in list m_aListenerContainer
diff --git a/framework/source/services/desktop.cxx b/framework/source/services/desktop.cxx
index 7c3c2e4b80d1..e96224815441 100644
--- a/framework/source/services/desktop.cxx
+++ b/framework/source/services/desktop.cxx
@@ -324,6 +324,10 @@ sal_Bool SAL_CALL Desktop::terminate()
         aWriteLock.clear();
         /* UNSAFE AREA ------------------------------------------------------------------------------------- */
 
+        // The clipboard listener needs to be the first. It can create copies of the
+        // existing document which needs basically all the available infrastructure.
+        impl_sendTerminateToClipboard();
+
         impl_sendNotifyTerminationEvent();
         {
             SolarMutexGuard aGuard;
@@ -1630,6 +1634,46 @@ void Desktop::impl_sendCancelTerminationEvent(const Desktop::TTerminateListenerL
     }
 }
 
+void Desktop::impl_sendTerminateToClipboard()
+{
+    TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
+
+    ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( cppu::UnoType<css::frame::XTerminateListener>::get());
+    if ( ! pContainer )
+        return;
+
+    ::cppu::OInterfaceIteratorHelper aIterator( *pContainer );
+    while ( aIterator.hasMoreElements() )
+    {
+        try
+        {
+            css::uno::Reference< css::lang::XServiceInfo > xInfo( aIterator.next(), css::uno::UNO_QUERY );
+            if ( !xInfo.is() )
+                continue;
+
+            if ( xInfo->getImplementationName() != "com.sun.star.comp.svt.TransferableHelperTerminateListener" )
+                continue;
+
+            css::uno::Reference< css::frame::XTerminateListener > xListener(xInfo, css::uno::UNO_QUERY);
+            if ( ! xListener.is() )
+                continue;
+
+            css::lang::EventObject aEvent( static_cast< ::cppu::OWeakObject* >(this) );
+            xListener->notifyTermination( aEvent );
+
+            // don't notify twice
+            aIterator.remove();
+        }
+        catch( const css::uno::Exception& )
+        {
+            // clean up container.
+            // E.g. dead remote listener objects can make trouble otherwise.
+            // Iterator implementation allows removing objects during it's used !
+            aIterator.remove();
+        }
+    }
+}
+
 void Desktop::impl_sendNotifyTerminationEvent()
 {
     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
diff --git a/include/svtools/transfer.hxx b/include/svtools/transfer.hxx
index bc3c6eceacab..f499a2a1fce4 100644
--- a/include/svtools/transfer.hxx
+++ b/include/svtools/transfer.hxx
@@ -29,6 +29,7 @@
 #include <sot/exchange.hxx>
 #include <cppuhelper/implbase.hxx>
 #include <com/sun/star/frame/XTerminateListener.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/lang/XUnoTunnel.hpp>
 #include <com/sun/star/datatransfer/XTransferable2.hpp>
 #include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp>
@@ -127,7 +128,7 @@ class SVT_DLLPUBLIC TransferableHelper : public cppu::WeakImplHelper< css::datat
 private:
 
     // nested class to implement the XTerminateListener interface
-    class TerminateListener : public cppu::WeakImplHelper< css::frame::XTerminateListener >
+    class TerminateListener : public cppu::WeakImplHelper< css::frame::XTerminateListener, css::lang::XServiceInfo >
     {
     private:
 
@@ -142,6 +143,11 @@ private:
         virtual void SAL_CALL queryTermination( const css::lang::EventObject& aEvent ) override;
         virtual void SAL_CALL notifyTermination( const css::lang::EventObject& aEvent ) override;
 
+        // XServiceInfo
+        virtual OUString SAL_CALL getImplementationName() override;
+        virtual sal_Bool SAL_CALL supportsService( const OUString& sServiceName ) override;
+        virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
     public:
 
                               TerminateListener( TransferableHelper& rDropTargetHelper );
diff --git a/svtools/source/misc/transfer.cxx b/svtools/source/misc/transfer.cxx
index 955e9b8d3276..d1913d795e4a 100644
--- a/svtools/source/misc/transfer.cxx
+++ b/svtools/source/misc/transfer.cxx
@@ -253,6 +253,21 @@ void SAL_CALL TransferableHelper::TerminateListener::notifyTermination( const Ev
     mrParent.ImplFlush();
 }
 
+OUString SAL_CALL TransferableHelper::TerminateListener::getImplementationName()
+{
+    return OUString("com.sun.star.comp.svt.TransferableHelperTerminateListener");
+}
+
+sal_Bool SAL_CALL TransferableHelper::TerminateListener::supportsService(const OUString& /*rServiceName*/)
+{
+    return false;
+}
+
+css::uno::Sequence<OUString> TransferableHelper::TerminateListener::getSupportedServiceNames()
+{
+    return css::uno::Sequence<OUString>();
+}
+
 
 Any SAL_CALL TransferableHelper::getTransferData( const DataFlavor& rFlavor )
 {


More information about the Libreoffice-commits mailing list