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