/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/generic/datectlg.cpp
ViewVC logotype

Contents of /trunk/3rdparty/wxWidgets/src/generic/datectlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 1 month ago) by william
File size: 15044 byte(s)
committing r3113 initial commit again...
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/datectlg.cpp
3 // Purpose: generic wxDatePickerCtrlGeneric implementation
4 // Author: Andreas Pflug
5 // Modified by:
6 // Created: 2005-01-19
7 // RCS-ID: $Id: datectlg.cpp 54407 2008-06-28 18:58:07Z VZ $
8 // Copyright: (c) 2005 Andreas Pflug <pgadmin@pse-consulting.de>
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #if wxUSE_DATEPICKCTRL
27
28 #include "wx/datectrl.h"
29
30 // use this version if we're explicitly requested to do it or if it's the only
31 // one we have
32 #if !defined(wxHAS_NATIVE_DATEPICKCTRL) || \
33 (defined(wxUSE_DATEPICKCTRL_GENERIC) && wxUSE_DATEPICKCTRL_GENERIC)
34
35 #ifndef WX_PRECOMP
36 #include "wx/dialog.h"
37 #include "wx/dcmemory.h"
38 #include "wx/panel.h"
39 #include "wx/textctrl.h"
40 #include "wx/valtext.h"
41 #endif
42
43 #ifdef wxHAS_NATIVE_DATEPICKCTRL
44 // this header is not included from wx/datectrl.h if we have a native
45 // version, but we do need it here
46 #include "wx/generic/datectrl.h"
47 #else
48 // we need to define _WX_DEFINE_DATE_EVENTS_ before including wx/dateevt.h to
49 // define the event types we use if we're the only date picker control version
50 // being compiled -- otherwise it's defined in the native version implementation
51 #define _WX_DEFINE_DATE_EVENTS_
52 #endif
53
54 #include "wx/dateevt.h"
55
56 #include "wx/calctrl.h"
57 #include "wx/combo.h"
58
59 // ----------------------------------------------------------------------------
60 // constants
61 // ----------------------------------------------------------------------------
62
63 #if defined(__WXMSW__)
64 #define CALBORDER 0
65 #else
66 #define CALBORDER 4
67 #endif
68
69 // ----------------------------------------------------------------------------
70 // global variables
71 // ----------------------------------------------------------------------------
72
73
74 // ----------------------------------------------------------------------------
75 // local classes
76 // ----------------------------------------------------------------------------
77
78 class wxCalendarComboPopup : public wxCalendarCtrl,
79 public wxComboPopup
80 {
81 public:
82
83 wxCalendarComboPopup() : wxCalendarCtrl(),
84 wxComboPopup()
85 {
86 }
87
88 virtual void Init()
89 {
90 }
91
92 // NB: Don't create lazily since it didn't work that way before
93 // wxComboCtrl was used, and changing behaviour would almost
94 // certainly introduce new bugs.
95 virtual bool Create(wxWindow* parent)
96 {
97 if ( !wxCalendarCtrl::Create(parent, wxID_ANY, wxDefaultDateTime,
98 wxPoint(0, 0), wxDefaultSize,
99 wxCAL_SHOW_HOLIDAYS | wxBORDER_SUNKEN) )
100 return false;
101
102 wxWindow *yearControl = wxCalendarCtrl::GetYearControl();
103
104 wxClientDC dc(yearControl);
105 dc.SetFont(yearControl->GetFont());
106 wxCoord width, dummy;
107 dc.GetTextExtent(wxT("2000"), &width, &dummy);
108 width += ConvertDialogToPixels(wxSize(20, 0)).x;
109
110 wxSize calSize = wxCalendarCtrl::GetBestSize();
111 wxSize yearSize = yearControl->GetSize();
112 yearSize.x = width;
113
114 wxPoint yearPosition = yearControl->GetPosition();
115
116 SetFormat(wxT("%x"));
117
118 width = yearPosition.x + yearSize.x+2+CALBORDER/2;
119 if (width < calSize.x-4)
120 width = calSize.x-4;
121
122 int calPos = (width-calSize.x)/2;
123 if (calPos == -1)
124 {
125 calPos = 0;
126 width += 2;
127 }
128 wxCalendarCtrl::SetSize(calPos, 0, calSize.x, calSize.y);
129 yearControl->SetSize(width-yearSize.x-CALBORDER/2, yearPosition.y,
130 yearSize.x, yearSize.y);
131 wxCalendarCtrl::GetMonthControl()->Move(0, 0);
132
133 m_useSize.x = width+CALBORDER/2;
134 m_useSize.y = calSize.y-2+CALBORDER;
135
136 wxWindow* tx = m_combo->GetTextCtrl();
137 if ( !tx )
138 tx = m_combo;
139
140 tx->Connect(wxEVT_KILL_FOCUS,
141 wxFocusEventHandler(wxCalendarComboPopup::OnKillTextFocus),
142 NULL, this);
143
144 return true;
145 }
146
147 virtual wxSize GetAdjustedSize(int WXUNUSED(minWidth),
148 int WXUNUSED(prefHeight),
149 int WXUNUSED(maxHeight))
150 {
151 return m_useSize;
152 }
153
154 virtual wxWindow *GetControl() { return this; }
155
156 void SetDateValue(const wxDateTime& date)
157 {
158 if ( date.IsValid() )
159 {
160 m_combo->SetText(date.Format(m_format));
161 SetDate(date);
162 }
163 else // invalid date
164 {
165 wxASSERT_MSG( HasDPFlag(wxDP_ALLOWNONE),
166 _T("this control must have a valid date") );
167
168 m_combo->SetText(wxEmptyString);
169 }
170 }
171
172 bool IsTextEmpty() const
173 {
174 return m_combo->GetTextCtrl()->IsEmpty();
175 }
176
177 bool ParseDateTime(const wxString& s, wxDateTime* pDt)
178 {
179 wxASSERT(pDt);
180
181 if ( !s.empty() )
182 {
183 pDt->ParseFormat(s, m_format);
184 if ( !pDt->IsValid() )
185 return false;
186 }
187
188 return true;
189 }
190
191 void SendDateEvent(const wxDateTime& dt)
192 {
193 //
194 // Sends both wxCalendarEvent and wxDateEvent
195 wxWindow* datePicker = m_combo->GetParent();
196
197 wxCalendarEvent cev((wxCalendarCtrl*) this, wxEVT_CALENDAR_SEL_CHANGED);
198 cev.SetEventObject(datePicker);
199 cev.SetId(datePicker->GetId());
200 cev.SetDate(dt);
201 datePicker->GetEventHandler()->ProcessEvent(cev);
202
203 wxDateEvent event(datePicker, dt, wxEVT_DATE_CHANGED);
204 datePicker->GetEventHandler()->ProcessEvent(event);
205 }
206
207 private:
208
209 void OnCalKey(wxKeyEvent & ev)
210 {
211 if (ev.GetKeyCode() == WXK_ESCAPE && !ev.HasModifiers())
212 Dismiss();
213 else
214 ev.Skip();
215 }
216
217 void OnSelChange(wxCalendarEvent &ev)
218 {
219 m_combo->SetText(GetDate().Format(m_format));
220
221 if ( ev.GetEventType() == wxEVT_CALENDAR_DOUBLECLICKED )
222 {
223 Dismiss();
224 }
225
226 SendDateEvent(GetDate());
227 }
228
229 void OnKillTextFocus(wxFocusEvent &ev)
230 {
231 ev.Skip();
232
233 const wxDateTime& dtOld = GetDate();
234
235 wxDateTime dt;
236 wxString value = m_combo->GetValue();
237 if ( !ParseDateTime(value, &dt) )
238 {
239 if ( !HasDPFlag(wxDP_ALLOWNONE) )
240 dt = dtOld;
241 }
242
243 m_combo->SetText(GetStringValueFor(dt));
244
245 if ( !dt.IsValid() && HasDPFlag(wxDP_ALLOWNONE) )
246 return;
247
248 // notify that we had to change the date after validation
249 if ( (dt.IsValid() && (!dtOld.IsValid() || dt != dtOld)) ||
250 (!dt.IsValid() && dtOld.IsValid()) )
251 {
252 SetDate(dt);
253 SendDateEvent(dt);
254 }
255 }
256
257 bool HasDPFlag(int flag)
258 {
259 return m_combo->GetParent()->HasFlag(flag);
260 }
261
262 bool SetFormat(const wxChar *fmt)
263 {
264 m_format.clear();
265
266 wxDateTime dt;
267 dt.ParseFormat(wxT("2003-10-13"), wxT("%Y-%m-%d"));
268 wxString str(dt.Format(fmt));
269
270 const wxChar *p = str.c_str();
271 while ( *p )
272 {
273 int n=wxAtoi(p);
274 if (n == dt.GetDay())
275 {
276 m_format.Append(wxT("%d"));
277 p += 2;
278 }
279 else if (n == (int)dt.GetMonth()+1)
280 {
281 m_format.Append(wxT("%m"));
282 p += 2;
283 }
284 else if (n == dt.GetYear())
285 {
286 m_format.Append(wxT("%Y"));
287 p += 4;
288 }
289 else if (n == (dt.GetYear() % 100))
290 {
291 if ( HasDPFlag(wxDP_SHOWCENTURY) )
292 m_format.Append(wxT("%Y"));
293 else
294 m_format.Append(wxT("%y"));
295 p += 2;
296 }
297 else
298 m_format.Append(*p++);
299 }
300
301 if ( m_combo )
302 {
303 wxArrayString allowedChars;
304 for ( wxChar c = _T('0'); c <= _T('9'); c++ )
305 allowedChars.Add(wxString(c, 1));
306
307 const wxChar *p2 = m_format.c_str();
308 while ( *p2 )
309 {
310 if ( *p2 == '%')
311 p2 += 2;
312 else
313 allowedChars.Add(wxString(*p2++, 1));
314 }
315
316 #if wxUSE_VALIDATORS
317 wxTextValidator tv(wxFILTER_INCLUDE_CHAR_LIST);
318 tv.SetIncludes(allowedChars);
319 m_combo->SetValidator(tv);
320 #endif
321
322 if ( GetDate().IsValid() )
323 m_combo->SetText(GetDate().Format(m_format));
324 }
325
326 return true;
327 }
328
329 virtual void SetStringValue(const wxString& s)
330 {
331 wxDateTime dt;
332 if ( !s.empty() && ParseDateTime(s, &dt) )
333 SetDate(dt);
334 //else: keep the old value
335 }
336
337 virtual wxString GetStringValue() const
338 {
339 return GetStringValueFor(GetDate());
340 }
341
342 private:
343 // returns either the given date representation using the current format or
344 // an empty string if it's invalid
345 wxString GetStringValueFor(const wxDateTime& dt) const
346 {
347 wxString val;
348 if ( dt.IsValid() )
349 val = dt.Format(m_format);
350
351 return val;
352 }
353
354 wxSize m_useSize;
355 wxString m_format;
356
357 DECLARE_EVENT_TABLE()
358 };
359
360
361 BEGIN_EVENT_TABLE(wxCalendarComboPopup, wxCalendarCtrl)
362 EVT_KEY_DOWN(wxCalendarComboPopup::OnCalKey)
363 EVT_CALENDAR_SEL_CHANGED(wxID_ANY, wxCalendarComboPopup::OnSelChange)
364 EVT_CALENDAR_DAY(wxID_ANY, wxCalendarComboPopup::OnSelChange)
365 EVT_CALENDAR_MONTH(wxID_ANY, wxCalendarComboPopup::OnSelChange)
366 EVT_CALENDAR_YEAR(wxID_ANY, wxCalendarComboPopup::OnSelChange)
367 EVT_CALENDAR(wxID_ANY, wxCalendarComboPopup::OnSelChange)
368 END_EVENT_TABLE()
369
370
371 // ============================================================================
372 // wxDatePickerCtrlGeneric implementation
373 // ============================================================================
374
375 BEGIN_EVENT_TABLE(wxDatePickerCtrlGeneric, wxDatePickerCtrlBase)
376 EVT_TEXT(wxID_ANY, wxDatePickerCtrlGeneric::OnText)
377 EVT_SIZE(wxDatePickerCtrlGeneric::OnSize)
378 EVT_SET_FOCUS(wxDatePickerCtrlGeneric::OnFocus)
379 END_EVENT_TABLE()
380
381 #ifndef wxHAS_NATIVE_DATEPICKCTRL
382 IMPLEMENT_DYNAMIC_CLASS(wxDatePickerCtrl, wxControl)
383 #endif
384
385 // ----------------------------------------------------------------------------
386 // creation
387 // ----------------------------------------------------------------------------
388
389 bool wxDatePickerCtrlGeneric::Create(wxWindow *parent,
390 wxWindowID id,
391 const wxDateTime& date,
392 const wxPoint& pos,
393 const wxSize& size,
394 long style,
395 const wxValidator& validator,
396 const wxString& name)
397 {
398 wxASSERT_MSG( !(style & wxDP_SPIN),
399 _T("wxDP_SPIN style not supported, use wxDP_DEFAULT") );
400
401 if ( !wxControl::Create(parent, id, pos, size,
402 style | wxCLIP_CHILDREN | wxWANTS_CHARS | wxBORDER_NONE,
403 validator, name) )
404 {
405 return false;
406 }
407
408 InheritAttributes();
409
410 m_combo = new wxComboCtrl(this, -1, wxEmptyString,
411 wxDefaultPosition, wxDefaultSize);
412
413 m_combo->SetCtrlMainWnd(this);
414
415 m_popup = new wxCalendarComboPopup();
416 m_cal = m_popup;
417
418 #if defined(__WXMSW__)
419 // without this keyboard navigation in month control doesn't work
420 m_combo->UseAltPopupWindow();
421 #endif
422 m_combo->SetPopupControl(m_popup);
423
424 m_popup->SetDateValue(date.IsValid() ? date : wxDateTime::Today());
425
426 SetInitialSize(size);
427
428 return true;
429 }
430
431
432 void wxDatePickerCtrlGeneric::Init()
433 {
434 m_combo = NULL;
435 m_popup = NULL;
436 m_cal = NULL;
437 }
438
439 wxDatePickerCtrlGeneric::~wxDatePickerCtrlGeneric()
440 {
441 }
442
443 bool wxDatePickerCtrlGeneric::Destroy()
444 {
445 if ( m_combo )
446 m_combo->Destroy();
447
448 m_combo = NULL;
449 m_popup = NULL;
450 m_cal = NULL;
451
452 return wxControl::Destroy();
453 }
454
455 // ----------------------------------------------------------------------------
456 // overridden base class methods
457 // ----------------------------------------------------------------------------
458
459 wxSize wxDatePickerCtrlGeneric::DoGetBestSize() const
460 {
461 return m_combo->GetBestSize();
462 }
463
464 // ----------------------------------------------------------------------------
465 // wxDatePickerCtrlGeneric API
466 // ----------------------------------------------------------------------------
467
468 bool
469 wxDatePickerCtrlGeneric::SetDateRange(const wxDateTime& lowerdate,
470 const wxDateTime& upperdate)
471 {
472 return m_popup->SetDateRange(lowerdate, upperdate);
473 }
474
475
476 wxDateTime wxDatePickerCtrlGeneric::GetValue() const
477 {
478 if ( HasFlag(wxDP_ALLOWNONE) && m_popup->IsTextEmpty() )
479 return wxInvalidDateTime;
480 return m_popup->GetDate();
481 }
482
483
484 void wxDatePickerCtrlGeneric::SetValue(const wxDateTime& date)
485 {
486 m_popup->SetDateValue(date);
487 }
488
489
490 bool wxDatePickerCtrlGeneric::GetRange(wxDateTime *dt1, wxDateTime *dt2) const
491 {
492 if (dt1)
493 *dt1 = m_popup->GetLowerDateLimit();
494 if (dt2)
495 *dt2 = m_popup->GetUpperDateLimit();
496 return true;
497 }
498
499
500 void
501 wxDatePickerCtrlGeneric::SetRange(const wxDateTime &dt1, const wxDateTime &dt2)
502 {
503 m_popup->SetDateRange(dt1, dt2);
504 }
505
506 // ----------------------------------------------------------------------------
507 // event handlers
508 // ----------------------------------------------------------------------------
509
510
511 void wxDatePickerCtrlGeneric::OnSize(wxSizeEvent& event)
512 {
513 if ( m_combo )
514 m_combo->SetSize(GetClientSize());
515
516 event.Skip();
517 }
518
519
520 void wxDatePickerCtrlGeneric::OnText(wxCommandEvent &ev)
521 {
522 ev.SetEventObject(this);
523 ev.SetId(GetId());
524 GetParent()->ProcessEvent(ev);
525
526 // We'll create an additional event if the date is valid.
527 // If the date isn't valid, the user's probably in the middle of typing
528 wxDateTime dt;
529 if ( !m_popup->ParseDateTime(m_combo->GetValue(), &dt) )
530 return;
531
532 m_popup->SendDateEvent(dt);
533 }
534
535
536 void wxDatePickerCtrlGeneric::OnFocus(wxFocusEvent& WXUNUSED(event))
537 {
538 m_combo->SetFocus();
539 }
540
541
542 #endif // wxUSE_DATEPICKCTRL_GENERIC
543
544 #endif // wxUSE_DATEPICKCTRL
545

  ViewVC Help
Powered by ViewVC 1.1.22