diff --git a/include/wx/generic/gridctrl.h b/include/wx/generic/gridctrl.h index ac78ebe999..1bdb812751 100644 --- a/include/wx/generic/gridctrl.h +++ b/include/wx/generic/gridctrl.h @@ -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; }; diff --git a/include/wx/generic/private/grid.h b/include/wx/generic/private/grid.h index 19df9d4c76..07c432f588 100644 --- a/include/wx/generic/private/grid.h +++ b/include/wx/generic/private/grid.h @@ -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 diff --git a/src/generic/gridctrl.cpp b/src/generic/gridctrl.cpp index 8485e60ff3..f1e83880d8 100644 --- a/src/generic/gridctrl.cpp +++ b/src/generic/gridctrl.cpp @@ -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 diff --git a/src/generic/grideditors.cpp b/src/generic/grideditors.cpp index 3183f628fb..5f0793bcd5 100644 --- a/src/generic/grideditors.cpp +++ b/src/generic/grideditors.cpp @@ -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().