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
;
30 // ----------------------------------------------------------------------------
32 // ----------------------------------------------------------------------------
34 wxDropTarget::wxDropTarget()
39 wxDropTarget::~wxDropTarget()
43 void wxDropTarget::Drop( GdkEventDropDataAvailable
*event
, int x
, int y
)
45 printf( "Drop data is of type %s.\n", event
->data_type
);
47 OnDrop( x
, y
, (char *)event
->data
);
50 void wxDropTarget::UnregisterWidget( GtkWidget
*widget
)
54 gtk_widget_dnd_drop_set( widget
, FALSE
, (gchar
**) NULL
, 0, FALSE
);
57 void wxDropTarget::RegisterWidget( GtkWidget
*widget
)
62 for ( size_t i
= 0; i
< GetFormatCount(); i
++ )
64 wxDataFormat df
= GetFormat( i
);
68 if (i
> 0) formats
+= ";";
69 formats
+= "text/plain";
73 if (i
> 0) formats
+= ";";
74 formats
+= "file:ALL";
82 char *str
= WXSTRINGCAST formats
;
84 gtk_widget_dnd_drop_set( widget
, TRUE
, &str
, valid
, FALSE
);
87 // ----------------------------------------------------------------------------
89 // ----------------------------------------------------------------------------
91 bool wxTextDropTarget::OnDrop( long x
, long y
, const void *pData
)
93 OnDropText( x
, y
, (const char*)pData
);
97 bool wxTextDropTarget::OnDropText( long x
, long y
, const char *psz
)
99 printf( "Got dropped text: %s.\n", psz
);
100 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
104 size_t wxTextDropTarget::GetFormatCount() const
109 wxDataFormat
wxTextDropTarget::GetFormat(size_t WXUNUSED(n
)) const
114 // ----------------------------------------------------------------------------
116 // ----------------------------------------------------------------------------
118 bool wxFileDropTarget::OnDropFiles( long x
, long y
, size_t nFiles
, const char * const aszFiles
[] )
120 printf( "Got %d dropped files.\n", (int)nFiles
);
121 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
122 for (size_t i
= 0; i
< nFiles
; i
++)
124 printf( aszFiles
[i
] );
130 bool wxFileDropTarget::OnDrop(long x
, long y
, const void *pData
)
133 char *text
= (char*) pData
;
134 for (int i
= 0; i
< m_size
; i
++)
135 if (text
[i
] == 0) number
++;
137 if (number
== 0) return TRUE
;
139 char **files
= new char*[number
];
141 text
= (char*) pData
;
142 for (size_t i
= 0; i
< number
; i
++)
145 int len
= strlen( text
);
149 bool ret
= OnDropFiles(x
, y
, 1, files
);
156 size_t wxFileDropTarget::GetFormatCount() const
161 wxDataFormat
wxFileDropTarget::GetFormat(size_t WXUNUSED(n
)) const
163 return wxDF_FILENAME
;
166 //-------------------------------------------------------------------------
168 //-------------------------------------------------------------------------
170 //-----------------------------------------------------------------------------
173 void gtk_drag_callback( GtkWidget
*widget
, GdkEvent
*event
, wxDropSource
*source
)
175 printf( "Data requested for dropping.\n" );
177 wxDataObject
*data
= source
->m_data
;
179 size_t size
= data
->GetDataSize();
180 char *ptr
= new char[size
];
181 data
->GetDataHere( ptr
);
183 gtk_widget_dnd_data_set( widget
, event
, ptr
, size
);
187 source
->m_retValue
= wxDragCopy
;
190 wxDropSource::wxDropSource( wxWindow
*win
)
192 g_blockEventsOnDrag
= TRUE
;
195 m_widget
= win
->m_widget
;
196 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
198 m_data
= (wxDataObject
*) NULL
;
199 m_retValue
= wxDragCancel
;
201 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
202 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
205 wxDropSource::wxDropSource( wxDataObject
&data
, wxWindow
*win
)
207 g_blockEventsOnDrag
= TRUE
;
210 m_widget
= win
->m_widget
;
211 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
212 m_retValue
= wxDragCancel
;
216 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
217 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
220 void wxDropSource::SetData( wxDataObject
&data
)
225 wxDropSource::~wxDropSource(void)
227 // if (m_data) delete m_data;
229 g_blockEventsOnDrag
= FALSE
;
232 wxDragResult
wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove
) )
234 if (gdk_dnd
.dnd_grabbed
) return (wxDragResult
) wxDragNone
;
235 if (gdk_dnd
.drag_really
) return (wxDragResult
) wxDragNone
;
237 wxASSERT_MSG( m_data
, "wxDragSource: no data" );
239 if (!m_data
) return (wxDragResult
) wxDragNone
;
240 if (m_data
->GetDataSize() == 0) return (wxDragResult
) wxDragNone
;
242 GdkWindowPrivate
*wp
= (GdkWindowPrivate
*) m_widget
->window
;
246 gdk_dnd
.drag_perhaps
= TRUE
;
248 gdk_dnd
.dnd_drag_start
.x
= 5;
249 gdk_dnd
.dnd_drag_start
.y
= 5;
250 gdk_dnd
.real_sw
= wp
;
252 if (gdk_dnd
.drag_startwindows
)
254 g_free( gdk_dnd
.drag_startwindows
);
255 gdk_dnd
.drag_startwindows
= (GdkWindow
**) NULL
;
257 gdk_dnd
.drag_numwindows
= gdk_dnd
.drag_really
= 0;
259 XWindowAttributes dnd_winattr
;
260 XGetWindowAttributes( gdk_display
, wp
->xwindow
, &dnd_winattr
);
261 wp
->dnd_drag_savedeventmask
= dnd_winattr
.your_event_mask
;
263 gdk_dnd_drag_addwindow( m_widget
->window
);
265 GdkEventDragBegin ev
;
266 ev
.type
= GDK_DRAG_BEGIN
;
267 ev
.window
= m_widget
->window
;
269 ev
.u
.flags
.protocol_version
= DND_PROTOCOL_VERSION
;
271 gdk_event_put( (GdkEvent
*)&ev
);
273 XGrabPointer( gdk_display
, wp
->xwindow
, False
,
274 ButtonMotionMask
| ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
,
275 GrabModeAsync
, GrabModeAsync
, gdk_root_window
, None
, CurrentTime
);
277 gdk_dnd_set_drag_cursors( m_defaultCursor
.GetCursor(), m_goaheadCursor
.GetCursor() );
279 gdk_dnd
.dnd_grabbed
= TRUE
;
280 gdk_dnd
.drag_really
= 1;
284 gdk_window_get_pointer( m_widget
->window
, &x
, &y
, (GdkModifierType
*) NULL
);
286 gdk_dnd_display_drag_cursor( x
, y
, FALSE
, TRUE
);
288 while (gdk_dnd
.drag_really
|| gdk_dnd
.drag_perhaps
) wxYield();
292 g_blockEventsOnDrag
= FALSE
;
297 void wxDropSource::RegisterWindow(void)
303 wxDataFormat df
= m_data
->GetPreferredFormat();
308 formats
+= "text/plain";
311 formats
+= "file:ALL";
317 char *str
= WXSTRINGCAST formats
;
319 gtk_widget_dnd_drag_set( m_widget
, TRUE
, &str
, 1 );
321 gtk_signal_connect( GTK_OBJECT(m_widget
), "drag_request_event",
322 GTK_SIGNAL_FUNC(gtk_drag_callback
), (gpointer
)this );
325 void wxDropSource::UnregisterWindow(void)
327 if (!m_widget
) return;
329 gtk_widget_dnd_drag_set( m_widget
, FALSE
, (gchar
**) NULL
, 0 );
331 gtk_signal_disconnect_by_data( GTK_OBJECT(m_widget
), (gpointer
)this );