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"
19 #include "gdk/gdkprivate.h"
23 // ----------------------------------------------------------------------------
25 // ----------------------------------------------------------------------------
27 extern bool g_blockEventsOnDrag
;
29 // ----------------------------------------------------------------------------
31 // ----------------------------------------------------------------------------
33 wxDropTarget::wxDropTarget()
37 wxDropTarget::~wxDropTarget()
41 void wxDropTarget::Drop( GdkEvent
*event
, int x
, int y
)
43 printf( "Drop data is of type %s.\n", event
->dropdataavailable
.data_type
);
45 OnDrop( x
, y
, (char *)event
->dropdataavailable
.data
);
48 void wxDropTarget::UnregisterWidget( GtkWidget
*widget
)
52 gtk_widget_dnd_drop_set( widget
, FALSE
, NULL
, 0, FALSE
);
55 void wxDropTarget::RegisterWidget( GtkWidget
*widget
)
60 for ( uint i
= 0; i
< GetFormatCount(); i
++ )
62 wxDataFormat df
= GetFormat( i
);
66 if (i
> 0) formats
+= ";";
67 formats
+= "text/plain";
71 if (i
> 0) formats
+= ";";
80 char *str
= WXSTRINGCAST formats
;
82 gtk_widget_dnd_drop_set( widget
, TRUE
, &str
, valid
, FALSE
);
85 // ----------------------------------------------------------------------------
87 // ----------------------------------------------------------------------------
89 bool wxTextDropTarget::OnDrop( long x
, long y
, const void *pData
)
91 OnDropText( x
, y
, (const char*)pData
);
95 bool wxTextDropTarget::OnDropText( long x
, long y
, const char *psz
)
97 printf( "Got dropped text: %s.\n", psz
);
98 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
102 size_t wxTextDropTarget::GetFormatCount() const
107 wxDataFormat
wxTextDropTarget::GetFormat(size_t WXUNUSED(n
)) const
112 // ----------------------------------------------------------------------------
114 // ----------------------------------------------------------------------------
116 bool wxFileDropTarget::OnDropFiles( long x
, long y
, size_t nFiles
, const char * const WXUNUSED(aszFiles
)[] )
118 printf( "Got %d dropped files.\n", (int)nFiles
);
119 printf( "At x: %d, y: %d.\n", (int)x
, (int)y
);
123 bool wxFileDropTarget::OnDrop(long x
, long y
, const void *WXUNUSED(pData
) )
125 char *str
= "/this/is/a/path.txt";
127 return OnDropFiles(x
, y
, 1, &str
);
130 size_t wxFileDropTarget::GetFormatCount() const
135 wxDataFormat
wxFileDropTarget::GetFormat(size_t WXUNUSED(n
)) const
137 return wxDF_FILENAME
;
140 //-------------------------------------------------------------------------
142 //-------------------------------------------------------------------------
144 //-----------------------------------------------------------------------------
147 void gtk_drag_callback( GtkWidget
*widget
, GdkEvent
*event
, wxDropSource
*source
)
149 printf( "Data requested for dropping.\n" );
151 wxDataObject
*data
= source
->m_data
;
153 uint size
= data
->GetDataSize();
154 char *ptr
= new char[size
];
155 data
->GetDataHere( ptr
);
157 gtk_widget_dnd_data_set( widget
, event
, ptr
, size
);
161 source
->m_retValue
= wxDropSource::Copy
;
164 wxDropSource::wxDropSource( wxWindow
*win
)
166 g_blockEventsOnDrag
= TRUE
;
169 m_widget
= win
->m_widget
;
170 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
175 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
176 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
179 wxDropSource::wxDropSource( wxDataObject
&data
, wxWindow
*win
)
181 g_blockEventsOnDrag
= TRUE
;
184 m_widget
= win
->m_widget
;
185 if (win
->m_wxwindow
) m_widget
= win
->m_wxwindow
;
190 m_defaultCursor
= wxCursor( wxCURSOR_NO_ENTRY
);
191 m_goaheadCursor
= wxCursor( wxCURSOR_HAND
);
194 void wxDropSource::SetData( wxDataObject
&data
)
199 wxDropSource::~wxDropSource(void)
201 // if (m_data) delete m_data;
203 g_blockEventsOnDrag
= FALSE
;
206 wxDropSource::DragResult
wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove
) )
208 if (gdk_dnd
.dnd_grabbed
) return None
;
209 if (gdk_dnd
.drag_really
) return None
;
211 wxASSERT_MSG( data
, "wxDragSource: no data" );
213 if (!m_data
) return None
;
214 if (m_data
->GetDataSize() == 0) return None
;
216 GdkWindowPrivate
*wp
= (GdkWindowPrivate
*) m_widget
->window
;
220 gdk_dnd
.drag_perhaps
= TRUE
;
222 gdk_dnd
.dnd_drag_start
.x
= 5;
223 gdk_dnd
.dnd_drag_start
.y
= 5;
224 gdk_dnd
.real_sw
= wp
;
226 if (gdk_dnd
.drag_startwindows
)
228 g_free( gdk_dnd
.drag_startwindows
);
229 gdk_dnd
.drag_startwindows
= NULL
;
231 gdk_dnd
.drag_numwindows
= gdk_dnd
.drag_really
= 0;
233 XWindowAttributes dnd_winattr
;
234 XGetWindowAttributes( gdk_display
, wp
->xwindow
, &dnd_winattr
);
235 wp
->dnd_drag_savedeventmask
= dnd_winattr
.your_event_mask
;
237 gdk_dnd_drag_addwindow( m_widget
->window
);
239 GdkEventDragBegin ev
;
240 ev
.type
= GDK_DRAG_BEGIN
;
241 ev
.window
= m_widget
->window
;
243 ev
.u
.flags
.protocol_version
= DND_PROTOCOL_VERSION
;
245 gdk_event_put( (GdkEvent
*)&ev
);
247 XGrabPointer( gdk_display
, wp
->xwindow
, False
,
248 ButtonMotionMask
| ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
,
249 GrabModeAsync
, GrabModeAsync
, gdk_root_window
, None
, CurrentTime
);
251 gdk_dnd_set_drag_cursors( m_defaultCursor
.GetCursor(), m_goaheadCursor
.GetCursor() );
253 gdk_dnd
.dnd_grabbed
= TRUE
;
254 gdk_dnd
.drag_really
= 1;
258 gdk_window_get_pointer( m_widget
->window
, &x
, &y
, NULL
);
260 gdk_dnd_display_drag_cursor( x
, y
, FALSE
, TRUE
);
262 while (gdk_dnd
.drag_really
|| gdk_dnd
.drag_perhaps
) wxYield();
266 g_blockEventsOnDrag
= FALSE
;
271 void wxDropSource::RegisterWindow(void)
277 wxDataFormat df
= m_data
->GetPreferredFormat();
282 formats
+= "text/plain";
285 formats
+= "url:any";
291 char *str
= WXSTRINGCAST formats
;
293 gtk_widget_dnd_drag_set( m_widget
, TRUE
, &str
, 1 );
295 gtk_signal_connect( GTK_OBJECT(m_widget
), "drag_request_event",
296 GTK_SIGNAL_FUNC(gtk_drag_callback
), (gpointer
)this );
299 void wxDropSource::UnregisterWindow(void)
301 if (!m_widget
) return;
303 gtk_widget_dnd_drag_set( m_widget
, FALSE
, NULL
, 0 );
305 gtk_signal_disconnect_by_data( GTK_OBJECT(m_widget
), (gpointer
)this );