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 <osl/mutex.hxx>
24 #include <tools/debug.hxx>
25 #include <vcl/svapp.hxx>
26 
27 #include <factory.hxx>
28 #include <svdata.hxx>
29 #include <salinst.hxx>
30 
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>
42 
43 #include <cppuhelper/compbase.hxx>
45 
46 using namespace com::sun::star;
47 using namespace com::sun::star::uno;
48 using namespace com::sun::star::lang;
49 
50 namespace vcl
51 {
52 namespace {
53 
54 // generic implementation to satisfy SalInstance
55 class GenericClipboard :
56  public cppu::WeakComponentImplHelper<
57  datatransfer::clipboard::XSystemClipboard,
58  XServiceInfo
59  >
60 {
61  osl::Mutex m_aMutex;
64  std::vector< Reference< css::datatransfer::clipboard::XClipboardListener > > m_aListeners;
65 
66 public:
67 
68  GenericClipboard() : cppu::WeakComponentImplHelper<
69  datatransfer::clipboard::XSystemClipboard,
70  XServiceInfo
71  >( m_aMutex )
72  {}
73 
74  /*
75  * XServiceInfo
76  */
77 
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;
81 
82  static Sequence< OUString > getSupportedServiceNames_static();
83 
84  /*
85  * XClipboard
86  */
87 
88  virtual Reference< css::datatransfer::XTransferable > SAL_CALL getContents() override;
89 
90  virtual void SAL_CALL setContents(
92  const Reference< css::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner ) override;
93 
94  virtual OUString SAL_CALL getName() override;
95 
96  /*
97  * XClipboardEx
98  */
99 
100  virtual sal_Int8 SAL_CALL getRenderingCapabilities() override;
101 
102  /*
103  * XClipboardNotifier
104  */
105  virtual void SAL_CALL addClipboardListener(
107 
108  virtual void SAL_CALL removeClipboardListener(
110 };
111 
112 }
113 
114 Sequence< OUString > GenericClipboard::getSupportedServiceNames_static()
115 {
116  Sequence< OUString > aRet { "com.sun.star.datatransfer.clipboard.SystemClipboard" };
117  return aRet;
118 }
119 
120 OUString GenericClipboard::getImplementationName()
121 {
122  return "com.sun.star.datatransfer.VCLGenericClipboard";
123 }
124 
125 Sequence< OUString > GenericClipboard::getSupportedServiceNames()
126 {
127  return getSupportedServiceNames_static();
128 }
129 
130 sal_Bool GenericClipboard::supportsService( const OUString& ServiceName )
131 {
132  return cppu::supportsService(this, ServiceName);
133 }
134 
135 Reference< css::datatransfer::XTransferable > GenericClipboard::getContents()
136 {
137  return m_aContents;
138 }
139 
140 void GenericClipboard::setContents(
143 {
144  osl::ClearableMutexGuard aGuard( m_aMutex );
147  m_aContents = xTrans;
148  m_aOwner = xClipboardOwner;
149 
150  std::vector< Reference< datatransfer::clipboard::XClipboardListener > > aListeners( m_aListeners );
151  datatransfer::clipboard::ClipboardEvent aEv;
152  aEv.Contents = m_aContents;
153 
154  aGuard.clear();
155 
156  if( xOldOwner.is() && xOldOwner != xClipboardOwner )
157  xOldOwner->lostOwnership( this, xOldContents );
158  for (auto const& listener : aListeners)
159  {
160  listener->changedContents( aEv );
161  }
162 }
163 
164 OUString GenericClipboard::getName()
165 {
166  return "CLIPBOARD";
167 }
168 
169 sal_Int8 GenericClipboard::getRenderingCapabilities()
170 {
171  return 0;
172 }
173 
174 void GenericClipboard::addClipboardListener( const Reference< datatransfer::clipboard::XClipboardListener >& listener )
175 {
176  osl::MutexGuard aGuard(m_aMutex);
177 
178  m_aListeners.push_back( listener );
179 }
180 
181 void GenericClipboard::removeClipboardListener( const Reference< datatransfer::clipboard::XClipboardListener >& listener )
182 {
183  osl::MutexGuard aGuard(m_aMutex);
184 
185  m_aListeners.erase(std::remove(m_aListeners.begin(), m_aListeners.end(), listener), m_aListeners.end());
186 }
187 
188 namespace {
189 
190 class ClipboardFactory : public ::cppu::WeakComponentImplHelper<
191  css::lang::XSingleServiceFactory
192 >
193 {
194  osl::Mutex m_aMutex;
195 public:
196  ClipboardFactory();
197 
198  /*
199  * XSingleServiceFactory
200  */
201  virtual Reference< XInterface > SAL_CALL createInstance() override;
202  virtual Reference< XInterface > SAL_CALL createInstanceWithArguments( const Sequence< Any >& rArgs ) override;
203 };
204 
205 }
206 
207 ClipboardFactory::ClipboardFactory() :
208  cppu::WeakComponentImplHelper<
209  css::lang::XSingleServiceFactory
210 >( m_aMutex )
211 {
212 }
213 
214 Reference< XInterface > ClipboardFactory::createInstance()
215 {
216  return createInstanceWithArguments( Sequence< Any >() );
217 }
218 
219 Reference< XInterface > ClipboardFactory::createInstanceWithArguments( const Sequence< Any >& arguments )
220 {
221  SolarMutexGuard aGuard;
223  return xResult;
224 }
225 
227 {
228  return
229  #if defined MACOSX
230  "com.sun.star.datatransfer.clipboard.AquaClipboard"
231  #elif defined IOS
232  "com.sun.star.datatransfer.clipboard.iOSClipboard"
233  #elif defined ANDROID
234  "com.sun.star.datatransfer.VCLGenericClipboard"
235  #elif defined UNX
236  "com.sun.star.datatransfer.X11ClipboardSupport"
237  #else
238  "com.sun.star.datatransfer.VCLGenericClipboard"
239  #endif
240  ;
241 }
242 
244 {
245  return Reference< XSingleServiceFactory >( new ClipboardFactory() );
246 }
247 
248 namespace {
249 
250 /*
251 * generic DragSource dummy
252 */
253 class GenericDragSource : public cppu::WeakComponentImplHelper<
254  datatransfer::dnd::XDragSource,
255  XInitialization,
256  css::lang::XServiceInfo
257  >
258 {
259  osl::Mutex m_aMutex;
260 public:
261  GenericDragSource() : WeakComponentImplHelper( m_aMutex ) {}
262 
263  // XDragSource
264  virtual sal_Bool SAL_CALL isDragImageSupported() override;
265  virtual sal_Int32 SAL_CALL getDefaultCursor( sal_Int8 dragAction ) override;
266  virtual void SAL_CALL startDrag(
267  const datatransfer::dnd::DragGestureEvent& trigger,
268  sal_Int8 sourceActions, sal_Int32 cursor, sal_Int32 image,
269  const Reference< datatransfer::XTransferable >& transferable,
271  ) override;
272 
273  // XInitialization
274  virtual void SAL_CALL initialize( const Sequence< Any >& arguments ) override;
275 
276  OUString SAL_CALL getImplementationName() override
277  { return "com.sun.star.datatransfer.dnd.VclGenericDragSource"; }
278 
279  sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
280  { return cppu::supportsService(this, ServiceName); }
281 
282  css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
283  { return getSupportedServiceNames_static(); }
284 
285  static Sequence< OUString > getSupportedServiceNames_static()
286  {
287  return { "com.sun.star.datatransfer.dnd.GenericDragSource" };
288  }
289 };
290 
291 }
292 
293 sal_Bool GenericDragSource::isDragImageSupported()
294 {
295  return false;
296 }
297 
298 sal_Int32 GenericDragSource::getDefaultCursor( sal_Int8 )
299 {
300  return 0;
301 }
302 
303 void GenericDragSource::startDrag( const datatransfer::dnd::DragGestureEvent&,
304  sal_Int8 /*sourceActions*/, sal_Int32 /*cursor*/, sal_Int32 /*image*/,
307  )
308 {
309  datatransfer::dnd::DragSourceDropEvent aEv;
310  aEv.DropAction = datatransfer::dnd::DNDConstants::ACTION_COPY;
311  aEv.DropSuccess = false;
312  listener->dragDropEnd( aEv );
313 }
314 
315 void GenericDragSource::initialize( const Sequence< Any >& )
316 {
317 }
318 
320 {
321 #if defined MACOSX
322  return { "com.sun.star.datatransfer.dnd.OleDragSource" };
323 #elif defined UNX
324  return { "com.sun.star.datatransfer.dnd.X11DragSource" };
325 #else
326  return { "com.sun.star.datatransfer.dnd.VclGenericDragSource" };
327 #endif
328 }
329 
331 {
332 #if defined MACOSX
333  return "com.sun.star.comp.datatransfer.dnd.OleDragSource_V1";
334 #elif defined UNX
335  return "com.sun.star.datatransfer.dnd.XdndSupport";
336 #else
337  return "com.sun.star.datatransfer.dnd.VclGenericDragSource";
338 #endif
339 }
340 
342 {
343  SolarMutexGuard aGuard;
345  return xResult;
346 }
347 
348 /*
349 * generic DragSource dummy
350 */
351 
352 namespace {
353 
354 class GenericDropTarget : public cppu::WeakComponentImplHelper<
355  datatransfer::dnd::XDropTarget,
356  XInitialization,
357  css::lang::XServiceInfo
358  >
359 {
360  osl::Mutex m_aMutex;
361 public:
362  GenericDropTarget() : WeakComponentImplHelper( m_aMutex )
363  {}
364 
365  // XInitialization
366  virtual void SAL_CALL initialize( const Sequence< Any >& args ) override;
367 
368  // XDropTarget
369  virtual void SAL_CALL addDropTargetListener( const Reference< css::datatransfer::dnd::XDropTargetListener >& ) override;
370  virtual void SAL_CALL removeDropTargetListener( const Reference< css::datatransfer::dnd::XDropTargetListener >& ) override;
371  virtual sal_Bool SAL_CALL isActive() override;
372  virtual void SAL_CALL setActive( sal_Bool active ) override;
373  virtual sal_Int8 SAL_CALL getDefaultActions() override;
374  virtual void SAL_CALL setDefaultActions( sal_Int8 actions ) override;
375 
376  OUString SAL_CALL getImplementationName() override
377  { return "com.sun.star.datatransfer.dnd.VclGenericDropTarget"; }
378 
379  sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
380  { return cppu::supportsService(this, ServiceName); }
381 
382  css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
383  { return getSupportedServiceNames_static(); }
384 
385  static Sequence< OUString > getSupportedServiceNames_static()
386  {
387  return { "com.sun.star.datatransfer.dnd.GenericDropTarget" };
388  }
389 };
390 
391 }
392 
393 void GenericDropTarget::initialize( const Sequence< Any >& )
394 {
395 }
396 
397 void GenericDropTarget::addDropTargetListener( const Reference< css::datatransfer::dnd::XDropTargetListener >& )
398 {
399 }
400 
401 void GenericDropTarget::removeDropTargetListener( const Reference< css::datatransfer::dnd::XDropTargetListener >& )
402 {
403 }
404 
405 sal_Bool GenericDropTarget::isActive()
406 {
407  return false;
408 }
409 
410 void GenericDropTarget::setActive( sal_Bool )
411 {
412 }
413 
414 sal_Int8 GenericDropTarget::getDefaultActions()
415 {
416  return 0;
417 }
418 
419 void GenericDropTarget::setDefaultActions( sal_Int8)
420 {
421 }
422 
424 {
425 #if defined MACOSX
426  return { "com.sun.star.datatransfer.dnd.OleDropTarget" };
427 #elif defined UNX
428  return { "com.sun.star.datatransfer.dnd.X11DropTarget" };
429 #else
430  return GenericDropTarget::getSupportedServiceNames_static();
431 #endif
432 }
433 
435 {
436  return
437  #if defined MACOSX
438  "com.sun.star.comp.datatransfer.dnd.OleDropTarget_V1"
439  #elif defined UNX
440  "com.sun.star.datatransfer.dnd.XdndDropTarget"
441  #else
442  "com.sun.star.datatransfer.dnd.VclGenericDropTarget"
443  #endif
444  ;
445 }
446 
448 {
449  SolarMutexGuard aGuard;
451  return xResult;
452 }
453 
454 } // namespace vcl
455 
456 /*
457 * SalInstance generic
458 */
460 {
461  if (arguments.hasElements()) {
462  throw css::lang::IllegalArgumentException(
463  "non-empty SalInstance::CreateClipboard arguments", {}, -1);
464  }
466  // In LOK, each document view shall have its own clipboard instance, and the way that
467  // (happens to?) work is that apparently this function is called at most once for each such
468  // document view, so it is OK if we hand out a fresh instance on each call in LOK (whereas
469  // in non-LOK below we keep handing out one single instance; see also
470  // <https://lists.freedesktop.org/archives/libreoffice/2020-April/084824.html> "Re: Linux
471  // SAL_USE_VCLPLUGIN=svp and the clipboard"):
472  return Reference< XInterface >( static_cast<cppu::OWeakObject *>(new vcl::GenericClipboard()) );
473  }
475  if (!m_clipboard.is()) {
476  m_clipboard = static_cast<cppu::OWeakObject *>(new vcl::GenericClipboard());
477  }
478  return m_clipboard;
479 }
480 
482 {
483  return Reference< XInterface >( static_cast<cppu::OWeakObject *>(new vcl::GenericDragSource()) );
484 }
485 
487 {
488  return Reference< XInterface >( static_cast<cppu::OWeakObject *>(new vcl::GenericDropTarget()) );
489 }
490 
491 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual css::uno::Reference< css::uno::XInterface > CreateDropTarget()
Definition: dtranscomp.cxx:486
virtual css::uno::Reference< css::uno::XInterface > CreateClipboard(const css::uno::Sequence< css::uno::Any > &i_rArguments)
Definition: dtranscomp.cxx:459
signed char sal_Int8
Reference< XSingleServiceFactory > Clipboard_createFactory()
Definition: dtranscomp.cxx:243
OUString getImplementationName()
OUString DragSource_getImplementationName()
Definition: dtranscomp.cxx:330
std::vector< Reference< css::datatransfer::clipboard::XClipboardListener > > m_aListeners
Definition: dtranscomp.cxx:64
OUString Clipboard_getImplementationName()
Definition: dtranscomp.cxx:226
virtual css::uno::Reference< css::uno::XInterface > CreateDragSource()
Definition: dtranscomp.cxx:481
Reference< css::datatransfer::XTransferable > m_aContents
Definition: dtranscomp.cxx:62
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
Listeners aListeners
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:75
Sequence< OUString > DropTarget_getSupportedServiceNames()
Definition: dtranscomp.cxx:423
css::uno::Sequence< OUString > getSupportedServiceNames()
Reference< XInterface > DragSource_createInstance(const Reference< XMultiServiceFactory > &)
Definition: dtranscomp.cxx:341
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
unsigned char sal_Bool
Sequence< OUString > DragSource_getSupportedServiceNames()
Definition: dtranscomp.cxx:319
OUString DropTarget_getImplementationName()
Definition: dtranscomp.cxx:434
bool isActive()
void setActive(bool bActive)
#define DBG_TESTSOLARMUTEX()
osl::Mutex m_aMutex
Definition: dtranscomp.cxx:61
css::uno::Reference< css::uno::XInterface > m_clipboard
Definition: salinst.hxx:85
Reference< XInterface > DropTarget_createInstance(const Reference< XMultiServiceFactory > &)
Definition: dtranscomp.cxx:447
SalInstance * mpDefInst
Definition: svdata.hxx:382
Reference< css::datatransfer::clipboard::XClipboardOwner > m_aOwner
Definition: dtranscomp.cxx:63