]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/dnd.cpp
Added support for frames without borders (such as for
[wxWidgets.git] / src / gtk1 / dnd.cpp
CommitLineData
c801d85f
KB
1///////////////////////////////////////////////////////////////////////////////
2// Name: dnd.cpp
3// Purpose: wxDropTarget class
4// Author: Robert Roebling
01111366
RR
5// Id: $id$
6// Copyright: (c) 1998 Robert Roebling
7// Licence: wxWindows licence
c801d85f
KB
8///////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
11#pragma implementation "dnd.h"
12#endif
13
14#include "wx/dnd.h"
15#include "wx/window.h"
16#include "wx/app.h"
17#include "wx/gdicmn.h"
1a5a8367 18#include <wx/intl.h>
c801d85f
KB
19
20#include "gdk/gdkprivate.h"
21
22#include <X11/Xlib.h>
23
24// ----------------------------------------------------------------------------
25// global
26// ----------------------------------------------------------------------------
27
28extern bool g_blockEventsOnDrag;
29
30// ----------------------------------------------------------------------------
31// wxDropTarget
32// ----------------------------------------------------------------------------
33
34wxDropTarget::wxDropTarget()
35{
ff7b1510 36}
c801d85f
KB
37
38wxDropTarget::~wxDropTarget()
39{
ff7b1510 40}
c801d85f
KB
41
42void wxDropTarget::Drop( GdkEvent *event, int x, int y )
43{
44 printf( "Drop data is of type %s.\n", event->dropdataavailable.data_type );
45
46 OnDrop( x, y, (char *)event->dropdataavailable.data);
ff7b1510 47}
c801d85f
KB
48
49void wxDropTarget::UnregisterWidget( GtkWidget *widget )
50{
e3e65dac
RR
51 if (!widget) return;
52
c67daf87 53 gtk_widget_dnd_drop_set( widget, FALSE, (gchar **) NULL, 0, FALSE );
ff7b1510 54}
c801d85f 55
e3e65dac
RR
56void wxDropTarget::RegisterWidget( GtkWidget *widget )
57{
58 wxString formats;
59 int valid = 0;
60
c86f1403 61 for ( size_t i = 0; i < GetFormatCount(); i++ )
e3e65dac
RR
62 {
63 wxDataFormat df = GetFormat( i );
64 switch (df)
65 {
66 case wxDF_TEXT:
67 if (i > 0) formats += ";";
68 formats += "text/plain";
69 valid++;
70 break;
71 case wxDF_FILENAME:
72 if (i > 0) formats += ";";
61607c36 73 formats += "file:ALL";
e3e65dac
RR
74 valid++;
75 break;
76 default:
77 break;
ff7b1510 78 }
e3e65dac
RR
79 }
80
81 char *str = WXSTRINGCAST formats;
82
83 gtk_widget_dnd_drop_set( widget, TRUE, &str, valid, FALSE );
ff7b1510 84}
e3e65dac 85
c801d85f
KB
86// ----------------------------------------------------------------------------
87// wxTextDropTarget
88// ----------------------------------------------------------------------------
89
90bool wxTextDropTarget::OnDrop( long x, long y, const void *pData )
91{
92 OnDropText( x, y, (const char*)pData );
93 return TRUE;
ff7b1510 94}
c801d85f
KB
95
96bool wxTextDropTarget::OnDropText( long x, long y, const char *psz )
97{
98 printf( "Got dropped text: %s.\n", psz );
99 printf( "At x: %d, y: %d.\n", (int)x, (int)y );
100 return TRUE;
ff7b1510 101}
c801d85f 102
e3e65dac 103size_t wxTextDropTarget::GetFormatCount() const
c801d85f 104{
e3e65dac
RR
105 return 1;
106}
107
108wxDataFormat wxTextDropTarget::GetFormat(size_t WXUNUSED(n)) const
109{
110 return wxDF_TEXT;
111}
112
113// ----------------------------------------------------------------------------
114// wxFileDropTarget
115// ----------------------------------------------------------------------------
116
117bool wxFileDropTarget::OnDropFiles( long x, long y, size_t nFiles, const char * const WXUNUSED(aszFiles)[] )
118{
119 printf( "Got %d dropped files.\n", (int)nFiles );
120 printf( "At x: %d, y: %d.\n", (int)x, (int)y );
121 return TRUE;
122}
123
124bool wxFileDropTarget::OnDrop(long x, long y, const void *WXUNUSED(pData) )
125{
126 char *str = "/this/is/a/path.txt";
127
128 return OnDropFiles(x, y, 1, &str );
129}
130
131size_t wxFileDropTarget::GetFormatCount() const
132{
133 return 1;
134}
135
136wxDataFormat wxFileDropTarget::GetFormat(size_t WXUNUSED(n)) const
137{
138 return wxDF_FILENAME;
139}
c801d85f
KB
140
141//-------------------------------------------------------------------------
e3e65dac 142// wxDropSource
c801d85f
KB
143//-------------------------------------------------------------------------
144
145//-----------------------------------------------------------------------------
146// drag request
147
b6af8d80 148void gtk_drag_callback( GtkWidget *widget, GdkEvent *event, wxDropSource *source )
c801d85f 149{
e3e65dac
RR
150 printf( "Data requested for dropping.\n" );
151
b6af8d80
RR
152 wxDataObject *data = source->m_data;
153
c86f1403 154 size_t size = data->GetDataSize();
e3e65dac
RR
155 char *ptr = new char[size];
156 data->GetDataHere( ptr );
157
158 gtk_widget_dnd_data_set( widget, event, ptr, size );
c801d85f 159
e3e65dac 160 delete ptr;
b6af8d80 161
46ccb510 162 source->m_retValue = wxDragCopy;
ff7b1510 163}
c801d85f 164
e3e65dac 165wxDropSource::wxDropSource( wxWindow *win )
c801d85f
KB
166{
167 g_blockEventsOnDrag = TRUE;
e3e65dac 168
c801d85f
KB
169 m_window = win;
170 m_widget = win->m_widget;
171 if (win->m_wxwindow) m_widget = win->m_wxwindow;
c801d85f 172
c67daf87 173 m_data = (wxDataObject *) NULL;
46ccb510 174 m_retValue = wxDragCancel;
e3e65dac 175
c801d85f
KB
176 m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY );
177 m_goaheadCursor = wxCursor( wxCURSOR_HAND );
ff7b1510 178}
c801d85f 179
e3e65dac 180wxDropSource::wxDropSource( wxDataObject &data, wxWindow *win )
c801d85f 181{
e3e65dac
RR
182 g_blockEventsOnDrag = TRUE;
183
184 m_window = win;
185 m_widget = win->m_widget;
186 if (win->m_wxwindow) m_widget = win->m_wxwindow;
46ccb510 187 m_retValue = wxDragCancel;
e3e65dac
RR
188
189 m_data = &data;
190
191 m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY );
192 m_goaheadCursor = wxCursor( wxCURSOR_HAND );
ff7b1510 193}
e3e65dac
RR
194
195void wxDropSource::SetData( wxDataObject &data )
c801d85f 196{
e3e65dac 197 m_data = &data;
ff7b1510 198}
c801d85f 199
e3e65dac 200wxDropSource::~wxDropSource(void)
c801d85f 201{
e3e65dac
RR
202// if (m_data) delete m_data;
203
204 g_blockEventsOnDrag = FALSE;
ff7b1510 205}
e3e65dac 206
46ccb510 207wxDragResult wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove) )
e3e65dac 208{
46ccb510
JS
209 if (gdk_dnd.dnd_grabbed) return (wxDragResult) wxDragNone;
210 if (gdk_dnd.drag_really) return (wxDragResult) wxDragNone;
e3e65dac 211
f6d53978 212 wxASSERT_MSG( m_data, "wxDragSource: no data" );
b6af8d80 213
46ccb510
JS
214 if (!m_data) return (wxDragResult) wxDragNone;
215 if (m_data->GetDataSize() == 0) return (wxDragResult) wxDragNone;
c801d85f
KB
216
217 GdkWindowPrivate *wp = (GdkWindowPrivate*) m_widget->window;
218
219 RegisterWindow();
c801d85f
KB
220
221 gdk_dnd.drag_perhaps = TRUE;
222
223 gdk_dnd.dnd_drag_start.x = 5;
224 gdk_dnd.dnd_drag_start.y = 5;
225 gdk_dnd.real_sw = wp;
226
227 if (gdk_dnd.drag_startwindows)
228 {
229 g_free( gdk_dnd.drag_startwindows );
c67daf87 230 gdk_dnd.drag_startwindows = (GdkWindow **) NULL;
ff7b1510 231 }
c801d85f
KB
232 gdk_dnd.drag_numwindows = gdk_dnd.drag_really = 0;
233
234 XWindowAttributes dnd_winattr;
235 XGetWindowAttributes( gdk_display, wp->xwindow, &dnd_winattr );
236 wp->dnd_drag_savedeventmask = dnd_winattr.your_event_mask;
237
238 gdk_dnd_drag_addwindow( m_widget->window );
239
240 GdkEventDragBegin ev;
241 ev.type = GDK_DRAG_BEGIN;
242 ev.window = m_widget->window;
243 ev.u.allflags = 0;
244 ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
245
246 gdk_event_put( (GdkEvent*)&ev );
247
248 XGrabPointer( gdk_display, wp->xwindow, False,
249 ButtonMotionMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
250 GrabModeAsync, GrabModeAsync, gdk_root_window, None, CurrentTime );
251
252 gdk_dnd_set_drag_cursors( m_defaultCursor.GetCursor(), m_goaheadCursor.GetCursor() );
253
254 gdk_dnd.dnd_grabbed = TRUE;
255 gdk_dnd.drag_really = 1;
e3e65dac
RR
256
257 int x = 0;
258 int y = 0;
c67daf87 259 gdk_window_get_pointer( m_widget->window, &x, &y, (GdkModifierType *) NULL );
e3e65dac 260
c801d85f
KB
261 gdk_dnd_display_drag_cursor( x, y, FALSE, TRUE );
262
263 while (gdk_dnd.drag_really || gdk_dnd.drag_perhaps) wxYield();
264
c801d85f 265 UnregisterWindow();
e3e65dac 266
30dea054
RR
267 g_blockEventsOnDrag = FALSE;
268
b6af8d80 269 return m_retValue;
ff7b1510 270}
c801d85f 271
e3e65dac 272void wxDropSource::RegisterWindow(void)
c801d85f 273{
e3e65dac 274 if (!m_data) return;
c801d85f 275
e3e65dac
RR
276 wxString formats;
277
278 wxDataFormat df = m_data->GetPreferredFormat();
c801d85f 279
e3e65dac
RR
280 switch (df)
281 {
282 case wxDF_TEXT:
283 formats += "text/plain";
284 break;
285 case wxDF_FILENAME:
61607c36 286 formats += "file:ALL";
e3e65dac
RR
287 break;
288 default:
289 break;
290 }
c801d85f 291
e3e65dac 292 char *str = WXSTRINGCAST formats;
c801d85f 293
e3e65dac 294 gtk_widget_dnd_drag_set( m_widget, TRUE, &str, 1 );
c801d85f 295
e3e65dac 296 gtk_signal_connect( GTK_OBJECT(m_widget), "drag_request_event",
b6af8d80 297 GTK_SIGNAL_FUNC(gtk_drag_callback), (gpointer)this );
ff7b1510 298}
c801d85f 299
e3e65dac 300void wxDropSource::UnregisterWindow(void)
c801d85f
KB
301{
302 if (!m_widget) return;
303
c67daf87 304 gtk_widget_dnd_drag_set( m_widget, FALSE, (gchar **) NULL, 0 );
e3e65dac 305
b6af8d80 306 gtk_signal_disconnect_by_data( GTK_OBJECT(m_widget), (gpointer)this );
ff7b1510 307}