cache foreign content in win32 clipboard code (tdf#133267)

The slowness in tdf#133267 on Windows is because the Calc operation
repeatedly calls ScDocument::IsClipboardSource(), which calls
ScModule::GetClipDoc(), which proceeds to fetch the clipboard
content, which means fetching it from the system clipboard if it's
not owned by LO.
Other LO clipboard implementations such as gtk3 or qt5 already
do caching, and it seems that it's easy to do for the win32 code.

Change-Id: I4696cc7488d66803fd5dd2963d27900957decdec
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95163
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
(cherry picked from commit fda6ad1458fcd5087c3dde56300b9d0367af6db5)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95246
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
diff --git a/dtrans/source/win32/clipb/WinClipbImpl.cxx b/dtrans/source/win32/clipb/WinClipbImpl.cxx
index 003a266..8d59be7 100644
--- a/dtrans/source/win32/clipb/WinClipbImpl.cxx
+++ b/dtrans/source/win32/clipb/WinClipbImpl.cxx
@@ -83,6 +83,10 @@
            return m_pCurrentClipContent->m_XTransferable;
        }

        // Content cached?
        if (m_foreignContent.is())
            return m_foreignContent;

        // release the mutex, so that the variable may be
        // changed by other threads
    }
@@ -101,6 +105,9 @@

        // remember pIDo destroys itself due to the smart pointer
        rClipContent = CDOTransferable::create( m_pWinClipboard->m_xContext, pIDo );

        MutexGuard aGuard(m_ClipContentMutex);
        m_foreignContent = rClipContent;
    }

    return rClipContent;
@@ -117,6 +124,8 @@
        {
            MutexGuard aGuard(m_ClipContentMutex);

            m_foreignContent.clear();

            m_pCurrentClipContent
                = new CXNotifyingDataObject(CDTransObjFactory::createDataObjFromTransferable(
                                                m_pWinClipboard->m_xContext, xTransferable),
@@ -176,7 +185,10 @@

    // reassociation to instance through static member
    if ( nullptr != s_pCWinClipbImpl )
    {
        s_pCWinClipbImpl->m_foreignContent.clear();
        s_pCWinClipbImpl->m_pWinClipboard->notifyAllClipboardListener( );
    }
}

void CWinClipbImpl::onReleaseDataObject( CXNotifyingDataObject* theCaller )
diff --git a/dtrans/source/win32/clipb/WinClipbImpl.hxx b/dtrans/source/win32/clipb/WinClipbImpl.hxx
index 55a9d8d..cd5878e 100644
--- a/dtrans/source/win32/clipb/WinClipbImpl.hxx
+++ b/dtrans/source/win32/clipb/WinClipbImpl.hxx
@@ -87,6 +87,7 @@
    CMtaOleClipboard        m_MtaOleClipboard;
    CWinClipboard*          m_pWinClipboard;
    CXNotifyingDataObject*  m_pCurrentClipContent;
    com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable > m_foreignContent;
    osl::Mutex              m_ClipContentMutex;

    static osl::Mutex       s_aMutex;