diff --git a/Makefile b/Makefile index ca6bef59..9403b83e 100644 --- a/Makefile +++ b/Makefile @@ -29,13 +29,13 @@ OBJS = swad_account.o swad_action.o swad_agenda.o swad_alert.o \ swad_announcement.o swad_API.o swad_assignment.o swad_attendance.o \ swad_banner.o swad_box.o swad_building.o swad_button.o \ - swad_calendar.o swad_center.o swad_center_config.o swad_chat.o \ - swad_config.o swad_connected.o swad_cookie.o swad_country.o \ - swad_country_config.o swad_course.o \ + swad_calendar.o swad_call_for_exam.o swad_center.o \ + swad_center_config.o swad_chat.o swad_config.o swad_connected.o \ + swad_cookie.o swad_country.o swad_country_config.o swad_course.o \ swad_course_config.o swad_cryptography.o \ swad_database.o swad_date.o swad_degree.o swad_degree_config.o \ swad_degree_type.o swad_department.o swad_duplicate.o \ - swad_enrolment.o swad_exam.o swad_exam_announcement.o swad_exam_log.o \ + swad_enrolment.o swad_exam.o swad_exam_log.o \ swad_exam_print.o swad_exam_result.o swad_exam_session.o \ swad_exam_set.o \ swad_figure.o swad_figure_cache.o swad_file.o swad_file_browser.o \ diff --git a/css/swad20.45.css b/css/swad20.45.css index 474b863c..127c4b6b 100644 --- a/css/swad20.45.css +++ b/css/swad20.45.css @@ -3272,13 +3272,13 @@ table.CELLS_PAD_10 > tbody > tr > td {padding:10px;} /***************************** Exam announcement *****************************/ /* Bottom space is used for signatures */ -.EXA_ANN_VISIBLE +.CALL_FOR_EXAM_VISIBLE { box-sizing:border-box; width:100%; padding:25px 25px 125px 25px; } -.EXA_ANN_HIDDEN +.CALL_FOR_EXAM_HIDDEN { box-sizing:border-box; width:100%; diff --git a/sql/cambios.sql b/sql/cambios.sql index ef90f7d5..a795b801 100644 --- a/sql/cambios.sql +++ b/sql/cambios.sql @@ -10645,7 +10645,7 @@ UPDATE usr_data SET EmailNtfEvents=(((EmailNtfEvents & ~0x7F) << 1) | (EmailNtfE /* Assessment tab */ Ntf_EVENT_ASSIGNMENT = 3, // old 3 - Ntf_EVENT_EXAM_ANNOUNCEMENT = 4, // old 4 + Ntf_EVENT_CALL_FOR_EXAM = 4, // old 4 Ntf_EVENT_MARKS_FILE = 5, // old 5 /* Enrollment tab */ diff --git a/swad_QR.c b/swad_QR.c index 4e075019..e7cb898c 100644 --- a/swad_QR.c +++ b/swad_QR.c @@ -160,7 +160,7 @@ void QR_LinkTo (unsigned Size,const char *ParamName,long Cod) void QR_ExamAnnnouncement (void) { - extern const char *Txt_Link_to_announcement_of_exam; + extern const char *Txt_Link_to_call_for_exam; char *URL; /***** Show QR code with direct link to the exam announcement *****/ @@ -171,7 +171,7 @@ void QR_ExamAnnnouncement (void) Cfg_URL_SWAD_CGI,Gbl.Hierarchy.Crs.CrsCod, Act_GetActCod (ActSeeAllExaAnn)) < 0) Lay_NotEnoughMemoryExit (); - HTM_IMG (URL,NULL,Txt_Link_to_announcement_of_exam, + HTM_IMG (URL,NULL,Txt_Link_to_call_for_exam, "style=\"width:250px;height:250px;\""); free (URL); diff --git a/swad_RSS.c b/swad_RSS.c index 7ead6ced..be1a00a7 100644 --- a/swad_RSS.c +++ b/swad_RSS.c @@ -29,9 +29,9 @@ #include // For NULL #include +#include "swad_call_for_exam.h" #include "swad_changelog.h" #include "swad_database.h" -#include "swad_exam_announcement.h" #include "swad_global.h" #include "swad_notice.h" #include "swad_RSS.h" @@ -260,7 +260,7 @@ static void RSS_WriteExamAnnouncements (FILE *FileRSS,struct Crs_Course *Crs) " WHERE CrsCod=%ld AND Status=%u AND ExamDate>=NOW()" " ORDER BY T", Gbl.Hierarchy.Crs.CrsCod, - (unsigned) ExaAnn_VISIBLE_EXAM_ANNOUNCEMENT); + (unsigned) Cfe_VISIBLE_CALL_FOR_EXAM); /***** Write items with notices *****/ if (NumExamAnnouncements) diff --git a/swad_action.c b/swad_action.c index cb798c22..7ae66303 100644 --- a/swad_action.c +++ b/swad_action.c @@ -32,6 +32,7 @@ #include "swad_banner.h" #include "swad_building.h" #include "swad_calendar.h" +#include "swad_call_for_exam.h" #include "swad_center_config.h" #include "swad_config.h" #include "swad_cookie.h" @@ -47,7 +48,6 @@ #include "swad_department.h" #include "swad_duplicate.h" #include "swad_exam.h" -#include "swad_exam_announcement.h" #include "swad_exam_print.h" #include "swad_exam_result.h" #include "swad_exam_session.h" @@ -554,7 +554,7 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = [ActSeeAss ] = { 15, 0,TabAss,ActSeeAss ,0x3F8,0x3C7, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Inf_ShowInfo ,"info" }, [ActSeeAsg ] = { 801, 1,TabAss,ActSeeAsg ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Asg_SeeAssignments ,"edit" }, [ActSeePrj ] = {1674, 2,TabAss,ActSeePrj ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Prj_SeeProjects ,"file-invoice" }, - [ActSeeAllExaAnn ] = { 85, 3,TabAss,ActSeeAllExaAnn ,0x3F8,0x3C7, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaAnn_ListExamAnnsSee ,"bullhorn" }, + [ActSeeAllExaAnn ] = { 85, 3,TabAss,ActSeeAllExaAnn ,0x3F8,0x3C7, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Cfe_ListCallsForExamsSee ,"bullhorn" }, [ActEdiTstQst ] = { 104, 4,TabAss,ActEdiTstQst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Dat_SetIniEndDates ,Tst_RequestEditTests ,"tasks" }, [ActReqTst ] = { 103, 5,TabAss,ActReqTst ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_RequestTest ,"check" }, [ActSeeAllExa ] = {1848, 6,TabAss,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Exa_SeeAllExams ,"file-signature" }, @@ -656,15 +656,15 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = [ActChgDatAssPrj ] = {1733,-1,TabUnk,ActSeePrj ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Brw_ChgFileMetadata ,NULL}, [ActDowAssPrj ] = {1734,-1,TabUnk,ActSeePrj ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_DOWNLD_FILE,Brw_DownloadFile ,NULL ,NULL}, - [ActSeeOneExaAnn ] = {1572,-1,TabUnk,ActSeeAllExaAnn ,0x3F8,0x3C7, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaAnn_ListExamAnnsCod ,NULL}, - [ActSeeDatExaAnn ] = {1571,-1,TabUnk,ActSeeAllExaAnn ,0x3F8,0x3C7, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaAnn_ListExamAnnsDay ,NULL}, - [ActEdiExaAnn ] = { 91,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaAnn_PutFrmEditAExamAnn ,NULL}, - [ActRcvExaAnn ] = { 110,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,ExaAnn_ReceiveExamAnn1 ,ExaAnn_ReceiveExamAnn2 ,NULL}, - [ActPrnExaAnn ] = { 179,-1,TabUnk,ActSeeAllExaAnn ,0x3F8,0x3C7, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,ExaAnn_PrintExamAnn ,NULL}, - [ActReqRemExaAnn ] = {1619,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaAnn_ReqRemoveExamAnn ,NULL}, - [ActRemExaAnn ] = { 187,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,ExaAnn_RemoveExamAnn1 ,ExaAnn_RemoveExamAnn2 ,NULL}, - [ActHidExaAnn ] = {1620,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,ExaAnn_HideExamAnn ,ExaAnn_ListExamAnnsEdit ,NULL}, - [ActUnhExaAnn ] = {1621,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,ExaAnn_UnhideExamAnn ,ExaAnn_ListExamAnnsEdit ,NULL}, + [ActSeeOneCfe ] = {1572,-1,TabUnk,ActSeeAllExaAnn ,0x3F8,0x3C7, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Cfe_ListCallsForExamsCod ,NULL}, + [ActSeeDatCfe ] = {1571,-1,TabUnk,ActSeeAllExaAnn ,0x3F8,0x3C7, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Cfe_ListCallsForExamsDay ,NULL}, + [ActEdiCfe ] = { 91,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Cfe_PutFrmEditACallForExam ,NULL}, + [ActRcvCfe ] = { 110,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Cfe_ReceiveCallForExam1 ,Cfe_ReceiveCallForExam2 ,NULL}, + [ActPrnCfe ] = { 179,-1,TabUnk,ActSeeAllExaAnn ,0x3F8,0x3C7, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Cfe_PrintCallForExam ,NULL}, + [ActReqRemCfe ] = {1619,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Cfe_ReqRemoveCallForExam ,NULL}, + [ActRemCfe ] = { 187,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Cfe_RemoveCallForExam1 ,Cfe_RemoveCallForExam2 ,NULL}, + [ActHidCfe ] = {1620,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Cfe_HideCallForExam ,Cfe_ListCallsForExamsEdit ,NULL}, + [ActUnhCfe ] = {1621,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Cfe_UnhideCallForExam ,Cfe_ListCallsForExamsEdit ,NULL}, [ActEdiOneTstQst ] = { 105,-1,TabUnk,ActEdiTstQst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_ShowFormEditOneQst ,NULL}, [ActReqImpTstQst ] = {1007,-1,TabUnk,ActEdiTstQst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,TsI_ShowFormImportQstsFromXML ,NULL}, @@ -1913,7 +1913,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActReqRemAllStdCrs, // #88 ActSeeRecSevStd, // #89 ActDelSntMsg, // #90 - ActEdiExaAnn, // #91 + ActEdiCfe, // #91 -1, // #92 (obsolete action) -1, // #93 (obsolete action) -1, // #94 (obsolete action) @@ -1932,7 +1932,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActReqRemGrp, // #107 ActReqEdiGrp, // #108 ActEdiFAQ, // #109 - ActRcvExaAnn, // #110 + ActRcvCfe, // #110 ActPrnRecSevStd, // #111 -1, // #112 (obsolete action) -1, // #113 (obsolete action) @@ -2001,7 +2001,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un -1, // #176 (obsolete action) -1, // #177 (obsolete action) -1, // #178 (obsolete action) - ActPrnExaAnn, // #179 + ActPrnCfe, // #179 -1, // #180 (obsolete action) ActInsIteSylPra, // #181 ActRcvURLCrsLnk, // #182 @@ -2009,7 +2009,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActRcvPagAss, // #184 ActRcvPagBib, // #185 -1, // #186 (obsolete action) - ActRemExaAnn, // #187 + ActRemCfe, // #187 -1, // #188 (obsolete action) -1, // #189 (obsolete action) -1, // #190 (obsolete action) @@ -3393,8 +3393,8 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActCnfID_Oth, // #1568 ActCnfID_Std, // #1569 ActCnfID_Tch, // #1570 - ActSeeDatExaAnn, // #1571 - ActSeeOneExaAnn, // #1572 + ActSeeDatCfe, // #1571 + ActSeeOneCfe, // #1572 ActChgCrsYeaCfg, // #1573 ActReqRemOthPho, // #1574 ActReqRemStdPho, // #1575 @@ -3441,9 +3441,9 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActLogInUsrAgdLan, // #1616 -1, // #1617 (obsolete action) ActPrnAgdQR, // #1618 - ActReqRemExaAnn, // #1619 - ActHidExaAnn, // #1620 - ActUnhExaAnn, // #1621 + ActReqRemCfe, // #1619 + ActHidCfe, // #1620 + ActUnhCfe, // #1621 ActSeeCal, // #1622 ActPrnCal, // #1623 ActChgCal1stDay, // #1624 diff --git a/swad_action.h b/swad_action.h index 4ed43363..d02e2ee8 100644 --- a/swad_action.h +++ b/swad_action.h @@ -618,15 +618,15 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActChgDatAssPrj (ActChgCrsTT1stDay + 97) #define ActDowAssPrj (ActChgCrsTT1stDay + 98) -#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 99) -#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 100) -#define ActEdiExaAnn (ActChgCrsTT1stDay + 101) -#define ActRcvExaAnn (ActChgCrsTT1stDay + 102) -#define ActPrnExaAnn (ActChgCrsTT1stDay + 103) -#define ActReqRemExaAnn (ActChgCrsTT1stDay + 104) -#define ActRemExaAnn (ActChgCrsTT1stDay + 105) -#define ActHidExaAnn (ActChgCrsTT1stDay + 106) -#define ActUnhExaAnn (ActChgCrsTT1stDay + 107) +#define ActSeeOneCfe (ActChgCrsTT1stDay + 99) +#define ActSeeDatCfe (ActChgCrsTT1stDay + 100) +#define ActEdiCfe (ActChgCrsTT1stDay + 101) +#define ActRcvCfe (ActChgCrsTT1stDay + 102) +#define ActPrnCfe (ActChgCrsTT1stDay + 103) +#define ActReqRemCfe (ActChgCrsTT1stDay + 104) +#define ActRemCfe (ActChgCrsTT1stDay + 105) +#define ActHidCfe (ActChgCrsTT1stDay + 106) +#define ActUnhCfe (ActChgCrsTT1stDay + 107) #define ActEdiOneTstQst (ActChgCrsTT1stDay + 108) #define ActReqImpTstQst (ActChgCrsTT1stDay + 109) diff --git a/swad_calendar.c b/swad_calendar.c index b4c510c3..49896a22 100644 --- a/swad_calendar.c +++ b/swad_calendar.c @@ -29,8 +29,8 @@ #include "swad_box.h" #include "swad_calendar.h" +#include "swad_call_for_exam.h" #include "swad_database.h" -#include "swad_exam_announcement.h" #include "swad_figure.h" #include "swad_form.h" #include "swad_global.h" @@ -219,7 +219,7 @@ void Cal_DrawCurrentMonth (void) Lan_STR_LANG_ID[Gbl.Prefs.Language]); Frm_SetParamsForm (ParamsStr,ActSeeCal,true); HTM_TxtF ("'%s',",ParamsStr); - Frm_SetParamsForm (ParamsStr,ActSeeDatExaAnn,true); + Frm_SetParamsForm (ParamsStr,ActSeeDatCfe,true); HTM_TxtF ("'%s');",ParamsStr); HTM_SCRIPT_End (); } @@ -288,7 +288,7 @@ static void Cal_DrawCalendar (Act_Action_t ActionSeeCalendar, Lan_STR_LANG_ID[Gbl.Prefs.Language]); Frm_SetParamsForm (ParamsStr,ActionSeeCalendar,true); HTM_TxtF ("'%s',",ParamsStr); - Frm_SetParamsForm (ParamsStr,ActSeeDatExaAnn,true); + Frm_SetParamsForm (ParamsStr,ActSeeDatCfe,true); HTM_TxtF ("'%s');",ParamsStr); HTM_SCRIPT_End (); diff --git a/swad_call_for_exam.c b/swad_call_for_exam.c new file mode 100644 index 00000000..981e60ee --- /dev/null +++ b/swad_call_for_exam.c @@ -0,0 +1,1811 @@ +// swad_exam_announcement.c: calls for exams + +/* + SWAD (Shared Workspace At a Distance), + 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-2021 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 3 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 . +*/ +/*****************************************************************************/ +/********************************* Headers ***********************************/ +/*****************************************************************************/ + +#define _GNU_SOURCE // For asprintf +#include // For NULL +#include // For sscanf, asprintf, etc. +#include // For exit, system, malloc, calloc, free, etc. +#include // For string functions + +#include "swad_box.h" +#include "swad_call_for_exam.h" +#include "swad_config.h" +#include "swad_database.h" +#include "swad_form.h" +#include "swad_global.h" +#include "swad_hierarchy.h" +#include "swad_HTML.h" +#include "swad_logo.h" +#include "swad_notification.h" +#include "swad_parameter.h" +#include "swad_QR.h" +#include "swad_RSS.h" +#include "swad_string.h" +#include "swad_timeline.h" +#include "swad_timeline_database.h" + +/*****************************************************************************/ +/************** External global variables from others modules ****************/ +/*****************************************************************************/ + +extern struct Globals Gbl; + +/*****************************************************************************/ +/***************************** Private constants *****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/******************************* Private types *******************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Private variables *****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Private prototypes ****************************/ +/*****************************************************************************/ + +static struct Cfe_CallsForExams *Cfe_GetGlobalCallsForExams (void); + +static long Cfe_GetParamsCallsForExams (struct Cfe_CallsForExams *CallsForExams); + +static void Cfe_AllocMemCallForExam (struct Cfe_CallsForExams *CallsForExams); +static void Cfe_FreeMemCallForExam (struct Cfe_CallsForExams *CallsForExams); + +static void Cfe_UpdateNumUsrsNotifiedByEMailAboutCallForExam (long ExaCod, + unsigned NumUsrsToBeNotifiedByEMail); + +static void Cfe_GetExaCodToHighlight (struct Cfe_CallsForExams *CallsForExams); +static void Cfe_GetDateToHighlight (struct Cfe_CallsForExams *CallsForExams); + +static void Cfe_ListCallsForExams (struct Cfe_CallsForExams *CallsForExams, + Cfe_TypeViewCallForExam_t TypeViewCallForExam); +static void Cfe_PutIconToCreateNewCallForExam (__attribute__((unused)) void *Args); +static void Cfe_PutButtonToCreateNewCallForExam (void); + +static long Cfe_AddCallForExamToDB (const struct Cfe_CallsForExams *CallsForExams); +static void Cfe_ModifyCallForExamInDB (const struct Cfe_CallsForExams *CallsForExams, + long ExaCod); +static void Cfe_GetDataCallForExamFromDB (struct Cfe_CallsForExams *CallsForExams, + long ExaCod); +static void Cfe_ShowCallForExam (struct Cfe_CallsForExams *CallsForExams, + long ExaCod, + Cfe_TypeViewCallForExam_t TypeViewCallForExam, + bool HighLight); +static void Cfe_PutIconsCallForExam (void *CallsForExams); +static void Cfe_PutParamExaCodToEdit (void *ExaCod); +static long Cfe_GetParamExaCod (void); + +static void Cfe_GetNotifContentCallForExam (const struct Cfe_CallsForExams *CallsForExams, + char **ContentStr); + +/*****************************************************************************/ +/******************** Get global calls for exams context *********************/ +/*****************************************************************************/ + +static struct Cfe_CallsForExams *Cfe_GetGlobalCallsForExams (void) + { + static struct Cfe_CallsForExams Cfe_GlobalCallsForExams; // Used to preserve information between priori and posteriori functions + + return &Cfe_GlobalCallsForExams; + } + +/*****************************************************************************/ +/********************** Reset calls for exams context *********************/ +/*****************************************************************************/ + +void Cfe_ResetCallsForExams (struct Cfe_CallsForExams *CallsForExams) + { + CallsForExams->NumCallsForExams = 0; + CallsForExams->Lst = NULL; + CallsForExams->NewExaCod = -1L; + CallsForExams->HighlightExaCod = -1L; + CallsForExams->HighlightDate[0] = '\0'; // No calls for exams highlighted + CallsForExams->ExaCod = -1L; + CallsForExams->Anchor = NULL; + + CallsForExams->CallForExam.CrsCod = -1L; + CallsForExams->CallForExam.Status = Cfe_STATUS_DEFAULT; + CallsForExams->CallForExam.CrsFullName[0] = '\0'; + CallsForExams->CallForExam.Year = 0; + CallsForExams->CallForExam.Session[0] = '\0'; + Dat_ResetDate (&CallsForExams->CallForExam.CallDate); + Dat_ResetDate (&CallsForExams->CallForExam.ExamDate); + Dat_ResetHour (&CallsForExams->CallForExam.StartTime); + Dat_ResetHour (&CallsForExams->CallForExam.Duration); + CallsForExams->CallForExam.Place = NULL; + CallsForExams->CallForExam.Mode = NULL; + CallsForExams->CallForExam.Structure = NULL; + CallsForExams->CallForExam.DocRequired = NULL; + CallsForExams->CallForExam.MatRequired = NULL; + CallsForExams->CallForExam.MatAllowed = NULL; + CallsForExams->CallForExam.OtherInfo = NULL; + } + +/*****************************************************************************/ +/************************ Form to edit a call for exam ***********************/ +/*****************************************************************************/ + +void Cfe_PutFrmEditACallForExam (void) + { + struct Cfe_CallsForExams CallsForExams; + long ExaCod; + + /***** Reset calls for exams context *****/ + Cfe_ResetCallsForExams (&CallsForExams); + + /***** Allocate memory for the call for exam *****/ + Cfe_AllocMemCallForExam (&CallsForExams); + + /***** Get the code of the call for exam *****/ + ExaCod = Cfe_GetParamsCallsForExams (&CallsForExams); + + if (ExaCod > 0) // -1 indicates that this is a new call for exam + /***** Read call for exam from the database *****/ + Cfe_GetDataCallForExamFromDB (&CallsForExams,ExaCod); + + /***** Show call for exam *****/ + Cfe_ShowCallForExam (&CallsForExams,ExaCod,Cfe_FORM_VIEW, + false); // Don't highlight + + /***** Free memory of the call for exam *****/ + Cfe_FreeMemCallForExam (&CallsForExams); + } + +/*****************************************************************************/ +/****************** Get parameters of a call for exam ************************/ +/*****************************************************************************/ + +static long Cfe_GetParamsCallsForExams (struct Cfe_CallsForExams *CallsForExams) + { + long ExaCod; + + /***** Get the code of the call for exam *****/ + ExaCod = Cfe_GetParamExaCod (); + + /***** Get the name of the course (it is allowed to be different from the official name of the course) *****/ + Par_GetParToText ("CrsName",CallsForExams->CallForExam.CrsFullName,Cns_HIERARCHY_MAX_BYTES_FULL_NAME); + // If the parameter is not present or is empty, initialize the string to the full name of the current course + if (!CallsForExams->CallForExam.CrsFullName[0]) + Str_Copy (CallsForExams->CallForExam.CrsFullName,Gbl.Hierarchy.Crs.FullName, + sizeof (CallsForExams->CallForExam.CrsFullName) - 1); + + /***** Get the year *****/ + CallsForExams->CallForExam.Year = (unsigned) + Par_GetParToUnsignedLong ("Year", + 0, // N.A. + Deg_MAX_YEARS_PER_DEGREE, + (unsigned long) Gbl.Hierarchy.Crs.Year); + + /***** Get the type of call for exam *****/ + Par_GetParToText ("ExamSession",CallsForExams->CallForExam.Session,Cfe_MAX_BYTES_SESSION); + + /***** Get the date of the exam *****/ + Dat_GetDateFromForm ("ExamDay","ExamMonth","ExamYear", + &CallsForExams->CallForExam.ExamDate.Day, + &CallsForExams->CallForExam.ExamDate.Month, + &CallsForExams->CallForExam.ExamDate.Year); + if (CallsForExams->CallForExam.ExamDate.Day == 0 || + CallsForExams->CallForExam.ExamDate.Month == 0 || + CallsForExams->CallForExam.ExamDate.Year == 0) + { + CallsForExams->CallForExam.ExamDate.Day = Gbl.Now.Date.Day; + CallsForExams->CallForExam.ExamDate.Month = Gbl.Now.Date.Month; + CallsForExams->CallForExam.ExamDate.Year = Gbl.Now.Date.Year; + } + + /***** Get the hour of the exam *****/ + CallsForExams->CallForExam.StartTime.Hour = (unsigned) Par_GetParToUnsignedLong ("ExamHour", + 0,23,0); + CallsForExams->CallForExam.StartTime.Minute = (unsigned) Par_GetParToUnsignedLong ("ExamMinute", + 0,59,0); + + /***** Get the duration of the exam *****/ + CallsForExams->CallForExam.Duration.Hour = (unsigned) Par_GetParToUnsignedLong ("DurationHour", + 0,23,0); + CallsForExams->CallForExam.Duration.Minute = (unsigned) Par_GetParToUnsignedLong ("DurationMinute", + 0,59,0); + + /***** Get the place where the exam will happen *****/ + Par_GetParToHTML ("Place",CallsForExams->CallForExam.Place,Cns_MAX_BYTES_TEXT); + + /***** Get the modality of exam *****/ + Par_GetParToHTML ("ExamMode",CallsForExams->CallForExam.Mode,Cns_MAX_BYTES_TEXT); + + /***** Get the structure of exam *****/ + Par_GetParToHTML ("Structure",CallsForExams->CallForExam.Structure,Cns_MAX_BYTES_TEXT); + + /***** Get the mandatory documentation *****/ + Par_GetParToHTML ("DocRequired",CallsForExams->CallForExam.DocRequired,Cns_MAX_BYTES_TEXT); + + /***** Get the mandatory material *****/ + Par_GetParToHTML ("MatRequired",CallsForExams->CallForExam.MatRequired,Cns_MAX_BYTES_TEXT); + + /***** Get the allowed material *****/ + Par_GetParToHTML ("MatAllowed",CallsForExams->CallForExam.MatAllowed,Cns_MAX_BYTES_TEXT); + + /***** Get other information *****/ + Par_GetParToHTML ("OtherInfo",CallsForExams->CallForExam.OtherInfo,Cns_MAX_BYTES_TEXT); + + return ExaCod; + } + +/*****************************************************************************/ +/* Allocate memory for those parameters of an exam anno. with a lot of text **/ +/*****************************************************************************/ + +static void Cfe_AllocMemCallForExam (struct Cfe_CallsForExams *CallsForExams) + { + if ((CallsForExams->CallForExam.Place = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) + Lay_NotEnoughMemoryExit (); + + if ((CallsForExams->CallForExam.Mode = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) + Lay_NotEnoughMemoryExit (); + + if ((CallsForExams->CallForExam.Structure = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) + Lay_NotEnoughMemoryExit (); + + if ((CallsForExams->CallForExam.DocRequired = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) + Lay_NotEnoughMemoryExit (); + + if ((CallsForExams->CallForExam.MatRequired = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) + Lay_NotEnoughMemoryExit (); + + if ((CallsForExams->CallForExam.MatAllowed = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) + Lay_NotEnoughMemoryExit (); + + if ((CallsForExams->CallForExam.OtherInfo = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) + Lay_NotEnoughMemoryExit (); + } + +/*****************************************************************************/ +/* Free memory of those parameters of an exam announcem. with a lot of text **/ +/*****************************************************************************/ + +static void Cfe_FreeMemCallForExam (struct Cfe_CallsForExams *CallsForExams) + { + if (CallsForExams->CallForExam.Place) + { + free (CallsForExams->CallForExam.Place); + CallsForExams->CallForExam.Place = NULL; + } + if (CallsForExams->CallForExam.Mode) + { + free (CallsForExams->CallForExam.Mode); + CallsForExams->CallForExam.Mode = NULL; + } + if (CallsForExams->CallForExam.Structure) + { + free (CallsForExams->CallForExam.Structure); + CallsForExams->CallForExam.Structure = NULL; + } + if (CallsForExams->CallForExam.DocRequired) + { + free (CallsForExams->CallForExam.DocRequired); + CallsForExams->CallForExam.DocRequired = NULL; + } + if (CallsForExams->CallForExam.MatRequired) + { + free (CallsForExams->CallForExam.MatRequired); + CallsForExams->CallForExam.MatRequired = NULL; + } + if (CallsForExams->CallForExam.MatAllowed) + { + free (CallsForExams->CallForExam.MatAllowed); + CallsForExams->CallForExam.MatAllowed = NULL; + } + if (CallsForExams->CallForExam.OtherInfo) + { + free (CallsForExams->CallForExam.OtherInfo); + CallsForExams->CallForExam.OtherInfo = NULL; + } + } + +/*****************************************************************************/ +/************************** Receive a call for exam **************************/ +/*****************************************************************************/ +// This function is splitted into a-priori and a-posteriori functions +// in order to view updated links in month of left column + +void Cfe_ReceiveCallForExam1 (void) + { + extern const char *Txt_Created_new_call_for_exam; + extern const char *Txt_The_call_for_exam_has_been_successfully_updated; + struct Cfe_CallsForExams *CallsForExams = Cfe_GetGlobalCallsForExams (); + long ExaCod; + bool NewCallForExam; + char *Anchor = NULL; + + /***** Reset calls for exams context *****/ + Cfe_ResetCallsForExams (CallsForExams); + + /***** Allocate memory for the call for exam *****/ + Cfe_AllocMemCallForExam (CallsForExams); + + /***** Get parameters of the call for exam *****/ + ExaCod = Cfe_GetParamsCallsForExams (CallsForExams); + NewCallForExam = (ExaCod < 0); + + /***** Add the call for exam to the database and read it again from the database *****/ + if (NewCallForExam) + CallsForExams->NewExaCod = ExaCod = Cfe_AddCallForExamToDB (CallsForExams); + else + Cfe_ModifyCallForExamInDB (CallsForExams,ExaCod); + + /***** Free memory of the call for exam *****/ + Cfe_FreeMemCallForExam (CallsForExams); + + /***** Create alert to show the change made *****/ + Frm_SetAnchorStr (ExaCod,&Anchor); + Ale_CreateAlert (Ale_SUCCESS,Anchor, + NewCallForExam ? Txt_Created_new_call_for_exam : + Txt_The_call_for_exam_has_been_successfully_updated); + Frm_FreeAnchorStr (Anchor); + + /***** Set exam to be highlighted *****/ + CallsForExams->HighlightExaCod = ExaCod; + } + +void Cfe_ReceiveCallForExam2 (void) + { + struct Cfe_CallsForExams *CallsForExams = Cfe_GetGlobalCallsForExams (); + unsigned NumUsrsToBeNotifiedByEMail; + + /***** Notify by email about the new call for exam *****/ + if ((NumUsrsToBeNotifiedByEMail = Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_CALL_FOR_EXAM,CallsForExams->HighlightExaCod))) + Cfe_UpdateNumUsrsNotifiedByEMailAboutCallForExam (CallsForExams->HighlightExaCod,NumUsrsToBeNotifiedByEMail); + + /***** Create a new social note about the new call for exam *****/ + Tml_Not_StoreAndPublishNote (TL_NOTE_CALL_FOR_EXAM,CallsForExams->HighlightExaCod); + + /***** Update RSS of current course *****/ + RSS_UpdateRSSFileForACrs (&Gbl.Hierarchy.Crs); + + /***** Show calls for exams *****/ + Cfe_ListCallsForExamsEdit (); + } + +/*****************************************************************************/ +/******* Update number of users notified in table of calls for exams *********/ +/*****************************************************************************/ + +static void Cfe_UpdateNumUsrsNotifiedByEMailAboutCallForExam (long ExaCod, + unsigned NumUsrsToBeNotifiedByEMail) + { + /***** Update number of users notified *****/ + DB_QueryUPDATE ("can not update the number of notifications" + " of a call for exam", + "UPDATE exam_announcements SET NumNotif=NumNotif+%u" + " WHERE ExaCod=%ld", + NumUsrsToBeNotifiedByEMail,ExaCod); + } + +/*****************************************************************************/ +/*************************** Print a call for exam ***************************/ +/*****************************************************************************/ + +void Cfe_PrintCallForExam (void) + { + struct Cfe_CallsForExams CallsForExams; + long ExaCod; + + /***** Reset calls for exams context *****/ + Cfe_ResetCallsForExams (&CallsForExams); + + /***** Allocate memory for the call for exam *****/ + Cfe_AllocMemCallForExam (&CallsForExams); + + /***** Get the code of the call for exam *****/ + if ((ExaCod = Cfe_GetParamExaCod ()) <= 0) + Lay_ShowErrorAndExit ("Code of call for exam is missing."); + + /***** Read call for exam from the database *****/ + Cfe_GetDataCallForExamFromDB (&CallsForExams,ExaCod); + + /***** Show call for exam *****/ + Cfe_ShowCallForExam (&CallsForExams,ExaCod,Cfe_PRINT_VIEW, + false); // Don't highlight + + /***** Free memory of the call for exam *****/ + Cfe_FreeMemCallForExam (&CallsForExams); + } + +/*****************************************************************************/ +/************************** Remove a call for exam ***************************/ +/*****************************************************************************/ + +void Cfe_ReqRemoveCallForExam (void) + { + extern const char *Txt_Do_you_really_want_to_remove_the_following_call_for_exam; + extern const char *Txt_Remove; + struct Cfe_CallsForExams CallsForExams; + long ExaCod; + + /***** Reset calls for exams context *****/ + Cfe_ResetCallsForExams (&CallsForExams); + + /***** Get the code of the call for exam *****/ + if ((ExaCod = Cfe_GetParamExaCod ()) <= 0) + Lay_ShowErrorAndExit ("Code of call for exam is missing."); + + /***** Show question and button to remove call for exam *****/ + /* Begin alert */ + Ale_ShowAlertAndButton1 (Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_following_call_for_exam); + + /* Show call for exam */ + Cfe_AllocMemCallForExam (&CallsForExams); + Cfe_GetDataCallForExamFromDB (&CallsForExams,ExaCod); + Cfe_ShowCallForExam (&CallsForExams,ExaCod,Cfe_NORMAL_VIEW, + false); // Don't highlight + Cfe_FreeMemCallForExam (&CallsForExams); + + /* End alert */ + + Ale_ShowAlertAndButton2 (ActRemCfe,NULL,NULL, + Cfe_PutParamExaCodToEdit,&CallsForExams.ExaCod, + Btn_REMOVE_BUTTON,Txt_Remove); + } + +/*****************************************************************************/ +/************************** Remove a call for exam ***************************/ +/*****************************************************************************/ +// This function is splitted into a-priori and a-posteriori functions +// in order to view updated links in month of left column + +void Cfe_RemoveCallForExam1 (void) + { + struct Cfe_CallsForExams *CallsForExams = Cfe_GetGlobalCallsForExams (); + long ExaCod; + + /***** Reset calls for exams context *****/ + Cfe_ResetCallsForExams (CallsForExams); + + /***** Get the code of the call for exam *****/ + if ((ExaCod = Cfe_GetParamExaCod ()) <= 0) + Lay_ShowErrorAndExit ("Code of call for exam is missing."); + + /***** Mark the call for exam as deleted in the database *****/ + DB_QueryUPDATE ("can not remove call for exam", + "UPDATE exam_announcements SET Status=%u" + " WHERE ExaCod=%ld AND CrsCod=%ld", + (unsigned) Cfe_DELETED_CALL_FOR_EXAM, + ExaCod,Gbl.Hierarchy.Crs.CrsCod); + + /***** Mark possible notifications as removed *****/ + Ntf_MarkNotifAsRemoved (Ntf_EVENT_CALL_FOR_EXAM,ExaCod); + + /***** Mark possible social note as unavailable *****/ + Tml_DB_MarkNoteAsUnavailable (TL_NOTE_CALL_FOR_EXAM,ExaCod); + + /***** Update RSS of current course *****/ + RSS_UpdateRSSFileForACrs (&Gbl.Hierarchy.Crs); + } + +void Cfe_RemoveCallForExam2 (void) + { + extern const char *Txt_Call_for_exam_removed; + + /***** Write message *****/ + Ale_ShowAlert (Ale_SUCCESS,Txt_Call_for_exam_removed); + + /***** List again all the remaining calls for exams *****/ + Cfe_ListCallsForExamsEdit (); + } + +/*****************************************************************************/ +/************************** Hide a call for exam *****************************/ +/*****************************************************************************/ +// This function is splitted into a-priori and a-posteriori functions +// in order to view updated links in month of left column + +void Cfe_HideCallForExam (void) + { + struct Cfe_CallsForExams *CallsForExams = Cfe_GetGlobalCallsForExams (); + long ExaCod; + + /***** Reset calls for exams context *****/ + Cfe_ResetCallsForExams (CallsForExams); + + /***** Get the code of the call for exam *****/ + if ((ExaCod = Cfe_GetParamExaCod ()) <= 0) + Lay_ShowErrorAndExit ("Code of call for exam is missing."); + + /***** Mark the call for exam as hidden in the database *****/ + DB_QueryUPDATE ("can not hide call for exam", + "UPDATE exam_announcements SET Status=%u" + " WHERE ExaCod=%ld AND CrsCod=%ld", + (unsigned) Cfe_HIDDEN_CALL_FOR_EXAM, + ExaCod,Gbl.Hierarchy.Crs.CrsCod); + + /***** Set exam to be highlighted *****/ + CallsForExams->HighlightExaCod = ExaCod; + } + +/*****************************************************************************/ +/************************** Unhide a call for exam ***************************/ +/*****************************************************************************/ +// This function is splitted into a-priori and a-posteriori functions +// in order to view updated links in month of left column + +void Cfe_UnhideCallForExam (void) + { + struct Cfe_CallsForExams *CallsForExams = Cfe_GetGlobalCallsForExams (); + long ExaCod; + + /***** Reset calls for exams context *****/ + Cfe_ResetCallsForExams (CallsForExams); + + /***** Get the code of the call for exam *****/ + if ((ExaCod = Cfe_GetParamExaCod ()) <= 0) + Lay_ShowErrorAndExit ("Code of call for exam is missing."); + + /***** Mark the call for exam as visible in the database *****/ + DB_QueryUPDATE ("can not unhide call for exam", + "UPDATE exam_announcements SET Status=%u" + " WHERE ExaCod=%ld AND CrsCod=%ld", + (unsigned) Cfe_VISIBLE_CALL_FOR_EXAM, + ExaCod,Gbl.Hierarchy.Crs.CrsCod); + + /***** Set exam to be highlighted *****/ + CallsForExams->HighlightExaCod = ExaCod; + } + +/*****************************************************************************/ +/**************** List all the calls for exams to see them *******************/ +/*****************************************************************************/ + +void Cfe_ListCallsForExamsSee (void) + { + struct Cfe_CallsForExams CallsForExams; + + /***** Reset calls for exams context *****/ + Cfe_ResetCallsForExams (&CallsForExams); + + /***** List all calls for exams *****/ + Cfe_ListCallsForExams (&CallsForExams,Cfe_NORMAL_VIEW); + + /***** Mark possible notifications as seen *****/ + Ntf_MarkNotifAsSeen (Ntf_EVENT_CALL_FOR_EXAM, + -1L,Gbl.Hierarchy.Crs.CrsCod, + Gbl.Usrs.Me.UsrDat.UsrCod); + } + +/*****************************************************************************/ +/************ List all the calls for exams to edit or remove them ************/ +/*****************************************************************************/ + +void Cfe_ListCallsForExamsEdit (void) + { + struct Cfe_CallsForExams *CallsForExams = Cfe_GetGlobalCallsForExams (); + + Cfe_ListCallsForExams (CallsForExams,Cfe_NORMAL_VIEW); + } + +/*****************************************************************************/ +/************** List call for exam given a call for exam code ****************/ +/*****************************************************************************/ + +void Cfe_ListCallsForExamsCod (void) + { + struct Cfe_CallsForExams CallsForExams; + + /***** Reset calls for exams context *****/ + Cfe_ResetCallsForExams (&CallsForExams); + + /***** Get call for exam code *****/ + Cfe_GetExaCodToHighlight (&CallsForExams); + + /***** List all calls for exams *****/ + Cfe_ListCallsForExams (&CallsForExams,Cfe_NORMAL_VIEW); + } + +/*****************************************************************************/ +/****************** List calls for exams on a given date *********************/ +/*****************************************************************************/ + +void Cfe_ListCallsForExamsDay (void) + { + struct Cfe_CallsForExams CallsForExams; + + /***** Reset calls for exams context *****/ + Cfe_ResetCallsForExams (&CallsForExams); + + /***** Get date *****/ + Cfe_GetDateToHighlight (&CallsForExams); + + /***** List all calls for exams *****/ + Cfe_ListCallsForExams (&CallsForExams,Cfe_NORMAL_VIEW); + } + +/*****************************************************************************/ +/************ Get date of calls for exams to show highlighted ****************/ +/*****************************************************************************/ + +static void Cfe_GetExaCodToHighlight (struct Cfe_CallsForExams *CallsForExams) + { + /***** Get the call for exam code + of the call for exam to highlight *****/ + CallsForExams->HighlightExaCod = Cfe_GetParamExaCod (); + } + +/*****************************************************************************/ +/************ Get date of calls for exams to show highlighted ****************/ +/*****************************************************************************/ + +static void Cfe_GetDateToHighlight (struct Cfe_CallsForExams *CallsForExams) + { + /***** Get the date (in YYYYMMDD format) + of the calls for exams to highlight *****/ + Par_GetParToText ("Date",CallsForExams->HighlightDate,4 + 2 + 2); + } + +/*****************************************************************************/ +/********************* List all the calls for exams **************************/ +/*****************************************************************************/ + +static void Cfe_ListCallsForExams (struct Cfe_CallsForExams *CallsForExams, + Cfe_TypeViewCallForExam_t TypeViewCallForExam) + { + extern const char *Hlp_ASSESSMENT_Calls_for_exams; + extern const char *Txt_Calls_for_exams; + extern const char *Txt_No_calls_for_exams_of_X; + char SubQueryStatus[64]; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned long NumExaAnn; + unsigned long NumExaAnns; + long ExaCod; + bool HighLight; + bool ICanEdit = (Gbl.Usrs.Me.Role.Logged == Rol_TCH || + Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM); + + /***** Build subquery about status depending on my role *****/ + if (ICanEdit) + sprintf (SubQueryStatus,"Status<>%u", + (unsigned) Cfe_DELETED_CALL_FOR_EXAM); + else + sprintf (SubQueryStatus,"Status=%u", + (unsigned) Cfe_VISIBLE_CALL_FOR_EXAM); + + /***** Get calls for exams (the most recent first) + in current course from database *****/ + NumExaAnns = DB_QuerySELECT (&mysql_res,"can not get calls for exams" + " in this course for listing", + "SELECT ExaCod" + " FROM exam_announcements" + " WHERE CrsCod=%ld AND %s" + " ORDER BY ExamDate DESC", + Gbl.Hierarchy.Crs.CrsCod,SubQueryStatus); + + /***** Begin box *****/ + if (ICanEdit) + Box_BoxBegin (NULL,Txt_Calls_for_exams, + Cfe_PutIconToCreateNewCallForExam,NULL, + Hlp_ASSESSMENT_Calls_for_exams,Box_NOT_CLOSABLE); + else + Box_BoxBegin (NULL,Txt_Calls_for_exams, + NULL,NULL, + Hlp_ASSESSMENT_Calls_for_exams,Box_NOT_CLOSABLE); + + /***** The result of the query may be empty *****/ + if (!NumExaAnns) + Ale_ShowAlert (Ale_INFO,Txt_No_calls_for_exams_of_X, + Gbl.Hierarchy.Crs.FullName); + + /***** List the existing calls for exams *****/ + for (NumExaAnn = 0; + NumExaAnn < NumExaAnns; + NumExaAnn++) + { + /***** Get the code of the call for exam (row[0]) *****/ + row = mysql_fetch_row (mysql_res); + + if (sscanf (row[0],"%ld",&ExaCod) != 1) + Lay_ShowErrorAndExit ("Wrong code of call for exam."); + + /***** Allocate memory for the call for exam *****/ + Cfe_AllocMemCallForExam (CallsForExams); + + /***** Read the data of the call for exam *****/ + Cfe_GetDataCallForExamFromDB (CallsForExams,ExaCod); + + /***** Show call for exam *****/ + HighLight = false; + if (ExaCod == CallsForExams->HighlightExaCod) + HighLight = true; + else if (CallsForExams->HighlightDate[0]) + { + if (!strcmp (CallsForExams->CallForExam.ExamDate.YYYYMMDD, + CallsForExams->HighlightDate)) + HighLight = true; + } + Cfe_ShowCallForExam (CallsForExams,ExaCod,TypeViewCallForExam, + HighLight); + + /***** Free memory of the call for exam *****/ + Cfe_FreeMemCallForExam (CallsForExams); + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + + /***** Button to create a new call for exam *****/ + if (ICanEdit) + Cfe_PutButtonToCreateNewCallForExam (); + + /***** End box *****/ + Box_BoxEnd (); + } + +/*****************************************************************************/ +/******************* Put icon to create a new call for exam ******************/ +/*****************************************************************************/ + +static void Cfe_PutIconToCreateNewCallForExam (__attribute__((unused)) void *Args) + { + extern const char *Txt_New_call_FOR_EXAM; + + Ico_PutContextualIconToAdd (ActEdiCfe,NULL, + NULL,NULL, + Txt_New_call_FOR_EXAM); + } + +/*****************************************************************************/ +/****************** Put button to create a new call for exam *****************/ +/*****************************************************************************/ + +static void Cfe_PutButtonToCreateNewCallForExam (void) + { + extern const char *Txt_New_call_FOR_EXAM; + + Frm_BeginForm (ActEdiCfe); + Btn_PutConfirmButton (Txt_New_call_FOR_EXAM); + Frm_EndForm (); + } + +/*****************************************************************************/ +/******************** Add a call for exam to the database ********************/ +/*****************************************************************************/ +// Return the code of the call for exam just added + +static long Cfe_AddCallForExamToDB (const struct Cfe_CallsForExams *CallsForExams) + { + long ExaCod; + + /***** Add call for exam *****/ + ExaCod = + DB_QueryINSERTandReturnCode ("can not create a new call for exam", + "INSERT INTO exam_announcements " + "(CrsCod,Status,NumNotif,CrsFullName,Year,ExamSession," + "CallDate,ExamDate,Duration," + "Place,ExamMode,Structure,DocRequired,MatRequired,MatAllowed,OtherInfo)" + " VALUES " + "(%ld,%u,0,'%s',%u,'%s'," + "NOW(),'%04u-%02u-%02u %02u:%02u:00','%02u:%02u:00','%s'," + "'%s','%s','%s','%s','%s','%s')", + Gbl.Hierarchy.Crs.CrsCod, + (unsigned) Cfe_VISIBLE_CALL_FOR_EXAM, + CallsForExams->CallForExam.CrsFullName, + CallsForExams->CallForExam.Year, + CallsForExams->CallForExam.Session, + CallsForExams->CallForExam.ExamDate.Year, + CallsForExams->CallForExam.ExamDate.Month, + CallsForExams->CallForExam.ExamDate.Day, + CallsForExams->CallForExam.StartTime.Hour, + CallsForExams->CallForExam.StartTime.Minute, + CallsForExams->CallForExam.Duration.Hour, + CallsForExams->CallForExam.Duration.Minute, + CallsForExams->CallForExam.Place, + CallsForExams->CallForExam.Mode, + CallsForExams->CallForExam.Structure, + CallsForExams->CallForExam.DocRequired, + CallsForExams->CallForExam.MatRequired, + CallsForExams->CallForExam.MatAllowed, + CallsForExams->CallForExam.OtherInfo); + + return ExaCod; + } + +/*****************************************************************************/ +/***************** Modify a call for exam in the database ********************/ +/*****************************************************************************/ + +static void Cfe_ModifyCallForExamInDB (const struct Cfe_CallsForExams *CallsForExams, + long ExaCod) + { + /***** Modify call for exam *****/ + DB_QueryUPDATE ("can not update a call for exam", + "UPDATE exam_announcements" + " SET CrsFullName='%s',Year=%u,ExamSession='%s'," + "ExamDate='%04u-%02u-%02u %02u:%02u:00'," + "Duration='%02u:%02u:00'," + "Place='%s',ExamMode='%s',Structure='%s'," + "DocRequired='%s',MatRequired='%s',MatAllowed='%s',OtherInfo='%s'" + " WHERE ExaCod=%ld", + CallsForExams->CallForExam.CrsFullName, + CallsForExams->CallForExam.Year, + CallsForExams->CallForExam.Session, + CallsForExams->CallForExam.ExamDate.Year, + CallsForExams->CallForExam.ExamDate.Month, + CallsForExams->CallForExam.ExamDate.Day, + CallsForExams->CallForExam.StartTime.Hour, + CallsForExams->CallForExam.StartTime.Minute, + CallsForExams->CallForExam.Duration.Hour, + CallsForExams->CallForExam.Duration.Minute, + CallsForExams->CallForExam.Place, + CallsForExams->CallForExam.Mode, + CallsForExams->CallForExam.Structure, + CallsForExams->CallForExam.DocRequired, + CallsForExams->CallForExam.MatRequired, + CallsForExams->CallForExam.MatAllowed, + CallsForExams->CallForExam.OtherInfo, + ExaCod); + } + +/*****************************************************************************/ +/******** Create a list with the dates of all the calls for exams ************/ +/*****************************************************************************/ + +void Cfe_CreateListCallsForExams (struct Cfe_CallsForExams *CallsForExams) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned long NumExaAnn; + unsigned long NumExaAnns; + + if (Gbl.DB.DatabaseIsOpen) + { + /***** Get exam dates (ordered from more recent to older) + of visible calls for exams + in current course from database *****/ + NumExaAnns = DB_QuerySELECT (&mysql_res,"can not get calls for exams" + " in this course", + "SELECT ExaCod,DATE(ExamDate)" + " FROM exam_announcements" + " WHERE CrsCod=%ld AND Status=%u" + " ORDER BY ExamDate DESC", + Gbl.Hierarchy.Crs.CrsCod, + (unsigned) Cfe_VISIBLE_CALL_FOR_EXAM); + + /***** The result of the query may be empty *****/ + CallsForExams->Lst = NULL; + CallsForExams->NumCallsForExams = 0; + if (NumExaAnns) + { + /***** Allocate memory for the list *****/ + if ((CallsForExams->Lst = calloc (NumExaAnns,sizeof (*CallsForExams->Lst))) == NULL) + Lay_NotEnoughMemoryExit (); + + /***** Get the dates of the existing calls for exams *****/ + for (NumExaAnn = 0; + NumExaAnn < NumExaAnns; + NumExaAnn++) + { + /***** Get next call for exam *****/ + row = mysql_fetch_row (mysql_res); + + /* Get exam code (row[0]) */ + CallsForExams->Lst[CallsForExams->NumCallsForExams].ExaCod = Str_ConvertStrCodToLongCod (row[0]); + + /* Read the date of the exam (row[1]) */ + if (sscanf (row[1],"%04u-%02u-%02u", + &CallsForExams->Lst[CallsForExams->NumCallsForExams].ExamDate.Year, + &CallsForExams->Lst[CallsForExams->NumCallsForExams].ExamDate.Month, + &CallsForExams->Lst[CallsForExams->NumCallsForExams].ExamDate.Day) != 3) + Lay_ShowErrorAndExit ("Wrong date of exam."); + + /***** Increment number of elements in list *****/ + CallsForExams->NumCallsForExams++; + } + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + } + } + +/*****************************************************************************/ +/****************** Free list of dates of calls for exams ********************/ +/*****************************************************************************/ + +void Cfe_FreeListCallsForExams (struct Cfe_CallsForExams *CallsForExams) + { + if (CallsForExams->Lst) + { + free (CallsForExams->Lst); + CallsForExams->Lst = NULL; + CallsForExams->NumCallsForExams = 0; + } + } + +/*****************************************************************************/ +/*********** Read the data of a call for exam from the database **************/ +/*****************************************************************************/ + +static void Cfe_GetDataCallForExamFromDB (struct Cfe_CallsForExams *CallsForExams, + long ExaCod) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned long NumExaAnns; + unsigned UnsignedNum; + unsigned Hour; + unsigned Minute; + unsigned Second; + + /***** Get data of a call for exam from database *****/ + NumExaAnns = DB_QuerySELECT (&mysql_res,"can not get data" + " of a call for exam", + "SELECT CrsCod,Status,CrsFullName,Year,ExamSession," + "CallDate,ExamDate,Duration,Place,ExamMode," + "Structure,DocRequired,MatRequired,MatAllowed,OtherInfo" + " FROM exam_announcements WHERE ExaCod=%ld", + ExaCod); + + /***** The result of the query must have one row *****/ + if (NumExaAnns != 1) + Lay_ShowErrorAndExit ("Error when getting data of a call for exam."); + + /***** Get the data of the call for exam *****/ + row = mysql_fetch_row (mysql_res); + + /* Code of the course in which the call for exam is inserted (row[0]) */ + CallsForExams->CallForExam.CrsCod = Str_ConvertStrCodToLongCod (row[0]); + + /* Status of the call for exam (row[1]) */ + if (sscanf (row[1],"%u",&UnsignedNum) != 1) + Lay_ShowErrorAndExit ("Wrong status."); + if (UnsignedNum >= Cfe_NUM_STATUS) + Lay_ShowErrorAndExit ("Wrong status."); + CallsForExams->CallForExam.Status = (Cfe_Status_t) UnsignedNum; + + /* Name of the course (row[2]) */ + Str_Copy (CallsForExams->CallForExam.CrsFullName,row[2], + sizeof (CallsForExams->CallForExam.CrsFullName) - 1); + + /* Year (row[3]) */ + if (sscanf (row[3],"%u",&CallsForExams->CallForExam.Year) != 1) + Lay_ShowErrorAndExit ("Wrong year."); + + /* Exam session (row[4]) */ + Str_Copy (CallsForExams->CallForExam.Session,row[4], + sizeof (CallsForExams->CallForExam.Session) - 1); + + /* Date of call for exam (row[5]) */ + if (sscanf (row[5],"%04u-%02u-%02u %02u:%02u:%02u", + &CallsForExams->CallForExam.CallDate.Year, + &CallsForExams->CallForExam.CallDate.Month, + &CallsForExams->CallForExam.CallDate.Day, + &Hour, + &Minute, + &Second) != 6) + Lay_ShowErrorAndExit ("Wrong date of call for exam."); + + /* Date of exam (row[6]) */ + if (sscanf (row[6],"%04u-%02u-%02u %02u:%02u:%02u", + &CallsForExams->CallForExam.ExamDate.Year, + &CallsForExams->CallForExam.ExamDate.Month, + &CallsForExams->CallForExam.ExamDate.Day, + &CallsForExams->CallForExam.StartTime.Hour, + &CallsForExams->CallForExam.StartTime.Minute, + &Second) != 6) + Lay_ShowErrorAndExit ("Wrong date of exam."); + snprintf (CallsForExams->CallForExam.ExamDate.YYYYMMDD, + sizeof (CallsForExams->CallForExam.ExamDate.YYYYMMDD),"%04u%02u%02u", + CallsForExams->CallForExam.ExamDate.Year, + CallsForExams->CallForExam.ExamDate.Month, + CallsForExams->CallForExam.ExamDate.Day); + + /* Approximate duration (row[7]) */ + if (sscanf (row[7],"%02u:%02u:%02u", + &CallsForExams->CallForExam.Duration.Hour, + &CallsForExams->CallForExam.Duration.Minute, + &Second) != 3) + Lay_ShowErrorAndExit ("Wrong duration of exam."); + + /* Place (row[8]), exam mode (row[9]), structure (row[10]), + documentation required (row[11]), material required (row[12]), + material allowed (row[13]) and other information for students (row[14]) */ + Str_Copy (CallsForExams->CallForExam.Place ,row[ 8],Cns_MAX_BYTES_TEXT); + Str_Copy (CallsForExams->CallForExam.Mode ,row[ 9],Cns_MAX_BYTES_TEXT); + Str_Copy (CallsForExams->CallForExam.Structure ,row[10],Cns_MAX_BYTES_TEXT); + Str_Copy (CallsForExams->CallForExam.DocRequired,row[11],Cns_MAX_BYTES_TEXT); + Str_Copy (CallsForExams->CallForExam.MatRequired,row[12],Cns_MAX_BYTES_TEXT); + Str_Copy (CallsForExams->CallForExam.MatAllowed ,row[13],Cns_MAX_BYTES_TEXT); + Str_Copy (CallsForExams->CallForExam.OtherInfo ,row[14],Cns_MAX_BYTES_TEXT); + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + } + +/*****************************************************************************/ +/************** Show a form with the data of a call for exam *****************/ +/*****************************************************************************/ + +static void Cfe_ShowCallForExam (struct Cfe_CallsForExams *CallsForExams, + long ExaCod, + Cfe_TypeViewCallForExam_t TypeViewCallForExam, + bool HighLight) + { + extern const char *Hlp_ASSESSMENT_Calls_for_exam_new_call; + extern const char *Hlp_ASSESSMENT_Announcements_edit_announcement; + extern const char *Txt_YEAR_OF_DEGREE[1 + Deg_MAX_YEARS_PER_DEGREE]; + extern const char *Txt_CALL_FOR_EXAM; + extern const char *Txt_CALL_FOR_EXAM_Course; + extern const char *Txt_CALL_FOR_EXAM_Year_or_semester; + extern const char *Txt_CALL_FOR_EXAM_Session; + extern const char *Txt_CALL_FOR_EXAM_Exam_date; + extern const char *Txt_CALL_FOR_EXAM_Start_time; + extern const char *Txt_CALL_FOR_EXAM_Approximate_duration; + extern const char *Txt_CALL_FOR_EXAM_Place_of_exam; + extern const char *Txt_CALL_FOR_EXAM_Mode; + extern const char *Txt_CALL_FOR_EXAM_Structure_of_the_exam; + extern const char *Txt_CALL_FOR_EXAM_Documentation_required; + extern const char *Txt_CALL_FOR_EXAM_Material_required; + extern const char *Txt_CALL_FOR_EXAM_Material_allowed; + extern const char *Txt_CALL_FOR_EXAM_Other_information; + extern const char *Txt_hours_ABBREVIATION; + extern const char *Txt_hour; + extern const char *Txt_hours; + extern const char *Txt_minute; + extern const char *Txt_minutes; + extern const char *Txt_Publish_call_FOR_EXAM; + struct Ins_Instit Ins; + char StrExamDate[Cns_MAX_BYTES_DATE + 1]; + unsigned Year; + unsigned Hour; + unsigned Minute; + char *Anchor = NULL; + const char *Width; + void (*FunctionToDrawContextualIcons) (void *Args); + const char *HelpLink; + static const char *ClassCallForExam[Cfe_NUM_VIEWS][Cfe_NUM_STATUS] = + { + [Cfe_NORMAL_VIEW][Cfe_VISIBLE_CALL_FOR_EXAM] = "CALL_FOR_EXAM_VISIBLE", + [Cfe_NORMAL_VIEW][Cfe_HIDDEN_CALL_FOR_EXAM ] = "CALL_FOR_EXAM_HIDDEN", + [Cfe_NORMAL_VIEW][Cfe_DELETED_CALL_FOR_EXAM] = NULL, // Not applicable here + + [Cfe_PRINT_VIEW ][Cfe_VISIBLE_CALL_FOR_EXAM] = "CALL_FOR_EXAM_VISIBLE", + [Cfe_PRINT_VIEW ][Cfe_HIDDEN_CALL_FOR_EXAM ] = "CALL_FOR_EXAM_VISIBLE", + [Cfe_PRINT_VIEW ][Cfe_DELETED_CALL_FOR_EXAM] = NULL, // Not applicable here + + [Cfe_FORM_VIEW ][Cfe_VISIBLE_CALL_FOR_EXAM] = "CALL_FOR_EXAM_VISIBLE", + [Cfe_FORM_VIEW ][Cfe_HIDDEN_CALL_FOR_EXAM ] = "CALL_FOR_EXAM_VISIBLE", + [Cfe_FORM_VIEW ][Cfe_DELETED_CALL_FOR_EXAM] = NULL, // Not applicable here + }; + + /***** Get data of institution of this degree *****/ + Ins.InsCod = Gbl.Hierarchy.Ins.InsCod; + Ins_GetDataOfInstitutionByCod (&Ins); + + /***** Build anchor string *****/ + Frm_SetAnchorStr (ExaCod,&Anchor); + + /***** Begin article *****/ + if (TypeViewCallForExam == Cfe_NORMAL_VIEW) + HTM_ARTICLE_Begin (Anchor); + + /***** Begin box *****/ + Width = "625px"; + CallsForExams->Anchor = Anchor; // Used to put contextual icons + CallsForExams->ExaCod = ExaCod; // Used to put contextual icons + FunctionToDrawContextualIcons = TypeViewCallForExam == Cfe_NORMAL_VIEW ? Cfe_PutIconsCallForExam : + NULL; + HelpLink = TypeViewCallForExam == Cfe_FORM_VIEW ? ((ExaCod > 0) ? Hlp_ASSESSMENT_Announcements_edit_announcement : + Hlp_ASSESSMENT_Calls_for_exam_new_call) : + NULL; + if (HighLight) + { + /* Show pending alerts */ + Ale_ShowAlerts (Anchor); + + /* Start highlighted box */ + Box_BoxShadowBegin (Width,NULL, + FunctionToDrawContextualIcons,CallsForExams, + HelpLink); + } + else // Don't highlight + /* Start normal box */ + Box_BoxBegin (Width,NULL, + FunctionToDrawContextualIcons,CallsForExams, + HelpLink,Box_NOT_CLOSABLE); + + if (TypeViewCallForExam == Cfe_FORM_VIEW) + { + /***** Begin form *****/ + Frm_StartFormAnchor (ActRcvCfe,Anchor); + if (ExaCod > 0) // Existing call for exam + Cfe_PutHiddenParamExaCod (ExaCod); + } + + /***** Begin table *****/ + HTM_TABLE_Begin ("%s CELLS_PAD_2", + ClassCallForExam[TypeViewCallForExam][CallsForExams->CallForExam.Status]); + + /***** Institution logo *****/ + HTM_TR_Begin (NULL); + HTM_TD_Begin ("colspan=\"2\" class=\"CM\""); + if (TypeViewCallForExam == Cfe_PRINT_VIEW) + HTM_SPAN_Begin ("class=\"EXAM_TIT\""); + else + HTM_A_Begin ("href=\"%s\" target=\"_blank\" class=\"EXAM_TIT\"", + Ins.WWW); + Lgo_DrawLogo (Hie_Lvl_INS,Ins.InsCod,Ins.FullName,64,NULL,true); + HTM_BR (); + HTM_Txt (Ins.FullName); + if (TypeViewCallForExam == Cfe_PRINT_VIEW) + HTM_SPAN_End (); + else + HTM_A_End (); + HTM_TD_End (); + HTM_TR_End (); + + /***** Degree *****/ + HTM_TR_Begin (NULL); + HTM_TD_Begin ("colspan=\"2\" class=\"EXAM_TIT CM\""); + if (TypeViewCallForExam == Cfe_NORMAL_VIEW) + HTM_A_Begin ("href=\"%s\" target=\"_blank\" class=\"EXAM_TIT\"", + Gbl.Hierarchy.Deg.WWW); + HTM_Txt (Gbl.Hierarchy.Deg.FullName); + if (TypeViewCallForExam == Cfe_NORMAL_VIEW) + HTM_A_End (); + HTM_TD_End (); + HTM_TR_End (); + + /***** Title *****/ + HTM_TR_Begin (NULL); + HTM_TD_Begin ("colspan=\"2\" class=\"EXAM CM\""); + HTM_NBSP (); + HTM_BR (); + HTM_STRONG_Begin (); + HTM_Txt (Txt_CALL_FOR_EXAM); + HTM_STRONG_End (); + HTM_TD_End (); + HTM_TR_End (); + + HTM_TR_Begin (NULL); + HTM_TD_Begin ("colspan=\"2\" class=\"EXAM LM\""); + HTM_NBSP (); + HTM_TD_End (); + HTM_TR_End (); + + /***** Name of the course *****/ + HTM_TR_Begin (NULL); + + /* Label */ + Frm_LabelColumn ("RT", + TypeViewCallForExam == Cfe_FORM_VIEW ? "CrsName" : + NULL, + Txt_CALL_FOR_EXAM_Course); + + /* Data */ + HTM_TD_Begin ("class=\"EXAM LB\""); + if (TypeViewCallForExam == Cfe_FORM_VIEW) + HTM_INPUT_TEXT ("CrsName",Cns_HIERARCHY_MAX_CHARS_FULL_NAME,CallsForExams->CallForExam.CrsFullName, + HTM_DONT_SUBMIT_ON_CHANGE, + "id=\"CrsName\" size=\"30\""); + else + { + HTM_STRONG_Begin (); + HTM_Txt (CallsForExams->CallForExam.CrsFullName); + HTM_STRONG_End (); + } + HTM_TD_End (); + + HTM_TR_End (); + + /***** Year/semester (N.A., 1º, 2º, 3º, 4º, 5º...) *****/ + HTM_TR_Begin (NULL); + + /* Label */ + Frm_LabelColumn ("RT", + TypeViewCallForExam == Cfe_FORM_VIEW ? "Year" : + NULL, + Txt_CALL_FOR_EXAM_Year_or_semester); + + /* Data */ + HTM_TD_Begin ("class=\"EXAM LB\""); + if (TypeViewCallForExam == Cfe_FORM_VIEW) + { + HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, + "id=\"Year\" name=\"Year\""); + for (Year = 0; + Year <= Deg_MAX_YEARS_PER_DEGREE; + Year++) + HTM_OPTION (HTM_Type_UNSIGNED,&Year, + CallsForExams->CallForExam.Year == Year,false, + "%s",Txt_YEAR_OF_DEGREE[Year]); + HTM_SELECT_End (); + } + else + HTM_Txt (Txt_YEAR_OF_DEGREE[CallsForExams->CallForExam.Year]); + HTM_TD_End (); + + HTM_TR_End (); + + /***** Exam session *****/ + HTM_TR_Begin (NULL); + + /* Label */ + Frm_LabelColumn ("RT", + TypeViewCallForExam == Cfe_FORM_VIEW ? "ExamSession" : + NULL, + Txt_CALL_FOR_EXAM_Session); + + /* Data */ + HTM_TD_Begin ("class=\"EXAM LB\""); + if (TypeViewCallForExam == Cfe_FORM_VIEW) + HTM_INPUT_TEXT ("ExamSession",Cfe_MAX_CHARS_SESSION,CallsForExams->CallForExam.Session, + HTM_DONT_SUBMIT_ON_CHANGE, + "id=\"ExamSession\" size=\"30\""); + else + HTM_Txt (CallsForExams->CallForExam.Session); + HTM_TD_End (); + + HTM_TR_End (); + + /***** Date of the exam *****/ + HTM_TR_Begin (NULL); + + /* Label */ + Frm_LabelColumn ("RT", + TypeViewCallForExam == Cfe_FORM_VIEW ? "ExamYear" : + NULL, + Txt_CALL_FOR_EXAM_Exam_date); + + /* Data */ + if (TypeViewCallForExam == Cfe_FORM_VIEW) + { + HTM_TD_Begin ("class=\"LB\""); + Dat_WriteFormDate (CallsForExams->CallForExam.ExamDate.Year < Gbl.Now.Date.Year ? CallsForExams->CallForExam.ExamDate.Year : + Gbl.Now.Date.Year, + Gbl.Now.Date.Year + 1,"Exam", + &(CallsForExams->CallForExam.ExamDate), + false,false); + HTM_TD_End (); + } + else + { + Dat_ConvDateToDateStr (&CallsForExams->CallForExam.ExamDate, + StrExamDate); + HTM_TD_Begin ("class=\"EXAM LB\""); + HTM_Txt (StrExamDate); + HTM_TD_End (); + } + HTM_TR_End (); + + /***** Start time *****/ + HTM_TR_Begin (NULL); + + /* Label */ + Frm_LabelColumn ("RT", + TypeViewCallForExam == Cfe_FORM_VIEW ? "ExamHour" : + NULL, + Txt_CALL_FOR_EXAM_Start_time); + + /* Data */ + HTM_TD_Begin ("class=\"EXAM LB\""); + if (TypeViewCallForExam == Cfe_FORM_VIEW) + { + HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, + "id=\"ExamHour\" name=\"ExamHour\""); + HTM_OPTION (HTM_Type_STRING,"0", + CallsForExams->CallForExam.StartTime.Hour == 0,false, + "-"); + for (Hour = 7; + Hour <= 22; + Hour++) + HTM_OPTION (HTM_Type_UNSIGNED,&Hour, + CallsForExams->CallForExam.StartTime.Hour == Hour,false, + "%02u %s",Hour,Txt_hours_ABBREVIATION); + HTM_SELECT_End (); + + HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, + "name=\"ExamMinute\""); + for (Minute = 0; + Minute <= 59; + Minute++) + HTM_OPTION (HTM_Type_UNSIGNED,&Minute, + CallsForExams->CallForExam.StartTime.Minute == Minute,false, + "%02u ′",Minute); + HTM_SELECT_End (); + } + else if (CallsForExams->CallForExam.StartTime.Hour) + HTM_TxtF ("%2u:%02u",CallsForExams->CallForExam.StartTime.Hour, + CallsForExams->CallForExam.StartTime.Minute); + HTM_TD_End (); + + HTM_TR_End (); + + /***** Approximate duration of the exam *****/ + HTM_TR_Begin (NULL); + + /* Label */ + Frm_LabelColumn ("RT", + TypeViewCallForExam == Cfe_FORM_VIEW ? "DurationHour" : + NULL, + Txt_CALL_FOR_EXAM_Approximate_duration); + + /* Data */ + HTM_TD_Begin ("class=\"EXAM LB\""); + if (TypeViewCallForExam == Cfe_FORM_VIEW) + { + HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, + "id=\"DurationHour\" name=\"DurationHour\""); + for (Hour = 0; + Hour <= 8; + Hour++) + HTM_OPTION (HTM_Type_UNSIGNED,&Hour, + CallsForExams->CallForExam.Duration.Hour == Hour,false, + "%02u %s",Hour,Txt_hours_ABBREVIATION); + HTM_SELECT_End (); + + HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, + "name=\"DurationMinute\""); + for (Minute = 0; + Minute <= 59; + Minute++) + HTM_OPTION (HTM_Type_UNSIGNED,&Minute, + CallsForExams->CallForExam.Duration.Minute == Minute,false, + "%02u ′",Minute); + HTM_SELECT_End (); + } + else if (CallsForExams->CallForExam.Duration.Hour || + CallsForExams->CallForExam.Duration.Minute) + { + if (CallsForExams->CallForExam.Duration.Hour) + { + if (CallsForExams->CallForExam.Duration.Minute) + HTM_TxtF ("%u%s %u′",CallsForExams->CallForExam.Duration.Hour, + Txt_hours_ABBREVIATION, + CallsForExams->CallForExam.Duration.Minute); + else + HTM_TxtF ("%u %s",CallsForExams->CallForExam.Duration.Hour, + CallsForExams->CallForExam.Duration.Hour == 1 ? Txt_hour : + Txt_hours); + } + else if (CallsForExams->CallForExam.Duration.Minute) + { + HTM_TxtF ("%u %s",CallsForExams->CallForExam.Duration.Minute, + CallsForExams->CallForExam.Duration.Minute == 1 ? Txt_minute : + Txt_minutes); + } + } + HTM_TD_End (); + + HTM_TR_End (); + + /***** Place where the exam will be made *****/ + HTM_TR_Begin (NULL); + + /* Label */ + Frm_LabelColumn ("RT", + TypeViewCallForExam == Cfe_FORM_VIEW ? "Place" : + NULL, + Txt_CALL_FOR_EXAM_Place_of_exam); + + /* Data */ + HTM_TD_Begin ("class=\"EXAM LB\""); + if (TypeViewCallForExam == Cfe_FORM_VIEW) + { + HTM_TEXTAREA_Begin ("id=\"Place\" name=\"Place\" cols=\"40\" rows=\"4\""); + HTM_Txt (CallsForExams->CallForExam.Place); + HTM_TEXTAREA_End (); + } + else + { + Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, + CallsForExams->CallForExam.Place, + Cns_MAX_BYTES_TEXT,false); + HTM_Txt (CallsForExams->CallForExam.Place); + } + HTM_TD_End (); + + HTM_TR_End (); + + /***** Exam mode *****/ + HTM_TR_Begin (NULL); + + /* Label */ + Frm_LabelColumn ("RT", + TypeViewCallForExam == Cfe_FORM_VIEW ? "ExamMode" : + NULL, + Txt_CALL_FOR_EXAM_Mode); + + /* Data */ + HTM_TD_Begin ("class=\"EXAM LB\""); + if (TypeViewCallForExam == Cfe_FORM_VIEW) + { + HTM_TEXTAREA_Begin ("id=\"ExamMode\" name=\"ExamMode\" cols=\"40\" rows=\"2\""); + HTM_Txt (CallsForExams->CallForExam.Mode); + HTM_TEXTAREA_End (); + } + else + { + Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, + CallsForExams->CallForExam.Mode, + Cns_MAX_BYTES_TEXT,false); + HTM_Txt (CallsForExams->CallForExam.Mode); + } + HTM_TD_End (); + + HTM_TR_End (); + + /***** Structure of the exam *****/ + HTM_TR_Begin (NULL); + + /* Label */ + Frm_LabelColumn ("RT", + TypeViewCallForExam == Cfe_FORM_VIEW ? "Structure" : + NULL, + Txt_CALL_FOR_EXAM_Structure_of_the_exam); + + /* Data */ + HTM_TD_Begin ("class=\"EXAM LB\""); + if (TypeViewCallForExam == Cfe_FORM_VIEW) + { + HTM_TEXTAREA_Begin ("id=\"Structure\" name=\"Structure\" cols=\"40\" rows=\"8\""); + HTM_Txt (CallsForExams->CallForExam.Structure); + HTM_TEXTAREA_End (); + } + else + { + Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, + CallsForExams->CallForExam.Structure, + Cns_MAX_BYTES_TEXT,false); + HTM_Txt (CallsForExams->CallForExam.Structure); + } + HTM_TD_End (); + + HTM_TR_End (); + + /***** Documentation required *****/ + HTM_TR_Begin (NULL); + + /* Label */ + Frm_LabelColumn ("RT", + TypeViewCallForExam == Cfe_FORM_VIEW ? "DocRequired" : + NULL, + Txt_CALL_FOR_EXAM_Documentation_required); + + /* Data */ + HTM_TD_Begin ("class=\"EXAM LB\""); + if (TypeViewCallForExam == Cfe_FORM_VIEW) + { + HTM_TEXTAREA_Begin ("id=\"DocRequired\" name=\"DocRequired\" cols=\"40\" rows=\"2\""); + HTM_Txt (CallsForExams->CallForExam.DocRequired); + HTM_TEXTAREA_End (); + } + else + { + Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, + CallsForExams->CallForExam.DocRequired, + Cns_MAX_BYTES_TEXT,false); + HTM_Txt (CallsForExams->CallForExam.DocRequired); + } + HTM_TD_End (); + + HTM_TR_End (); + + /***** Material required *****/ + HTM_TR_Begin (NULL); + + /* Label */ + Frm_LabelColumn ("RT", + TypeViewCallForExam == Cfe_FORM_VIEW ? "MatRequired" : + NULL, + Txt_CALL_FOR_EXAM_Material_required); + + /* Data */ + HTM_TD_Begin ("class=\"EXAM LB\""); + if (TypeViewCallForExam == Cfe_FORM_VIEW) + { + HTM_TEXTAREA_Begin ("id=\"MatRequired\" name=\"MatRequired\" cols=\"40\" rows=\"4\""); + HTM_Txt (CallsForExams->CallForExam.MatRequired); + HTM_TEXTAREA_End (); + } + else + { + Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, + CallsForExams->CallForExam.MatRequired, + Cns_MAX_BYTES_TEXT,false); + HTM_Txt (CallsForExams->CallForExam.MatRequired); + } + HTM_TD_End (); + + HTM_TR_End (); + + /***** Material allowed *****/ + HTM_TR_Begin (NULL); + + /* Label */ + Frm_LabelColumn ("RT", + TypeViewCallForExam == Cfe_FORM_VIEW ? "MatAllowed" : + NULL, + Txt_CALL_FOR_EXAM_Material_allowed); + + /* Data */ + HTM_TD_Begin ("class=\"EXAM LB\""); + if (TypeViewCallForExam == Cfe_FORM_VIEW) + { + HTM_TEXTAREA_Begin ("id=\"MatAllowed\" name=\"MatAllowed\" cols=\"40\" rows=\"4\""); + HTM_Txt (CallsForExams->CallForExam.MatAllowed); + HTM_TEXTAREA_End (); + } + else + { + Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, + CallsForExams->CallForExam.MatAllowed, + Cns_MAX_BYTES_TEXT,false); + HTM_Txt (CallsForExams->CallForExam.MatAllowed); + } + HTM_TD_End (); + + HTM_TR_End (); + + /***** Other information to students *****/ + HTM_TR_Begin (NULL); + + /* Label */ + Frm_LabelColumn ("RT", + TypeViewCallForExam == Cfe_FORM_VIEW ? "OtherInfo" : + NULL, + Txt_CALL_FOR_EXAM_Other_information); + + /* Data */ + HTM_TD_Begin ("class=\"EXAM LB\""); + if (TypeViewCallForExam == Cfe_FORM_VIEW) + { + HTM_TEXTAREA_Begin ("id=\"OtherInfo\" name=\"OtherInfo\" cols=\"40\" rows=\"5\""); + HTM_Txt (CallsForExams->CallForExam.OtherInfo); + HTM_TEXTAREA_End (); + } + else + { + Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, + CallsForExams->CallForExam.OtherInfo, + Cns_MAX_BYTES_TEXT,false); + HTM_Txt (CallsForExams->CallForExam.OtherInfo); + } + HTM_TD_End (); + + HTM_TR_End (); + + /***** End table, send button and end box *****/ + if (TypeViewCallForExam == Cfe_FORM_VIEW) + Box_BoxTableWithButtonEnd ((ExaCod > 0) ? Btn_CONFIRM_BUTTON : + Btn_CREATE_BUTTON, + Txt_Publish_call_FOR_EXAM); + else + Box_BoxTableEnd (); + + /***** Show QR code *****/ + if (TypeViewCallForExam == Cfe_PRINT_VIEW) + QR_ExamAnnnouncement (); + + /***** End article *****/ + if (TypeViewCallForExam == Cfe_NORMAL_VIEW) + HTM_ARTICLE_End (); + + /***** Free anchor string *****/ + Frm_FreeAnchorStr (Anchor); + } + +/*****************************************************************************/ +/*********** Put icons to remove / edit / print a call for exam **************/ +/*****************************************************************************/ + +static void Cfe_PutIconsCallForExam (void *CallsForExams) + { + if (CallsForExams) + { + if (Gbl.Usrs.Me.Role.Logged == Rol_TCH || + Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM) + { + /***** Link to remove this call for exam *****/ + Ico_PutContextualIconToRemove (ActReqRemCfe,NULL, + Cfe_PutParamExaCodToEdit, + &((struct Cfe_CallsForExams *) CallsForExams)->ExaCod); + + /***** Put form to hide/show exam announement *****/ + switch (((struct Cfe_CallsForExams *) CallsForExams)->CallForExam.Status) + { + case Cfe_VISIBLE_CALL_FOR_EXAM: + Ico_PutContextualIconToHide (ActHidCfe,((struct Cfe_CallsForExams *) CallsForExams)->Anchor, + Cfe_PutParamExaCodToEdit, + &((struct Cfe_CallsForExams *) CallsForExams)->ExaCod); + break; + case Cfe_HIDDEN_CALL_FOR_EXAM: + Ico_PutContextualIconToUnhide (ActUnhCfe,((struct Cfe_CallsForExams *) CallsForExams)->Anchor, + Cfe_PutParamExaCodToEdit, + &((struct Cfe_CallsForExams *) CallsForExams)->ExaCod); + break; + case Cfe_DELETED_CALL_FOR_EXAM: // Not applicable here + break; + } + + /***** Link to edit this call for exam *****/ + Ico_PutContextualIconToEdit (ActEdiCfe,NULL, + Cfe_PutParamExaCodToEdit, + &((struct Cfe_CallsForExams *) CallsForExams)->ExaCod); + } + + /***** Link to print view *****/ + Ico_PutContextualIconToPrint (ActPrnCfe, + Cfe_PutParamExaCodToEdit, + &((struct Cfe_CallsForExams *) CallsForExams)->ExaCod); + } + } + +/*****************************************************************************/ +/***************** Param with the code of a call for exam ********************/ +/*****************************************************************************/ + +static void Cfe_PutParamExaCodToEdit (void *ExaCod) + { + if (ExaCod) + Cfe_PutHiddenParamExaCod (*((long *) ExaCod)); + } + +void Cfe_PutHiddenParamExaCod (long ExaCod) + { + Par_PutHiddenParamLong (NULL,"ExaCod",ExaCod); + } + +/*****************************************************************************/ +/************ Get parameter with the code of a call for exam *****************/ +/*****************************************************************************/ + +static long Cfe_GetParamExaCod (void) + { + /* Get notice code */ + return Par_GetParToLong ("ExaCod"); + } + +/*****************************************************************************/ +/************** Get summary and content about a call for exam ****************/ +/*****************************************************************************/ + +void Cfe_GetSummaryAndContentCallForExam (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1], + char **ContentStr, + long ExaCod,bool GetContent) + { + extern const char *Txt_hours_ABBREVIATION; + struct Cfe_CallsForExams CallsForExams; + char CrsNameAndDate[Cns_HIERARCHY_MAX_BYTES_FULL_NAME + (2 + Cns_MAX_BYTES_DATE + 7) + 1]; + char StrExamDate[Cns_MAX_BYTES_DATE + 1]; + + /***** Reset calls for exams context *****/ + Cfe_ResetCallsForExams (&CallsForExams); + + /***** Initializations *****/ + SummaryStr[0] = '\0'; // Return nothing on error + + /***** Allocate memory for the call for exam *****/ + Cfe_AllocMemCallForExam (&CallsForExams); + + /***** Get data of a call for exam from database *****/ + Cfe_GetDataCallForExamFromDB (&CallsForExams,ExaCod); + + /***** Content *****/ + if (GetContent) + Cfe_GetNotifContentCallForExam (&CallsForExams,ContentStr); + + /***** Summary *****/ + /* Name of the course and date of exam */ + Dat_ConvDateToDateStr (&CallsForExams.CallForExam.ExamDate,StrExamDate); + snprintf (CrsNameAndDate,sizeof (CrsNameAndDate),"%s, %s, %2u:%02u", + CallsForExams.CallForExam.CrsFullName, + StrExamDate, + CallsForExams.CallForExam.StartTime.Hour, + CallsForExams.CallForExam.StartTime.Minute); + Str_Copy (SummaryStr,CrsNameAndDate,Ntf_MAX_BYTES_SUMMARY); + + /***** Free memory of the call for exam *****/ + Cfe_FreeMemCallForExam (&CallsForExams); + } + +/*****************************************************************************/ +/************** Show a form with the data of a call for exam *****************/ +/*****************************************************************************/ + +static void Cfe_GetNotifContentCallForExam (const struct Cfe_CallsForExams *CallsForExams, + char **ContentStr) + { + extern const char *Txt_Institution; + extern const char *Txt_Degree; + extern const char *Txt_YEAR_OF_DEGREE[1 + Deg_MAX_YEARS_PER_DEGREE]; + extern const char *Txt_CALL_FOR_EXAM_Course; + extern const char *Txt_CALL_FOR_EXAM_Year_or_semester; + extern const char *Txt_CALL_FOR_EXAM_Session; + extern const char *Txt_CALL_FOR_EXAM_Exam_date; + extern const char *Txt_CALL_FOR_EXAM_Start_time; + extern const char *Txt_CALL_FOR_EXAM_Approximate_duration; + extern const char *Txt_CALL_FOR_EXAM_Place_of_exam; + extern const char *Txt_CALL_FOR_EXAM_Mode; + extern const char *Txt_CALL_FOR_EXAM_Structure_of_the_exam; + extern const char *Txt_CALL_FOR_EXAM_Documentation_required; + extern const char *Txt_CALL_FOR_EXAM_Material_required; + extern const char *Txt_CALL_FOR_EXAM_Material_allowed; + extern const char *Txt_CALL_FOR_EXAM_Other_information; + extern const char *Txt_hours_ABBREVIATION; + struct Hie_Hierarchy Hie; + char StrExamDate[Cns_MAX_BYTES_DATE + 1]; + + /***** Get data of course *****/ + Hie.Crs.CrsCod = CallsForExams->CallForExam.CrsCod; + Crs_GetDataOfCourseByCod (&Hie.Crs); + + /***** Get data of degree *****/ + Hie.Deg.DegCod = Hie.Crs.DegCod; + Deg_GetDataOfDegreeByCod (&Hie.Deg); + + /***** Get data of institution *****/ + Hie.Ins.InsCod = Deg_GetInsCodOfDegreeByCod (Hie.Deg.DegCod); + Ins_GetDataOfInstitutionByCod (&Hie.Ins); + + /***** Convert struct date to a date string *****/ + Dat_ConvDateToDateStr (&CallsForExams->CallForExam.ExamDate,StrExamDate); + + /***** Fill content string *****/ + if (asprintf (ContentStr,"%s: %s
" + "%s: %s
" + "%s: %s
" + "%s: %s
" + "%s: %s
" + "%s: %s
" + "%s: %2u:%02u %s
" + "%s: %2u:%02u %s
" + "%s: %s
" + "%s: %s
" + "%s: %s
" + "%s: %s
" + "%s: %s
" + "%s: %s
" + "%s: %s", + Txt_Institution,Hie.Ins.FullName, + Txt_Degree,Hie.Deg.FullName, + Txt_CALL_FOR_EXAM_Course,CallsForExams->CallForExam.CrsFullName, + Txt_CALL_FOR_EXAM_Year_or_semester,Txt_YEAR_OF_DEGREE[CallsForExams->CallForExam.Year], + Txt_CALL_FOR_EXAM_Session,CallsForExams->CallForExam.Session, + Txt_CALL_FOR_EXAM_Exam_date,StrExamDate, + Txt_CALL_FOR_EXAM_Start_time,CallsForExams->CallForExam.StartTime.Hour, + CallsForExams->CallForExam.StartTime.Minute, + Txt_hours_ABBREVIATION, + Txt_CALL_FOR_EXAM_Approximate_duration,CallsForExams->CallForExam.Duration.Hour, + CallsForExams->CallForExam.Duration.Minute, + Txt_hours_ABBREVIATION, + Txt_CALL_FOR_EXAM_Place_of_exam,CallsForExams->CallForExam.Place, + Txt_CALL_FOR_EXAM_Mode,CallsForExams->CallForExam.Mode, + Txt_CALL_FOR_EXAM_Structure_of_the_exam,CallsForExams->CallForExam.Structure, + Txt_CALL_FOR_EXAM_Documentation_required,CallsForExams->CallForExam.DocRequired, + Txt_CALL_FOR_EXAM_Material_required,CallsForExams->CallForExam.MatRequired, + Txt_CALL_FOR_EXAM_Material_allowed,CallsForExams->CallForExam.MatAllowed, + Txt_CALL_FOR_EXAM_Other_information,CallsForExams->CallForExam.OtherInfo) < 0) + Lay_NotEnoughMemoryExit (); + } diff --git a/swad_call_for_exam.h b/swad_call_for_exam.h new file mode 100644 index 00000000..0d90e926 --- /dev/null +++ b/swad_call_for_exam.h @@ -0,0 +1,129 @@ +// swad_call_for_exam.h: calls for exams + +#ifndef _SWAD_CFE +#define _SWAD_CFE +/* + SWAD (Shared Workspace At a Distance), + 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-2021 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 3 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 . +*/ +/*****************************************************************************/ +/********************************* Headers ***********************************/ +/*****************************************************************************/ + +#include // For boolean type + +#include "swad_constant.h" +#include "swad_course.h" +#include "swad_date.h" +#include "swad_notification.h" + +/*****************************************************************************/ +/************************** Public types and constants ***********************/ +/*****************************************************************************/ + +#define Cfe_NUM_VIEWS 3 +typedef enum + { + Cfe_NORMAL_VIEW, + Cfe_PRINT_VIEW, + Cfe_FORM_VIEW, + } Cfe_TypeViewCallForExam_t; + +#define Cfe_NUM_STATUS 3 +typedef enum + { + Cfe_VISIBLE_CALL_FOR_EXAM = 0, + Cfe_HIDDEN_CALL_FOR_EXAM = 1, + Cfe_DELETED_CALL_FOR_EXAM = 2, + } Cfe_Status_t; // Don't change these numbers because they are used in database +#define Cfe_STATUS_DEFAULT Cfe_VISIBLE_CALL_FOR_EXAM + +#define Cfe_MAX_CHARS_SESSION (128 - 1) // 127 +#define Cfe_MAX_BYTES_SESSION ((Cfe_MAX_CHARS_SESSION + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 2047 + +struct Cfe_CallForExam + { + long CrsCod; + Cfe_Status_t Status; + char CrsFullName[Cns_HIERARCHY_MAX_BYTES_FULL_NAME + 1]; + unsigned Year; // Number of year (0 (N.A.), 1, 2, 3, 4, 5, 6) in the degree + char Session[Cfe_MAX_BYTES_SESSION + 1]; // Exam session is june, september, etc. + struct Date CallDate; + struct Date ExamDate; + struct Hour StartTime; + struct Hour Duration; + char *Place; + char *Mode; + char *Structure; + char *DocRequired; + char *MatRequired; + char *MatAllowed; + char *OtherInfo; + }; + +struct Cfe_ExamCodeAndDate + { + long ExaCod; + struct Date ExamDate; + }; + +struct Cfe_CallsForExams + { + unsigned NumCallsForExams; // Number of calls for exams in the list + struct Cfe_ExamCodeAndDate *Lst; // List of calls for exams + long NewExaCod; // New call for exam just created + long HighlightExaCod; // Call for exam to be highlighted + char HighlightDate[4 + 2 + 2 + 1]; // Date with calls for exams to be highlighted (in YYYYMMDD format) + long ExaCod; // Used to put contextual icons + const char *Anchor; // Used to put contextual icons + struct Cfe_CallForExam CallForExam; + }; + +/*****************************************************************************/ +/***************************** Public prototypes *****************************/ +/*****************************************************************************/ + +void Cfe_ResetCallsForExams (struct Cfe_CallsForExams *CallsForExams); + +void Cfe_PutFrmEditACallForExam (void); +void Cfe_ReceiveCallForExam1 (void); +void Cfe_ReceiveCallForExam2 (void); +void Cfe_PrintCallForExam (void); +void Cfe_ReqRemoveCallForExam (void); +void Cfe_RemoveCallForExam1 (void); +void Cfe_RemoveCallForExam2 (void); +void Cfe_HideCallForExam (void); +void Cfe_UnhideCallForExam (void); + +void Cfe_FreeListCallsForExams (struct Cfe_CallsForExams *CallsForExams); +void Cfe_ListCallsForExamsSee (void); +void Cfe_ListCallsForExamsEdit (void); + +void Cfe_ListCallsForExamsCod (void); +void Cfe_ListCallsForExamsDay (void); + +void Cfe_CreateListCallsForExams (struct Cfe_CallsForExams *CallsForExams); +void Cfe_PutHiddenParamExaCod (long ExaCod); + +void Cfe_GetSummaryAndContentCallForExam (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1], + char **ContentStr, + long ExaCod,bool GetContent); + +#endif diff --git a/swad_changelog.h b/swad_changelog.h index eeb190f2..350f8e30 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -600,12 +600,14 @@ TODO: Salvador Romero Cort TODO: FIX BUG, URGENT! En las fechas como parámetro Dat_WriteParamsIniEndDates(), por ejemplo al cambiar el color de la gráfica de accesos por día y hora, no se respeta la zona horaria. */ -#define Log_PLATFORM_VERSION "SWAD 20.50.11 (2021-03-17)" +#define Log_PLATFORM_VERSION "SWAD 20.51 (2021-03-18)" #define CSS_FILE "swad20.45.css" #define JS_FILE "swad20.6.2.js" /* TODO: Rename CENTRE to CENTER in help wiki. +TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams + Version 20.51: Mar 18, 2021 Call for exam module renamed. (307459 lines) Version 20.50.11: Mar 17, 2021 Departments database table renamed. (307450 lines) 1 change necessary in database: RENAME TABLE departments TO dpt_departments; diff --git a/swad_course.c b/swad_course.c index 93e9a373..190c5874 100644 --- a/swad_course.c +++ b/swad_course.c @@ -32,10 +32,10 @@ #include // For string functions #include "swad_attendance.h" +#include "swad_call_for_exam.h" #include "swad_course.h" #include "swad_course_config.h" #include "swad_database.h" -#include "swad_exam_announcement.h" #include "swad_figure.h" #include "swad_figure_cache.h" #include "swad_form.h" @@ -1948,7 +1948,7 @@ static void Crs_EmptyCourseCompletely (long CrsCod) DB_QueryUPDATE ("can not remove exam announcements of a course", "UPDATE exam_announcements SET Status=%u" " WHERE CrsCod=%ld", - (unsigned) ExaAnn_DELETED_EXAM_ANNOUNCEMENT,CrsCod); + (unsigned) Cfe_DELETED_CALL_FOR_EXAM,CrsCod); /***** Remove course cards of the course *****/ /* Remove content of course cards */ diff --git a/swad_database.c b/swad_database.c index 0718d3d7..828de854 100644 --- a/swad_database.c +++ b/swad_database.c @@ -1214,7 +1214,7 @@ mysql> DESCRIBE exam_announcements; "NumNotif INT NOT NULL DEFAULT 0," "CrsFullName VARCHAR(2047) NOT NULL," // Cns_HIERARCHY_MAX_BYTES_FULL_NAME "Year TINYINT NOT NULL," - "ExamSession VARCHAR(2047) NOT NULL," // ExaAnn_MAX_BYTES_SESSION + "ExamSession VARCHAR(2047) NOT NULL," // Cfe_MAX_BYTES_SESSION "CallDate DATETIME NOT NULL," "ExamDate DATETIME NOT NULL," "Duration TIME NOT NULL," diff --git a/swad_exam_announcement.c b/swad_exam_announcement.c deleted file mode 100644 index 93aa8558..00000000 --- a/swad_exam_announcement.c +++ /dev/null @@ -1,1804 +0,0 @@ -// swad_exam_announcement.c: exam announcements - -/* - SWAD (Shared Workspace At a Distance), - 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-2021 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 3 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 . -*/ -/*****************************************************************************/ -/********************************* Headers ***********************************/ -/*****************************************************************************/ - -#define _GNU_SOURCE // For asprintf -#include // For NULL -#include // For sscanf, asprintf, etc. -#include // For exit, system, malloc, calloc, free, etc. -#include // For string functions - -#include "swad_box.h" -#include "swad_config.h" -#include "swad_database.h" -#include "swad_exam_announcement.h" -#include "swad_form.h" -#include "swad_global.h" -#include "swad_hierarchy.h" -#include "swad_HTML.h" -#include "swad_logo.h" -#include "swad_notification.h" -#include "swad_parameter.h" -#include "swad_QR.h" -#include "swad_RSS.h" -#include "swad_string.h" -#include "swad_timeline.h" -#include "swad_timeline_database.h" - -/*****************************************************************************/ -/************** External global variables from others modules ****************/ -/*****************************************************************************/ - -extern struct Globals Gbl; - -/*****************************************************************************/ -/***************************** Private constants *****************************/ -/*****************************************************************************/ - -/*****************************************************************************/ -/******************************* Private types *******************************/ -/*****************************************************************************/ - -/*****************************************************************************/ -/***************************** Private variables *****************************/ -/*****************************************************************************/ - -/*****************************************************************************/ -/***************************** Private prototypes ****************************/ -/*****************************************************************************/ - -static struct ExaAnn_ExamAnnouncements *ExaAnn_GetGlobalExamAnns (void); - -static long ExaAnn_GetParamsExamAnn (struct ExaAnn_ExamAnnouncements *ExamAnns); - -static void ExaAnn_AllocMemExamAnn (struct ExaAnn_ExamAnnouncements *ExamAnns); -static void ExaAnn_FreeMemExamAnn (struct ExaAnn_ExamAnnouncements *ExamAnns); - -static void ExaAnn_UpdateNumUsrsNotifiedByEMailAboutExamAnn (long ExaCod,unsigned NumUsrsToBeNotifiedByEMail); - -static void ExaAnn_GetExaCodToHighlight (struct ExaAnn_ExamAnnouncements *ExamAnns); -static void ExaAnn_GetDateToHighlight (struct ExaAnn_ExamAnnouncements *ExamAnns); - -static void ExaAnn_ListExamAnns (struct ExaAnn_ExamAnnouncements *ExamAnns, - ExaAnn_TypeViewExamAnnouncement_t TypeViewExamAnnouncement); -static void ExaAnn_PutIconToCreateNewExamAnn (__attribute__((unused)) void *Args); -static void ExaAnn_PutButtonToCreateNewExamAnn (void); - -static long ExaAnn_AddExamAnnToDB (const struct ExaAnn_ExamAnnouncements *ExamAnns); -static void ExaAnn_ModifyExamAnnInDB (const struct ExaAnn_ExamAnnouncements *ExamAnns, - long ExaCod); -static void ExaAnn_GetDataExamAnnFromDB (struct ExaAnn_ExamAnnouncements *ExamAnns, - long ExaCod); -static void ExaAnn_ShowExamAnn (struct ExaAnn_ExamAnnouncements *ExamAnns, - long ExaCod, - ExaAnn_TypeViewExamAnnouncement_t TypeViewExamAnnouncement, - bool HighLight); -static void ExaAnn_PutIconsExamAnn (void *ExamAnns); -static void ExaAnn_PutParamExaCodToEdit (void *ExaCod); -static long ExaAnn_GetParamExaCod (void); - -static void ExaAnn_GetNotifContentExamAnn (const struct ExaAnn_ExamAnnouncements *ExamAnns, - char **ContentStr); - -/*****************************************************************************/ -/******************* Get global exam announcements context *******************/ -/*****************************************************************************/ - -static struct ExaAnn_ExamAnnouncements *ExaAnn_GetGlobalExamAnns (void) - { - static struct ExaAnn_ExamAnnouncements ExaAnn_GlobalExamAnns; // Used to preserve information between priori and posteriori functions - - return &ExaAnn_GlobalExamAnns; - } - -/*****************************************************************************/ -/********************** Reset exam announcements context *********************/ -/*****************************************************************************/ - -void ExaAnn_ResetExamAnns (struct ExaAnn_ExamAnnouncements *ExamAnns) - { - ExamAnns->NumExaAnns = 0; - ExamAnns->Lst = NULL; - ExamAnns->NewExaCod = -1L; - ExamAnns->HighlightExaCod = -1L; - ExamAnns->HighlightDate[0] = '\0'; // No exam announcements highlighted - ExamAnns->ExaCod = -1L; - ExamAnns->Anchor = NULL; - - ExamAnns->ExamAnn.CrsCod = -1L; - ExamAnns->ExamAnn.Status = ExaAnn_STATUS_DEFAULT; - ExamAnns->ExamAnn.CrsFullName[0] = '\0'; - ExamAnns->ExamAnn.Year = 0; - ExamAnns->ExamAnn.Session[0] = '\0'; - Dat_ResetDate (&ExamAnns->ExamAnn.CallDate); - Dat_ResetDate (&ExamAnns->ExamAnn.ExamDate); - Dat_ResetHour (&ExamAnns->ExamAnn.StartTime); - Dat_ResetHour (&ExamAnns->ExamAnn.Duration); - ExamAnns->ExamAnn.Place = NULL; - ExamAnns->ExamAnn.Mode = NULL; - ExamAnns->ExamAnn.Structure = NULL; - ExamAnns->ExamAnn.DocRequired = NULL; - ExamAnns->ExamAnn.MatRequired = NULL; - ExamAnns->ExamAnn.MatAllowed = NULL; - ExamAnns->ExamAnn.OtherInfo = NULL; - } - -/*****************************************************************************/ -/********************** Form to edit an exam announcement ********************/ -/*****************************************************************************/ - -void ExaAnn_PutFrmEditAExamAnn (void) - { - struct ExaAnn_ExamAnnouncements ExamAnns; - long ExaCod; - - /***** Reset exam announcements context *****/ - ExaAnn_ResetExamAnns (&ExamAnns); - - /***** Allocate memory for the exam announcement *****/ - ExaAnn_AllocMemExamAnn (&ExamAnns); - - /***** Get the code of the exam announcement *****/ - ExaCod = ExaAnn_GetParamsExamAnn (&ExamAnns); - - if (ExaCod > 0) // -1 indicates that this is a new exam announcement - /***** Read exam announcement from the database *****/ - ExaAnn_GetDataExamAnnFromDB (&ExamAnns,ExaCod); - - /***** Show exam announcement *****/ - ExaAnn_ShowExamAnn (&ExamAnns,ExaCod,ExaAnn_FORM_VIEW, - false); // Don't highlight - - /***** Free memory of the exam announcement *****/ - ExaAnn_FreeMemExamAnn (&ExamAnns); - } - -/*****************************************************************************/ -/**************** Get parameters of an exam announcement *********************/ -/*****************************************************************************/ - -static long ExaAnn_GetParamsExamAnn (struct ExaAnn_ExamAnnouncements *ExamAnns) - { - long ExaCod; - - /***** Get the code of the exam announcement *****/ - ExaCod = ExaAnn_GetParamExaCod (); - - /***** Get the name of the course (it is allowed to be different from the official name of the course) *****/ - Par_GetParToText ("CrsName",ExamAnns->ExamAnn.CrsFullName,Cns_HIERARCHY_MAX_BYTES_FULL_NAME); - // If the parameter is not present or is empty, initialize the string to the full name of the current course - if (!ExamAnns->ExamAnn.CrsFullName[0]) - Str_Copy (ExamAnns->ExamAnn.CrsFullName,Gbl.Hierarchy.Crs.FullName, - sizeof (ExamAnns->ExamAnn.CrsFullName) - 1); - - /***** Get the year *****/ - ExamAnns->ExamAnn.Year = (unsigned) - Par_GetParToUnsignedLong ("Year", - 0, // N.A. - Deg_MAX_YEARS_PER_DEGREE, - (unsigned long) Gbl.Hierarchy.Crs.Year); - - /***** Get the type of exam announcement *****/ - Par_GetParToText ("ExamSession",ExamAnns->ExamAnn.Session,ExaAnn_MAX_BYTES_SESSION); - - /***** Get the date of the exam *****/ - Dat_GetDateFromForm ("ExamDay","ExamMonth","ExamYear", - &ExamAnns->ExamAnn.ExamDate.Day, - &ExamAnns->ExamAnn.ExamDate.Month, - &ExamAnns->ExamAnn.ExamDate.Year); - if (ExamAnns->ExamAnn.ExamDate.Day == 0 || - ExamAnns->ExamAnn.ExamDate.Month == 0 || - ExamAnns->ExamAnn.ExamDate.Year == 0) - { - ExamAnns->ExamAnn.ExamDate.Day = Gbl.Now.Date.Day; - ExamAnns->ExamAnn.ExamDate.Month = Gbl.Now.Date.Month; - ExamAnns->ExamAnn.ExamDate.Year = Gbl.Now.Date.Year; - } - - /***** Get the hour of the exam *****/ - ExamAnns->ExamAnn.StartTime.Hour = (unsigned) Par_GetParToUnsignedLong ("ExamHour", - 0,23,0); - ExamAnns->ExamAnn.StartTime.Minute = (unsigned) Par_GetParToUnsignedLong ("ExamMinute", - 0,59,0); - - /***** Get the duration of the exam *****/ - ExamAnns->ExamAnn.Duration.Hour = (unsigned) Par_GetParToUnsignedLong ("DurationHour", - 0,23,0); - ExamAnns->ExamAnn.Duration.Minute = (unsigned) Par_GetParToUnsignedLong ("DurationMinute", - 0,59,0); - - /***** Get the place where the exam will happen *****/ - Par_GetParToHTML ("Place",ExamAnns->ExamAnn.Place,Cns_MAX_BYTES_TEXT); - - /***** Get the modality of exam *****/ - Par_GetParToHTML ("ExamMode",ExamAnns->ExamAnn.Mode,Cns_MAX_BYTES_TEXT); - - /***** Get the structure of exam *****/ - Par_GetParToHTML ("Structure",ExamAnns->ExamAnn.Structure,Cns_MAX_BYTES_TEXT); - - /***** Get the mandatory documentation *****/ - Par_GetParToHTML ("DocRequired",ExamAnns->ExamAnn.DocRequired,Cns_MAX_BYTES_TEXT); - - /***** Get the mandatory material *****/ - Par_GetParToHTML ("MatRequired",ExamAnns->ExamAnn.MatRequired,Cns_MAX_BYTES_TEXT); - - /***** Get the allowed material *****/ - Par_GetParToHTML ("MatAllowed",ExamAnns->ExamAnn.MatAllowed,Cns_MAX_BYTES_TEXT); - - /***** Get other information *****/ - Par_GetParToHTML ("OtherInfo",ExamAnns->ExamAnn.OtherInfo,Cns_MAX_BYTES_TEXT); - - return ExaCod; - } - -/*****************************************************************************/ -/* Allocate memory for those parameters of an exam anno. with a lot of text **/ -/*****************************************************************************/ - -static void ExaAnn_AllocMemExamAnn (struct ExaAnn_ExamAnnouncements *ExamAnns) - { - if ((ExamAnns->ExamAnn.Place = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) - Lay_NotEnoughMemoryExit (); - - if ((ExamAnns->ExamAnn.Mode = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) - Lay_NotEnoughMemoryExit (); - - if ((ExamAnns->ExamAnn.Structure = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) - Lay_NotEnoughMemoryExit (); - - if ((ExamAnns->ExamAnn.DocRequired = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) - Lay_NotEnoughMemoryExit (); - - if ((ExamAnns->ExamAnn.MatRequired = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) - Lay_NotEnoughMemoryExit (); - - if ((ExamAnns->ExamAnn.MatAllowed = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) - Lay_NotEnoughMemoryExit (); - - if ((ExamAnns->ExamAnn.OtherInfo = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) - Lay_NotEnoughMemoryExit (); - } - -/*****************************************************************************/ -/* Free memory of those parameters of an exam announcem. with a lot of text **/ -/*****************************************************************************/ - -static void ExaAnn_FreeMemExamAnn (struct ExaAnn_ExamAnnouncements *ExamAnns) - { - if (ExamAnns->ExamAnn.Place) - { - free (ExamAnns->ExamAnn.Place); - ExamAnns->ExamAnn.Place = NULL; - } - if (ExamAnns->ExamAnn.Mode) - { - free (ExamAnns->ExamAnn.Mode); - ExamAnns->ExamAnn.Mode = NULL; - } - if (ExamAnns->ExamAnn.Structure) - { - free (ExamAnns->ExamAnn.Structure); - ExamAnns->ExamAnn.Structure = NULL; - } - if (ExamAnns->ExamAnn.DocRequired) - { - free (ExamAnns->ExamAnn.DocRequired); - ExamAnns->ExamAnn.DocRequired = NULL; - } - if (ExamAnns->ExamAnn.MatRequired) - { - free (ExamAnns->ExamAnn.MatRequired); - ExamAnns->ExamAnn.MatRequired = NULL; - } - if (ExamAnns->ExamAnn.MatAllowed) - { - free (ExamAnns->ExamAnn.MatAllowed); - ExamAnns->ExamAnn.MatAllowed = NULL; - } - if (ExamAnns->ExamAnn.OtherInfo) - { - free (ExamAnns->ExamAnn.OtherInfo); - ExamAnns->ExamAnn.OtherInfo = NULL; - } - } - -/*****************************************************************************/ -/************************ Receive an exam announcement ***********************/ -/*****************************************************************************/ -// This function is splitted into a-priori and a-posteriori functions -// in order to view updated links in month of left column - -void ExaAnn_ReceiveExamAnn1 (void) - { - extern const char *Txt_Created_new_announcement_of_exam; - extern const char *Txt_The_announcement_of_exam_has_been_successfully_updated; - struct ExaAnn_ExamAnnouncements *ExamAnns = ExaAnn_GetGlobalExamAnns (); - long ExaCod; - bool NewExamAnnouncement; - char *Anchor = NULL; - - /***** Reset exam announcements context *****/ - ExaAnn_ResetExamAnns (ExamAnns); - - /***** Allocate memory for the exam announcement *****/ - ExaAnn_AllocMemExamAnn (ExamAnns); - - /***** Get parameters of the exam announcement *****/ - ExaCod = ExaAnn_GetParamsExamAnn (ExamAnns); - NewExamAnnouncement = (ExaCod < 0); - - /***** Add the exam announcement to the database and read it again from the database *****/ - if (NewExamAnnouncement) - ExamAnns->NewExaCod = ExaCod = ExaAnn_AddExamAnnToDB (ExamAnns); - else - ExaAnn_ModifyExamAnnInDB (ExamAnns,ExaCod); - - /***** Free memory of the exam announcement *****/ - ExaAnn_FreeMemExamAnn (ExamAnns); - - /***** Create alert to show the change made *****/ - Frm_SetAnchorStr (ExaCod,&Anchor); - Ale_CreateAlert (Ale_SUCCESS,Anchor, - NewExamAnnouncement ? Txt_Created_new_announcement_of_exam : - Txt_The_announcement_of_exam_has_been_successfully_updated); - Frm_FreeAnchorStr (Anchor); - - /***** Set exam to be highlighted *****/ - ExamAnns->HighlightExaCod = ExaCod; - } - -void ExaAnn_ReceiveExamAnn2 (void) - { - struct ExaAnn_ExamAnnouncements *ExamAnns = ExaAnn_GetGlobalExamAnns (); - unsigned NumUsrsToBeNotifiedByEMail; - - /***** Notify by email about the new exam announcement *****/ - if ((NumUsrsToBeNotifiedByEMail = Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_EXAM_ANNOUNCEMENT,ExamAnns->HighlightExaCod))) - ExaAnn_UpdateNumUsrsNotifiedByEMailAboutExamAnn (ExamAnns->HighlightExaCod,NumUsrsToBeNotifiedByEMail); - - /***** Create a new social note about the new exam announcement *****/ - Tml_Not_StoreAndPublishNote (TL_NOTE_EXAM_ANNOUNCEMENT,ExamAnns->HighlightExaCod); - - /***** Update RSS of current course *****/ - RSS_UpdateRSSFileForACrs (&Gbl.Hierarchy.Crs); - - /***** Show exam announcements *****/ - ExaAnn_ListExamAnnsEdit (); - } - -/*****************************************************************************/ -/***** Update number of users notified in table of exam announcements ********/ -/*****************************************************************************/ - -static void ExaAnn_UpdateNumUsrsNotifiedByEMailAboutExamAnn (long ExaCod,unsigned NumUsrsToBeNotifiedByEMail) - { - /***** Update number of users notified *****/ - DB_QueryUPDATE ("can not update the number of notifications" - " of an exam announcement", - "UPDATE exam_announcements SET NumNotif=NumNotif+%u" - " WHERE ExaCod=%ld", - NumUsrsToBeNotifiedByEMail,ExaCod); - } - -/*****************************************************************************/ -/************************* Print an exam announcement ************************/ -/*****************************************************************************/ - -void ExaAnn_PrintExamAnn (void) - { - struct ExaAnn_ExamAnnouncements ExamAnns; - long ExaCod; - - /***** Reset exam announcements context *****/ - ExaAnn_ResetExamAnns (&ExamAnns); - - /***** Allocate memory for the exam announcement *****/ - ExaAnn_AllocMemExamAnn (&ExamAnns); - - /***** Get the code of the exam announcement *****/ - if ((ExaCod = ExaAnn_GetParamExaCod ()) <= 0) - Lay_ShowErrorAndExit ("Code of exam announcement is missing."); - - /***** Read exam announcement from the database *****/ - ExaAnn_GetDataExamAnnFromDB (&ExamAnns,ExaCod); - - /***** Show exam announcement *****/ - ExaAnn_ShowExamAnn (&ExamAnns,ExaCod,ExaAnn_PRINT_VIEW, - false); // Don't highlight - - /***** Free memory of the exam announcement *****/ - ExaAnn_FreeMemExamAnn (&ExamAnns); - } - -/*****************************************************************************/ -/************************ Remove an exam announcement ************************/ -/*****************************************************************************/ - -void ExaAnn_ReqRemoveExamAnn (void) - { - extern const char *Txt_Do_you_really_want_to_remove_the_following_announcement_of_exam; - extern const char *Txt_Remove; - struct ExaAnn_ExamAnnouncements ExamAnns; - long ExaCod; - - /***** Reset exam announcements context *****/ - ExaAnn_ResetExamAnns (&ExamAnns); - - /***** Get the code of the exam announcement *****/ - if ((ExaCod = ExaAnn_GetParamExaCod ()) <= 0) - Lay_ShowErrorAndExit ("Code of exam announcement is missing."); - - /***** Show question and button to remove exam announcement *****/ - /* Begin alert */ - Ale_ShowAlertAndButton1 (Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_following_announcement_of_exam); - - /* Show announcement */ - ExaAnn_AllocMemExamAnn (&ExamAnns); - ExaAnn_GetDataExamAnnFromDB (&ExamAnns,ExaCod); - ExaAnn_ShowExamAnn (&ExamAnns,ExaCod,ExaAnn_NORMAL_VIEW, - false); // Don't highlight - ExaAnn_FreeMemExamAnn (&ExamAnns); - - /* End alert */ - - Ale_ShowAlertAndButton2 (ActRemExaAnn,NULL,NULL, - ExaAnn_PutParamExaCodToEdit,&ExamAnns.ExaCod, - Btn_REMOVE_BUTTON,Txt_Remove); - } - -/*****************************************************************************/ -/************************ Remove an exam announcement ************************/ -/*****************************************************************************/ -// This function is splitted into a-priori and a-posteriori functions -// in order to view updated links in month of left column - -void ExaAnn_RemoveExamAnn1 (void) - { - struct ExaAnn_ExamAnnouncements *ExamAnns = ExaAnn_GetGlobalExamAnns (); - long ExaCod; - - /***** Reset exam announcements context *****/ - ExaAnn_ResetExamAnns (ExamAnns); - - /***** Get the code of the exam announcement *****/ - if ((ExaCod = ExaAnn_GetParamExaCod ()) <= 0) - Lay_ShowErrorAndExit ("Code of exam announcement is missing."); - - /***** Mark the exam announcement as deleted in the database *****/ - DB_QueryUPDATE ("can not remove exam announcement", - "UPDATE exam_announcements SET Status=%u" - " WHERE ExaCod=%ld AND CrsCod=%ld", - (unsigned) ExaAnn_DELETED_EXAM_ANNOUNCEMENT, - ExaCod,Gbl.Hierarchy.Crs.CrsCod); - - /***** Mark possible notifications as removed *****/ - Ntf_MarkNotifAsRemoved (Ntf_EVENT_EXAM_ANNOUNCEMENT,ExaCod); - - /***** Mark possible social note as unavailable *****/ - Tml_DB_MarkNoteAsUnavailable (TL_NOTE_EXAM_ANNOUNCEMENT,ExaCod); - - /***** Update RSS of current course *****/ - RSS_UpdateRSSFileForACrs (&Gbl.Hierarchy.Crs); - } - -void ExaAnn_RemoveExamAnn2 (void) - { - extern const char *Txt_Announcement_of_exam_removed; - - /***** Write message *****/ - Ale_ShowAlert (Ale_SUCCESS,Txt_Announcement_of_exam_removed); - - /***** List again all the remaining exam announcements *****/ - ExaAnn_ListExamAnnsEdit (); - } - -/*****************************************************************************/ -/************************ Hide an exam announcement **************************/ -/*****************************************************************************/ -// This function is splitted into a-priori and a-posteriori functions -// in order to view updated links in month of left column - -void ExaAnn_HideExamAnn (void) - { - struct ExaAnn_ExamAnnouncements *ExamAnns = ExaAnn_GetGlobalExamAnns (); - long ExaCod; - - /***** Reset exam announcements context *****/ - ExaAnn_ResetExamAnns (ExamAnns); - - /***** Get the code of the exam announcement *****/ - if ((ExaCod = ExaAnn_GetParamExaCod ()) <= 0) - Lay_ShowErrorAndExit ("Code of exam announcement is missing."); - - /***** Mark the exam announcement as hidden in the database *****/ - DB_QueryUPDATE ("can not hide exam announcement", - "UPDATE exam_announcements SET Status=%u" - " WHERE ExaCod=%ld AND CrsCod=%ld", - (unsigned) ExaAnn_HIDDEN_EXAM_ANNOUNCEMENT, - ExaCod,Gbl.Hierarchy.Crs.CrsCod); - - /***** Set exam to be highlighted *****/ - ExamAnns->HighlightExaCod = ExaCod; - } - -/*****************************************************************************/ -/************************ Unhide an exam announcement ************************/ -/*****************************************************************************/ -// This function is splitted into a-priori and a-posteriori functions -// in order to view updated links in month of left column - -void ExaAnn_UnhideExamAnn (void) - { - struct ExaAnn_ExamAnnouncements *ExamAnns = ExaAnn_GetGlobalExamAnns (); - long ExaCod; - - /***** Reset exam announcements context *****/ - ExaAnn_ResetExamAnns (ExamAnns); - - /***** Get the code of the exam announcement *****/ - if ((ExaCod = ExaAnn_GetParamExaCod ()) <= 0) - Lay_ShowErrorAndExit ("Code of exam announcement is missing."); - - /***** Mark the exam announcement as visible in the database *****/ - DB_QueryUPDATE ("can not unhide exam announcement", - "UPDATE exam_announcements SET Status=%u" - " WHERE ExaCod=%ld AND CrsCod=%ld", - (unsigned) ExaAnn_VISIBLE_EXAM_ANNOUNCEMENT, - ExaCod,Gbl.Hierarchy.Crs.CrsCod); - - /***** Set exam to be highlighted *****/ - ExamAnns->HighlightExaCod = ExaCod; - } - -/*****************************************************************************/ -/*************** List all the exam announcements to see them *****************/ -/*****************************************************************************/ - -void ExaAnn_ListExamAnnsSee (void) - { - struct ExaAnn_ExamAnnouncements ExamAnns; - - /***** Reset exam announcements context *****/ - ExaAnn_ResetExamAnns (&ExamAnns); - - /***** List all exam announcements *****/ - ExaAnn_ListExamAnns (&ExamAnns,ExaAnn_NORMAL_VIEW); - - /***** Mark possible notifications as seen *****/ - Ntf_MarkNotifAsSeen (Ntf_EVENT_EXAM_ANNOUNCEMENT, - -1L,Gbl.Hierarchy.Crs.CrsCod, - Gbl.Usrs.Me.UsrDat.UsrCod); - } - -/*****************************************************************************/ -/********** List all the exam announcements to edit or remove them ***********/ -/*****************************************************************************/ - -void ExaAnn_ListExamAnnsEdit (void) - { - struct ExaAnn_ExamAnnouncements *ExamAnns = ExaAnn_GetGlobalExamAnns (); - - ExaAnn_ListExamAnns (ExamAnns,ExaAnn_NORMAL_VIEW); - } - -/*****************************************************************************/ -/********** List exam announcement given an exam announcement code ***********/ -/*****************************************************************************/ - -void ExaAnn_ListExamAnnsCod (void) - { - struct ExaAnn_ExamAnnouncements ExamAnns; - - /***** Reset exam announcements context *****/ - ExaAnn_ResetExamAnns (&ExamAnns); - - /***** Get exam announcement code *****/ - ExaAnn_GetExaCodToHighlight (&ExamAnns); - - /***** List all exam announcements *****/ - ExaAnn_ListExamAnns (&ExamAnns,ExaAnn_NORMAL_VIEW); - } - -/*****************************************************************************/ -/***************** List exam announcements on a given date *******************/ -/*****************************************************************************/ - -void ExaAnn_ListExamAnnsDay (void) - { - struct ExaAnn_ExamAnnouncements ExamAnns; - - /***** Reset exam announcements context *****/ - ExaAnn_ResetExamAnns (&ExamAnns); - - /***** Get date *****/ - ExaAnn_GetDateToHighlight (&ExamAnns); - - /***** List all exam announcements *****/ - ExaAnn_ListExamAnns (&ExamAnns,ExaAnn_NORMAL_VIEW); - } - -/*****************************************************************************/ -/*********** Get date of exam announcements to show highlighted **************/ -/*****************************************************************************/ - -static void ExaAnn_GetExaCodToHighlight (struct ExaAnn_ExamAnnouncements *ExamAnns) - { - /***** Get the exam announcement code - of the exam announcement to highlight *****/ - ExamAnns->HighlightExaCod = ExaAnn_GetParamExaCod (); - } - -/*****************************************************************************/ -/*********** Get date of exam announcements to show highlighted **************/ -/*****************************************************************************/ - -static void ExaAnn_GetDateToHighlight (struct ExaAnn_ExamAnnouncements *ExamAnns) - { - /***** Get the date (in YYYYMMDD format) - of the exam announcements to highlight *****/ - Par_GetParToText ("Date",ExamAnns->HighlightDate,4 + 2 + 2); - } - -/*****************************************************************************/ -/******************** List all the exam announcements ************************/ -/*****************************************************************************/ - -static void ExaAnn_ListExamAnns (struct ExaAnn_ExamAnnouncements *ExamAnns, - ExaAnn_TypeViewExamAnnouncement_t TypeViewExamAnnouncement) - { - extern const char *Hlp_ASSESSMENT_Announcements; - extern const char *Txt_Announcements_of_exams; - extern const char *Txt_No_announcements_of_exams_of_X; - char SubQueryStatus[64]; - MYSQL_RES *mysql_res; - MYSQL_ROW row; - unsigned long NumExaAnn; - unsigned long NumExaAnns; - long ExaCod; - bool HighLight; - bool ICanEdit = (Gbl.Usrs.Me.Role.Logged == Rol_TCH || - Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM); - - /***** Build subquery about status depending on my role *****/ - if (ICanEdit) - sprintf (SubQueryStatus,"Status<>%u", - (unsigned) ExaAnn_DELETED_EXAM_ANNOUNCEMENT); - else - sprintf (SubQueryStatus,"Status=%u", - (unsigned) ExaAnn_VISIBLE_EXAM_ANNOUNCEMENT); - - /***** Get exam announcements (the most recent first) - in current course from database *****/ - NumExaAnns = DB_QuerySELECT (&mysql_res,"can not get exam announcements" - " in this course for listing", - "SELECT ExaCod" - " FROM exam_announcements" - " WHERE CrsCod=%ld AND %s" - " ORDER BY ExamDate DESC", - Gbl.Hierarchy.Crs.CrsCod,SubQueryStatus); - - /***** Begin box *****/ - if (ICanEdit) - Box_BoxBegin (NULL,Txt_Announcements_of_exams, - ExaAnn_PutIconToCreateNewExamAnn,NULL, - Hlp_ASSESSMENT_Announcements,Box_NOT_CLOSABLE); - else - Box_BoxBegin (NULL,Txt_Announcements_of_exams, - NULL,NULL, - Hlp_ASSESSMENT_Announcements,Box_NOT_CLOSABLE); - - /***** The result of the query may be empty *****/ - if (!NumExaAnns) - Ale_ShowAlert (Ale_INFO,Txt_No_announcements_of_exams_of_X, - Gbl.Hierarchy.Crs.FullName); - - /***** List the existing exam announcements *****/ - for (NumExaAnn = 0; - NumExaAnn < NumExaAnns; - NumExaAnn++) - { - /***** Get the code of the exam announcement (row[0]) *****/ - row = mysql_fetch_row (mysql_res); - - if (sscanf (row[0],"%ld",&ExaCod) != 1) - Lay_ShowErrorAndExit ("Wrong code of exam announcement."); - - /***** Allocate memory for the exam announcement *****/ - ExaAnn_AllocMemExamAnn (ExamAnns); - - /***** Read the data of the exam announcement *****/ - ExaAnn_GetDataExamAnnFromDB (ExamAnns,ExaCod); - - /***** Show exam announcement *****/ - HighLight = false; - if (ExaCod == ExamAnns->HighlightExaCod) - HighLight = true; - else if (ExamAnns->HighlightDate[0]) - { - if (!strcmp (ExamAnns->ExamAnn.ExamDate.YYYYMMDD, - ExamAnns->HighlightDate)) - HighLight = true; - } - ExaAnn_ShowExamAnn (ExamAnns,ExaCod,TypeViewExamAnnouncement, - HighLight); - - /***** Free memory of the exam announcement *****/ - ExaAnn_FreeMemExamAnn (ExamAnns); - } - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - - /***** Button to create a new exam announcement *****/ - if (ICanEdit) - ExaAnn_PutButtonToCreateNewExamAnn (); - - /***** End box *****/ - Box_BoxEnd (); - } - -/*****************************************************************************/ -/***************** Put icon to create a new exam announcement ****************/ -/*****************************************************************************/ - -static void ExaAnn_PutIconToCreateNewExamAnn (__attribute__((unused)) void *Args) - { - extern const char *Txt_New_announcement_OF_EXAM; - - Ico_PutContextualIconToAdd (ActEdiExaAnn,NULL, - NULL,NULL, - Txt_New_announcement_OF_EXAM); - } - -/*****************************************************************************/ -/**************** Put button to create a new exam announcement ***************/ -/*****************************************************************************/ - -static void ExaAnn_PutButtonToCreateNewExamAnn (void) - { - extern const char *Txt_New_announcement_OF_EXAM; - - Frm_BeginForm (ActEdiExaAnn); - Btn_PutConfirmButton (Txt_New_announcement_OF_EXAM); - Frm_EndForm (); - } - -/*****************************************************************************/ -/****************** Add an exam announcement to the database *****************/ -/*****************************************************************************/ -// Return the code of the exam announcement just added - -static long ExaAnn_AddExamAnnToDB (const struct ExaAnn_ExamAnnouncements *ExamAnns) - { - long ExaCod; - - /***** Add exam announcement *****/ - ExaCod = - DB_QueryINSERTandReturnCode ("can not create a new exam announcement", - "INSERT INTO exam_announcements " - "(CrsCod,Status,NumNotif,CrsFullName,Year,ExamSession," - "CallDate,ExamDate,Duration," - "Place,ExamMode,Structure,DocRequired,MatRequired,MatAllowed,OtherInfo)" - " VALUES " - "(%ld,%u,0,'%s',%u,'%s'," - "NOW(),'%04u-%02u-%02u %02u:%02u:00','%02u:%02u:00','%s'," - "'%s','%s','%s','%s','%s','%s')", - Gbl.Hierarchy.Crs.CrsCod, - (unsigned) ExaAnn_VISIBLE_EXAM_ANNOUNCEMENT, - ExamAnns->ExamAnn.CrsFullName, - ExamAnns->ExamAnn.Year, - ExamAnns->ExamAnn.Session, - ExamAnns->ExamAnn.ExamDate.Year, - ExamAnns->ExamAnn.ExamDate.Month, - ExamAnns->ExamAnn.ExamDate.Day, - ExamAnns->ExamAnn.StartTime.Hour, - ExamAnns->ExamAnn.StartTime.Minute, - ExamAnns->ExamAnn.Duration.Hour, - ExamAnns->ExamAnn.Duration.Minute, - ExamAnns->ExamAnn.Place, - ExamAnns->ExamAnn.Mode, - ExamAnns->ExamAnn.Structure, - ExamAnns->ExamAnn.DocRequired, - ExamAnns->ExamAnn.MatRequired, - ExamAnns->ExamAnn.MatAllowed, - ExamAnns->ExamAnn.OtherInfo); - - return ExaCod; - } - -/*****************************************************************************/ -/*************** Modify an exam announcement in the database *****************/ -/*****************************************************************************/ - -static void ExaAnn_ModifyExamAnnInDB (const struct ExaAnn_ExamAnnouncements *ExamAnns, - long ExaCod) - { - /***** Modify exam announcement *****/ - DB_QueryUPDATE ("can not update an exam announcement", - "UPDATE exam_announcements" - " SET CrsFullName='%s',Year=%u,ExamSession='%s'," - "ExamDate='%04u-%02u-%02u %02u:%02u:00'," - "Duration='%02u:%02u:00'," - "Place='%s',ExamMode='%s',Structure='%s'," - "DocRequired='%s',MatRequired='%s',MatAllowed='%s',OtherInfo='%s'" - " WHERE ExaCod=%ld", - ExamAnns->ExamAnn.CrsFullName, - ExamAnns->ExamAnn.Year, - ExamAnns->ExamAnn.Session, - ExamAnns->ExamAnn.ExamDate.Year, - ExamAnns->ExamAnn.ExamDate.Month, - ExamAnns->ExamAnn.ExamDate.Day, - ExamAnns->ExamAnn.StartTime.Hour, - ExamAnns->ExamAnn.StartTime.Minute, - ExamAnns->ExamAnn.Duration.Hour, - ExamAnns->ExamAnn.Duration.Minute, - ExamAnns->ExamAnn.Place, - ExamAnns->ExamAnn.Mode, - ExamAnns->ExamAnn.Structure, - ExamAnns->ExamAnn.DocRequired, - ExamAnns->ExamAnn.MatRequired, - ExamAnns->ExamAnn.MatAllowed, - ExamAnns->ExamAnn.OtherInfo, - ExaCod); - } - -/*****************************************************************************/ -/******* Create a list with the dates of all the exam announcements **********/ -/*****************************************************************************/ - -void ExaAnn_CreateListExamAnns (struct ExaAnn_ExamAnnouncements *ExamAnns) - { - MYSQL_RES *mysql_res; - MYSQL_ROW row; - unsigned long NumExaAnn; - unsigned long NumExaAnns; - - if (Gbl.DB.DatabaseIsOpen) - { - /***** Get exam dates (ordered from more recent to older) - of visible exam announcements - in current course from database *****/ - NumExaAnns = DB_QuerySELECT (&mysql_res,"can not get exam announcements" - " in this course", - "SELECT ExaCod,DATE(ExamDate)" - " FROM exam_announcements" - " WHERE CrsCod=%ld AND Status=%u" - " ORDER BY ExamDate DESC", - Gbl.Hierarchy.Crs.CrsCod, - (unsigned) ExaAnn_VISIBLE_EXAM_ANNOUNCEMENT); - - /***** The result of the query may be empty *****/ - ExamAnns->Lst = NULL; - ExamAnns->NumExaAnns = 0; - if (NumExaAnns) - { - /***** Allocate memory for the list *****/ - if ((ExamAnns->Lst = calloc (NumExaAnns,sizeof (*ExamAnns->Lst))) == NULL) - Lay_NotEnoughMemoryExit (); - - /***** Get the dates of the existing exam announcements *****/ - for (NumExaAnn = 0; - NumExaAnn < NumExaAnns; - NumExaAnn++) - { - /***** Get next exam announcement *****/ - row = mysql_fetch_row (mysql_res); - - /* Get exam code (row[0]) */ - ExamAnns->Lst[ExamAnns->NumExaAnns].ExaCod = Str_ConvertStrCodToLongCod (row[0]); - - /* Read the date of the exam (row[1]) */ - if (sscanf (row[1],"%04u-%02u-%02u", - &ExamAnns->Lst[ExamAnns->NumExaAnns].ExamDate.Year, - &ExamAnns->Lst[ExamAnns->NumExaAnns].ExamDate.Month, - &ExamAnns->Lst[ExamAnns->NumExaAnns].ExamDate.Day) != 3) - Lay_ShowErrorAndExit ("Wrong date of exam."); - - /***** Increment number of elements in list *****/ - ExamAnns->NumExaAnns++; - } - } - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - } - } - -/*****************************************************************************/ -/***************** Free list of dates of exam announcements ******************/ -/*****************************************************************************/ - -void ExaAnn_FreeListExamAnns (struct ExaAnn_ExamAnnouncements *ExamAnns) - { - if (ExamAnns->Lst) - { - free (ExamAnns->Lst); - ExamAnns->Lst = NULL; - ExamAnns->NumExaAnns = 0; - } - } - -/*****************************************************************************/ -/******** Read the data of an exam announcement from the database ************/ -/*****************************************************************************/ - -static void ExaAnn_GetDataExamAnnFromDB (struct ExaAnn_ExamAnnouncements *ExamAnns, - long ExaCod) - { - MYSQL_RES *mysql_res; - MYSQL_ROW row; - unsigned long NumExaAnns; - unsigned UnsignedNum; - unsigned Hour; - unsigned Minute; - unsigned Second; - - /***** Get data of an exam announcement from database *****/ - NumExaAnns = DB_QuerySELECT (&mysql_res,"can not get data" - " of an exam announcement", - "SELECT CrsCod,Status,CrsFullName,Year,ExamSession," - "CallDate,ExamDate,Duration,Place,ExamMode," - "Structure,DocRequired,MatRequired,MatAllowed,OtherInfo" - " FROM exam_announcements WHERE ExaCod=%ld", - ExaCod); - - /***** The result of the query must have one row *****/ - if (NumExaAnns != 1) - Lay_ShowErrorAndExit ("Error when getting data of an exam announcement."); - - /***** Get the data of the exam announcement *****/ - row = mysql_fetch_row (mysql_res); - - /* Code of the course in which the exam announcement is inserted (row[0]) */ - ExamAnns->ExamAnn.CrsCod = Str_ConvertStrCodToLongCod (row[0]); - - /* Status of the exam announcement (row[1]) */ - if (sscanf (row[1],"%u",&UnsignedNum) != 1) - Lay_ShowErrorAndExit ("Wrong status."); - if (UnsignedNum >= ExaAnn_NUM_STATUS) - Lay_ShowErrorAndExit ("Wrong status."); - ExamAnns->ExamAnn.Status = (ExaAnn_Status_t) UnsignedNum; - - /* Name of the course (row[2]) */ - Str_Copy (ExamAnns->ExamAnn.CrsFullName,row[2], - sizeof (ExamAnns->ExamAnn.CrsFullName) - 1); - - /* Year (row[3]) */ - if (sscanf (row[3],"%u",&ExamAnns->ExamAnn.Year) != 1) - Lay_ShowErrorAndExit ("Wrong year."); - - /* Exam session (row[4]) */ - Str_Copy (ExamAnns->ExamAnn.Session,row[4], - sizeof (ExamAnns->ExamAnn.Session) - 1); - - /* Date of exam announcement (row[5]) */ - if (sscanf (row[5],"%04u-%02u-%02u %02u:%02u:%02u", - &ExamAnns->ExamAnn.CallDate.Year, - &ExamAnns->ExamAnn.CallDate.Month, - &ExamAnns->ExamAnn.CallDate.Day, - &Hour, - &Minute, - &Second) != 6) - Lay_ShowErrorAndExit ("Wrong date of exam announcement."); - - /* Date of exam (row[6]) */ - if (sscanf (row[6],"%04u-%02u-%02u %02u:%02u:%02u", - &ExamAnns->ExamAnn.ExamDate.Year, - &ExamAnns->ExamAnn.ExamDate.Month, - &ExamAnns->ExamAnn.ExamDate.Day, - &ExamAnns->ExamAnn.StartTime.Hour, - &ExamAnns->ExamAnn.StartTime.Minute, - &Second) != 6) - Lay_ShowErrorAndExit ("Wrong date of exam."); - snprintf (ExamAnns->ExamAnn.ExamDate.YYYYMMDD, - sizeof (ExamAnns->ExamAnn.ExamDate.YYYYMMDD),"%04u%02u%02u", - ExamAnns->ExamAnn.ExamDate.Year, - ExamAnns->ExamAnn.ExamDate.Month, - ExamAnns->ExamAnn.ExamDate.Day); - - /* Approximate duration (row[7]) */ - if (sscanf (row[7],"%02u:%02u:%02u", - &ExamAnns->ExamAnn.Duration.Hour, - &ExamAnns->ExamAnn.Duration.Minute, - &Second) != 3) - Lay_ShowErrorAndExit ("Wrong duration of exam."); - - /* Place (row[8]), exam mode (row[9]), structure (row[10]), - documentation required (row[11]), material required (row[12]), - material allowed (row[13]) and other information for students (row[14]) */ - Str_Copy (ExamAnns->ExamAnn.Place ,row[ 8],Cns_MAX_BYTES_TEXT); - Str_Copy (ExamAnns->ExamAnn.Mode ,row[ 9],Cns_MAX_BYTES_TEXT); - Str_Copy (ExamAnns->ExamAnn.Structure ,row[10],Cns_MAX_BYTES_TEXT); - Str_Copy (ExamAnns->ExamAnn.DocRequired,row[11],Cns_MAX_BYTES_TEXT); - Str_Copy (ExamAnns->ExamAnn.MatRequired,row[12],Cns_MAX_BYTES_TEXT); - Str_Copy (ExamAnns->ExamAnn.MatAllowed ,row[13],Cns_MAX_BYTES_TEXT); - Str_Copy (ExamAnns->ExamAnn.OtherInfo ,row[14],Cns_MAX_BYTES_TEXT); - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - } - -/*****************************************************************************/ -/************ Show a form with the data of an exam announcement **************/ -/*****************************************************************************/ - -static void ExaAnn_ShowExamAnn (struct ExaAnn_ExamAnnouncements *ExamAnns, - long ExaCod, - ExaAnn_TypeViewExamAnnouncement_t TypeViewExamAnnouncement, - bool HighLight) - { - extern const char *Hlp_ASSESSMENT_Announcements_new_announcement; - extern const char *Hlp_ASSESSMENT_Announcements_edit_announcement; - extern const char *Txt_YEAR_OF_DEGREE[1 + Deg_MAX_YEARS_PER_DEGREE]; - extern const char *Txt_EXAM_ANNOUNCEMENT; - extern const char *Txt_EXAM_ANNOUNCEMENT_Course; - extern const char *Txt_EXAM_ANNOUNCEMENT_Year_or_semester; - extern const char *Txt_EXAM_ANNOUNCEMENT_Session; - extern const char *Txt_EXAM_ANNOUNCEMENT_Exam_date; - extern const char *Txt_EXAM_ANNOUNCEMENT_Start_time; - extern const char *Txt_EXAM_ANNOUNCEMENT_Approximate_duration; - extern const char *Txt_EXAM_ANNOUNCEMENT_Place_of_exam; - extern const char *Txt_EXAM_ANNOUNCEMENT_Mode; - extern const char *Txt_EXAM_ANNOUNCEMENT_Structure_of_the_exam; - extern const char *Txt_EXAM_ANNOUNCEMENT_Documentation_required; - extern const char *Txt_EXAM_ANNOUNCEMENT_Material_required; - extern const char *Txt_EXAM_ANNOUNCEMENT_Material_allowed; - extern const char *Txt_EXAM_ANNOUNCEMENT_Other_information; - extern const char *Txt_hours_ABBREVIATION; - extern const char *Txt_hour; - extern const char *Txt_hours; - extern const char *Txt_minute; - extern const char *Txt_minutes; - extern const char *Txt_Publish_announcement_OF_EXAM; - struct Ins_Instit Ins; - char StrExamDate[Cns_MAX_BYTES_DATE + 1]; - unsigned Year; - unsigned Hour; - unsigned Minute; - char *Anchor = NULL; - const char *Width; - void (*FunctionToDrawContextualIcons) (void *Args); - const char *HelpLink; - static const char *ClassExaAnnouncement[ExaAnn_NUM_VIEWS][ExaAnn_NUM_STATUS] = - { - [ExaAnn_NORMAL_VIEW][ExaAnn_VISIBLE_EXAM_ANNOUNCEMENT] = "EXA_ANN_VISIBLE", - [ExaAnn_NORMAL_VIEW][ExaAnn_HIDDEN_EXAM_ANNOUNCEMENT ] = "EXA_ANN_HIDDEN", - [ExaAnn_NORMAL_VIEW][ExaAnn_DELETED_EXAM_ANNOUNCEMENT] = NULL, // Not applicable here - - [ExaAnn_PRINT_VIEW ][ExaAnn_VISIBLE_EXAM_ANNOUNCEMENT] = "EXA_ANN_VISIBLE", - [ExaAnn_PRINT_VIEW ][ExaAnn_HIDDEN_EXAM_ANNOUNCEMENT ] = "EXA_ANN_VISIBLE", - [ExaAnn_PRINT_VIEW ][ExaAnn_DELETED_EXAM_ANNOUNCEMENT] = NULL, // Not applicable here - - [ExaAnn_FORM_VIEW ][ExaAnn_VISIBLE_EXAM_ANNOUNCEMENT] = "EXA_ANN_VISIBLE", - [ExaAnn_FORM_VIEW ][ExaAnn_HIDDEN_EXAM_ANNOUNCEMENT ] = "EXA_ANN_VISIBLE", - [ExaAnn_FORM_VIEW ][ExaAnn_DELETED_EXAM_ANNOUNCEMENT] = NULL, // Not applicable here - }; - - /***** Get data of institution of this degree *****/ - Ins.InsCod = Gbl.Hierarchy.Ins.InsCod; - Ins_GetDataOfInstitutionByCod (&Ins); - - /***** Build anchor string *****/ - Frm_SetAnchorStr (ExaCod,&Anchor); - - /***** Begin article *****/ - if (TypeViewExamAnnouncement == ExaAnn_NORMAL_VIEW) - HTM_ARTICLE_Begin (Anchor); - - /***** Begin box *****/ - Width = "625px"; - ExamAnns->Anchor = Anchor; // Used to put contextual icons - ExamAnns->ExaCod = ExaCod; // Used to put contextual icons - FunctionToDrawContextualIcons = TypeViewExamAnnouncement == ExaAnn_NORMAL_VIEW ? ExaAnn_PutIconsExamAnn : - NULL; - HelpLink = TypeViewExamAnnouncement == ExaAnn_FORM_VIEW ? ((ExaCod > 0) ? Hlp_ASSESSMENT_Announcements_edit_announcement : - Hlp_ASSESSMENT_Announcements_new_announcement) : - NULL; - if (HighLight) - { - /* Show pending alerts */ - Ale_ShowAlerts (Anchor); - - /* Start highlighted box */ - Box_BoxShadowBegin (Width,NULL, - FunctionToDrawContextualIcons,ExamAnns, - HelpLink); - } - else // Don't highlight - /* Start normal box */ - Box_BoxBegin (Width,NULL, - FunctionToDrawContextualIcons,ExamAnns, - HelpLink,Box_NOT_CLOSABLE); - - if (TypeViewExamAnnouncement == ExaAnn_FORM_VIEW) - { - /***** Begin form *****/ - Frm_StartFormAnchor (ActRcvExaAnn,Anchor); - if (ExaCod > 0) // Existing announcement of exam - ExaAnn_PutHiddenParamExaCod (ExaCod); - } - - /***** Begin table *****/ - HTM_TABLE_Begin ("%s CELLS_PAD_2", - ClassExaAnnouncement[TypeViewExamAnnouncement][ExamAnns->ExamAnn.Status]); - - /***** Institution logo *****/ - HTM_TR_Begin (NULL); - HTM_TD_Begin ("colspan=\"2\" class=\"CM\""); - if (TypeViewExamAnnouncement == ExaAnn_PRINT_VIEW) - HTM_SPAN_Begin ("class=\"EXAM_TIT\""); - else - HTM_A_Begin ("href=\"%s\" target=\"_blank\" class=\"EXAM_TIT\"", - Ins.WWW); - Lgo_DrawLogo (Hie_Lvl_INS,Ins.InsCod,Ins.FullName,64,NULL,true); - HTM_BR (); - HTM_Txt (Ins.FullName); - if (TypeViewExamAnnouncement == ExaAnn_PRINT_VIEW) - HTM_SPAN_End (); - else - HTM_A_End (); - HTM_TD_End (); - HTM_TR_End (); - - /***** Degree *****/ - HTM_TR_Begin (NULL); - HTM_TD_Begin ("colspan=\"2\" class=\"EXAM_TIT CM\""); - if (TypeViewExamAnnouncement == ExaAnn_NORMAL_VIEW) - HTM_A_Begin ("href=\"%s\" target=\"_blank\" class=\"EXAM_TIT\"", - Gbl.Hierarchy.Deg.WWW); - HTM_Txt (Gbl.Hierarchy.Deg.FullName); - if (TypeViewExamAnnouncement == ExaAnn_NORMAL_VIEW) - HTM_A_End (); - HTM_TD_End (); - HTM_TR_End (); - - /***** Title *****/ - HTM_TR_Begin (NULL); - HTM_TD_Begin ("colspan=\"2\" class=\"EXAM CM\""); - HTM_NBSP (); - HTM_BR (); - HTM_STRONG_Begin (); - HTM_Txt (Txt_EXAM_ANNOUNCEMENT); - HTM_STRONG_End (); - HTM_TD_End (); - HTM_TR_End (); - - HTM_TR_Begin (NULL); - HTM_TD_Begin ("colspan=\"2\" class=\"EXAM LM\""); - HTM_NBSP (); - HTM_TD_End (); - HTM_TR_End (); - - /***** Name of the course *****/ - HTM_TR_Begin (NULL); - - /* Label */ - Frm_LabelColumn ("RT", - TypeViewExamAnnouncement == ExaAnn_FORM_VIEW ? "CrsName" : - NULL, - Txt_EXAM_ANNOUNCEMENT_Course); - - /* Data */ - HTM_TD_Begin ("class=\"EXAM LB\""); - if (TypeViewExamAnnouncement == ExaAnn_FORM_VIEW) - HTM_INPUT_TEXT ("CrsName",Cns_HIERARCHY_MAX_CHARS_FULL_NAME,ExamAnns->ExamAnn.CrsFullName, - HTM_DONT_SUBMIT_ON_CHANGE, - "id=\"CrsName\" size=\"30\""); - else - { - HTM_STRONG_Begin (); - HTM_Txt (ExamAnns->ExamAnn.CrsFullName); - HTM_STRONG_End (); - } - HTM_TD_End (); - - HTM_TR_End (); - - /***** Year/semester (N.A., 1º, 2º, 3º, 4º, 5º...) *****/ - HTM_TR_Begin (NULL); - - /* Label */ - Frm_LabelColumn ("RT", - TypeViewExamAnnouncement == ExaAnn_FORM_VIEW ? "Year" : - NULL, - Txt_EXAM_ANNOUNCEMENT_Year_or_semester); - - /* Data */ - HTM_TD_Begin ("class=\"EXAM LB\""); - if (TypeViewExamAnnouncement == ExaAnn_FORM_VIEW) - { - HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, - "id=\"Year\" name=\"Year\""); - for (Year = 0; - Year <= Deg_MAX_YEARS_PER_DEGREE; - Year++) - HTM_OPTION (HTM_Type_UNSIGNED,&Year, - ExamAnns->ExamAnn.Year == Year,false, - "%s",Txt_YEAR_OF_DEGREE[Year]); - HTM_SELECT_End (); - } - else - HTM_Txt (Txt_YEAR_OF_DEGREE[ExamAnns->ExamAnn.Year]); - HTM_TD_End (); - - HTM_TR_End (); - - /***** Exam session *****/ - HTM_TR_Begin (NULL); - - /* Label */ - Frm_LabelColumn ("RT", - TypeViewExamAnnouncement == ExaAnn_FORM_VIEW ? "ExamSession" : - NULL, - Txt_EXAM_ANNOUNCEMENT_Session); - - /* Data */ - HTM_TD_Begin ("class=\"EXAM LB\""); - if (TypeViewExamAnnouncement == ExaAnn_FORM_VIEW) - HTM_INPUT_TEXT ("ExamSession",ExaAnn_MAX_CHARS_SESSION,ExamAnns->ExamAnn.Session, - HTM_DONT_SUBMIT_ON_CHANGE, - "id=\"ExamSession\" size=\"30\""); - else - HTM_Txt (ExamAnns->ExamAnn.Session); - HTM_TD_End (); - - HTM_TR_End (); - - /***** Date of the exam *****/ - HTM_TR_Begin (NULL); - - /* Label */ - Frm_LabelColumn ("RT", - TypeViewExamAnnouncement == ExaAnn_FORM_VIEW ? "ExamYear" : - NULL, - Txt_EXAM_ANNOUNCEMENT_Exam_date); - - /* Data */ - if (TypeViewExamAnnouncement == ExaAnn_FORM_VIEW) - { - HTM_TD_Begin ("class=\"LB\""); - Dat_WriteFormDate (ExamAnns->ExamAnn.ExamDate.Year < Gbl.Now.Date.Year ? ExamAnns->ExamAnn.ExamDate.Year : - Gbl.Now.Date.Year, - Gbl.Now.Date.Year + 1,"Exam", - &(ExamAnns->ExamAnn.ExamDate), - false,false); - HTM_TD_End (); - } - else - { - Dat_ConvDateToDateStr (&ExamAnns->ExamAnn.ExamDate, - StrExamDate); - HTM_TD_Begin ("class=\"EXAM LB\""); - HTM_Txt (StrExamDate); - HTM_TD_End (); - } - HTM_TR_End (); - - /***** Start time *****/ - HTM_TR_Begin (NULL); - - /* Label */ - Frm_LabelColumn ("RT", - TypeViewExamAnnouncement == ExaAnn_FORM_VIEW ? "ExamHour" : - NULL, - Txt_EXAM_ANNOUNCEMENT_Start_time); - - /* Data */ - HTM_TD_Begin ("class=\"EXAM LB\""); - if (TypeViewExamAnnouncement == ExaAnn_FORM_VIEW) - { - HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, - "id=\"ExamHour\" name=\"ExamHour\""); - HTM_OPTION (HTM_Type_STRING,"0", - ExamAnns->ExamAnn.StartTime.Hour == 0,false, - "-"); - for (Hour = 7; - Hour <= 22; - Hour++) - HTM_OPTION (HTM_Type_UNSIGNED,&Hour, - ExamAnns->ExamAnn.StartTime.Hour == Hour,false, - "%02u %s",Hour,Txt_hours_ABBREVIATION); - HTM_SELECT_End (); - - HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, - "name=\"ExamMinute\""); - for (Minute = 0; - Minute <= 59; - Minute++) - HTM_OPTION (HTM_Type_UNSIGNED,&Minute, - ExamAnns->ExamAnn.StartTime.Minute == Minute,false, - "%02u ′",Minute); - HTM_SELECT_End (); - } - else if (ExamAnns->ExamAnn.StartTime.Hour) - HTM_TxtF ("%2u:%02u",ExamAnns->ExamAnn.StartTime.Hour, - ExamAnns->ExamAnn.StartTime.Minute); - HTM_TD_End (); - - HTM_TR_End (); - - /***** Approximate duration of the exam *****/ - HTM_TR_Begin (NULL); - - /* Label */ - Frm_LabelColumn ("RT", - TypeViewExamAnnouncement == ExaAnn_FORM_VIEW ? "DurationHour" : - NULL, - Txt_EXAM_ANNOUNCEMENT_Approximate_duration); - - /* Data */ - HTM_TD_Begin ("class=\"EXAM LB\""); - if (TypeViewExamAnnouncement == ExaAnn_FORM_VIEW) - { - HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, - "id=\"DurationHour\" name=\"DurationHour\""); - for (Hour = 0; - Hour <= 8; - Hour++) - HTM_OPTION (HTM_Type_UNSIGNED,&Hour, - ExamAnns->ExamAnn.Duration.Hour == Hour,false, - "%02u %s",Hour,Txt_hours_ABBREVIATION); - HTM_SELECT_End (); - - HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, - "name=\"DurationMinute\""); - for (Minute = 0; - Minute <= 59; - Minute++) - HTM_OPTION (HTM_Type_UNSIGNED,&Minute, - ExamAnns->ExamAnn.Duration.Minute == Minute,false, - "%02u ′",Minute); - HTM_SELECT_End (); - } - else if (ExamAnns->ExamAnn.Duration.Hour || - ExamAnns->ExamAnn.Duration.Minute) - { - if (ExamAnns->ExamAnn.Duration.Hour) - { - if (ExamAnns->ExamAnn.Duration.Minute) - HTM_TxtF ("%u%s %u′",ExamAnns->ExamAnn.Duration.Hour, - Txt_hours_ABBREVIATION, - ExamAnns->ExamAnn.Duration.Minute); - else - HTM_TxtF ("%u %s",ExamAnns->ExamAnn.Duration.Hour, - ExamAnns->ExamAnn.Duration.Hour == 1 ? Txt_hour : - Txt_hours); - } - else if (ExamAnns->ExamAnn.Duration.Minute) - { - HTM_TxtF ("%u %s",ExamAnns->ExamAnn.Duration.Minute, - ExamAnns->ExamAnn.Duration.Minute == 1 ? Txt_minute : - Txt_minutes); - } - } - HTM_TD_End (); - - HTM_TR_End (); - - /***** Place where the exam will be made *****/ - HTM_TR_Begin (NULL); - - /* Label */ - Frm_LabelColumn ("RT", - TypeViewExamAnnouncement == ExaAnn_FORM_VIEW ? "Place" : - NULL, - Txt_EXAM_ANNOUNCEMENT_Place_of_exam); - - /* Data */ - HTM_TD_Begin ("class=\"EXAM LB\""); - if (TypeViewExamAnnouncement == ExaAnn_FORM_VIEW) - { - HTM_TEXTAREA_Begin ("id=\"Place\" name=\"Place\" cols=\"40\" rows=\"4\""); - HTM_Txt (ExamAnns->ExamAnn.Place); - HTM_TEXTAREA_End (); - } - else - { - Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, - ExamAnns->ExamAnn.Place, - Cns_MAX_BYTES_TEXT,false); - HTM_Txt (ExamAnns->ExamAnn.Place); - } - HTM_TD_End (); - - HTM_TR_End (); - - /***** Exam mode *****/ - HTM_TR_Begin (NULL); - - /* Label */ - Frm_LabelColumn ("RT", - TypeViewExamAnnouncement == ExaAnn_FORM_VIEW ? "ExamMode" : - NULL, - Txt_EXAM_ANNOUNCEMENT_Mode); - - /* Data */ - HTM_TD_Begin ("class=\"EXAM LB\""); - if (TypeViewExamAnnouncement == ExaAnn_FORM_VIEW) - { - HTM_TEXTAREA_Begin ("id=\"ExamMode\" name=\"ExamMode\" cols=\"40\" rows=\"2\""); - HTM_Txt (ExamAnns->ExamAnn.Mode); - HTM_TEXTAREA_End (); - } - else - { - Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, - ExamAnns->ExamAnn.Mode, - Cns_MAX_BYTES_TEXT,false); - HTM_Txt (ExamAnns->ExamAnn.Mode); - } - HTM_TD_End (); - - HTM_TR_End (); - - /***** Structure of the exam *****/ - HTM_TR_Begin (NULL); - - /* Label */ - Frm_LabelColumn ("RT", - TypeViewExamAnnouncement == ExaAnn_FORM_VIEW ? "Structure" : - NULL, - Txt_EXAM_ANNOUNCEMENT_Structure_of_the_exam); - - /* Data */ - HTM_TD_Begin ("class=\"EXAM LB\""); - if (TypeViewExamAnnouncement == ExaAnn_FORM_VIEW) - { - HTM_TEXTAREA_Begin ("id=\"Structure\" name=\"Structure\" cols=\"40\" rows=\"8\""); - HTM_Txt (ExamAnns->ExamAnn.Structure); - HTM_TEXTAREA_End (); - } - else - { - Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, - ExamAnns->ExamAnn.Structure, - Cns_MAX_BYTES_TEXT,false); - HTM_Txt (ExamAnns->ExamAnn.Structure); - } - HTM_TD_End (); - - HTM_TR_End (); - - /***** Documentation required *****/ - HTM_TR_Begin (NULL); - - /* Label */ - Frm_LabelColumn ("RT", - TypeViewExamAnnouncement == ExaAnn_FORM_VIEW ? "DocRequired" : - NULL, - Txt_EXAM_ANNOUNCEMENT_Documentation_required); - - /* Data */ - HTM_TD_Begin ("class=\"EXAM LB\""); - if (TypeViewExamAnnouncement == ExaAnn_FORM_VIEW) - { - HTM_TEXTAREA_Begin ("id=\"DocRequired\" name=\"DocRequired\" cols=\"40\" rows=\"2\""); - HTM_Txt (ExamAnns->ExamAnn.DocRequired); - HTM_TEXTAREA_End (); - } - else - { - Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, - ExamAnns->ExamAnn.DocRequired, - Cns_MAX_BYTES_TEXT,false); - HTM_Txt (ExamAnns->ExamAnn.DocRequired); - } - HTM_TD_End (); - - HTM_TR_End (); - - /***** Material required *****/ - HTM_TR_Begin (NULL); - - /* Label */ - Frm_LabelColumn ("RT", - TypeViewExamAnnouncement == ExaAnn_FORM_VIEW ? "MatRequired" : - NULL, - Txt_EXAM_ANNOUNCEMENT_Material_required); - - /* Data */ - HTM_TD_Begin ("class=\"EXAM LB\""); - if (TypeViewExamAnnouncement == ExaAnn_FORM_VIEW) - { - HTM_TEXTAREA_Begin ("id=\"MatRequired\" name=\"MatRequired\" cols=\"40\" rows=\"4\""); - HTM_Txt (ExamAnns->ExamAnn.MatRequired); - HTM_TEXTAREA_End (); - } - else - { - Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, - ExamAnns->ExamAnn.MatRequired, - Cns_MAX_BYTES_TEXT,false); - HTM_Txt (ExamAnns->ExamAnn.MatRequired); - } - HTM_TD_End (); - - HTM_TR_End (); - - /***** Material allowed *****/ - HTM_TR_Begin (NULL); - - /* Label */ - Frm_LabelColumn ("RT", - TypeViewExamAnnouncement == ExaAnn_FORM_VIEW ? "MatAllowed" : - NULL, - Txt_EXAM_ANNOUNCEMENT_Material_allowed); - - /* Data */ - HTM_TD_Begin ("class=\"EXAM LB\""); - if (TypeViewExamAnnouncement == ExaAnn_FORM_VIEW) - { - HTM_TEXTAREA_Begin ("id=\"MatAllowed\" name=\"MatAllowed\" cols=\"40\" rows=\"4\""); - HTM_Txt (ExamAnns->ExamAnn.MatAllowed); - HTM_TEXTAREA_End (); - } - else - { - Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, - ExamAnns->ExamAnn.MatAllowed, - Cns_MAX_BYTES_TEXT,false); - HTM_Txt (ExamAnns->ExamAnn.MatAllowed); - } - HTM_TD_End (); - - HTM_TR_End (); - - /***** Other information to students *****/ - HTM_TR_Begin (NULL); - - /* Label */ - Frm_LabelColumn ("RT", - TypeViewExamAnnouncement == ExaAnn_FORM_VIEW ? "OtherInfo" : - NULL, - Txt_EXAM_ANNOUNCEMENT_Other_information); - - /* Data */ - HTM_TD_Begin ("class=\"EXAM LB\""); - if (TypeViewExamAnnouncement == ExaAnn_FORM_VIEW) - { - HTM_TEXTAREA_Begin ("id=\"OtherInfo\" name=\"OtherInfo\" cols=\"40\" rows=\"5\""); - HTM_Txt (ExamAnns->ExamAnn.OtherInfo); - HTM_TEXTAREA_End (); - } - else - { - Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, - ExamAnns->ExamAnn.OtherInfo, - Cns_MAX_BYTES_TEXT,false); - HTM_Txt (ExamAnns->ExamAnn.OtherInfo); - } - HTM_TD_End (); - - HTM_TR_End (); - - /***** End table, send button and end box *****/ - if (TypeViewExamAnnouncement == ExaAnn_FORM_VIEW) - Box_BoxTableWithButtonEnd ((ExaCod > 0) ? Btn_CONFIRM_BUTTON : - Btn_CREATE_BUTTON, - Txt_Publish_announcement_OF_EXAM); - else - Box_BoxTableEnd (); - - /***** Show QR code *****/ - if (TypeViewExamAnnouncement == ExaAnn_PRINT_VIEW) - QR_ExamAnnnouncement (); - - /***** End article *****/ - if (TypeViewExamAnnouncement == ExaAnn_NORMAL_VIEW) - HTM_ARTICLE_End (); - - /***** Free anchor string *****/ - Frm_FreeAnchorStr (Anchor); - } - -/*****************************************************************************/ -/********* Put icons to remove / edit / print an exam announcement ***********/ -/*****************************************************************************/ - -static void ExaAnn_PutIconsExamAnn (void *ExamAnns) - { - if (ExamAnns) - { - if (Gbl.Usrs.Me.Role.Logged == Rol_TCH || - Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM) - { - /***** Link to remove this exam announcement *****/ - Ico_PutContextualIconToRemove (ActReqRemExaAnn,NULL, - ExaAnn_PutParamExaCodToEdit,&((struct ExaAnn_ExamAnnouncements *) ExamAnns)->ExaCod); - - /***** Put form to hide/show exam announement *****/ - switch (((struct ExaAnn_ExamAnnouncements *) ExamAnns)->ExamAnn.Status) - { - case ExaAnn_VISIBLE_EXAM_ANNOUNCEMENT: - Ico_PutContextualIconToHide (ActHidExaAnn,((struct ExaAnn_ExamAnnouncements *) ExamAnns)->Anchor, - ExaAnn_PutParamExaCodToEdit,&((struct ExaAnn_ExamAnnouncements *) ExamAnns)->ExaCod); - break; - case ExaAnn_HIDDEN_EXAM_ANNOUNCEMENT: - Ico_PutContextualIconToUnhide (ActUnhExaAnn,((struct ExaAnn_ExamAnnouncements *) ExamAnns)->Anchor, - ExaAnn_PutParamExaCodToEdit,&((struct ExaAnn_ExamAnnouncements *) ExamAnns)->ExaCod); - break; - case ExaAnn_DELETED_EXAM_ANNOUNCEMENT: // Not applicable here - break; - } - - /***** Link to edit this exam announcement *****/ - Ico_PutContextualIconToEdit (ActEdiExaAnn,NULL, - ExaAnn_PutParamExaCodToEdit,&((struct ExaAnn_ExamAnnouncements *) ExamAnns)->ExaCod); - } - - /***** Link to print view *****/ - Ico_PutContextualIconToPrint (ActPrnExaAnn, - ExaAnn_PutParamExaCodToEdit,&((struct ExaAnn_ExamAnnouncements *) ExamAnns)->ExaCod); - } - } - -/*****************************************************************************/ -/*************** Param with the code of an exam announcement *****************/ -/*****************************************************************************/ - -static void ExaAnn_PutParamExaCodToEdit (void *ExaCod) - { - if (ExaCod) - ExaAnn_PutHiddenParamExaCod (*((long *) ExaCod)); - } - -void ExaAnn_PutHiddenParamExaCod (long ExaCod) - { - Par_PutHiddenParamLong (NULL,"ExaCod",ExaCod); - } - -/*****************************************************************************/ -/********** Get parameter with the code of an exam announcement **************/ -/*****************************************************************************/ - -static long ExaAnn_GetParamExaCod (void) - { - /* Get notice code */ - return Par_GetParToLong ("ExaCod"); - } - -/*****************************************************************************/ -/************ Get summary and content about an exam announcement *************/ -/*****************************************************************************/ - -void ExaAnn_GetSummaryAndContentExamAnn (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1], - char **ContentStr, - long ExaCod,bool GetContent) - { - extern const char *Txt_hours_ABBREVIATION; - struct ExaAnn_ExamAnnouncements ExamAnns; - char CrsNameAndDate[Cns_HIERARCHY_MAX_BYTES_FULL_NAME + (2 + Cns_MAX_BYTES_DATE + 7) + 1]; - char StrExamDate[Cns_MAX_BYTES_DATE + 1]; - - /***** Reset exam announcements context *****/ - ExaAnn_ResetExamAnns (&ExamAnns); - - /***** Initializations *****/ - SummaryStr[0] = '\0'; // Return nothing on error - - /***** Allocate memory for the exam announcement *****/ - ExaAnn_AllocMemExamAnn (&ExamAnns); - - /***** Get data of an exam announcement from database *****/ - ExaAnn_GetDataExamAnnFromDB (&ExamAnns,ExaCod); - - /***** Content *****/ - if (GetContent) - ExaAnn_GetNotifContentExamAnn (&ExamAnns,ContentStr); - - /***** Summary *****/ - /* Name of the course and date of exam */ - Dat_ConvDateToDateStr (&ExamAnns.ExamAnn.ExamDate,StrExamDate); - snprintf (CrsNameAndDate,sizeof (CrsNameAndDate),"%s, %s, %2u:%02u", - ExamAnns.ExamAnn.CrsFullName, - StrExamDate, - ExamAnns.ExamAnn.StartTime.Hour, - ExamAnns.ExamAnn.StartTime.Minute); - Str_Copy (SummaryStr,CrsNameAndDate,Ntf_MAX_BYTES_SUMMARY); - - /***** Free memory of the exam announcement *****/ - ExaAnn_FreeMemExamAnn (&ExamAnns); - } - -/*****************************************************************************/ -/************ Show a form with the data of an exam announcement **************/ -/*****************************************************************************/ - -static void ExaAnn_GetNotifContentExamAnn (const struct ExaAnn_ExamAnnouncements *ExamAnns, - char **ContentStr) - { - extern const char *Txt_Institution; - extern const char *Txt_Degree; - extern const char *Txt_YEAR_OF_DEGREE[1 + Deg_MAX_YEARS_PER_DEGREE]; - extern const char *Txt_EXAM_ANNOUNCEMENT_Course; - extern const char *Txt_EXAM_ANNOUNCEMENT_Year_or_semester; - extern const char *Txt_EXAM_ANNOUNCEMENT_Session; - extern const char *Txt_EXAM_ANNOUNCEMENT_Exam_date; - extern const char *Txt_EXAM_ANNOUNCEMENT_Start_time; - extern const char *Txt_EXAM_ANNOUNCEMENT_Approximate_duration; - extern const char *Txt_EXAM_ANNOUNCEMENT_Place_of_exam; - extern const char *Txt_EXAM_ANNOUNCEMENT_Mode; - extern const char *Txt_EXAM_ANNOUNCEMENT_Structure_of_the_exam; - extern const char *Txt_EXAM_ANNOUNCEMENT_Documentation_required; - extern const char *Txt_EXAM_ANNOUNCEMENT_Material_required; - extern const char *Txt_EXAM_ANNOUNCEMENT_Material_allowed; - extern const char *Txt_EXAM_ANNOUNCEMENT_Other_information; - extern const char *Txt_hours_ABBREVIATION; - struct Hie_Hierarchy Hie; - char StrExamDate[Cns_MAX_BYTES_DATE + 1]; - - /***** Get data of course *****/ - Hie.Crs.CrsCod = ExamAnns->ExamAnn.CrsCod; - Crs_GetDataOfCourseByCod (&Hie.Crs); - - /***** Get data of degree *****/ - Hie.Deg.DegCod = Hie.Crs.DegCod; - Deg_GetDataOfDegreeByCod (&Hie.Deg); - - /***** Get data of institution *****/ - Hie.Ins.InsCod = Deg_GetInsCodOfDegreeByCod (Hie.Deg.DegCod); - Ins_GetDataOfInstitutionByCod (&Hie.Ins); - - /***** Convert struct date to a date string *****/ - Dat_ConvDateToDateStr (&ExamAnns->ExamAnn.ExamDate,StrExamDate); - - /***** Fill content string *****/ - if (asprintf (ContentStr,"%s: %s
" - "%s: %s
" - "%s: %s
" - "%s: %s
" - "%s: %s
" - "%s: %s
" - "%s: %2u:%02u %s
" - "%s: %2u:%02u %s
" - "%s: %s
" - "%s: %s
" - "%s: %s
" - "%s: %s
" - "%s: %s
" - "%s: %s
" - "%s: %s", - Txt_Institution,Hie.Ins.FullName, - Txt_Degree,Hie.Deg.FullName, - Txt_EXAM_ANNOUNCEMENT_Course,ExamAnns->ExamAnn.CrsFullName, - Txt_EXAM_ANNOUNCEMENT_Year_or_semester,Txt_YEAR_OF_DEGREE[ExamAnns->ExamAnn.Year], - Txt_EXAM_ANNOUNCEMENT_Session,ExamAnns->ExamAnn.Session, - Txt_EXAM_ANNOUNCEMENT_Exam_date,StrExamDate, - Txt_EXAM_ANNOUNCEMENT_Start_time,ExamAnns->ExamAnn.StartTime.Hour, - ExamAnns->ExamAnn.StartTime.Minute, - Txt_hours_ABBREVIATION, - Txt_EXAM_ANNOUNCEMENT_Approximate_duration,ExamAnns->ExamAnn.Duration.Hour, - ExamAnns->ExamAnn.Duration.Minute, - Txt_hours_ABBREVIATION, - Txt_EXAM_ANNOUNCEMENT_Place_of_exam,ExamAnns->ExamAnn.Place, - Txt_EXAM_ANNOUNCEMENT_Mode,ExamAnns->ExamAnn.Mode, - Txt_EXAM_ANNOUNCEMENT_Structure_of_the_exam,ExamAnns->ExamAnn.Structure, - Txt_EXAM_ANNOUNCEMENT_Documentation_required,ExamAnns->ExamAnn.DocRequired, - Txt_EXAM_ANNOUNCEMENT_Material_required,ExamAnns->ExamAnn.MatRequired, - Txt_EXAM_ANNOUNCEMENT_Material_allowed,ExamAnns->ExamAnn.MatAllowed, - Txt_EXAM_ANNOUNCEMENT_Other_information,ExamAnns->ExamAnn.OtherInfo) < 0) - Lay_NotEnoughMemoryExit (); - } diff --git a/swad_exam_announcement.h b/swad_exam_announcement.h deleted file mode 100644 index bc25a801..00000000 --- a/swad_exam_announcement.h +++ /dev/null @@ -1,129 +0,0 @@ -// swad_exam_announcement.h: exam announcements - -#ifndef _SWAD_EXA_ANN -#define _SWAD_EXA_ANN -/* - SWAD (Shared Workspace At a Distance), - 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-2021 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 3 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 . -*/ -/*****************************************************************************/ -/********************************* Headers ***********************************/ -/*****************************************************************************/ - -#include // For boolean type - -#include "swad_constant.h" -#include "swad_course.h" -#include "swad_date.h" -#include "swad_notification.h" - -/*****************************************************************************/ -/************************** Public types and constants ***********************/ -/*****************************************************************************/ - -#define ExaAnn_NUM_VIEWS 3 -typedef enum - { - ExaAnn_NORMAL_VIEW, - ExaAnn_PRINT_VIEW, - ExaAnn_FORM_VIEW, - } ExaAnn_TypeViewExamAnnouncement_t; - -#define ExaAnn_NUM_STATUS 3 -typedef enum - { - ExaAnn_VISIBLE_EXAM_ANNOUNCEMENT = 0, - ExaAnn_HIDDEN_EXAM_ANNOUNCEMENT = 1, - ExaAnn_DELETED_EXAM_ANNOUNCEMENT = 2, - } ExaAnn_Status_t; // Don't change these numbers because they are used in database -#define ExaAnn_STATUS_DEFAULT ExaAnn_VISIBLE_EXAM_ANNOUNCEMENT - -#define ExaAnn_MAX_CHARS_SESSION (128 - 1) // 127 -#define ExaAnn_MAX_BYTES_SESSION ((ExaAnn_MAX_CHARS_SESSION + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 2047 - -struct ExaAnn_ExamAnnouncement - { - long CrsCod; - ExaAnn_Status_t Status; - char CrsFullName[Cns_HIERARCHY_MAX_BYTES_FULL_NAME + 1]; - unsigned Year; // Number of year (0 (N.A.), 1, 2, 3, 4, 5, 6) in the degree - char Session[ExaAnn_MAX_BYTES_SESSION + 1]; // Exam session is june, september, etc. - struct Date CallDate; - struct Date ExamDate; - struct Hour StartTime; - struct Hour Duration; - char *Place; - char *Mode; - char *Structure; - char *DocRequired; - char *MatRequired; - char *MatAllowed; - char *OtherInfo; - }; - -struct ExaAnn_ExamCodeAndDate - { - long ExaCod; - struct Date ExamDate; - }; - -struct ExaAnn_ExamAnnouncements - { - unsigned NumExaAnns; // Number of announcements of exam in the list - struct ExaAnn_ExamCodeAndDate *Lst; // List of exam announcements - long NewExaCod; // New exam announcement just created - long HighlightExaCod; // Exam announcement to be highlighted - char HighlightDate[4 + 2 + 2 + 1]; // Date with exam announcements to be highlighted (in YYYYMMDD format) - long ExaCod; // Used to put contextual icons - const char *Anchor; // Used to put contextual icons - struct ExaAnn_ExamAnnouncement ExamAnn; - }; - -/*****************************************************************************/ -/***************************** Public prototypes *****************************/ -/*****************************************************************************/ - -void ExaAnn_ResetExamAnns (struct ExaAnn_ExamAnnouncements *ExamAnns); - -void ExaAnn_PutFrmEditAExamAnn (void); -void ExaAnn_ReceiveExamAnn1 (void); -void ExaAnn_ReceiveExamAnn2 (void); -void ExaAnn_PrintExamAnn (void); -void ExaAnn_ReqRemoveExamAnn (void); -void ExaAnn_RemoveExamAnn1 (void); -void ExaAnn_RemoveExamAnn2 (void); -void ExaAnn_HideExamAnn (void); -void ExaAnn_UnhideExamAnn (void); - -void ExaAnn_FreeListExamAnns (struct ExaAnn_ExamAnnouncements *ExamAnns); -void ExaAnn_ListExamAnnsSee (void); -void ExaAnn_ListExamAnnsEdit (void); - -void ExaAnn_ListExamAnnsCod (void); -void ExaAnn_ListExamAnnsDay (void); - -void ExaAnn_CreateListExamAnns (struct ExaAnn_ExamAnnouncements *ExamAnns); -void ExaAnn_PutHiddenParamExaCod (long ExaCod); - -void ExaAnn_GetSummaryAndContentExamAnn (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1], - char **ContentStr, - long ExaCod,bool GetContent); - -#endif diff --git a/swad_global.c b/swad_global.c index d20adfa6..c914ab3f 100644 --- a/swad_global.c +++ b/swad_global.c @@ -36,11 +36,10 @@ #include "swad_action.h" #include "swad_API.h" #include "swad_calendar.h" -#include "swad_room.h" +#include "swad_call_for_exam.h" #include "swad_config.h" #include "swad_constant.h" #include "swad_department.h" -#include "swad_exam_announcement.h" #include "swad_follow.h" #include "swad_global.h" #include "swad_hierarchy.h" @@ -50,6 +49,7 @@ #include "swad_program.h" #include "swad_project.h" #include "swad_role.h" +#include "swad_room.h" #include "swad_setting.h" #include "swad_statistic.h" #include "swad_theme.h" diff --git a/swad_help_URL.c b/swad_help_URL.c index 0af36628..f674fbb8 100644 --- a/swad_help_URL.c +++ b/swad_help_URL.c @@ -1873,67 +1873,67 @@ const char *Hlp_ASSESSMENT_Surveys_questions = "ASSESSMENT.Surveys.en#questions"; #endif -const char *Hlp_ASSESSMENT_Announcements = +const char *Hlp_ASSESSMENT_Calls_for_exams = #if L==1 - "ASSESSMENT.Announcements.es"; + "ASSESSMENT.Calls_for_exams.es"; #elif L==2 - "ASSESSMENT.Announcements.en"; + "ASSESSMENT.Calls_for_exams.en"; #elif L==3 - "ASSESSMENT.Announcements.en"; + "ASSESSMENT.Calls_for_exams.en"; #elif L==4 - "ASSESSMENT.Announcements.es"; + "ASSESSMENT.Calls_for_exams.es"; #elif L==5 - "ASSESSMENT.Announcements.en"; + "ASSESSMENT.Calls_for_exams.en"; #elif L==6 - "ASSESSMENT.Announcements.es"; + "ASSESSMENT.Calls_for_exams.es"; #elif L==7 - "ASSESSMENT.Announcements.en"; + "ASSESSMENT.Calls_for_exams.en"; #elif L==8 - "ASSESSMENT.Announcements.en"; + "ASSESSMENT.Calls_for_exams.en"; #elif L==9 - "ASSESSMENT.Announcements.en"; + "ASSESSMENT.Calls_for_exams.en"; #endif -const char *Hlp_ASSESSMENT_Announcements_new_announcement = +const char *Hlp_ASSESSMENT_Calls_for_exam_new_call = #if L==1 - "ASSESSMENT.Announcements.es#nueva-convocatoria"; + "ASSESSMENT.Calls_for_exams.es#nueva-convocatoria"; #elif L==2 - "ASSESSMENT.Announcements.en#new-announcement"; + "ASSESSMENT.Calls_for_exams.en#new-call"; #elif L==3 - "ASSESSMENT.Announcements.en#new-announcement"; + "ASSESSMENT.Calls_for_exams.en#new-call"; #elif L==4 - "ASSESSMENT.Announcements.es#nueva-convocatoria"; + "ASSESSMENT.Calls_for_exams.es#nueva-convocatoria"; #elif L==5 - "ASSESSMENT.Announcements.en#new-announcement"; + "ASSESSMENT.Calls_for_exams.en#new-call"; #elif L==6 - "ASSESSMENT.Announcements.es#nueva-convocatoria"; + "ASSESSMENT.Calls_for_exams.es#nueva-convocatoria"; #elif L==7 - "ASSESSMENT.Announcements.en#new-announcement"; + "ASSESSMENT.Calls_for_exams.en#new-call"; #elif L==8 - "ASSESSMENT.Announcements.en#new-announcement"; + "ASSESSMENT.Calls_for_exams.en#new-call"; #elif L==9 - "ASSESSMENT.Announcements.en#new-announcement"; + "ASSESSMENT.Calls_for_exams.en#new-call"; #endif const char *Hlp_ASSESSMENT_Announcements_edit_announcement = #if L==1 - "ASSESSMENT.Announcements.es#editar-convocatoria"; + "ASSESSMENT.Calls_for_exams.es#editar-convocatoria"; #elif L==2 - "ASSESSMENT.Announcements.en#edit-announcement"; + "ASSESSMENT.Calls_for_exams.en#edit-call"; #elif L==3 - "ASSESSMENT.Announcements.en#edit-announcement"; + "ASSESSMENT.Calls_for_exams.en#edit-call"; #elif L==4 - "ASSESSMENT.Announcements.es#editar-convocatoria"; + "ASSESSMENT.Calls_for_exams.es#editar-convocatoria"; #elif L==5 - "ASSESSMENT.Announcements.en#edit-announcement"; + "ASSESSMENT.Calls_for_exams.en#edit-call"; #elif L==6 - "ASSESSMENT.Announcements.es#editar-convocatoria"; + "ASSESSMENT.Calls_for_exams.es#editar-convocatoria"; #elif L==7 - "ASSESSMENT.Announcements.en#edit-announcement"; + "ASSESSMENT.Calls_for_exams.en#edit-call"; #elif L==8 - "ASSESSMENT.Announcements.en#edit-announcement"; + "ASSESSMENT.Calls_for_exams.en#edit-call"; #elif L==9 - "ASSESSMENT.Announcements.en#edit-announcement"; + "ASSESSMENT.Calls_for_exams.en#edit-call"; #endif /***** FILES tab *****/ diff --git a/swad_layout.c b/swad_layout.c index ce34305c..f03dd6a4 100644 --- a/swad_layout.c +++ b/swad_layout.c @@ -34,11 +34,11 @@ #include "swad_banner.h" #include "swad_box.h" #include "swad_calendar.h" +#include "swad_call_for_exam.h" #include "swad_changelog.h" #include "swad_config.h" #include "swad_connected.h" #include "swad_database.h" -#include "swad_exam_announcement.h" #include "swad_exam_session.h" #include "swad_firewall.h" #include "swad_follow.h" @@ -495,7 +495,7 @@ static void Lay_WriteScripts (void) extern const char *Txt_DAYS_SMALL[7]; extern const char *Txt_Exam_of_X; struct Hld_Holidays Holidays; - struct ExaAnn_ExamAnnouncements ExamAnns; + struct Cfe_CallsForExams ExamAnns; unsigned DayOfWeek; /* 0, 1, 2, 3, 4, 5, 6 */ unsigned NumHld; unsigned NumExamAnnouncement; // Number of exam announcement @@ -542,10 +542,10 @@ static void Lay_WriteScripts (void) Hld_GetListHolidays (&Holidays); /***** Reset exam announcements context *****/ - ExaAnn_ResetExamAnns (&ExamAnns); + Cfe_ResetCallsForExams (&ExamAnns); /***** Create list of exam announcements *****/ - ExaAnn_CreateListExamAnns (&ExamAnns); + Cfe_CreateListCallsForExams (&ExamAnns); /***** Write script to initialize variables used to draw months *****/ HTM_SCRIPT_Begin (NULL,NULL); @@ -579,7 +579,7 @@ static void Lay_WriteScripts (void) HTM_TxtF ("\tvar LstExamAnnouncements = [];\n"); for (NumExamAnnouncement = 0; - NumExamAnnouncement < ExamAnns.NumExaAnns; + NumExamAnnouncement < ExamAnns.NumCallsForExams; NumExamAnnouncement++) HTM_TxtF ("LstExamAnnouncements.push({ ExaCod: %ld, Year: %u, Month: %u, Day: %u });\n", ExamAnns.Lst[NumExamAnnouncement].ExaCod, @@ -590,7 +590,7 @@ static void Lay_WriteScripts (void) HTM_SCRIPT_End (); /***** Free list of exam announcements *****/ - ExaAnn_FreeListExamAnns (&ExamAnns); + Cfe_FreeListCallsForExams (&ExamAnns); /***** Free list of holidays *****/ Hld_FreeListHolidays (&Holidays); diff --git a/swad_notification.c b/swad_notification.c index 011f57b0..2b07d706 100644 --- a/swad_notification.c +++ b/swad_notification.c @@ -33,11 +33,11 @@ #include "swad_action.h" #include "swad_box.h" +#include "swad_call_for_exam.h" #include "swad_config.h" #include "swad_config.h" #include "swad_database.h" #include "swad_enrolment.h" -#include "swad_exam_announcement.h" #include "swad_figure.h" #include "swad_follow.h" #include "swad_form.h" @@ -85,7 +85,7 @@ const char *Ntf_WSNotifyEvents[Ntf_NUM_NOTIFY_EVENTS] = /* Assessment tab */ [Ntf_EVENT_ASSIGNMENT ] = "assignment", [Ntf_EVENT_SURVEY ] = "survey", - [Ntf_EVENT_EXAM_ANNOUNCEMENT] = "examAnnouncement", + [Ntf_EVENT_CALL_FOR_EXAM] = "examAnnouncement", /* Files tab */ [Ntf_EVENT_DOCUMENT_FILE ] = "documentFile", [Ntf_EVENT_TEACHERS_FILE ] = "teachersFile", @@ -123,7 +123,7 @@ static const Act_Action_t Ntf_DefaultActions[Ntf_NUM_NOTIFY_EVENTS] = /* Assessment tab */ [Ntf_EVENT_ASSIGNMENT ] = ActSeeAsg, [Ntf_EVENT_SURVEY ] = ActSeeAllSvy, - [Ntf_EVENT_EXAM_ANNOUNCEMENT] = ActSeeAllExaAnn, + [Ntf_EVENT_CALL_FOR_EXAM] = ActSeeAllExaAnn, /* Files tab */ [Ntf_EVENT_DOCUMENT_FILE ] = ActSeeAdmDocCrsGrp, [Ntf_EVENT_TEACHERS_FILE ] = ActAdmTchCrsGrp, @@ -166,7 +166,7 @@ static const char *Ntf_ParamNotifMeAboutNotifyEvents[Ntf_NUM_NOTIFY_EVENTS] = /* Assessment tab */ [Ntf_EVENT_ASSIGNMENT ] = "NotifyNtfEventAssignment", [Ntf_EVENT_SURVEY ] = "NotifyNtfEventSurvey", - [Ntf_EVENT_EXAM_ANNOUNCEMENT] = "NotifyNtfEventExamAnnouncement", + [Ntf_EVENT_CALL_FOR_EXAM] = "NotifyNtfEventExamAnnouncement", /* Files tab */ [Ntf_EVENT_DOCUMENT_FILE ] = "NotifyNtfEventDocumentFile", [Ntf_EVENT_TEACHERS_FILE ] = "NotifyNtfEventTeachersFile", @@ -205,7 +205,7 @@ static const char *Ntf_ParamEmailMeAboutNotifyEvents[Ntf_NUM_NOTIFY_EVENTS] = /* Assessment tab */ [Ntf_EVENT_ASSIGNMENT ] = "EmailNtfEventAssignment", [Ntf_EVENT_SURVEY ] = "EmailNtfEventSurvey", - [Ntf_EVENT_EXAM_ANNOUNCEMENT] = "EmailNtfEventExamAnnouncement", + [Ntf_EVENT_CALL_FOR_EXAM] = "EmailNtfEventExamAnnouncement", /* Files tab */ [Ntf_EVENT_DOCUMENT_FILE ] = "EmailNtfEventDocumentFile", [Ntf_EVENT_TEACHERS_FILE ] = "EmailNtfEventTeachersFile", @@ -244,7 +244,7 @@ static const char *Ntf_Icons[Ntf_NUM_NOTIFY_EVENTS] = /* Assessment tab */ [Ntf_EVENT_ASSIGNMENT ] = "edit.svg", [Ntf_EVENT_SURVEY ] = "poll.svg", - [Ntf_EVENT_EXAM_ANNOUNCEMENT] = "bullhorn.svg", + [Ntf_EVENT_CALL_FOR_EXAM] = "bullhorn.svg", /* Files tab */ [Ntf_EVENT_DOCUMENT_FILE ] = "file.svg", [Ntf_EVENT_TEACHERS_FILE ] = "file.svg", @@ -858,8 +858,8 @@ void Ntf_GetNotifSummaryAndContent (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1], case Ntf_EVENT_ASSIGNMENT: Asg_GetNotifAssignment (SummaryStr,ContentStr,Cod,GetContent); break; - case Ntf_EVENT_EXAM_ANNOUNCEMENT: - ExaAnn_GetSummaryAndContentExamAnn (SummaryStr,ContentStr,Cod,GetContent); + case Ntf_EVENT_CALL_FOR_EXAM: + Cfe_GetSummaryAndContentCallForExam (SummaryStr,ContentStr,Cod,GetContent); break; case Ntf_EVENT_MARKS_FILE: Mrk_GetNotifMyMarks (SummaryStr,ContentStr,Cod,UsrCod,GetContent); @@ -1250,7 +1250,7 @@ unsigned Ntf_StoreNotifyEventsToAllUsrs (Ntf_NotifyEvent_t NotifyEvent,long Cod) Cod,Cod,Gbl.Usrs.Me.UsrDat.UsrCod, Cod,Gbl.Usrs.Me.UsrDat.UsrCod); break; - case Ntf_EVENT_EXAM_ANNOUNCEMENT: + case Ntf_EVENT_CALL_FOR_EXAM: case Ntf_EVENT_NOTICE: NumRows = DB_QuerySELECT (&mysql_res,"can not get users" " to be notified", @@ -1708,7 +1708,7 @@ static void Ntf_SendPendingNotifByEMailToOneUsr (struct UsrData *ToUsrDat,unsign case Ntf_EVENT_TEACHERS_FILE: case Ntf_EVENT_SHARED_FILE: case Ntf_EVENT_ASSIGNMENT: - case Ntf_EVENT_EXAM_ANNOUNCEMENT: + case Ntf_EVENT_CALL_FOR_EXAM: case Ntf_EVENT_MARKS_FILE: case Ntf_EVENT_ENROLMENT_STD: case Ntf_EVENT_ENROLMENT_NET: diff --git a/swad_notification.h b/swad_notification.h index dc8d3bee..2c322fac 100644 --- a/swad_notification.h +++ b/swad_notification.h @@ -69,7 +69,7 @@ typedef enum // TODO: Change numbers (also in database)!!!!!!!!!!!!!! /* Assessment tab */ Ntf_EVENT_ASSIGNMENT = 4, Ntf_EVENT_SURVEY = 19, - Ntf_EVENT_EXAM_ANNOUNCEMENT = 5, + Ntf_EVENT_CALL_FOR_EXAM = 5, /* Files tab */ Ntf_EVENT_DOCUMENT_FILE = 1, Ntf_EVENT_TEACHERS_FILE = 2, diff --git a/swad_text.c b/swad_text.c index d6dda8d4..bfd84fea 100644 --- a/swad_text.c +++ b/swad_text.c @@ -1761,48 +1761,6 @@ const char *Txt_Announcements = "Anúncios"; #endif -const char *Txt_Announcement_of_exam_removed = -#if L==1 // ca - "Convocatòria d'examen eliminada."; -#elif L==2 // de - "Aufruf zur Prüfung entfernt."; -#elif L==3 // en - "Announcement of exam removed."; -#elif L==4 // es - "Convocatoria de examen eliminada."; -#elif L==5 // fr - "Convocation pour l'examen supprimé."; -#elif L==6 // gn - "Convocatoria de examen eliminada."; // Okoteve traducción -#elif L==7 // it - "Appello d'esame rimosso."; -#elif L==8 // pl - "Ogloszenie egzamin usuniete."; -#elif L==9 // pt - "Chamada para exame removida."; -#endif - -const char *Txt_Announcements_of_exams = -#if L==1 // ca - "Convocatòries d'exàmens"; -#elif L==2 // de - "Aufrufe für Prüfung"; -#elif L==3 // en - "Announcements of exams"; -#elif L==4 // es - "Convocatorias de exámenes"; -#elif L==5 // fr - "Convocations à examens"; -#elif L==6 // gn - "Convocatorias de exámenes"; // Okoteve traducción -#elif L==7 // it - "Appelli d'esame"; -#elif L==8 // pl - "Ogloszenia egzaminów"; -#elif L==9 // pt - "Chamadas para exames"; -#endif - const char *Txt_Another_building = #if L==1 // ca "Un altre edifici"; @@ -3492,6 +3450,321 @@ const char *Txt_Calendar = "Calendário"; #endif +const char *Txt_CALL_FOR_EXAM = +#if L==1 // ca + "CONVOCATÒRIA D'EXAMEN"; +#elif L==2 // de + "PRÜFUNGSAUFRUF"; +#elif L==3 // en + "CALL FOR EXAM"; +#elif L==4 // es + "CONVOCATORIA DE EXAMEN"; +#elif L==5 // fr + "CONVOCATION À UN EXAMEN"; +#elif L==6 // gn + "CONVOCATORIA DE EXAMEN"; // Okoteve traducción +#elif L==7 // it + "APPELLO D'ESAME"; +#elif L==8 // pl + "OGLOSZENIE egzaminu"; +#elif L==9 // pt + "CHAMADA DE EXAME"; +#endif + +const char *Txt_CALL_FOR_EXAM_Approximate_duration = +#if L==1 // ca + "Duración aproximada"; // Necessita traduccio +#elif L==2 // de + "Voraussichtliche Dauer"; +#elif L==3 // en + "Approximate duration"; +#elif L==4 // es + "Duración aproximada"; +#elif L==5 // fr + "Durée approximative"; +#elif L==6 // gn + "Duración aproximada"; // Okoteve traducción +#elif L==7 // it + "Durata approssimativa"; +#elif L==8 // pl + "Przyblizony czas trwania"; +#elif L==9 // pt + "Duração aproximada"; +#endif + +const char *Txt_CALL_FOR_EXAM_Course = +#if L==1 // ca + "Assignatura"; +#elif L==2 // de + "Kurs"; +#elif L==3 // en + "Course"; +#elif L==4 // es + "Asignatura"; +#elif L==5 // fr + "Matière"; +#elif L==6 // gn + "Mbo'esyry"; +#elif L==7 // it + "Corso"; +#elif L==8 // pl + "Kurs"; +#elif L==9 // pt + "Disciplina"; +#endif + +const char *Txt_CALL_FOR_EXAM_Documentation_required = +#if L==1 // ca + "Documentación exigida"; // Necessita traduccio +#elif L==2 // de + "Ausweis erforderlich"; +#elif L==3 // en + "ID required"; +#elif L==4 // es + "Documentación exigida"; +#elif L==5 // fr + "Pièce d'identité obligatoire"; +#elif L==6 // gn + "Documentación exigida"; // Okoteve traducción +#elif L==7 // it + "Documentazione richiesta"; +#elif L==8 // pl + "ID wymagane"; +#elif L==9 // pt + "Documentação necessária"; +#endif + +const char *Txt_CALL_FOR_EXAM_Exam_date = +#if L==1 // ca + "Fecha del examen"; // Necessita traduccio +#elif L==2 // de + "Prüfungsdatum"; +#elif L==3 // en + "Exam date"; +#elif L==4 // es + "Fecha del examen"; +#elif L==5 // fr + "Date de l'examen"; +#elif L==6 // gn + "Fecha del examen"; // Okoteve traducción +#elif L==7 // it + "Data d'esame"; +#elif L==8 // pl + "Termin egzaminu"; +#elif L==9 // pt + "Exame data"; +#endif + +const char *Txt_CALL_FOR_EXAM_Material_allowed = +#if L==1 // ca + "Material permitido"; // Necessita traduccio +#elif L==2 // de + "Erlaubte Unterlagen"; +#elif L==3 // en + "Material allowed"; +#elif L==4 // es + "Material permitido"; +#elif L==5 // fr + "Matériel autorisé"; +#elif L==6 // gn + "Material permitido"; // Okoteve traducción +#elif L==7 // it + "Materiale permesso"; +#elif L==8 // pl + "Material dozwolone"; +#elif L==9 // pt + "Material autorizado"; +#endif + +const char *Txt_CALL_FOR_EXAM_Material_required = +#if L==1 // ca + "Material obligatorio"; // Necessita traduccio +#elif L==2 // de + "Erforderliche Unterlagen"; +#elif L==3 // en + "Material required"; +#elif L==4 // es + "Material obligatorio"; +#elif L==5 // fr + "Matériel nécessaire"; +#elif L==6 // gn + "Material obligatorio"; // Okoteve traducción +#elif L==7 // it + "Materiale richiesto"; +#elif L==8 // pl + "Materialy niezbedne do"; +#elif L==9 // pt + "Material obrigatório"; +#endif + +const char *Txt_CALL_FOR_EXAM_Mode = +#if L==1 // ca + "Modalidad
(escrito, oral,…)"; // Necessita traduccio +#elif L==2 // de + "Prüfungsart
(schriftlich, mündlich,…)"; +#elif L==3 // en + "Mode
(written, oral,…)"; +#elif L==4 // es + "Modalidad
(escrito, oral,…)"; +#elif L==5 // fr + "Mode
(écrit, oral,…)"; +#elif L==6 // gn + "Modalidad
(escrito, oral,…)"; // Okoteve traducción +#elif L==7 // it + "Modalità
(scritto, orale,…)"; +#elif L==8 // pl + "Tryb
(pisemnej, ustnej,…)"; +#elif L==9 // pt + "Modalidade
(escrita, oral,…)"; +#endif + +const char *Txt_CALL_FOR_EXAM_Other_information = +#if L==1 // ca + "Otras indicaciones"; // Necessita traduccio +#elif L==2 // de + "Weitere Informationen"; +#elif L==3 // en + "Other information"; +#elif L==4 // es + "Otras indicaciones"; +#elif L==5 // fr + "Autres informations"; +#elif L==6 // gn + "Otras indicaciones"; // Okoteve traducción +#elif L==7 // it + "Altre informazioni"; +#elif L==8 // pl + "Inne informacje"; +#elif L==9 // pt + "Outras informações"; +#endif + +const char *Txt_CALL_FOR_EXAM_Place_of_exam = +#if L==1 // ca + "Lugar de realización"; // Necessita traduccio +#elif L==2 // de + "Prüfungsort"; +#elif L==3 // en + "Place of exam"; +#elif L==4 // es + "Lugar de realización"; +#elif L==5 // fr + "Lieu de l'examen"; +#elif L==6 // gn + "Lugar de realización"; // Okoteve traducción +#elif L==7 // it + "Luogo d'esame"; +#elif L==8 // pl + "Miejsce egzaminu"; +#elif L==9 // pt + "Local do exame"; +#endif + +const char *Txt_CALL_FOR_EXAM_Session = +#if L==1 // ca + "Convocatoria
(junio, septiembre,…)"; // Necessita traduccio +#elif L==2 // de + "Einberufung
(Juni, September,…)"; +#elif L==3 // en + "Session
(june, september,…)"; +#elif L==4 // es + "Convocatoria
(junio, septiembre,…)"; +#elif L==5 // fr + "Période
(juin, septembre,…)"; +#elif L==6 // gn + "Convocatoria
(junio, septiembre,…)"; // Okoteve traducción +#elif L==7 // it + "Sessione
(giugno, settembre,…)"; +#elif L==8 // pl + "Sesja
(czerwiec, wrzesien,…)"; +#elif L==9 // pt + "Período
(junho, setembro,…)"; +#endif + +const char *Txt_CALL_FOR_EXAM_Start_time = +#if L==1 // ca + "Hora de inicio"; // Necessita traduccio +#elif L==2 // de + "Beginn um"; +#elif L==3 // en + "Start time"; +#elif L==4 // es + "Hora de inicio"; +#elif L==5 // fr + "Heure de début"; +#elif L==6 // gn + "Hora de inicio"; // Okoteve traducción +#elif L==7 // it + "Ora d'inizio"; +#elif L==8 // pl + "Czas rozpoczecia"; +#elif L==9 // pt + "Hora de início"; +#endif + +const char *Txt_CALL_FOR_EXAM_Structure_of_the_exam = +#if L==1 // ca + "Estructura del examen"; // Necessita traduccio +#elif L==2 // de + "Prüfungsstruktur"; +#elif L==3 // en + "Structure of the exam"; +#elif L==4 // es + "Estructura del examen"; +#elif L==5 // fr + "Structure de l'examen"; +#elif L==6 // gn + "Estructura del examen"; // Okoteve traducción +#elif L==7 // it + "Struttura d'esame"; +#elif L==8 // pl + "Struktura egzaminu"; +#elif L==9 // pt + "Estrutura do exame"; +#endif + +const char *Txt_CALL_FOR_EXAM_Year_or_semester = // 1, 2, 3..., not 1984, 2038... +#if L==1 // ca + "Any o semestre"; +#elif L==2 // de + "Jahr oder Semester"; +#elif L==3 // en + "Year or semester"; +#elif L==4 // es + "Año o semestre"; +#elif L==5 // fr + "Année ou semestre"; +#elif L==6 // gn + "Año o semestre"; // Okoteve traducción +#elif L==7 // it + "Anno o semestre"; +#elif L==8 // pl + "Rok lub semestr"; +#elif L==9 // pt + "Ano ou semestre"; +#endif + +const char *Txt_Call_for_exam_removed = +#if L==1 // ca + "Convocatòria d'examen eliminada."; +#elif L==2 // de + "Aufruf zur Prüfung entfernt."; +#elif L==3 // en + "Call for exam removed."; +#elif L==4 // es + "Convocatoria de examen eliminada."; +#elif L==5 // fr + "Convocation pour l'examen supprimé."; +#elif L==6 // gn + "Convocatoria de examen eliminada."; // Okoteve traducción +#elif L==7 // it + "Appello d'esame rimosso."; +#elif L==8 // pl + "Ogloszenie egzamin usuniete."; +#elif L==9 // pt + "Chamada para exame removida."; +#endif + const char *Txt_Call_the_roll = #if L==1 // ca "Passar llista"; @@ -3513,6 +3786,27 @@ const char *Txt_Call_the_roll = "Lista de presença"; #endif +const char *Txt_Calls_for_exams = +#if L==1 // ca + "Convocatòries d'exàmens"; +#elif L==2 // de + "Aufrufe für Prüfung"; +#elif L==3 // en + "Calls for exams"; +#elif L==4 // es + "Convocatorias de exámenes"; +#elif L==5 // fr + "Convocations à examens"; +#elif L==6 // gn + "Convocatorias de exámenes"; // Okoteve traducción +#elif L==7 // it + "Appelli d'esame"; +#elif L==8 // pl + "Ogloszenia egzaminów"; +#elif L==9 // pt + "Chamadas para exames"; +#endif + const char *Txt_Can_not_create_the_folder_X_because_it_would_exceed_the_disk_quota = // Warning: it is very important to include %s in the following sentences #if L==1 // ca "No s'ha creat la carpeta %s" @@ -5094,7 +5388,6 @@ const char *Txt_Could_not_detect_any_face_in_front_position_ = "Não foi possível detectar nenhum rosto na posição frontal."; #endif - const char *Txt_Countdown = #if L==1 // ca "Compte enrere"; @@ -6553,27 +6846,6 @@ const char *Txt_Create_ZIP_file = "Criar arquivo ZIP"; #endif -const char *Txt_Created_new_announcement_of_exam = -#if L==1 // ca - "Creada nueva convocatoria de examen."; // Necessita traduccio -#elif L==2 // de - "Neuer Aufruf zur Prüfung erstellt."; -#elif L==3 // en - "Created new announcement of exam."; -#elif L==4 // es - "Creada nueva convocatoria de examen."; -#elif L==5 // fr - "Créé nouvelle convocation à un examen."; -#elif L==6 // gn - "Creada nueva convocatoria de examen."; // Okoteve traducción -#elif L==7 // it - "Creato nuovo appello d'esame."; -#elif L==8 // pl - "Utworzono nowe ogloszenie egzamin."; -#elif L==9 // pt - "Criado nova chamada para exame."; -#endif - const char *Txt_Created_new_assignment_X = // Warning: it is very important to include %s in the following sentences #if L==1 // ca "Creada nova activitat %s."; @@ -6637,6 +6909,27 @@ const char *Txt_Created_new_building_X = // Warning: it is very important to inc "Criado novo edifício %s."; #endif +const char *Txt_Created_new_call_for_exam = +#if L==1 // ca + "Creada nueva convocatoria de examen."; // Necessita traduccio +#elif L==2 // de + "Neuer Aufruf zur Prüfung erstellt."; +#elif L==3 // en + "Created new call for exam."; +#elif L==4 // es + "Creada nueva convocatoria de examen."; +#elif L==5 // fr + "Créé nouvelle convocation à un examen."; +#elif L==6 // gn + "Creada nueva convocatoria de examen."; // Okoteve traducción +#elif L==7 // it + "Creato nuovo appello d'esame."; +#elif L==8 // pl + "Utworzono nowe ogloszenie egzamin."; +#elif L==9 // pt + "Criado nova chamada para exame."; +#endif + const char *Txt_Created_new_center_X = // Warning: it is very important to include %s in the following sentences #if L==1 // ca "Creat nou center %s."; // Necessita traduccio @@ -9248,13 +9541,13 @@ const char *Txt_Do_you_really_want_to_remove_the_folder_X = // Warning: it is ve " o diretório %s e todo o seu conteúdo?"; #endif -const char *Txt_Do_you_really_want_to_remove_the_following_announcement_of_exam = +const char *Txt_Do_you_really_want_to_remove_the_following_call_for_exam = #if L==1 // ca "De veres voleu eliminar la següent convocatòria d'examen?"; #elif L==2 // de "Wollen Sie wirklich, um die folgende Aufruf für Prüfung?"; #elif L==3 // en - "Do you really want to remove the following announcement of exam?"; + "Do you really want to remove the following call for exam?"; #elif L==4 // es "¿Realmente desea eliminar la siguiente convocatoria de examen?"; #elif L==5 // fr @@ -11731,300 +12024,6 @@ const char *Txt_Exam = "Exame"; #endif -const char *Txt_EXAM_ANNOUNCEMENT = -#if L==1 // ca - "CONVOCATÒRIA D'EXAMEN"; -#elif L==2 // de - "PRÜFUNGSAUFRUF"; -#elif L==3 // en - "ANNOUNCEMENT OF EXAM"; -#elif L==4 // es - "CONVOCATORIA DE EXAMEN"; -#elif L==5 // fr - "CONVOCATION À UN EXAMEN"; -#elif L==6 // gn - "CONVOCATORIA DE EXAMEN"; // Okoteve traducción -#elif L==7 // it - "APPELLO D'ESAME"; -#elif L==8 // pl - "OGLOSZENIE egzaminu"; -#elif L==9 // pt - "CHAMADA DE EXAME"; -#endif - -const char *Txt_EXAM_ANNOUNCEMENT_Approximate_duration = -#if L==1 // ca - "Duración aproximada"; // Necessita traduccio -#elif L==2 // de - "Voraussichtliche Dauer"; -#elif L==3 // en - "Approximate duration"; -#elif L==4 // es - "Duración aproximada"; -#elif L==5 // fr - "Durée approximative"; -#elif L==6 // gn - "Duración aproximada"; // Okoteve traducción -#elif L==7 // it - "Durata approssimativa"; -#elif L==8 // pl - "Przyblizony czas trwania"; -#elif L==9 // pt - "Duração aproximada"; -#endif - -const char *Txt_EXAM_ANNOUNCEMENT_Course = -#if L==1 // ca - "Assignatura"; -#elif L==2 // de - "Kurs"; -#elif L==3 // en - "Course"; -#elif L==4 // es - "Asignatura"; -#elif L==5 // fr - "Matière"; -#elif L==6 // gn - "Mbo'esyry"; -#elif L==7 // it - "Corso"; -#elif L==8 // pl - "Kurs"; -#elif L==9 // pt - "Disciplina"; -#endif - -const char *Txt_EXAM_ANNOUNCEMENT_Documentation_required = -#if L==1 // ca - "Documentación exigida"; // Necessita traduccio -#elif L==2 // de - "Ausweis erforderlich"; -#elif L==3 // en - "ID required"; -#elif L==4 // es - "Documentación exigida"; -#elif L==5 // fr - "Pièce d'identité obligatoire"; -#elif L==6 // gn - "Documentación exigida"; // Okoteve traducción -#elif L==7 // it - "Documentazione richiesta"; -#elif L==8 // pl - "ID wymagane"; -#elif L==9 // pt - "Documentação necessária"; -#endif - -const char *Txt_EXAM_ANNOUNCEMENT_Exam_date = -#if L==1 // ca - "Fecha del examen"; // Necessita traduccio -#elif L==2 // de - "Prüfungsdatum"; -#elif L==3 // en - "Exam date"; -#elif L==4 // es - "Fecha del examen"; -#elif L==5 // fr - "Date de l'examen"; -#elif L==6 // gn - "Fecha del examen"; // Okoteve traducción -#elif L==7 // it - "Data d'esame"; -#elif L==8 // pl - "Termin egzaminu"; -#elif L==9 // pt - "Exame data"; -#endif - -const char *Txt_EXAM_ANNOUNCEMENT_Material_allowed = -#if L==1 // ca - "Material permitido"; // Necessita traduccio -#elif L==2 // de - "Erlaubte Unterlagen"; -#elif L==3 // en - "Material allowed"; -#elif L==4 // es - "Material permitido"; -#elif L==5 // fr - "Matériel autorisé"; -#elif L==6 // gn - "Material permitido"; // Okoteve traducción -#elif L==7 // it - "Materiale permesso"; -#elif L==8 // pl - "Material dozwolone"; -#elif L==9 // pt - "Material autorizado"; -#endif - -const char *Txt_EXAM_ANNOUNCEMENT_Material_required = -#if L==1 // ca - "Material obligatorio"; // Necessita traduccio -#elif L==2 // de - "Erforderliche Unterlagen"; -#elif L==3 // en - "Material required"; -#elif L==4 // es - "Material obligatorio"; -#elif L==5 // fr - "Matériel nécessaire"; -#elif L==6 // gn - "Material obligatorio"; // Okoteve traducción -#elif L==7 // it - "Materiale richiesto"; -#elif L==8 // pl - "Materialy niezbedne do"; -#elif L==9 // pt - "Material obrigatório"; -#endif - -const char *Txt_EXAM_ANNOUNCEMENT_Mode = -#if L==1 // ca - "Modalidad
(escrito, oral,…)"; // Necessita traduccio -#elif L==2 // de - "Prüfungsart
(schriftlich, mündlich,…)"; -#elif L==3 // en - "Mode
(written, oral,…)"; -#elif L==4 // es - "Modalidad
(escrito, oral,…)"; -#elif L==5 // fr - "Mode
(écrit, oral,…)"; -#elif L==6 // gn - "Modalidad
(escrito, oral,…)"; // Okoteve traducción -#elif L==7 // it - "Modalità
(scritto, orale,…)"; -#elif L==8 // pl - "Tryb
(pisemnej, ustnej,…)"; -#elif L==9 // pt - "Modalidade
(escrita, oral,…)"; -#endif - -const char *Txt_EXAM_ANNOUNCEMENT_Other_information = -#if L==1 // ca - "Otras indicaciones"; // Necessita traduccio -#elif L==2 // de - "Weitere Informationen"; -#elif L==3 // en - "Other information"; -#elif L==4 // es - "Otras indicaciones"; -#elif L==5 // fr - "Autres informations"; -#elif L==6 // gn - "Otras indicaciones"; // Okoteve traducción -#elif L==7 // it - "Altre informazioni"; -#elif L==8 // pl - "Inne informacje"; -#elif L==9 // pt - "Outras informações"; -#endif - -const char *Txt_EXAM_ANNOUNCEMENT_Place_of_exam = -#if L==1 // ca - "Lugar de realización"; // Necessita traduccio -#elif L==2 // de - "Prüfungsort"; -#elif L==3 // en - "Place of exam"; -#elif L==4 // es - "Lugar de realización"; -#elif L==5 // fr - "Lieu de l'examen"; -#elif L==6 // gn - "Lugar de realización"; // Okoteve traducción -#elif L==7 // it - "Luogo d'esame"; -#elif L==8 // pl - "Miejsce egzaminu"; -#elif L==9 // pt - "Local do exame"; -#endif - -const char *Txt_EXAM_ANNOUNCEMENT_Session = -#if L==1 // ca - "Convocatoria
(junio, septiembre,…)"; // Necessita traduccio -#elif L==2 // de - "Einberufung
(Juni, September,…)"; -#elif L==3 // en - "Session
(june, september,…)"; -#elif L==4 // es - "Convocatoria
(junio, septiembre,…)"; -#elif L==5 // fr - "Période
(juin, septembre,…)"; -#elif L==6 // gn - "Convocatoria
(junio, septiembre,…)"; // Okoteve traducción -#elif L==7 // it - "Sessione
(giugno, settembre,…)"; -#elif L==8 // pl - "Sesja
(czerwiec, wrzesien,…)"; -#elif L==9 // pt - "Período
(junho, setembro,…)"; -#endif - -const char *Txt_EXAM_ANNOUNCEMENT_Start_time = -#if L==1 // ca - "Hora de inicio"; // Necessita traduccio -#elif L==2 // de - "Beginn um"; -#elif L==3 // en - "Start time"; -#elif L==4 // es - "Hora de inicio"; -#elif L==5 // fr - "Heure de début"; -#elif L==6 // gn - "Hora de inicio"; // Okoteve traducción -#elif L==7 // it - "Ora d'inizio"; -#elif L==8 // pl - "Czas rozpoczecia"; -#elif L==9 // pt - "Hora de início"; -#endif - -const char *Txt_EXAM_ANNOUNCEMENT_Structure_of_the_exam = -#if L==1 // ca - "Estructura del examen"; // Necessita traduccio -#elif L==2 // de - "Prüfungsstruktur"; -#elif L==3 // en - "Structure of the exam"; -#elif L==4 // es - "Estructura del examen"; -#elif L==5 // fr - "Structure de l'examen"; -#elif L==6 // gn - "Estructura del examen"; // Okoteve traducción -#elif L==7 // it - "Struttura d'esame"; -#elif L==8 // pl - "Struktura egzaminu"; -#elif L==9 // pt - "Estrutura do exame"; -#endif - -const char *Txt_EXAM_ANNOUNCEMENT_Year_or_semester = // 1, 2, 3..., not 1984, 2038... -#if L==1 // ca - "Any o semestre"; -#elif L==2 // de - "Jahr oder Semester"; -#elif L==3 // en - "Year or semester"; -#elif L==4 // es - "Año o semestre"; -#elif L==5 // fr - "Année ou semestre"; -#elif L==6 // gn - "Año o semestre"; // Okoteve traducción -#elif L==7 // it - "Anno o semestre"; -#elif L==8 // pl - "Rok lub semestr"; -#elif L==9 // pt - "Ano ou semestre"; -#endif - const char *Txt_EXAM_LOG_ACTIONS[ExaLog_NUM_ACTIONS] = { [ExaLog_UNKNOWN_ACTION] = @@ -18567,13 +18566,13 @@ const char *Txt_Link_X_removed = // Warning: it is very important to include %s "Ligação %s removida."; #endif -const char *Txt_Link_to_announcement_of_exam = +const char *Txt_Link_to_call_for_exam = #if L==1 // ca "Enllaç a convocatòria d'examen"; #elif L==2 // de "Link zu Aufruf für Prüfung"; #elif L==3 // en - "Link to announcement of exam"; + "Link to call for exam"; #elif L==4 // es "Enlace a convocatoria de examen"; #elif L==5 // fr @@ -22282,7 +22281,7 @@ const char *Txt_MENU_SUBTITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = #elif L==2 // de "Prüfungsaufruf" #elif L==3 // en - "Announcements of exams" + "Calls for exams" #elif L==4 // es "Listado de convocatorias de exámenes de esta asignatura" #elif L==5 // fr @@ -25124,7 +25123,7 @@ const char *Txt_New_announcement = "Novo anúncio"; #endif -const char *Txt_New_announcement_OF_EXAM = +const char *Txt_New_call_FOR_EXAM = #if L==1 // ca "Nova convocatòria"; #elif L==2 // de @@ -26153,27 +26152,6 @@ const char *Txt_No_announcements = "Não há anúncios"; #endif -const char *Txt_No_announcements_of_exams_of_X = // Warning: it is very important to include %s in the following sentences -#if L==1 // ca - "No hay convocatorias de examen de %s."; // Necessita traduccio -#elif L==2 // de - "Keine Aufrufe für Prüfung von %s."; -#elif L==3 // en - "No announcements of exams of %s."; -#elif L==4 // es - "No hay convocatorias de examen de %s."; -#elif L==5 // fr - "Aucune convocation à un examen de %s."; -#elif L==6 // gn - "No hay convocatorias de examen de %s."; // Okoteve traducción -#elif L==7 // it - "Nessun appello d'esame di %s."; -#elif L==8 // pl - "Brak ogloszen egzaminów %s."; -#elif L==9 // pt - "Não chamadas para exame de %s."; -#endif - const char *Txt_No_assigned_building = #if L==1 // ca "Sense edifici assignat"; @@ -26258,6 +26236,27 @@ const char *Txt_No_banners = "Não há banners."; #endif +const char *Txt_No_calls_for_exams_of_X = // Warning: it is very important to include %s in the following sentences +#if L==1 // ca + "No hay convocatorias de examen de %s."; // Necessita traduccio +#elif L==2 // de + "Keine Aufrufe für Prüfung von %s."; +#elif L==3 // en + "No calls for exams of %s."; +#elif L==4 // es + "No hay convocatorias de examen de %s."; +#elif L==5 // fr + "Aucune convocation à un examen de %s."; +#elif L==6 // gn + "No hay convocatorias de examen de %s."; // Okoteve traducción +#elif L==7 // it + "Nessun appello d'esame di %s."; +#elif L==8 // pl + "Brak ogloszen egzaminów %s."; +#elif L==9 // pt + "Não chamadas para exame de %s."; +#endif + const char *Txt_no_course_of_origin = // Means: "message sent from any course" #if L==1 // ca "sin asignatura de origen"; // Necessita traduccio @@ -27793,13 +27792,13 @@ const char *Txt_NOTIFY_EVENTS_PLURAL[Ntf_NUM_NOTIFY_EVENTS] = "Novas atividades" #endif , - [Ntf_EVENT_EXAM_ANNOUNCEMENT] = + [Ntf_EVENT_CALL_FOR_EXAM] = #if L==1 // ca "Noves convocatòries d'examen" #elif L==2 // de "Neue Aufrufe für Prüfung" #elif L==3 // en - "New announcements of exam" + "New calls for exam" #elif L==4 // es "Nuevas convocatorias de examen" #elif L==5 // fr @@ -28237,13 +28236,13 @@ const char *Txt_NOTIFY_EVENTS_SINGULAR[Ntf_NUM_NOTIFY_EVENTS] = "Atividade" #endif , - [Ntf_EVENT_EXAM_ANNOUNCEMENT] = + [Ntf_EVENT_CALL_FOR_EXAM] = #if L==1 // ca "Convocatòria d'examen" #elif L==2 // de "Aufrufe für Prüfung" #elif L==3 // en - "Announcement of exam" + "Call for exam" #elif L==4 // es "Convocatoria de examen" #elif L==5 // fr @@ -32851,13 +32850,13 @@ const char *Txt_Public_views = "Acessos públicos"; #endif -const char *Txt_Publish_announcement_OF_EXAM = +const char *Txt_Publish_call_FOR_EXAM = #if L==1 // ca "Publicar convocatòria"; #elif L==2 // de "Veröffentlichen Aufruf"; #elif L==3 // en - "Publish announcement"; + "Publish call"; #elif L==4 // es "Publicar convocatoria"; #elif L==5 // fr @@ -46252,27 +46251,6 @@ const char *Txt_The_alphabetical_code_X_is_not_correct = // Warning: it is very "O código alfabético ISO 3166-1 %s não está correto."; #endif -const char *Txt_The_announcement_of_exam_has_been_successfully_updated = -#if L==1 // ca - "La convocatòria d'examen s'ha actualitzat correctament."; -#elif L==2 // de - "Der Aufruf zur Prüfung wurde erfolgreich aktualisiert."; -#elif L==3 // en - "The announcement of exam has been successfully updated."; -#elif L==4 // es - "La convocatoria de examen se ha actualizado correctamente."; -#elif L==5 // fr - "La convocation pour l'examen a été mis à jour avec succès."; -#elif L==6 // gn - "La convocatoria de examen se ha actualizado correctamente."; // Okoteve traducción -#elif L==7 // it - "L'apello d'esame è stata aggiornata con successo."; -#elif L==8 // pl - "Ogloszenie egzamin został pomyślnie zaktualizowany."; -#elif L==9 // pt - "A chamada para exame foi atualizada com sucesso."; -#endif - const char *Txt_The_answers_of_the_question_with_code_X_will_appear_shuffled = // Warning: it is very important to include %ld in the following sentences #if L==1 // ca "Las respuestas de la pregunta con código %ld" @@ -46480,6 +46458,27 @@ const char *Txt_The_building_of_room_X_is_now_Y = // Warning: it is very importa "O edifício da sala %s é agora %s."; #endif +const char *Txt_The_call_for_exam_has_been_successfully_updated = +#if L==1 // ca + "La convocatòria d'examen s'ha actualitzat correctament."; +#elif L==2 // de + "Der Aufruf zur Prüfung wurde erfolgreich aktualisiert."; +#elif L==3 // en + "The call for exam has been successfully updated."; +#elif L==4 // es + "La convocatoria de examen se ha actualizado correctamente."; +#elif L==5 // fr + "La convocation pour l'examen a été mis à jour avec succès."; +#elif L==6 // gn + "La convocatoria de examen se ha actualizado correctamente."; // Okoteve traducción +#elif L==7 // it + "L'apello d'esame è stata aggiornata con successo."; +#elif L==8 // pl + "Ogloszenie egzamin został pomyślnie zaktualizowany."; +#elif L==9 // pt + "A chamada para exame foi atualizada com sucesso."; +#endif + const char *Txt_The_capacity_of_room_X_has_not_changed = // Warning: it is very important to include %s in the following sentences #if L==1 // ca "L'aforament de la sala %s no ha canviat."; @@ -52779,13 +52778,13 @@ const char *Txt_TIMELINE_NOTE[TL_NOT_NUM_NOTE_TYPES] = "Arquivo compartilhado público (disciplina)" #endif , - [TL_NOTE_EXAM_ANNOUNCEMENT] = + [TL_NOTE_CALL_FOR_EXAM] = #if L==1 // ca "Convocatòria d'examen" #elif L==2 // de "Aufrufe für Prüfung" #elif L==3 // en - "Announcement of exam" + "Call for exam" #elif L==4 // es "Convocatoria de examen" #elif L==5 // fr diff --git a/swad_text_action.c b/swad_text_action.c index b2108421..80b68d09 100644 --- a/swad_text_action.c +++ b/swad_text_action.c @@ -9556,7 +9556,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "Download file from the assessment zone of a project" // Precisa de tradução #endif , - [ActSeeOneExaAnn] = + [ActSeeOneCfe] = #if L==1 // ca "See one exam announcement" // Necessita traducció #elif L==2 // de @@ -9577,7 +9577,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "See one exam announcement" // Precisa de tradução #endif , - [ActSeeDatExaAnn] = + [ActSeeDatCfe] = #if L==1 // ca "See exam announcements of a given date" // Necessita traducció #elif L==2 // de @@ -9598,7 +9598,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "See exam announcements of a given date" // Precisa de tradução #endif , - [ActEdiExaAnn] = + [ActEdiCfe] = #if L==1 // ca "Edit an exam announcement" // Necessita traducció #elif L==2 // de @@ -9619,7 +9619,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "Edit an exam announcement" // Precisa de tradução #endif , - [ActRcvExaAnn] = + [ActRcvCfe] = #if L==1 // ca "Send an exam announcement" // Necessita traducció #elif L==2 // de @@ -9640,7 +9640,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "Send an exam announcement" // Precisa de tradução #endif , - [ActPrnExaAnn] = + [ActPrnCfe] = #if L==1 // ca "See an exam announcement ready to be printed" // Necessita traducció #elif L==2 // de @@ -9661,7 +9661,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "See an exam announcement ready to be printed" // Precisa de tradução #endif , - [ActReqRemExaAnn] = + [ActReqRemCfe] = #if L==1 // ca "Request removal of an exam announcement" // Necessita traducció #elif L==2 // de @@ -9682,7 +9682,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "Request removal of an exam announcement" // Precisa de tradução #endif , - [ActRemExaAnn] = + [ActRemCfe] = #if L==1 // ca "Remove exam announcement" // Necessita traducció #elif L==2 // de @@ -9703,7 +9703,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "Remove exam announcement" // Precisa de tradução #endif , - [ActHidExaAnn] = + [ActHidCfe] = #if L==1 // ca "Hide exam announcement" // Necessita traducció #elif L==2 // de @@ -9724,7 +9724,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "Hide exam announcement" // Precisa de tradução #endif , - [ActUnhExaAnn] = + [ActUnhCfe] = #if L==1 // ca "Unhide exam announcement" // Necessita traducció #elif L==2 // de diff --git a/swad_text_no_html.c b/swad_text_no_html.c index 361c4a61..36b96684 100644 --- a/swad_text_no_html.c +++ b/swad_text_no_html.c @@ -469,12 +469,12 @@ const char *Txt_NOTIFY_EVENTS_SINGULAR_NO_HTML[Ntf_NUM_NOTIFY_EVENTS][1 + Lan_NU [Lan_LANGUAGE_PL ] = "Nowe zadania", [Lan_LANGUAGE_PT ] = "Nova atividade", }, -[Ntf_EVENT_EXAM_ANNOUNCEMENT] = +[Ntf_EVENT_CALL_FOR_EXAM] = { [Lan_LANGUAGE_UNKNOWN] = "", [Lan_LANGUAGE_CA ] = "Nova convocatòria d'examen", [Lan_LANGUAGE_DE ] = "Neue Aufrufe für Prüfung", - [Lan_LANGUAGE_EN ] = "New announcement of exam", + [Lan_LANGUAGE_EN ] = "New call for exam", [Lan_LANGUAGE_ES ] = "Nueva convocatoria de examen", [Lan_LANGUAGE_FR ] = "Nouvelle convocation à un examen", [Lan_LANGUAGE_GN ] = "Nueva convocatoria de examen", // Okoteve traducción diff --git a/swad_timeline_note.c b/swad_timeline_note.c index dd83a158..fb11ea61 100644 --- a/swad_timeline_note.c +++ b/swad_timeline_note.c @@ -31,8 +31,8 @@ #include "swad_alert.h" #include "swad_box.h" +#include "swad_call_for_exam.h" #include "swad_course.h" -#include "swad_exam_announcement.h" #include "swad_forum.h" #include "swad_global.h" #include "swad_hierarchy.h" @@ -138,7 +138,7 @@ void Tml_Not_ShowHighlightedNote (struct Tml_Timeline *Timeline, /* Assessment tab */ [Ntf_EVENT_ASSIGNMENT ] = Tml_TOP_MESSAGE_NONE, [Ntf_EVENT_SURVEY ] = Tml_TOP_MESSAGE_NONE, - [Ntf_EVENT_EXAM_ANNOUNCEMENT] = Tml_TOP_MESSAGE_NONE, + [Ntf_EVENT_CALL_FOR_EXAM] = Tml_TOP_MESSAGE_NONE, /* Files tab */ [Ntf_EVENT_DOCUMENT_FILE ] = Tml_TOP_MESSAGE_NONE, [Ntf_EVENT_TEACHERS_FILE ] = Tml_TOP_MESSAGE_NONE, @@ -467,7 +467,7 @@ static void Tml_Not_GetLocationInHierarchy (const struct Tml_Not_Note *Not, break; case TL_NOTE_CRS_DOC_PUB_FILE: case TL_NOTE_CRS_SHA_PUB_FILE: - case TL_NOTE_EXAM_ANNOUNCEMENT: + case TL_NOTE_CALL_FOR_EXAM: case TL_NOTE_NOTICE: /* Get course data */ Hie->Crs.CrsCod = Not->HieCod; @@ -524,7 +524,7 @@ static void Tml_Not_WriteLocationInHierarchy (const struct Tml_Not_Note *Not, break; case TL_NOTE_CRS_DOC_PUB_FILE: case TL_NOTE_CRS_SHA_PUB_FILE: - case TL_NOTE_EXAM_ANNOUNCEMENT: + case TL_NOTE_CALL_FOR_EXAM: case TL_NOTE_NOTICE: /* Write location (course) in hierarchy */ HTM_DIV_Begin ("class=\"TL_LOC\""); @@ -572,7 +572,7 @@ static void Tml_Not_PutFormGoToAction (const struct Tml_Not_Note *Not, [TL_NOTE_CRS_DOC_PUB_FILE ] = ActReqDatSeeDocCrs, [TL_NOTE_CRS_SHA_PUB_FILE ] = ActReqDatShaCrs, /* Assessment tab */ - [TL_NOTE_EXAM_ANNOUNCEMENT] = ActSeeOneExaAnn, + [TL_NOTE_CALL_FOR_EXAM] = ActSeeOneCfe, /* Users tab */ /* Messages tab */ [TL_NOTE_NOTICE ] = ActSeeOneNot, @@ -598,7 +598,7 @@ static void Tml_Not_PutFormGoToAction (const struct Tml_Not_Note *Not, [TL_NOTE_CRS_DOC_PUB_FILE ] = "file.svg", [TL_NOTE_CRS_SHA_PUB_FILE ] = "file.svg", /* Assessment tab */ - [TL_NOTE_EXAM_ANNOUNCEMENT] = "bullhorn.svg", + [TL_NOTE_CALL_FOR_EXAM] = "bullhorn.svg", /* Users tab */ /* Messages tab */ [TL_NOTE_NOTICE ] = "sticky-note.svg", @@ -658,12 +658,12 @@ static void Tml_Not_PutFormGoToAction (const struct Tml_Not_Note *Not, if (Not->HieCod != Gbl.Hierarchy.Crs.CrsCod) // Not the current course Crs_PutParamCrsCod (Not->HieCod); // Go to another course break; - case TL_NOTE_EXAM_ANNOUNCEMENT: + case TL_NOTE_CALL_FOR_EXAM: Frm_SetAnchorStr (Not->Cod,&Anchor); Frm_BeginFormUniqueAnchor (TL_DefaultActions[Not->NoteType], Anchor); // Locate on this specific exam Frm_FreeAnchorStr (Anchor); - ExaAnn_PutHiddenParamExaCod (Not->Cod); + Cfe_PutHiddenParamExaCod (Not->Cod); if (Not->HieCod != Gbl.Hierarchy.Crs.CrsCod) // Not the current course Crs_PutParamCrsCod (Not->HieCod); // Go to another course break; @@ -741,8 +741,8 @@ void Tml_Not_GetNoteSummary (const struct Tml_Not_Note *Not, case TL_NOTE_CRS_SHA_PUB_FILE: Brw_GetSummaryAndContentOfFile (SummaryStr,NULL,Not->Cod,false); break; - case TL_NOTE_EXAM_ANNOUNCEMENT: - ExaAnn_GetSummaryAndContentExamAnn (SummaryStr,NULL,Not->Cod,false); + case TL_NOTE_CALL_FOR_EXAM: + Cfe_GetSummaryAndContentCallForExam (SummaryStr,NULL,Not->Cod,false); break; case TL_NOTE_POST: // Not applicable @@ -916,7 +916,7 @@ void Tml_Not_StoreAndPublishNoteInternal (Tml_Not_NoteType_t NoteType,long Cod, break; case TL_NOTE_CRS_DOC_PUB_FILE: case TL_NOTE_CRS_SHA_PUB_FILE: - case TL_NOTE_EXAM_ANNOUNCEMENT: + case TL_NOTE_CALL_FOR_EXAM: case TL_NOTE_NOTICE: HieCod = Gbl.Hierarchy.Crs.CrsCod; break; diff --git a/swad_timeline_note.h b/swad_timeline_note.h index fbe6462a..d04946b5 100644 --- a/swad_timeline_note.h +++ b/swad_timeline_note.h @@ -58,7 +58,7 @@ typedef enum TL_NOTE_CRS_DOC_PUB_FILE = 7, // Public file in documents of course TL_NOTE_CRS_SHA_PUB_FILE = 8, // Public file in shared files of course /* Assessment tab */ - TL_NOTE_EXAM_ANNOUNCEMENT = 9, // Exam announcement in a course + TL_NOTE_CALL_FOR_EXAM = 9, // Exam announcement in a course /* Users tab */ /* Messages tab */ TL_NOTE_NOTICE = 12, // A public notice in a course