/[pcsx2_0.9.7]/branch/r3113_0.9.7_beta/3rdparty/wxWidgets/src/generic/datectlg.cpp
ViewVC logotype

Annotation of /branch/r3113_0.9.7_beta/3rdparty/wxWidgets/src/generic/datectlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years ago) by william
Original Path: trunk/3rdparty/wxWidgets/src/generic/datectlg.cpp
File size: 15044 byte(s)
committing r3113 initial commit again...
1 william 31 /////////////////////////////////////////////////////////////////////////////
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