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