Further DnD changes. Untested.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4072 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
7cdc2f1e42
commit
8e00741dbd
@ -1719,8 +1719,9 @@ from within wxWindow::OnSize functions.}
|
||||
|
||||
\wxheading{Remarks}
|
||||
|
||||
Note that this function is actually disabled for wxWindow and only indirectly
|
||||
takes affect for children of wxDialog, wxFrame, wxNotebook and wxSplitterWindow.
|
||||
Note that this function is actually disabled for wxWindow (and wxPanel). It has
|
||||
effect for wxDialog, wxFrame and wxScrolledWindow as well as indirectly for
|
||||
children of wxNotebook and wxSplitterWindow.
|
||||
|
||||
\wxheading{See also}
|
||||
|
||||
|
@ -184,6 +184,8 @@ public:
|
||||
wxFileDataObject();
|
||||
|
||||
void AddFile( const wxString &file );
|
||||
void SetFiles( const wxString &files )
|
||||
{ m_files = files; }
|
||||
wxString GetFiles() const;
|
||||
|
||||
virtual wxDataFormat GetPreferredFormat() const
|
||||
|
@ -46,125 +46,50 @@ class wxDropSource;
|
||||
class wxDropTarget: public wxObject
|
||||
{
|
||||
public:
|
||||
wxDropTarget( wxDataObject *data );
|
||||
~wxDropTarget();
|
||||
|
||||
wxDropTarget();
|
||||
~wxDropTarget();
|
||||
|
||||
/* may be overridden to react to events */
|
||||
virtual void OnEnter();
|
||||
virtual void OnLeave();
|
||||
|
||||
/* may be overridden to reject certain formats or drops
|
||||
on certain areas. always returns TRUE by default
|
||||
indicating that you'd accept the data from the drag. */
|
||||
virtual bool OnMove( long x, long y );
|
||||
|
||||
/* has to be overridden to accept a drop event. call
|
||||
IsSupported() to ask which formats are available
|
||||
and then call RequestData() to indicate the format
|
||||
you request. */
|
||||
virtual bool OnDrop( long x, long y );
|
||||
|
||||
/* this gets called once the data has actually arrived. get
|
||||
it with GetData(). this has to be overridden. */
|
||||
virtual bool OnData( long x, long 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 */
|
||||
bool IsSupported( wxDataFormat format );
|
||||
|
||||
/* fill data with data from the dragging source */
|
||||
bool GetData( wxDataObject *data );
|
||||
|
||||
virtual size_t GetFormatCount() const = 0;
|
||||
virtual wxDataFormat GetFormat(size_t n) const = 0;
|
||||
/* may be overridden to react to events */
|
||||
virtual bool OnEnter( int x, int y );
|
||||
|
||||
virtual void OnLeave();
|
||||
|
||||
/* may be overridden to reject certain formats or drops
|
||||
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 );
|
||||
|
||||
/* has to be overridden to accept a drop event. call
|
||||
IsSupported() to ask which formats are available
|
||||
and then call RequestData() to indicate the format
|
||||
you request. */
|
||||
virtual bool OnDrop( int x, int y );
|
||||
|
||||
/* this gets called once the data has actually arrived.
|
||||
it will call GetData() to fill up its wxDataObject */
|
||||
virtual bool OnData( int x, int y );
|
||||
|
||||
/* fill data with data from the dragging source */
|
||||
bool GetData();
|
||||
|
||||
// implementation
|
||||
|
||||
void RegisterWidget( GtkWidget *widget );
|
||||
void UnregisterWidget( GtkWidget *widget );
|
||||
GdkAtom GetMatchingPair();
|
||||
|
||||
GdkDragContext *m_dragContext;
|
||||
GtkWidget *m_dragWidget;
|
||||
GtkSelectionData *m_dragData;
|
||||
guint m_dragTime;
|
||||
bool m_firstMotion; /* gdk has no "gdk_drag_enter" event */
|
||||
void RegisterWidget( GtkWidget *widget );
|
||||
void UnregisterWidget( GtkWidget *widget );
|
||||
|
||||
void SetDragContext( GdkDragContext *dc ) { m_dragContext = dc; }
|
||||
void SetDragWidget( GtkWidget *w ) { m_dragWidget = w; }
|
||||
void SetDragData( GtkSelectionData *sd ) { m_dragData = sd; }
|
||||
void SetDragTime( guint time ) { m_dragTime = time; }
|
||||
};
|
||||
wxDataObject *m_data;
|
||||
GdkDragContext *m_dragContext;
|
||||
GtkWidget *m_dragWidget;
|
||||
GtkSelectionData *m_dragData;
|
||||
guint m_dragTime;
|
||||
bool m_firstMotion; /* gdk has no "gdk_drag_enter" event */
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// wxTextDropTarget
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
class wxTextDropTarget: public wxDropTarget
|
||||
{
|
||||
public:
|
||||
|
||||
wxTextDropTarget() {}
|
||||
|
||||
virtual bool OnData( long x, long y );
|
||||
|
||||
/* you have to override OnDropData to get at the text */
|
||||
virtual bool OnDropText( long x, long y, const wxChar *text ) = 0;
|
||||
|
||||
virtual size_t GetFormatCount() const
|
||||
{ return 1; }
|
||||
virtual wxDataFormat GetFormat(size_t n) const
|
||||
{ return wxDF_TEXT; }
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// wxPrivateDropTarget
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
class wxPrivateDropTarget: public wxDropTarget
|
||||
{
|
||||
public:
|
||||
|
||||
wxPrivateDropTarget();
|
||||
wxPrivateDropTarget( const wxString &id );
|
||||
|
||||
virtual bool OnMove( long x, long y );
|
||||
virtual bool OnDrop( long x, long y );
|
||||
virtual bool OnData( long x, long y );
|
||||
|
||||
virtual bool OnDropData( long x, long y, void *data, size_t size ) = 0;
|
||||
|
||||
void SetId( const wxString& id ) { m_id = id; }
|
||||
wxString GetId() { return m_id; }
|
||||
|
||||
private:
|
||||
|
||||
wxString m_id;
|
||||
};
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// A drop target which accepts files (dragged from File Manager or Explorer)
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class wxFileDropTarget: public wxDropTarget
|
||||
{
|
||||
public:
|
||||
|
||||
wxFileDropTarget() {}
|
||||
|
||||
virtual bool OnData( long x, long y );
|
||||
|
||||
virtual bool OnDropFiles( long x, long y, size_t nFiles, const wxChar * const aszFiles[] ) = 0;
|
||||
|
||||
virtual size_t GetFormatCount() const
|
||||
{ return 1; }
|
||||
virtual wxDataFormat GetFormat(size_t n) const
|
||||
{ return wxDF_FILENAME; }
|
||||
void SetDragContext( GdkDragContext *dc ) { m_dragContext = dc; }
|
||||
void SetDragWidget( GtkWidget *w ) { m_dragWidget = w; }
|
||||
void SetDragData( GtkSelectionData *sd ) { m_dragData = sd; }
|
||||
void SetDragTime( guint time ) { m_dragTime = time; }
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -184,6 +184,8 @@ public:
|
||||
wxFileDataObject();
|
||||
|
||||
void AddFile( const wxString &file );
|
||||
void SetFiles( const wxString &files )
|
||||
{ m_files = files; }
|
||||
wxString GetFiles() const;
|
||||
|
||||
virtual wxDataFormat GetPreferredFormat() const
|
||||
|
@ -46,125 +46,50 @@ class wxDropSource;
|
||||
class wxDropTarget: public wxObject
|
||||
{
|
||||
public:
|
||||
wxDropTarget( wxDataObject *data );
|
||||
~wxDropTarget();
|
||||
|
||||
wxDropTarget();
|
||||
~wxDropTarget();
|
||||
|
||||
/* may be overridden to react to events */
|
||||
virtual void OnEnter();
|
||||
virtual void OnLeave();
|
||||
|
||||
/* may be overridden to reject certain formats or drops
|
||||
on certain areas. always returns TRUE by default
|
||||
indicating that you'd accept the data from the drag. */
|
||||
virtual bool OnMove( long x, long y );
|
||||
|
||||
/* has to be overridden to accept a drop event. call
|
||||
IsSupported() to ask which formats are available
|
||||
and then call RequestData() to indicate the format
|
||||
you request. */
|
||||
virtual bool OnDrop( long x, long y );
|
||||
|
||||
/* this gets called once the data has actually arrived. get
|
||||
it with GetData(). this has to be overridden. */
|
||||
virtual bool OnData( long x, long 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 */
|
||||
bool IsSupported( wxDataFormat format );
|
||||
|
||||
/* fill data with data from the dragging source */
|
||||
bool GetData( wxDataObject *data );
|
||||
|
||||
virtual size_t GetFormatCount() const = 0;
|
||||
virtual wxDataFormat GetFormat(size_t n) const = 0;
|
||||
/* may be overridden to react to events */
|
||||
virtual bool OnEnter( int x, int y );
|
||||
|
||||
virtual void OnLeave();
|
||||
|
||||
/* may be overridden to reject certain formats or drops
|
||||
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 );
|
||||
|
||||
/* has to be overridden to accept a drop event. call
|
||||
IsSupported() to ask which formats are available
|
||||
and then call RequestData() to indicate the format
|
||||
you request. */
|
||||
virtual bool OnDrop( int x, int y );
|
||||
|
||||
/* this gets called once the data has actually arrived.
|
||||
it will call GetData() to fill up its wxDataObject */
|
||||
virtual bool OnData( int x, int y );
|
||||
|
||||
/* fill data with data from the dragging source */
|
||||
bool GetData();
|
||||
|
||||
// implementation
|
||||
|
||||
void RegisterWidget( GtkWidget *widget );
|
||||
void UnregisterWidget( GtkWidget *widget );
|
||||
GdkAtom GetMatchingPair();
|
||||
|
||||
GdkDragContext *m_dragContext;
|
||||
GtkWidget *m_dragWidget;
|
||||
GtkSelectionData *m_dragData;
|
||||
guint m_dragTime;
|
||||
bool m_firstMotion; /* gdk has no "gdk_drag_enter" event */
|
||||
void RegisterWidget( GtkWidget *widget );
|
||||
void UnregisterWidget( GtkWidget *widget );
|
||||
|
||||
void SetDragContext( GdkDragContext *dc ) { m_dragContext = dc; }
|
||||
void SetDragWidget( GtkWidget *w ) { m_dragWidget = w; }
|
||||
void SetDragData( GtkSelectionData *sd ) { m_dragData = sd; }
|
||||
void SetDragTime( guint time ) { m_dragTime = time; }
|
||||
};
|
||||
wxDataObject *m_data;
|
||||
GdkDragContext *m_dragContext;
|
||||
GtkWidget *m_dragWidget;
|
||||
GtkSelectionData *m_dragData;
|
||||
guint m_dragTime;
|
||||
bool m_firstMotion; /* gdk has no "gdk_drag_enter" event */
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// wxTextDropTarget
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
class wxTextDropTarget: public wxDropTarget
|
||||
{
|
||||
public:
|
||||
|
||||
wxTextDropTarget() {}
|
||||
|
||||
virtual bool OnData( long x, long y );
|
||||
|
||||
/* you have to override OnDropData to get at the text */
|
||||
virtual bool OnDropText( long x, long y, const wxChar *text ) = 0;
|
||||
|
||||
virtual size_t GetFormatCount() const
|
||||
{ return 1; }
|
||||
virtual wxDataFormat GetFormat(size_t n) const
|
||||
{ return wxDF_TEXT; }
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// wxPrivateDropTarget
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
class wxPrivateDropTarget: public wxDropTarget
|
||||
{
|
||||
public:
|
||||
|
||||
wxPrivateDropTarget();
|
||||
wxPrivateDropTarget( const wxString &id );
|
||||
|
||||
virtual bool OnMove( long x, long y );
|
||||
virtual bool OnDrop( long x, long y );
|
||||
virtual bool OnData( long x, long y );
|
||||
|
||||
virtual bool OnDropData( long x, long y, void *data, size_t size ) = 0;
|
||||
|
||||
void SetId( const wxString& id ) { m_id = id; }
|
||||
wxString GetId() { return m_id; }
|
||||
|
||||
private:
|
||||
|
||||
wxString m_id;
|
||||
};
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// A drop target which accepts files (dragged from File Manager or Explorer)
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class wxFileDropTarget: public wxDropTarget
|
||||
{
|
||||
public:
|
||||
|
||||
wxFileDropTarget() {}
|
||||
|
||||
virtual bool OnData( long x, long y );
|
||||
|
||||
virtual bool OnDropFiles( long x, long y, size_t nFiles, const wxChar * const aszFiles[] ) = 0;
|
||||
|
||||
virtual size_t GetFormatCount() const
|
||||
{ return 1; }
|
||||
virtual wxDataFormat GetFormat(size_t n) const
|
||||
{ return wxDF_FILENAME; }
|
||||
void SetDragContext( GdkDragContext *dc ) { m_dragContext = dc; }
|
||||
void SetDragWidget( GtkWidget *w ) { m_dragWidget = w; }
|
||||
void SetDragData( GtkSelectionData *sd ) { m_dragData = sd; }
|
||||
void SetDragTime( guint time ) { m_dragTime = time; }
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
252
src/gtk/dnd.cpp
252
src/gtk/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
|
||||
@ -258,6 +262,27 @@ static gboolean target_drag_drop( GtkWidget *widget,
|
||||
FALSE, /* don't delete data on dropping side */
|
||||
time );
|
||||
}
|
||||
else
|
||||
{
|
||||
#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 );
|
||||
@ -324,137 +349,114 @@ static void target_drag_data_received( GtkWidget *WXUNUSED(widget),
|
||||
// wxDropTarget
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
wxDropTarget::wxDropTarget()
|
||||
wxDropTarget::wxDropTarget( wxDataObject *data )
|
||||
{
|
||||
m_firstMotion = TRUE;
|
||||
m_dragContext = (GdkDragContext*) NULL;
|
||||
m_dragWidget = (GtkWidget*) NULL;
|
||||
m_dragData = (GtkSelectionData*) NULL;
|
||||
m_dragTime = 0;
|
||||
m_data = data;
|
||||
}
|
||||
|
||||
wxDropTarget::~wxDropTarget()
|
||||
{
|
||||
}
|
||||
|
||||
void wxDropTarget::OnEnter()
|
||||
bool wxDropTarget::OnEnter( int WXUNUSED(x), int WXUNUSED(y) )
|
||||
{
|
||||
if (!m_data)
|
||||
return FALSE;
|
||||
|
||||
return (GetMatchingPair() != (GdkAtom) 0);
|
||||
}
|
||||
|
||||
void wxDropTarget::OnLeave()
|
||||
{
|
||||
}
|
||||
|
||||
bool wxDropTarget::OnMove( long WXUNUSED(x), long WXUNUSED(y) )
|
||||
bool wxDropTarget::OnMove( int WXUNUSED(x), int WXUNUSED(y) )
|
||||
{
|
||||
if (GetFormatCount() == 0)
|
||||
if (!m_data)
|
||||
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_data)
|
||||
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_data)
|
||||
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_data)
|
||||
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_data->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_data)
|
||||
return FALSE;
|
||||
|
||||
if (data_object->GetFormat().GetType() == wxDF_TEXT)
|
||||
wxDataFormat dragFormat( m_dragData->target );
|
||||
|
||||
if (!m_data->IsSupportedFormat( dragFormat ))
|
||||
return FALSE;
|
||||
|
||||
if (dragFormat.GetType() == wxDF_TEXT)
|
||||
{
|
||||
wxTextDataObject *text_object = (wxTextDataObject*)data_object;
|
||||
wxTextDataObject *text_object = (wxTextDataObject*)m_data;
|
||||
text_object->SetText( (const char*)m_dragData->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*)m_dragData->data, (size_t)m_dragData->length );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
if (dragFormat.GetType() == wxDF_FILENAME)
|
||||
{
|
||||
wxFileDataObject *file_object = (wxFileDataObject*)m_data;
|
||||
file_object->SetFiles( (const char*)m_dragData->data );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void wxDropTarget::UnregisterWidget( GtkWidget *widget )
|
||||
@ -509,100 +511,6 @@ void wxDropTarget::RegisterWidget( GtkWidget *widget )
|
||||
GTK_SIGNAL_FUNC(target_drag_data_received), (gpointer) this );
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// wxTextDropTarget
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
bool wxTextDropTarget::OnData( long x, long y )
|
||||
{
|
||||
wxTextDataObject data;
|
||||
if (!GetData( &data )) return FALSE;
|
||||
|
||||
OnDropText( x, y, data.GetText() );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// wxPrivateDropTarget
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
wxPrivateDropTarget::wxPrivateDropTarget()
|
||||
{
|
||||
m_id = wxTheApp->GetAppName();
|
||||
}
|
||||
|
||||
wxPrivateDropTarget::wxPrivateDropTarget( const wxString &id )
|
||||
{
|
||||
m_id = id;
|
||||
}
|
||||
|
||||
bool wxPrivateDropTarget::OnMove( long WXUNUSED(x), long WXUNUSED(y) )
|
||||
{
|
||||
return IsSupported( m_id );
|
||||
}
|
||||
|
||||
bool wxPrivateDropTarget::OnDrop( long WXUNUSED(x), long WXUNUSED(y) )
|
||||
{
|
||||
if (!IsSupported( m_id ))
|
||||
{
|
||||
RequestData( m_id );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool wxPrivateDropTarget::OnData( long x, long 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 );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// "drag_data_get"
|
||||
//----------------------------------------------------------------------------
|
||||
|
252
src/gtk1/dnd.cpp
252
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
|
||||
@ -258,6 +262,27 @@ static gboolean target_drag_drop( GtkWidget *widget,
|
||||
FALSE, /* don't delete data on dropping side */
|
||||
time );
|
||||
}
|
||||
else
|
||||
{
|
||||
#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 );
|
||||
@ -324,137 +349,114 @@ static void target_drag_data_received( GtkWidget *WXUNUSED(widget),
|
||||
// wxDropTarget
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
wxDropTarget::wxDropTarget()
|
||||
wxDropTarget::wxDropTarget( wxDataObject *data )
|
||||
{
|
||||
m_firstMotion = TRUE;
|
||||
m_dragContext = (GdkDragContext*) NULL;
|
||||
m_dragWidget = (GtkWidget*) NULL;
|
||||
m_dragData = (GtkSelectionData*) NULL;
|
||||
m_dragTime = 0;
|
||||
m_data = data;
|
||||
}
|
||||
|
||||
wxDropTarget::~wxDropTarget()
|
||||
{
|
||||
}
|
||||
|
||||
void wxDropTarget::OnEnter()
|
||||
bool wxDropTarget::OnEnter( int WXUNUSED(x), int WXUNUSED(y) )
|
||||
{
|
||||
if (!m_data)
|
||||
return FALSE;
|
||||
|
||||
return (GetMatchingPair() != (GdkAtom) 0);
|
||||
}
|
||||
|
||||
void wxDropTarget::OnLeave()
|
||||
{
|
||||
}
|
||||
|
||||
bool wxDropTarget::OnMove( long WXUNUSED(x), long WXUNUSED(y) )
|
||||
bool wxDropTarget::OnMove( int WXUNUSED(x), int WXUNUSED(y) )
|
||||
{
|
||||
if (GetFormatCount() == 0)
|
||||
if (!m_data)
|
||||
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_data)
|
||||
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_data)
|
||||
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_data)
|
||||
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_data->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_data)
|
||||
return FALSE;
|
||||
|
||||
if (data_object->GetFormat().GetType() == wxDF_TEXT)
|
||||
wxDataFormat dragFormat( m_dragData->target );
|
||||
|
||||
if (!m_data->IsSupportedFormat( dragFormat ))
|
||||
return FALSE;
|
||||
|
||||
if (dragFormat.GetType() == wxDF_TEXT)
|
||||
{
|
||||
wxTextDataObject *text_object = (wxTextDataObject*)data_object;
|
||||
wxTextDataObject *text_object = (wxTextDataObject*)m_data;
|
||||
text_object->SetText( (const char*)m_dragData->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*)m_dragData->data, (size_t)m_dragData->length );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
if (dragFormat.GetType() == wxDF_FILENAME)
|
||||
{
|
||||
wxFileDataObject *file_object = (wxFileDataObject*)m_data;
|
||||
file_object->SetFiles( (const char*)m_dragData->data );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void wxDropTarget::UnregisterWidget( GtkWidget *widget )
|
||||
@ -509,100 +511,6 @@ void wxDropTarget::RegisterWidget( GtkWidget *widget )
|
||||
GTK_SIGNAL_FUNC(target_drag_data_received), (gpointer) this );
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// wxTextDropTarget
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
bool wxTextDropTarget::OnData( long x, long y )
|
||||
{
|
||||
wxTextDataObject data;
|
||||
if (!GetData( &data )) return FALSE;
|
||||
|
||||
OnDropText( x, y, data.GetText() );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// wxPrivateDropTarget
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
wxPrivateDropTarget::wxPrivateDropTarget()
|
||||
{
|
||||
m_id = wxTheApp->GetAppName();
|
||||
}
|
||||
|
||||
wxPrivateDropTarget::wxPrivateDropTarget( const wxString &id )
|
||||
{
|
||||
m_id = id;
|
||||
}
|
||||
|
||||
bool wxPrivateDropTarget::OnMove( long WXUNUSED(x), long WXUNUSED(y) )
|
||||
{
|
||||
return IsSupported( m_id );
|
||||
}
|
||||
|
||||
bool wxPrivateDropTarget::OnDrop( long WXUNUSED(x), long WXUNUSED(y) )
|
||||
{
|
||||
if (!IsSupported( m_id ))
|
||||
{
|
||||
RequestData( m_id );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool wxPrivateDropTarget::OnData( long x, long 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 );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// "drag_data_get"
|
||||
//----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user