~wxDataViewTreeNode()
{
- delete m_branchData;
+ if ( m_branchData )
+ {
+ wxDataViewTreeNodes& nodes = m_branchData->children;
+ for ( wxDataViewTreeNodes::iterator i = nodes.begin();
+ i != nodes.end();
+ ++i )
+ {
+ delete *i;
+ }
+
+ delete m_branchData;
+ }
}
static wxDataViewTreeNode* CreateRootNode()
wxDataViewTreeNode * GetParent() const { return m_parent; }
- wxDataViewTreeNodes& GetNodes()
+ const wxDataViewTreeNodes& GetChildNodes() const
{
wxASSERT( m_branchData != NULL );
- return m_branchData->nodes;
+ return m_branchData->children;
}
- void AddNode( wxDataViewTreeNode * node )
+ void AddChild( wxDataViewTreeNode * node )
{
if ( !m_branchData )
m_branchData = new BranchNodeData;
- m_branchData->nodes.Add( node );
+ m_branchData->children.Add( node );
// TODO: insert into sorted array directly in O(log n) instead of resorting in O(n log n)
if (g_column >= -1)
- m_branchData->nodes.Sort( &wxGenericTreeModelNodeCmp );
+ m_branchData->children.Sort( &wxGenericTreeModelNodeCmp );
+ }
+
+ void RemoveChild(wxDataViewTreeNode *node)
+ {
+ wxCHECK_RET( m_branchData != NULL, "leaf node doesn't have children" );
+ m_branchData->children.Remove(node);
}
const wxDataViewItem & GetItem() const { return m_item; }
int sum = 0;
- const wxDataViewTreeNodes& nodes = m_branchData->nodes;
+ const wxDataViewTreeNodes& nodes = m_branchData->children;
const int len = nodes.GetCount();
for ( int i = 0;i < len; i ++)
sum += 1 + nodes[i]->GetSubTreeCount();
}
// "HasChildren" property corresponds to model's IsContainer(). Note that it may be true
- // even if GetNodes() is empty; see below.
+ // even if GetChildNodes() is empty; see below.
bool HasChildren() const
{
return m_branchData != NULL;
if (g_column >= -1)
{
- wxDataViewTreeNodes& nodes = m_branchData->nodes;
+ wxDataViewTreeNodes& nodes = m_branchData->children;
nodes.Sort( &wxGenericTreeModelNodeCmp );
int len = nodes.GetCount();
// Child nodes. Note that this may be empty even if m_hasChildren in
// case this branch of the tree wasn't expanded and realized yet.
- wxDataViewTreeNodes nodes;
+ wxDataViewTreeNodes children;
// Is the branch node currently open (expanded)?
bool open;
const wxString &name = wxT("wxdataviewctrlmainwindow") );
virtual ~wxDataViewMainWindow();
- bool IsList() const { return GetOwner()->GetModel()->IsListModel(); }
+ bool IsList() const { return GetModel()->IsListModel(); }
bool IsVirtualList() const { return m_root == NULL; }
// notifications from wxDataViewModel
void SortPrepare()
{
- g_model = GetOwner()->GetModel();
+ g_model = GetModel();
wxDataViewColumn* col = GetOwner()->GetSortingColumn();
if( !col )
{
wxDataViewCtrl *GetOwner() { return m_owner; }
const wxDataViewCtrl *GetOwner() const { return m_owner; }
+ wxDataViewModel* GetModel() { return GetOwner()->GetModel(); }
+ const wxDataViewModel* GetModel() const { return GetOwner()->GetModel(); }
+
#if wxUSE_DRAG_AND_DROP
wxBitmap CreateItemBitmap( unsigned int row, int &indent );
#endif // wxUSE_DRAG_AND_DROP
wxDataViewItem item = GetItemByRow( row );
- wxDataViewModel *model = GetOwner()->GetModel();
+ wxDataViewModel *model = GetModel();
wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE, m_owner->GetId() );
event.SetEventObject( m_owner );
wxDataViewItem item = GetItemByRow( row );
- wxDataViewModel *model = GetOwner()->GetModel();
+ wxDataViewModel *model = GetModel();
wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_DROP_POSSIBLE, m_owner->GetId() );
event.SetEventObject( m_owner );
wxDataViewItem item = GetItemByRow( row );
- wxDataViewModel *model = GetOwner()->GetModel();
+ wxDataViewModel *model = GetModel();
wxCustomDataObject *obj = (wxCustomDataObject *) GetDropTarget()->GetDataObject();
void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
{
- wxDataViewModel *model = GetOwner()->GetModel();
+ wxDataViewModel *model = GetModel();
wxAutoBufferedPaintDC dc( this );
#ifdef __WXMSW__
virtual ~DoJob() { }
// The return value control how the tree-walker tranverse the tree
- // 0: Job done, stop tranverse and return
- // 1: Ignore the current node's subtree and continue
- // 2: Job not done, continue
- enum { OK = 0 , IGR = 1, CONT = 2 };
+ enum
+ {
+ DONE, // Job done, stop traversing and return
+ SKIP_SUBTREE, // Ignore the current node's subtree and continue
+ CONTINUE // Job not done, continue
+ };
+
virtual int operator() ( wxDataViewTreeNode * node ) = 0;
};
switch( func( node ) )
{
- case DoJob::OK:
+ case DoJob::DONE:
return true;
- case DoJob::IGR:
+ case DoJob::SKIP_SUBTREE:
return false;
- case DoJob::CONT:
+ case DoJob::CONTINUE:
break;
}
if ( node->HasChildren() )
{
- const wxDataViewTreeNodes& nodes = node->GetNodes();
+ const wxDataViewTreeNodes& nodes = node->GetChildNodes();
for ( wxDataViewTreeNodes::const_iterator i = nodes.begin();
i != nodes.end();
if (IsVirtualList())
{
wxDataViewVirtualListModel *list_model =
- (wxDataViewVirtualListModel*) GetOwner()->GetModel();
+ (wxDataViewVirtualListModel*) GetModel();
m_count = list_model->GetCount();
}
else
return false;
wxDataViewTreeNode *itemNode = new wxDataViewTreeNode(parentNode, item);
- itemNode->SetHasChildren(GetOwner()->GetModel()->IsContainer(item));
+ itemNode->SetHasChildren(GetModel()->IsContainer(item));
parentNode->SetHasChildren(true);
- parentNode->AddNode(itemNode);
+ parentNode->AddChild(itemNode);
parentNode->ChangeSubTreeCount(+1);
m_count = -1;
return true;
}
-static void DestroyTreeHelper( wxDataViewTreeNode * node);
-
bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent,
const wxDataViewItem& item)
{
if (IsVirtualList())
{
wxDataViewVirtualListModel *list_model =
- (wxDataViewVirtualListModel*) GetOwner()->GetModel();
+ (wxDataViewVirtualListModel*) GetModel();
m_count = list_model->GetCount();
if ( !m_selection.empty() )
return false;
wxCHECK_MSG( parentNode->HasChildren(), false, "parent node doesn't have children?" );
- const wxDataViewTreeNodes& parentsChildren = parentNode->GetNodes();
+ const wxDataViewTreeNodes& parentsChildren = parentNode->GetChildNodes();
// We can't use FindNode() to find 'item', because it was already
// removed from the model by the time ItemDeleted() is called, so we
{
// If this was the last child to be removed, it's possible the parent
// node became a leaf. Let's ask the model about it.
- if ( parentNode->GetNodes().empty() )
- parentNode->SetHasChildren(GetOwner()->GetModel()->IsContainer(parent));
+ if ( parentNode->GetChildNodes().empty() )
+ parentNode->SetHasChildren(GetModel()->IsContainer(parent));
return false;
}
// Delete the item from wxDataViewTreeNode representation:
const int itemsDeleted = 1 + itemNode->GetSubTreeCount();
- parentNode->GetNodes().Remove(itemNode);
- ::DestroyTreeHelper(itemNode);
+ parentNode->RemoveChild(itemNode);
+ delete itemNode;
parentNode->ChangeSubTreeCount(-itemsDeleted);
// Make the row number invalid and get a new valid one when user call GetRowCount
// If this was the last child to be removed, it's possible the parent
// node became a leaf. Let's ask the model about it.
- if ( parentNode->GetNodes().empty() )
- parentNode->SetHasChildren(GetOwner()->GetModel()->IsContainer(parent));
+ if ( parentNode->GetChildNodes().empty() )
+ parentNode->SetHasChildren(GetModel()->IsContainer(parent));
// Update selection by removing 'item' and its entire children tree from the selection.
if ( !m_selection.empty() )
else
{
// row number is that of the sibling above 'item' + its subtree if any + 1
- const wxDataViewTreeNode *siblingNode = parentNode->GetNodes()[itemPosInNode - 1];
+ const wxDataViewTreeNode *siblingNode = parentNode->GetChildNodes()[itemPosInNode - 1];
itemRow = GetRowByItem(siblingNode->GetItem()) +
siblingNode->GetSubTreeCount() +
wxWindow *parent = GetParent();
wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED, parent->GetId());
le.SetEventObject(parent);
- le.SetModel(GetOwner()->GetModel());
+ le.SetModel(GetModel());
le.SetItem(item);
parent->GetEventHandler()->ProcessEvent(le);
wxWindow *parent = GetParent();
wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED, parent->GetId());
le.SetEventObject(parent);
- le.SetModel(GetOwner()->GetModel());
+ le.SetModel(GetModel());
le.SetItem(item);
le.SetColumn(view_column);
le.SetDataViewColumn(GetOwner()->GetColumn(view_column));
m_selection.Clear();
SortPrepare();
- BuildTree( GetOwner()->GetModel() );
+ BuildTree( GetModel() );
GetOwner()->UpdateColBestWidths();
UpdateDisplay();
void wxDataViewMainWindow::RecalculateDisplay()
{
- wxDataViewModel *model = GetOwner()->GetModel();
+ wxDataViewModel *model = GetModel();
if (!model)
{
Refresh();
wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, parent->GetId());
le.SetEventObject(parent);
- le.SetModel(GetOwner()->GetModel());
+ le.SetModel(GetModel());
le.SetItem( item );
parent->GetEventHandler()->ProcessEvent(le);
int wxDataViewMainWindow::GetLineStart( unsigned int row ) const
{
- const wxDataViewModel *model = GetOwner()->GetModel();
+ const wxDataViewModel *model = GetModel();
if (GetOwner()->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT)
{
int wxDataViewMainWindow::GetLineAt( unsigned int y ) const
{
- const wxDataViewModel *model = GetOwner()->GetModel();
+ const wxDataViewModel *model = GetModel();
// check for the easy case first
if ( !GetOwner()->HasFlag(wxDV_VARIABLE_LINE_HEIGHT) )
int wxDataViewMainWindow::GetLineHeight( unsigned int row ) const
{
- const wxDataViewModel *model = GetOwner()->GetModel();
+ const wxDataViewModel *model = GetModel();
if (GetOwner()->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT)
{
if( current == static_cast<int>(row))
{
ret = node;
- return DoJob::OK;
+ return DoJob::DONE;
}
if( node->GetSubTreeCount() + current < static_cast<int>(row) )
{
current += node->GetSubTreeCount();
- return DoJob::IGR;
+ return DoJob::SKIP_SUBTREE;
}
else
{
// desired node directly. This can speed up finding the node
// in some cases, and will have a very good effect for list views.
if ( node->HasChildren() &&
- (int)node->GetNodes().size() == node->GetSubTreeCount() )
+ (int)node->GetChildNodes().size() == node->GetSubTreeCount() )
{
const int index = static_cast<int>(row) - current - 1;
- ret = node->GetNodes()[index];
- return DoJob::OK;
+ ret = node->GetChildNodes()[index];
+ return DoJob::DONE;
}
- return DoJob::CONT;
+ return DoJob::CONTINUE;
}
}
wxDataViewEvent le(type, parent->GetId());
le.SetEventObject(parent);
- le.SetModel(GetOwner()->GetModel());
+ le.SetModel(GetModel());
le.SetItem( item );
return !parent->ProcessWindowEvent(le) || le.IsAllowed();
node->ToggleOpen();
// build the children of current node
- if( node->GetNodes().empty() )
+ if( node->GetChildNodes().empty() )
{
SortPrepare();
- ::BuildTreeHelper(GetOwner()->GetModel(), node->GetItem(), node);
+ ::BuildTreeHelper(GetModel(), node->GetItem(), node);
}
// By expanding the node all row indices that are currently in the selection list
wxDataViewTreeNode * wxDataViewMainWindow::FindNode( const wxDataViewItem & item )
{
- const wxDataViewModel * model = GetOwner()->GetModel();
+ const wxDataViewModel * model = GetModel();
if( model == NULL )
return NULL;
{
if( node->HasChildren() )
{
- if( node->GetNodes().empty() )
+ if( node->GetChildNodes().empty() )
{
// Even though the item is a container, it doesn't have any
// child nodes in the control's representation yet. We have
::BuildTreeHelper(model, node->GetItem(), node);
}
- const wxDataViewTreeNodes& nodes = node->GetNodes();
+ const wxDataViewTreeNodes& nodes = node->GetChildNodes();
bool found = false;
for (unsigned i = 0; i < nodes.GetCount(); ++i)
if (IsVirtualList())
{
wxDataViewVirtualListModel *list_model =
- (wxDataViewVirtualListModel*) GetOwner()->GetModel();
+ (wxDataViewVirtualListModel*) GetModel();
return list_model->GetCount();
}
ret ++;
if( node->GetItem() == item )
{
- return DoJob::OK;
+ return DoJob::DONE;
}
if( node->GetItem() == *m_iter )
{
m_iter++;
- return DoJob::CONT;
+ return DoJob::CONTINUE;
}
else
{
ret += node->GetSubTreeCount();
- return DoJob::IGR;
+ return DoJob::SKIP_SUBTREE;
}
}
int wxDataViewMainWindow::GetRowByItem(const wxDataViewItem & item) const
{
- const wxDataViewModel * model = GetOwner()->GetModel();
+ const wxDataViewModel * model = GetModel();
if( model == NULL )
return -1;
if( model->IsContainer(children[index]) )
n->SetHasChildren( true );
- node->AddNode(n);
+ node->AddChild(n);
}
wxASSERT( node->IsOpen() );
{
DestroyTree();
- if (GetOwner()->GetModel()->IsVirtualListModel())
+ if (GetModel()->IsVirtualListModel())
{
m_count = -1;
return;
m_count = -1;
}
-static void DestroyTreeHelper( wxDataViewTreeNode * node )
-{
- if ( node->HasChildren() )
- {
- wxDataViewTreeNodes& nodes = node->GetNodes();
- const int len = nodes.size();
- for (int i = 0; i < len; i++)
- DestroyTreeHelper(nodes[i]);
- }
- delete node;
-}
-
void wxDataViewMainWindow::DestroyTree()
{
if (!IsVirtualList())
{
- ::DestroyTreeHelper(m_root);
- m_count = 0;
- m_root = NULL;
+ wxDELETE(m_root);
+ m_count = 0;
}
}
switch ( event.GetKeyCode() )
{
case WXK_RETURN:
+ case WXK_SPACE:
{
wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED,
parent->GetId());
le.SetItem( GetItemByRow(m_currentRow) );
le.SetEventObject(parent);
- le.SetModel(GetOwner()->GetModel());
+ le.SetModel(GetModel());
parent->GetEventHandler()->ProcessEvent(le);
}
}
}
- wxDataViewModel *model = GetOwner()->GetModel();
+ wxDataViewModel *model = GetModel();
#if wxUSE_DRAG_AND_DROP
if (event.Dragging())
le.SetColumn( col->GetModelColumn() );
le.SetDataViewColumn( col );
le.SetEventObject(parent);
- le.SetModel(GetOwner()->GetModel());
+ le.SetModel(GetModel());
parent->GetEventHandler()->ProcessEvent(le);
}
le.SetColumn( col->GetModelColumn() );
le.SetDataViewColumn( col );
le.SetEventObject(parent);
- le.SetModel(GetOwner()->GetModel());
+ le.SetModel(GetModel());
le.SetValue(value);
parent->GetEventHandler()->ProcessEvent(le);
}