Moved code around preparing the sorted model.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37765 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2006-02-28 15:04:25 +00:00
parent 53754b9293
commit 8f850e2831
4 changed files with 152 additions and 101 deletions

View File

@@ -29,6 +29,8 @@
// wxDataViewCtrl globals // wxDataViewCtrl globals
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class WXDLLIMPEXP_CORE wxDataViewModel;
class WXDLLIMPEXP_CORE wxDataViewListModel;
class WXDLLIMPEXP_CORE wxDataViewCtrl; class WXDLLIMPEXP_CORE wxDataViewCtrl;
class WXDLLIMPEXP_CORE wxDataViewColumn; class WXDLLIMPEXP_CORE wxDataViewColumn;
class WXDLLIMPEXP_CORE wxDataViewCell; class WXDLLIMPEXP_CORE wxDataViewCell;
@@ -53,7 +55,8 @@ protected:
// wxDataViewListModelNotifier // wxDataViewListModelNotifier
// --------------------------------------------------------- // ---------------------------------------------------------
class wxDataViewListModelNotifier
class wxDataViewListModelNotifier: public wxObject
{ {
public: public:
wxDataViewListModelNotifier() { } wxDataViewListModelNotifier() { }
@@ -66,13 +69,31 @@ public:
virtual bool RowChanged( size_t row ) = 0; virtual bool RowChanged( size_t row ) = 0;
virtual bool ValueChanged( size_t col, size_t row ) = 0; virtual bool ValueChanged( size_t col, size_t row ) = 0;
virtual bool Cleared() = 0; virtual bool Cleared() = 0;
virtual bool ValueChanged( wxDataViewColumn *view_column, size_t model_column, size_t row ) = 0;
void SetOwner( wxDataViewListModel *owner ) { m_owner = owner; }
wxDataViewListModel *GetOwner() { return m_owner; }
private:
wxDataViewListModel *m_owner;
}; };
// --------------------------------------------------------- // ---------------------------------------------------------
// wxDataViewListModel // wxDataViewListModel
// --------------------------------------------------------- // ---------------------------------------------------------
class wxDataViewViewingColumn: public wxObject
{
public:
wxDataViewViewingColumn( wxDataViewColumn *view_column, size_t model_column )
{
m_viewColumn = view_column;
m_modelColumn = model_column;
}
wxDataViewColumn *m_viewColumn;
size_t m_modelColumn;
};
class wxDataViewListModel: public wxDataViewModel class wxDataViewListModel: public wxDataViewModel
{ {
public: public:
@@ -101,13 +122,11 @@ public:
virtual void AddViewingColumn( wxDataViewColumn *view_column, size_t model_column ); virtual void AddViewingColumn( wxDataViewColumn *view_column, size_t model_column );
virtual void RemoveViewingColumn( wxDataViewColumn *column ); virtual void RemoveViewingColumn( wxDataViewColumn *column );
// Used internally virtual void AddNotifier( wxDataViewListModelNotifier *notifier );
virtual void SetNotifier( wxDataViewListModelNotifier *notifier ); virtual void RemoveNotifier( wxDataViewListModelNotifier *notifier );
virtual wxDataViewListModelNotifier* GetNotifier();
private: wxList m_notifiers;
wxDataViewListModelNotifier *m_notifier; wxList m_viewingColumns;
wxList m_viewingColumns;
protected: protected:
DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewListModel) DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewListModel)
@@ -146,10 +165,8 @@ public:
virtual bool ValueChanged( size_t col, size_t row ); virtual bool ValueChanged( size_t col, size_t row );
virtual bool Cleared(); virtual bool Cleared();
// Used internally virtual void Resort();
void SetNotifier( wxDataViewListModelNotifier *notifier );
wxDataViewListModelNotifier* GetNotifier();
private: private:
wxDataViewListModel *m_child; wxDataViewListModel *m_child;
wxDataViewSortedIndexArray m_array; wxDataViewSortedIndexArray m_array;

View File

@@ -222,7 +222,8 @@ public:
private: private:
friend class wxDataViewCtrlDC; friend class wxDataViewCtrlDC;
friend class wxGtkDataViewListModelNotifier; friend class wxGtkDataViewListModelNotifier;
GtkWidget *m_treeview; GtkWidget *m_treeview;
wxDataViewListModelNotifier *m_notifier;
private: private:
DECLARE_DYNAMIC_CLASS(wxDataViewCtrl) DECLARE_DYNAMIC_CLASS(wxDataViewCtrl)

View File

@@ -34,89 +34,108 @@ IMPLEMENT_ABSTRACT_CLASS(wxDataViewModel, wxObject)
// wxDataViewListModel // wxDataViewListModel
// --------------------------------------------------------- // ---------------------------------------------------------
class wxDataViewViewingColumn: public wxObject
{
public:
wxDataViewViewingColumn( wxDataViewColumn *view_column, size_t model_column )
{
m_viewColumn = view_column;
m_modelColumn = model_column;
}
wxDataViewColumn *m_viewColumn;
size_t m_modelColumn;
};
IMPLEMENT_ABSTRACT_CLASS(wxDataViewListModel, wxDataViewModel) IMPLEMENT_ABSTRACT_CLASS(wxDataViewListModel, wxDataViewModel)
wxDataViewListModel::wxDataViewListModel() wxDataViewListModel::wxDataViewListModel()
{ {
m_notifier = NULL;
m_viewingColumns.DeleteContents( true ); m_viewingColumns.DeleteContents( true );
m_notifiers.DeleteContents( true );
} }
wxDataViewListModel::~wxDataViewListModel() wxDataViewListModel::~wxDataViewListModel()
{ {
if (m_notifier)
delete m_notifier;
} }
bool wxDataViewListModel::RowAppended() bool wxDataViewListModel::RowAppended()
{ {
if (m_notifier) bool ret = true;
return m_notifier->RowAppended();
wxNode *node = m_notifiers.GetFirst();
while (node)
{
wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
if (!notifier->RowAppended())
ret = false;
node = node->GetNext();
}
return false; return ret;
} }
bool wxDataViewListModel::RowPrepended() bool wxDataViewListModel::RowPrepended()
{ {
if (m_notifier) bool ret = true;
return m_notifier->RowPrepended();
wxNode *node = m_notifiers.GetFirst();
while (node)
{
wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
if (!notifier->RowPrepended())
ret = false;
node = node->GetNext();
}
return false; return ret;
} }
bool wxDataViewListModel::RowInserted( size_t before ) bool wxDataViewListModel::RowInserted( size_t before )
{ {
if (m_notifier) bool ret = true;
return m_notifier->RowInserted( before );
wxNode *node = m_notifiers.GetFirst();
while (node)
{
wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
if (!notifier->RowInserted(before))
ret = false;
node = node->GetNext();
}
return false; return ret;
} }
bool wxDataViewListModel::RowDeleted( size_t row ) bool wxDataViewListModel::RowDeleted( size_t row )
{ {
if (m_notifier) bool ret = true;
return m_notifier->RowDeleted( row );
wxNode *node = m_notifiers.GetFirst();
while (node)
{
wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
if (!notifier->RowDeleted( row ))
ret = false;
node = node->GetNext();
}
return false; return ret;
} }
bool wxDataViewListModel::RowChanged( size_t row ) bool wxDataViewListModel::RowChanged( size_t row )
{ {
if (m_notifier) bool ret = true;
return m_notifier->RowChanged( row );
wxNode *node = m_notifiers.GetFirst();
while (node)
{
wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
if (!notifier->RowChanged( row ))
ret = false;
node = node->GetNext();
}
return false; return ret;
} }
bool wxDataViewListModel::ValueChanged( size_t col, size_t row ) bool wxDataViewListModel::ValueChanged( size_t col, size_t row )
{ {
bool ret = false; bool ret = true;
if (m_notifier) wxNode *node = m_notifiers.GetFirst();
ret = m_notifier->ValueChanged( col, row );
wxNode *node = m_viewingColumns.GetFirst();
while (node) while (node)
{ {
wxDataViewViewingColumn* tmp = (wxDataViewViewingColumn*) node->GetData(); wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
if (!notifier->ValueChanged( col, row ))
if (tmp->m_modelColumn == col) ret = false;
m_notifier->ValueChanged( tmp->m_viewColumn, col, row );
node = node->GetNext(); node = node->GetNext();
} }
@@ -125,10 +144,18 @@ bool wxDataViewListModel::ValueChanged( size_t col, size_t row )
bool wxDataViewListModel::Cleared() bool wxDataViewListModel::Cleared()
{ {
if (m_notifier) bool ret = true;
return m_notifier->Cleared();
wxNode *node = m_notifiers.GetFirst();
while (node)
{
wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData();
if (!notifier->Cleared())
ret = false;
node = node->GetNext();
}
return false; return ret;
} }
void wxDataViewListModel::AddViewingColumn( wxDataViewColumn *view_column, size_t model_column ) void wxDataViewListModel::AddViewingColumn( wxDataViewColumn *view_column, size_t model_column )
@@ -153,17 +180,15 @@ void wxDataViewListModel::RemoveViewingColumn( wxDataViewColumn *column )
} }
} }
void wxDataViewListModel::SetNotifier( wxDataViewListModelNotifier *notifier ) void wxDataViewListModel::AddNotifier( wxDataViewListModelNotifier *notifier )
{ {
if (m_notifier) m_notifiers.Append( notifier );
delete m_notifier; notifier->SetOwner( this );
m_notifier = notifier;
} }
wxDataViewListModelNotifier* wxDataViewListModel::GetNotifier() void wxDataViewListModel::RemoveNotifier( wxDataViewListModelNotifier *notifier )
{ {
return m_notifier; m_notifiers.DeleteObject( notifier );
} }
// --------------------------------------------------------- // ---------------------------------------------------------
@@ -226,12 +251,23 @@ wxDataViewSortedListModel::wxDataViewSortedListModel( wxDataViewListModel *child
s_CmpCol = 0; s_CmpCol = 0;
s_CmpModel = child; s_CmpModel = child;
s_CmpFunc = wxDataViewListModelSortedDefaultCompare; s_CmpFunc = wxDataViewListModelSortedDefaultCompare;
Resort();
} }
wxDataViewSortedListModel::~wxDataViewSortedListModel() wxDataViewSortedListModel::~wxDataViewSortedListModel()
{ {
} }
void wxDataViewSortedListModel::Resort()
{
m_array.Clear();
size_t n = m_child->GetNumberOfRows();
size_t i;
for (i = 0; i < n; i++)
m_array.Add( i );
}
size_t wxDataViewSortedListModel::GetNumberOfRows() size_t wxDataViewSortedListModel::GetNumberOfRows()
{ {
return m_child->GetNumberOfRows(); return m_child->GetNumberOfRows();
@@ -332,16 +368,6 @@ bool wxDataViewSortedListModel::Cleared()
return ret; return ret;
} }
void wxDataViewSortedListModel::SetNotifier( wxDataViewListModelNotifier *notifier )
{
wxDataViewListModel::SetNotifier( notifier );
}
wxDataViewListModelNotifier* wxDataViewSortedListModel::GetNotifier()
{
return wxDataViewListModel::GetNotifier();
}
// --------------------------------------------------------- // ---------------------------------------------------------
// wxDataViewCellBase // wxDataViewCellBase
// --------------------------------------------------------- // ---------------------------------------------------------

View File

@@ -736,7 +736,6 @@ public:
virtual bool RowChanged( size_t row ); virtual bool RowChanged( size_t row );
virtual bool ValueChanged( size_t col, size_t row ); virtual bool ValueChanged( size_t col, size_t row );
virtual bool Cleared(); virtual bool Cleared();
virtual bool ValueChanged( wxDataViewColumn *view_column, size_t model_column, size_t row );
GtkWxListStore *m_gtk_store; GtkWxListStore *m_gtk_store;
wxDataViewListModel *m_wx_model; wxDataViewListModel *m_wx_model;
@@ -805,9 +804,35 @@ bool wxGtkDataViewListModelNotifier::RowChanged( size_t row )
return true; return true;
} }
bool wxGtkDataViewListModelNotifier::ValueChanged( size_t col, size_t row ) bool wxGtkDataViewListModelNotifier::ValueChanged( size_t model_col, size_t model_row )
{ {
return RowChanged( row ); // This adds GTK+'s missing MVC logic for SetValue
wxNode *node = GetOwner()->m_viewingColumns.GetFirst();
while (node)
{
wxDataViewViewingColumn* viewing_column = (wxDataViewViewingColumn*) node->GetData();
if (viewing_column->m_modelColumn == model_col)
{
GtkTreeView *widget = GTK_TREE_VIEW(viewing_column->m_viewColumn->GetOwner()->m_treeview);
GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN(viewing_column->m_viewColumn->GetGtkHandle());
// Get cell area
GtkTreePath *path = gtk_tree_path_new();
gtk_tree_path_append_index( path, model_row );
GdkRectangle cell_area;
gtk_tree_view_get_cell_area( widget, path, column, &cell_area );
gtk_tree_path_free( path );
int ydiff = column->button->allocation.height;
// Redraw
gtk_widget_queue_draw_area( GTK_WIDGET(widget),
cell_area.x, ydiff + cell_area.y, cell_area.width, cell_area.height );
}
node = node->GetNext();
}
return true;
} }
bool wxGtkDataViewListModelNotifier::Cleared() bool wxGtkDataViewListModelNotifier::Cleared()
@@ -815,26 +840,6 @@ bool wxGtkDataViewListModelNotifier::Cleared()
return false; return false;
} }
bool wxGtkDataViewListModelNotifier::ValueChanged( wxDataViewColumn *view_column, size_t model_column, size_t row )
{
GtkTreeView *widget = GTK_TREE_VIEW(view_column->GetOwner()->m_treeview);
GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN(view_column->GetGtkHandle());
// Get cell area
GtkTreePath *path = gtk_tree_path_new();
gtk_tree_path_append_index( path, row );
GdkRectangle cell_area;
gtk_tree_view_get_cell_area( widget, path, column, &cell_area );
gtk_tree_path_free( path );
int ydiff = column->button->allocation.height;
// Redraw
gtk_widget_queue_draw_area( GTK_WIDGET(widget),
cell_area.x, ydiff + cell_area.y, cell_area.width, cell_area.height );
return true;
}
// --------------------------------------------------------- // ---------------------------------------------------------
// wxDataViewCell // wxDataViewCell
// --------------------------------------------------------- // ---------------------------------------------------------
@@ -1353,10 +1358,13 @@ IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl, wxDataViewCtrlBase)
wxDataViewCtrl::~wxDataViewCtrl() wxDataViewCtrl::~wxDataViewCtrl()
{ {
if (m_notifier)
GetModel()->RemoveNotifier( m_notifier );
} }
void wxDataViewCtrl::Init() void wxDataViewCtrl::Init()
{ {
m_notifier = NULL;
} }
bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id,
@@ -1400,10 +1408,9 @@ bool wxDataViewCtrl::AssociateModel( wxDataViewListModel *model )
GtkWxListStore *gtk_store = wxgtk_list_store_new(); GtkWxListStore *gtk_store = wxgtk_list_store_new();
gtk_store->model = model; gtk_store->model = model;
wxGtkDataViewListModelNotifier *notifier = m_notifier = new wxGtkDataViewListModelNotifier( gtk_store, model );
new wxGtkDataViewListModelNotifier( gtk_store, model );
model->SetNotifier( notifier ); model->AddNotifier( m_notifier );
gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview), GTK_TREE_MODEL(gtk_store) ); gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview), GTK_TREE_MODEL(gtk_store) );
g_object_unref( gtk_store ); g_object_unref( gtk_store );