X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a3e7d24d21f5371c88caffe4a85c8e4a5362db3f..572c6194d35ad2791c71aee05d6996da2761b07a:/src/gtk1/dnd.cpp diff --git a/src/gtk1/dnd.cpp b/src/gtk1/dnd.cpp index d8ba14eba0..a22731b164 100644 --- a/src/gtk1/dnd.cpp +++ b/src/gtk1/dnd.cpp @@ -188,14 +188,18 @@ static gboolean target_drag_motion( GtkWidget *WXUNUSED(widget), this is only valid for the duration of this call */ drop_target->SetDragContext( context ); + bool ret = FALSE; + if (drop_target->m_firstMotion) { /* the first "drag_motion" event substitutes a "drag_enter" event */ - drop_target->OnEnter(); + ret = drop_target->OnEnter( x, y ); + } + else + { + /* give program a chance to react (i.e. to say no by returning FALSE) */ + ret = drop_target->OnMove( x, y ); } - - /* give program a chance to react (i.e. to say no by returning FALSE) */ - bool ret = drop_target->OnMove( x, y ); /* we don't yet handle which "actions" (i.e. copy or move) the target accepts. so far we simply accept the @@ -252,12 +256,37 @@ static gboolean target_drag_drop( GtkWidget *widget, if (!ret) { + wxLogDebug( wxT( "Drop target: OnDrop returned TRUE") ); + /* cancel the whole thing */ gtk_drag_finish( context, FALSE, /* no success */ FALSE, /* don't delete data on dropping side */ time ); } + else + { + wxLogDebug( wxT( "Drop target: OnDrop returned TRUE") ); + +#if wxUSE_THREADS + /* disable GUI threads */ + wxapp_uninstall_thread_wakeup(); +#endif + + GdkAtom format = drop_target->GetMatchingPair(); + wxASSERT( format ); + + /* this should trigger an "drag_data_received" event */ + gtk_drag_get_data( widget, + context, + format, + time ); + +#if wxUSE_THREADS + /* re-enable GUI threads */ + wxapp_install_thread_wakeup(); +#endif + } /* after this, invalidate the drop_target's GdkDragContext */ drop_target->SetDragContext( (GdkDragContext*) NULL ); @@ -299,7 +328,7 @@ static void target_drag_data_received( GtkWidget *WXUNUSED(widget), return; } - wxLogDebug( wxT( "Drop target: data received") ); + wxLogDebug( wxT( "Drop target: data received event") ); /* inform the wxDropTarget about the current GtkSelectionData. this is only valid for the duration of this call */ @@ -307,11 +336,15 @@ static void target_drag_data_received( GtkWidget *WXUNUSED(widget), if (drop_target->OnData( x, y )) { + wxLogDebug( wxT( "Drop target: OnData returned TRUE") ); + /* tell GTK that data transfer was successfull */ gtk_drag_finish( context, TRUE, FALSE, time ); } else { + wxLogDebug( wxT( "Drop target: OnData returned FALSE") ); + /* tell GTK that data transfer was not successfull */ gtk_drag_finish( context, FALSE, FALSE, time ); } @@ -324,7 +357,8 @@ static void target_drag_data_received( GtkWidget *WXUNUSED(widget), // wxDropTarget //---------------------------------------------------------------------------- -wxDropTarget::wxDropTarget() +wxDropTarget::wxDropTarget( wxDataObject *data ) + : wxDropTargetBase( data ) { m_firstMotion = TRUE; m_dragContext = (GdkDragContext*) NULL; @@ -333,127 +367,97 @@ wxDropTarget::wxDropTarget() m_dragTime = 0; } -wxDropTarget::~wxDropTarget() -{ -} - -void wxDropTarget::OnEnter() -{ -} - -void wxDropTarget::OnLeave() +bool wxDropTarget::OnEnter( int WXUNUSED(x), int WXUNUSED(y) ) { + if (!m_dataObject) + return FALSE; + + return (GetMatchingPair() != (GdkAtom) 0); } -bool wxDropTarget::OnMove( long WXUNUSED(x), long WXUNUSED(y) ) +bool wxDropTarget::OnMove( int WXUNUSED(x), int WXUNUSED(y) ) { - if (GetFormatCount() == 0) + if (!m_dataObject) return FALSE; - for (size_t i = 0; i < GetFormatCount(); i++) - { - if (IsSupported( GetFormat(i) )) - return TRUE; - } - - return FALSE; + return (GetMatchingPair() != (GdkAtom) 0); } -bool wxDropTarget::OnDrop( long WXUNUSED(x), long WXUNUSED(y) ) +bool wxDropTarget::OnDrop( int WXUNUSED(x), int WXUNUSED(y) ) { - if (GetFormatCount() == 0) + if (!m_dataObject) return FALSE; - for (size_t i = 0; i < GetFormatCount(); i++) - { - if (IsSupported( GetFormat(i) )) - { - RequestData( GetFormat(i) ); - return TRUE; - } - } - - return FALSE; + return (GetMatchingPair() != (GdkAtom) 0); } -bool wxDropTarget::OnData( long WXUNUSED(x), long WXUNUSED(y) ) +bool wxDropTarget::OnData( int WXUNUSED(x), int WXUNUSED(y) ) { - return FALSE; + if (!m_dataObject) + return FALSE; + + if (GetMatchingPair() == (GdkAtom) 0) + return FALSE; + + return GetData(); } -bool wxDropTarget::RequestData( wxDataFormat format ) +GdkAtom wxDropTarget::GetMatchingPair() { - if (!m_dragContext) return FALSE; - if (!m_dragWidget) return FALSE; + if (!m_dataObject) + return (GdkAtom) 0; -/* - wxPrintf( wxT("format: %s.\n"), format.GetId().c_str() ); - if (format.GetType() == wxDF_PRIVATE) wxPrintf( wxT("private data.\n") ); - if (format.GetType() == wxDF_TEXT) wxPrintf( wxT("text data.\n") ); -*/ - -#if wxUSE_THREADS - /* disable GUI threads */ - wxapp_uninstall_thread_wakeup(); -#endif - - /* this should trigger an "drag_data_received" event */ - gtk_drag_get_data( m_dragWidget, - m_dragContext, - format, - m_dragTime ); - -#if wxUSE_THREADS - /* re-enable GUI threads */ - wxapp_install_thread_wakeup(); -#endif - - return TRUE; -} - -bool wxDropTarget::IsSupported( wxDataFormat format ) -{ - if (!m_dragContext) return FALSE; + if (!m_dragContext) + return (GdkAtom) 0; GList *child = m_dragContext->targets; while (child) { GdkAtom formatAtom = (GdkAtom) GPOINTER_TO_INT(child->data); + wxDataFormat format( formatAtom ); #ifdef __WXDEBUG__ char *name = gdk_atom_name( formatAtom ); if (name) wxLogDebug( "Drop target: drag has format: %s", name ); #endif + if (m_dataObject->IsSupportedFormat( format )) + return formatAtom; - if (formatAtom == format) return TRUE; child = child->next; } - return FALSE; + return (GdkAtom) 0; } -bool wxDropTarget::GetData( wxDataObject *data_object ) +bool wxDropTarget::GetData() { - if (!m_dragData) return FALSE; + if (!m_dragData) + return FALSE; - if (m_dragData->target != data_object->GetFormat()) return FALSE; + if (!m_dataObject) + return FALSE; - if (data_object->GetFormat().GetType() == wxDF_TEXT) - { - wxTextDataObject *text_object = (wxTextDataObject*)data_object; - text_object->SetText( (const char*)m_dragData->data ); - } else + wxDataFormat dragFormat( m_dragData->target ); + + if (!m_dataObject->IsSupportedFormat( dragFormat )) + return FALSE; - if (data_object->GetFormat().GetType() == wxDF_FILENAME) + if (dragFormat.GetType() == wxDF_TEXT) { - } else + wxTextDataObject *text_object = (wxTextDataObject*)m_dataObject; + text_object->SetText( (const char*)m_dragData->data ); + return TRUE; + } - if (data_object->GetFormat().GetType() == wxDF_PRIVATE) + if (dragFormat.GetType() == wxDF_FILENAME) { - wxPrivateDataObject *priv_object = (wxPrivateDataObject*)data_object; - priv_object->SetData( (const char*)m_dragData->data, (size_t)m_dragData->length ); + wxFileDataObject *file_object = (wxFileDataObject*)m_dataObject; + file_object->SetData( 0, (const char*)m_dragData->data ); + return TRUE; } + m_dataObject->SetData( dragFormat, (size_t)m_dragData->length, (const void*)m_dragData->data ); + return TRUE; } @@ -509,98 +513,39 @@ void wxDropTarget::RegisterWidget( GtkWidget *widget ) GTK_SIGNAL_FUNC(target_drag_data_received), (gpointer) this ); } -//------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- // wxTextDropTarget -//------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- -bool wxTextDropTarget::OnData( long x, long y ) +wxTextDropTarget::wxTextDropTarget() + : wxDropTarget(new wxTextDataObject) { - wxTextDataObject data; - if (!GetData( &data )) return FALSE; - - OnDropText( x, y, data.GetText() ); - - return TRUE; } -//------------------------------------------------------------------------- -// wxPrivateDropTarget -//------------------------------------------------------------------------- - -/* -wxPrivateDropTarget::wxPrivateDropTarget() +bool wxTextDropTarget::OnData(wxCoord x, wxCoord y) { - m_id = wxTheApp->GetAppName(); -} + if ( !GetData() ) + return FALSE; -wxPrivateDropTarget::wxPrivateDropTarget( const wxString &id ) -{ - m_id = id; + return OnDropText(x, y, ((wxTextDataObject *)m_dataObject)->GetText()); } -bool wxPrivateDropTarget::OnMove( long WXUNUSED(x), long WXUNUSED(y) ) -{ - return IsSupported( m_id ); -} +// ---------------------------------------------------------------------------- +// wxFileDropTarget +// ---------------------------------------------------------------------------- -bool wxPrivateDropTarget::OnDrop( long WXUNUSED(x), long WXUNUSED(y) ) +wxFileDropTarget::wxFileDropTarget() + : wxDropTarget(new wxFileDataObject) { - if (!IsSupported( m_id )) - { - RequestData( m_id ); - return FALSE; - } - - return FALSE; } -bool wxPrivateDropTarget::OnData( long x, long y ) +bool wxFileDropTarget::OnData(wxCoord x, wxCoord y) { - if (!IsSupported( m_id )) return FALSE; - - wxPrivateDataObject data; - if (!GetData( &data )) return FALSE; - - OnDropData( x, y, data.GetData(), data.GetSize() ); - - return TRUE; -} -*/ - -//---------------------------------------------------------------------------- -// A drop target which accepts files (dragged from File Manager or Explorer) -//---------------------------------------------------------------------------- - -bool wxFileDropTarget::OnData( long x, long y ) -{ - wxFileDataObject data; - if (!GetData( &data )) return FALSE; - - // get number of substrings /root/mytext.txt/0/root/myothertext.txt/0/0 - size_t number = 0; - size_t i; - size_t size = data.GetFiles().Length(); - wxChar *text = WXSTRINGCAST data.GetFiles(); - for ( i = 0; i < size; i++) - if (text[i] == 0) number++; - - if (number == 0) return FALSE; - - wxChar **files = new wxChar*[number]; - - text = WXSTRINGCAST data.GetFiles(); - for (i = 0; i < number; i++) - { - files[i] = text; - int len = wxStrlen( text ); - text += len+1; - } - - OnDropFiles( x, y, number, files ); - - free( files ); + if ( !GetData() ) + return FALSE; - return TRUE; + return OnDropFiles(x, y, + ((wxFileDataObject *)m_dataObject)->GetFilenames()); } //---------------------------------------------------------------------------- @@ -617,33 +562,41 @@ source_drag_data_get (GtkWidget *WXUNUSED(widget), { if (g_isIdle) wxapp_install_idle_handler(); -#ifdef __WXDEBUG__ - char *name = gdk_atom_name( selection_data->target ); - if (name) wxLogDebug( wxT("Drop source: format requested: %s"), name ); -#endif + wxDataFormat format( selection_data->target ); + + wxLogDebug( wxT("Drop source: format requested: %s"), format.GetId().c_str() ); drop_source->m_retValue = wxDragCancel; - wxDataObject *data = drop_source->m_data; + wxDataObject *data = drop_source->GetDataObject(); if (!data) + { + wxLogDebug( wxT("Drop source: no data object") ); return; + } - if (!data->IsSupportedFormat(selection_data->target)) + if (!data->IsSupportedFormat(format)) + { + wxLogDebug( wxT("Drop source: unsupported format") ); return; + } - if (data->GetDataSize(selection_data->target) == 0) + if (data->GetDataSize(format) == 0) + { + wxLogDebug( wxT("Drop source: empty data") ); return; + } - size_t size = data->GetDataSize(selection_data->target); + size_t size = data->GetDataSize(format); // printf( "data size: %d.\n", (int)data_size ); guchar *d = new guchar[size]; - if (!data->GetDataHere( selection_data->target, (void*)d )) + if (!data->GetDataHere( format, (void*)d )) { - free( d ); + delete[] d; return; } @@ -663,7 +616,7 @@ source_drag_data_get (GtkWidget *WXUNUSED(widget), wxapp_install_thread_wakeup(); #endif - free( d ); + delete[] d; /* so far only copy, no moves. TODO. */ drop_source->m_retValue = wxDragCopy; @@ -725,7 +678,6 @@ wxDropSource::wxDropSource( wxWindow *win, const wxIcon &go, const wxIcon &stop m_widget = win->m_widget; if (win->m_wxwindow) m_widget = win->m_wxwindow; - m_data = (wxDataObject*) NULL; m_retValue = wxDragCancel; m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY ); @@ -741,14 +693,14 @@ wxDropSource::wxDropSource( wxDataObject& data, wxWindow *win, const wxIcon &go, const wxIcon &stop ) { m_waiting = TRUE; + + SetData( data ); m_window = win; m_widget = win->m_widget; if (win->m_wxwindow) m_widget = win->m_wxwindow; m_retValue = wxDragCancel; - m_data = &data; - m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY ); m_goaheadCursor = wxCursor( wxCURSOR_HAND ); @@ -758,19 +710,8 @@ wxDropSource::wxDropSource( wxDataObject& data, wxWindow *win, if (wxNullIcon == stop) m_stopIcon = wxIcon( gv_xpm ); } -void wxDropSource::SetData( wxDataObject& data ) -{ - if (m_data) - delete m_data; - - m_data = &data; -} - wxDropSource::~wxDropSource() { - if (m_data) -// delete m_data; - g_blockEventsOnDrag = FALSE; } @@ -793,7 +734,7 @@ wxDragResult wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove) ) GtkTargetList *target_list = gtk_target_list_new( (GtkTargetEntry*) NULL, 0 ); wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ]; - m_data->GetAllFormats( array, TRUE ); + m_data->GetAllFormats( array ); for (size_t i = 0; i < m_data->GetFormatCount(); i++) { GdkAtom atom = array[i];