// Author: Vadim Zeitlin
// Modified by:
// Created: 29.12.99
-// RCS-ID: $Id$
// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// wxWin macros
// ----------------------------------------------------------------------------
+#ifdef wxHAS_NATIVE_CALENDARCTRL
+
+wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxGenericCalendarCtrl, wxControl,"wx/calctrl.h")
+
+#endif
+
BEGIN_EVENT_TABLE(wxGenericCalendarCtrl, wxControl)
EVT_PAINT(wxGenericCalendarCtrl::OnPaint)
EVT_SYS_COLOUR_CHANGED(wxGenericCalendarCtrl::OnSysColourChanged)
END_EVENT_TABLE()
-#if wxUSE_EXTENDED_RTTI
-WX_DEFINE_FLAGS( wxCalendarCtrlStyle )
-
-wxBEGIN_FLAGS( wxCalendarCtrlStyle )
- // new style border flags, we put them first to
- // use them for streaming out
- wxFLAGS_MEMBER(wxBORDER_SIMPLE)
- wxFLAGS_MEMBER(wxBORDER_SUNKEN)
- wxFLAGS_MEMBER(wxBORDER_DOUBLE)
- wxFLAGS_MEMBER(wxBORDER_RAISED)
- wxFLAGS_MEMBER(wxBORDER_STATIC)
- wxFLAGS_MEMBER(wxBORDER_NONE)
-
- // old style border flags
- wxFLAGS_MEMBER(wxSIMPLE_BORDER)
- wxFLAGS_MEMBER(wxSUNKEN_BORDER)
- wxFLAGS_MEMBER(wxDOUBLE_BORDER)
- wxFLAGS_MEMBER(wxRAISED_BORDER)
- wxFLAGS_MEMBER(wxSTATIC_BORDER)
- wxFLAGS_MEMBER(wxBORDER)
-
- // standard window styles
- wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
- wxFLAGS_MEMBER(wxCLIP_CHILDREN)
- wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
- wxFLAGS_MEMBER(wxWANTS_CHARS)
- wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
- wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
- wxFLAGS_MEMBER(wxVSCROLL)
- wxFLAGS_MEMBER(wxHSCROLL)
-
- wxFLAGS_MEMBER(wxCAL_SUNDAY_FIRST)
- wxFLAGS_MEMBER(wxCAL_MONDAY_FIRST)
- wxFLAGS_MEMBER(wxCAL_SHOW_HOLIDAYS)
- wxFLAGS_MEMBER(wxCAL_NO_YEAR_CHANGE)
- wxFLAGS_MEMBER(wxCAL_NO_MONTH_CHANGE)
- wxFLAGS_MEMBER(wxCAL_SEQUENTIAL_MONTH_SELECTION)
- wxFLAGS_MEMBER(wxCAL_SHOW_SURROUNDING_WEEKS)
- wxFLAGS_MEMBER(wxCAL_SHOW_WEEK_NUMBERS)
-
-wxEND_FLAGS( wxCalendarCtrlStyle )
-
-IMPLEMENT_DYNAMIC_CLASS_XTI(wxGenericCalendarCtrl, wxControl,"wx/calctrl.h")
-
-wxBEGIN_PROPERTIES_TABLE(wxGenericCalendarCtrl)
- wxEVENT_RANGE_PROPERTY( Updated , wxEVT_CALENDAR_SEL_CHANGED , wxEVT_CALENDAR_WEEK_CLICKED , wxCalendarEvent )
- wxHIDE_PROPERTY( Children )
- wxPROPERTY( Date,wxDateTime, SetDate , GetDate, , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
- wxPROPERTY_FLAGS( WindowStyle , wxCalendarCtrlStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
-wxEND_PROPERTIES_TABLE()
-
-wxBEGIN_HANDLERS_TABLE(wxGenericCalendarCtrl)
-wxEND_HANDLERS_TABLE()
-
-wxCONSTRUCTOR_6( wxGenericCalendarCtrl , wxWindow* , Parent , wxWindowID , Id , wxDateTime , Date , wxPoint , Position , wxSize , Size , long , WindowStyle )
-#else
-IMPLEMENT_DYNAMIC_CLASS(wxGenericCalendarCtrl, wxControl)
-#endif
-
// ============================================================================
// implementation
// ============================================================================
wxDefaultCoord,
wxSIZE_AUTO_WIDTH|wxSIZE_AUTO_HEIGHT);
- m_comboMonth->Connect(m_comboMonth->GetId(), wxEVT_COMMAND_COMBOBOX_SELECTED,
+ m_comboMonth->Connect(m_comboMonth->GetId(), wxEVT_COMBOBOX,
wxCommandEventHandler(wxGenericCalendarCtrl::OnMonthChange),
NULL, this);
}
wxDefaultSize,
wxSP_ARROW_KEYS | wxCLIP_SIBLINGS,
-4300, 10000, GetDate().GetYear());
-#ifdef __WXMAC__
- m_spinYear->SetSize( 90, -1 );
-#endif
- m_spinYear->Connect(m_spinYear->GetId(), wxEVT_COMMAND_TEXT_UPDATED,
+ m_spinYear->Connect(m_spinYear->GetId(), wxEVT_TEXT,
wxCommandEventHandler(wxGenericCalendarCtrl::OnYearTextChange),
NULL, this);
- m_spinYear->Connect(m_spinYear->GetId(), wxEVT_COMMAND_SPINCTRL_UPDATED,
+ m_spinYear->Connect(m_spinYear->GetId(), wxEVT_SPINCTRL,
wxSpinEventHandler(wxGenericCalendarCtrl::OnYearChange),
NULL, this);
}
wxDateTime date = wxDateTime(1, tm.mon, tm.year);
// rewind back
- date.SetToPrevWeekDay(GetWindowStyle() & wxCAL_MONDAY_FIRST
- ? wxDateTime::Mon : wxDateTime::Sun);
+ date.SetToPrevWeekDay(GetWeekStart());
if ( GetWindowStyle() & wxCAL_SHOW_SURROUNDING_WEEKS )
{
&& ( ( m_highdate.IsValid() ) ? ( date <= m_highdate ) : true ) );
}
-bool wxGenericCalendarCtrl::ChangeYear(wxDateTime* target) const
+bool wxGenericCalendarCtrl::AdjustDateToRange(wxDateTime *date) const
{
- bool retval = false;
-
- if ( !(IsDateInRange(*target)) )
+ if ( m_lowdate.IsValid() && *date < m_lowdate )
{
- if ( target->GetYear() < m_date.GetYear() )
- {
- if ( target->GetYear() >= GetLowerDateLimit().GetYear() )
- {
- *target = GetLowerDateLimit();
- retval = true;
- }
- else
- {
- *target = m_date;
- }
- }
- else
- {
- if ( target->GetYear() <= GetUpperDateLimit().GetYear() )
- {
- *target = GetUpperDateLimit();
- retval = true;
- }
- else
- {
- *target = m_date;
- }
- }
- }
- else
- {
- retval = true;
+ *date = m_lowdate;
+ return true;
}
- return retval;
-}
-
-bool wxGenericCalendarCtrl::ChangeMonth(wxDateTime* target) const
-{
- bool retval = true;
-
- if ( !(IsDateInRange(*target)) )
+ if ( m_highdate.IsValid() && *date > m_highdate )
{
- retval = false;
-
- if ( target->GetMonth() < m_date.GetMonth() )
- {
- *target = GetLowerDateLimit();
- }
- else
- {
- *target = GetUpperDateLimit();
- }
+ *date = m_highdate;
+ return true;
}
- return retval;
+ return false;
}
size_t wxGenericCalendarCtrl::GetWeek(const wxDateTime& date) const
{
- size_t retval = date.GetWeekOfMonth(GetWindowStyle() & wxCAL_MONDAY_FIRST
+ size_t retval = date.GetWeekOfMonth(HasFlag(wxCAL_MONDAY_FIRST)
? wxDateTime::Monday_First
: wxDateTime::Sunday_First);
wxDateTime datetest = wxDateTime(1, tm.mon, tm.year);
// rewind back
- datetest.SetToPrevWeekDay(GetWindowStyle() & wxCAL_MONDAY_FIRST
- ? wxDateTime::Mon : wxDateTime::Sun);
+ datetest.SetToPrevWeekDay(GetWeekStart());
if ( datetest.GetDay() == 1 )
{
height += wxMax(bestSizeCombo.y, m_spinYear->GetBestSize().y)
+ VERT_MARGIN;
-#ifdef __WXMAC__
- // the spin control get clipped otherwise
- width += 10;
-#endif
- wxCoord w2 = bestSizeCombo.x + HORZ_MARGIN + GetCharWidth()*6;
+ wxCoord w2 = bestSizeCombo.x + HORZ_MARGIN + GetCharWidth()*8;
if ( width < w2 )
width = w2;
}
int maxHeight = wxMax(sizeSpin.y, sizeCombo.y);
int dy = (maxHeight - sizeStatic.y) / 2;
-#ifdef __WXMAC__
- m_comboMonth->Move(x, y + (maxHeight - sizeCombo.y)/2 + 2); // FIXME, something is reporting the wrong size..
-#else
m_comboMonth->Move(x, y + (maxHeight - sizeCombo.y)/2);
-#endif
- m_staticMonth->SetSize(x, y + dy, sizeCombo.x, -1, sizeStatic.y);
+ m_staticMonth->SetSize(x, y + dy, sizeCombo.x, -1);
int xDiff = sizeCombo.x + HORZ_MARGIN;
void wxGenericCalendarCtrl::DoGetSize(int *width, int *height) const
{
-#ifdef __WXMAC__
wxControl::DoGetSize( width, height );
-
- if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) && m_staticMonth && height )
- {
- wxSize sizeCombo = m_comboMonth->GetEffectiveMinSize();
- wxSize sizeSpin = m_spinYear->GetSize();
-
- int maxHeight = wxMax(sizeSpin.y, sizeCombo.y);
- *height += maxHeight + VERT_MARGIN;
- }
-#else
- wxControl::DoGetSize( width, height );
-#endif
}
void wxGenericCalendarCtrl::RecalcGeometry()
dc.SetPen(wxPen(m_colHeaderBg, 1, wxPENSTYLE_SOLID));
dc.DrawRectangle(0, y, GetClientSize().x, m_heightRow);
- bool startOnMonday = (GetWindowStyle() & wxCAL_MONDAY_FIRST) != 0;
+ bool startOnMonday = HasFlag(wxCAL_MONDAY_FIRST);
for ( int wd = 0; wd < 7; wd++ )
{
size_t n;
colBg = attr->GetBackgroundColour();
}
- if ( colFg.Ok() )
+ if ( colFg.IsOk() )
{
dc.SetTextForeground(colFg);
changedColours = true;
}
- if ( colBg.Ok() )
+ if ( colBg.IsOk() )
{
dc.SetTextBackground(colBg);
changedColours = true;
if ( IsDateShown(date) )
{
- bool startOnMonday = ( GetWindowStyle() & wxCAL_MONDAY_FIRST ) != 0;
+ bool startOnMonday = HasFlag(wxCAL_MONDAY_FIRST);
// Find day
*day = date.GetWeekDay();
*date += wxDateSpan::Week() * (( pos.y - m_rowOffset ) / m_heightRow - 1 );
}
if ( wd )
- *wd = ( GetWindowStyle() & wxCAL_MONDAY_FIRST ) ? wxDateTime::Mon : wxDateTime::Sun;
+ *wd = GetWeekStart();
return wxCAL_HITTEST_WEEK;
}
else // early exit -> the rest of the function checks for clicks on days
{
if ( wd )
{
- if ( GetWindowStyle() & wxCAL_MONDAY_FIRST )
+ if ( HasFlag(wxCAL_MONDAY_FIRST) )
{
wday = wday == 6 ? 0 : wday + 1;
}
tm.mday = wxDateTime::GetNumberOfDays(mon, tm.year);
}
- wxDateTime target = wxDateTime(tm.mday, mon, tm.year);
+ wxDateTime dt(tm.mday, mon, tm.year);
+ if ( AdjustDateToRange(&dt) )
+ {
+ // The date must have been changed to ensure it's in valid range,
+ // reflect this in the month choice control.
+ m_comboMonth->SetSelection(dt.GetMonth());
+ }
- ChangeMonth(&target);
- SetDateAndNotify(target);
+ SetDateAndNotify(dt);
}
void wxGenericCalendarCtrl::HandleYearChange(wxCommandEvent& event)
tm.mday = wxDateTime::GetNumberOfDays(tm.mon, year);
}
- wxDateTime target = wxDateTime(tm.mday, tm.mon, year);
-
- if ( ChangeYear(&target) )
+ wxDateTime dt(tm.mday, tm.mon, year);
+ if ( AdjustDateToRange(&dt) )
{
- SetDateAndNotify(target);
- }
- else
- {
- // In this case we don't want to change the date. That would put us
- // inside the same year but a strange number of months forward/back..
- m_spinYear->SetValue(target.GetYear());
+ // As above, if the date was changed to keep it in valid range, its
+ // possibly changed year must be shown in the GUI.
+ m_spinYear->SetValue(dt.GetYear());
}
+
+ SetDateAndNotify(dt);
}
void wxGenericCalendarCtrl::OnYearChange(wxSpinEvent& event)
void wxGenericCalendarCtrl::OnChar(wxKeyEvent& event)
{
- wxDateTime target;
switch ( event.GetKeyCode() )
{
case wxT('+'):
case WXK_ADD:
- target = m_date + wxDateSpan::Year();
- if ( ChangeYear(&target) )
- {
- SetDateAndNotify(target);
- }
+ SetDateAndNotify(m_date + wxDateSpan::Year());
break;
case wxT('-'):
case WXK_SUBTRACT:
- target = m_date - wxDateSpan::Year();
- if ( ChangeYear(&target) )
- {
- SetDateAndNotify(target);
- }
+ SetDateAndNotify(m_date - wxDateSpan::Year());
break;
case WXK_PAGEUP:
- target = m_date - wxDateSpan::Month();
- ChangeMonth(&target);
- SetDateAndNotify(target); // always
+ SetDateAndNotify(m_date - wxDateSpan::Month());
break;
case WXK_PAGEDOWN:
- target = m_date + wxDateSpan::Month();
- ChangeMonth(&target);
- SetDateAndNotify(target); // always
+ SetDateAndNotify(m_date + wxDateSpan::Month());
break;
case WXK_RIGHT:
if ( event.ControlDown() )
{
- target = wxDateTime(m_date).SetToNextWeekDay(
- GetWindowStyle() & wxCAL_MONDAY_FIRST
- ? wxDateTime::Sun : wxDateTime::Sat);
- if ( !IsDateInRange(target) )
- {
- target = GetUpperDateLimit();
- }
+ wxDateTime target = m_date.SetToNextWeekDay(GetWeekEnd());
+ AdjustDateToRange(&target);
SetDateAndNotify(target);
}
else
case WXK_LEFT:
if ( event.ControlDown() )
{
- target = wxDateTime(m_date).SetToPrevWeekDay(
- GetWindowStyle() & wxCAL_MONDAY_FIRST
- ? wxDateTime::Mon : wxDateTime::Sun);
- if ( !IsDateInRange(target) )
- {
- target = GetLowerDateLimit();
- }
+ wxDateTime target = m_date.SetToPrevWeekDay(GetWeekStart());
+ AdjustDateToRange(&target);
SetDateAndNotify(target);
}
else