1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxDropTarget class
4 // Author: Robert Roebling
5 // Copyright: Robert Roebling
6 // Licence: wxWindows license
7 ///////////////////////////////////////////////////////////////////////////////
10 #pragma implementation "dnd.h"
14 #include "wx/window.h"
16 #include "wx/gdicmn.h"
18 #include "gdk/gdkprivate.h"
22 // ----------------------------------------------------------------------------
24 // ----------------------------------------------------------------------------
26 extern bool g_blockEventsOnDrag
;
28 // ----------------------------------------------------------------------------
30 // ----------------------------------------------------------------------------
32 wxDropTarget::wxDropTarget()
36 wxDropTarget::~wxDropTarget()
40 void wxDropTarget::Drop( GdkEvent
*event
, int x
, int y
)
42 printf( "Drop data is of type %s.\n", event
->dropdataavailable
.data_type
);
44 OnDrop( x
, y
, (char *)event
->dropdataavailable
.data
);
47 void wxDropTarget::UnregisterWidget( GtkWidget
*widget
)
51 gtk_widget_dnd_drop_set( widget
, FALSE
, NULL
, 0, FALSE
);
54 void wxDropTarget::RegisterWidget( GtkWidget
*widget
)
59 for ( uint i
= 0; i
< GetFormatCount(); i
++ )
61 wxDataFormat df
= GetFormat( i
);
65 if (i
> 0) formats
+= ";";
66 formats
+= "text/plain";
70 if (i
> 0) formats
+= ";";
79 char *str
= WXSTRINGCAST formats
;
81 gtk_widget_dnd_drop_set( widget
, TRUE
, &str
, valid
, FALSE
);
84 // ----------------------------------------------------------------------------
86 // ----------------------------------------------------------------------------
88 bool wxTextDropTarget::OnDrop( long x
, long y
, const void *pData
)
90 OnDropText( x
, y
, (const char*)pData
);
94 bool wxTextDropTarget::OnDropText( long x
, long y
, const char *psz
)
96 printf( "Got dropped text: %s.\n", psz
);
97 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
101 size_t wxTextDropTarget::GetFormatCount() const
106 wxDataFormat
wxTextDropTarget::GetFormat(size_t WXUNUSED(n
)) const
111 // ----------------------------------------------------------------------------
113 // ----------------------------------------------------------------------------
115 bool wxFileDropTarget::OnDropFiles( long x
, long y
, size_t nFiles
, const char * const WXUNUSED(aszFiles
)[] )
117 printf( "Got %d dropped files.\n", (int)nFiles
);
118 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
122 bool wxFileDropTarget::OnDrop(long x
, long y
, const void *WXUNUSED(pData
) )
124 char *str
= "/this/is/a/path.txt";
126 return OnDropFiles(x
, y
, 1, &str
);
129 size_t wxFileDropTarget::GetFormatCount() const
134 wxDataFormat
wxFileDropTarget::GetFormat(size_t WXUNUSED(n
)) const
136 return wxDF_FILENAME
;
139 //-------------------------------------------------------------------------
141 //-------------------------------------------------------------------------
143 //-----------------------------------------------------------------------------
146 void gtk_drag_callback( GtkWidget
*widget
, GdkEvent
*event
, wxDataObject
*data
)
148 printf( "Data requested for dropping.\n" );
150 uint size
= data
->GetDataSize();
151 char *ptr
= new char[size
];
152 data
->GetDataHere( ptr
);
154 gtk_widget_dnd_data_set( widget
, event
, ptr
, size
);
159 wxDropSource::wxDropSource( wxWindow
*win
)
161 g_blockEventsOnDrag
= TRUE
;
164 m_widget
= win
->m_widget
;
165 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
169 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
170 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
173 wxDropSource::wxDropSource( wxDataObject
&data
, wxWindow
*win
)
175 g_blockEventsOnDrag
= TRUE
;
178 m_widget
= win
->m_widget
;
179 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
183 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
184 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
187 void wxDropSource::SetData( wxDataObject
&data
)
192 wxDropSource::~wxDropSource(void)
194 // if (m_data) delete m_data;
196 g_blockEventsOnDrag
= FALSE
;
199 wxDropSource::DragResult
wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove
) )
201 if (gdk_dnd
.dnd_grabbed
) return None
;
202 if (gdk_dnd
.drag_really
) return None
;
204 if (!m_data
) return None
;
205 if (m_data
->GetDataSize() == 0) return None
;
207 GdkWindowPrivate
*wp
= (GdkWindowPrivate
*) m_widget
->window
;
211 gdk_dnd
.drag_perhaps
= TRUE
;
213 gdk_dnd
.dnd_drag_start
.x
= 5;
214 gdk_dnd
.dnd_drag_start
.y
= 5;
215 gdk_dnd
.real_sw
= wp
;
217 if (gdk_dnd
.drag_startwindows
)
219 g_free( gdk_dnd
.drag_startwindows
);
220 gdk_dnd
.drag_startwindows
= NULL
;
222 gdk_dnd
.drag_numwindows
= gdk_dnd
.drag_really
= 0;
224 XWindowAttributes dnd_winattr
;
225 XGetWindowAttributes( gdk_display
, wp
->xwindow
, &dnd_winattr
);
226 wp
->dnd_drag_savedeventmask
= dnd_winattr
.your_event_mask
;
228 gdk_dnd_drag_addwindow( m_widget
->window
);
230 GdkEventDragBegin ev
;
231 ev
.type
= GDK_DRAG_BEGIN
;
232 ev
.window
= m_widget
->window
;
234 ev
.u
.flags
.protocol_version
= DND_PROTOCOL_VERSION
;
236 gdk_event_put( (GdkEvent
*)&ev
);
238 XGrabPointer( gdk_display
, wp
->xwindow
, False
,
239 ButtonMotionMask
| ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
,
240 GrabModeAsync
, GrabModeAsync
, gdk_root_window
, None
, CurrentTime
);
242 gdk_dnd_set_drag_cursors( m_defaultCursor
.GetCursor(), m_goaheadCursor
.GetCursor() );
244 gdk_dnd
.dnd_grabbed
= TRUE
;
245 gdk_dnd
.drag_really
= 1;
249 gdk_window_get_pointer( m_widget
->window
, &x
, &y
, NULL
);
251 gdk_dnd_display_drag_cursor( x
, y
, FALSE
, TRUE
);
253 while (gdk_dnd
.drag_really
|| gdk_dnd
.drag_perhaps
) wxYield();
260 void wxDropSource::RegisterWindow(void)
266 wxDataFormat df
= m_data
->GetPreferredFormat();
271 formats
+= "text/plain";
274 formats
+= "url:any";
280 char *str
= WXSTRINGCAST formats
;
282 gtk_widget_dnd_drag_set( m_widget
, TRUE
, &str
, 1 );
284 gtk_signal_connect( GTK_OBJECT(m_widget
), "drag_request_event",
285 GTK_SIGNAL_FUNC(gtk_drag_callback
), (gpointer
)m_data
);
288 void wxDropSource::UnregisterWindow(void)
290 if (!m_widget
) return;
292 gtk_widget_dnd_drag_set( m_widget
, FALSE
, NULL
, 0 );
294 gtk_signal_disconnect_by_data( GTK_OBJECT(m_widget
), (gpointer
)m_data
);