// monthviewgen.cpp - Xestia Calendar month view generation 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 "monthviewgen.h" using namespace std; int PreviousMonthNumberofDays(int Month, int Year){ // Work out what the previous month is. // Return 31 if month matches. if (Month == 1 || Month == 2 || Month == 4 || Month == 6 || Month == 8 || Month == 9 || Month == 11){ return 31; } // Return 30 if month matches. if (Month == 5 || Month == 7 || Month == 10 || Month == 12){ return 30; } // Work out if year is a leap year and return 28 or 29 // for february. if (Year % 4 == 0){ if (Year % 100 == 0){ if (Year % 400 == 0){ return 29; } else { return 28; } } return 29; } else { return 28; } } XCCalendarMonthViewGrid GenerateMonthGrid(int Month, int Year){ XCCalendarMonthViewGrid MonthViewOutput; // Work out which day of the week the first day of // the month is. time_t EmptyTime; struct tm * FirstDay; int PreviousMonthNumDays = PreviousMonthNumberofDays(Month, Year); int PreviousMonthDays = 0; int PreviousMonth = 0; int PreviousYear = Year; int DayWeekCount = 0; bool ProcessGrid = true; bool FirstWeekProcessing = true; time(&EmptyTime); FirstDay = localtime(&EmptyTime); FirstDay->tm_year = Year - 1900; FirstDay->tm_mon = Month - 1; FirstDay->tm_mday = 1; mktime(FirstDay); if (FirstDay->tm_wday == 0){ PreviousMonthDays = 6; } else { PreviousMonthDays = FirstDay->tm_wday - 1; } if (Month == 1){ PreviousMonth = 12; PreviousYear--; } else { PreviousMonth = Month - 1; } // Workout the days of the previous month for the // first week to be displayed. XCCalendarMonthViewGridDayWeek FirstWeek; for (int PreviousMonthDaysProcessing = 0; PreviousMonthDaysProcessing < PreviousMonthDays; PreviousMonthDaysProcessing++){ XCCalendarMonthViewGridDayData DayItem; DayItem.Day = PreviousMonthNumDays - PreviousMonthDaysProcessing; DayItem.Month = PreviousMonth; DayItem.Year = PreviousYear; DayItem.IsInMonth = false; FirstWeek.DayList.insert(FirstWeek.DayList.begin(), DayItem); DayWeekCount++; } // Process the actual days of the month. XCCalendarMonthViewGridDayWeek MonthWeek; int ProcessDay = 1; while (ProcessGrid == true){ if (DayWeekCount == 7){ // Add to the month view grid. if (FirstWeekProcessing == true){ FirstWeekProcessing = false; MonthViewOutput.WeekList.push_back(FirstWeek); } else { MonthViewOutput.WeekList.push_back(MonthWeek); MonthWeek.DayList.clear(); } DayWeekCount = 0; continue; } XCCalendarMonthViewGridDayData DayItem; DayItem.Day = ProcessDay; DayItem.Month = Month; DayItem.Year = Year; DayItem.IsInMonth = true; if (FirstWeekProcessing == true){ FirstWeek.DayList.push_back(DayItem); } else { MonthWeek.DayList.push_back(DayItem); } DayWeekCount++; if ((Month == 1 || Month == 3 || Month == 5 || Month == 7 || Month == 8 || Month == 10 || Month == 12) && ProcessDay == 31){ break; } if ((Month == 4 || Month == 6 || Month == 9 || Month == 11) && ProcessDay == 30){ break; } if (Year % 4 == 0){ if (Year % 100 == 0){ if (Year % 400 == 0){ if (Month == 2 && ProcessDay == 29){ break; } } else { if (Month == 2 && ProcessDay == 28){ break; } } } if (Month == 2 && ProcessDay == 29){ break; } } else if ((Month == 2 && ProcessDay == 28) && Year % 4 != 0){ break; } ProcessDay++; } // At the end of the month add any remaining days // (if required). int NextMonthYear = Year; int NextMonth = 0; int NextMonthDay = 1; if (Month == 12){ NextMonth = 1; NextMonthYear++; } else { NextMonth = Month + 1; } for (; DayWeekCount < 7; DayWeekCount++){ XCCalendarMonthViewGridDayData DayItem; DayItem.Day = NextMonthDay; DayItem.Month = NextMonth; DayItem.Year = NextMonthYear; DayItem.IsInMonth = false; MonthWeek.DayList.push_back(DayItem); NextMonthDay++; } if (DayWeekCount == 7){ MonthViewOutput.WeekList.push_back(MonthWeek); } return MonthViewOutput; }