]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/datavgen.cpp
miscellaneous small enhancements
[wxWidgets.git] / src / generic / datavgen.cpp
index 7112252982747fee84a87527625893adffc052ef..388cd1b52ff26b154decd61de44674e9b2ac6eee 100644 (file)
@@ -91,7 +91,7 @@ public:
 protected:
     // implement/override wxHeaderCtrl functions by forwarding them to the main
     // control
-    virtual wxHeaderColumnBase& GetColumn(unsigned int idx)
+    virtual const wxHeaderColumn& GetColumn(unsigned int idx) const
     {
         return *(GetOwner()->GetColumn(idx));
     }
@@ -125,9 +125,46 @@ private:
 
     void OnClick(wxHeaderCtrlEvent& event)
     {
-        if ( !SendEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK,
-                        event.GetColumn()) )
+        const unsigned idx = event.GetColumn();
+
+        if ( SendEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK, idx) )
+            return;
+
+        // default handling for the column click is to sort by this column or
+        // toggle its sort order
+        wxDataViewCtrl * const owner = GetOwner();
+        wxDataViewColumn * const col = owner->GetColumn(idx);
+        if ( !col->IsSortable() )
+        {
+            // no default handling for non-sortable columns
             event.Skip();
+            return;
+        }
+
+        if ( col->IsSortKey() )
+        {
+            // already using this column for sorting, just change the order
+            col->ToggleSortOrder();
+        }
+        else // not using this column for sorting yet
+        {
+            // first unset the old sort column if any
+            int oldSortKey = owner->GetSortingColumnIndex();
+            if ( oldSortKey != wxNOT_FOUND )
+            {
+                owner->GetColumn(oldSortKey)->UnsetAsSortKey();
+                owner->OnColumnChange(oldSortKey);
+            }
+
+            owner->SetSortingColumnIndex(idx);
+            col->SetAsSortKey();
+        }
+
+        wxDataViewModel * const model = owner->GetModel();
+        if ( model )
+            model->Resort();
+
+        owner->OnColumnChange(idx);
     }
 
     void OnRClick(wxHeaderCtrlEvent& event)
@@ -137,29 +174,20 @@ private:
             event.Skip();
     }
 
-    void OnBeginResize(wxHeaderCtrlEvent& event)
-    {
-        if ( !GetColumn(event.GetColumn()).IsResizeable() )
-            event.Veto();
-    }
-
-    void OnResizing(wxHeaderCtrlEvent& event)
+    void OnEndResize(wxHeaderCtrlEvent& event)
     {
-        const wxHeaderColumnBase& col = GetColumn(event.GetColumn());
+        wxDataViewCtrl * const owner = GetOwner();
 
-        const int minWidth = col.GetMinWidth();
-        if ( event.GetWidth() < minWidth )
-            event.Veto();
+        const unsigned col = event.GetColumn();
+        owner->GetColumn(col)->SetWidth(event.GetWidth());
+        GetOwner()->OnColumnChange(col);
     }
 
-    void OnEndResize(wxHeaderCtrlEvent& event)
+    void OnEndReorder(wxHeaderCtrlEvent& event)
     {
-        if ( !event.IsCancelled() )
-        {
-            const unsigned col = event.GetColumn();
-            GetColumn(col).SetWidth(event.GetWidth());
-            GetOwner()->OnColumnChange(col);
-        }
+        wxDataViewCtrl * const owner = GetOwner();
+        owner->ColumnMoved(owner->GetColumn(event.GetColumn()),
+                           event.GetNewOrder());
     }
 
     DECLARE_EVENT_TABLE()
@@ -170,9 +198,9 @@ BEGIN_EVENT_TABLE(wxDataViewHeaderWindow, wxHeaderCtrl)
     EVT_HEADER_CLICK(wxID_ANY, wxDataViewHeaderWindow::OnClick)
     EVT_HEADER_RIGHT_CLICK(wxID_ANY, wxDataViewHeaderWindow::OnRClick)
 
-    EVT_HEADER_BEGIN_RESIZE(wxID_ANY, wxDataViewHeaderWindow::OnBeginResize)
-    EVT_HEADER_RESIZING(wxID_ANY, wxDataViewHeaderWindow::OnResizing)
     EVT_HEADER_END_RESIZE(wxID_ANY, wxDataViewHeaderWindow::OnEndResize)
+
+    EVT_HEADER_END_REORDER(wxID_ANY, wxDataViewHeaderWindow::OnEndReorder)
 END_EVENT_TABLE()
 
 //-----------------------------------------------------------------------------
@@ -455,6 +483,7 @@ public:
 
     void Expand( unsigned int row ) { OnExpanding( row ); }
     void Collapse( unsigned int row ) { OnCollapsing( row ); }
+    bool IsExpanded( unsigned int row ) const;
 private:
     wxDataViewTreeNode * GetTreeNodeByRow( unsigned int row ) const;
     //We did not need this temporarily
@@ -1207,7 +1236,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
     unsigned int x_start;
     for (x_start = 0; col_start < cols; col_start++)
     {
-        wxDataViewColumn *col = GetOwner()->GetColumn(col_start);
+        wxDataViewColumn *col = GetOwner()->GetColumnAt(col_start);
         if (col->IsHidden())
             continue;      // skip it!
 
@@ -1222,7 +1251,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
     unsigned int x_last = x_start;
     for (; col_last < cols; col_last++)
     {
-        wxDataViewColumn *col = GetOwner()->GetColumn(col_last);
+        wxDataViewColumn *col = GetOwner()->GetColumnAt(col_last);
         if (col->IsHidden())
             continue;      // skip it!
 
@@ -1254,7 +1283,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
         int x = x_start;
         for (unsigned int i = col_start; i < col_last; i++)
         {
-            wxDataViewColumn *col = GetOwner()->GetColumn(i);
+            wxDataViewColumn *col = GetOwner()->GetColumnAt(i);
             if (col->IsHidden())
                 continue;       // skip it
 
@@ -1295,8 +1324,8 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
     wxDataViewColumn *expander = GetOwner()->GetExpanderColumn();
     if (!expander)
     {
-        // TODO: last column for RTL support
-        expander = GetOwner()->GetColumn( 0 );
+        // TODO-RTL: last column for RTL support
+        expander = GetOwner()->GetColumnAt( 0 );
         GetOwner()->SetExpanderColumn(expander);
     }
 
@@ -1306,7 +1335,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
     for (unsigned int i = col_start; i < col_last; i++)
     {
 
-        wxDataViewColumn *col = GetOwner()->GetColumn( i );
+        wxDataViewColumn *col = GetOwner()->GetColumnAt( i );
         wxDataViewRenderer *cell = col->GetRenderer();
         cell_rect.width = col->GetWidth();
 
@@ -1456,7 +1485,7 @@ void wxDataViewMainWindow::OnRenameTimer()
     unsigned int i;
     for (i = 0; i < cols; i++)
     {
-        wxDataViewColumn *c = GetOwner()->GetColumn( i );
+        wxDataViewColumn *c = GetOwner()->GetColumnAt( i );
         if (c->IsHidden())
             continue;      // skip it!
 
@@ -1767,7 +1796,7 @@ void wxDataViewMainWindow::ScrollTo( int rows, int column )
         m_owner->CalcUnscrolledPosition( rect.x, rect.y, &xx, &yy );
         for (x_start = 0; colnum < column; colnum++)
         {
-            wxDataViewColumn *col = GetOwner()->GetColumn(colnum);
+            wxDataViewColumn *col = GetOwner()->GetColumnAt(colnum);
             if (col->IsHidden())
                 continue;      // skip it!
 
@@ -1802,7 +1831,7 @@ int wxDataViewMainWindow::GetEndOfLastCol() const
     for (i = 0; i < GetOwner()->GetColumnCount(); i++)
     {
         const wxDataViewColumn *c =
-            const_cast<wxDataViewCtrl*>(GetOwner())->GetColumn( i );
+            const_cast<wxDataViewCtrl*>(GetOwner())->GetColumnAt( i );
 
         if (!c->IsHidden())
             width += c->GetWidth();
@@ -2383,6 +2412,23 @@ wxDataViewEvent wxDataViewMainWindow::SendExpanderEvent( wxEventType type, const
     return le;
 }
 
+
+bool wxDataViewMainWindow::IsExpanded( unsigned int row ) const
+{
+    if (IsVirtualList())
+       return false;
+       
+    wxDataViewTreeNode * node = GetTreeNodeByRow(row);
+    if (!node)
+       return false;
+       
+    if (!node->HasChildren())
+       return false;
+    
+    return node->IsOpen();
+}
+
+
 void wxDataViewMainWindow::OnExpanding( unsigned int row )
 {
     if (IsVirtualList())
@@ -2529,7 +2575,7 @@ void wxDataViewMainWindow::HitTest( const wxPoint & point, wxDataViewItem & item
     m_owner->CalcUnscrolledPosition( point.x, point.y, &x, &y );
     for (unsigned x_start = 0; colnum < cols; colnum++)
     {
-        col = GetOwner()->GetColumn(colnum);
+        col = GetOwner()->GetColumnAt(colnum);
         if (col->IsHidden())
             continue;      // skip it!
 
@@ -2553,9 +2599,9 @@ wxRect wxDataViewMainWindow::GetItemRect( const wxDataViewItem & item, const wxD
     wxDataViewColumn *col = NULL;
     for( int i = 0, cols = GetOwner()->GetColumnCount(); i < cols; i ++ )
     {
-       col = GetOwner()->GetColumn( i );
+       col = GetOwner()->GetColumnAt( i );
        x += col->GetWidth();
-       if( GetOwner()->GetColumn(i+1) == column )
+       if( GetOwner()->GetColumnAt(i+1) == column )
            break;
     }
     int w = col->GetWidth();
@@ -2759,7 +2805,7 @@ void wxDataViewMainWindow::OnChar( wxKeyEvent &event )
     {
         case WXK_RETURN:
         {
-            if (m_currentRow > 0)
+            if (m_currentRow >= 0)
             {
                 wxWindow *parent = GetParent();
                 wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, parent->GetId());
@@ -2844,7 +2890,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
     unsigned int i;
     for (i = 0; i < cols; i++)
     {
-        wxDataViewColumn *c = GetOwner()->GetColumn( i );
+        wxDataViewColumn *c = GetOwner()->GetColumnAt( i );
         if (c->IsHidden())
             continue;      // skip it!
 
@@ -2860,7 +2906,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
 
     wxDataViewRenderer *cell = col->GetRenderer();
     unsigned int current = GetLineAt( y );
-    if ((current > GetRowCount()) || (x > GetEndOfLastCol()))
+    if ((current >= GetRowCount()) || (x > GetEndOfLastCol()))
     {
         // Unselect all if below the last row ?
         return;
@@ -2992,6 +3038,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
             // select single line
             SelectAllRows( false );
             SelectRow( m_lineSelectSingleOnUp, true );
+            SendSelectionChangedEvent( GetItemByRow(m_lineSelectSingleOnUp) );
         }
 
         //Process the event of user clicking the expander
@@ -3205,7 +3252,8 @@ void wxDataViewCtrl::Init()
     m_notifier = NULL;
 
     // No sorting column at start
-    m_sortingColumn = NULL;
+    m_sortingColumnIdx = wxNOT_FOUND;
+
     m_headerArea = NULL;
 }
 
@@ -3378,16 +3426,34 @@ wxDataViewColumn* wxDataViewCtrl::GetColumn( unsigned int idx ) const
     return m_cols[idx];
 }
 
-void wxDataViewCtrl::ColumnMoved( wxDataViewColumn* col, unsigned int new_pos )
+wxDataViewColumn *wxDataViewCtrl::GetColumnAt(unsigned int pos) const
 {
-    if (new_pos > m_cols.GetCount()) return;
+    // columns can't be reordered if there is no header window which allows
+    // to do this
+    const unsigned idx = m_headerArea ? m_headerArea->GetColumnsOrder()[pos]
+                                      : pos;
 
-    // Exchange position
-    m_cols.DeleteContents(false);
-    m_cols.DeleteObject( col );
-    m_cols.Insert( new_pos, col );
-    m_cols.DeleteContents(true);
+    return GetColumn(idx);
+}
+
+int wxDataViewCtrl::GetColumnIndex(const wxDataViewColumn *column) const
+{
+    const unsigned count = m_cols.size();
+    for ( unsigned n = 0; n < count; n++ )
+    {
+        if ( m_cols[n] == column )
+            return n;
+    }
+
+    return wxNOT_FOUND;
+}
 
+void wxDataViewCtrl::ColumnMoved(wxDataViewColumn * WXUNUSED(col),
+                                 unsigned int WXUNUSED(new_pos))
+{
+    // do _not_ reorder m_cols elements here, they should always be in the
+    // order in which columns were added, we only display the columns in
+    // different order
     m_clientArea->UpdateDisplay();
 }
 
@@ -3412,17 +3478,18 @@ bool wxDataViewCtrl::ClearColumns()
 
 int wxDataViewCtrl::GetColumnPosition( const wxDataViewColumn *column ) const
 {
-    int ret = 0, dead = 0;
-    int len = GetColumnCount();
-    for (int i=0; i<len; i++)
+    int ret = 0,
+        dummy = 0;
+    unsigned int len = GetColumnCount();
+    for ( unsigned int i = 0; i < len; i++ )
     {
-        wxDataViewColumn * col = GetColumn(i);
+        wxDataViewColumn * col = GetColumnAt(i);
         if (col->IsHidden())
             continue;
         ret += col->GetWidth();
         if (column==col)
         {
-            CalcScrolledPosition( ret, dead, &ret, &dead );
+            CalcScrolledPosition( ret, dummy, &ret, &dummy );
             break;
         }
     }
@@ -3431,7 +3498,8 @@ int wxDataViewCtrl::GetColumnPosition( const wxDataViewColumn *column ) const
 
 wxDataViewColumn *wxDataViewCtrl::GetSortingColumn() const
 {
-    return NULL;
+    return m_sortingColumnIdx == wxNOT_FOUND ? NULL
+                                             : GetColumn(m_sortingColumnIdx);
 }
 
 //Selection code with wxDataViewItem as parameters
@@ -3456,18 +3524,33 @@ int wxDataViewCtrl::GetSelections( wxDataViewItemArray & sel ) const
 void wxDataViewCtrl::SetSelections( const wxDataViewItemArray & sel )
 {
     wxDataViewSelection selection(wxDataViewSelectionCmp);
+
+    wxDataViewItem last_parent;
+
     int len = sel.GetCount();
     for( int i = 0; i < len; i ++ )
     {
-        int row = m_clientArea->GetRowByItem( sel[i] );
+        wxDataViewItem item = sel[i];
+        wxDataViewItem parent = GetModel()->GetParent( item );
+        if (parent)
+        {
+            if (parent != last_parent)
+                ExpandAncestors(item);
+        }
+        
+        last_parent = parent;
+        int row = m_clientArea->GetRowByItem( item );
         if( row >= 0 )
             selection.Add( static_cast<unsigned int>(row) );
     }
+    
     m_clientArea->SetSelections( selection );
 }
 
 void wxDataViewCtrl::Select( const wxDataViewItem & item )
 {
+    ExpandAncestors( item );
+    
     int row = m_clientArea->GetRowByItem( item );
     if( row >= 0 )
     {
@@ -3591,23 +3674,17 @@ void wxDataViewCtrl::EnsureVisible( int row, int column )
 
 void wxDataViewCtrl::EnsureVisible( const wxDataViewItem & item, const wxDataViewColumn * column )
 {
+    ExpandAncestors( item );
+  
+    m_clientArea->RecalculateDisplay();
+
     int row = m_clientArea->GetRowByItem(item);
     if( row >= 0 )
     {
         if( column == NULL )
             EnsureVisible(row, -1);
         else
-        {
-            int col = 0;
-            int len = GetColumnCount();
-            for( int i = 0; i < len; i ++ )
-                if( GetColumn(i) == column )
-                {
-                    col = i;
-                    break;
-                }
-            EnsureVisible( row, col );
-        }
+            EnsureVisible( row, GetColumnIndex(column) );
     }
 
 }
@@ -3646,6 +3723,15 @@ void wxDataViewCtrl::Collapse( const wxDataViewItem & item )
         m_clientArea->Collapse(row);
 }
 
+bool wxDataViewCtrl::IsExpanded( const wxDataViewItem & item ) const
+{
+    int row = m_clientArea->GetRowByItem( item );
+    if (row != -1)
+        return m_clientArea->IsExpanded(row);
+    return false;
+}
+
+
  #endif
     // !wxUSE_GENERICDATAVIEWCTRL