diff options
author | Caolán McNamara <caolanm@redhat.com> | 2016-01-23 21:10:03 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2016-01-26 13:25:16 +0000 |
commit | 0b354d18ccfc05e7c2582f851d9201e2aa353d7d (patch) | |
tree | f69493f977b915f8cd14f693b7052ae3e02b3120 /vcl/inc | |
parent | 93fdb8dc67bf04c7a1e22c8dd15152212799c4f2 (diff) |
Related: tdf#93054 gtk3: implement enough dnd to be dragged into...
from another application, e.g. text from gedit or a standalone
image (view image) from firefox
Change-Id: I68b82217eb2513cedc096f5ff653fb7c75b48052
Diffstat (limited to 'vcl/inc')
-rw-r--r-- | vcl/inc/unx/gtk/gtkframe.hxx | 30 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gtkinst.hxx | 81 |
2 files changed, 111 insertions, 0 deletions
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index fbf84e053147..584a2ab96922 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -54,6 +54,8 @@ typedef ::Window GdkNativeWindow; #define GDK_WINDOW_XWINDOW(o) GDK_WINDOW_XID(o) #define gdk_set_sm_client_id(i) gdk_x11_set_sm_client_id(i) #define gdk_window_foreign_new_for_display(a,b) gdk_x11_window_foreign_new_for_display(a,b) +class GtkDropTarget; +class GtkDnDTransferable; #endif #if !(GLIB_MAJOR_VERSION > 2 || GLIB_MINOR_VERSION >= 26) @@ -206,6 +208,9 @@ class GtkSalFrame : public SalFrame long m_nWidthRequest; long m_nHeightRequest; cairo_region_t* m_pRegion; + GtkDropTarget* m_pDropTarget; + bool m_bInDrag; + GtkDnDTransferable* m_pFormatConversionRequest; #else GdkRegion* m_pRegion; #endif @@ -237,6 +242,13 @@ class GtkSalFrame : public SalFrame static gboolean signalTooltipQuery(GtkWidget*, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer frame); + static gboolean signalDragMotion(GtkWidget *widget, GdkDragContext *context, gint x, gint y, + guint time, gpointer frame); + static gboolean signalDragDrop(GtkWidget* widget, GdkDragContext *context, gint x, gint y, + guint time, gpointer frame); + static void signalDragDropReceived(GtkWidget *widget, GdkDragContext *context, gint x, gint y, + GtkSelectionData *data, guint ttype, guint time, gpointer frame); + static void signalDragLeave(GtkWidget *widget, GdkDragContext *context, guint time, gpointer frame); #if GTK_CHECK_VERSION(3,14,0) static void gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, gdouble velocity_y, gpointer frame); static void gestureLongPress(GtkGestureLongPress* gesture, gpointer frame); @@ -360,6 +372,24 @@ public: cairo_t* getCairoContext() const; void damaged(sal_Int32 nExtentsLeft, sal_Int32 nExtentsTop, sal_Int32 nExtentsRight, sal_Int32 nExtentsBottom) const; + + void registerDropTarget(GtkDropTarget* pDropTarget) + { + assert(!m_pDropTarget); + m_pDropTarget = pDropTarget; + } + + void deregisterDropTarget(GtkDropTarget* pDropTarget) + { + assert(m_pDropTarget == pDropTarget); (void)pDropTarget; + m_pDropTarget = nullptr; + } + + void SetFormatConversionRequest(GtkDnDTransferable *pRequest) + { + m_pFormatConversionRequest = pRequest; + } + #endif virtual ~GtkSalFrame(); diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx index adcb142e21ac..a2f8f78943dc 100644 --- a/vcl/inc/unx/gtk/gtkinst.hxx +++ b/vcl/inc/unx/gtk/gtkinst.hxx @@ -23,6 +23,11 @@ #include <unx/salinst.h> #include <unx/gensys.h> #include <headless/svpinst.hxx> +#include <com/sun/star/datatransfer/DataFlavor.hpp> +#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/compbase.hxx> #include <gtk/gtk.h> namespace vcl @@ -44,6 +49,82 @@ public: void ThreadsLeave(); }; +#if GTK_CHECK_VERSION(3,0,0) +class GtkSalFrame; + +struct VclToGtkHelper +{ + std::vector<css::datatransfer::DataFlavor> aInfoToFlavor; + std::vector<GtkTargetEntry> FormatsToGtk(const css::uno::Sequence<css::datatransfer::DataFlavor> &rFormats); +private: + GtkTargetEntry makeGtkTargetEntry(const css::datatransfer::DataFlavor& rFlavor); +}; + +class GtkTransferable : public cppu::WeakImplHelper<css::datatransfer::XTransferable> +{ +protected: + std::map<OUString, GdkAtom> m_aMimeTypeToAtom; + + std::vector<css::datatransfer::DataFlavor> getTransferDataFlavorsAsVector(GdkAtom *targets, gint n_targets); +public: + + virtual css::uno::Any SAL_CALL getTransferData(const css::datatransfer::DataFlavor& rFlavor) + throw(css::datatransfer::UnsupportedFlavorException, + css::io::IOException, + css::uno::RuntimeException, std::exception) override = 0; + + virtual std::vector<css::datatransfer::DataFlavor> getTransferDataFlavorsAsVector() = 0; + + virtual css::uno::Sequence<css::datatransfer::DataFlavor> SAL_CALL getTransferDataFlavors() + throw(css::uno::RuntimeException, std::exception) override; + virtual sal_Bool SAL_CALL isDataFlavorSupported(const css::datatransfer::DataFlavor& rFlavor) + throw(css::uno::RuntimeException, std::exception) override; +}; + +class GtkDropTarget : public cppu::WeakComponentImplHelper<css::datatransfer::dnd::XDropTarget, + css::lang::XInitialization, + css::lang::XServiceInfo> +{ + osl::Mutex m_aMutex; + GtkSalFrame* m_pFrame; + bool m_bActive; + sal_Int8 m_nDefaultActions; + std::list<css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>> m_aListeners; +public: + GtkDropTarget(); + virtual ~GtkDropTarget(); + + // XInitialization + virtual void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& rArgs) + throw (css::uno::Exception, std::exception) override; + void deinitialize(); + + // XDropTarget + virtual void SAL_CALL addDropTargetListener(const css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>&) + throw (std::exception) override; + virtual void SAL_CALL removeDropTargetListener(const css::uno::Reference<css::datatransfer::dnd::XDropTargetListener>&) + throw (std::exception) override; + virtual sal_Bool SAL_CALL isActive() throw(std::exception) override; + virtual void SAL_CALL setActive(sal_Bool active) throw(std::exception) override; + virtual sal_Int8 SAL_CALL getDefaultActions() throw(std::exception) override; + virtual void SAL_CALL setDefaultActions(sal_Int8 actions) throw(std::exception) override; + + OUString SAL_CALL getImplementationName() + throw (css::uno::RuntimeException, std::exception) override; + + sal_Bool SAL_CALL supportsService(OUString const & ServiceName) + throw (css::uno::RuntimeException, std::exception) override; + + css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() + throw (css::uno::RuntimeException, std::exception) override; + + void fire_dragEnter(const css::datatransfer::dnd::DropTargetDragEnterEvent& dtdee); + void fire_dragOver(const css::datatransfer::dnd::DropTargetDragEvent& dtde); + void fire_drop(const css::datatransfer::dnd::DropTargetDropEvent& dtde); + void fire_dragExit(const css::datatransfer::dnd::DropTargetEvent& dte); +}; +#endif + class GtkSalTimer; #if GTK_CHECK_VERSION(3,0,0) class GtkInstance : public SvpSalInstance |