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