Get dates directly from table in wxGridCellDateEditor if possible
Unlike wxGridCellDateRenderer, which already did it, the editor class always got the cell value from the table as a string, even if the table supported returning the dates directly. Fix this by using the same code in the editor as in the renderer, which required a further refactoring in order to make it reusable: the helper TryParseDate() was replaced with TryGetValueAsDate() and DateParseParams was added to allow overriding the arguments passed to it in the overridden wxGridCellDateTimeRenderer::GetDateParseParams().
This commit is contained in:
@@ -171,6 +171,8 @@ public:
|
||||
|
||||
#include "wx/datetime.h"
|
||||
|
||||
namespace wxGridPrivate { class DateParseParams; }
|
||||
|
||||
// renderer for the cells containing dates only, without time component
|
||||
class WXDLLIMPEXP_ADV wxGridCellDateRenderer : public wxGridCellStringRenderer
|
||||
{
|
||||
@@ -207,7 +209,11 @@ public:
|
||||
|
||||
protected:
|
||||
wxString GetString(const wxGrid& grid, int row, int col);
|
||||
virtual bool Parse(const wxString& text, wxDateTime& result);
|
||||
|
||||
// This is overridden in wxGridCellDateTimeRenderer which uses a separate
|
||||
// input format and forbids fallback to ParseDate().
|
||||
virtual void
|
||||
GetDateParseParams(wxGridPrivate::DateParseParams& params) const;
|
||||
|
||||
wxString m_oformat;
|
||||
wxDateTime::TimeZone m_tz;
|
||||
@@ -229,7 +235,8 @@ public:
|
||||
virtual wxGridCellRenderer *Clone() const wxOVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual bool Parse(const wxString& text, wxDateTime& result) wxOVERRIDE;
|
||||
virtual void
|
||||
GetDateParseParams(wxGridPrivate::DateParseParams& params) const wxOVERRIDE;
|
||||
|
||||
wxString m_iformat;
|
||||
};
|
||||
|
@@ -1089,11 +1089,51 @@ namespace wxGridPrivate
|
||||
|
||||
#if wxUSE_DATETIME
|
||||
|
||||
// Helper function trying to parse the given string using the specified date
|
||||
// format and then using ParseDate() as a fallback if it failed. If this still
|
||||
// fails, returns false.
|
||||
// This is used as TryGetValueAsDate() parameter.
|
||||
class DateParseParams
|
||||
{
|
||||
public:
|
||||
// Unfortunately we have to provide the default ctor (and also make the
|
||||
// members non-const) because we use these objects as out-parameters as
|
||||
// they are not fully declared in the public headers. The factory functions
|
||||
// below must be used to create a really usable object.
|
||||
DateParseParams() : fallbackParseDate(false) { }
|
||||
|
||||
// Use these functions to really initialize the object.
|
||||
static DateParseParams WithFallback(const wxString& format)
|
||||
{
|
||||
return DateParseParams(format, true);
|
||||
}
|
||||
|
||||
static DateParseParams WithoutFallback(const wxString& format)
|
||||
{
|
||||
return DateParseParams(format, false);
|
||||
}
|
||||
|
||||
// The usual format, e.g. "%x" or "%Y-%m-%d".
|
||||
wxString format;
|
||||
|
||||
// Whether fall back to ParseDate() is allowed.
|
||||
bool fallbackParseDate;
|
||||
|
||||
private:
|
||||
DateParseParams(const wxString& format_, bool fallbackParseDate_)
|
||||
: format(format_),
|
||||
fallbackParseDate(fallbackParseDate_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// Helper function trying to get a date from the given cell: if possible, get
|
||||
// the date value from the table directly, otherwise get the string value for
|
||||
// this cell and try to parse it using the specified date format and, if this
|
||||
// doesn't work and fallbackParseDate is true, try using ParseDate() as a
|
||||
// fallback. If this still fails, returns false.
|
||||
bool
|
||||
TryParseDate(wxDateTime& result, const wxString& text, const wxString& format);
|
||||
TryGetValueAsDate(wxDateTime& result,
|
||||
const DateParseParams& params,
|
||||
const wxGrid& grid,
|
||||
int row, int col);
|
||||
|
||||
#endif // wxUSE_DATETIME
|
||||
|
||||
|
@@ -77,22 +77,46 @@ void wxGridCellRenderer::Draw(wxGrid& grid,
|
||||
#if wxUSE_DATETIME
|
||||
|
||||
bool
|
||||
wxGridPrivate::TryParseDate(wxDateTime& result,
|
||||
const wxString& text,
|
||||
const wxString& format)
|
||||
wxGridPrivate::TryGetValueAsDate(wxDateTime& result,
|
||||
const DateParseParams& params,
|
||||
const wxGrid& grid,
|
||||
int row, int col)
|
||||
{
|
||||
wxGridTableBase *table = grid.GetTable();
|
||||
|
||||
if ( table->CanGetValueAs(row, col, wxGRID_VALUE_DATETIME) )
|
||||
{
|
||||
void * tempval = table->GetValueAsCustom(row, col,wxGRID_VALUE_DATETIME);
|
||||
|
||||
if (tempval)
|
||||
{
|
||||
result = *((wxDateTime *)tempval);
|
||||
delete (wxDateTime *)tempval;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const wxString text = table->GetValue(row, col);
|
||||
|
||||
wxString::const_iterator end;
|
||||
|
||||
// Try parsing using the same format we use for output first.
|
||||
if ( result.ParseFormat(text, format, &end) && end == text.end() )
|
||||
if ( result.ParseFormat(text, params.format, &end) && end == text.end() )
|
||||
return true;
|
||||
|
||||
// But fall back to free-form parsing, which notably allows us to parse
|
||||
// strings such as "today" or "tomorrow" which would be never accepted by
|
||||
// ParseFormat().
|
||||
return result.ParseDate(text, &end) && end == text.end();
|
||||
// Check if we can fall back to free-form parsing, which notably allows us
|
||||
// to parse strings such as "today" or "tomorrow" which would be never
|
||||
// accepted by ParseFormat().
|
||||
if ( params.fallbackParseDate &&
|
||||
result.ParseDate(text, &end) && end == text.end() )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
using namespace wxGridPrivate;
|
||||
|
||||
// Enables a grid cell to display a formatted date
|
||||
|
||||
wxGridCellDateRenderer::wxGridCellDateRenderer(const wxString& outformat)
|
||||
@@ -115,40 +139,23 @@ wxGridCellRenderer *wxGridCellDateRenderer::Clone() const
|
||||
|
||||
wxString wxGridCellDateRenderer::GetString(const wxGrid& grid, int row, int col)
|
||||
{
|
||||
wxGridTableBase *table = grid.GetTable();
|
||||
|
||||
bool hasDatetime = false;
|
||||
wxDateTime val;
|
||||
wxString text;
|
||||
if ( table->CanGetValueAs(row, col, wxGRID_VALUE_DATETIME) )
|
||||
{
|
||||
void * tempval = table->GetValueAsCustom(row, col,wxGRID_VALUE_DATETIME);
|
||||
|
||||
if (tempval)
|
||||
{
|
||||
val = *((wxDateTime *)tempval);
|
||||
hasDatetime = true;
|
||||
delete (wxDateTime *)tempval;
|
||||
}
|
||||
DateParseParams params;
|
||||
GetDateParseParams(params);
|
||||
|
||||
}
|
||||
|
||||
if (!hasDatetime )
|
||||
{
|
||||
text = table->GetValue(row, col);
|
||||
hasDatetime = Parse(text, val);
|
||||
}
|
||||
|
||||
if ( hasDatetime )
|
||||
wxDateTime val;
|
||||
if ( TryGetValueAsDate(val, params, grid, row, col) )
|
||||
text = val.Format(m_oformat, m_tz );
|
||||
|
||||
// If we failed to parse string just show what we where given?
|
||||
return text;
|
||||
}
|
||||
|
||||
bool wxGridCellDateRenderer::Parse(const wxString& text, wxDateTime& result)
|
||||
void
|
||||
wxGridCellDateRenderer::GetDateParseParams(DateParseParams& params) const
|
||||
{
|
||||
return wxGridPrivate::TryParseDate(result, text, m_oformat);
|
||||
params = DateParseParams::WithFallback(m_oformat);
|
||||
}
|
||||
|
||||
void wxGridCellDateRenderer::Draw(wxGrid& grid,
|
||||
@@ -216,10 +223,10 @@ wxGridCellRenderer *wxGridCellDateTimeRenderer::Clone() const
|
||||
return new wxGridCellDateTimeRenderer(*this);
|
||||
}
|
||||
|
||||
bool wxGridCellDateTimeRenderer::Parse(const wxString& text, wxDateTime& result)
|
||||
void
|
||||
wxGridCellDateTimeRenderer::GetDateParseParams(DateParseParams& params) const
|
||||
{
|
||||
const char * const end = result.ParseFormat(text, m_iformat);
|
||||
return end && !*end;
|
||||
params = DateParseParams::WithoutFallback(m_iformat);
|
||||
}
|
||||
|
||||
#endif // wxUSE_DATETIME
|
||||
|
@@ -1920,8 +1920,10 @@ void wxGridCellDateEditor::BeginEdit(int row, int col, wxGrid* grid)
|
||||
{
|
||||
wxASSERT_MSG(m_control, "The wxGridCellDateEditor must be created first!");
|
||||
|
||||
const wxString dateStr = grid->GetTable()->GetValue(row, col);
|
||||
if ( !wxGridPrivate::TryParseDate(m_value, dateStr, m_format) )
|
||||
using namespace wxGridPrivate;
|
||||
|
||||
if ( !TryGetValueAsDate(m_value, DateParseParams::WithFallback(m_format),
|
||||
*grid, row, col) )
|
||||
{
|
||||
// Invalidate m_value, so that it always compares different
|
||||
// to any value returned from DatePicker()->GetValue().
|
||||
|
Reference in New Issue
Block a user