1 // frmEventEditor.cpp - frmEventEditor form functions.
3 // (c) 2016-2017 Xestia Software Development.
5 // This file is part of Xestia Calendar.
7 // Xestia Calendar is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
11 // Xestia Calendar is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Calendar. If not, see <http://www.gnu.org/licenses/>
19 #include "frmEventEditor.h"
23 frmEventEditor::frmEventEditor( wxWindow* parent )
25 frmEventEditorADT( parent )
30 void frmEventEditor::SetupForm(CalendarDataStorage *dataStorage, XCALPreferences *preferences){
32 this->preferences = preferences;
33 this->dataStorage = dataStorage;
35 // Go thorugh the accounts and get the list of calendars associated
36 // with the account and add them to the list of available calendars.
38 CDSAccountList accountList = dataStorage->GetAccountList();
40 for (std::vector<CDSGetAccountInfo>::iterator accountSeek = accountList.accountList.begin();
41 accountSeek != accountList.accountList.end(); accountSeek++){
43 CDSCalendarList calendarList = dataStorage->GetCalendarList((*accountSeek).accountID);
45 for (std::vector<int>::iterator calendarSeek = calendarList.calendarList.begin();
46 calendarSeek != calendarList.calendarList.end(); calendarSeek++){
48 string combinedName = "";
50 combinedName = (*accountSeek).accountName;
51 combinedName += " : ";
53 CDSGetCalendarInfo calendarInfo = dataStorage->GetCalendar((*calendarSeek));
55 combinedName += calendarInfo.calendarName;
56 cmbCalendar->Append(wxString(combinedName.c_str(), wxConvUTF8));
57 calendarIDList.push_back(calendarInfo.calendarID);
63 // Check the edit mode and get the event data.
65 if (editMode == true){
67 CDSGetCalendarEntryInfo eventInfo = dataStorage->GetEvent(eventID);
69 // Set the calendar ID.
71 calendarID = eventInfo.calendarID;
73 // Set the calendar combination box to the name.
75 string combinedName = dataStorage->GetCalendar(calendarID).accountName;
76 combinedName += " : ";
77 combinedName += dataStorage->GetCalendar(eventInfo.calendarID).calendarName;
79 // Load the calendar info.
81 cmbCalendar->SetSelection(cmbCalendar->FindString(combinedName));
82 cmbCalendar->Show(false);
83 lblCalendar->Show(false);
88 // Load the data into the form.
90 txtEventName->SetValue(wxString(eventInfo.entryName.c_str(), wxConvUTF8));
91 txtEventDescription->SetValue(wxString(eventInfo.entryDescription.c_str(), wxConvUTF8));
93 // Load the start and end dates.
96 startDate.Set(eventInfo.entryStartDay, (wxDateTime::Month)(eventInfo.entryStartMonth -1), eventInfo.entryStartYear, 0, 0, 0);
97 dapStartDate->SetValue(startDate);
100 endDate.Set(eventInfo.entryEndDay, (wxDateTime::Month)(eventInfo.entryEndMonth -1), eventInfo.entryEndYear, 0, 0, 0);
101 dapEndDate->SetValue(endDate);
103 // Load the start and end times.
108 stringstream stringData;
110 stringData << setw(2) << setfill('0') << eventInfo.entryStartHour;
112 stringData << setw(2) << setfill('0') << eventInfo.entryStartMinute;
114 txtStartTime->SetValue((wxString)stringData.str());
117 stringData << setw(2) << setfill('0') << eventInfo.entryEndHour;
119 stringData << setw(2) << setfill('0') << eventInfo.entryEndMinute;
121 txtEndTime->SetValue((wxString)stringData.str());
125 eventFilePath = eventInfo.entryFilename;
127 // Load the required data.
129 eventData.LoadFile(eventFilePath);
131 // TODO: Set the duration data.
135 // Setup the date and time with some default values (today's date and time).
137 SetDefaultDateTime();
141 // Enable window updating and update window name.
144 enableUpdates = true;
148 void frmEventEditor::SetEditMode(bool editMode){
150 this->editMode = editMode;
154 void frmEventEditor::SaveContact(wxCommandEvent &event){
160 void frmEventEditor::SaveNewContact(wxCommandEvent &event){
167 // Reset the form for a new entry.
169 cmbCalendar->SetSelection(-1);
174 SetDefaultDateTime();
176 txtEventName->Clear();
177 txtEventDescription->Clear();
179 cmbCalendar->Show(true);
180 lblCalendar->Show(true);
181 szrDetails->Layout();
186 bool frmEventEditor::SaveContact(){
188 // Verify that a calendar has been selected.
190 if (cmbCalendar->GetSelection() == -1 && editMode == false){
192 wxMessageBox("Please select a calendar for this entry.", "No calendar selected", wxOK);
197 // Do verification of entry name (shouldn't be blank).
199 if (txtEventName->GetValue().IsEmpty()){
201 wxMessageBox("The event name cannot be left empty.", "Event name is empty", wxOK);
206 // Do verification of start time.
208 bool timeValid = false;
210 // TODO: Do verification of end time.
214 // TODO: Do verification of duration.
218 // TODO: Do verification that end date is later than
223 bool durationValid = false;
225 // Set the data into the calendar event object.
227 eventData.summaryData = string(txtEventName->GetValue().ToUTF8());
229 if (eventData.descriptionList.size() > 0)
231 eventData.descriptionList[0] = string(txtEventDescription->GetValue().ToUTF8());
235 eventData.descriptionList.push_back(string(txtEventDescription->GetValue().ToUTF8()));
236 eventData.descriptionListAltRep.push_back("");
237 eventData.descriptionListLanguage.push_back("");
238 eventData.descriptionListTokens.push_back("");
241 eventData.descriptionList.push_back(string(txtEventDescription->GetValue().ToUTF8()));
242 eventData.descriptionListAltRep.push_back("");
243 eventData.descriptionListLanguage.push_back("");
244 eventData.descriptionListTokens.push_back("");
246 stringstream stringData;
248 stringData << setw(4) << setfill('0') << dapStartDate->GetValue().GetYear();
249 stringData << setw(2) << setfill('0') << (dapStartDate->GetValue().GetMonth() + 1);
250 stringData << setw(2) << setfill('0') << dapStartDate->GetValue().GetDay();
252 stringData << txtStartTime->GetValue().ToStdString().substr(0, 2).c_str();
253 stringData << txtStartTime->GetValue().ToStdString().substr(3, 2).c_str();
256 eventData.dateTimeStartData = stringData.str();
257 eventData.dateTimeStampData = stringData.str();
261 stringData << setw(4) << setfill('0') << dapEndDate->GetValue().GetYear();
262 stringData << setw(2) << setfill('0') << (dapEndDate->GetValue().GetMonth() + 1);
263 stringData << setw(2) << setfill('0') << dapEndDate->GetValue().GetDay();
265 stringData << txtEndTime->GetValue().ToStdString().substr(0, 2).c_str();
266 stringData << txtEndTime->GetValue().ToStdString().substr(3, 2).c_str();
269 eventData.dateTimeEndData = stringData.str();
271 // TODO: Implement Duration.
273 if (editMode == false){
275 // This is a new event so create a new UUID.
277 string NewUUID = GenerateUUID();
279 // Setup the calendar directory path.
281 CDSGetCalendarInfo calendarInfo = dataStorage->GetCalendar(calendarIDList[cmbCalendar->GetSelection()]);
282 CDSGetAccountInfo accountInfo = dataStorage->GetAccount(calendarInfo.accountName);
284 string calendarDirectory = string(GetUserDir().ToUTF8());
285 calendarDirectory += "accounts";
286 calendarDirectory += "/";
287 calendarDirectory += string(preferences->accounts.GetAccountDirectory(accountInfo.accountPreferencesID).ToUTF8());
288 calendarDirectory += ".";
289 calendarDirectory += string(preferences->accounts.GetAccountType(accountInfo.accountPreferencesID).ToUTF8());
290 calendarDirectory += "/";
291 calendarDirectory += calendarInfo.calendarTextID;
292 calendarDirectory += "/";
294 string eventFile = calendarDirectory;
295 eventFile += NewUUID;
298 eventData.uniqueID = NewUUID;
302 CalendarObjectSaveResult saveResult = eventData.SaveFile(eventFile);
304 // Add the event to the calendar data storage.
306 CDSAddEntryResult addEventResult = dataStorage->AddEvent(calendarIDList[cmbCalendar->GetSelection()], eventFile);
308 // Post an event to show the new entry in
311 EventProperties *eventInfo = new EventProperties;
312 eventInfo->eventName = string(txtEventName->GetValue().ToUTF8());
313 eventInfo->eventDescipriton = string(txtEventDescription->GetValue().ToUTF8());
314 eventInfo->calendarID = calendarIDList[cmbCalendar->GetSelection()];
315 eventInfo->eventID = addEventResult.calendarEntryID;
316 eventInfo->eventYear = dapStartDate->GetValue().GetYear();
317 eventInfo->eventMonth = dapStartDate->GetValue().GetMonth();
318 eventInfo->eventDay = dapStartDate->GetValue().GetDay();
319 eventInfo->eventHour = atoi(txtStartTime->GetValue().ToStdString().substr(0, 2).c_str());
320 eventInfo->eventMinute = atoi(txtStartTime->GetValue().ToStdString().substr(3, 2).c_str());
321 eventInfo->eventSecond = 0;
323 wxCommandEvent addEvent(XCMAIN_ADDEVENT);
324 addEvent.SetClientData(eventInfo);
325 addEvent.SetId(ID_ADDENTRY);
326 wxPostEvent(this->GetParent(), addEvent);
328 eventFilePath = eventFile;
330 calendarID = eventInfo->calendarID;
332 eventID = addEventResult.calendarEntryID;
334 // Hide the calendar selection controls.
336 cmbCalendar->Show(false);
337 lblCalendar->Show(false);
339 szrDetails->Layout();
344 // Setup the calendar directory path.
346 CDSGetCalendarEntryInfo eventDataInfo = dataStorage->GetEvent(eventID);
350 CalendarObjectSaveResult saveResult = eventData.SaveFile(eventFilePath);
352 // Update the data in the calendar data storage.
354 CDSEditEntryResult editEventResult = dataStorage->UpdateEvent(eventID, eventFilePath);
356 // Post an event to update the new entry in
359 EventProperties *eventInfo = new EventProperties;
360 eventInfo->eventName = string(txtEventName->GetValue().ToUTF8());
361 eventInfo->eventDescipriton = string(txtEventDescription->GetValue().ToUTF8());
362 eventInfo->calendarID = calendarID;
363 eventInfo->eventID = eventID;
364 eventInfo->eventYear = dapStartDate->GetValue().GetYear();
365 eventInfo->eventMonth = dapStartDate->GetValue().GetMonth();
366 eventInfo->eventDay = dapStartDate->GetValue().GetDay();
367 eventInfo->eventHour = atoi(txtStartTime->GetValue().ToStdString().substr(0, 2).c_str());
368 eventInfo->eventMinute = atoi(txtStartTime->GetValue().ToStdString().substr(3, 2).c_str());
369 eventInfo->eventSecond = 0;
371 wxCommandEvent updateEvent(XCMAIN_UPDATEEVENT);
372 updateEvent.SetClientData(eventInfo);
373 updateEvent.SetId(ID_UPDATEENTRY);
374 wxPostEvent(this->GetParent(), updateEvent);
382 void frmEventEditor::CloseWindow(wxCommandEvent &event)
389 void frmEventEditor::CloseWindow(wxCloseEvent &event)
392 WindowData *deleteWindowData = new WindowData;
394 deleteWindowData->DataType = 1;
395 deleteWindowData->WindowPointer = (void*)this;
396 deleteWindowData->WindowID = windowID;
398 // Delete the window from the window list.
400 wxCommandEvent deleteEvent(XCMAIN_DELETEWINDOWINFO);
401 deleteEvent.SetId(ID_DELETEWINDOW);
402 deleteEvent.SetClientData(deleteWindowData);
403 wxPostEvent(this->GetParent(), deleteEvent);
409 bool frmEventEditor::ProcessEvent(wxEvent& event)
412 // Process the cut/copy/paste events.
414 // This section has been taken from the wxWidgets sample code of richtext.cpp
415 // so that simple Cut/Copy/Paste code can be made.
417 // As this code comes from the samples of the wxWidgets library, this is licenced
418 // under the wxWindows Library Licence and is compatable with the LGPL and is
419 // compatable with Xestia Address Book's licence.
421 if (event.IsCommandEvent() && !event.IsKindOf(CLASSINFO(wxChildFocusEvent))){
422 // Problem: we can get infinite recursion because the events
423 // climb back up to this frame, and repeat.
424 // Assume that command events don't cause another command event
425 // to be called, so we can rely on inCommand not being overwritten
427 static int s_eventType = 0;
428 static wxWindowID s_id = 0;
430 if (s_id != event.GetId() && s_eventType != event.GetEventType()){
432 s_eventType = event.GetEventType();
433 s_id = event.GetId();
435 wxWindow* focusWin = wxFindFocusDescendant(this);
436 if (focusWin && focusWin->GetEventHandler()->ProcessEvent(event)){
452 return wxFrame::ProcessEvent(event);
456 void frmEventEditor::CutText(wxCommandEvent &event){
460 void frmEventEditor::CopyText(wxCommandEvent &event){
464 void frmEventEditor::PasteText(wxCommandEvent &event){
468 void frmEventEditor::SetEventID(int eventID){
470 this->eventID = eventID;
474 void frmEventEditor::SetDefaultDateTime(){
476 wxDateTime DTNow = wxDateTime::Now();
480 string formattedTime = "";
482 dapStartDate->SetValue(DTNow);
484 if (DTNow.GetHour() < 10){
485 formattedTime += "0";
486 formattedTime += to_string(DTNow.GetHour());
488 formattedTime += to_string(DTNow.GetHour());
491 formattedTime += ":";
493 if (DTNow.GetMinute() < 10){
494 formattedTime += "0";
495 formattedTime += to_string(DTNow.GetMinute());
497 formattedTime += to_string(DTNow.GetMinute());
500 txtStartTime->SetValue((wxString)formattedTime);
502 dapEndDate->SetValue(DTNow.Add(oneHour));
504 formattedTime.clear();
506 if (DTNow.Add(oneHour.Hour()).GetHour() < 10){
507 formattedTime += "0";
508 formattedTime += to_string(DTNow.GetHour());
510 formattedTime += to_string(DTNow.GetHour());
513 formattedTime += ":";
515 if (DTNow.GetMinute() < 10){
516 formattedTime += "0";
517 formattedTime += to_string(DTNow.GetMinute());
519 formattedTime += to_string(DTNow.GetMinute());
522 txtEndTime->SetValue((wxString)formattedTime);
526 void frmEventEditor::SetWindowMenuItemID(int windowID)
529 this->windowID = windowID;
533 void frmEventEditor::ProcessCalendarControl(wxCommandEvent &event)
540 void frmEventEditor::ProcessEventName(wxCommandEvent &event)
547 void frmEventEditor::UpdateWindowName()
550 // Generate the window title.
552 wxString windowTitle;
554 if (cmbCalendar->GetSelection() == -1)
556 windowTitle += "(calendar not selected)";
560 windowTitle += cmbCalendar->GetStringSelection();
563 if (txtEventName->IsEmpty())
565 windowTitle += " - ";
566 windowTitle += "(unamed event)";
570 windowTitle += " - ";
571 windowTitle += txtEventName->GetValue();
574 SetTitle(windowTitle);
576 // Check if post window title updating is enabled before
577 // going any further.
579 if (enableUpdates == false)
584 WindowData *updateWindowData = new WindowData;
586 updateWindowData->DataType = 1;
587 updateWindowData->WindowPointer = (void*)this;
588 updateWindowData->WindowID = windowID;
590 // Delete the window from the window list.
592 wxCommandEvent updateEvent(XCMAIN_UPDATEWINDOWINFO);
593 updateEvent.SetId(ID_UPDATEWINDOW);
594 updateEvent.SetClientData(updateWindowData);
595 wxPostEvent(this->GetParent(), updateEvent);