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 57c7a8f072..c464cbd50e 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 e53695fcfb..778bda4d67 100644 --- a/include/wx/qt/dataview.h +++ b/include/wx/qt/dataview.h @@ -115,7 +115,6 @@ public: virtual wxRect GetItemRect( const wxDataViewItem &item, const wxDataViewColumn *column = NULL ) const; - virtual void Expand( const wxDataViewItem & item ); virtual void Collapse( const wxDataViewItem & item ); virtual bool IsExpanded( const wxDataViewItem & item ) const; @@ -132,6 +131,7 @@ public: protected: virtual void DoSetExpanderColumn(); virtual void DoSetIndent(); + 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/samples/dataview/dataview.cpp b/samples/dataview/dataview.cpp index 98630dc39a..db9150bb15 100644 --- a/samples/dataview/dataview.cpp +++ b/samples/dataview/dataview.cpp @@ -742,6 +742,9 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int mainSizer->Add( m_log, 0, wxGROW ); SetSizerAndFit(mainSizer); + + // Allow using the control from keyboard on startup. + m_ctrl[Page_Music]->SetFocus(); } MyFrame::~MyFrame() 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 2dfd7a953c..2e47cfbae8 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,16 +3919,17 @@ 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; - if ( m_rowHeightCache ) - { - // Expand makes new rows visible thus we invalidates all following - // rows in the height cache - m_rowHeightCache->Remove(row); - } - if (!node->IsOpen()) { if ( !SendExpanderEvent(wxEVT_DATAVIEW_ITEM_EXPANDING, node->GetItem()) ) @@ -3934,6 +3938,13 @@ void wxDataViewMainWindow::Expand( unsigned int row ) return; } + if ( m_rowHeightCache ) + { + // Expand makes new rows visible thus we invalidates all following + // rows in the height cache + m_rowHeightCache->Remove(row); + } + node->ToggleOpen(this); // build the children of current node @@ -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) @@ -4579,7 +4612,27 @@ void wxDataViewMainWindow::OnChar( wxKeyEvent &event ) case WXK_DOWN: OnVerticalNavigation(event, +1); break; - // Add the process for tree expanding/collapsing + + case '+': + case WXK_ADD: + Expand(m_currentRow); + break; + + case '*': + case WXK_MULTIPLY: + if ( !IsExpanded(m_currentRow) ) + { + Expand(m_currentRow, true /* recursively */); + break; + } + //else: fall through to Collapse() + wxFALLTHROUGH; + + case '-': + case WXK_SUBTRACT: + Collapse(m_currentRow); + break; + case WXK_LEFT: OnLeftKey(event); break; @@ -6309,11 +6362,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 77ff3da90a..40c4fd2c59 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 1b16d555e8..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::Expand( 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,