]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/grid.cpp
better guarding when no printing architecture exists (patch from Joel Low)
[wxWidgets.git] / src / generic / grid.cpp
index bc42be31a1d8db356870512d3c33f0c1b22d1bd9..bdd93204b5472c16cfe3bd21581fc03d63bac969 100644 (file)
@@ -953,7 +953,6 @@ void wxGridCellNumberEditor::BeginEdit(int row, int col, wxGrid* grid)
 bool wxGridCellNumberEditor::EndEdit(int row, int col,
                                      wxGrid* grid)
 {
 bool wxGridCellNumberEditor::EndEdit(int row, int col,
                                      wxGrid* grid)
 {
-    bool changed;
     long value = 0;
     wxString text;
 
     long value = 0;
     wxString text;
 
@@ -961,26 +960,40 @@ bool wxGridCellNumberEditor::EndEdit(int row, int col,
     if ( HasRange() )
     {
         value = Spin()->GetValue();
     if ( HasRange() )
     {
         value = Spin()->GetValue();
-        changed = value != m_valueOld;
-        if (changed)
-            text = wxString::Format(wxT("%ld"), value);
+        if ( value == m_valueOld )
+            return false;
+
+        text.Printf(wxT("%ld"), value);
     }
     }
-    else
-#endif
+    else // using unconstrained input
+#endif // wxUSE_SPINCTRL
     {
     {
+        const wxString textOld(grid->GetCellValue(row, col));
         text = Text()->GetValue();
         text = Text()->GetValue();
-        changed = (text.empty() || text.ToLong(&value)) && (value != m_valueOld);
-    }
+        if ( text.empty() )
+        {
+            if ( textOld.empty() )
+                return false;
+        }
+        else // non-empty text now (maybe 0)
+        {
+            if ( !text.ToLong(&value) )
+                return false;
 
 
-    if ( changed )
-    {
-        if (grid->GetTable()->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER))
-            grid->GetTable()->SetValueAsLong(row, col, value);
-        else
-            grid->GetTable()->SetValue(row, col, text);
+            // if value == m_valueOld == 0 but old text was "" and new one is
+            // "0" something still did change
+            if ( value == m_valueOld && (value || !textOld.empty()) )
+                return false;
+        }
     }
 
     }
 
-    return changed;
+    wxGridTableBase * const table = grid->GetTable();
+    if ( table->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER) )
+        table->SetValueAsLong(row, col, value);
+    else
+        table->SetValue(row, col, text);
+
+    return true;
 }
 
 void wxGridCellNumberEditor::Reset()
 }
 
 void wxGridCellNumberEditor::Reset()
@@ -1113,7 +1126,7 @@ void wxGridCellFloatEditor::Create(wxWindow* parent,
 void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid)
 {
     // first get the value
 void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid)
 {
     // first get the value
-    wxGridTableBase *table = grid->GetTable();
+    wxGridTableBase * const table = grid->GetTable();
     if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) )
     {
         m_valueOld = table->GetValueAsDouble(row, col);
     if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) )
     {
         m_valueOld = table->GetValueAsDouble(row, col);
@@ -1121,35 +1134,53 @@ void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid)
     else
     {
         m_valueOld = 0.0;
     else
     {
         m_valueOld = 0.0;
-        wxString sValue = table->GetValue(row, col);
-        if (! sValue.ToDouble(&m_valueOld) && ! sValue.empty())
+
+        const wxString value = table->GetValue(row, col);
+        if ( !value.empty() )
         {
         {
-            wxFAIL_MSG( _T("this cell doesn't have float value") );
-            return;
+            if ( !value.ToDouble(&m_valueOld) )
+            {
+                wxFAIL_MSG( _T("this cell doesn't have float value") );
+                return;
+            }
         }
     }
 
     DoBeginEdit(GetString());
 }
 
         }
     }
 
     DoBeginEdit(GetString());
 }
 
-bool wxGridCellFloatEditor::EndEdit(int row, int col,
-                                     wxGrid* grid)
+bool wxGridCellFloatEditor::EndEdit(int row, int col, wxGrid* grid)
 {
 {
-    double value = 0.0;
-    wxString text(Text()->GetValue());
+    const wxString text(Text()->GetValue()),
+                   textOld(grid->GetCellValue(row, col));
 
 
-    if ( (text.empty() || text.ToDouble(&value)) &&
-            !wxIsSameDouble(value, m_valueOld) )
+    double value;
+    if ( !text.empty() )
     {
     {
-        if (grid->GetTable()->CanSetValueAs(row, col, wxGRID_VALUE_FLOAT))
-            grid->GetTable()->SetValueAsDouble(row, col, value);
-        else
-            grid->GetTable()->SetValue(row, col, text);
+        if ( !text.ToDouble(&value) )
+            return false;
+    }
+    else // new value is empty string
+    {
+        if ( textOld.empty() )
+            return false;           // nothing changed
 
 
-        return true;
+        value = 0.;
     }
 
     }
 
-    return false;
+    // the test for empty strings ensures that we don't skip the value setting
+    // when "" is replaced by "0" or vice versa as "" numeric value is also 0.
+    if ( wxIsSameDouble(value, m_valueOld) && !text.empty() && !textOld.empty() )
+        return false;           // nothing changed
+
+    wxGridTableBase * const table = grid->GetTable();
+
+    if ( table->CanSetValueAs(row, col, wxGRID_VALUE_FLOAT) )
+        table->SetValueAsDouble(row, col, value);
+    else
+        table->SetValue(row, col, text);
+
+    return true;
 }
 
 void wxGridCellFloatEditor::Reset()
 }
 
 void wxGridCellFloatEditor::Reset()
@@ -1580,19 +1611,7 @@ void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid)
 
     m_startValue = grid->GetTable()->GetValue(row, col);
 
 
     m_startValue = grid->GetTable()->GetValue(row, col);
 
-    if (m_allowOthers)
-    {
-        Combo()->SetValue(m_startValue);
-        Combo()->SetInsertionPointEnd();
-    }
-    else // the combobox is read-only
-    {
-        // find the right position, or default to the first if not found
-        int pos = Combo()->FindString(m_startValue);
-        if (pos == wxNOT_FOUND)
-            pos = 0;
-        Combo()->SetSelection(pos);
-    }
+    Reset(); // this updates combo box to correspond to m_startValue
 
     Combo()->SetFocus();
 
 
     Combo()->SetFocus();
 
@@ -1620,8 +1639,19 @@ bool wxGridCellChoiceEditor::EndEdit(int row, int col,
 
 void wxGridCellChoiceEditor::Reset()
 {
 
 void wxGridCellChoiceEditor::Reset()
 {
-    Combo()->SetValue(m_startValue);
-    Combo()->SetInsertionPointEnd();
+    if (m_allowOthers)
+    {
+        Combo()->SetValue(m_startValue);
+        Combo()->SetInsertionPointEnd();
+    }
+    else // the combobox is read-only
+    {
+        // find the right position, or default to the first if not found
+        int pos = Combo()->FindString(m_startValue);
+        if (pos == wxNOT_FOUND)
+            pos = 0;
+        Combo()->SetSelection(pos);
+    }
 }
 
 void wxGridCellChoiceEditor::SetParameters(const wxString& params)
 }
 
 void wxGridCellChoiceEditor::SetParameters(const wxString& params)
@@ -9914,9 +9944,14 @@ void wxGrid::ClearAttrCache()
 {
     if ( m_attrCache.row != -1 )
     {
 {
     if ( m_attrCache.row != -1 )
     {
-        wxSafeDecRef(m_attrCache.attr);
+        wxGridCellAttr *oldAttr = m_attrCache.attr; 
         m_attrCache.attr = NULL;
         m_attrCache.row = -1;
         m_attrCache.attr = NULL;
         m_attrCache.row = -1;
+        // wxSafeDecRec(...) might cause event processing that accesses
+        // the cached attribute, if one exists (e.g. by deleting the
+        // editor stored within the attribute). Therefore it is important
+       // to invalidate the cache  before calling wxSafeDecRef!
+        wxSafeDecRef(oldAttr);
     }
 }
 
     }
 }
 
@@ -10159,7 +10194,7 @@ void wxGrid::SetCellSize( int row, int col, int num_rows, int num_cols )
                       wxT("wxGrid::SetCellSize setting cell size to < 1"));
 
         // if this was already a multicell then "turn off" the other cells first
                       wxT("wxGrid::SetCellSize setting cell size to < 1"));
 
         // if this was already a multicell then "turn off" the other cells first
-        if ((cell_rows > 1) || (cell_rows > 1))
+        if ((cell_rows > 1) || (cell_cols > 1))
         {
             int i, j;
             for (j=row; j < row + cell_rows; j++)
         {
             int i, j;
             for (j=row; j < row + cell_rows; j++)
@@ -10322,6 +10357,19 @@ void wxGrid::SetRowSize( int row, int height )
 {
     wxCHECK_RET( row >= 0 && row < m_numRows, _T("invalid row index") );
 
 {
     wxCHECK_RET( row >= 0 && row < m_numRows, _T("invalid row index") );
 
+    // if < 0 then calculate new height from label
+    if ( height < 0 )
+    {
+        long w, h;
+        wxArrayString lines;
+        wxClientDC dc(m_rowLabelWin);
+        dc.SetFont(GetLabelFont());
+        StringToLines(GetRowLabelValue( row ), lines);
+       GetTextBoxSize( dc, lines, &w, &h );
+       //check that it is not less than the minimal height
+       height = wxMax(h, GetRowMinimalAcceptableHeight());
+    }
+
     // See comment in SetColSize
     if ( height < GetRowMinimalAcceptableHeight())
         return;
     // See comment in SetColSize
     if ( height < GetRowMinimalAcceptableHeight())
         return;
@@ -10367,6 +10415,23 @@ void wxGrid::SetColSize( int col, int width )
 {
     wxCHECK_RET( col >= 0 && col < m_numCols, _T("invalid column index") );
 
 {
     wxCHECK_RET( col >= 0 && col < m_numCols, _T("invalid column index") );
 
+    // if < 0 then calculate new width from label
+    if ( width < 0 )
+    {
+        long w, h;
+        wxArrayString lines;
+        wxClientDC dc(m_colLabelWin);
+        dc.SetFont(GetLabelFont());
+        StringToLines(GetColLabelValue(col), lines);
+        if ( GetColLabelTextOrientation() == wxHORIZONTAL )
+            GetTextBoxSize( dc, lines, &w, &h );
+        else
+            GetTextBoxSize( dc, lines, &h, &w );
+        width = w + 6;
+       //check that it is not less than the minimal width
+       width = wxMax(width, GetColMinimalAcceptableWidth()); 
+    }
+
     // should we check that it's bigger than GetColMinimalWidth(col) here?
     //                                                                 (VZ)
     // No, because it is reasonable to assume the library user know's
     // should we check that it's bigger than GetColMinimalWidth(col) here?
     //                                                                 (VZ)
     // No, because it is reasonable to assume the library user know's
@@ -10384,18 +10449,6 @@ void wxGrid::SetColSize( int col, int width )
         InitColWidths();
     }
 
         InitColWidths();
     }
 
-    // if < 0 then calculate new width from label
-    if ( width < 0 )
-    {
-        long w, h;
-        wxArrayString lines;
-        wxClientDC dc(m_colLabelWin);
-        dc.SetFont(GetLabelFont());
-        StringToLines(GetColLabelValue(col), lines);
-        GetTextBoxSize(dc, lines, &w, &h);
-        width = w + 6;
-    }
-
     int w = wxMax( 0, width );
     int diff = w - m_colWidths[col];
     m_colWidths[col] = w;
     int w = wxMax( 0, width );
     int diff = w - m_colWidths[col];
     m_colWidths[col] = w;
@@ -10763,9 +10816,6 @@ void wxGrid::AutoSize()
 
 void wxGrid::AutoSizeRowLabelSize( int row )
 {
 
 void wxGrid::AutoSizeRowLabelSize( int row )
 {
-    wxArrayString lines;
-    long w, h;
-
     // Hide the edit control, so it
     // won't interfere with drag-shrinking.
     if ( IsCellEditControlShown() )
     // Hide the edit control, so it
     // won't interfere with drag-shrinking.
     if ( IsCellEditControlShown() )
@@ -10775,20 +10825,12 @@ void wxGrid::AutoSizeRowLabelSize( int row )
     }
 
     // autosize row height depending on label text
     }
 
     // autosize row height depending on label text
-    StringToLines( GetRowLabelValue( row ), lines );
-    wxClientDC dc( m_rowLabelWin );
-    GetTextBoxSize( dc, lines, &w, &h );
-    if ( h < m_defaultRowHeight )
-        h = m_defaultRowHeight;
-    SetRowSize(row, h);
+    SetRowSize(row, -1);
     ForceRefresh();
 }
 
 void wxGrid::AutoSizeColLabelSize( int col )
 {
     ForceRefresh();
 }
 
 void wxGrid::AutoSizeColLabelSize( int col )
 {
-    wxArrayString lines;
-    long w, h;
-
     // Hide the edit control, so it
     // won't interfere with drag-shrinking.
     if ( IsCellEditControlShown() )
     // Hide the edit control, so it
     // won't interfere with drag-shrinking.
     if ( IsCellEditControlShown() )
@@ -10798,15 +10840,7 @@ void wxGrid::AutoSizeColLabelSize( int col )
     }
 
     // autosize column width depending on label text
     }
 
     // autosize column width depending on label text
-    StringToLines( GetColLabelValue( col ), lines );
-    wxClientDC dc( m_colLabelWin );
-    if ( GetColLabelTextOrientation() == wxHORIZONTAL )
-        GetTextBoxSize( dc, lines, &w, &h );
-    else
-        GetTextBoxSize( dc, lines, &h, &w );
-    if ( w < m_defaultColWidth )
-        w = m_defaultColWidth;
-    SetColSize(col, w);
+    SetColSize(col, -1);
     ForceRefresh();
 }
 
     ForceRefresh();
 }