Merge branch 'grid-date-format'

Fixes for using custom wxGrid date format.

See https://github.com/wxWidgets/wxWidgets/pull/2108

Closes #18876.
This commit is contained in:
Vadim Zeitlin
2020-11-05 16:12:28 +01:00
6 changed files with 145 additions and 49 deletions

View File

@@ -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;
@@ -222,18 +228,17 @@ public:
wxGridCellDateTimeRenderer(const wxGridCellDateTimeRenderer& other)
: wxGridCellDateRenderer(other),
m_iformat(other.m_iformat),
m_dateDef(other.m_dateDef)
m_iformat(other.m_iformat)
{
}
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;
wxDateTime m_dateDef;
};
#endif // wxUSE_DATETIME

View File

@@ -390,7 +390,9 @@ public:
class WXDLLIMPEXP_ADV wxGridCellDateEditor : public wxGridCellEditor
{
public:
wxGridCellDateEditor() { }
explicit wxGridCellDateEditor(const wxString& format = wxString());
virtual void SetParameters(const wxString& params) wxOVERRIDE;
virtual void Create(wxWindow* parent,
wxWindowID id,
@@ -414,6 +416,7 @@ protected:
private:
wxDateTime m_value;
wxString m_format;
wxDECLARE_NO_COPY_CLASS(wxGridCellDateEditor);
};

View File

@@ -1084,5 +1084,60 @@ wxGetContentRect(wxSize contentSize,
int hAlign,
int vAlign);
namespace wxGridPrivate
{
#if wxUSE_DATETIME
// 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
TryGetValueAsDate(wxDateTime& result,
const DateParseParams& params,
const wxGrid& grid,
int row, int col);
#endif // wxUSE_DATETIME
} // namespace wxGridPrivate
#endif // wxUSE_GRID
#endif // _WX_GENERIC_GRID_PRIVATE_H_

View File

@@ -248,16 +248,6 @@ public:
*/
wxGridCellDateTimeRenderer(const wxString& outformat = wxDefaultDateTimeFormat,
const wxString& informat = wxDefaultDateTimeFormat);
/**
Sets the strptime()-like format string which will be used to parse
the date/time.
@param params
strptime()-like format string used to parse the date/time.
*/
virtual void SetParameters(const wxString& params);
};
/**
@@ -1092,8 +1082,14 @@ class wxGridCellDateEditor : public wxGridCellEditor
public:
/**
Date editor constructor.
@param format Optional format for the date displayed in the associated
cell. By default, the locale-specific date format ("%x") is assumed.
You would typically want to specify the same format as the one
used with the cell renderer, if a non-default one is used.
Note that this parameter is only available since wxWidgets 3.1.5.
*/
wxGridCellDateEditor();
explicit wxGridCellDateEditor(const wxString& format = wxString());
};

View File

@@ -76,6 +76,47 @@ void wxGridCellRenderer::Draw(wxGrid& grid,
#if wxUSE_DATETIME
bool
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;
if ( result.ParseFormat(text, params.format, &end) && end == text.end() )
return true;
// 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)
@@ -98,41 +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
{
wxString::const_iterator end;
return result.ParseDate(text, &end) && end == text.end();
params = DateParseParams::WithFallback(m_oformat);
}
void wxGridCellDateRenderer::Draw(wxGrid& grid,
@@ -192,7 +215,6 @@ void wxGridCellDateRenderer::SetParameters(const wxString& params)
wxGridCellDateTimeRenderer::wxGridCellDateTimeRenderer(const wxString& outformat, const wxString& informat)
: wxGridCellDateRenderer(outformat)
, m_iformat(informat)
, m_dateDef(wxDefaultDateTime)
{
}
@@ -201,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, m_dateDef);
return end && !*end;
params = DateParseParams::WithoutFallback(m_iformat);
}
#endif // wxUSE_DATETIME

View File

@@ -1861,6 +1861,19 @@ struct wxGridCellDateEditorKeyHandler
};
#endif // __WXGTK__
wxGridCellDateEditor::wxGridCellDateEditor(const wxString& format)
{
SetParameters(format);
}
void wxGridCellDateEditor::SetParameters(const wxString& params)
{
if ( params.empty() )
m_format = "%x";
else
m_format = params;
}
void wxGridCellDateEditor::Create(wxWindow* parent, wxWindowID id,
wxEvtHandler* evtHandler)
{
@@ -1907,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 ( !m_value.ParseDate(dateStr) )
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().
@@ -1960,7 +1975,7 @@ void wxGridCellDateEditor::Reset()
wxGridCellEditor *wxGridCellDateEditor::Clone() const
{
return new wxGridCellDateEditor();
return new wxGridCellDateEditor(m_format);
}
wxString wxGridCellDateEditor::GetValue() const