]> git.saurik.com Git - wxWidgets.git/commitdiff
Fix crash when auto-sizing a wxDataViewCtrl column.
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 30 Sep 2013 23:49:26 +0000 (23:49 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 30 Sep 2013 23:49:26 +0000 (23:49 +0000)
The code was confused about the difference between the model and view columns
indices and incorrectly used the former as the latter, which could result in
an out of bound array access.

Closes #15420.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74889 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
include/wx/generic/dataview.h
src/generic/datavgen.cpp

index e260d24c220a0d9a5c12280aebf7c1d642b2c16a..699222a9aaf672683efcc9ce6767b06018724ec7 100644 (file)
@@ -579,6 +579,7 @@ All (GUI):
 - wxPropertyGrid: improve composite flags handling (Jens Lody).
 - Don't crash laying out wxGridBagSizer with only hidden elements (briceandre).
 - Fix alignment and transparency of bitmaps in wxDataViewCtrl (Eric Jensen).
+- Fix crash when auto-sizing a wxDataViewCtrl column (Spencer T. Parkin).
 - Add wxHtmlTag::GetParamAsString() convenience method.
 
 wxGTK:
index 396c81ba6c93bece57ebe4d4fd26318fd92a25a8..f3ac8ee59823c8fbccb3feca10c546eb2c0edea2 100644 (file)
@@ -227,6 +227,9 @@ public:     // utility functions not part of the API
     // return the index of the given column in m_cols
     int GetColumnIndex(const wxDataViewColumn *column) const;
 
+    // Return the index of the column having the given model index.
+    int GetModelColumnIndex(unsigned int model_column) const;
+
     // return the column displayed at the given position in the control
     wxDataViewColumn *GetColumnAt(unsigned int pos) const;
 
index d5c0614e608226d0c319859b9a7eb2c1c56046e1..d36e86116ba9a59807babcc060547fed46631176 100644 (file)
@@ -2489,18 +2489,8 @@ bool wxDataViewMainWindow::ItemChanged(const wxDataViewItem & item)
 
 bool wxDataViewMainWindow::ValueChanged( const wxDataViewItem & item, unsigned int model_column )
 {
-    int view_column = -1;
-    unsigned int n_col = m_owner->GetColumnCount();
-    for (unsigned i = 0; i < n_col; i++)
-    {
-        wxDataViewColumn *column = m_owner->GetColumn( i );
-        if (column->GetModelColumn() == model_column)
-        {
-            view_column = (int) i;
-            break;
-        }
-    }
-    if (view_column == -1)
+    int view_column = m_owner->GetModelColumnIndex(model_column);
+    if ( view_column == wxNOT_FOUND )
         return false;
 
     // NOTE: to be valid, we cannot use e.g. INT_MAX - 1
@@ -4730,6 +4720,14 @@ void wxDataViewCtrl::OnColumnsCountChanged()
 
 void wxDataViewCtrl::DoSetExpanderColumn()
 {
+    wxDataViewColumn* column = GetExpanderColumn();
+    if ( column )
+    {
+        int index = GetColumnIndex(column);
+        if ( index != wxNOT_FOUND )
+            InvalidateColBestWidth(index);
+    }
+
     m_clientArea->UpdateDisplay();
 }
 
@@ -4780,6 +4778,18 @@ int wxDataViewCtrl::GetColumnIndex(const wxDataViewColumn *column) const
     return wxNOT_FOUND;
 }
 
+int wxDataViewCtrl::GetModelColumnIndex( unsigned int model_column ) const
+{
+    const int count = GetColumnCount();
+    for ( int index = 0; index < count; index++ )
+    {
+        wxDataViewColumn* column = GetColumn(index);
+        if ( column->GetModelColumn() == model_column )
+            return index;
+    }
+    return wxNOT_FOUND;
+}
+
 unsigned int wxDataViewCtrl::GetBestColumnWidth(int idx) const
 {
     if ( m_colsBestWidths[idx].width != 0 )
@@ -4797,21 +4807,23 @@ unsigned int wxDataViewCtrl::GetBestColumnWidth(int idx) const
                            wxDataViewMainWindow *clientArea,
                            wxDataViewRenderer *renderer,
                            const wxDataViewModel *model,
-                           unsigned column,
+                           unsigned int model_column,
                            int expanderSize)
             : m_width(0),
               m_dvc(dvc),
               m_clientArea(clientArea),
               m_renderer(renderer),
               m_model(model),
-              m_column(column),
+              m_model_column(model_column),
               m_expanderSize(expanderSize)
 
         {
+            int index = dvc->GetModelColumnIndex( model_column );
+            wxDataViewColumn* column = index == wxNOT_FOUND ? NULL : dvc->GetColumn(index);
             m_isExpanderCol =
                 !clientArea->IsList() &&
                 (column == 0 ||
-                 GetExpanderColumnOrFirstOne(const_cast<wxDataViewCtrl*>(dvc)) == dvc->GetColumnAt(column));
+                 GetExpanderColumnOrFirstOne(const_cast<wxDataViewCtrl*>(dvc)) == column );
         }
 
         void UpdateWithWidth(int width)
@@ -4835,7 +4847,7 @@ unsigned int wxDataViewCtrl::GetBestColumnWidth(int idx) const
                 item = m_clientArea->GetItemByRow(row);
             }
 
-            m_renderer->PrepareForItem(m_model, item, m_column);
+            m_renderer->PrepareForItem(m_model, item, m_model_column);
             m_width = wxMax(m_width, m_renderer->GetSize().x + indent);
         }
 
@@ -4847,7 +4859,7 @@ unsigned int wxDataViewCtrl::GetBestColumnWidth(int idx) const
         wxDataViewMainWindow *m_clientArea;
         wxDataViewRenderer *m_renderer;
         const wxDataViewModel *m_model;
-        unsigned m_column;
+        unsigned m_model_column;
         bool m_isExpanderCol;
         int m_expanderSize;
     };