| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548 | 
							- /////////////////////////////////////////////////////////////////////////////
 
- // Name:        mymodels.cpp
 
- // Purpose:     wxDataViewCtrl wxWidgets sample
 
- // Author:      Robert Roebling
 
- // Modified by: Francesco Montorsi, Bo Yang
 
- // Created:     06/01/06
 
- // Copyright:   (c) Robert Roebling
 
- // Licence:     wxWindows licence
 
- /////////////////////////////////////////////////////////////////////////////
 
- // 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, "My Music" );
 
-     // setup pop music
 
-     m_pop = new MyMusicTreeModelNode( m_root, "Pop music" );
 
-     m_pop->Append(
 
-         new MyMusicTreeModelNode( m_pop, "You are not alone", "Michael Jackson", 1995 ) );
 
-     m_pop->Append(
 
-         new MyMusicTreeModelNode( m_pop, "Take a bow", "Madonna", 1994 ) );
 
-     m_root->Append( m_pop );
 
-     // setup classical music
 
-     m_classical = new MyMusicTreeModelNode( m_root, "Classical music" );
 
-     m_ninth = new MyMusicTreeModelNode( m_classical, "Ninth symphony",
 
-                                         "Ludwig van Beethoven", 1824 );
 
-     m_classical->Append( m_ninth );
 
-     m_classical->Append( new MyMusicTreeModelNode( m_classical, "German Requiem",
 
-                                                    "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;
 
- }
 
- wxString MyMusicTreeModel::GetArtist( const wxDataViewItem &item ) const
 
- {
 
-     MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();
 
-     if (!node)      // happens if item.IsOk()==false
 
-         return wxEmptyString;
 
-     return node->m_artist;
 
- }
 
- 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, "Classical music" );
 
-         m_root->Append( m_classical );
 
-         // notify control
 
-         wxDataViewItem child( (void*) m_classical );
 
-         wxDataViewItem parent( (void*) m_root );
 
-         ItemAdded( parent, child );
 
-     }
 
-     // add to the classical music node a new node:
 
-     MyMusicTreeModelNode *child_node =
 
-         new MyMusicTreeModelNode( m_classical, title, artist, year );
 
-     m_classical->Append( child_node );
 
-     // FIXME: what's m_classicalMusicIsKnownToControl for?
 
-     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 ) const
 
- {
 
-     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:
 
-         variant = 80L;  // all music is very 80% popular
 
-         break;
 
-     case 5:
 
-         if (GetYear(item) < 1900)
 
-             variant = "old";
 
-         else
 
-             variant = "new";
 
-         break;
 
-     default:
 
-         wxLogError( "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( "MyMusicTreeModel::SetValue: wrong column" );
 
-     }
 
-     return false;
 
- }
 
- bool MyMusicTreeModel::IsEnabled( const wxDataViewItem &item,
 
-                                   unsigned int col ) const
 
- {
 
-     wxASSERT(item.IsOk());
 
-     MyMusicTreeModelNode *node = (MyMusicTreeModelNode*) item.GetID();
 
-     // disable Beethoven's ratings, his pieces can only be good
 
-     return !(col == 3 && node->m_artist.EndsWith("Beethoven"));
 
- }
 
- 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;
 
- }
 
- #define INITIAL_NUMBER_OF_ITEMS 10000
 
- MyListModel::MyListModel() :
 
-         wxDataViewVirtualListModel( INITIAL_NUMBER_OF_ITEMS )
 
- {
 
-     // the first 100 items are really stored in this model;
 
-     // all the others are synthesized on request
 
-     static const unsigned NUMBER_REAL_ITEMS = 100;
 
-     m_textColValues.reserve(NUMBER_REAL_ITEMS);
 
-     m_textColValues.push_back("first row with long label to test ellipsization");
 
-     for (unsigned int i = 1; i < NUMBER_REAL_ITEMS; i++)
 
-     {
 
-         m_textColValues.push_back(wxString::Format("real row %d", i));
 
-     }
 
-     m_iconColValues.assign(NUMBER_REAL_ITEMS, "test");
 
-     m_icon[0] = wxIcon( null_xpm );
 
-     m_icon[1] = wxIcon( wx_small_xpm );
 
- }
 
- void MyListModel::Prepend( const wxString &text )
 
- {
 
-     m_textColValues.Insert( text, 0 );
 
-     RowPrepended();
 
- }
 
- void MyListModel::DeleteItem( const wxDataViewItem &item )
 
- {
 
-     unsigned int row = GetRow( item );
 
-     if (row >= m_textColValues.GetCount())
 
-         return;
 
-     m_textColValues.RemoveAt( row );
 
-     RowDeleted( row );
 
- }
 
- void MyListModel::DeleteItems( const wxDataViewItemArray &items )
 
- {
 
-     unsigned i;
 
-     wxArrayInt rows;
 
-     for (i = 0; i < items.GetCount(); i++)
 
-     {
 
-         unsigned int row = GetRow( items[i] );
 
-         if (row < m_textColValues.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_textColValues.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_textColValues.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()
 
- {
 
-     Reset( GetCount()+1000 );
 
- }
 
- void MyListModel::GetValueByRow( wxVariant &variant,
 
-                                  unsigned int row, unsigned int col ) const
 
- {
 
-     switch ( col )
 
-     {
 
-         case Col_EditableText:
 
-             if (row >= m_textColValues.GetCount())
 
-                 variant = wxString::Format( "virtual row %d", row );
 
-             else
 
-                 variant = m_textColValues[ row ];
 
-             break;
 
-         case Col_IconText:
 
-             {
 
-                 wxString text;
 
-                 if ( row >= m_iconColValues.GetCount() )
 
-                     text = "virtual icon";
 
-                 else
 
-                     text = m_iconColValues[row];
 
-                 variant << wxDataViewIconText(text, m_icon[row % 2]);
 
-             }
 
-             break;
 
-         case Col_TextWithAttr:
 
-             {
 
-                 static const char *labels[5] =
 
-                 {
 
-                     "blue", "green", "red", "bold cyan", "default",
 
-                 };
 
-                 variant = labels[row % 5];
 
-             }
 
-             break;
 
-         case Col_Custom:
 
-             variant = wxString::Format("%d", row % 100);
 
-             break;
 
-         case Col_Max:
 
-             wxFAIL_MSG( "invalid column" );
 
-     }
 
- }
 
- bool MyListModel::GetAttrByRow( unsigned int row, unsigned int col,
 
-                                 wxDataViewItemAttr &attr ) const
 
- {
 
-     switch ( col )
 
-     {
 
-         case Col_EditableText:
 
-             return false;
 
-         case Col_IconText:
 
-             if ( !(row % 2) )
 
-                 return false;
 
-             attr.SetColour(*wxLIGHT_GREY);
 
-             break;
 
-         case Col_TextWithAttr:
 
-         case Col_Custom:
 
-             // do what the labels defined in GetValueByRow() hint at
 
-             switch ( row % 5 )
 
-             {
 
-                 case 0:
 
-                     attr.SetColour(*wxBLUE);
 
-                     break;
 
-                 case 1:
 
-                     attr.SetColour(*wxGREEN);
 
-                     break;
 
-                 case 2:
 
-                     attr.SetColour(*wxRED);
 
-                     break;
 
-                 case 3:
 
-                     attr.SetColour(*wxCYAN);
 
-                     attr.SetBold(true);
 
-                     break;
 
-                 case 4:
 
-                     return false;
 
-             }
 
-             break;
 
-         case Col_Max:
 
-             wxFAIL_MSG( "invalid column" );
 
-     }
 
-     return true;
 
- }
 
- bool MyListModel::SetValueByRow( const wxVariant &variant,
 
-                                  unsigned int row, unsigned int col )
 
- {
 
-     switch ( col )
 
-     {
 
-         case Col_EditableText:
 
-         case Col_IconText:
 
-             if (row >= m_textColValues.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_textColValues.GetCount() );
 
-                 return false;
 
-             }
 
-             if ( col == Col_EditableText )
 
-             {
 
-                 m_textColValues[row] = variant.GetString();
 
-             }
 
-             else // col == Col_IconText
 
-             {
 
-                 wxDataViewIconText iconText;
 
-                 iconText << variant;
 
-                 m_iconColValues[row] = iconText.GetText();
 
-             }
 
-             return true;
 
-         case Col_TextWithAttr:
 
-         case Col_Custom:
 
-             wxLogError("Cannot edit the column %d", col);
 
-             break;
 
-         case Col_Max:
 
-             wxFAIL_MSG( "invalid column" );
 
-     }
 
-     return false;
 
- }
 
- // ----------------------------------------------------------------------------
 
- // MyListStoreDerivedModel
 
- // ----------------------------------------------------------------------------
 
- bool MyListStoreDerivedModel::IsEnabledByRow(unsigned int row, unsigned int col) const
 
- {
 
-     // disabled the last two checkboxes
 
-     return !(col == 0 && 8 <= row && row <= 9);
 
- }
 
 
  |