LibreOffice Module vcl (master) 1
dtranscomp.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <comphelper/lok.hxx>
23#include <tools/debug.hxx>
24#include <vcl/svapp.hxx>
25
26#include <factory.hxx>
27#include <svdata.hxx>
28#include <salinst.hxx>
29
30#include <com/sun/star/lang/IllegalArgumentException.hpp>
31#include <com/sun/star/lang/XMultiServiceFactory.hpp>
32#include <com/sun/star/lang/XServiceInfo.hpp>
33#include <com/sun/star/lang/XSingleServiceFactory.hpp>
34#include <com/sun/star/lang/XInitialization.hpp>
35#include <com/sun/star/datatransfer/XTransferable.hpp>
36#include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp>
37#include <com/sun/star/datatransfer/clipboard/XSystemClipboard.hpp>
38#include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
39#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
40#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
41
44
45using namespace com::sun::star;
46using namespace com::sun::star::uno;
47using namespace com::sun::star::lang;
48
49namespace vcl
50{
51namespace {
52
53// generic implementation to satisfy SalInstance
54class GenericClipboard :
56 datatransfer::clipboard::XSystemClipboard,
57 XServiceInfo
58 >
59{
62 std::vector< Reference< css::datatransfer::clipboard::XClipboardListener > > m_aListeners;
63
64public:
65
66 GenericClipboard()
67 {}
68
69 /*
70 * XServiceInfo
71 */
72
73 virtual OUString SAL_CALL getImplementationName() override;
74 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
75 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
76
77 static Sequence< OUString > getSupportedServiceNames_static();
78
79 /*
80 * XClipboard
81 */
82
83 virtual Reference< css::datatransfer::XTransferable > SAL_CALL getContents() override;
84
85 virtual void SAL_CALL setContents(
87 const Reference< css::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner ) override;
88
89 virtual OUString SAL_CALL getName() override;
90
91 /*
92 * XClipboardEx
93 */
94
95 virtual sal_Int8 SAL_CALL getRenderingCapabilities() override;
96
97 /*
98 * XClipboardNotifier
99 */
100 virtual void SAL_CALL addClipboardListener(
102
103 virtual void SAL_CALL removeClipboardListener(
105};
106
107}
108
109Sequence< OUString > GenericClipboard::getSupportedServiceNames_static()
110{
111 Sequence< OUString > aRet { "com.sun.star.datatransfer.clipboard.SystemClipboard" };
112 return aRet;
113}
114
115OUString GenericClipboard::getImplementationName()
116{
117 return "com.sun.star.datatransfer.VCLGenericClipboard";
118}
119
120Sequence< OUString > GenericClipboard::getSupportedServiceNames()
121{
122 return getSupportedServiceNames_static();
123}
124
125sal_Bool GenericClipboard::supportsService( const OUString& ServiceName )
126{
127 return cppu::supportsService(this, ServiceName);
128}
129
130Reference< css::datatransfer::XTransferable > GenericClipboard::getContents()
131{
132 return m_aContents;
133}
134
135void GenericClipboard::setContents(
138{
139 std::unique_lock aGuard( m_aMutex );
142 m_aContents = xTrans;
143 m_aOwner = xClipboardOwner;
144
145 std::vector< Reference< datatransfer::clipboard::XClipboardListener > > aListeners( m_aListeners );
146 datatransfer::clipboard::ClipboardEvent aEv;
147 aEv.Contents = m_aContents;
148
149 aGuard.unlock();
150
151 if( xOldOwner.is() && xOldOwner != xClipboardOwner )
152 xOldOwner->lostOwnership( this, xOldContents );
153 for (auto const& listener : aListeners)
154 {
155 listener->changedContents( aEv );
156 }
157}
158
159OUString GenericClipboard::getName()
160{
161 return "CLIPBOARD";
162}
163
164sal_Int8 GenericClipboard::getRenderingCapabilities()
165{
166 return 0;
167}
168
169void GenericClipboard::addClipboardListener( const Reference< datatransfer::clipboard::XClipboardListener >& listener )
170{
171 std::unique_lock aGuard(m_aMutex);
172
173 m_aListeners.push_back( listener );
174}
175
176void GenericClipboard::removeClipboardListener( const Reference< datatransfer::clipboard::XClipboardListener >& listener )
177{
178 std::unique_lock aGuard(m_aMutex);
179
180 m_aListeners.erase(std::remove(m_aListeners.begin(), m_aListeners.end(), listener), m_aListeners.end());
181}
182
183
184
185extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
187 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const& args)
188{
189 SolarMutexGuard aGuard;
190 auto xClipboard = ImplGetSVData()->mpDefInst->CreateClipboard( args );
191 if (xClipboard.is())
192 xClipboard->acquire();
193 return xClipboard.get();
194}
195
196namespace {
197
198/*
199* generic DragSource dummy
200*/
201class GenericDragSource : public ::comphelper::WeakComponentImplHelper<
202 datatransfer::dnd::XDragSource,
203 XInitialization,
204 css::lang::XServiceInfo
205 >
206{
207 css::uno::Reference<css::datatransfer::XTransferable> m_xTrans;
208public:
209 GenericDragSource() {}
210
211 // XDragSource
212 virtual sal_Bool SAL_CALL isDragImageSupported() override;
213 virtual sal_Int32 SAL_CALL getDefaultCursor( sal_Int8 dragAction ) override;
214 virtual void SAL_CALL startDrag(
215 const datatransfer::dnd::DragGestureEvent& trigger,
216 sal_Int8 sourceActions, sal_Int32 cursor, sal_Int32 image,
219 ) override;
220
221 // XInitialization
222 virtual void SAL_CALL initialize( const Sequence< Any >& arguments ) override;
223
224 OUString SAL_CALL getImplementationName() override
225 { return "com.sun.star.datatransfer.dnd.VclGenericDragSource"; }
226
227 sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
228 { return cppu::supportsService(this, ServiceName); }
229
230 css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
231 { return getSupportedServiceNames_static(); }
232
233 static Sequence< OUString > getSupportedServiceNames_static()
234 {
235 return { "com.sun.star.datatransfer.dnd.GenericDragSource" };
236 }
237};
238
239}
240
241sal_Bool GenericDragSource::isDragImageSupported()
242{
243 return false;
244}
245
246sal_Int32 GenericDragSource::getDefaultCursor( sal_Int8 )
247{
248 return 0;
249}
250
251void GenericDragSource::startDrag( const datatransfer::dnd::DragGestureEvent&,
252 sal_Int8 /*sourceActions*/, sal_Int32 /*cursor*/, sal_Int32 /*image*/,
255 )
256{
258 m_xTrans = rTrans;
259 return;
260 }
261
262 datatransfer::dnd::DragSourceDropEvent aEv;
263 aEv.DropAction = datatransfer::dnd::DNDConstants::ACTION_COPY;
264 aEv.DropSuccess = false;
265 listener->dragDropEnd( aEv );
266}
267
268void GenericDragSource::initialize( const Sequence< Any >& )
269{
270}
271
273{
274#if defined MACOSX
275 return { "com.sun.star.datatransfer.dnd.OleDragSource" };
276#elif defined UNX
277 return { "com.sun.star.datatransfer.dnd.X11DragSource" };
278#else
279 return { "com.sun.star.datatransfer.dnd.VclGenericDragSource" };
280#endif
281}
282
284{
285#if defined MACOSX
286 return "com.sun.star.comp.datatransfer.dnd.OleDragSource_V1";
287#elif defined UNX
288 return "com.sun.star.datatransfer.dnd.XdndSupport";
289#else
290 return "com.sun.star.datatransfer.dnd.VclGenericDragSource";
291#endif
292}
293
295{
296 SolarMutexGuard aGuard;
298 return xResult;
299}
300
301/*
302* generic DragSource dummy
303*/
304
305namespace {
306
307class GenericDropTarget : public comphelper::WeakComponentImplHelper<
308 datatransfer::dnd::XDropTarget,
309 XInitialization,
310 css::lang::XServiceInfo
311 >
312{
313public:
314 GenericDropTarget() {}
315
316 // XInitialization
317 virtual void SAL_CALL initialize( const Sequence< Any >& args ) override;
318
319 // XDropTarget
320 virtual void SAL_CALL addDropTargetListener( const Reference< css::datatransfer::dnd::XDropTargetListener >& ) override;
321 virtual void SAL_CALL removeDropTargetListener( const Reference< css::datatransfer::dnd::XDropTargetListener >& ) override;
322 virtual sal_Bool SAL_CALL isActive() override;
323 virtual void SAL_CALL setActive( sal_Bool active ) override;
324 virtual sal_Int8 SAL_CALL getDefaultActions() override;
325 virtual void SAL_CALL setDefaultActions( sal_Int8 actions ) override;
326
327 OUString SAL_CALL getImplementationName() override
328 { return "com.sun.star.datatransfer.dnd.VclGenericDropTarget"; }
329
330 sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
331 { return cppu::supportsService(this, ServiceName); }
332
333 css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
334 { return getSupportedServiceNames_static(); }
335
336 static Sequence< OUString > getSupportedServiceNames_static()
337 {
338 return { "com.sun.star.datatransfer.dnd.GenericDropTarget" };
339 }
340};
341
342}
343
344void GenericDropTarget::initialize( const Sequence< Any >& )
345{
346}
347
348void GenericDropTarget::addDropTargetListener( const Reference< css::datatransfer::dnd::XDropTargetListener >& )
349{
350}
351
352void GenericDropTarget::removeDropTargetListener( const Reference< css::datatransfer::dnd::XDropTargetListener >& )
353{
354}
355
356sal_Bool GenericDropTarget::isActive()
357{
358 return false;
359}
360
361void GenericDropTarget::setActive( sal_Bool )
362{
363}
364
365sal_Int8 GenericDropTarget::getDefaultActions()
366{
367 return 0;
368}
369
370void GenericDropTarget::setDefaultActions( sal_Int8)
371{
372}
373
375{
376#if defined MACOSX
377 return { "com.sun.star.datatransfer.dnd.OleDropTarget" };
378#elif defined UNX
379 return { "com.sun.star.datatransfer.dnd.X11DropTarget" };
380#else
381 return GenericDropTarget::getSupportedServiceNames_static();
382#endif
383}
384
386{
387 return
388 #if defined MACOSX
389 "com.sun.star.comp.datatransfer.dnd.OleDropTarget_V1"
390 #elif defined UNX
391 "com.sun.star.datatransfer.dnd.XdndDropTarget"
392 #else
393 "com.sun.star.datatransfer.dnd.VclGenericDropTarget"
394 #endif
395 ;
396}
397
399{
400 SolarMutexGuard aGuard;
402 return xResult;
403}
404
405} // namespace vcl
406
407/*
408* SalInstance generic
409*/
411{
412 if (arguments.hasElements()) {
413 throw css::lang::IllegalArgumentException(
414 "non-empty SalInstance::CreateClipboard arguments", {}, -1);
415 }
416#ifdef IOS
417 return Reference< XInterface >( static_cast<cppu::OWeakObject *>(new vcl::GenericClipboard()) );
418#else
420 // In LOK, each document view shall have its own clipboard instance, and the way that
421 // (happens to?) work is that apparently this function is called at most once for each such
422 // document view, so it is OK if we hand out a fresh instance on each call in LOK (whereas
423 // in non-LOK below we keep handing out one single instance; see also
424 // <https://lists.freedesktop.org/archives/libreoffice/2020-April/084824.html> "Re: Linux
425 // SAL_USE_VCLPLUGIN=svp and the clipboard"):
426 return Reference< XInterface >( static_cast<cppu::OWeakObject *>(new vcl::GenericClipboard()) );
427 }
428#endif
430 if (!m_clipboard.is()) {
431 m_clipboard = static_cast<cppu::OWeakObject *>(new vcl::GenericClipboard());
432 }
433 return m_clipboard;
434}
435
436uno::Reference<uno::XInterface> SalInstance::ImplCreateDragSource(const SystemEnvData*)
437{
438 return css::uno::Reference<css::uno::XInterface>();
439}
440
442{
443 // We run unit tests in parallel, which is a problem when touching a shared resource
444 // the system clipboard, so rather use the dummy GenericClipboard.
446 return Reference<XInterface>(static_cast<cppu::OWeakObject*>(new vcl::GenericDragSource()));
447 return ImplCreateDragSource(pSysEnv);
448}
449
450uno::Reference<uno::XInterface> SalInstance::ImplCreateDropTarget(const SystemEnvData*)
451{
452 return css::uno::Reference<css::uno::XInterface>();
453}
454
456{
457 // see SalInstance::CreateDragSource
459 return Reference<XInterface>(static_cast<cppu::OWeakObject*>(new vcl::GenericDropTarget()));
460 return ImplCreateDropTarget(pSysEnv);
461}
462
463/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool IsHeadlessModeEnabled()
Determines if headless mode is enabled.
Definition: svapp.cxx:1658
virtual css::uno::Reference< css::uno::XInterface > CreateClipboard(const css::uno::Sequence< css::uno::Any > &i_rArguments)
Definition: dtranscomp.cxx:410
static bool IsRunningUnitTest()
Definition: salinst.hxx:216
css::uno::Reference< css::uno::XInterface > CreateDropTarget(const SystemEnvData *=nullptr)
Definition: dtranscomp.cxx:455
virtual css::uno::Reference< css::uno::XInterface > ImplCreateDropTarget(const SystemEnvData *)
Definition: dtranscomp.cxx:450
virtual css::uno::Reference< css::uno::XInterface > ImplCreateDragSource(const SystemEnvData *)
Definition: dtranscomp.cxx:436
css::uno::Reference< css::uno::XInterface > CreateDragSource(const SystemEnvData *=nullptr)
Definition: dtranscomp.cxx:441
css::uno::Reference< css::uno::XInterface > m_clipboard
Definition: salinst.hxx:80
#define DBG_TESTSOLARMUTEX()
Listeners aListeners
Reference< css::datatransfer::clipboard::XClipboardOwner > m_aOwner
Definition: dtranscomp.cxx:61
css::uno::Reference< css::datatransfer::XTransferable > m_xTrans
Definition: dtranscomp.cxx:207
Reference< css::datatransfer::XTransferable > m_aContents
Definition: dtranscomp.cxx:60
std::vector< Reference< css::datatransfer::clipboard::XClipboardListener > > m_aListeners
Definition: dtranscomp.cxx:62
void setActive(bool bActive)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
args
OUString DragSource_getImplementationName()
Definition: dtranscomp.cxx:283
Reference< XInterface > DragSource_createInstance(const Reference< XMultiServiceFactory > &)
Definition: dtranscomp.cxx:294
Sequence< OUString > DropTarget_getSupportedServiceNames()
Definition: dtranscomp.cxx:374
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * vcl_SystemClipboard_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &args)
Definition: dtranscomp.cxx:186
Sequence< OUString > DragSource_getSupportedServiceNames()
Definition: dtranscomp.cxx:272
Reference< XInterface > DropTarget_createInstance(const Reference< XMultiServiceFactory > &)
Definition: dtranscomp.cxx:398
OUString DropTarget_getImplementationName()
Definition: dtranscomp.cxx:385
SalInstance * mpDefInst
Definition: svdata.hxx:392
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:76
unsigned char sal_Bool
signed char sal_Int8