Document domain parameter of wxTranslations::GetTranslatedString().
[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 // Copyright: (c) Vadim Zeitlin
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
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
26 // for all others, include the necessary headers
27 #ifndef WX_PRECOMP
28 #include "wx/app.h"
29 #include "wx/log.h"
30 #include "wx/frame.h"
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"
36 #include "wx/icon.h"
37 #include "wx/button.h"
38 #include "wx/sizer.h"
39 #include "wx/textctrl.h"
40 #include "wx/settings.h"
41 #endif
42
43 #include "wx/calctrl.h"
44 #include "wx/splitter.h"
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
52
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
60 #include "../sample.xpm"
61
62 #ifdef wxHAS_NATIVE_CALENDARCTRL
63 #include "wx/generic/calctrlg.h"
64 #endif
65
66 // ----------------------------------------------------------------------------
67 // private classes
68 // ----------------------------------------------------------------------------
69
70 // Define a new application type, each program should derive a class from wxApp
71 class MyApp : public wxApp
72 {
73 public:
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
83 class MyPanel : public wxPanel
84 {
85 public:
86 MyPanel(wxWindow *parent);
87
88 void OnCalendar(wxCalendarEvent& event);
89 void OnCalendarWeekDayClick(wxCalendarEvent& event);
90 void OnCalendarWeekClick(wxCalendarEvent& event);
91 void OnCalendarChange(wxCalendarEvent& event);
92 void OnCalMonthChange(wxCalendarEvent& event);
93
94 wxCalendarCtrlBase *GetCal() const { return m_calendar; }
95
96 // turn on/off the specified style bit on the calendar control
97 void ToggleCalStyle(bool on, int style);
98
99 bool IsUsingGeneric() const { return m_usingGeneric; }
100 void ToggleUseGeneric()
101 {
102 m_usingGeneric = !m_usingGeneric;
103 RecreateCalendar(m_calendar->GetWindowStyle());
104 }
105
106 void HighlightSpecial(bool on);
107 void LimitDateRange(bool on);
108
109 wxDateTime GetDate() const { return m_calendar->GetDate(); }
110 void SetDate(const wxDateTime& dt) { m_calendar->SetDate(dt); }
111
112 private:
113 wxCalendarCtrlBase *DoCreateCalendar(const wxDateTime& dt, long style);
114
115 void RecreateCalendar(long style);
116
117 wxCalendarCtrlBase *m_calendar;
118 wxStaticText *m_date;
119 wxSizer *m_sizer;
120
121 bool m_usingGeneric;
122
123
124 DECLARE_EVENT_TABLE()
125 };
126
127 // Define a new frame type: this is going to be our main frame
128 class MyFrame : public wxFrame
129 {
130 public:
131 // ctor(s)
132 MyFrame(const wxString& title, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize);
133
134 // event handlers (these functions should _not_ be virtual)
135 void OnAbout(wxCommandEvent& event);
136 void OnClearLog(wxCommandEvent& event);
137 void OnQuit(wxCommandEvent& event);
138
139 #if wxUSE_DATEPICKCTRL
140 void OnAskDate(wxCommandEvent& event);
141
142 void OnUpdateUIStartWithNone(wxUpdateUIEvent& event);
143 #endif // wxUSE_DATEPICKCTRL
144
145 #if wxUSE_TIMEPICKCTRL
146 void OnAskTime(wxCommandEvent& event);
147 #endif // wxUSE_TIMEPICKCTRL
148
149 #ifdef wxHAS_NATIVE_CALENDARCTRL
150 void OnCalGeneric(wxCommandEvent& WXUNUSED(event))
151 {
152 m_panel->ToggleUseGeneric();
153 }
154 #endif // wxHAS_NATIVE_CALENDARCTRL
155
156 void OnCalMonday(wxCommandEvent& event);
157 void OnCalHolidays(wxCommandEvent& event);
158 void OnCalSpecial(wxCommandEvent& event);
159
160 void OnCalAllowMonth(wxCommandEvent& event);
161 void OnCalLimitDates(wxCommandEvent& event);
162 void OnCalSeqMonth(wxCommandEvent& event);
163 void OnCalShowSurroundingWeeks(wxCommandEvent& event);
164 void OnCalShowWeekNumbers(wxCommandEvent& event);
165
166 void OnSetDate(wxCommandEvent& event);
167 void OnToday(wxCommandEvent& event);
168 void OnBeginDST(wxCommandEvent& event);
169
170 void OnCalToggleResizable(wxCommandEvent& event);
171
172 void OnUpdateUIGenericOnly(wxUpdateUIEvent& event)
173 {
174 event.Enable(m_panel->IsUsingGeneric());
175 }
176
177 void OnCalRClick(wxMouseEvent& event);
178
179 private:
180 MyPanel *m_panel;
181 wxTextCtrl *m_logWindow;
182
183 // any class wishing to process wxWidgets events must use this macro
184 DECLARE_EVENT_TABLE()
185 };
186
187 #if wxUSE_DATEPICKCTRL
188
189 // Define a simple modal dialog which asks the user for a date
190 class MyDateDialog : public wxDialog
191 {
192 public:
193 MyDateDialog(wxWindow *parent, const wxDateTime& dt, int dtpStyle);
194
195 wxDateTime GetDate() const { return m_datePicker->GetValue(); }
196
197 private:
198 void OnDateChange(wxDateEvent& event);
199
200
201 wxDatePickerCtrlBase *m_datePicker;
202 wxStaticText *m_dateText;
203
204
205 DECLARE_EVENT_TABLE()
206 };
207
208 #endif // wxUSE_DATEPICKCTRL
209
210 #if wxUSE_TIMEPICKCTRL
211
212 // Another simple dialog, this one asking for time.
213 class MyTimeDialog : public wxDialog
214 {
215 public:
216 MyTimeDialog(wxWindow* parent);
217
218 wxDateTime GetTime() const { return m_timePicker->GetValue(); }
219
220 private:
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
231 // ----------------------------------------------------------------------------
232 // constants
233 // ----------------------------------------------------------------------------
234
235 // IDs for the controls and the menu commands
236 enum
237 {
238 // menu items
239 Calendar_File_About = wxID_ABOUT,
240 Calendar_File_ClearLog = wxID_CLEAR,
241 Calendar_File_Quit = wxID_EXIT,
242 Calendar_Cal_Generic = 200,
243 Calendar_Cal_Monday,
244 Calendar_Cal_Holidays,
245 Calendar_Cal_Special,
246 Calendar_Cal_Month,
247 Calendar_Cal_LimitDates,
248 Calendar_Cal_SeqMonth,
249 Calendar_Cal_SurroundWeeks,
250 Calendar_Cal_WeekNumbers,
251 Calendar_Cal_SetDate,
252 Calendar_Cal_Today,
253 Calendar_Cal_BeginDST,
254 Calendar_Cal_Resizable,
255 #if wxUSE_DATEPICKCTRL
256 Calendar_DatePicker_AskDate = 300,
257 Calendar_DatePicker_ShowCentury,
258 Calendar_DatePicker_DropDown,
259 Calendar_DatePicker_AllowNone,
260 Calendar_DatePicker_StartWithNone,
261 #if wxUSE_DATEPICKCTRL_GENERIC
262 Calendar_DatePicker_Generic,
263 #endif // wxUSE_DATEPICKCTRL_GENERIC
264 #endif // wxUSE_DATEPICKCTRL
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
271 Calendar_CalCtrl = 1000
272 };
273
274 // ----------------------------------------------------------------------------
275 // event tables and other macros for wxWidgets
276 // ----------------------------------------------------------------------------
277
278 // the event tables connect the wxWidgets events with the functions (event
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.
281 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
282 EVT_MENU(Calendar_File_About, MyFrame::OnAbout)
283 EVT_MENU(Calendar_File_ClearLog, MyFrame::OnClearLog)
284 EVT_MENU(Calendar_File_Quit, MyFrame::OnQuit)
285
286 #if wxUSE_DATEPICKCTRL
287 EVT_MENU(Calendar_DatePicker_AskDate, MyFrame::OnAskDate)
288
289 EVT_UPDATE_UI(Calendar_DatePicker_StartWithNone,
290 MyFrame::OnUpdateUIStartWithNone)
291 #endif // wxUSE_DATEPICKCTRL
292
293 #if wxUSE_TIMEPICKCTRL
294 EVT_MENU(Calendar_TimePicker_AskTime, MyFrame::OnAskTime)
295 #endif // wxUSE_TIMEPICKCTRL
296
297 #ifdef wxHAS_NATIVE_CALENDARCTRL
298 EVT_MENU(Calendar_Cal_Generic, MyFrame::OnCalGeneric)
299 #endif // wxHAS_NATIVE_CALENDARCTRL
300
301 EVT_MENU(Calendar_Cal_Monday, MyFrame::OnCalMonday)
302 EVT_MENU(Calendar_Cal_Holidays, MyFrame::OnCalHolidays)
303 EVT_MENU(Calendar_Cal_Special, MyFrame::OnCalSpecial)
304
305 EVT_MENU(Calendar_Cal_Month, MyFrame::OnCalAllowMonth)
306
307 EVT_MENU(Calendar_Cal_LimitDates, MyFrame::OnCalLimitDates)
308
309 EVT_MENU(Calendar_Cal_SeqMonth, MyFrame::OnCalSeqMonth)
310 EVT_MENU(Calendar_Cal_SurroundWeeks, MyFrame::OnCalShowSurroundingWeeks)
311 EVT_MENU(Calendar_Cal_WeekNumbers, MyFrame::OnCalShowWeekNumbers)
312
313 EVT_MENU(Calendar_Cal_SetDate, MyFrame::OnSetDate)
314 EVT_MENU(Calendar_Cal_Today, MyFrame::OnToday)
315 EVT_MENU(Calendar_Cal_BeginDST, MyFrame::OnBeginDST)
316
317 EVT_MENU(Calendar_Cal_Resizable, MyFrame::OnCalToggleResizable)
318
319
320 EVT_UPDATE_UI(Calendar_Cal_SeqMonth, MyFrame::OnUpdateUIGenericOnly)
321 #ifdef __WXGTK20__
322 EVT_UPDATE_UI(Calendar_Cal_Monday, MyFrame::OnUpdateUIGenericOnly)
323 EVT_UPDATE_UI(Calendar_Cal_Holidays, MyFrame::OnUpdateUIGenericOnly)
324 #endif
325 EVT_UPDATE_UI(Calendar_Cal_Special, MyFrame::OnUpdateUIGenericOnly)
326 EVT_UPDATE_UI(Calendar_Cal_SurroundWeeks, MyFrame::OnUpdateUIGenericOnly)
327 END_EVENT_TABLE()
328
329 BEGIN_EVENT_TABLE(MyPanel, wxPanel)
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)
333 EVT_CALENDAR_WEEKDAY_CLICKED(Calendar_CalCtrl, MyPanel::OnCalendarWeekDayClick)
334 EVT_CALENDAR_WEEK_CLICKED(Calendar_CalCtrl, MyPanel::OnCalendarWeekClick)
335 END_EVENT_TABLE()
336
337 // Create a new application object: this macro will allow wxWidgets to create
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)
342 IMPLEMENT_APP(MyApp)
343
344 // ============================================================================
345 // implementation
346 // ============================================================================
347
348 // ----------------------------------------------------------------------------
349 // the application class
350 // ----------------------------------------------------------------------------
351
352 // `Main program' equivalent: the program execution "starts" here
353 bool MyApp::OnInit()
354 {
355 if ( !wxApp::OnInit() )
356 return false;
357
358 // Create the main application window
359 MyFrame *frame = new MyFrame(wxT("Calendar wxWidgets sample")
360 #ifndef __WXWINCE__
361 ,wxPoint(50, 50), wxSize(450, 340)
362 #endif
363 );
364
365 frame->Show(true);
366
367 // success: wxApp::OnRun() will be called which will enter the main message
368 // loop and the application will run. If we returned false here, the
369 // application would exit immediately.
370 return true;
371 }
372
373 // ----------------------------------------------------------------------------
374 // main frame
375 // ----------------------------------------------------------------------------
376
377 // frame constructor
378 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
379 : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size)
380 {
381 // set the frame icon
382 SetIcon(wxICON(sample));
383
384 // create a menu bar
385 wxMenuBar *menuBar = new wxMenuBar;
386
387 wxMenu *menuFile = new wxMenu;
388 menuFile->Append(Calendar_File_About, wxT("&About\tCtrl-A"), wxT("Show about dialog"));
389 menuFile->AppendSeparator();
390 menuFile->Append(Calendar_File_ClearLog, wxT("&Clear log\tCtrl-L"));
391 menuFile->AppendSeparator();
392 menuFile->Append(Calendar_File_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
393 menuBar->Append(menuFile, wxT("&File"));
394
395 wxMenu *menuCal = new wxMenu;
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
401 menuCal->Append(Calendar_Cal_Monday,
402 wxT("Monday &first weekday\tCtrl-F"),
403 wxT("Toggle between Mon and Sun as the first week day"),
404 true);
405 menuCal->Append(Calendar_Cal_Holidays, wxT("Show &holidays\tCtrl-H"),
406 wxT("Toggle highlighting the holidays"),
407 true);
408 menuCal->Append(Calendar_Cal_Special, wxT("Highlight &special dates\tCtrl-S"),
409 wxT("Test custom highlighting"),
410 true);
411 menuCal->Append(Calendar_Cal_SurroundWeeks,
412 wxT("Show s&urrounding weeks\tCtrl-W"),
413 wxT("Show the neighbouring weeks in the prev/next month"),
414 true);
415 menuCal->Append(Calendar_Cal_WeekNumbers,
416 wxT("Show &week numbers"),
417 wxT("Toggle week numbers"),
418 true);
419 menuCal->AppendSeparator();
420 menuCal->Append(Calendar_Cal_SeqMonth,
421 wxT("Toggle month selector st&yle\tCtrl-Y"),
422 wxT("Use another style for the calendar controls"),
423 true);
424 menuCal->Append(Calendar_Cal_Month, wxT("&Month can be changed\tCtrl-M"),
425 wxT("Allow changing the month in the calendar"),
426 true);
427 menuCal->AppendCheckItem(Calendar_Cal_LimitDates, wxT("Toggle date ra&nge\tCtrl-N"),
428 wxT("Limit the valid dates"));
429 menuCal->AppendSeparator();
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."));
432 menuCal->Append(Calendar_Cal_BeginDST, "Call SetDate(GetBeginDST())");
433 menuCal->AppendSeparator();
434 menuCal->AppendCheckItem(Calendar_Cal_Resizable, wxT("Make &resizable\tCtrl-R"));
435 menuBar->Append(menuCal, wxT("&Calendar"));
436
437 #if wxUSE_DATEPICKCTRL
438 wxMenu *menuDate = new wxMenu;
439 menuDate->AppendCheckItem(Calendar_DatePicker_ShowCentury,
440 wxT("Al&ways show century"));
441 menuDate->AppendCheckItem(Calendar_DatePicker_DropDown,
442 wxT("Use &drop down control"));
443 menuDate->AppendCheckItem(Calendar_DatePicker_AllowNone,
444 wxT("Allow &no date"));
445 menuDate->AppendCheckItem(Calendar_DatePicker_StartWithNone,
446 wxT("Start &with no date"));
447 #if wxUSE_DATEPICKCTRL_GENERIC
448 menuDate->AppendCheckItem(Calendar_DatePicker_Generic,
449 wxT("Use &generic version of the control"));
450 #endif // wxUSE_DATEPICKCTRL_GENERIC
451 menuDate->AppendSeparator();
452 menuDate->Append(Calendar_DatePicker_AskDate, wxT("&Choose date...\tCtrl-D"), wxT("Show dialog with wxDatePickerCtrl"));
453 menuBar->Append(menuDate, wxT("&Date picker"));
454 #endif // wxUSE_DATEPICKCTRL
455
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
467 menuBar->Check(Calendar_Cal_Monday, true);
468 menuBar->Check(Calendar_Cal_Holidays, true);
469 menuBar->Check(Calendar_Cal_Month, true);
470 menuBar->Check(Calendar_Cal_LimitDates, false);
471
472 #if wxUSE_DATEPICKCTRL
473 menuBar->Check(Calendar_DatePicker_ShowCentury, true);
474 #endif // wxUSE_DATEPICKCTRL
475
476 // ... and attach this menu bar to the frame
477 SetMenuBar(menuBar);
478
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));
489 }
490
491 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
492 {
493 // true is to force the frame to close
494 Close(true);
495 }
496
497 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
498 {
499 wxMessageBox(wxT("wxCalendarCtrl sample\n(c) 2000--2008 Vadim Zeitlin"),
500 wxT("About Calendar"), wxOK | wxICON_INFORMATION, this);
501 }
502
503 void MyFrame::OnClearLog(wxCommandEvent& WXUNUSED(event))
504 {
505 m_logWindow->Clear();
506 }
507
508 void MyFrame::OnCalMonday(wxCommandEvent& event)
509 {
510 m_panel->ToggleCalStyle(event.IsChecked(), wxCAL_MONDAY_FIRST);
511 }
512
513 void MyFrame::OnCalHolidays(wxCommandEvent& event)
514 {
515 m_panel->GetCal()->EnableHolidayDisplay(event.IsChecked());
516 }
517
518 void MyFrame::OnCalSpecial(wxCommandEvent& event)
519 {
520 m_panel->HighlightSpecial(GetMenuBar()->IsChecked(event.GetId()));
521 }
522
523 void MyFrame::OnCalLimitDates(wxCommandEvent& event)
524 {
525 m_panel->LimitDateRange(GetMenuBar()->IsChecked(event.GetId()));
526 }
527
528 void MyFrame::OnCalAllowMonth(wxCommandEvent& event)
529 {
530 m_panel->GetCal()->EnableMonthChange(event.IsChecked());
531 }
532
533 void MyFrame::OnCalSeqMonth(wxCommandEvent& event)
534 {
535 m_panel->ToggleCalStyle(event.IsChecked(),
536 wxCAL_SEQUENTIAL_MONTH_SELECTION);
537 }
538
539 void MyFrame::OnCalShowSurroundingWeeks(wxCommandEvent& event)
540 {
541 m_panel->ToggleCalStyle(event.IsChecked(), wxCAL_SHOW_SURROUNDING_WEEKS);
542 }
543
544 void MyFrame::OnCalShowWeekNumbers(wxCommandEvent& event)
545 {
546 m_panel->ToggleCalStyle(event.IsChecked(), wxCAL_SHOW_WEEK_NUMBERS);
547 }
548
549 void MyFrame::OnSetDate(wxCommandEvent &WXUNUSED(event))
550 {
551 m_panel->SetDate(wxDateTime(24, wxDateTime::Dec, 2005, 22, 00, 00));
552 }
553
554 void MyFrame::OnToday(wxCommandEvent &WXUNUSED(event))
555 {
556 m_panel->SetDate(wxDateTime::Today());
557 }
558
559 void MyFrame::OnBeginDST(wxCommandEvent &WXUNUSED(event))
560 {
561 m_panel->SetDate(wxDateTime::GetBeginDST(m_panel->GetDate().GetYear()));
562 }
563
564 void 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
582 void 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
624 #if wxUSE_DATEPICKCTRL
625
626 void 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
632 void MyFrame::OnAskDate(wxCommandEvent& WXUNUSED(event))
633 {
634 wxDateTime dt = m_panel->GetCal()->GetDate();
635
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;
641 if ( GetMenuBar()->IsChecked(Calendar_DatePicker_AllowNone) )
642 {
643 style |= wxDP_ALLOWNONE;
644
645 if ( GetMenuBar()->IsChecked(Calendar_DatePicker_StartWithNone) )
646 dt = wxDefaultDateTime;
647 }
648
649 MyDateDialog dlg(this, dt, style);
650 if ( dlg.ShowModal() == wxID_OK )
651 {
652 dt = dlg.GetDate();
653 if ( dt.IsValid() )
654 {
655 const wxDateTime today = wxDateTime::Today();
656
657 if ( dt.GetDay() == today.GetDay() &&
658 dt.GetMonth() == today.GetMonth() )
659 {
660 wxMessageBox(wxT("Happy birthday!"), wxT("Calendar Sample"));
661 }
662
663 m_panel->SetDate(dt);
664
665 wxLogStatus(wxT("Changed the date to your input"));
666 }
667 else
668 {
669 wxLogStatus(wxT("No date entered"));
670 }
671 }
672 }
673
674 #endif // wxUSE_DATEPICKCTRL
675
676 #if wxUSE_TIMEPICKCTRL
677
678 void 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
689 // ----------------------------------------------------------------------------
690 // MyPanel
691 // ----------------------------------------------------------------------------
692
693 MyPanel::MyPanel(wxWindow *parent)
694 : wxPanel(parent, wxID_ANY)
695 {
696 #ifdef wxHAS_NATIVE_CALENDARCTRL
697 m_usingGeneric = false;
698 #else
699 m_usingGeneric = true;
700 #endif
701
702 wxString date;
703 date.Printf(wxT("Selected date: %s"),
704 wxDateTime::Today().FormatISODate().c_str());
705 m_date = new wxStaticText(this, wxID_ANY, date);
706 m_calendar = DoCreateCalendar(wxDefaultDateTime,
707 wxCAL_MONDAY_FIRST | wxCAL_SHOW_HOLIDAYS);
708
709 // adjust to vertical/horizontal display, check mostly dedicated to WinCE
710 bool horizontal = ( wxSystemSettings::GetMetric(wxSYS_SCREEN_X) > wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) );
711 m_sizer = new wxBoxSizer( horizontal ? wxHORIZONTAL : wxVERTICAL );
712
713 m_sizer->Add(m_date, 0, wxALIGN_CENTER | wxALL, 10 );
714 m_sizer->Add(m_calendar, 0, wxALIGN_CENTER | wxALIGN_LEFT);
715
716 SetSizer( m_sizer );
717 m_sizer->SetSizeHints( this );
718 }
719
720 void MyPanel::OnCalendar(wxCalendarEvent& event)
721 {
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());
731 }
732
733 void MyPanel::OnCalendarChange(wxCalendarEvent& event)
734 {
735 wxString s;
736 s.Printf(wxT("Selected date: %s"), event.GetDate().FormatISODate().c_str());
737
738 m_date->SetLabel(s);
739 wxLogStatus(s);
740 }
741
742 void MyPanel::OnCalMonthChange(wxCalendarEvent& event)
743 {
744 wxLogStatus(wxT("Calendar month changed to %s %d"),
745 wxDateTime::GetMonthName(event.GetDate().GetMonth()),
746 event.GetDate().GetYear());
747 }
748
749 void MyPanel::OnCalendarWeekDayClick(wxCalendarEvent& event)
750 {
751 wxLogMessage(wxT("Clicked on %s"),
752 wxDateTime::GetWeekDayName(event.GetWeekDay()).c_str());
753 }
754
755 void MyPanel::OnCalendarWeekClick(wxCalendarEvent& event)
756 {
757 wxLogMessage(wxT("Clicked on week %d"), event.GetDate().GetWeekOfYear());
758 }
759
760 wxCalendarCtrlBase *MyPanel::DoCreateCalendar(const wxDateTime& dt, long style)
761 {
762 wxCalendarCtrlBase *calendar;
763 #ifdef wxHAS_NATIVE_CALENDARCTRL
764 if ( m_usingGeneric )
765 calendar = new wxGenericCalendarCtrl(this, Calendar_CalCtrl,
766 dt,
767 wxDefaultPosition,
768 wxDefaultSize,
769 style);
770 else
771 #endif // wxHAS_NATIVE_CALENDARCTRL
772 calendar = new wxCalendarCtrl(this, Calendar_CalCtrl,
773 dt,
774 wxDefaultPosition,
775 wxDefaultSize,
776 style);
777
778 calendar->Connect(wxEVT_RIGHT_DOWN,
779 wxMouseEventHandler(MyFrame::OnCalRClick),
780 NULL,
781 ( MyFrame * )wxGetTopLevelParent(this));
782
783 return calendar;
784 }
785
786 void MyPanel::RecreateCalendar(long style)
787 {
788 wxCalendarCtrlBase *calendar = DoCreateCalendar(m_calendar->GetDate(), style);
789
790 m_sizer->Replace(m_calendar, calendar);
791 delete m_calendar;
792 m_calendar = calendar;
793
794 m_sizer->Layout();
795 }
796
797 void MyPanel::ToggleCalStyle(bool on, int flag)
798 {
799 long style = m_calendar->GetWindowStyle();
800 if ( on )
801 style |= flag;
802 else
803 style &= ~flag;
804
805 if ( flag == wxCAL_SEQUENTIAL_MONTH_SELECTION
806 || flag == wxCAL_SHOW_WEEK_NUMBERS)
807 {
808 // changing this style requires recreating the control
809 RecreateCalendar(style);
810 }
811 else // just changing the style is enough
812 {
813 m_calendar->SetWindowStyle(style);
814
815 m_calendar->Refresh();
816 }
817 }
818
819 void 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 }
841
842 // Toggle a restricted date range to the six months centered on today's date.
843 void 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.");
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 }
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 }
888
889 // ----------------------------------------------------------------------------
890 // MyDateDialog
891 // ----------------------------------------------------------------------------
892
893 #if wxUSE_DATEPICKCTRL
894
895 BEGIN_EVENT_TABLE(MyDateDialog, wxDialog)
896 EVT_DATE_CHANGED(wxID_ANY, MyDateDialog::OnDateChange)
897 END_EVENT_TABLE()
898
899 MyDateDialog::MyDateDialog(wxWindow *parent, const wxDateTime& dt, int dtpStyle)
900 : wxDialog(parent, wxID_ANY, wxString(wxT("Calendar: Choose a date")))
901 {
902 #if wxUSE_DATEPICKCTRL_GENERIC
903 wxFrame *frame = (wxFrame *)wxGetTopLevelParent(parent);
904 if ( frame && frame->GetMenuBar()->IsChecked(Calendar_DatePicker_Generic) )
905 m_datePicker = new wxDatePickerCtrlGeneric(this, wxID_ANY, dt,
906 wxDefaultPosition,
907 wxDefaultSize,
908 dtpStyle);
909 else
910 #endif // wxUSE_DATEPICKCTRL_GENERIC
911 m_datePicker = new wxDatePickerCtrl(this, wxID_ANY, dt,
912 wxDefaultPosition, wxDefaultSize,
913 dtpStyle);
914 m_datePicker->SetRange(wxDateTime(1, wxDateTime::Jan, 1900),
915 wxDefaultDateTime);
916 m_dateText = new wxStaticText(this, wxID_ANY,
917 dt.IsValid() ? dt.FormatISODate()
918 : wxString());
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);
924
925 sizerMain->Add(new wxStaticText(this, wxID_ANY, "Date in ISO format:"),
926 flags);
927 sizerMain->Add(m_dateText, flags);
928
929 wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
930 sizerTop->Add(sizerMain, flags);
931 sizerTop->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), flags);
932
933 SetSizerAndFit(sizerTop);
934 }
935
936 void MyDateDialog::OnDateChange(wxDateEvent& event)
937 {
938 const wxDateTime dt = event.GetDate();
939 if ( dt.IsValid() )
940 m_dateText->SetLabel(dt.FormatISODate());
941 else
942 m_dateText->SetLabel(wxEmptyString);
943 }
944
945 #endif // wxUSE_DATEPICKCTRL
946
947 // ----------------------------------------------------------------------------
948 // MyTimeDialog
949 // ----------------------------------------------------------------------------
950
951 #if wxUSE_TIMEPICKCTRL
952
953 BEGIN_EVENT_TABLE(MyTimeDialog, wxDialog)
954 EVT_TIME_CHANGED(wxID_ANY, MyTimeDialog::OnTimeChange)
955 END_EVENT_TABLE()
956
957 MyTimeDialog::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);
967 m_timeText = new wxStaticText(this, wxID_ANY,
968 m_timePicker->GetValue().FormatISOTime());
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
979 wxSizer* sizerTop = new wxBoxSizer(wxVERTICAL);
980 sizerTop->Add(sizerMain, flags);
981 sizerTop->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), flags);
982
983 SetSizerAndFit(sizerTop);
984 }
985
986 void MyTimeDialog::OnTimeChange(wxDateEvent& event)
987 {
988 m_timeText->SetLabel(event.GetDate().FormatISOTime());
989 }
990
991 #endif // wxUSE_TIMEPICKCTRL