DEFINE_EVENT_TYPE(wxEVT_GRID_COL_MOVE)
DEFINE_EVENT_TYPE(wxEVT_GRID_COL_SORT)
DEFINE_EVENT_TYPE(wxEVT_GRID_RANGE_SELECT)
-DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGE)
+DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGING)
+DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGED)
DEFINE_EVENT_TYPE(wxEVT_GRID_SELECT_CELL)
DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_SHOWN)
DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_HIDDEN)
wxID_ANY,
wxDefaultPosition,
wxDefaultSize,
- owner->CanDragColMove() ? wxHD_DRAGDROP : 0)
+ wxHD_ALLOW_HIDE |
+ (owner->CanDragColMove() ? wxHD_ALLOW_REORDER : 0))
{
}
protected:
- virtual wxHeaderColumn& GetColumn(unsigned int idx)
+ virtual const wxHeaderColumn& GetColumn(unsigned int idx) const
{
return m_columns[idx];
}
return true;
}
+ // overridden to react to the actions using the columns popup menu
+ virtual void UpdateColumnVisibility(unsigned int idx, bool show)
+ {
+ GetOwner()->SetColSize(idx, show ? wxGRID_AUTOSIZE : 0);
+
+ // as this is done by the user we should notify the main program about
+ // it
+ GetOwner()->SendEvent(wxEVT_GRID_COL_SIZE, -1, idx);
+ }
+
+ // overridden to react to the columns order changes in the customization
+ // dialog
+ virtual void UpdateColumnsOrder(const wxArrayInt& order)
+ {
+ GetOwner()->SetColumnsOrder(order);
+ }
+
// event handlers forwarding wxHeaderCtrl events to wxGrid
void OnClick(wxHeaderCtrlEvent& event)
{
wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!"));
- m_startValue = grid->GetTable()->GetValue(row, col);
+ m_value = grid->GetTable()->GetValue(row, col);
- DoBeginEdit(m_startValue);
+ DoBeginEdit(m_value);
}
void wxGridCellTextEditor::DoBeginEdit(const wxString& startValue)
Text()->SetFocus();
}
-bool wxGridCellTextEditor::EndEdit(int row, int col, wxGrid* grid)
+bool wxGridCellTextEditor::EndEdit(const wxString& WXUNUSED(oldval),
+ wxString *newval)
{
- wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!"));
+ wxCHECK_MSG( m_control, false,
+ "wxGridCellTextEditor must be created first!" );
- bool changed = false;
- wxString value = Text()->GetValue();
- if (value != m_startValue)
- changed = true;
+ const wxString value = Text()->GetValue();
+ if ( value == m_value )
+ return false;
- if (changed)
- grid->GetTable()->SetValue(row, col, value);
+ m_value = value;
- m_startValue = wxEmptyString;
+ if ( newval )
+ *newval = m_value;
- // No point in setting the text of the hidden control
- //Text()->SetValue(m_startValue);
+ return true;
+}
- return changed;
+void wxGridCellTextEditor::ApplyEdit(int row, int col, wxGrid* grid)
+{
+ grid->GetTable()->SetValue(row, col, m_value);
+ m_value.clear();
}
void wxGridCellTextEditor::Reset()
{
- wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be created first!"));
+ wxASSERT_MSG( m_control, "wxGridCellTextEditor must be created first!" );
- DoReset(m_startValue);
+ DoReset(m_value);
}
void wxGridCellTextEditor::DoReset(const wxString& startValue)
wxGridTableBase *table = grid->GetTable();
if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
{
- m_valueOld = table->GetValueAsLong(row, col);
+ m_value = table->GetValueAsLong(row, col);
}
else
{
- m_valueOld = 0;
+ m_value = 0;
wxString sValue = table->GetValue(row, col);
- if (! sValue.ToLong(&m_valueOld) && ! sValue.empty())
+ if (! sValue.ToLong(&m_value) && ! sValue.empty())
{
wxFAIL_MSG( _T("this cell doesn't have numeric value") );
return;
#if wxUSE_SPINCTRL
if ( HasRange() )
{
- Spin()->SetValue((int)m_valueOld);
+ Spin()->SetValue((int)m_value);
Spin()->SetFocus();
}
else
}
}
-bool wxGridCellNumberEditor::EndEdit(int row, int col,
- wxGrid* grid)
+bool wxGridCellNumberEditor::EndEdit(const wxString& oldval, wxString *newval)
{
long value = 0;
wxString text;
if ( HasRange() )
{
value = Spin()->GetValue();
- if ( value == m_valueOld )
+ if ( value == m_value )
return false;
text.Printf(wxT("%ld"), value);
else // using unconstrained input
#endif // wxUSE_SPINCTRL
{
- const wxString textOld(grid->GetCellValue(row, col));
text = Text()->GetValue();
if ( text.empty() )
{
- if ( textOld.empty() )
+ if ( oldval.empty() )
return false;
}
else // non-empty text now (maybe 0)
if ( !text.ToLong(&value) )
return false;
- // if value == m_valueOld == 0 but old text was "" and new one is
+ // if value == m_value == 0 but old text was "" and new one is
// "0" something still did change
- if ( value == m_valueOld && (value || !textOld.empty()) )
+ if ( value == m_value && (value || !oldval.empty()) )
return false;
}
}
+ m_value = value;
+
+ if ( newval )
+ *newval = text;
+
+ return true;
+}
+
+void wxGridCellNumberEditor::ApplyEdit(int row, int col, wxGrid* grid)
+{
wxGridTableBase * const table = grid->GetTable();
if ( table->CanSetValueAs(row, col, wxGRID_VALUE_NUMBER) )
- table->SetValueAsLong(row, col, value);
+ table->SetValueAsLong(row, col, m_value);
else
- table->SetValue(row, col, text);
-
- return true;
+ table->SetValue(row, col, wxString::Format("%ld", m_value));
}
void wxGridCellNumberEditor::Reset()
#if wxUSE_SPINCTRL
if ( HasRange() )
{
- Spin()->SetValue((int)m_valueOld);
+ Spin()->SetValue((int)m_value);
}
else
#endif
wxGridTableBase * const table = grid->GetTable();
if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) )
{
- m_valueOld = table->GetValueAsDouble(row, col);
+ m_value = table->GetValueAsDouble(row, col);
}
else
{
- m_valueOld = 0.0;
+ m_value = 0.0;
const wxString value = table->GetValue(row, col);
if ( !value.empty() )
{
- if ( !value.ToDouble(&m_valueOld) )
+ if ( !value.ToDouble(&m_value) )
{
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(const wxString& oldval, wxString *newval)
{
- const wxString text(Text()->GetValue()),
- textOld(grid->GetCellValue(row, col));
+ const wxString text(Text()->GetValue());
double value;
if ( !text.empty() )
}
else // new value is empty string
{
- if ( textOld.empty() )
+ if ( oldval.empty() )
return false; // nothing changed
value = 0.;
// 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() )
+ if ( wxIsSameDouble(value, m_value) && !text.empty() && !oldval.empty() )
return false; // nothing changed
+ m_value = value;
+
+ if ( newval )
+ *newval = text;
+
+ return true;
+}
+
+void wxGridCellFloatEditor::ApplyEdit(int row, int col, wxGrid* grid)
+{
wxGridTableBase * const table = grid->GetTable();
if ( table->CanSetValueAs(row, col, wxGRID_VALUE_FLOAT) )
- table->SetValueAsDouble(row, col, value);
+ table->SetValueAsDouble(row, col, m_value);
else
- table->SetValue(row, col, text);
-
- return true;
+ table->SetValue(row, col, Text()->GetValue());
}
void wxGridCellFloatEditor::Reset()
fmt = _T("%f");
}
- return wxString::Format(fmt, m_valueOld);
+ return wxString::Format(fmt, m_value);
}
bool wxGridCellFloatEditor::IsAcceptedKey(wxKeyEvent& event)
if (grid->GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL))
{
- m_startValue = grid->GetTable()->GetValueAsBool(row, col);
+ m_value = grid->GetTable()->GetValueAsBool(row, col);
}
else
{
wxString cellval( grid->GetTable()->GetValue(row, col) );
if ( cellval == ms_stringValues[false] )
- m_startValue = false;
+ m_value = false;
else if ( cellval == ms_stringValues[true] )
- m_startValue = true;
+ m_value = true;
else
{
// do not try to be smart here and convert it to true or false
}
}
- CBox()->SetValue(m_startValue);
+ CBox()->SetValue(m_value);
CBox()->SetFocus();
}
-bool wxGridCellBoolEditor::EndEdit(int row, int col,
- wxGrid* grid)
+bool wxGridCellBoolEditor::EndEdit(const wxString& WXUNUSED(oldval),
+ wxString *newval)
{
- wxASSERT_MSG(m_control,
- wxT("The wxGridCellEditor must be created first!"));
-
- bool changed = false;
bool value = CBox()->GetValue();
- if ( value != m_startValue )
- changed = true;
+ if ( value == m_value )
+ return false;
- if ( changed )
- {
- wxGridTableBase * const table = grid->GetTable();
- if ( table->CanGetValueAs(row, col, wxGRID_VALUE_BOOL) )
- table->SetValueAsBool(row, col, value);
- else
- table->SetValue(row, col, GetValue());
- }
+ m_value = value;
- return changed;
+ if ( newval )
+ *newval = GetValue();
+
+ return true;
+}
+
+void wxGridCellBoolEditor::ApplyEdit(int row, int col, wxGrid* grid)
+{
+ wxGridTableBase * const table = grid->GetTable();
+ if ( table->CanSetValueAs(row, col, wxGRID_VALUE_BOOL) )
+ table->SetValueAsBool(row, col, m_value);
+ else
+ table->SetValue(row, col, GetValue());
}
void wxGridCellBoolEditor::Reset()
wxASSERT_MSG(m_control,
wxT("The wxGridCellEditor must be created first!"));
- CBox()->SetValue(m_startValue);
+ CBox()->SetValue(m_value);
}
void wxGridCellBoolEditor::StartingClick()
if (evtHandler)
evtHandler->SetInSetFocus(true);
- m_startValue = grid->GetTable()->GetValue(row, col);
+ m_value = grid->GetTable()->GetValue(row, col);
- Reset(); // this updates combo box to correspond to m_startValue
+ Reset(); // this updates combo box to correspond to m_value
Combo()->SetFocus();
}
}
-bool wxGridCellChoiceEditor::EndEdit(int row, int col,
- wxGrid* grid)
+bool wxGridCellChoiceEditor::EndEdit(const wxString& WXUNUSED(oldval),
+ wxString *newval)
{
- wxString value = Combo()->GetValue();
- if ( value == m_startValue )
+ const wxString value = Combo()->GetValue();
+ if ( value == m_value )
return false;
- grid->GetTable()->SetValue(row, col, value);
+ m_value = value;
+
+ if ( newval )
+ *newval = value;
return true;
}
+void wxGridCellChoiceEditor::ApplyEdit(int row, int col, wxGrid* grid)
+{
+ grid->GetTable()->SetValue(row, col, m_value);
+}
+
void wxGridCellChoiceEditor::Reset()
{
if (m_allowOthers)
{
- Combo()->SetValue(m_startValue);
+ Combo()->SetValue(m_value);
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);
+ int pos = Combo()->FindString(m_value);
if (pos == wxNOT_FOUND)
pos = 0;
Combo()->SetSelection(pos);
m_gridWin->Refresh();
}
+void wxGrid::SetColumnsOrder(const wxArrayInt& order)
+{
+ m_colAt = order;
+
+ RefreshAfterColPosChange();
+}
+
void wxGrid::SetColPos(int idx, int pos)
{
// we're going to need m_colAt now, initialize it if needed
// Generate a grid event of specified type, return value same as above
//
-int wxGrid::SendEvent(const wxEventType type, int row, int col)
+int
+wxGrid::SendEvent(const wxEventType type, int row, int col, const wxString& s)
{
bool claimed, vetoed;
else
{
wxGridEvent gridEvt( GetId(), type, this, row, col );
+ gridEvt.SetString(s);
claimed = GetEventHandler()->ProcessEvent(gridEvt);
vetoed = !gridEvt.IsAllowed();
}
else
{
- //FIXME:add veto support
SendEvent(wxEVT_GRID_EDITOR_HIDDEN);
HideCellEditControl();
wxGridCellAttr* attr = GetCellAttr(row, col);
wxGridCellEditor* editor = attr->GetEditor(this, row, col);
- bool changed = editor->EndEdit(row, col, this);
- editor->DecRef();
- attr->DecRef();
+ wxString newval;
+ bool changed = editor->EndEdit(oldval, &newval);
- if (changed)
+ if ( changed && SendEvent(wxEVT_GRID_CELL_CHANGING, newval) != -1 )
{
- if ( SendEvent(wxEVT_GRID_CELL_CHANGE) == -1 )
+ editor->ApplyEdit(row, col, this);
+
+ // for compatibility reasons dating back to wx 2.8 when this event
+ // was called wxEVT_GRID_CELL_CHANGE and wxEVT_GRID_CELL_CHANGING
+ // didn't exist we allow vetoing this one too
+ if ( SendEvent(wxEVT_GRID_CELL_CHANGED, oldval) == -1 )
{
// Event has been vetoed, set the data back.
SetCellValue(row, col, oldval);
}
}
+
+ editor->DecRef();
+ attr->DecRef();
}
}