X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7d2c43731bd3d78b2d67c63ac48d7d65de092365..a2fd8a45eca03f90371a1c41b2f7450df088b07c:/src/generic/grid.cpp diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 33f31d9f2a..6590754456 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -83,13 +83,26 @@ struct wxGridCellWithAttr 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(); @@ -659,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, @@ -1103,7 +1113,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); @@ -1111,35 +1121,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() @@ -1570,19 +1598,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(); @@ -1610,8 +1626,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) @@ -2601,6 +2628,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 ) { @@ -2616,7 +2646,7 @@ void wxGridCellAttrData::SetAttr(wxGridCellAttr *attr, int row, int col) if ( attr ) { // change the attribute - m_attrs[(size_t)n].attr = attr; + m_attrs[(size_t)n].ChangeAttr(attr); } else { @@ -2757,7 +2787,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); } @@ -2766,15 +2797,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); @@ -5999,7 +6034,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 ); @@ -6017,7 +6053,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 ); @@ -11019,9 +11056,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(); }