Merge branch 'grid-activatable-editors'
Add support for activatable editors in wxGrid and make wxGridCellBoolEditor activatable. Also a couple of editor-related bug fixes. See https://github.com/wxWidgets/wxWidgets/pull/1917
This commit is contained in:
commit
5a0723223d
@ -233,6 +233,130 @@ public:
|
||||
// Smart pointer to wxGridCellRenderer, calling DecRef() on it automatically.
|
||||
typedef wxObjectDataPtr<wxGridCellRenderer> wxGridCellRendererPtr;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Helper classes used by wxGridCellEditor::TryActivate() and DoActivate().
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// This class represents a source of cell activation, which may be either a
|
||||
// user event (mouse or keyboard) or the program itself.
|
||||
//
|
||||
// Note that objects of this class are supposed to be ephemeral and so store
|
||||
// pointers to the events specified when creating them, which are supposed to
|
||||
// have life-time greater than that of the objects of this class.
|
||||
class wxGridActivationSource
|
||||
{
|
||||
public:
|
||||
enum Origin
|
||||
{
|
||||
Program,
|
||||
Key,
|
||||
Mouse
|
||||
};
|
||||
|
||||
// Factory functions, only used by the library itself.
|
||||
static wxGridActivationSource FromProgram()
|
||||
{
|
||||
return wxGridActivationSource(Program, NULL);
|
||||
}
|
||||
|
||||
static wxGridActivationSource From(const wxKeyEvent& event)
|
||||
{
|
||||
return wxGridActivationSource(Key, &event);
|
||||
}
|
||||
|
||||
static wxGridActivationSource From(const wxMouseEvent& event)
|
||||
{
|
||||
return wxGridActivationSource(Mouse, &event);
|
||||
}
|
||||
|
||||
// Accessors allowing to retrieve information about the source.
|
||||
|
||||
// Can be called for any object.
|
||||
Origin GetOrigin() const { return m_origin; }
|
||||
|
||||
// Can be called for objects with Key origin only.
|
||||
const wxKeyEvent& GetKeyEvent() const
|
||||
{
|
||||
wxASSERT( m_origin == Key );
|
||||
|
||||
return *static_cast<const wxKeyEvent*>(m_event);
|
||||
}
|
||||
|
||||
// Can be called for objects with Mouse origin only.
|
||||
const wxMouseEvent& GetMouseEvent() const
|
||||
{
|
||||
wxASSERT( m_origin == Mouse );
|
||||
|
||||
return *static_cast<const wxMouseEvent*>(m_event);
|
||||
}
|
||||
|
||||
private:
|
||||
wxGridActivationSource(Origin origin, const wxEvent* event)
|
||||
: m_origin(origin),
|
||||
m_event(event)
|
||||
{
|
||||
}
|
||||
|
||||
const Origin m_origin;
|
||||
const wxEvent* const m_event;
|
||||
};
|
||||
|
||||
// This class represents the result of TryActivate(), which may be either
|
||||
// absence of any action (if activating wouldn't change the value anyhow),
|
||||
// attempt to change the value to the specified one or just start normal
|
||||
// editing, which is the default for the editors not supporting activation.
|
||||
class wxGridActivationResult
|
||||
{
|
||||
public:
|
||||
enum Action
|
||||
{
|
||||
Ignore,
|
||||
Change,
|
||||
ShowEditor
|
||||
};
|
||||
|
||||
// Factory functions, only used by the library itself.
|
||||
static wxGridActivationResult DoNothing()
|
||||
{
|
||||
return wxGridActivationResult(Ignore);
|
||||
}
|
||||
|
||||
static wxGridActivationResult DoChange(const wxString& newval)
|
||||
{
|
||||
return wxGridActivationResult(Change, newval);
|
||||
}
|
||||
|
||||
static wxGridActivationResult DoEdit()
|
||||
{
|
||||
return wxGridActivationResult(ShowEditor);
|
||||
}
|
||||
|
||||
// Accessors allowing to retrieve information about the result.
|
||||
|
||||
// Can be called for any object.
|
||||
Action GetAction() const { return m_action; }
|
||||
|
||||
// Can be called for objects with Change action type only.
|
||||
const wxString& GetNewValue() const
|
||||
{
|
||||
wxASSERT( m_action == Change );
|
||||
|
||||
return m_newval;
|
||||
}
|
||||
|
||||
private:
|
||||
explicit
|
||||
wxGridActivationResult(Action action, const wxString& newval = wxString())
|
||||
: m_action(action),
|
||||
m_newval(newval)
|
||||
{
|
||||
}
|
||||
|
||||
const Action m_action;
|
||||
const wxString m_newval;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGridCellEditor: This class is responsible for providing and manipulating
|
||||
// the in-place edit controls for the grid. Instances of wxGridCellEditor
|
||||
@ -335,6 +459,32 @@ public:
|
||||
wxControl* GetControl() { return wxDynamicCast(m_control, wxControl); }
|
||||
void SetControl(wxControl* control) { m_control = control; }
|
||||
|
||||
|
||||
// Support for "activatable" editors: those change the value of the cell
|
||||
// immediately, instead of creating an editor control and waiting for user
|
||||
// input.
|
||||
//
|
||||
// See wxGridCellBoolEditor for an example of such editor.
|
||||
|
||||
// Override this function to return "Change" activation result from it to
|
||||
// show that the editor supports activation. DoActivate() will be called if
|
||||
// the cell changing event is not vetoed.
|
||||
virtual
|
||||
wxGridActivationResult
|
||||
TryActivate(int WXUNUSED(row), int WXUNUSED(col),
|
||||
wxGrid* WXUNUSED(grid),
|
||||
const wxGridActivationSource& WXUNUSED(actSource))
|
||||
{
|
||||
return wxGridActivationResult::DoEdit();
|
||||
}
|
||||
|
||||
virtual
|
||||
void
|
||||
DoActivate(int WXUNUSED(row), int WXUNUSED(col), wxGrid* WXUNUSED(grid))
|
||||
{
|
||||
wxFAIL_MSG( "Must be overridden if TryActivate() is overridden" );
|
||||
}
|
||||
|
||||
protected:
|
||||
// the dtor is private because only DecRef() can delete us
|
||||
virtual ~wxGridCellEditor();
|
||||
@ -373,6 +523,34 @@ protected:
|
||||
// Smart pointer to wxGridCellEditor, calling DecRef() on it automatically.
|
||||
typedef wxObjectDataPtr<wxGridCellEditor> wxGridCellEditorPtr;
|
||||
|
||||
// Base class for editors that can be only activated and not edited normally.
|
||||
class wxGridCellActivatableEditor : public wxGridCellEditor
|
||||
{
|
||||
public:
|
||||
// In this class these methods must be overridden.
|
||||
virtual wxGridActivationResult
|
||||
TryActivate(int row, int col, wxGrid* grid,
|
||||
const wxGridActivationSource& actSource) = 0;
|
||||
virtual void DoActivate(int row, int col, wxGrid* grid) = 0;
|
||||
|
||||
// All the other methods that normally must be implemented in an editor are
|
||||
// defined as just stubs below, as they should be never called.
|
||||
|
||||
virtual void Create(wxWindow*, wxWindowID, wxEvtHandler*) wxOVERRIDE
|
||||
{ wxFAIL; }
|
||||
virtual void BeginEdit(int, int, wxGrid*) wxOVERRIDE
|
||||
{ wxFAIL; }
|
||||
virtual bool EndEdit(int, int, const wxGrid*,
|
||||
const wxString&, wxString*) wxOVERRIDE
|
||||
{ wxFAIL; return false; }
|
||||
virtual void ApplyEdit(int, int, wxGrid*) wxOVERRIDE
|
||||
{ wxFAIL; }
|
||||
virtual void Reset() wxOVERRIDE
|
||||
{ wxFAIL; }
|
||||
virtual wxString GetValue() const wxOVERRIDE
|
||||
{ wxFAIL; return wxString(); }
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGridHeaderRenderer and company: like wxGridCellRenderer but for headers
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -2609,28 +2787,34 @@ protected:
|
||||
bool Redimension( wxGridTableMessage& );
|
||||
|
||||
|
||||
// Send the given grid event and return -1 if it was vetoed or, as a
|
||||
// special exception, if an event for a particular cell resulted in this
|
||||
// cell being deleted, 1 if it was processed (but not vetoed) and 0 if it
|
||||
// wasn't processed.
|
||||
int DoSendEvent(wxGridEvent& gridEvt);
|
||||
enum EventResult
|
||||
{
|
||||
Event_Vetoed = -1,
|
||||
Event_Unhandled,
|
||||
Event_Handled,
|
||||
Event_CellDeleted // Event handler deleted the cell.
|
||||
};
|
||||
|
||||
// Send the given grid event and returns one of the event handling results
|
||||
// defined above.
|
||||
EventResult DoSendEvent(wxGridEvent& gridEvt);
|
||||
|
||||
// Generate an event of the given type and call DoSendEvent().
|
||||
int SendEvent(wxEventType evtType,
|
||||
EventResult SendEvent(wxEventType evtType,
|
||||
int row, int col,
|
||||
const wxMouseEvent& e);
|
||||
int SendEvent(wxEventType evtType,
|
||||
EventResult SendEvent(wxEventType evtType,
|
||||
const wxGridCellCoords& coords,
|
||||
const wxMouseEvent& e)
|
||||
{ return SendEvent(evtType, coords.GetRow(), coords.GetCol(), e); }
|
||||
int SendEvent(wxEventType evtType,
|
||||
EventResult SendEvent(wxEventType evtType,
|
||||
int row, int col,
|
||||
const wxString& s = wxString());
|
||||
int SendEvent(wxEventType evtType,
|
||||
EventResult SendEvent(wxEventType evtType,
|
||||
const wxGridCellCoords& coords,
|
||||
const wxString& s = wxString())
|
||||
{ return SendEvent(evtType, coords.GetRow(), coords.GetCol(), s); }
|
||||
int SendEvent(wxEventType evtType, const wxString& s = wxString())
|
||||
EventResult SendEvent(wxEventType evtType, const wxString& s = wxString())
|
||||
{ return SendEvent(evtType, m_currentCellCoords, s); }
|
||||
|
||||
// send wxEVT_GRID_{ROW,COL}_SIZE or wxEVT_GRID_COL_AUTO_SIZE, return true
|
||||
@ -2908,13 +3092,17 @@ private:
|
||||
}
|
||||
|
||||
// Show/hide the cell editor for the current cell unconditionally.
|
||||
void DoShowCellEditControl();
|
||||
|
||||
// Return false if the editor was activated instead of being shown and also
|
||||
// sets m_cellEditCtrlEnabled to true when it returns true as a side effect.
|
||||
bool DoShowCellEditControl(const wxGridActivationSource& actSource);
|
||||
void DoHideCellEditControl();
|
||||
|
||||
// Unconditionally try showing the editor for the current cell.
|
||||
//
|
||||
// Returns false if the user code vetoed wxEVT_GRID_EDITOR_SHOWN.
|
||||
bool DoEnableCellEditControl();
|
||||
// Returns false if the user code vetoed wxEVT_GRID_EDITOR_SHOWN or if the
|
||||
// editor was simply activated and won't be permanently shown.
|
||||
bool DoEnableCellEditControl(const wxGridActivationSource& actSource);
|
||||
|
||||
// Unconditionally disable (accepting the changes) the editor.
|
||||
void DoDisableCellEditControl();
|
||||
|
@ -238,6 +238,11 @@ class WXDLLIMPEXP_ADV wxGridCellBoolEditor : public wxGridCellEditor
|
||||
public:
|
||||
wxGridCellBoolEditor() { }
|
||||
|
||||
virtual wxGridActivationResult
|
||||
TryActivate(int row, int col, wxGrid* grid,
|
||||
const wxGridActivationSource& actSource) wxOVERRIDE;
|
||||
virtual void DoActivate(int row, int col, wxGrid* grid) wxOVERRIDE;
|
||||
|
||||
virtual void Create(wxWindow* parent,
|
||||
wxWindowID id,
|
||||
wxEvtHandler* evtHandler) wxOVERRIDE;
|
||||
@ -275,6 +280,15 @@ protected:
|
||||
wxCheckBox *CBox() const { return (wxCheckBox *)m_control; }
|
||||
|
||||
private:
|
||||
// These functions modify or use m_value.
|
||||
void SetValueFromGrid(int row, int col, wxGrid* grid);
|
||||
void SetGridFromValue(int row, int col, wxGrid* grid) const;
|
||||
|
||||
wxString GetStringValue() const { return GetStringValue(m_value); }
|
||||
|
||||
static
|
||||
wxString GetStringValue(bool value) { return ms_stringValues[value]; }
|
||||
|
||||
bool m_value;
|
||||
|
||||
static wxString ms_stringValues[2];
|
||||
|
@ -447,6 +447,97 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Represents a source of cell activation, which may be either a user event
|
||||
(mouse or keyboard) or the program itself.
|
||||
|
||||
An object of this class is passed to wxGridCellEditor::TryActivate() by the
|
||||
library and the code overriding this method may use its GetOrigin() method
|
||||
to determine how exactly the cell is being activated.
|
||||
|
||||
@since 3.1.4
|
||||
*/
|
||||
class wxGridActivationSource
|
||||
{
|
||||
public:
|
||||
/// Result of GetOrigin().
|
||||
enum Origin
|
||||
{
|
||||
/// Activated due to an explicit wxGrid::EnableCellEditControl() call.
|
||||
Program,
|
||||
|
||||
/// Activated due to the user pressing a key, see GetKeyEvent().
|
||||
Key,
|
||||
|
||||
/// Activated due to the user clicking on a cell, see GetMouseEvent().
|
||||
Mouse
|
||||
};
|
||||
|
||||
/// Get the origin of the activation.
|
||||
Origin GetOrigin() const;
|
||||
|
||||
/**
|
||||
Get the key event corresponding to the key press activating the cell.
|
||||
|
||||
This method can be called for objects with Key origin only, use
|
||||
GetOrigin() to check for this first.
|
||||
*/
|
||||
const wxKeyEvent& GetKeyEvent() const;
|
||||
|
||||
/**
|
||||
Get the mouse event corresponding to the click activating the cell.
|
||||
|
||||
This method can be called for objects with Mouse origin only, use
|
||||
GetOrigin() to check for this first.
|
||||
*/
|
||||
const wxMouseEvent& GetMouseEvent() const;
|
||||
};
|
||||
|
||||
/**
|
||||
Represents the result of wxGridCellEditor::TryActivate().
|
||||
|
||||
Editors overriding wxGridCellEditor::TryActivate() must use one of
|
||||
DoNothing(), DoChange() or DoEdit() methods to return an object of this
|
||||
type corresponding to the desired action.
|
||||
|
||||
@since 3.1.4
|
||||
*/
|
||||
class wxGridActivationResult
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Indicate that nothing should be done and the cell shouldn't be edited
|
||||
at all.
|
||||
|
||||
Note that this is different from DoEdit() and may be useful when the
|
||||
value of the cell wouldn't change if it were activated anyhow, e.g.
|
||||
because the key or mouse event carried by wxGridActivationSource would
|
||||
leave the cell value unchanged.
|
||||
*/
|
||||
static wxGridActivationResult DoNothing();
|
||||
|
||||
/**
|
||||
Indicate that activating the cell is possible and would change its
|
||||
value to the given one.
|
||||
|
||||
This is the method to call for activatable editors, using it will
|
||||
result in changing the value of the cell to @a newval without showing
|
||||
the editor control at all.
|
||||
|
||||
Note that the change may still be vetoed by wxEVT_GRID_CELL_CHANGING
|
||||
handler.
|
||||
*/
|
||||
static wxGridActivationResult DoChange(const wxString& newval);
|
||||
|
||||
/**
|
||||
Indicate that the editor control should be shown and the cell should be
|
||||
edited normally.
|
||||
|
||||
This is the default return value of wxGridCellEditor::TryActivate().
|
||||
*/
|
||||
static wxGridActivationResult DoEdit();
|
||||
};
|
||||
|
||||
/**
|
||||
@class wxGridCellEditor
|
||||
|
||||
@ -456,6 +547,15 @@ public:
|
||||
the cell attributes for individual cells, rows, columns, or even for the
|
||||
entire grid.
|
||||
|
||||
Normally wxGridCellEditor shows some UI control allowing the user to edit
|
||||
the cell, but starting with wxWidgets 3.1.4 it's also possible to define
|
||||
"activatable" cell editors, that change the value of the cell directly when
|
||||
it's activated (typically by pressing Space key or clicking on it), see
|
||||
TryActivate() method. Note that when implementing an editor which is always
|
||||
activatable, i.e. never shows any in-place editor, it is more convenient to
|
||||
derive its class from wxGridCellActivatableEditor than from wxGridCellEditor
|
||||
itself.
|
||||
|
||||
@library{wxcore}
|
||||
@category{grid}
|
||||
|
||||
@ -627,6 +727,41 @@ public:
|
||||
void SetControl(wxControl* control);
|
||||
|
||||
|
||||
/**
|
||||
Function allowing to create an "activatable" editor.
|
||||
|
||||
As explained in this class description, activatable editors don't show
|
||||
any edit control but change the cell value directly, when it is
|
||||
activated (by any way described by wxGridActivationSource).
|
||||
|
||||
To create such editor, this method must be overridden to return
|
||||
wxGridActivationResult::DoChange() passing it the new value of the
|
||||
cell. If the change is not vetoed by wxEVT_GRID_CELL_CHANGING handler,
|
||||
DoActivate() will be called to actually change the value, so it must be
|
||||
overridden as well if TryActivate() is overridden.
|
||||
|
||||
By default, wxGridActivationResult::DoEdit() is returned, meaning that
|
||||
this is a normal editor, using an edit control for changing the cell
|
||||
value.
|
||||
|
||||
@since 3.1.4
|
||||
*/
|
||||
virtual wxGridActivationResult
|
||||
TryActivate(int row, int col, wxGrid* grid,
|
||||
const wxGridActivationSource& actSource);
|
||||
|
||||
/**
|
||||
Function which must be overridden for "activatable" editors.
|
||||
|
||||
If TryActivate() is overridden to return "change" action, this function
|
||||
will be called to actually apply this change. Note that it is not
|
||||
passed the value to apply, as it is assumed that the editor class
|
||||
stores this value as a member variable anyhow.
|
||||
|
||||
@since 3.1.4
|
||||
*/
|
||||
virtual void DoActivate(int row, int col, wxGrid* grid);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
@ -635,6 +770,34 @@ protected:
|
||||
virtual ~wxGridCellEditor();
|
||||
};
|
||||
|
||||
/**
|
||||
Base class for activatable editors.
|
||||
|
||||
Inheriting from this class makes it simpler to implement editors that
|
||||
support only activation, but not in-place editing, as they only need to
|
||||
implement TryActivate(), DoActivate() and Clone() methods, but not all the
|
||||
other pure virtual methods of wxGridCellEditor.
|
||||
|
||||
@since 3.1.4
|
||||
*/
|
||||
class wxGridCellActivatableEditor : public wxGridCellEditor
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Same method as in wxGridCellEditor, but pure virtual.
|
||||
|
||||
Note that the implementation of this method must never return
|
||||
wxGridActivationResult::DoEdit() for the editors inheriting from this
|
||||
class, as it doesn't support normal editing.
|
||||
*/
|
||||
virtual wxGridActivationResult
|
||||
TryActivate(int row, int col, wxGrid* grid,
|
||||
const wxGridActivationSource& actSource) = 0;
|
||||
|
||||
/// Same method as in wxGridCellEditor, but pure virtual.
|
||||
virtual void DoActivate(int row, int col, wxGrid* grid) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
Smart pointer wrapping wxGridCellEditor.
|
||||
|
||||
|
@ -121,6 +121,135 @@ private:
|
||||
wxDECLARE_NO_COPY_CLASS(CustomColumnHeadersProvider);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Custom wxGrid renderer and editor for showing stars as used for rating
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Max number of stars shown by MyGridStarRenderer.
|
||||
static const int MAX_STARS = 5;
|
||||
|
||||
// Helper function returning the number between 0 and MAX_STARS corresponding
|
||||
// to the value of the cell.
|
||||
static int GetStarValue(wxGrid& grid, int row, int col)
|
||||
{
|
||||
unsigned long n = 0;
|
||||
if ( !grid.GetCellValue(row, col).ToULong(&n) || n > MAX_STARS )
|
||||
n = 0;
|
||||
|
||||
return static_cast<int>(n);
|
||||
}
|
||||
|
||||
// Another helper returning the string containing the appropriate number of
|
||||
// black and white stars.
|
||||
static wxString GetStarString(int numBlackStars)
|
||||
{
|
||||
const wxUniChar BLACK_STAR = 0x2605;
|
||||
const wxUniChar WHITE_STAR = 0x2606;
|
||||
|
||||
return wxString(BLACK_STAR, numBlackStars) +
|
||||
wxString(WHITE_STAR, MAX_STARS - numBlackStars);
|
||||
}
|
||||
|
||||
// Renders the value of the cell, which is supposed to be a number between 1
|
||||
// and 5, as a sequence of that number of black stars followed by the number of
|
||||
// white stars needed to have 5 stars in total.
|
||||
class MyGridStarRenderer : public wxGridCellRenderer
|
||||
{
|
||||
public:
|
||||
virtual void Draw(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
const wxRect& rect,
|
||||
int row, int col,
|
||||
bool isSelected) wxOVERRIDE
|
||||
{
|
||||
wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
|
||||
|
||||
grid.DrawTextRectangle(dc, GetStarString(GetStarValue(grid, row, col)),
|
||||
rect, attr);
|
||||
}
|
||||
|
||||
virtual wxSize GetBestSize(wxGrid& WXUNUSED(grid),
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
int WXUNUSED(row),
|
||||
int WXUNUSED(col)) wxOVERRIDE
|
||||
{
|
||||
dc.SetFont(attr.GetFont());
|
||||
return dc.GetTextExtent(GetStarString(MAX_STARS));
|
||||
}
|
||||
|
||||
virtual wxGridCellRenderer *Clone() const wxOVERRIDE
|
||||
{
|
||||
return new MyGridStarRenderer();
|
||||
}
|
||||
};
|
||||
|
||||
// Activatable editor cycling the number of stars on each activation.
|
||||
class MyGridStarEditor : public wxGridCellActivatableEditor
|
||||
{
|
||||
public:
|
||||
virtual wxGridActivationResult
|
||||
TryActivate(int row, int col, wxGrid* grid,
|
||||
const wxGridActivationSource& actSource) wxOVERRIDE
|
||||
{
|
||||
int numStars = -1;
|
||||
|
||||
switch ( actSource.GetOrigin() )
|
||||
{
|
||||
case wxGridActivationSource::Program:
|
||||
// It isn't really possible to programmatically start editing a
|
||||
// cell using this editor.
|
||||
return wxGridActivationResult::DoNothing();
|
||||
|
||||
case wxGridActivationSource::Key:
|
||||
switch ( actSource.GetKeyEvent().GetKeyCode() )
|
||||
{
|
||||
case '0': numStars = 0; break;
|
||||
case '1': numStars = 1; break;
|
||||
case '2': numStars = 2; break;
|
||||
case '3': numStars = 3; break;
|
||||
case '4': numStars = 4; break;
|
||||
case '5': numStars = 5; break;
|
||||
case ' ':
|
||||
// Use space key to cycle over the values.
|
||||
break;
|
||||
|
||||
default:
|
||||
return wxGridActivationResult::DoNothing();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case wxGridActivationSource::Mouse:
|
||||
// Ideally we should use the mouse event position to determine
|
||||
// on which star the user clicked, but for now keep it simple
|
||||
// and just cycle through the star value.
|
||||
break;
|
||||
}
|
||||
|
||||
if ( numStars == -1 )
|
||||
numStars = (GetStarValue(*grid, row, col) + 1) % (MAX_STARS + 1);
|
||||
|
||||
m_value.Printf("%d", numStars);
|
||||
|
||||
return wxGridActivationResult::DoChange(m_value);
|
||||
}
|
||||
|
||||
virtual void DoActivate(int row, int col, wxGrid* grid) wxOVERRIDE
|
||||
{
|
||||
grid->SetCellValue(row, col, m_value);
|
||||
}
|
||||
|
||||
virtual wxGridCellEditor *Clone() const
|
||||
{
|
||||
return new MyGridStarEditor();
|
||||
}
|
||||
|
||||
private:
|
||||
wxString m_value;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxWin macros
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -517,6 +646,10 @@ GridFrame::GridFrame()
|
||||
grid->SetCellAlignment(4, 4, wxALIGN_CENTRE, wxALIGN_CENTRE);
|
||||
grid->SetCellRenderer(4, 4, new MyGridCellRenderer);
|
||||
|
||||
grid->SetCellValue(4, 5, "3");
|
||||
grid->SetCellRenderer(4, 5, new MyGridStarRenderer);
|
||||
grid->SetCellEditor(4, 5, new MyGridStarEditor);
|
||||
|
||||
grid->SetCellRenderer(3, 0, new wxGridCellBoolRenderer);
|
||||
grid->SetCellEditor(3, 0, new wxGridCellBoolEditor);
|
||||
grid->SetCellBackgroundColour(3, 0, wxColour(255, 127, 127));
|
||||
@ -534,7 +667,7 @@ GridFrame::GridFrame()
|
||||
grid->SetRowAttr(5, attr);
|
||||
|
||||
grid->SetCellValue(2, 4, "a wider column");
|
||||
grid->SetColSize(4, 3*grid->GetDefaultColLabelSize()/2);
|
||||
grid->SetColSize(4, 3*grid->GetDefaultColSize()/2);
|
||||
grid->SetColMinimalWidth(4, grid->GetColSize(4));
|
||||
|
||||
grid->SetCellTextColour(5, 8, *wxGREEN);
|
||||
|
@ -3716,7 +3716,7 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event, wxGridRowLabelWindo
|
||||
{
|
||||
row = YToRow(pos.y);
|
||||
if ( row >= 0 &&
|
||||
!SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, row, -1, event ) )
|
||||
SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, row, -1, event ) == Event_Unhandled )
|
||||
{
|
||||
// Check if row selection is possible and allowed, before doing
|
||||
// anything else, including changing the cursor mode to "select
|
||||
@ -3792,7 +3792,7 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event, wxGridRowLabelWindo
|
||||
{
|
||||
row = YToRow(pos.y);
|
||||
if ( row >=0 &&
|
||||
!SendEvent( wxEVT_GRID_LABEL_LEFT_DCLICK, row, -1, event ) )
|
||||
SendEvent( wxEVT_GRID_LABEL_LEFT_DCLICK, row, -1, event ) == Event_Unhandled )
|
||||
{
|
||||
// no default action at the moment
|
||||
}
|
||||
@ -3816,7 +3816,7 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event, wxGridRowLabelWindo
|
||||
{
|
||||
row = YToRow(pos.y);
|
||||
if ( row < 0 ||
|
||||
!SendEvent( wxEVT_GRID_LABEL_RIGHT_CLICK, row, -1, event ) )
|
||||
SendEvent( wxEVT_GRID_LABEL_RIGHT_CLICK, row, -1, event ) == Event_Unhandled )
|
||||
{
|
||||
// no default action at the moment
|
||||
event.Skip();
|
||||
@ -3829,7 +3829,7 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event, wxGridRowLabelWindo
|
||||
{
|
||||
row = YToRow(pos.y);
|
||||
if ( row < 0 ||
|
||||
!SendEvent( wxEVT_GRID_LABEL_RIGHT_DCLICK, row, -1, event ) )
|
||||
SendEvent( wxEVT_GRID_LABEL_RIGHT_DCLICK, row, -1, event ) == Event_Unhandled )
|
||||
{
|
||||
// no default action at the moment
|
||||
event.Skip();
|
||||
@ -3954,7 +3954,7 @@ void wxGrid::DoColHeaderClick(int col)
|
||||
{
|
||||
// we consider that the grid was resorted if this event is processed and
|
||||
// not vetoed
|
||||
if ( SendEvent(wxEVT_GRID_COL_SORT, -1, col) == 1 )
|
||||
if ( SendEvent(wxEVT_GRID_COL_SORT, -1, col) == Event_Handled )
|
||||
{
|
||||
SetSortingColumn(col, IsSortingBy(col) ? !m_sortIsAscending : true);
|
||||
Refresh();
|
||||
@ -4112,7 +4112,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event, wxGridColLabelWindo
|
||||
else // not a request to start resizing
|
||||
{
|
||||
if ( col >= 0 &&
|
||||
!SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, col, event ) )
|
||||
SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, col, event ) == Event_Unhandled )
|
||||
{
|
||||
if ( m_canDragColMove )
|
||||
{
|
||||
@ -4187,7 +4187,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event, wxGridColLabelWindo
|
||||
if ( colEdge == -1 )
|
||||
{
|
||||
if ( col >= 0 &&
|
||||
! SendEvent( wxEVT_GRID_LABEL_LEFT_DCLICK, -1, col, event ) )
|
||||
SendEvent( wxEVT_GRID_LABEL_LEFT_DCLICK, -1, col, event ) == Event_Unhandled )
|
||||
{
|
||||
// no default action at the moment
|
||||
}
|
||||
@ -4268,7 +4268,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event, wxGridColLabelWindo
|
||||
else if ( event.RightDown() )
|
||||
{
|
||||
if ( col < 0 ||
|
||||
!SendEvent( wxEVT_GRID_LABEL_RIGHT_CLICK, -1, col, event ) )
|
||||
SendEvent( wxEVT_GRID_LABEL_RIGHT_CLICK, -1, col, event ) == Event_Unhandled )
|
||||
{
|
||||
// no default action at the moment
|
||||
event.Skip();
|
||||
@ -4280,7 +4280,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event, wxGridColLabelWindo
|
||||
else if ( event.RightDClick() )
|
||||
{
|
||||
if ( col < 0 ||
|
||||
!SendEvent( wxEVT_GRID_LABEL_RIGHT_DCLICK, -1, col, event ) )
|
||||
SendEvent( wxEVT_GRID_LABEL_RIGHT_DCLICK, -1, col, event ) == Event_Unhandled )
|
||||
{
|
||||
// no default action at the moment
|
||||
event.Skip();
|
||||
@ -4322,7 +4322,7 @@ void wxGrid::ProcessCornerLabelMouseEvent( wxMouseEvent& event )
|
||||
// indicate corner label by having both row and
|
||||
// col args == -1
|
||||
//
|
||||
if ( !SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, -1, event ) )
|
||||
if ( SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, -1, event ) == Event_Unhandled )
|
||||
{
|
||||
SelectAll();
|
||||
}
|
||||
@ -4333,7 +4333,7 @@ void wxGrid::ProcessCornerLabelMouseEvent( wxMouseEvent& event )
|
||||
}
|
||||
else if ( event.RightDown() )
|
||||
{
|
||||
if ( !SendEvent( wxEVT_GRID_LABEL_RIGHT_CLICK, -1, -1, event ) )
|
||||
if ( SendEvent( wxEVT_GRID_LABEL_RIGHT_CLICK, -1, -1, event ) == Event_Unhandled )
|
||||
{
|
||||
// no default action at the moment
|
||||
event.Skip();
|
||||
@ -4341,7 +4341,7 @@ void wxGrid::ProcessCornerLabelMouseEvent( wxMouseEvent& event )
|
||||
}
|
||||
else if ( event.RightDClick() )
|
||||
{
|
||||
if ( !SendEvent( wxEVT_GRID_LABEL_RIGHT_DCLICK, -1, -1, event ) )
|
||||
if ( SendEvent( wxEVT_GRID_LABEL_RIGHT_DCLICK, -1, -1, event ) == Event_Unhandled )
|
||||
{
|
||||
// no default action at the moment
|
||||
event.Skip();
|
||||
@ -4494,7 +4494,7 @@ wxGrid::DoGridCellDrag(wxMouseEvent& event,
|
||||
if ( CanDragCell() )
|
||||
{
|
||||
// if event is handled by user code, no further processing
|
||||
return SendEvent(wxEVT_GRID_CELL_BEGIN_DRAG, coords, event) == 0;
|
||||
return SendEvent(wxEVT_GRID_CELL_BEGIN_DRAG, coords, event) == Event_Unhandled;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -4543,7 +4543,7 @@ wxGrid::DoGridCellLeftDown(wxMouseEvent& event,
|
||||
const wxGridCellCoords& coords,
|
||||
const wxPoint& pos)
|
||||
{
|
||||
if ( SendEvent(wxEVT_GRID_CELL_LEFT_CLICK, coords, event) )
|
||||
if ( SendEvent(wxEVT_GRID_CELL_LEFT_CLICK, coords, event) != Event_Unhandled )
|
||||
{
|
||||
// event handled by user code, no need to do anything here
|
||||
return;
|
||||
@ -4644,7 +4644,7 @@ wxGrid::DoGridCellLeftDClick(wxMouseEvent& event,
|
||||
{
|
||||
if ( XToEdgeOfCol(pos.x) < 0 && YToEdgeOfRow(pos.y) < 0 )
|
||||
{
|
||||
if ( !SendEvent(wxEVT_GRID_CELL_LEFT_DCLICK, coords, event) )
|
||||
if ( SendEvent(wxEVT_GRID_CELL_LEFT_DCLICK, coords, event) == Event_Unhandled )
|
||||
{
|
||||
// we want double click to select a cell and start editing
|
||||
// (i.e. to behave in same way as sequence of two slow clicks):
|
||||
@ -4664,7 +4664,7 @@ wxGrid::DoGridCellLeftUp(wxMouseEvent& event,
|
||||
{
|
||||
ClearSelection();
|
||||
|
||||
if ( DoEnableCellEditControl() )
|
||||
if ( DoEnableCellEditControl(wxGridActivationSource::From(event)) )
|
||||
GetCurrentCellEditorPtr()->StartingClick();
|
||||
|
||||
m_waitForSlowClick = false;
|
||||
@ -4835,9 +4835,9 @@ void wxGrid::ProcessGridCellMouseEvent(wxMouseEvent& event, wxGridWindow *eventG
|
||||
else if ( event.LeftDClick() )
|
||||
handled = (DoGridCellLeftDClick(event, coords, pos), true);
|
||||
else if ( event.RightDown() )
|
||||
handled = SendEvent(wxEVT_GRID_CELL_RIGHT_CLICK, coords, event) != 0;
|
||||
handled = SendEvent(wxEVT_GRID_CELL_RIGHT_CLICK, coords, event) != Event_Unhandled;
|
||||
else if ( event.RightDClick() )
|
||||
handled = SendEvent(wxEVT_GRID_CELL_RIGHT_DCLICK, coords, event) != 0;
|
||||
handled = SendEvent(wxEVT_GRID_CELL_RIGHT_DCLICK, coords, event) != Event_Unhandled;
|
||||
}
|
||||
}
|
||||
else if ( event.Moving() )
|
||||
@ -4949,9 +4949,8 @@ void wxGrid::DoEndMoveCol(int pos)
|
||||
{
|
||||
wxASSERT_MSG( m_dragMoveCol != -1, "no matching DoStartMoveCol?" );
|
||||
|
||||
if ( SendEvent(wxEVT_GRID_COL_MOVE, -1, m_dragMoveCol) != -1 )
|
||||
if ( SendEvent(wxEVT_GRID_COL_MOVE, -1, m_dragMoveCol) != Event_Vetoed )
|
||||
SetColPos(m_dragMoveCol, pos);
|
||||
//else: vetoed by user
|
||||
|
||||
m_dragMoveCol = -1;
|
||||
}
|
||||
@ -5285,31 +5284,27 @@ wxGrid::SendGridSizeEvent(wxEventType type,
|
||||
return ProcessWindowEvent(gridEvt);
|
||||
}
|
||||
|
||||
// Process the event and return
|
||||
// -1 if the event was vetoed or if event cell was deleted
|
||||
// +1 if the event was processed (but not vetoed)
|
||||
// 0 if the event wasn't handled
|
||||
int wxGrid::DoSendEvent(wxGridEvent& gridEvt)
|
||||
wxGrid::EventResult wxGrid::DoSendEvent(wxGridEvent& gridEvt)
|
||||
{
|
||||
const bool claimed = ProcessWindowEvent(gridEvt);
|
||||
|
||||
// A Veto'd event may not be `claimed' so test this first
|
||||
if ( !gridEvt.IsAllowed() )
|
||||
return -1;
|
||||
return Event_Vetoed;
|
||||
|
||||
// We also return -1 if the event cell was deleted, as this allows to have
|
||||
// checks in several functions that generate an event and then proceed
|
||||
// doing something by default with the selected cell: this shouldn't be
|
||||
// done if the user-defined handler deleted this cell.
|
||||
// Detect the special case in which the event cell was deleted, as this
|
||||
// allows to have checks in several functions that generate an event and
|
||||
// then proceed doing something by default with the selected cell: this
|
||||
// shouldn't be done if the user-defined handler deleted this cell.
|
||||
if ( gridEvt.GetRow() >= GetNumberRows() ||
|
||||
gridEvt.GetCol() >= GetNumberCols() )
|
||||
return -1;
|
||||
return Event_CellDeleted;
|
||||
|
||||
return claimed ? 1 : 0;
|
||||
return claimed ? Event_Handled : Event_Unhandled;
|
||||
}
|
||||
|
||||
// Generate a grid event based on a mouse event and call DoSendEvent() with it.
|
||||
int
|
||||
wxGrid::EventResult
|
||||
wxGrid::SendEvent(wxEventType type,
|
||||
int row, int col,
|
||||
const wxMouseEvent& mouseEv)
|
||||
@ -5362,7 +5357,7 @@ wxGrid::SendEvent(wxEventType type,
|
||||
|
||||
// Generate a grid event of specified type, return value same as above
|
||||
//
|
||||
int
|
||||
wxGrid::EventResult
|
||||
wxGrid::SendEvent(wxEventType type, int row, int col, const wxString& s)
|
||||
{
|
||||
wxGridEvent gridEvt( GetId(), type, this, row, col );
|
||||
@ -5969,7 +5964,8 @@ void wxGrid::OnChar( wxKeyEvent& event )
|
||||
// ensure cell is visble
|
||||
MakeCellVisible(m_currentCellCoords);
|
||||
|
||||
if ( DoEnableCellEditControl() && !specialEditKey )
|
||||
if ( DoEnableCellEditControl(wxGridActivationSource::From(event))
|
||||
&& !specialEditKey )
|
||||
editor->StartingKey(event);
|
||||
}
|
||||
else
|
||||
@ -6048,10 +6044,18 @@ void wxGrid::DoGridProcessTab(wxKeyboardState& kbdState)
|
||||
|
||||
bool wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
|
||||
{
|
||||
if ( SendEvent(wxEVT_GRID_SELECT_CELL, coords) == -1 )
|
||||
switch ( SendEvent(wxEVT_GRID_SELECT_CELL, coords) )
|
||||
{
|
||||
// the event has been vetoed - do nothing
|
||||
return false;
|
||||
case Event_Vetoed:
|
||||
case Event_CellDeleted:
|
||||
// We shouldn't do anything if the event was vetoed and can't do
|
||||
// anything if the cell doesn't exist any longer.
|
||||
return false;
|
||||
|
||||
case Event_Unhandled:
|
||||
case Event_Handled:
|
||||
// But it doesn't matter here if the event was skipped or not.
|
||||
break;
|
||||
}
|
||||
|
||||
wxGridWindow *currentGridWindow = CellToGridWindow(coords);
|
||||
@ -7149,7 +7153,7 @@ void wxGrid::EnableCellEditControl( bool enable )
|
||||
// this should be checked by the caller!
|
||||
wxCHECK_RET( CanEnableCellControl(), wxT("can't enable editing for this cell!") );
|
||||
|
||||
DoEnableCellEditControl();
|
||||
DoEnableCellEditControl(wxGridActivationSource::FromProgram());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -7158,14 +7162,31 @@ void wxGrid::EnableCellEditControl( bool enable )
|
||||
}
|
||||
}
|
||||
|
||||
bool wxGrid::DoEnableCellEditControl()
|
||||
bool wxGrid::DoEnableCellEditControl(const wxGridActivationSource& actSource)
|
||||
{
|
||||
if ( SendEvent(wxEVT_GRID_EDITOR_SHOWN) == -1 )
|
||||
switch ( SendEvent(wxEVT_GRID_EDITOR_SHOWN) )
|
||||
{
|
||||
case Event_Vetoed:
|
||||
case Event_CellDeleted:
|
||||
// We shouldn't do anything if the event was vetoed and can't do
|
||||
// anything if the cell doesn't exist any longer.
|
||||
return false;
|
||||
|
||||
case Event_Unhandled:
|
||||
case Event_Handled:
|
||||
// But it doesn't matter here if the event was skipped or not.
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !DoShowCellEditControl(actSource) )
|
||||
{
|
||||
// We have to send the HIDDEN event matching the SHOWN one above as the
|
||||
// user code may reasonably expect always getting them in pairs, so do
|
||||
// it even if the editor hadn't really been shown at all.
|
||||
SendEvent(wxEVT_GRID_EDITOR_HIDDEN);
|
||||
|
||||
return false;
|
||||
|
||||
m_cellEditCtrlEnabled = true;
|
||||
|
||||
DoShowCellEditControl();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -7217,16 +7238,64 @@ void wxGrid::ShowCellEditControl()
|
||||
return;
|
||||
}
|
||||
|
||||
DoShowCellEditControl();
|
||||
DoShowCellEditControl(wxGridActivationSource::FromProgram());
|
||||
}
|
||||
}
|
||||
|
||||
void wxGrid::DoShowCellEditControl()
|
||||
bool wxGrid::DoShowCellEditControl(const wxGridActivationSource& actSource)
|
||||
{
|
||||
wxRect rect = CellToRect( m_currentCellCoords );
|
||||
int row = m_currentCellCoords.GetRow();
|
||||
int col = m_currentCellCoords.GetCol();
|
||||
|
||||
wxGridCellAttrPtr attr = GetCellAttrPtr(row, col);
|
||||
wxGridCellEditorPtr editor = attr->GetEditorPtr(this, row, col);
|
||||
|
||||
const wxGridActivationResult&
|
||||
res = editor->TryActivate(row, col, this, actSource);
|
||||
switch ( res.GetAction() )
|
||||
{
|
||||
case wxGridActivationResult::Change:
|
||||
// This is somewhat similar to what DoSaveEditControlValue() does.
|
||||
// but we don't allow vetoing CHANGED event here as this code is
|
||||
// new and shouldn't have to support this obsolete usage.
|
||||
switch ( SendEvent(wxEVT_GRID_CELL_CHANGING, res.GetNewValue()) )
|
||||
{
|
||||
case Event_Vetoed:
|
||||
case Event_CellDeleted:
|
||||
break;
|
||||
|
||||
case Event_Unhandled:
|
||||
case Event_Handled:
|
||||
const wxString& oldval = GetCellValue(m_currentCellCoords);
|
||||
|
||||
editor->DoActivate(row, col, this);
|
||||
|
||||
// Show the new cell value.
|
||||
RefreshBlock(m_currentCellCoords, m_currentCellCoords);
|
||||
|
||||
if ( SendEvent(wxEVT_GRID_CELL_CHANGED, oldval) == Event_Vetoed )
|
||||
{
|
||||
wxFAIL_MSG( "Vetoing wxEVT_GRID_CELL_CHANGED is ignored" );
|
||||
}
|
||||
break;
|
||||
}
|
||||
wxFALLTHROUGH;
|
||||
|
||||
case wxGridActivationResult::Ignore:
|
||||
// In any case, don't start editing normally.
|
||||
return false;
|
||||
|
||||
case wxGridActivationResult::ShowEditor:
|
||||
// Continue normally.
|
||||
break;
|
||||
}
|
||||
|
||||
// It's not enabled just yet, but will be soon, and we need to set it
|
||||
// before generating any events in case their user-defined handlers decide
|
||||
// to call EnableCellEditControl() to avoid reentrancy problems.
|
||||
m_cellEditCtrlEnabled = true;
|
||||
|
||||
wxGridWindow *gridWindow = CellToGridWindow(row, col);
|
||||
|
||||
// if this is part of a multicell, find owner (topleft)
|
||||
@ -7251,8 +7320,6 @@ void wxGrid::DoShowCellEditControl()
|
||||
rect.Deflate(1, 1);
|
||||
#endif
|
||||
|
||||
wxGridCellAttrPtr attr = GetCellAttrPtr(row, col);
|
||||
wxGridCellEditorPtr editor = attr->GetEditorPtr(this, row, col);
|
||||
if ( !editor->IsCreated() )
|
||||
{
|
||||
editor->Create(gridWindow, wxID_ANY,
|
||||
@ -7348,6 +7415,8 @@ void wxGrid::DoShowCellEditControl()
|
||||
|
||||
editor->BeginEdit(row, col, this);
|
||||
editor->SetCellAttr(NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wxGrid::HideCellEditControl()
|
||||
@ -7443,21 +7512,32 @@ void wxGrid::DoSaveEditControlValue()
|
||||
wxGridCellEditorPtr editor = GetCurrentCellEditorPtr();
|
||||
|
||||
wxString newval;
|
||||
bool changed = editor->EndEdit(row, col, this, oldval, &newval);
|
||||
if ( !editor->EndEdit(row, col, this, oldval, &newval) )
|
||||
return;
|
||||
|
||||
if ( changed && SendEvent(wxEVT_GRID_CELL_CHANGING, newval) != -1 )
|
||||
switch ( SendEvent(wxEVT_GRID_CELL_CHANGING, newval) )
|
||||
{
|
||||
editor->ApplyEdit(row, col, this);
|
||||
case Event_Vetoed:
|
||||
case Event_CellDeleted:
|
||||
break;
|
||||
|
||||
// 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(m_currentCellCoords, oldval);
|
||||
case Event_Unhandled:
|
||||
case Event_Handled:
|
||||
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) == Event_Vetoed )
|
||||
{
|
||||
// Event has been vetoed, set the data back.
|
||||
//
|
||||
// Note that we must use row and col here, which are sure to
|
||||
// not have been changed, while m_currentCellCoords could have
|
||||
// been changed by the event handler.
|
||||
SetCellValue(row, col, oldval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wxGrid::OnHideEditor(wxCommandEvent& WXUNUSED(event))
|
||||
|
@ -671,6 +671,8 @@ void wxGridCellTextEditor::SetParameters(const wxString& params)
|
||||
void wxGridCellTextEditor::SetValidator(const wxValidator& validator)
|
||||
{
|
||||
m_validator.reset(static_cast<wxValidator*>(validator.Clone()));
|
||||
if ( m_validator && IsCreated() )
|
||||
Text()->SetValidator(*m_validator);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1247,6 +1249,61 @@ bool wxGridCellFloatEditor::IsAcceptedKey(wxKeyEvent& event)
|
||||
// the default values for GetValue()
|
||||
wxString wxGridCellBoolEditor::ms_stringValues[2] = { wxT(""), wxT("1") };
|
||||
|
||||
wxGridActivationResult
|
||||
wxGridCellBoolEditor::TryActivate(int row, int col, wxGrid* grid,
|
||||
const wxGridActivationSource& actSource)
|
||||
{
|
||||
SetValueFromGrid(row, col, grid);
|
||||
|
||||
switch ( actSource.GetOrigin() )
|
||||
{
|
||||
case wxGridActivationSource::Program:
|
||||
// It's not really clear what should happen in this case, so for
|
||||
// now show the editor interactively to avoid making the choice.
|
||||
return wxGridActivationResult::DoEdit();
|
||||
|
||||
case wxGridActivationSource::Mouse:
|
||||
m_value = !m_value;
|
||||
return wxGridActivationResult::DoChange(GetStringValue());
|
||||
|
||||
case wxGridActivationSource::Key:
|
||||
switch ( actSource.GetKeyEvent().GetKeyCode() )
|
||||
{
|
||||
// Handle F2 as space here because we must handle it somehow,
|
||||
// because pressing it always starts editing in wxGrid, and
|
||||
// it's not really clear what else could it do.
|
||||
case WXK_F2:
|
||||
case WXK_SPACE:
|
||||
m_value = !m_value;
|
||||
break;
|
||||
|
||||
case '+':
|
||||
if ( m_value )
|
||||
return wxGridActivationResult::DoNothing();
|
||||
|
||||
m_value = true;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
if ( !m_value )
|
||||
return wxGridActivationResult::DoNothing();
|
||||
|
||||
m_value = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return wxGridActivationResult::DoChange(GetStringValue());
|
||||
}
|
||||
|
||||
wxFAIL_MSG( "unknown activation source origin" );
|
||||
return wxGridActivationResult::DoNothing();
|
||||
}
|
||||
|
||||
void wxGridCellBoolEditor::DoActivate(int row, int col, wxGrid* grid)
|
||||
{
|
||||
SetGridFromValue(row, col, grid);
|
||||
}
|
||||
|
||||
void wxGridCellBoolEditor::Create(wxWindow* parent,
|
||||
wxWindowID id,
|
||||
wxEvtHandler* evtHandler)
|
||||
@ -1312,27 +1369,7 @@ void wxGridCellBoolEditor::BeginEdit(int row, int col, wxGrid* grid)
|
||||
wxASSERT_MSG(m_control,
|
||||
wxT("The wxGridCellEditor must be created first!"));
|
||||
|
||||
if (grid->GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL))
|
||||
{
|
||||
m_value = grid->GetTable()->GetValueAsBool(row, col);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString cellval( grid->GetTable()->GetValue(row, col) );
|
||||
|
||||
if ( cellval == ms_stringValues[false] )
|
||||
m_value = false;
|
||||
else if ( cellval == ms_stringValues[true] )
|
||||
m_value = true;
|
||||
else
|
||||
{
|
||||
// do not try to be smart here and convert it to true or false
|
||||
// because we'll still overwrite it with something different and
|
||||
// this risks to be very surprising for the user code, let them
|
||||
// know about it
|
||||
wxFAIL_MSG( wxT("invalid value for a cell with bool editor!") );
|
||||
}
|
||||
}
|
||||
SetValueFromGrid(row, col, grid);
|
||||
|
||||
CBox()->SetValue(m_value);
|
||||
CBox()->SetFocus();
|
||||
@ -1358,11 +1395,7 @@ bool wxGridCellBoolEditor::EndEdit(int WXUNUSED(row),
|
||||
|
||||
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());
|
||||
SetGridFromValue(row, col, grid);
|
||||
}
|
||||
|
||||
void wxGridCellBoolEditor::Reset()
|
||||
@ -1416,7 +1449,7 @@ void wxGridCellBoolEditor::StartingKey(wxKeyEvent& event)
|
||||
|
||||
wxString wxGridCellBoolEditor::GetValue() const
|
||||
{
|
||||
return ms_stringValues[CBox()->GetValue()];
|
||||
return GetStringValue(CBox()->GetValue());
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
@ -1433,6 +1466,43 @@ wxGridCellBoolEditor::IsTrueValue(const wxString& value)
|
||||
return value == ms_stringValues[true];
|
||||
}
|
||||
|
||||
void wxGridCellBoolEditor::SetValueFromGrid(int row, int col, wxGrid* grid)
|
||||
{
|
||||
if (grid->GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL))
|
||||
{
|
||||
m_value = grid->GetTable()->GetValueAsBool(row, col);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString cellval( grid->GetTable()->GetValue(row, col) );
|
||||
|
||||
if ( cellval == ms_stringValues[false] )
|
||||
m_value = false;
|
||||
else if ( cellval == ms_stringValues[true] )
|
||||
m_value = true;
|
||||
else
|
||||
{
|
||||
// do not try to be smart here and convert it to true or false
|
||||
// because we'll still overwrite it with something different and
|
||||
// this risks to be very surprising for the user code, let them
|
||||
// know about it
|
||||
wxFAIL_MSG( wxT("invalid value for a cell with bool editor!") );
|
||||
|
||||
// Still need to initialize it to something.
|
||||
m_value = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wxGridCellBoolEditor::SetGridFromValue(int row, int col, wxGrid* grid) const
|
||||
{
|
||||
wxGridTableBase * const table = grid->GetTable();
|
||||
if ( table->CanSetValueAs(row, col, wxGRID_VALUE_BOOL) )
|
||||
table->SetValueAsBool(row, col, m_value);
|
||||
else
|
||||
table->SetValue(row, col, GetStringValue());
|
||||
}
|
||||
|
||||
#endif // wxUSE_CHECKBOX
|
||||
|
||||
#if wxUSE_COMBOBOX
|
||||
|
Loading…
Reference in New Issue
Block a user