Patch from Bo, implement sorting in wxDVC

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@47718 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2007-07-25 18:09:47 +00:00
parent cf4a8b2698
commit d47db7e06a

View File

@@ -254,36 +254,49 @@ public:
// wxDataViewTreeNode // wxDataViewTreeNode
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class wxDataViewTreeNode; class wxDataViewTreeNode;
WX_DEFINE_ARRAY_PTR( wxDataViewTreeNode *, wxDataViewTreeNodes ); WX_DEFINE_SORTED_ARRAY( wxDataViewTreeNode *, wxDataViewTreeNodes );
WX_DEFINE_SORTED_ARRAY( void* , wxDataViewTreeLeaves);
int LINKAGEMODE wxGenericTreeModelNodeCmp( wxDataViewTreeNode * node1, wxDataViewTreeNode * node2);
int LINKAGEMODE wxGenericTreeModelItemCmp( void * id1, void * id2);
class wxDataViewTreeNode class wxDataViewTreeNode
{ {
public: public:
wxDataViewTreeNode( wxDataViewTreeNode * parent ) wxDataViewTreeNode( wxDataViewTreeNode * parent )
:leaves( wxGenericTreeModelItemCmp ),
nodes(wxGenericTreeModelNodeCmp)
{ this->parent = parent; { this->parent = parent;
if( parent == NULL ) if( parent == NULL )
open = true; open = true;
else else
open = false; open = false;
hasChildren = false; hasChildren = false;
subTreeCount = 0;
} }
//I don't know what I need to do in the destructure //I don't know what I need to do in the destructure
~wxDataViewTreeNode() ~wxDataViewTreeNode()
{ } {
}
wxDataViewTreeNode * GetParent() { return parent; } wxDataViewTreeNode * GetParent() { return parent; }
void SetParent( wxDataViewTreeNode * parent ) { this->parent = parent; } void SetParent( wxDataViewTreeNode * parent ) { this->parent = parent; }
wxDataViewTreeNodes & GetChildren() { return children; } wxDataViewTreeNodes & GetNodes() { return nodes; }
void SetChildren( wxDataViewTreeNodes children ) { this->children = children; } wxDataViewTreeLeaves & GetChildren() { return leaves; }
wxDataViewTreeNode * GetChild( unsigned int n ) { return children.Item( n ); } void AddNode( wxDataViewTreeNode * node )
void InsertChild( wxDataViewTreeNode * child, unsigned int n) { children.Insert( child, n); } {
void AppendChild( wxDataViewTreeNode * child ) { children.Add( child ); } nodes.Add( node );
leaves.Add( node->GetItem().GetID() );
}
void AddLeaf( void * leaf ) { leaves.Add( leaf ); }
wxDataViewItem & GetItem() { return item; } wxDataViewItem & GetItem() { return item; }
void SetItem( const wxDataViewItem & item ) { this->item = item; } void SetItem( const wxDataViewItem & item ) { this->item = item; }
unsigned int GetChildrenNumber() { return children.GetCount(); } unsigned int GetChildrenNumber() { return leaves.GetCount(); }
unsigned int GetNodeNumber() { return nodes.GetCount(); }
int GetIndentLevel() int GetIndentLevel()
{ {
int ret = 0 ; int ret = 0 ;
@@ -296,18 +309,70 @@ public:
return ret; return ret;
} }
bool IsOpen() { return open; } bool IsOpen()
void ToggleOpen(){ open = !open; } {
return open ;
}
void ToggleOpen()
{
int len = nodes.GetCount();
int sum = 0;
for ( int i = 0 ;i < len ; i ++)
sum += nodes[i]->GetSubTreeCount();
sum += leaves.GetCount();
if( open )
{
ChangeSubTreeCount(-sum);
open = !open;
}
else
{
open = !open;
ChangeSubTreeCount(sum);
}
}
bool HasChildren() { return hasChildren; } bool HasChildren() { return hasChildren; }
void SetHasChildren( bool has ){ hasChildren = has; } void SetHasChildren( bool has ){ hasChildren = has; }
void SetSubTreeCount( int num ) { subTreeCount = num; }
int GetSubTreeCount() { return subTreeCount; }
void ChangeSubTreeCount( int num )
{
if( !open )
return ;
subTreeCount += num;
if( parent )
parent->ChangeSubTreeCount(num);
}
private: private:
wxDataViewTreeNode * parent; wxDataViewTreeNode * parent;
wxDataViewTreeNodes children; wxDataViewTreeNodes nodes;
wxDataViewTreeLeaves leaves;
wxDataViewItem item; wxDataViewItem item;
bool open; bool open;
bool hasChildren; bool hasChildren;
int subTreeCount;
}; };
//Below is the compare stuff
//For the generic implements, both the leaf nodes and the nodes are sorted for fast search when needed
static wxDataViewModel * g_model;
int LINKAGEMODE wxGenericTreeModelNodeCmp( wxDataViewTreeNode * node1, wxDataViewTreeNode * node2)
{
return g_model->Compare( node1->GetItem(), node2->GetItem() );
}
int LINKAGEMODE wxGenericTreeModelItemCmp( void * id1, void * id2)
{
return g_model->Compare( id1, id2 );
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// wxDataViewMainWindow // wxDataViewMainWindow
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -1718,8 +1783,10 @@ public:
// 2: Job not done, continue // 2: Job not done, continue
enum { OK = 0 , IGR = 1, CONT = 2 }; enum { OK = 0 , IGR = 1, CONT = 2 };
virtual int operator() ( wxDataViewTreeNode * node ) = 0 ; virtual int operator() ( wxDataViewTreeNode * node ) = 0 ;
virtual int operator() ( void * n ) = 0;
}; };
#if 0
class ItemAddJob: public DoJob class ItemAddJob: public DoJob
{ {
public: public:
@@ -1745,37 +1812,61 @@ private:
int * m_count; int * m_count;
wxDataViewItem parent, item; wxDataViewItem parent, item;
}; };
#endif
bool Walker( wxDataViewTreeNode * node, DoJob & func ) bool Walker( wxDataViewTreeNode * node, DoJob & func )
{ {
if( node==NULL || !node->HasChildren()) if( node==NULL || !node->HasChildren())
return false; return false;
wxDataViewTreeNodes nodes = node->GetChildren(); wxDataViewTreeNodes nodes = node->GetNodes();
int len = node->GetChildrenNumber(); wxDataViewTreeLeaves leaves = node->GetChildren();
int i = 0 ;
int len_nodes = nodes.GetCount();
int len = leaves.GetCount();
int i = 0, nodes_i = 0;
for( ; i < len ; i ++ ) for( ; i < len ; i ++ )
{ {
wxDataViewTreeNode * n = nodes[i]; void * n = leaves[i];
switch( func( n ) ) if( nodes_i < len_nodes && n == nodes[nodes_i]->GetItem().GetID() )
{ {
case DoJob::OK : wxDataViewTreeNode * nd = nodes[nodes_i];
return true ; nodes_i++;
case DoJob::IGR:
continue; switch( func( nd ) )
case DoJob::CONT: {
default: case DoJob::OK :
; return true ;
} case DoJob::IGR:
continue;
case DoJob::CONT:
default:
;
}
if( Walker( n , func ) ) if( Walker( nd , func ) )
return true; return true;
}
else
switch( func( n ) )
{
case DoJob::OK :
return true ;
case DoJob::IGR:
continue;
case DoJob::CONT:
default:
;
}
} }
return false; return false;
} }
bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxDataViewItem & item) bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxDataViewItem & item)
{ {
g_model = GetOwner()->GetModel();
wxDataViewTreeNode * node; wxDataViewTreeNode * node;
node = FindNode(parent); node = FindNode(parent);
@@ -1783,14 +1874,24 @@ bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxData
return false; return false;
node->SetHasChildren( true ); node->SetHasChildren( true );
wxDataViewTreeNode * newnode = new wxDataViewTreeNode( node );
newnode->SetItem(item); if( g_model->IsContainer( item ) )
node->AppendChild( newnode); {
wxDataViewTreeNode * newnode = new wxDataViewTreeNode( node );
newnode->SetItem(item);
node->AddNode( newnode);
}
else
node->AddLeaf( item.GetID() );
node->ChangeSubTreeCount(1);
m_count = -1; m_count = -1;
UpdateDisplay(); UpdateDisplay();
return true; return true;
} }
#if 0
class ItemDeleteJob: public DoJob class ItemDeleteJob: public DoJob
{ {
public: public:
@@ -1812,29 +1913,61 @@ private:
int * m_count; int * m_count;
wxDataViewItem m_item; wxDataViewItem m_item;
}; };
#endif
void DestroyTreeHelper( wxDataViewTreeNode * node);
bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem & item) bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem & item)
{ {
wxDataViewTreeNode * node; g_model = GetOwner()->GetModel();
node = FindNode(item);
if( node == NULL ) wxDataViewTreeNode * node;
wxDataViewItem parent_item = g_model->GetParent( item );
node = FindNode(parent_item);
if( node == NULL || node->GetChildren().Index( item.GetID() ) == wxNOT_FOUND )
{ {
return false; return false;
} }
wxDataViewTreeNode * parent = node->GetParent(); int sub = -1;
parent->GetChildren().Remove( node ); node->GetChildren().Remove( item.GetID() );
if( parent->GetChildrenNumber() == 0) if( GetOwner()->GetModel()->IsContainer( item ) )
parent->SetHasChildren( false ); {
wxDataViewTreeNode * n ;
wxDataViewTreeNodes nodes = node->GetNodes();
int len = nodes.GetCount();
for( int i = 0 ; i < len; i ++)
{
if( nodes[i]->GetItem() == item )
{
n = nodes[i];
break;
}
}
node->GetNodes().Remove( n );
sub -= n->GetSubTreeCount();
DestroyTreeHelper(n);
}
if( node->GetChildrenNumber() == 0)
node->SetHasChildren( false );
//Make the row number invalid and get a new valid one when user call GetRowCount
m_count = -1;
node->ChangeSubTreeCount(sub);
//Change the current row to the last row if the current exceed the max row number
if( m_currentRow > GetRowCount() )
m_currentRow = m_count - 1;
m_count = -1;
UpdateDisplay(); UpdateDisplay();
return true; return true;
} }
bool wxDataViewMainWindow::ItemChanged(const wxDataViewItem & item) bool wxDataViewMainWindow::ItemChanged(const wxDataViewItem & item)
{ {
g_model = GetOwner()->GetModel();
unsigned int row = GetRowByItem(item); unsigned int row = GetRowByItem(item);
RefreshRow( row ); RefreshRow( row );
return true; return true;
@@ -1851,6 +1984,8 @@ bool wxDataViewMainWindow::ValueChanged( const wxDataViewItem & item, unsigned i
return true; return true;
*/ */
g_model = GetOwner()->GetModel();
unsigned int row = GetRowByItem(item); unsigned int row = GetRowByItem(item);
RefreshRow( row ); RefreshRow( row );
return true; return true;
@@ -1858,6 +1993,8 @@ bool wxDataViewMainWindow::ValueChanged( const wxDataViewItem & item, unsigned i
bool wxDataViewMainWindow::Cleared() bool wxDataViewMainWindow::Cleared()
{ {
g_model = GetOwner()->GetModel();
DestroyTree(); DestroyTree();
UpdateDisplay(); UpdateDisplay();
return true; return true;
@@ -2036,7 +2173,9 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
wxVariant value; wxVariant value;
wxDataViewTreeNode * node = GetTreeNodeByRow(item); wxDataViewTreeNode * node = GetTreeNodeByRow(item);
if( node == NULL ) if( node == NULL )
{
continue; continue;
}
wxDataViewItem dataitem = node->GetItem(); wxDataViewItem dataitem = node->GetItem();
model->GetValue( value, dataitem, col->GetModelColumn()); model->GetValue( value, dataitem, col->GetModelColumn());
@@ -2045,8 +2184,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
// update the y offset // update the y offset
cell_rect.y = item * m_lineHeight; cell_rect.y = item * m_lineHeight;
//Draw the expander here. Please notice that I use const number for all pixel data. When the final API are determined //Draw the expander here.
//I will change this to the data member of the class wxDataViewCtrl
int indent = node->GetIndentLevel(); int indent = node->GetIndentLevel();
if( col->GetModelColumn() == GetOwner()->GetExpanderColumn() ) if( col->GetModelColumn() == GetOwner()->GetExpanderColumn() )
{ {
@@ -2071,7 +2209,9 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
} }
else else
{ {
// I am wandering whether we should draw dot lines between tree nodes // I am wandering whether we should draw dot lines between tree nodes
delete node;
//Yes, if the node does not have any child, it must be a leaf which mean that it is a temporarily created by GetTreeNodeByRow
} }
//force the expander column to left-center align //force the expander column to left-center align
@@ -2403,19 +2543,33 @@ public:
virtual ~RowToItemJob(){}; virtual ~RowToItemJob(){};
virtual int operator() ( wxDataViewTreeNode * node ) virtual int operator() ( wxDataViewTreeNode * node )
{ {
if( current == static_cast<int>(row)) current ++;
{ if( current == static_cast<int>(row))
ret = node->GetItem() ; {
return DoJob::OK; ret = node->GetItem() ;
} return DoJob::OK;
current ++; }
if ( node->IsOpen())
return DoJob::CONT;
else
return DoJob::IGR;
}
if( node->GetSubTreeCount() + current < static_cast<int>(row) )
{
current += node->GetSubTreeCount();
return DoJob::IGR;
}
else
return DoJob::CONT;
}
virtual int operator() ( void * n )
{
current ++;
if( current == static_cast<int>(row))
{
ret = wxDataViewItem( n ) ;
return DoJob::OK;
}
return DoJob::CONT;
}
wxDataViewItem GetResult(){ return ret; } wxDataViewItem GetResult(){ return ret; }
private: private:
unsigned int row; unsigned int row;
@@ -2425,7 +2579,7 @@ private:
wxDataViewItem wxDataViewMainWindow::GetItemByRow(unsigned int row) wxDataViewItem wxDataViewMainWindow::GetItemByRow(unsigned int row)
{ {
RowToItemJob job( row, 0 ); RowToItemJob job( row, -1 );
Walker( m_root , job ); Walker( m_root , job );
return job.GetResult(); return job.GetResult();
} }
@@ -2433,38 +2587,67 @@ wxDataViewItem wxDataViewMainWindow::GetItemByRow(unsigned int row)
class RowToTreeNodeJob: public DoJob class RowToTreeNodeJob: public DoJob
{ {
public: public:
RowToTreeNodeJob( unsigned int row , int current ) { this->row = row; this->current = current ; ret = NULL ; } RowToTreeNodeJob( unsigned int row , int current, wxDataViewTreeNode * node )
{
this->row = row;
this->current = current ;
ret = NULL ;
parent = node;
}
virtual ~RowToTreeNodeJob(){}; virtual ~RowToTreeNodeJob(){};
virtual int operator() ( wxDataViewTreeNode * node ) virtual int operator() ( wxDataViewTreeNode * node )
{ {
current ++;
if( current == static_cast<int>(row)) if( current == static_cast<int>(row))
{ {
ret = node ; ret = node ;
return DoJob::OK; return DoJob::OK;
} }
current ++;
if ( node->IsOpen()) if( node->GetSubTreeCount() + current < static_cast<int>(row) )
return DoJob::CONT; {
current += node->GetSubTreeCount();
return DoJob::IGR;
}
else else
return DoJob::IGR; {
parent = node;
return DoJob::CONT;
}
} }
virtual int operator() ( void * n )
{
current ++;
if( current == static_cast<int>(row))
{
ret = new wxDataViewTreeNode( parent ) ;
ret->SetItem( wxDataViewItem( n ));
ret->SetHasChildren(false);
return DoJob::OK;
}
return DoJob::CONT;
}
wxDataViewTreeNode * GetResult(){ return ret; } wxDataViewTreeNode * GetResult(){ return ret; }
private: private:
unsigned int row; unsigned int row;
int current ; int current ;
wxDataViewTreeNode * ret; wxDataViewTreeNode * ret;
wxDataViewTreeNode * parent ;
}; };
wxDataViewTreeNode * wxDataViewMainWindow::GetTreeNodeByRow(unsigned int row) wxDataViewTreeNode * wxDataViewMainWindow::GetTreeNodeByRow(unsigned int row)
{ {
RowToTreeNodeJob job( row , 0 ); RowToTreeNodeJob job( row , -1, m_root );
Walker( m_root , job ); Walker( m_root , job );
return job.GetResult(); return job.GetResult();
} }
#if 0
class CountJob : public DoJob class CountJob : public DoJob
{ {
public: public:
@@ -2487,6 +2670,7 @@ public:
private: private:
unsigned int count; unsigned int count;
}; };
#endif
void wxDataViewMainWindow::OnExpanding( unsigned int row ) void wxDataViewMainWindow::OnExpanding( unsigned int row )
{ {
@@ -2509,6 +2693,8 @@ void wxDataViewMainWindow::OnExpanding( unsigned int row )
SelectRow( row + 1, true ); SelectRow( row + 1, true );
ChangeCurrentRow( row + 1 ); ChangeCurrentRow( row + 1 );
} }
else
delete node;
} }
} }
@@ -2517,6 +2703,8 @@ void wxDataViewMainWindow::OnCollapsing(unsigned int row)
wxDataViewTreeNode * node = GetTreeNodeByRow(row); wxDataViewTreeNode * node = GetTreeNodeByRow(row);
if( node != NULL ) if( node != NULL )
{ {
wxDataViewTreeNode * nd = node;
if( node->HasChildren() && node->IsOpen() ) if( node->HasChildren() && node->IsOpen() )
{ {
node->ToggleOpen(); node->ToggleOpen();
@@ -2535,6 +2723,8 @@ void wxDataViewMainWindow::OnCollapsing(unsigned int row)
ChangeCurrentRow( parent ); ChangeCurrentRow( parent );
} }
} }
if( !nd->HasChildren())
delete nd;
} }
} }
@@ -2566,8 +2756,8 @@ wxDataViewTreeNode * wxDataViewMainWindow::FindNode( const wxDataViewItem & item
if( node->GetChildrenNumber() == 0 ) if( node->GetChildrenNumber() == 0 )
BuildTreeHelper(model, node->GetItem(), node); BuildTreeHelper(model, node->GetItem(), node);
int len = node->GetChildrenNumber(); int len = node->GetNodeNumber();
wxDataViewTreeNodes nodes = node->GetChildren(); wxDataViewTreeNodes nodes = node->GetNodes();
int j = 0; int j = 0;
for( ; j < len; j ++) for( ; j < len; j ++)
{ {
@@ -2592,39 +2782,71 @@ wxDataViewTreeNode * wxDataViewMainWindow::FindNode( const wxDataViewItem & item
int wxDataViewMainWindow::RecalculateCount() int wxDataViewMainWindow::RecalculateCount()
{ {
CountJob job; return m_root->GetSubTreeCount();
Walker( m_root, job );
return job.GetResult();
} }
class ItemToRowJob : public DoJob class ItemToRowJob : public DoJob
{ {
public: public:
ItemToRowJob(const wxDataViewItem & item){ this->item = item ; ret = 0 ; } ItemToRowJob(const wxDataViewItem & item, ItemList::Node * node )
{ this->item = item ; ret = 0 ; nd = node ; }
virtual ~ItemToRowJob(){}; virtual ~ItemToRowJob(){};
virtual int operator() ( wxDataViewTreeNode * node) virtual int operator() ( wxDataViewTreeNode * node)
{ {
ret ++; ret ++;
if( node->GetItem() == item ) if( node->GetItem() == item )
{
return DoJob::OK; return DoJob::OK;
}
if( node->IsOpen()) if( nd && node->GetItem() == *(nd->GetData()))
{
nd = nd->GetNext();
return DoJob::CONT; return DoJob::CONT;
}
else else
{
ret += node->GetSubTreeCount();
return DoJob::IGR; return DoJob::IGR;
}
} }
virtual int operator() ( void * n )
{
ret ++;
if( n == item.GetID() )
return DoJob::OK;
return DoJob::CONT;
}
//the row number is begin from zero //the row number is begin from zero
int GetResult(){ return ret -1 ; } int GetResult(){ return ret -1 ; }
private: private:
ItemList::Node * nd;
wxDataViewItem item; wxDataViewItem item;
int ret; int ret;
}; };
unsigned int wxDataViewMainWindow::GetRowByItem(const wxDataViewItem & item) unsigned int wxDataViewMainWindow::GetRowByItem(const wxDataViewItem & item)
{ {
ItemToRowJob job( item ); wxDataViewModel * model = GetOwner()->GetModel();
if( model == NULL )
return 0;
//Compose the a parent-chain of the finding item
ItemList list;
list.DeleteContents( true );
wxDataViewItem it( item );
while( it.IsOk() )
{
wxDataViewItem * pItem = new wxDataViewItem( it );
list.Insert( pItem );
it = model->GetParent( it );
}
ItemToRowJob job( item, list.GetFirst() );
Walker(m_root , job ); Walker(m_root , job );
return job.GetResult(); return job.GetResult();
} }
@@ -2635,32 +2857,46 @@ void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, wxDataVie
return ; return ;
wxDataViewItem i = model->GetFirstChild( item ); wxDataViewItem i = model->GetFirstChild( item );
int num = 0;
while( i.IsOk() ) while( i.IsOk() )
{ {
wxDataViewTreeNode * n = new wxDataViewTreeNode( node ); num ++;
n->SetItem(i); if( model->IsContainer( i ) )
n->SetHasChildren( model->IsContainer( i )) ; {
node->AppendChild(n); wxDataViewTreeNode * n = new wxDataViewTreeNode( node );
//BuildTreeHelper( model, i, n) ; n->SetItem(i);
n->SetHasChildren( true ) ;
node->AddNode( n );
}
else
{
node->AddLeaf( i.GetID() );
}
i = model->GetNextSibling( i ); i = model->GetNextSibling( i );
} }
node->SetSubTreeCount( num );
wxDataViewTreeNode * n = node->GetParent();
if( n != NULL)
n->ChangeSubTreeCount(num);
} }
void wxDataViewMainWindow::BuildTree(wxDataViewModel * model) void wxDataViewMainWindow::BuildTree(wxDataViewModel * model)
{ {
//First we define a invalid item to fetch the top-level elements //First we define a invalid item to fetch the top-level elements
wxDataViewItem item; wxDataViewItem item;
g_model = GetOwner()->GetModel();
BuildTreeHelper( model, item, m_root); BuildTreeHelper( model, item, m_root);
m_count = -1 ; m_count = -1 ;
} }
void DestroyTreeHelper( wxDataViewTreeNode * node ) void DestroyTreeHelper( wxDataViewTreeNode * node )
{ {
if( node->HasChildren() ) if( node->GetNodeNumber() != 0 )
{ {
int len = node->GetChildrenNumber(); int len = node->GetNodeNumber();
int i = 0 ; int i = 0 ;
wxDataViewTreeNodes nodes = node->GetChildren(); wxDataViewTreeNodes nodes = node->GetNodes();
for( ; i < len; i ++ ) for( ; i < len; i ++ )
{ {
DestroyTreeHelper(nodes[i]); DestroyTreeHelper(nodes[i]);
@@ -2672,6 +2908,7 @@ void DestroyTreeHelper( wxDataViewTreeNode * node )
void wxDataViewMainWindow::DestroyTree() void wxDataViewMainWindow::DestroyTree()
{ {
DestroyTreeHelper(m_root); DestroyTreeHelper(m_root);
m_root->SetSubTreeCount(0);
m_count = 0 ; m_count = 0 ;
} }
@@ -3028,7 +3265,8 @@ wxDataViewItem wxDataViewMainWindow::GetSelection()
{ {
if( m_selection.GetCount() != 1 ) if( m_selection.GetCount() != 1 )
return wxDataViewItem(); return wxDataViewItem();
return GetItemByRow( m_selection.Item( 0 ) );
return GetItemByRow( m_selection.Item(0));
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------