Bo's patch adding Selection API and some more changes, doesn't compile yet

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@48182 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2007-08-19 19:03:01 +00:00
parent 0c6fcb099e
commit b7e9f8b136
5 changed files with 458 additions and 211 deletions

View File

@@ -2,7 +2,7 @@
// Name: wx/dataview.h // Name: wx/dataview.h
// Purpose: wxDataViewCtrl base classes // Purpose: wxDataViewCtrl base classes
// Author: Robert Roebling // Author: Robert Roebling
// Modified by: // Modified by: Bo Yang
// Created: 08.01.06 // Created: 08.01.06
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Robert Roebling // Copyright: (c) Robert Roebling
@@ -21,10 +21,11 @@
#include "wx/bitmap.h" #include "wx/bitmap.h"
#include "wx/variant.h" #include "wx/variant.h"
#include "wx/listctrl.h" #include "wx/listctrl.h"
#include "wx/dynarray.h"
#if defined(__WXGTK20__) #if defined(__WXGTK20__)
// for testing // for testing
// #define wxUSE_GENERICDATAVIEWCTRL 1 #define wxUSE_GENERICDATAVIEWCTRL 1
#elif defined(__WXMAC__) #elif defined(__WXMAC__)
#else #else
#define wxUSE_GENERICDATAVIEWCTRL 1 #define wxUSE_GENERICDATAVIEWCTRL 1
@@ -44,7 +45,6 @@ class WXDLLIMPEXP_FWD_ADV wxDataViewCtrl;
class WXDLLIMPEXP_FWD_ADV wxDataViewColumn; class WXDLLIMPEXP_FWD_ADV wxDataViewColumn;
class WXDLLIMPEXP_FWD_ADV wxDataViewRenderer; class WXDLLIMPEXP_FWD_ADV wxDataViewRenderer;
class WXDLLIMPEXP_FWD_ADV wxDataViewModelNotifier; class WXDLLIMPEXP_FWD_ADV wxDataViewModelNotifier;
class wxDataViewEventModelNotifier;
extern WXDLLIMPEXP_DATA_ADV(const wxChar) wxDataViewCtrlNameStr[]; extern WXDLLIMPEXP_DATA_ADV(const wxChar) wxDataViewCtrlNameStr[];
@@ -396,6 +396,8 @@ protected:
// wxDataViewCtrlBase // wxDataViewCtrlBase
// --------------------------------------------------------- // ---------------------------------------------------------
WX_DECLARE_OBJARRAY(wxDataViewItem, wxDataViewItemArray);
#define wxDV_SINGLE 0x0000 // for convenience #define wxDV_SINGLE 0x0000 // for convenience
#define wxDV_MULTIPLE 0x0001 // can select multiple items #define wxDV_MULTIPLE 0x0001 // can select multiple items
@@ -472,8 +474,29 @@ public:
int GetIndent() const int GetIndent() const
{ return m_indent; } { return m_indent; }
// TODO selection code //Selection Code
virtual wxDataViewItem GetSelection() = 0; virtual int GetSelections( wxDataViewItemArray & sel ) const = 0;
virtual void SetSelections( const wxDataViewItemArray & sel ) = 0;
virtual void Select( const wxDataViewItem & item ) = 0;
virtual void Unselect( const wxDataViewItem & item ) = 0;
virtual bool IsSelected( const wxDataViewItem & item ) const = 0;
virtual int GetSelections( wxArrayInt & sel ) const = 0;
virtual void SetSelections( const wxArrayInt & sel ) = 0;
virtual void Select( int row ) = 0;
virtual void Unselect( int row ) = 0;
virtual bool IsSelected( int row ) const = 0;
virtual void SelectRange( int from, int to ) = 0;
virtual void UnselectRange( int from, int to ) = 0;
virtual void SelectAll() = 0;
virtual void UnselectAll() = 0;
virtual void EnsureVisible( int row ) = 0;
virtual void EnsureVisible( const wxDataViewItem & item ) = 0;
virtual wxDataViewItem GetItemByRow( unsigned int row ) const = 0;
virtual int GetRowByItem( const wxDataViewItem & item ) const = 0;
protected: protected:
virtual void DoSetExpanderColumn() = 0 ; virtual void DoSetExpanderColumn() = 0 ;
@@ -482,7 +505,6 @@ protected:
private: private:
wxDataViewModel *m_model; wxDataViewModel *m_model;
wxList m_cols; wxList m_cols;
wxDataViewEventModelNotifier *m_eventNotifier;
unsigned int m_expander_column; unsigned int m_expander_column;
int m_indent ; int m_indent ;

View File

@@ -2,6 +2,7 @@
// Name: wx/generic/dataview.h // Name: wx/generic/dataview.h
// Purpose: wxDataViewCtrl generic implementation header // Purpose: wxDataViewCtrl generic implementation header
// Author: Robert Roebling // Author: Robert Roebling
// Modified By: Bo Yang
// Id: $Id$ // Id: $Id$
// Copyright: (c) 1998 Robert Roebling // Copyright: (c) 1998 Robert Roebling
// Licence: wxWindows licence // Licence: wxWindows licence
@@ -352,18 +353,29 @@ public:
virtual void DoSetExpanderColumn(); virtual void DoSetExpanderColumn();
virtual void DoSetIndent(); virtual void DoSetIndent();
virtual wxDataViewItem GetSelection() ; virtual int GetSelections( wxDataViewItemArray & sel ) const;
virtual void SetSelections( const wxDataViewItemArray & sel );
virtual void Select( const wxDataViewItem & item );
virtual void Unselect( const wxDataViewItem & item );
virtual bool IsSelected( const wxDataViewItem & item ) const;
/********************selection code********************* virtual int GetSelections( wxArrayInt & sel ) const;
virtual void SetSelection( int row ); // -1 for unselect virtual void SetSelections( const wxArrayInt & sel );
virtual void SetSelectionRange( unsigned int from, unsigned int to ); virtual void Select( int row );
virtual void SetSelections( const wxArrayInt& aSelections); virtual void Unselect( int row );
virtual void Unselect( unsigned int row ); virtual bool IsSelected( int row ) const;
virtual void SelectRange( int from, int to );
virtual void UnselectRange( int from, int to );
virtual void SelectAll();
virtual void UnselectAll();
virtual void EnsureVisible( int row );
virtual void EnsureVisible( const wxDataViewItem & item );
virtual wxDataViewItem GetItemByRow( unsigned int row ) const;
virtual int GetRowByItem( const wxDataViewItem & item ) const;
virtual bool IsSelected( unsigned int row ) const;
virtual int GetSelection() const;
virtual int GetSelections(wxArrayInt& aSelections) const;
*****************************************************/
public: // utility functions not part of the API public: // utility functions not part of the API

View File

@@ -2,7 +2,7 @@
// Name: dataview.cpp // Name: dataview.cpp
// Purpose: wxDataViewCtrl wxWidgets sample // Purpose: wxDataViewCtrl wxWidgets sample
// Author: Robert Roebling // Author: Robert Roebling
// Modified by: Francesco Montorsi // Modified by: Francesco Montorsi, Bo Yang
// Created: 06/01/06 // Created: 06/01/06
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Robert Roebling // Copyright: (c) Robert Roebling
@@ -146,6 +146,7 @@ public:
// add to data // add to data
MyMusicModelNode *child_node = MyMusicModelNode *child_node =
new MyMusicModelNode( m_classical, title, artist, year ); new MyMusicModelNode( m_classical, title, artist, year );
m_classical->Append( child_node ); m_classical->Append( child_node );
if (m_classicalMusicIsKnownToControl) if (m_classicalMusicIsKnownToControl)
@@ -164,6 +165,11 @@ public:
// notify control // notify control
ItemDeleted( parent, item ); ItemDeleted( parent, item );
//We must delete the node after we call ItemDeleted
//The reason is that:
//When we use wxSortedArray, the array find a node through binary search for speed.
//And when the array is searching for some node, it call the model's compare function.
//The compare function need the node to be compared. So we should delete the node later, here.
node->GetParent()->GetChildren().Remove( node ); node->GetParent()->GetChildren().Remove( node );
delete node; delete node;
} }
@@ -417,6 +423,13 @@ public:
void OnValueChanged( wxDataViewEvent &event ); void OnValueChanged( wxDataViewEvent &event );
void OnItemAdded( wxDataViewEvent &event ); void OnItemAdded( wxDataViewEvent &event );
void OnItemDeleted( wxDataViewEvent &event ); void OnItemDeleted( wxDataViewEvent &event );
void OnActivated( wxDataViewEvent &event );
void OnHeaderClick( wxDataViewEvent &event );
void OnHeaderRightClick( wxDataViewEvent &event );
void OnSorted( wxDataViewEvent &event );
void OnRightClick( wxMouseEvent &event );
void OnGoto( wxCommandEvent &event);
private: private:
wxDataViewCtrl* m_musicCtrl; wxDataViewCtrl* m_musicCtrl;
@@ -426,6 +439,7 @@ private:
wxObjectDataPtr<MyListModel> m_list_model; wxObjectDataPtr<MyListModel> m_list_model;
wxTextCtrl * m_log; wxTextCtrl * m_log;
wxLog *m_logOld;
private: private:
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
@@ -473,7 +487,8 @@ enum
ID_DELETE_MUSIC = 101, ID_DELETE_MUSIC = 101,
ID_PREPEND_LIST = 200, ID_PREPEND_LIST = 200,
ID_DELETE_LIST = 201 ID_DELETE_LIST = 201,
ID_GOTO = 202
}; };
BEGIN_EVENT_TABLE(MyFrame, wxFrame) BEGIN_EVENT_TABLE(MyFrame, wxFrame)
@@ -483,9 +498,16 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_BUTTON( ID_DELETE_MUSIC, MyFrame::OnDeleteMusic ) EVT_BUTTON( ID_DELETE_MUSIC, MyFrame::OnDeleteMusic )
EVT_BUTTON( ID_PREPEND_LIST, MyFrame::OnPrependList ) EVT_BUTTON( ID_PREPEND_LIST, MyFrame::OnPrependList )
EVT_BUTTON( ID_DELETE_LIST, MyFrame::OnDeleteList ) EVT_BUTTON( ID_DELETE_LIST, MyFrame::OnDeleteList )
EVT_BUTTON( ID_GOTO, MyFrame::OnGoto)
EVT_DATAVIEW_MODEL_ITEM_ADDED( ID_MUSIC_CTRL, MyFrame::OnItemAdded ) EVT_DATAVIEW_MODEL_ITEM_ADDED( ID_MUSIC_CTRL, MyFrame::OnItemAdded )
EVT_DATAVIEW_MODEL_ITEM_DELETED( ID_MUSIC_CTRL, MyFrame::OnItemDeleted ) EVT_DATAVIEW_MODEL_ITEM_DELETED( ID_MUSIC_CTRL, MyFrame::OnItemDeleted )
EVT_DATAVIEW_MODEL_VALUE_CHANGED( ID_MUSIC_CTRL, MyFrame::OnValueChanged ) EVT_DATAVIEW_MODEL_VALUE_CHANGED( ID_MUSIC_CTRL, MyFrame::OnValueChanged )
EVT_DATAVIEW_MODEL_ITEM_CHANGED( ID_MUSIC_CTRL, MyFrame::OnValueChanged )
EVT_DATAVIEW_ITEM_ACTIVATED(ID_MUSIC_CTRL, MyFrame::OnActivated )
EVT_DATAVIEW_COLUMN_HEADER_CLICK(ID_MUSIC_CTRL, MyFrame::OnHeaderClick)
EVT_DATAVIEW_COLUMN_HEADER_RIGHT_CLICKED(ID_MUSIC_CTRL, MyFrame::OnHeaderRightClick)
EVT_DATAVIEW_COLUMN_SORTED(ID_MUSIC_CTRL, MyFrame::OnSorted)
EVT_RIGHT_UP(MyFrame::OnRightClick)
END_EVENT_TABLE() END_EVENT_TABLE()
MyFrame::MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h): MyFrame::MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h):
@@ -515,7 +537,7 @@ MyFrame::MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h):
// MyMusic // MyMusic
m_musicCtrl = new wxDataViewCtrl( this, ID_MUSIC_CTRL, wxDefaultPosition, m_musicCtrl = new wxDataViewCtrl( this, ID_MUSIC_CTRL, wxDefaultPosition,
wxDefaultSize ); wxDefaultSize, wxDV_MULTIPLE );
m_music_model = new MyMusicModel; m_music_model = new MyMusicModel;
m_musicCtrl->AssociateModel( m_music_model.get() ); m_musicCtrl->AssociateModel( m_music_model.get() );
@@ -534,7 +556,7 @@ MyFrame::MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h):
// MyList // MyList
m_listCtrl = new wxDataViewCtrl( this, wxID_ANY, wxDefaultPosition, m_listCtrl = new wxDataViewCtrl( this, wxID_ANY, wxDefaultPosition,
wxDefaultSize ); wxDefaultSize, wxDV_MULTIPLE );
m_list_model = new MyListModel; m_list_model = new MyListModel;
m_listCtrl->AssociateModel( m_list_model.get() ); m_listCtrl->AssociateModel( m_list_model.get() );
@@ -555,10 +577,13 @@ MyFrame::MyFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h):
button_sizer->Add( 10, 10, 1 ); button_sizer->Add( 10, 10, 1 );
button_sizer->Add( new wxButton( this, ID_PREPEND_LIST, "Prepend"), 0, wxALL, 10 ); button_sizer->Add( new wxButton( this, ID_PREPEND_LIST, "Prepend"), 0, wxALL, 10 );
button_sizer->Add( new wxButton( this, ID_DELETE_LIST, "Delete selected"), 0, wxALL, 10 ); button_sizer->Add( new wxButton( this, ID_DELETE_LIST, "Delete selected"), 0, wxALL, 10 );
button_sizer->Add( new wxButton( this, ID_GOTO, "Goto 50"), 0, wxALL, 10 );
main_sizer->Add( button_sizer, 0, wxGROW, 0 ); main_sizer->Add( button_sizer, 0, wxGROW, 0 );
m_log = new wxTextCtrl( this, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); m_log = new wxTextCtrl( this, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
m_logOld = wxLog::SetActiveTarget(new wxLogTextCtrl(m_log));
wxLogMessage("This is the log window");
main_sizer->Add( m_log, 1, wxGROW ); main_sizer->Add( m_log, 1, wxGROW );
@@ -577,9 +602,11 @@ void MyFrame::OnAddMozart(wxCommandEvent& WXUNUSED(event) )
void MyFrame::OnDeleteMusic(wxCommandEvent& WXUNUSED(event) ) void MyFrame::OnDeleteMusic(wxCommandEvent& WXUNUSED(event) )
{ {
wxDataViewItem item = m_musicCtrl->GetSelection(); wxDataViewItemArray items;
if (item.IsOk()) int len = m_musicCtrl->GetSelections( items );
m_music_model->Delete( item ); for( int i = 0; i < len; i ++ )
if (items[i].IsOk())
m_music_model->Delete( items[i] );
} }
void MyFrame::OnPrependList( wxCommandEvent& WXUNUSED(event) ) void MyFrame::OnPrependList( wxCommandEvent& WXUNUSED(event) )
@@ -589,9 +616,11 @@ void MyFrame::OnPrependList( wxCommandEvent& WXUNUSED(event) )
void MyFrame::OnDeleteList( wxCommandEvent& WXUNUSED(event) ) void MyFrame::OnDeleteList( wxCommandEvent& WXUNUSED(event) )
{ {
wxDataViewItem item = m_listCtrl->GetSelection(); wxDataViewItemArray items;
if (item.IsOk()) int len = m_listCtrl->GetSelections( items );
m_list_model->DeleteItem( item ); for( int i = 0; i < len; i ++ )
if (items[i].IsOk())
m_list_model->DeleteItem( items[i] );
} }
void MyFrame::OnItemAdded( wxDataViewEvent &event ) void MyFrame::OnItemAdded( wxDataViewEvent &event )
@@ -599,7 +628,7 @@ void MyFrame::OnItemAdded( wxDataViewEvent &event )
if (!m_log) if (!m_log)
return; return;
m_log->AppendText( "EVT_DATAVIEW_MODEL_ITEM_ADDED\n" ); wxLogMessage("wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_ADDED, Item Id: %d",event.GetItem().GetID());
} }
void MyFrame::OnItemDeleted( wxDataViewEvent &event ) void MyFrame::OnItemDeleted( wxDataViewEvent &event )
@@ -607,7 +636,7 @@ void MyFrame::OnItemDeleted( wxDataViewEvent &event )
if (!m_log) if (!m_log)
return; return;
m_log->AppendText( "EVT_DATAVIEW_MODEL_ITEM_DELETED\n" ); wxLogMessage( "EVT_DATAVIEW_MODEL_ITEM_DELETED, Item Id: %d", event.GetItem().GetID() );
} }
void MyFrame::OnValueChanged( wxDataViewEvent &event ) void MyFrame::OnValueChanged( wxDataViewEvent &event )
@@ -615,7 +644,52 @@ void MyFrame::OnValueChanged( wxDataViewEvent &event )
if (!m_log) if (!m_log)
return; return;
m_log->AppendText( "EVT_DATAVIEW_MODEL_VALUE_CHANGED\n" ); wxLogMessage( "EVT_DATAVIEW_MODEL_VALUE_CHANGED, Item Id: %d; Column: %d", event.GetItem().GetID(), event.GetColumn() );
}
void MyFrame::OnActivated( wxDataViewEvent &event )
{
if(!m_log)
return;
wxLogMessage("wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, Item Id: %d; Column: %d", event.GetItem().GetID(), event.GetColumn());
}
void MyFrame::OnHeaderClick( wxDataViewEvent &event )
{
if(!m_log)
return;
wxLogMessage("wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK, Column: %d", event.GetColumn());
}
void MyFrame::OnHeaderRightClick( wxDataViewEvent &event )
{
if(!m_log)
return;
wxLogMessage("wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK, Column: %d", event.GetColumn());
}
void MyFrame::OnSorted( wxDataViewEvent &event )
{
if(!m_log)
return;
wxLogMessage("wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED, Column: %d", event.GetColumn());
}
void MyFrame::OnRightClick( wxMouseEvent &event )
{
if(!m_log)
return;
wxLogMessage("wxEVT_MOUSE_RIGHT_UP, Click Point is X: %d, Y: %d", event.GetX(), event.GetY());
}
void MyFrame::OnGoto( wxCommandEvent &event)
{
m_listCtrl->EnsureVisible(50);
} }
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) ) void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )

View File

@@ -533,6 +533,9 @@ void wxDataViewColumnBase::SetFlags(int flags)
// wxDataViewCtrlBase // wxDataViewCtrlBase
// --------------------------------------------------------- // ---------------------------------------------------------
#include "wx/arrimpl.cpp"
WX_DEFINE_OBJARRAY(wxDataViewItemArray);
IMPLEMENT_ABSTRACT_CLASS(wxDataViewCtrlBase, wxControl) IMPLEMENT_ABSTRACT_CLASS(wxDataViewCtrlBase, wxControl)
wxDataViewCtrlBase::wxDataViewCtrlBase() wxDataViewCtrlBase::wxDataViewCtrlBase()

View File

@@ -66,7 +66,7 @@ static const int EXPANDER_MARGIN = 4;
// wxDataViewHeaderWindow // wxDataViewHeaderWindow
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#define USE_NATIVE_HEADER_WINDOW 1 #define USE_NATIVE_HEADER_WINDOW 0
// NB: for some reason, this class must be dllexport'ed or we get warnings from // NB: for some reason, this class must be dllexport'ed or we get warnings from
// MSVC in DLL build // MSVC in DLL build
@@ -263,7 +263,7 @@ int LINKAGEMODE wxGenericTreeModelItemCmp( void * id1, void * id2);
class wxDataViewTreeNode class wxDataViewTreeNode
{ {
public: public:
wxDataViewTreeNode( wxDataViewTreeNode * parent ) wxDataViewTreeNode( wxDataViewTreeNode * parent = NULL )
:leaves( wxGenericTreeModelItemCmp ), :leaves( wxGenericTreeModelItemCmp ),
nodes(wxGenericTreeModelNodeCmp) nodes(wxGenericTreeModelNodeCmp)
{ this->parent = parent; { this->parent = parent;
@@ -418,6 +418,7 @@ public:
virtual ~wxDataViewMainWindow(); virtual ~wxDataViewMainWindow();
// notifications from wxDataViewModel // notifications from wxDataViewModel
void SendModelEvent( wxEventType type, const wxDataViewItem & item);
bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ); bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item );
bool ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item ); bool ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item );
bool ItemChanged( const wxDataViewItem &item ); bool ItemChanged( const wxDataViewItem &item );
@@ -444,6 +445,7 @@ public:
void OnRenameTimer(); void OnRenameTimer();
void ScrollWindow( int dx, int dy, const wxRect *rect = NULL ); void ScrollWindow( int dx, int dy, const wxRect *rect = NULL );
void ScrollTo( int rows );
bool HasCurrentRow() { return m_currentRow != (unsigned int)-1; } bool HasCurrentRow() { return m_currentRow != (unsigned int)-1; }
void ChangeCurrentRow( unsigned int row ); void ChangeCurrentRow( unsigned int row );
@@ -459,7 +461,8 @@ public:
unsigned int GetRowCount() ; unsigned int GetRowCount() ;
wxDataViewItem GetSelection(); wxDataViewItem GetSelection();
wxDataViewSelection GetSelections(){ return m_selection; }
void SetSelections( const wxDataViewSelection & sel ) { m_selection = sel; UpdateDisplay(); }
void Select( const wxArrayInt& aSelections ); void Select( const wxArrayInt& aSelections );
void SelectAllRows( bool on ); void SelectAllRows( bool on );
void SelectRow( unsigned int row, bool on ); void SelectRow( unsigned int row, bool on );
@@ -482,7 +485,7 @@ public:
//Some useful functions for row and item mapping //Some useful functions for row and item mapping
wxDataViewItem GetItemByRow( unsigned int row ); wxDataViewItem GetItemByRow( unsigned int row );
unsigned int GetRowByItem( const wxDataViewItem & item ); int GetRowByItem( const wxDataViewItem & item );
//Methods for building the mapping tree //Methods for building the mapping tree
void BuildTree( wxDataViewModel * model ); void BuildTree( wxDataViewModel * model );
@@ -1191,6 +1194,16 @@ void wxDataViewHeaderWindowMSW::UpdateDisplay()
hdi.cxy = col->GetWidth(); hdi.cxy = col->GetWidth();
hdi.cchTextMax = sizeof(hdi.pszText)/sizeof(hdi.pszText[0]); hdi.cchTextMax = sizeof(hdi.pszText)/sizeof(hdi.pszText[0]);
hdi.fmt = HDF_LEFT | HDF_STRING; hdi.fmt = HDF_LEFT | HDF_STRING;
//hdi.fmt &= ~(HDF_SORTDOWN|HDF_SORTUP);
//sorting support
if(model && model->GetSortingColumn() == i)
{
//The Microsoft Comctrl32.dll 6.0 support SORTUP/SORTDOWN, but they are not default
//see http://msdn2.microsoft.com/en-us/library/ms649534.aspx for more detail
//hdi.fmt |= model->GetSortOrderAscending()? HDF_SORTUP:HDF_SORTDOWN;
;
}
// lParam is reserved for application's use: // lParam is reserved for application's use:
// we store there the column index to use it later in MSWOnNotify // we store there the column index to use it later in MSWOnNotify
@@ -1323,12 +1336,12 @@ bool wxDataViewHeaderWindowMSW::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARA
{ {
bool order = col->IsSortOrderAscending(); bool order = col->IsSortOrderAscending();
col->SetSortOrder(!order); col->SetSortOrder(!order);
// model->SetSortOrderAscending(!order); model->SetSortOrderAscending(!order);
} }
else if(model) else if(model)
{ {
model->SetSortingColumn(idx); model->SetSortingColumn(idx);
// model->SetSortOrderAscending(true); model->SetSortOrderAscending(col->IsSortOrderAscending());
} }
} }
UpdateDisplay(); UpdateDisplay();
@@ -1492,7 +1505,7 @@ void wxGenericDataViewHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
int ch = h; int ch = h;
wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE; wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE;
if (col->IsSortable()) if (col->IsSortable() && GetOwner()->GetModel()->GetSortingColumn() == i)
{ {
if (col->IsSortOrderAscending()) if (col->IsSortOrderAscending())
sortArrow = wxHDR_SORT_ICON_UP; sortArrow = wxHDR_SORT_ICON_UP;
@@ -1645,10 +1658,37 @@ void wxGenericDataViewHeaderWindow::OnMouse( wxMouseEvent &event )
} }
else // click on a column else // click on a column
{ {
wxDataViewModel * model = GetOwner()->GetModel();
wxEventType evt = event.LeftDown() ? wxEventType evt = event.LeftDown() ?
wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK : wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK :
wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK; wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK;
SendEvent(evt, m_column); SendEvent(evt, m_column);
//Left click the header
if(event.LeftDown())
{
wxDataViewColumn *col = GetColumn(m_column);
if(col->IsSortable())
{
unsigned int colnum = model->GetSortingColumn();
if(model && static_cast<int>(colnum) == m_column)
{
bool order = col->IsSortOrderAscending();
col->SetSortOrder(!order);
model->SetSortOrderAscending(!order);
}
else if(model)
{
model->SetSortingColumn(m_column);
model->SetSortOrderAscending(col->IsSortOrderAscending());
}
}
UpdateDisplay();
if(model)
model->Resort();
//Send the column sorted event
SendEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED, m_column);
}
} }
} }
else if (event.Moving()) else if (event.Moving())
@@ -1840,45 +1880,29 @@ public:
virtual int operator() ( void * n ) = 0; virtual int operator() ( void * n ) = 0;
}; };
#if 0
class ItemAddJob: public DoJob
{
public:
ItemAddJob( const wxDataViewItem & parent, const wxDataViewItem & item, int * count )
{ this->parent = parent ; this->item = item ; m_count = count; }
virtual ~ItemAddJob(){};
virtual int operator() ( wxDataViewTreeNode * node )
{
if( node->GetItem() == parent )
{
node->SetHasChildren( true );
wxDataViewTreeNode * newnode = new wxDataViewTreeNode( node );
newnode->SetItem(item);
node->AppendChild( newnode);
*m_count = -1;
return OK;
}
return CONT;
}
private:
int * m_count;
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;
switch( func( node ) )
{
case DoJob::OK :
return true ;
case DoJob::IGR:
return false;
case DoJob::CONT:
default:
;
}
wxDataViewTreeNodes nodes = node->GetNodes(); wxDataViewTreeNodes nodes = node->GetNodes();
wxDataViewTreeLeaves leaves = node->GetChildren(); wxDataViewTreeLeaves leaves = node->GetChildren();
int len_nodes = nodes.GetCount(); int len_nodes = nodes.GetCount();
int len = leaves.GetCount(); int len = leaves.GetCount();
int i = 0, nodes_i = 0; int i = 0, nodes_i = 0;
for( ; i < len ; i ++ ) for( ; i < len ; i ++ )
{ {
void * n = leaves[i]; void * n = leaves[i];
@@ -1887,17 +1911,6 @@ bool Walker( wxDataViewTreeNode * node, DoJob & func )
wxDataViewTreeNode * nd = nodes[nodes_i]; wxDataViewTreeNode * nd = nodes[nodes_i];
nodes_i++; nodes_i++;
switch( func( nd ) )
{
case DoJob::OK :
return true ;
case DoJob::IGR:
continue;
case DoJob::CONT:
default:
;
}
if( Walker( nd , func ) ) if( Walker( nd , func ) )
return true; return true;
@@ -1917,12 +1930,25 @@ bool Walker( wxDataViewTreeNode * node, DoJob & func )
return false; return false;
} }
void wxDataViewMainWindow::SendModelEvent( wxEventType type, const wxDataViewItem & item )
{
wxWindow *parent = GetParent();
wxDataViewEvent le(type, parent->GetId());
le.SetEventObject(parent);
le.SetModel(GetOwner()->GetModel());
le.SetItem( item );
parent->GetEventHandler()->ProcessEvent(le);
}
bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxDataViewItem & item) bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxDataViewItem & item)
{ {
g_model = GetOwner()->GetModel(); g_model = GetOwner()->GetModel();
wxDataViewTreeNode * node; wxDataViewTreeNode * node;
node = FindNode(parent); node = FindNode(parent);
SendModelEvent(wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_ADDED, item );
if( node == NULL ) if( node == NULL )
return false; return false;
@@ -1933,6 +1959,7 @@ bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxData
{ {
wxDataViewTreeNode * newnode = new wxDataViewTreeNode( node ); wxDataViewTreeNode * newnode = new wxDataViewTreeNode( node );
newnode->SetItem(item); newnode->SetItem(item);
newnode->SetHasChildren( true );
node->AddNode( newnode); node->AddNode( newnode);
} }
else else
@@ -1942,33 +1969,10 @@ bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxData
m_count = -1; m_count = -1;
UpdateDisplay(); UpdateDisplay();
return true; return true;
} }
#if 0
class ItemDeleteJob: public DoJob
{
public:
ItemDeleteJob( const wxDataViewItem & item, int * count ) { m_item = item; m_count = count; }
virtual ~ItemDeleteJob(){}
virtual int operator() ( wxDataViewTreeNode * node )
{
if( node->GetItem() == m_item )
{
node->GetParent()->GetChildren().Remove( node );
delete node;
*m_count = -1;
return DoJob::OK;
}
return DoJob::CONT;
}
private:
int * m_count;
wxDataViewItem m_item;
};
#endif
void DestroyTreeHelper( wxDataViewTreeNode * node); void DestroyTreeHelper( wxDataViewTreeNode * node);
bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent, bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent,
@@ -1978,6 +1982,7 @@ bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent,
wxDataViewTreeNode * node; wxDataViewTreeNode * node;
node = FindNode(parent); node = FindNode(parent);
SendModelEvent(wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_DELETED, item);
if( node == NULL || node->GetChildren().Index( item.GetID() ) == wxNOT_FOUND ) if( node == NULL || node->GetChildren().Index( item.GetID() ) == wxNOT_FOUND )
{ {
@@ -2025,13 +2030,14 @@ bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent,
bool wxDataViewMainWindow::ItemChanged(const wxDataViewItem & item) bool wxDataViewMainWindow::ItemChanged(const wxDataViewItem & item)
{ {
g_model = GetOwner()->GetModel(); g_model = GetOwner()->GetModel();
g_model->Resort();
SendModelEvent(wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_CHANGED,item);
unsigned int row = GetRowByItem(item);
RefreshRow( row );
return true; return true;
} }
bool wxDataViewMainWindow::ValueChanged( const wxDataViewItem & item, unsigned int WXUNUSED(col) ) bool wxDataViewMainWindow::ValueChanged( const wxDataViewItem & item, unsigned int col )
{ {
// NOTE: to be valid, we cannot use e.g. INT_MAX - 1 // NOTE: to be valid, we cannot use e.g. INT_MAX - 1
/*#define MAX_VIRTUAL_WIDTH 100000 /*#define MAX_VIRTUAL_WIDTH 100000
@@ -2043,9 +2049,18 @@ bool wxDataViewMainWindow::ValueChanged( const wxDataViewItem & item, unsigned i
return true; return true;
*/ */
g_model = GetOwner()->GetModel(); g_model = GetOwner()->GetModel();
g_model->Resort();
//Send event
wxWindow *parent = GetParent();
wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_MODEL_VALUE_CHANGED, parent->GetId());
le.SetEventObject(parent);
le.SetModel(GetOwner()->GetModel());
le.SetItem(item);
le.SetColumn(col);
le.SetDataViewColumn(GetOwner()->GetColumn(col));
parent->GetEventHandler()->ProcessEvent(le);
unsigned int row = GetRowByItem(item);
RefreshRow( row );
return true; return true;
} }
@@ -2055,6 +2070,13 @@ bool wxDataViewMainWindow::Cleared()
DestroyTree(); DestroyTree();
UpdateDisplay(); UpdateDisplay();
wxWindow *parent = GetParent();
wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_MODEL_CLEARED, parent->GetId());
le.SetEventObject(parent);
le.SetModel(GetOwner()->GetModel());
parent->GetEventHandler()->ProcessEvent(le);
return true; return true;
} }
@@ -2100,6 +2122,14 @@ void wxDataViewMainWindow::ScrollWindow( int dx, int dy, const wxRect *rect )
GetOwner()->m_headerArea->ScrollWindow( dx, 0 ); GetOwner()->m_headerArea->ScrollWindow( dx, 0 );
} }
void wxDataViewMainWindow::ScrollTo( int rows )
{
int x, y;
m_owner->GetScrollPixelsPerUnit( &x, &y );
int sc = rows*m_lineHeight/y;
m_owner->Scroll(0, sc );
}
void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
{ {
wxDataViewModel *model = GetOwner()->GetModel(); wxDataViewModel *model = GetOwner()->GetModel();
@@ -2615,8 +2645,18 @@ public:
return DoJob::IGR; return DoJob::IGR;
} }
else else
{
//If the current has no child node, we can find the desired item of the row number directly.
//This if can speed up finding in some case, and will has a very good effect when it comes to list view
if( node->GetNodes().GetCount() == 0)
{
int index = static_cast<int>(row) - current - 1;
ret = node->GetChildren().Item( index );
return DoJob::OK;
}
return DoJob::CONT; return DoJob::CONT;
} }
}
virtual int operator() ( void * n ) virtual int operator() ( void * n )
{ {
@@ -2637,7 +2677,7 @@ private:
wxDataViewItem wxDataViewMainWindow::GetItemByRow(unsigned int row) wxDataViewItem wxDataViewMainWindow::GetItemByRow(unsigned int row)
{ {
RowToItemJob job( row, -1 ); RowToItemJob job( row, -2 );
Walker( m_root , job ); Walker( m_root , job );
return job.GetResult(); return job.GetResult();
} }
@@ -2671,9 +2711,21 @@ public:
else else
{ {
parent = node; parent = node;
//If the current has no child node, we can find the desired item of the row number directly.
//This if can speed up finding in some case, and will has a very good effect when it comes to list view
if( node->GetNodes().GetCount() == 0)
{
int index = static_cast<int>(row) - current - 1;
void * n = node->GetChildren().Item( index );
ret = new wxDataViewTreeNode( parent ) ;
ret->SetItem( wxDataViewItem( n ));
ret->SetHasChildren(false);
return DoJob::OK;
}
return DoJob::CONT; return DoJob::CONT;
} }
} }
virtual int operator() ( void * n ) virtual int operator() ( void * n )
@@ -2700,36 +2752,11 @@ private:
wxDataViewTreeNode * wxDataViewMainWindow::GetTreeNodeByRow(unsigned int row) wxDataViewTreeNode * wxDataViewMainWindow::GetTreeNodeByRow(unsigned int row)
{ {
RowToTreeNodeJob job( row , -1, m_root ); RowToTreeNodeJob job( row , -2, m_root );
Walker( m_root , job ); Walker( m_root , job );
return job.GetResult(); return job.GetResult();
} }
#if 0
class CountJob : public DoJob
{
public:
CountJob(){ count = 0 ; }
virtual ~CountJob(){};
virtual int operator () ( wxDataViewTreeNode * node )
{
count ++;
if ( node->IsOpen())
return DoJob::CONT;
else
return DoJob::IGR;
}
unsigned int GetResult()
{
return count ;
}
private:
unsigned int count;
};
#endif
void wxDataViewMainWindow::OnExpanding( unsigned int row ) void wxDataViewMainWindow::OnExpanding( unsigned int row )
{ {
wxDataViewTreeNode * node = GetTreeNodeByRow(row); wxDataViewTreeNode * node = GetTreeNodeByRow(row);
@@ -2776,11 +2803,14 @@ void wxDataViewMainWindow::OnCollapsing(unsigned int row)
if( node != NULL ) if( node != NULL )
{ {
int parent = GetRowByItem( node->GetItem() ) ; int parent = GetRowByItem( node->GetItem() ) ;
if( parent >= 0 )
{
SelectRow( row, false); SelectRow( row, false);
SelectRow(parent , true ); SelectRow(parent , true );
ChangeCurrentRow( parent ); ChangeCurrentRow( parent );
} }
} }
}
if( !nd->HasChildren()) if( !nd->HasChildren())
delete nd; delete nd;
} }
@@ -2805,7 +2835,6 @@ wxDataViewTreeNode * wxDataViewMainWindow::FindNode( const wxDataViewItem & item
//Find the item along the parent-chain. //Find the item along the parent-chain.
//This algorithm is designed to speed up the node-finding method //This algorithm is designed to speed up the node-finding method
bool found = true;
wxDataViewTreeNode * node = m_root; wxDataViewTreeNode * node = m_root;
for( ItemList::Node * n = list.GetFirst(); n; n = n->GetNext() ) for( ItemList::Node * n = list.GetFirst(); n; n = n->GetNext() )
{ {
@@ -2814,23 +2843,14 @@ 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->GetNodeNumber();
wxDataViewTreeNodes nodes = node->GetNodes(); wxDataViewTreeNodes nodes = node->GetNodes();
int j = 0; //The wxSortedArray search a node in binary search, so using Item() is more efficient
for( ; j < len; j ++) wxDataViewTreeNode temp;
{ temp.SetItem(*(n->GetData()));
if( nodes[j]->GetItem() == *(n->GetData())) int index = nodes.Index( &temp );
{ if( index == wxNOT_FOUND )
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; return NULL;
} node = nodes[index];
} }
else else
return NULL; return NULL;
@@ -2847,9 +2867,10 @@ class ItemToRowJob : public DoJob
{ {
public: public:
ItemToRowJob(const wxDataViewItem & item, ItemList::Node * node ) ItemToRowJob(const wxDataViewItem & item, ItemList::Node * node )
{ this->item = item ; ret = 0 ; nd = node ; } { this->item = item ; ret = -1 ; nd = node ; }
virtual ~ItemToRowJob(){}; virtual ~ItemToRowJob(){};
//Maybe binary search will help to speed up this process
virtual int operator() ( wxDataViewTreeNode * node) virtual int operator() ( wxDataViewTreeNode * node)
{ {
ret ++; ret ++;
@@ -2887,22 +2908,28 @@ private:
}; };
unsigned int wxDataViewMainWindow::GetRowByItem(const wxDataViewItem & item) int wxDataViewMainWindow::GetRowByItem(const wxDataViewItem & item)
{ {
wxDataViewModel * model = GetOwner()->GetModel(); wxDataViewModel * model = GetOwner()->GetModel();
if( model == NULL ) if( model == NULL )
return 0; return 0;
if( !item.IsOk() )
return -1;
//Compose the a parent-chain of the finding item //Compose the a parent-chain of the finding item
ItemList list; ItemList list;
wxDataViewItem * pItem = NULL;
list.DeleteContents( true ); list.DeleteContents( true );
wxDataViewItem it( item ); wxDataViewItem it( item );
while( it.IsOk() ) while( it.IsOk() )
{ {
wxDataViewItem * pItem = new wxDataViewItem( it ); pItem = new wxDataViewItem( it );
list.Insert( pItem ); list.Insert( pItem );
it = model->GetParent( it ); it = model->GetParent( it );
} }
pItem = new wxDataViewItem( );
list.Insert( pItem );
ItemToRowJob job( item, list.GetFirst() ); ItemToRowJob job( item, list.GetFirst() );
Walker(m_root , job ); Walker(m_root , job );
@@ -3142,6 +3169,16 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
wxRect cell_rect( xpos, current * m_lineHeight, wxRect cell_rect( xpos, current * m_lineHeight,
col->GetWidth(), m_lineHeight ); col->GetWidth(), m_lineHeight );
cell->Activate( cell_rect, model, item, col->GetModelColumn() ); cell->Activate( cell_rect, model, item, col->GetModelColumn() );
wxWindow *parent = GetParent();
wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, parent->GetId());
le.SetEventObject(parent);
le.SetColumn(col->GetModelColumn());
le.SetDataViewColumn(col);
le.SetModel(GetOwner()->GetModel());
parent->GetEventHandler()->ProcessEvent(le);
} }
return; return;
} }
@@ -3456,53 +3493,152 @@ void wxDataViewCtrl::DoSetIndent()
m_clientArea->UpdateDisplay(); m_clientArea->UpdateDisplay();
} }
wxDataViewItem wxDataViewCtrl::GetSelection() //Selection code with wxDataViewItem as parameters
int wxDataViewCtrl::GetSelections( wxDataViewItemArray & sel ) const
{ {
return m_clientArea->GetSelection(); sel.Empty();
wxDataViewSelection selection = m_clientArea->GetSelections();
int len = selection.GetCount();
for( int i = 0; i < len; i ++)
{
unsigned int row = selection[i];
sel.Add( m_clientArea->GetItemByRow( row ) );
}
return len;
} }
/******************************************************************** void wxDataViewCtrl::SetSelections( const wxDataViewItemArray & sel )
void wxDataViewCtrl::SetSelection( int row )
{ {
wxDataViewSelection selection(wxDataViewSelectionCmp) ;
int len = sel.GetCount();
for( int i = 0; i < len; i ++ )
{
int row = m_clientArea->GetRowByItem( sel[i] );
if( row >= 0 )
selection.Add( static_cast<unsigned int>(row) );
}
m_clientArea->SetSelections( selection );
}
void wxDataViewCtrl::Select( const wxDataViewItem & item )
{
int row = m_clientArea->GetRowByItem( item );
if( row >= 0 )
m_clientArea->SelectRow(row, true); m_clientArea->SelectRow(row, true);
} }
void wxDataViewCtrl::SetSelectionRange( unsigned int from, unsigned int to ) void wxDataViewCtrl::Unselect( const wxDataViewItem & item )
{ {
m_clientArea->SelectRows(from, to, true); int row = m_clientArea->GetRowByItem( item );
if( row >= 0 )
m_clientArea->SelectRow(row, false);
} }
void wxDataViewCtrl::SetSelections( const wxArrayInt& aSelections ) bool wxDataViewCtrl::IsSelected( const wxDataViewItem & item ) const
{ {
m_clientArea->Select(aSelections); int row = m_clientArea->GetRowByItem( item );
if( row >= 0 )
{
return m_clientArea->IsRowSelected(row);
} }
void wxDataViewCtrl::Unselect( unsigned int WXUNUSED(row) )
{
// FIXME - TODO
}
bool wxDataViewCtrl::IsSelected( unsigned int WXUNUSED(row) ) const
{
// FIXME - TODO
return false; return false;
} }
int wxDataViewCtrl::GetSelection() const //Selection code with row number as parameter
int wxDataViewCtrl::GetSelections( wxArrayInt & sel ) const
{ {
// FIXME - TODO sel.Empty();
wxDataViewSelection selection = m_clientArea->GetSelections();
return -1; int len = selection.GetCount();
for( int i = 0; i < len; i ++)
{
unsigned int row = selection[i];
sel.Add( row );
}
return len;
} }
int wxDataViewCtrl::GetSelections(wxArrayInt& WXUNUSED(aSelections) ) const void wxDataViewCtrl::SetSelections( const wxArrayInt & sel )
{ {
// FIXME - TODO wxDataViewSelection selection(wxDataViewSelectionCmp) ;
int len = sel.GetCount();
return 0; for( int i = 0; i < len; i ++ )
{
int row = sel[i];
if( row >= 0 )
selection.Add( static_cast<unsigned int>(row) );
} }
*********************************************************************/ m_clientArea->SetSelections( selection );
}
void wxDataViewCtrl::Select( int row )
{
if( row >= 0 )
m_clientArea->SelectRow( row, true );
}
void wxDataViewCtrl::Unselect( int row )
{
if( row >= 0 )
m_clientArea->SelectRow(row, false);
}
bool wxDataViewCtrl::IsSelected( int row ) const
{
if( row >= 0 )
return m_clientArea->IsRowSelected(row);
return false;
}
void wxDataViewCtrl::SelectRange( int from, int to )
{
wxArrayInt sel;
for( int i = from; i < to; i ++ )
sel.Add( i );
m_clientArea->Select(sel);
}
void wxDataViewCtrl::UnselectRange( int from, int to )
{
wxDataViewSelection sel = m_clientArea->GetSelections();
for( int i = from; i < to; i ++ )
if( sel.Index( i ) != wxNOT_FOUND )
sel.Remove( i );
m_clientArea->SetSelections(sel);
}
void wxDataViewCtrl::SelectAll()
{
m_clientArea->SelectAllRows(true);
}
void wxDataViewCtrl::UnselectAll()
{
m_clientArea->SelectAllRows(false);
}
void wxDataViewCtrl::EnsureVisible( int row )
{
m_clientArea->ScrollTo( row );
}
void wxDataViewCtrl::EnsureVisible( const wxDataViewItem & item )
{
int row = m_clientArea->GetRowByItem(item);
if( row >= 0 )
EnsureVisible(row);
}
wxDataViewItem wxDataViewCtrl::GetItemByRow( unsigned int row ) const
{
return m_clientArea->GetItemByRow( row );
}
int wxDataViewCtrl::GetRowByItem( const wxDataViewItem & item ) const
{
return m_clientArea->GetRowByItem( item );
}
#endif #endif
// !wxUSE_GENERICDATAVIEWCTRL // !wxUSE_GENERICDATAVIEWCTRL