From: Robert Roebling Date: Thu, 5 Jul 2007 00:13:28 +0000 (+0000) Subject: New API for wxdataViewCtrl (doesn't run yet). X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/e0062c047ecb5a7d4790b980777dfa70869f4834?ds=inline New API for wxdataViewCtrl (doesn't run yet). git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@47131 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/dataview.h b/include/wx/dataview.h index 012a2d6774..085655fb16 100644 --- a/include/wx/dataview.h +++ b/include/wx/dataview.h @@ -38,12 +38,13 @@ // wxDataViewCtrl globals // ---------------------------------------------------------------------------- +class WXDLLIMPEXP_ADV wxDataViewItem; class WXDLLIMPEXP_ADV wxDataViewModel; -class WXDLLIMPEXP_ADV wxDataViewListModel; class WXDLLIMPEXP_ADV wxDataViewCtrl; class WXDLLIMPEXP_ADV wxDataViewColumn; class WXDLLIMPEXP_ADV wxDataViewRenderer; -class wxDataViewEventListModelNotifier; +class WXDLLIMPEXP_ADV wxDataViewModelNotifier; +class wxDataViewEventModelNotifier; extern WXDLLIMPEXP_DATA_ADV(const wxChar) wxDataViewCtrlNameStr[]; @@ -61,159 +62,98 @@ extern WXDLLIMPEXP_DATA_ADV(const wxChar) wxDataViewCtrlNameStr[]; // --------------------------------------------------------- -// wxDataViewModel +// wxDataViewItem // --------------------------------------------------------- -class WXDLLIMPEXP_ADV wxDataViewModel: public wxObjectRefData +class WXDLLIMPEXP_ADV wxDataViewItem { public: - wxDataViewModel() { } - -protected: - // the user should not delete this class directly: he should use DecRef() instead! - virtual ~wxDataViewModel() { } -}; - -// --------------------------------------------------------- -// wxDataViewListModelNotifier -// --------------------------------------------------------- - -class WXDLLIMPEXP_ADV wxDataViewListModelNotifier: public wxObject -{ + wxDataViewItem( wxUint32 id = 0 ) + { m_id = id; m_reserved1 = 0; m_reserved2 = NULL; } + wxDataViewItem( const wxDataViewItem &item ) + { m_id = item.m_id; m_reserved1 = item.m_reserved1; m_reserved2 = item.m_reserved2; } + bool IsOk() const { return m_id != 0; } + wxUint32 GetID() const { return m_id; } + public: - wxDataViewListModelNotifier() { } - virtual ~wxDataViewListModelNotifier() { m_owner = NULL; } - - virtual bool RowAppended() = 0; - virtual bool RowPrepended() = 0; - virtual bool RowInserted( unsigned int before ) = 0; - virtual bool RowDeleted( unsigned int row ) = 0; - virtual bool RowChanged( unsigned int row ) = 0; - virtual bool ValueChanged( unsigned int col, unsigned int row ) = 0; - virtual bool RowsReordered( unsigned int *new_order ) = 0; - virtual bool Cleared() = 0; - - void SetOwner( wxDataViewListModel *owner ) { m_owner = owner; } - wxDataViewListModel *GetOwner() { return m_owner; } - + wxUint32 m_reserved1; + void* m_reserved2; + private: - wxDataViewListModel *m_owner; + wxUint32 m_id; }; // --------------------------------------------------------- -// wxDataViewListModel +// wxDataViewModel // --------------------------------------------------------- -class WXDLLIMPEXP_ADV wxDataViewListModel: public wxDataViewModel +class WXDLLIMPEXP_ADV wxDataViewModel: public wxObjectRefData { public: - wxDataViewListModel(); + wxDataViewModel(); - virtual unsigned int GetRowCount() const = 0; virtual unsigned int GetColumnCount() const = 0; // return type as reported by wxVariant virtual wxString GetColumnType( unsigned int col ) const = 0; // get value into a wxVariant - virtual void GetValue( wxVariant &variant, unsigned int col, unsigned int row ) const = 0; + virtual void GetValue( wxVariant &variant, + const wxDataViewItem &item, unsigned int col ) const = 0; // set value, call ValueChanged() afterwards! - virtual bool SetValue( const wxVariant &variant, unsigned int col, unsigned int row ) = 0; + virtual bool SetValue( const wxVariant &variant, + const wxDataViewItem &item, unsigned int col ) = 0; - // override to set cell attributes - virtual void GetAttr( wxListItemAttr& WXUNUSED(attr), - unsigned int WXUNUSED(col), - unsigned int WXUNUSED(row) ) - { - } + // define hierachy + virtual bool HasChildren( const wxDataViewItem &item ) const = 0; + virtual int GetChildCount( const wxDataViewItem &item ) const = 0; + virtual wxDataViewItem GetParent( const wxDataViewItem &child ) const = 0; + virtual wxDataViewItem GetFirstChild( const wxDataViewItem &parent ) const = 0; + virtual wxDataViewItem GetNextSibling( const wxDataViewItem &item ) const = 0; + virtual wxDataViewItem GetNthChild( const wxDataViewItem &parent, unsigned int n ) const = 0; // delegated notifiers - virtual bool RowAppended(); - virtual bool RowPrepended(); - virtual bool RowInserted( unsigned int before ); - virtual bool RowDeleted( unsigned int row ); - virtual bool RowChanged( unsigned int row ); - virtual bool ValueChanged( unsigned int col, unsigned int row ); - virtual bool RowsReordered( unsigned int *new_order ); + virtual bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ); + virtual bool ItemDeleted( const wxDataViewItem &item ); + virtual bool ItemChanged( const wxDataViewItem &item ); + virtual bool ValueChanged( const wxDataViewItem &item, unsigned int col ); virtual bool Cleared(); - void AddNotifier( wxDataViewListModelNotifier *notifier ); - void RemoveNotifier( wxDataViewListModelNotifier *notifier ); + void AddNotifier( wxDataViewModelNotifier *notifier ); + void RemoveNotifier( wxDataViewModelNotifier *notifier ); protected: // the user should not delete this class directly: he should use DecRef() instead! - virtual ~wxDataViewListModel(); + virtual ~wxDataViewModel(); wxList m_notifiers; }; // --------------------------------------------------------- -// wxDataViewSortedListModel +// wxDataViewModelNotifier // --------------------------------------------------------- -typedef int (wxCALLBACK *wxDataViewListModelCompare) - (unsigned int row1, unsigned int row2, unsigned int col, wxDataViewListModel* model ); - -WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_SIZE_T(unsigned int, - wxDataViewSortedIndexArray, WXDLLIMPEXP_ADV); - -class WXDLLIMPEXP_ADV wxDataViewSortedListModel: public wxDataViewListModel +class WXDLLIMPEXP_ADV wxDataViewModelNotifier: public wxObject { - friend class wxDataViewSortedListModelNotifier; - public: - wxDataViewSortedListModel( wxDataViewListModel *child ); - virtual ~wxDataViewSortedListModel(); - - void SetAscending( bool ascending ) { m_ascending = ascending; } - bool IsAscending() const { return m_ascending; } - - virtual unsigned int GetRowCount() const; - virtual unsigned int GetColumnCount() const; - - // return type as reported by wxVariant - virtual wxString GetColumnType( unsigned int col ) const; - - // get value into a wxVariant - virtual void GetValue( wxVariant &variant, unsigned int col, unsigned int row ) const; + wxDataViewModelNotifier() { } + virtual ~wxDataViewModelNotifier() { m_owner = NULL; } - // set value, call ValueChanged() afterwards! - virtual bool SetValue( const wxVariant &variant, unsigned int col, unsigned int row ); - - // called from user - virtual bool RowAppended(); - virtual bool RowPrepended(); - virtual bool RowInserted( unsigned int before ); - virtual bool RowDeleted( unsigned int row ); - virtual bool RowChanged( unsigned int row ); - virtual bool ValueChanged( unsigned int col, unsigned int row ); - virtual bool RowsReordered( unsigned int *new_order ); - virtual bool Cleared(); + virtual bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ) = 0; + virtual bool ItemDeleted( const wxDataViewItem &item ) = 0; + virtual bool ItemChanged( const wxDataViewItem &item ) = 0; + virtual bool ValueChanged( const wxDataViewItem &item, unsigned int col ) = 0; + virtual bool Cleared() = 0; - // called if child's notifiers are called - bool ChildRowAppended(); - bool ChildRowPrepended(); - bool ChildRowInserted( unsigned int before ); - bool ChildRowDeleted( unsigned int row ); - bool ChildRowChanged( unsigned int row ); - bool ChildValueChanged( unsigned int col, unsigned int row ); - bool ChildRowsReordered( unsigned int *new_order ); - bool ChildCleared(); - - virtual void Resort(); - - void DetachChild(); + void SetOwner( wxDataViewModel *owner ) { m_owner = owner; } + wxDataViewModel *GetOwner() { return m_owner; } private: - bool m_ascending; - wxDataViewListModel *m_child; - wxDataViewSortedIndexArray m_array; - wxDataViewListModelNotifier *m_notifierOnChild; - - void InitStatics(); // BAD + wxDataViewModel *m_owner; }; + //----------------------------------------------------------------------------- // wxDataViewEditorCtrlEvtHandler //----------------------------------------------------------------------------- @@ -300,7 +240,7 @@ public: wxVariant& WXUNUSED(value)) { return false; } - virtual bool StartEditing( unsigned int row, wxRect labelRect ); + virtual bool StartEditing( const wxDataViewItem &item, wxRect labelRect ); virtual void CancelEditing(); virtual bool FinishEditing(); @@ -310,7 +250,7 @@ protected: wxString m_variantType; wxDataViewColumn *m_owner; wxControl *m_editorCtrl; - unsigned int m_row; // for m_editorCtrl + wxDataViewItem m_item; // for m_editorCtrl // internal utility: const wxDataViewCtrl* GetView() const; @@ -408,8 +348,8 @@ public: wxDataViewCtrlBase(); virtual ~wxDataViewCtrlBase(); - virtual bool AssociateModel( wxDataViewListModel *model ); - wxDataViewListModel* GetModel(); + virtual bool AssociateModel( wxDataViewModel *model ); + wxDataViewModel* GetModel(); // short cuts bool AppendTextColumn( const wxString &label, unsigned int model_column, @@ -461,26 +401,17 @@ public: virtual bool ClearColumns(); virtual wxDataViewColumn* GetColumn( unsigned int pos ); - virtual void SetSelection( int row ) = 0; // -1 for unselect - inline void ClearSelection() { SetSelection( -1 ); } - virtual void Unselect( unsigned int row ) = 0; - virtual void SetSelectionRange( unsigned int from, unsigned int to ) = 0; - virtual void SetSelections( const wxArrayInt& aSelections) = 0; - - virtual bool IsSelected( unsigned int row ) const = 0; - virtual int GetSelection() const = 0; - virtual int GetSelections(wxArrayInt& aSelections) const = 0; + // TODO selection code private: - wxDataViewListModel *m_model; + wxDataViewModel *m_model; wxList m_cols; - wxDataViewEventListModelNotifier *m_eventNotifier; + wxDataViewEventModelNotifier *m_eventNotifier; protected: DECLARE_DYNAMIC_CLASS_NO_COPY(wxDataViewCtrlBase) }; - // ---------------------------------------------------------------------------- // wxDataViewEvent - the event class for the wxDataViewCtrl notifications // ---------------------------------------------------------------------------- @@ -490,30 +421,28 @@ class WXDLLIMPEXP_ADV wxDataViewEvent : public wxNotifyEvent public: wxDataViewEvent(wxEventType commandType = wxEVT_NULL, int winid = 0) : wxNotifyEvent(commandType, winid), + m_item(0), m_col(-1), - m_row(-1), m_model(NULL), m_value(wxNullVariant), - m_editCancelled(false), m_column(NULL) { } wxDataViewEvent(const wxDataViewEvent& event) : wxNotifyEvent(event), + m_item(event.m_item), m_col(event.m_col), - m_row(event.m_col), m_model(event.m_model), m_value(event.m_value), - m_editCancelled(event.m_editCancelled), m_column(event.m_column) { } + wxDataViewItem GetItem() const { return m_item; } + void SetItem( const wxDataViewItem &item ) { m_item = item; } + int GetColumn() const { return m_col; } void SetColumn( int col ) { m_col = col; } - int GetRow() const { return m_row; } - void SetRow( int row ) { m_row = row; } - wxDataViewModel* GetModel() const { return m_model; } void SetModel( wxDataViewModel *model ) { m_model = model; } @@ -524,18 +453,13 @@ public: void SetDataViewColumn( wxDataViewColumn *col ) { m_column = col; } wxDataViewColumn *GetDataViewColumn() const { return m_column; } - // was label editing canceled? (for wxEVT_COMMAND_DATVIEW_END_LABEL_EDIT only) - bool IsEditCancelled() const { return m_editCancelled; } - void SetEditCanceled(bool editCancelled) { m_editCancelled = editCancelled; } - virtual wxEvent *Clone() const { return new wxDataViewEvent(*this); } protected: + wxDataViewItem m_item; int m_col; - int m_row; wxDataViewModel *m_model; wxVariant m_value; - bool m_editCancelled; wxDataViewColumn *m_column; private: @@ -543,19 +467,16 @@ private: }; BEGIN_DECLARE_EVENT_TYPES() - DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_ROW_SELECTED, -1) - DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_ROW_ACTIVATED, -1) + DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_ITEM_SELECTED, -1) + DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, -1) DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK, -1) DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK, -1) DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED, -1) // notifications from the model to the control - DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_MODEL_ROW_APPENDED, -1) - DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_MODEL_ROW_PREPENDED, -1) - DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_MODEL_ROW_INSERTED, -1) - DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_MODEL_ROW_DELETED, -1) - DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_MODEL_ROW_CHANGED, -1) + DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_ADDED, -1) + DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_DELETED, -1) + DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_CHANGED, -1) DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_MODEL_VALUE_CHANGED, -1) - DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_MODEL_ROWS_REORDERED, -1) DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_ADV, wxEVT_COMMAND_DATAVIEW_MODEL_CLEARED, -1) END_DECLARE_EVENT_TYPES() @@ -567,19 +488,16 @@ typedef void (wxEvtHandler::*wxDataViewEventFunction)(wxDataViewEvent&); #define wx__DECLARE_DATAVIEWEVT(evt, id, fn) \ wx__DECLARE_EVT1(wxEVT_COMMAND_DATAVIEW_ ## evt, id, wxDataViewEventHandler(fn)) -#define EVT_DATAVIEW_ROW_SELECTED(id, fn) wx__DECLARE_DATAVIEWEVT(ROW_SELECTED, id, fn) -#define EVT_DATAVIEW_ROW_ACTIVATED(id, fn) wx__DECLARE_DATAVIEWEVT(ROW_ACTIVATED, id, fn) +#define EVT_DATAVIEW_ITEM_SELECTED(id, fn) wx__DECLARE_DATAVIEWEVT(ITEM_SELECTED, id, fn) +#define EVT_DATAVIEW_ITEM_ACTIVATED(id, fn) wx__DECLARE_DATAVIEWEVT(ITEM_ACTIVATED, id, fn) #define EVT_DATAVIEW_COLUMN_HEADER_CLICK(id, fn) wx__DECLARE_DATAVIEWEVT(COLUMN_HEADER_CLICK, id, fn) #define EVT_DATAVIEW_COLUMN_HEADER_RIGHT_CLICKED(id, fn) wx__DECLARE_DATAVIEWEVT(COLUMN_HEADER_RIGHT_CLICK, id, fn) #define EVT_DATAVIEW_COLUMN_SORTED(id, fn) wx__DECLARE_DATAVIEWEVT(COLUMN_SORTED, id, fn) -#define EVT_DATAVIEW_MODEL_ROW_APPENDED(id, fn) wx__DECLARE_DATAVIEWEVT(MODEL_ROW_APPENDED, id, fn) -#define EVT_DATAVIEW_MODEL_ROW_PREPENDED(id, fn) wx__DECLARE_DATAVIEWEVT(MODEL_ROW_PREPENDED, id, fn) -#define EVT_DATAVIEW_MODEL_ROW_INSERTED(id, fn) wx__DECLARE_DATAVIEWEVT(MODEL_ROW_INSERTED, id, fn) -#define EVT_DATAVIEW_MODEL_ROW_DELETED(id, fn) wx__DECLARE_DATAVIEWEVT(MODEL_ROW_DELETED, id, fn) -#define EVT_DATAVIEW_MODEL_ROW_CHANGED(id, fn) wx__DECLARE_DATAVIEWEVT(MODEL_ROW_CHANGED, id, fn) +#define EVT_DATAVIEW_MODEL_ITEM_ADDED(id, fn) wx__DECLARE_DATAVIEWEVT(MODEL_ITEM_APPENDED, id, fn) +#define EVT_DATAVIEW_MODEL_ITEM_DELETED(id, fn) wx__DECLARE_DATAVIEWEVT(MODEL_ITEM_DELETED, id, fn) +#define EVT_DATAVIEW_MODEL_ITEM_CHANGED(id, fn) wx__DECLARE_DATAVIEWEVT(MODEL_ITEM_CHANGED, id, fn) #define EVT_DATAVIEW_MODEL_VALUE_CHANGED(id, fn) wx__DECLARE_DATAVIEWEVT(MODEL_VALUE_CHANGED, id, fn) -#define EVT_DATAVIEW_MODEL_ROWS_REORDERED(id, fn) wx__DECLARE_DATAVIEWEVT(MODEL_ROWS_REORDERED, id, fn) #define EVT_DATAVIEW_MODEL_CLEARED(id, fn) wx__DECLARE_DATAVIEWEVT(MODEL_CLEARED, id, fn) diff --git a/include/wx/gtk/dataview.h b/include/wx/gtk/dataview.h index acef40fa2e..70dd914559 100644 --- a/include/wx/gtk/dataview.h +++ b/include/wx/gtk/dataview.h @@ -123,17 +123,17 @@ public: virtual wxSize GetSize() const = 0; virtual bool Activate( wxRect cell, - wxDataViewListModel *model, unsigned int col, unsigned int row ) + wxDataViewModel *model, const wxDataViewItem &item, unsigned int col ) { return false; } virtual bool LeftClick( wxPoint cursor, wxRect cell, - wxDataViewListModel *model, unsigned int col, unsigned int row ) + wxDataViewModel *model, const wxDataViewItem &item, unsigned int col ) { return false; } virtual bool RightClick( wxPoint cursor, wxRect cell, - wxDataViewListModel *model, unsigned int col, unsigned int row ) + wxDataViewModel *model, const wxDataViewItem &item, unsigned int col ) { return false; } virtual bool StartDrag( wxPoint cursor, wxRect cell, - wxDataViewListModel *model, unsigned int col, unsigned int row ) + wxDataViewModel *model, const wxDataViewItem &item, unsigned int col ) { return false; } // Create DC on request @@ -195,7 +195,7 @@ public: virtual bool Render( wxRect cell, wxDC *dc, int state ); virtual wxSize GetSize() const; virtual bool Activate( wxRect cell, - wxDataViewListModel *model, unsigned int col, unsigned int row ); + wxDataViewModel *model, const wxDataViewItem &item, unsigned int col ); private: wxDateTime m_date; @@ -302,17 +302,10 @@ public: const wxSize& size = wxDefaultSize, long style = 0, const wxValidator& validator = wxDefaultValidator ); - virtual bool AssociateModel( wxDataViewListModel *model ); + virtual bool AssociateModel( wxDataViewModel *model ); virtual bool AppendColumn( wxDataViewColumn *col ); - virtual void SetSelection( int row ); // -1 for unselect - virtual void SetSelectionRange( unsigned int from, unsigned int to ); - virtual void SetSelections( const wxArrayInt& aSelections); - virtual void Unselect( unsigned int row ); - - virtual bool IsSelected( unsigned int row ) const; - virtual int GetSelection() const; - virtual int GetSelections(wxArrayInt& aSelections) const; + // selection code static wxVisualAttributes GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); @@ -323,9 +316,9 @@ public: private: friend class wxDataViewCtrlDC; friend class wxDataViewColumn; - friend class wxGtkDataViewListModelNotifier; - GtkWidget *m_treeview; - wxDataViewListModelNotifier *m_notifier; + friend class wxGtkDataViewModelNotifier; + GtkWidget *m_treeview; + wxDataViewModelNotifier *m_notifier; virtual void OnInternalIdle(); diff --git a/src/common/datavcmn.cpp b/src/common/datavcmn.cpp index ab02b8e824..75aa10454b 100644 --- a/src/common/datavcmn.cpp +++ b/src/common/datavcmn.cpp @@ -30,56 +30,20 @@ const wxChar wxDataViewCtrlNameStr[] = wxT("dataviewCtrl"); // wxDataViewListModel // --------------------------------------------------------- -wxDataViewListModel::wxDataViewListModel() +wxDataViewModel::wxDataViewModel() { m_notifiers.DeleteContents( true ); } -wxDataViewListModel::~wxDataViewListModel() -{ -} - -bool wxDataViewListModel::RowAppended() -{ - bool ret = true; - - wxList::compatibility_iterator node = m_notifiers.GetFirst(); - while (node) - { - wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData(); - if (!notifier->RowAppended()) - ret = false; - node = node->GetNext(); - } - - return ret; -} - -bool wxDataViewListModel::RowPrepended() -{ - bool ret = true; - - wxList::compatibility_iterator node = m_notifiers.GetFirst(); - while (node) - { - wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData(); - if (!notifier->RowPrepended()) - ret = false; - node = node->GetNext(); - } - - return ret; -} - -bool wxDataViewListModel::RowInserted( unsigned int before ) +bool wxDataViewModel::ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ) { bool ret = true; wxList::compatibility_iterator node = m_notifiers.GetFirst(); while (node) { - wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData(); - if (!notifier->RowInserted(before)) + wxDataViewModelNotifier* notifier = (wxDataViewModelNotifier*) node->GetData(); + if (!notifier->ItemAdded( parent, item )) ret = false; node = node->GetNext(); } @@ -87,15 +51,15 @@ bool wxDataViewListModel::RowInserted( unsigned int before ) return ret; } -bool wxDataViewListModel::RowDeleted( unsigned int row ) +bool wxDataViewModel::ItemDeleted( const wxDataViewItem &item ) { bool ret = true; wxList::compatibility_iterator node = m_notifiers.GetFirst(); while (node) { - wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData(); - if (!notifier->RowDeleted( row )) + wxDataViewModelNotifier* notifier = (wxDataViewModelNotifier*) node->GetData(); + if (!notifier->ItemDeleted( item )) ret = false; node = node->GetNext(); } @@ -103,15 +67,15 @@ bool wxDataViewListModel::RowDeleted( unsigned int row ) return ret; } -bool wxDataViewListModel::RowChanged( unsigned int row ) +bool wxDataViewModel::ItemChanged( const wxDataViewItem &item ) { bool ret = true; wxList::compatibility_iterator node = m_notifiers.GetFirst(); while (node) { - wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData(); - if (!notifier->RowChanged( row )) + wxDataViewModelNotifier* notifier = (wxDataViewModelNotifier*) node->GetData(); + if (!notifier->ItemChanged( item )) ret = false; node = node->GetNext(); } @@ -119,15 +83,15 @@ bool wxDataViewListModel::RowChanged( unsigned int row ) return ret; } -bool wxDataViewListModel::ValueChanged( unsigned int col, unsigned int row ) +bool wxDataViewModel::ValueChanged( const wxDataViewItem &item, unsigned int col ) { bool ret = true; wxList::compatibility_iterator node = m_notifiers.GetFirst(); while (node) { - wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData(); - if (!notifier->ValueChanged( col, row )) + wxDataViewModelNotifier* notifier = (wxDataViewModelNotifier*) node->GetData(); + if (!notifier->ValueChanged( item, col )) ret = false; node = node->GetNext(); } @@ -135,30 +99,14 @@ bool wxDataViewListModel::ValueChanged( unsigned int col, unsigned int row ) return ret; } -bool wxDataViewListModel::RowsReordered( unsigned int *new_order ) +bool wxDataViewModel::Cleared() { bool ret = true; wxList::compatibility_iterator node = m_notifiers.GetFirst(); while (node) { - wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData(); - if (!notifier->RowsReordered( new_order )) - ret = false; - node = node->GetNext(); - } - - return ret; -} - -bool wxDataViewListModel::Cleared() -{ - bool ret = true; - - wxList::compatibility_iterator node = m_notifiers.GetFirst(); - while (node) - { - wxDataViewListModelNotifier* notifier = (wxDataViewListModelNotifier*) node->GetData(); + wxDataViewModelNotifier* notifier = (wxDataViewModelNotifier*) node->GetData(); if (!notifier->Cleared()) ret = false; node = node->GetNext(); @@ -167,554 +115,17 @@ bool wxDataViewListModel::Cleared() return ret; } -void wxDataViewListModel::AddNotifier( wxDataViewListModelNotifier *notifier ) +void wxDataViewModel::AddNotifier( wxDataViewModelNotifier *notifier ) { m_notifiers.Append( notifier ); notifier->SetOwner( this ); } -void wxDataViewListModel::RemoveNotifier( wxDataViewListModelNotifier *notifier ) +void wxDataViewModel::RemoveNotifier( wxDataViewModelNotifier *notifier ) { m_notifiers.DeleteObject( notifier ); } -// --------------------------------------------------------- -// wxDataViewSortedListModelNotifier -// --------------------------------------------------------- - -class wxDataViewSortedListModelNotifier: public wxDataViewListModelNotifier -{ -public: - wxDataViewSortedListModelNotifier( wxDataViewSortedListModel *model ) - { m_model = model; } - - virtual bool RowAppended() - { return m_model->ChildRowAppended(); } - - virtual bool RowPrepended() - { return m_model->ChildRowPrepended(); } - - virtual bool RowInserted( unsigned int before ) - { return m_model->ChildRowInserted( before ); } - - virtual bool RowDeleted( unsigned int row ) - { return m_model->ChildRowDeleted( row ); } - - virtual bool RowChanged( unsigned int row ) - { return m_model->ChildRowChanged( row ); } - - virtual bool ValueChanged( unsigned int col, unsigned int row ) - { return m_model->ChildValueChanged( col, row); } - - virtual bool RowsReordered( unsigned int *new_order ) - { return m_model->ChildRowsReordered( new_order ); } - - virtual bool Cleared() - { return m_model->ChildCleared(); } - - wxDataViewSortedListModel *m_model; -}; - -// --------------------------------------------------------- -// wxDataViewSortedListModel compare function -// --------------------------------------------------------- - -int wxCALLBACK wxDataViewListModelSortedDefaultCompare - (unsigned int row1, unsigned int row2, unsigned int col, wxDataViewListModel* model ) -{ - wxVariant value1,value2; - model->GetValue( value1, col, row1 ); - model->GetValue( value2, col, row2 ); - if (value1.GetType() == wxT("string")) - { - wxString str1 = value1.GetString(); - wxString str2 = value2.GetString(); - return str1.Cmp( str2 ); - } - if (value1.GetType() == wxT("long")) - { - long l1 = value1.GetLong(); - long l2 = value2.GetLong(); - return l1-l2; - } - if (value1.GetType() == wxT("double")) - { - double d1 = value1.GetDouble(); - double d2 = value2.GetDouble(); - if (d1 == d2) return 0; - if (d1 < d2) return 1; - return -1; - } - if (value1.GetType() == wxT("datetime")) - { - wxDateTime dt1 = value1.GetDateTime(); - wxDateTime dt2 = value2.GetDateTime(); - if (dt1.IsEqualTo(dt2)) return 0; - if (dt1.IsEarlierThan(dt2)) return 1; - return -1; - } - - return 0; -} - -int wxCALLBACK wxDataViewListModelSortedDefaultCompareDescending - (unsigned int row1, unsigned int row2, unsigned int col, wxDataViewListModel* model ) -{ - return wxDataViewListModelSortedDefaultCompare( row2, row1, col, model ); -} - -static wxDataViewListModelCompare s_CmpFunc; -static wxDataViewListModel *s_CmpModel; -static unsigned int s_CmpCol; - -int LINKAGEMODE wxDataViewIntermediateCmp( unsigned int row1, unsigned int row2 ) -{ - return s_CmpFunc( row1, row2, s_CmpCol, s_CmpModel ); -} - -// --------------------------------------------------------- -// wxDataViewSortedListModel -// --------------------------------------------------------- - -wxDataViewSortedListModel::wxDataViewSortedListModel( wxDataViewListModel *child ) : - m_array( wxDataViewIntermediateCmp ) -{ - m_child = child; - - m_ascending = true; - - m_notifierOnChild = new wxDataViewSortedListModelNotifier( this ); - m_child->AddNotifier( m_notifierOnChild ); - - m_child->IncRef(); - - Resort(); -} - -wxDataViewSortedListModel::~wxDataViewSortedListModel() -{ - DetachChild(); -} - -void wxDataViewSortedListModel::DetachChild() -{ - if (m_child) - { - m_child->RemoveNotifier( m_notifierOnChild ); - m_child->DecRef(); - } - - m_child = NULL; -} - -// FIXME -void wxDataViewSortedListModel::InitStatics() -{ - s_CmpCol = 0; - s_CmpModel = m_child; - if (m_ascending) - s_CmpFunc = wxDataViewListModelSortedDefaultCompare; - else - s_CmpFunc = wxDataViewListModelSortedDefaultCompareDescending; -} - -void wxDataViewSortedListModel::Resort() -{ - InitStatics(); - - if (!m_child) return; - - unsigned int n = m_child->GetRowCount(); - - unsigned int i; - if (n != m_array.GetCount()) - { - // probably sorted for the first time -> no reordered - // -- just create index and leave - m_array.Clear(); - for (i = 0; i < n; i++) - m_array.Add( i ); - return; - } - - unsigned int *old_array = new unsigned int[ n ]; - - for (i = 0; i < n; i++) - old_array[i] = m_array[ i ]; - - m_array.Clear(); - for (i = 0; i < n; i++) - m_array.Add( i ); - - unsigned int *order = new unsigned int[ n ]; - - for (i = 0; i < n; i++) - { - unsigned int new_value = m_array[i]; - - unsigned int old_pos; - for (old_pos = 0; old_pos < n; old_pos++) - if (old_array[old_pos] == new_value) - break; - order[i] = old_pos; - } - - delete [] old_array; - - wxDataViewListModel::RowsReordered( order ); - - delete [] order; -} - -#if 0 -static void Dump( wxDataViewListModel *model, unsigned int col ) -{ - unsigned int n = model->GetRowCount(); - unsigned int i; - for (i = 0; i < n; i++) - { - wxVariant variant; - model->GetValue( variant, col, i ); - wxString tmp; - tmp = variant.GetString(); - wxPrintf( wxT("%d: %s\n"), (int) i, tmp.c_str() ); - } -} -#endif - -bool wxDataViewSortedListModel::ChildRowAppended() -{ - // no need to fix up array - - unsigned int len = m_array.GetCount(); - - unsigned int 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 - unsigned int i; - unsigned int len = m_array.GetCount(); - for (i = 0; i < len; i++) - { - unsigned int value = m_array[i]; - m_array[i] = value+1; - } - - unsigned int pos = m_array.Add( 0 ); - - if (pos == 0) - return wxDataViewListModel::RowPrepended(); - - if (pos == len) - return wxDataViewListModel::RowAppended(); - - return wxDataViewListModel::RowInserted( pos ); -} - -bool wxDataViewSortedListModel::ChildRowInserted( unsigned int before ) -{ - // fix up array - unsigned int i; - unsigned int len = m_array.GetCount(); - for (i = 0; i < len; i++) - { - unsigned int value = m_array[i]; - if (value >= before) - m_array[i] = value+1; - } - - unsigned int pos = m_array.Add( before ); - - if (pos == 0) - return wxDataViewListModel::RowPrepended(); - - if (pos == len) - return wxDataViewListModel::RowAppended(); - - return wxDataViewListModel::RowInserted( pos ); -} - -bool wxDataViewSortedListModel::ChildRowDeleted( unsigned int row ) -{ - unsigned int i; - unsigned int len = m_array.GetCount(); - int pos = -1; - for (i = 0; i < len; i++) - { - unsigned int 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( (unsigned int) pos ); - - return wxDataViewListModel::RowDeleted( (unsigned int) pos); -} - -bool wxDataViewSortedListModel::ChildRowChanged( unsigned int row ) -{ - unsigned int i; - unsigned int len = m_array.GetCount(); - - // Remove and readd sorted. Find out at which - // position it was and where it ended. - unsigned int 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. - unsigned int *order = new unsigned int[ 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( unsigned int col, unsigned int row ) -{ - unsigned int i; - unsigned int len = m_array.GetCount(); - - // Remove and readd sorted. Find out at which - // position it was and where it ended. - unsigned int 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::ValueChanged( col, start_pos ); - - // Create an array where order[old] -> new_pos, so that - // if nothing changed order[0] -> 0 etc. - unsigned int *order = new unsigned int[ 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::ChildRowsReordered( unsigned int *WXUNUSED(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(); -} - -unsigned int wxDataViewSortedListModel::GetRowCount() const -{ - if (!m_child) return 0; - - return m_child->GetRowCount(); -} - -unsigned int wxDataViewSortedListModel::GetColumnCount() const -{ - if (!m_child) return 0; - - return m_child->GetColumnCount(); -} - -wxString wxDataViewSortedListModel::GetColumnType( unsigned int col ) const -{ - return m_child->GetColumnType( col ); -} - -void wxDataViewSortedListModel::GetValue( wxVariant &variant, unsigned int col, unsigned int row ) const -{ - unsigned int child_row = m_array[row]; - m_child->GetValue( variant, col, child_row ); -} - -bool wxDataViewSortedListModel::SetValue( const wxVariant &variant, unsigned int col, unsigned int row ) -{ - unsigned int child_row = m_array[row]; - bool ret = m_child->SetValue( variant, col, child_row ); - - // Do nothing here as the change in the - // child model will be reported back. - - return ret; -} - -bool wxDataViewSortedListModel::RowAppended() -{ - // you can only append - bool ret = m_child->RowAppended(); - - // Do nothing here as the change in the - // child model will be reported back. - - return ret; -} - -bool wxDataViewSortedListModel::RowPrepended() -{ - // you can only append - bool ret = m_child->RowAppended(); - - // Do nothing here as the change in the - // child model will be reported back. - - return ret; -} - -bool wxDataViewSortedListModel::RowInserted( unsigned int WXUNUSED(before) ) -{ - // you can only append - bool ret = m_child->RowAppended(); - - // Do nothing here as the change in the - // child model will be reported back. - - return ret; -} - -bool wxDataViewSortedListModel::RowDeleted( unsigned int row ) -{ - unsigned int child_row = m_array[row]; - - bool ret = m_child->RowDeleted( child_row ); - - // Do nothing here as the change in the - // child model will be reported back. - - return ret; -} - -bool wxDataViewSortedListModel::RowChanged( unsigned int row ) -{ - unsigned int child_row = m_array[row]; - bool ret = m_child->RowChanged( child_row ); - - // Do nothing here as the change in the - // child model will be reported back. - - return ret; -} - -bool wxDataViewSortedListModel::ValueChanged( unsigned int col, unsigned int row ) -{ - unsigned int child_row = m_array[row]; - bool ret = m_child->ValueChanged( col, child_row ); - - // Do nothing here as the change in the - // child model will be reported back. - - return ret; -} - -bool wxDataViewSortedListModel::RowsReordered( unsigned int *WXUNUSED(new_order) ) -{ - // We sort them ourselves. - - return false; -} - -bool wxDataViewSortedListModel::Cleared() -{ - bool ret = m_child->Cleared(); - - // Do nothing here as the change in the - // child model will be reported back. - - return ret; -} - // --------------------------------------------------------- // wxDataViewRendererBase // --------------------------------------------------------- @@ -727,7 +138,6 @@ wxDataViewRendererBase::wxDataViewRendererBase( const wxString &varianttype, { m_variantType = varianttype; m_editorCtrl = NULL; - m_row = (unsigned int) -1; } const wxDataViewCtrl* wxDataViewRendererBase::GetView() const @@ -735,13 +145,13 @@ const wxDataViewCtrl* wxDataViewRendererBase::GetView() const return wx_const_cast(wxDataViewRendererBase*, this)->GetOwner()->GetOwner(); } -bool wxDataViewRendererBase::StartEditing( unsigned int row, wxRect labelRect ) +bool wxDataViewRendererBase::StartEditing( const wxDataViewItem &item, wxRect labelRect ) { - m_row = row; // remember for later + m_item = item; // remember for later unsigned int col = GetOwner()->GetModelColumn(); wxVariant value; - GetOwner()->GetOwner()->GetModel()->GetValue( value, col, row ); + GetOwner()->GetOwner()->GetModel()->GetValue( value, item, col ); m_editorCtrl = CreateEditorCtrl( GetOwner()->GetOwner()->GetMainWindow(), labelRect, value ); @@ -781,8 +191,8 @@ bool wxDataViewRendererBase::FinishEditing() return false; unsigned int col = GetOwner()->GetModelColumn(); - GetOwner()->GetOwner()->GetModel()->SetValue( value, col, m_row ); - GetOwner()->GetOwner()->GetModel()->ValueChanged( col, m_row ); + GetOwner()->GetOwner()->GetModel()->SetValue( value, m_item, col ); + GetOwner()->GetOwner()->GetModel()->ValueChanged( m_item, col ); // m_editorCtrl->PopEventHandler( true ); @@ -915,38 +325,35 @@ void wxDataViewColumnBase::SetFlags(int flags) } // --------------------------------------------------------- -// wxDataViewEventListModelNotifier +// wxDataViewEventModelNotifier // --------------------------------------------------------- -class WXDLLIMPEXP_ADV wxDataViewEventListModelNotifier: public wxDataViewListModelNotifier +class WXDLLIMPEXP_ADV wxDataViewEventModelNotifier: public wxDataViewModelNotifier { public: - wxDataViewEventListModelNotifier( wxDataViewCtrl *ctrl ) { m_ctrl = ctrl; } + wxDataViewEventModelNotifier( wxDataViewCtrl *ctrl ) { m_ctrl = ctrl; } - bool SendEvent( wxEventType event_type, unsigned int row = 0, unsigned int col = 0 ) + bool SendEvent( wxEventType event_type, const wxDataViewItem &item, unsigned int col = 0 ) { wxDataViewEvent event( event_type, m_ctrl->GetId() ); event.SetEventObject( m_ctrl ); event.SetModel( m_ctrl->GetModel() ); - event.SetRow( row ); + event.SetItem( item ); event.SetColumn( col ); m_ctrl->GetEventHandler()->ProcessEvent( event ); return true; } - virtual bool RowAppended() { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ROW_APPENDED ); } - virtual bool RowPrepended() { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ROW_PREPENDED ); } - virtual bool RowInserted( unsigned int before ) - { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ROW_INSERTED, before ); } - virtual bool RowDeleted( unsigned int row ) - { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ROW_DELETED, row ); } - virtual bool RowChanged( unsigned int row ) - { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ROW_CHANGED, row ); } - virtual bool ValueChanged( unsigned int col, unsigned int row ) - { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_VALUE_CHANGED, row, col ); } - virtual bool RowsReordered( unsigned int * WXUNUSED(new_order) ) - { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ROWS_REORDERED ); } - virtual bool Cleared() { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_CLEARED ); } + virtual bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ) + { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_ADDED, item ); } + virtual bool ItemDeleted( const wxDataViewItem &item ) + { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_DELETED, item ); } + virtual bool ItemChanged( const wxDataViewItem &item ) + { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_CHANGED, item ); } + virtual bool ValueChanged( const wxDataViewItem &item, unsigned int col ) + { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_VALUE_CHANGED, item, col ); } + virtual bool Cleared() + { return SendEvent( wxEVT_COMMAND_DATAVIEW_MODEL_CLEARED, wxDataViewItem(0) ); } private: wxDataViewCtrl *m_ctrl; @@ -984,7 +391,7 @@ wxDataViewCtrlBase::~wxDataViewCtrlBase() } } -bool wxDataViewCtrlBase::AssociateModel( wxDataViewListModel *model ) +bool wxDataViewCtrlBase::AssociateModel( wxDataViewModel *model ) { if (m_model) { @@ -1000,14 +407,14 @@ bool wxDataViewCtrlBase::AssociateModel( wxDataViewListModel *model ) if (m_model) { m_model->IncRef(); - m_eventNotifier = new wxDataViewEventListModelNotifier( (wxDataViewCtrl*) this ); + m_eventNotifier = new wxDataViewEventModelNotifier( (wxDataViewCtrl*) this ); m_model->AddNotifier( m_eventNotifier ); } return true; } -wxDataViewListModel* wxDataViewCtrlBase::GetModel() +wxDataViewModel* wxDataViewCtrlBase::GetModel() { return m_model; } @@ -1125,19 +532,16 @@ wxDataViewColumn* wxDataViewCtrlBase::GetColumn( unsigned int pos ) IMPLEMENT_DYNAMIC_CLASS(wxDataViewEvent,wxNotifyEvent) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ROW_SELECTED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ROW_ACTIVATED) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_SELECTED) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED) DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK) DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK) DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ROW_APPENDED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ROW_PREPENDED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ROW_INSERTED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ROW_DELETED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ROW_CHANGED) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_ADDED) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_DELETED) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_CHANGED) DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_VALUE_CHANGED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_ROWS_REORDERED) DEFINE_EVENT_TYPE(wxEVT_COMMAND_DATAVIEW_MODEL_CLEARED) #endif diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index 46bea947cc..17b3a894ee 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -50,158 +50,158 @@ class wxDataViewCtrl; extern bool g_blockEventsOnDrag; //----------------------------------------------------------------------------- -// define new GTK+ class wxGtkListStore +// define new GTK+ class wxGtkTreeModel //----------------------------------------------------------------------------- extern "C" { -#define GTK_TYPE_WX_LIST_STORE (gtk_wx_list_store_get_type ()) -#define GTK_WX_LIST_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_LIST_STORE, GtkWxListStore)) -#define GTK_WX_LIST_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_LIST_STORE, GtkWxListStoreClass)) -#define GTK_IS_WX_LIST_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_LIST_STORE)) -#define GTK_IS_WX_LIST_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_LIST_STORE)) -#define GTK_WX_LIST_STORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_LIST_STORE, GtkWxListStoreClass)) +#define GTK_TYPE_WX_TREE_MODEL (gtk_wx_tree_model_get_type ()) +#define GTK_WX_TREE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModel)) +#define GTK_WX_TREE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass)) +#define GTK_IS_WX_TREE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_TREE_MODEL)) +#define GTK_IS_WX_TREE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_TREE_MODEL)) +#define GTK_WX_TREE_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass)) -GType gtk_wx_list_store_get_type (void); +GType gtk_wx_tree_model_get_type (void); -typedef struct _GtkWxListStore GtkWxListStore; -typedef struct _GtkWxListStoreClass GtkWxListStoreClass; +typedef struct _GtkWxTreeModel GtkWxTreeModel; +typedef struct _GtkWxTreeModelClass GtkWxTreeModelClass; -struct _GtkWxListStore +struct _GtkWxTreeModel { GObject parent; /*< private >*/ gint stamp; - wxDataViewListModel *model; + wxDataViewModel *model; }; -struct _GtkWxListStoreClass +struct _GtkWxTreeModelClass { GObjectClass list_parent_class; }; -static GtkWxListStore *wxgtk_list_store_new (void); -static void wxgtk_list_store_init (GtkWxListStore *list_store); -static void wxgtk_list_store_class_init (GtkWxListStoreClass *klass); -static void wxgtk_list_store_tree_model_init (GtkTreeModelIface *iface); -static void wxgtk_list_store_finalize (GObject *object); -static GtkTreeModelFlags wxgtk_list_store_get_flags (GtkTreeModel *tree_model); -static gint wxgtk_list_store_get_n_columns (GtkTreeModel *tree_model); -static GType wxgtk_list_store_get_column_type (GtkTreeModel *tree_model, +static GtkWxTreeModel *wxgtk_tree_model_new (void); +static void wxgtk_tree_model_init (GtkWxTreeModel *tree_model); +static void wxgtk_tree_model_class_init (GtkWxTreeModelClass *klass); +static void wxgtk_tree_model_tree_model_init (GtkTreeModelIface *iface); +static void wxgtk_tree_model_finalize (GObject *object); +static GtkTreeModelFlags wxgtk_tree_model_get_flags (GtkTreeModel *tree_model); +static gint wxgtk_tree_model_get_n_columns (GtkTreeModel *tree_model); +static GType wxgtk_tree_model_get_column_type (GtkTreeModel *tree_model, gint index); -static gboolean wxgtk_list_store_get_iter (GtkTreeModel *tree_model, +static gboolean wxgtk_tree_model_get_iter (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path); -static GtkTreePath *wxgtk_list_store_get_path (GtkTreeModel *tree_model, +static GtkTreePath *wxgtk_tree_model_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter); -static void wxgtk_list_store_get_value (GtkTreeModel *tree_model, +static void wxgtk_tree_model_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value); -static gboolean wxgtk_list_store_iter_next (GtkTreeModel *tree_model, +static gboolean wxgtk_tree_model_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter); -static gboolean wxgtk_list_store_iter_children (GtkTreeModel *tree_model, +static gboolean wxgtk_tree_model_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent); -static gboolean wxgtk_list_store_iter_has_child (GtkTreeModel *tree_model, +static gboolean wxgtk_tree_model_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter); -static gint wxgtk_list_store_iter_n_children (GtkTreeModel *tree_model, +static gint wxgtk_tree_model_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *iter); -static gboolean wxgtk_list_store_iter_nth_child (GtkTreeModel *tree_model, +static gboolean wxgtk_tree_model_iter_nth_child (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n); -static gboolean wxgtk_list_store_iter_parent (GtkTreeModel *tree_model, +static gboolean wxgtk_tree_model_iter_parent (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child); static GObjectClass *list_parent_class = NULL; GType -gtk_wx_list_store_get_type (void) +gtk_wx_tree_model_get_type (void) { - static GType list_store_type = 0; + static GType tree_model_type = 0; - if (!list_store_type) + if (!tree_model_type) { - const GTypeInfo list_store_info = + const GTypeInfo tree_model_info = { - sizeof (GtkWxListStoreClass), + sizeof (GtkWxTreeModelClass), NULL, /* base_init */ NULL, /* base_finalize */ - (GClassInitFunc) wxgtk_list_store_class_init, + (GClassInitFunc) wxgtk_tree_model_class_init, NULL, /* class_finalize */ NULL, /* class_data */ - sizeof (GtkWxListStore), + sizeof (GtkWxTreeModel), 0, - (GInstanceInitFunc) wxgtk_list_store_init, + (GInstanceInitFunc) wxgtk_tree_model_init, }; - static const GInterfaceInfo tree_model_info = + static const GInterfaceInfo tree_model_iface_info = { - (GInterfaceInitFunc) wxgtk_list_store_tree_model_init, + (GInterfaceInitFunc) wxgtk_tree_model_tree_model_init, NULL, NULL }; - list_store_type = g_type_register_static (G_TYPE_OBJECT, "GtkWxListStore", - &list_store_info, (GTypeFlags)0 ); + tree_model_type = g_type_register_static (G_TYPE_OBJECT, "GtkWxTreeModel", + &tree_model_info, (GTypeFlags)0 ); - g_type_add_interface_static (list_store_type, + g_type_add_interface_static (tree_model_type, GTK_TYPE_TREE_MODEL, - &tree_model_info); + &tree_model_iface_info); } - return list_store_type; + return tree_model_type; } -static GtkWxListStore * -wxgtk_list_store_new(void) +static GtkWxTreeModel * +wxgtk_tree_model_new(void) { - GtkWxListStore *retval = (GtkWxListStore *) g_object_new (GTK_TYPE_WX_LIST_STORE, NULL); + GtkWxTreeModel *retval = (GtkWxTreeModel *) g_object_new (GTK_TYPE_WX_TREE_MODEL, NULL); return retval; } static void -wxgtk_list_store_class_init (GtkWxListStoreClass *klass) +wxgtk_tree_model_class_init (GtkWxTreeModelClass *klass) { list_parent_class = (GObjectClass*) g_type_class_peek_parent (klass); GObjectClass *object_class = (GObjectClass*) klass; - object_class->finalize = wxgtk_list_store_finalize; + object_class->finalize = wxgtk_tree_model_finalize; } static void -wxgtk_list_store_tree_model_init (GtkTreeModelIface *iface) -{ - iface->get_flags = wxgtk_list_store_get_flags; - iface->get_n_columns = wxgtk_list_store_get_n_columns; - iface->get_column_type = wxgtk_list_store_get_column_type; - iface->get_iter = wxgtk_list_store_get_iter; - iface->get_path = wxgtk_list_store_get_path; - iface->get_value = wxgtk_list_store_get_value; - iface->iter_next = wxgtk_list_store_iter_next; - iface->iter_children = wxgtk_list_store_iter_children; - iface->iter_has_child = wxgtk_list_store_iter_has_child; - iface->iter_n_children = wxgtk_list_store_iter_n_children; - iface->iter_nth_child = wxgtk_list_store_iter_nth_child; - iface->iter_parent = wxgtk_list_store_iter_parent; +wxgtk_tree_model_tree_model_init (GtkTreeModelIface *iface) +{ + iface->get_flags = wxgtk_tree_model_get_flags; + iface->get_n_columns = wxgtk_tree_model_get_n_columns; + iface->get_column_type = wxgtk_tree_model_get_column_type; + iface->get_iter = wxgtk_tree_model_get_iter; + iface->get_path = wxgtk_tree_model_get_path; + iface->get_value = wxgtk_tree_model_get_value; + iface->iter_next = wxgtk_tree_model_iter_next; + iface->iter_children = wxgtk_tree_model_iter_children; + iface->iter_has_child = wxgtk_tree_model_iter_has_child; + iface->iter_n_children = wxgtk_tree_model_iter_n_children; + iface->iter_nth_child = wxgtk_tree_model_iter_nth_child; + iface->iter_parent = wxgtk_tree_model_iter_parent; } static void -wxgtk_list_store_init (GtkWxListStore *list_store) +wxgtk_tree_model_init (GtkWxTreeModel *tree_model) { - list_store->model = NULL; - list_store->stamp = g_random_int(); + tree_model->model = NULL; + tree_model->stamp = g_random_int(); } static void -wxgtk_list_store_finalize (GObject *object) +wxgtk_tree_model_finalize (GObject *object) { - /* GtkWxListStore *list_store = GTK_WX_LIST_STORE (object); */ + /* GtkWxTreeModel *tree_model = GTK_WX_LIST_STORE (object); */ /* we need to sort out, which class deletes what */ - /* delete list_store->model; */ + /* delete tree_model->model; */ /* must chain up */ (* list_parent_class->finalize) (object); @@ -210,44 +210,37 @@ wxgtk_list_store_finalize (GObject *object) } // extern "C" //----------------------------------------------------------------------------- -// implement callbacks from wxGtkListStore class by letting -// them call the methods of wxWidgets' wxDataViewListModel +// implement callbacks from wxGtkTreeModel class by letting +// them call the methods of wxWidgets' wxDataViewModel //----------------------------------------------------------------------------- static GtkTreeModelFlags -wxgtk_list_store_get_flags (GtkTreeModel *tree_model) +wxgtk_tree_model_get_flags (GtkTreeModel *tree_model) { - g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), (GtkTreeModelFlags)0 ); + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (tree_model), (GtkTreeModelFlags)0 ); - // GTK+ list store uses a linked list for storing the - // items and a pointer to a child is used as the member - // field of a GtkTreeIter. This means that the iter is - // valid in the GtkListStore as long as the child exists. - // We use the index of the row and since the index of a - // specific row will change if a row above is deleted, - // the iter does not persist - return /* GTK_TREE_MODEL_ITERS_PERSIST | */ GTK_TREE_MODEL_LIST_ONLY; + return GTK_TREE_MODEL_ITERS_PERSIST; } static gint -wxgtk_list_store_get_n_columns (GtkTreeModel *tree_model) +wxgtk_tree_model_get_n_columns (GtkTreeModel *tree_model) { - GtkWxListStore *list_store = (GtkWxListStore *) tree_model; - g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), 0); + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), 0); - return list_store->model->GetColumnCount(); + return wxtree_model->model->GetColumnCount(); } static GType -wxgtk_list_store_get_column_type (GtkTreeModel *tree_model, +wxgtk_tree_model_get_column_type (GtkTreeModel *tree_model, gint index) { - GtkWxListStore *list_store = (GtkWxListStore *) tree_model; - g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), G_TYPE_INVALID); + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), G_TYPE_INVALID); GType gtype = G_TYPE_INVALID; - wxString wxtype = list_store->model->GetColumnType( (unsigned int) index ); + wxString wxtype = wxtree_model->model->GetColumnType( (unsigned int) index ); if (wxtype == wxT("string")) gtype = G_TYPE_STRING; @@ -260,61 +253,99 @@ wxgtk_list_store_get_column_type (GtkTreeModel *tree_model, } static gboolean -wxgtk_list_store_get_iter (GtkTreeModel *tree_model, +wxgtk_tree_model_get_iter (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path) { - GtkWxListStore *list_store = (GtkWxListStore *) tree_model; - g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), FALSE); + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE); - unsigned int i = (unsigned int)gtk_tree_path_get_indices (path)[0]; + wxDataViewModel *model = wxtree_model->model; + + int depth = gtk_tree_path_get_depth( path ); - if (i >= list_store->model->GetRowCount()) - return FALSE; + wxDataViewItem item; + + int i; + for (i = 0; i < depth; i++) + { + gint pos = gtk_tree_path_get_indices (path)[i]; + item = model->GetNthChild( item, (unsigned int) pos ); + + if (!item.IsOk()) + { + wxPrintf( wxT("wrong item from path\n") ); + return FALSE; + } + } - iter->stamp = list_store->stamp; - // user_data is just the index - iter->user_data = (gpointer) i; + iter->stamp = wxtree_model->stamp; + iter->user_data = (gpointer) item.GetID(); return TRUE; } static GtkTreePath * -wxgtk_list_store_get_path (GtkTreeModel *tree_model, +wxgtk_tree_model_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter) { - g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), NULL); - g_return_val_if_fail (iter->stamp == GTK_WX_LIST_STORE (tree_model)->stamp, NULL); + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), NULL); + g_return_val_if_fail (iter->stamp == GTK_WX_TREE_MODEL (wxtree_model)->stamp, NULL); GtkTreePath *retval = gtk_tree_path_new (); - // user_data is just the index - int i = (wxUIntPtr) iter->user_data; - gtk_tree_path_append_index (retval, i); + wxDataViewItem item( (wxUint32) iter->user_data ); + + wxDataViewModel *model = wxtree_model->model; + + while (item.IsOk()) + { + int n = 0; + wxDataViewItem parent = model->GetParent( item ); + + if (!parent.IsOk()) + wxPrintf( wxT("wrong parent\n") ); + + wxDataViewItem node = model->GetFirstChild( parent ); + + while (node.GetID() != item.GetID()) + { + node = model->GetNextSibling( node ); + + if (!node.IsOk()) + wxPrintf( wxT("wrong node\n") ); + + n++; + } + + gtk_tree_path_prepend_index( retval, n ); + + item = model->GetParent( item ); + } + return retval; } static void -wxgtk_list_store_get_value (GtkTreeModel *tree_model, +wxgtk_tree_model_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value) { - GtkWxListStore *list_store = (GtkWxListStore *) tree_model; - g_return_if_fail (GTK_IS_WX_LIST_STORE (tree_model) ); + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model; + g_return_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model) ); - wxDataViewListModel *model = list_store->model; + wxDataViewModel *model = wxtree_model->model; wxString mtype = model->GetColumnType( (unsigned int) column ); if (mtype == wxT("string")) { wxVariant variant; g_value_init( value, G_TYPE_STRING ); - model->GetValue( variant, - (unsigned int) column, - wxPtrToUInt(iter->user_data) ); + wxDataViewItem item( (wxUint32) iter->user_data ); + model->GetValue( variant, item, (unsigned int) column ); - // FIXME: we should support different encodings here - g_value_set_string( value, wxGTK_CONV_SYS(variant.GetString()) ); + g_value_set_string( value, variant.GetString().utf8_str() ); } else { @@ -323,97 +354,128 @@ wxgtk_list_store_get_value (GtkTreeModel *tree_model, } static gboolean -wxgtk_list_store_iter_next (GtkTreeModel *tree_model, +wxgtk_tree_model_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter) { - g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), FALSE); - GtkWxListStore *list_store = (GtkWxListStore *) tree_model; - - g_return_val_if_fail (list_store->stamp == iter->stamp, FALSE); + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); - int n = (wxUIntPtr) iter->user_data; + g_return_val_if_fail (wxtree_model->stamp == iter->stamp, FALSE); - if (n == -1) - return FALSE; + wxDataViewModel *model = wxtree_model->model; - if (n >= (int) list_store->model->GetRowCount()-1) + wxDataViewItem item( (wxUint32) iter->user_data ); + item = model->GetNextSibling( item ); + if (!item.IsOk()) return FALSE; - iter->user_data = (gpointer) ++n; + iter->user_data = (gpointer) item.GetID(); return TRUE; } static gboolean -wxgtk_list_store_iter_children (GtkTreeModel *tree_model, +wxgtk_tree_model_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent) { - g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), FALSE); - GtkWxListStore *list_store = (GtkWxListStore *) tree_model; + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); - // this is a list, nodes have no children - if (parent) + g_return_val_if_fail (wxtree_model->stamp == parent->stamp, FALSE); + + wxDataViewModel *model = wxtree_model->model; + + wxDataViewItem item( (wxUint32) parent->user_data ); + item = model->GetFirstChild( item ); + if (!item.IsOk()) return FALSE; - iter->stamp = list_store->stamp; - iter->user_data = (gpointer) -1; + iter->stamp = wxtree_model->stamp; + iter->user_data = (gpointer) item.GetID(); return TRUE; } static gboolean -wxgtk_list_store_iter_has_child (GtkTreeModel *tree_model, +wxgtk_tree_model_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter) { - return FALSE; + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); + + g_return_val_if_fail (wxtree_model->stamp == iter->stamp, FALSE); + + wxDataViewModel *model = wxtree_model->model; + + wxDataViewItem item( (wxUint32) iter->user_data ); + + return model->HasChildren( item ); } static gint -wxgtk_list_store_iter_n_children (GtkTreeModel *tree_model, +wxgtk_tree_model_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *iter) { - g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), -1); - GtkWxListStore *list_store = (GtkWxListStore *) tree_model; - - if (iter == NULL) - return (gint) list_store->model->GetRowCount(); + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); - g_return_val_if_fail (list_store->stamp == iter->stamp, -1); - - return 0; + g_return_val_if_fail (wxtree_model->stamp == iter->stamp, 0); + + wxDataViewModel *model = wxtree_model->model; + + wxDataViewItem item( (wxUint32) iter->user_data ); + + return model->GetChildCount( item ); } static gboolean -wxgtk_list_store_iter_nth_child (GtkTreeModel *tree_model, +wxgtk_tree_model_iter_nth_child (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n) { - g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), FALSE); - GtkWxListStore *list_store = (GtkWxListStore *) tree_model; - - if (parent) + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); + + g_return_val_if_fail (wxtree_model->stamp == parent->stamp, FALSE); + + wxDataViewModel *model = wxtree_model->model; + + wxDataViewItem item( (wxUint32) parent->user_data ); + item = model->GetNthChild( item, n ); + + if (!item.IsOk()) return FALSE; - - if (n < 0) - return FALSE; - - if (n >= (gint) list_store->model->GetRowCount()) - return FALSE; - - iter->stamp = list_store->stamp; - iter->user_data = (gpointer) n; + + iter->stamp = wxtree_model->stamp; + iter->user_data = (gpointer) item.GetID(); return TRUE; } static gboolean -wxgtk_list_store_iter_parent (GtkTreeModel *tree_model, +wxgtk_tree_model_iter_parent (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child) { - return FALSE; + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); + + g_return_val_if_fail (wxtree_model->stamp == child->stamp, FALSE); + + wxDataViewModel *model = wxtree_model->model; + + wxDataViewItem item( (wxUint32) child->user_data ); + item = model->GetParent( item ); + + if (!item.IsOk()) + return FALSE; + + iter->stamp = wxtree_model->stamp; + iter->user_data = (gpointer) item.GetID(); + + return TRUE; } //----------------------------------------------------------------------------- @@ -722,7 +784,7 @@ gtk_wx_cell_renderer_activate( wxRect renderrect( rect.x, rect.y, rect.width, rect.height ); - wxDataViewListModel *model = cell->GetOwner()->GetOwner()->GetModel(); + wxDataViewModel *model = cell->GetOwner()->GetOwner()->GetModel(); GtkTreePath *treepath = gtk_tree_path_new_from_string( path ); unsigned int model_row = (unsigned int)gtk_tree_path_get_indices (treepath)[0]; @@ -771,28 +833,25 @@ gtk_wx_cell_renderer_activate( } // --------------------------------------------------------- -// wxGtkDataViewListModelNotifier +// wxGtkDataViewModelNotifier // --------------------------------------------------------- -class wxGtkDataViewListModelNotifier: public wxDataViewListModelNotifier +class wxGtkDataViewModelNotifier: public wxDataViewModelNotifier { public: - wxGtkDataViewListModelNotifier( GtkWxListStore* gtk_store, - wxDataViewListModel *wx_model, - wxDataViewCtrl* ctrl ); - ~wxGtkDataViewListModelNotifier(); - - virtual bool RowAppended(); - virtual bool RowPrepended(); - virtual bool RowInserted( unsigned int before ); - virtual bool RowDeleted( unsigned int row ); - virtual bool RowChanged( unsigned int row ); - virtual bool ValueChanged( unsigned int col, unsigned int row ); - virtual bool RowsReordered( unsigned int *new_order ); + wxGtkDataViewModelNotifier( GtkWxTreeModel *wxgtk_model, + wxDataViewModel *wx_model, + wxDataViewCtrl *ctrl ); + ~wxGtkDataViewModelNotifier(); + + virtual bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ); + virtual bool ItemDeleted( const wxDataViewItem &item ); + virtual bool ItemChanged( const wxDataViewItem &item ); + virtual bool ValueChanged( const wxDataViewItem &item, unsigned int col ); virtual bool Cleared(); - GtkWxListStore *m_gtk_store; - wxDataViewListModel *m_wx_model; + GtkWxTreeModel *m_wxgtk_model; + wxDataViewModel *m_wx_model; wxDataViewCtrl *m_owner; }; @@ -800,88 +859,67 @@ public: // wxGtkDataViewListModelNotifier // --------------------------------------------------------- -wxGtkDataViewListModelNotifier::wxGtkDataViewListModelNotifier( - GtkWxListStore* gtk_store, wxDataViewListModel *wx_model, +wxGtkDataViewModelNotifier::wxGtkDataViewModelNotifier( + GtkWxTreeModel* wxgtk_model, wxDataViewModel *wx_model, wxDataViewCtrl *ctrl ) { - m_gtk_store = gtk_store; + m_wxgtk_model = wxgtk_model; m_wx_model = wx_model; m_owner = ctrl; } -wxGtkDataViewListModelNotifier::~wxGtkDataViewListModelNotifier() +wxGtkDataViewModelNotifier::~wxGtkDataViewModelNotifier() { m_wx_model = NULL; - m_gtk_store = NULL; + m_wxgtk_model = NULL; } -bool wxGtkDataViewListModelNotifier::RowAppended() +bool wxGtkDataViewModelNotifier::ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ) { - unsigned int pos = m_wx_model->GetRowCount()-1; - GtkTreeIter iter; - iter.stamp = m_gtk_store->stamp; - iter.user_data = (gpointer) pos; + iter.stamp = m_wxgtk_model->stamp; + iter.user_data = (gpointer) item.GetID(); - GtkTreePath *path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, (gint) pos); - gtk_tree_model_row_inserted (GTK_TREE_MODEL (m_gtk_store), path, &iter); + GtkTreePath *path = wxgtk_tree_model_get_path( + GTK_TREE_MODEL(m_wxgtk_model), &iter ); + gtk_tree_model_row_inserted( + GTK_TREE_MODEL(m_wxgtk_model), path, &iter); gtk_tree_path_free (path); return true; } -bool wxGtkDataViewListModelNotifier::RowPrepended() +bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem &item ) { GtkTreeIter iter; - iter.stamp = m_gtk_store->stamp; - iter.user_data = (gpointer) 0; + iter.stamp = m_wxgtk_model->stamp; + iter.user_data = (gpointer) item.GetID(); - GtkTreePath *path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, (gint) 0); - gtk_tree_model_row_inserted (GTK_TREE_MODEL (m_gtk_store), path, &iter); + GtkTreePath *path = wxgtk_tree_model_get_path( + GTK_TREE_MODEL(m_wxgtk_model), &iter ); + gtk_tree_model_row_deleted( + GTK_TREE_MODEL(m_wxgtk_model), path ); gtk_tree_path_free (path); return true; } -bool wxGtkDataViewListModelNotifier::RowInserted( unsigned int before ) +bool wxGtkDataViewModelNotifier::ItemChanged( const wxDataViewItem &item ) { 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( unsigned int row ) -{ - 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; -} + iter.stamp = m_wxgtk_model->stamp; + iter.user_data = (gpointer) item.GetID(); -bool wxGtkDataViewListModelNotifier::RowChanged( unsigned int row ) -{ - GtkTreeIter iter; - iter.stamp = m_gtk_store->stamp; - iter.user_data = (gpointer) row; - GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (m_gtk_store), &iter); - gtk_tree_model_row_changed (GTK_TREE_MODEL (m_gtk_store), path, &iter); + GtkTreePath *path = wxgtk_tree_model_get_path( + GTK_TREE_MODEL(m_wxgtk_model), &iter ); + gtk_tree_model_row_changed( + GTK_TREE_MODEL(m_wxgtk_model), path, &iter ); gtk_tree_path_free (path); return true; } -bool wxGtkDataViewListModelNotifier::ValueChanged( unsigned int model_col, unsigned int model_row ) +bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem &item, unsigned int model_col ) { // This adds GTK+'s missing MVC logic for ValueChanged unsigned int index; @@ -894,8 +932,11 @@ bool wxGtkDataViewListModelNotifier::ValueChanged( unsigned int model_col, unsig GtkTreeViewColumn *gcolumn = GTK_TREE_VIEW_COLUMN(column->GetGtkHandle()); // Get cell area - GtkTreePath *path = gtk_tree_path_new(); - gtk_tree_path_append_index( path, model_row ); + GtkTreeIter iter; + iter.stamp = m_wxgtk_model->stamp; + iter.user_data = (gpointer) item.GetID(); + GtkTreePath *path = wxgtk_tree_model_get_path( + GTK_TREE_MODEL(m_wxgtk_model), &iter ); GdkRectangle cell_area; gtk_tree_view_get_cell_area( widget, path, gcolumn, &cell_area ); gtk_tree_path_free( path ); @@ -914,23 +955,7 @@ bool wxGtkDataViewListModelNotifier::ValueChanged( unsigned int model_col, unsig return true; } -bool wxGtkDataViewListModelNotifier::RowsReordered( unsigned int *new_order ) -{ - // Assume sizeof(unsigned int)= == sizeof(gint) - - GtkTreePath *path = gtk_tree_path_new (); - gtk_tree_model_rows_reordered (GTK_TREE_MODEL (m_gtk_store), path, NULL, (gint*)new_order); - gtk_tree_path_free (path); - - // This adds GTK+'s missing MVC logic for RowsReordered - GtkTreeView *widget = GTK_TREE_VIEW(m_owner->m_treeview); - // Doesn't work yet... - gtk_widget_queue_draw( GTK_WIDGET(widget) ); - - return true; -} - -bool wxGtkDataViewListModelNotifier::Cleared() +bool wxGtkDataViewModelNotifier::Cleared() { return false; } @@ -1084,7 +1109,7 @@ static void wxGtkTextRendererEditedCallback( GtkCellRendererText *renderer, if (!cell->Validate( value )) return; - wxDataViewListModel *model = cell->GetOwner()->GetOwner()->GetModel(); + wxDataViewModel *model = cell->GetOwner()->GetOwner()->GetModel(); GtkTreePath *path = gtk_tree_path_new_from_string( arg1 ); unsigned int model_row = (unsigned int)gtk_tree_path_get_indices (path)[0]; @@ -1256,7 +1281,7 @@ static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle *renderer, if (!cell->Validate( value )) return; - wxDataViewListModel *model = cell->GetOwner()->GetOwner()->GetModel(); + wxDataViewModel *model = cell->GetOwner()->GetOwner()->GetModel(); GtkTreePath *gtk_path = gtk_tree_path_new_from_string( path ); unsigned int model_row = (unsigned int)gtk_tree_path_get_indices (gtk_path)[0]; @@ -1496,12 +1521,12 @@ class wxDataViewDateRendererPopupTransient: public wxPopupTransientWindow { public: wxDataViewDateRendererPopupTransient( wxWindow* parent, wxDateTime *value, - wxDataViewListModel *model, unsigned int col, unsigned int row ) : + wxDataViewModel *model, const wxDataViewItem &item, unsigned int col ) : wxPopupTransientWindow( parent, wxBORDER_SIMPLE ) { m_model = model; + m_item = item; m_col = col; - m_row = row; m_cal = new wxCalendarCtrl( this, -1, *value ); wxBoxSizer *sizer = new wxBoxSizer( wxHORIZONTAL ); sizer->Add( m_cal, 1, wxGROW ); @@ -1515,10 +1540,10 @@ public: void OnCalendar( wxCalendarEvent &event ); - wxCalendarCtrl *m_cal; - wxDataViewListModel *m_model; - unsigned int m_col; - unsigned int m_row; + wxCalendarCtrl *m_cal; + wxDataViewModel *m_model; + wxDataViewItem m_item; + unsigned int m_col; private: DECLARE_EVENT_TABLE() @@ -1532,8 +1557,8 @@ void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent &event ) { wxDateTime date = event.GetDate(); wxVariant value = date; - m_model->SetValue( value, m_col, m_row ); - m_model->ValueChanged( m_col, m_row ); + m_model->SetValue( value, m_item, m_col ); + m_model->ValueChanged( m_item, m_col ); DismissAndNotify(); } @@ -1576,15 +1601,15 @@ wxSize wxDataViewDateRenderer::GetSize() const return wxSize(x,y+d); } -bool wxDataViewDateRenderer::Activate( wxRect cell, wxDataViewListModel *model, - unsigned int col, unsigned int row ) +bool wxDataViewDateRenderer::Activate( wxRect cell, wxDataViewModel *model, + const wxDataViewItem &item, unsigned int col ) { wxVariant variant; - model->GetValue( variant, col, row ); + model->GetValue( variant, item, col ); wxDateTime value = variant.GetDateTime(); wxDataViewDateRendererPopupTransient *popup = new wxDataViewDateRendererPopupTransient( - GetOwner()->GetOwner()->GetParent(), &value, model, col, row ); + GetOwner()->GetOwner()->GetParent(), &value, model, item, col ); wxPoint pos = wxGetMousePosition(); popup->Move( pos ); popup->Layout(); @@ -1633,15 +1658,15 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column, GtkTreeIter *iter, gpointer data ) { - g_return_if_fail (GTK_IS_WX_LIST_STORE (model)); - GtkWxListStore *list_store = (GtkWxListStore *) model; + g_return_if_fail (GTK_IS_WX_TREE_MODEL (model)); + GtkWxTreeModel *tree_model = (GtkWxTreeModel *) model; wxDataViewRenderer *cell = (wxDataViewRenderer*) data; - unsigned int model_row = wxPtrToUInt(iter->user_data); + wxDataViewItem item( (wxUint32) iter->user_data ); wxVariant value; - list_store->model->GetValue( value, cell->GetOwner()->GetModelColumn(), model_row ); + tree_model->model->GetValue( value, item, cell->GetOwner()->GetModelColumn() ); if (value.GetType() != cell->GetVariantType()) wxLogError( wxT("Wrong type, required: %s but: %s"), @@ -1650,8 +1675,9 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column, cell->SetValue( value ); +#if 0 wxListItemAttr attr; - list_store->model->GetAttr( attr, cell->GetOwner()->GetModelColumn(), model_row ); + tree_model->model->GetAttr( attr, cell->GetOwner()->GetModelColumn(), model_row ); if (attr.HasBackgroundColour()) { @@ -1672,6 +1698,8 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column, g_object_set_property( G_OBJECT(renderer), "cell-background-set", &gvalue ); g_value_unset( &gvalue ); } +#endif + } IMPLEMENT_CLASS(wxDataViewColumn, wxDataViewColumnBase) @@ -1922,8 +1950,8 @@ wxdataview_selection_changed_callback( GtkTreeSelection* selection, wxDataViewCt if (!GTK_WIDGET_REALIZED(dv->m_widget)) return; - wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ROW_SELECTED, dv->GetId() ); - event.SetRow( dv->GetSelection() ); + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_SELECTED, dv->GetId() ); + // TODO: item event.SetModel( dv->GetModel() ); dv->GetEventHandler()->ProcessEvent( event ); } @@ -1932,9 +1960,8 @@ static void wxdataview_row_activated_callback( GtkTreeView* treeview, GtkTreePath *path, GtkTreeViewColumn *column, wxDataViewCtrl *dv ) { - wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ROW_ACTIVATED, dv->GetId() ); - unsigned int row = (unsigned int)gtk_tree_path_get_indices (path)[0]; - event.SetRow( row ); + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, dv->GetId() ); + // TODO: item event.SetModel( dv->GetModel() ); dv->GetEventHandler()->ProcessEvent( event ); } @@ -2091,15 +2118,15 @@ void wxDataViewCtrl::OnInternalIdle() } } -bool wxDataViewCtrl::AssociateModel( wxDataViewListModel *model ) +bool wxDataViewCtrl::AssociateModel( wxDataViewModel *model ) { if (!wxDataViewCtrlBase::AssociateModel( model )) return false; - GtkWxListStore *gtk_store = wxgtk_list_store_new(); + GtkWxTreeModel *gtk_store = wxgtk_tree_model_new(); gtk_store->model = model; - m_notifier = new wxGtkDataViewListModelNotifier( gtk_store, model, this ); + m_notifier = new wxGtkDataViewModelNotifier( gtk_store, model, this ); model->AddNotifier( m_notifier ); @@ -2135,190 +2162,6 @@ void wxDataViewCtrl::GtkEnableSelectionEvents() (gpointer) (wxdataview_selection_changed_callback), this); } -void wxDataViewCtrl::SetSelection( int row ) -{ - GtkDisableSelectionEvents(); - - GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); - - if (row < 0) - { - gtk_tree_selection_unselect_all( selection ); - } - else - { - GtkTreePath *path = gtk_tree_path_new (); - gtk_tree_path_append_index( path, row ); - - gtk_tree_selection_select_path( selection, path ); - - gtk_tree_path_free( path ); - } - - GtkEnableSelectionEvents(); -} - -void wxDataViewCtrl::Unselect( unsigned int row ) -{ - GtkDisableSelectionEvents(); - - GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); - - GtkTreePath *path = gtk_tree_path_new (); - gtk_tree_path_append_index( path, row ); - - gtk_tree_selection_unselect_path( selection, path ); - - gtk_tree_path_free( path ); - - GtkEnableSelectionEvents(); -} - -void wxDataViewCtrl::SetSelectionRange( unsigned int from, unsigned int to ) -{ - GtkDisableSelectionEvents(); - - if (from > to) - { - unsigned int tmp = from; - from = to; - to = tmp; - } - - GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); - - GtkTreePath *path_from = gtk_tree_path_new (); - gtk_tree_path_append_index( path_from, from ); - GtkTreePath *path_to = gtk_tree_path_new (); - gtk_tree_path_append_index( path_to, to ); - - gtk_tree_selection_select_range( selection, path_from, path_to ); - - gtk_tree_path_free( path_to ); - gtk_tree_path_free( path_from ); - - GtkEnableSelectionEvents(); -} - -void wxDataViewCtrl::SetSelections( const wxArrayInt& aSelections) -{ - GtkDisableSelectionEvents(); - - GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); - - unsigned int i; - for (i = 0; i < aSelections.GetCount(); i++) - { - GtkTreePath *path = gtk_tree_path_new (); - gtk_tree_path_append_index( path, aSelections[i] ); - - gtk_tree_selection_select_path( selection, path ); - - gtk_tree_path_free( path ); - } - - GtkEnableSelectionEvents(); -} - -bool wxDataViewCtrl::IsSelected( unsigned int row ) const -{ - GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); - - GtkTreePath *path = gtk_tree_path_new (); - gtk_tree_path_append_index( path, row ); - - gboolean ret = gtk_tree_selection_path_is_selected( selection, path ); - - gtk_tree_path_free( path ); - - return ret; -} - -int wxDataViewCtrl::GetSelection() const -{ - GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); - if (HasFlag(wxDV_MULTIPLE)) - { - GtkTreeModel *model; - GList *list = gtk_tree_selection_get_selected_rows( selection, &model ); - - // do something - if (list) - { - // list = g_list_nth( list, 0 ); should be a noop - GtkTreePath *path = (GtkTreePath*) list->data; - - unsigned int row = (unsigned int)gtk_tree_path_get_indices (path)[0]; - - // delete list - g_list_foreach( list, (GFunc) gtk_tree_path_free, NULL ); - g_list_free( list ); - - return (int) row; - } - } - else - { - - GtkTreeModel *model; - GtkTreeIter iter; - gboolean has_selection = gtk_tree_selection_get_selected( selection, &model, &iter ); - if (has_selection) - { - unsigned int row = (wxUIntPtr) iter.user_data; - return (int) row; - } - } - - return -1; -} - -int wxDataViewCtrl::GetSelections(wxArrayInt& aSelections) const -{ - aSelections.Clear(); - - GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); - if (HasFlag(wxDV_MULTIPLE)) - { - GtkTreeModel *model; - GList *list = gtk_tree_selection_get_selected_rows( selection, &model ); - - int count = 0; - while (list) - { - - // list = g_list_nth( list, 0 ); should be a noop - GtkTreePath *path = (GtkTreePath*) list->data; - - unsigned int row = (unsigned int)gtk_tree_path_get_indices (path)[0]; - - aSelections.Add( (int) row ); - - list = g_list_next( list ); - } - - // delete list - g_list_foreach( list, (GFunc) gtk_tree_path_free, NULL ); - g_list_free( list ); - - return count; - } - else - { - GtkTreeModel *model; - GtkTreeIter iter; - gboolean has_selection = gtk_tree_selection_get_selected( selection, &model, &iter ); - if (has_selection) - { - unsigned int row = (wxUIntPtr) iter.user_data; - aSelections.Add( (int) row ); - return 1; - } - } - - return 0; -} - // static wxVisualAttributes wxDataViewCtrl::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))