");
+ Lay_PutLinkToPrintView1 (ActPrnCal);
+ Lay_PutLinkToPrintView2 ();
+ fprintf (Gbl.F.Out,"
");
+ }
+ Lay_StartRoundFrameTable10 (NULL,0,NULL);
+ Lay_WriteHeaderClassPhoto (1,PrintView,false,
+ Gbl.CurrentIns.Ins.InsCod,
+ Gbl.CurrentDeg.Deg.DegCod,
+ Gbl.CurrentCrs.Crs.CrsCod);
+
+ /***** Create list of calls for examination *****/
+ Exa_CreateListOfExamAnnouncements ();
+
+ /***** Draw several months *****/
+ fprintf (Gbl.F.Out,""
+ ""
+ "");
+ for (Row = 0;
+ Row < 4;
+ Row++)
+ {
+ fprintf (Gbl.F.Out,"");
+ for (Col = 0;
+ Col < 4;
+ Col++)
+ {
+ fprintf (Gbl.F.Out,"");
+ Cal_DrawMonth (Year,Month,true,!PrintView,(Gbl.CurrentAct == ActPrnCal));
+ fprintf (Gbl.F.Out," | ");
+ if (++Month == 13)
+ {
+ Month = 1;
+ Year++;
+ }
+ }
+ fprintf (Gbl.F.Out," ");
+ }
+ fprintf (Gbl.F.Out," "
+ " | "
+ "
");
+
+ /***** Free list of dates of exam announcements *****/
+ Exa_FreeListExamAnnouncements ();
+
+ /***** End frame *****/
+ Lay_EndRoundFrameTable10 ();
+ }
+
+/*****************************************************************************/
+/******************************** Draw a month *******************************/
+/*****************************************************************************/
+
+static void Cal_DrawMonth (unsigned RealYear,unsigned RealMonth,
+ bool DrawingCalendar,bool PutLinkToEvents,bool PrintView)
+ {
+ extern const unsigned Dat_NumDaysMonth[1+12];
+ extern const char *Txt_Show_calendar;
+ extern const char *Txt_DAYS_CAPS[7];
+ extern const char *Txt_MONTHS_CAPS[12];
+ extern const char *Txt_Exam_of_X;
+ char StrExamOfX[512+Crs_MAX_LENGTH_COURSE_FULL_NAME];
+ unsigned Week;
+ unsigned DayOfWeek; /* 0, 1, 2, 3, 4, 5 ķ 6 */
+ unsigned DayOfMonth;
+ unsigned NumDaysInMonth;
+ unsigned Year = RealYear;
+ unsigned Month = RealMonth;
+ char YYYYMMDD[4+2+2+1];
+ unsigned NumHld;
+ char *ClassForDay; // Class of day depending on type of day
+ char *TextForDay; // Text associated to a day, for example the name of the holiday
+ unsigned NumExamAnnouncement; // Number of exam announcement
+ int ResultOfCmpStartDate;
+ bool ContinueSearching;
+ bool PutLinkToCalendar = !DrawingCalendar && Gbl.CurrentCrs.Crs.CrsCod > 0;
+ bool ThisDayHasEvent = false;
+ bool IsToday;
+
+ /***** Compute number of day of month for the first box *****/
+ /* The initial day of month can be -5, -4, -3, -2, -1, 0, or 1
+ If it's -5 then write 6 boxes of the previous month.
+ If it's -4 then write 5 boxes of the previous month.
+ If it's -3 then write 4 boxes of the previous month.
+ If it's -2 then write 3 boxes of the previous month.
+ If it's -1 then write 2 boxes of the previous month.
+ If it's 0 then write 1 box of the previous month.
+ If it's 1 then write 0 boxes of the previous month. */
+
+ if ((DayOfWeek = Dat_GetDayOfWeek (Year,Month,1)) == 0)
+ DayOfMonth = 1;
+ else
+ {
+ if (Month <= 1)
+ {
+ Month = 12;
+ Year--;
+ }
+ else
+ Month--;
+ NumDaysInMonth = (Month == 2) ? Dat_GetNumDaysFebruary (Year) :
+ Dat_NumDaysMonth[Month];
+ DayOfMonth = NumDaysInMonth - DayOfWeek + 1;
+ }
+
+ /***** Start of month *****/
+ fprintf (Gbl.F.Out,"");
+
+ /***** Month name *****/
+ fprintf (Gbl.F.Out,"
");
+ if (PutLinkToCalendar)
+ {
+ Act_FormStart (ActSeeCal);
+ Act_LinkFormSubmit (Txt_Show_calendar,"MONTH");
+ }
+ fprintf (Gbl.F.Out,"%s %u",
+ Txt_MONTHS_CAPS[RealMonth-1],RealYear);
+ if (PutLinkToCalendar)
+ fprintf (Gbl.F.Out,""
+ "");
+ fprintf (Gbl.F.Out,"
");
+
+ /***** Month head: first letter for each day of week *****/
+ fprintf (Gbl.F.Out,"
"
+ "");
+ for (DayOfWeek = 0;
+ DayOfWeek < 7;
+ DayOfWeek++)
+ fprintf (Gbl.F.Out,""
+ "%c"
+ " | ",
+ (DayOfWeek == 6) ? "DAY_NO_WRK_HEAD" :
+ "DAY_WRK_HEAD",
+ Txt_DAYS_CAPS[DayOfWeek][0]);
+ fprintf (Gbl.F.Out,"
");
+
+ /***** Draw every week of the month *****/
+ for (Week = 0;
+ Week < 6;
+ Week++)
+ {
+ fprintf (Gbl.F.Out,"");
+
+ /***** Draw every day of the week *****/
+ for (DayOfWeek = 0;
+ DayOfWeek < 7;
+ DayOfWeek++)
+ {
+ /***** Set class for day being drawn *****/
+ ClassForDay = (Month == RealMonth) ? "DAY_WRK" :
+ "DAY_WRK_LIGHT";
+ TextForDay = NULL;
+
+ /* Check if day is a holiday or a school day */
+ sprintf (YYYYMMDD,"%04u%02u%02u",Year,Month,DayOfMonth);
+ for (NumHld = 0, ContinueSearching = true;
+ NumHld < Gbl.Hlds.Num && ContinueSearching;
+ NumHld++)
+ if (Gbl.Hlds.Lst[NumHld].PlcCod <= 0 ||
+ Gbl.Hlds.Lst[NumHld].PlcCod == Gbl.CurrentCtr.Ctr.PlcCod)
+ {
+ ResultOfCmpStartDate = strcmp (Gbl.Hlds.Lst[NumHld].StartDate.YYYYMMDD,YYYYMMDD);
+ if (ResultOfCmpStartDate > 0) // List is ordered by start date. If start date is greater than date being drawn, don't continue searching
+
+ ContinueSearching = false;
+ else // ResultOfCmpStartDate <= 0 <==> start date <= date being drawn
+ switch (Gbl.Hlds.Lst[NumHld].HldTyp)
+ {
+ case Hld_HOLIDAY:
+ if (ResultOfCmpStartDate == 0) // If start date == date being drawn
+ {
+ ClassForDay = (Month == RealMonth) ? "DAY_HLD" :
+ "DAY_HLD_LIGHT";
+ TextForDay = Gbl.Hlds.Lst[NumHld].Name;
+ ContinueSearching = false;
+ }
+ break;
+ case Hld_NON_SCHOOL_PERIOD:
+ if (strcmp (Gbl.Hlds.Lst[NumHld].EndDate.YYYYMMDD,YYYYMMDD) >= 0) // If start date <= date being drawn <= end date
+ {
+ ClassForDay = (Month == RealMonth) ? "DAY_NO_WORK" :
+ "DAY_NO_WORK_LIGHT";
+ TextForDay = Gbl.Hlds.Lst[NumHld].Name;
+ }
+ break;
+ }
+ }
+
+ /* Day being drawn is sunday? */
+ if (DayOfWeek == 6) // All the sundays are holidays
+ ClassForDay = (Month == RealMonth) ? "DAY_HLD" :
+ "DAY_HLD_LIGHT";
+
+ /* Date being drawn is today? */
+ IsToday = (Gbl.CurrentAct != ActPrnCal && Month == RealMonth &&
+ Year == Gbl.Now.Date.Year &&
+ Month == Gbl.Now.Date.Month &&
+ DayOfMonth == Gbl.Now.Date.Day);
+
+ /* Check if day has an exam announcement */
+ ThisDayHasEvent = false;
+ if (!DrawingCalendar || Month == RealMonth) // If drawing calendar and the month is not the real one, don't draw exam announcements
+ for (NumExamAnnouncement = 0;
+ NumExamAnnouncement < Gbl.LstExamAnnouncements.NumExamAnnounc;
+ NumExamAnnouncement++)
+ if (Year == Gbl.LstExamAnnouncements.Lst[NumExamAnnouncement].Year &&
+ Month == Gbl.LstExamAnnouncements.Lst[NumExamAnnouncement].Month &&
+ DayOfMonth == Gbl.LstExamAnnouncements.Lst[NumExamAnnouncement].Day)
+ {
+ ThisDayHasEvent = true;
+ if (PutLinkToEvents)
+ {
+ sprintf (StrExamOfX,Txt_Exam_of_X,Gbl.CurrentCrs.Crs.FullName);
+ sprintf (Gbl.Title,"%s: %02u/%02u/%04u",
+ StrExamOfX,
+ Gbl.LstExamAnnouncements.Lst[NumExamAnnouncement].Day,
+ Gbl.LstExamAnnouncements.Lst[NumExamAnnouncement].Month,
+ Gbl.LstExamAnnouncements.Lst[NumExamAnnouncement].Year);
+ }
+ break;
+ }
+
+ /***** Write the box with the day *****/
+ fprintf (Gbl.F.Out,"",
+ IsToday ? (ThisDayHasEvent ? "TODAY_EVENT" :
+ "TODAY") :
+ (ThisDayHasEvent ? "DAY_EVENT" :
+ "DAY" ));
+
+ /* If day has an exam announcement */
+ if (PutLinkToEvents && ThisDayHasEvent)
+ {
+ Act_FormStart (ActSeeExaAnn);
+ fprintf (Gbl.F.Out,""
+ ""
+ "",
+ ClassForDay);
+ Act_LinkFormSubmit (Gbl.Title,ClassForDay);
+ }
+ else
+ {
+ fprintf (Gbl.F.Out," ");
+ }
+
+ /* Write the day of month */
+ fprintf (Gbl.F.Out,"%u",DayOfMonth);
+
+ /* If day has an exam announcement */
+ if (PutLinkToEvents && ThisDayHasEvent)
+ fprintf (Gbl.F.Out,""
+ " | "
+ " "
+ " "
+ "");
+ else
+ fprintf (Gbl.F.Out,"");
+
+ fprintf (Gbl.F.Out," | ");
+
+ /***** Set the next day *****/
+ NumDaysInMonth = (Month == 2) ? Dat_GetNumDaysFebruary (Year) :
+ Dat_NumDaysMonth[Month];
+ if (++DayOfMonth > NumDaysInMonth)
+ {
+ if (++Month > 12)
+ {
+ Year++;
+ Month = 1;
+ }
+ DayOfMonth = 1;
+ }
+ }
+ fprintf (Gbl.F.Out,"
");
+ }
+
+ /***** End of month *****/
+ fprintf (Gbl.F.Out,"
"
+ "
");
+ }
diff --git a/swad_calendar.h b/swad_calendar.h
new file mode 100644
index 000000000..d943d6763
--- /dev/null
+++ b/swad_calendar.h
@@ -0,0 +1,45 @@
+// swad_calendar.h: Draw month and calendar
+
+#ifndef _SWAD_CAL
+#define _SWAD_CAL
+/*
+ SWAD (Shared Workspace At a Distance in Spanish),
+ is a web platform developed at the University of Granada (Spain),
+ and used to support university teaching.
+
+ This file is part of SWAD core.
+ Copyright (C) 1999-2015 Antonio Caņas Vargas
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see