]> git.saurik.com Git - wxWidgets.git/blame - samples/calendar/calendar.cpp
Always use icons with wxToolbook in the notebook sample.
[wxWidgets.git] / samples / calendar / calendar.cpp
CommitLineData
74a533f7
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: calendar.cpp
3// Purpose: wxCalendarCtrl sample
4// Author: Vadim Zeitlin
4e6bceff 5// Modified by:
74a533f7
VZ
6// Created: 02.01.00
7// RCS-ID: $Id$
8// Copyright: (c) Vadim Zeitlin
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
74a533f7
VZ
20// For compilers that support precompilation, includes "wx/wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
273b7ed9 27// for all others, include the necessary headers
74a533f7
VZ
28#ifndef WX_PRECOMP
29 #include "wx/app.h"
788233da 30 #include "wx/log.h"
74a533f7 31 #include "wx/frame.h"
273b7ed9
VZ
32 #include "wx/panel.h"
33 #include "wx/stattext.h"
34 #include "wx/menu.h"
35 #include "wx/layout.h"
36 #include "wx/msgdlg.h"
d9210ab7 37 #include "wx/icon.h"
574d4d1c
PC
38 #include "wx/button.h"
39 #include "wx/sizer.h"
40 #include "wx/textctrl.h"
41 #include "wx/settings.h"
74a533f7
VZ
42#endif
43
44#include "wx/calctrl.h"
628e155d 45#include "wx/splitter.h"
7ff2dfba
VZ
46
47#if wxUSE_DATEPICKCTRL
48 #include "wx/datectrl.h"
49 #if wxUSE_DATEPICKCTRL_GENERIC
50 #include "wx/generic/datectrl.h"
51 #endif // wxUSE_DATEPICKCTRL_GENERIC
52#endif // wxUSE_DATEPICKCTRL
feb72429 53
48263511 54#include "../sample.xpm"
3200f37d 55
628e155d
VZ
56#ifdef wxHAS_NATIVE_CALENDARCTRL
57 #include "wx/generic/calctrlg.h"
58#endif
59
74a533f7
VZ
60// ----------------------------------------------------------------------------
61// private classes
62// ----------------------------------------------------------------------------
63
64// Define a new application type, each program should derive a class from wxApp
65class MyApp : public wxApp
66{
67public:
68 // override base class virtuals
69 // ----------------------------
70
71 // this one is called on application startup and is a good place for the app
72 // initialization (doing it here and not in the ctor allows to have an error
73 // return: if OnInit() returns false, the application terminates)
74 virtual bool OnInit();
75};
76
77class MyPanel : public wxPanel
78{
79public:
628e155d 80 MyPanel(wxWindow *parent);
74a533f7
VZ
81
82 void OnCalendar(wxCalendarEvent& event);
83 void OnCalendarWeekDayClick(wxCalendarEvent& event);
232b2162 84 void OnCalendarWeekClick(wxCalendarEvent& event);
74a533f7 85 void OnCalendarChange(wxCalendarEvent& event);
0de868d9 86 void OnCalMonthChange(wxCalendarEvent& event);
74a533f7 87
628e155d 88 wxCalendarCtrlBase *GetCal() const { return m_calendar; }
bc385ba9 89
37df1f33
VZ
90 // turn on/off the specified style bit on the calendar control
91 void ToggleCalStyle(bool on, int style);
92
628e155d
VZ
93 bool IsUsingGeneric() const { return m_usingGeneric; }
94 void ToggleUseGeneric()
95 {
96 m_usingGeneric = !m_usingGeneric;
97 RecreateCalendar(m_calendar->GetWindowStyle());
98 }
99
74a533f7 100 void HighlightSpecial(bool on);
a5cf7942 101 void LimitDateRange(bool on);
74a533f7 102
a3c3a4cd
VZ
103 wxDateTime GetDate() const { return m_calendar->GetDate(); }
104 void SetDate(const wxDateTime& dt) { m_calendar->SetDate(dt); }
a7c58211 105
74a533f7 106private:
ee22a3a2
VZ
107 wxCalendarCtrlBase *DoCreateCalendar(const wxDateTime& dt, long style);
108
628e155d
VZ
109 void RecreateCalendar(long style);
110
111 wxCalendarCtrlBase *m_calendar;
74a533f7 112 wxStaticText *m_date;
2522d529 113 wxSizer *m_sizer;
74a533f7 114
628e155d
VZ
115 bool m_usingGeneric;
116
117
74a533f7
VZ
118 DECLARE_EVENT_TABLE()
119};
120
121// Define a new frame type: this is going to be our main frame
122class MyFrame : public wxFrame
123{
124public:
125 // ctor(s)
f9cc9706 126 MyFrame(const wxString& title, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize);
74a533f7
VZ
127
128 // event handlers (these functions should _not_ be virtual)
74a533f7 129 void OnAbout(wxCommandEvent& event);
628e155d
VZ
130 void OnClearLog(wxCommandEvent& event);
131 void OnQuit(wxCommandEvent& event);
74a533f7 132
ac78ab7b 133#if wxUSE_DATEPICKCTRL
feb72429 134 void OnAskDate(wxCommandEvent& event);
404e855d
VZ
135
136 void OnUpdateUIStartWithNone(wxUpdateUIEvent& event);
ac78ab7b 137#endif // wxUSE_DATEPICKCTRL
feb72429 138
628e155d
VZ
139#ifdef wxHAS_NATIVE_CALENDARCTRL
140 void OnCalGeneric(wxCommandEvent& WXUNUSED(event))
141 {
142 m_panel->ToggleUseGeneric();
143 }
144#endif // wxHAS_NATIVE_CALENDARCTRL
145
74a533f7
VZ
146 void OnCalMonday(wxCommandEvent& event);
147 void OnCalHolidays(wxCommandEvent& event);
148 void OnCalSpecial(wxCommandEvent& event);
149
bc385ba9 150 void OnCalAllowMonth(wxCommandEvent& event);
a5cf7942 151 void OnCalLimitDates(wxCommandEvent& event);
37df1f33
VZ
152 void OnCalSeqMonth(wxCommandEvent& event);
153 void OnCalShowSurroundingWeeks(wxCommandEvent& event);
7b0ccb8a 154 void OnCalShowWeekNumbers(wxCommandEvent& event);
37df1f33 155
605dfd91
JS
156 void OnSetDate(wxCommandEvent& event);
157 void OnToday(wxCommandEvent& event);
a3c3a4cd 158 void OnBeginDST(wxCommandEvent& event);
605dfd91 159
5f324bb6
VZ
160 void OnCalToggleResizable(wxCommandEvent& event);
161
628e155d
VZ
162 void OnUpdateUIGenericOnly(wxUpdateUIEvent& event)
163 {
164 event.Enable(m_panel->IsUsingGeneric());
165 }
bc385ba9 166
ee22a3a2
VZ
167 void OnCalRClick(wxMouseEvent& event);
168
74a533f7
VZ
169private:
170 MyPanel *m_panel;
628e155d 171 wxTextCtrl *m_logWindow;
74a533f7 172
be5a51fb 173 // any class wishing to process wxWidgets events must use this macro
74a533f7
VZ
174 DECLARE_EVENT_TABLE()
175};
176
ac78ab7b 177#if wxUSE_DATEPICKCTRL
feb72429
VZ
178
179// Define a simple modal dialog which asks the user for a date
180class MyDialog : public wxDialog
181{
182public:
d1fd3c26 183 MyDialog(wxWindow *parent, const wxDateTime& dt, int dtpStyle);
feb72429
VZ
184
185 wxDateTime GetDate() const { return m_datePicker->GetValue(); }
186
187private:
188 void OnDateChange(wxDateEvent& event);
189
190
7ff2dfba 191 wxDatePickerCtrlBase *m_datePicker;
feb72429
VZ
192 wxTextCtrl *m_text;
193
194
195 DECLARE_EVENT_TABLE()
196};
197
ac78ab7b 198#endif // wxUSE_DATEPICKCTRL
feb72429 199
74a533f7
VZ
200// ----------------------------------------------------------------------------
201// constants
202// ----------------------------------------------------------------------------
203
204// IDs for the controls and the menu commands
205enum
206{
207 // menu items
feb72429 208 Calendar_File_About = wxID_ABOUT,
628e155d 209 Calendar_File_ClearLog = wxID_CLEAR,
feb72429 210 Calendar_File_Quit = wxID_EXIT,
628e155d
VZ
211 Calendar_Cal_Generic = 200,
212 Calendar_Cal_Monday,
74a533f7
VZ
213 Calendar_Cal_Holidays,
214 Calendar_Cal_Special,
bc385ba9 215 Calendar_Cal_Month,
a5cf7942 216 Calendar_Cal_LimitDates,
37df1f33
VZ
217 Calendar_Cal_SeqMonth,
218 Calendar_Cal_SurroundWeeks,
7b0ccb8a 219 Calendar_Cal_WeekNumbers,
605dfd91
JS
220 Calendar_Cal_SetDate,
221 Calendar_Cal_Today,
a3c3a4cd 222 Calendar_Cal_BeginDST,
5f324bb6 223 Calendar_Cal_Resizable,
d1fd3c26
VZ
224#if wxUSE_DATEPICKCTRL
225 Calendar_DatePicker_AskDate = 300,
226 Calendar_DatePicker_ShowCentury,
227 Calendar_DatePicker_DropDown,
3200f37d 228 Calendar_DatePicker_AllowNone,
404e855d 229 Calendar_DatePicker_StartWithNone,
7ff2dfba
VZ
230#if wxUSE_DATEPICKCTRL_GENERIC
231 Calendar_DatePicker_Generic,
232#endif // wxUSE_DATEPICKCTRL_GENERIC
d1fd3c26 233#endif // wxUSE_DATEPICKCTRL
e9561b3b 234 Calendar_CalCtrl = 1000
74a533f7
VZ
235};
236
237// ----------------------------------------------------------------------------
be5a51fb 238// event tables and other macros for wxWidgets
74a533f7
VZ
239// ----------------------------------------------------------------------------
240
be5a51fb 241// the event tables connect the wxWidgets events with the functions (event
74a533f7
VZ
242// handlers) which process them. It can be also done at run-time, but for the
243// simple menu events like this the static method is much simpler.
244BEGIN_EVENT_TABLE(MyFrame, wxFrame)
74a533f7 245 EVT_MENU(Calendar_File_About, MyFrame::OnAbout)
628e155d
VZ
246 EVT_MENU(Calendar_File_ClearLog, MyFrame::OnClearLog)
247 EVT_MENU(Calendar_File_Quit, MyFrame::OnQuit)
74a533f7 248
ac78ab7b 249#if wxUSE_DATEPICKCTRL
d1fd3c26 250 EVT_MENU(Calendar_DatePicker_AskDate, MyFrame::OnAskDate)
404e855d
VZ
251
252 EVT_UPDATE_UI(Calendar_DatePicker_StartWithNone,
253 MyFrame::OnUpdateUIStartWithNone)
ac78ab7b 254#endif // wxUSE_DATEPICKCTRL
feb72429 255
628e155d
VZ
256#ifdef wxHAS_NATIVE_CALENDARCTRL
257 EVT_MENU(Calendar_Cal_Generic, MyFrame::OnCalGeneric)
258#endif // wxHAS_NATIVE_CALENDARCTRL
259
74a533f7
VZ
260 EVT_MENU(Calendar_Cal_Monday, MyFrame::OnCalMonday)
261 EVT_MENU(Calendar_Cal_Holidays, MyFrame::OnCalHolidays)
262 EVT_MENU(Calendar_Cal_Special, MyFrame::OnCalSpecial)
bc385ba9
VZ
263
264 EVT_MENU(Calendar_Cal_Month, MyFrame::OnCalAllowMonth)
bc385ba9 265
a5cf7942
VZ
266 EVT_MENU(Calendar_Cal_LimitDates, MyFrame::OnCalLimitDates)
267
37df1f33
VZ
268 EVT_MENU(Calendar_Cal_SeqMonth, MyFrame::OnCalSeqMonth)
269 EVT_MENU(Calendar_Cal_SurroundWeeks, MyFrame::OnCalShowSurroundingWeeks)
7b0ccb8a 270 EVT_MENU(Calendar_Cal_WeekNumbers, MyFrame::OnCalShowWeekNumbers)
37df1f33 271
605dfd91
JS
272 EVT_MENU(Calendar_Cal_SetDate, MyFrame::OnSetDate)
273 EVT_MENU(Calendar_Cal_Today, MyFrame::OnToday)
a3c3a4cd 274 EVT_MENU(Calendar_Cal_BeginDST, MyFrame::OnBeginDST)
605dfd91 275
5f324bb6
VZ
276 EVT_MENU(Calendar_Cal_Resizable, MyFrame::OnCalToggleResizable)
277
605dfd91 278
628e155d 279 EVT_UPDATE_UI(Calendar_Cal_SeqMonth, MyFrame::OnUpdateUIGenericOnly)
db0b0942 280#ifdef __WXGTK20__
628e155d
VZ
281 EVT_UPDATE_UI(Calendar_Cal_Monday, MyFrame::OnUpdateUIGenericOnly)
282 EVT_UPDATE_UI(Calendar_Cal_Holidays, MyFrame::OnUpdateUIGenericOnly)
a5cf7942 283 EVT_UPDATE_UI(Calendar_Cal_LimitDates, MyFrame::OnUpdateUIGenericOnly)
6d9b6716 284#endif
628e155d
VZ
285 EVT_UPDATE_UI(Calendar_Cal_Special, MyFrame::OnUpdateUIGenericOnly)
286 EVT_UPDATE_UI(Calendar_Cal_SurroundWeeks, MyFrame::OnUpdateUIGenericOnly)
74a533f7
VZ
287END_EVENT_TABLE()
288
289BEGIN_EVENT_TABLE(MyPanel, wxPanel)
628e155d
VZ
290 EVT_CALENDAR(Calendar_CalCtrl, MyPanel::OnCalendar)
291 EVT_CALENDAR_PAGE_CHANGED(Calendar_CalCtrl, MyPanel::OnCalMonthChange)
292 EVT_CALENDAR_SEL_CHANGED(Calendar_CalCtrl, MyPanel::OnCalendarChange)
74a533f7 293 EVT_CALENDAR_WEEKDAY_CLICKED(Calendar_CalCtrl, MyPanel::OnCalendarWeekDayClick)
232b2162 294 EVT_CALENDAR_WEEK_CLICKED(Calendar_CalCtrl, MyPanel::OnCalendarWeekClick)
74a533f7
VZ
295END_EVENT_TABLE()
296
ac78ab7b 297#if wxUSE_DATEPICKCTRL
feb72429
VZ
298
299BEGIN_EVENT_TABLE(MyDialog, wxDialog)
300 EVT_DATE_CHANGED(wxID_ANY, MyDialog::OnDateChange)
301END_EVENT_TABLE()
302
ac78ab7b 303#endif // wxUSE_DATEPICKCTRL
feb72429 304
be5a51fb 305// Create a new application object: this macro will allow wxWidgets to create
74a533f7
VZ
306// the application object during program execution (it's better than using a
307// static object for many reasons) and also declares the accessor function
308// wxGetApp() which will return the reference of the right type (i.e. MyApp and
309// not wxApp)
310IMPLEMENT_APP(MyApp)
311
312// ============================================================================
313// implementation
314// ============================================================================
315
316// ----------------------------------------------------------------------------
317// the application class
318// ----------------------------------------------------------------------------
319
320// `Main program' equivalent: the program execution "starts" here
321bool MyApp::OnInit()
322{
45e6e6f8
VZ
323 if ( !wxApp::OnInit() )
324 return false;
325
74a533f7 326 // Create the main application window
9a83f860 327 MyFrame *frame = new MyFrame(wxT("Calendar wxWidgets sample")
f9cc9706
WS
328#ifndef __WXWINCE__
329 ,wxPoint(50, 50), wxSize(450, 340)
330#endif
232b2162 331 );
74a533f7 332
9230b621 333 frame->Show(true);
74a533f7
VZ
334
335 // success: wxApp::OnRun() will be called which will enter the main message
5014bb3a 336 // loop and the application will run. If we returned false here, the
74a533f7 337 // application would exit immediately.
9230b621 338 return true;
74a533f7
VZ
339}
340
341// ----------------------------------------------------------------------------
342// main frame
343// ----------------------------------------------------------------------------
344
345// frame constructor
346MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
9230b621 347 : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size)
74a533f7 348{
3200f37d 349 // set the frame icon
3cb332c1 350 SetIcon(wxICON(sample));
3200f37d 351
74a533f7
VZ
352 // create a menu bar
353 wxMenu *menuFile = new wxMenu;
9a83f860 354 menuFile->Append(Calendar_File_About, wxT("&About...\tCtrl-A"), wxT("Show about dialog"));
74a533f7 355 menuFile->AppendSeparator();
9a83f860 356 menuFile->Append(Calendar_File_ClearLog, wxT("&Clear log\tCtrl-L"));
628e155d 357 menuFile->AppendSeparator();
9a83f860 358 menuFile->Append(Calendar_File_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
74a533f7
VZ
359
360 wxMenu *menuCal = new wxMenu;
628e155d
VZ
361#ifdef wxHAS_NATIVE_CALENDARCTRL
362 menuCal->AppendCheckItem(Calendar_Cal_Generic, "Use &generic version\tCtrl-G",
363 "Toggle between native and generic control");
364 menuCal->AppendSeparator();
365#endif // wxHAS_NATIVE_CALENDARCTRL
74a533f7 366 menuCal->Append(Calendar_Cal_Monday,
9a83f860
VZ
367 wxT("Monday &first weekday\tCtrl-F"),
368 wxT("Toggle between Mon and Sun as the first week day"),
9230b621 369 true);
9a83f860
VZ
370 menuCal->Append(Calendar_Cal_Holidays, wxT("Show &holidays\tCtrl-H"),
371 wxT("Toggle highlighting the holidays"),
9230b621 372 true);
9a83f860
VZ
373 menuCal->Append(Calendar_Cal_Special, wxT("Highlight &special dates\tCtrl-S"),
374 wxT("Test custom highlighting"),
9230b621 375 true);
37df1f33 376 menuCal->Append(Calendar_Cal_SurroundWeeks,
9a83f860
VZ
377 wxT("Show s&urrounding weeks\tCtrl-W"),
378 wxT("Show the neighbouring weeks in the prev/next month"),
9230b621 379 true);
7b0ccb8a 380 menuCal->Append(Calendar_Cal_WeekNumbers,
9a83f860
VZ
381 wxT("Show &week numbers"),
382 wxT("Toggle week numbers"),
7b0ccb8a 383 true);
bc385ba9 384 menuCal->AppendSeparator();
37df1f33 385 menuCal->Append(Calendar_Cal_SeqMonth,
9a83f860
VZ
386 wxT("Toggle month selector st&yle\tCtrl-Y"),
387 wxT("Use another style for the calendar controls"),
9230b621 388 true);
9a83f860
VZ
389 menuCal->Append(Calendar_Cal_Month, wxT("&Month can be changed\tCtrl-M"),
390 wxT("Allow changing the month in the calendar"),
9230b621 391 true);
a5cf7942
VZ
392 menuCal->AppendCheckItem(Calendar_Cal_LimitDates, wxT("Toggle date ra&nge\tCtrl-N"),
393 wxT("Limit the valid dates"));
605dfd91 394 menuCal->AppendSeparator();
9a83f860
VZ
395 menuCal->Append(Calendar_Cal_SetDate, wxT("Call &SetDate(2005-12-24)"), wxT("Set date to 2005-12-24."));
396 menuCal->Append(Calendar_Cal_Today, wxT("Call &Today()"), wxT("Set to the current date."));
a3c3a4cd 397 menuCal->Append(Calendar_Cal_BeginDST, "Call SetDate(GetBeginDST())");
5f324bb6 398 menuCal->AppendSeparator();
9a83f860 399 menuCal->AppendCheckItem(Calendar_Cal_Resizable, wxT("Make &resizable\tCtrl-R"));
74a533f7 400
d1fd3c26
VZ
401#if wxUSE_DATEPICKCTRL
402 wxMenu *menuDate = new wxMenu;
403 menuDate->AppendCheckItem(Calendar_DatePicker_ShowCentury,
9a83f860 404 wxT("Al&ways show century"));
d1fd3c26 405 menuDate->AppendCheckItem(Calendar_DatePicker_DropDown,
9a83f860 406 wxT("Use &drop down control"));
3200f37d 407 menuDate->AppendCheckItem(Calendar_DatePicker_AllowNone,
9a83f860 408 wxT("Allow &no date"));
404e855d 409 menuDate->AppendCheckItem(Calendar_DatePicker_StartWithNone,
9a83f860 410 wxT("Start &with no date"));
7ff2dfba
VZ
411#if wxUSE_DATEPICKCTRL_GENERIC
412 menuDate->AppendCheckItem(Calendar_DatePicker_Generic,
9a83f860 413 wxT("Use &generic version of the control"));
7ff2dfba 414#endif // wxUSE_DATEPICKCTRL_GENERIC
d1fd3c26 415 menuDate->AppendSeparator();
9a83f860 416 menuDate->Append(Calendar_DatePicker_AskDate, wxT("&Choose date...\tCtrl-D"), wxT("Show dialog with wxDatePickerCtrl"));
d1fd3c26
VZ
417#endif // wxUSE_DATEPICKCTRL
418
74a533f7
VZ
419 // now append the freshly created menu to the menu bar...
420 wxMenuBar *menuBar = new wxMenuBar;
9a83f860
VZ
421 menuBar->Append(menuFile, wxT("&File"));
422 menuBar->Append(menuCal, wxT("&Calendar"));
d1fd3c26 423#if wxUSE_DATEPICKCTRL
9a83f860 424 menuBar->Append(menuDate, wxT("&Date picker"));
d1fd3c26 425#endif // wxUSE_DATEPICKCTRL
74a533f7 426
9230b621
VS
427 menuBar->Check(Calendar_Cal_Monday, true);
428 menuBar->Check(Calendar_Cal_Holidays, true);
429 menuBar->Check(Calendar_Cal_Month, true);
a5cf7942 430 menuBar->Check(Calendar_Cal_LimitDates, false);
74a533f7 431
d1fd3c26
VZ
432#if wxUSE_DATEPICKCTRL
433 menuBar->Check(Calendar_DatePicker_ShowCentury, true);
434#endif // wxUSE_DATEPICKCTRL
435
74a533f7
VZ
436 // ... and attach this menu bar to the frame
437 SetMenuBar(menuBar);
438
628e155d
VZ
439 wxSplitterWindow *splitter = new wxSplitterWindow(this, wxID_ANY,
440 wxDefaultPosition, wxDefaultSize,
441 wxSP_NOBORDER);
442 m_panel = new MyPanel(splitter);
443 m_logWindow = new wxTextCtrl(splitter, wxID_ANY, wxEmptyString,
444 wxDefaultPosition, wxDefaultSize,
445 wxTE_READONLY | wxTE_MULTILINE);
446 splitter->SplitHorizontally(m_panel, m_logWindow);
447 splitter->SetMinimumPaneSize(20);
448 wxLog::SetActiveTarget(new wxLogTextCtrl(m_logWindow));
74a533f7
VZ
449}
450
451void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
452{
5014bb3a 453 // true is to force the frame to close
9230b621 454 Close(true);
74a533f7
VZ
455}
456
457void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
458{
9a83f860
VZ
459 wxMessageBox(wxT("wxCalendarCtrl sample\n(c) 2000--2008 Vadim Zeitlin"),
460 wxT("About Calendar"), wxOK | wxICON_INFORMATION, this);
74a533f7
VZ
461}
462
628e155d 463void MyFrame::OnClearLog(wxCommandEvent& WXUNUSED(event))
74a533f7 464{
628e155d
VZ
465 m_logWindow->Clear();
466}
37df1f33 467
628e155d
VZ
468void MyFrame::OnCalMonday(wxCommandEvent& event)
469{
470 m_panel->ToggleCalStyle(event.IsChecked(), wxCAL_MONDAY_FIRST);
74a533f7
VZ
471}
472
473void MyFrame::OnCalHolidays(wxCommandEvent& event)
474{
bf956fac 475 m_panel->GetCal()->EnableHolidayDisplay(event.IsChecked());
74a533f7
VZ
476}
477
478void MyFrame::OnCalSpecial(wxCommandEvent& event)
479{
89a0a322 480 m_panel->HighlightSpecial(GetMenuBar()->IsChecked(event.GetId()));
bc385ba9
VZ
481}
482
a5cf7942
VZ
483void MyFrame::OnCalLimitDates(wxCommandEvent& event)
484{
485 m_panel->LimitDateRange(GetMenuBar()->IsChecked(event.GetId()));
486}
487
bc385ba9
VZ
488void MyFrame::OnCalAllowMonth(wxCommandEvent& event)
489{
628e155d 490 m_panel->GetCal()->EnableMonthChange(event.IsChecked());
bc385ba9
VZ
491}
492
37df1f33
VZ
493void MyFrame::OnCalSeqMonth(wxCommandEvent& event)
494{
628e155d
VZ
495 m_panel->ToggleCalStyle(event.IsChecked(),
496 wxCAL_SEQUENTIAL_MONTH_SELECTION);
37df1f33
VZ
497}
498
499void MyFrame::OnCalShowSurroundingWeeks(wxCommandEvent& event)
500{
628e155d 501 m_panel->ToggleCalStyle(event.IsChecked(), wxCAL_SHOW_SURROUNDING_WEEKS);
74a533f7
VZ
502}
503
7b0ccb8a
RR
504void MyFrame::OnCalShowWeekNumbers(wxCommandEvent& event)
505{
506 m_panel->ToggleCalStyle(event.IsChecked(), wxCAL_SHOW_WEEK_NUMBERS);
507}
508
87728739 509void MyFrame::OnSetDate(wxCommandEvent &WXUNUSED(event))
605dfd91 510{
628e155d 511 m_panel->SetDate(wxDateTime(24, wxDateTime::Dec, 2005, 22, 00, 00));
605dfd91
JS
512}
513
87728739 514void MyFrame::OnToday(wxCommandEvent &WXUNUSED(event))
605dfd91 515{
a3c3a4cd
VZ
516 m_panel->SetDate(wxDateTime::Today());
517}
518
519void MyFrame::OnBeginDST(wxCommandEvent &WXUNUSED(event))
520{
521 m_panel->SetDate(wxDateTime::GetBeginDST(m_panel->GetDate().GetYear()));
605dfd91
JS
522}
523
5f324bb6
VZ
524void MyFrame::OnCalToggleResizable(wxCommandEvent& event)
525{
526 wxSizer * const sizer = m_panel->GetSizer();
527 wxSizerItem * const item = sizer->GetItem(m_panel->GetCal());
528 if ( event.IsChecked() )
529 {
530 item->SetProportion(1);
531 item->SetFlag(wxEXPAND);
532 }
533 else // not resizable
534 {
535 item->SetProportion(0);
536 item->SetFlag(wxALIGN_CENTER);
537 }
538
539 sizer->Layout();
540}
541
ee22a3a2
VZ
542void MyFrame::OnCalRClick(wxMouseEvent& event)
543{
544 wxDateTime dt;
545 wxDateTime::WeekDay wd;
546
547 const wxPoint pt = event.GetPosition();
548 wxString msg = wxString::Format("Point (%d, %d) is ", pt.x, pt.y);
549
550 switch ( m_panel->GetCal()->HitTest(pt, &dt, &wd) )
551 {
552 default:
553 wxFAIL_MSG( "unexpected" );
554 // fall through
555
556 case wxCAL_HITTEST_NOWHERE:
557 msg += "nowhere";
558 break;
559
560 case wxCAL_HITTEST_HEADER:
561 msg += wxString::Format("over %s", wxDateTime::GetWeekDayName(wd));
562 break;
563
564 case wxCAL_HITTEST_DAY:
565 msg += wxString::Format("over %s", dt.FormatISODate());
566 break;
567
568 case wxCAL_HITTEST_INCMONTH:
569 msg += "over next month button";
570 break;
571
572 case wxCAL_HITTEST_DECMONTH:
573 msg += "over previous month button";
574 break;
575
576 case wxCAL_HITTEST_SURROUNDING_WEEK:
577 msg += "over a day from another month";
578 break;
579 }
580
581 wxLogMessage("%s", msg);
582}
583
ac78ab7b 584#if wxUSE_DATEPICKCTRL
feb72429 585
404e855d
VZ
586void MyFrame::OnUpdateUIStartWithNone(wxUpdateUIEvent& event)
587{
588 // it only makes sense to start with invalid date if we can have no date
589 event.Enable( GetMenuBar()->IsChecked(Calendar_DatePicker_AllowNone) );
590}
591
feb72429
VZ
592void MyFrame::OnAskDate(wxCommandEvent& WXUNUSED(event))
593{
404e855d
VZ
594 wxDateTime dt = m_panel->GetCal()->GetDate();
595
d1fd3c26
VZ
596 int style = wxDP_DEFAULT;
597 if ( GetMenuBar()->IsChecked(Calendar_DatePicker_ShowCentury) )
598 style |= wxDP_SHOWCENTURY;
599 if ( GetMenuBar()->IsChecked(Calendar_DatePicker_DropDown) )
600 style |= wxDP_DROPDOWN;
3200f37d 601 if ( GetMenuBar()->IsChecked(Calendar_DatePicker_AllowNone) )
404e855d 602 {
3200f37d 603 style |= wxDP_ALLOWNONE;
d1fd3c26 604
404e855d
VZ
605 if ( GetMenuBar()->IsChecked(Calendar_DatePicker_StartWithNone) )
606 dt = wxDefaultDateTime;
607 }
608
609 MyDialog dlg(this, dt, style);
feb72429
VZ
610 if ( dlg.ShowModal() == wxID_OK )
611 {
404e855d 612 dt = dlg.GetDate();
3200f37d 613 if ( dt.IsValid() )
feb72429 614 {
3200f37d 615 const wxDateTime today = wxDateTime::Today();
feb72429 616
3200f37d
VZ
617 if ( dt.GetDay() == today.GetDay() &&
618 dt.GetMonth() == today.GetMonth() )
619 {
9a83f860 620 wxMessageBox(wxT("Happy birthday!"), wxT("Calendar Sample"));
3200f37d 621 }
feb72429 622
a3c3a4cd 623 m_panel->SetDate(dt);
3200f37d 624
9a83f860 625 wxLogStatus(wxT("Changed the date to your input"));
3200f37d
VZ
626 }
627 else
628 {
9a83f860 629 wxLogStatus(wxT("No date entered"));
3200f37d 630 }
feb72429
VZ
631 }
632}
633
ac78ab7b 634#endif // wxUSE_DATEPICKCTRL
feb72429 635
74a533f7
VZ
636// ----------------------------------------------------------------------------
637// MyPanel
638// ----------------------------------------------------------------------------
639
628e155d
VZ
640MyPanel::MyPanel(wxWindow *parent)
641 : wxPanel(parent, wxID_ANY)
74a533f7 642{
628e155d
VZ
643#ifdef wxHAS_NATIVE_CALENDARCTRL
644 m_usingGeneric = false;
645#else
646 m_usingGeneric = true;
647#endif
648
4e6bceff 649 wxString date;
4693b20c 650 date.Printf(wxT("Selected date: %s"),
74a533f7 651 wxDateTime::Today().FormatISODate().c_str());
9230b621 652 m_date = new wxStaticText(this, wxID_ANY, date);
ee22a3a2
VZ
653 m_calendar = DoCreateCalendar(wxDefaultDateTime,
654 wxCAL_MONDAY_FIRST | wxCAL_SHOW_HOLIDAYS);
74a533f7 655
f9cc9706
WS
656 // adjust to vertical/horizontal display, check mostly dedicated to WinCE
657 bool horizontal = ( wxSystemSettings::GetMetric(wxSYS_SCREEN_X) > wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) );
2522d529 658 m_sizer = new wxBoxSizer( horizontal ? wxHORIZONTAL : wxVERTICAL );
4e6bceff 659
9230b621
VS
660 m_sizer->Add(m_date, 0, wxALIGN_CENTER | wxALL, 10 );
661 m_sizer->Add(m_calendar, 0, wxALIGN_CENTER | wxALIGN_LEFT);
4e6bceff 662
9230b621
VS
663 SetSizer( m_sizer );
664 m_sizer->SetSizeHints( this );
74a533f7
VZ
665}
666
667void MyPanel::OnCalendar(wxCalendarEvent& event)
668{
82c6027b
VZ
669 // clicking the same date twice unmarks it (convenient for testing)
670 static wxDateTime s_dateLast;
671 const bool mark = !s_dateLast.IsValid() || event.GetDate() != s_dateLast;
672
673 s_dateLast = event.GetDate();
674
675 m_calendar->Mark(event.GetDate().GetDay(), mark);
676 wxLogMessage(wxT("Selected (and %smarked) %s from calendar."),
677 mark ? "" : "un", s_dateLast.FormatISODate().c_str());
74a533f7
VZ
678}
679
680void MyPanel::OnCalendarChange(wxCalendarEvent& event)
681{
682 wxString s;
4693b20c 683 s.Printf(wxT("Selected date: %s"), event.GetDate().FormatISODate().c_str());
74a533f7
VZ
684
685 m_date->SetLabel(s);
628e155d 686 wxLogStatus(s);
74a533f7
VZ
687}
688
628e155d 689void MyPanel::OnCalMonthChange(wxCalendarEvent& event)
0de868d9 690{
628e155d
VZ
691 wxLogStatus(wxT("Calendar month changed to %s %d"),
692 wxDateTime::GetMonthName(event.GetDate().GetMonth()),
693 event.GetDate().GetYear());
0de868d9
VZ
694}
695
74a533f7
VZ
696void MyPanel::OnCalendarWeekDayClick(wxCalendarEvent& event)
697{
4693b20c 698 wxLogMessage(wxT("Clicked on %s"),
74a533f7
VZ
699 wxDateTime::GetWeekDayName(event.GetWeekDay()).c_str());
700}
701
232b2162
VZ
702void MyPanel::OnCalendarWeekClick(wxCalendarEvent& event)
703{
704 wxLogMessage(wxT("Clicked on week %d"), event.GetDate().GetWeekOfYear());
705}
706
ee22a3a2 707wxCalendarCtrlBase *MyPanel::DoCreateCalendar(const wxDateTime& dt, long style)
628e155d
VZ
708{
709 wxCalendarCtrlBase *calendar;
710#ifdef wxHAS_NATIVE_CALENDARCTRL
711 if ( m_usingGeneric )
712 calendar = new wxGenericCalendarCtrl(this, Calendar_CalCtrl,
ee22a3a2 713 dt,
628e155d
VZ
714 wxDefaultPosition,
715 wxDefaultSize,
716 style);
717 else
718#endif // wxHAS_NATIVE_CALENDARCTRL
719 calendar = new wxCalendarCtrl(this, Calendar_CalCtrl,
ee22a3a2 720 dt,
628e155d
VZ
721 wxDefaultPosition,
722 wxDefaultSize,
723 style);
724
ee22a3a2
VZ
725 calendar->Connect(wxEVT_RIGHT_DOWN,
726 wxMouseEventHandler(MyFrame::OnCalRClick),
727 NULL,
3c778901 728 ( MyFrame * )wxGetTopLevelParent(this));
ee22a3a2
VZ
729
730 return calendar;
731}
732
733void MyPanel::RecreateCalendar(long style)
734{
735 wxCalendarCtrlBase *calendar = DoCreateCalendar(m_calendar->GetDate(), style);
736
628e155d
VZ
737 m_sizer->Replace(m_calendar, calendar);
738 delete m_calendar;
739 m_calendar = calendar;
740
741 m_sizer->Layout();
742}
743
37df1f33 744void MyPanel::ToggleCalStyle(bool on, int flag)
74a533f7
VZ
745{
746 long style = m_calendar->GetWindowStyle();
747 if ( on )
37df1f33 748 style |= flag;
74a533f7 749 else
37df1f33 750 style &= ~flag;
74a533f7 751
232b2162 752 if ( flag == wxCAL_SEQUENTIAL_MONTH_SELECTION
7b0ccb8a 753 || flag == wxCAL_SHOW_WEEK_NUMBERS)
2522d529
VZ
754 {
755 // changing this style requires recreating the control
628e155d 756 RecreateCalendar(style);
2522d529
VZ
757 }
758 else // just changing the style is enough
759 {
760 m_calendar->SetWindowStyle(style);
74a533f7 761
2522d529
VZ
762 m_calendar->Refresh();
763 }
74a533f7
VZ
764}
765
74a533f7
VZ
766void MyPanel::HighlightSpecial(bool on)
767{
768 if ( on )
769 {
770 wxCalendarDateAttr
771 *attrRedCircle = new wxCalendarDateAttr(wxCAL_BORDER_ROUND, *wxRED),
772 *attrGreenSquare = new wxCalendarDateAttr(wxCAL_BORDER_SQUARE, *wxGREEN),
773 *attrHeaderLike = new wxCalendarDateAttr(*wxBLUE, *wxLIGHT_GREY);
774
775 m_calendar->SetAttr(17, attrRedCircle);
776 m_calendar->SetAttr(29, attrGreenSquare);
777 m_calendar->SetAttr(13, attrHeaderLike);
778 }
779 else // off
780 {
781 m_calendar->ResetAttr(17);
782 m_calendar->ResetAttr(29);
783 m_calendar->ResetAttr(13);
784 }
785
786 m_calendar->Refresh();
787}
605dfd91 788
a5cf7942
VZ
789// Toggle a restricted date range to the six months centered on today's date.
790void MyPanel::LimitDateRange(bool on)
791{
792 if ( on )
793 {
794 // limit the choice of date to 3 months around today
795 const wxDateSpan diff = wxDateSpan::Months(3);
796 const wxDateTime today = wxDateTime::Today();
797
798 // Set the restricted date range.
799 if ( m_calendar->SetDateRange(today - diff, today + diff) )
800 {
801 wxLogStatus("Date range limited to 3 months around today.");
7b342d55
VZ
802 wxDateTime firstValidDate;
803 wxDateTime lastValidDate;
804 if ( m_calendar->GetDateRange(&firstValidDate, &lastValidDate) )
805 {
806 wxLogMessage("First valid date: %s, last valid date: %s",
807 firstValidDate.FormatISODate(),
808 lastValidDate.FormatISODate());
809 }
810 else
811 {
812 wxLogWarning("Failed to get back the valid dates range.");
813 }
a5cf7942
VZ
814 }
815 else
816 {
817 wxLogWarning("Date range not supported.");
818 }
819 }
820 else // off
821 {
822 // Remove the date restrictions.
823 if ( m_calendar->SetDateRange() )
824 {
825 wxLogStatus("Date choice is unlimited now.");
826 }
827 else
828 {
829 wxLogWarning("Date range not supported.");
830 }
831 }
832
833 m_calendar->Refresh();
834}
628e155d 835
feb72429
VZ
836// ----------------------------------------------------------------------------
837// MyDialog
838// ----------------------------------------------------------------------------
839
ac78ab7b 840#if wxUSE_DATEPICKCTRL
feb72429 841
d1fd3c26 842MyDialog::MyDialog(wxWindow *parent, const wxDateTime& dt, int dtpStyle)
9a83f860 843 : wxDialog(parent, wxID_ANY, wxString(wxT("Calendar: Choose a date")))
feb72429
VZ
844{
845 wxStdDialogButtonSizer *sizerBtns = new wxStdDialogButtonSizer;
846 sizerBtns->AddButton(new wxButton(this, wxID_OK));
847 sizerBtns->AddButton(new wxButton(this, wxID_CANCEL));
718903fe 848 sizerBtns->Realize();
feb72429
VZ
849
850 wxSizer *sizerText = new wxBoxSizer(wxHORIZONTAL);
9a83f860 851 sizerText->Add(new wxStaticText(this, wxID_ANY, wxT("Date in ISO format: ")),
b7e542be 852 wxSizerFlags().Border().Align(wxALIGN_CENTRE_VERTICAL));
a7c58211 853 m_text = new wxTextCtrl(this, wxID_ANY);
b7e542be
VZ
854 sizerText->Add(m_text, wxSizerFlags().
855 Expand().Border().Align(wxALIGN_CENTRE_VERTICAL));
feb72429
VZ
856
857 wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
858 sizerTop->Add(new wxStaticText
859 (
a7c58211 860 this, wxID_ANY,
9a83f860 861 wxT("Enter your birthday date (not before 20th century):")
feb72429
VZ
862 ),
863 wxSizerFlags().Border());
864
7ff2dfba
VZ
865#if wxUSE_DATEPICKCTRL_GENERIC
866 wxFrame *frame = (wxFrame *)wxGetTopLevelParent(parent);
867 if ( frame && frame->GetMenuBar()->IsChecked(Calendar_DatePicker_Generic) )
a7c58211 868 m_datePicker = new wxDatePickerCtrlGeneric(this, wxID_ANY, dt,
7ff2dfba
VZ
869 wxDefaultPosition,
870 wxDefaultSize,
871 dtpStyle);
872 else
873#endif // wxUSE_DATEPICKCTRL_GENERIC
a7c58211 874 m_datePicker = new wxDatePickerCtrl(this, wxID_ANY, dt,
d1fd3c26
VZ
875 wxDefaultPosition, wxDefaultSize,
876 dtpStyle);
feb72429
VZ
877 m_datePicker->SetRange(wxDateTime(1, wxDateTime::Jan, 1900),
878 wxDefaultDateTime);
879 sizerTop->Add(m_datePicker, wxSizerFlags().Expand().Border());
880
881 sizerTop->AddStretchSpacer(1);
882 sizerTop->Add(sizerText);
883
884 sizerTop->Add(sizerBtns, wxSizerFlags().Centre().Border());
885
886 SetSizerAndFit(sizerTop);
887 Layout();
888}
889
890void MyDialog::OnDateChange(wxDateEvent& event)
891{
b7e542be 892 const wxDateTime dt = event.GetDate();
404e855d 893 if ( dt.IsValid() )
a7c58211
WS
894 m_text->SetValue(dt.FormatISODate());
895 else
896 m_text->SetValue(wxEmptyString);
feb72429
VZ
897}
898
ac78ab7b 899#endif // wxUSE_DATEPICKCTRL