X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/15cac64f7564d48c274c6490774a77bd8c09f808..f5f172485bf36ac1025395efc8073c1592c30c08:/src/gtk/dataview.cpp diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index 8fd5e37932..2d8a29c111 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -20,10 +20,7 @@ #include "wx/log.h" #include "wx/dcclient.h" #include "wx/sizer.h" - #include "wx/icon.h" - #include "wx/list.h" #include "wx/settings.h" - #include "wx/dataobj.h" #include "wx/crt.h" #endif @@ -39,9 +36,7 @@ //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -class wxDataViewCtrlInternal; - -wxDataViewCtrlInternal *g_internal = NULL; +static wxDataViewCtrlInternal *gs_internal = NULL; class wxGtkTreeModelNode; @@ -56,7 +51,7 @@ typedef struct _GtkWxTreeModel GtkWxTreeModel; WX_DECLARE_LIST(wxDataViewItem, ItemList); WX_DEFINE_LIST(ItemList) -class wxDataViewCtrlInternal +class WXDLLIMPEXP_ADV wxDataViewCtrlInternal { public: wxDataViewCtrlInternal( wxDataViewCtrl *owner, wxDataViewModel *wx_model, GtkWxTreeModel *gtk_model ); @@ -74,9 +69,10 @@ public: gboolean iter_parent( GtkTreeIter *iter, GtkTreeIter *child ); // 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 ); gboolean drag_data_get( GtkTreeDragSource *drag_source, GtkTreePath *path, @@ -127,8 +123,14 @@ 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; }; @@ -136,10 +138,11 @@ private: // wxGtkTreeModelNode //----------------------------------------------------------------------------- +static int LINKAGEMODE wxGtkTreeModelChildCmp( void** id1, void** id2 ) { - int ret = g_internal->GetDataViewModel()->Compare( *id1, *id2, - g_internal->GetSortColumn(), (g_internal->GetSortOrder() == GTK_SORT_ASCENDING) ); + int ret = gs_internal->GetDataViewModel()->Compare( *id1, *id2, + gs_internal->GetSortColumn(), (gs_internal->GetSortOrder() == GTK_SORT_ASCENDING) ); return ret; } @@ -179,7 +182,7 @@ public: if (m_internal->IsSorted() || m_internal->GetDataViewModel()->HasDefaultCompare()) { - g_internal = m_internal; + gs_internal = m_internal; m_children.Sort( &wxGtkTreeModelChildCmp ); return m_children.Index( id ); } @@ -193,7 +196,7 @@ public: if (m_internal->IsSorted() || m_internal->GetDataViewModel()->HasDefaultCompare()) { - g_internal = m_internal; + gs_internal = m_internal; m_children.Sort( &wxGtkTreeModelChildCmp ); return m_children.Index( id ); } @@ -638,8 +641,10 @@ wxgtk_tree_model_iter_n_children (GtkTreeModel *tree_model, { GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model; g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); - g_return_val_if_fail (wxtree_model->stamp == iter->stamp, 0); - + + if (iter != NULL) + g_return_val_if_fail (wxtree_model->stamp == iter->stamp, 0); + return wxtree_model->internal->iter_n_children( iter ); } @@ -1100,11 +1105,10 @@ gtk_wx_cell_renderer_render (GtkCellRenderer *renderer, wxRect renderrect( rect.x, rect.y, rect.width, rect.height ); wxWindowDC* dc = (wxWindowDC*) cell->GetDC(); wxWindowDCImpl *impl = (wxWindowDCImpl *) dc->GetImpl(); - if (impl->m_gdkwindow == NULL) - { - impl->m_gdkwindow = window; - impl->SetUpDC(); - } + // Reinitilise GDK window everytime as drawing can also + // be done into DnD drop window. + impl->m_gdkwindow = window; + impl->SetUpDC(); int state = 0; if (flags & GTK_CELL_RENDERER_SELECTED) @@ -2829,7 +2833,7 @@ void wxGtkTreeModelNode::Resort() wxGtkTreeModelChildren temp; WX_APPEND_ARRAY( temp, m_children ); - g_internal = m_internal; + gs_internal = m_internal; m_children.Sort( &wxGtkTreeModelChildCmp ); gint *new_order = new gint[child_count]; @@ -2878,6 +2882,9 @@ wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl *owner, m_sort_column = -1; m_dataview_sort_column = NULL; + m_dragDataObject = NULL; + m_dropDataObject = NULL; + if (!m_wx_model->IsVirtualListModel()) InitTree(); } @@ -2885,6 +2892,9 @@ wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl *owner, wxDataViewCtrlInternal::~wxDataViewCtrlInternal() { g_object_unref( m_gtk_model ); + + delete m_dragDataObject; + delete m_dropDataObject; } void wxDataViewCtrlInternal::InitTree() @@ -2922,30 +2932,58 @@ bool wxDataViewCtrlInternal::EnableDragSource( const wxDataFormat &format ) { wxGtkString atom_str( gdk_atom_name( format ) ); m_dragSourceTargetEntryTarget = wxCharBuffer( atom_str ); - + m_dragSourceTargetEntry.target = m_dragSourceTargetEntryTarget.data(); m_dragSourceTargetEntry.flags = 0; m_dragSourceTargetEntry.info = static_cast(-1); - + gtk_tree_view_enable_model_drag_source( GTK_TREE_VIEW(m_owner->GtkGetTreeView() ), GDK_BUTTON1_MASK, &m_dragSourceTargetEntry, 1, (GdkDragAction) GDK_ACTION_COPY ); - + + return true; +} + +bool wxDataViewCtrlInternal::EnableDropTarget( const wxDataFormat &format ) +{ + wxGtkString atom_str( gdk_atom_name( format ) ); + m_dropTargetTargetEntryTarget = wxCharBuffer( atom_str ); + + m_dropTargetTargetEntry.target = m_dropTargetTargetEntryTarget.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 ) { + delete m_dragDataObject; + GtkTreeIter iter; if (!get_iter( &iter, path )) return FALSE; wxDataViewItem item( (void*) iter.user_data ); - wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_DRAGGABLE, m_owner->GetId() ); + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG, m_owner->GetId() ); + event.SetEventObject( m_owner ); event.SetItem( item ); event.SetModel( m_wx_model ); - m_owner->HandleWindowEvent( event ); - - return event.IsDraggable(); + if (!m_owner->HandleWindowEvent( event )) + return FALSE; + + if (!event.IsAllowed()) + return FALSE; + + wxDataObject *obj = event.GetDataObject(); + if (!obj) + return FALSE; + + m_dragDataObject = obj; + + return TRUE; } gboolean @@ -2962,45 +3000,75 @@ gboolean wxDataViewCtrlInternal::drag_data_get( GtkTreeDragSource *WXUNUSED(drag if (!get_iter( &iter, path )) return FALSE; wxDataViewItem item( (void*) iter.user_data ); - wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_GET_DRAG_DATA_SIZE, m_owner->GetId() ); - event.SetItem( item ); - event.SetModel( m_wx_model ); - event.SetDataFormat( selection_data->target ); - m_owner->HandleWindowEvent( event ); - if (event.GetDragDataSize() < 1) return FALSE; - size_t size = (size_t) event.GetDragDataSize(); + if (!m_dragDataObject->IsSupported( selection_data->target )) + return FALSE; + + size_t size = m_dragDataObject->GetDataSize( selection_data->target ); + if (size == 0) + return FALSE; - void *data = malloc( size ); + void *buf = malloc( size ); - event.SetEventType( wxEVT_COMMAND_DATAVIEW_ITEM_GET_DRAG_DATA ); - event.SetDragDataBuffer( data ); gboolean res = FALSE; - if (m_owner->HandleWindowEvent( event )) + if (m_dragDataObject->GetDataHere( selection_data->target, buf )) { - gtk_selection_data_set( selection_data, selection_data->target, - 8, (const guchar*) data, size ); res = TRUE; + + gtk_selection_data_set( selection_data, selection_data->target, + 8, (const guchar*) buf, size ); } - free( data ); + free( buf ); return res; } 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 @@ -3276,6 +3344,9 @@ gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter ) } else { + if (iter == NULL) + return m_root->GetChildCount(); + wxDataViewItem item( (void*) iter->user_data ); if (!m_wx_model->IsContainer( item )) @@ -3803,7 +3874,7 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, gtk_tree_view_set_rules_hint( GTK_TREE_VIEW(m_treeview), (style & wxDV_ROW_LINES) != 0 ); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget), - GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_show (m_treeview); m_parent->DoAddChild( this ); @@ -3892,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)) @@ -4050,7 +4126,7 @@ bool wxDataViewCtrl::IsExpanded( const wxDataViewItem & item ) const GtkTreePath *path = m_internal->get_path( &iter ); bool res = gtk_tree_view_row_expanded( GTK_TREE_VIEW(m_treeview), path ); gtk_tree_path_free( path ); - + return res; }