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 #ifndef INCLUDED_VCL_TRANSFER_HXX
21 #define INCLUDED_VCL_TRANSFER_HXX
23 #include <vcl/dllapi.h>
24 #include <tools/globname.hxx>
25 #include <tools/gen.hxx>
26 #include <tools/solar.h>
27 #include <sot/formats.hxx>
28 #include <sot/exchange.hxx>
29 #include <cppuhelper/implbase.hxx>
30 #include <com/sun/star/frame/XTerminateListener.hpp>
31 #include <com/sun/star/lang/XServiceInfo.hpp>
32 #include <com/sun/star/datatransfer/XTransferable2.hpp>
33 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
34 #include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp>
35 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
36 #include <com/sun/star/datatransfer/dnd/XDragGestureListener.hpp>
37 #include <com/sun/star/datatransfer/dnd/DropTargetDragEvent.hpp>
38 #include <com/sun/star/datatransfer/dnd/DropTargetDropEvent.hpp>
39 #include <com/sun/star/datatransfer/dnd/XDragSourceListener.hpp>
40 #include <com/sun/star/datatransfer/dnd/XDropTargetListener.hpp>
41 #include <com/sun/star/embed/Aspects.hpp>
46 namespace com::sun::star::datatransfer::dnd
{ class XDragGestureRecognizer
; }
47 namespace com::sun::star::io
{ class XInputStream
; }
48 namespace com::sun::star::datatransfer::dnd
{ class XDropTarget
; }
50 namespace tools
{ template <typename T
> class SvRef
; }
51 template <typename Arg
, typename Ret
> class Link
;
60 class SotStorageStream
;
61 namespace vcl
{ class Window
; }
65 #define DND_ACTION_NONE css::datatransfer::dnd::DNDConstants::ACTION_NONE
66 #define DND_ACTION_COPY css::datatransfer::dnd::DNDConstants::ACTION_COPY
67 #define DND_ACTION_MOVE css::datatransfer::dnd::DNDConstants::ACTION_MOVE
68 #define DND_ACTION_COPYMOVE css::datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE
69 #define DND_ACTION_LINK css::datatransfer::dnd::DNDConstants::ACTION_LINK
71 #define DND_POINTER_NONE 0
72 #define DND_IMAGE_NONE 0
74 struct TransferableObjectDescriptor
76 SvGlobalName maClassName
;
77 sal_uInt16 mnViewAspect
;
81 OUString maDisplayName
;
83 TransferableObjectDescriptor()
84 : mnViewAspect(css::embed::Aspects::MSOLE_CONTENT
)
87 VCL_DLLPUBLIC
friend SvStream
& WriteTransferableObjectDescriptor( SvStream
& rOStm
, const TransferableObjectDescriptor
& rObjDesc
);
90 struct AcceptDropEvent
93 const css::datatransfer::dnd::DropTargetDragEvent maDragEvent
;
99 mnAction( DND_ACTION_NONE
),
101 mbDefault( false ) {}
103 AcceptDropEvent( sal_Int8 nAction
,
104 const Point
& rPosPixel
,
105 css::datatransfer::dnd::DropTargetDragEvent aDragEvent
) :
106 maPosPixel( rPosPixel
),
107 maDragEvent(std::move( aDragEvent
)),
110 mbDefault( false ) {}
113 struct ExecuteDropEvent
116 const css::datatransfer::dnd::DropTargetDropEvent maDropEvent
;
120 ExecuteDropEvent( sal_Int8 nAction
,
121 const Point
& rPosPixel
,
122 css::datatransfer::dnd::DropTargetDropEvent aDropEvent
) :
123 maPosPixel( rPosPixel
),
124 maDropEvent(std::move( aDropEvent
)),
126 mbDefault( false ) {}
129 class VCL_DLLPUBLIC TransferableHelper
: public cppu::WeakImplHelper
< css::datatransfer::XTransferable2
,
130 css::datatransfer::clipboard::XClipboardOwner
,
131 css::datatransfer::dnd::XDragSourceListener
>
135 // nested class to implement the XTerminateListener interface
136 class SAL_DLLPRIVATE TerminateListener final
: public cppu::WeakImplHelper
< css::frame::XTerminateListener
, css::lang::XServiceInfo
>
140 TransferableHelper
& mrParent
;
145 virtual void SAL_CALL
disposing( const css::lang::EventObject
& Source
) override
;
147 // XTerminateListener
148 virtual void SAL_CALL
queryTermination( const css::lang::EventObject
& aEvent
) override
;
149 virtual void SAL_CALL
notifyTermination( const css::lang::EventObject
& aEvent
) override
;
152 virtual OUString SAL_CALL
getImplementationName() override
;
153 virtual sal_Bool SAL_CALL
supportsService( const OUString
& sServiceName
) override
;
154 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
158 TerminateListener( TransferableHelper
& rDropTargetHelper
);
159 virtual ~TerminateListener() override
;
162 friend class TransferableHelper::TerminateListener
;
167 OUString maLastFormat
;
168 mutable css::uno::Reference
< css::datatransfer::clipboard::XClipboard
> mxClipboard
;
169 css::uno::Reference
< css::frame::XTerminateListener
> mxTerminateListener
;
170 DataFlavorExVector maFormats
;
171 std::unique_ptr
<TransferableObjectDescriptor
> mxObjDesc
;
174 ~TransferableHelper();
176 const css::uno::Reference
< css::datatransfer::clipboard::XClipboard
>&
177 getOwnClipboard() const { return mxClipboard
; }
182 virtual css::uno::Any SAL_CALL
getTransferData( const css::datatransfer::DataFlavor
& rFlavor
) override
;
183 virtual css::uno::Sequence
< css::datatransfer::DataFlavor
> SAL_CALL
getTransferDataFlavors() override
;
184 virtual sal_Bool SAL_CALL
isDataFlavorSupported( const css::datatransfer::DataFlavor
& rFlavor
) override
;
187 virtual css::uno::Any SAL_CALL
getTransferData2(
188 const css::datatransfer::DataFlavor
& rFlavor
, const OUString
& rDestDoc
) override
;
189 virtual sal_Bool SAL_CALL
isComplex() override
;
194 virtual void SAL_CALL
disposing( const css::lang::EventObject
& Source
) override
;
196 // XDragSourceListener
197 virtual void SAL_CALL
dragDropEnd( const css::datatransfer::dnd::DragSourceDropEvent
& dsde
) override
;
198 virtual void SAL_CALL
dragEnter( const css::datatransfer::dnd::DragSourceDragEvent
& dsde
) override
;
199 virtual void SAL_CALL
dragExit( const css::datatransfer::dnd::DragSourceEvent
& dse
) override
;
200 virtual void SAL_CALL
dragOver( const css::datatransfer::dnd::DragSourceDragEvent
& dsde
) override
;
201 virtual void SAL_CALL
dropActionChanged( const css::datatransfer::dnd::DragSourceDragEvent
& dsde
) override
;
204 virtual void SAL_CALL
lostOwnership( const css::uno::Reference
< css::datatransfer::clipboard::XClipboard
>& xClipboard
, const css::uno::Reference
< css::datatransfer::XTransferable
>& xTrans
) override
;
207 // derivees need to access lostOwnership in case hey override it
208 // on windows, changing the access rights to a method gives unresolved externals, so we introduce
209 // this impl-method here 'til the next incompatible update
210 void implCallOwnLostOwnership(
211 const css::uno::Reference
< css::datatransfer::clipboard::XClipboard
>& _rxClipboard
,
212 const css::uno::Reference
< css::datatransfer::XTransferable
>& _rxTrans
215 TransferableHelper::lostOwnership( _rxClipboard
, _rxTrans
);
221 SAL_DLLPRIVATE
void ImplFlush();
225 void AddFormat( SotClipboardFormatId nFormat
);
226 void AddFormat( const css::datatransfer::DataFlavor
& rFlavor
);
227 void RemoveFormat( SotClipboardFormatId nFormat
);
228 void RemoveFormat( const css::datatransfer::DataFlavor
& rFlavor
);
229 bool HasFormat( SotClipboardFormatId nFormat
);
232 bool SetAny( const css::uno::Any
& rAny
);
233 bool SetString( const OUString
& rString
);
234 bool SetBitmapEx( const BitmapEx
& rBitmap
, const css::datatransfer::DataFlavor
& rFlavor
);
235 bool SetGDIMetaFile( const GDIMetaFile
& rMtf
);
236 bool SetGraphic( const Graphic
& rGraphic
);
237 bool SetImageMap( const ImageMap
& rIMap
);
238 bool SetTransferableObjectDescriptor( const TransferableObjectDescriptor
& rDesc
);
239 bool SetINetBookmark( const INetBookmark
& rBmk
, const css::datatransfer::DataFlavor
& rFlavor
);
240 bool SetINetImage( const INetImage
& rINtImg
, const css::datatransfer::DataFlavor
& rFlavor
);
241 bool SetObject( void* pUserObject
, sal_uInt32 nUserObjectId
, const css::datatransfer::DataFlavor
& rFlavor
);
245 virtual void AddSupportedFormats() = 0;
246 virtual bool GetData( const css::datatransfer::DataFlavor
& rFlavor
, const OUString
& rDestDoc
) = 0;
247 virtual bool WriteObject( SvStream
& rOStm
, void* pUserObject
, sal_uInt32 nUserObjectId
, const css::datatransfer::DataFlavor
& rFlavor
);
248 virtual void DragFinished( sal_Int8 nDropAction
);
249 virtual void ObjectReleased();
251 void CopyToSelection(const css::uno::Reference
<css::datatransfer::clipboard::XClipboard
> &rClipboard
) const;
254 void PrepareOLE( const TransferableObjectDescriptor
& rObjDesc
);
256 void CopyToClipboard(const css::uno::Reference
<css::datatransfer::clipboard::XClipboard
> &rClipboard
) const;
258 // convenience versions of the above which extract the XClipboard from the pWindow
259 void CopyToClipboard( vcl::Window
*pWindow
) const;
260 void CopyToPrimarySelection() const;
262 void StartDrag( vcl::Window
* pWindow
, sal_Int8 nDragSourceActions
);
264 static void ClearPrimarySelection();
267 struct TransferableDataHelper_Impl
;
269 class VCL_DLLPUBLIC TransferableDataHelper final
271 friend class DropTargetHelper
;
273 css::uno::Reference
< css::datatransfer::XTransferable
> mxTransfer
;
274 css::uno::Reference
< css::datatransfer::clipboard::XClipboard
> mxClipboard
;
275 DataFlavorExVector maFormats
;
276 std::unique_ptr
<TransferableObjectDescriptor
> mxObjDesc
;
277 std::unique_ptr
<TransferableDataHelper_Impl
> mxImpl
;
283 static void FillDataFlavorExVector( const css::uno::Sequence
< css::datatransfer::DataFlavor
>& rDataFlavorSeq
,
284 DataFlavorExVector
& rDataFlavorExVector
);
286 TransferableDataHelper();
287 TransferableDataHelper( const TransferableDataHelper
& rDataHelper
);
288 TransferableDataHelper( TransferableDataHelper
&& rDataHelper
) noexcept
;
289 TransferableDataHelper( const css::uno::Reference
< css::datatransfer::XTransferable
>& rxTransferable
);
290 ~TransferableDataHelper();
292 TransferableDataHelper
& operator=( const TransferableDataHelper
& rDataHelper
);
293 TransferableDataHelper
& operator=( TransferableDataHelper
&& rDataHelper
);
295 const css::uno::Reference
< css::datatransfer::XTransferable
>& GetTransferable() const { return mxTransfer
; }
296 css::uno::Reference
< css::datatransfer::XTransferable
> GetXTransferable() const;
298 bool HasFormat( SotClipboardFormatId nFormat
) const;
299 bool HasFormat( const css::datatransfer::DataFlavor
& rFlavor
) const;
301 sal_uInt32
GetFormatCount() const;
303 SotClipboardFormatId
GetFormat( sal_uInt32 nFormat
) const;
304 css::datatransfer::DataFlavor
GetFormatDataFlavor( sal_uInt32 nFormat
) const;
306 const DataFlavorExVector
& GetDataFlavorExVector() const {return maFormats
; }
308 bool StartClipboardListening( );
309 void StopClipboardListening( );
311 void Rebind( const css::uno::Reference
< css::datatransfer::XTransferable
>& _rxNewData
);
313 css::uno::Any
GetAny( SotClipboardFormatId nFormat
, const OUString
& rDestDoc
) const;
314 css::uno::Any
GetAny( const css::datatransfer::DataFlavor
& rFlavor
, const OUString
& rDestDoc
) const;
316 bool GetString( SotClipboardFormatId nFormat
, OUString
& rStr
) const;
317 bool GetString( const css::datatransfer::DataFlavor
& rFlavor
, OUString
& rStr
) const;
319 bool GetBitmapEx( SotClipboardFormatId nFormat
, BitmapEx
& rBmp
) const;
320 bool GetBitmapEx( const css::datatransfer::DataFlavor
& rFlavor
, BitmapEx
& rBmp
) const;
322 /** Return as GDI metafile.
324 @param nMaxAction Allows you to limit the amount of actions; defaults to 0 which means no limit.
326 When you eg. Ctrl+a in Excel, you can get the entire sheet as
327 metafile, with over 3 million (!) actions; which is just too large for
328 any reasonable handling - and you need to set a limit.
330 bool GetGDIMetaFile( SotClipboardFormatId nFormat
, GDIMetaFile
& rMtf
, size_t nMaxActions
= 0 ) const;
331 bool GetGDIMetaFile( const css::datatransfer::DataFlavor
& rFlavor
, GDIMetaFile
& rMtf
) const;
333 bool GetGraphic( SotClipboardFormatId nFormat
, Graphic
& rGraphic
) const;
334 bool GetGraphic( const css::datatransfer::DataFlavor
& rFlavor
, Graphic
& rGraphic
) const;
336 bool GetImageMap( SotClipboardFormatId nFormat
, ImageMap
& rIMap
) const;
337 bool GetImageMap( const css::datatransfer::DataFlavor
& rFlavor
, ImageMap
& rImap
) const;
339 bool GetTransferableObjectDescriptor( SotClipboardFormatId nFormat
, TransferableObjectDescriptor
& rDesc
) const;
340 bool GetTransferableObjectDescriptor( TransferableObjectDescriptor
& rDesc
) const;
342 bool GetINetBookmark( SotClipboardFormatId nFormat
, INetBookmark
& rBmk
) const;
343 bool GetINetBookmark( const css::datatransfer::DataFlavor
& rFlavor
, INetBookmark
& rBmk
) const;
345 bool GetINetImage( SotClipboardFormatId nFormat
, INetImage
& rINtImg
) const;
346 bool GetINetImage( const css::datatransfer::DataFlavor
& rFlavor
, INetImage
& rINtImg
) const;
348 bool GetFileList( SotClipboardFormatId nFormat
, FileList
& rFileList
) const;
349 bool GetFileList( FileList
& rFileList
) const;
351 css::uno::Sequence
<sal_Int8
> GetSequence( SotClipboardFormatId nFormat
, const OUString
& rDestDoc
) const;
352 css::uno::Sequence
<sal_Int8
> GetSequence( const css::datatransfer::DataFlavor
& rFlavor
, const OUString
& rDestDoc
) const;
354 std::unique_ptr
<SvStream
> GetSotStorageStream( SotClipboardFormatId nFormat
) const;
355 std::unique_ptr
<SvStream
> GetSotStorageStream( const css::datatransfer::DataFlavor
& rFlavor
) const;
357 css::uno::Reference
<css::io::XInputStream
> GetInputStream( SotClipboardFormatId nFormat
, const OUString
& rDestDoc
) const;
358 css::uno::Reference
<css::io::XInputStream
> GetInputStream( const css::datatransfer::DataFlavor
& rFlavor
, const OUString
& rDestDoc
) const;
360 static TransferableDataHelper
CreateFromClipboard(const css::uno::Reference
<css::datatransfer::clipboard::XClipboard
>& rClipboard
);
361 static TransferableDataHelper
CreateFromSystemClipboard( vcl::Window
* pWindow
);
362 static TransferableDataHelper
CreateFromPrimarySelection();
363 static bool IsEqual( const css::datatransfer::DataFlavor
& rInternalFlavor
,
364 const css::datatransfer::DataFlavor
& rRequestFlavor
);
365 static bool WriteDDELink(SvStream
& stream
, std::u16string_view application
,
366 std::u16string_view topic
, std::u16string_view item
,
367 std::u16string_view extra
= {});
368 bool ReadDDELink(OUString
& application
, OUString
& topic
, OUString
& item
, OUString
& rest
) const;
371 class VCL_DLLPUBLIC
SAL_LOPLUGIN_ANNOTATE("crosscast") DragSourceHelper
375 // nested class to implement the XDragGestureListener interface
376 class SAL_DLLPRIVATE DragGestureListener final
: public cppu::WeakImplHelper
< css::datatransfer::dnd::XDragGestureListener
>
380 DragSourceHelper
& mrParent
;
385 virtual void SAL_CALL
disposing( const css::lang::EventObject
& Source
) override
;
387 // XDragGestureListener
388 virtual void SAL_CALL
dragGestureRecognized( const css::datatransfer::dnd::DragGestureEvent
& rDGE
) override
;
392 DragGestureListener( DragSourceHelper
& rDragSourceHelper
);
393 virtual ~DragGestureListener() override
;
396 friend class DragSourceHelper::DragGestureListener
;
400 css::uno::Reference
< css::datatransfer::dnd::XDragGestureRecognizer
> mxDragGestureRecognizer
;
402 css::uno::Reference
< css::datatransfer::dnd::XDragGestureListener
> mxDragGestureListener
;
404 DragSourceHelper
& operator=( const DragSourceHelper
& rDragSourceHelper
) = delete;
405 bool operator==( const DragSourceHelper
& rDragSourceHelper
) const = delete;
409 // to be overridden by the application
410 virtual void StartDrag( sal_Int8 nAction
, const Point
& rPosPixel
);
412 DragSourceHelper( vcl::Window
* pWindow
);
414 virtual ~DragSourceHelper();
417 class VCL_DLLPUBLIC
SAL_LOPLUGIN_ANNOTATE("crosscast") DropTargetHelper
421 // nested class to implement the XDropTargetListener interface
422 class SAL_DLLPRIVATE DropTargetListener final
: public cppu::WeakImplHelper
< css::datatransfer::dnd::XDropTargetListener
>
426 DropTargetHelper
& mrParent
;
427 std::unique_ptr
<AcceptDropEvent
> mpLastDragOverEvent
;
430 virtual void SAL_CALL
disposing( const css::lang::EventObject
& Source
) override
;
432 // XDropTargetListener
433 virtual void SAL_CALL
drop( const css::datatransfer::dnd::DropTargetDropEvent
& dtde
) override
;
434 virtual void SAL_CALL
dragEnter( const css::datatransfer::dnd::DropTargetDragEnterEvent
& dtdee
) override
;
435 virtual void SAL_CALL
dragExit( const css::datatransfer::dnd::DropTargetEvent
& dte
) override
;
436 virtual void SAL_CALL
dragOver( const css::datatransfer::dnd::DropTargetDragEvent
& dtde
) override
;
437 virtual void SAL_CALL
dropActionChanged( const css::datatransfer::dnd::DropTargetDragEvent
& dtde
) override
;
441 DropTargetListener( DropTargetHelper
& rDropTargetHelper
);
442 virtual ~DropTargetListener() override
;
445 friend class DropTargetHelper::DropTargetListener
;
449 css::uno::Reference
< css::datatransfer::dnd::XDropTarget
> mxDropTarget
;
451 css::uno::Reference
< css::datatransfer::dnd::XDropTargetListener
> mxDropTargetListener
;
452 DataFlavorExVector maFormats
;
454 DropTargetHelper() = delete;
455 DropTargetHelper
& operator=( const DropTargetHelper
& rDropTargetHelper
) = delete;
456 bool operator==( const DropTargetHelper
& rDropTargetHelper
) const = delete;
458 void ImplConstruct();
460 // called by our own implementation of XDropTargetListener (DropTargetListener instance)
461 SAL_DLLPRIVATE
void ImplBeginDrag( const css::uno::Sequence
< css::datatransfer::DataFlavor
>& rSupportedDataFlavors
);
462 SAL_DLLPRIVATE
void ImplEndDrag();
466 // to be overridden by the application
467 SAL_DLLPRIVATE
virtual sal_Int8
AcceptDrop( const AcceptDropEvent
& rEvt
);
468 SAL_DLLPRIVATE
virtual sal_Int8
ExecuteDrop( const ExecuteDropEvent
& rEvt
);
470 DropTargetHelper( vcl::Window
* pWindow
);
471 DropTargetHelper( const css::uno::Reference
< css::datatransfer::dnd::XDropTarget
>& rxDropTarget
);
474 virtual ~DropTargetHelper();
476 // typically called by the application in ::AcceptDrop and ::ExecuteDrop and (see above)
477 bool IsDropFormatSupported(SotClipboardFormatId nFormat
) const;
479 const DataFlavorExVector
& GetDataFlavorExVector() const {return maFormats
; }
483 struct TransferDataContainer_Impl
;
485 class VCL_DLLPUBLIC TransferDataContainer
: public TransferableHelper
487 std::unique_ptr
<TransferDataContainer_Impl
> pImpl
;
489 virtual void AddSupportedFormats() override
;
490 virtual bool GetData( const css::datatransfer::DataFlavor
& rFlavor
, const OUString
& rDestDoc
) override
;
494 TransferDataContainer();
495 virtual ~TransferDataContainer() override
;
497 void CopyINetBookmark( const INetBookmark
& rBkmk
);
498 void CopyString( const OUString
& rStr
);
499 void CopyString( SotClipboardFormatId nFmt
, const OUString
& rStr
);
501 void CopyByteString( SotClipboardFormatId nFormatId
, const OString
& rStr
);
502 void CopyAnyData( SotClipboardFormatId nFormatId
, const char* pData
, sal_uLong nLen
);
504 bool HasAnyData() const;
506 using TransferableHelper::StartDrag
;
507 void StartDrag( vcl::Window
* pWindow
, sal_Int8 nDragSourceActions
,
508 const Link
<sal_Int8
,void>& rCallback
);
509 virtual void DragFinished( sal_Int8 nDropAction
) override
;
512 css::uno::Reference
<css::datatransfer::clipboard::XClipboard
> VCL_DLLPUBLIC
GetSystemClipboard();
513 css::uno::Reference
<css::datatransfer::clipboard::XClipboard
> VCL_DLLPUBLIC
GetSystemPrimarySelection();
517 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */