Drag'n'Drop works in a basic form
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2150 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -117,13 +117,24 @@ public:
|
|||||||
virtual void OnLeave();
|
virtual void OnLeave();
|
||||||
|
|
||||||
/* may be overridden to reject certain formats or drops
|
/* may be overridden to reject certain formats or drops
|
||||||
on certain areas */
|
on certain areas. always returns TRUE by default
|
||||||
|
indicating that you'd accept the data from the drag. */
|
||||||
virtual bool OnMove( int x, int y );
|
virtual bool OnMove( int x, int y );
|
||||||
|
|
||||||
/* has to be overridden to accept drop. call GetData() to
|
/* has to be overridden to accept a drop event. call
|
||||||
indicate the format you request and get the data. */
|
IsSupported() to ask which formats are available
|
||||||
|
and then call RequestData() to indicate the format
|
||||||
|
you request. */
|
||||||
virtual bool OnDrop( int x, int y );
|
virtual bool OnDrop( int x, int y );
|
||||||
|
|
||||||
|
/* this gets called once the data has actually arrived. get
|
||||||
|
it with GetData(). this has to be overridden. */
|
||||||
|
virtual bool OnData( int x, int y );
|
||||||
|
|
||||||
|
/* called from within OnDrop() to request a certain format
|
||||||
|
from the drop event. */
|
||||||
|
bool RequestData( wxDataFormat format );
|
||||||
|
|
||||||
/* called to query what formats are available */
|
/* called to query what formats are available */
|
||||||
bool IsSupported( wxDataFormat format );
|
bool IsSupported( wxDataFormat format );
|
||||||
|
|
||||||
@@ -137,14 +148,13 @@ public:
|
|||||||
|
|
||||||
GdkDragContext *m_dragContext;
|
GdkDragContext *m_dragContext;
|
||||||
GtkWidget *m_dragWidget;
|
GtkWidget *m_dragWidget;
|
||||||
|
GtkSelectionData *m_dragData;
|
||||||
guint m_dragTime;
|
guint m_dragTime;
|
||||||
bool m_firstMotion; /* gdk has no "gdk_drag_enter" event */
|
bool m_firstMotion; /* gdk has no "gdk_drag_enter" event */
|
||||||
bool m_waiting; /* asynchronous process */
|
|
||||||
bool m_dataRetrieveSuccess;
|
|
||||||
wxDataObject *m_currentDataObject;
|
|
||||||
|
|
||||||
void SetDragContext( GdkDragContext *dc ) { m_dragContext = dc; }
|
void SetDragContext( GdkDragContext *dc ) { m_dragContext = dc; }
|
||||||
void SetDragWidget( GtkWidget *w ) { m_dragWidget = w; }
|
void SetDragWidget( GtkWidget *w ) { m_dragWidget = w; }
|
||||||
|
void SetDragData( GtkSelectionData *sd ) { m_dragData = sd; }
|
||||||
void SetDragTime( guint time ) { m_dragTime = time; }
|
void SetDragTime( guint time ) { m_dragTime = time; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -160,6 +170,7 @@ public:
|
|||||||
|
|
||||||
virtual bool OnMove( int x, int y );
|
virtual bool OnMove( int x, int y );
|
||||||
virtual bool OnDrop( int x, int y );
|
virtual bool OnDrop( int x, int y );
|
||||||
|
virtual bool OnData( int x, int y );
|
||||||
|
|
||||||
/* you have to override OnDropData to get at the text */
|
/* you have to override OnDropData to get at the text */
|
||||||
virtual bool OnDropText( int x, int y, const char *text ) = 0;
|
virtual bool OnDropText( int x, int y, const char *text ) = 0;
|
||||||
@@ -182,6 +193,7 @@ public:
|
|||||||
|
|
||||||
virtual bool OnMove( int x, int y );
|
virtual bool OnMove( int x, int y );
|
||||||
virtual bool OnDrop( int x, int y );
|
virtual bool OnDrop( int x, int y );
|
||||||
|
virtual bool OnData( int x, int y );
|
||||||
|
|
||||||
/* you have to override OnDropData to get at the data */
|
/* you have to override OnDropData to get at the data */
|
||||||
virtual bool OnDropData( int x, int y, void *data, size_t size ) = 0;
|
virtual bool OnDropData( int x, int y, void *data, size_t size ) = 0;
|
||||||
@@ -210,7 +222,7 @@ public:
|
|||||||
|
|
||||||
virtual bool OnMove( int x, int y );
|
virtual bool OnMove( int x, int y );
|
||||||
virtual bool OnDrop( int x, int y );
|
virtual bool OnDrop( int x, int y );
|
||||||
virtual void OnData( int x, int y );
|
virtual bool OnData( int x, int y );
|
||||||
|
|
||||||
/* you have to override OnDropFiles to get at the file names */
|
/* you have to override OnDropFiles to get at the file names */
|
||||||
virtual bool OnDropFiles( int x, int y, size_t nFiles, const char * const aszFiles[] ) = 0;
|
virtual bool OnDropFiles( int x, int y, size_t nFiles, const char * const aszFiles[] ) = 0;
|
||||||
|
@@ -117,13 +117,24 @@ public:
|
|||||||
virtual void OnLeave();
|
virtual void OnLeave();
|
||||||
|
|
||||||
/* may be overridden to reject certain formats or drops
|
/* may be overridden to reject certain formats or drops
|
||||||
on certain areas */
|
on certain areas. always returns TRUE by default
|
||||||
|
indicating that you'd accept the data from the drag. */
|
||||||
virtual bool OnMove( int x, int y );
|
virtual bool OnMove( int x, int y );
|
||||||
|
|
||||||
/* has to be overridden to accept drop. call GetData() to
|
/* has to be overridden to accept a drop event. call
|
||||||
indicate the format you request and get the data. */
|
IsSupported() to ask which formats are available
|
||||||
|
and then call RequestData() to indicate the format
|
||||||
|
you request. */
|
||||||
virtual bool OnDrop( int x, int y );
|
virtual bool OnDrop( int x, int y );
|
||||||
|
|
||||||
|
/* this gets called once the data has actually arrived. get
|
||||||
|
it with GetData(). this has to be overridden. */
|
||||||
|
virtual bool OnData( int x, int y );
|
||||||
|
|
||||||
|
/* called from within OnDrop() to request a certain format
|
||||||
|
from the drop event. */
|
||||||
|
bool RequestData( wxDataFormat format );
|
||||||
|
|
||||||
/* called to query what formats are available */
|
/* called to query what formats are available */
|
||||||
bool IsSupported( wxDataFormat format );
|
bool IsSupported( wxDataFormat format );
|
||||||
|
|
||||||
@@ -137,14 +148,13 @@ public:
|
|||||||
|
|
||||||
GdkDragContext *m_dragContext;
|
GdkDragContext *m_dragContext;
|
||||||
GtkWidget *m_dragWidget;
|
GtkWidget *m_dragWidget;
|
||||||
|
GtkSelectionData *m_dragData;
|
||||||
guint m_dragTime;
|
guint m_dragTime;
|
||||||
bool m_firstMotion; /* gdk has no "gdk_drag_enter" event */
|
bool m_firstMotion; /* gdk has no "gdk_drag_enter" event */
|
||||||
bool m_waiting; /* asynchronous process */
|
|
||||||
bool m_dataRetrieveSuccess;
|
|
||||||
wxDataObject *m_currentDataObject;
|
|
||||||
|
|
||||||
void SetDragContext( GdkDragContext *dc ) { m_dragContext = dc; }
|
void SetDragContext( GdkDragContext *dc ) { m_dragContext = dc; }
|
||||||
void SetDragWidget( GtkWidget *w ) { m_dragWidget = w; }
|
void SetDragWidget( GtkWidget *w ) { m_dragWidget = w; }
|
||||||
|
void SetDragData( GtkSelectionData *sd ) { m_dragData = sd; }
|
||||||
void SetDragTime( guint time ) { m_dragTime = time; }
|
void SetDragTime( guint time ) { m_dragTime = time; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -160,6 +170,7 @@ public:
|
|||||||
|
|
||||||
virtual bool OnMove( int x, int y );
|
virtual bool OnMove( int x, int y );
|
||||||
virtual bool OnDrop( int x, int y );
|
virtual bool OnDrop( int x, int y );
|
||||||
|
virtual bool OnData( int x, int y );
|
||||||
|
|
||||||
/* you have to override OnDropData to get at the text */
|
/* you have to override OnDropData to get at the text */
|
||||||
virtual bool OnDropText( int x, int y, const char *text ) = 0;
|
virtual bool OnDropText( int x, int y, const char *text ) = 0;
|
||||||
@@ -182,6 +193,7 @@ public:
|
|||||||
|
|
||||||
virtual bool OnMove( int x, int y );
|
virtual bool OnMove( int x, int y );
|
||||||
virtual bool OnDrop( int x, int y );
|
virtual bool OnDrop( int x, int y );
|
||||||
|
virtual bool OnData( int x, int y );
|
||||||
|
|
||||||
/* you have to override OnDropData to get at the data */
|
/* you have to override OnDropData to get at the data */
|
||||||
virtual bool OnDropData( int x, int y, void *data, size_t size ) = 0;
|
virtual bool OnDropData( int x, int y, void *data, size_t size ) = 0;
|
||||||
@@ -210,7 +222,7 @@ public:
|
|||||||
|
|
||||||
virtual bool OnMove( int x, int y );
|
virtual bool OnMove( int x, int y );
|
||||||
virtual bool OnDrop( int x, int y );
|
virtual bool OnDrop( int x, int y );
|
||||||
virtual void OnData( int x, int y );
|
virtual bool OnData( int x, int y );
|
||||||
|
|
||||||
/* you have to override OnDropFiles to get at the file names */
|
/* you have to override OnDropFiles to get at the file names */
|
||||||
virtual bool OnDropFiles( int x, int y, size_t nFiles, const char * const aszFiles[] ) = 0;
|
virtual bool OnDropFiles( int x, int y, size_t nFiles, const char * const aszFiles[] ) = 0;
|
||||||
|
163
src/gtk/dnd.cpp
163
src/gtk/dnd.cpp
@@ -232,15 +232,7 @@ static gboolean target_drag_drop( GtkWidget *widget,
|
|||||||
|
|
||||||
bool ret = drop_target->OnDrop( x, y );
|
bool ret = drop_target->OnDrop( x, y );
|
||||||
|
|
||||||
if (ret)
|
if (!ret)
|
||||||
{
|
|
||||||
/* this should trigger an "drag_data_received" event */
|
|
||||||
gtk_drag_get_data( widget,
|
|
||||||
context,
|
|
||||||
GPOINTER_TO_INT (context->targets->data),
|
|
||||||
time );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* cancel the whole thing */
|
/* cancel the whole thing */
|
||||||
gtk_drag_finish( context,
|
gtk_drag_finish( context,
|
||||||
@@ -279,47 +271,32 @@ static void target_drag_data_received( GtkWidget *WXUNUSED(widget),
|
|||||||
|
|
||||||
// printf( "data received.\n" );
|
// printf( "data received.\n" );
|
||||||
|
|
||||||
/* strangely, we get a "drag_data_received" event even when
|
|
||||||
we don't request them. this checks this. */
|
|
||||||
if (!drop_target->m_currentDataObject) return;
|
|
||||||
|
|
||||||
wxDataObject *data_object = drop_target->m_currentDataObject;
|
|
||||||
|
|
||||||
if ((data->length <= 0) || (data->format != 8))
|
if ((data->length <= 0) || (data->format != 8))
|
||||||
{
|
{
|
||||||
/* negative data length and non 8-bit data format
|
/* negative data length and non 8-bit data format
|
||||||
qualifies for junk */
|
qualifies for junk */
|
||||||
gtk_drag_finish (context, FALSE, FALSE, time);
|
gtk_drag_finish (context, FALSE, FALSE, time);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wxASSERT_MSG( data->target == data_object->GetFormat().GetAtom(), "DnD GetData target mismatch." );
|
|
||||||
|
|
||||||
if (data_object->GetFormat().GetType() == wxDF_TEXT)
|
return;
|
||||||
{
|
|
||||||
wxTextDataObject *text_object = (wxTextDataObject*)data_object;
|
|
||||||
text_object->SetText( (const char*)data->data );
|
|
||||||
} else
|
|
||||||
|
|
||||||
if (data_object->GetFormat().GetType() == wxDF_FILENAME)
|
|
||||||
{
|
|
||||||
} else
|
|
||||||
|
|
||||||
if (data_object->GetFormat().GetType() == wxDF_PRIVATE)
|
|
||||||
{
|
|
||||||
wxPrivateDataObject *priv_object = (wxPrivateDataObject*)data_object;
|
|
||||||
priv_object->SetData( (const char*)data->data, (size_t)data->length );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tell wxDropTarget that data transfer was successfull */
|
/* inform the wxDropTarget about the current GtkSelectionData.
|
||||||
drop_target->m_dataRetrieveSuccess = TRUE;
|
this is only valid for the duration of this call */
|
||||||
|
drop_target->SetDragData( data );
|
||||||
|
|
||||||
|
if (drop_target->OnData( x, y ))
|
||||||
|
{
|
||||||
/* tell GTK that data transfer was successfull */
|
/* tell GTK that data transfer was successfull */
|
||||||
gtk_drag_finish( context, TRUE, FALSE, time );
|
gtk_drag_finish( context, TRUE, FALSE, time );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* tell GTK that data transfer was not successfull */
|
||||||
|
gtk_drag_finish( context, FALSE, FALSE, time );
|
||||||
|
}
|
||||||
|
|
||||||
/* tell wxDropTarget that data has arrived (or not) */
|
/* after this, invalidate the drop_target's drag data */
|
||||||
drop_target->m_waiting = FALSE;
|
drop_target->SetDragData( (GtkSelectionData*) NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -331,9 +308,8 @@ wxDropTarget::wxDropTarget()
|
|||||||
m_firstMotion = TRUE;
|
m_firstMotion = TRUE;
|
||||||
m_dragContext = (GdkDragContext*) NULL;
|
m_dragContext = (GdkDragContext*) NULL;
|
||||||
m_dragWidget = (GtkWidget*) NULL;
|
m_dragWidget = (GtkWidget*) NULL;
|
||||||
|
m_dragData = (GtkSelectionData*) NULL;
|
||||||
m_dragTime = 0;
|
m_dragTime = 0;
|
||||||
m_currentDataObject = (wxDataObject*) NULL;
|
|
||||||
m_dataRetrieveSuccess = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxDropTarget::~wxDropTarget()
|
wxDropTarget::~wxDropTarget()
|
||||||
@@ -358,6 +334,25 @@ bool wxDropTarget::OnDrop( int WXUNUSED(x), int WXUNUSED(y) )
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxDropTarget::OnData( int WXUNUSED(x), int WXUNUSED(y) )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxDropTarget::RequestData( wxDataFormat format )
|
||||||
|
{
|
||||||
|
if (!m_dragContext) return FALSE;
|
||||||
|
if (!m_dragWidget) return FALSE;
|
||||||
|
|
||||||
|
/* this should trigger an "drag_data_received" event */
|
||||||
|
gtk_drag_get_data( m_dragWidget,
|
||||||
|
m_dragContext,
|
||||||
|
format.GetAtom(),
|
||||||
|
m_dragTime );
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
bool wxDropTarget::IsSupported( wxDataFormat format )
|
bool wxDropTarget::IsSupported( wxDataFormat format )
|
||||||
{
|
{
|
||||||
if (!m_dragContext) return FALSE;
|
if (!m_dragContext) return FALSE;
|
||||||
@@ -377,32 +372,29 @@ bool wxDropTarget::IsSupported( wxDataFormat format )
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxDropTarget::GetData( wxDataObject *data )
|
bool wxDropTarget::GetData( wxDataObject *data_object )
|
||||||
{
|
{
|
||||||
if (!m_dragContext) return FALSE;
|
if (!m_dragData) return FALSE;
|
||||||
if (!m_dragWidget) return FALSE;
|
|
||||||
|
|
||||||
m_currentDataObject = data;
|
if (m_dragData->target != data_object->GetFormat().GetAtom()) return FALSE;
|
||||||
m_dataRetrieveSuccess = FALSE;
|
|
||||||
|
|
||||||
/* this should trigger an "drag_data_received" event */
|
if (data_object->GetFormat().GetType() == wxDF_TEXT)
|
||||||
gtk_drag_get_data( m_dragWidget,
|
{
|
||||||
m_dragContext,
|
wxTextDataObject *text_object = (wxTextDataObject*)data_object;
|
||||||
data->GetFormat().GetAtom(),
|
text_object->SetText( (const char*)m_dragData->data );
|
||||||
m_dragTime );
|
} else
|
||||||
|
|
||||||
/* wait for the "drag_data_received" event */
|
if (data_object->GetFormat().GetType() == wxDF_FILENAME)
|
||||||
|
{
|
||||||
|
} else
|
||||||
|
|
||||||
// printf( "pre wait.\n" );
|
if (data_object->GetFormat().GetType() == wxDF_PRIVATE)
|
||||||
|
{
|
||||||
|
wxPrivateDataObject *priv_object = (wxPrivateDataObject*)data_object;
|
||||||
|
priv_object->SetData( (const char*)m_dragData->data, (size_t)m_dragData->length );
|
||||||
|
}
|
||||||
|
|
||||||
m_waiting = TRUE;
|
return TRUE;
|
||||||
while (m_waiting) wxYield();
|
|
||||||
|
|
||||||
// printf( "post wait.\n" );
|
|
||||||
|
|
||||||
m_currentDataObject = (wxDataObject*) NULL;
|
|
||||||
|
|
||||||
return m_dataRetrieveSuccess;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxDropTarget::UnregisterWidget( GtkWidget *widget )
|
void wxDropTarget::UnregisterWidget( GtkWidget *widget )
|
||||||
@@ -463,17 +455,27 @@ void wxDropTarget::RegisterWidget( GtkWidget *widget )
|
|||||||
|
|
||||||
bool wxTextDropTarget::OnMove( int WXUNUSED(x), int WXUNUSED(y) )
|
bool wxTextDropTarget::OnMove( int WXUNUSED(x), int WXUNUSED(y) )
|
||||||
{
|
{
|
||||||
return IsSupported( wxDF_TEXT ); // same as "STRING"
|
return IsSupported( wxDF_TEXT );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxTextDropTarget::OnDrop( int x, int y )
|
bool wxTextDropTarget::OnDrop( int WXUNUSED(x), int WXUNUSED(y) )
|
||||||
{
|
{
|
||||||
if (!IsSupported( wxDF_TEXT )) return FALSE;
|
if (IsSupported( wxDF_TEXT ))
|
||||||
|
{
|
||||||
|
RequestData( wxDF_TEXT );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxTextDropTarget::OnData( int x, int y )
|
||||||
|
{
|
||||||
wxTextDataObject data;
|
wxTextDataObject data;
|
||||||
if (!GetData( &data )) return FALSE;
|
if (!GetData( &data )) return FALSE;
|
||||||
|
|
||||||
OnDropText( x, y, data.GetText() );
|
OnDropText( x, y, data.GetText() );
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,7 +498,18 @@ bool wxPrivateDropTarget::OnMove( int WXUNUSED(x), int WXUNUSED(y) )
|
|||||||
return IsSupported( m_id );
|
return IsSupported( m_id );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxPrivateDropTarget::OnDrop( int x, int y )
|
bool wxPrivateDropTarget::OnDrop( int WXUNUSED(x), int WXUNUSED(y) )
|
||||||
|
{
|
||||||
|
if (!IsSupported( m_id ))
|
||||||
|
{
|
||||||
|
RequestData( m_id );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxPrivateDropTarget::OnData( int x, int y )
|
||||||
{
|
{
|
||||||
if (!IsSupported( m_id )) return FALSE;
|
if (!IsSupported( m_id )) return FALSE;
|
||||||
|
|
||||||
@@ -514,18 +527,24 @@ bool wxPrivateDropTarget::OnDrop( int x, int y )
|
|||||||
|
|
||||||
bool wxFileDropTarget::OnMove( int WXUNUSED(x), int WXUNUSED(y) )
|
bool wxFileDropTarget::OnMove( int WXUNUSED(x), int WXUNUSED(y) )
|
||||||
{
|
{
|
||||||
return IsSupported( wxDF_FILENAME ); // same as "file:ALL"
|
return IsSupported( wxDF_FILENAME );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxFileDropTarget::OnDrop( int x, int y )
|
bool wxFileDropTarget::OnDrop( int x, int y )
|
||||||
{
|
{
|
||||||
return IsSupported( wxDF_FILENAME ); // same as "file:ALL"
|
if (IsSupported( wxDF_FILENAME ))
|
||||||
|
{
|
||||||
|
RequestData( wxDF_FILENAME );
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxFileDropTarget::OnData( int x, int y )
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxFileDropTarget::OnData( int x, int y )
|
||||||
{
|
{
|
||||||
wxFileDataObject data;
|
wxFileDataObject data;
|
||||||
if (!GetData( &data )) return;
|
if (!GetData( &data )) return FALSE;
|
||||||
|
|
||||||
/* get number of substrings /root/mytext.txt/0/root/myothertext.txt/0/0 */
|
/* get number of substrings /root/mytext.txt/0/root/myothertext.txt/0/0 */
|
||||||
size_t number = 0;
|
size_t number = 0;
|
||||||
@@ -535,7 +554,7 @@ void wxFileDropTarget::OnData( int x, int y )
|
|||||||
for ( i = 0; i < size; i++)
|
for ( i = 0; i < size; i++)
|
||||||
if (text[i] == 0) number++;
|
if (text[i] == 0) number++;
|
||||||
|
|
||||||
if (number == 0) return;
|
if (number == 0) return FALSE;
|
||||||
|
|
||||||
char **files = new char*[number];
|
char **files = new char*[number];
|
||||||
|
|
||||||
@@ -550,6 +569,8 @@ void wxFileDropTarget::OnData( int x, int y )
|
|||||||
OnDropFiles( x, y, number, files );
|
OnDropFiles( x, y, number, files );
|
||||||
|
|
||||||
free( files );
|
free( files );
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -564,8 +585,8 @@ source_drag_data_get (GtkWidget *WXUNUSED(widget),
|
|||||||
guint WXUNUSED(time),
|
guint WXUNUSED(time),
|
||||||
wxDropSource *drop_source )
|
wxDropSource *drop_source )
|
||||||
{
|
{
|
||||||
char *name = gdk_atom_name( selection_data->target );
|
// char *name = gdk_atom_name( selection_data->target );
|
||||||
if (name) printf( "Format requested: %s.\n", name );
|
// if (name) printf( "Format requested: %s.\n", name );
|
||||||
|
|
||||||
wxNode *node = drop_source->m_data->m_dataObjects.First();
|
wxNode *node = drop_source->m_data->m_dataObjects.First();
|
||||||
while (node)
|
while (node)
|
||||||
@@ -784,6 +805,8 @@ wxDragResult wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove) )
|
|||||||
0,
|
0,
|
||||||
0 );
|
0 );
|
||||||
|
|
||||||
|
gdk_flush();
|
||||||
|
|
||||||
while (m_waiting) wxYield();
|
while (m_waiting) wxYield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
163
src/gtk1/dnd.cpp
163
src/gtk1/dnd.cpp
@@ -232,15 +232,7 @@ static gboolean target_drag_drop( GtkWidget *widget,
|
|||||||
|
|
||||||
bool ret = drop_target->OnDrop( x, y );
|
bool ret = drop_target->OnDrop( x, y );
|
||||||
|
|
||||||
if (ret)
|
if (!ret)
|
||||||
{
|
|
||||||
/* this should trigger an "drag_data_received" event */
|
|
||||||
gtk_drag_get_data( widget,
|
|
||||||
context,
|
|
||||||
GPOINTER_TO_INT (context->targets->data),
|
|
||||||
time );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* cancel the whole thing */
|
/* cancel the whole thing */
|
||||||
gtk_drag_finish( context,
|
gtk_drag_finish( context,
|
||||||
@@ -279,47 +271,32 @@ static void target_drag_data_received( GtkWidget *WXUNUSED(widget),
|
|||||||
|
|
||||||
// printf( "data received.\n" );
|
// printf( "data received.\n" );
|
||||||
|
|
||||||
/* strangely, we get a "drag_data_received" event even when
|
|
||||||
we don't request them. this checks this. */
|
|
||||||
if (!drop_target->m_currentDataObject) return;
|
|
||||||
|
|
||||||
wxDataObject *data_object = drop_target->m_currentDataObject;
|
|
||||||
|
|
||||||
if ((data->length <= 0) || (data->format != 8))
|
if ((data->length <= 0) || (data->format != 8))
|
||||||
{
|
{
|
||||||
/* negative data length and non 8-bit data format
|
/* negative data length and non 8-bit data format
|
||||||
qualifies for junk */
|
qualifies for junk */
|
||||||
gtk_drag_finish (context, FALSE, FALSE, time);
|
gtk_drag_finish (context, FALSE, FALSE, time);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wxASSERT_MSG( data->target == data_object->GetFormat().GetAtom(), "DnD GetData target mismatch." );
|
|
||||||
|
|
||||||
if (data_object->GetFormat().GetType() == wxDF_TEXT)
|
return;
|
||||||
{
|
|
||||||
wxTextDataObject *text_object = (wxTextDataObject*)data_object;
|
|
||||||
text_object->SetText( (const char*)data->data );
|
|
||||||
} else
|
|
||||||
|
|
||||||
if (data_object->GetFormat().GetType() == wxDF_FILENAME)
|
|
||||||
{
|
|
||||||
} else
|
|
||||||
|
|
||||||
if (data_object->GetFormat().GetType() == wxDF_PRIVATE)
|
|
||||||
{
|
|
||||||
wxPrivateDataObject *priv_object = (wxPrivateDataObject*)data_object;
|
|
||||||
priv_object->SetData( (const char*)data->data, (size_t)data->length );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tell wxDropTarget that data transfer was successfull */
|
/* inform the wxDropTarget about the current GtkSelectionData.
|
||||||
drop_target->m_dataRetrieveSuccess = TRUE;
|
this is only valid for the duration of this call */
|
||||||
|
drop_target->SetDragData( data );
|
||||||
|
|
||||||
|
if (drop_target->OnData( x, y ))
|
||||||
|
{
|
||||||
/* tell GTK that data transfer was successfull */
|
/* tell GTK that data transfer was successfull */
|
||||||
gtk_drag_finish( context, TRUE, FALSE, time );
|
gtk_drag_finish( context, TRUE, FALSE, time );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* tell GTK that data transfer was not successfull */
|
||||||
|
gtk_drag_finish( context, FALSE, FALSE, time );
|
||||||
|
}
|
||||||
|
|
||||||
/* tell wxDropTarget that data has arrived (or not) */
|
/* after this, invalidate the drop_target's drag data */
|
||||||
drop_target->m_waiting = FALSE;
|
drop_target->SetDragData( (GtkSelectionData*) NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -331,9 +308,8 @@ wxDropTarget::wxDropTarget()
|
|||||||
m_firstMotion = TRUE;
|
m_firstMotion = TRUE;
|
||||||
m_dragContext = (GdkDragContext*) NULL;
|
m_dragContext = (GdkDragContext*) NULL;
|
||||||
m_dragWidget = (GtkWidget*) NULL;
|
m_dragWidget = (GtkWidget*) NULL;
|
||||||
|
m_dragData = (GtkSelectionData*) NULL;
|
||||||
m_dragTime = 0;
|
m_dragTime = 0;
|
||||||
m_currentDataObject = (wxDataObject*) NULL;
|
|
||||||
m_dataRetrieveSuccess = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxDropTarget::~wxDropTarget()
|
wxDropTarget::~wxDropTarget()
|
||||||
@@ -358,6 +334,25 @@ bool wxDropTarget::OnDrop( int WXUNUSED(x), int WXUNUSED(y) )
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxDropTarget::OnData( int WXUNUSED(x), int WXUNUSED(y) )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxDropTarget::RequestData( wxDataFormat format )
|
||||||
|
{
|
||||||
|
if (!m_dragContext) return FALSE;
|
||||||
|
if (!m_dragWidget) return FALSE;
|
||||||
|
|
||||||
|
/* this should trigger an "drag_data_received" event */
|
||||||
|
gtk_drag_get_data( m_dragWidget,
|
||||||
|
m_dragContext,
|
||||||
|
format.GetAtom(),
|
||||||
|
m_dragTime );
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
bool wxDropTarget::IsSupported( wxDataFormat format )
|
bool wxDropTarget::IsSupported( wxDataFormat format )
|
||||||
{
|
{
|
||||||
if (!m_dragContext) return FALSE;
|
if (!m_dragContext) return FALSE;
|
||||||
@@ -377,32 +372,29 @@ bool wxDropTarget::IsSupported( wxDataFormat format )
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxDropTarget::GetData( wxDataObject *data )
|
bool wxDropTarget::GetData( wxDataObject *data_object )
|
||||||
{
|
{
|
||||||
if (!m_dragContext) return FALSE;
|
if (!m_dragData) return FALSE;
|
||||||
if (!m_dragWidget) return FALSE;
|
|
||||||
|
|
||||||
m_currentDataObject = data;
|
if (m_dragData->target != data_object->GetFormat().GetAtom()) return FALSE;
|
||||||
m_dataRetrieveSuccess = FALSE;
|
|
||||||
|
|
||||||
/* this should trigger an "drag_data_received" event */
|
if (data_object->GetFormat().GetType() == wxDF_TEXT)
|
||||||
gtk_drag_get_data( m_dragWidget,
|
{
|
||||||
m_dragContext,
|
wxTextDataObject *text_object = (wxTextDataObject*)data_object;
|
||||||
data->GetFormat().GetAtom(),
|
text_object->SetText( (const char*)m_dragData->data );
|
||||||
m_dragTime );
|
} else
|
||||||
|
|
||||||
/* wait for the "drag_data_received" event */
|
if (data_object->GetFormat().GetType() == wxDF_FILENAME)
|
||||||
|
{
|
||||||
|
} else
|
||||||
|
|
||||||
// printf( "pre wait.\n" );
|
if (data_object->GetFormat().GetType() == wxDF_PRIVATE)
|
||||||
|
{
|
||||||
|
wxPrivateDataObject *priv_object = (wxPrivateDataObject*)data_object;
|
||||||
|
priv_object->SetData( (const char*)m_dragData->data, (size_t)m_dragData->length );
|
||||||
|
}
|
||||||
|
|
||||||
m_waiting = TRUE;
|
return TRUE;
|
||||||
while (m_waiting) wxYield();
|
|
||||||
|
|
||||||
// printf( "post wait.\n" );
|
|
||||||
|
|
||||||
m_currentDataObject = (wxDataObject*) NULL;
|
|
||||||
|
|
||||||
return m_dataRetrieveSuccess;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxDropTarget::UnregisterWidget( GtkWidget *widget )
|
void wxDropTarget::UnregisterWidget( GtkWidget *widget )
|
||||||
@@ -463,17 +455,27 @@ void wxDropTarget::RegisterWidget( GtkWidget *widget )
|
|||||||
|
|
||||||
bool wxTextDropTarget::OnMove( int WXUNUSED(x), int WXUNUSED(y) )
|
bool wxTextDropTarget::OnMove( int WXUNUSED(x), int WXUNUSED(y) )
|
||||||
{
|
{
|
||||||
return IsSupported( wxDF_TEXT ); // same as "STRING"
|
return IsSupported( wxDF_TEXT );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxTextDropTarget::OnDrop( int x, int y )
|
bool wxTextDropTarget::OnDrop( int WXUNUSED(x), int WXUNUSED(y) )
|
||||||
{
|
{
|
||||||
if (!IsSupported( wxDF_TEXT )) return FALSE;
|
if (IsSupported( wxDF_TEXT ))
|
||||||
|
{
|
||||||
|
RequestData( wxDF_TEXT );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxTextDropTarget::OnData( int x, int y )
|
||||||
|
{
|
||||||
wxTextDataObject data;
|
wxTextDataObject data;
|
||||||
if (!GetData( &data )) return FALSE;
|
if (!GetData( &data )) return FALSE;
|
||||||
|
|
||||||
OnDropText( x, y, data.GetText() );
|
OnDropText( x, y, data.GetText() );
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,7 +498,18 @@ bool wxPrivateDropTarget::OnMove( int WXUNUSED(x), int WXUNUSED(y) )
|
|||||||
return IsSupported( m_id );
|
return IsSupported( m_id );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxPrivateDropTarget::OnDrop( int x, int y )
|
bool wxPrivateDropTarget::OnDrop( int WXUNUSED(x), int WXUNUSED(y) )
|
||||||
|
{
|
||||||
|
if (!IsSupported( m_id ))
|
||||||
|
{
|
||||||
|
RequestData( m_id );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxPrivateDropTarget::OnData( int x, int y )
|
||||||
{
|
{
|
||||||
if (!IsSupported( m_id )) return FALSE;
|
if (!IsSupported( m_id )) return FALSE;
|
||||||
|
|
||||||
@@ -514,18 +527,24 @@ bool wxPrivateDropTarget::OnDrop( int x, int y )
|
|||||||
|
|
||||||
bool wxFileDropTarget::OnMove( int WXUNUSED(x), int WXUNUSED(y) )
|
bool wxFileDropTarget::OnMove( int WXUNUSED(x), int WXUNUSED(y) )
|
||||||
{
|
{
|
||||||
return IsSupported( wxDF_FILENAME ); // same as "file:ALL"
|
return IsSupported( wxDF_FILENAME );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxFileDropTarget::OnDrop( int x, int y )
|
bool wxFileDropTarget::OnDrop( int x, int y )
|
||||||
{
|
{
|
||||||
return IsSupported( wxDF_FILENAME ); // same as "file:ALL"
|
if (IsSupported( wxDF_FILENAME ))
|
||||||
|
{
|
||||||
|
RequestData( wxDF_FILENAME );
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxFileDropTarget::OnData( int x, int y )
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxFileDropTarget::OnData( int x, int y )
|
||||||
{
|
{
|
||||||
wxFileDataObject data;
|
wxFileDataObject data;
|
||||||
if (!GetData( &data )) return;
|
if (!GetData( &data )) return FALSE;
|
||||||
|
|
||||||
/* get number of substrings /root/mytext.txt/0/root/myothertext.txt/0/0 */
|
/* get number of substrings /root/mytext.txt/0/root/myothertext.txt/0/0 */
|
||||||
size_t number = 0;
|
size_t number = 0;
|
||||||
@@ -535,7 +554,7 @@ void wxFileDropTarget::OnData( int x, int y )
|
|||||||
for ( i = 0; i < size; i++)
|
for ( i = 0; i < size; i++)
|
||||||
if (text[i] == 0) number++;
|
if (text[i] == 0) number++;
|
||||||
|
|
||||||
if (number == 0) return;
|
if (number == 0) return FALSE;
|
||||||
|
|
||||||
char **files = new char*[number];
|
char **files = new char*[number];
|
||||||
|
|
||||||
@@ -550,6 +569,8 @@ void wxFileDropTarget::OnData( int x, int y )
|
|||||||
OnDropFiles( x, y, number, files );
|
OnDropFiles( x, y, number, files );
|
||||||
|
|
||||||
free( files );
|
free( files );
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -564,8 +585,8 @@ source_drag_data_get (GtkWidget *WXUNUSED(widget),
|
|||||||
guint WXUNUSED(time),
|
guint WXUNUSED(time),
|
||||||
wxDropSource *drop_source )
|
wxDropSource *drop_source )
|
||||||
{
|
{
|
||||||
char *name = gdk_atom_name( selection_data->target );
|
// char *name = gdk_atom_name( selection_data->target );
|
||||||
if (name) printf( "Format requested: %s.\n", name );
|
// if (name) printf( "Format requested: %s.\n", name );
|
||||||
|
|
||||||
wxNode *node = drop_source->m_data->m_dataObjects.First();
|
wxNode *node = drop_source->m_data->m_dataObjects.First();
|
||||||
while (node)
|
while (node)
|
||||||
@@ -784,6 +805,8 @@ wxDragResult wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove) )
|
|||||||
0,
|
0,
|
||||||
0 );
|
0 );
|
||||||
|
|
||||||
|
gdk_flush();
|
||||||
|
|
||||||
while (m_waiting) wxYield();
|
while (m_waiting) wxYield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user