wxGridCellWithAttr& operator=(const wxGridCellWithAttr& other)
{
coords = other.coords;
- attr->DecRef();
- attr = other.attr;
- attr->IncRef();
-
+ 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()
{
attr->DecRef();
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,
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);
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()
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();
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 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 )
{
if ( attr )
{
// change the attribute
- m_attrs[(size_t)n].attr = attr;
+ m_attrs[(size_t)n].ChangeAttr(attr);
}
else
{
{
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);
}
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);
}
- 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 );
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 );
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();
}