1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_dtrans.hxx" 30 31 //------------------------------------------------------------------------ 32 // includes 33 //------------------------------------------------------------------------ 34 #include <osl/diagnose.h> 35 #include "WinClipbImpl.hxx" 36 37 #include <systools/win32/comtools.hxx> 38 #include "..\..\inc\DtObjFactory.hxx" 39 #include "..\dtobj\APNDataObject.hxx" 40 #include "WinClipboard.hxx" 41 #include <com/sun/star/datatransfer/clipboard/RenderingCapabilities.hpp> 42 #include "..\dtobj\XNotifyingDataObject.hxx" 43 44 #if defined _MSC_VER 45 #pragma warning(push,1) 46 #endif 47 #include <windows.h> 48 #include <ole2.h> 49 #include <objidl.h> 50 #if defined _MSC_VER 51 #pragma warning(pop) 52 #endif 53 54 //------------------------------------------------------------------------ 55 // namespace directives 56 //------------------------------------------------------------------------ 57 58 using namespace rtl; 59 using namespace osl; 60 using namespace std; 61 using namespace cppu; 62 63 using namespace com::sun::star::uno; 64 using namespace com::sun::star::datatransfer; 65 using namespace com::sun::star::datatransfer::clipboard; 66 using namespace com::sun::star::datatransfer::clipboard::RenderingCapabilities; 67 68 //------------------------------------------------------------------------ 69 // deklarations 70 //------------------------------------------------------------------------ 71 72 // definition of static members 73 CWinClipbImpl* CWinClipbImpl::s_pCWinClipbImpl = NULL; 74 osl::Mutex CWinClipbImpl::s_aMutex; 75 76 //------------------------------------------------------------------------ 77 // 78 //------------------------------------------------------------------------ 79 80 CWinClipbImpl::CWinClipbImpl( const OUString& aClipboardName, CWinClipboard* theWinClipboard ) : 81 m_itsName( aClipboardName ), 82 m_pWinClipboard( theWinClipboard ), 83 m_pCurrentClipContent( NULL ) 84 { 85 OSL_ASSERT( NULL != m_pWinClipboard ); 86 87 // necessary to reassociate from 88 // the static callback function 89 s_pCWinClipbImpl = this; 90 registerClipboardViewer( ); 91 } 92 93 //------------------------------------------------------------------------ 94 // 95 //------------------------------------------------------------------------ 96 97 CWinClipbImpl::~CWinClipbImpl( ) 98 { 99 ClearableMutexGuard aGuard( s_aMutex ); 100 s_pCWinClipbImpl = NULL; 101 aGuard.clear( ); 102 103 unregisterClipboardViewer( ); 104 } 105 106 //------------------------------------------------------------------------ 107 // getContent 108 //------------------------------------------------------------------------ 109 110 Reference< XTransferable > SAL_CALL CWinClipbImpl::getContents( ) throw( RuntimeException ) 111 { 112 // use the shotcut or create a transferable from 113 // system clipboard 114 ClearableMutexGuard aGuard( m_ClipContentMutex ); 115 116 if ( NULL != m_pCurrentClipContent ) 117 { 118 return m_pCurrentClipContent->m_XTransferable; 119 } 120 121 // release the mutex, so that the variable may be 122 // changed by other threads 123 aGuard.clear( ); 124 125 Reference< XTransferable > rClipContent; 126 127 // get the current dataobject from clipboard 128 IDataObjectPtr pIDataObject; 129 HRESULT hr = m_MtaOleClipboard.getClipboard( &pIDataObject ); 130 131 if ( SUCCEEDED( hr ) ) 132 { 133 // create an apartment neutral dataobject and initialize it with a 134 // com smart pointer to the IDataObject from clipboard 135 IDataObjectPtr pIDo( new CAPNDataObject( pIDataObject ) ); 136 137 CDTransObjFactory objFactory; 138 139 // remeber pIDo destroys itself due to the smart pointer 140 rClipContent = objFactory.createTransferableFromDataObj( m_pWinClipboard->m_SrvMgr, pIDo ); 141 } 142 143 return rClipContent; 144 } 145 146 //------------------------------------------------------------------------ 147 // setContent 148 //------------------------------------------------------------------------ 149 150 void SAL_CALL CWinClipbImpl::setContents( 151 const Reference< XTransferable >& xTransferable, 152 const Reference< XClipboardOwner >& xClipboardOwner ) 153 throw( RuntimeException ) 154 { 155 CDTransObjFactory objFactory; 156 IDataObjectPtr pIDataObj; 157 158 if ( xTransferable.is( ) ) 159 { 160 ClearableMutexGuard aGuard( m_ClipContentMutex ); 161 162 m_pCurrentClipContent = new CXNotifyingDataObject( 163 objFactory.createDataObjFromTransferable( m_pWinClipboard->m_SrvMgr , xTransferable ), 164 xTransferable, 165 xClipboardOwner, 166 this ); 167 168 aGuard.clear( ); 169 170 pIDataObj = IDataObjectPtr( m_pCurrentClipContent ); 171 } 172 173 m_MtaOleClipboard.setClipboard(pIDataObj.get()); 174 } 175 176 //------------------------------------------------------------------------ 177 // 178 //------------------------------------------------------------------------ 179 180 OUString SAL_CALL CWinClipbImpl::getName( ) throw( RuntimeException ) 181 { 182 return m_itsName; 183 } 184 185 //------------------------------------------------------------------------ 186 // 187 //------------------------------------------------------------------------ 188 189 sal_Int8 SAL_CALL CWinClipbImpl::getRenderingCapabilities( ) throw( RuntimeException ) 190 { 191 return ( Delayed | Persistant ); 192 } 193 194 //------------------------------------------------------------------------ 195 // 196 //------------------------------------------------------------------------ 197 198 void SAL_CALL CWinClipbImpl::flushClipboard( ) throw( RuntimeException ) 199 { 200 // sollte eigentlich hier stehen: ClearableMutexGuard aGuard( m_ClipContentMutex ); 201 // geht aber nicht, da FlushClipboard zur�ckruft und das DataObject 202 // freigibt und damit w�rde es einen Deadlock in onReleaseDataObject geben 203 // FlushClipboard mu� synchron sein, damit das runterfahren ggf. erst weitergeht, 204 // wenn alle Clipboard-Formate gerendert wurden 205 // die Abfrage ist n�tig, damit nur geflusht wird, wenn wir wirklich Clipboardowner 206 // sind (ich weiss nicht genau was passiert, wenn man flusht und nicht Clipboard 207 // owner ist). 208 // eventuell kann man aber die Abfrage in den Clipboard STA Thread verlagern, indem 209 // man sich dort das DataObject merkt und vor dem flushen OleIsCurrentClipboard ruft 210 211 if ( NULL != m_pCurrentClipContent ) 212 m_MtaOleClipboard.flushClipboard( ); 213 } 214 215 //------------------------------------------------------------------------ 216 // 217 //------------------------------------------------------------------------ 218 219 void SAL_CALL CWinClipbImpl::registerClipboardViewer( ) 220 { 221 m_MtaOleClipboard.registerClipViewer( CWinClipbImpl::onClipboardContentChanged ); 222 } 223 224 //------------------------------------------------------------------------ 225 // 226 //------------------------------------------------------------------------ 227 228 void SAL_CALL CWinClipbImpl::unregisterClipboardViewer( ) 229 { 230 m_MtaOleClipboard.registerClipViewer( NULL ); 231 } 232 233 //------------------------------------------------------------------------ 234 // 235 //------------------------------------------------------------------------ 236 237 void SAL_CALL CWinClipbImpl::dispose() throw( RuntimeException ) 238 { 239 OSL_ENSURE( !m_pCurrentClipContent, "Clipboard was not flushed before shutdown!" ); 240 } 241 242 //------------------------------------------------------------------------ 243 // 244 //------------------------------------------------------------------------ 245 246 void WINAPI CWinClipbImpl::onClipboardContentChanged( void ) 247 { 248 MutexGuard aGuard( s_aMutex ); 249 250 // reassocition to instance through static member 251 if ( NULL != s_pCWinClipbImpl ) 252 s_pCWinClipbImpl->m_pWinClipboard->notifyAllClipboardListener( ); 253 } 254 255 //------------------------------------------------------------------------ 256 // 257 //------------------------------------------------------------------------ 258 259 void SAL_CALL CWinClipbImpl::onReleaseDataObject( CXNotifyingDataObject* theCaller ) 260 { 261 OSL_ASSERT( NULL != theCaller ); 262 263 if ( theCaller ) 264 theCaller->lostOwnership( ); 265 266 // if the current caller is the one we currently 267 // hold, then set it to NULL because an external 268 // source must be the clipboardowner now 269 MutexGuard aGuard( m_ClipContentMutex ); 270 271 if ( m_pCurrentClipContent == theCaller ) 272 m_pCurrentClipContent = NULL; 273 } 274