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:
@@ -171,6 +171,8 @@ public:
|
|||||||
|
|
||||||
#include "wx/datetime.h"
|
#include "wx/datetime.h"
|
||||||
|
|
||||||
|
namespace wxGridPrivate { class DateParseParams; }
|
||||||
|
|
||||||
// renderer for the cells containing dates only, without time component
|
// renderer for the cells containing dates only, without time component
|
||||||
class WXDLLIMPEXP_ADV wxGridCellDateRenderer : public wxGridCellStringRenderer
|
class WXDLLIMPEXP_ADV wxGridCellDateRenderer : public wxGridCellStringRenderer
|
||||||
{
|
{
|
||||||
@@ -207,7 +209,11 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
wxString GetString(const wxGrid& grid, int row, int col);
|
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;
|
wxString m_oformat;
|
||||||
wxDateTime::TimeZone m_tz;
|
wxDateTime::TimeZone m_tz;
|
||||||
@@ -222,18 +228,17 @@ public:
|
|||||||
|
|
||||||
wxGridCellDateTimeRenderer(const wxGridCellDateTimeRenderer& other)
|
wxGridCellDateTimeRenderer(const wxGridCellDateTimeRenderer& other)
|
||||||
: wxGridCellDateRenderer(other),
|
: wxGridCellDateRenderer(other),
|
||||||
m_iformat(other.m_iformat),
|
m_iformat(other.m_iformat)
|
||||||
m_dateDef(other.m_dateDef)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual wxGridCellRenderer *Clone() const wxOVERRIDE;
|
virtual wxGridCellRenderer *Clone() const wxOVERRIDE;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool Parse(const wxString& text, wxDateTime& result) wxOVERRIDE;
|
virtual void
|
||||||
|
GetDateParseParams(wxGridPrivate::DateParseParams& params) const wxOVERRIDE;
|
||||||
|
|
||||||
wxString m_iformat;
|
wxString m_iformat;
|
||||||
wxDateTime m_dateDef;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // wxUSE_DATETIME
|
#endif // wxUSE_DATETIME
|
||||||
|
@@ -390,7 +390,9 @@ public:
|
|||||||
class WXDLLIMPEXP_ADV wxGridCellDateEditor : public wxGridCellEditor
|
class WXDLLIMPEXP_ADV wxGridCellDateEditor : public wxGridCellEditor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxGridCellDateEditor() { }
|
explicit wxGridCellDateEditor(const wxString& format = wxString());
|
||||||
|
|
||||||
|
virtual void SetParameters(const wxString& params) wxOVERRIDE;
|
||||||
|
|
||||||
virtual void Create(wxWindow* parent,
|
virtual void Create(wxWindow* parent,
|
||||||
wxWindowID id,
|
wxWindowID id,
|
||||||
@@ -414,6 +416,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
wxDateTime m_value;
|
wxDateTime m_value;
|
||||||
|
wxString m_format;
|
||||||
|
|
||||||
wxDECLARE_NO_COPY_CLASS(wxGridCellDateEditor);
|
wxDECLARE_NO_COPY_CLASS(wxGridCellDateEditor);
|
||||||
};
|
};
|
||||||
|
@@ -1084,5 +1084,60 @@ wxGetContentRect(wxSize contentSize,
|
|||||||
int hAlign,
|
int hAlign,
|
||||||
int vAlign);
|
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 // wxUSE_GRID
|
||||||
#endif // _WX_GENERIC_GRID_PRIVATE_H_
|
#endif // _WX_GENERIC_GRID_PRIVATE_H_
|
||||||
|
@@ -248,16 +248,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
wxGridCellDateTimeRenderer(const wxString& outformat = wxDefaultDateTimeFormat,
|
wxGridCellDateTimeRenderer(const wxString& outformat = wxDefaultDateTimeFormat,
|
||||||
const wxString& informat = 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:
|
public:
|
||||||
/**
|
/**
|
||||||
Date editor constructor.
|
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());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -76,6 +76,47 @@ void wxGridCellRenderer::Draw(wxGrid& grid,
|
|||||||
|
|
||||||
#if wxUSE_DATETIME
|
#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
|
// Enables a grid cell to display a formatted date
|
||||||
|
|
||||||
wxGridCellDateRenderer::wxGridCellDateRenderer(const wxString& outformat)
|
wxGridCellDateRenderer::wxGridCellDateRenderer(const wxString& outformat)
|
||||||
@@ -98,41 +139,23 @@ wxGridCellRenderer *wxGridCellDateRenderer::Clone() const
|
|||||||
|
|
||||||
wxString wxGridCellDateRenderer::GetString(const wxGrid& grid, int row, int col)
|
wxString wxGridCellDateRenderer::GetString(const wxGrid& grid, int row, int col)
|
||||||
{
|
{
|
||||||
wxGridTableBase *table = grid.GetTable();
|
|
||||||
|
|
||||||
bool hasDatetime = false;
|
|
||||||
wxDateTime val;
|
|
||||||
wxString text;
|
wxString text;
|
||||||
if ( table->CanGetValueAs(row, col, wxGRID_VALUE_DATETIME) )
|
|
||||||
{
|
|
||||||
void * tempval = table->GetValueAsCustom(row, col,wxGRID_VALUE_DATETIME);
|
|
||||||
|
|
||||||
if (tempval)
|
DateParseParams params;
|
||||||
{
|
GetDateParseParams(params);
|
||||||
val = *((wxDateTime *)tempval);
|
|
||||||
hasDatetime = true;
|
|
||||||
delete (wxDateTime *)tempval;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
wxDateTime val;
|
||||||
|
if ( TryGetValueAsDate(val, params, grid, row, col) )
|
||||||
if (!hasDatetime )
|
|
||||||
{
|
|
||||||
text = table->GetValue(row, col);
|
|
||||||
hasDatetime = Parse(text, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( hasDatetime )
|
|
||||||
text = val.Format(m_oformat, m_tz );
|
text = val.Format(m_oformat, m_tz );
|
||||||
|
|
||||||
// If we failed to parse string just show what we where given?
|
// If we failed to parse string just show what we where given?
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxGridCellDateRenderer::Parse(const wxString& text, wxDateTime& result)
|
void
|
||||||
|
wxGridCellDateRenderer::GetDateParseParams(DateParseParams& params) const
|
||||||
{
|
{
|
||||||
wxString::const_iterator end;
|
params = DateParseParams::WithFallback(m_oformat);
|
||||||
return result.ParseDate(text, &end) && end == text.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxGridCellDateRenderer::Draw(wxGrid& grid,
|
void wxGridCellDateRenderer::Draw(wxGrid& grid,
|
||||||
@@ -192,7 +215,6 @@ void wxGridCellDateRenderer::SetParameters(const wxString& params)
|
|||||||
wxGridCellDateTimeRenderer::wxGridCellDateTimeRenderer(const wxString& outformat, const wxString& informat)
|
wxGridCellDateTimeRenderer::wxGridCellDateTimeRenderer(const wxString& outformat, const wxString& informat)
|
||||||
: wxGridCellDateRenderer(outformat)
|
: wxGridCellDateRenderer(outformat)
|
||||||
, m_iformat(informat)
|
, m_iformat(informat)
|
||||||
, m_dateDef(wxDefaultDateTime)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,10 +223,10 @@ wxGridCellRenderer *wxGridCellDateTimeRenderer::Clone() const
|
|||||||
return new wxGridCellDateTimeRenderer(*this);
|
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);
|
params = DateParseParams::WithoutFallback(m_iformat);
|
||||||
return end && !*end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_DATETIME
|
#endif // wxUSE_DATETIME
|
||||||
|
@@ -1861,6 +1861,19 @@ struct wxGridCellDateEditorKeyHandler
|
|||||||
};
|
};
|
||||||
#endif // __WXGTK__
|
#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,
|
void wxGridCellDateEditor::Create(wxWindow* parent, wxWindowID id,
|
||||||
wxEvtHandler* evtHandler)
|
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!");
|
wxASSERT_MSG(m_control, "The wxGridCellDateEditor must be created first!");
|
||||||
|
|
||||||
const wxString dateStr = grid->GetTable()->GetValue(row, col);
|
using namespace wxGridPrivate;
|
||||||
if ( !m_value.ParseDate(dateStr) )
|
|
||||||
|
if ( !TryGetValueAsDate(m_value, DateParseParams::WithFallback(m_format),
|
||||||
|
*grid, row, col) )
|
||||||
{
|
{
|
||||||
// Invalidate m_value, so that it always compares different
|
// Invalidate m_value, so that it always compares different
|
||||||
// to any value returned from DatePicker()->GetValue().
|
// to any value returned from DatePicker()->GetValue().
|
||||||
@@ -1960,7 +1975,7 @@ void wxGridCellDateEditor::Reset()
|
|||||||
|
|
||||||
wxGridCellEditor *wxGridCellDateEditor::Clone() const
|
wxGridCellEditor *wxGridCellDateEditor::Clone() const
|
||||||
{
|
{
|
||||||
return new wxGridCellDateEditor();
|
return new wxGridCellDateEditor(m_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString wxGridCellDateEditor::GetValue() const
|
wxString wxGridCellDateEditor::GetValue() const
|
||||||
|
Reference in New Issue
Block a user