]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/datavgen.cpp
use wxWindow::GetClientSize() instead of ::GetClientRect() in wxActiveXContainer...
[wxWidgets.git] / src / generic / datavgen.cpp
index ca912681712915b58ac26dc1160ed1f69e2e2cfb..388cd1b52ff26b154decd61de44674e9b2ac6eee 100644 (file)
@@ -88,12 +88,26 @@ public:
     wxDataViewCtrl *GetOwner() const
         { return static_cast<wxDataViewCtrl *>(GetParent()); }
 
-private:
-    virtual wxHeaderColumnBase& GetColumn(unsigned int idx)
+protected:
+    // implement/override wxHeaderCtrl functions by forwarding them to the main
+    // control
+    virtual const wxHeaderColumn& GetColumn(unsigned int idx) const
     {
         return *(GetOwner()->GetColumn(idx));
     }
 
+    virtual bool UpdateColumnWidthToFit(unsigned int idx, int widthTitle)
+    {
+        wxDataViewCtrl * const owner = GetOwner();
+
+        int widthContents = owner->GetBestColumnWidth(idx);
+        owner->GetColumn(idx)->SetWidth(wxMax(widthTitle, widthContents));
+        owner->OnColumnChange(idx);
+
+        return true;
+    }
+
+private:
     bool SendEvent(wxEventType type, unsigned int n)
     {
         wxDataViewCtrl * const owner = GetOwner();
@@ -111,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)
@@ -123,6 +174,22 @@ private:
             event.Skip();
     }
 
+    void OnEndResize(wxHeaderCtrlEvent& event)
+    {
+        wxDataViewCtrl * const owner = GetOwner();
+
+        const unsigned col = event.GetColumn();
+        owner->GetColumn(col)->SetWidth(event.GetWidth());
+        GetOwner()->OnColumnChange(col);
+    }
+
+    void OnEndReorder(wxHeaderCtrlEvent& event)
+    {
+        wxDataViewCtrl * const owner = GetOwner();
+        owner->ColumnMoved(owner->GetColumn(event.GetColumn()),
+                           event.GetNewOrder());
+    }
+
     DECLARE_EVENT_TABLE()
     DECLARE_NO_COPY_CLASS(wxDataViewHeaderWindow)
 };
@@ -130,6 +197,10 @@ private:
 BEGIN_EVENT_TABLE(wxDataViewHeaderWindow, wxHeaderCtrl)
     EVT_HEADER_CLICK(wxID_ANY, wxDataViewHeaderWindow::OnClick)
     EVT_HEADER_RIGHT_CLICK(wxID_ANY, wxDataViewHeaderWindow::OnRClick)
+
+    EVT_HEADER_END_RESIZE(wxID_ANY, wxDataViewHeaderWindow::OnEndResize)
+
+    EVT_HEADER_END_REORDER(wxID_ANY, wxDataViewHeaderWindow::OnEndReorder)
 END_EVENT_TABLE()
 
 //-----------------------------------------------------------------------------
@@ -412,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
@@ -1164,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!
 
@@ -1179,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!
 
@@ -1211,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
 
@@ -1252,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);
     }
 
@@ -1263,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();
 
@@ -1413,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!
 
@@ -1724,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!
 
@@ -1759,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();
@@ -2340,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())
@@ -2486,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!
 
@@ -2510,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();
@@ -2716,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());
@@ -2801,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!
 
@@ -2817,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;
@@ -2949,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
@@ -3162,7 +3252,8 @@ void wxDataViewCtrl::Init()
     m_notifier = NULL;
 
     // No sorting column at start
-    m_sortingColumn = NULL;
+    m_sortingColumnIdx = wxNOT_FOUND;
+
     m_headerArea = NULL;
 }
 
@@ -3275,7 +3366,7 @@ bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col )
         return false;
 
     m_cols.Append( col );
-    OnColumnChange();
+    OnColumnsCountChanged();
     return true;
 }
 
@@ -3285,7 +3376,7 @@ bool wxDataViewCtrl::PrependColumn( wxDataViewColumn *col )
         return false;
 
     m_cols.Insert( col );
-    OnColumnChange();
+    OnColumnsCountChanged();
     return true;
 }
 
@@ -3295,11 +3386,19 @@ bool wxDataViewCtrl::InsertColumn( unsigned int pos, wxDataViewColumn *col )
         return false;
 
     m_cols.Insert( pos, col );
-    OnColumnChange();
+    OnColumnsCountChanged();
     return true;
 }
 
-void wxDataViewCtrl::OnColumnChange()
+void wxDataViewCtrl::OnColumnChange(unsigned int idx)
+{
+    if ( m_headerArea )
+        m_headerArea->UpdateColumn(idx);
+
+    m_clientArea->UpdateDisplay();
+}
+
+void wxDataViewCtrl::OnColumnsCountChanged()
 {
     if (m_headerArea)
         m_headerArea->SetColumnCount(GetColumnCount());
@@ -3322,32 +3421,39 @@ unsigned int wxDataViewCtrl::GetColumnCount() const
     return m_cols.GetCount();
 }
 
-wxDataViewColumn* wxDataViewCtrl::GetColumn( unsigned int pos ) const
+wxDataViewColumn* wxDataViewCtrl::GetColumn( unsigned int idx ) const
 {
-    wxDataViewColumnList::const_iterator iter;
-    unsigned int i = 0;
-    for (iter = m_cols.begin(); iter!=m_cols.end(); iter++)
-    {
-        if (i == pos)
-            return *iter;
+    return m_cols[idx];
+}
 
-        if ((*iter)->IsHidden())
-            continue;
-        i ++;
-    }
-    return NULL;
+wxDataViewColumn *wxDataViewCtrl::GetColumnAt(unsigned int pos) const
+{
+    // 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;
+
+    return GetColumn(idx);
 }
 
-void wxDataViewCtrl::ColumnMoved( wxDataViewColumn* col, unsigned int new_pos )
+int wxDataViewCtrl::GetColumnIndex(const wxDataViewColumn *column) const
 {
-    if (new_pos > m_cols.GetCount()) return;
+    const unsigned count = m_cols.size();
+    for ( unsigned n = 0; n < count; n++ )
+    {
+        if ( m_cols[n] == column )
+            return n;
+    }
 
-    // Exchange position
-    m_cols.DeleteContents(false);
-    m_cols.DeleteObject( col );
-    m_cols.Insert( new_pos, col );
-    m_cols.DeleteContents(true);
+    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();
 }
 
@@ -3358,7 +3464,7 @@ bool wxDataViewCtrl::DeleteColumn( wxDataViewColumn *column )
         return false;
 
     m_cols.Erase(ret);
-    OnColumnChange();
+    OnColumnsCountChanged();
 
     return true;
 }
@@ -3366,23 +3472,24 @@ bool wxDataViewCtrl::DeleteColumn( wxDataViewColumn *column )
 bool wxDataViewCtrl::ClearColumns()
 {
     m_cols.Clear();
-    OnColumnChange();
+    OnColumnsCountChanged();
     return true;
 }
 
 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;
         }
     }
@@ -3391,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
@@ -3416,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 )
     {
@@ -3551,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) );
     }
 
 }
@@ -3606,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