diff --git a/include/wx/dataview.h b/include/wx/dataview.h index bb831d0df8..0d7f46cd8f 100644 --- a/include/wx/dataview.h +++ b/include/wx/dataview.h @@ -740,6 +740,7 @@ public: virtual void UnselectAll() = 0; void Expand( const wxDataViewItem & item ); + void ExpandChildren( const wxDataViewItem & item ); void ExpandAncestors( const wxDataViewItem & item ); virtual void Collapse( const wxDataViewItem & item ) = 0; virtual bool IsExpanded( const wxDataViewItem & item ) const = 0; @@ -793,7 +794,9 @@ protected: // Just expand this item assuming it is already shown, i.e. its parent has // been already expanded using ExpandAncestors(). - virtual void DoExpand(const wxDataViewItem & item) = 0; + // + // If expandChildren is true, also expand all its children recursively. + virtual void DoExpand(const wxDataViewItem & item, bool expandChildren) = 0; private: // Implementation of the public Set/GetCurrentItem() methods which are only diff --git a/include/wx/generic/dataview.h b/include/wx/generic/dataview.h index d15991e810..b773882488 100644 --- a/include/wx/generic/dataview.h +++ b/include/wx/generic/dataview.h @@ -364,7 +364,7 @@ private: virtual wxDataViewItem DoGetCurrentItem() const wxOVERRIDE; virtual void DoSetCurrentItem(const wxDataViewItem& item) wxOVERRIDE; - virtual void DoExpand(const wxDataViewItem& item) wxOVERRIDE; + virtual void DoExpand(const wxDataViewItem& item, bool expandChildren) wxOVERRIDE; void InvalidateColBestWidths(); void InvalidateColBestWidth(int idx); diff --git a/include/wx/gtk/dataview.h b/include/wx/gtk/dataview.h index ae2d2f0165..b5933cd33a 100644 --- a/include/wx/gtk/dataview.h +++ b/include/wx/gtk/dataview.h @@ -218,7 +218,7 @@ protected: virtual void DoSetExpanderColumn() wxOVERRIDE; virtual void DoSetIndent() wxOVERRIDE; - virtual void DoExpand(const wxDataViewItem& item) wxOVERRIDE; + virtual void DoExpand(const wxDataViewItem& item, bool expandChildren) wxOVERRIDE; virtual void DoApplyWidgetStyle(GtkRcStyle *style) wxOVERRIDE; virtual GdkWindow* GTKGetWindow(wxArrayGdkWindows& windows) const wxOVERRIDE; diff --git a/include/wx/osx/cocoa/dataview.h b/include/wx/osx/cocoa/dataview.h index 41d16201d8..97b2946ede 100644 --- a/include/wx/osx/cocoa/dataview.h +++ b/include/wx/osx/cocoa/dataview.h @@ -530,7 +530,7 @@ public: // virtual void DoSetIndent(int indent); - virtual void DoExpand(const wxDataViewItem& item); + virtual void DoExpand(const wxDataViewItem& item, bool expandChildren); virtual void HitTest(const wxPoint& point, wxDataViewItem& item, diff --git a/include/wx/osx/core/dataview.h b/include/wx/osx/core/dataview.h index f3ac6d33fd..c9b7bde6ae 100644 --- a/include/wx/osx/core/dataview.h +++ b/include/wx/osx/core/dataview.h @@ -105,7 +105,7 @@ public: // other methods // virtual void DoSetIndent (int indent) = 0; // sets the indentation in the native control - virtual void DoExpand (wxDataViewItem const& item) = 0; // expands the passed item in the native control + virtual void DoExpand (wxDataViewItem const& item, bool expandChildren) = 0; // expands the passed item in the native control virtual void HitTest (wxPoint const& point, wxDataViewItem& item, wxDataViewColumn*& columnPtr) const = 0; // return the item and column pointer that contains with the passed point virtual void SetRowHeight(int height) = 0; // sets the height of all rows diff --git a/include/wx/osx/dataview.h b/include/wx/osx/dataview.h index a7a58d6f54..28e4d557c2 100644 --- a/include/wx/osx/dataview.h +++ b/include/wx/osx/dataview.h @@ -276,7 +276,7 @@ protected: virtual void DoSetExpanderColumn() wxOVERRIDE; virtual void DoSetIndent() wxOVERRIDE; - virtual void DoExpand(const wxDataViewItem& item) wxOVERRIDE; + virtual void DoExpand(const wxDataViewItem& item, bool expandChildren) wxOVERRIDE; virtual wxSize DoGetBestSize() const wxOVERRIDE; diff --git a/include/wx/qt/dataview.h b/include/wx/qt/dataview.h index b61f803f75..778bda4d67 100644 --- a/include/wx/qt/dataview.h +++ b/include/wx/qt/dataview.h @@ -131,7 +131,7 @@ public: protected: virtual void DoSetExpanderColumn(); virtual void DoSetIndent(); - virtual void DoExpand( const wxDataViewItem & item ); + virtual void DoExpand( const wxDataViewItem & item, bool expandChildren ); private: virtual wxDataViewItem DoGetCurrentItem() const; diff --git a/interface/wx/dataview.h b/interface/wx/dataview.h index 76266e4126..582af1ac53 100644 --- a/interface/wx/dataview.h +++ b/interface/wx/dataview.h @@ -1402,6 +1402,16 @@ public: */ void ExpandAncestors( const wxDataViewItem & item ); + /** + Expand all all children of the given item recursively. + + This is the same as calling Expand() on the @a item itself and then + calling it for all of its children, grandchildren etc recursively. + + @since 3.1.5 + */ + void ExpandChildren( const wxDataViewItem & item ); + /** Returns pointer to the column. @a pos refers to the position in the control which may change after reordering columns by the user. diff --git a/src/common/datavcmn.cpp b/src/common/datavcmn.cpp index 14609bbccd..1f5fd4d66b 100644 --- a/src/common/datavcmn.cpp +++ b/src/common/datavcmn.cpp @@ -1265,7 +1265,14 @@ void wxDataViewCtrlBase::Expand(const wxDataViewItem& item) { ExpandAncestors(item); - DoExpand(item); + DoExpand(item, false); +} + +void wxDataViewCtrlBase::ExpandChildren(const wxDataViewItem& item) +{ + ExpandAncestors(item); + + DoExpand(item, true); } void wxDataViewCtrlBase::ExpandAncestors( const wxDataViewItem & item ) @@ -1287,7 +1294,7 @@ void wxDataViewCtrlBase::ExpandAncestors( const wxDataViewItem & item ) // then we expand the parents, starting at the root while (!parentChain.empty()) { - DoExpand(parentChain.back()); + DoExpand(parentChain.back(), false); parentChain.pop_back(); } } diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 4b3ae669ec..d2c5a03a75 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -874,7 +874,7 @@ public: void HitTest( const wxPoint & point, wxDataViewItem & item, wxDataViewColumn* &column ); wxRect GetItemRect( const wxDataViewItem & item, const wxDataViewColumn* column ); - void Expand( unsigned int row ); + void Expand( unsigned int row, bool expandChildren = false ); void Collapse( unsigned int row ); bool IsExpanded( unsigned int row ) const; bool HasChildren( unsigned int row ) const; @@ -990,6 +990,9 @@ private: return NULL; } + // Helper of public Expand(), must be called with a valid node. + void DoExpand(wxDataViewTreeNode* node, unsigned int row, bool expandChildren); + private: wxDataViewCtrl *m_owner; int m_lineHeight; @@ -3907,7 +3910,7 @@ bool wxDataViewMainWindow::HasChildren( unsigned int row ) const return true; } -void wxDataViewMainWindow::Expand( unsigned int row ) +void wxDataViewMainWindow::Expand( unsigned int row, bool expandChildren ) { if (IsList()) return; @@ -3916,6 +3919,14 @@ void wxDataViewMainWindow::Expand( unsigned int row ) if (!node) return; + return DoExpand(node, row, expandChildren); +} + +void +wxDataViewMainWindow::DoExpand(wxDataViewTreeNode* node, + unsigned int row, + bool expandChildren) +{ if (!node->HasChildren()) return; @@ -3961,6 +3972,28 @@ void wxDataViewMainWindow::Expand( unsigned int row ) // Send the expanded event SendExpanderEvent(wxEVT_DATAVIEW_ITEM_EXPANDED,node->GetItem()); } + + // Note that we have to expand the children when expanding recursively even + // when this node itself was already open. + if ( expandChildren ) + { + const wxDataViewTreeNodes& children = node->GetChildNodes(); + + for ( wxDataViewTreeNodes::const_iterator i = children.begin(); + i != children.end(); + ++i ) + { + wxDataViewTreeNode* const child = *i; + + // Row currently corresponds to the previous item, so increment it + // first to correspond to this child. + DoExpand(child, ++row, true); + + // We don't need +1 here because we'll increment the row during the + // next loop iteration. + row += child->GetSubTreeCount(); + } + } } void wxDataViewMainWindow::Collapse(unsigned int row) @@ -6309,11 +6342,11 @@ int wxDataViewCtrl::GetRowByItem( const wxDataViewItem & item ) const return m_clientArea->GetRowByItem( item ); } -void wxDataViewCtrl::DoExpand( const wxDataViewItem & item ) +void wxDataViewCtrl::DoExpand( const wxDataViewItem & item, bool expandChildren ) { int row = m_clientArea->GetRowByItem( item ); if (row != -1) - m_clientArea->Expand(row); + m_clientArea->Expand(row, expandChildren); } void wxDataViewCtrl::Collapse( const wxDataViewItem & item ) diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index 39c18815a3..43e13deb6e 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -5068,12 +5068,13 @@ wxDataViewColumn *wxDataViewCtrl::GetSortingColumn() const return m_internal->GetDataViewSortColumn(); } -void wxDataViewCtrl::DoExpand( const wxDataViewItem & item ) +void wxDataViewCtrl::DoExpand( const wxDataViewItem & item, bool expandChildren ) { GtkTreeIter iter; iter.user_data = item.GetID(); wxGtkTreePath path(m_internal->get_path( &iter )); - gtk_tree_view_expand_row( GTK_TREE_VIEW(m_treeview), path, false ); + gtk_tree_view_expand_row( GTK_TREE_VIEW(m_treeview), path, + expandChildren ? TRUE : FALSE ); } void wxDataViewCtrl::Collapse( const wxDataViewItem & item ) diff --git a/src/osx/cocoa/dataview.mm b/src/osx/cocoa/dataview.mm index 770719e4a9..9b5cc05f59 100644 --- a/src/osx/cocoa/dataview.mm +++ b/src/osx/cocoa/dataview.mm @@ -2314,9 +2314,9 @@ void wxCocoaDataViewControl::EnsureVisible(const wxDataViewItem& item, const wxD } } -void wxCocoaDataViewControl::DoExpand(const wxDataViewItem& item) +void wxCocoaDataViewControl::DoExpand(const wxDataViewItem& item, bool expandChildren) { - [m_OutlineView expandItem:[m_DataSource getDataViewItemFromBuffer:item]]; + [m_OutlineView expandItem:[m_DataSource getDataViewItemFromBuffer:item] expandChildren:expandChildren]; } unsigned int wxCocoaDataViewControl::GetCount() const diff --git a/src/osx/dataview_osx.cpp b/src/osx/dataview_osx.cpp index ad197cc85c..9812036eef 100644 --- a/src/osx/dataview_osx.cpp +++ b/src/osx/dataview_osx.cpp @@ -516,9 +516,9 @@ void wxDataViewCtrl::EnsureVisible(wxDataViewItem const& item, wxDataViewColumn } } -void wxDataViewCtrl::DoExpand(wxDataViewItem const& item) +void wxDataViewCtrl::DoExpand(wxDataViewItem const& item, bool expandChildren) { - return GetDataViewPeer()->DoExpand(item); + return GetDataViewPeer()->DoExpand(item, expandChildren); } bool wxDataViewCtrl::IsExpanded( const wxDataViewItem & item ) const diff --git a/src/qt/dataview.cpp b/src/qt/dataview.cpp index ee2b5177d8..61cf681ca0 100644 --- a/src/qt/dataview.cpp +++ b/src/qt/dataview.cpp @@ -267,7 +267,7 @@ wxRect wxDataViewCtrl::GetItemRect( const wxDataViewItem &item, return wxRect(); } -void wxDataViewCtrl::DoExpand( const wxDataViewItem & item ) +void wxDataViewCtrl::DoExpand( const wxDataViewItem & item, bool expandChildren ) { } diff --git a/tests/controls/dataviewctrltest.cpp b/tests/controls/dataviewctrltest.cpp index 2f88a0aa17..f970c886b2 100644 --- a/tests/controls/dataviewctrltest.cpp +++ b/tests/controls/dataviewctrltest.cpp @@ -271,6 +271,19 @@ TEST_CASE_METHOD(SingleSelectDataViewCtrlTestCase, CHECK( !m_dvc->IsExpanded(m_grandchild) ); #endif CHECK( !m_dvc->IsExpanded(m_child2) ); + + m_dvc->Collapse(m_root); + CHECK( !m_dvc->IsExpanded(m_root) ); + + m_dvc->ExpandChildren(m_root); + CHECK( m_dvc->IsExpanded(m_root) ); + CHECK( m_dvc->IsExpanded(m_child1) ); + + // Expanding an already expanded node must still expand all its children. + m_dvc->Collapse(m_child1); + CHECK( !m_dvc->IsExpanded(m_child1) ); + m_dvc->ExpandChildren(m_root); + CHECK( m_dvc->IsExpanded(m_child1) ); } TEST_CASE_METHOD(SingleSelectDataViewCtrlTestCase,