1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: WinClipbImpl.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dtrans.hxx"
34 //------------------------------------------------------------------------
36 //------------------------------------------------------------------------
37 #include <osl/diagnose.h>
38 #include "WinClipbImpl.hxx"
40 #include <systools/win32/comtools.hxx>
41 #include "..\..\inc\DtObjFactory.hxx"
42 #include "..\dtobj\APNDataObject.hxx"
43 #include "WinClipboard.hxx"
44 #include <com/sun/star/datatransfer/clipboard/RenderingCapabilities.hpp>
45 #include "..\dtobj\XNotifyingDataObject.hxx"
48 #pragma warning(push,1)
57 //------------------------------------------------------------------------
58 // namespace directives
59 //------------------------------------------------------------------------
66 using namespace com::sun::star::uno
;
67 using namespace com::sun::star::datatransfer
;
68 using namespace com::sun::star::datatransfer::clipboard
;
69 using namespace com::sun::star::datatransfer::clipboard::RenderingCapabilities
;
71 //------------------------------------------------------------------------
73 //------------------------------------------------------------------------
75 // definition of static members
76 CWinClipbImpl
* CWinClipbImpl::s_pCWinClipbImpl
= NULL
;
77 osl::Mutex
CWinClipbImpl::s_aMutex
;
79 //------------------------------------------------------------------------
81 //------------------------------------------------------------------------
83 CWinClipbImpl::CWinClipbImpl( const OUString
& aClipboardName
, CWinClipboard
* theWinClipboard
) :
84 m_itsName( aClipboardName
),
85 m_pWinClipboard( theWinClipboard
),
86 m_pCurrentClipContent( NULL
)
88 OSL_ASSERT( NULL
!= m_pWinClipboard
);
90 // necessary to reassociate from
91 // the static callback function
92 s_pCWinClipbImpl
= this;
93 registerClipboardViewer( );
96 //------------------------------------------------------------------------
98 //------------------------------------------------------------------------
100 CWinClipbImpl::~CWinClipbImpl( )
102 ClearableMutexGuard
aGuard( s_aMutex
);
103 s_pCWinClipbImpl
= NULL
;
106 unregisterClipboardViewer( );
109 //------------------------------------------------------------------------
111 //------------------------------------------------------------------------
113 Reference
< XTransferable
> SAL_CALL
CWinClipbImpl::getContents( ) throw( RuntimeException
)
115 // use the shotcut or create a transferable from
117 ClearableMutexGuard
aGuard( m_ClipContentMutex
);
119 if ( NULL
!= m_pCurrentClipContent
)
121 return m_pCurrentClipContent
->m_XTransferable
;
124 // release the mutex, so that the variable may be
125 // changed by other threads
128 Reference
< XTransferable
> rClipContent
;
130 // get the current dataobject from clipboard
131 IDataObjectPtr pIDataObject
;
132 HRESULT hr
= m_MtaOleClipboard
.getClipboard( &pIDataObject
);
134 if ( SUCCEEDED( hr
) )
136 // create an apartment neutral dataobject and initialize it with a
137 // com smart pointer to the IDataObject from clipboard
138 IDataObjectPtr
pIDo( new CAPNDataObject( pIDataObject
) );
140 CDTransObjFactory objFactory
;
142 // remeber pIDo destroys itself due to the smart pointer
143 rClipContent
= objFactory
.createTransferableFromDataObj( m_pWinClipboard
->m_SrvMgr
, pIDo
);
149 //------------------------------------------------------------------------
151 //------------------------------------------------------------------------
153 void SAL_CALL
CWinClipbImpl::setContents(
154 const Reference
< XTransferable
>& xTransferable
,
155 const Reference
< XClipboardOwner
>& xClipboardOwner
)
156 throw( RuntimeException
)
158 CDTransObjFactory objFactory
;
159 IDataObjectPtr pIDataObj
;
161 if ( xTransferable
.is( ) )
163 ClearableMutexGuard
aGuard( m_ClipContentMutex
);
165 m_pCurrentClipContent
= new CXNotifyingDataObject(
166 objFactory
.createDataObjFromTransferable( m_pWinClipboard
->m_SrvMgr
, xTransferable
),
173 pIDataObj
= IDataObjectPtr( m_pCurrentClipContent
);
176 m_MtaOleClipboard
.setClipboard(pIDataObj
.get());
179 //------------------------------------------------------------------------
181 //------------------------------------------------------------------------
183 OUString SAL_CALL
CWinClipbImpl::getName( ) throw( RuntimeException
)
188 //------------------------------------------------------------------------
190 //------------------------------------------------------------------------
192 sal_Int8 SAL_CALL
CWinClipbImpl::getRenderingCapabilities( ) throw( RuntimeException
)
194 return ( Delayed
| Persistant
);
197 //------------------------------------------------------------------------
199 //------------------------------------------------------------------------
201 void SAL_CALL
CWinClipbImpl::flushClipboard( ) throw( RuntimeException
)
203 // sollte eigentlich hier stehen: ClearableMutexGuard aGuard( m_ClipContentMutex );
204 // geht aber nicht, da FlushClipboard zurückruft und das DataObject
205 // freigibt und damit würde es einen Deadlock in onReleaseDataObject geben
206 // FlushClipboard muß synchron sein, damit das runterfahren ggf. erst weitergeht,
207 // wenn alle Clipboard-Formate gerendert wurden
208 // die Abfrage ist nötig, damit nur geflusht wird, wenn wir wirklich Clipboardowner
209 // sind (ich weiss nicht genau was passiert, wenn man flusht und nicht Clipboard
211 // eventuell kann man aber die Abfrage in den Clipboard STA Thread verlagern, indem
212 // man sich dort das DataObject merkt und vor dem flushen OleIsCurrentClipboard ruft
214 if ( NULL
!= m_pCurrentClipContent
)
215 m_MtaOleClipboard
.flushClipboard( );
218 //------------------------------------------------------------------------
220 //------------------------------------------------------------------------
222 void SAL_CALL
CWinClipbImpl::registerClipboardViewer( )
224 m_MtaOleClipboard
.registerClipViewer( CWinClipbImpl::onClipboardContentChanged
);
227 //------------------------------------------------------------------------
229 //------------------------------------------------------------------------
231 void SAL_CALL
CWinClipbImpl::unregisterClipboardViewer( )
233 m_MtaOleClipboard
.registerClipViewer( NULL
);
236 //------------------------------------------------------------------------
238 //------------------------------------------------------------------------
240 void SAL_CALL
CWinClipbImpl::dispose() throw( RuntimeException
)
242 OSL_ENSURE( !m_pCurrentClipContent
, "Clipboard was not flushed before shutdown!" );
245 //------------------------------------------------------------------------
247 //------------------------------------------------------------------------
249 void WINAPI
CWinClipbImpl::onClipboardContentChanged( void )
251 MutexGuard
aGuard( s_aMutex
);
253 // reassocition to instance through static member
254 if ( NULL
!= s_pCWinClipbImpl
)
255 s_pCWinClipbImpl
->m_pWinClipboard
->notifyAllClipboardListener( );
258 //------------------------------------------------------------------------
260 //------------------------------------------------------------------------
262 void SAL_CALL
CWinClipbImpl::onReleaseDataObject( CXNotifyingDataObject
* theCaller
)
264 OSL_ASSERT( NULL
!= theCaller
);
267 theCaller
->lostOwnership( );
269 // if the current caller is the one we currently
270 // hold, then set it to NULL because an external
271 // source must be the clipboardowner now
272 MutexGuard
aGuard( m_ClipContentMutex
);
274 if ( m_pCurrentClipContent
== theCaller
)
275 m_pCurrentClipContent
= NULL
;