Patch from Bo to optimize FindNode() in internal tree structure
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@47693 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -42,6 +42,8 @@
|
|||||||
#include "wx/renderer.h"
|
#include "wx/renderer.h"
|
||||||
#include "wx/dcbuffer.h"
|
#include "wx/dcbuffer.h"
|
||||||
#include "wx/icon.h"
|
#include "wx/icon.h"
|
||||||
|
#include "wx/list.h"
|
||||||
|
#include "wx/listimpl.cpp"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// classes
|
// classes
|
||||||
@@ -279,7 +281,7 @@ public:
|
|||||||
void AppendChild( wxDataViewTreeNode * child ) { children.Add( child ); }
|
void AppendChild( wxDataViewTreeNode * child ) { children.Add( child ); }
|
||||||
|
|
||||||
wxDataViewItem & GetItem() { return item; }
|
wxDataViewItem & GetItem() { return item; }
|
||||||
void SetItem( wxDataViewItem & item ) { this->item = item; }
|
void SetItem( const wxDataViewItem & item ) { this->item = item; }
|
||||||
|
|
||||||
unsigned int GetChildrenNumber() { return children.GetCount(); }
|
unsigned int GetChildrenNumber() { return children.GetCount(); }
|
||||||
int GetIndentLevel()
|
int GetIndentLevel()
|
||||||
@@ -312,6 +314,8 @@ private:
|
|||||||
|
|
||||||
WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_SIZE_T(unsigned int, wxDataViewSelection,
|
WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_SIZE_T(unsigned int, wxDataViewSelection,
|
||||||
WXDLLIMPEXP_ADV);
|
WXDLLIMPEXP_ADV);
|
||||||
|
WX_DECLARE_LIST(wxDataViewItem, ItemList);
|
||||||
|
WX_DEFINE_LIST(ItemList);
|
||||||
|
|
||||||
class wxDataViewMainWindow: public wxWindow
|
class wxDataViewMainWindow: public wxWindow
|
||||||
{
|
{
|
||||||
@@ -401,6 +405,8 @@ private:
|
|||||||
void OnExpanding( unsigned int row );
|
void OnExpanding( unsigned int row );
|
||||||
void OnCollapsing( unsigned int row );
|
void OnCollapsing( unsigned int row );
|
||||||
|
|
||||||
|
wxDataViewTreeNode * FindNode( const wxDataViewItem & item );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxDataViewCtrl *m_owner;
|
wxDataViewCtrl *m_owner;
|
||||||
int m_lineHeight;
|
int m_lineHeight;
|
||||||
@@ -1770,8 +1776,17 @@ bool Walker( wxDataViewTreeNode * node, DoJob & func )
|
|||||||
|
|
||||||
bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxDataViewItem & item)
|
bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxDataViewItem & item)
|
||||||
{
|
{
|
||||||
ItemAddJob job( parent, item, &m_count);
|
wxDataViewTreeNode * node;
|
||||||
Walker( m_root , job);
|
node = FindNode(parent);
|
||||||
|
|
||||||
|
if( node == NULL )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
node->SetHasChildren( true );
|
||||||
|
wxDataViewTreeNode * newnode = new wxDataViewTreeNode( node );
|
||||||
|
newnode->SetItem(item);
|
||||||
|
node->AppendChild( newnode);
|
||||||
|
m_count = -1;
|
||||||
UpdateDisplay();
|
UpdateDisplay();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1800,8 +1815,20 @@ private:
|
|||||||
|
|
||||||
bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem & item)
|
bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem & item)
|
||||||
{
|
{
|
||||||
ItemDeleteJob job( item, &m_count);
|
wxDataViewTreeNode * node;
|
||||||
Walker( m_root, job);
|
node = FindNode(item);
|
||||||
|
|
||||||
|
if( node == NULL )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxDataViewTreeNode * parent = node->GetParent();
|
||||||
|
parent->GetChildren().Remove( node );
|
||||||
|
if( parent->GetChildrenNumber() == 0)
|
||||||
|
parent->SetHasChildren( false );
|
||||||
|
|
||||||
|
m_count = -1;
|
||||||
UpdateDisplay();
|
UpdateDisplay();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2474,7 +2501,13 @@ void wxDataViewMainWindow::OnExpanding( unsigned int row )
|
|||||||
if( node->GetChildrenNumber() == 0 )
|
if( node->GetChildrenNumber() == 0 )
|
||||||
BuildTreeHelper(GetOwner()->GetModel(), node->GetItem(), node);
|
BuildTreeHelper(GetOwner()->GetModel(), node->GetItem(), node);
|
||||||
m_count = -1;
|
m_count = -1;
|
||||||
Refresh();
|
UpdateDisplay();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SelectRow( row, false );
|
||||||
|
SelectRow( row + 1, true );
|
||||||
|
ChangeCurrentRow( row + 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2488,7 +2521,7 @@ void wxDataViewMainWindow::OnCollapsing(unsigned int row)
|
|||||||
{
|
{
|
||||||
node->ToggleOpen();
|
node->ToggleOpen();
|
||||||
m_count = -1;
|
m_count = -1;
|
||||||
Refresh();
|
UpdateDisplay();
|
||||||
//RefreshRows(row,GetLastVisibleRow());
|
//RefreshRows(row,GetLastVisibleRow());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2505,6 +2538,58 @@ void wxDataViewMainWindow::OnCollapsing(unsigned int row)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxDataViewTreeNode * wxDataViewMainWindow::FindNode( const wxDataViewItem & item )
|
||||||
|
{
|
||||||
|
wxDataViewModel * model = GetOwner()->GetModel();
|
||||||
|
if( model == NULL )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
//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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//Find the item along the parent-chain.
|
||||||
|
//This algorithm is designed to speed up the node-finding method
|
||||||
|
bool found = true;
|
||||||
|
wxDataViewTreeNode * node = m_root;
|
||||||
|
for( ItemList::Node * n = list.GetFirst(); n; n = n->GetNext() )
|
||||||
|
{
|
||||||
|
if( node->HasChildren() )
|
||||||
|
{
|
||||||
|
if( node->GetChildrenNumber() == 0 )
|
||||||
|
BuildTreeHelper(model, node->GetItem(), node);
|
||||||
|
|
||||||
|
int len = node->GetChildrenNumber();
|
||||||
|
wxDataViewTreeNodes nodes = node->GetChildren();
|
||||||
|
int j = 0;
|
||||||
|
for( ; j < len; j ++)
|
||||||
|
{
|
||||||
|
if( nodes[j]->GetItem() == *(n->GetData()))
|
||||||
|
{
|
||||||
|
node = nodes[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Whenever we can't find the node in any level, return NULL to indicate the item can't be found
|
||||||
|
if( j == len )
|
||||||
|
{
|
||||||
|
found = false;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
int wxDataViewMainWindow::RecalculateCount()
|
int wxDataViewMainWindow::RecalculateCount()
|
||||||
{
|
{
|
||||||
CountJob job;
|
CountJob job;
|
||||||
@@ -2546,7 +2631,7 @@ unsigned int wxDataViewMainWindow::GetRowByItem(const wxDataViewItem & item)
|
|||||||
|
|
||||||
void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, wxDataViewTreeNode * node)
|
void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, wxDataViewTreeNode * node)
|
||||||
{
|
{
|
||||||
if( !model->HasChildren( item ) )
|
if( !model->IsContainer( item ) )
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
wxDataViewItem i = model->GetFirstChild( item );
|
wxDataViewItem i = model->GetFirstChild( item );
|
||||||
@@ -2554,7 +2639,7 @@ void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, wxDataVie
|
|||||||
{
|
{
|
||||||
wxDataViewTreeNode * n = new wxDataViewTreeNode( node );
|
wxDataViewTreeNode * n = new wxDataViewTreeNode( node );
|
||||||
n->SetItem(i);
|
n->SetItem(i);
|
||||||
n->SetHasChildren( model->HasChildren( i )) ;
|
n->SetHasChildren( model->IsContainer( i )) ;
|
||||||
node->AppendChild(n);
|
node->AppendChild(n);
|
||||||
//BuildTreeHelper( model, i, n) ;
|
//BuildTreeHelper( model, i, n) ;
|
||||||
i = model->GetNextSibling( i );
|
i = model->GetNextSibling( i );
|
||||||
|
Reference in New Issue
Block a user