1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <comphelper/lok.hxx>
23 #include <osl/mutex.hxx>
24 #include <tools/debug.hxx>
25 #include <vcl/svapp.hxx>
27 #include <factory.hxx>
29 #include <salinst.hxx>
31 #include <com/sun/star/lang/IllegalArgumentException.hpp>
32 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
33 #include <com/sun/star/lang/XServiceInfo.hpp>
34 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
35 #include <com/sun/star/lang/XInitialization.hpp>
36 #include <com/sun/star/datatransfer/XTransferable.hpp>
37 #include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp>
38 #include <com/sun/star/datatransfer/clipboard/XSystemClipboard.hpp>
39 #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
40 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
41 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
43 #include <cppuhelper/compbase.hxx>
44 #include <cppuhelper/supportsservice.hxx>
46 using namespace com::sun::star
;
47 using namespace com::sun::star::uno
;
48 using namespace com::sun::star::lang
;
54 // generic implementation to satisfy SalInstance
55 class GenericClipboard
:
56 public cppu::WeakComponentImplHelper
<
57 datatransfer::clipboard::XSystemClipboard
,
62 Reference
< css::datatransfer::XTransferable
> m_aContents
;
63 Reference
< css::datatransfer::clipboard::XClipboardOwner
> m_aOwner
;
64 std::vector
< Reference
< css::datatransfer::clipboard::XClipboardListener
> > m_aListeners
;
68 GenericClipboard() : cppu::WeakComponentImplHelper
<
69 datatransfer::clipboard::XSystemClipboard
,
78 virtual OUString SAL_CALL
getImplementationName() override
;
79 virtual sal_Bool SAL_CALL
supportsService( const OUString
& ServiceName
) override
;
80 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
82 static Sequence
< OUString
> getSupportedServiceNames_static();
88 virtual Reference
< css::datatransfer::XTransferable
> SAL_CALL
getContents() override
;
90 virtual void SAL_CALL
setContents(
91 const Reference
< css::datatransfer::XTransferable
>& xTrans
,
92 const Reference
< css::datatransfer::clipboard::XClipboardOwner
>& xClipboardOwner
) override
;
94 virtual OUString SAL_CALL
getName() override
;
100 virtual sal_Int8 SAL_CALL
getRenderingCapabilities() override
;
105 virtual void SAL_CALL
addClipboardListener(
106 const Reference
< css::datatransfer::clipboard::XClipboardListener
>& listener
) override
;
108 virtual void SAL_CALL
removeClipboardListener(
109 const Reference
< css::datatransfer::clipboard::XClipboardListener
>& listener
) override
;
114 Sequence
< OUString
> GenericClipboard::getSupportedServiceNames_static()
116 Sequence
< OUString
> aRet
{ "com.sun.star.datatransfer.clipboard.SystemClipboard" };
120 OUString
GenericClipboard::getImplementationName()
122 return "com.sun.star.datatransfer.VCLGenericClipboard";
125 Sequence
< OUString
> GenericClipboard::getSupportedServiceNames()
127 return getSupportedServiceNames_static();
130 sal_Bool
GenericClipboard::supportsService( const OUString
& ServiceName
)
132 return cppu::supportsService(this, ServiceName
);
135 Reference
< css::datatransfer::XTransferable
> GenericClipboard::getContents()
140 void GenericClipboard::setContents(
141 const Reference
< css::datatransfer::XTransferable
>& xTrans
,
142 const Reference
< css::datatransfer::clipboard::XClipboardOwner
>& xClipboardOwner
)
144 osl::ClearableMutexGuard
aGuard( m_aMutex
);
145 Reference
< datatransfer::clipboard::XClipboardOwner
> xOldOwner( m_aOwner
);
146 Reference
< datatransfer::XTransferable
> xOldContents( m_aContents
);
147 m_aContents
= xTrans
;
148 m_aOwner
= xClipboardOwner
;
150 std::vector
< Reference
< datatransfer::clipboard::XClipboardListener
> > aListeners( m_aListeners
);
151 datatransfer::clipboard::ClipboardEvent aEv
;
152 aEv
.Contents
= m_aContents
;
156 if( xOldOwner
.is() && xOldOwner
!= xClipboardOwner
)
157 xOldOwner
->lostOwnership( this, xOldContents
);
158 for (auto const& listener
: aListeners
)
160 listener
->changedContents( aEv
);
164 OUString
GenericClipboard::getName()
169 sal_Int8
GenericClipboard::getRenderingCapabilities()
174 void GenericClipboard::addClipboardListener( const Reference
< datatransfer::clipboard::XClipboardListener
>& listener
)
176 osl::MutexGuard
aGuard(m_aMutex
);
178 m_aListeners
.push_back( listener
);
181 void GenericClipboard::removeClipboardListener( const Reference
< datatransfer::clipboard::XClipboardListener
>& listener
)
183 osl::MutexGuard
aGuard(m_aMutex
);
185 m_aListeners
.erase(std::remove(m_aListeners
.begin(), m_aListeners
.end(), listener
), m_aListeners
.end());
190 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
191 vcl_SystemClipboard_get_implementation(
192 css::uno::XComponentContext
* , css::uno::Sequence
<css::uno::Any
> const& args
)
194 SolarMutexGuard aGuard
;
195 auto xClipboard
= ImplGetSVData()->mpDefInst
->CreateClipboard( args
);
197 xClipboard
->acquire();
198 return xClipboard
.get();
204 * generic DragSource dummy
206 class GenericDragSource
: public cppu::WeakComponentImplHelper
<
207 datatransfer::dnd::XDragSource
,
209 css::lang::XServiceInfo
214 GenericDragSource() : WeakComponentImplHelper( m_aMutex
) {}
217 virtual sal_Bool SAL_CALL
isDragImageSupported() override
;
218 virtual sal_Int32 SAL_CALL
getDefaultCursor( sal_Int8 dragAction
) override
;
219 virtual void SAL_CALL
startDrag(
220 const datatransfer::dnd::DragGestureEvent
& trigger
,
221 sal_Int8 sourceActions
, sal_Int32 cursor
, sal_Int32 image
,
222 const Reference
< datatransfer::XTransferable
>& transferable
,
223 const Reference
< datatransfer::dnd::XDragSourceListener
>& listener
227 virtual void SAL_CALL
initialize( const Sequence
< Any
>& arguments
) override
;
229 OUString SAL_CALL
getImplementationName() override
230 { return "com.sun.star.datatransfer.dnd.VclGenericDragSource"; }
232 sal_Bool SAL_CALL
supportsService(OUString
const & ServiceName
) override
233 { return cppu::supportsService(this, ServiceName
); }
235 css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
236 { return getSupportedServiceNames_static(); }
238 static Sequence
< OUString
> getSupportedServiceNames_static()
240 return { "com.sun.star.datatransfer.dnd.GenericDragSource" };
246 sal_Bool
GenericDragSource::isDragImageSupported()
251 sal_Int32
GenericDragSource::getDefaultCursor( sal_Int8
)
256 void GenericDragSource::startDrag( const datatransfer::dnd::DragGestureEvent
&,
257 sal_Int8
/*sourceActions*/, sal_Int32
/*cursor*/, sal_Int32
/*image*/,
258 const Reference
< datatransfer::XTransferable
>&,
259 const Reference
< datatransfer::dnd::XDragSourceListener
>& listener
262 datatransfer::dnd::DragSourceDropEvent aEv
;
263 aEv
.DropAction
= datatransfer::dnd::DNDConstants::ACTION_COPY
;
264 aEv
.DropSuccess
= false;
265 listener
->dragDropEnd( aEv
);
268 void GenericDragSource::initialize( const Sequence
< Any
>& )
272 Sequence
< OUString
> DragSource_getSupportedServiceNames()
275 return { "com.sun.star.datatransfer.dnd.OleDragSource" };
277 return { "com.sun.star.datatransfer.dnd.X11DragSource" };
279 return { "com.sun.star.datatransfer.dnd.VclGenericDragSource" };
283 OUString
DragSource_getImplementationName()
286 return "com.sun.star.comp.datatransfer.dnd.OleDragSource_V1";
288 return "com.sun.star.datatransfer.dnd.XdndSupport";
290 return "com.sun.star.datatransfer.dnd.VclGenericDragSource";
294 Reference
< XInterface
> DragSource_createInstance( const Reference
< XMultiServiceFactory
>& )
296 SolarMutexGuard aGuard
;
297 Reference
< XInterface
> xResult
= ImplGetSVData()->mpDefInst
->CreateDragSource();
302 * generic DragSource dummy
307 class GenericDropTarget
: public cppu::WeakComponentImplHelper
<
308 datatransfer::dnd::XDropTarget
,
310 css::lang::XServiceInfo
315 GenericDropTarget() : WeakComponentImplHelper( m_aMutex
)
319 virtual void SAL_CALL
initialize( const Sequence
< Any
>& args
) override
;
322 virtual void SAL_CALL
addDropTargetListener( const Reference
< css::datatransfer::dnd::XDropTargetListener
>& ) override
;
323 virtual void SAL_CALL
removeDropTargetListener( const Reference
< css::datatransfer::dnd::XDropTargetListener
>& ) override
;
324 virtual sal_Bool SAL_CALL
isActive() override
;
325 virtual void SAL_CALL
setActive( sal_Bool active
) override
;
326 virtual sal_Int8 SAL_CALL
getDefaultActions() override
;
327 virtual void SAL_CALL
setDefaultActions( sal_Int8 actions
) override
;
329 OUString SAL_CALL
getImplementationName() override
330 { return "com.sun.star.datatransfer.dnd.VclGenericDropTarget"; }
332 sal_Bool SAL_CALL
supportsService(OUString
const & ServiceName
) override
333 { return cppu::supportsService(this, ServiceName
); }
335 css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
336 { return getSupportedServiceNames_static(); }
338 static Sequence
< OUString
> getSupportedServiceNames_static()
340 return { "com.sun.star.datatransfer.dnd.GenericDropTarget" };
346 void GenericDropTarget::initialize( const Sequence
< Any
>& )
350 void GenericDropTarget::addDropTargetListener( const Reference
< css::datatransfer::dnd::XDropTargetListener
>& )
354 void GenericDropTarget::removeDropTargetListener( const Reference
< css::datatransfer::dnd::XDropTargetListener
>& )
358 sal_Bool
GenericDropTarget::isActive()
363 void GenericDropTarget::setActive( sal_Bool
)
367 sal_Int8
GenericDropTarget::getDefaultActions()
372 void GenericDropTarget::setDefaultActions( sal_Int8
)
376 Sequence
< OUString
> DropTarget_getSupportedServiceNames()
379 return { "com.sun.star.datatransfer.dnd.OleDropTarget" };
381 return { "com.sun.star.datatransfer.dnd.X11DropTarget" };
383 return GenericDropTarget::getSupportedServiceNames_static();
387 OUString
DropTarget_getImplementationName()
391 "com.sun.star.comp.datatransfer.dnd.OleDropTarget_V1"
393 "com.sun.star.datatransfer.dnd.XdndDropTarget"
395 "com.sun.star.datatransfer.dnd.VclGenericDropTarget"
400 Reference
< XInterface
> DropTarget_createInstance( const Reference
< XMultiServiceFactory
>& )
402 SolarMutexGuard aGuard
;
403 Reference
< XInterface
> xResult
= ImplGetSVData()->mpDefInst
->CreateDropTarget();
410 * SalInstance generic
412 Reference
< XInterface
> SalInstance::CreateClipboard( const Sequence
< Any
>& arguments
)
414 if (arguments
.hasElements()) {
415 throw css::lang::IllegalArgumentException(
416 "non-empty SalInstance::CreateClipboard arguments", {}, -1);
418 if (comphelper::LibreOfficeKit::isActive()) {
419 // In LOK, each document view shall have its own clipboard instance, and the way that
420 // (happens to?) work is that apparently this function is called at most once for each such
421 // document view, so it is OK if we hand out a fresh instance on each call in LOK (whereas
422 // in non-LOK below we keep handing out one single instance; see also
423 // <https://lists.freedesktop.org/archives/libreoffice/2020-April/084824.html> "Re: Linux
424 // SAL_USE_VCLPLUGIN=svp and the clipboard"):
425 return Reference
< XInterface
>( static_cast<cppu::OWeakObject
*>(new vcl::GenericClipboard()) );
427 DBG_TESTSOLARMUTEX();
428 if (!m_clipboard
.is()) {
429 m_clipboard
= static_cast<cppu::OWeakObject
*>(new vcl::GenericClipboard());
434 Reference
< XInterface
> SalInstance::CreateDragSource()
436 return Reference
< XInterface
>( static_cast<cppu::OWeakObject
*>(new vcl::GenericDragSource()) );
439 Reference
< XInterface
> SalInstance::CreateDropTarget()
441 return Reference
< XInterface
>( static_cast<cppu::OWeakObject
*>(new vcl::GenericDropTarget()) );
444 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */