From e4de825ee6f3f991e2aa86159d6e3457afb6a8e0 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Tue, 20 Jan 2009 13:46:21 +0000 Subject: [PATCH 1/1] Add event based Drop API git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58240 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/dataview.h | 31 ++++++++++++++-- interface/wx/dataview.h | 51 +++++++++++++++++++++++-- samples/dataview/dataview.cpp | 35 ++++++++++++++++++ src/common/datavcmn.cpp | 7 ++++ src/gtk/dataview.cpp | 70 ++++++++++++++++++++++++++++++++--- 5 files changed, 181 insertions(+), 13 deletions(-) diff --git a/include/wx/dataview.h b/include/wx/dataview.h index 17d6f3e092..2437dac427 100644 --- a/include/wx/dataview.h +++ b/include/wx/dataview.h @@ -715,6 +715,7 @@ public: virtual wxRect GetItemRect( const wxDataViewItem & item, const wxDataViewColumn *column = NULL ) const = 0; virtual bool EnableDragSource( const wxDataFormat &format ); + virtual bool EnableDropTarget( const wxDataFormat &format ); protected: virtual void DoSetExpanderColumn() = 0 ; @@ -744,7 +745,9 @@ public: m_value(wxNullVariant), m_column(NULL), m_pos(-1,-1), - m_dataObject(NULL) + m_dataObject(NULL), + m_dataBuffer(NULL), + m_dataSize(0) { } wxDataViewEvent(const wxDataViewEvent& event) @@ -755,7 +758,10 @@ public: m_value(event.m_value), m_column(event.m_column), m_pos(m_pos), - m_dataObject(event.m_dataObject) + m_dataObject(event.m_dataObject), + m_dataFormat(event.m_dataFormat), + m_dataBuffer(event.m_dataBuffer), + m_dataSize(event.m_dataSize) { } wxDataViewItem GetItem() const { return m_item; } @@ -778,9 +784,17 @@ public: wxPoint GetPosition() const { return m_pos; } void SetPosition( int x, int y ) { m_pos.x = x; m_pos.y = y; } - // For DnD operations + // For drag operations void SetDataObject( wxDataObject *obj ) { m_dataObject = obj; } - wxDataObject *GetDataObject() { return m_dataObject; } + wxDataObject *GetDataObject() const { return m_dataObject; } + + // For drop operations + void SetDataFormat( const wxDataFormat &format ) { m_dataFormat = format; } + wxDataFormat GetDataFormat() const { return m_dataFormat; } + void SetDataSize( size_t size ) { m_dataSize = size; } + size_t GetDataSize() const { return m_dataSize; } + void SetDataBuffer( void* buf ) { m_dataBuffer = buf;} + void *GetDataBuffer() const { return m_dataBuffer; } virtual wxEvent *Clone() const { return new wxDataViewEvent(*this); } @@ -791,7 +805,12 @@ protected: wxVariant m_value; wxDataViewColumn *m_column; wxPoint m_pos; + wxDataObject *m_dataObject; + + wxDataFormat m_dataFormat; + void* m_dataBuffer; + size_t m_dataSize; private: DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxDataViewEvent) @@ -816,6 +835,8 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED, wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_COLUMN_REORDERED, wxDataViewEvent ) wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG, wxDataViewEvent ) +wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE, wxDataViewEvent ) +wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_ITEM_DROP, wxDataViewEvent ) typedef void (wxEvtHandler::*wxDataViewEventFunction)(wxDataViewEvent&); @@ -844,6 +865,8 @@ typedef void (wxEvtHandler::*wxDataViewEventFunction)(wxDataViewEvent&); #define EVT_DATAVIEW_COLUMN_REORDERED(id, fn) wx__DECLARE_DATAVIEWEVT(COLUMN_REORDERED, id, fn) #define EVT_DATAVIEW_ITEM_BEGIN_DRAG(id, fn) wx__DECLARE_DATAVIEWEVT(ITEM_BEGIN_DRAG, id, fn) +#define EVT_DATAVIEW_ITEM_DROP_POSSIBLE(id, fn) wx__DECLARE_DATAVIEWEVT(ITEM_DROP_POSSIBLE, id, fn) +#define EVT_DATAVIEW_ITEM_DROP(id, fn) wx__DECLARE_DATAVIEWEVT(ITEM_DROP, id, fn) #ifdef wxHAS_GENERIC_DATAVIEWCTRL // this symbol doesn't follow the convention for wxUSE_XXX symbols which diff --git a/interface/wx/dataview.h b/interface/wx/dataview.h index 550edd0a89..c4ac26a10b 100644 --- a/interface/wx/dataview.h +++ b/interface/wx/dataview.h @@ -556,6 +556,10 @@ public: Process a wxEVT_COMMAND_DATAVIEW_COLUMN_REORDERED event. @event{EVT_DATAVIEW_ITEM_BEGIN_DRAG(id, func)} Process a wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG event. + @event{EVT_DATAVIEW_ITEM_DROP_POSSIBLE(id, func)} + Process a wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE event. + @event{EVT_DATAVIEW_ITEM_DROP(id, func)} + Process a wxEVT_COMMAND_DATAVIEW_ITEM_DROP event. @endEventTable @library{wxadv} @@ -765,6 +769,16 @@ public: */ virtual bool DeleteColumn(wxDataViewColumn* column); + /** + Enable drag operations using the given @a format. + */ + virtual bool EnableDragSource( const wxDataFormat &format ); + + /** + Enable drop operations using the given @a format. + */ + virtual bool EnableDropTarget( const wxDataFormat &format ); + /** Call this to ensure that the given item is visible. */ @@ -2253,13 +2267,44 @@ public: void SetValue(const wxVariant& value); /** - Set wxDataObject for Drag'n'drop data transfer. + Set wxDataObject for data transfer within a drag operation. */ void SetDataObject( wxDataObject *obj ); /** - Gets associated wxDataObject for Drag'n'drop data transfer. + Used internally. Gets associated wxDataObject for data transfer + within a drag operation. + */ + wxDataObject *GetDataObject() const; + + /** + Used internally. Sets the wxDataFormat during a drop operation. + */ + void SetDataFormat( const wxDataFormat &format ); + + /** + Gets the wxDataFormat during a drop operation. + */ + wxDataFormat GetDataFormat() const; + + /** + Used internally. Sets the data size for a drop data transfer. + */ + void SetDataSize( size_t size ); + + /** + Gets the data size for a drop data transfer. + */ + size_t GetDataSize() const; + + /** + Used internally. Sets the data buffer for a drop data transfer. + */ + void SetDataBuffer( void* buf ); + + /** + Gets the data buffer for a drop data transfer. */ - wxDataObject *GetDataObject(); + void *GetDataBuffer() const; }; diff --git a/samples/dataview/dataview.cpp b/samples/dataview/dataview.cpp index b533b57bdb..0df4c89a4b 100644 --- a/samples/dataview/dataview.cpp +++ b/samples/dataview/dataview.cpp @@ -670,6 +670,8 @@ public: void OnAddMany( wxCommandEvent &event); void OnBeginDrag( wxDataViewEvent &event ); + void OnDropPossible( wxDataViewEvent &event ); + void OnDrop( wxDataViewEvent &event ); private: wxDataViewCtrl* m_musicCtrl; @@ -767,6 +769,8 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_DATAVIEW_ITEM_CONTEXT_MENU(ID_MUSIC_CTRL, MyFrame::OnContextMenu) EVT_DATAVIEW_ITEM_BEGIN_DRAG( ID_MUSIC_CTRL, MyFrame::OnBeginDrag ) + EVT_DATAVIEW_ITEM_DROP_POSSIBLE( ID_MUSIC_CTRL, MyFrame::OnDropPossible ) + EVT_DATAVIEW_ITEM_DROP( ID_MUSIC_CTRL, MyFrame::OnDrop ) EVT_RIGHT_UP(MyFrame::OnRightClick) END_EVENT_TABLE() @@ -807,6 +811,7 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int m_musicCtrl->AssociateModel( m_music_model.get() ); m_musicCtrl->EnableDragSource( wxDF_TEXT ); + m_musicCtrl->EnableDropTarget( wxDF_TEXT ); wxDataViewTextRenderer *tr = new wxDataViewTextRenderer( wxT("string"), wxDATAVIEW_CELL_INERT ); wxDataViewColumn *column0 = new wxDataViewColumn( wxT("title"), tr, 0, 200, wxALIGN_LEFT, @@ -1171,3 +1176,33 @@ void MyFrame::OnBeginDrag( wxDataViewEvent &event ) obj->SetText( node->m_title ); event.SetDataObject( obj ); } + +void MyFrame::OnDropPossible( wxDataViewEvent &event ) +{ + wxDataViewItem item( event.GetItem() ); + + // only allow drags for item, not containers + if (m_music_model->IsContainer( item ) ) + event.Veto(); + + if (event.GetDataFormat() != wxDF_TEXT) + event.Veto(); +} + +void MyFrame::OnDrop( wxDataViewEvent &event ) +{ + wxDataViewItem item( event.GetItem() ); + + // only allow drags for item, not containers + if (m_music_model->IsContainer( item ) ) + event.Veto(); + + if (event.GetDataFormat() != wxDF_TEXT) + event.Veto(); + + wxTextDataObject obj; + obj.SetData( wxDF_TEXT, event.GetDataSize(), event.GetDataBuffer() ); + + wxLogMessage(wxT("Text dropped: %s"), obj.GetText() ); +} + diff --git a/src/common/datavcmn.cpp b/src/common/datavcmn.cpp index 2bc6102f0f..39d6ba8b8e 100644 --- a/src/common/datavcmn.cpp +++ b/src/common/datavcmn.cpp @@ -901,6 +901,11 @@ bool wxDataViewCtrlBase::EnableDragSource( const wxDataFormat &WXUNUSED(format) return false; } +bool wxDataViewCtrlBase::EnableDropTarget( const wxDataFormat &WXUNUSED(format) ) +{ + return false; +} + void wxDataViewCtrlBase::ExpandAncestors( const wxDataViewItem & item ) { if (!m_model) return; @@ -1236,6 +1241,8 @@ wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED, wxDataViewEvent ) wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_COLUMN_REORDERED, wxDataViewEvent ) wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG, wxDataViewEvent ) +wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE, wxDataViewEvent ) +wxDEFINE_EVENT( wxEVT_COMMAND_DATAVIEW_ITEM_DROP, wxDataViewEvent ) // ------------------------------------- // wxDataViewSpinRenderer diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index 62eb070d42..5c9c64c115 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -76,6 +76,7 @@ public: // dnd iface bool EnableDragSource( const wxDataFormat &format ); + bool EnableDropTarget( const wxDataFormat &format ); gboolean row_draggable( GtkTreeDragSource *drag_source, GtkTreePath *path ); gboolean drag_data_delete( GtkTreeDragSource *drag_source, GtkTreePath* path ); @@ -127,9 +128,13 @@ private: GtkSortType m_sort_order; wxDataViewColumn *m_dataview_sort_column; int m_sort_column; + GtkTargetEntry m_dragSourceTargetEntry; wxCharBuffer m_dragSourceTargetEntryTarget; wxDataObject *m_dragDataObject; + + GtkTargetEntry m_dropTargetTargetEntry; + wxCharBuffer m_dropTargetTargetEntryTarget; wxDataObject *m_dropDataObject; }; @@ -2941,6 +2946,21 @@ bool wxDataViewCtrlInternal::EnableDragSource( const wxDataFormat &format ) return true; } +bool wxDataViewCtrlInternal::EnableDropTarget( const wxDataFormat &format ) +{ + wxGtkString atom_str( gdk_atom_name( format ) ); + m_dropTargetTargetEntryTarget = wxCharBuffer( atom_str ); + + m_dropTargetTargetEntry.target = m_dragSourceTargetEntryTarget.data(); + m_dropTargetTargetEntry.flags = 0; + m_dropTargetTargetEntry.info = static_cast(-1); + + gtk_tree_view_enable_model_drag_dest( GTK_TREE_VIEW(m_owner->GtkGetTreeView() ), + &m_dropTargetTargetEntry, 1, (GdkDragAction) GDK_ACTION_COPY ); + + return true; +} + gboolean wxDataViewCtrlInternal::row_draggable( GtkTreeDragSource *WXUNUSED(drag_source), GtkTreePath *path ) { @@ -2951,6 +2971,7 @@ gboolean wxDataViewCtrlInternal::row_draggable( GtkTreeDragSource *WXUNUSED(drag wxDataViewItem item( (void*) iter.user_data ); wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG, m_owner->GetId() ); + event.SetEventObject( m_owner ); event.SetItem( item ); event.SetModel( m_wx_model ); if (!m_owner->HandleWindowEvent( event )) @@ -3007,18 +3028,50 @@ gboolean wxDataViewCtrlInternal::drag_data_get( GtkTreeDragSource *WXUNUSED(drag gboolean wxDataViewCtrlInternal::drag_data_received(GtkTreeDragDest *WXUNUSED(drag_dest), - GtkTreePath *WXUNUSED(dest), - GtkSelectionData *WXUNUSED(selection_data)) + GtkTreePath *path, + GtkSelectionData *selection_data) { - return FALSE; + GtkTreeIter iter; + if (!get_iter( &iter, path )) return FALSE; + wxDataViewItem item( (void*) iter.user_data ); + + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_DROP, m_owner->GetId() ); + event.SetEventObject( m_owner ); + event.SetItem( item ); + event.SetModel( m_wx_model ); + event.SetDataFormat( selection_data->target ); + event.SetDataSize( selection_data->length ); + event.SetDataBuffer( selection_data->data ); + if (!m_owner->HandleWindowEvent( event )) + return FALSE; + + if (!event.IsAllowed()) + return FALSE; + + return TRUE; } gboolean wxDataViewCtrlInternal::row_drop_possible(GtkTreeDragDest *WXUNUSED(drag_dest), - GtkTreePath *WXUNUSED(dest_path), - GtkSelectionData *WXUNUSED(selection_data)) + GtkTreePath *path, + GtkSelectionData *selection_data) { - return FALSE; + GtkTreeIter iter; + if (!get_iter( &iter, path )) return FALSE; + wxDataViewItem item( (void*) iter.user_data ); + + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE, m_owner->GetId() ); + event.SetEventObject( m_owner ); + event.SetItem( item ); + event.SetModel( m_wx_model ); + event.SetDataFormat( selection_data->target ); + if (!m_owner->HandleWindowEvent( event )) + return FALSE; + + if (!event.IsAllowed()) + return FALSE; + + return TRUE; } // notifications from wxDataViewModel @@ -3910,6 +3963,11 @@ bool wxDataViewCtrl::EnableDragSource( const wxDataFormat &format ) return m_internal->EnableDragSource( format ); } +bool wxDataViewCtrl::EnableDropTarget( const wxDataFormat &format ) +{ + return m_internal->EnableDropTarget( format ); +} + bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col ) { if (!wxDataViewCtrlBase::AppendColumn(col)) -- 2.45.2