// frmEventEditor.cpp - frmEventEditor form functions.
//
// (c) 2016-2017 Xestia Software Development.
//
// This file is part of Xestia Calendar.
//
// Xestia Calendar is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by the
// Free Software Foundation, version 3 of the license.
//
// Xestia Calendar is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with Xestia Calendar. If not, see
#include "frmEventEditor.h"
using namespace std;
frmEventEditor::frmEventEditor( wxWindow* parent )
:
frmEventEditorADT( parent )
{
}
void frmEventEditor::SetupForm(CalendarDataStorage *dataStorage, XCALPreferences *preferences){
this->preferences = preferences;
this->dataStorage = dataStorage;
// Go thorugh the accounts and get the list of calendars associated
// with the account and add them to the list of available calendars.
CDSAccountList accountList = dataStorage->GetAccountList();
for (std::vector::iterator accountSeek = accountList.accountList.begin();
accountSeek != accountList.accountList.end(); accountSeek++){
CDSCalendarList calendarList = dataStorage->GetCalendarList((*accountSeek).accountID);
for (std::vector::iterator calendarSeek = calendarList.calendarList.begin();
calendarSeek != calendarList.calendarList.end(); calendarSeek++){
string combinedName = "";
combinedName = (*accountSeek).accountName;
combinedName += " : ";
CDSGetCalendarInfo calendarInfo = dataStorage->GetCalendar((*calendarSeek));
combinedName += calendarInfo.calendarName;
cmbCalendar->Append((wxString)combinedName);
calendarIDList.push_back(calendarInfo.calendarID);
}
}
// Check the edit mode and get the event data.
if (editMode == true){
CDSGetCalendarEntryInfo eventInfo = dataStorage->GetEvent(eventID);
// Load the calendar info.
cmbCalendar->Show(false);
lblCalendar->Show(false);
szrDetails->Layout();
szrList->Layout();
// Load the data into the form.
txtEventName->SetValue(wxString(eventInfo.entryName));
txtEventDescription->SetValue(wxString(eventInfo.entryDescription));
// Load the start and end dates.
wxDateTime startDate;
startDate.Set(eventInfo.entryStartDay, (wxDateTime::Month)(eventInfo.entryStartMonth -1), eventInfo.entryStartYear, 0, 0, 0);
dapStartDate->SetValue(startDate);
wxDateTime endDate;
endDate.Set(eventInfo.entryEndDay, (wxDateTime::Month)(eventInfo.entryEndMonth -1), eventInfo.entryEndYear, 0, 0, 0);
dapEndDate->SetValue(endDate);
// Load the start and end times.
string startTime;
string endTime;
stringstream stringData;
stringData << setw(2) << setfill('0') << eventInfo.entryStartHour;
stringData << ":";
stringData << setw(2) << setfill('0') << eventInfo.entryStartMinute;
txtStartTime->SetValue((wxString)stringData.str());
stringData.str("");
stringData << setw(2) << setfill('0') << eventInfo.entryEndHour;
stringData << ":";
stringData << setw(2) << setfill('0') << eventInfo.entryEndMinute;
txtEndTime->SetValue((wxString)stringData.str());
// Set the filename.
eventFilePath = eventInfo.entryFilename;
// Load the required data.
eventData.LoadFile(eventFilePath);
// TODO: Set the duration data.
return;
}
// Setup the date and time with some default values (today's date and time).
SetDefaultDateTime();
}
void frmEventEditor::SetEditMode(bool editMode){
this->editMode = editMode;
}
void frmEventEditor::SaveContact(wxCommandEvent &event){
SaveContact();
}
void frmEventEditor::SaveNewContact(wxCommandEvent &event){
SaveContact();
// Reset the form for a new entry.
cmbCalendar->SetSelection(-1);
editMode = false;
eventData.Clear();
SetDefaultDateTime();
txtEventName->Clear();
txtEventDescription->Clear();
cmbCalendar->Show(true);
lblCalendar->Show(true);
szrDetails->Layout();
szrList->Layout();
}
void frmEventEditor::SaveContact(){
// Verify that a calendar has been selected.
if (cmbCalendar->GetSelection() == -1 && editMode == false){
wxMessageBox("Please select a calendar for this entry.", "No calendar selected", wxOK);
return;
}
// Do verification of entry name (shouldn't be blank).
if (txtEventName->GetValue().IsEmpty()){
wxMessageBox("The event name cannot be left empty.", "Event name is empty", wxOK);
return;
}
// Do verification of start time.
bool timeValid = false;
// TODO: Do verification of end time.
timeValid = false;
// TODO: Do verification of duration.
// TODO: Do verification that end date is later than
// the start date.
bool durationValid = false;
// Set the data into the calendar event object.
eventData.summaryData = txtEventName->GetValue().ToStdString();
eventData.descriptionList.push_back(txtEventDescription->GetValue().ToStdString());
eventData.descriptionListAltRep.push_back("");
eventData.descriptionListLanguage.push_back("");
eventData.descriptionListTokens.push_back("");
stringstream stringData;
stringData << setw(4) << setfill('0') << dapStartDate->GetValue().GetYear();
stringData << setw(2) << setfill('0') << (dapStartDate->GetValue().GetMonth() + 1);
stringData << setw(2) << setfill('0') << dapStartDate->GetValue().GetDay();
stringData << "T";
stringData << txtStartTime->GetValue().ToStdString().substr(0, 2).c_str();
stringData << txtStartTime->GetValue().ToStdString().substr(3, 2).c_str();
stringData << "00Z";
eventData.dateTimeStartData = stringData.str();
eventData.dateTimeStampData = stringData.str();
stringData.str("");
stringData << setw(4) << setfill('0') << dapEndDate->GetValue().GetYear();
stringData << setw(2) << setfill('0') << (dapEndDate->GetValue().GetMonth() + 1);
stringData << setw(2) << setfill('0') << dapEndDate->GetValue().GetDay();
stringData << "T";
stringData << txtEndTime->GetValue().ToStdString().substr(0, 2).c_str();
stringData << txtEndTime->GetValue().ToStdString().substr(3, 2).c_str();
stringData << "00Z";
eventData.dateTimeEndData = stringData.str();
// TODO: Implement Duration.
if (editMode == false){
// This is a new event so create a new UUID.
string NewUUID = GenerateUUID();
// Setup the calendar directory path.
CDSGetCalendarInfo calendarInfo = dataStorage->GetCalendar(calendarIDList[cmbCalendar->GetSelection()]);
CDSGetAccountInfo accountInfo = dataStorage->GetAccount(calendarInfo.accountName);
string calendarDirectory = GetUserDir().ToStdString();
calendarDirectory += "accounts";
calendarDirectory += "/";
calendarDirectory += preferences->accounts.GetAccountDirectory(accountInfo.accountPreferencesID).ToStdString();
calendarDirectory += ".";
calendarDirectory += preferences->accounts.GetAccountType(accountInfo.accountPreferencesID).ToStdString();
calendarDirectory += "/";
calendarDirectory += calendarInfo.calendarTextID;
calendarDirectory += "/";
string eventFile = calendarDirectory;
eventFile += NewUUID;
eventFile += ".ics";
eventData.uniqueID = NewUUID;
// Write the file.
CalendarObjectSaveResult saveResult = eventData.SaveFile(eventFile);
// Add the event to the calendar data storage.
CDSAddEntryResult addEventResult = dataStorage->AddEvent(calendarIDList[cmbCalendar->GetSelection()], eventFile);
// Post an event to show the new entry in
// the main window.
EventProperties *eventInfo = new EventProperties;
eventInfo->eventName = txtEventName->GetValue().ToStdString();
eventInfo->calendarID = calendarIDList[cmbCalendar->GetSelection()];
eventInfo->eventID = addEventResult.calendarEntryID;
eventInfo->eventYear = dapStartDate->GetValue().GetYear();
eventInfo->eventMonth = dapStartDate->GetValue().GetMonth();
eventInfo->eventDay = dapStartDate->GetValue().GetDay();
eventInfo->eventHour = atoi(txtStartTime->GetValue().ToStdString().substr(0, 2).c_str());
eventInfo->eventMinute = atoi(txtStartTime->GetValue().ToStdString().substr(3, 2).c_str());
eventInfo->eventSecond = 0;
wxCommandEvent addEvent(XCMAIN_ADDEVENT);
addEvent.SetClientData(eventInfo);
addEvent.SetId(ID_ADDENTRY);
wxPostEvent(this->GetParent(), addEvent);
eventFilePath = eventFile;
editMode = true;
eventID = addEventResult.calendarEntryID;
// Hide the calendar selection controls.
cmbCalendar->Show(false);
lblCalendar->Show(false);
szrDetails->Layout();
szrList->Layout();
} else {
// Setup the calendar directory path.
CDSGetCalendarEntryInfo eventDataInfo = dataStorage->GetEvent(eventID);
// Write the file.
CalendarObjectSaveResult saveResult = eventData.SaveFile(eventFilePath);
// Update the data in the calendar data storage.
CDSEditEntryResult editEventResult = dataStorage->UpdateEvent(eventID, eventFilePath);
// Post an event to update the new entry in
// the main window.
EventProperties *eventInfo = new EventProperties;
eventInfo->eventName = txtEventName->GetValue().ToStdString();
eventInfo->calendarID = calendarIDList[cmbCalendar->GetSelection()];
eventInfo->eventID = eventID;
eventInfo->eventYear = dapStartDate->GetValue().GetYear();
eventInfo->eventMonth = dapStartDate->GetValue().GetMonth();
eventInfo->eventDay = dapStartDate->GetValue().GetDay();
eventInfo->eventHour = atoi(txtStartTime->GetValue().ToStdString().substr(0, 2).c_str());
eventInfo->eventMinute = atoi(txtStartTime->GetValue().ToStdString().substr(3, 2).c_str());
eventInfo->eventSecond = 0;
wxCommandEvent updateEvent(XCMAIN_UPDATEEVENT);
updateEvent.SetClientData(eventInfo);
updateEvent.SetId(ID_UPDATEENTRY);
wxPostEvent(this->GetParent(), updateEvent);
}
}
void frmEventEditor::CloseWindow(wxCommandEvent &event){
this->Close();
}
bool frmEventEditor::ProcessEvent(wxEvent& event)
{
// Process the cut/copy/paste events.
// This section has been taken from the wxWidgets sample code of richtext.cpp
// so that simple Cut/Copy/Paste code can be made.
// As this code comes from the samples of the wxWidgets library, this is licenced
// under the wxWindows Library Licence and is compatable with the LGPL and is
// compatable with Xestia Address Book's licence.
if (event.IsCommandEvent() && !event.IsKindOf(CLASSINFO(wxChildFocusEvent))){
// Problem: we can get infinite recursion because the events
// climb back up to this frame, and repeat.
// Assume that command events don't cause another command event
// to be called, so we can rely on inCommand not being overwritten
static int s_eventType = 0;
static wxWindowID s_id = 0;
if (s_id != event.GetId() && s_eventType != event.GetEventType()){
s_eventType = event.GetEventType();
s_id = event.GetId();
wxWindow* focusWin = wxFindFocusDescendant(this);
if (focusWin && focusWin->GetEventHandler()->ProcessEvent(event)){
//s_command = NULL;
s_eventType = 0;
s_id = 0;
return true;
}
s_eventType = 0;
s_id = 0;
} else {
return false;
}
}
return wxFrame::ProcessEvent(event);
}
void frmEventEditor::CutText(wxCommandEvent &event){
}
void frmEventEditor::CopyText(wxCommandEvent &event){
}
void frmEventEditor::PasteText(wxCommandEvent &event){
}
void frmEventEditor::SetEventID(int eventID){
this->eventID = eventID;
}
void frmEventEditor::SetDefaultDateTime(){
wxDateTime DTNow = wxDateTime::Now();
wxTimeSpan oneHour;
string formattedTime = "";
dapStartDate->SetValue(DTNow);
if (DTNow.GetHour() < 10){
formattedTime += "0";
formattedTime += to_string(DTNow.GetHour());
} else {
formattedTime += to_string(DTNow.GetHour());
}
formattedTime += ":";
if (DTNow.GetMinute() < 10){
formattedTime += "0";
formattedTime += to_string(DTNow.GetMinute());
} else {
formattedTime += to_string(DTNow.GetMinute());
}
txtStartTime->SetValue((wxString)formattedTime);
dapEndDate->SetValue(DTNow.Add(oneHour));
formattedTime.clear();
if (DTNow.Add(oneHour.Hour()).GetHour() < 10){
formattedTime += "0";
formattedTime += to_string(DTNow.GetHour());
} else {
formattedTime += to_string(DTNow.GetHour());
}
formattedTime += ":";
if (DTNow.GetMinute() < 10){
formattedTime += "0";
formattedTime += to_string(DTNow.GetMinute());
} else {
formattedTime += to_string(DTNow.GetMinute());
}
txtEndTime->SetValue((wxString)formattedTime);
}