]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/grid.cpp
mark long-deprecated methods as such, and don't use them in wx code
[wxWidgets.git] / src / generic / grid.cpp
index 69debf772705481ca6244420c1e3dd2da89ffafd..d0288aebc0d2ef1b645c22b11086dd111e5646c6 100644 (file)
@@ -70,6 +70,37 @@ struct wxGridCellWithAttr
     wxGridCellWithAttr(int row, int col, wxGridCellAttr *attr_)
         : coords(row, col), attr(attr_)
     {
+        wxASSERT( attr );
+    }
+
+    wxGridCellWithAttr(const wxGridCellWithAttr& other)
+        : coords(other.coords),
+          attr(other.attr)
+    {
+        attr->IncRef();
+    }
+
+    wxGridCellWithAttr& operator=(const wxGridCellWithAttr& other)
+    {
+        coords = other.coords;
+        if (attr != other.attr)
+        {
+            attr->DecRef();
+            attr = other.attr;
+            attr->IncRef();
+        }
+        return *this;
+    }
+
+    void ChangeAttr(wxGridCellAttr* new_attr)
+    {
+        if (attr != new_attr)
+        {
+           // "Delete" (i.e. DecRef) the old attribute.
+            attr->DecRef();
+            attr = new_attr;
+            // Take ownership of the new attribute, i.e. no IncRef.
+        }
     }
 
     ~wxGridCellWithAttr()
@@ -79,10 +110,6 @@ struct wxGridCellWithAttr
 
     wxGridCellCoords coords;
     wxGridCellAttr  *attr;
-
-// Cannot do this:
-//  DECLARE_NO_COPY_CLASS(wxGridCellWithAttr)
-// without rewriting the macros, which require a public copy constructor.
 };
 
 WX_DECLARE_OBJARRAY_WITH_DECL(wxGridCellWithAttr, wxGridCellWithAttrArray,
@@ -645,10 +672,7 @@ void wxGridCellTextEditor::DoCreate(wxWindow* parent,
                                     wxEvtHandler* evtHandler,
                                     long style)
 {
-    style |= wxTE_PROCESS_ENTER |
-             wxTE_PROCESS_TAB |
-             wxTE_AUTO_SCROLL |
-             wxNO_BORDER;
+    style |= wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB | wxNO_BORDER;
 
     m_control = new wxTextCtrl(parent, id, wxEmptyString,
                                wxDefaultPosition, wxDefaultSize,
@@ -929,7 +953,6 @@ void wxGridCellNumberEditor::BeginEdit(int row, int col, wxGrid* grid)
 bool wxGridCellNumberEditor::EndEdit(int row, int col,
                                      wxGrid* grid)
 {
-    bool changed;
     long value = 0;
     wxString text;
 
@@ -937,26 +960,40 @@ bool wxGridCellNumberEditor::EndEdit(int row, int col,
     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();
-        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()
@@ -1089,7 +1126,7 @@ void wxGridCellFloatEditor::Create(wxWindow* parent,
 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);
@@ -1097,35 +1134,53 @@ void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid)
     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());
 }
 
-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()
@@ -1556,19 +1611,7 @@ void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid)
 
     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();
 
@@ -1596,8 +1639,19 @@ bool wxGridCellChoiceEditor::EndEdit(int row, int col,
 
 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)
@@ -2587,6 +2641,9 @@ wxGridCellEditor* wxGridCellAttr::GetEditor(const wxGrid* grid, int row, int col
 
 void wxGridCellAttrData::SetAttr(wxGridCellAttr *attr, int row, int col)
 {
+    // Note: contrary to wxGridRowOrColAttrData::SetAttr, we must not
+    //       touch attribute's reference counting explicitly, since this
+    //       is managed by class wxGridCellWithAttr
     int n = FindIndex(row, col);
     if ( n == wxNOT_FOUND )
     {
@@ -2597,15 +2654,12 @@ void wxGridCellAttrData::SetAttr(wxGridCellAttr *attr, int row, int col)
         }
         //else: nothing to do
     }
-    else
+    else // we already have an attribute for this cell
     {
-        // free the old attribute
-        m_attrs[(size_t)n].attr->DecRef();
-
         if ( attr )
         {
             // change the attribute
-            m_attrs[(size_t)n].attr = attr;
+            m_attrs[(size_t)n].ChangeAttr(attr);
         }
         else
         {
@@ -2654,8 +2708,6 @@ void wxGridCellAttrData::UpdateAttrRows( size_t pos, int numRows )
                 else
                 {
                     // ...or remove the attribute
-                    // No need to DecRef the attribute itself since this is
-                    // done be wxGridCellWithAttr's destructor!
                     m_attrs.RemoveAt(n);
                     n--;
                     count--;
@@ -2690,8 +2742,6 @@ void wxGridCellAttrData::UpdateAttrCols( size_t pos, int numCols )
                 else
                 {
                     // ...or remove the attribute
-                    // No need to DecRef the attribute itself since this is
-                    // done be wxGridCellWithAttr's destructor!
                     m_attrs.RemoveAt(n);
                     n--;
                     count--;
@@ -2750,7 +2800,8 @@ void wxGridRowOrColAttrData::SetAttr(wxGridCellAttr *attr, int rowOrCol)
     {
         if ( attr )
         {
-            // add the attribute
+            // add the attribute - no need to do anything to reference count
+            //                     since we take ownership of the attribute.
             m_rowsOrCols.Add(rowOrCol);
             m_attrs.Add(attr);
         }
@@ -2759,15 +2810,19 @@ void wxGridRowOrColAttrData::SetAttr(wxGridCellAttr *attr, int rowOrCol)
     else
     {
         size_t n = (size_t)i;
+        if ( m_attrs[n] == attr )
+            // nothing to do
+            return; 
         if ( attr )
         {
-            // change the attribute
+            // change the attribute, handling reference count manually,
+            //                       taking ownership of the new attribute.
             m_attrs[n]->DecRef();
             m_attrs[n] = attr;
         }
         else
         {
-            // remove this attribute
+            // remove this attribute, handling reference count manually
             m_attrs[n]->DecRef();
             m_rowsOrCols.RemoveAt(n);
             m_attrs.RemoveAt(n);
@@ -3168,7 +3223,8 @@ void wxGridTableBase::SetAttr(wxGridCellAttr* attr, int row, int col)
 {
     if ( m_attrProvider )
     {
-        attr->SetKind(wxGridCellAttr::Cell);
+        if ( attr )
+            attr->SetKind(wxGridCellAttr::Cell);
         m_attrProvider->SetAttr(attr, row, col);
     }
     else
@@ -5991,7 +6047,8 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
 
 
         }
-        else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_ROW )
+        else if ( event.LeftIsDown() &&
+                  m_cursorMode == WXGRID_CURSOR_RESIZE_ROW )
         {
             int cw, ch, left, dummy;
             m_gridWin->GetClientSize( &cw, &ch );
@@ -6009,7 +6066,8 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
             dc.DrawLine( left, y, left+cw, y );
             m_dragLastPos = y;
         }
-        else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_COL )
+        else if ( event.LeftIsDown() &&
+                  m_cursorMode == WXGRID_CURSOR_RESIZE_COL )
         {
             int cw, ch, dummy, top;
             m_gridWin->GetClientSize( &cw, &ch );
@@ -10010,6 +10068,8 @@ void wxGrid::SetColFormatCustom(int col, const wxString& typeName)
         attr = new wxGridCellAttr;
     wxGridCellRenderer *renderer = GetDefaultRendererForType(typeName);
     attr->SetRenderer(renderer);
+    wxGridCellEditor *editor = GetDefaultEditorForType(typeName); 
+    attr->SetEditor(editor); 
 
     SetColAttr(col, attr);
 
@@ -11009,9 +11069,13 @@ wxArrayInt wxGrid::GetSelectedCols() const
 
 void wxGrid::ClearSelection()
 {
+    wxRect r1 = BlockToDeviceRect( m_selectingTopLeft, m_selectingBottomRight);
+    wxRect r2 = BlockToDeviceRect( m_currentCellCoords, m_selectingKeyboard );
     m_selectingTopLeft =
     m_selectingBottomRight =
     m_selectingKeyboard = wxGridNoCellCoords;
+    Refresh( false, &r1 );
+    Refresh( false, &r2 );
     if ( m_selection )
         m_selection->ClearSelection();
 }