Implement most of AppendRow(), PrependRow(), InsertRow(),
DeleteRow() for GTK+ version and sorted model. Added tests for these. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41450 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
|
||||
#if defined(__WXGTK20__)
|
||||
// for testing
|
||||
#define wxUSE_GENERICDATAVIEWCTRL 1
|
||||
// #define wxUSE_GENERICDATAVIEWCTRL 1
|
||||
#elif defined(__WXMAC__)
|
||||
#define wxUSE_GENERICDATAVIEWCTRL 1
|
||||
#else
|
||||
@@ -168,7 +168,7 @@ public:
|
||||
// set value, call ValueChanged() afterwards!
|
||||
virtual bool SetValue( wxVariant &variant, size_t col, size_t row );
|
||||
|
||||
// delegated notifiers
|
||||
// called from user
|
||||
virtual bool RowAppended();
|
||||
virtual bool RowPrepended();
|
||||
virtual bool RowInserted( size_t before );
|
||||
@@ -178,7 +178,15 @@ public:
|
||||
virtual bool RowsReordered( size_t *new_order );
|
||||
virtual bool Cleared();
|
||||
|
||||
// called if child's notifiers are called
|
||||
bool ChildRowAppended();
|
||||
bool ChildRowPrepended();
|
||||
bool ChildRowInserted( size_t before );
|
||||
bool ChildRowDeleted( size_t row );
|
||||
bool ChildRowChanged( size_t row );
|
||||
bool ChildValueChanged( size_t col, size_t row );
|
||||
bool ChildRowsReordered( size_t *new_order );
|
||||
bool ChildCleared();
|
||||
|
||||
virtual void Resort();
|
||||
|
||||
|
@@ -218,6 +218,30 @@ public:
|
||||
|
||||
}
|
||||
|
||||
void AppendRow( const wxString &text )
|
||||
{
|
||||
m_list.Add( text );
|
||||
RowAppended();
|
||||
}
|
||||
|
||||
void PrependRow( const wxString &text )
|
||||
{
|
||||
m_list.Insert( text, 0 );
|
||||
RowPrepended();
|
||||
}
|
||||
|
||||
void InsertRowAt1( const wxString &text )
|
||||
{
|
||||
m_list.Insert( text, 1 );
|
||||
RowInserted( 1 );
|
||||
}
|
||||
|
||||
void DeleteRow( size_t index )
|
||||
{
|
||||
m_list.RemoveAt( index );
|
||||
RowDeleted( index );
|
||||
}
|
||||
|
||||
wxArrayString m_list;
|
||||
};
|
||||
|
||||
@@ -293,6 +317,8 @@ private:
|
||||
wxDataViewCtrl* dataview_left;
|
||||
wxDataViewCtrl* dataview_right;
|
||||
|
||||
MyUnsortedTextModel *m_unsorted_model;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
@@ -412,6 +438,9 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
|
||||
|
||||
BEGIN_EVENT_TABLE(MySortingFrame,wxFrame)
|
||||
EVT_BUTTON( ID_APPEND_ROW_LEFT, MySortingFrame::OnAppendRowLeft )
|
||||
EVT_BUTTON( ID_PREPEND_ROW_LEFT, MySortingFrame::OnPrependRowLeft )
|
||||
EVT_BUTTON( ID_INSERT_ROW_LEFT, MySortingFrame::OnInsertRowLeft )
|
||||
EVT_BUTTON( ID_DELETE_ROW_LEFT, MySortingFrame::OnDeleteRowLeft )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
MySortingFrame::MySortingFrame(wxFrame *frame, wxChar *title, int x, int y, int w, int h):
|
||||
@@ -439,8 +468,8 @@ MySortingFrame::MySortingFrame(wxFrame *frame, wxChar *title, int x, int y, int
|
||||
// Left wxDataViewCtrl
|
||||
dataview_left = new wxDataViewCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_MULTIPLE );
|
||||
|
||||
MyUnsortedTextModel *model = new MyUnsortedTextModel;
|
||||
dataview_left->AssociateModel( model );
|
||||
m_unsorted_model = new MyUnsortedTextModel;
|
||||
dataview_left->AssociateModel( m_unsorted_model );
|
||||
wxDataViewTextCell *text_cell = new wxDataViewTextCell( wxT("string"), wxDATAVIEW_CELL_EDITABLE );
|
||||
wxDataViewColumn *column = new wxDataViewColumn( wxT("editable"), text_cell, 0 );
|
||||
dataview_left->AppendColumn( column );
|
||||
@@ -449,7 +478,7 @@ MySortingFrame::MySortingFrame(wxFrame *frame, wxChar *title, int x, int y, int
|
||||
// Right wxDataViewCtrl using the sorting model
|
||||
dataview_right = new wxDataViewCtrl( this, wxID_ANY );
|
||||
wxDataViewSortedListModel *sorted_model =
|
||||
new wxDataViewSortedListModel( model );
|
||||
new wxDataViewSortedListModel( m_unsorted_model );
|
||||
dataview_right->AssociateModel( sorted_model );
|
||||
text_cell = new wxDataViewTextCell( wxT("string"), wxDATAVIEW_CELL_EDITABLE );
|
||||
column = new wxDataViewColumn( wxT("editable"), text_cell, 0 );
|
||||
@@ -504,18 +533,40 @@ void MySortingFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
|
||||
|
||||
void MySortingFrame::OnAppendRowLeft(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxTextEntryDialog dialog( this, wxT("Enter text to append") );
|
||||
if (dialog.ShowModal() == wxID_OK)
|
||||
{
|
||||
wxString value = dialog.GetValue();
|
||||
if (!value.empty())
|
||||
m_unsorted_model->AppendRow( value );
|
||||
}
|
||||
}
|
||||
|
||||
void MySortingFrame::OnPrependRowLeft(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxTextEntryDialog dialog( this, wxT("Enter text to prepend") );
|
||||
if (dialog.ShowModal() == wxID_OK)
|
||||
{
|
||||
wxString value = dialog.GetValue();
|
||||
if (!value.empty())
|
||||
m_unsorted_model->PrependRow( value );
|
||||
}
|
||||
}
|
||||
|
||||
void MySortingFrame::OnInsertRowLeft(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxTextEntryDialog dialog( this, wxT("Enter text to insert at #2") );
|
||||
if (dialog.ShowModal() == wxID_OK)
|
||||
{
|
||||
wxString value = dialog.GetValue();
|
||||
if (!value.empty())
|
||||
m_unsorted_model->InsertRowAt1( value );
|
||||
}
|
||||
}
|
||||
|
||||
void MySortingFrame::OnDeleteRowLeft(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
m_unsorted_model->DeleteRow( 1 );
|
||||
}
|
||||
|
||||
void MySortingFrame::OnEditRowLeft(wxCommandEvent& WXUNUSED(event))
|
||||
|
@@ -218,15 +218,29 @@ public:
|
||||
wxDataViewSortedListModelNotifier( wxDataViewSortedListModel *model )
|
||||
{ m_model = model; }
|
||||
|
||||
virtual bool RowAppended() { return true; }
|
||||
virtual bool RowPrepended() { return true; }
|
||||
virtual bool RowInserted( size_t WXUNUSED(before) ) { return true; }
|
||||
virtual bool RowDeleted( size_t WXUNUSED(row) ) { return true; }
|
||||
virtual bool RowChanged( size_t WXUNUSED(row) ) { return true; }
|
||||
virtual bool RowAppended()
|
||||
{ return m_model->ChildRowAppended(); }
|
||||
|
||||
virtual bool RowPrepended()
|
||||
{ return m_model->ChildRowPrepended(); }
|
||||
|
||||
virtual bool RowInserted( size_t before )
|
||||
{ return m_model->ChildRowInserted( before ); }
|
||||
|
||||
virtual bool RowDeleted( size_t row )
|
||||
{ return m_model->ChildRowDeleted( row ); }
|
||||
|
||||
virtual bool RowChanged( size_t row )
|
||||
{ return m_model->ChildRowChanged( row ); }
|
||||
|
||||
virtual bool ValueChanged( size_t col, size_t row )
|
||||
{ return m_model->ChildValueChanged( col, row); }
|
||||
virtual bool RowsReordered( size_t *WXUNUSED(new_order) ) { return true; }
|
||||
virtual bool Cleared() { return true; }
|
||||
|
||||
virtual bool RowsReordered( size_t *new_order )
|
||||
{ return m_model->ChildRowsReordered( new_order ); }
|
||||
|
||||
virtual bool Cleared()
|
||||
{ return m_model->ChildCleared(); }
|
||||
|
||||
wxDataViewSortedListModel *m_model;
|
||||
};
|
||||
@@ -332,6 +346,152 @@ static void Dump( wxDataViewListModel *model, size_t col )
|
||||
}
|
||||
#endif
|
||||
|
||||
bool wxDataViewSortedListModel::ChildRowAppended()
|
||||
{
|
||||
// no need to fix up array
|
||||
|
||||
size_t len = m_array.GetCount();
|
||||
|
||||
size_t pos = m_array.Add( len );
|
||||
|
||||
if (pos == 0)
|
||||
return wxDataViewListModel::RowPrepended();
|
||||
|
||||
if (pos == len)
|
||||
return wxDataViewListModel::RowAppended();
|
||||
|
||||
return wxDataViewListModel::RowInserted( pos );
|
||||
}
|
||||
|
||||
bool wxDataViewSortedListModel::ChildRowPrepended()
|
||||
{
|
||||
// fix up array
|
||||
size_t i;
|
||||
size_t len = m_array.GetCount();
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
size_t value = m_array[i];
|
||||
m_array[i] = value+1;
|
||||
}
|
||||
|
||||
size_t pos = m_array.Add( 0 );
|
||||
|
||||
if (pos == 0)
|
||||
return wxDataViewListModel::RowPrepended();
|
||||
|
||||
if (pos == len)
|
||||
return wxDataViewListModel::RowAppended();
|
||||
|
||||
return wxDataViewListModel::RowInserted( pos );
|
||||
}
|
||||
|
||||
bool wxDataViewSortedListModel::ChildRowInserted( size_t before )
|
||||
{
|
||||
// fix up array
|
||||
size_t i;
|
||||
size_t len = m_array.GetCount();
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
size_t value = m_array[i];
|
||||
if (value >= before)
|
||||
m_array[i] = value+1;
|
||||
}
|
||||
|
||||
size_t pos = m_array.Add( before );
|
||||
|
||||
if (pos == 0)
|
||||
return wxDataViewListModel::RowPrepended();
|
||||
|
||||
if (pos == len)
|
||||
return wxDataViewListModel::RowAppended();
|
||||
|
||||
return wxDataViewListModel::RowInserted( pos );
|
||||
}
|
||||
|
||||
bool wxDataViewSortedListModel::ChildRowDeleted( size_t row )
|
||||
{
|
||||
size_t i;
|
||||
size_t len = m_array.GetCount();
|
||||
int pos = -1;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
size_t value = m_array[i];
|
||||
if (value == row)
|
||||
{
|
||||
// delete later
|
||||
pos = (int) i;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fix up array
|
||||
if (value > row)
|
||||
m_array[i] = value-1;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos == -1)
|
||||
return false; // we should probably assert
|
||||
|
||||
// remove
|
||||
m_array.RemoveAt( (size_t) pos );
|
||||
|
||||
return wxDataViewListModel::RowDeleted( (size_t) pos);
|
||||
}
|
||||
|
||||
bool wxDataViewSortedListModel::ChildRowChanged( size_t row )
|
||||
{
|
||||
size_t i;
|
||||
size_t len = m_array.GetCount();
|
||||
|
||||
// Remove and readd sorted. Find out at which
|
||||
// position it was and where it ended.
|
||||
size_t start_pos = 0,end_pos = 0;
|
||||
for (i = 0; i < len; i++)
|
||||
if (m_array[i] == row)
|
||||
{
|
||||
start_pos = i;
|
||||
break;
|
||||
}
|
||||
m_array.RemoveAt( start_pos );
|
||||
m_array.Add( row );
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (m_array[i] == row)
|
||||
{
|
||||
end_pos = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (end_pos == start_pos)
|
||||
return wxDataViewListModel::RowChanged( start_pos );
|
||||
|
||||
// Create an array where order[old] -> new_pos, so that
|
||||
// if nothing changed order[0] -> 0 etc.
|
||||
size_t *order = new size_t[ len ];
|
||||
// Fill up initial values.
|
||||
for (i = 0; i < len; i++)
|
||||
order[i] = i;
|
||||
|
||||
if (start_pos < end_pos)
|
||||
{
|
||||
for (i = start_pos; i < end_pos; i++)
|
||||
order[i] = order[i+1];
|
||||
order[end_pos] = start_pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = end_pos; i > start_pos; i--)
|
||||
order[i] = order[i-1];
|
||||
order[start_pos] = end_pos;
|
||||
}
|
||||
|
||||
wxDataViewListModel::RowsReordered( order );
|
||||
|
||||
delete [] order;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxDataViewSortedListModel::ChildValueChanged( size_t col, size_t row )
|
||||
{
|
||||
size_t i;
|
||||
@@ -386,6 +546,19 @@ bool wxDataViewSortedListModel::ChildValueChanged( size_t col, size_t row )
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxDataViewSortedListModel::ChildRowsReordered( size_t *new_order )
|
||||
{
|
||||
// Nothing needs to be done. If the sort criteria
|
||||
// of this list don't change, the order of the
|
||||
// items of the child list isn't relevant.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxDataViewSortedListModel::ChildCleared()
|
||||
{
|
||||
return wxDataViewListModel::Cleared();
|
||||
}
|
||||
|
||||
size_t wxDataViewSortedListModel::GetNumberOfRows()
|
||||
{
|
||||
return m_array.GetCount();
|
||||
@@ -412,7 +585,8 @@ bool wxDataViewSortedListModel::SetValue( wxVariant &variant, size_t col, size_t
|
||||
size_t child_row = m_array[row];
|
||||
bool ret = m_child->SetValue( variant, col, child_row );
|
||||
|
||||
// Resort in ::ChildValueChanged() which gets reported back.
|
||||
// Do nothing here as the change in the
|
||||
// child model will be reported back.
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -422,7 +596,8 @@ bool wxDataViewSortedListModel::RowAppended()
|
||||
// you can only append
|
||||
bool ret = m_child->RowAppended();
|
||||
|
||||
// report RowInsrted
|
||||
// Do nothing here as the change in the
|
||||
// child model will be reported back.
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -432,7 +607,8 @@ bool wxDataViewSortedListModel::RowPrepended()
|
||||
// you can only append
|
||||
bool ret = m_child->RowAppended();
|
||||
|
||||
// report RowInsrted
|
||||
// Do nothing here as the change in the
|
||||
// child model will be reported back.
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -442,7 +618,8 @@ bool wxDataViewSortedListModel::RowInserted( size_t WXUNUSED(before) )
|
||||
// you can only append
|
||||
bool ret = m_child->RowAppended();
|
||||
|
||||
// report different RowInsrted
|
||||
// Do nothing here as the change in the
|
||||
// child model will be reported back.
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -492,7 +669,8 @@ bool wxDataViewSortedListModel::Cleared()
|
||||
{
|
||||
bool ret = m_child->Cleared();
|
||||
|
||||
wxDataViewListModel::Cleared();
|
||||
// Do nothing here as the change in the
|
||||
// child model will be reported back.
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -783,12 +783,26 @@ bool wxGtkDataViewListModelNotifier::RowPrepended()
|
||||
|
||||
bool wxGtkDataViewListModelNotifier::RowInserted( size_t before )
|
||||
{
|
||||
return false;
|
||||
GtkTreeIter iter;
|
||||
iter.stamp = m_gtk_store->stamp;
|
||||
iter.user_data = (gpointer) before;
|
||||
|
||||
GtkTreePath *path = gtk_tree_path_new ();
|
||||
gtk_tree_path_append_index (path, (gint) before);
|
||||
gtk_tree_model_row_inserted (GTK_TREE_MODEL (m_gtk_store), path, &iter);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxGtkDataViewListModelNotifier::RowDeleted( size_t row )
|
||||
{
|
||||
return false;
|
||||
GtkTreePath *path = gtk_tree_path_new ();
|
||||
gtk_tree_path_append_index (path, (gint) row);
|
||||
gtk_tree_model_row_deleted (GTK_TREE_MODEL (m_gtk_store), path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxGtkDataViewListModelNotifier::RowChanged( size_t row )
|
||||
|
Reference in New Issue
Block a user