X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/482d06f8b5917f9ba0bf1b5623a70262220aed52..055400c94e55d93025f64bc79c613c444261406b:/src/generic/datavgen.cpp diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 254507c2e6..44638e2aef 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -46,6 +46,7 @@ #include "wx/listimpl.cpp" #include "wx/imaglist.h" #include "wx/headerctrl.h" +#include "wx/dnd.h" //----------------------------------------------------------------------------- // classes @@ -484,6 +485,15 @@ public: void Expand( unsigned int row ) { OnExpanding( row ); } void Collapse( unsigned int row ) { OnCollapsing( row ); } bool IsExpanded( unsigned int row ) const; + + bool EnableDragSource( const wxDataFormat &format ); + bool EnableDropTarget( const wxDataFormat &format ); + + wxDragResult OnDragOver( wxDataFormat format, wxCoord x, wxCoord y, wxDragResult def ); + bool OnDrop( wxDataFormat format, wxCoord x, wxCoord y ); + wxDragResult OnData( wxDataFormat format, wxCoord x, wxCoord y, wxDragResult def ); + void OnLeave(); + private: wxDataViewTreeNode * GetTreeNodeByRow( unsigned int row ) const; //We did not need this temporarily @@ -513,6 +523,12 @@ private: int m_dragCount; wxPoint m_dragStart; + + bool m_dragEnabled; + wxDataFormat m_dragFormat; + + bool m_dropEnabled; + wxDataFormat m_dropFormat; // for double click logic unsigned int m_lineLastClicked, @@ -1115,6 +1131,51 @@ wxDataViewIconTextRenderer::GetValueFromEditorCtrl(wxControl* WXUNUSED(editor), return false; } +//----------------------------------------------------------------------------- +// wxDataViewDropTarget +//----------------------------------------------------------------------------- + +class wxDataViewDropTarget: public wxDropTarget +{ +public: + wxDataViewDropTarget( wxDataObject *obj, wxDataViewMainWindow *win ) : + wxDropTarget( obj ) + { + m_win = win; + } + + virtual wxDragResult OnDragOver( wxCoord x, wxCoord y, wxDragResult def ) + { + wxDataFormat format = GetMatchingPair(); + if (format == wxDF_INVALID) + return wxDragNone; + return m_win->OnDragOver( format, x, y, def); + } + + virtual bool OnDrop( wxCoord x, wxCoord y ) + { + wxDataFormat format = GetMatchingPair(); + if (format == wxDF_INVALID) + return false; + return m_win->OnDrop( format, x, y ); + } + + virtual wxDragResult OnData( wxCoord x, wxCoord y, wxDragResult def ) + { + wxDataFormat format = GetMatchingPair(); + if (format == wxDF_INVALID) + return wxDragNone; + if (!GetData()) + return wxDragNone; + return m_win->OnData( format, x, y, def ); + } + + virtual void OnLeave() + { m_win->OnLeave(); } + + wxDataViewMainWindow *m_win; +}; + //----------------------------------------------------------------------------- // wxDataViewRenameTimer //----------------------------------------------------------------------------- @@ -1177,6 +1238,9 @@ wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl *parent, wxWindowID i m_lineBeforeLastClicked = (unsigned int) -1; m_lineSelectSingleOnUp = (unsigned int) -1; + m_dragEnabled = false; + m_dropEnabled = false; + m_hasFocus = false; SetBackgroundColour( *wxWHITE ); @@ -1203,6 +1267,117 @@ wxDataViewMainWindow::~wxDataViewMainWindow() delete m_renameTimer; } +bool wxDataViewMainWindow::EnableDragSource( const wxDataFormat &format ) +{ + m_dragFormat = format; + m_dragEnabled = format != wxDF_INVALID; + + return true; +} + +bool wxDataViewMainWindow::EnableDropTarget( const wxDataFormat &format ) +{ + m_dropFormat = format; + m_dropEnabled = format != wxDF_INVALID; + + if (m_dropEnabled) + SetDropTarget( new wxDataViewDropTarget( new wxCustomDataObject( format ), this ) ); + + return true; +} + +wxDragResult wxDataViewMainWindow::OnDragOver( wxDataFormat format, wxCoord x, wxCoord y, wxDragResult def ) +{ + int xx = x; + int yy = y; + m_owner->CalcUnscrolledPosition( xx, yy, &xx, &yy ); + unsigned int row = GetLineAt( yy ); + + if ((row >= GetRowCount()) || (yy > GetEndOfLastCol())) + return wxDragNone; + + wxDataViewItem item = GetItemByRow( row ); + + wxDataViewModel *model = GetOwner()->GetModel(); + + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE, m_owner->GetId() ); + event.SetEventObject( m_owner ); + event.SetItem( item ); + event.SetModel( model ); + event.SetDataFormat( format ); + if (!m_owner->HandleWindowEvent( event )) + return wxDragNone; + + if (!event.IsAllowed()) + return wxDragNone; + + return def; +} + +bool wxDataViewMainWindow::OnDrop( wxDataFormat format, wxCoord x, wxCoord y ) +{ + int xx = x; + int yy = y; + m_owner->CalcUnscrolledPosition( xx, yy, &xx, &yy ); + unsigned int row = GetLineAt( yy ); + + if ((row >= GetRowCount()) || (yy > GetEndOfLastCol())) + return false; + + wxDataViewItem item = GetItemByRow( row ); + + wxDataViewModel *model = GetOwner()->GetModel(); + + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE, m_owner->GetId() ); + event.SetEventObject( m_owner ); + event.SetItem( item ); + event.SetModel( model ); + event.SetDataFormat( format ); + if (!m_owner->HandleWindowEvent( event )) + return false; + + if (!event.IsAllowed()) + return false; + + return true; +} + +wxDragResult wxDataViewMainWindow::OnData( wxDataFormat format, wxCoord x, wxCoord y, wxDragResult def ) +{ + int xx = x; + int yy = y; + m_owner->CalcUnscrolledPosition( xx, yy, &xx, &yy ); + unsigned int row = GetLineAt( yy ); + + if ((row >= GetRowCount()) || (yy > GetEndOfLastCol())) + return wxDragNone; + + wxDataViewItem item = GetItemByRow( row ); + + wxDataViewModel *model = GetOwner()->GetModel(); + + wxCustomDataObject *obj = (wxCustomDataObject *) GetDropTarget()->GetDataObject(); + + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_DROP, m_owner->GetId() ); + event.SetEventObject( m_owner ); + event.SetItem( item ); + event.SetModel( model ); + event.SetDataFormat( format ); + event.SetDataSize( obj->GetSize() ); + event.SetDataBuffer( obj->GetData() ); + if (!m_owner->HandleWindowEvent( event )) + return wxDragNone; + + if (!event.IsAllowed()) + return wxDragNone; + + return def; +} + +void wxDataViewMainWindow::OnLeave() +{ +} + void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) { wxDataViewModel *model = GetOwner()->GetModel(); @@ -2423,7 +2598,10 @@ bool wxDataViewMainWindow::IsExpanded( unsigned int row ) const return false; if (!node->HasChildren()) + { + delete node; return false; + } return node->IsOpen(); } @@ -2516,6 +2694,9 @@ wxDataViewTreeNode * wxDataViewMainWindow::FindNode( const wxDataViewItem & item wxDataViewModel * model = GetOwner()->GetModel(); if( model == NULL ) return NULL; + + if (!item.IsOk()) + return m_root; //Compose the a parent-chain of the finding item ItemList list; @@ -2717,6 +2898,7 @@ static void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, wx wxDataViewItemArray children; unsigned int num = model->GetChildren( item, children); + unsigned int index = 0; while( index < num ) { @@ -2974,7 +3156,31 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) if (event.LeftIsDown()) { + m_owner->CalcUnscrolledPosition( m_dragStart.x, m_dragStart.y, &m_dragStart.x, &m_dragStart.y ); + unsigned int drag_item_row = GetLineAt( m_dragStart.y ); + wxDataViewItem item = GetItemByRow( drag_item_row ); + // Notify cell about drag + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_BEGIN_DRAG, m_owner->GetId() ); + event.SetEventObject( m_owner ); + event.SetItem( item ); + event.SetModel( model ); + if (!m_owner->HandleWindowEvent( event )) + return; + + if (!event.IsAllowed()) + return; + + wxDataObject *obj = event.GetDataObject(); + if (!obj) + return; + + wxDropSource drag( m_owner ); + drag.SetData( *obj ); + // wxImage image( 80, 20 ); + // wxBitmap bitmap( image ); + wxDragResult res = drag.DoDragDrop(); + delete obj; } return; } @@ -3038,6 +3244,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) // select single line SelectAllRows( false ); SelectRow( m_lineSelectSingleOnUp, true ); + SendSelectionChangedEvent( GetItemByRow(m_lineSelectSingleOnUp) ); } //Process the event of user clicking the expander @@ -3359,6 +3566,16 @@ bool wxDataViewCtrl::AssociateModel( wxDataViewModel *model ) return true; } +bool wxDataViewCtrl::EnableDragSource( const wxDataFormat &format ) +{ + return m_clientArea->EnableDragSource( format ); +} + +bool wxDataViewCtrl::EnableDropTarget( const wxDataFormat &format ) +{ + return m_clientArea->EnableDropTarget( format ); +} + bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col ) { if (!wxDataViewCtrlBase::AppendColumn(col)) @@ -3523,18 +3740,33 @@ int wxDataViewCtrl::GetSelections( wxDataViewItemArray & sel ) const void wxDataViewCtrl::SetSelections( const wxDataViewItemArray & sel ) { wxDataViewSelection selection(wxDataViewSelectionCmp); + + wxDataViewItem last_parent; + int len = sel.GetCount(); for( int i = 0; i < len; i ++ ) { - int row = m_clientArea->GetRowByItem( sel[i] ); + wxDataViewItem item = sel[i]; + wxDataViewItem parent = GetModel()->GetParent( item ); + if (parent) + { + if (parent != last_parent) + ExpandAncestors(item); + } + + last_parent = parent; + int row = m_clientArea->GetRowByItem( item ); if( row >= 0 ) selection.Add( static_cast(row) ); } + m_clientArea->SetSelections( selection ); } void wxDataViewCtrl::Select( const wxDataViewItem & item ) { + ExpandAncestors( item ); + int row = m_clientArea->GetRowByItem( item ); if( row >= 0 ) { @@ -3658,6 +3890,10 @@ void wxDataViewCtrl::EnsureVisible( int row, int column ) void wxDataViewCtrl::EnsureVisible( const wxDataViewItem & item, const wxDataViewColumn * column ) { + ExpandAncestors( item ); + + m_clientArea->RecalculateDisplay(); + int row = m_clientArea->GetRowByItem(item); if( row >= 0 ) {