1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxDropTarget class
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "dnd.h"
15 #include "wx/window.h"
17 #include "wx/gdicmn.h"
20 #include "gdk/gdkprivate.h"
24 // ----------------------------------------------------------------------------
26 // ----------------------------------------------------------------------------
28 extern bool g_blockEventsOnDrag
;
31 #if (GTK_MINOR_VERSION == 1)
32 #if (GTK_MICRO_VERSION >= 3)
33 #define NEW_GTK_DND_CODE
37 #ifdef NEW_GTK_DND_CODE
39 wxDropTarget::wxDropTarget()
43 wxDropTarget::~wxDropTarget()
47 void wxDropTarget::UnregisterWidget( GtkWidget
*widget
)
54 void wxDropTarget::RegisterWidget( GtkWidget
*widget
)
61 for ( size_t i
= 0; i
< GetFormatCount(); i
++ )
63 wxDataFormat df
= GetFormat( i
);
67 if (i
> 0) formats
+= ";";
68 formats
+= "text/plain";
72 if (i
> 0) formats
+= ";";
73 formats
+= "file:ALL";
81 char *str
= WXSTRINGCAST formats
;
86 // ----------------------------------------------------------------------------
88 // ----------------------------------------------------------------------------
90 bool wxTextDropTarget::OnDrop( long x
, long y
, const void *data
, size_t WXUNUSED(size
) )
92 OnDropText( x
, y
, (const char*)data
);
96 bool wxTextDropTarget::OnDropText( long x
, long y
, const char *psz
)
98 printf( "Got dropped text: %s.\n", psz
);
99 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
103 size_t wxTextDropTarget::GetFormatCount() const
108 wxDataFormat
wxTextDropTarget::GetFormat(size_t WXUNUSED(n
)) const
113 // ----------------------------------------------------------------------------
115 // ----------------------------------------------------------------------------
117 bool wxFileDropTarget::OnDropFiles( long x
, long y
, size_t nFiles
, const char * const aszFiles
[] )
119 printf( "Got %d dropped files.\n", (int)nFiles
);
120 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
121 for (size_t i
= 0; i
< nFiles
; i
++)
123 printf( aszFiles
[i
] );
129 bool wxFileDropTarget::OnDrop(long x
, long y
, const void *data
, size_t size
)
132 char *text
= (char*) data
;
133 for (size_t i
= 0; i
< size
; i
++)
134 if (text
[i
] == 0) number
++;
136 if (number
== 0) return TRUE
;
138 char **files
= new char*[number
];
141 for (size_t i
= 0; i
< number
; i
++)
144 int len
= strlen( text
);
148 bool ret
= OnDropFiles( x
, y
, 1, files
);
155 size_t wxFileDropTarget::GetFormatCount() const
160 wxDataFormat
wxFileDropTarget::GetFormat(size_t WXUNUSED(n
)) const
162 return wxDF_FILENAME
;
165 //-------------------------------------------------------------------------
167 //-------------------------------------------------------------------------
169 wxDropSource::wxDropSource( wxWindow
*win
)
171 g_blockEventsOnDrag
= TRUE
;
174 m_widget
= win
->m_widget
;
175 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
177 m_data
= (wxDataObject
*) NULL
;
178 m_retValue
= wxDragCancel
;
180 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
181 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
184 wxDropSource::wxDropSource( wxDataObject
&data
, wxWindow
*win
)
186 g_blockEventsOnDrag
= TRUE
;
189 m_widget
= win
->m_widget
;
190 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
191 m_retValue
= wxDragCancel
;
195 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
196 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
199 void wxDropSource::SetData( wxDataObject
&data
)
204 wxDropSource::~wxDropSource(void)
206 // if (m_data) delete m_data;
208 g_blockEventsOnDrag
= FALSE
;
211 wxDragResult
wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove
) )
213 wxASSERT_MSG( m_data
, "wxDragSource: no data" );
215 if (!m_data
) return (wxDragResult
) wxDragNone
;
216 if (m_data
->GetDataSize() == 0) return (wxDragResult
) wxDragNone
;
224 g_blockEventsOnDrag
= FALSE
;
229 void wxDropSource::RegisterWindow(void)
235 wxDataFormat df
= m_data
->GetPreferredFormat();
240 formats
+= "text/plain";
243 formats
+= "file:ALL";
249 char *str
= WXSTRINGCAST formats
;
254 void wxDropSource::UnregisterWindow(void)
256 if (!m_widget
) return;
263 // ----------------------------------------------------------------------------
265 // ----------------------------------------------------------------------------
267 wxDropTarget::wxDropTarget()
271 wxDropTarget::~wxDropTarget()
275 void wxDropTarget::UnregisterWidget( GtkWidget
*widget
)
279 gtk_widget_dnd_drop_set( widget
, FALSE
, (gchar
**) NULL
, 0, FALSE
);
282 void wxDropTarget::RegisterWidget( GtkWidget
*widget
)
287 for ( size_t i
= 0; i
< GetFormatCount(); i
++ )
289 wxDataFormat df
= GetFormat( i
);
293 if (i
> 0) formats
+= ";";
294 formats
+= "text/plain";
298 if (i
> 0) formats
+= ";";
299 formats
+= "file:ALL";
307 char *str
= WXSTRINGCAST formats
;
309 gtk_widget_dnd_drop_set( widget
, TRUE
, &str
, valid
, FALSE
);
312 // ----------------------------------------------------------------------------
314 // ----------------------------------------------------------------------------
316 bool wxTextDropTarget::OnDrop( long x
, long y
, const void *data
, size_t WXUNUSED(size
) )
318 OnDropText( x
, y
, (const char*)data
);
322 bool wxTextDropTarget::OnDropText( long x
, long y
, const char *psz
)
324 printf( "Got dropped text: %s.\n", psz
);
325 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
329 size_t wxTextDropTarget::GetFormatCount() const
334 wxDataFormat
wxTextDropTarget::GetFormat(size_t WXUNUSED(n
)) const
339 // ----------------------------------------------------------------------------
341 // ----------------------------------------------------------------------------
343 bool wxFileDropTarget::OnDropFiles( long x
, long y
, size_t nFiles
, const char * const aszFiles
[] )
345 printf( "Got %d dropped files.\n", (int)nFiles
);
346 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
347 for (size_t i
= 0; i
< nFiles
; i
++)
349 printf( aszFiles
[i
] );
355 bool wxFileDropTarget::OnDrop(long x
, long y
, const void *data
, size_t size
)
358 char *text
= (char*) data
;
359 for (size_t i
= 0; i
< size
; i
++)
360 if (text
[i
] == 0) number
++;
362 if (number
== 0) return TRUE
;
364 char **files
= new char*[number
];
367 for (size_t i
= 0; i
< number
; i
++)
370 int len
= strlen( text
);
374 bool ret
= OnDropFiles( x
, y
, 1, files
);
381 size_t wxFileDropTarget::GetFormatCount() const
386 wxDataFormat
wxFileDropTarget::GetFormat(size_t WXUNUSED(n
)) const
388 return wxDF_FILENAME
;
391 //-------------------------------------------------------------------------
393 //-------------------------------------------------------------------------
395 //-----------------------------------------------------------------------------
398 void gtk_drag_callback( GtkWidget
*widget
, GdkEvent
*event
, wxDropSource
*source
)
400 printf( "Data requested for dropping.\n" );
402 wxDataObject
*data
= source
->m_data
;
404 size_t size
= data
->GetDataSize();
405 char *ptr
= new char[size
];
406 data
->GetDataHere( ptr
);
408 gtk_widget_dnd_data_set( widget
, event
, ptr
, size
);
412 source
->m_retValue
= wxDragCopy
;
415 wxDropSource::wxDropSource( wxWindow
*win
)
417 g_blockEventsOnDrag
= TRUE
;
420 m_widget
= win
->m_widget
;
421 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
423 m_data
= (wxDataObject
*) NULL
;
424 m_retValue
= wxDragCancel
;
426 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
427 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
430 wxDropSource::wxDropSource( wxDataObject
&data
, wxWindow
*win
)
432 g_blockEventsOnDrag
= TRUE
;
435 m_widget
= win
->m_widget
;
436 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
437 m_retValue
= wxDragCancel
;
441 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
442 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
445 void wxDropSource::SetData( wxDataObject
&data
)
450 wxDropSource::~wxDropSource(void)
452 // if (m_data) delete m_data;
454 g_blockEventsOnDrag
= FALSE
;
457 wxDragResult
wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove
) )
459 if (gdk_dnd
.dnd_grabbed
) return (wxDragResult
) wxDragNone
;
460 if (gdk_dnd
.drag_really
) return (wxDragResult
) wxDragNone
;
462 wxASSERT_MSG( m_data
, "wxDragSource: no data" );
464 if (!m_data
) return (wxDragResult
) wxDragNone
;
465 if (m_data
->GetDataSize() == 0) return (wxDragResult
) wxDragNone
;
467 GdkWindowPrivate
*wp
= (GdkWindowPrivate
*) m_widget
->window
;
471 gdk_dnd
.drag_perhaps
= TRUE
;
473 gdk_dnd
.dnd_drag_start
.x
= 5;
474 gdk_dnd
.dnd_drag_start
.y
= 5;
475 gdk_dnd
.real_sw
= wp
;
477 if (gdk_dnd
.drag_startwindows
)
479 g_free( gdk_dnd
.drag_startwindows
);
480 gdk_dnd
.drag_startwindows
= (GdkWindow
**) NULL
;
482 gdk_dnd
.drag_numwindows
= gdk_dnd
.drag_really
= 0;
484 XWindowAttributes dnd_winattr
;
485 XGetWindowAttributes( gdk_display
, wp
->xwindow
, &dnd_winattr
);
486 wp
->dnd_drag_savedeventmask
= dnd_winattr
.your_event_mask
;
488 gdk_dnd_drag_addwindow( m_widget
->window
);
490 GdkEventDragBegin ev
;
491 ev
.type
= GDK_DRAG_BEGIN
;
492 ev
.window
= m_widget
->window
;
494 ev
.u
.flags
.protocol_version
= DND_PROTOCOL_VERSION
;
496 gdk_event_put( (GdkEvent
*)&ev
);
498 XGrabPointer( gdk_display
, wp
->xwindow
, False
,
499 ButtonMotionMask
| ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
,
500 GrabModeAsync
, GrabModeAsync
, gdk_root_window
, None
, CurrentTime
);
502 gdk_dnd_set_drag_cursors( m_defaultCursor
.GetCursor(), m_goaheadCursor
.GetCursor() );
504 gdk_dnd
.dnd_grabbed
= TRUE
;
505 gdk_dnd
.drag_really
= 1;
509 gdk_window_get_pointer( m_widget
->window
, &x
, &y
, (GdkModifierType
*) NULL
);
511 gdk_dnd_display_drag_cursor( x
, y
, FALSE
, TRUE
);
513 while (gdk_dnd
.drag_really
|| gdk_dnd
.drag_perhaps
) wxYield();
517 g_blockEventsOnDrag
= FALSE
;
522 void wxDropSource::RegisterWindow(void)
528 wxDataFormat df
= m_data
->GetPreferredFormat();
533 formats
+= "text/plain";
536 formats
+= "file:ALL";
542 char *str
= WXSTRINGCAST formats
;
544 gtk_widget_dnd_drag_set( m_widget
, TRUE
, &str
, 1 );
546 gtk_signal_connect( GTK_OBJECT(m_widget
), "drag_request_event",
547 GTK_SIGNAL_FUNC(gtk_drag_callback
), (gpointer
)this );
550 void wxDropSource::UnregisterWindow(void)
552 if (!m_widget
) return;
554 gtk_widget_dnd_drag_set( m_widget
, FALSE
, (gchar
**) NULL
, 0 );
556 gtk_signal_disconnect_by_data( GTK_OBJECT(m_widget
), (gpointer
)this );