// 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; }