// XCCalendarDay.cpp - Xestia Calendar XCCalendarDay widget class.
//
// (c) 2016 Xestia Software Development.
//
// This file is part of Xestia Calendar.
//
// Xestia Address Book 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 Address Book 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 "XCCalendarDay.h"
using namespace std;
wxDEFINE_EVENT(XCCALENDARDAY_DESELECTOTHERENTRIES, wxCommandEvent);
wxDEFINE_EVENT(XCCALENDARDAY_DESELECTALLENTRIES, wxCommandEvent);
wxDEFINE_EVENT(XCCALENDARDAY_HIDEACCOUNTENTRIES, wxCommandEvent);
wxDEFINE_EVENT(XCCALENDARDAY_SHOWACCOUNTENTRIES, wxCommandEvent);
wxDEFINE_EVENT(XCCALENDARDAY_HIDECALENDARENTRIES, wxCommandEvent);
wxDEFINE_EVENT(XCCALENDARDAY_SHOWCALENDARENTRIES, wxCommandEvent);
wxDEFINE_EVENT(XCCALENDARDAY_DELETECALENDARENTRIES, wxCommandEvent);
wxDEFINE_EVENT(XCCALENDARDAY_DELETEENTRY, wxCommandEvent);
wxDEFINE_EVENT(XCCALENDARDAY_ADDENTRY, wxCommandEvent);
wxDEFINE_EVENT(XCCALENDARDAY_UPDATEENTRY, wxCommandEvent);
wxDEFINE_EVENT(XCCALENDARDAY_UPDATECALENDARCOLOUR, wxCommandEvent);
BEGIN_EVENT_TABLE(XCCalendarDay, wxPanel)
END_EVENT_TABLE()
XCCalendarDay::XCCalendarDay(wxWindow *parent, const wxString& title, const wxPoint& pos, const wxSize& size)
: wxPanel(parent, wxID_ANY, pos, size, wxTAB_TRAVERSAL, title){
this->SetMinSize( wxSize( 100,100 ) );
// Setup the top panel.
topPanel = new wxPanel(this, wxID_ANY, wxPoint(0,0), wxSize(50, 40), wxTAB_TRAVERSAL);
mainPanel = new wxPanel(this, wxID_ANY, wxPoint(0,0), wxSize(200, 200), wxTAB_TRAVERSAL);
// Setip the icons.
highPriorityIcon = new wxStaticBitmap(topPanel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize(32,32), 0);
alertIcon = new wxStaticBitmap(topPanel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize(32,32), 0);
wxMemoryInputStream alerticon(icons_alert32_png, sizeof(icons_alert32_png));
wxMemoryInputStream priorityicon(icons_priority32_png, sizeof(icons_priority32_png));
wxImage icons_alert_png(alerticon, wxBITMAP_TYPE_PNG);
wxBitmap imgAlertIcon(icons_alert_png, -1);
wxImage icons_priority_png(priorityicon, wxBITMAP_TYPE_PNG);
wxBitmap imgPriorityIcon(icons_priority_png, -1);
alertIcon->SetBitmap(imgAlertIcon);
highPriorityIcon->SetBitmap(imgPriorityIcon);
numberText = new wxStaticText(topPanel, wxID_ANY, wxT("09"), wxDefaultPosition, wxDefaultSize, 0);
numberText->SetFont(wxFont(24, 70, 90, 92, false, wxEmptyString));
topSectionSizer->Add(highPriorityIcon, 0, wxALL|wxALIGN_CENTER_VERTICAL, 0);
topSectionSizer->Add(alertIcon, 0, wxALL|wxALIGN_CENTER_VERTICAL, 0);
topSectionSizer->Add(0, 0, 1, wxEXPAND, 5);
topSectionSizer->Add(numberText, 0, wxALL|wxRIGHT|wxALIGN_CENTER_VERTICAL, 5);
// Setup the scrollable section.
eventListFrame = new wxScrolledWindow(mainPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
Colour eventColour;
eventColour.red = 40; eventColour.green = 80; eventColour.blue = 80;
eventListFrame->SetSizer(eventListFrameSizer);
eventListFrame->SetScrollRate(0,1);
eventListFrameSizer->Fit(eventListFrame);
eventListFrameSizer->Layout();
// Setup the scroll window.
mainSectionSizer->Add(eventListFrame, 1, wxGROW | wxALL, 5);
topPanel->SetSizer(topSectionSizer);
mainPanel->SetSizer(mainSectionSizer);
windowSizer->Add(topPanel, 1, wxEXPAND, 0);
windowSizer->Add(mainPanel, 1, wxEXPAND, 0);
this->SetSizer(windowSizer);
this->SetSize(size);
this->Layout();
this->Centre(wxBOTH);
UpdateTopIcons();
// Bind events to the control.
Bind(XCCALENDARDAY_DESELECTOTHERENTRIES, &XCCalendarDay::DeselectOthersEvent, this, ID_DESELECTOTHERENTRIES);
Bind(XCCALENDARDAY_DESELECTALLENTRIES, &XCCalendarDay::DeselectAllEvent, this, ID_DESELECTALLITEMS);
Bind(XCCALENDARDAY_HIDEACCOUNTENTRIES, &XCCalendarDay::HideAccountEntries, this, ID_HIDEENTRIES);
Bind(XCCALENDARDAY_SHOWACCOUNTENTRIES, &XCCalendarDay::ShowAccountEntries, this, ID_SHOWENTRIES);
Bind(XCCALENDARDAY_HIDECALENDARENTRIES, &XCCalendarDay::HideCalendarEntries, this, ID_HIDECALENDARENTRIES);
Bind(XCCALENDARDAY_SHOWCALENDARENTRIES, &XCCalendarDay::ShowCalendarEntries, this, ID_SHOWCALENDARENTRIES);
Bind(XCCALENDARDAY_DELETECALENDARENTRIES, &XCCalendarDay::DeleteCalendarEntries, this, ID_DELETECALENDARENTRIES);
Bind(XCCALENDARDAY_DELETEENTRY, &XCCalendarDay::DeleteCalendarEntry, this, ID_DELETEENTRY);
Bind(XCCALENDARDAY_ADDENTRY, &XCCalendarDay::AddCalendarEntry, this, ID_ADDENTRY);
Bind(XCCALENDARDAY_UPDATEENTRY, &XCCalendarDay::UpdateCalendarEntry, this, ID_UPDATEENTRY);
Bind(XCCALENDARDAY_UPDATECALENDARCOLOUR, &XCCalendarDay::UpdateCalendarColour, this, ID_UPDATECOLOUR);
}
XCCalendarDay::~XCCalendarDay(){
// Destory the controls from the widget.
Unbind(XCCALENDARDAY_DESELECTOTHERENTRIES, &XCCalendarDay::DeselectOthersEvent, this, ID_DESELECTOTHERENTRIES);
Unbind(XCCALENDARDAY_DESELECTALLENTRIES, &XCCalendarDay::DeselectAllEvent, this, ID_DESELECTALLITEMS);
Unbind(XCCALENDARDAY_HIDEACCOUNTENTRIES, &XCCalendarDay::HideAccountEntries, this, ID_HIDEENTRIES);
Unbind(XCCALENDARDAY_SHOWACCOUNTENTRIES, &XCCalendarDay::ShowAccountEntries, this, ID_SHOWENTRIES);
Unbind(XCCALENDARDAY_HIDECALENDARENTRIES, &XCCalendarDay::HideCalendarEntries, this, ID_HIDECALENDARENTRIES);
Unbind(XCCALENDARDAY_SHOWCALENDARENTRIES, &XCCalendarDay::ShowCalendarEntries, this, ID_SHOWCALENDARENTRIES);
Unbind(XCCALENDARDAY_DELETECALENDARENTRIES, &XCCalendarDay::DeleteCalendarEntries, this, ID_DELETECALENDARENTRIES);
Unbind(XCCALENDARDAY_DELETEENTRY, &XCCalendarDay::DeleteCalendarEntry, this, ID_DELETEENTRY);
Unbind(XCCALENDARDAY_ADDENTRY, &XCCalendarDay::AddCalendarEntry, this, ID_ADDENTRY);
Unbind(XCCALENDARDAY_UPDATEENTRY, &XCCalendarDay::UpdateCalendarEntry, this, ID_UPDATEENTRY);
Unbind(XCCALENDARDAY_UPDATECALENDARCOLOUR, &XCCalendarDay::UpdateCalendarColour, this, ID_UPDATECOLOUR);
for (vector::iterator calendarEntryIter = calendarEntryList.begin();
calendarEntryIter != calendarEntryList.end(); calendarEntryIter++){
delete((*calendarEntryIter));
}
eventListFrameSizer->Clear();
eventListFrame->SetSizer(nullptr, true);
mainSectionSizer->Clear();
topSectionSizer->Clear();
windowSizer->Clear();
delete alertIcon;
alertIcon = nullptr;
delete highPriorityIcon;
highPriorityIcon = nullptr;
delete eventListFrame;
eventListFrame = nullptr;
delete numberText;
numberText = nullptr;
delete topPanel;
topPanel = nullptr;
delete mainPanel;
mainPanel = nullptr;
calendarEntryList.clear();
this->SetSizer(nullptr, true);
monthViewPointer = nullptr;
dataStorage = nullptr;
}
void XCCalendarDay::UpdateTopIcons(){
bool alarmFound = false;
bool highPriorityFound = false;
for (vector::iterator entryIter = calendarEntryList.begin();
entryIter != calendarEntryList.end(); entryIter++){
if ((*entryIter)->GetDisplayAlarm() == true){
alarmFound = true;
}
if ((*entryIter)->GetDisplayHighPriority() == true){
highPriorityFound = true;
}
if (alarmFound == true && highPriorityFound == true){
break;
}
}
alertIcon->Show(alarmFound);
highPriorityIcon->Show(highPriorityFound);
}
void XCCalendarDay::ResizeFrameEvent(wxSizeEvent &sizeEvent)
{
// TODO: Check if window size is less than 120 pixels and if it is,
// switch to the small block mode.
// Refresh the window.
this->Refresh();
topPanel->Refresh();
mainPanel->Refresh();
topSectionSizer->Layout();
mainSectionSizer->Layout();
windowSizer->Layout();
}
void XCCalendarDay::DeselectOthersEvent(wxCommandEvent &deselectEvent)
{
int selectedEntryID = deselectEvent.GetInt();
wxCommandEvent deselectEntryEvent(XCCALENDARDAYENTRY_DESELECT);
deselectEntryEvent.SetId(ID_ENTRYDESELECT);
for (vector::iterator entryIter = calendarEntryList.begin();
entryIter != calendarEntryList.end(); entryIter++){
if ((*entryIter)->GetID() != selectedEntryID){
wxPostEvent((*entryIter), deselectEntryEvent);
}
}
// Send event notification to deselect the other calendar entries.
if (this->monthViewPointer != nullptr){
wxCommandEvent deselectMonthEvent(XCCALENDARMONTH_DESELECTOTHERENTRIES);
deselectMonthEvent.SetClientData(this);
deselectMonthEvent.SetId(ID_MONTHVIEWCLEARSELECTION);
wxPostEvent(this->monthViewPointer, deselectMonthEvent);
}
}
void XCCalendarDay::DeselectAllEvent(wxCommandEvent &deselectEvent)
{
int selectedEntryID = deselectEvent.GetInt();
wxCommandEvent deselectEntryEvent(XCCALENDARDAYENTRY_DESELECT);
deselectEntryEvent.SetId(ID_ENTRYDESELECT);
for (vector::iterator entryIter = calendarEntryList.begin();
entryIter != calendarEntryList.end(); entryIter++){
wxPostEvent((*entryIter), deselectEntryEvent);
}
}
void XCCalendarDay::SetupControl(int setupDay, int setupMonth, int setupYear, bool setupIsInMonth, XCCalendarMonthView *monthViewPointer, CalendarDataStorage *dataStorage, vector *hideAccounts, vector *hideCalendars)
{
this->dataStorage = dataStorage;
// Set the day
numberText->SetLabel(wxString::Format("%02i", setupDay));
calendarDay = setupDay;
// Set the month
calendarMonth = setupMonth;
// Set the year.
calendarYear = setupYear;
// Setup the Is In Month value.
isInMonth = setupIsInMonth;
if (isInMonth)
{
topPanel->SetBackgroundColour(wxColor(255,255,255));
mainPanel->SetBackgroundColour(wxColor(225,225,225));
eventListFrame->SetBackgroundColour(wxColor(225,225,225));
}
else
{
topPanel->SetBackgroundColour(wxColor(185,185,185));
mainPanel->SetBackgroundColour(wxColor(155,155,155));
eventListFrame->SetBackgroundColour(wxColor(155,155,155));
}
// Setup the month view pointer.
this->monthViewPointer = monthViewPointer;
// Setup the calendar items.
CDSEntryList calendarItems = dataStorage->GetEventListByDate(setupYear, setupMonth, setupDay);
for (int entrySeek = 0; entrySeek < calendarItems.entryList.size(); entrySeek++){
// Get the information about the calendar entry.
CDSGetCalendarEntryInfo newEntryInfo = dataStorage->GetEvent(calendarItems.entryList[entrySeek]);
CDSGetCalendarInfo newEntryCalendarInfo = dataStorage->GetCalendar(newEntryInfo.calendarID);
// Setup the calendar entry.
XCCalendarDayEntry *newEntry = new XCCalendarDayEntry(eventListFrame, newEntryInfo.entryName, wxDefaultPosition, wxDefaultSize, calendarItems.entryList[entrySeek]);
newEntry->SetColour(&newEntryCalendarInfo.calendarColour);
newEntry->SetTime(newEntryInfo.entryStartHour, newEntryInfo.entryStartMinute, newEntryInfo.entryStartSecond);
newEntry->SetEntryIDs(newEntryCalendarInfo.accountID, newEntryInfo.calendarID, newEntryInfo.calendarEntryID);
eventListFrameSizer->Add(newEntry, 0, wxEXPAND, 5);
wxSizerItem *afterSpacer = eventListFrameSizer->Add(0, 5, 0, 0, 5);
newEntry->SetAfterSpacer(afterSpacer);
// Go through the list of calendar entries to hide by account.
for (vector::iterator hideAccountsItem = hideAccounts->begin();
hideAccountsItem != hideAccounts->end(); hideAccountsItem++){
if (*hideAccountsItem == newEntryCalendarInfo.accountID){
newEntry->Show(false);
newEntry->GetAfterSpacer()->Show(false);
}
}
// Go through the list of calendar entries to hide by calendar.
for (vector::iterator hideCalendarsItem = hideCalendars->begin();
hideCalendarsItem != hideCalendars->end(); hideCalendarsItem++){
if (*hideCalendarsItem == newEntryInfo.calendarID){
newEntry->Show(false);
newEntry->GetAfterSpacer()->Show(false);
}
}
calendarEntryList.push_back(newEntry);
}
}
void XCCalendarDay::HideAccountEntries(wxCommandEvent &accountData){
// Go through each of the controls and hide the controls (and spacing) that
// have the matched account IDs.
int sizerPosition = 0;
for (vector::iterator calendarEntryIter = calendarEntryList.begin();
calendarEntryIter != calendarEntryList.end(); calendarEntryIter++){
(*calendarEntryIter)->SetShowAccountStatus(false);
if ((*calendarEntryIter)->GetAccountID() == accountData.GetInt()){
wxSizerItem *calendarItem = eventListFrameSizer->GetItem((*calendarEntryIter));
(*calendarEntryIter)->Show(false);
// Get the spacing and hide it as well.
wxSizerItem *afterSpacer = (*calendarEntryIter)->GetAfterSpacer();
afterSpacer->Show(false);
}
}
this->Refresh();
}
void XCCalendarDay::ShowAccountEntries(wxCommandEvent &accountData){
// Go through each of the controls and hide the controls (and spacing) that
// have the matched account IDs.
int sizerPosition = 0;
for (vector::iterator calendarEntryIter = calendarEntryList.begin();
calendarEntryIter != calendarEntryList.end(); calendarEntryIter++){
(*calendarEntryIter)->SetShowAccountStatus(true);
if ((*calendarEntryIter)->GetShowCalendarStatus() == false){
continue;
}
if ((*calendarEntryIter)->GetAccountID() == accountData.GetInt()){
wxSizerItem *calendarItem = eventListFrameSizer->GetItem((*calendarEntryIter));
(*calendarEntryIter)->Show(true);
// Get the spacing and hide it as well.
wxSizerItem *afterSpacer = (*calendarEntryIter)->GetAfterSpacer();
afterSpacer->Show(true);
}
}
this->Refresh();
}
void XCCalendarDay::HideCalendarEntries(wxCommandEvent &calendarData){
// Go through each of the controls and hide the controls (and spacing) that
// have the matched account IDs.
int sizerPosition = 0;
for (vector::iterator calendarEntryIter = calendarEntryList.begin();
calendarEntryIter != calendarEntryList.end(); calendarEntryIter++){
if ((*calendarEntryIter)->GetCalendarID() == calendarData.GetInt()){
(*calendarEntryIter)->SetShowCalendarStatus(false);
wxSizerItem *calendarItem = eventListFrameSizer->GetItem((*calendarEntryIter));
(*calendarEntryIter)->Show(false);
// Get the spacing and hide it as well.
wxSizerItem *afterSpacer = (*calendarEntryIter)->GetAfterSpacer();
afterSpacer->Show(false);
}
}
this->Refresh();
}
void XCCalendarDay::ShowCalendarEntries(wxCommandEvent &calendarData){
// Go through each of the controls and hide the controls (and spacing) that
// have the matched account IDs.
int sizerPosition = 0;
for (vector::iterator calendarEntryIter = calendarEntryList.begin();
calendarEntryIter != calendarEntryList.end(); calendarEntryIter++){
if ((*calendarEntryIter)->GetCalendarID() == calendarData.GetInt()){
(*calendarEntryIter)->SetShowCalendarStatus(true);
if ((*calendarEntryIter)->GetShowAccountStatus() == false){
// Don't show the calendar entry because the account status
// is set to hidden. Continue to the next one.
continue;
}
wxSizerItem *calendarItem = eventListFrameSizer->GetItem((*calendarEntryIter));
(*calendarEntryIter)->Show(true);
// Get the spacing and hide it as well.
wxSizerItem *afterSpacer = (*calendarEntryIter)->GetAfterSpacer();
afterSpacer->Show(true);
}
}
this->Refresh();
}
void XCCalendarDay::DeleteCalendarEntries(wxCommandEvent &calendarData){
vector::iterator> deleteEntriesList;
for (vector::iterator calendarEntryIter = calendarEntryList.begin();
calendarEntryIter != calendarEntryList.end(); calendarEntryIter++){
if ((*calendarEntryIter)->GetCalendarID() == calendarData.GetInt()){
wxSizerItem *calendarItem = eventListFrameSizer->GetItem((*calendarEntryIter));
(*calendarEntryIter)->Show(false);
// Get the spacing and hide it as well.
wxSizerItem *afterSpacer = (*calendarEntryIter)->GetAfterSpacer();
afterSpacer->Show(false);
delete afterSpacer;
afterSpacer = nullptr;
delete (*calendarEntryIter);
deleteEntriesList.push_back(calendarEntryIter);
}
}
this->Refresh();
mainPanel->Layout();
for (auto deleteIter : deleteEntriesList) {
calendarEntryList.erase(deleteIter);
}
if (calendarEntryList.size() > 0)
{
eventListFrame->Layout();
eventListFrameSizer->Layout();
}
}
void XCCalendarDay::DeleteCalendarEntry(wxCommandEvent &eventData){
vector::iterator> deleteEntriesList;
for (vector::iterator calendarEntryIter = calendarEntryList.begin();
calendarEntryIter != calendarEntryList.end(); calendarEntryIter++){
if ((*calendarEntryIter)->GetEventID() == eventData.GetInt()){
wxSizerItem *calendarItem = eventListFrameSizer->GetItem((*calendarEntryIter));
(*calendarEntryIter)->Show(false);
// Get the spacing and hide it as well.
wxSizerItem *afterSpacer = (*calendarEntryIter)->GetAfterSpacer();
afterSpacer->Show(false);
delete (*calendarEntryIter);
deleteEntriesList.push_back(calendarEntryIter);
}
}
for (auto deleteIter : deleteEntriesList){
calendarEntryList.erase(deleteIter);
}
this->Refresh();
this->Layout();
eventListFrame->Layout();
eventListFrameSizer->Layout();
}
void XCCalendarDay::AddCalendarEntry(wxCommandEvent &eventData){
EventProperties *eventInfo = (EventProperties*)eventData.GetClientData();
// TODO: Fix conversion from string to wxString
XCCalendarDayEntry *newEntry = new XCCalendarDayEntry(eventListFrame, wxString(eventInfo->eventName.c_str(), wxConvUTF8), wxDefaultPosition, wxDefaultSize, eventInfo->eventID);
CDSGetCalendarInfo calendarInfo = dataStorage->GetCalendar(eventInfo->calendarID);
newEntry->SetColour(&calendarInfo.calendarColour);
newEntry->SetTime(eventInfo->eventHour, eventInfo->eventMinute, eventInfo->eventSecond);
newEntry->SetEntryIDs(calendarInfo.accountID, eventInfo->calendarID, eventInfo->eventID);
eventListFrameSizer->Add(newEntry, 0, wxEXPAND, 5);
wxSizerItem *afterSpacer = eventListFrameSizer->Add(0, 5, 0, 0, 5);
newEntry->SetAfterSpacer(afterSpacer);
// Go through the list of calendar entries to hide by account.
for (vector::iterator hideAccountsItem = eventInfo->hideAccountsList.begin();
hideAccountsItem != eventInfo->hideAccountsList.end(); hideAccountsItem++){
if (*hideAccountsItem = calendarInfo.accountID){
newEntry->Show(false);
newEntry->GetAfterSpacer()->Show(false);
}
}
// Go through the list of calendar entries to hide by calendar.
for (vector::iterator hideCalendarsItem = eventInfo->hideCalendarsList.begin();
hideCalendarsItem != eventInfo->hideCalendarsList.end(); hideCalendarsItem++){
if (*hideCalendarsItem == eventInfo->calendarID){
newEntry->Show(false);
newEntry->GetAfterSpacer()->Show(false);
}
}
calendarEntryList.push_back(newEntry);
this->Refresh();
mainPanel->Layout();
eventListFrame->Layout();
eventListFrameSizer->Layout();
}
void XCCalendarDay::UpdateCalendarEntry(wxCommandEvent &eventData){
// Go thorugh each of the entries in the day and
// then update it.
EventProperties *eventInfo = (EventProperties*)eventData.GetClientData();
for (vector::iterator calendarEntryIter = calendarEntryList.begin();
calendarEntryIter != calendarEntryList.end(); calendarEntryIter++){
if ((*calendarEntryIter)->GetEventID() == eventInfo->eventID){
(*calendarEntryIter)->SetEventName(eventInfo->eventName);
(*calendarEntryIter)->SetTime(eventInfo->eventHour, eventInfo->eventMinute, eventInfo->eventSecond);
}
}
delete eventInfo;
eventInfo = nullptr;
}
void XCCalendarDay::UpdateCalendarColour(wxCommandEvent &colourData){
// Go thorugh each of the entries in the day and
// then update it.
ColourUpdateProperties *colourInfo = (ColourUpdateProperties*)colourData.GetClientData();
for (vector::iterator calendarEntryIter = calendarEntryList.begin();
calendarEntryIter != calendarEntryList.end(); calendarEntryIter++){
if ((*calendarEntryIter)->GetCalendarID() == colourInfo->calendarID){
(*calendarEntryIter)->SetColour(&colourInfo->newColour);
}
}
}
int XCCalendarDay::GetCalendarDay(){
return calendarDay;
}
int XCCalendarDay::GetCalendarMonth(){
return calendarMonth;
}
int XCCalendarDay::GetCalendarYear(){
return calendarYear;
}