-/////////////////////////////////////////////////////////////////////////////\r
-// Name: mymodels.cpp\r
-// Purpose: wxDataViewCtrl wxWidgets sample\r
-// Author: Robert Roebling\r
-// Modified by: Francesco Montorsi, Bo Yang\r
-// Created: 06/01/06\r
-// RCS-ID: $Id$\r
-// Copyright: (c) Robert Roebling\r
-// Licence: wxWindows license\r
-/////////////////////////////////////////////////////////////////////////////\r
-\r
-\r
-// For compilers that support precompilation, includes "wx/wx.h".\r
-#include "wx/wxprec.h"\r
-\r
-#ifdef __BORLANDC__\r
-#pragma hdrstop\r
-#endif\r
-\r
-#ifndef WX_PRECOMP\r
- #include "wx/wx.h"\r
-#endif\r
-\r
-#include "wx/dataview.h"\r
-#include "mymodels.h"\r
-\r
-// ----------------------------------------------------------------------------\r
-// resources\r
-// ----------------------------------------------------------------------------\r
-\r
-#include "null.xpm"\r
-#include "wx_small.xpm"\r
-\r
-\r
-// ----------------------------------------------------------------------------\r
-// MyMusicTreeModel\r
-// ----------------------------------------------------------------------------\r
-\r
-MyMusicTreeModel::MyMusicTreeModel()\r
-{\r
- m_root = new MyMusicTreeModelNode( NULL, wxT("My Music" ));\r
-\r
- // setup pop music\r
- m_pop = new MyMusicTreeModelNode( m_root, wxT("Pop music") );\r
- m_pop->Append(\r
- new MyMusicTreeModelNode( m_pop, wxT("You are not alone"), wxT("Michael Jackson"), 1995 ) );\r
- m_pop->Append(\r
- new MyMusicTreeModelNode( m_pop, wxT("Take a bow"), wxT("Madonna"), 1994 ) );\r
- m_root->Append( m_pop );\r
-\r
- // setup classical music\r
- m_classical = new MyMusicTreeModelNode( m_root, wxT("Classical music") );\r
- m_ninth = new MyMusicTreeModelNode( m_classical, wxT("Ninth symphony"),\r
- wxT("Ludwig van Beethoven"), 1824 );\r
- m_classical->Append( m_ninth );\r
- m_classical->Append( new MyMusicTreeModelNode( m_classical, wxT("German Requiem"),\r
- wxT("Johannes Brahms"), 1868 ) );\r
- m_root->Append( m_classical );\r
-\r
- m_classicalMusicIsKnownToControl = false;\r
-}\r
-\r
-wxString MyMusicTreeModel::GetTitle( const wxDataViewItem &item ) const\r
-{\r
- MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();\r
- if (!node) // happens if item.IsOk()==false\r
- return wxEmptyString;\r
-\r
- return node->m_title;\r
-}\r
-\r
-int MyMusicTreeModel::GetYear( const wxDataViewItem &item ) const\r
-{\r
- MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();\r
- if (!node) // happens if item.IsOk()==false\r
- return 2000;\r
-\r
- return node->m_year;\r
-}\r
-\r
-void MyMusicTreeModel::AddToClassical( const wxString &title, const wxString &artist,\r
- unsigned int year )\r
-{\r
- if (!m_classical)\r
- {\r
- wxASSERT(m_root);\r
-\r
- // it was removed: restore it\r
- m_classical = new MyMusicTreeModelNode( m_root, wxT("Classical music") );\r
- m_root->Append( m_classical );\r
- }\r
-\r
- // add to the classical music node a new node:\r
- MyMusicTreeModelNode *child_node =\r
- new MyMusicTreeModelNode( m_classical, title, artist, year );\r
- m_classical->Append( child_node );\r
-\r
- if (m_classicalMusicIsKnownToControl)\r
- {\r
- // notify control\r
- wxDataViewItem child( (void*) child_node );\r
- wxDataViewItem parent( (void*) m_classical );\r
- ItemAdded( parent, child );\r
- }\r
-}\r
-\r
-void MyMusicTreeModel::Delete( const wxDataViewItem &item )\r
-{\r
- MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();\r
- if (!node) // happens if item.IsOk()==false\r
- return;\r
-\r
- wxDataViewItem parent( node->GetParent() );\r
- if (!parent.IsOk())\r
- {\r
- wxASSERT(node == m_root);\r
-\r
- // don't make the control completely empty:\r
- wxLogError("Cannot remove the root item!");\r
- return;\r
- }\r
-\r
- // is the node one of those we keep stored in special pointers?\r
- if (node == m_pop)\r
- m_pop = NULL;\r
- else if (node == m_classical)\r
- m_classical = NULL;\r
- else if (node == m_ninth)\r
- m_ninth = NULL;\r
-\r
- // first remove the node from the parent's array of children;\r
- // NOTE: MyMusicTreeModelNodePtrArray is only an array of _pointers_\r
- // thus removing the node from it doesn't result in freeing it\r
- node->GetParent()->GetChildren().Remove( node );\r
-\r
- // free the node\r
- delete node;\r
-\r
- // notify control\r
- ItemDeleted( parent, item );\r
-}\r
-\r
-int MyMusicTreeModel::Compare( const wxDataViewItem &item1, const wxDataViewItem &item2,\r
- unsigned int column, bool ascending )\r
-{\r
- wxASSERT(item1.IsOk() && item2.IsOk());\r
- // should never happen\r
-\r
- if (IsContainer(item1) && IsContainer(item2))\r
- {\r
- wxVariant value1, value2;\r
- GetValue( value1, item1, 0 );\r
- GetValue( value2, item2, 0 );\r
-\r
- wxString str1 = value1.GetString();\r
- wxString str2 = value2.GetString();\r
- int res = str1.Cmp( str2 );\r
- if (res) return res;\r
-\r
- // items must be different\r
- wxUIntPtr litem1 = (wxUIntPtr) item1.GetID();\r
- wxUIntPtr litem2 = (wxUIntPtr) item2.GetID();\r
-\r
- return litem1-litem2;\r
- }\r
-\r
- return wxDataViewModel::Compare( item1, item2, column, ascending );\r
-}\r
-\r
-void MyMusicTreeModel::GetValue( wxVariant &variant,\r
- const wxDataViewItem &item, unsigned int col ) const\r
-{\r
- wxASSERT(item.IsOk());\r
-\r
- MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();\r
- switch (col)\r
- {\r
- case 0:\r
- variant = node->m_title;\r
- break;\r
- case 1:\r
- variant = node->m_artist;\r
- break;\r
- case 2:\r
- variant = (long) node->m_year;\r
- break;\r
- case 3:\r
- variant = node->m_quality;\r
- break;\r
- case 4:\r
- // wxMac doesn't conceal the popularity progress renderer, return 0 for containers\r
- if (IsContainer(item))\r
- variant = (long) 0;\r
- else\r
- variant = (long) 80; // all music is very 80% popular\r
- break;\r
- case 5:\r
- // Make size of red square depend on year\r
- if (GetYear(item) < 1900)\r
- variant = (long) 35;\r
- else\r
- variant = (long) 25;\r
- break;\r
-\r
- default:\r
- wxLogError( wxT("MyMusicTreeModel::GetValue: wrong column %d"), col );\r
- }\r
-}\r
-\r
-bool MyMusicTreeModel::SetValue( const wxVariant &variant,\r
- const wxDataViewItem &item, unsigned int col )\r
-{\r
- wxASSERT(item.IsOk());\r
-\r
- MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();\r
- switch (col)\r
- {\r
- case 0:\r
- node->m_title = variant.GetString();\r
- return true;\r
- case 1:\r
- node->m_artist = variant.GetString();\r
- return true;\r
- case 2:\r
- node->m_year = variant.GetLong();\r
- return true;\r
- case 3:\r
- node->m_quality = variant.GetString();\r
- return true;\r
-\r
- default:\r
- wxLogError( wxT("MyMusicTreeModel::SetValue: wrong column") );\r
- }\r
- return false;\r
-}\r
-\r
-wxDataViewItem MyMusicTreeModel::GetParent( const wxDataViewItem &item ) const\r
-{\r
- // the invisible root node has no parent\r
- if (!item.IsOk())\r
- return wxDataViewItem(0);\r
-\r
- MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();\r
-\r
- // "MyMusic" also has no parent\r
- if (node == m_root)\r
- return wxDataViewItem(0);\r
-\r
- return wxDataViewItem( (void*) node->GetParent() );\r
-}\r
-\r
-bool MyMusicTreeModel::IsContainer( const wxDataViewItem &item ) const\r
-{\r
- // the invisble root node can have children\r
- // (in our model always "MyMusic")\r
- if (!item.IsOk())\r
- return true;\r
-\r
- MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();\r
- return node->IsContainer();\r
-}\r
-\r
-unsigned int MyMusicTreeModel::GetChildren( const wxDataViewItem &parent,\r
- wxDataViewItemArray &array ) const\r
-{\r
- MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) parent.GetID();\r
- if (!node)\r
- {\r
- array.Add( wxDataViewItem( (void*) m_root ) );\r
- return 1;\r
- }\r
-\r
- if (node == m_classical)\r
- {\r
- MyMusicTreeModel *model = (MyMusicTreeModel*)(const MyMusicTreeModel*) this;\r
- model->m_classicalMusicIsKnownToControl = true;\r
- }\r
-\r
- if (node->GetChildCount() == 0)\r
- {\r
- return 0;\r
- }\r
-\r
- unsigned int count = node->GetChildren().GetCount();\r
- for (unsigned int pos = 0; pos < count; pos++)\r
- {\r
- MyMusicTreeModelNode *child = node->GetChildren().Item( pos );\r
- array.Add( wxDataViewItem( (void*) child ) );\r
- }\r
-\r
- return count;\r
-}\r
-\r
-\r
-\r
-// ----------------------------------------------------------------------------\r
-// MyListModel\r
-// ----------------------------------------------------------------------------\r
-\r
-static int my_sort_reverse( int *v1, int *v2 )\r
-{\r
- return *v2-*v1;\r
-}\r
-\r
-static int my_sort( int *v1, int *v2 )\r
-{\r
- return *v1-*v2;\r
-}\r
-\r
-#ifdef __WXMAC__\r
- #define INITIAL_NUMBER_OF_ITEMS 100\r
-#else\r
- #define INITIAL_NUMBER_OF_ITEMS 100000\r
-#endif\r
-\r
-MyListModel::MyListModel() :\r
- wxDataViewVirtualListModel( INITIAL_NUMBER_OF_ITEMS )\r
-{\r
- m_virtualItems = INITIAL_NUMBER_OF_ITEMS;\r
-\r
- // the first 100 items are really stored in this model;\r
- // all the others are synthetized on request\r
- for (unsigned int i = 0; i < 100; i++)\r
- {\r
- wxString str;\r
- str.Printf( wxT("real row %d"), i );\r
- m_array.Add( str );\r
- }\r
-\r
- m_icon[0] = wxIcon( null_xpm );\r
- m_icon[1] = wxIcon( wx_small_xpm );\r
-}\r
-\r
-void MyListModel::Prepend( const wxString &text )\r
-{\r
- m_array.Insert( text, 0 );\r
- RowPrepended();\r
-}\r
-\r
-void MyListModel::DeleteItem( const wxDataViewItem &item )\r
-{\r
- unsigned int row = GetRow( item );\r
- if (row >= m_array.GetCount())\r
- return;\r
-\r
- m_array.RemoveAt( row );\r
- RowDeleted( row );\r
-}\r
-\r
-void MyListModel::DeleteItems( const wxDataViewItemArray &items )\r
-{\r
- unsigned i;\r
- wxArrayInt rows;\r
- for (int i = 0; i < items.GetCount(); i++)\r
- {\r
- unsigned int row = GetRow( items[i] );\r
- if (row < m_array.GetCount())\r
- rows.Add( row );\r
- }\r
-\r
- if (rows.GetCount() == 0)\r
- {\r
- // none of the selected items were in the range of the items\r
- // which we store... for simplicity, don't allow removing them\r
- wxLogError("Cannot remove rows with an index greater than %d", m_array.GetCount());\r
- return;\r
- }\r
-\r
- // Sort in descending order so that the last\r
- // row will be deleted first. Otherwise the\r
- // remaining indeces would all be wrong.\r
- rows.Sort( my_sort_reverse );\r
- for (i = 0; i < rows.GetCount(); i++)\r
- m_array.RemoveAt( rows[i] );\r
-\r
- // This is just to test if wxDataViewCtrl can\r
- // cope with removing rows not sorted in\r
- // descending order\r
- rows.Sort( my_sort );\r
- RowsDeleted( rows );\r
-}\r
-\r
-void MyListModel::AddMany()\r
-{\r
- m_virtualItems += 1000;\r
- Reset( m_array.GetCount() + m_virtualItems );\r
-}\r
-\r
-void MyListModel::GetValueByRow( wxVariant &variant,\r
- unsigned int row, unsigned int col ) const\r
-{\r
- if (col==0)\r
- {\r
- if (row >= m_array.GetCount())\r
- variant = wxString::Format( wxT("virtual row %d"), row );\r
- else\r
- variant = m_array[ row ];\r
- }\r
- else if (col==1)\r
- {\r
- wxDataViewIconText data( wxT("test"), m_icon[ row%2 ] );\r
- variant << data;\r
- }\r
- else if (col==2)\r
- {\r
- if (row >= m_array.GetCount())\r
- variant = wxT("plain");\r
- else\r
- variant = wxT("blue/green/red");\r
- }\r
-}\r
-\r
-bool MyListModel::GetAttrByRow( unsigned int row, unsigned int col,\r
- wxDataViewItemAttr &attr )\r
-{\r
- if (col != 2)\r
- return false;\r
-\r
- if (row < m_array.GetCount())\r
- {\r
- attr.SetColour( (row%2) == 0 ? *wxBLUE :\r
- ((row%3) == 0 ? *wxGREEN : *wxRED) );\r
- attr.SetItalic( (row%2) == 5 );\r
- }\r
-\r
- return true;\r
-}\r
-\r
-bool MyListModel::SetValueByRow( const wxVariant &variant,\r
- unsigned int row, unsigned int col )\r
-{\r
- if (col == 0)\r
- {\r
- if (row >= m_array.GetCount())\r
- {\r
- // the item is not in the range of the items\r
- // which we store... for simplicity, don't allow editing it\r
- wxLogError("Cannot edit rows with an index greater than %d", m_array.GetCount());\r
- return false;\r
- }\r
-\r
- m_array[row] = variant.GetString();\r
- return true;\r
- }\r
-\r
- return false;\r
-}\r
+/////////////////////////////////////////////////////////////////////////////
+// Name: mymodels.cpp
+// Purpose: wxDataViewCtrl wxWidgets sample
+// Author: Robert Roebling
+// Modified by: Francesco Montorsi, Bo Yang
+// Created: 06/01/06
+// RCS-ID: $Id$
+// Copyright: (c) Robert Roebling
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/wx.h"
+#endif
+
+#include "wx/dataview.h"
+#include "mymodels.h"
+
+// ----------------------------------------------------------------------------
+// resources
+// ----------------------------------------------------------------------------
+
+#include "null.xpm"
+#include "wx_small.xpm"
+
+
+// ----------------------------------------------------------------------------
+// MyMusicTreeModel
+// ----------------------------------------------------------------------------
+
+MyMusicTreeModel::MyMusicTreeModel()
+{
+ m_root = new MyMusicTreeModelNode( NULL, wxT("My Music" ));
+
+ // setup pop music
+ m_pop = new MyMusicTreeModelNode( m_root, wxT("Pop music") );
+ m_pop->Append(
+ new MyMusicTreeModelNode( m_pop, wxT("You are not alone"), wxT("Michael Jackson"), 1995 ) );
+ m_pop->Append(
+ new MyMusicTreeModelNode( m_pop, wxT("Take a bow"), wxT("Madonna"), 1994 ) );
+ m_root->Append( m_pop );
+
+ // setup classical music
+ m_classical = new MyMusicTreeModelNode( m_root, wxT("Classical music") );
+ m_ninth = new MyMusicTreeModelNode( m_classical, wxT("Ninth symphony"),
+ wxT("Ludwig van Beethoven"), 1824 );
+ m_classical->Append( m_ninth );
+ m_classical->Append( new MyMusicTreeModelNode( m_classical, wxT("German Requiem"),
+ wxT("Johannes Brahms"), 1868 ) );
+ m_root->Append( m_classical );
+
+ m_classicalMusicIsKnownToControl = false;
+}
+
+wxString MyMusicTreeModel::GetTitle( const wxDataViewItem &item ) const
+{
+ MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();
+ if (!node) // happens if item.IsOk()==false
+ return wxEmptyString;
+
+ return node->m_title;
+}
+
+int MyMusicTreeModel::GetYear( const wxDataViewItem &item ) const
+{
+ MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();
+ if (!node) // happens if item.IsOk()==false
+ return 2000;
+
+ return node->m_year;
+}
+
+void MyMusicTreeModel::AddToClassical( const wxString &title, const wxString &artist,
+ unsigned int year )
+{
+ if (!m_classical)
+ {
+ wxASSERT(m_root);
+
+ // it was removed: restore it
+ m_classical = new MyMusicTreeModelNode( m_root, wxT("Classical music") );
+ m_root->Append( m_classical );
+ }
+
+ // add to the classical music node a new node:
+ MyMusicTreeModelNode *child_node =
+ new MyMusicTreeModelNode( m_classical, title, artist, year );
+ m_classical->Append( child_node );
+
+ if (m_classicalMusicIsKnownToControl)
+ {
+ // notify control
+ wxDataViewItem child( (void*) child_node );
+ wxDataViewItem parent( (void*) m_classical );
+ ItemAdded( parent, child );
+ }
+}
+
+void MyMusicTreeModel::Delete( const wxDataViewItem &item )
+{
+ MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();
+ if (!node) // happens if item.IsOk()==false
+ return;
+
+ wxDataViewItem parent( node->GetParent() );
+ if (!parent.IsOk())
+ {
+ wxASSERT(node == m_root);
+
+ // don't make the control completely empty:
+ wxLogError("Cannot remove the root item!");
+ return;
+ }
+
+ // is the node one of those we keep stored in special pointers?
+ if (node == m_pop)
+ m_pop = NULL;
+ else if (node == m_classical)
+ m_classical = NULL;
+ else if (node == m_ninth)
+ m_ninth = NULL;
+
+ // first remove the node from the parent's array of children;
+ // NOTE: MyMusicTreeModelNodePtrArray is only an array of _pointers_
+ // thus removing the node from it doesn't result in freeing it
+ node->GetParent()->GetChildren().Remove( node );
+
+ // free the node
+ delete node;
+
+ // notify control
+ ItemDeleted( parent, item );
+}
+
+int MyMusicTreeModel::Compare( const wxDataViewItem &item1, const wxDataViewItem &item2,
+ unsigned int column, bool ascending )
+{
+ wxASSERT(item1.IsOk() && item2.IsOk());
+ // should never happen
+
+ if (IsContainer(item1) && IsContainer(item2))
+ {
+ wxVariant value1, value2;
+ GetValue( value1, item1, 0 );
+ GetValue( value2, item2, 0 );
+
+ wxString str1 = value1.GetString();
+ wxString str2 = value2.GetString();
+ int res = str1.Cmp( str2 );
+ if (res) return res;
+
+ // items must be different
+ wxUIntPtr litem1 = (wxUIntPtr) item1.GetID();
+ wxUIntPtr litem2 = (wxUIntPtr) item2.GetID();
+
+ return litem1-litem2;
+ }
+
+ return wxDataViewModel::Compare( item1, item2, column, ascending );
+}
+
+void MyMusicTreeModel::GetValue( wxVariant &variant,
+ const wxDataViewItem &item, unsigned int col ) const
+{
+ wxASSERT(item.IsOk());
+
+ MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();
+ switch (col)
+ {
+ case 0:
+ variant = node->m_title;
+ break;
+ case 1:
+ variant = node->m_artist;
+ break;
+ case 2:
+ variant = (long) node->m_year;
+ break;
+ case 3:
+ variant = node->m_quality;
+ break;
+ case 4:
+ // wxMac doesn't conceal the popularity progress renderer, return 0 for containers
+ if (IsContainer(item))
+ variant = (long) 0;
+ else
+ variant = (long) 80; // all music is very 80% popular
+ break;
+ case 5:
+ // Make size of red square depend on year
+ if (GetYear(item) < 1900)
+ variant = (long) 35;
+ else
+ variant = (long) 25;
+ break;
+
+ default:
+ wxLogError( wxT("MyMusicTreeModel::GetValue: wrong column %d"), col );
+ }
+}
+
+bool MyMusicTreeModel::SetValue( const wxVariant &variant,
+ const wxDataViewItem &item, unsigned int col )
+{
+ wxASSERT(item.IsOk());
+
+ MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();
+ switch (col)
+ {
+ case 0:
+ node->m_title = variant.GetString();
+ return true;
+ case 1:
+ node->m_artist = variant.GetString();
+ return true;
+ case 2:
+ node->m_year = variant.GetLong();
+ return true;
+ case 3:
+ node->m_quality = variant.GetString();
+ return true;
+
+ default:
+ wxLogError( wxT("MyMusicTreeModel::SetValue: wrong column") );
+ }
+ return false;
+}
+
+wxDataViewItem MyMusicTreeModel::GetParent( const wxDataViewItem &item ) const
+{
+ // the invisible root node has no parent
+ if (!item.IsOk())
+ return wxDataViewItem(0);
+
+ MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();
+
+ // "MyMusic" also has no parent
+ if (node == m_root)
+ return wxDataViewItem(0);
+
+ return wxDataViewItem( (void*) node->GetParent() );
+}
+
+bool MyMusicTreeModel::IsContainer( const wxDataViewItem &item ) const
+{
+ // the invisble root node can have children
+ // (in our model always "MyMusic")
+ if (!item.IsOk())
+ return true;
+
+ MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();
+ return node->IsContainer();
+}
+
+unsigned int MyMusicTreeModel::GetChildren( const wxDataViewItem &parent,
+ wxDataViewItemArray &array ) const
+{
+ MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) parent.GetID();
+ if (!node)
+ {
+ array.Add( wxDataViewItem( (void*) m_root ) );
+ return 1;
+ }
+
+ if (node == m_classical)
+ {
+ MyMusicTreeModel *model = (MyMusicTreeModel*)(const MyMusicTreeModel*) this;
+ model->m_classicalMusicIsKnownToControl = true;
+ }
+
+ if (node->GetChildCount() == 0)
+ {
+ return 0;
+ }
+
+ unsigned int count = node->GetChildren().GetCount();
+ for (unsigned int pos = 0; pos < count; pos++)
+ {
+ MyMusicTreeModelNode *child = node->GetChildren().Item( pos );
+ array.Add( wxDataViewItem( (void*) child ) );
+ }
+
+ return count;
+}
+
+
+
+// ----------------------------------------------------------------------------
+// MyListModel
+// ----------------------------------------------------------------------------
+
+static int my_sort_reverse( int *v1, int *v2 )
+{
+ return *v2-*v1;
+}
+
+static int my_sort( int *v1, int *v2 )
+{
+ return *v1-*v2;
+}
+
+#ifdef __WXMAC__
+ #define INITIAL_NUMBER_OF_ITEMS 100
+#else
+ #define INITIAL_NUMBER_OF_ITEMS 100000
+#endif
+
+MyListModel::MyListModel() :
+ wxDataViewVirtualListModel( INITIAL_NUMBER_OF_ITEMS )
+{
+ m_virtualItems = INITIAL_NUMBER_OF_ITEMS;
+
+ // the first 100 items are really stored in this model;
+ // all the others are synthetized on request
+ for (unsigned int i = 0; i < 100; i++)
+ {
+ wxString str;
+ str.Printf( wxT("real row %d"), i );
+ m_array.Add( str );
+ }
+
+ m_icon[0] = wxIcon( null_xpm );
+ m_icon[1] = wxIcon( wx_small_xpm );
+}
+
+void MyListModel::Prepend( const wxString &text )
+{
+ m_array.Insert( text, 0 );
+ RowPrepended();
+}
+
+void MyListModel::DeleteItem( const wxDataViewItem &item )
+{
+ unsigned int row = GetRow( item );
+ if (row >= m_array.GetCount())
+ return;
+
+ m_array.RemoveAt( row );
+ RowDeleted( row );
+}
+
+void MyListModel::DeleteItems( const wxDataViewItemArray &items )
+{
+ unsigned i;
+ wxArrayInt rows;
+ for (int i = 0; i < items.GetCount(); i++)
+ {
+ unsigned int row = GetRow( items[i] );
+ if (row < m_array.GetCount())
+ rows.Add( row );
+ }
+
+ if (rows.GetCount() == 0)
+ {
+ // none of the selected items were in the range of the items
+ // which we store... for simplicity, don't allow removing them
+ wxLogError("Cannot remove rows with an index greater than %d", m_array.GetCount());
+ return;
+ }
+
+ // Sort in descending order so that the last
+ // row will be deleted first. Otherwise the
+ // remaining indeces would all be wrong.
+ rows.Sort( my_sort_reverse );
+ for (i = 0; i < rows.GetCount(); i++)
+ m_array.RemoveAt( rows[i] );
+
+ // This is just to test if wxDataViewCtrl can
+ // cope with removing rows not sorted in
+ // descending order
+ rows.Sort( my_sort );
+ RowsDeleted( rows );
+}
+
+void MyListModel::AddMany()
+{
+ m_virtualItems += 1000;
+ Reset( m_array.GetCount() + m_virtualItems );
+}
+
+void MyListModel::GetValueByRow( wxVariant &variant,
+ unsigned int row, unsigned int col ) const
+{
+ if (col==0)
+ {
+ if (row >= m_array.GetCount())
+ variant = wxString::Format( wxT("virtual row %d"), row );
+ else
+ variant = m_array[ row ];
+ }
+ else if (col==1)
+ {
+ wxDataViewIconText data( wxT("test"), m_icon[ row%2 ] );
+ variant << data;
+ }
+ else if (col==2)
+ {
+ if (row >= m_array.GetCount())
+ variant = wxT("plain");
+ else
+ variant = wxT("blue/green/red");
+ }
+}
+
+bool MyListModel::GetAttrByRow( unsigned int row, unsigned int col,
+ wxDataViewItemAttr &attr )
+{
+ if (col != 2)
+ return false;
+
+ if (row < m_array.GetCount())
+ {
+ attr.SetColour( (row%2) == 0 ? *wxBLUE :
+ ((row%3) == 0 ? *wxGREEN : *wxRED) );
+ attr.SetItalic( (row%2) == 5 );
+ }
+
+ return true;
+}
+
+bool MyListModel::SetValueByRow( const wxVariant &variant,
+ unsigned int row, unsigned int col )
+{
+ if (col == 0)
+ {
+ if (row >= m_array.GetCount())
+ {
+ // the item is not in the range of the items
+ // which we store... for simplicity, don't allow editing it
+ wxLogError("Cannot edit rows with an index greater than %d", m_array.GetCount());
+ return false;
+ }
+
+ m_array[row] = variant.GetString();
+ return true;
+ }
+
+ return false;
+}
-/////////////////////////////////////////////////////////////////////////////\r
-// Name: mymodels.h\r
-// Purpose: wxDataViewCtrl wxWidgets sample\r
-// Author: Robert Roebling\r
-// Modified by: Francesco Montorsi, Bo Yang\r
-// Created: 06/01/06\r
-// RCS-ID: $Id$\r
-// Copyright: (c) Robert Roebling\r
-// Licence: wxWindows license\r
-/////////////////////////////////////////////////////////////////////////////\r
-\r
-\r
-// ----------------------------------------------------------------------------\r
-// MyMusicTreeModelNode: a node inside MyMusicTreeModel\r
-// ----------------------------------------------------------------------------\r
-\r
-class MyMusicTreeModelNode;\r
-WX_DEFINE_ARRAY_PTR( MyMusicTreeModelNode*, MyMusicTreeModelNodePtrArray );\r
-\r
-class MyMusicTreeModelNode\r
-{\r
-public:\r
- MyMusicTreeModelNode( MyMusicTreeModelNode* parent,\r
- const wxString &title, const wxString &artist, \r
- unsigned int year )\r
- {\r
- m_parent = parent;\r
-\r
- m_title = title;\r
- m_artist = artist;\r
- m_year = year;\r
- m_quality = "good";\r
- }\r
-\r
- MyMusicTreeModelNode( MyMusicTreeModelNode* parent,\r
- const wxString &branch )\r
- {\r
- m_parent = parent;\r
-\r
- m_title = branch;\r
- m_year = -1;\r
- }\r
-\r
- ~MyMusicTreeModelNode()\r
- {\r
- // free all our children nodes\r
- size_t count = m_children.GetCount();\r
- for (size_t i = 0; i < count; i++)\r
- {\r
- MyMusicTreeModelNode *child = m_children[i];\r
- delete child;\r
- }\r
- }\r
-\r
- bool IsContainer() const\r
- { return m_children.GetCount()>0; }\r
-\r
- MyMusicTreeModelNode* GetParent()\r
- { return m_parent; }\r
- MyMusicTreeModelNodePtrArray& GetChildren()\r
- { return m_children; }\r
- MyMusicTreeModelNode* GetNthChild( unsigned int n )\r
- { return m_children.Item( n ); }\r
- void Insert( MyMusicTreeModelNode* child, unsigned int n)\r
- { m_children.Insert( child, n); }\r
- void Append( MyMusicTreeModelNode* child )\r
- { m_children.Add( child ); }\r
- unsigned int GetChildCount() const\r
- { return m_children.GetCount(); }\r
-\r
-public: // public to avoid getters/setters\r
- wxString m_title;\r
- wxString m_artist;\r
- int m_year;\r
- wxString m_quality;\r
-\r
-private:\r
- MyMusicTreeModelNode *m_parent;\r
- MyMusicTreeModelNodePtrArray m_children;\r
-};\r
-\r
-\r
-// ----------------------------------------------------------------------------\r
-// MyMusicTreeModel\r
-// ----------------------------------------------------------------------------\r
-\r
-/*\r
-Implement this data model\r
- Title Artist Year Judgement\r
---------------------------------------------------------------------------\r
-1: My Music:\r
- 2: Pop music\r
- 3: You are not alone Michael Jackson 1995 good\r
- 4: Take a bow Madonna 1994 good\r
- 5: Classical music\r
- 6: Ninth Symphony Ludwig v. Beethoven 1824 good\r
- 7: German Requiem Johannes Brahms 1868 good\r
-*/\r
-\r
-class MyMusicTreeModel: public wxDataViewModel\r
-{\r
-public:\r
- MyMusicTreeModel();\r
- ~MyMusicTreeModel()\r
- {\r
- delete m_root;\r
- }\r
-\r
- // helper method for wxLog\r
-\r
- wxString GetTitle( const wxDataViewItem &item ) const;\r
- int GetYear( const wxDataViewItem &item ) const;\r
-\r
- // helper methods to change the model\r
-\r
- void AddToClassical( const wxString &title, const wxString &artist, \r
- unsigned int year );\r
- void Delete( const wxDataViewItem &item );\r
-\r
- wxDataViewItem GetNinthItem() const\r
- {\r
- return wxDataViewItem( m_ninth );\r
- }\r
-\r
- // override sorting to always sort branches ascendingly\r
-\r
- int Compare( const wxDataViewItem &item1, const wxDataViewItem &item2,\r
- unsigned int column, bool ascending );\r
-\r
- // implementation of base class virtuals to define model\r
-\r
- virtual unsigned int GetColumnCount() const\r
- {\r
- return 6;\r
- }\r
-\r
- virtual wxString GetColumnType( unsigned int col ) const\r
- {\r
- if (col == 2)\r
- return wxT("long");\r
-\r
- return wxT("string");\r
- }\r
-\r
- virtual void GetValue( wxVariant &variant,\r
- const wxDataViewItem &item, unsigned int col ) const;\r
- virtual bool SetValue( const wxVariant &variant,\r
- const wxDataViewItem &item, unsigned int col );\r
-\r
- virtual wxDataViewItem GetParent( const wxDataViewItem &item ) const;\r
- virtual bool IsContainer( const wxDataViewItem &item ) const;\r
- virtual unsigned int GetChildren( const wxDataViewItem &parent, \r
- wxDataViewItemArray &array ) const;\r
-\r
-private:\r
- MyMusicTreeModelNode* m_root;\r
-\r
- // pointers to some "special" nodes of the tree:\r
- MyMusicTreeModelNode* m_pop;\r
- MyMusicTreeModelNode* m_classical;\r
- MyMusicTreeModelNode* m_ninth;\r
-\r
- // ??\r
- bool m_classicalMusicIsKnownToControl;\r
-};\r
-\r
-\r
-// ----------------------------------------------------------------------------\r
-// MyListModel\r
-// ----------------------------------------------------------------------------\r
-\r
-class MyListModel: public wxDataViewVirtualListModel\r
-{\r
-public:\r
- MyListModel();\r
-\r
- // helper methods to change the model\r
-\r
- void Prepend( const wxString &text );\r
- void DeleteItem( const wxDataViewItem &item );\r
- void DeleteItems( const wxDataViewItemArray &items );\r
- void AddMany();\r
-\r
-\r
- // implementation of base class virtuals to define model\r
-\r
- virtual unsigned int GetColumnCount() const\r
- {\r
- return 3;\r
- }\r
-\r
- virtual wxString GetColumnType( unsigned int col ) const\r
- {\r
- if (col == 1)\r
- return wxT("wxDataViewIconText");\r
-\r
- return wxT("string");\r
- }\r
-\r
- virtual unsigned int GetRowCount()\r
- {\r
- return m_array.GetCount();\r
- }\r
-\r
- virtual void GetValueByRow( wxVariant &variant,\r
- unsigned int row, unsigned int col ) const;\r
- virtual bool GetAttrByRow( unsigned int row, unsigned int col, wxDataViewItemAttr &attr );\r
- virtual bool SetValueByRow( const wxVariant &variant,\r
- unsigned int row, unsigned int col );\r
-\r
-private:\r
- wxArrayString m_array;\r
- wxIcon m_icon[2];\r
- int m_virtualItems;\r
-};\r
-\r
+/////////////////////////////////////////////////////////////////////////////
+// Name: mymodels.h
+// Purpose: wxDataViewCtrl wxWidgets sample
+// Author: Robert Roebling
+// Modified by: Francesco Montorsi, Bo Yang
+// Created: 06/01/06
+// RCS-ID: $Id$
+// Copyright: (c) Robert Roebling
+// Licence: wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+
+// ----------------------------------------------------------------------------
+// MyMusicTreeModelNode: a node inside MyMusicTreeModel
+// ----------------------------------------------------------------------------
+
+class MyMusicTreeModelNode;
+WX_DEFINE_ARRAY_PTR( MyMusicTreeModelNode*, MyMusicTreeModelNodePtrArray );
+
+class MyMusicTreeModelNode
+{
+public:
+ MyMusicTreeModelNode( MyMusicTreeModelNode* parent,
+ const wxString &title, const wxString &artist,
+ unsigned int year )
+ {
+ m_parent = parent;
+
+ m_title = title;
+ m_artist = artist;
+ m_year = year;
+ m_quality = "good";
+ }
+
+ MyMusicTreeModelNode( MyMusicTreeModelNode* parent,
+ const wxString &branch )
+ {
+ m_parent = parent;
+
+ m_title = branch;
+ m_year = -1;
+ }
+
+ ~MyMusicTreeModelNode()
+ {
+ // free all our children nodes
+ size_t count = m_children.GetCount();
+ for (size_t i = 0; i < count; i++)
+ {
+ MyMusicTreeModelNode *child = m_children[i];
+ delete child;
+ }
+ }
+
+ bool IsContainer() const
+ { return m_children.GetCount()>0; }
+
+ MyMusicTreeModelNode* GetParent()
+ { return m_parent; }
+ MyMusicTreeModelNodePtrArray& GetChildren()
+ { return m_children; }
+ MyMusicTreeModelNode* GetNthChild( unsigned int n )
+ { return m_children.Item( n ); }
+ void Insert( MyMusicTreeModelNode* child, unsigned int n)
+ { m_children.Insert( child, n); }
+ void Append( MyMusicTreeModelNode* child )
+ { m_children.Add( child ); }
+ unsigned int GetChildCount() const
+ { return m_children.GetCount(); }
+
+public: // public to avoid getters/setters
+ wxString m_title;
+ wxString m_artist;
+ int m_year;
+ wxString m_quality;
+
+private:
+ MyMusicTreeModelNode *m_parent;
+ MyMusicTreeModelNodePtrArray m_children;
+};
+
+
+// ----------------------------------------------------------------------------
+// MyMusicTreeModel
+// ----------------------------------------------------------------------------
+
+/*
+Implement this data model
+ Title Artist Year Judgement
+--------------------------------------------------------------------------
+1: My Music:
+ 2: Pop music
+ 3: You are not alone Michael Jackson 1995 good
+ 4: Take a bow Madonna 1994 good
+ 5: Classical music
+ 6: Ninth Symphony Ludwig v. Beethoven 1824 good
+ 7: German Requiem Johannes Brahms 1868 good
+*/
+
+class MyMusicTreeModel: public wxDataViewModel
+{
+public:
+ MyMusicTreeModel();
+ ~MyMusicTreeModel()
+ {
+ delete m_root;
+ }
+
+ // helper method for wxLog
+
+ wxString GetTitle( const wxDataViewItem &item ) const;
+ int GetYear( const wxDataViewItem &item ) const;
+
+ // helper methods to change the model
+
+ void AddToClassical( const wxString &title, const wxString &artist,
+ unsigned int year );
+ void Delete( const wxDataViewItem &item );
+
+ wxDataViewItem GetNinthItem() const
+ {
+ return wxDataViewItem( m_ninth );
+ }
+
+ // override sorting to always sort branches ascendingly
+
+ int Compare( const wxDataViewItem &item1, const wxDataViewItem &item2,
+ unsigned int column, bool ascending );
+
+ // implementation of base class virtuals to define model
+
+ virtual unsigned int GetColumnCount() const
+ {
+ return 6;
+ }
+
+ virtual wxString GetColumnType( unsigned int col ) const
+ {
+ if (col == 2)
+ return wxT("long");
+
+ return wxT("string");
+ }
+
+ virtual void GetValue( wxVariant &variant,
+ const wxDataViewItem &item, unsigned int col ) const;
+ virtual bool SetValue( const wxVariant &variant,
+ const wxDataViewItem &item, unsigned int col );
+
+ virtual wxDataViewItem GetParent( const wxDataViewItem &item ) const;
+ virtual bool IsContainer( const wxDataViewItem &item ) const;
+ virtual unsigned int GetChildren( const wxDataViewItem &parent,
+ wxDataViewItemArray &array ) const;
+
+private:
+ MyMusicTreeModelNode* m_root;
+
+ // pointers to some "special" nodes of the tree:
+ MyMusicTreeModelNode* m_pop;
+ MyMusicTreeModelNode* m_classical;
+ MyMusicTreeModelNode* m_ninth;
+
+ // ??
+ bool m_classicalMusicIsKnownToControl;
+};
+
+
+// ----------------------------------------------------------------------------
+// MyListModel
+// ----------------------------------------------------------------------------
+
+class MyListModel: public wxDataViewVirtualListModel
+{
+public:
+ MyListModel();
+
+ // helper methods to change the model
+
+ void Prepend( const wxString &text );
+ void DeleteItem( const wxDataViewItem &item );
+ void DeleteItems( const wxDataViewItemArray &items );
+ void AddMany();
+
+
+ // implementation of base class virtuals to define model
+
+ virtual unsigned int GetColumnCount() const
+ {
+ return 3;
+ }
+
+ virtual wxString GetColumnType( unsigned int col ) const
+ {
+ if (col == 1)
+ return wxT("wxDataViewIconText");
+
+ return wxT("string");
+ }
+
+ virtual unsigned int GetRowCount()
+ {
+ return m_array.GetCount();
+ }
+
+ virtual void GetValueByRow( wxVariant &variant,
+ unsigned int row, unsigned int col ) const;
+ virtual bool GetAttrByRow( unsigned int row, unsigned int col, wxDataViewItemAttr &attr );
+ virtual bool SetValueByRow( const wxVariant &variant,
+ unsigned int row, unsigned int col );
+
+private:
+ wxArrayString m_array;
+ wxIcon m_icon[2];
+ int m_virtualItems;
+};
+