~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Externals/wxWidgets3/src/generic/calctrlg.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
///////////////////////////////////////////////////////////////////////////////
 
2
// Name:        src/generic/calctrlg.cpp
 
3
// Purpose:     implementation of the wxGenericCalendarCtrl
 
4
// Author:      Vadim Zeitlin
 
5
// Modified by:
 
6
// Created:     29.12.99
 
7
// Copyright:   (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
 
8
// Licence:     wxWindows licence
 
9
///////////////////////////////////////////////////////////////////////////////
 
10
 
 
11
// ============================================================================
 
12
// declarations
 
13
// ============================================================================
 
14
 
 
15
// ----------------------------------------------------------------------------
 
16
// headers
 
17
// ----------------------------------------------------------------------------
 
18
 
 
19
// For compilers that support precompilation, includes "wx.h".
 
20
#include "wx/wxprec.h"
 
21
 
 
22
#ifdef __BORLANDC__
 
23
    #pragma hdrstop
 
24
#endif
 
25
 
 
26
#ifndef WX_PRECOMP
 
27
    #include "wx/dcclient.h"
 
28
    #include "wx/settings.h"
 
29
    #include "wx/brush.h"
 
30
    #include "wx/combobox.h"
 
31
    #include "wx/listbox.h"
 
32
    #include "wx/stattext.h"
 
33
    #include "wx/textctrl.h"
 
34
#endif //WX_PRECOMP
 
35
 
 
36
 
 
37
#if wxUSE_CALENDARCTRL
 
38
 
 
39
#include "wx/spinctrl.h"
 
40
#include "wx/calctrl.h"
 
41
#include "wx/generic/calctrlg.h"
 
42
 
 
43
#define DEBUG_PAINT 0
 
44
 
 
45
// ----------------------------------------------------------------------------
 
46
// wxWin macros
 
47
// ----------------------------------------------------------------------------
 
48
 
 
49
#ifdef wxHAS_NATIVE_CALENDARCTRL
 
50
 
 
51
wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxGenericCalendarCtrl, wxControl,"wx/calctrl.h")
 
52
 
 
53
#endif
 
54
 
 
55
BEGIN_EVENT_TABLE(wxGenericCalendarCtrl, wxControl)
 
56
    EVT_PAINT(wxGenericCalendarCtrl::OnPaint)
 
57
 
 
58
    EVT_CHAR(wxGenericCalendarCtrl::OnChar)
 
59
 
 
60
    EVT_LEFT_DOWN(wxGenericCalendarCtrl::OnClick)
 
61
    EVT_LEFT_DCLICK(wxGenericCalendarCtrl::OnDClick)
 
62
 
 
63
    EVT_SYS_COLOUR_CHANGED(wxGenericCalendarCtrl::OnSysColourChanged)
 
64
END_EVENT_TABLE()
 
65
 
 
66
// ============================================================================
 
67
// implementation
 
68
// ============================================================================
 
69
 
 
70
// ----------------------------------------------------------------------------
 
71
// helper functions
 
72
// ----------------------------------------------------------------------------
 
73
 
 
74
namespace
 
75
{
 
76
 
 
77
// add attributes that are set in attr
 
78
void AddAttr(wxCalendarDateAttr *self, const wxCalendarDateAttr& attr)
 
79
{
 
80
    if (attr.HasTextColour())
 
81
        self->SetTextColour(attr.GetTextColour());
 
82
    if (attr.HasBackgroundColour())
 
83
        self->SetBackgroundColour(attr.GetBackgroundColour());
 
84
    if (attr.HasBorderColour())
 
85
        self->SetBorderColour(attr.GetBorderColour());
 
86
    if (attr.HasFont())
 
87
        self->SetFont(attr.GetFont());
 
88
    if (attr.HasBorder())
 
89
        self->SetBorder(attr.GetBorder());
 
90
    if (attr.IsHoliday())
 
91
        self->SetHoliday(true);
 
92
}
 
93
 
 
94
// remove attributes that are set in attr
 
95
void DelAttr(wxCalendarDateAttr *self, const wxCalendarDateAttr &attr)
 
96
{
 
97
    if (attr.HasTextColour())
 
98
        self->SetTextColour(wxNullColour);
 
99
    if (attr.HasBackgroundColour())
 
100
        self->SetBackgroundColour(wxNullColour);
 
101
    if (attr.HasBorderColour())
 
102
        self->SetBorderColour(wxNullColour);
 
103
    if (attr.HasFont())
 
104
        self->SetFont(wxNullFont);
 
105
    if (attr.HasBorder())
 
106
        self->SetBorder(wxCAL_BORDER_NONE);
 
107
    if (attr.IsHoliday())
 
108
        self->SetHoliday(false);
 
109
}
 
110
 
 
111
} // anonymous namespace
 
112
 
 
113
// ----------------------------------------------------------------------------
 
114
// wxGenericCalendarCtrl
 
115
// ----------------------------------------------------------------------------
 
116
 
 
117
wxGenericCalendarCtrl::wxGenericCalendarCtrl(wxWindow *parent,
 
118
                                             wxWindowID id,
 
119
                                             const wxDateTime& date,
 
120
                                             const wxPoint& pos,
 
121
                                             const wxSize& size,
 
122
                                             long style,
 
123
                                             const wxString& name)
 
124
{
 
125
    Init();
 
126
 
 
127
    (void)Create(parent, id, date, pos, size, style, name);
 
128
}
 
129
 
 
130
void wxGenericCalendarCtrl::Init()
 
131
{
 
132
    m_comboMonth = NULL;
 
133
    m_spinYear = NULL;
 
134
    m_staticYear = NULL;
 
135
    m_staticMonth = NULL;
 
136
 
 
137
    m_userChangedYear = false;
 
138
 
 
139
    m_widthCol =
 
140
    m_heightRow =
 
141
    m_calendarWeekWidth = 0;
 
142
 
 
143
    wxDateTime::WeekDay wd;
 
144
    for ( wd = wxDateTime::Sun; wd < wxDateTime::Inv_WeekDay; wxNextWDay(wd) )
 
145
    {
 
146
        m_weekdays[wd] = wxDateTime::GetWeekDayName(wd, wxDateTime::Name_Abbr);
 
147
    }
 
148
 
 
149
    for ( size_t n = 0; n < WXSIZEOF(m_attrs); n++ )
 
150
    {
 
151
        m_attrs[n] = NULL;
 
152
    }
 
153
 
 
154
    InitColours();
 
155
}
 
156
 
 
157
void wxGenericCalendarCtrl::InitColours()
 
158
{
 
159
    m_colHighlightFg = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
 
160
    m_colHighlightBg = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
 
161
    m_colBackground = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
 
162
    m_colSurrounding = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT);
 
163
 
 
164
    m_colHolidayFg = *wxRED;
 
165
    // don't set m_colHolidayBg - by default, same as our bg colour
 
166
 
 
167
    m_colHeaderFg = *wxBLUE;
 
168
    m_colHeaderBg = *wxLIGHT_GREY;
 
169
}
 
170
 
 
171
bool wxGenericCalendarCtrl::Create(wxWindow *parent,
 
172
                                   wxWindowID id,
 
173
                                   const wxDateTime& date,
 
174
                                   const wxPoint& pos,
 
175
                                   const wxSize& size,
 
176
                                   long style,
 
177
                                   const wxString& name)
 
178
{
 
179
    if ( !wxControl::Create(parent, id, pos, size,
 
180
                            style | wxCLIP_CHILDREN | wxWANTS_CHARS | wxFULL_REPAINT_ON_RESIZE,
 
181
                            wxDefaultValidator, name) )
 
182
    {
 
183
        return false;
 
184
    }
 
185
 
 
186
    // needed to get the arrow keys normally used for the dialog navigation
 
187
    SetWindowStyle(style | wxWANTS_CHARS);
 
188
 
 
189
    m_date = date.IsValid() ? date : wxDateTime::Today();
 
190
 
 
191
    m_lowdate = wxDefaultDateTime;
 
192
    m_highdate = wxDefaultDateTime;
 
193
 
 
194
    if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) )
 
195
    {
 
196
        CreateYearSpinCtrl();
 
197
        m_staticYear = new wxStaticText(GetParent(), wxID_ANY, m_date.Format(wxT("%Y")),
 
198
                                        wxDefaultPosition, wxDefaultSize,
 
199
                                        wxALIGN_CENTRE);
 
200
        CreateMonthComboBox();
 
201
        m_staticMonth = new wxStaticText(GetParent(), wxID_ANY, m_date.Format(wxT("%B")),
 
202
                                         wxDefaultPosition, wxDefaultSize,
 
203
                                         wxALIGN_CENTRE);
 
204
    }
 
205
 
 
206
    ShowCurrentControls();
 
207
 
 
208
    // we need to set the position as well because the main control position
 
209
    // is not the same as the one specified in pos if we have the controls
 
210
    // above it
 
211
    SetInitialSize(size);
 
212
    SetPosition(pos);
 
213
 
 
214
    // Since we don't paint the whole background make sure that the platform
 
215
    // will use the right one.
 
216
    SetBackgroundColour(m_colBackground);
 
217
 
 
218
    SetHolidayAttrs();
 
219
 
 
220
    return true;
 
221
}
 
222
 
 
223
wxGenericCalendarCtrl::~wxGenericCalendarCtrl()
 
224
{
 
225
    for ( size_t n = 0; n < WXSIZEOF(m_attrs); n++ )
 
226
    {
 
227
        delete m_attrs[n];
 
228
    }
 
229
 
 
230
    if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) )
 
231
    {
 
232
        delete m_comboMonth;
 
233
        delete m_staticMonth;
 
234
        delete m_spinYear;
 
235
        delete m_staticYear;
 
236
    }
 
237
}
 
238
 
 
239
void wxGenericCalendarCtrl::SetWindowStyleFlag(long style)
 
240
{
 
241
    // changing this style doesn't work because the controls are not
 
242
    // created/shown/hidden accordingly
 
243
    wxASSERT_MSG( (style & wxCAL_SEQUENTIAL_MONTH_SELECTION) ==
 
244
                    (m_windowStyle & wxCAL_SEQUENTIAL_MONTH_SELECTION),
 
245
                  wxT("wxCAL_SEQUENTIAL_MONTH_SELECTION can't be changed after creation") );
 
246
 
 
247
    wxControl::SetWindowStyleFlag(style);
 
248
}
 
249
 
 
250
// ----------------------------------------------------------------------------
 
251
// Create the wxComboBox and wxSpinCtrl
 
252
// ----------------------------------------------------------------------------
 
253
 
 
254
void wxGenericCalendarCtrl::CreateMonthComboBox()
 
255
{
 
256
    m_comboMonth = new wxComboBox(GetParent(), wxID_ANY,
 
257
                                  wxEmptyString,
 
258
                                  wxDefaultPosition,
 
259
                                  wxDefaultSize,
 
260
                                  0, NULL,
 
261
                                  wxCB_READONLY | wxCLIP_SIBLINGS);
 
262
 
 
263
    wxDateTime::Month m;
 
264
    for ( m = wxDateTime::Jan; m < wxDateTime::Inv_Month; wxNextMonth(m) )
 
265
    {
 
266
        m_comboMonth->Append(wxDateTime::GetMonthName(m));
 
267
    }
 
268
 
 
269
    m_comboMonth->SetSelection(GetDate().GetMonth());
 
270
    m_comboMonth->SetSize(wxDefaultCoord,
 
271
                          wxDefaultCoord,
 
272
                          wxDefaultCoord,
 
273
                          wxDefaultCoord,
 
274
                          wxSIZE_AUTO_WIDTH|wxSIZE_AUTO_HEIGHT);
 
275
 
 
276
    m_comboMonth->Connect(m_comboMonth->GetId(), wxEVT_COMBOBOX,
 
277
                          wxCommandEventHandler(wxGenericCalendarCtrl::OnMonthChange),
 
278
                          NULL, this);
 
279
}
 
280
 
 
281
void wxGenericCalendarCtrl::CreateYearSpinCtrl()
 
282
{
 
283
    m_spinYear = new wxSpinCtrl(GetParent(), wxID_ANY,
 
284
                                GetDate().Format(wxT("%Y")),
 
285
                                wxDefaultPosition,
 
286
                                wxDefaultSize,
 
287
                                wxSP_ARROW_KEYS | wxCLIP_SIBLINGS,
 
288
                                -4300, 10000, GetDate().GetYear());
 
289
 
 
290
    m_spinYear->Connect(m_spinYear->GetId(), wxEVT_TEXT,
 
291
                        wxCommandEventHandler(wxGenericCalendarCtrl::OnYearTextChange),
 
292
                        NULL, this);
 
293
 
 
294
    m_spinYear->Connect(m_spinYear->GetId(), wxEVT_SPINCTRL,
 
295
                        wxSpinEventHandler(wxGenericCalendarCtrl::OnYearChange),
 
296
                        NULL, this);
 
297
}
 
298
 
 
299
// ----------------------------------------------------------------------------
 
300
// forward wxWin functions to subcontrols
 
301
// ----------------------------------------------------------------------------
 
302
 
 
303
bool wxGenericCalendarCtrl::Destroy()
 
304
{
 
305
    if ( m_staticYear )
 
306
        m_staticYear->Destroy();
 
307
    if ( m_spinYear )
 
308
        m_spinYear->Destroy();
 
309
    if ( m_comboMonth )
 
310
        m_comboMonth->Destroy();
 
311
    if ( m_staticMonth )
 
312
        m_staticMonth->Destroy();
 
313
 
 
314
    m_staticYear = NULL;
 
315
    m_spinYear = NULL;
 
316
    m_comboMonth = NULL;
 
317
    m_staticMonth = NULL;
 
318
 
 
319
    return wxControl::Destroy();
 
320
}
 
321
 
 
322
bool wxGenericCalendarCtrl::Show(bool show)
 
323
{
 
324
    if ( !wxControl::Show(show) )
 
325
    {
 
326
        return false;
 
327
    }
 
328
 
 
329
    if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION) )
 
330
    {
 
331
        if ( GetMonthControl() )
 
332
        {
 
333
            GetMonthControl()->Show(show);
 
334
            GetYearControl()->Show(show);
 
335
        }
 
336
    }
 
337
 
 
338
    return true;
 
339
}
 
340
 
 
341
bool wxGenericCalendarCtrl::Enable(bool enable)
 
342
{
 
343
    if ( !wxControl::Enable(enable) )
 
344
    {
 
345
        return false;
 
346
    }
 
347
 
 
348
    if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION) )
 
349
    {
 
350
        GetMonthControl()->Enable(enable);
 
351
        GetYearControl()->Enable(enable);
 
352
    }
 
353
 
 
354
    return true;
 
355
}
 
356
 
 
357
// ----------------------------------------------------------------------------
 
358
// enable/disable month/year controls
 
359
// ----------------------------------------------------------------------------
 
360
 
 
361
void wxGenericCalendarCtrl::ShowCurrentControls()
 
362
{
 
363
    if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) )
 
364
    {
 
365
        if ( AllowMonthChange() )
 
366
        {
 
367
            m_comboMonth->Show();
 
368
            m_staticMonth->Hide();
 
369
 
 
370
            if ( AllowYearChange() )
 
371
            {
 
372
                m_spinYear->Show();
 
373
                m_staticYear->Hide();
 
374
 
 
375
                // skip the rest
 
376
                return;
 
377
            }
 
378
        }
 
379
        else
 
380
        {
 
381
            m_comboMonth->Hide();
 
382
            m_staticMonth->Show();
 
383
        }
 
384
 
 
385
        // year change not allowed here
 
386
        m_spinYear->Hide();
 
387
        m_staticYear->Show();
 
388
    }
 
389
    //else: these controls are not even created, don't show/hide them
 
390
}
 
391
 
 
392
wxControl *wxGenericCalendarCtrl::GetMonthControl() const
 
393
{
 
394
    return AllowMonthChange() ? (wxControl *)m_comboMonth : (wxControl *)m_staticMonth;
 
395
}
 
396
 
 
397
wxControl *wxGenericCalendarCtrl::GetYearControl() const
 
398
{
 
399
    return AllowYearChange() ? (wxControl *)m_spinYear : (wxControl *)m_staticYear;
 
400
}
 
401
 
 
402
void wxGenericCalendarCtrl::EnableYearChange(bool enable)
 
403
{
 
404
    if ( enable != AllowYearChange() )
 
405
    {
 
406
        long style = GetWindowStyle();
 
407
        if ( enable )
 
408
            style &= ~wxCAL_NO_YEAR_CHANGE;
 
409
        else
 
410
            style |= wxCAL_NO_YEAR_CHANGE;
 
411
        SetWindowStyle(style);
 
412
 
 
413
        ShowCurrentControls();
 
414
        if ( GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION )
 
415
        {
 
416
            Refresh();
 
417
        }
 
418
    }
 
419
}
 
420
 
 
421
bool wxGenericCalendarCtrl::EnableMonthChange(bool enable)
 
422
{
 
423
    if ( !wxCalendarCtrlBase::EnableMonthChange(enable) )
 
424
        return false;
 
425
 
 
426
    ShowCurrentControls();
 
427
    if ( GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION )
 
428
        Refresh();
 
429
 
 
430
    return true;
 
431
}
 
432
 
 
433
// ----------------------------------------------------------------------------
 
434
// changing date
 
435
// ----------------------------------------------------------------------------
 
436
 
 
437
bool wxGenericCalendarCtrl::SetDate(const wxDateTime& date)
 
438
{
 
439
    bool retval = true;
 
440
 
 
441
    bool sameMonth = m_date.GetMonth() == date.GetMonth(),
 
442
         sameYear = m_date.GetYear() == date.GetYear();
 
443
 
 
444
    if ( IsDateInRange(date) )
 
445
    {
 
446
        if ( sameMonth && sameYear )
 
447
        {
 
448
            // just change the day
 
449
            ChangeDay(date);
 
450
        }
 
451
        else
 
452
        {
 
453
            if ( AllowMonthChange() && (AllowYearChange() || sameYear) )
 
454
            {
 
455
                // change everything
 
456
                m_date = date;
 
457
 
 
458
                if ( !(GetWindowStyle() & wxCAL_SEQUENTIAL_MONTH_SELECTION) )
 
459
                {
 
460
                    // update the controls
 
461
                    m_comboMonth->SetSelection(m_date.GetMonth());
 
462
 
 
463
                    if ( AllowYearChange() )
 
464
                    {
 
465
                        if ( !m_userChangedYear )
 
466
                            m_spinYear->SetValue(m_date.Format(wxT("%Y")));
 
467
                    }
 
468
                }
 
469
 
 
470
                // as the month changed, holidays did too
 
471
                SetHolidayAttrs();
 
472
 
 
473
                // update the calendar
 
474
                Refresh();
 
475
            }
 
476
            else
 
477
            {
 
478
                // forbidden
 
479
                retval = false;
 
480
            }
 
481
        }
 
482
    }
 
483
 
 
484
    m_userChangedYear = false;
 
485
 
 
486
    return retval;
 
487
}
 
488
 
 
489
void wxGenericCalendarCtrl::ChangeDay(const wxDateTime& date)
 
490
{
 
491
    if ( m_date != date )
 
492
    {
 
493
        // we need to refresh the row containing the old date and the one
 
494
        // containing the new one
 
495
        wxDateTime dateOld = m_date;
 
496
        m_date = date;
 
497
 
 
498
        RefreshDate(dateOld);
 
499
 
 
500
        // if the date is in the same row, it was already drawn correctly
 
501
        if ( GetWeek(m_date) != GetWeek(dateOld) )
 
502
        {
 
503
            RefreshDate(m_date);
 
504
        }
 
505
    }
 
506
}
 
507
 
 
508
void wxGenericCalendarCtrl::SetDateAndNotify(const wxDateTime& date)
 
509
{
 
510
    const wxDateTime dateOld = GetDate();
 
511
    if ( date != dateOld && SetDate(date) )
 
512
    {
 
513
        GenerateAllChangeEvents(dateOld);
 
514
    }
 
515
}
 
516
 
 
517
// ----------------------------------------------------------------------------
 
518
// date range
 
519
// ----------------------------------------------------------------------------
 
520
 
 
521
bool wxGenericCalendarCtrl::SetLowerDateLimit(const wxDateTime& date /* = wxDefaultDateTime */)
 
522
{
 
523
    bool retval = true;
 
524
 
 
525
    if ( !(date.IsValid()) || ( ( m_highdate.IsValid() ) ? ( date <= m_highdate ) : true ) )
 
526
    {
 
527
        m_lowdate = date;
 
528
    }
 
529
    else
 
530
    {
 
531
        retval = false;
 
532
    }
 
533
 
 
534
    return retval;
 
535
}
 
536
 
 
537
bool wxGenericCalendarCtrl::SetUpperDateLimit(const wxDateTime& date /* = wxDefaultDateTime */)
 
538
{
 
539
    bool retval = true;
 
540
 
 
541
    if ( !(date.IsValid()) || ( ( m_lowdate.IsValid() ) ? ( date >= m_lowdate ) : true ) )
 
542
    {
 
543
        m_highdate = date;
 
544
    }
 
545
    else
 
546
    {
 
547
        retval = false;
 
548
    }
 
549
 
 
550
    return retval;
 
551
}
 
552
 
 
553
bool wxGenericCalendarCtrl::SetDateRange(const wxDateTime& lowerdate /* = wxDefaultDateTime */, const wxDateTime& upperdate /* = wxDefaultDateTime */)
 
554
{
 
555
    bool retval = true;
 
556
 
 
557
    if (
 
558
        ( !( lowerdate.IsValid() ) || ( ( upperdate.IsValid() ) ? ( lowerdate <= upperdate ) : true ) ) &&
 
559
        ( !( upperdate.IsValid() ) || ( ( lowerdate.IsValid() ) ? ( upperdate >= lowerdate ) : true ) ) )
 
560
    {
 
561
        m_lowdate = lowerdate;
 
562
        m_highdate = upperdate;
 
563
    }
 
564
    else
 
565
    {
 
566
        retval = false;
 
567
    }
 
568
 
 
569
    return retval;
 
570
}
 
571
 
 
572
bool wxGenericCalendarCtrl::GetDateRange(wxDateTime *lowerdate,
 
573
                                         wxDateTime *upperdate) const
 
574
{
 
575
    if ( lowerdate )
 
576
        *lowerdate = m_lowdate;
 
577
    if ( upperdate )
 
578
        *upperdate = m_highdate;
 
579
 
 
580
    return m_lowdate.IsValid() || m_highdate.IsValid();
 
581
}
 
582
 
 
583
// ----------------------------------------------------------------------------
 
584
// date helpers
 
585
// ----------------------------------------------------------------------------
 
586
 
 
587
wxDateTime wxGenericCalendarCtrl::GetStartDate() const
 
588
{
 
589
    wxDateTime::Tm tm = m_date.GetTm();
 
590
 
 
591
    wxDateTime date = wxDateTime(1, tm.mon, tm.year);
 
592
 
 
593
    // rewind back
 
594
    date.SetToPrevWeekDay(GetWeekStart());
 
595
 
 
596
    if ( GetWindowStyle() & wxCAL_SHOW_SURROUNDING_WEEKS )
 
597
    {
 
598
        // We want to offset the calendar if we start on the first..
 
599
        if ( date.GetDay() == 1 )
 
600
        {
 
601
            date -= wxDateSpan::Week();
 
602
        }
 
603
    }
 
604
 
 
605
    return date;
 
606
}
 
607
 
 
608
bool wxGenericCalendarCtrl::IsDateShown(const wxDateTime& date) const
 
609
{
 
610
    if ( !(GetWindowStyle() & wxCAL_SHOW_SURROUNDING_WEEKS) )
 
611
    {
 
612
        return date.GetMonth() == m_date.GetMonth();
 
613
    }
 
614
    else
 
615
    {
 
616
        return true;
 
617
    }
 
618
}
 
619
 
 
620
bool wxGenericCalendarCtrl::IsDateInRange(const wxDateTime& date) const
 
621
{
 
622
    // Check if the given date is in the range specified
 
623
    return ( ( ( m_lowdate.IsValid() ) ? ( date >= m_lowdate ) : true )
 
624
        && ( ( m_highdate.IsValid() ) ? ( date <= m_highdate ) : true ) );
 
625
}
 
626
 
 
627
bool wxGenericCalendarCtrl::AdjustDateToRange(wxDateTime *date) const
 
628
{
 
629
    if ( m_lowdate.IsValid() && *date < m_lowdate )
 
630
    {
 
631
        *date = m_lowdate;
 
632
        return true;
 
633
    }
 
634
 
 
635
    if ( m_highdate.IsValid() && *date > m_highdate )
 
636
    {
 
637
        *date = m_highdate;
 
638
        return true;
 
639
    }
 
640
 
 
641
    return false;
 
642
}
 
643
 
 
644
size_t wxGenericCalendarCtrl::GetWeek(const wxDateTime& date) const
 
645
{
 
646
    size_t retval = date.GetWeekOfMonth(HasFlag(wxCAL_MONDAY_FIRST)
 
647
                                   ? wxDateTime::Monday_First
 
648
                                   : wxDateTime::Sunday_First);
 
649
 
 
650
    if ( (GetWindowStyle() & wxCAL_SHOW_SURROUNDING_WEEKS) )
 
651
    {
 
652
        // we need to offset an extra week if we "start" on the 1st of the month
 
653
        wxDateTime::Tm tm = date.GetTm();
 
654
 
 
655
        wxDateTime datetest = wxDateTime(1, tm.mon, tm.year);
 
656
 
 
657
        // rewind back
 
658
        datetest.SetToPrevWeekDay(GetWeekStart());
 
659
 
 
660
        if ( datetest.GetDay() == 1 )
 
661
        {
 
662
            retval += 1;
 
663
        }
 
664
    }
 
665
 
 
666
    return retval;
 
667
}
 
668
 
 
669
// ----------------------------------------------------------------------------
 
670
// size management
 
671
// ----------------------------------------------------------------------------
 
672
 
 
673
// this is a composite control and it must arrange its parts each time its
 
674
// size or position changes: the combobox and spinctrl are along the top of
 
675
// the available area and the calendar takes up the rest of the space
 
676
 
 
677
// the static controls are supposed to be always smaller than combo/spin so we
 
678
// always use the latter for size calculations and position the static to take
 
679
// the same space
 
680
 
 
681
// the constants used for the layout
 
682
#define VERT_MARGIN    5           // distance between combo and calendar
 
683
#define HORZ_MARGIN    5           //                            spin
 
684
 
 
685
wxSize wxGenericCalendarCtrl::DoGetBestSize() const
 
686
{
 
687
    // calc the size of the calendar
 
688
    const_cast<wxGenericCalendarCtrl *>(this)->RecalcGeometry();
 
689
 
 
690
    wxCoord width = 7*m_widthCol + m_calendarWeekWidth,
 
691
            height = 7*m_heightRow + m_rowOffset + VERT_MARGIN;
 
692
 
 
693
    if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) )
 
694
    {
 
695
        const wxSize bestSizeCombo = m_comboMonth->GetBestSize();
 
696
 
 
697
        height += wxMax(bestSizeCombo.y, m_spinYear->GetBestSize().y)
 
698
                    + VERT_MARGIN;
 
699
 
 
700
        wxCoord w2 = bestSizeCombo.x + HORZ_MARGIN + GetCharWidth()*8;
 
701
        if ( width < w2 )
 
702
            width = w2;
 
703
    }
 
704
 
 
705
    wxSize best(width, height);
 
706
    if ( !HasFlag(wxBORDER_NONE) )
 
707
    {
 
708
        best += GetWindowBorderSize();
 
709
    }
 
710
 
 
711
    CacheBestSize(best);
 
712
 
 
713
    return best;
 
714
}
 
715
 
 
716
void wxGenericCalendarCtrl::DoMoveWindow(int x, int y, int width, int height)
 
717
{
 
718
    int yDiff;
 
719
 
 
720
    if ( !HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) && m_staticMonth )
 
721
    {
 
722
        wxSize sizeCombo = m_comboMonth->GetEffectiveMinSize();
 
723
        wxSize sizeStatic = m_staticMonth->GetSize();
 
724
        wxSize sizeSpin = m_spinYear->GetSize();
 
725
 
 
726
        int maxHeight = wxMax(sizeSpin.y, sizeCombo.y);
 
727
        int dy = (maxHeight - sizeStatic.y) / 2;
 
728
        m_comboMonth->Move(x, y + (maxHeight - sizeCombo.y)/2);
 
729
        m_staticMonth->SetSize(x, y + dy, sizeCombo.x, -1);
 
730
 
 
731
        int xDiff = sizeCombo.x + HORZ_MARGIN;
 
732
 
 
733
        m_spinYear->SetSize(x + xDiff, y + (maxHeight - sizeSpin.y)/2, width - xDiff, maxHeight);
 
734
        m_staticYear->SetSize(x + xDiff, y + dy, width - xDiff, sizeStatic.y);
 
735
 
 
736
        yDiff = maxHeight + VERT_MARGIN;
 
737
    }
 
738
    else // no controls on the top
 
739
    {
 
740
        yDiff = 0;
 
741
    }
 
742
 
 
743
    wxControl::DoMoveWindow(x, y + yDiff, width, height - yDiff);
 
744
}
 
745
 
 
746
void wxGenericCalendarCtrl::DoGetSize(int *width, int *height) const
 
747
{
 
748
    wxControl::DoGetSize( width, height );
 
749
}
 
750
 
 
751
void wxGenericCalendarCtrl::RecalcGeometry()
 
752
{
 
753
    wxClientDC dc(this);
 
754
 
 
755
    dc.SetFont(GetFont());
 
756
 
 
757
    // determine the column width (weekday names are not necessarily wider
 
758
    // than the numbers (in some languages), so let's not assume that they are)
 
759
    m_widthCol = 0;
 
760
    for ( int day = 10; day <= 31; day++)
 
761
    {
 
762
        wxCoord width;
 
763
        dc.GetTextExtent(wxString::Format(wxT("%d"), day), &width, &m_heightRow);
 
764
        if ( width > m_widthCol )
 
765
        {
 
766
            // 1.5 times the width gives nice margins even if the weekday
 
767
            // names are short
 
768
            m_widthCol = width+width/2;
 
769
        }
 
770
    }
 
771
    wxDateTime::WeekDay wd;
 
772
    for ( wd = wxDateTime::Sun; wd < wxDateTime::Inv_WeekDay; wxNextWDay(wd) )
 
773
    {
 
774
        wxCoord width;
 
775
        dc.GetTextExtent(m_weekdays[wd], &width, &m_heightRow);
 
776
        if ( width > m_widthCol )
 
777
        {
 
778
            m_widthCol = width;
 
779
        }
 
780
    }
 
781
 
 
782
    m_calendarWeekWidth = HasFlag( wxCAL_SHOW_WEEK_NUMBERS )
 
783
        ? dc.GetTextExtent( wxString::Format( wxT( "%d" ), 42 )).GetWidth() + 4 : 0;
 
784
 
 
785
    // leave some margins
 
786
    m_widthCol += 2;
 
787
    m_heightRow += 2;
 
788
 
 
789
    m_rowOffset = HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) ? m_heightRow : 0; // conditional in relation to style
 
790
}
 
791
 
 
792
// ----------------------------------------------------------------------------
 
793
// drawing
 
794
// ----------------------------------------------------------------------------
 
795
 
 
796
void wxGenericCalendarCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
 
797
{
 
798
    wxPaintDC dc(this);
 
799
 
 
800
    dc.SetFont(GetFont());
 
801
 
 
802
    RecalcGeometry();
 
803
 
 
804
#if DEBUG_PAINT
 
805
    wxLogDebug("--- starting to paint, selection: %s, week %u\n",
 
806
           m_date.Format("%a %d-%m-%Y %H:%M:%S").c_str(),
 
807
           GetWeek(m_date));
 
808
#endif
 
809
 
 
810
    wxCoord y = 0;
 
811
    wxCoord x0 = m_calendarWeekWidth;
 
812
 
 
813
    if ( HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) )
 
814
    {
 
815
        // draw the sequential month-selector
 
816
 
 
817
        dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
 
818
        dc.SetTextForeground(*wxBLACK);
 
819
        dc.SetBrush(wxBrush(m_colHeaderBg, wxBRUSHSTYLE_SOLID));
 
820
        dc.SetPen(wxPen(m_colHeaderBg, 1, wxPENSTYLE_SOLID));
 
821
        dc.DrawRectangle(0, y, GetClientSize().x, m_heightRow);
 
822
 
 
823
        // Get extent of month-name + year
 
824
        wxCoord monthw, monthh;
 
825
        wxString headertext = m_date.Format(wxT("%B %Y"));
 
826
        dc.GetTextExtent(headertext, &monthw, &monthh);
 
827
 
 
828
        // draw month-name centered above weekdays
 
829
        wxCoord monthx = ((m_widthCol * 7) - monthw) / 2 + x0;
 
830
        wxCoord monthy = ((m_heightRow - monthh) / 2) + y;
 
831
        dc.DrawText(headertext, monthx,  monthy);
 
832
 
 
833
        // calculate the "month-arrows"
 
834
        wxPoint leftarrow[3];
 
835
        wxPoint rightarrow[3];
 
836
 
 
837
        int arrowheight = monthh / 2;
 
838
 
 
839
        leftarrow[0] = wxPoint(0, arrowheight / 2);
 
840
        leftarrow[1] = wxPoint(arrowheight / 2, 0);
 
841
        leftarrow[2] = wxPoint(arrowheight / 2, arrowheight - 1);
 
842
 
 
843
        rightarrow[0] = wxPoint(0,0);
 
844
        rightarrow[1] = wxPoint(arrowheight / 2, arrowheight / 2);
 
845
        rightarrow[2] = wxPoint(0, arrowheight - 1);
 
846
 
 
847
        // draw the "month-arrows"
 
848
 
 
849
        wxCoord arrowy = (m_heightRow - arrowheight) / 2;
 
850
        wxCoord larrowx = (m_widthCol - (arrowheight / 2)) / 2 + x0;
 
851
        wxCoord rarrowx = ((m_widthCol - (arrowheight / 2)) / 2) + m_widthCol*6 + x0;
 
852
        m_leftArrowRect = m_rightArrowRect = wxRect(0,0,0,0);
 
853
 
 
854
        if ( AllowMonthChange() )
 
855
        {
 
856
            wxDateTime ldpm = wxDateTime(1,m_date.GetMonth(), m_date.GetYear()) - wxDateSpan::Day(); // last day prev month
 
857
            // Check if range permits change
 
858
            if ( IsDateInRange(ldpm) && ( ( ldpm.GetYear() == m_date.GetYear() ) ? true : AllowYearChange() ) )
 
859
            {
 
860
                m_leftArrowRect = wxRect(larrowx - 3, arrowy - 3, (arrowheight / 2) + 8, (arrowheight + 6));
 
861
                dc.SetBrush(*wxBLACK_BRUSH);
 
862
                dc.SetPen(*wxBLACK_PEN);
 
863
                dc.DrawPolygon(3, leftarrow, larrowx , arrowy, wxWINDING_RULE);
 
864
                dc.SetBrush(*wxTRANSPARENT_BRUSH);
 
865
                dc.DrawRectangle(m_leftArrowRect);
 
866
            }
 
867
            wxDateTime fdnm = wxDateTime(1,m_date.GetMonth(), m_date.GetYear()) + wxDateSpan::Month(); // first day next month
 
868
            if ( IsDateInRange(fdnm) && ( ( fdnm.GetYear() == m_date.GetYear() ) ? true : AllowYearChange() ) )
 
869
            {
 
870
                m_rightArrowRect = wxRect(rarrowx - 4, arrowy - 3, (arrowheight / 2) + 8, (arrowheight + 6));
 
871
                dc.SetBrush(*wxBLACK_BRUSH);
 
872
                dc.SetPen(*wxBLACK_PEN);
 
873
                dc.DrawPolygon(3, rightarrow, rarrowx , arrowy, wxWINDING_RULE);
 
874
                dc.SetBrush(*wxTRANSPARENT_BRUSH);
 
875
                dc.DrawRectangle(m_rightArrowRect);
 
876
            }
 
877
        }
 
878
 
 
879
        y += m_heightRow;
 
880
    }
 
881
 
 
882
    // first draw the week days
 
883
    if ( IsExposed(x0, y, x0 + 7*m_widthCol, m_heightRow) )
 
884
    {
 
885
#if DEBUG_PAINT
 
886
        wxLogDebug("painting the header");
 
887
#endif
 
888
 
 
889
        dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
 
890
        dc.SetTextForeground(m_colHeaderFg);
 
891
        dc.SetBrush(wxBrush(m_colHeaderBg, wxBRUSHSTYLE_SOLID));
 
892
        dc.SetPen(wxPen(m_colHeaderBg, 1, wxPENSTYLE_SOLID));
 
893
        dc.DrawRectangle(0, y, GetClientSize().x, m_heightRow);
 
894
 
 
895
        bool startOnMonday = HasFlag(wxCAL_MONDAY_FIRST);
 
896
        for ( int wd = 0; wd < 7; wd++ )
 
897
        {
 
898
            size_t n;
 
899
            if ( startOnMonday )
 
900
                n = wd == 6 ? 0 : wd + 1;
 
901
            else
 
902
                n = wd;
 
903
            wxCoord dayw, dayh;
 
904
            dc.GetTextExtent(m_weekdays[n], &dayw, &dayh);
 
905
            dc.DrawText(m_weekdays[n], x0 + (wd*m_widthCol) + ((m_widthCol- dayw) / 2), y); // center the day-name
 
906
        }
 
907
    }
 
908
 
 
909
    // then the calendar itself
 
910
    dc.SetTextForeground(*wxBLACK);
 
911
    //dc.SetFont(*wxNORMAL_FONT);
 
912
 
 
913
    y += m_heightRow;
 
914
 
 
915
    // draw column with calendar week nr
 
916
    if ( HasFlag( wxCAL_SHOW_WEEK_NUMBERS ) && IsExposed( 0, y, m_calendarWeekWidth, m_heightRow * 6 ))
 
917
    {
 
918
        dc.SetBackgroundMode(wxTRANSPARENT);
 
919
        dc.SetBrush(wxBrush(m_colHeaderBg, wxSOLID));
 
920
        dc.SetPen(wxPen(m_colHeaderBg, 1, wxSOLID));
 
921
        dc.DrawRectangle( 0, y, m_calendarWeekWidth, m_heightRow * 6 );
 
922
        wxDateTime date = GetStartDate();
 
923
        for ( size_t i = 0; i < 6; ++i )
 
924
        {
 
925
            const int weekNr = date.GetWeekOfYear();
 
926
            wxString text = wxString::Format( wxT( "%d" ), weekNr );
 
927
            dc.DrawText( text, m_calendarWeekWidth - dc.GetTextExtent( text ).GetWidth() - 2, y + m_heightRow * i );
 
928
            date += wxDateSpan::Week();
 
929
        }
 
930
    }
 
931
 
 
932
    wxDateTime date = GetStartDate();
 
933
 
 
934
#if DEBUG_PAINT
 
935
    wxLogDebug("starting calendar from %s\n",
 
936
            date.Format("%a %d-%m-%Y %H:%M:%S").c_str());
 
937
#endif
 
938
 
 
939
    dc.SetBackgroundMode(wxBRUSHSTYLE_SOLID);
 
940
    for ( size_t nWeek = 1; nWeek <= 6; nWeek++, y += m_heightRow )
 
941
    {
 
942
        // if the update region doesn't intersect this row, don't paint it
 
943
        if ( !IsExposed(x0, y, x0 + 7*m_widthCol, m_heightRow - 1) )
 
944
        {
 
945
            date += wxDateSpan::Week();
 
946
 
 
947
            continue;
 
948
        }
 
949
 
 
950
#if DEBUG_PAINT
 
951
        wxLogDebug("painting week %d at y = %d\n", nWeek, y);
 
952
#endif
 
953
 
 
954
        for ( int wd = 0; wd < 7; wd++ )
 
955
        {
 
956
            dc.SetTextBackground(m_colBackground);
 
957
            if ( IsDateShown(date) )
 
958
            {
 
959
                // don't use wxDate::Format() which prepends 0s
 
960
                unsigned int day = date.GetDay();
 
961
                wxString dayStr = wxString::Format(wxT("%u"), day);
 
962
                wxCoord width;
 
963
                dc.GetTextExtent(dayStr, &width, NULL);
 
964
 
 
965
                bool changedColours = false,
 
966
                     changedFont = false;
 
967
 
 
968
                bool isSel = false;
 
969
                wxCalendarDateAttr *attr = NULL;
 
970
 
 
971
                if ( date.GetMonth() != m_date.GetMonth() || !IsDateInRange(date) )
 
972
                {
 
973
                    // draw the days of adjacent months in different colour
 
974
                    dc.SetTextForeground(m_colSurrounding);
 
975
                    changedColours = true;
 
976
                }
 
977
                else
 
978
                {
 
979
                    isSel = date.IsSameDate(m_date);
 
980
                    attr = m_attrs[day - 1];
 
981
 
 
982
                    if ( isSel )
 
983
                    {
 
984
                        dc.SetTextForeground(m_colHighlightFg);
 
985
                        dc.SetTextBackground(m_colHighlightBg);
 
986
 
 
987
                        changedColours = true;
 
988
                    }
 
989
                    else if ( attr )
 
990
                    {
 
991
                        wxColour colFg, colBg;
 
992
 
 
993
                        if ( attr->IsHoliday() )
 
994
                        {
 
995
                            colFg = m_colHolidayFg;
 
996
                            colBg = m_colHolidayBg;
 
997
                        }
 
998
                        else
 
999
                        {
 
1000
                            colFg = attr->GetTextColour();
 
1001
                            colBg = attr->GetBackgroundColour();
 
1002
                        }
 
1003
 
 
1004
                        if ( colFg.IsOk() )
 
1005
                        {
 
1006
                            dc.SetTextForeground(colFg);
 
1007
                            changedColours = true;
 
1008
                        }
 
1009
 
 
1010
                        if ( colBg.IsOk() )
 
1011
                        {
 
1012
                            dc.SetTextBackground(colBg);
 
1013
                            changedColours = true;
 
1014
                        }
 
1015
 
 
1016
                        if ( attr->HasFont() )
 
1017
                        {
 
1018
                            dc.SetFont(attr->GetFont());
 
1019
                            changedFont = true;
 
1020
                        }
 
1021
                    }
 
1022
                }
 
1023
 
 
1024
                wxCoord x = wd*m_widthCol + (m_widthCol - width) / 2 + x0;
 
1025
                dc.DrawText(dayStr, x, y + 1);
 
1026
 
 
1027
                if ( !isSel && attr && attr->HasBorder() )
 
1028
                {
 
1029
                    wxColour colBorder;
 
1030
                    if ( attr->HasBorderColour() )
 
1031
                    {
 
1032
                        colBorder = attr->GetBorderColour();
 
1033
                    }
 
1034
                    else
 
1035
                    {
 
1036
                        colBorder = GetForegroundColour();
 
1037
                    }
 
1038
 
 
1039
                    wxPen pen(colBorder, 1, wxPENSTYLE_SOLID);
 
1040
                    dc.SetPen(pen);
 
1041
                    dc.SetBrush(*wxTRANSPARENT_BRUSH);
 
1042
 
 
1043
                    switch ( attr->GetBorder() )
 
1044
                    {
 
1045
                        case wxCAL_BORDER_SQUARE:
 
1046
                            dc.DrawRectangle(x - 2, y,
 
1047
                                             width + 4, m_heightRow);
 
1048
                            break;
 
1049
 
 
1050
                        case wxCAL_BORDER_ROUND:
 
1051
                            dc.DrawEllipse(x - 2, y,
 
1052
                                           width + 4, m_heightRow);
 
1053
                            break;
 
1054
 
 
1055
                        default:
 
1056
                            wxFAIL_MSG(wxT("unknown border type"));
 
1057
                    }
 
1058
                }
 
1059
 
 
1060
                if ( changedColours )
 
1061
                {
 
1062
                    dc.SetTextForeground(GetForegroundColour());
 
1063
                    dc.SetTextBackground(GetBackgroundColour());
 
1064
                }
 
1065
 
 
1066
                if ( changedFont )
 
1067
                {
 
1068
                    dc.SetFont(GetFont());
 
1069
                }
 
1070
            }
 
1071
            //else: just don't draw it
 
1072
 
 
1073
            date += wxDateSpan::Day();
 
1074
        }
 
1075
    }
 
1076
 
 
1077
    // Greying out out-of-range background
 
1078
    bool showSurrounding = (GetWindowStyle() & wxCAL_SHOW_SURROUNDING_WEEKS) != 0;
 
1079
 
 
1080
    date = ( showSurrounding ) ? GetStartDate() : wxDateTime(1, m_date.GetMonth(), m_date.GetYear());
 
1081
    if ( !IsDateInRange(date) )
 
1082
    {
 
1083
        wxDateTime firstOOR = GetLowerDateLimit() - wxDateSpan::Day(); // first out-of-range
 
1084
 
 
1085
        wxBrush oorbrush = *wxLIGHT_GREY_BRUSH;
 
1086
        oorbrush.SetStyle(wxBRUSHSTYLE_FDIAGONAL_HATCH);
 
1087
 
 
1088
        HighlightRange(&dc, date, firstOOR, wxTRANSPARENT_PEN, &oorbrush);
 
1089
    }
 
1090
 
 
1091
    date = ( showSurrounding ) ? GetStartDate() + wxDateSpan::Weeks(6) - wxDateSpan::Day() : wxDateTime().SetToLastMonthDay(m_date.GetMonth(), m_date.GetYear());
 
1092
    if ( !IsDateInRange(date) )
 
1093
    {
 
1094
        wxDateTime firstOOR = GetUpperDateLimit() + wxDateSpan::Day(); // first out-of-range
 
1095
 
 
1096
        wxBrush oorbrush = *wxLIGHT_GREY_BRUSH;
 
1097
        oorbrush.SetStyle(wxBRUSHSTYLE_FDIAGONAL_HATCH);
 
1098
 
 
1099
        HighlightRange(&dc, firstOOR, date, wxTRANSPARENT_PEN, &oorbrush);
 
1100
    }
 
1101
 
 
1102
#if DEBUG_PAINT
 
1103
    wxLogDebug("+++ finished painting");
 
1104
#endif
 
1105
}
 
1106
 
 
1107
void wxGenericCalendarCtrl::RefreshDate(const wxDateTime& date)
 
1108
{
 
1109
    RecalcGeometry();
 
1110
 
 
1111
    wxRect rect;
 
1112
 
 
1113
    // always refresh the whole row at once because our OnPaint() will draw
 
1114
    // the whole row anyhow - and this allows the small optimization in
 
1115
    // OnClick() below to work
 
1116
    rect.x = m_calendarWeekWidth;
 
1117
 
 
1118
    rect.y = (m_heightRow * GetWeek(date)) + m_rowOffset;
 
1119
 
 
1120
    rect.width = 7*m_widthCol;
 
1121
    rect.height = m_heightRow;
 
1122
 
 
1123
#ifdef __WXMSW__
 
1124
    // VZ: for some reason, the selected date seems to occupy more space under
 
1125
    //     MSW - this is probably some bug in the font size calculations, but I
 
1126
    //     don't know where exactly. This fix is ugly and leads to more
 
1127
    //     refreshes than really needed, but without it the selected days
 
1128
    //     leaves even more ugly underscores on screen.
 
1129
    rect.Inflate(0, 1);
 
1130
#endif // MSW
 
1131
 
 
1132
#if DEBUG_PAINT
 
1133
    wxLogDebug("*** refreshing week %d at (%d, %d)-(%d, %d)\n",
 
1134
           GetWeek(date),
 
1135
           rect.x, rect.y,
 
1136
           rect.x + rect.width, rect.y + rect.height);
 
1137
#endif
 
1138
 
 
1139
    Refresh(true, &rect);
 
1140
}
 
1141
 
 
1142
void wxGenericCalendarCtrl::HighlightRange(wxPaintDC* pDC, const wxDateTime& fromdate, const wxDateTime& todate, const wxPen* pPen, const wxBrush* pBrush)
 
1143
{
 
1144
    // Highlights the given range using pen and brush
 
1145
    // Does nothing if todate < fromdate
 
1146
 
 
1147
 
 
1148
#if DEBUG_PAINT
 
1149
    wxLogDebug("+++ HighlightRange: (%s) - (%s) +++", fromdate.Format("%d %m %Y"), todate.Format("%d %m %Y"));
 
1150
#endif
 
1151
 
 
1152
    if ( todate >= fromdate )
 
1153
    {
 
1154
        // do stuff
 
1155
        // date-coordinates
 
1156
        int fd, fw;
 
1157
        int td, tw;
 
1158
 
 
1159
        // implicit: both dates must be currently shown - checked by GetDateCoord
 
1160
        if ( GetDateCoord(fromdate, &fd, &fw) && GetDateCoord(todate, &td, &tw) )
 
1161
        {
 
1162
#if DEBUG_PAINT
 
1163
            wxLogDebug("Highlight range: (%i, %i) - (%i, %i)", fd, fw, td, tw);
 
1164
#endif
 
1165
            if ( ( (tw - fw) == 1 ) && ( td < fd ) )
 
1166
            {
 
1167
                // special case: interval 7 days or less not in same week
 
1168
                // split in two separate intervals
 
1169
                wxDateTime tfd = fromdate + wxDateSpan::Days(7-fd);
 
1170
                wxDateTime ftd = tfd + wxDateSpan::Day();
 
1171
#if DEBUG_PAINT
 
1172
                wxLogDebug("Highlight: Separate segments");
 
1173
#endif
 
1174
                // draw separately
 
1175
                HighlightRange(pDC, fromdate, tfd, pPen, pBrush);
 
1176
                HighlightRange(pDC, ftd, todate, pPen, pBrush);
 
1177
            }
 
1178
            else
 
1179
            {
 
1180
                int numpoints;
 
1181
                wxPoint corners[8]; // potentially 8 corners in polygon
 
1182
                wxCoord x0 = m_calendarWeekWidth;
 
1183
 
 
1184
                if ( fw == tw )
 
1185
                {
 
1186
                    // simple case: same week
 
1187
                    numpoints = 4;
 
1188
                    corners[0] = wxPoint(x0 + (fd - 1) * m_widthCol, (fw * m_heightRow) + m_rowOffset);
 
1189
                    corners[1] = wxPoint(x0 + (fd - 1) * m_widthCol, ((fw + 1 ) * m_heightRow) + m_rowOffset);
 
1190
                    corners[2] = wxPoint(x0 + td * m_widthCol, ((tw + 1) * m_heightRow) + m_rowOffset);
 
1191
                    corners[3] = wxPoint(x0 + td * m_widthCol, (tw * m_heightRow) + m_rowOffset);
 
1192
                }
 
1193
                else
 
1194
                {
 
1195
                    int cidx = 0;
 
1196
                    // "complex" polygon
 
1197
                    corners[cidx] = wxPoint(x0 + (fd - 1) * m_widthCol, (fw * m_heightRow) + m_rowOffset); cidx++;
 
1198
 
 
1199
                    if ( fd > 1 )
 
1200
                    {
 
1201
                        corners[cidx] = wxPoint(x0 + (fd - 1) * m_widthCol, ((fw + 1) * m_heightRow) + m_rowOffset); cidx++;
 
1202
                        corners[cidx] = wxPoint(x0, ((fw + 1) * m_heightRow) + m_rowOffset); cidx++;
 
1203
                    }
 
1204
 
 
1205
                    corners[cidx] = wxPoint(x0, ((tw + 1) * m_heightRow) + m_rowOffset); cidx++;
 
1206
                    corners[cidx] = wxPoint(x0 + td * m_widthCol, ((tw + 1) * m_heightRow) + m_rowOffset); cidx++;
 
1207
 
 
1208
                    if ( td < 7 )
 
1209
                    {
 
1210
                        corners[cidx] = wxPoint(x0 + td * m_widthCol, (tw * m_heightRow) + m_rowOffset); cidx++;
 
1211
                        corners[cidx] = wxPoint(x0 + 7 * m_widthCol, (tw * m_heightRow) + m_rowOffset); cidx++;
 
1212
                    }
 
1213
 
 
1214
                    corners[cidx] = wxPoint(x0 + 7 * m_widthCol, (fw * m_heightRow) + m_rowOffset); cidx++;
 
1215
 
 
1216
                    numpoints = cidx;
 
1217
                }
 
1218
 
 
1219
                // draw the polygon
 
1220
                pDC->SetBrush(*pBrush);
 
1221
                pDC->SetPen(*pPen);
 
1222
                pDC->DrawPolygon(numpoints, corners);
 
1223
            }
 
1224
        }
 
1225
    }
 
1226
    // else do nothing
 
1227
#if DEBUG_PAINT
 
1228
    wxLogDebug("--- HighlightRange ---");
 
1229
#endif
 
1230
}
 
1231
 
 
1232
bool wxGenericCalendarCtrl::GetDateCoord(const wxDateTime& date, int *day, int *week) const
 
1233
{
 
1234
    bool retval = true;
 
1235
 
 
1236
#if DEBUG_PAINT
 
1237
    wxLogDebug("+++ GetDateCoord: (%s) +++", date.Format("%d %m %Y"));
 
1238
#endif
 
1239
 
 
1240
    if ( IsDateShown(date) )
 
1241
    {
 
1242
        bool startOnMonday = HasFlag(wxCAL_MONDAY_FIRST);
 
1243
 
 
1244
        // Find day
 
1245
        *day = date.GetWeekDay();
 
1246
 
 
1247
        if ( *day == 0 ) // sunday
 
1248
        {
 
1249
            *day = ( startOnMonday ) ? 7 : 1;
 
1250
        }
 
1251
        else
 
1252
        {
 
1253
            *day += ( startOnMonday ) ? 0 : 1;
 
1254
        }
 
1255
 
 
1256
        int targetmonth = date.GetMonth() + (12 * date.GetYear());
 
1257
        int thismonth = m_date.GetMonth() + (12 * m_date.GetYear());
 
1258
 
 
1259
        // Find week
 
1260
        if ( targetmonth == thismonth )
 
1261
        {
 
1262
            *week = GetWeek(date);
 
1263
        }
 
1264
        else
 
1265
        {
 
1266
            if ( targetmonth < thismonth )
 
1267
            {
 
1268
                *week = 1; // trivial
 
1269
            }
 
1270
            else // targetmonth > thismonth
 
1271
            {
 
1272
                wxDateTime ldcm;
 
1273
                int lastweek;
 
1274
                int lastday;
 
1275
 
 
1276
                // get the datecoord of the last day in the month currently shown
 
1277
#if DEBUG_PAINT
 
1278
                wxLogDebug("     +++ LDOM +++");
 
1279
#endif
 
1280
                GetDateCoord(ldcm.SetToLastMonthDay(m_date.GetMonth(), m_date.GetYear()), &lastday, &lastweek);
 
1281
#if DEBUG_PAINT
 
1282
                wxLogDebug("     --- LDOM ---");
 
1283
#endif
 
1284
 
 
1285
                wxTimeSpan span = date - ldcm;
 
1286
 
 
1287
                int daysfromlast = span.GetDays();
 
1288
#if DEBUG_PAINT
 
1289
                wxLogDebug("daysfromlast: %i", daysfromlast);
 
1290
#endif
 
1291
                if ( daysfromlast + lastday > 7 ) // past week boundary
 
1292
                {
 
1293
                    int wholeweeks = (daysfromlast / 7);
 
1294
                    *week = wholeweeks + lastweek;
 
1295
                    if ( (daysfromlast - (7 * wholeweeks) + lastday) > 7 )
 
1296
                    {
 
1297
                        *week += 1;
 
1298
                    }
 
1299
                }
 
1300
                else
 
1301
                {
 
1302
                    *week = lastweek;
 
1303
                }
 
1304
            }
 
1305
        }
 
1306
    }
 
1307
    else
 
1308
    {
 
1309
        *day = -1;
 
1310
        *week = -1;
 
1311
        retval = false;
 
1312
    }
 
1313
 
 
1314
#if DEBUG_PAINT
 
1315
    wxLogDebug("--- GetDateCoord: (%s) = (%i, %i) ---", date.Format("%d %m %Y"), *day, *week);
 
1316
#endif
 
1317
 
 
1318
    return retval;
 
1319
}
 
1320
 
 
1321
// ----------------------------------------------------------------------------
 
1322
// mouse handling
 
1323
// ----------------------------------------------------------------------------
 
1324
 
 
1325
void wxGenericCalendarCtrl::OnDClick(wxMouseEvent& event)
 
1326
{
 
1327
    if ( HitTest(event.GetPosition()) != wxCAL_HITTEST_DAY )
 
1328
    {
 
1329
        event.Skip();
 
1330
    }
 
1331
    else
 
1332
    {
 
1333
        GenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED);
 
1334
    }
 
1335
}
 
1336
 
 
1337
void wxGenericCalendarCtrl::OnClick(wxMouseEvent& event)
 
1338
{
 
1339
    wxDateTime date;
 
1340
    wxDateTime::WeekDay wday;
 
1341
    switch ( HitTest(event.GetPosition(), &date, &wday) )
 
1342
    {
 
1343
        case wxCAL_HITTEST_DAY:
 
1344
            if ( IsDateInRange(date) )
 
1345
            {
 
1346
                ChangeDay(date);
 
1347
 
 
1348
                GenerateEvent(wxEVT_CALENDAR_SEL_CHANGED);
 
1349
 
 
1350
                // we know that the month/year never change when the user
 
1351
                // clicks on the control so there is no need to call
 
1352
                // GenerateAllChangeEvents() here, we know which event to send
 
1353
                GenerateEvent(wxEVT_CALENDAR_DAY_CHANGED);
 
1354
            }
 
1355
        break;
 
1356
 
 
1357
        case wxCAL_HITTEST_WEEK:
 
1358
        {
 
1359
            wxCalendarEvent send( this, date, wxEVT_CALENDAR_WEEK_CLICKED );
 
1360
            HandleWindowEvent( send );
 
1361
        }
 
1362
        break;
 
1363
 
 
1364
        case wxCAL_HITTEST_HEADER:
 
1365
            {
 
1366
                wxCalendarEvent eventWd(this, GetDate(),
 
1367
                                        wxEVT_CALENDAR_WEEKDAY_CLICKED);
 
1368
                eventWd.SetWeekDay(wday);
 
1369
                (void)GetEventHandler()->ProcessEvent(eventWd);
 
1370
            }
 
1371
            break;
 
1372
 
 
1373
        case wxCAL_HITTEST_DECMONTH:
 
1374
        case wxCAL_HITTEST_INCMONTH:
 
1375
        case wxCAL_HITTEST_SURROUNDING_WEEK:
 
1376
            SetDateAndNotify(date); // we probably only want to refresh the control. No notification.. (maybe as an option?)
 
1377
            break;
 
1378
 
 
1379
        default:
 
1380
            wxFAIL_MSG(wxT("unknown hittest code"));
 
1381
            // fall through
 
1382
 
 
1383
        case wxCAL_HITTEST_NOWHERE:
 
1384
            event.Skip();
 
1385
            break;
 
1386
    }
 
1387
 
 
1388
    // as we don't (always) skip the message, we're not going to receive the
 
1389
    // focus on click by default if we don't do it ourselves
 
1390
    SetFocus();
 
1391
}
 
1392
 
 
1393
wxCalendarHitTestResult wxGenericCalendarCtrl::HitTest(const wxPoint& pos,
 
1394
                                                wxDateTime *date,
 
1395
                                                wxDateTime::WeekDay *wd)
 
1396
{
 
1397
    RecalcGeometry();
 
1398
 
 
1399
    // the position where the calendar really begins
 
1400
    wxCoord x0 = m_calendarWeekWidth;
 
1401
 
 
1402
    if ( HasFlag(wxCAL_SEQUENTIAL_MONTH_SELECTION) )
 
1403
    {
 
1404
        // Header: month
 
1405
 
 
1406
        // we need to find out if the hit is on left arrow, on month or on right arrow
 
1407
        // left arrow?
 
1408
        if ( m_leftArrowRect.Contains(pos) )
 
1409
        {
 
1410
            if ( date )
 
1411
            {
 
1412
                if ( IsDateInRange(m_date - wxDateSpan::Month()) )
 
1413
                {
 
1414
                    *date = m_date - wxDateSpan::Month();
 
1415
                }
 
1416
                else
 
1417
                {
 
1418
                    *date = GetLowerDateLimit();
 
1419
                }
 
1420
            }
 
1421
 
 
1422
            return wxCAL_HITTEST_DECMONTH;
 
1423
        }
 
1424
 
 
1425
        if ( m_rightArrowRect.Contains(pos) )
 
1426
        {
 
1427
            if ( date )
 
1428
            {
 
1429
                if ( IsDateInRange(m_date + wxDateSpan::Month()) )
 
1430
                {
 
1431
                    *date = m_date + wxDateSpan::Month();
 
1432
                }
 
1433
                else
 
1434
                {
 
1435
                    *date = GetUpperDateLimit();
 
1436
                }
 
1437
            }
 
1438
 
 
1439
            return wxCAL_HITTEST_INCMONTH;
 
1440
        }
 
1441
    }
 
1442
 
 
1443
    if ( pos.x - x0 < 0 )
 
1444
    {
 
1445
        if ( pos.x >= 0 && pos.y > m_rowOffset + m_heightRow && pos.y <= m_rowOffset + m_heightRow * 7 )
 
1446
        {
 
1447
            if ( date )
 
1448
            {
 
1449
                *date = GetStartDate();
 
1450
                *date += wxDateSpan::Week() * (( pos.y - m_rowOffset ) / m_heightRow - 1 );
 
1451
            }
 
1452
            if ( wd )
 
1453
                *wd = GetWeekStart();
 
1454
            return wxCAL_HITTEST_WEEK;
 
1455
        }
 
1456
        else    // early exit -> the rest of the function checks for clicks on days
 
1457
            return wxCAL_HITTEST_NOWHERE;
 
1458
    }
 
1459
 
 
1460
    // header: week days
 
1461
    int wday = (pos.x - x0) / m_widthCol;
 
1462
    if ( wday > 6 )
 
1463
        return wxCAL_HITTEST_NOWHERE;
 
1464
    if ( pos.y < (m_heightRow + m_rowOffset))
 
1465
    {
 
1466
        if ( pos.y > m_rowOffset )
 
1467
        {
 
1468
            if ( wd )
 
1469
            {
 
1470
                if ( HasFlag(wxCAL_MONDAY_FIRST) )
 
1471
                {
 
1472
                    wday = wday == 6 ? 0 : wday + 1;
 
1473
                }
 
1474
 
 
1475
                *wd = (wxDateTime::WeekDay)wday;
 
1476
            }
 
1477
 
 
1478
            return wxCAL_HITTEST_HEADER;
 
1479
        }
 
1480
        else
 
1481
        {
 
1482
            return wxCAL_HITTEST_NOWHERE;
 
1483
        }
 
1484
    }
 
1485
 
 
1486
    int week = (pos.y - (m_heightRow + m_rowOffset)) / m_heightRow;
 
1487
    if ( week >= 6 || wday >= 7 )
 
1488
    {
 
1489
        return wxCAL_HITTEST_NOWHERE;
 
1490
    }
 
1491
 
 
1492
    wxDateTime dt = GetStartDate() + wxDateSpan::Days(7*week + wday);
 
1493
 
 
1494
    if ( IsDateShown(dt) )
 
1495
    {
 
1496
        if ( date )
 
1497
            *date = dt;
 
1498
 
 
1499
        if ( dt.GetMonth() == m_date.GetMonth() )
 
1500
        {
 
1501
 
 
1502
            return wxCAL_HITTEST_DAY;
 
1503
        }
 
1504
        else
 
1505
        {
 
1506
            return wxCAL_HITTEST_SURROUNDING_WEEK;
 
1507
        }
 
1508
    }
 
1509
    else
 
1510
    {
 
1511
        return wxCAL_HITTEST_NOWHERE;
 
1512
    }
 
1513
}
 
1514
 
 
1515
// ----------------------------------------------------------------------------
 
1516
// subcontrols events handling
 
1517
// ----------------------------------------------------------------------------
 
1518
 
 
1519
void wxGenericCalendarCtrl::OnMonthChange(wxCommandEvent& event)
 
1520
{
 
1521
    wxDateTime::Tm tm = m_date.GetTm();
 
1522
 
 
1523
    wxDateTime::Month mon = (wxDateTime::Month)event.GetInt();
 
1524
    if ( tm.mday > wxDateTime::GetNumberOfDays(mon, tm.year) )
 
1525
    {
 
1526
        tm.mday = wxDateTime::GetNumberOfDays(mon, tm.year);
 
1527
    }
 
1528
 
 
1529
    wxDateTime dt(tm.mday, mon, tm.year);
 
1530
    if ( AdjustDateToRange(&dt) )
 
1531
    {
 
1532
        // The date must have been changed to ensure it's in valid range,
 
1533
        // reflect this in the month choice control.
 
1534
        m_comboMonth->SetSelection(dt.GetMonth());
 
1535
    }
 
1536
 
 
1537
    SetDateAndNotify(dt);
 
1538
}
 
1539
 
 
1540
void wxGenericCalendarCtrl::HandleYearChange(wxCommandEvent& event)
 
1541
{
 
1542
    int year = (int)event.GetInt();
 
1543
    if ( year == INT_MIN )
 
1544
    {
 
1545
        // invalid year in the spin control, ignore it
 
1546
        return;
 
1547
    }
 
1548
 
 
1549
    wxDateTime::Tm tm = m_date.GetTm();
 
1550
 
 
1551
    if ( tm.mday > wxDateTime::GetNumberOfDays(tm.mon, year) )
 
1552
    {
 
1553
        tm.mday = wxDateTime::GetNumberOfDays(tm.mon, year);
 
1554
    }
 
1555
 
 
1556
    wxDateTime dt(tm.mday, tm.mon, year);
 
1557
    if ( AdjustDateToRange(&dt) )
 
1558
    {
 
1559
        // As above, if the date was changed to keep it in valid range, its
 
1560
        // possibly changed year must be shown in the GUI.
 
1561
        m_spinYear->SetValue(dt.GetYear());
 
1562
    }
 
1563
 
 
1564
    SetDateAndNotify(dt);
 
1565
}
 
1566
 
 
1567
void wxGenericCalendarCtrl::OnYearChange(wxSpinEvent& event)
 
1568
{
 
1569
    HandleYearChange( event );
 
1570
}
 
1571
 
 
1572
void wxGenericCalendarCtrl::OnYearTextChange(wxCommandEvent& event)
 
1573
{
 
1574
    SetUserChangedYear();
 
1575
    HandleYearChange(event);
 
1576
}
 
1577
 
 
1578
// Responds to colour changes, and passes event on to children.
 
1579
void wxGenericCalendarCtrl::OnSysColourChanged(wxSysColourChangedEvent& event)
 
1580
{
 
1581
    // reinit colours
 
1582
    InitColours();
 
1583
 
 
1584
    // Propagate the event to the children
 
1585
    wxControl::OnSysColourChanged(event);
 
1586
 
 
1587
    // Redraw control area
 
1588
    SetBackgroundColour(m_colBackground);
 
1589
    Refresh();
 
1590
}
 
1591
 
 
1592
// ----------------------------------------------------------------------------
 
1593
// keyboard interface
 
1594
// ----------------------------------------------------------------------------
 
1595
 
 
1596
void wxGenericCalendarCtrl::OnChar(wxKeyEvent& event)
 
1597
{
 
1598
    switch ( event.GetKeyCode() )
 
1599
    {
 
1600
        case wxT('+'):
 
1601
        case WXK_ADD:
 
1602
            SetDateAndNotify(m_date + wxDateSpan::Year());
 
1603
            break;
 
1604
 
 
1605
        case wxT('-'):
 
1606
        case WXK_SUBTRACT:
 
1607
            SetDateAndNotify(m_date - wxDateSpan::Year());
 
1608
            break;
 
1609
 
 
1610
        case WXK_PAGEUP:
 
1611
            SetDateAndNotify(m_date - wxDateSpan::Month());
 
1612
            break;
 
1613
 
 
1614
        case WXK_PAGEDOWN:
 
1615
            SetDateAndNotify(m_date + wxDateSpan::Month());
 
1616
            break;
 
1617
 
 
1618
        case WXK_RIGHT:
 
1619
            if ( event.ControlDown() )
 
1620
            {
 
1621
                wxDateTime target = m_date.SetToNextWeekDay(GetWeekEnd());
 
1622
                AdjustDateToRange(&target);
 
1623
                SetDateAndNotify(target);
 
1624
            }
 
1625
            else
 
1626
                SetDateAndNotify(m_date + wxDateSpan::Day());
 
1627
            break;
 
1628
 
 
1629
        case WXK_LEFT:
 
1630
            if ( event.ControlDown() )
 
1631
            {
 
1632
                wxDateTime target = m_date.SetToPrevWeekDay(GetWeekStart());
 
1633
                AdjustDateToRange(&target);
 
1634
                SetDateAndNotify(target);
 
1635
            }
 
1636
            else
 
1637
                SetDateAndNotify(m_date - wxDateSpan::Day());
 
1638
            break;
 
1639
 
 
1640
        case WXK_UP:
 
1641
            SetDateAndNotify(m_date - wxDateSpan::Week());
 
1642
            break;
 
1643
 
 
1644
        case WXK_DOWN:
 
1645
            SetDateAndNotify(m_date + wxDateSpan::Week());
 
1646
            break;
 
1647
 
 
1648
        case WXK_HOME:
 
1649
            if ( event.ControlDown() )
 
1650
                SetDateAndNotify(wxDateTime::Today());
 
1651
            else
 
1652
                SetDateAndNotify(wxDateTime(1, m_date.GetMonth(), m_date.GetYear()));
 
1653
            break;
 
1654
 
 
1655
        case WXK_END:
 
1656
            SetDateAndNotify(wxDateTime(m_date).SetToLastMonthDay());
 
1657
            break;
 
1658
 
 
1659
        case WXK_RETURN:
 
1660
            GenerateEvent(wxEVT_CALENDAR_DOUBLECLICKED);
 
1661
            break;
 
1662
 
 
1663
        default:
 
1664
            event.Skip();
 
1665
    }
 
1666
}
 
1667
 
 
1668
// ----------------------------------------------------------------------------
 
1669
// holidays handling
 
1670
// ----------------------------------------------------------------------------
 
1671
 
 
1672
void wxGenericCalendarCtrl::SetHoliday(size_t day)
 
1673
{
 
1674
    wxCHECK_RET( day > 0 && day < 32, wxT("invalid day in SetHoliday") );
 
1675
 
 
1676
    wxCalendarDateAttr *attr = GetAttr(day);
 
1677
    if ( !attr )
 
1678
    {
 
1679
        attr = new wxCalendarDateAttr;
 
1680
    }
 
1681
 
 
1682
    attr->SetHoliday(true);
 
1683
 
 
1684
    // can't use SetAttr() because it would delete this pointer
 
1685
    m_attrs[day - 1] = attr;
 
1686
}
 
1687
 
 
1688
void wxGenericCalendarCtrl::ResetHolidayAttrs()
 
1689
{
 
1690
    for ( size_t day = 0; day < 31; day++ )
 
1691
    {
 
1692
        if ( m_attrs[day] )
 
1693
        {
 
1694
            m_attrs[day]->SetHoliday(false);
 
1695
        }
 
1696
    }
 
1697
}
 
1698
 
 
1699
void wxGenericCalendarCtrl::Mark(size_t day, bool mark)
 
1700
{
 
1701
    wxCHECK_RET( day > 0 && day < 32, wxT("invalid day in Mark") );
 
1702
 
 
1703
    const wxCalendarDateAttr& m = wxCalendarDateAttr::GetMark();
 
1704
    if (mark) {
 
1705
        if ( m_attrs[day - 1] )
 
1706
            AddAttr(m_attrs[day - 1], m);
 
1707
        else
 
1708
            SetAttr(day, new wxCalendarDateAttr(m));
 
1709
    }
 
1710
    else {
 
1711
        if ( m_attrs[day - 1] )
 
1712
            DelAttr(m_attrs[day - 1], m);
 
1713
    }
 
1714
}
 
1715
 
 
1716
//static
 
1717
wxVisualAttributes
 
1718
wxGenericCalendarCtrl::GetClassDefaultAttributes(wxWindowVariant variant)
 
1719
{
 
1720
    // Use the same color scheme as wxListBox
 
1721
    return wxListBox::GetClassDefaultAttributes(variant);
 
1722
}
 
1723
 
 
1724
#endif // wxUSE_CALENDARCTRL