Bumped copyright dates for 2013
[barry.git] / desktop / src / CalendarEditDlg.cc
blob4de8d5e312bcda838fa7f94bc4f28fd4d7181144
1 ///
2 /// \file CalendarEditDlg.cc
3 /// Dialog class to handle the editing of the Calendar record
4 ///
6 /*
7 Copyright (C) 2012-2013, Net Direct Inc. (http://www.netdirect.ca/)
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
22 #include "CalendarEditDlg.h"
23 #include "windowids.h"
24 #include <wx/valgen.h>
25 #include "wxval.h"
26 #include "util.h"
28 using namespace std;
29 using namespace Barry;
31 // begin wxGlade: ::extracode
32 // end wxGlade
35 //////////////////////////////////////////////////////////////////////////////
36 // CalendarEditDlg class
38 CalendarEditDlg::CalendarEditDlg(wxWindow* parent,
39 Barry::Calendar &rec,
40 bool editable,
41 const Barry::TimeZones *device_zones)
42 : wxDialog(parent, Dialog_CalendarEdit, _W("Calendar Record"))
43 , m_zones(device_zones ? device_zones : &m_static_zones)
44 , m_rec(rec)
45 , m_duration_hours(0)
46 , m_duration_minutes(0)
47 , m_reminder_hours(0)
48 , m_reminder_minutes(0)
49 , m_interval(0)
50 , m_relative_date(false)
52 // set all weekday 'bits' to false
53 for( int i = 0; i < 7; i++ )
54 m_weekdays[i] = false;
56 if( editable ) {
57 bottom_buttons = CreateButtonSizer(wxOK | wxCANCEL);
59 else {
60 bottom_buttons = CreateButtonSizer(wxCANCEL);
63 // begin wxGlade: CalendarEditDlg::CalendarEditDlg
64 label_1 = new wxStaticText(this, wxID_ANY, _W("Subject:"));
65 m_Subject = new wxTextCtrl(this, wxID_ANY, wxEmptyString);
66 label_2 = new wxStaticText(this, wxID_ANY, _W("Location:"));
67 m_Location = new wxTextCtrl(this, wxID_ANY, wxEmptyString);
68 static_line_1 = new wxStaticLine(this, wxID_ANY);
69 label_4 = new wxStaticText(this, wxID_ANY, _W("All Day Event:"));
70 m_AllDayCheck = new wxCheckBox(this, Dialog_CalendarEdit_AllDayCheck, wxEmptyString);
71 label_5 = new wxStaticText(this, wxID_ANY, _W("Start:"));
72 m_StartDateCtrl = new wxDatePickerCtrl(this, Dialog_CalendarEdit_StartDateCtrl, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxDP_DROPDOWN|wxDP_SHOWCENTURY);
73 m_StartHoursSpinner = new wxSpinCtrl(this, Dialog_CalendarEdit_StartHoursSpinner, wxT(""), wxDefaultPosition, wxDefaultSize, wxSP_WRAP|wxTE_NOHIDESEL, 0, 23);
74 label_11 = new wxStaticText(this, wxID_ANY, wxT(":"));
75 m_StartMinutesSpinner = new wxSpinCtrl(this, Dialog_CalendarEdit_StartMinutesSpinner, wxT(""), wxDefaultPosition, wxDefaultSize, wxSP_WRAP|wxTE_NOHIDESEL, 0, 59);
76 label_6 = new wxStaticText(this, wxID_ANY, _W("End:"));
77 m_EndDateCtrl = new wxDatePickerCtrl(this, Dialog_CalendarEdit_EndDateCtrl, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxDP_DROPDOWN|wxDP_SHOWCENTURY);
78 m_EndHoursSpinner = new wxSpinCtrl(this, Dialog_CalendarEdit_EndHoursSpinner, wxT(""), wxDefaultPosition, wxDefaultSize, wxSP_WRAP|wxTE_NOHIDESEL, 0, 23);
79 label_12 = new wxStaticText(this, wxID_ANY, wxT(":"));
80 m_EndMinutesSpinner = new wxSpinCtrl(this, Dialog_CalendarEdit_EndMinutesSpinner, wxT(""), wxDefaultPosition, wxDefaultSize, wxSP_WRAP|wxTE_NOHIDESEL, 0, 59);
81 label_7 = new wxStaticText(this, wxID_ANY, _W("Duration:"));
82 m_DurationHoursSpinner = new wxSpinCtrl(this, Dialog_CalendarEdit_DurationHoursSpinner, wxT(""), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 999);
83 label_13 = new wxStaticText(this, wxID_ANY, _W("hours and"));
84 m_DurationMinutesSpinner = new wxSpinCtrl(this, Dialog_CalendarEdit_DurationMinutesSpinner, wxT(""), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 59);
85 label_17 = new wxStaticText(this, wxID_ANY, _W("minutes."));
86 label_8 = new wxStaticText(this, wxID_ANY, _W("Time Zone:"));
87 const wxString m_TimezoneChoice_choices[] = {
88 _W("System Time Zone")
90 m_TimezoneChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 1, m_TimezoneChoice_choices, 0);
91 label_9 = new wxStaticText(this, wxID_ANY, _W("Show As:"));
93 const wxString m_ShowAsChoice_choices[] = {
94 wxT("Free"),
95 wxT("Tentative"),
96 wxT("Busy"),
97 wxT("Out of Office")
100 wxArrayString m_ShowAsChoice_choices;
101 m_ShowAsChoice_choices.Add( _W("Free") );
102 m_ShowAsChoice_choices.Add( _W("Tentative") );
103 m_ShowAsChoice_choices.Add( _W("Busy") );
104 m_ShowAsChoice_choices.Add( _W("Out of Office") );
106 m_ShowAsChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_ShowAsChoice_choices, 0);
107 label_10 = new wxStaticText(this, wxID_ANY, _W("Reminder:"));
108 m_ReminderHoursSpinner = new wxSpinCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 999);
109 label_13_copy = new wxStaticText(this, wxID_ANY, _W("hours and"));
110 m_ReminderMinutesSpinner = new wxSpinCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 59);
111 label_17_copy = new wxStaticText(this, wxID_ANY, _W("minutes."));
112 static_line_2 = new wxStaticLine(this, wxID_ANY);
113 label_18 = new wxStaticText(this, wxID_ANY, _W("Recurrence:"));
115 const wxString m_RecurrenceChoice_choices[] = {
116 wxT("None"),
117 wxT("Daily"),
118 wxT("Weekly"),
119 wxT("Monthly"),
120 wxT("Yearly")
123 wxArrayString m_RecurrenceChoice_choices;
124 m_RecurrenceChoice_choices.Add( _W("None") );
125 m_RecurrenceChoice_choices.Add( _W("Daily") );
126 m_RecurrenceChoice_choices.Add( _W("Weekly") );
127 m_RecurrenceChoice_choices.Add( _W("Monthly") );
128 m_RecurrenceChoice_choices.Add( _W("Yearly") );
130 m_RecurrenceChoice = new wxChoice(this, Dialog_CalendarEdit_RecurrenceChoice, wxDefaultPosition, wxDefaultSize, m_RecurrenceChoice_choices, 0);
131 RecurIntervalLabel = new wxStaticText(this, wxID_ANY, _W("Interval:"));
132 RecurIntervalLabelB = new wxStaticText(this, wxID_ANY, _W("Every"));
133 m_IntervalSpinner = new wxSpinCtrl(this, wxID_ANY, wxT("1"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 999);
134 m_IntervalUnitLabel = new wxStaticText(this, wxID_ANY, _W("days? weeks? months?"), wxDefaultPosition, wxDefaultSize, wxST_NO_AUTORESIZE);
135 RecurDaysLabel = new wxStaticText(this, wxID_ANY, _W("Days:"));
136 m_SunCheck = new wxCheckBox(this, wxID_ANY, wxT("S"));
137 m_MonCheck = new wxCheckBox(this, wxID_ANY, wxT("M"));
138 m_TueCheck = new wxCheckBox(this, wxID_ANY, wxT("T"));
139 m_WedCheck = new wxCheckBox(this, wxID_ANY, wxT("W"));
140 m_ThuCheck = new wxCheckBox(this, wxID_ANY, wxT("T"));
141 m_FriCheck = new wxCheckBox(this, wxID_ANY, wxT("F"));
142 m_SatCheck = new wxCheckBox(this, wxID_ANY, wxT("S"));
143 RecurRelativeDateLabel = new wxStaticText(this, wxID_ANY, _W("Relative Date:"));
144 m_RelativeDateCheck = new wxCheckBox(this, wxID_ANY, wxEmptyString);
145 RecurEndDateLabel = new wxStaticText(this, wxID_ANY, _W("End Date:"));
146 m_NeverEndsCheck = new wxCheckBox(this, Dialog_CalendarEdit_NeverEndsCheck, _W("Never ends"));
147 m_RecurEndDateCtrl = new wxDatePickerCtrl(this, wxID_ANY, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxDP_DROPDOWN|wxDP_SHOWCENTURY);
148 static_line_3 = new wxStaticLine(this, wxID_ANY);
149 label_14 = new wxStaticText(this, wxID_ANY, _W("Organizer:"));
150 m_OrganizerText = new wxTextCtrl(this, wxID_ANY, wxEmptyString);
151 label_15 = new wxStaticText(this, wxID_ANY, _W("Invited:"));
152 m_InvitedText = new wxTextCtrl(this, wxID_ANY, wxEmptyString);
153 label_16 = new wxStaticText(this, wxID_ANY, _W("Accepted By:"));
154 m_AcceptedByText = new wxTextCtrl(this, wxID_ANY, wxEmptyString);
155 static_line_4 = new wxStaticLine(this, wxID_ANY);
157 const wxString m_ClassRadioBox_choices[] = {
158 wxT("Public"),
159 wxT("Private"),
160 wxT("Confidential")
163 wxArrayString m_ClassRadioBox_choices;
164 m_ClassRadioBox_choices.Add( _W("Public") );
165 m_ClassRadioBox_choices.Add( _W("Private") );
166 m_ClassRadioBox_choices.Add( _W("Confidential") );
168 m_ClassRadioBox = new wxRadioBox(this, wxID_ANY, _W("Class"), wxDefaultPosition, wxDefaultSize, m_ClassRadioBox_choices, 3, wxRA_SPECIFY_COLS);
169 static_line_5 = new wxStaticLine(this, wxID_ANY);
170 label_3 = new wxStaticText(this, wxID_ANY, _W("Notes:"));
171 m_NotesText = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
173 set_properties();
174 do_layout();
175 // end wxGlade
177 m_top_sizer->Add(bottom_buttons, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, 5);
179 // fill the time zone control with real time zones
180 m_TimezoneChoice->Clear();
181 m_TimezoneChoice->Append(_W("Assume Local Timezone"), (void*)0);
182 Barry::TimeZones::const_iterator b, e;
183 for( b = m_zones->begin(), e = m_zones->end(); b != e; ++b ) {
184 m_TimezoneChoice->Append(
185 wxString(b->GetDescription().c_str(), wxConvUTF8),
186 (void*) &b->Index);
188 m_TimezoneChoice->SetSelection(0);
190 // layout again, in case sizes are different
191 RedoLayout();
194 void CalendarEditDlg::RedoLayout()
196 m_top_sizer->Fit(this);
197 Layout();
200 BEGIN_EVENT_TABLE(CalendarEditDlg, wxDialog)
201 // begin wxGlade: CalendarEditDlg::event_table
202 EVT_CHECKBOX(Dialog_CalendarEdit_AllDayCheck, CalendarEditDlg::OnAllDayEvent)
203 EVT_DATE_CHANGED(Dialog_CalendarEdit_StartDateCtrl, CalendarEditDlg::OnStartDateChanged)
204 EVT_SPINCTRL(Dialog_CalendarEdit_StartHoursSpinner, CalendarEditDlg::OnStartHoursSpin)
205 EVT_SPINCTRL(Dialog_CalendarEdit_StartMinutesSpinner, CalendarEditDlg::OnStartMinutesSpin)
206 EVT_DATE_CHANGED(Dialog_CalendarEdit_EndDateCtrl, CalendarEditDlg::OnEndDateChanged)
207 EVT_SPINCTRL(Dialog_CalendarEdit_EndHoursSpinner, CalendarEditDlg::OnEndHoursSpin)
208 EVT_SPINCTRL(Dialog_CalendarEdit_EndMinutesSpinner, CalendarEditDlg::OnEndMinutesSpin)
209 EVT_SPINCTRL(Dialog_CalendarEdit_DurationHoursSpinner, CalendarEditDlg::OnDurationHoursSpin)
210 EVT_SPINCTRL(Dialog_CalendarEdit_DurationMinutesSpinner, CalendarEditDlg::OnDurationMinutesSpin)
211 EVT_CHOICE(Dialog_CalendarEdit_RecurrenceChoice, CalendarEditDlg::OnRecurrenceChoice)
212 EVT_CHECKBOX(Dialog_CalendarEdit_NeverEndsCheck, CalendarEditDlg::OnEndDateCheckbox)
213 // end wxGlade
214 END_EVENT_TABLE();
217 void CalendarEditDlg::OnAllDayEvent(wxCommandEvent &event)
219 bool checked = m_AllDayCheck->IsChecked();
221 if( checked ) {
222 // set start time to date at 00:00 and end time at
223 // day + 1 at 00:00
225 // time
226 m_StartHoursSpinner->SetValue(0);
227 m_StartMinutesSpinner->SetValue(0);
228 m_EndHoursSpinner->SetValue(0);
229 m_EndMinutesSpinner->SetValue(0);
231 // date
232 m_StartDateCtrl->SetValue(m_StartDateCtrl->GetValue().GetDateOnly());
233 m_EndDateCtrl->SetValue(m_StartDateCtrl->GetValue().GetDateOnly() + wxDateSpan::Day());
235 // duration
236 m_DurationHoursSpinner->SetValue(24);
237 m_DurationMinutesSpinner->SetValue(0);
240 EnableAllDayMode(checked);
243 void CalendarEditDlg::OnStartDateChanged(wxDateEvent &event)
245 UpdateDuration();
248 void CalendarEditDlg::OnStartHoursSpin(wxSpinEvent &event)
250 UpdateDuration();
253 void CalendarEditDlg::OnStartMinutesSpin(wxSpinEvent &event)
255 UpdateDuration();
258 void CalendarEditDlg::OnEndDateChanged(wxDateEvent &event)
260 UpdateDuration();
263 void CalendarEditDlg::OnEndHoursSpin(wxSpinEvent &event)
265 UpdateDuration();
268 void CalendarEditDlg::OnEndMinutesSpin(wxSpinEvent &event)
270 UpdateDuration();
273 void CalendarEditDlg::OnDurationHoursSpin(wxSpinEvent &event)
275 UpdateEndDate();
278 void CalendarEditDlg::OnDurationMinutesSpin(wxSpinEvent &event)
280 UpdateEndDate();
283 void CalendarEditDlg::OnRecurrenceChoice(wxCommandEvent &event)
285 TransferDataFromWindow();
286 EnableRecurMode(m_rec.Recurring);
290 void CalendarEditDlg::OnEndDateCheckbox(wxCommandEvent &event)
292 m_RecurEndDateCtrl->Enable( !m_NeverEndsCheck->IsChecked() );
296 // wxGlade: add CalendarEditDlg event handlers
299 void CalendarEditDlg::set_properties()
301 // begin wxGlade: CalendarEditDlg::set_properties
302 SetTitle(_W("Calendar Event"));
303 m_Subject->SetFocus();
304 m_Subject->SetValidator(wxTextValidator(wxFILTER_NONE, m_strings.Add(m_rec.Subject)));
305 m_Location->SetValidator(wxTextValidator(wxFILTER_NONE, m_strings.Add(m_rec.Location)));
306 m_AllDayCheck->SetValidator(wxGenericValidator(&m_rec.AllDayEvent));
307 m_StartDateCtrl->SetMinSize(wxSize(110, -1));
308 m_StartDateCtrl->SetValidator(DateTimeValidator(&m_StartDateObj.m_date));
309 m_StartHoursSpinner->SetMinSize(wxSize(45, -1));
310 m_StartHoursSpinner->SetValidator(wxGenericValidator(&m_StartDateObj.m_hour));
311 m_StartMinutesSpinner->SetMinSize(wxSize(45, -1));
312 m_StartMinutesSpinner->SetValidator(wxGenericValidator(&m_StartDateObj.m_min));
313 m_EndDateCtrl->SetMinSize(wxSize(110, -1));
314 m_EndDateCtrl->SetValidator(DateTimeValidator(&m_EndDateObj.m_date));
315 m_EndHoursSpinner->SetMinSize(wxSize(45, -1));
316 m_EndHoursSpinner->SetValidator(wxGenericValidator(&m_EndDateObj.m_hour));
317 m_EndMinutesSpinner->SetMinSize(wxSize(45, -1));
318 m_EndMinutesSpinner->SetValidator(wxGenericValidator(&m_EndDateObj.m_min));
319 m_DurationHoursSpinner->SetMinSize(wxSize(45, -1));
320 m_DurationHoursSpinner->SetValidator(wxGenericValidator(&m_duration_hours));
321 m_DurationMinutesSpinner->SetMinSize(wxSize(45, -1));
322 m_DurationMinutesSpinner->SetValidator(wxGenericValidator(&m_duration_minutes));
323 m_TimezoneChoice->SetSelection(0);
324 m_ShowAsChoice->SetSelection(2);
325 m_ReminderHoursSpinner->SetMinSize(wxSize(45, -1));
326 m_ReminderHoursSpinner->SetToolTip(_W("Set Reminder to 0 to disable"));
327 m_ReminderHoursSpinner->SetValidator(wxGenericValidator(&m_reminder_hours));
328 m_ReminderMinutesSpinner->SetMinSize(wxSize(45, -1));
329 m_ReminderMinutesSpinner->SetToolTip(_W("Set Reminder to 0 to disable"));
330 m_ReminderMinutesSpinner->SetValidator(wxGenericValidator(&m_reminder_minutes));
331 m_RecurrenceChoice->SetValidator(wxGenericValidator(&m_recur_choice));
332 m_RecurrenceChoice->SetSelection(0);
333 m_IntervalSpinner->SetMinSize(wxSize(45, -1));
334 m_IntervalSpinner->SetValidator(wxGenericValidator(&m_interval));
335 m_SunCheck->SetValidator(wxGenericValidator(&m_weekdays[0]));
336 m_MonCheck->SetValidator(wxGenericValidator(&m_weekdays[1]));
337 m_TueCheck->SetValidator(wxGenericValidator(&m_weekdays[2]));
338 m_WedCheck->SetValidator(wxGenericValidator(&m_weekdays[3]));
339 m_ThuCheck->SetValidator(wxGenericValidator(&m_weekdays[4]));
340 m_FriCheck->SetValidator(wxGenericValidator(&m_weekdays[5]));
341 m_SatCheck->SetValidator(wxGenericValidator(&m_weekdays[6]));
342 RecurRelativeDateLabel->SetToolTip(_W("Relative monthly or yearly dates take the weekday of the start date into account. (eg. every first Sunday of month)"));
343 m_RelativeDateCheck->SetToolTip(_W("Relative monthly or yearly dates take the weekday of the start date into account. (eg. every first Sunday of month)"));
344 m_RelativeDateCheck->SetValidator(wxGenericValidator(&m_relative_date));
345 m_NeverEndsCheck->SetValidator(wxGenericValidator(&m_rec.Perpetual));
346 m_NeverEndsCheck->SetValue(1);
347 m_RecurEndDateCtrl->SetMinSize(wxSize(110, -1));
348 m_RecurEndDateCtrl->Enable(false);
349 m_RecurEndDateCtrl->SetValidator(DateTimeValidator(&m_RecurEndDateObj.m_date));
350 m_OrganizerText->SetValidator(wxTextValidator(wxFILTER_NONE, m_strings.Add(m_organizer)));
351 m_InvitedText->SetValidator(wxTextValidator(wxFILTER_NONE, m_strings.Add(m_invited)));
352 m_AcceptedByText->SetValidator(wxTextValidator(wxFILTER_NONE, m_strings.Add(m_accepted_by)));
353 m_ClassRadioBox->SetValidator(MakeRadioBoxValidator(&m_rec.ClassFlag).Add(Barry::Calendar::Public).Add(Barry::Calendar::Private).Add(Barry::Calendar::Confidential));
354 m_ClassRadioBox->SetSelection(0);
355 m_NotesText->SetMinSize(wxSize(-1, 61));
356 m_NotesText->SetValidator(wxTextValidator(wxFILTER_NONE, m_strings.Add(m_rec.Notes)));
357 // end wxGlade
361 void CalendarEditDlg::do_layout()
363 // begin wxGlade: CalendarEditDlg::do_layout
364 wxBoxSizer* sizer_surround = new wxBoxSizer(wxVERTICAL);
365 wxBoxSizer* sizer_1 = new wxBoxSizer(wxVERTICAL);
366 wxBoxSizer* sizer_2 = new wxBoxSizer(wxHORIZONTAL);
367 wxFlexGridSizer* grid_sizer_3 = new wxFlexGridSizer(3, 2, 5, 5);
368 wxFlexGridSizer* grid_sizer_4 = new wxFlexGridSizer(5, 2, 5, 5);
369 wxBoxSizer* sizer_8 = new wxBoxSizer(wxHORIZONTAL);
370 wxBoxSizer* m_DaysCtrlsSizer = new wxBoxSizer(wxHORIZONTAL);
371 wxBoxSizer* m_IntervalCtrlsSizer = new wxBoxSizer(wxHORIZONTAL);
372 wxFlexGridSizer* grid_sizer_2 = new wxFlexGridSizer(7, 2, 5, 5);
373 wxBoxSizer* sizer_5_copy = new wxBoxSizer(wxHORIZONTAL);
374 wxBoxSizer* sizer_5 = new wxBoxSizer(wxHORIZONTAL);
375 wxBoxSizer* sizer_4 = new wxBoxSizer(wxHORIZONTAL);
376 wxBoxSizer* sizer_3 = new wxBoxSizer(wxHORIZONTAL);
377 wxFlexGridSizer* grid_sizer_1 = new wxFlexGridSizer(2, 2, 5, 5);
378 grid_sizer_1->Add(label_1, 0, 0, 0);
379 grid_sizer_1->Add(m_Subject, 0, wxEXPAND, 0);
380 grid_sizer_1->Add(label_2, 0, 0, 0);
381 grid_sizer_1->Add(m_Location, 0, wxEXPAND, 0);
382 grid_sizer_1->AddGrowableCol(1);
383 sizer_1->Add(grid_sizer_1, 0, wxEXPAND, 0);
384 sizer_1->Add(static_line_1, 0, wxALL|wxEXPAND, 5);
385 grid_sizer_2->Add(label_4, 0, 0, 0);
386 grid_sizer_2->Add(m_AllDayCheck, 0, 0, 0);
387 grid_sizer_2->Add(label_5, 0, wxALIGN_CENTER_VERTICAL, 0);
388 sizer_3->Add(m_StartDateCtrl, 0, 0, 0);
389 sizer_3->Add(20, 20, 0, 0, 0);
390 sizer_3->Add(m_StartHoursSpinner, 0, 0, 0);
391 sizer_3->Add(label_11, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 1);
392 sizer_3->Add(m_StartMinutesSpinner, 0, 0, 0);
393 grid_sizer_2->Add(sizer_3, 1, wxEXPAND, 0);
394 grid_sizer_2->Add(label_6, 0, wxALIGN_CENTER_VERTICAL, 0);
395 sizer_4->Add(m_EndDateCtrl, 0, 0, 0);
396 sizer_4->Add(20, 20, 0, 0, 0);
397 sizer_4->Add(m_EndHoursSpinner, 0, 0, 0);
398 sizer_4->Add(label_12, 0, wxALL|wxALIGN_CENTER_VERTICAL, 1);
399 sizer_4->Add(m_EndMinutesSpinner, 0, 0, 0);
400 grid_sizer_2->Add(sizer_4, 1, wxEXPAND, 0);
401 grid_sizer_2->Add(label_7, 0, wxALIGN_CENTER_VERTICAL, 0);
402 sizer_5->Add(m_DurationHoursSpinner, 0, wxRIGHT, 5);
403 sizer_5->Add(label_13, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5);
404 sizer_5->Add(m_DurationMinutesSpinner, 0, wxRIGHT, 5);
405 sizer_5->Add(label_17, 0, wxALIGN_CENTER_VERTICAL, 0);
406 grid_sizer_2->Add(sizer_5, 1, wxEXPAND, 0);
407 grid_sizer_2->Add(label_8, 0, wxALIGN_CENTER_VERTICAL, 0);
408 grid_sizer_2->Add(m_TimezoneChoice, 0, 0, 0);
409 grid_sizer_2->Add(label_9, 0, wxALIGN_CENTER_VERTICAL, 0);
410 grid_sizer_2->Add(m_ShowAsChoice, 0, 0, 0);
411 grid_sizer_2->Add(label_10, 0, wxALIGN_CENTER_VERTICAL, 0);
412 sizer_5_copy->Add(m_ReminderHoursSpinner, 0, wxRIGHT, 5);
413 sizer_5_copy->Add(label_13_copy, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5);
414 sizer_5_copy->Add(m_ReminderMinutesSpinner, 0, wxRIGHT, 5);
415 sizer_5_copy->Add(label_17_copy, 0, wxALIGN_CENTER_VERTICAL, 0);
416 grid_sizer_2->Add(sizer_5_copy, 1, wxEXPAND, 0);
417 grid_sizer_2->AddGrowableCol(1);
418 sizer_1->Add(grid_sizer_2, 0, wxEXPAND, 0);
419 sizer_1->Add(static_line_2, 0, wxALL|wxEXPAND, 5);
420 grid_sizer_4->Add(label_18, 0, wxALIGN_CENTER_VERTICAL, 0);
421 grid_sizer_4->Add(m_RecurrenceChoice, 0, 0, 0);
422 grid_sizer_4->Add(RecurIntervalLabel, 0, wxALIGN_CENTER_VERTICAL, 0);
423 m_IntervalCtrlsSizer->Add(RecurIntervalLabelB, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5);
424 m_IntervalCtrlsSizer->Add(m_IntervalSpinner, 0, wxRIGHT, 5);
425 m_IntervalCtrlsSizer->Add(m_IntervalUnitLabel, 1, wxALIGN_CENTER_VERTICAL, 0);
426 grid_sizer_4->Add(m_IntervalCtrlsSizer, 1, wxEXPAND, 0);
427 grid_sizer_4->Add(RecurDaysLabel, 0, wxALIGN_CENTER_VERTICAL, 0);
428 m_DaysCtrlsSizer->Add(m_SunCheck, 0, wxRIGHT, 5);
429 m_DaysCtrlsSizer->Add(m_MonCheck, 0, wxRIGHT, 5);
430 m_DaysCtrlsSizer->Add(m_TueCheck, 0, wxRIGHT, 5);
431 m_DaysCtrlsSizer->Add(m_WedCheck, 0, wxRIGHT, 5);
432 m_DaysCtrlsSizer->Add(m_ThuCheck, 0, wxRIGHT, 5);
433 m_DaysCtrlsSizer->Add(m_FriCheck, 0, wxRIGHT, 5);
434 m_DaysCtrlsSizer->Add(m_SatCheck, 0, wxRIGHT, 5);
435 grid_sizer_4->Add(m_DaysCtrlsSizer, 1, wxEXPAND, 0);
436 grid_sizer_4->Add(RecurRelativeDateLabel, 0, wxALIGN_CENTER_VERTICAL, 0);
437 grid_sizer_4->Add(m_RelativeDateCheck, 0, 0, 0);
438 grid_sizer_4->Add(RecurEndDateLabel, 0, wxALIGN_CENTER_VERTICAL, 0);
439 sizer_8->Add(m_NeverEndsCheck, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 10);
440 sizer_8->Add(m_RecurEndDateCtrl, 0, wxALIGN_CENTER_VERTICAL, 0);
441 grid_sizer_4->Add(sizer_8, 1, wxEXPAND, 0);
442 grid_sizer_4->AddGrowableCol(1);
443 sizer_1->Add(grid_sizer_4, 0, wxEXPAND, 0);
444 sizer_1->Add(static_line_3, 0, wxALL|wxEXPAND, 5);
445 grid_sizer_3->Add(label_14, 0, wxALIGN_CENTER_VERTICAL, 0);
446 grid_sizer_3->Add(m_OrganizerText, 0, wxEXPAND, 0);
447 grid_sizer_3->Add(label_15, 0, wxALIGN_CENTER_VERTICAL, 0);
448 grid_sizer_3->Add(m_InvitedText, 0, wxEXPAND, 0);
449 grid_sizer_3->Add(label_16, 0, wxALIGN_CENTER_VERTICAL, 0);
450 grid_sizer_3->Add(m_AcceptedByText, 0, wxEXPAND, 0);
451 grid_sizer_3->AddGrowableCol(1);
452 sizer_1->Add(grid_sizer_3, 0, wxEXPAND, 0);
453 sizer_1->Add(static_line_4, 0, wxALL|wxEXPAND, 5);
454 sizer_1->Add(m_ClassRadioBox, 0, wxEXPAND, 0);
455 sizer_1->Add(static_line_5, 0, wxALL|wxEXPAND, 5);
456 sizer_2->Add(label_3, 0, wxRIGHT, 5);
457 sizer_2->Add(m_NotesText, 1, wxEXPAND, 0);
458 sizer_1->Add(sizer_2, 1, wxEXPAND, 0);
459 sizer_surround->Add(sizer_1, 1, wxALL|wxEXPAND, 10);
460 SetSizer(sizer_surround);
461 sizer_surround->Fit(this);
462 Layout();
463 // end wxGlade
465 m_top_sizer = sizer_surround;
468 bool CalendarEditDlg::TransferDataToWindow()
470 // prepare temporary variables, from record
472 m_organizer = m_rec.Organizer.ToCommaSeparated();
473 m_invited = m_rec.Invited.ToCommaSeparated();
474 m_accepted_by = m_rec.AcceptedBy.ToCommaSeparated();
476 m_StartDateObj.Set(m_rec.StartTime.Time);
477 m_EndDateObj.Set(m_rec.EndTime.Time);
479 int duration = m_rec.EndTime.Time - m_rec.StartTime.Time;
480 duration /= 60; // convert to minutes
481 if( m_rec.EndTime.Time >= m_rec.StartTime.Time ) {
482 m_duration_hours = duration / 60;
483 m_duration_minutes = duration % 60;
486 if( m_rec.NotificationTime.Time ) {
487 int span = m_rec.StartTime.Time - m_rec.NotificationTime.Time;
488 span /= 60; // convert to minutes
489 if( m_rec.StartTime.Time > m_rec.NotificationTime.Time ) {
490 m_reminder_hours = span / 60;
491 m_reminder_minutes = span % 60;
493 else {
494 m_reminder_hours = 0;
495 m_reminder_minutes = 15;
499 EnableAllDayMode(m_rec.AllDayEvent);
501 // set the timezone choice only if the record's data is valid
502 m_TimezoneChoice->SetSelection(0); // default to none
503 if( m_rec.TimeZoneValid ) {
504 TimeZones::const_iterator i = m_zones->Find(m_rec.TimeZoneCode);
505 if( i != m_zones->end() ) {
506 int array_index = i - m_zones->begin();
507 // select item, skipping 0's "none" option
508 m_TimezoneChoice->SetSelection(array_index + 1);
512 #define SA_FREE 0
513 #define SA_TENTATIVE 1
514 #define SA_BUSY 2
515 #define SA_OUT_OF_OFFICE 3
516 switch( m_rec.FreeBusyFlag )
518 case Barry::Calendar::Free:
519 m_ShowAsChoice->SetSelection(SA_FREE);
520 break;
522 case Barry::Calendar::Tentative:
523 m_ShowAsChoice->SetSelection(SA_TENTATIVE);
524 break;
526 case Barry::Calendar::Busy:
527 default:
528 m_ShowAsChoice->SetSelection(SA_BUSY);
529 break;
531 case Barry::Calendar::OutOfOffice:
532 m_ShowAsChoice->SetSelection(SA_OUT_OF_OFFICE);
533 break;
536 // Note that recur_choice values are (zero-based) in the following
537 // order:
538 // None, Daily, Weekly, Monthly, Yearly
539 #define RC_NONE 0
540 #define RC_DAILY 1
541 #define RC_WEEKLY 2
542 #define RC_MONTHLY 3
543 #define RC_YEARLY 4
545 if( m_rec.Recurring ) {
546 switch( m_rec.RecurringType )
548 case Barry::RecurBase::Day:
549 m_recur_choice = RC_DAILY;
550 m_relative_date = false;
551 break;
553 case Barry::RecurBase::MonthByDate:
554 m_recur_choice = RC_MONTHLY;
555 m_relative_date = false;
556 break;
558 case Barry::RecurBase::MonthByDay:
559 m_recur_choice = RC_MONTHLY;
560 m_relative_date = true;
561 break;
563 case Barry::RecurBase::YearByDate:
564 m_recur_choice = RC_YEARLY;
565 m_relative_date = false;
566 break;
568 case Barry::RecurBase::YearByDay:
569 m_recur_choice = RC_YEARLY;
570 m_relative_date = true;
571 break;
573 case Barry::RecurBase::Week:
574 m_recur_choice = RC_WEEKLY;
575 m_relative_date = false;
576 m_weekdays[0] = m_rec.WeekDays & CAL_WD_SUN;
577 m_weekdays[1] = m_rec.WeekDays & CAL_WD_MON;
578 m_weekdays[2] = m_rec.WeekDays & CAL_WD_TUE;
579 m_weekdays[3] = m_rec.WeekDays & CAL_WD_WED;
580 m_weekdays[4] = m_rec.WeekDays & CAL_WD_THU;
581 m_weekdays[5] = m_rec.WeekDays & CAL_WD_FRI;
582 m_weekdays[6] = m_rec.WeekDays & CAL_WD_SAT;
583 break;
585 default:
586 cerr << "Bad RecurringType in CalendarEditDlg" << endl;
587 m_recur_choice = RC_NONE;
588 m_relative_date = false;
591 else {
592 m_recur_choice = RC_NONE;
593 m_relative_date = false;
596 m_interval = m_rec.Interval;
598 m_RecurEndDateObj.Set(m_rec.RecurringEndTime.Time);
599 if( m_rec.Perpetual ) {
600 m_RecurEndDateCtrl->Enable(false);
602 else {
603 m_RecurEndDateCtrl->Enable();
606 EnableRecurMode(m_rec.Recurring);
608 m_strings.RefreshWx();
610 // let the base class call the validaors to do the rest
611 if( wxDialog::TransferDataToWindow() ) {
612 // on success, do just a little bit of fine tuning
613 MakeDateRecent(true, m_StartDateCtrl);
614 MakeDateRecent(true, m_EndDateCtrl);
615 MakeDateRecent(true, m_RecurEndDateCtrl);
616 return true;
618 else {
619 return false;
623 bool CalendarEditDlg::TransferDataFromWindow()
625 if( !wxDialog::TransferDataFromWindow() )
626 return false;
628 m_strings.Sync();
630 m_rec.Organizer.clear();
631 m_rec.Organizer.AddCommaSeparated(m_organizer);
633 m_rec.Invited.clear();
634 m_rec.Invited.AddCommaSeparated(m_invited);
636 m_rec.AcceptedBy.clear();
637 m_rec.AcceptedBy.AddCommaSeparated(m_accepted_by);
639 m_rec.StartTime.Time = m_StartDateObj.Get();
640 m_rec.EndTime.Time = m_EndDateObj.Get();
641 if( m_rec.EndTime.Time < m_rec.StartTime.Time ) {
642 wxMessageBox(_W("Start time must come before end time."),
643 _W("Validation Error"), wxOK | wxICON_INFORMATION,
644 this);
645 return false;
648 int span = ((m_reminder_hours * 60) + m_reminder_minutes) * 60;
649 m_rec.NotificationTime.Time = m_rec.StartTime.Time - span;
651 switch( m_ShowAsChoice->GetSelection() )
653 case SA_FREE:
654 m_rec.FreeBusyFlag = Barry::Calendar::Free;
655 break;
657 case SA_TENTATIVE:
658 m_rec.FreeBusyFlag = Barry::Calendar::Tentative;
659 break;
661 case SA_BUSY:
662 default:
663 m_rec.FreeBusyFlag = Barry::Calendar::Busy;
664 break;
666 case SA_OUT_OF_OFFICE:
667 m_rec.FreeBusyFlag = Barry::Calendar::OutOfOffice;
668 break;
671 // set the timezone choice only if the record's data is valid
672 int sel = m_TimezoneChoice->GetSelection();
673 if( sel > 0 ) {
674 m_rec.TimeZoneCode = (*m_zones)[sel-1].Index;
675 m_rec.TimeZoneValid = true;
677 else {
678 // default was selected
679 m_rec.TimeZoneValid = false;
682 // Note that recur_choice values are (zero-based) in the following
683 // order:
684 // None, Daily, Weekly, Monthly, Yearly
685 switch( m_recur_choice )
687 case RC_NONE:
688 default:
689 m_rec.Recurring = false;
690 break;
692 case RC_DAILY:
693 m_rec.Recurring = true;
694 m_rec.RecurringType = Barry::RecurBase::Day;
695 break;
697 case RC_WEEKLY:
698 m_rec.Recurring = true;
699 m_rec.RecurringType = Barry::RecurBase::Week;
700 m_rec.WeekDays = 0;
701 if( m_weekdays[0] ) m_rec.WeekDays |= CAL_WD_SUN;
702 if( m_weekdays[1] ) m_rec.WeekDays |= CAL_WD_MON;
703 if( m_weekdays[2] ) m_rec.WeekDays |= CAL_WD_TUE;
704 if( m_weekdays[3] ) m_rec.WeekDays |= CAL_WD_WED;
705 if( m_weekdays[4] ) m_rec.WeekDays |= CAL_WD_THU;
706 if( m_weekdays[5] ) m_rec.WeekDays |= CAL_WD_FRI;
707 if( m_weekdays[6] ) m_rec.WeekDays |= CAL_WD_SAT;
708 break;
710 case RC_MONTHLY:
711 m_rec.Recurring = true;
712 if( m_relative_date )
713 m_rec.RecurringType = Barry::RecurBase::MonthByDay;
714 else
715 m_rec.RecurringType = Barry::RecurBase::MonthByDate;
716 break;
718 case RC_YEARLY:
719 m_rec.Recurring = true;
720 if( m_relative_date )
721 m_rec.RecurringType = Barry::RecurBase::YearByDay;
722 else
723 m_rec.RecurringType = Barry::RecurBase::YearByDate;
724 break;
728 m_rec.Interval = m_interval;
730 if( !m_rec.Perpetual ) {
731 m_rec.RecurringEndTime.Time = m_RecurEndDateObj.Get();
734 return true;
737 void CalendarEditDlg::UpdateDuration()
739 TransferDataFromWindow();
741 if( m_EndDateObj.Get() < m_StartDateObj.Get() ) {
742 // error... end date cannot be before start date
743 // set end date to start date
744 m_EndDateCtrl->SetValue(m_StartDateCtrl->GetValue());
745 m_EndHoursSpinner->SetValue(m_StartHoursSpinner->GetValue());
746 m_EndMinutesSpinner->SetValue(m_StartMinutesSpinner->GetValue());
748 // duration is 0
749 m_DurationHoursSpinner->SetValue(0);
750 m_DurationMinutesSpinner->SetValue(0);
751 return;
753 else {
754 // set duration to time span of End - Start
755 time_t diff = m_EndDateObj.Get() - m_StartDateObj.Get();
756 diff /= 60; // convert to minutes
757 m_DurationHoursSpinner->SetValue(diff / 60);
758 m_DurationMinutesSpinner->SetValue(diff % 60);
762 void CalendarEditDlg::UpdateEndDate()
764 TransferDataFromWindow();
766 m_EndDateObj.Set( m_StartDateObj.Get() +
767 m_duration_hours * 60 * 60 +
768 m_duration_minutes * 60 );
770 m_EndDateCtrl->SetValue(wxDateTime(m_EndDateObj.m_date));
771 m_EndHoursSpinner->SetValue(m_EndDateObj.m_hour);
772 m_EndMinutesSpinner->SetValue(m_EndDateObj.m_min);
775 void CalendarEditDlg::EnableAllDayMode(bool all_day)
777 // if in all day mode, disable start time, end time, duration spinners
778 m_StartHoursSpinner->Enable(!all_day);
779 m_StartMinutesSpinner->Enable(!all_day);
780 m_EndHoursSpinner->Enable(!all_day);
781 m_EndMinutesSpinner->Enable(!all_day);
782 m_DurationHoursSpinner->Enable(!all_day);
783 m_DurationMinutesSpinner->Enable(!all_day);
786 void CalendarEditDlg::EnableRecurMode(bool recur)
788 // show all controls
789 RecurIntervalLabel->Show(recur);
790 RecurIntervalLabelB->Show(recur);
791 m_IntervalSpinner->Show(recur);
792 m_IntervalUnitLabel->Show(recur);
793 RecurDaysLabel->Show(recur);
794 m_SunCheck->Show(recur);
795 m_MonCheck->Show(recur);
796 m_TueCheck->Show(recur);
797 m_WedCheck->Show(recur);
798 m_ThuCheck->Show(recur);
799 m_FriCheck->Show(recur);
800 m_SatCheck->Show(recur);
801 RecurRelativeDateLabel->Show(recur);
802 m_RelativeDateCheck->Show(recur);
803 RecurEndDateLabel->Show(recur);
804 m_NeverEndsCheck->Show(recur);
805 m_RecurEndDateCtrl->Show(recur);
807 // enable based on choice
808 int choice = m_RecurrenceChoice->GetSelection();
809 m_SunCheck->Enable(choice == RC_WEEKLY);
810 m_MonCheck->Enable(choice == RC_WEEKLY);
811 m_TueCheck->Enable(choice == RC_WEEKLY);
812 m_WedCheck->Enable(choice == RC_WEEKLY);
813 m_ThuCheck->Enable(choice == RC_WEEKLY);
814 m_FriCheck->Enable(choice == RC_WEEKLY);
815 m_SatCheck->Enable(choice == RC_WEEKLY);
817 // update labels
818 if( recur ) {
819 switch( m_RecurrenceChoice->GetSelection() )
821 case RC_NONE:
822 default:
823 m_IntervalUnitLabel->SetLabel(_T(""));
824 break;
826 case RC_DAILY:
827 m_IntervalUnitLabel->SetLabel(_W("day(s)"));
828 break;
830 case RC_WEEKLY:
831 m_IntervalUnitLabel->SetLabel(_W("week(s)"));
832 break;
834 case RC_MONTHLY:
835 m_IntervalUnitLabel->SetLabel(_W("month(s)"));
836 break;
838 case RC_YEARLY:
839 m_IntervalUnitLabel->SetLabel(_W("year(s)"));
840 break;
844 RedoLayout();
849 // Note: this file is very similar to TaskEditDlg.cc, and should be kept
850 // in lock step as much as possible. They are in separate files, since
851 // the GUI code is generated with wxglade