1. wxDateTimeHolidayAuthority class for calculating the holidays added
2. wxCalendarCtrl adjustments and some new features git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5182 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
c88275cb7d
commit
4f6aed9c6a
@ -6,6 +6,11 @@ next release (2.1.12 or 2.2?)
|
||||
|
||||
wxBase:
|
||||
|
||||
- wxDateTime replaces and extends old wxDate and wxTime classes (still
|
||||
available but strongly deprecated) with many new features
|
||||
|
||||
- wxLongLong class provides support for (signed) 64 bit integers
|
||||
|
||||
- it is now possible to build wxBase under Win32 (using VC++ only so far)
|
||||
and BeOS (without thread support yet)
|
||||
|
||||
@ -22,10 +27,14 @@ wxBase:
|
||||
- wxArray::RemoveAt() replaces deprectaed wxArray::Remove(index)
|
||||
|
||||
all (GUI):
|
||||
|
||||
- new wxCalendarCtrl class for picking a date interactively
|
||||
|
||||
- wxMenu(Bar)::Insert() and Remove() functions for dynamic menu menagament
|
||||
- wxToolBar supports arbitrary controls (not only buttons) and can be
|
||||
dynamically changed (Delete/Insert functions)
|
||||
- vertical toolbars supported by MSW and GTK native wxToolBar classes
|
||||
|
||||
- wxTreeCtrl and wxListCtrl allow setting colour/fonts for individual items
|
||||
- "file open" dialog allows selecting multiple files at once (contributed by
|
||||
John Norris)
|
||||
|
@ -193,7 +193,8 @@ does exactly the same as \helpref{Item()}{wxarrayitem} method.
|
||||
\membersection{Adding items}
|
||||
|
||||
\helpref{Add}{wxarrayadd}\\
|
||||
\helpref{Insert}{wxarrayinsert}
|
||||
\helpref{Insert}{wxarrayinsert}\\
|
||||
\helpref{WX\_APPEND\_ARRAY}{wxappendarray}
|
||||
|
||||
\membersection{Removing items}
|
||||
|
||||
@ -311,6 +312,13 @@ public:
|
||||
WX_DEFINE_OBJARRAY(wxArrayOfMyClass);
|
||||
\end{verbatim}
|
||||
|
||||
\membersection{WX\_APPEND\_ARRAY}\label{wxappendarray}
|
||||
|
||||
\func{void}{WX\_APPEND\_ARRAY}{\param{wxArray\& }{array}, \param{wxArray\& }{other}}
|
||||
|
||||
This macro may be used to append all elements of the {\it other} array to the
|
||||
{\it array}. The two arrays must be of the same type.
|
||||
|
||||
\membersection{WX\_CLEAR\_ARRAY}\label{wxcleararray}
|
||||
|
||||
\func{void}{WX\_CLEAR\_ARRAY}{\param{wxArray\& }{array}}
|
||||
@ -385,6 +393,9 @@ to the array, however, the array will make a copy of the item and will not take
|
||||
ownership of the original item. Once again, it only makes sense for wxObjArrays
|
||||
because the other array types never take ownership of their elements.
|
||||
|
||||
You may also use \helpref{WX\_APPEND\_ARRAY}{wxappendarray} macro to append all
|
||||
elements of one array to another one.
|
||||
|
||||
\membersection{wxArray::Alloc}\label{wxarrayalloc}
|
||||
|
||||
\func{void}{Alloc}{\param{size\_t }{count}}
|
||||
|
22
docs/latex/wx/calctrl.tex
Normal file
22
docs/latex/wx/calctrl.tex
Normal file
@ -0,0 +1,22 @@
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% Name: calctrl.tex
|
||||
%% Purpose: wxCalendarCtrl documentation
|
||||
%% Author: Vadim Zeitlin
|
||||
%% Modified by:
|
||||
%% Created: 03.01.00
|
||||
%% RCS-ID: $Id$
|
||||
%% Copyright: (c) Vadim Zeitlin
|
||||
%% Licence: wxWindows licence
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
\section{\class{wxCalendarCtrl}}\label{wxcalendarctrl}
|
||||
|
||||
The calendar control allows the user to pick a date interactively.
|
||||
|
||||
\wxheading{Include files}
|
||||
|
||||
<wx/calctrl.h>
|
||||
|
||||
\wxheading{See also:}
|
||||
|
||||
\helpref{Calendar sample}{samplecalendar}
|
@ -19,6 +19,12 @@ make it easier to find the relevant one if a simple grep through all sources
|
||||
didn't help. They also provide some notes about using the samples and what
|
||||
features of wxWindows are they supposed to test.
|
||||
|
||||
\subsection{Calendar sample}\label{samplecalendar}
|
||||
|
||||
This font shows the \helpref{calendar control}{wxcalendarctrl} in action. It
|
||||
shows how to configure the control (see the different options in the calendar
|
||||
menu) and also how to process the notifications from it.
|
||||
|
||||
\subsection{Checklist sample}\label{samplechecklist}
|
||||
|
||||
This sample demonstrates the use of the \helpref{wxCheckListBox}{wxchecklistbox}
|
||||
|
@ -9,9 +9,18 @@
|
||||
// Licence: wxWindows license
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
TODO
|
||||
|
||||
1. implement multiple selections for date ranges
|
||||
2. background bitmap for the calendar?
|
||||
*/
|
||||
|
||||
#ifndef _WX_CALCTRL_H
|
||||
#define _WX_CALCTRL_H
|
||||
|
||||
#include "wx/datetime.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// constants
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -24,17 +33,85 @@ enum wxCalendarHitTestResult
|
||||
wxCAL_HITTEST_DAY // on a day in the calendar
|
||||
};
|
||||
|
||||
// border types for a date
|
||||
enum wxCalendarDateBorder
|
||||
{
|
||||
wxCAL_BORDER_NONE, // no border (default)
|
||||
wxCAL_BORDER_SQUARE, // a rectangular border
|
||||
wxCAL_BORDER_ROUND // a round border
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxCalendarCtrl
|
||||
// wxCalendarDateAttr: custom attributes for a calendar date
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// so far we only have a generic version, so keep it simple
|
||||
#include "wx/generic/calctrl.h"
|
||||
class WXDLLEXPORT wxCalendarDateAttr
|
||||
{
|
||||
public:
|
||||
// ctors
|
||||
wxCalendarDateAttr() { Init(); }
|
||||
wxCalendarDateAttr(const wxColour& colText,
|
||||
const wxColour& colBack = wxNullColour,
|
||||
const wxColour& colBorder = wxNullColour,
|
||||
const wxFont& font = wxNullFont,
|
||||
wxCalendarDateBorder border = wxCAL_BORDER_NONE)
|
||||
: m_colText(colText), m_colBack(colBack),
|
||||
m_colBorder(colBorder), m_font(font)
|
||||
{
|
||||
Init(border);
|
||||
}
|
||||
wxCalendarDateAttr(wxCalendarDateBorder border,
|
||||
const wxColour& colBorder = wxNullColour)
|
||||
: m_colBorder(colBorder)
|
||||
{
|
||||
Init(border);
|
||||
}
|
||||
|
||||
// setters
|
||||
void SetTextColour(const wxColour& colText) { m_colText = colText; }
|
||||
void SetBackgroundColour(const wxColour& colBack) { m_colBack = colBack; }
|
||||
void SetBorderColour(const wxColour& col) { m_colBorder = col; }
|
||||
void SetFont(const wxFont& font) { m_font = font; }
|
||||
void SetBorder(wxCalendarDateBorder border) { m_border = border; }
|
||||
void SetHoliday(bool holiday) { m_holiday = holiday; }
|
||||
|
||||
// accessors
|
||||
bool HasTextColour() const { return m_colText.Ok(); }
|
||||
bool HasBackgroundColour() const { return m_colBack.Ok(); }
|
||||
bool HasBorderColour() const { return m_colBorder.Ok(); }
|
||||
bool HasFont() const { return m_font.Ok(); }
|
||||
bool HasBorder() const { return m_border != wxCAL_BORDER_NONE; }
|
||||
|
||||
bool IsHoliday() const { return m_holiday; }
|
||||
|
||||
const wxColour& GetTextColour() const { return m_colText; }
|
||||
const wxColour& GetBackgroundColour() const { return m_colBack; }
|
||||
const wxColour& GetBorderColour() const { return m_colBorder; }
|
||||
const wxFont& GetFont() const { return m_font; }
|
||||
wxCalendarDateBorder GetBorder() const { return m_border; }
|
||||
|
||||
protected:
|
||||
void Init(wxCalendarDateBorder border = wxCAL_BORDER_NONE)
|
||||
{
|
||||
m_border = border;
|
||||
m_holiday = FALSE;
|
||||
}
|
||||
|
||||
private:
|
||||
wxColour m_colText,
|
||||
m_colBack,
|
||||
m_colBorder;
|
||||
wxFont m_font;
|
||||
wxCalendarDateBorder m_border;
|
||||
bool m_holiday;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxCalendarCtrl events
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLEXPORT wxCalendarCtrl;
|
||||
|
||||
class WXDLLEXPORT wxCalendarEvent : public wxCommandEvent
|
||||
{
|
||||
friend class wxCalendarCtrl;
|
||||
@ -53,6 +130,17 @@ private:
|
||||
wxDateTime::WeekDay m_wday;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxCalendarCtrl
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// so far we only have a generic version, so keep it simple
|
||||
#include "wx/generic/calctrl.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// calendar events macros
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define EVT_CALENDAR(id, fn) { wxEVT_CALENDAR_DOUBLECLICKED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL },
|
||||
#define EVT_CALENDAR_SEL_CHANGED(id, fn) { wxEVT_CALENDAR_SEL_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL },
|
||||
#define EVT_CALENDAR_DAY(id, fn) { wxEVT_CALENDAR_DAY_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL },
|
||||
|
@ -38,9 +38,10 @@ class WXDLLEXPORT wxDateSpan;
|
||||
* TODO Well, everything :-)
|
||||
*
|
||||
* + 1. Time zones with minutes (make TimeZone a class)
|
||||
* 2. getdate() function like under Solaris
|
||||
* ? 2. getdate() function like under Solaris
|
||||
* + 3. text conversion for wxDateSpan
|
||||
* 4. pluggable modules for the workdays calculations
|
||||
* + 4. pluggable modules for the workdays calculations
|
||||
* 5. wxDateTimeHolidayAuthority for Easter and other christian feasts
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -618,17 +619,21 @@ public:
|
||||
// default assignment operator is ok
|
||||
|
||||
// calendar calculations (functions which set the date only leave the time
|
||||
// unchanged, e.g. don't explictly zero it)
|
||||
// unchanged, e.g. don't explictly zero it): SetXXX() functions modify the
|
||||
// object itself, GetXXX() ones return a new object.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// set to the given week day in the same week as this one
|
||||
wxDateTime& SetToWeekDayInSameWeek(WeekDay weekday);
|
||||
inline wxDateTime GetWeekDayInSameWeek(WeekDay weekday) const;
|
||||
|
||||
// set to the next week day following this one
|
||||
wxDateTime& SetToNextWeekDay(WeekDay weekday);
|
||||
inline wxDateTime GetNextWeekDay(WeekDay weekday) const;
|
||||
|
||||
// set to the previous week day before this one
|
||||
wxDateTime& SetToPrevWeekDay(WeekDay weekday);
|
||||
inline wxDateTime GetPrevWeekDay(WeekDay weekday) const;
|
||||
|
||||
// set to Nth occurence of given weekday in the given month of the
|
||||
// given year (time is set to 0), return TRUE on success and FALSE on
|
||||
@ -638,24 +643,35 @@ public:
|
||||
int n = 1,
|
||||
Month month = Inv_Month,
|
||||
int year = Inv_Year);
|
||||
inline wxDateTime GetWeekDay(WeekDay weekday,
|
||||
int n = 1,
|
||||
Month month = Inv_Month,
|
||||
int year = Inv_Year) const;
|
||||
|
||||
// sets to the last weekday in the given month, year
|
||||
inline bool SetToLastWeekDay(WeekDay weekday,
|
||||
Month month = Inv_Month,
|
||||
int year = Inv_Year);
|
||||
inline wxDateTime GetLastWeekDay(WeekDay weekday,
|
||||
Month month = Inv_Month,
|
||||
int year = Inv_Year);
|
||||
|
||||
// sets the date to the given day of the given week in the year,
|
||||
// returns TRUE on success and FALSE if given date doesn't exist (e.g.
|
||||
// numWeek is > 53)
|
||||
bool SetToTheWeek(wxDateTime_t numWeek, WeekDay weekday = Mon);
|
||||
inline wxDateTime GetWeek(wxDateTime_t numWeek, WeekDay weekday = Mon) const;
|
||||
|
||||
// sets the date to the last day of the given (or current) month or the
|
||||
// given (or current) year
|
||||
wxDateTime& SetToLastMonthDay(Month month = Inv_Month,
|
||||
int year = Inv_Year);
|
||||
inline wxDateTime GetLastMonthDay(Month month = Inv_Month,
|
||||
int year = Inv_Year) const;
|
||||
|
||||
// sets to the given year day (1..365 or 366)
|
||||
wxDateTime& SetToYearDay(wxDateTime_t yday);
|
||||
inline wxDateTime GetYearDay(wxDateTime_t yday) const;
|
||||
|
||||
// The definitions below were taken verbatim from
|
||||
//
|
||||
@ -784,13 +800,12 @@ public:
|
||||
|
||||
// is this date a work day? This depends on a country, of course,
|
||||
// because the holidays are different in different countries
|
||||
bool IsWorkDay(Country country = Country_Default,
|
||||
const TimeZone& tz = Local) const;
|
||||
bool IsWorkDay(Country country = Country_Default) const;
|
||||
|
||||
// is this date later than Gregorian calendar introduction for the
|
||||
// given country (see enum GregorianAdoption)?
|
||||
//
|
||||
// NB: this function shouldn't be considered as absolute authoiruty in
|
||||
// NB: this function shouldn't be considered as absolute authority in
|
||||
// the matter. Besides, for some countries the exact date of
|
||||
// adoption of the Gregorian calendar is simply unknown.
|
||||
bool IsGregorianDate(GregorianAdoption country = Gr_Standard) const;
|
||||
@ -891,9 +906,12 @@ public:
|
||||
wxString FormatDate() const { return Format(_T("%x")); }
|
||||
// preferred time representation for the current locale
|
||||
wxString FormatTime() const { return Format(_T("%X")); }
|
||||
// return the string representing the date in ISO 8601 format
|
||||
// returns the string representing the date in ISO 8601 format
|
||||
// (YYYY-MM-DD)
|
||||
wxString FormatISODate() const { return Format(_T("%Y-%m-%d")); }
|
||||
// returns the string representing the time in ISO 8601 format
|
||||
// (HH:MM:SS)
|
||||
wxString FormatISOTime() const { return Format(_T("%H:%M:%S")); }
|
||||
|
||||
// implementation
|
||||
// ------------------------------------------------------------------------
|
||||
@ -1098,7 +1116,12 @@ private:
|
||||
// one month to Feb, 15 - we want to get Mar, 15, of course).
|
||||
//
|
||||
// When adding a month to the date, all lesser components (days, hours, ...)
|
||||
// won't be changed.
|
||||
// won't be changed unless the resulting date would be invalid: for example,
|
||||
// Jan 31 + 1 month will be Feb 28, not (non existing) Feb 31.
|
||||
//
|
||||
// Because of this feature, adding and substracting back again the same
|
||||
// wxDateSpan will *not*, in general give back the original date: Feb 28 - 1
|
||||
// month will be Jan 28, not Jan 31!
|
||||
//
|
||||
// wxDateSpan can be either positive or negative. They may be
|
||||
// multiplied by scalars which multiply all deltas by the scalar: i.e. 2*(1
|
||||
@ -1210,10 +1233,75 @@ private:
|
||||
m_days;
|
||||
};
|
||||
|
||||
WXDLLEXPORT_DATA(extern wxDateSpan) wxYear;
|
||||
WXDLLEXPORT_DATA(extern wxDateSpan) wxMonth;
|
||||
WXDLLEXPORT_DATA(extern wxDateSpan) wxWeek;
|
||||
WXDLLEXPORT_DATA(extern wxDateSpan) wxDay;
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDateTimeArray: array of dates.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "wx/dynarray.h"
|
||||
|
||||
WX_DECLARE_OBJARRAY(wxDateTime, wxDateTimeArray);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDateTimeHolidayAuthority: an object of this class will decide whether a
|
||||
// given date is a holiday and is used by all functions working with "work
|
||||
// days".
|
||||
//
|
||||
// NB: the base class is an ABC, derived classes must implement the pure
|
||||
// virtual methods to work with the holidays they correspond to.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLEXPORT wxDateTimeHolidayAuthority;
|
||||
WX_DEFINE_ARRAY(wxDateTimeHolidayAuthority *, wxHolidayAuthoritiesArray);
|
||||
|
||||
class WXDLLEXPORT wxDateTimeHolidayAuthority
|
||||
{
|
||||
public:
|
||||
// returns TRUE if the given date is a holiday
|
||||
static bool IsHoliday(const wxDateTime& dt);
|
||||
|
||||
// fills the provided array with all holidays in the given range, returns
|
||||
// the number of them
|
||||
static size_t GetHolidaysInRange(const wxDateTime& dtStart,
|
||||
const wxDateTime& dtEnd,
|
||||
wxDateTimeArray& holidays);
|
||||
|
||||
// clear the list of holiday authorities
|
||||
static void ClearAllAuthorities();
|
||||
|
||||
// add a new holiday authority (the pointer will be deleted by
|
||||
// wxDateTimeHolidayAuthority)
|
||||
static void AddAuthority(wxDateTimeHolidayAuthority *auth);
|
||||
|
||||
protected:
|
||||
// this function is called to determine whether a given day is a holiday
|
||||
virtual bool DoIsHoliday(const wxDateTime& dt) const = 0;
|
||||
|
||||
// this function should fill the array with all holidays between the two
|
||||
// given dates - it is implemented in the base class, but in a very
|
||||
// inefficient way (it just iterates over all days and uses IsHoliday() for
|
||||
// each of them), so it must be overridden in the derived class where the
|
||||
// base class version may be explicitly used if needed
|
||||
//
|
||||
// returns the number of holidays in the given range and fills holidays
|
||||
// array
|
||||
virtual size_t DoGetHolidaysInRange(const wxDateTime& dtStart,
|
||||
const wxDateTime& dtEnd,
|
||||
wxDateTimeArray& holidays) const = 0;
|
||||
|
||||
private:
|
||||
// all holiday authorities
|
||||
static wxHolidayAuthoritiesArray ms_authorities;
|
||||
};
|
||||
|
||||
// the holidays for this class are all Saturdays and Sundays
|
||||
class WXDLLEXPORT wxDateTimeWorkDays : public wxDateTimeHolidayAuthority
|
||||
{
|
||||
protected:
|
||||
virtual bool DoIsHoliday(const wxDateTime& dt) const;
|
||||
virtual size_t DoGetHolidaysInRange(const wxDateTime& dtStart,
|
||||
const wxDateTime& dtEnd,
|
||||
wxDateTimeArray& holidays) const;
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// inline functions implementation
|
||||
|
@ -16,8 +16,21 @@
|
||||
#error "This file is only included by wx/datetime.h, don't include it manually!"
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// private macros
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define MILLISECONDS_PER_DAY 86400000l
|
||||
|
||||
// some broken compilers (HP-UX CC) refuse to compile the "normal" version, but
|
||||
// using a temp variable always might prevent other compilers from optimising
|
||||
// it away - hence use of this ugly macro
|
||||
#ifndef __HPUX__
|
||||
#define MODIFY_AND_RETURN(op) return wxDateTime(*this).op
|
||||
#else
|
||||
#define MODIFY_AND_RETURN(op) wxDateTime dt(*this); dt.op; return dt
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDateTime construction
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -138,6 +151,57 @@ bool wxDateTime::SetToLastWeekDay(WeekDay weekday,
|
||||
return SetToWeekDay(weekday, -1, month, year);
|
||||
}
|
||||
|
||||
wxDateTime wxDateTime::GetWeekDayInSameWeek(WeekDay weekday) const
|
||||
{
|
||||
MODIFY_AND_RETURN( SetToWeekDayInSameWeek(weekday) );
|
||||
}
|
||||
|
||||
wxDateTime wxDateTime::GetNextWeekDay(WeekDay weekday) const
|
||||
{
|
||||
MODIFY_AND_RETURN( SetToNextWeekDay(weekday) );
|
||||
}
|
||||
|
||||
wxDateTime wxDateTime::GetPrevWeekDay(WeekDay weekday) const
|
||||
{
|
||||
MODIFY_AND_RETURN( SetToPrevWeekDay(weekday) );
|
||||
}
|
||||
|
||||
wxDateTime wxDateTime::GetWeekDay(WeekDay weekday,
|
||||
int n,
|
||||
Month month,
|
||||
int year) const
|
||||
{
|
||||
wxDateTime dt(*this);
|
||||
|
||||
return dt.SetToWeekDay(weekday, n, month, year) ? dt : wxInvalidDateTime;
|
||||
}
|
||||
|
||||
wxDateTime wxDateTime::GetLastWeekDay(WeekDay weekday,
|
||||
Month month,
|
||||
int year)
|
||||
{
|
||||
wxDateTime dt(*this);
|
||||
|
||||
return dt.SetToLastWeekDay(weekday, month, year) ? dt : wxInvalidDateTime;
|
||||
}
|
||||
|
||||
wxDateTime wxDateTime::GetWeek(wxDateTime_t numWeek, WeekDay weekday) const
|
||||
{
|
||||
wxDateTime dt(*this);
|
||||
|
||||
return dt.SetToTheWeek(numWeek, weekday) ? dt : wxInvalidDateTime;
|
||||
}
|
||||
|
||||
wxDateTime wxDateTime::GetLastMonthDay(Month month, int year) const
|
||||
{
|
||||
MODIFY_AND_RETURN( SetToLastMonthDay(month, year) );
|
||||
}
|
||||
|
||||
wxDateTime wxDateTime::GetYearDay(wxDateTime_t yday) const
|
||||
{
|
||||
MODIFY_AND_RETURN( SetToYearDay(yday) );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDateTime comparison
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -287,8 +351,7 @@ wxDateTime& wxDateTime::operator+=(const wxDateSpan& diff)
|
||||
wxDateTime wxDateTime::ToTimezone(const wxDateTime::TimeZone& tz,
|
||||
bool noDST) const
|
||||
{
|
||||
wxDateTime dt(*this);
|
||||
return dt.MakeTimezone(tz, noDST);
|
||||
MODIFY_AND_RETURN( MakeTimezone(tz, noDST) );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -437,3 +500,5 @@ wxDateSpan& wxDateSpan::Neg()
|
||||
}
|
||||
|
||||
#undef MILLISECONDS_PER_DAY
|
||||
|
||||
#undef MODIFY_AND_RETURN
|
||||
|
@ -448,6 +448,16 @@ WX_DEFINE_EXPORTED_ARRAY(void *, wxArrayPtrVoid);
|
||||
// convinience macros
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// append all element of one array to another one
|
||||
#define WX_APPEND_ARRAY(array, other) \
|
||||
{ \
|
||||
size_t count = other.Count(); \
|
||||
for ( size_t n = 0; n < count; n++ ) \
|
||||
{ \
|
||||
array.Add(other[n]); \
|
||||
} \
|
||||
}
|
||||
|
||||
// delete all array elements
|
||||
//
|
||||
// NB: the class declaration of the array elements must be visible from the
|
||||
|
@ -18,9 +18,9 @@
|
||||
|
||||
#include "wx/control.h" // the base class
|
||||
|
||||
#include "wx/datetime.h" // for m_date
|
||||
#include "wx/combobox.h" // for m_comboMonth
|
||||
#include "wx/spinctrl.h" // for m_spinYear
|
||||
#include "wx/spinctrl.h" // for wxSpinEvent
|
||||
|
||||
class WXDLLEXPORT wxComboBox;
|
||||
|
||||
#define wxCalendarNameStr _T("CalendarCtrl")
|
||||
|
||||
@ -41,7 +41,7 @@ public:
|
||||
const wxDateTime& date = wxDefaultDateTime,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = 0,
|
||||
long style = wxCAL_SHOW_HOLIDAYS,
|
||||
const wxString& name = wxCalendarNameStr)
|
||||
: wxControl(parent, id, pos, size,
|
||||
style | wxWANTS_CHARS, wxDefaultValidator, name)
|
||||
@ -56,15 +56,81 @@ public:
|
||||
const wxDateTime& date = wxDefaultDateTime,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = 0,
|
||||
long style = wxCAL_SHOW_HOLIDAYS,
|
||||
const wxString& name = wxCalendarNameStr);
|
||||
|
||||
virtual ~wxCalendarCtrl();
|
||||
|
||||
// set/get the current date
|
||||
// ------------------------
|
||||
|
||||
void SetDate(const wxDateTime& date);
|
||||
const wxDateTime& GetDate() const { return m_date; }
|
||||
|
||||
// customization
|
||||
// -------------
|
||||
|
||||
// header colours are used for painting the weekdays at the top
|
||||
void SetHeaderColours(const wxColour& colFg, const wxColour& colBg)
|
||||
{
|
||||
m_colHeaderFg = colFg;
|
||||
m_colHeaderBg = colBg;
|
||||
}
|
||||
|
||||
const wxColour& GetHeaderColourFg() const { return m_colHeaderFg; }
|
||||
const wxColour& GetHeaderColourBg() const { return m_colHeaderBg; }
|
||||
|
||||
// highlight colour is used for the currently selected date
|
||||
void SetHighlightColours(const wxColour& colFg, const wxColour& colBg)
|
||||
{
|
||||
m_colHighlightFg = colFg;
|
||||
m_colHighlightBg = colBg;
|
||||
}
|
||||
|
||||
const wxColour& GetHighlightColourFg() const { return m_colHighlightFg; }
|
||||
const wxColour& GetHighlightColourBg() const { return m_colHighlightBg; }
|
||||
|
||||
// holiday colour is used for the holidays (if style & wxCAL_SHOW_HOLIDAYS)
|
||||
void SetHolidayColours(const wxColour& colFg, const wxColour& colBg)
|
||||
{
|
||||
m_colHolidayFg = colFg;
|
||||
m_colHolidayBg = colBg;
|
||||
}
|
||||
|
||||
const wxColour& GetHolidayColourFg() const { return m_colHolidayFg; }
|
||||
const wxColour& GetHolidayColourBg() const { return m_colHolidayBg; }
|
||||
|
||||
// this function should be called instead of directly changing the
|
||||
// wxCAL_SHOW_HOLIDAYS bit in the control style after the control creation
|
||||
// (this won't work)
|
||||
void EnableHolidayDisplay(bool display = TRUE);
|
||||
|
||||
// an item without custom attributes is drawn with the default colours and
|
||||
// font and without border, setting custom attributes allows to modify this
|
||||
//
|
||||
// the day parameter should be in 1..31 range, for days 29, 30, 31 the
|
||||
// corresponding attribute is just unused if there is no such day in the
|
||||
// current month
|
||||
|
||||
wxCalendarDateAttr *GetAttr(size_t day) const
|
||||
{
|
||||
wxCHECK_MSG( day > 0 && day < 32, NULL, _T("invalid day") );
|
||||
|
||||
return m_attrs[day - 1];
|
||||
}
|
||||
|
||||
void SetAttr(size_t day, wxCalendarDateAttr *attr)
|
||||
{
|
||||
wxCHECK_RET( day > 0 && day < 32, _T("invalid day") );
|
||||
|
||||
delete m_attrs[day - 1];
|
||||
m_attrs[day - 1] = attr;
|
||||
}
|
||||
|
||||
void SetHoliday(size_t day);
|
||||
|
||||
void ResetAttr(size_t day) { SetAttr(day, (wxCalendarDateAttr *)NULL); }
|
||||
|
||||
// returns one of wxCAL_HITTEST_XXX constants and fills either date or wd
|
||||
// with the corresponding value (none for NOWHERE, the date for DAY and wd
|
||||
// for HEADER)
|
||||
@ -90,6 +156,7 @@ private:
|
||||
void OnChar(wxKeyEvent& event);
|
||||
void OnMonthChange(wxCommandEvent& event);
|
||||
void OnYearChange(wxSpinEvent& event);
|
||||
void OnCalMonthChange(wxCalendarEvent& event);
|
||||
|
||||
// override some base class virtuals
|
||||
virtual wxSize DoGetBestSize() const;
|
||||
@ -119,16 +186,43 @@ private:
|
||||
// change the date inside the same month/year
|
||||
void ChangeDay(const wxDateTime& date);
|
||||
|
||||
// generate the given calendar event and a "selection changed" one if
|
||||
// selChanged is TRUE
|
||||
void GenerateEvent(wxEventType type, bool selChanged = TRUE);
|
||||
// set the attributes for the holidays if needed
|
||||
void SetHolidayAttrs();
|
||||
|
||||
// reset all holidays
|
||||
void ResetHolidayAttrs();
|
||||
|
||||
// generate the given calendar event(s)
|
||||
void GenerateEvent(wxEventType type)
|
||||
{
|
||||
wxCalendarEvent event(this, type);
|
||||
(void)GetEventHandler()->ProcessEvent(event);
|
||||
}
|
||||
|
||||
void GenerateEvents(wxEventType type1, wxEventType type2)
|
||||
{
|
||||
GenerateEvent(type1);
|
||||
GenerateEvent(type2);
|
||||
}
|
||||
|
||||
// the subcontrols
|
||||
wxComboBox *m_comboMonth;
|
||||
wxSpinCtrl *m_spinYear;
|
||||
|
||||
// the current selection
|
||||
wxDateTime m_date;
|
||||
|
||||
// default attributes
|
||||
wxColour m_colHighlightFg,
|
||||
m_colHighlightBg,
|
||||
m_colHolidayFg,
|
||||
m_colHolidayBg,
|
||||
m_colHeaderFg,
|
||||
m_colHeaderBg;
|
||||
|
||||
// the attributes for each of the month days
|
||||
wxCalendarDateAttr *m_attrs[31];
|
||||
|
||||
// the width and height of one column/row in the calendar
|
||||
wxCoord m_widthCol,
|
||||
m_heightRow;
|
||||
|
@ -67,6 +67,7 @@
|
||||
#include "wx/string.h"
|
||||
#include "wx/intl.h"
|
||||
#include "wx/log.h"
|
||||
#include "wx/module.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
#include "wx/thread.h"
|
||||
@ -99,6 +100,31 @@
|
||||
#endif
|
||||
#endif // !WX_TIMEZONE
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// private classes
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class wxDateTimeHolidaysModule : public wxModule
|
||||
{
|
||||
public:
|
||||
virtual bool OnInit()
|
||||
{
|
||||
wxDateTimeHolidayAuthority::AddAuthority(new wxDateTimeWorkDays);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
virtual void OnExit()
|
||||
{
|
||||
wxDateTimeHolidayAuthority::ClearAllAuthorities();
|
||||
}
|
||||
|
||||
private:
|
||||
DECLARE_DYNAMIC_CLASS(wxDateTimeHolidaysModule)
|
||||
};
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxDateTimeHolidaysModule, wxModule)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// constants
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -160,6 +186,18 @@ wxDateTime::Country wxDateTime::ms_country = wxDateTime::Country_Unknown;
|
||||
// private functions
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// debugger helper: shows what the date really is
|
||||
#ifdef __WXDEBUG__
|
||||
extern const wxChar *wxDumpDate(const wxDateTime* dt)
|
||||
{
|
||||
static wxChar buf[20];
|
||||
|
||||
wxStrcpy(buf, dt->Format(_T("%Y-%m-%d (%a) %H:%M:%S")));
|
||||
|
||||
return buf;
|
||||
}
|
||||
#endif // Debug
|
||||
|
||||
// get the number of days in the given month of the given year
|
||||
static inline
|
||||
wxDateTime::wxDateTime_t GetNumOfDaysInMonth(int year, wxDateTime::Month month)
|
||||
@ -437,6 +475,9 @@ void wxDateTime::Tm::AddMonths(int monDiff)
|
||||
mon = (wxDateTime::Month)(mon + monDiff);
|
||||
|
||||
wxASSERT_MSG( mon >= 0 && mon < MONTHS_IN_YEAR, _T("logic error") );
|
||||
|
||||
// NB: we don't check here that the resulting date is valid, this function
|
||||
// is private and the caller must check it if needed
|
||||
}
|
||||
|
||||
void wxDateTime::Tm::AddDays(int dayDiff)
|
||||
@ -1358,6 +1399,20 @@ wxDateTime& wxDateTime::Add(const wxDateSpan& diff)
|
||||
|
||||
tm.year += diff.GetYears();
|
||||
tm.AddMonths(diff.GetMonths());
|
||||
|
||||
// check that the resulting date is valid
|
||||
if ( tm.mday > GetNumOfDaysInMonth(tm.year, tm.mon) )
|
||||
{
|
||||
// We suppose that when adding one month to Jan 31 we want to get Feb
|
||||
// 28 (or 29), i.e. adding a month to the last day of the month should
|
||||
// give the last day of the next month which is quite logical.
|
||||
//
|
||||
// Unfortunately, there is no logic way to understand what should
|
||||
// Jan 30 + 1 month be - Feb 28 too or Feb 27 (assuming non leap year)?
|
||||
// We make it Feb 28 (last day too), but it is highly questionable.
|
||||
tm.mday = GetNumOfDaysInMonth(tm.year, tm.mon);
|
||||
}
|
||||
|
||||
tm.AddDays(diff.GetTotalDays());
|
||||
|
||||
Set(tm);
|
||||
@ -1372,6 +1427,23 @@ wxDateTime& wxDateTime::Add(const wxDateSpan& diff)
|
||||
// Weekday and monthday stuff
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxDateTime::SetToTheWeek(wxDateTime_t numWeek, WeekDay weekday)
|
||||
{
|
||||
int year = GetYear();
|
||||
|
||||
// Jan 4 always lies in the 1st week of the year
|
||||
Set(4, Jan, year);
|
||||
SetToWeekDayInSameWeek(weekday) += wxDateSpan::Weeks(numWeek);
|
||||
|
||||
if ( GetYear() != year )
|
||||
{
|
||||
// oops... numWeek was too big
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
wxDateTime& wxDateTime::SetToLastMonthDay(Month month,
|
||||
int year)
|
||||
{
|
||||
@ -1396,11 +1468,11 @@ wxDateTime& wxDateTime::SetToWeekDayInSameWeek(WeekDay weekday)
|
||||
}
|
||||
else if ( weekday < wdayThis )
|
||||
{
|
||||
return Substract(wxTimeSpan::Days(wdayThis - weekday));
|
||||
return Substract(wxDateSpan::Days(wdayThis - weekday));
|
||||
}
|
||||
else // weekday > wdayThis
|
||||
{
|
||||
return Add(wxTimeSpan::Days(weekday - wdayThis));
|
||||
return Add(wxDateSpan::Days(weekday - wdayThis));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1425,7 +1497,7 @@ wxDateTime& wxDateTime::SetToNextWeekDay(WeekDay weekday)
|
||||
diff = weekday - wdayThis;
|
||||
}
|
||||
|
||||
return Add(wxTimeSpan::Days(diff));
|
||||
return Add(wxDateSpan::Days(diff));
|
||||
}
|
||||
|
||||
wxDateTime& wxDateTime::SetToPrevWeekDay(WeekDay weekday)
|
||||
@ -1449,7 +1521,7 @@ wxDateTime& wxDateTime::SetToPrevWeekDay(WeekDay weekday)
|
||||
diff = wdayThis - weekday;
|
||||
}
|
||||
|
||||
return Substract(wxTimeSpan::Days(diff));
|
||||
return Substract(wxDateSpan::Days(diff));
|
||||
}
|
||||
|
||||
bool wxDateTime::SetToWeekDay(WeekDay weekday,
|
||||
@ -3240,6 +3312,15 @@ const wxChar *wxDateTime::ParseTime(const wxChar *time)
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Workdays and holidays support
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxDateTime::IsWorkDay(Country WXUNUSED(country)) const
|
||||
{
|
||||
return !wxDateTimeHolidayAuthority::IsHoliday(*this);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// wxTimeSpan
|
||||
// ============================================================================
|
||||
@ -3325,3 +3406,121 @@ wxString wxTimeSpan::Format(const wxChar *format) const
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// wxDateTimeHolidayAuthority and related classes
|
||||
// ============================================================================
|
||||
|
||||
#include "wx/arrimpl.cpp"
|
||||
|
||||
WX_DEFINE_OBJARRAY(wxDateTimeArray)
|
||||
|
||||
static int wxCMPFUNC_CONV
|
||||
wxDateTimeCompareFunc(wxDateTime **first, wxDateTime **second)
|
||||
{
|
||||
wxDateTime dt1 = **first,
|
||||
dt2 = **second;
|
||||
|
||||
return dt1 == dt2 ? 0 : dt1 < dt2 ? -1 : +1;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDateTimeHolidayAuthority
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxHolidayAuthoritiesArray wxDateTimeHolidayAuthority::ms_authorities;
|
||||
|
||||
/* static */
|
||||
bool wxDateTimeHolidayAuthority::IsHoliday(const wxDateTime& dt)
|
||||
{
|
||||
size_t count = ms_authorities.GetCount();
|
||||
for ( size_t n = 0; n < count; n++ )
|
||||
{
|
||||
if ( ms_authorities[n]->DoIsHoliday(dt) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* static */
|
||||
size_t
|
||||
wxDateTimeHolidayAuthority::GetHolidaysInRange(const wxDateTime& dtStart,
|
||||
const wxDateTime& dtEnd,
|
||||
wxDateTimeArray& holidays)
|
||||
{
|
||||
wxDateTimeArray hol;
|
||||
|
||||
holidays.Empty();
|
||||
|
||||
size_t count = ms_authorities.GetCount();
|
||||
for ( size_t n = 0; n < count; n++ )
|
||||
{
|
||||
ms_authorities[n]->DoGetHolidaysInRange(dtStart, dtEnd, hol);
|
||||
|
||||
WX_APPEND_ARRAY(holidays, hol);
|
||||
}
|
||||
|
||||
holidays.Sort(wxDateTimeCompareFunc);
|
||||
|
||||
return holidays.GetCount();
|
||||
}
|
||||
|
||||
/* static */
|
||||
void wxDateTimeHolidayAuthority::ClearAllAuthorities()
|
||||
{
|
||||
WX_CLEAR_ARRAY(ms_authorities);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void wxDateTimeHolidayAuthority::AddAuthority(wxDateTimeHolidayAuthority *auth)
|
||||
{
|
||||
ms_authorities.Add(auth);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDateTimeWorkDays
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxDateTimeWorkDays::DoIsHoliday(const wxDateTime& dt) const
|
||||
{
|
||||
wxDateTime::WeekDay wd = dt.GetWeekDay();
|
||||
|
||||
return (wd == wxDateTime::Sun) || (wd == wxDateTime::Sat);
|
||||
}
|
||||
|
||||
size_t wxDateTimeWorkDays::DoGetHolidaysInRange(const wxDateTime& dtStart,
|
||||
const wxDateTime& dtEnd,
|
||||
wxDateTimeArray& holidays) const
|
||||
{
|
||||
if ( dtStart > dtEnd )
|
||||
{
|
||||
wxFAIL_MSG( _T("invalid date range in GetHolidaysInRange") );
|
||||
|
||||
return 0u;
|
||||
}
|
||||
|
||||
holidays.Empty();
|
||||
|
||||
// instead of checking all days, start with the first Sat after dtStart and
|
||||
// end with the last Sun before dtEnd
|
||||
wxDateTime dtSatFirst = dtStart.GetNextWeekDay(wxDateTime::Sat),
|
||||
dtSatLast = dtEnd.GetPrevWeekDay(wxDateTime::Sat),
|
||||
dtSunFirst = dtStart.GetNextWeekDay(wxDateTime::Sun),
|
||||
dtSunLast = dtEnd.GetPrevWeekDay(wxDateTime::Sun),
|
||||
dt;
|
||||
|
||||
for ( dt = dtSatFirst; dt <= dtSatLast; dt += wxDateSpan::Week() )
|
||||
{
|
||||
holidays.Add(dt);
|
||||
}
|
||||
|
||||
for ( dt = dtSunFirst; dt <= dtSunLast; dt += wxDateSpan::Week() )
|
||||
{
|
||||
holidays.Add(dt);
|
||||
}
|
||||
|
||||
return holidays.GetCount();
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "wx/dcclient.h"
|
||||
#include "wx/settings.h"
|
||||
#include "wx/brush.h"
|
||||
#include "wx/combobox.h"
|
||||
#endif //WX_PRECOMP
|
||||
|
||||
#include "wx/calctrl.h"
|
||||
@ -79,6 +80,9 @@ BEGIN_EVENT_TABLE(wxCalendarCtrl, wxControl)
|
||||
|
||||
EVT_LEFT_DOWN(wxCalendarCtrl::OnClick)
|
||||
EVT_LEFT_DCLICK(wxCalendarCtrl::OnDClick)
|
||||
|
||||
EVT_CALENDAR_MONTH(-1, wxCalendarCtrl::OnCalMonthChange)
|
||||
EVT_CALENDAR_YEAR(-1, wxCalendarCtrl::OnCalMonthChange)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
BEGIN_EVENT_TABLE(wxMonthComboBox, wxComboBox)
|
||||
@ -146,6 +150,21 @@ void wxCalendarCtrl::Init()
|
||||
{
|
||||
m_weekdays[wd] = wxDateTime::GetWeekDayName(wd, wxDateTime::Name_Abbr);
|
||||
}
|
||||
|
||||
for ( size_t n = 0; n < WXSIZEOF(m_attrs); n++ )
|
||||
{
|
||||
m_attrs[n] = NULL;
|
||||
}
|
||||
|
||||
wxSystemSettings ss;
|
||||
m_colHighlightFg = ss.GetSystemColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
|
||||
m_colHighlightBg = ss.GetSystemColour(wxSYS_COLOUR_HIGHLIGHT);
|
||||
|
||||
m_colHolidayFg = *wxRED;
|
||||
// don't set m_colHolidayBg - by default, same as our bg colour
|
||||
|
||||
m_colHeaderFg = *wxBLUE;
|
||||
m_colHeaderBg = *wxLIGHT_GREY;
|
||||
}
|
||||
|
||||
bool wxCalendarCtrl::Create(wxWindow * WXUNUSED(parent),
|
||||
@ -182,15 +201,17 @@ bool wxCalendarCtrl::Create(wxWindow * WXUNUSED(parent),
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
SetFont(*wxSWISS_FONT);
|
||||
|
||||
SetHolidayAttrs();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
wxCalendarCtrl::~wxCalendarCtrl()
|
||||
{
|
||||
#if 0
|
||||
m_comboMonth->PopEventHandler();
|
||||
m_spinYear->PopEventHandler();
|
||||
#endif // 0
|
||||
for ( size_t n = 0; n < WXSIZEOF(m_attrs); n++ )
|
||||
{
|
||||
delete m_attrs[n];
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -285,7 +306,7 @@ void wxCalendarCtrl::SetDateAndNotify(const wxDateTime& date)
|
||||
|
||||
SetDate(date);
|
||||
|
||||
GenerateEvent(type);
|
||||
GenerateEvents(type, wxEVT_CALENDAR_SEL_CHANGED);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -302,9 +323,6 @@ wxDateTime wxCalendarCtrl::GetStartDate() const
|
||||
date.SetToPrevWeekDay(GetWindowStyle() & wxCAL_MONDAY_FIRST
|
||||
? wxDateTime::Mon : wxDateTime::Sun);
|
||||
|
||||
// be sure to do it or it might gain 1 hour if DST changed in between
|
||||
date.ResetTime();
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
@ -444,10 +462,10 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
|
||||
puts("painting the header");
|
||||
#endif
|
||||
|
||||
dc.SetTextForeground(*wxBLUE);
|
||||
dc.SetBrush(wxBrush(*wxLIGHT_GREY, wxSOLID));
|
||||
dc.SetBackgroundMode(wxTRANSPARENT);
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
dc.SetTextForeground(m_colHeaderFg);
|
||||
dc.SetBrush(wxBrush(m_colHeaderBg, wxSOLID));
|
||||
dc.SetPen(wxPen(m_colHeaderBg, 1, wxSOLID));
|
||||
dc.DrawRectangle(0, 0, 7*m_widthCol, m_heightRow);
|
||||
|
||||
bool startOnMonday = (GetWindowStyle() & wxCAL_MONDAY_FIRST) != 0;
|
||||
@ -495,24 +513,104 @@ void wxCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
|
||||
if ( IsDateShown(date) )
|
||||
{
|
||||
// don't use wxDate::Format() which prepends 0s
|
||||
wxString day = wxString::Format(_T("%u"), date.GetDay());
|
||||
unsigned int day = date.GetDay();
|
||||
wxString dayStr = wxString::Format(_T("%u"), day);
|
||||
wxCoord width;
|
||||
dc.GetTextExtent(day, &width, (wxCoord *)NULL);
|
||||
dc.GetTextExtent(dayStr, &width, (wxCoord *)NULL);
|
||||
|
||||
bool changedColours = FALSE,
|
||||
changedFont = FALSE;
|
||||
|
||||
wxCalendarDateAttr *attr = m_attrs[day - 1];
|
||||
|
||||
bool isSel = m_date == date;
|
||||
if ( isSel )
|
||||
{
|
||||
dc.SetTextForeground(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
|
||||
dc.SetTextBackground(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT));
|
||||
dc.SetTextForeground(m_colHighlightFg);
|
||||
dc.SetTextBackground(m_colHighlightBg);
|
||||
|
||||
changedColours = TRUE;
|
||||
}
|
||||
else if ( attr )
|
||||
{
|
||||
wxColour colFg, colBg;
|
||||
|
||||
if ( attr->IsHoliday() )
|
||||
{
|
||||
colFg = m_colHolidayFg;
|
||||
colBg = m_colHolidayBg;
|
||||
}
|
||||
else
|
||||
{
|
||||
colFg = attr->GetTextColour();
|
||||
colBg = attr->GetBackgroundColour();
|
||||
}
|
||||
|
||||
if ( colFg.Ok() )
|
||||
{
|
||||
dc.SetTextForeground(colFg);
|
||||
changedColours = TRUE;
|
||||
}
|
||||
|
||||
if ( colBg.Ok() )
|
||||
{
|
||||
dc.SetTextBackground(colBg);
|
||||
changedColours = TRUE;
|
||||
}
|
||||
|
||||
if ( attr->HasFont() )
|
||||
{
|
||||
dc.SetFont(attr->GetFont());
|
||||
changedFont = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
dc.DrawText(day, wd*m_widthCol + (m_widthCol - width) / 2, y);
|
||||
wxCoord x = wd*m_widthCol + (m_widthCol - width) / 2;
|
||||
dc.DrawText(dayStr, x, y + 1);
|
||||
|
||||
if ( isSel )
|
||||
if ( !isSel && attr && attr->HasBorder() )
|
||||
{
|
||||
wxColour colBorder;
|
||||
if ( attr->HasBorderColour() )
|
||||
{
|
||||
colBorder = attr->GetBorderColour();
|
||||
}
|
||||
else
|
||||
{
|
||||
colBorder = m_foregroundColour;
|
||||
}
|
||||
|
||||
wxPen pen(colBorder, 1, wxSOLID);
|
||||
dc.SetPen(pen);
|
||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||
|
||||
switch ( attr->GetBorder() )
|
||||
{
|
||||
case wxCAL_BORDER_SQUARE:
|
||||
dc.DrawRectangle(x - 2, y,
|
||||
width + 4, m_heightRow);
|
||||
break;
|
||||
|
||||
case wxCAL_BORDER_ROUND:
|
||||
dc.DrawEllipse(x - 2, y,
|
||||
width + 4, m_heightRow);
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG(_T("unknown border type"));
|
||||
}
|
||||
}
|
||||
|
||||
if ( changedColours )
|
||||
{
|
||||
dc.SetTextForeground(m_foregroundColour);
|
||||
dc.SetTextBackground(m_backgroundColour);
|
||||
}
|
||||
|
||||
if ( changedFont )
|
||||
{
|
||||
dc.SetFont(m_font);
|
||||
}
|
||||
}
|
||||
//else: just don't draw it
|
||||
|
||||
@ -560,7 +658,7 @@ void wxCalendarCtrl::OnDClick(wxMouseEvent& event)
|
||||
}
|
||||
else
|
||||
{
|
||||
GenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED, FALSE);
|
||||
GenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED);
|
||||
}
|
||||
}
|
||||
|
||||
@ -573,7 +671,8 @@ void wxCalendarCtrl::OnClick(wxMouseEvent& event)
|
||||
case wxCAL_HITTEST_DAY:
|
||||
ChangeDay(date);
|
||||
|
||||
GenerateEvent(wxEVT_CALENDAR_DAY_CHANGED);
|
||||
GenerateEvents(wxEVT_CALENDAR_DAY_CHANGED,
|
||||
wxEVT_CALENDAR_SEL_CHANGED);
|
||||
break;
|
||||
|
||||
case wxCAL_HITTEST_HEADER:
|
||||
@ -655,7 +754,7 @@ void wxCalendarCtrl::OnMonthChange(wxCommandEvent& event)
|
||||
|
||||
SetDate(wxDateTime(tm.mday, mon, tm.year));
|
||||
|
||||
GenerateEvent(wxEVT_CALENDAR_MONTH_CHANGED);
|
||||
GenerateEvents(wxEVT_CALENDAR_MONTH_CHANGED, wxEVT_CALENDAR_SEL_CHANGED);
|
||||
}
|
||||
|
||||
void wxCalendarCtrl::OnYearChange(wxSpinEvent& event)
|
||||
@ -670,7 +769,7 @@ void wxCalendarCtrl::OnYearChange(wxSpinEvent& event)
|
||||
|
||||
SetDate(wxDateTime(tm.mday, tm.mon, year));
|
||||
|
||||
GenerateEvent(wxEVT_CALENDAR_YEAR_CHANGED);
|
||||
GenerateEvents(wxEVT_CALENDAR_YEAR_CHANGED, wxEVT_CALENDAR_SEL_CHANGED);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -736,30 +835,96 @@ void wxCalendarCtrl::OnChar(wxKeyEvent& event)
|
||||
SetDateAndNotify(wxDateTime(m_date).SetToLastMonthDay());
|
||||
break;
|
||||
|
||||
case WXK_RETURN:
|
||||
GenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED);
|
||||
break;
|
||||
|
||||
default:
|
||||
event.Skip();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxCalendarEvent
|
||||
// holidays handling
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void wxCalendarCtrl::GenerateEvent(wxEventType type, bool selChanged)
|
||||
void wxCalendarCtrl::OnCalMonthChange(wxCalendarEvent& event)
|
||||
{
|
||||
// we're called for a change in some particular date field but we always
|
||||
// also generate a generic "changed" event
|
||||
wxCalendarEvent event(this, type);
|
||||
(void)GetEventHandler()->ProcessEvent(event);
|
||||
SetHolidayAttrs();
|
||||
|
||||
if ( selChanged )
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void wxCalendarCtrl::EnableHolidayDisplay(bool display)
|
||||
{
|
||||
long style = GetWindowStyle();
|
||||
if ( display )
|
||||
style |= wxCAL_SHOW_HOLIDAYS;
|
||||
else
|
||||
style &= ~wxCAL_SHOW_HOLIDAYS;
|
||||
|
||||
SetWindowStyle(style);
|
||||
|
||||
if ( display )
|
||||
SetHolidayAttrs();
|
||||
else
|
||||
ResetHolidayAttrs();
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void wxCalendarCtrl::SetHolidayAttrs()
|
||||
{
|
||||
if ( GetWindowStyle() & wxCAL_SHOW_HOLIDAYS )
|
||||
{
|
||||
wxCalendarEvent event2(this, wxEVT_CALENDAR_SEL_CHANGED);
|
||||
ResetHolidayAttrs();
|
||||
|
||||
(void)GetEventHandler()->ProcessEvent(event2);
|
||||
wxDateTime::Tm tm = m_date.GetTm();
|
||||
wxDateTime dtStart(1, tm.mon, tm.year),
|
||||
dtEnd = dtStart.GetLastMonthDay();
|
||||
|
||||
wxDateTimeArray hol;
|
||||
wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
|
||||
|
||||
size_t count = hol.GetCount();
|
||||
for ( size_t n = 0; n < count; n++ )
|
||||
{
|
||||
SetHoliday(hol[n].GetDay());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wxCalendarCtrl::SetHoliday(size_t day)
|
||||
{
|
||||
wxCHECK_RET( day > 0 && day < 32, _T("invalid day in SetHoliday") );
|
||||
|
||||
wxCalendarDateAttr *attr = GetAttr(day);
|
||||
if ( !attr )
|
||||
{
|
||||
attr = new wxCalendarDateAttr;
|
||||
}
|
||||
|
||||
attr->SetHoliday(TRUE);
|
||||
|
||||
// can't use SetAttr() because it would delete this pointer
|
||||
m_attrs[day - 1] = attr;
|
||||
}
|
||||
|
||||
void wxCalendarCtrl::ResetHolidayAttrs()
|
||||
{
|
||||
for ( size_t day = 0; day < 31; day++ )
|
||||
{
|
||||
if ( m_attrs[day] )
|
||||
{
|
||||
m_attrs[day]->SetHoliday(FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxCalendarEvent
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void wxCalendarEvent::Init()
|
||||
{
|
||||
m_wday = wxDateTime::Inv_WeekDay;
|
||||
|
Loading…
Reference in New Issue
Block a user