From c899d13400dd596e34f58e9f5b7c7ed35af22ec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ca=C3=B1as=20Vargas?= Date: Tue, 29 Nov 2016 15:02:23 +0100 Subject: [PATCH] Version 16.77 --- swad_action.c | 182 ++--- swad_action.h | 154 ++--- swad_changelog.h | 8 +- swad_global.h | 10 +- swad_help.c | 5 +- swad_location.c | 1710 ++++++++++++++++++++++++++++++++-------------- swad_location.h | 55 +- swad_text.c | 208 ++---- 8 files changed, 1484 insertions(+), 848 deletions(-) diff --git a/swad_action.c b/swad_action.c index 943bfc34f..b4cdc3d9d 100644 --- a/swad_action.c +++ b/swad_action.c @@ -81,7 +81,7 @@ extern struct Globals Gbl; /************************ Internal global variables **************************/ /*****************************************************************************/ /* -1230 actions in one CGI: +1232 actions in one CGI: 0. ActAll Any action (used for statistics) 1. ActUnk Unknown action 2. ActHom Show home menu @@ -1328,7 +1328,7 @@ Profile: 1141. ActMyCrs Select one of my courses 1142. ActSeeMyTT Show the timetable of all courses of the logged user 1143. ActSeeMyAgd Show my agenda (personal organizer) - 1144. ActSeeMyLoc Show my location + 1144. ActSeeMyLoc Show my locations 1145. ActFrmMyAcc Show form to the creation or change of user's account 1146. ActReqEdiRecCom Request the edition of the record with the personal data of the user 1147. ActEdiPrf Show forms to edit preferences @@ -1344,89 +1344,91 @@ Profile: 1155. ActAnnSee Mark announcement as seen 1156. ActChgMyRol Change type of logged user - 1157. ActEdiLoc Edit my locations - 1158. ActNewLoc Request the creation of a location - 1159. ActRemLoc Remove a location - 1160. ActChgLocStrDat Change start date of a location - 1161. ActChgLocEndDat Change end date of a location - 1162. ActRenLoc Rename a location + 1157. ActFrmNewLoc Form to create a new location + 1158. ActEdiOneLoc Edit one location + 1159. ActNewLoc Create new location + 1160. ActChgLoc Modify data of an existing location + 1161. ActReqRemLoc Request the removal of a location + 1162. ActRemLoc Remove location + 1163. ActHidLoc Hide location + 1164. ActShoLoc Show location - 1163. ActChkUsrAcc Check if already exists a new account without password associated to a ID - 1164. ActCreUsrAcc Create new user account - 1165. ActRemID_Me Remove one of my user's IDs - 1166. ActNewIDMe Create a new user's ID for me - 1167. ActRemOldNic Remove one of my old nicknames - 1168. ActChgNic Change my nickname - 1169. ActRemMaiMe Remove one of my old emails - 1170. ActNewMaiMe Change my email address - 1171. ActCnfMai Confirm email address - 1172. ActFrmChgMyPwd Show form to the change of the password - 1173. ActChgPwd Change the password - 1174. ActReqRemMyAcc Request the removal of my account - 1175. ActRemMyAcc Remove my account + 1165. ActChkUsrAcc Check if already exists a new account without password associated to a ID + 1166. ActCreUsrAcc Create new user account + 1167. ActRemID_Me Remove one of my user's IDs + 1168. ActNewIDMe Create a new user's ID for me + 1169. ActRemOldNic Remove one of my old nicknames + 1170. ActChgNic Change my nickname + 1171. ActRemMaiMe Remove one of my old emails + 1172. ActNewMaiMe Change my email address + 1173. ActCnfMai Confirm email address + 1174. ActFrmChgMyPwd Show form to the change of the password + 1175. ActChgPwd Change the password + 1176. ActReqRemMyAcc Request the removal of my account + 1177. ActRemMyAcc Remove my account - 1176. ActChgMyData Update my personal data + 1178. ActChgMyData Update my personal data - 1177. ActReqMyPho Show form to send my photo - 1178. ActDetMyPho Receive my photo and detect faces on it - 1179. ActUpdMyPho Update my photo - 1180. ActReqRemMyPho Request the removal of my photo - 1181. ActRemMyPho Remove my photo + 1179. ActReqMyPho Show form to send my photo + 1180. ActDetMyPho Receive my photo and detect faces on it + 1181. ActUpdMyPho Update my photo + 1182. ActReqRemMyPho Request the removal of my photo + 1183. ActRemMyPho Remove my photo - 1182. ActEdiPri Edit my privacy - 1183. ActChgPriPho Change privacy of my photo - 1184. ActChgPriPrf Change privacy of my public profile + 1184. ActEdiPri Edit my privacy + 1185. ActChgPriPho Change privacy of my photo + 1186. ActChgPriPrf Change privacy of my public profile - 1185. ActReqEdiMyIns Request the edition of my institution, centre and department - 1186. ActChgCtyMyIns Change the country of my institution - 1187. ActChgMyIns Change my institution - 1188. ActChgMyCtr Change my centre - 1189. ActChgMyDpt Change my department - 1190. ActChgMyOff Change my office - 1191. ActChgMyOffPho Change my office phone + 1187. ActReqEdiMyIns Request the edition of my institution, centre and department + 1188. ActChgCtyMyIns Change the country of my institution + 1189. ActChgMyIns Change my institution + 1190. ActChgMyCtr Change my centre + 1191. ActChgMyDpt Change my department + 1192. ActChgMyOff Change my office + 1193. ActChgMyOffPho Change my office phone - 1192. ActReqEdiMyNet Request the edition of my social networks - 1193. ActChgMyNet Change my web and social networks + 1194. ActReqEdiMyNet Request the edition of my social networks + 1195. ActChgMyNet Change my web and social networks - 1194. ActChgThe Change theme - 1195. ActReqChgLan Ask if change language - 1196. ActChgLan Change language - 1197. ActChg1stDay Change first day of the week - 1198. ActChgCol Change side columns - 1119. ActHidLftCol Hide left side column - 1200. ActHidRgtCol Hide right side column - 1201. ActShoLftCol Show left side column - 1202. ActShoRgtCol Show right side column - 1203. ActChgIco Change icon set - 1204. ActChgMnu Change menu - 1205. ActChgNtfPrf Change whether to notify by email new messages - 1206. ActPrnUsrQR Show my QR code ready to print + 1196. ActChgThe Change theme + 1197. ActReqChgLan Ask if change language + 1198. ActChgLan Change language + 1199. ActChg1stDay Change first day of the week + 1200. ActChgCol Change side columns + 1201. ActHidLftCol Hide left side column + 1202. ActHidRgtCol Hide right side column + 1203. ActShoLftCol Show left side column + 1204. ActShoRgtCol Show right side column + 1205. ActChgIco Change icon set + 1206. ActChgMnu Change menu + 1207. ActChgNtfPrf Change whether to notify by email new messages + 1208. ActPrnUsrQR Show my QR code ready to print - 1207. ActPrnMyTT Show the timetable listo to impresión of all my courses - 1208. ActEdiTut Edit the timetable of tutorías - 1209. ActChgTut Modify the timetable of tutorías - 1210. ActChgMyTT1stDay Change first day of week and show timetable of the course + 1209. ActPrnMyTT Show the timetable listo to impresión of all my courses + 1210. ActEdiTut Edit the timetable of tutorías + 1211. ActChgTut Modify the timetable of tutorías + 1212. ActChgMyTT1stDay Change first day of week and show timetable of the course - 1211. ActReqRemFilBrf Request removal of a file of the briefcase - 1212. ActRemFilBrf Remove a file of the briefcase - 1213. ActRemFolBrf Remove a folder empty of the briefcase - 1214. ActCopBrf Set source of copy in the briefcase - 1215. ActPasBrf Paste a folder or file in the briefcase - 1216. ActRemTreBrf Remove a folder no empty of the briefcase - 1217. ActFrmCreBrf Form to crear a folder or file in the briefcase - 1218. ActCreFolBrf Create a new folder in the briefcase - 1219. ActCreLnkBrf Create a new link in the briefcase - 1220. ActRenFolBrf Rename a folder of the briefcase - 1221. ActRcvFilBrfDZ Receive a file in the briefcase using Dropzone.js - 1222. ActRcvFilBrfCla Receive a file in the briefcase using the classic way - 1223. ActExpBrf Expand a folder in briefcase - 1224. ActConBrf Contract a folder in briefcase - 1225. ActZIPBrf Compress a folder in briefcase - 1226. ActReqDatBrf Ask for metadata of a file in the briefcase - 1227. ActChgDatBrf Change metadata of a file in the briefcase - 1228. ActDowBrf Download a file in the briefcase - 1229. ActReqRemOldBrf Ask for removing old files in the briefcase - 1230. ActRemOldBrf Remove old files in the briefcase + 1213. ActReqRemFilBrf Request removal of a file of the briefcase + 1214. ActRemFilBrf Remove a file of the briefcase + 1215. ActRemFolBrf Remove a folder empty of the briefcase + 1216. ActCopBrf Set source of copy in the briefcase + 1217. ActPasBrf Paste a folder or file in the briefcase + 1218. ActRemTreBrf Remove a folder no empty of the briefcase + 1219. ActFrmCreBrf Form to crear a folder or file in the briefcase + 1220. ActCreFolBrf Create a new folder in the briefcase + 1221. ActCreLnkBrf Create a new link in the briefcase + 1222. ActRenFolBrf Rename a folder of the briefcase + 1223. ActRcvFilBrfDZ Receive a file in the briefcase using Dropzone.js + 1224. ActRcvFilBrfCla Receive a file in the briefcase using the classic way + 1225. ActExpBrf Expand a folder in briefcase + 1226. ActConBrf Contract a folder in briefcase + 1227. ActZIPBrf Compress a folder in briefcase + 1228. ActReqDatBrf Ask for metadata of a file in the briefcase + 1229. ActChgDatBrf Change metadata of a file in the briefcase + 1230. ActDowBrf Download a file in the briefcase + 1231. ActReqRemOldBrf Ask for removing old files in the briefcase + 1232. ActRemOldBrf Remove old files in the briefcase */ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = @@ -2792,12 +2794,14 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActAnnSee */{1234,-1,TabUnk,ActFrmRolSes ,0x1FE,0x1FE,0x1FE,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Ann_MarkAnnouncementAsSeen ,NULL}, /* ActChgMyRol */{ 589,-1,TabUnk,ActFrmRolSes ,0x1FE,0x1FE,0x1FE,Act_CONT_NORM,Act_THIS_WINDOW,Rol_ChangeMyRole ,Usr_ShowFormsLogoutAndRole ,NULL}, - /* ActEdiLoc */{1603,-1,TabUnk,ActSeeMyLoc ,0x100,0x100,0x100,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_EditLocations ,NULL}, - /* ActNewLoc */{1604,-1,TabUnk,ActSeeMyLoc ,0x100,0x100,0x100,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_RecFormNewLocation ,NULL}, - /* ActRemLoc */{1605,-1,TabUnk,ActSeeMyLoc ,0x100,0x100,0x100,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_RemoveLocation ,NULL}, - /* ActChgLocStrDat */{1606,-1,TabUnk,ActSeeMyLoc ,0x100,0x100,0x100,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_ChangeStartDate ,NULL}, - /* ActChgLocEndDat */{1607,-1,TabUnk,ActSeeMyLoc ,0x100,0x100,0x100,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_ChangeEndDate ,NULL}, - /* ActRenLoc */{1608,-1,TabUnk,ActSeeMyLoc ,0x100,0x100,0x100,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_RenameLocation ,NULL}, + /* ActFrmNewLoc */{1603,-1,TabUnk,ActSeeMyLoc ,0x100,0x100,0x000,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_RequestCreatOrEditLoc ,NULL}, + /* ActEdiOneLoc */{1604,-1,TabUnk,ActSeeMyLoc ,0x100,0x100,0x000,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_RequestCreatOrEditLoc ,NULL}, + /* ActNewLoc */{1605,-1,TabUnk,ActSeeMyLoc ,0x100,0x100,0x000,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_RecFormLocation ,NULL}, + /* ActChgLoc */{1606,-1,TabUnk,ActSeeMyLoc ,0x100,0x100,0x000,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_RecFormLocation ,NULL}, + /* ActReqRemLoc */{1607,-1,TabUnk,ActSeeMyLoc ,0x100,0x100,0x000,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_AskRemLocation ,NULL}, + /* ActRemLoc */{1608,-1,TabUnk,ActSeeMyLoc ,0x100,0x100,0x000,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_RemoveLocation ,NULL}, + /* ActHidLoc */{1609,-1,TabUnk,ActSeeMyLoc ,0x100,0x100,0x000,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_HideLocation ,NULL}, + /* ActShoLoc */{1610,-1,TabUnk,ActSeeMyLoc ,0x100,0x100,0x000,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_ShowLocation ,NULL}, /* ActChkUsrAcc */{1584,-1,TabUnk,ActFrmMyAcc ,0x1FF,0x1FF,0x1FF,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Acc_CheckIfEmptyAccountExists ,NULL}, /* ActCreUsrAcc */{1163,-1,TabUnk,ActFrmMyAcc ,0x1FF,0x1FF,0x1FF,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Acc_AfterCreationNewAccount ,NULL}, @@ -4491,12 +4495,14 @@ Act_Action_t Act_FromActCodToAction[1+Act_MAX_ACTION_COD] = // Do not reuse uniq ActRenCrsFulCfg, // #1600 ActRenCrsShoCfg, // #1601 ActSeeMyLoc, // #1602 - ActEdiLoc, // #1603 - ActNewLoc, // #1604 - ActRemLoc, // #1605 - ActChgLocStrDat, // #1606 - ActChgLocEndDat, // #1607 - ActRenLoc, // #1608 + ActFrmNewLoc, // #1603 + ActEdiOneLoc, // #1604 + ActNewLoc, // #1605 + ActChgLoc, // #1606 + ActReqRemLoc, // #1607 + ActRemLoc, // #1608 + ActHidLoc, // #1609 + ActShoLoc, // #1610 }; /*****************************************************************************/ diff --git a/swad_action.h b/swad_action.h index 482f58dcc..f2de761ea 100644 --- a/swad_action.h +++ b/swad_action.h @@ -55,9 +55,9 @@ typedef enum typedef int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action -#define Act_NUM_ACTIONS (1+9+51+14+93+73+70+249+186+155+172+36+31+92) +#define Act_NUM_ACTIONS (1+9+51+14+93+73+70+249+186+155+172+36+31+94) -#define Act_MAX_ACTION_COD 1608 +#define Act_MAX_ACTION_COD 1610 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 11 @@ -1381,90 +1381,92 @@ typedef int Act_Action_t; // Must be a signed type, because -1 is used to indica #define ActAutUsrChgLan (ActSeeMyUsgRep+16) #define ActAnnSee (ActSeeMyUsgRep+17) #define ActChgMyRol (ActSeeMyUsgRep+18) -#define ActEdiLoc (ActSeeMyUsgRep+19) -#define ActNewLoc (ActSeeMyUsgRep+20) -#define ActRemLoc (ActSeeMyUsgRep+21) -#define ActChgLocStrDat (ActSeeMyUsgRep+22) -#define ActChgLocEndDat (ActSeeMyUsgRep+23) -#define ActRenLoc (ActSeeMyUsgRep+24) -#define ActChkUsrAcc (ActSeeMyUsgRep+25) -#define ActCreUsrAcc (ActSeeMyUsgRep+26) -#define ActRemID_Me (ActSeeMyUsgRep+27) -#define ActNewIDMe (ActSeeMyUsgRep+28) -#define ActRemOldNic (ActSeeMyUsgRep+29) -#define ActChgNic (ActSeeMyUsgRep+30) -#define ActRemMaiMe (ActSeeMyUsgRep+31) -#define ActNewMaiMe (ActSeeMyUsgRep+32) -#define ActCnfMai (ActSeeMyUsgRep+33) -#define ActFrmChgMyPwd (ActSeeMyUsgRep+34) -#define ActChgPwd (ActSeeMyUsgRep+35) -#define ActReqRemMyAcc (ActSeeMyUsgRep+36) -#define ActRemMyAcc (ActSeeMyUsgRep+37) +#define ActFrmNewLoc (ActSeeMyUsgRep+19) +#define ActEdiOneLoc (ActSeeMyUsgRep+20) +#define ActNewLoc (ActSeeMyUsgRep+21) +#define ActChgLoc (ActSeeMyUsgRep+22) +#define ActReqRemLoc (ActSeeMyUsgRep+23) +#define ActRemLoc (ActSeeMyUsgRep+24) +#define ActHidLoc (ActSeeMyUsgRep+25) +#define ActShoLoc (ActSeeMyUsgRep+26) +#define ActChkUsrAcc (ActSeeMyUsgRep+27) +#define ActCreUsrAcc (ActSeeMyUsgRep+28) +#define ActRemID_Me (ActSeeMyUsgRep+29) +#define ActNewIDMe (ActSeeMyUsgRep+30) +#define ActRemOldNic (ActSeeMyUsgRep+31) +#define ActChgNic (ActSeeMyUsgRep+32) +#define ActRemMaiMe (ActSeeMyUsgRep+33) +#define ActNewMaiMe (ActSeeMyUsgRep+34) +#define ActCnfMai (ActSeeMyUsgRep+35) +#define ActFrmChgMyPwd (ActSeeMyUsgRep+36) +#define ActChgPwd (ActSeeMyUsgRep+37) +#define ActReqRemMyAcc (ActSeeMyUsgRep+38) +#define ActRemMyAcc (ActSeeMyUsgRep+39) -#define ActChgMyData (ActSeeMyUsgRep+38) +#define ActChgMyData (ActSeeMyUsgRep+40) -#define ActReqMyPho (ActSeeMyUsgRep+39) -#define ActDetMyPho (ActSeeMyUsgRep+40) -#define ActUpdMyPho (ActSeeMyUsgRep+41) -#define ActReqRemMyPho (ActSeeMyUsgRep+42) -#define ActRemMyPho (ActSeeMyUsgRep+43) +#define ActReqMyPho (ActSeeMyUsgRep+41) +#define ActDetMyPho (ActSeeMyUsgRep+42) +#define ActUpdMyPho (ActSeeMyUsgRep+43) +#define ActReqRemMyPho (ActSeeMyUsgRep+44) +#define ActRemMyPho (ActSeeMyUsgRep+45) -#define ActEdiPri (ActSeeMyUsgRep+44) -#define ActChgPriPho (ActSeeMyUsgRep+45) -#define ActChgPriPrf (ActSeeMyUsgRep+46) +#define ActEdiPri (ActSeeMyUsgRep+46) +#define ActChgPriPho (ActSeeMyUsgRep+47) +#define ActChgPriPrf (ActSeeMyUsgRep+48) -#define ActReqEdiMyIns (ActSeeMyUsgRep+47) -#define ActChgCtyMyIns (ActSeeMyUsgRep+48) -#define ActChgMyIns (ActSeeMyUsgRep+49) -#define ActChgMyCtr (ActSeeMyUsgRep+50) -#define ActChgMyDpt (ActSeeMyUsgRep+51) -#define ActChgMyOff (ActSeeMyUsgRep+52) -#define ActChgMyOffPho (ActSeeMyUsgRep+53) +#define ActReqEdiMyIns (ActSeeMyUsgRep+49) +#define ActChgCtyMyIns (ActSeeMyUsgRep+50) +#define ActChgMyIns (ActSeeMyUsgRep+51) +#define ActChgMyCtr (ActSeeMyUsgRep+52) +#define ActChgMyDpt (ActSeeMyUsgRep+53) +#define ActChgMyOff (ActSeeMyUsgRep+54) +#define ActChgMyOffPho (ActSeeMyUsgRep+55) -#define ActReqEdiMyNet (ActSeeMyUsgRep+54) -#define ActChgMyNet (ActSeeMyUsgRep+55) +#define ActReqEdiMyNet (ActSeeMyUsgRep+56) +#define ActChgMyNet (ActSeeMyUsgRep+57) -#define ActChgThe (ActSeeMyUsgRep+56) -#define ActReqChgLan (ActSeeMyUsgRep+57) -#define ActChgLan (ActSeeMyUsgRep+58) -#define ActChg1stDay (ActSeeMyUsgRep+59) -#define ActChgCol (ActSeeMyUsgRep+60) -#define ActHidLftCol (ActSeeMyUsgRep+61) -#define ActHidRgtCol (ActSeeMyUsgRep+62) -#define ActShoLftCol (ActSeeMyUsgRep+63) -#define ActShoRgtCol (ActSeeMyUsgRep+64) -#define ActChgIco (ActSeeMyUsgRep+65) -#define ActChgMnu (ActSeeMyUsgRep+66) -#define ActChgNtfPrf (ActSeeMyUsgRep+67) +#define ActChgThe (ActSeeMyUsgRep+58) +#define ActReqChgLan (ActSeeMyUsgRep+59) +#define ActChgLan (ActSeeMyUsgRep+60) +#define ActChg1stDay (ActSeeMyUsgRep+61) +#define ActChgCol (ActSeeMyUsgRep+62) +#define ActHidLftCol (ActSeeMyUsgRep+63) +#define ActHidRgtCol (ActSeeMyUsgRep+64) +#define ActShoLftCol (ActSeeMyUsgRep+65) +#define ActShoRgtCol (ActSeeMyUsgRep+66) +#define ActChgIco (ActSeeMyUsgRep+67) +#define ActChgMnu (ActSeeMyUsgRep+68) +#define ActChgNtfPrf (ActSeeMyUsgRep+69) -#define ActPrnUsrQR (ActSeeMyUsgRep+68) +#define ActPrnUsrQR (ActSeeMyUsgRep+70) -#define ActPrnMyTT (ActSeeMyUsgRep+69) -#define ActEdiTut (ActSeeMyUsgRep+70) -#define ActChgTut (ActSeeMyUsgRep+71) -#define ActChgMyTT1stDay (ActSeeMyUsgRep+72) +#define ActPrnMyTT (ActSeeMyUsgRep+71) +#define ActEdiTut (ActSeeMyUsgRep+72) +#define ActChgTut (ActSeeMyUsgRep+73) +#define ActChgMyTT1stDay (ActSeeMyUsgRep+74) -#define ActReqRemFilBrf (ActSeeMyUsgRep+73) -#define ActRemFilBrf (ActSeeMyUsgRep+74) -#define ActRemFolBrf (ActSeeMyUsgRep+75) -#define ActCopBrf (ActSeeMyUsgRep+76) -#define ActPasBrf (ActSeeMyUsgRep+77) -#define ActRemTreBrf (ActSeeMyUsgRep+78) -#define ActFrmCreBrf (ActSeeMyUsgRep+79) -#define ActCreFolBrf (ActSeeMyUsgRep+80) -#define ActCreLnkBrf (ActSeeMyUsgRep+81) -#define ActRenFolBrf (ActSeeMyUsgRep+82) -#define ActRcvFilBrfDZ (ActSeeMyUsgRep+83) -#define ActRcvFilBrfCla (ActSeeMyUsgRep+84) -#define ActExpBrf (ActSeeMyUsgRep+85) -#define ActConBrf (ActSeeMyUsgRep+86) -#define ActZIPBrf (ActSeeMyUsgRep+87) -#define ActReqDatBrf (ActSeeMyUsgRep+88) -#define ActChgDatBrf (ActSeeMyUsgRep+89) -#define ActDowBrf (ActSeeMyUsgRep+90) +#define ActReqRemFilBrf (ActSeeMyUsgRep+75) +#define ActRemFilBrf (ActSeeMyUsgRep+76) +#define ActRemFolBrf (ActSeeMyUsgRep+77) +#define ActCopBrf (ActSeeMyUsgRep+78) +#define ActPasBrf (ActSeeMyUsgRep+79) +#define ActRemTreBrf (ActSeeMyUsgRep+80) +#define ActFrmCreBrf (ActSeeMyUsgRep+81) +#define ActCreFolBrf (ActSeeMyUsgRep+82) +#define ActCreLnkBrf (ActSeeMyUsgRep+83) +#define ActRenFolBrf (ActSeeMyUsgRep+84) +#define ActRcvFilBrfDZ (ActSeeMyUsgRep+85) +#define ActRcvFilBrfCla (ActSeeMyUsgRep+86) +#define ActExpBrf (ActSeeMyUsgRep+87) +#define ActConBrf (ActSeeMyUsgRep+88) +#define ActZIPBrf (ActSeeMyUsgRep+89) +#define ActReqDatBrf (ActSeeMyUsgRep+90) +#define ActChgDatBrf (ActSeeMyUsgRep+91) +#define ActDowBrf (ActSeeMyUsgRep+92) -#define ActReqRemOldBrf (ActSeeMyUsgRep+91) -#define ActRemOldBrf (ActSeeMyUsgRep+92) +#define ActReqRemOldBrf (ActSeeMyUsgRep+93) +#define ActRemOldBrf (ActSeeMyUsgRep+94) /*****************************************************************************/ /******************************** Public types *******************************/ diff --git a/swad_changelog.h b/swad_changelog.h index 915fcc688..100cbd345 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -172,17 +172,23 @@ // TODO: List only confirmed emails to send a message with MESSAGES > Email ? +// TODO: When activating folders in groups, go to section for that type of group +// TODO: I can not remove a folder inside assignments (see swad.ugr.es -> EC -> assignment acanas) +// TODO: When teacher sees "No hay estudiantes", put a button to add students +// TODO: When admin sees "No hay profesores", put a button to add teachers + /*****************************************************************************/ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 16.76 (2016-11-29)" +#define Log_PLATFORM_VERSION "SWAD 16.77 (2016-11-29)" #define CSS_FILE "swad16.69.css" #define JS_FILE "swad16.46.1.js" // Number of lines (includes comments but not blank lines) has been got with the following command: // nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*?.h sql/swad*.sql | tail -1 /* + Version 16.77: Nov 29, 2016 Changes in location. Not finished. (209483 lines) Version 16.76: Nov 29, 2016 New form to create location. Not finished. (208936 lines) 8 changes necessary in database: CREATE TABLE IF NOT EXISTS locations (LocCod INT NOT NULL AUTO_INCREMENT,StartDate DATE NOT NULL,EndDate DATE NOT NULL,Location VARCHAR(255) NOT NULL,UNIQUE INDEX(LocCod)); diff --git a/swad_global.h b/swad_global.h index beb6cb0eb..9a6c6a7f1 100644 --- a/swad_global.h +++ b/swad_global.h @@ -357,11 +357,11 @@ struct Globals } MyCrss; struct { - bool LstIsRead; // Is the list already read from database, or it needs to be read? - unsigned Num; // Number of locations - struct Location *Lst; // List of locations - struct Location EditingLoc; - Loc_OrderType_t SelectedOrderType; + bool LstIsRead; // Is the list already read from database, or it needs to be read? + unsigned Num; // Number of locations + long *LstLocCods; // List of location codes + Loc_Order_t SelectedOrderType; + long LocCodToEdit; // Used as parameter in contextual links } Locs; Usr_ShowUsrsType_t ListType; // My preference about user's list type unsigned NumFollowers; // Number of users who follow me diff --git a/swad_help.c b/swad_help.c index 8a49d7a46..d3e79734b 100644 --- a/swad_help.c +++ b/swad_help.c @@ -227,8 +227,9 @@ const char *Hlp_PROFILE_Courses = WIKI "PROFILE.Courses"; const char *Hlp_PROFILE_Timetable = WIKI "PROFILE.Timetable"; -const char *Hlp_PROFILE_Location = WIKI "PROFILE.Location"; -const char *Hlp_PROFILE_Location_edit = WIKI "PROFILE.Location#edit"; +const char *Hlp_PROFILE_Location = WIKI "PROFILE.Location"; +const char *Hlp_PROFILE_Location_new_location = WIKI "PROFILE.Location#new-location"; +const char *Hlp_PROFILE_Location_edit_location = WIKI "PROFILE.Location#edit-location"; const char *Hlp_PROFILE_Record = WIKI "PROFILE.Record"; const char *Hlp_PROFILE_Institution = WIKI "PROFILE.Institution"; diff --git a/swad_location.c b/swad_location.c index cc1401291..85da4fe70 100644 --- a/swad_location.c +++ b/swad_location.c @@ -25,15 +25,20 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ +#include // For PATH_MAX #include // For NULL #include // For calloc #include // For string functions +#include "swad_location.h" #include "swad_database.h" #include "swad_global.h" -#include "swad_location.h" +#include "swad_group.h" +#include "swad_notification.h" +#include "swad_pagination.h" #include "swad_parameter.h" -#include "swad_text.h" +#include "swad_photo.h" +#include "swad_string.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ @@ -57,102 +62,374 @@ extern struct Globals Gbl; /***************************** Private prototypes ****************************/ /*****************************************************************************/ +static void Loc_ShowAllLocations (void); +static bool Loc_CheckIfICanCreateLocations (void); +static void Loc_PutIconsListLocations (void); +static void Loc_PutIconToCreateNewLoc (void); +static void Loc_PutButtonToCreateNewLoc (void); +static void Loc_PutParamsToCreateNewLoc (void); +static void Loc_ShowOneLocation (long LocCod); +static void Loc_WriteLocAuthor (struct Location *Loc); static void Loc_GetParamLocOrderType (void); -static void Loc_PutIconToEditLocs (void); -static void Loc_GetDataOfLocationByCod (struct Location *Loc); - -static void Loc_ListLocationsForEdition (void); +static void Loc_PutFormsToRemEditOneLoc (long LocCod,bool Hidden); +static void Loc_PutParams (void); +static void Loc_GetDataOfLocation (struct Location *Loc,const char *Query); +static void Loc_GetLocationTxtFromDB (long LocCod,char *Txt); static void Loc_PutParamLocCod (long LocCod); -static void Loc_ChangeDate (Loc_StartOrEndDate_t StartOrEndDate); -static void Loc_PutFormToCreateLocation (void); -static void Loc_PutHeadLocations (void); -static void Loc_CreateLocation (struct Location *Loc); +static bool Loc_CheckIfSimilarLocationExists (const char *Field,const char *Value,long LocCod); +static void Loc_UpdateNumUsrsNotifiedByEMailAboutLocation (long LocCod,unsigned NumUsrsToBeNotifiedByEMail); +static void Loc_CreateLocation (struct Location *Loc,const char *Txt); +static void Loc_UpdateLocation (struct Location *Loc,const char *Txt); +static bool Loc_CheckIfIBelongToCrsThisLocation (long LocCod); /*****************************************************************************/ -/*************************** List all my locations ***************************/ +/************************* List all the locations ****************************/ /*****************************************************************************/ void Loc_SeeLocations (void) + { + /***** Get parameters *****/ + Loc_GetParamLocOrderType (); + Grp_GetParamWhichGrps (); + Pag_GetParamPagNum (Pag_ASSIGNMENTS); + + /***** Show all the locations *****/ + Loc_ShowAllLocations (); + } + +/*****************************************************************************/ +/************************* Show all the locations ****************************/ +/*****************************************************************************/ + +static void Loc_ShowAllLocations (void) { extern const char *Hlp_PROFILE_Location; extern const char *Txt_Locations; - extern const char *Txt_LOCATIONS_HELP_ORDER[2]; - extern const char *Txt_LOCATIONS_ORDER[2]; + extern const char *Txt_ASG_ATT_OR_SVY_HELP_ORDER[2]; + extern const char *Txt_ASG_ATT_OR_SVY_ORDER[2]; extern const char *Txt_Location; - Loc_OrderType_t Order; + extern const char *Txt_Upload_files_QUESTION; + extern const char *Txt_Folder; + extern const char *Txt_No_locations; + Loc_Order_t Order; + struct Pagination Pagination; unsigned NumLoc; - /***** Get parameter with the type of order in the list of locations *****/ - Loc_GetParamLocOrderType (); - /***** Get list of locations *****/ Loc_GetListLocations (); - /***** Table head *****/ - Lay_StartRoundFrameTable (NULL,Txt_Locations, - Gbl.Usrs.Me.LoggedRole >= Rol_INS_ADM ? Loc_PutIconToEditLocs : - NULL, - Hlp_PROFILE_Location,2); - fprintf (Gbl.F.Out,""); - for (Order = Loc_ORDER_BY_START_DATE; - Order <= Loc_ORDER_BY_END_DATE; - Order++) - { - fprintf (Gbl.F.Out,""); - Act_FormStart (ActSeeMyLoc); - Par_PutHiddenParamUnsigned ("Order",(unsigned) Order); - Act_LinkFormSubmit (Txt_LOCATIONS_HELP_ORDER[Order],"TIT_TBL",NULL); - if (Order == Gbl.Usrs.Me.Locs.SelectedOrderType) - fprintf (Gbl.F.Out,""); - fprintf (Gbl.F.Out,"%s",Txt_LOCATIONS_ORDER[Order]); - if (Order == Gbl.Usrs.Me.Locs.SelectedOrderType) - fprintf (Gbl.F.Out,""); - fprintf (Gbl.F.Out,""); - Act_FormEnd (); - fprintf (Gbl.F.Out,""); - } - fprintf (Gbl.F.Out,"" - "%s" - "" - "", - Txt_Location); + /***** Compute variables related to pagination *****/ + Pagination.NumItems = Gbl.Usrs.Me.Locs.Num; + Pagination.CurrentPage = (int) Gbl.Pag.CurrentPage; + Pag_CalculatePagination (&Pagination); + Gbl.Pag.CurrentPage = (unsigned) Pagination.CurrentPage; - /***** Write all the locations *****/ - for (NumLoc = 0; - NumLoc < Gbl.Usrs.Me.Locs.Num; - NumLoc++) + /***** Write links to pages *****/ + if (Pagination.MoreThanOnePage) + Pag_WriteLinksToPagesCentered (Pag_ASSIGNMENTS,0,&Pagination); + + /***** Start frame *****/ + Lay_StartRoundFrame ("100%",Txt_Locations, + Loc_PutIconsListLocations,Hlp_PROFILE_Location); + + if (Gbl.Usrs.Me.Locs.Num) { - /* Write data of this location */ - fprintf (Gbl.F.Out,"" - "" - " %04u-%02u-%02u" - "", - Gbl.Usrs.Me.Locs.Lst[NumLoc].StartDate.Year, - Gbl.Usrs.Me.Locs.Lst[NumLoc].StartDate.Month, - Gbl.Usrs.Me.Locs.Lst[NumLoc].StartDate.Day); - fprintf (Gbl.F.Out,"" - " %04u-%02u-%02u" - "", - Gbl.Usrs.Me.Locs.Lst[NumLoc].EndDate.Year, - Gbl.Usrs.Me.Locs.Lst[NumLoc].EndDate.Month, - Gbl.Usrs.Me.Locs.Lst[NumLoc].EndDate.Day); - fprintf (Gbl.F.Out,"" - " %s" - "" + /***** Table head *****/ + fprintf (Gbl.F.Out,"" + ""); + for (Order = Loc_ORDER_BY_START_DATE; + Order <= Loc_ORDER_BY_END_DATE; + Order++) + { + fprintf (Gbl.F.Out,""); + } + fprintf (Gbl.F.Out,"" + "" + "" "", - Gbl.Usrs.Me.Locs.Lst[NumLoc].Location); - } + Txt_Location, + Txt_Upload_files_QUESTION, + Txt_Folder); - /***** End table *****/ - Lay_EndRoundFrameTable (); + /***** Write all the locations *****/ + for (NumLoc = Pagination.FirstItemVisible; + NumLoc <= Pagination.LastItemVisible; + NumLoc++) + Loc_ShowOneLocation (Gbl.Usrs.Me.Locs.LstLocCods[NumLoc - 1]); + + /***** End table *****/ + fprintf (Gbl.F.Out,"
"); + Act_FormStart (ActSeeMyLoc); + Grp_PutParamWhichGrps (); + Pag_PutHiddenParamPagNum (Gbl.Pag.CurrentPage); + Par_PutHiddenParamUnsigned ("Order",(unsigned) Order); + Act_LinkFormSubmit (Txt_ASG_ATT_OR_SVY_HELP_ORDER[Order],"TIT_TBL",NULL); + if (Order == Gbl.Usrs.Me.Locs.SelectedOrderType) + fprintf (Gbl.F.Out,""); + fprintf (Gbl.F.Out,"%s",Txt_ASG_ATT_OR_SVY_ORDER[Order]); + if (Order == Gbl.Usrs.Me.Locs.SelectedOrderType) + fprintf (Gbl.F.Out,""); + fprintf (Gbl.F.Out,""); + Act_FormEnd (); + fprintf (Gbl.F.Out,"" + "%s" + "" + "%s" + "" + "%s" + "
"); + } + else // No locations created + Lay_ShowAlert (Lay_INFO,Txt_No_locations); + + /***** Button to create a new location *****/ + if (Loc_CheckIfICanCreateLocations ()) + Loc_PutButtonToCreateNewLoc (); + + /***** End frame *****/ + Lay_EndRoundFrame (); + + /***** Write again links to pages *****/ + if (Pagination.MoreThanOnePage) + Pag_WriteLinksToPagesCentered (Pag_ASSIGNMENTS,0,&Pagination); /***** Free list of locations *****/ Loc_FreeListLocations (); } /*****************************************************************************/ -/********* Get parameter with the type or order in list of locations *********/ +/********************* Check if I can create locations ***********************/ +/*****************************************************************************/ + +static bool Loc_CheckIfICanCreateLocations (void) + { + return (bool) (Gbl.Usrs.Me.LoggedRole == Rol_TEACHER || + Gbl.Usrs.Me.LoggedRole == Rol_SYS_ADM); + } + +/*****************************************************************************/ +/**************** Put contextual icons in list of locations ******************/ +/*****************************************************************************/ + +static void Loc_PutIconsListLocations (void) + { + /***** Put icon to create a new location *****/ + if (Loc_CheckIfICanCreateLocations ()) + Loc_PutIconToCreateNewLoc (); + + /***** Put icon to show a figure *****/ + Gbl.Stat.FigureType = Sta_ASSIGNMENTS; + Sta_PutIconToShowFigure (); + } + +/*****************************************************************************/ +/******************** Put icon to create a new location **********************/ +/*****************************************************************************/ + +static void Loc_PutIconToCreateNewLoc (void) + { + extern const char *Txt_New_location; + + /***** Put form to create a new location *****/ + Lay_PutContextualLink (ActFrmNewLoc,Loc_PutParamsToCreateNewLoc, + "plus64x64.png", + Txt_New_location,NULL, + NULL); + } + +/*****************************************************************************/ +/******************* Put button to create a new location *********************/ +/*****************************************************************************/ + +static void Loc_PutButtonToCreateNewLoc (void) + { + extern const char *Txt_New_location; + + Act_FormStart (ActFrmNewLoc); + Loc_PutParamsToCreateNewLoc (); + Lay_PutConfirmButton (Txt_New_location); + Act_FormEnd (); + } + +/*****************************************************************************/ +/****************** Put parameters to create a new location ******************/ +/*****************************************************************************/ + +static void Loc_PutParamsToCreateNewLoc (void) + { + Loc_PutHiddenParamLocOrderType (); + Grp_PutParamWhichGrps (); + Pag_PutHiddenParamPagNum (Gbl.Pag.CurrentPage); + } + +/*****************************************************************************/ +/**************************** Show one location ******************************/ +/*****************************************************************************/ + +static void Loc_ShowOneLocation (long LocCod) + { + extern const char *Txt_Today; + extern const char *Txt_ASSIGNMENT_TYPES[Loc_NUM_TYPES_SEND_WORK]; + extern const char *Txt_Yes; + extern const char *Txt_No; + static unsigned UniqueId = 0; + struct Location Loc; + char Txt[Cns_MAX_BYTES_TEXT+1]; + + /***** Get data of this location *****/ + Loc.LocCod = LocCod; + Loc_GetDataOfLocationByCod (&Loc); + + /***** Write first row of data of this location *****/ + /* Start date/time */ + UniqueId++; + fprintf (Gbl.F.Out,"" + "" + "" + "", + UniqueId, + Loc.Hidden ? (Loc.Open ? "DATE_GREEN_LIGHT" : + "DATE_RED_LIGHT") : + (Loc.Open ? "DATE_GREEN" : + "DATE_RED"), + Gbl.RowEvenOdd, + UniqueId,Loc.TimeUTC[Loc_START_TIME],Txt_Today); + + /* End date/time */ + UniqueId++; + fprintf (Gbl.F.Out,"" + "" + "", + UniqueId, + Loc.Hidden ? (Loc.Open ? "DATE_GREEN_LIGHT" : + "DATE_RED_LIGHT") : + (Loc.Open ? "DATE_GREEN" : + "DATE_RED"), + Gbl.RowEvenOdd, + UniqueId,Loc.TimeUTC[Loc_END_TIME],Txt_Today); + + /* Location title */ + fprintf (Gbl.F.Out,"" + "
%s
", + Gbl.RowEvenOdd, + Loc.Hidden ? "ASG_TITLE_LIGHT" : + "ASG_TITLE", + Loc.Title); + fprintf (Gbl.F.Out,""); + + /* Send work? */ + fprintf (Gbl.F.Out,"" + "\"%s\"" + "
%s" + "", + (Loc.SendWork == Loc_SEND_WORK) ? "DAT_N" : + "DAT", + Gbl.RowEvenOdd, + Gbl.Prefs.IconsURL, + (Loc.SendWork == Loc_SEND_WORK) ? "file_on" : + "file_off", + Txt_ASSIGNMENT_TYPES[Loc.SendWork], + Txt_ASSIGNMENT_TYPES[Loc.SendWork], + (Loc.SendWork == Loc_SEND_WORK) ? Txt_Yes : + Txt_No); + + /***** Write second row of data of this location *****/ + fprintf (Gbl.F.Out,"" + "", + Gbl.RowEvenOdd); + + /* Author of the location */ + Loc_WriteLocAuthor (&Loc); + + /* Forms to remove/edit this location */ + switch (Gbl.Usrs.Me.LoggedRole) + { + case Rol_TEACHER: + case Rol_SYS_ADM: + Loc_PutFormsToRemEditOneLoc (Loc.LocCod,Loc.Hidden); + break; + default: + break; + } + fprintf (Gbl.F.Out,""); + + /* Text of the location */ + Loc_GetLocationTxtFromDB (Loc.LocCod,Txt); + Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, + Txt,Cns_MAX_BYTES_TEXT,false); // Convert from HTML to recpectful HTML + Str_InsertLinks (Txt,Cns_MAX_BYTES_TEXT,60); // Insert links + fprintf (Gbl.F.Out,"", + Gbl.RowEvenOdd); + + fprintf (Gbl.F.Out,"

" + "%s" + "

" + "" + "", + Loc.Hidden ? "DAT_LIGHT" : + "DAT", + Txt); + + Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd; + + /***** Mark possible notification as seen *****/ + Ntf_MarkNotifAsSeen (Ntf_EVENT_ASSIGNMENT, + LocCod,Gbl.CurrentCrs.Crs.CrsCod, + Gbl.Usrs.Me.UsrDat.UsrCod); + } + +/*****************************************************************************/ +/********************** Write the author of an location **********************/ +/*****************************************************************************/ + +static void Loc_WriteLocAuthor (struct Location *Loc) + { + bool ShowPhoto = false; + char PhotoURL[PATH_MAX+1]; + char FirstName[Usr_MAX_BYTES_NAME+1]; + char Surnames[2*(Usr_MAX_BYTES_NAME+1)]; + struct UsrData UsrDat; + + /***** Initialize structure with user's data *****/ + Usr_UsrDataConstructor (&UsrDat); + + /***** Get data of author *****/ + UsrDat.UsrCod = Loc->UsrCod; + if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat)) + ShowPhoto = Pho_ShowUsrPhotoIsAllowed (&UsrDat,PhotoURL); + + /***** Show photo *****/ + Pho_ShowUsrPhoto (&UsrDat,ShowPhoto ? PhotoURL : + NULL, + "PHOTO15x20",Pho_ZOOM,false); + + /***** Write name *****/ + strcpy (FirstName,UsrDat.FirstName); + strcpy (Surnames,UsrDat.Surname1); + if (UsrDat.Surname2[0]) + { + strcat (Surnames," "); + strcat (Surnames,UsrDat.Surname2); + } + Str_LimitLengthHTMLStr (FirstName,9); + Str_LimitLengthHTMLStr (Surnames,9); + fprintf (Gbl.F.Out,"%s %s", + Loc->Hidden ? "MSG_AUT_LIGHT" : + "MSG_AUT", + FirstName,Surnames); + + /***** Free memory used for user's data *****/ + Usr_UsrDataDestructor (&UsrDat); + } + +/*****************************************************************************/ +/******** Get parameter with the type or order in list of locations **********/ /*****************************************************************************/ static void Loc_GetParamLocOrderType (void) @@ -162,272 +439,326 @@ static void Loc_GetParamLocOrderType (void) Par_GetParToText ("Order",UnsignedStr,10); if (sscanf (UnsignedStr,"%u",&UnsignedNum) == 1) - Gbl.Usrs.Me.Locs.SelectedOrderType = (Loc_OrderType_t) UnsignedNum; + Gbl.Usrs.Me.Locs.SelectedOrderType = (Loc_Order_t) UnsignedNum; else Gbl.Usrs.Me.Locs.SelectedOrderType = Loc_DEFAULT_ORDER_TYPE; } /*****************************************************************************/ -/************************* Put icon to edit locations ************************/ +/**** Put a hidden parameter with the type of order in list of locations *****/ /*****************************************************************************/ -static void Loc_PutIconToEditLocs (void) +void Loc_PutHiddenParamLocOrderType (void) { + Par_PutHiddenParamUnsigned ("Order",(unsigned) Gbl.Usrs.Me.Locs.SelectedOrderType); + } + +/*****************************************************************************/ +/****************** Put a link (form) to edit one location *******************/ +/*****************************************************************************/ + +static void Loc_PutFormsToRemEditOneLoc (long LocCod,bool Hidden) + { + extern const char *Txt_Remove; + extern const char *Txt_Show; + extern const char *Txt_Hide; extern const char *Txt_Edit; - Lay_PutContextualLink (ActEdiLoc,NULL, + fprintf (Gbl.F.Out,"
"); + + Gbl.Usrs.Me.Locs.LocCodToEdit = LocCod; // Used as parameter in contextual links + + /***** Put form to remove location *****/ + Lay_PutContextualLink (ActReqRemLoc,Loc_PutParams, + "remove-on64x64.png", + Txt_Remove,NULL, + NULL); + + /***** Put form to hide/show location *****/ + if (Hidden) + Lay_PutContextualLink (ActShoLoc,Loc_PutParams, + "eye-slash-on64x64.png", + Txt_Show,NULL, + NULL); + else + Lay_PutContextualLink (ActHidLoc,Loc_PutParams, + "eye-on64x64.png", + Txt_Hide,NULL, + NULL); + + /***** Put form to edit location *****/ + Lay_PutContextualLink (ActEdiOneLoc,Loc_PutParams, "edit64x64.png", Txt_Edit,NULL, NULL); + + fprintf (Gbl.F.Out,"
"); } /*****************************************************************************/ -/************************ Put forms to edit degree types *********************/ +/********************* Params used to edit a location ************************/ /*****************************************************************************/ -void Loc_EditLocations (void) +static void Loc_PutParams (void) { - extern const char *Txt_There_are_no_locations; - - /***** Get list of places *****/ - Plc_GetListPlaces (); - - /***** Get list of locations *****/ - Loc_GetListLocations (); - - if (!Gbl.Usrs.Me.Locs.Num) - /***** Help message *****/ - Lay_ShowAlert (Lay_INFO,Txt_There_are_no_locations); - - /***** Put a form to create a new location *****/ - Loc_PutFormToCreateLocation (); - - /***** Forms to edit current locations *****/ - if (Gbl.Usrs.Me.Locs.Num) - Loc_ListLocationsForEdition (); - - /***** Free list of locations *****/ - Loc_FreeListLocations (); - - /***** Free list of places *****/ - Plc_FreeListPlaces (); + Loc_PutParamLocCod (Gbl.Usrs.Me.Locs.LocCodToEdit); + Loc_PutHiddenParamLocOrderType (); + Grp_PutParamWhichGrps (); + Pag_PutHiddenParamPagNum (Gbl.Pag.CurrentPage); } /*****************************************************************************/ -/*************************** List all the locations **************************/ +/************************* List all the locations ****************************/ /*****************************************************************************/ void Loc_GetListLocations (void) { + char HiddenSubQuery[256]; char OrderBySubQuery[256]; - char Query[512]; + char Query[2048]; MYSQL_RES *mysql_res; MYSQL_ROW row; + unsigned long NumRows; unsigned NumLoc; - struct Location *Loc; - if (Gbl.DB.DatabaseIsOpen) + if (Gbl.Usrs.Me.Locs.LstIsRead) + Loc_FreeListLocations (); + + /***** Get list of locations from database *****/ + switch (Gbl.Usrs.Me.LoggedRole) { - if (Gbl.Usrs.Me.Locs.LstIsRead) - Loc_FreeListLocations (); - - /***** Get locations from database *****/ - switch (Gbl.Usrs.Me.Locs.SelectedOrderType) - { - case Loc_ORDER_BY_START_DATE: - sprintf (OrderBySubQuery,"StartDate,EndDate,Location"); - break; - case Loc_ORDER_BY_END_DATE: - sprintf (OrderBySubQuery,"EndDate,StartDate,Location"); - break; - } - sprintf (Query,"SELECT LocCod," - "DATE_FORMAT(StartDate,'%%Y%%m%%d') AS StartDate," - "DATE_FORMAT(EndDate,'%%Y%%m%%d') AS EndDate," - "Location" - " FROM locations" - " ORDER BY %s", - OrderBySubQuery); - if ((Gbl.Usrs.Me.Locs.Num = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get locations"))) // Locations found... - { - /***** Create list of locations *****/ - if ((Gbl.Usrs.Me.Locs.Lst = (struct Location *) calloc ((size_t) Gbl.Usrs.Me.Locs.Num,sizeof (struct Location))) == NULL) - Lay_ShowErrorAndExit ("Not enough memory to store locations."); - - /***** Get the locations *****/ - for (NumLoc = 0; - NumLoc < Gbl.Usrs.Me.Locs.Num; - NumLoc++) - { - Loc = &(Gbl.Usrs.Me.Locs.Lst[NumLoc]); - - /* Get next location */ - row = mysql_fetch_row (mysql_res); - - /* Get location code (row[0]) */ - if ((Loc->LocCod = Str_ConvertStrCodToLongCod (row[0])) < 0) - Lay_ShowErrorAndExit ("Wrong location code."); - - /* Get start date (row[1] holds the start date in YYYYMMDD format) */ - if (!(Dat_GetDateFromYYYYMMDD (&(Loc->StartDate),row[1]))) - Lay_ShowErrorAndExit ("Wrong start date."); - - /* Get end date (row[2] holds the end date in YYYYMMDD format) */ - if (!(Dat_GetDateFromYYYYMMDD (&(Loc->EndDate),row[2]))) - Lay_ShowErrorAndExit ("Wrong end date."); - - /* Get the location (row[3]) */ - strcpy (Loc->Location,row[3]); - } - } - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - - Gbl.Usrs.Me.Locs.LstIsRead = true; + case Rol_TEACHER: + case Rol_SYS_ADM: + HiddenSubQuery[0] = '\0'; + break; + default: + sprintf (HiddenSubQuery,"AND Hidden='N'"); + break; } + switch (Gbl.Usrs.Me.Locs.SelectedOrderType) + { + case Loc_ORDER_BY_START_DATE: + sprintf (OrderBySubQuery,"StartTime DESC,EndTime DESC,Title DESC"); + break; + case Loc_ORDER_BY_END_DATE: + sprintf (OrderBySubQuery,"EndTime DESC,StartTime DESC,Title DESC"); + break; + } + sprintf (Query,"SELECT LocCod" + " FROM locations" + " WHERE CrsCod='%ld'%s" + " ORDER BY %s", + Gbl.CurrentCrs.Crs.CrsCod,HiddenSubQuery,OrderBySubQuery); + NumRows = DB_QuerySELECT (Query,&mysql_res,"can not get locations"); + + if (NumRows) // Locations found... + { + Gbl.Usrs.Me.Locs.Num = (unsigned) NumRows; + + /***** Create list of locations *****/ + if ((Gbl.Usrs.Me.Locs.LstLocCods = (long *) calloc (NumRows,sizeof (long))) == NULL) + Lay_ShowErrorAndExit ("Not enough memory to store list of locations."); + + /***** Get the locations codes *****/ + for (NumLoc = 0; + NumLoc < Gbl.Usrs.Me.Locs.Num; + NumLoc++) + { + /* Get next location code */ + row = mysql_fetch_row (mysql_res); + if ((Gbl.Usrs.Me.Locs.LstLocCods[NumLoc] = Str_ConvertStrCodToLongCod (row[0])) < 0) + Lay_ShowErrorAndExit ("Error: wrong location code."); + } + } + else + Gbl.Usrs.Me.Locs.Num = 0; + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + + Gbl.Usrs.Me.Locs.LstIsRead = true; } /*****************************************************************************/ -/************************* Get location data by code *************************/ +/******************** Get location data using its code ***********************/ /*****************************************************************************/ -static void Loc_GetDataOfLocationByCod (struct Location *Loc) +void Loc_GetDataOfLocationByCod (struct Location *Loc) { char Query[1024]; + + /***** Build query *****/ + sprintf (Query,"SELECT LocCod,Hidden,UsrCod," + "UNIX_TIMESTAMP(StartTime)," + "UNIX_TIMESTAMP(EndTime)," + "NOW() BETWEEN StartTime AND EndTime," + "Title,Folder" + " FROM locations" + " WHERE LocCod='%ld' AND CrsCod='%ld'", + Loc->LocCod,Gbl.CurrentCrs.Crs.CrsCod); + + /***** Get data of location *****/ + Loc_GetDataOfLocation (Loc,Query); + } + +/*****************************************************************************/ +/*************************** Get location data *******************************/ +/*****************************************************************************/ + +static void Loc_GetDataOfLocation (struct Location *Loc,const char *Query) + { MYSQL_RES *mysql_res; MYSQL_ROW row; + unsigned long NumRows; - /***** Clear data *****/ - Loc->StartDate.Day = - Loc->StartDate.Month = - Loc->StartDate.Year = 0; - Loc->Location[0] = '\0'; - - /***** Check if location code is correct *****/ - if (Loc->LocCod <= 0) - Lay_ShowErrorAndExit ("Wrong code of location."); + /***** Clear all location data *****/ + Loc->LocCod = -1L; + Loc->Hidden = false; + Loc->UsrCod = -1L; + Loc->TimeUTC[Loc_START_TIME] = + Loc->TimeUTC[Loc_END_TIME ] = (time_t) 0; + Loc->Open = false; + Loc->Title[0] = '\0'; + Loc->SendWork = false; + Loc->Folder[0] = '\0'; + Loc->IBelongToCrsOrGrps = false; /***** Get data of location from database *****/ - sprintf (Query,"SELECT " - "DATE_FORMAT(StartDate,'%%Y%%m%%d')," - "DATE_FORMAT(EndDate,'%%Y%%m%%d')," - "Location" - " FROM locations" - " WHERE LocCod='%ld'", - Loc->LocCod); - if (DB_QuerySELECT (Query,&mysql_res,"can not get data of a location")) // Location found... + NumRows = DB_QuerySELECT (Query,&mysql_res,"can not get location data"); + + if (NumRows) // Location found... { /* Get row */ row = mysql_fetch_row (mysql_res); - /* Get start date (row[0] holds the start date in YYYYMMDD format) */ - if (!(Dat_GetDateFromYYYYMMDD (&(Loc->StartDate),row[0]))) - Lay_ShowErrorAndExit ("Wrong start date."); + /* Get code of the location (row[0]) */ + Loc->LocCod = Str_ConvertStrCodToLongCod (row[0]); - /* Get end date (row[1] holds the end date in YYYYMMDD format) */ - if (!(Dat_GetDateFromYYYYMMDD (&(Loc->EndDate),row[1]))) - Lay_ShowErrorAndExit ("Wrong end date."); + /* Get whether the location is hidden or not (row[1]) */ + Loc->Hidden = (row[1][0] == 'Y'); - /* Get the location (row[2]) */ - strcpy (Loc->Location,row[2]); + /* Get author of the location (row[2]) */ + Loc->UsrCod = Str_ConvertStrCodToLongCod (row[2]); + + /* Get start date (row[3] holds the start UTC time) */ + Loc->TimeUTC[Loc_START_TIME] = Dat_GetUNIXTimeFromStr (row[3]); + + /* Get end date (row[4] holds the end UTC time) */ + Loc->TimeUTC[Loc_END_TIME ] = Dat_GetUNIXTimeFromStr (row[4]); + + /* Get whether the location is open or closed (row(5)) */ + Loc->Open = (row[5][0] == '1'); + + /* Get the title of the location (row[6]) */ + strcpy (Loc->Title,row[6]); + + /* Get the folder for the location files (row[7]) */ + strcpy (Loc->Folder,row[7]); + Loc->SendWork = (Loc->Folder[0] != '\0'); + + /* Can I do this location? */ + Loc->IBelongToCrsOrGrps = Loc_CheckIfIBelongToCrsThisLocation (Loc->LocCod); } - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); } /*****************************************************************************/ -/**************************** Free list of locations *************************/ +/************************** Free list of locations ***************************/ /*****************************************************************************/ void Loc_FreeListLocations (void) { - if (Gbl.Usrs.Me.Locs.LstIsRead && Gbl.Usrs.Me.Locs.Lst) + if (Gbl.Usrs.Me.Locs.LstIsRead && Gbl.Usrs.Me.Locs.LstLocCods) { - /***** Free memory used by the list of courses in degree *****/ - free ((void *) Gbl.Usrs.Me.Locs.Lst); - Gbl.Usrs.Me.Locs.Lst = NULL; + /***** Free memory used by the list of locations *****/ + free ((void *) Gbl.Usrs.Me.Locs.LstLocCods); + Gbl.Usrs.Me.Locs.LstLocCods = NULL; Gbl.Usrs.Me.Locs.Num = 0; Gbl.Usrs.Me.Locs.LstIsRead = false; } } /*****************************************************************************/ -/********************* List all the locations for edition ********************/ +/********************* Get location text from database ***********************/ /*****************************************************************************/ -static void Loc_ListLocationsForEdition (void) +static void Loc_GetLocationTxtFromDB (long LocCod,char *Txt) { - extern const char *Hlp_PROFILE_Location_edit; - extern const char *Txt_Locations; - unsigned NumLoc; - struct Location *Loc; + char Query[512]; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned long NumRows; - Lay_StartRoundFrameTable (NULL,Txt_Locations, - NULL,Hlp_PROFILE_Location_edit,2); + /***** Get text of location from database *****/ + sprintf (Query,"SELECT Txt FROM locations" + " WHERE LocCod='%ld' AND CrsCod='%ld'", + LocCod,Gbl.CurrentCrs.Crs.CrsCod); + NumRows = DB_QuerySELECT (Query,&mysql_res,"can not get location text"); - /***** Table head *****/ - Loc_PutHeadLocations (); - - /***** Write all the locations *****/ - for (NumLoc = 0; - NumLoc < Gbl.Usrs.Me.Locs.Num; - NumLoc++) + /***** The result of the query must have one row or none *****/ + if (NumRows == 1) { - Loc = &Gbl.Usrs.Me.Locs.Lst[NumLoc]; - - /* Put icon to remove location */ - fprintf (Gbl.F.Out,"" - ""); - Act_FormStart (ActRemLoc); - Loc_PutParamLocCod (Loc->LocCod); - Lay_PutIconRemove (); - Act_FormEnd (); - fprintf (Gbl.F.Out,""); - - /* Location start date */ - fprintf (Gbl.F.Out,""); - Act_FormStart (ActChgLocStrDat); - Loc_PutParamLocCod (Loc->LocCod); - Dat_WriteFormDate (Gbl.Now.Date.Year - 1, - Gbl.Now.Date.Year + 1, - "Start", - &(Gbl.Usrs.Me.Locs.Lst[NumLoc].StartDate), - true,false); - Act_FormEnd (); - fprintf (Gbl.F.Out,""); - - /* Location end date */ - fprintf (Gbl.F.Out,""); - Act_FormStart (ActChgLocEndDat); - Loc_PutParamLocCod (Loc->LocCod); - Dat_WriteFormDate (Gbl.Now.Date.Year - 1, - Gbl.Now.Date.Year + 1, - "End", - &(Gbl.Usrs.Me.Locs.Lst[NumLoc].EndDate), - true,false); - Act_FormEnd (); - fprintf (Gbl.F.Out,""); - - /* Location */ - fprintf (Gbl.F.Out,""); - Act_FormStart (ActRenLoc); - Loc_PutParamLocCod (Loc->LocCod); - fprintf (Gbl.F.Out,"", - Loc_MAX_LENGTH_LOCATION,Loc->Location,Gbl.Form.Id); - Act_FormEnd (); - fprintf (Gbl.F.Out,"" - ""); + /* Get info text */ + row = mysql_fetch_row (mysql_res); + strcpy (Txt,row[0]); } + else + Txt[0] = '\0'; - Lay_EndRoundFrameTable (); + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + + if (NumRows > 1) + Lay_ShowErrorAndExit ("Error when getting location text."); } /*****************************************************************************/ -/******************** Write parameter with code of location ******************/ +/****************** Get summary and content of a location *******************/ +/*****************************************************************************/ +// This function may be called inside a web service + +void Loc_GetNotifLocation (char *SummaryStr,char **ContentStr, + long LocCod,unsigned MaxChars,bool GetContent) + { + char Query[512]; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + + SummaryStr[0] = '\0'; // Return nothing on error + + /***** Build query *****/ + sprintf (Query,"SELECT Title,Txt FROM locations WHERE LocCod='%ld'", + LocCod); + if (!mysql_query (&Gbl.mysql,Query)) + if ((mysql_res = mysql_store_result (&Gbl.mysql)) != NULL) + { + /***** Result should have a unique row *****/ + if (mysql_num_rows (mysql_res) == 1) + { + /***** Get row *****/ + row = mysql_fetch_row (mysql_res); + + /***** Get summary *****/ + strcpy (SummaryStr,row[0]); + if (MaxChars) + Str_LimitLengthHTMLStr (SummaryStr,MaxChars); + + /***** Get content *****/ + if (GetContent) + { + if ((*ContentStr = (char *) malloc (512+Cns_MAX_BYTES_TEXT)) == NULL) + Lay_ShowErrorAndExit ("Error allocating memory for notification content."); + strcpy (*ContentStr,row[1]); + } + } + mysql_free_result (mysql_res); + } + } + +/*****************************************************************************/ +/****************** Write parameter with code of location ********************/ /*****************************************************************************/ static void Loc_PutParamLocCod (long LocCod) @@ -436,7 +767,7 @@ static void Loc_PutParamLocCod (long LocCod) } /*****************************************************************************/ -/********************* Get parameter with code of location *******************/ +/******************* Get parameter with code of location *********************/ /*****************************************************************************/ long Loc_GetParamLocCod (void) @@ -449,13 +780,88 @@ long Loc_GetParamLocCod (void) } /*****************************************************************************/ -/******************************* Remove a location ***************************/ +/************* Ask for confirmation of removing of a location ****************/ +/*****************************************************************************/ + +void Loc_AskRemLocation (void) + { + extern const char *Txt_Do_you_really_want_to_remove_the_location_X; + extern const char *Txt_Remove_location; + struct Location Loc; + + /***** Get parameters *****/ + Loc_GetParamLocOrderType (); + Grp_GetParamWhichGrps (); + Pag_GetParamPagNum (Pag_ASSIGNMENTS); + + /***** Get location code *****/ + if ((Loc.LocCod = Loc_GetParamLocCod ()) == -1L) + Lay_ShowErrorAndExit ("Code of location is missing."); + + /***** Get data of the location from database *****/ + Loc_GetDataOfLocationByCod (&Loc); + + /***** Button of confirmation of removing *****/ + Act_FormStart (ActRemLoc); + Loc_PutParamLocCod (Loc.LocCod); + Loc_PutHiddenParamLocOrderType (); + Grp_PutParamWhichGrps (); + Pag_PutHiddenParamPagNum (Gbl.Pag.CurrentPage); + + /***** Ask for confirmation of removing *****/ + sprintf (Gbl.Message,Txt_Do_you_really_want_to_remove_the_location_X, + Loc.Title); + Lay_ShowAlert (Lay_WARNING,Gbl.Message); + Lay_PutRemoveButton (Txt_Remove_location); + Act_FormEnd (); + + /***** Show locations again *****/ + Loc_SeeLocations (); + } + +/*****************************************************************************/ +/***************************** Remove a location *****************************/ /*****************************************************************************/ void Loc_RemoveLocation (void) { - extern const char *Txt_Location_removed; - char Query[128]; + extern const char *Txt_Location_X_removed; + char Query[512]; + struct Location Loc; + + /***** Get location code *****/ + if ((Loc.LocCod = Loc_GetParamLocCod ()) == -1L) + Lay_ShowErrorAndExit ("Code of location is missing."); + + /***** Get data of the location from database *****/ + Loc_GetDataOfLocationByCod (&Loc); // Inside this function, the course is checked to be the current one + + /***** Remove location *****/ + sprintf (Query,"DELETE FROM locations" + " WHERE LocCod='%ld' AND CrsCod='%ld'", + Loc.LocCod,Gbl.CurrentCrs.Crs.CrsCod); + DB_QueryDELETE (Query,"can not remove location"); + + /***** Mark possible notifications as removed *****/ + Ntf_MarkNotifAsRemoved (Ntf_EVENT_ASSIGNMENT,Loc.LocCod); + + /***** Write message to show the change made *****/ + sprintf (Gbl.Message,Txt_Location_X_removed, + Loc.Title); + Lay_ShowAlert (Lay_SUCCESS,Gbl.Message); + + /***** Show locations again *****/ + Loc_SeeLocations (); + } + +/*****************************************************************************/ +/****************************** Hide a location ******************************/ +/*****************************************************************************/ + +void Loc_HideLocation (void) + { + extern const char *Txt_Location_X_is_now_hidden; + char Query[512]; struct Location Loc; /***** Get location code *****/ @@ -465,311 +871,583 @@ void Loc_RemoveLocation (void) /***** Get data of the location from database *****/ Loc_GetDataOfLocationByCod (&Loc); - /***** Remove location *****/ - sprintf (Query,"DELETE FROM locations WHERE LocCod='%ld'",Loc.LocCod); - DB_QueryDELETE (Query,"can not remove a location"); + /***** Hide location *****/ + sprintf (Query,"UPDATE locations SET Hidden='Y'" + " WHERE LocCod='%ld' AND CrsCod='%ld'", + Loc.LocCod,Gbl.CurrentCrs.Crs.CrsCod); + DB_QueryUPDATE (Query,"can not hide location"); /***** Write message to show the change made *****/ - sprintf (Gbl.Message,Txt_Location_removed,Loc.Location); + sprintf (Gbl.Message,Txt_Location_X_is_now_hidden, + Loc.Title); Lay_ShowAlert (Lay_SUCCESS,Gbl.Message); - /***** Show the form again *****/ - Loc_EditLocations (); + /***** Show locations again *****/ + Loc_SeeLocations (); } /*****************************************************************************/ -/******************* Change the start date of a location *********************/ +/****************************** Show a location ******************************/ /*****************************************************************************/ -void Loc_ChangeStartDate (void) +void Loc_ShowLocation (void) { - Loc_ChangeDate (LOC_START_DATE); - } - -/*****************************************************************************/ -/******************** Change the end date of a location **********************/ -/*****************************************************************************/ - -void Loc_ChangeEndDate (void) - { - Loc_ChangeDate (LOC_END_DATE); - } - -/*****************************************************************************/ -/**************** Change the start/end date of a location ********************/ -/*****************************************************************************/ - -static void Loc_ChangeDate (Loc_StartOrEndDate_t StartOrEndDate) - { - extern const char *Txt_The_date_of_the_location_has_changed_to_X; + extern const char *Txt_Location_X_is_now_visible; char Query[512]; - struct Location *Loc; - struct Date NewDate; - struct Date *PtrDate = NULL; // Initialized to avoid warning - const char *StrStartOrEndDate; - char StrDate[11]; + struct Location Loc; - Loc = &Gbl.Usrs.Me.Locs.EditingLoc; + /***** Get location code *****/ + if ((Loc.LocCod = Loc_GetParamLocCod ()) == -1L) + Lay_ShowErrorAndExit ("Code of location is missing."); + + /***** Get data of the location from database *****/ + Loc_GetDataOfLocationByCod (&Loc); + + /***** Hide location *****/ + sprintf (Query,"UPDATE locations SET Hidden='N'" + " WHERE LocCod='%ld' AND CrsCod='%ld'", + Loc.LocCod,Gbl.CurrentCrs.Crs.CrsCod); + DB_QueryUPDATE (Query,"can not show location"); + + /***** Write message to show the change made *****/ + sprintf (Gbl.Message,Txt_Location_X_is_now_visible, + Loc.Title); + Lay_ShowAlert (Lay_SUCCESS,Gbl.Message); + + /***** Show locations again *****/ + Loc_SeeLocations (); + } + +/*****************************************************************************/ +/********* Check if the title or the folder of an location exists ************/ +/*****************************************************************************/ + +static bool Loc_CheckIfSimilarLocationExists (const char *Field,const char *Value,long LocCod) + { + char Query[512]; + + /***** Get number of locations with a field value from database *****/ + sprintf (Query,"SELECT COUNT(*) FROM locations" + " WHERE CrsCod='%ld' AND %s='%s' AND LocCod<>'%ld'", + Gbl.CurrentCrs.Crs.CrsCod,Field,Value,LocCod); + return (DB_QueryCOUNT (Query,"can not get similar locations") != 0); + } + +/*****************************************************************************/ +/******************* Put a form to create a new location *********************/ +/*****************************************************************************/ + +void Loc_RequestCreatOrEditLoc (void) + { + extern const char *Hlp_PROFILE_Location_new_location; + extern const char *Hlp_PROFILE_Location_edit_location; + extern const char *The_ClassForm[The_NUM_THEMES]; + extern const char *Txt_New_location; + extern const char *Txt_Edit_location; + extern const char *Txt_Title; + extern const char *Txt_Upload_files_QUESTION; + extern const char *Txt_Folder; + extern const char *Txt_Description; + extern const char *Txt_Create_location; + extern const char *Txt_Save; + struct Location Loc; + bool ItsANewLocation; + char Txt[Cns_MAX_BYTES_TEXT+1]; + + /***** Get parameters *****/ + Loc_GetParamLocOrderType (); + Grp_GetParamWhichGrps (); + Pag_GetParamPagNum (Pag_ASSIGNMENTS); /***** Get the code of the location *****/ - if ((Loc->LocCod = Loc_GetParamLocCod ()) == -1L) - Lay_ShowErrorAndExit ("Code of location is missing."); + ItsANewLocation = ((Loc.LocCod = Loc_GetParamLocCod ()) == -1L); /***** Get from the database the data of the location *****/ - Loc_GetDataOfLocationByCod (Loc); - - /***** Get the new date for the location *****/ - switch (StartOrEndDate) + if (ItsANewLocation) { - case LOC_START_DATE: - StrStartOrEndDate = "StartDate"; - PtrDate = &(Loc->StartDate); - Dat_GetDateFromForm ("StartDay","StartMonth","StartYear", - &(NewDate.Day),&(NewDate.Month),&(NewDate.Year)); - if (NewDate.Day == 0 || - NewDate.Month == 0 || - NewDate.Year == 0) - Dat_AssignDate (&NewDate,&Gbl.Now.Date); - break; - case LOC_END_DATE: - StrStartOrEndDate = "EndDate"; - PtrDate = &(Loc->EndDate); - Dat_GetDateFromForm ("EndDay","EndMonth","EndYear", - &(NewDate.Day),&(NewDate.Month),&(NewDate.Year)); - if (NewDate.Day == 0 || - NewDate.Month == 0 || - NewDate.Year == 0) - Dat_AssignDate (&NewDate,&Gbl.Now.Date); - break; + /* Initialize to empty location */ + Loc.LocCod = -1L; + Loc.TimeUTC[Loc_START_TIME] = Gbl.StartExecutionTimeUTC; + Loc.TimeUTC[Loc_END_TIME ] = Gbl.StartExecutionTimeUTC + (2 * 60 * 60); // +2 hours + Loc.Open = true; + Loc.Title[0] = '\0'; + Loc.SendWork = false; + Loc.Folder[0] = '\0'; + Loc.IBelongToCrsOrGrps = false; } - - /***** Update the date in database *****/ - sprintf (Query,"UPDATE locations SET %s='%04u%02u%02u' WHERE LocCod='%ld'", - StrStartOrEndDate, - NewDate.Year, - NewDate.Month, - NewDate.Day, - Loc->LocCod); - DB_QueryUPDATE (Query,"can not update the date of a location"); - - /***** Write message to show the change made *****/ - sprintf (StrDate,"%04u-%02u-%02u", - NewDate.Year,NewDate.Month,NewDate.Day); // Change format depending on location - sprintf (Gbl.Message,Txt_The_date_of_the_location_has_changed_to_X,StrDate); - Lay_ShowAlert (Lay_SUCCESS,Gbl.Message); - - /***** Show the form again *****/ - Dat_AssignDate (PtrDate,&NewDate); - Loc_EditLocations (); - } - -/*****************************************************************************/ -/***************************** Rename the location ***************************/ -/*****************************************************************************/ - -void Loc_RenameLocation (void) - { - extern const char *Txt_You_can_not_leave_the_location_empty; - extern const char *Txt_The_location_has_changed_to_X; - extern const char *Txt_The_location_has_not_changed; - char Query[512]; - struct Location *Loc; - char NewLoc[Loc_MAX_LENGTH_LOCATION+1]; - - Loc = &Gbl.Usrs.Me.Locs.EditingLoc; - - /***** Get parameters from form *****/ - /* Get the code of the location */ - if ((Loc->LocCod = Loc_GetParamLocCod ()) == -1L) - Lay_ShowErrorAndExit ("Code of location is missing."); - - /* Get the new location */ - Par_GetParToText ("Location",NewLoc,Loc_MAX_LENGTH_LOCATION); - - /***** Get from the database the old location *****/ - Loc_GetDataOfLocationByCod (Loc); - - /***** Check if new location is empty *****/ - if (!NewLoc[0]) - Lay_ShowAlert (Lay_WARNING,Txt_You_can_not_leave_the_location_empty); else { - /***** Check if old and new locations are the same - (this happens when user press enter - with no changes in the form) *****/ - if (strcmp (Loc->Location,NewLoc)) // Different locations - { - /***** If degree was in database... *****/ - /* Update the table changing old location by new location */ - sprintf (Query,"UPDATE locations SET Location='%s' WHERE LocCod='%ld'", - NewLoc,Loc->LocCod); - DB_QueryUPDATE (Query,"can not update the location"); + /* Get data of the location from database */ + Loc_GetDataOfLocationByCod (&Loc); - /***** Write message to show the change made *****/ - sprintf (Gbl.Message,Txt_The_location_has_changed_to_X,NewLoc); - Lay_ShowAlert (Lay_SUCCESS,Gbl.Message); - } - else // The same location - Lay_ShowAlert (Lay_INFO,Txt_The_location_has_not_changed); + /* Get text of the location from database */ + Loc_GetLocationTxtFromDB (Loc.LocCod,Txt); } - /***** Show the form again *****/ - strcpy (Loc->Location,NewLoc); - Loc_EditLocations (); - } - -/*****************************************************************************/ -/********************* Put a form to create a new location *******************/ -/*****************************************************************************/ - -static void Loc_PutFormToCreateLocation (void) - { - extern const char *Hlp_PROFILE_Location_edit; - extern const char *Txt_New_location; - extern const char *Txt_Create_location; - struct Location *Loc; - - Loc = &Gbl.Usrs.Me.Locs.EditingLoc; - /***** Start form *****/ - Act_FormStart (ActNewLoc); + if (ItsANewLocation) + Act_FormStart (ActFrmNewLoc); + else + { + Act_FormStart (ActChgLoc); + Loc_PutParamLocCod (Loc.LocCod); + } + Loc_PutHiddenParamLocOrderType (); + Grp_PutParamWhichGrps (); + Pag_PutHiddenParamPagNum (Gbl.Pag.CurrentPage); - /***** Start of frame *****/ - Lay_StartRoundFrameTable (NULL,Txt_New_location, - NULL,Hlp_PROFILE_Location_edit,2); + /***** Table start *****/ + Lay_StartRoundFrameTable (NULL, + ItsANewLocation ? Txt_New_location : + Txt_Edit_location, + NULL, + ItsANewLocation ? Hlp_PROFILE_Location_new_location : + Hlp_PROFILE_Location_edit_location, + 2); - /***** Table head *****/ - Loc_PutHeadLocations (); - - /***** Put disabled icon to remove centre *****/ + /***** Location title *****/ fprintf (Gbl.F.Out,"" - ""); - Lay_PutIconRemovalNotAllowed (); - fprintf (Gbl.F.Out,""); - - /***** Location start date *****/ - fprintf (Gbl.F.Out,""); - Dat_WriteFormDate (Gbl.Now.Date.Year - 1, - Gbl.Now.Date.Year + 1, - "Start", - &(Loc->StartDate), - false,false); - fprintf (Gbl.F.Out,""); - - /***** Location end date *****/ - fprintf (Gbl.F.Out,""); - Dat_WriteFormDate (Gbl.Now.Date.Year - 1, - Gbl.Now.Date.Year + 1, - "End", - &(Loc->EndDate), - false,false); - fprintf (Gbl.F.Out,""); - - /***** Location *****/ - fprintf (Gbl.F.Out,"" - "" + "%s:" + "" + "" + "" "" - "" "", - Loc_MAX_LENGTH_LOCATION,Loc->Location); + The_ClassForm[Gbl.Prefs.Theme], + Txt_Title, + Loc_MAX_LENGTH_ASSIGNMENT_TITLE,Loc.Title); - /***** Send button and end of frame *****/ - Lay_EndRoundFrameTableWithButton (Lay_CREATE_BUTTON,Txt_Create_location); - - /***** End of form *****/ - Act_FormEnd (); - } - -/*****************************************************************************/ -/******************* Write header with fields of a location ******************/ -/*****************************************************************************/ - -static void Loc_PutHeadLocations (void) - { - extern const char *Txt_Start_date; - extern const char *Txt_End_date; - extern const char *Txt_Location; + /***** Location start and end dates *****/ + Dat_PutFormStartEndClientLocalDateTimes (Loc.TimeUTC); + /***** Send work? *****/ fprintf (Gbl.F.Out,"" - "" - "" - "%s" - "" - "" - "%s" - "" - "" - "%s" - "" + "" + "%s:" + "" + "" + "%s: " + "" + "" "", - Txt_Start_date, - Txt_End_date, - Txt_Location); + The_ClassForm[Gbl.Prefs.Theme], + Txt_Upload_files_QUESTION, + Txt_Folder, + Loc_MAX_LENGTH_FOLDER,Loc_MAX_LENGTH_FOLDER,Loc.Folder); + + /***** Location text *****/ + fprintf (Gbl.F.Out,"" + "" + "%s:" + "" + "" + "" + "" + ""); + + /***** New location *****/ + if (ItsANewLocation) + Lay_EndRoundFrameTableWithButton (Lay_CREATE_BUTTON,Txt_Create_location); + else + Lay_EndRoundFrameTableWithButton (Lay_CONFIRM_BUTTON,Txt_Save); + Act_FormEnd (); + + /***** Show current locations, if any *****/ + Loc_ShowAllLocations (); } /*****************************************************************************/ -/******************* Receive form to create a new location *******************/ +/******************** Receive form to create a new location ******************/ /*****************************************************************************/ -void Loc_RecFormNewLocation (void) +void Loc_RecFormLocation (void) { - extern const char *Txt_You_must_specify_the_new_location; - struct Location *Loc; + extern const char *Txt_Already_existed_an_location_with_the_title_X; + extern const char *Txt_You_must_specify_the_title_of_the_location; + extern const char *Txt_Created_new_location_X; + extern const char *Txt_The_location_has_been_modified; + struct Location OldLoc; + struct Location NewLoc; + bool ItsANewLocation; + bool NewLocationIsCorrect = true; + unsigned NumUsrsToBeNotifiedByEMail; + char Txt[Cns_MAX_BYTES_TEXT+1]; - Loc = &Gbl.Usrs.Me.Locs.EditingLoc; + /***** Get the code of the location *****/ + ItsANewLocation = ((NewLoc.LocCod = Loc_GetParamLocCod ()) == -1L); - /***** Get start date *****/ - Dat_GetDateFromForm ("StartDay","StartMonth","StartYear", - &(Loc->StartDate.Day),&(Loc->StartDate.Month),&(Loc->StartDate.Year)); - if (Loc->StartDate.Day == 0 || - Loc->StartDate.Month == 0 || - Loc->StartDate.Year == 0) - Dat_AssignDate (&Loc->StartDate,&Gbl.Now.Date); + if (!ItsANewLocation) + { + /* Get data of the old (current) location from database */ + OldLoc.LocCod = NewLoc.LocCod; + Loc_GetDataOfLocationByCod (&OldLoc); + } - /***** Get end date *****/ - Dat_GetDateFromForm ("EndDay","EndMonth","EndYear", - &(Loc->EndDate.Day),&(Loc->EndDate.Month),&(Loc->EndDate.Year)); - if (Loc->EndDate.Day == 0 || - Loc->EndDate.Month == 0 || - Loc->EndDate.Year == 0) - Dat_AssignDate (&Loc->EndDate,&Gbl.Now.Date); + /***** Get start/end date-times *****/ + NewLoc.TimeUTC[Loc_START_TIME] = Dat_GetTimeUTCFromForm ("StartTimeUTC"); + NewLoc.TimeUTC[Loc_END_TIME ] = Dat_GetTimeUTCFromForm ("EndTimeUTC" ); - /***** Get location *****/ - Par_GetParToText ("Location",Loc->Location,Loc_MAX_LENGTH_LOCATION); + /***** Get location title *****/ + Par_GetParToText ("Title",NewLoc.Title,Loc_MAX_LENGTH_ASSIGNMENT_TITLE); - /***** Create the new location or write warning message *****/ - if (Loc->Location[0]) // If there's a location - Loc_CreateLocation (Loc); - else // If there is not a location - Lay_ShowAlert (Lay_WARNING,Txt_You_must_specify_the_new_location); + /***** Get folder name where to send works of the location *****/ + Par_GetParToText ("Folder",NewLoc.Folder,Loc_MAX_LENGTH_FOLDER); + NewLoc.SendWork = (NewLoc.Folder[0]) ? Loc_SEND_WORK : + Loc_DO_NOT_SEND_WORK; - /***** Show the form again *****/ - Loc_EditLocations (); + /***** Get location text *****/ + Par_GetParToHTML ("Txt",Txt,Cns_MAX_BYTES_TEXT); // Store in HTML format (not rigorous) + + /***** Adjust dates *****/ + if (NewLoc.TimeUTC[Loc_START_TIME] == 0) + NewLoc.TimeUTC[Loc_START_TIME] = Gbl.StartExecutionTimeUTC; + if (NewLoc.TimeUTC[Loc_END_TIME] == 0) + NewLoc.TimeUTC[Loc_END_TIME] = NewLoc.TimeUTC[Loc_START_TIME] + 2*60*60; // +2 hours + + /***** Check if title is correct *****/ + if (NewLoc.Title[0]) // If there's an location title + { + /* If title of location was in database... */ + if (Loc_CheckIfSimilarLocationExists ("Title",NewLoc.Title,NewLoc.LocCod)) + { + NewLocationIsCorrect = false; + sprintf (Gbl.Message,Txt_Already_existed_an_location_with_the_title_X, + NewLoc.Title); + Lay_ShowAlert (Lay_WARNING,Gbl.Message); + } + } + else // If there is not an location title + { + NewLocationIsCorrect = false; + Lay_ShowAlert (Lay_WARNING,Txt_You_must_specify_the_title_of_the_location); + } + + /***** Create a new location or update an existing one *****/ + if (NewLocationIsCorrect) + { + if (ItsANewLocation) + { + Loc_CreateLocation (&NewLoc,Txt); // Add new location to database + + /***** Write success message *****/ + sprintf (Gbl.Message,Txt_Created_new_location_X,NewLoc.Title); + Lay_ShowAlert (Lay_SUCCESS,Gbl.Message); + } + else + { + if (OldLoc.Folder[0] && NewLoc.Folder[0]) + if (strcmp (OldLoc.Folder,NewLoc.Folder)) // Folder name has changed + NewLocationIsCorrect = Brw_UpdateFoldersAssigmentsIfExistForAllUsrs (OldLoc.Folder,NewLoc.Folder); + if (NewLocationIsCorrect) + { + Loc_UpdateLocation (&NewLoc,Txt); + + /***** Write success message *****/ + Lay_ShowAlert (Lay_SUCCESS,Txt_The_location_has_been_modified); + } + } + + /* Free memory for list of selected groups */ + Grp_FreeListCodSelectedGrps (); + + /***** Notify by email about the new location *****/ + if ((NumUsrsToBeNotifiedByEMail = Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_ASSIGNMENT,NewLoc.LocCod))) + Loc_UpdateNumUsrsNotifiedByEMailAboutLocation (NewLoc.LocCod,NumUsrsToBeNotifiedByEMail); + Ntf_ShowAlertNumUsrsToBeNotifiedByEMail (NumUsrsToBeNotifiedByEMail); + + /***** Show locations again *****/ + Loc_SeeLocations (); + } + else + // TODO: The form should be filled with partial data, now is always empty + Loc_RequestCreatOrEditLoc (); } /*****************************************************************************/ -/**************************** Create a new location **************************/ +/********* Update number of users notified in table of locations *************/ /*****************************************************************************/ -static void Loc_CreateLocation (struct Location *Loc) +static void Loc_UpdateNumUsrsNotifiedByEMailAboutLocation (long LocCod,unsigned NumUsrsToBeNotifiedByEMail) { - extern const char *Txt_Created_new_location; - char Query[256+Loc_MAX_LENGTH_LOCATION]; + char Query[512]; + + /***** Update number of users notified *****/ + sprintf (Query,"UPDATE locations SET NumNotif=NumNotif+'%u'" + " WHERE LocCod='%ld'", + NumUsrsToBeNotifiedByEMail,LocCod); + DB_QueryUPDATE (Query,"can not update the number of notifications of an location"); + } + +/*****************************************************************************/ +/************************* Create a new location *****************************/ +/*****************************************************************************/ + +static void Loc_CreateLocation (struct Location *Loc,const char *Txt) + { + char Query[1024+Cns_MAX_BYTES_TEXT]; /***** Create a new location *****/ - sprintf (Query,"INSERT INTO locations (StartDate,EndDate,Location)" - " VALUES ('%04u%02u%02u','%04u%02u%02u','%s')", - Loc->StartDate.Year, - Loc->StartDate.Month, - Loc->StartDate.Day, - Loc->EndDate.Year, - Loc->EndDate.Month, - Loc->EndDate.Day, - Loc->Location); - DB_QueryINSERT (Query,"can not create location"); - - /***** Write success message *****/ - Lay_ShowAlert (Lay_SUCCESS,Txt_Created_new_location); + sprintf (Query,"INSERT INTO locations" + " (CrsCod,UsrCod,StartTime,EndTime,Title,Folder,Txt)" + " VALUES" + " ('%ld','%ld',FROM_UNIXTIME('%ld'),FROM_UNIXTIME('%ld')," + "'%s','%s','%s')", + Gbl.CurrentCrs.Crs.CrsCod, + Gbl.Usrs.Me.UsrDat.UsrCod, + Loc->TimeUTC[Loc_START_TIME], + Loc->TimeUTC[Loc_END_TIME ], + Loc->Title, + Loc->Folder, + Txt); + Loc->LocCod = DB_QueryINSERTandReturnCode (Query,"can not create new location"); + } + +/*****************************************************************************/ +/********************** Update an existing location **************************/ +/*****************************************************************************/ + +static void Loc_UpdateLocation (struct Location *Loc,const char *Txt) + { + char Query[1024+Cns_MAX_BYTES_TEXT]; + + /***** Update the data of the location *****/ + sprintf (Query,"UPDATE locations SET " + "StartTime=FROM_UNIXTIME('%ld')," + "EndTime=FROM_UNIXTIME('%ld')," + "Title='%s',Folder='%s',Txt='%s'" + " WHERE LocCod='%ld' AND CrsCod='%ld'", + Loc->TimeUTC[Loc_START_TIME], + Loc->TimeUTC[Loc_END_TIME ], + Loc->Title, + Loc->Folder, + Txt, + Loc->LocCod,Gbl.CurrentCrs.Crs.CrsCod); + DB_QueryUPDATE (Query,"can not update location"); + } + +/*****************************************************************************/ +/******************* Remove all the locations of a course ********************/ +/*****************************************************************************/ + +void Loc_RemoveCrsLocations (long CrsCod) + { + char Query[128]; + + /***** Remove locations *****/ + sprintf (Query,"DELETE FROM locations WHERE CrsCod='%ld'",CrsCod); + DB_QueryDELETE (Query,"can not remove all the locations of a course"); + } + +/*****************************************************************************/ +/********** Check if I belong to any of the groups of an location ************/ +/*****************************************************************************/ + +static bool Loc_CheckIfIBelongToCrsThisLocation (long LocCod) + { + char Query[512]; + + if (Gbl.Usrs.Me.LoggedRole == Rol_STUDENT || + Gbl.Usrs.Me.LoggedRole == Rol_TEACHER) + { + // Students and teachers can edit locations depending on groups + /***** Get if I can edit an location from database *****/ + sprintf (Query,"SELECT COUNT(*) FROM locations" + " WHERE LocCod='%ld'", + LocCod); + return (DB_QueryCOUNT (Query,"can not check if I can do an location") != 0); + } + else + return (Gbl.Usrs.Me.LoggedRole > Rol_TEACHER); // Admins can edit locations + } + +/*****************************************************************************/ +/******************* Get number of locations in a course *********************/ +/*****************************************************************************/ + +unsigned Loc_GetNumLocationsInCrs (long CrsCod) + { + char Query[256]; + + /***** Get number of locations in a course from database *****/ + sprintf (Query,"SELECT COUNT(*) FROM locations WHERE CrsCod='%ld'", + CrsCod); + return (unsigned) DB_QueryCOUNT (Query,"can not get number of locations in course"); + } + +/*****************************************************************************/ +/******************* Get number of courses with locations ********************/ +/*****************************************************************************/ +// Returns the number of courses with locations +// in this location (all the platform, current degree or current course) + +unsigned Loc_GetNumCoursesWithLocations (Sco_Scope_t Scope) + { + char Query[1024]; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumCourses; + + /***** Get number of courses with locations from database *****/ + switch (Scope) + { + case Sco_SCOPE_SYS: + sprintf (Query,"SELECT COUNT(DISTINCT CrsCod)" + " FROM locations" + " WHERE CrsCod>'0'"); + break; + case Sco_SCOPE_CTY: + sprintf (Query,"SELECT COUNT(DISTINCT locations.CrsCod)" + " FROM institutions,centres,degrees,courses,locations" + " WHERE institutions.CtyCod='%ld'" + " AND institutions.InsCod=centres.InsCod" + " AND centres.CtrCod=degrees.CtrCod" + " AND degrees.DegCod=courses.DegCod" + " AND courses.Status=0" + " AND courses.CrsCod=locations.CrsCod", + Gbl.CurrentCty.Cty.CtyCod); + break; + case Sco_SCOPE_INS: + sprintf (Query,"SELECT COUNT(DISTINCT locations.CrsCod)" + " FROM centres,degrees,courses,locations" + " WHERE centres.InsCod='%ld'" + " AND centres.CtrCod=degrees.CtrCod" + " AND degrees.DegCod=courses.DegCod" + " AND courses.Status=0" + " AND courses.CrsCod=locations.CrsCod", + Gbl.CurrentIns.Ins.InsCod); + break; + case Sco_SCOPE_CTR: + sprintf (Query,"SELECT COUNT(DISTINCT locations.CrsCod)" + " FROM degrees,courses,locations" + " WHERE degrees.CtrCod='%ld'" + " AND degrees.DegCod=courses.DegCod" + " AND courses.Status=0" + " AND courses.CrsCod=locations.CrsCod", + Gbl.CurrentCtr.Ctr.CtrCod); + break; + case Sco_SCOPE_DEG: + sprintf (Query,"SELECT COUNT(DISTINCT locations.CrsCod)" + " FROM courses,locations" + " WHERE courses.DegCod='%ld'" + " AND courses.Status=0" + " AND courses.CrsCod=locations.CrsCod", + Gbl.CurrentDeg.Deg.DegCod); + break; + case Sco_SCOPE_CRS: + sprintf (Query,"SELECT COUNT(DISTINCT CrsCod)" + " FROM locations" + " WHERE CrsCod='%ld'", + Gbl.CurrentCrs.Crs.CrsCod); + break; + default: + Lay_ShowErrorAndExit ("Wrong scope."); + break; + } + DB_QuerySELECT (Query,&mysql_res,"can not get number of courses with locations"); + + /***** Get number of courses *****/ + row = mysql_fetch_row (mysql_res); + if (sscanf (row[0],"%u",&NumCourses) != 1) + Lay_ShowErrorAndExit ("Error when getting number of courses with locations."); + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + + return NumCourses; + } + +/*****************************************************************************/ +/************************* Get number of locations ***************************/ +/*****************************************************************************/ +// Returns the number of locations +// in this location (all the platform, current degree or current course) + +unsigned Loc_GetNumLocations (Sco_Scope_t Scope,unsigned *NumNotif) + { + char Query[1024]; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumLocations; + + /***** Get number of locations from database *****/ + switch (Scope) + { + case Sco_SCOPE_SYS: + sprintf (Query,"SELECT COUNT(*),SUM(NumNotif)" + " FROM locations" + " WHERE CrsCod>'0'"); + break; + case Sco_SCOPE_CTY: + sprintf (Query,"SELECT COUNT(*),SUM(locations.NumNotif)" + " FROM institutions,centres,degrees,courses,locations" + " WHERE institutions.CtyCod='%ld'" + " AND institutions.InsCod=centres.InsCod" + " AND centres.CtrCod=degrees.CtrCod" + " AND degrees.DegCod=courses.DegCod" + " AND courses.CrsCod=locations.CrsCod", + Gbl.CurrentCty.Cty.CtyCod); + break; + case Sco_SCOPE_INS: + sprintf (Query,"SELECT COUNT(*),SUM(locations.NumNotif)" + " FROM centres,degrees,courses,locations" + " WHERE centres.InsCod='%ld'" + " AND centres.CtrCod=degrees.CtrCod" + " AND degrees.DegCod=courses.DegCod" + " AND courses.CrsCod=locations.CrsCod", + Gbl.CurrentIns.Ins.InsCod); + break; + case Sco_SCOPE_CTR: + sprintf (Query,"SELECT COUNT(*),SUM(locations.NumNotif)" + " FROM degrees,courses,locations" + " WHERE degrees.CtrCod='%ld'" + " AND degrees.DegCod=courses.DegCod" + " AND courses.CrsCod=locations.CrsCod", + Gbl.CurrentCtr.Ctr.CtrCod); + break; + case Sco_SCOPE_DEG: + sprintf (Query,"SELECT COUNT(*),SUM(locations.NumNotif)" + " FROM courses,locations" + " WHERE courses.DegCod='%ld'" + " AND courses.CrsCod=locations.CrsCod", + Gbl.CurrentDeg.Deg.DegCod); + break; + case Sco_SCOPE_CRS: + sprintf (Query,"SELECT COUNT(*),SUM(NumNotif)" + " FROM locations" + " WHERE CrsCod='%ld'", + Gbl.CurrentCrs.Crs.CrsCod); + break; + default: + Lay_ShowErrorAndExit ("Wrong scope."); + break; + } + DB_QuerySELECT (Query,&mysql_res,"can not get number of locations"); + + /***** Get number of locations *****/ + row = mysql_fetch_row (mysql_res); + if (sscanf (row[0],"%u",&NumLocations) != 1) + Lay_ShowErrorAndExit ("Error when getting number of locations."); + + /***** Get number of notifications by email *****/ + if (row[1]) + { + if (sscanf (row[1],"%u",NumNotif) != 1) + Lay_ShowErrorAndExit ("Error when getting number of notifications of locations."); + } + else + *NumNotif = 0; + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + + return NumLocations; } diff --git a/swad_location.h b/swad_location.h index e29dfe247..41ff6a6df 100644 --- a/swad_location.h +++ b/swad_location.h @@ -28,33 +28,51 @@ /*****************************************************************************/ #include "swad_date.h" -#include "swad_place.h" +#include "swad_user.h" /*****************************************************************************/ /************************** Public types and constants ***********************/ /*****************************************************************************/ -#define Loc_MAX_LENGTH_LOCATION 255 +#define Loc_MAX_LENGTH_ASSIGNMENT_TITLE 255 +#define Loc_MAX_LENGTH_FOLDER 32 + +#define Loc_NUM_TYPES_SEND_WORK 2 typedef enum { - LOC_START_DATE, - LOC_END_DATE - } Loc_StartOrEndDate_t; + Loc_DO_NOT_SEND_WORK = 0, + Loc_SEND_WORK = 1, + } Loc_SendWork_t; + +#define Loc_NUM_DATES 2 +typedef enum + { + Loc_START_TIME = 0, + Loc_END_TIME = 1, + } Loc_StartOrEndTime_t; struct Location { long LocCod; - struct Date StartDate; - struct Date EndDate; - char Location[Loc_MAX_LENGTH_LOCATION+1]; + bool Hidden; + long UsrCod; + time_t TimeUTC[Loc_NUM_DATES]; + bool Open; + char Title[Loc_MAX_LENGTH_ASSIGNMENT_TITLE+1]; + Loc_SendWork_t SendWork; + char Folder[Loc_MAX_LENGTH_FOLDER+1]; + bool IBelongToCrsOrGrps; // I can do this location + // (it is associated to no groups + // or, if associated to groups, + // I belong to any of the groups) }; typedef enum { Loc_ORDER_BY_START_DATE = 0, Loc_ORDER_BY_END_DATE = 1, - } Loc_OrderType_t; + } Loc_Order_t; #define Loc_DEFAULT_ORDER_TYPE Loc_ORDER_BY_START_DATE @@ -63,15 +81,24 @@ typedef enum /*****************************************************************************/ void Loc_SeeLocations (void); -void Loc_EditLocations (void); +void Loc_PutHiddenParamLocOrderType (void); +void Loc_RequestCreatOrEditLoc (void); void Loc_GetListLocations (void); +void Loc_GetDataOfLocationByCod (struct Location *Loc); void Loc_FreeListLocations (void); +void Loc_GetNotifLocation (char *SummaryStr,char **ContentStr,long LocCod,unsigned MaxChars,bool GetContent); + long Loc_GetParamLocCod (void); +void Loc_AskRemLocation (void); void Loc_RemoveLocation (void); -void Loc_ChangeStartDate (void); -void Loc_ChangeEndDate (void); -void Loc_RenameLocation (void); -void Loc_RecFormNewLocation (void); +void Loc_HideLocation (void); +void Loc_ShowLocation (void); +void Loc_RecFormLocation (void); +void Loc_RemoveCrsLocations (long CrsCod); +unsigned Loc_GetNumLocationsInCrs(long CrsCod); + +unsigned Loc_GetNumCoursesWithLocations (Sco_Scope_t Scope); +unsigned Loc_GetNumLocations (Sco_Scope_t Scope,unsigned *NumNotif); #endif diff --git a/swad_text.c b/swad_text.c index 42ed3f28f..9fd0fd851 100644 --- a/swad_text.c +++ b/swad_text.c @@ -6842,25 +6842,25 @@ const char *Txt_Created_new_link_X = // Warning: it is very important to include "Criado nova ligação %s."; #endif -const char *Txt_Created_new_location = +const char *Txt_Created_new_location_X = // Warning: it is very important to include %s in the following sentences #if L==1 - "Creada nova ubicació."; + "Creada nova ubicació %s."; #elif L==2 - "Neuer Standort eingegeben."; + "Neuer Standort %s eingegeben."; #elif L==3 - "Created new location."; + "Created new location %s."; #elif L==4 - "Creada nueva ubicación."; + "Creada nueva ubicación %s."; #elif L==5 - "Créé nouvel emplacement."; + "Créé nouvel emplacement %s."; #elif L==6 - "Creada nueva ubicación."; // Okoteve traducción + "Creada nueva ubicación %s."; // Okoteve traducción #elif L==7 - "Creata nuova posizione."; + "Creata nuova posizione %s."; #elif L==8 - "Utworzono nowe lokacja."; + "Utworzono nowe lokacja %s."; #elif L==9 - "Criado nova localização."; + "Criado nova localização %s."; #endif const char *Txt_Created_new_place_X = // Warning: it is very important to include %s in the following sentences @@ -17110,25 +17110,25 @@ const char *Txt_Location = "Localização"; #endif -const char *Txt_Location_removed = +const char *Txt_Location_X_removed = // Warning: it is very important to include %s in the following sentences #if L==1 - "Ubicació eliminada."; + "Ubicació %s eliminada."; #elif L==2 - "Standort entfernt."; + "Standort %s entfernt."; #elif L==3 - "Location removed."; + "Location %s removed."; #elif L==4 - "Ubicación eliminada."; + "Ubicación %s eliminada."; #elif L==5 - "Emplacement supprimé."; + "Emplacement %s supprimé."; #elif L==6 - "Ubicación eliminada."; // Okoteve traducción + "Ubicación %s eliminada."; // Okoteve traducción #elif L==7 - "Posizione rimossa."; + "Posizione %s rimossa."; #elif L==8 - "Lokacja usuniete."; + "Lokacja %s usuniete."; #elif L==9 - "Localização removida."; + "Localização %s removida."; #endif const char *Txt_Locations = @@ -24572,6 +24572,27 @@ const char *Txt_No_institutions = "Não há instituções."; #endif +const char *Txt_No_locations = +#if L==1 + "No hi ha ubicacions."; +#elif L==2 + "Es gibt keine Standorte."; +#elif L==3 + "No locations."; +#elif L==4 + "No existen ubicaciones."; +#elif L==5 + "Il n'y a pas d'emplacements."; +#elif L==6 + "No existen ubicaciones."; // Okoteve traducción +#elif L==7 + "Non ci sono posizioni."; +#elif L==8 + "Brak lokalizacje."; +#elif L==9 + "Não existem localizações."; +#endif + const char *Txt_No_BR_msgs = #if L==1 "Nº
mens."; // Necessita traduccio @@ -30787,6 +30808,27 @@ const char *Txt_Remove_link = "Remover ligação"; #endif +const char *Txt_Remove_location = +#if L==1 + "Eliminar ubicació"; +#elif L==2 + "Entfernen Standort"; +#elif L==3 + "Remove location"; +#elif L==4 + "Eliminar ubicación"; +#elif L==5 + "Supprimer emplacement"; +#elif L==6 + "Eliminar ubicación"; // Okoteve traducción +#elif L==7 + "Rimuovere posizione"; +#elif L==8 + "Usuń lokacja"; +#elif L==9 + "Remover localização"; +#endif + const char *Txt_Remove_logo = #if L==1 "Eliminar logo"; @@ -42287,27 +42329,6 @@ const char *Txt_The_date_of_the_holiday_X_has_changed_to_Y = // Warning: it is v "The date of the holiday %s has changed to %s."; // Necessita de tradução #endif -const char *Txt_The_date_of_the_location_has_changed_to_X = // Warning: it is very important to include %s in the following sentences -#if L==1 - "La fecha de la festividad ha cambiado a %s."; // Necessita traduccio -#elif L==2 - "The date of the location has changed to %s."; // Need Übersetzung -#elif L==3 - "The date of the location has changed to %s."; -#elif L==4 - "La fecha de la ubicación ha cambiado a %s."; -#elif L==5 - "The date of the location has changed to %s."; // Besoin de traduction -#elif L==6 - "La fecha de la ubicación ha cambiado a %s."; // Okoteve traducción -#elif L==7 - "La data delle posizione è cambiata a %s."; -#elif L==8 - "The date of the location has changed to %s."; // Potrzebujesz tlumaczenie -#elif L==9 - "The date of the location has changed to %s."; // Necessita de tradução -#endif - const char *Txt_The_date_range_must_be_less_than_or_equal_to_X_days = // Warning: it is very important to include %u in the following sentences #if L==1 "El rango de fechas debe ser menor o igual a %u días."; // Necessita traduccio @@ -43580,48 +43601,6 @@ const char *Txt_The_list_of_X_users_is_too_large_to_be_displayed = // Warning: i "The list of %u users is too large to be displayed."; // Necessita de tradução #endif -const char *Txt_The_location_has_changed_to_X = // Warning: it is very important to include %s in the following sentences -#if L==1 - "La ubicació ha canviat a %s."; -#elif L==2 - "Der Standort wurde in %s geändert."; -#elif L==3 - "The location has changed to %s."; -#elif L==4 - "La ubicación ha cambiado a %s."; -#elif L==5 - "L'emplacement a changé en %s."; -#elif L==6 - "La ubicación ha cambiado a %s."; // Okoteve traducción -#elif L==7 - "La posizione è cambiato a %s."; -#elif L==8 - "Zmieniona na miejscu %s."; -#elif L==9 - "A localização mudou para %s."; -#endif - -const char *Txt_The_location_has_not_changed = -#if L==1 - "La ubicació no ha canviat."; -#elif L==2 - "Der Standort wurde nicht geändert."; -#elif L==3 - "The location has not changed."; -#elif L==4 - "La ubicación no ha cambiado."; -#elif L==5 - "L'emplacement n'a pas changé."; -#elif L==6 - "La ubicación no ha cambiado."; // Okoteve traducción -#elif L==7 - "La posizione non è cambiato."; -#elif L==8 - "Miejsca nie uległa zmianie."; -#elif L==9 - "A localização não foi alterado."; -#endif - const char *Txt_The_lower_limit_of_correct_answers_must_be_less_than_or_equal_to_the_upper_limit = #if L==1 "El límite inferior del intervalo de respuestas correctas" @@ -46634,27 +46613,6 @@ const char *Txt_There_are_no_links = "There are no links."; // Necessita de tradução #endif -const char *Txt_There_are_no_locations = -#if L==1 - "No hi ha ubicacions."; -#elif L==2 - "Es gibt keine Standorte."; -#elif L==3 - "There are no locations."; -#elif L==4 - "No existen ubicaciones."; -#elif L==5 - "Il n'y a pas d'emplacements."; -#elif L==6 - "No existen ubicaciones."; // Okoteve traducción -#elif L==7 - "Non ci sono posizioni."; -#elif L==8 - "Brak lokalizacje."; -#elif L==9 - "Não existem localizações."; -#endif - const char *Txt_There_are_no_places = #if L==1 "No existen lugares."; // Necessita traduccio @@ -52169,27 +52127,6 @@ const char *Txt_You_can_not_leave_the_IP_address_empty = "You can not leave the IP address empty."; // Necessita de tradução #endif -const char *Txt_You_can_not_leave_the_location_empty = -#if L==1 - "No es pot deixar la ubicació buido."; -#elif L==2 - "Sie können den Standort nicht leer lassen."; -#elif L==3 - "You can not leave the location empty."; -#elif L==4 - "No puede dejar la ubicación vacía."; -#elif L==5 - "Vous ne pouvez pas laisser l'emplacement vide."; -#elif L==6 - "No puede dejar la ubicación vacía."; // Okoteve traducción -#elif L==7 - "Non puoi lasciare la posizione vuota."; -#elif L==8 - "Nie można pozostawić miejsca pustego."; -#elif L==9 - "Você não pode deixar a localização vazia."; -#endif - const char *Txt_You_can_not_leave_the_logo_empty = #if L==1 "No puede dejar el logo vacío."; // Necessita traduccio @@ -54092,27 +54029,6 @@ const char *Txt_You_must_specify_the_name_of_the_new_type_of_group = "You must specify the name of the new type of group."; // Necessita de tradução #endif -const char *Txt_You_must_specify_the_new_location = -#if L==1 - "Cal especificar la nova ubicació."; -#elif L==2 - "Sie müssen den neuen Speicherort angeben."; -#elif L==3 - "You must specify the new location."; -#elif L==4 - "Debe especificar la nueva ubicación."; -#elif L==5 - "Vous devez spécifier le nouvel emplacement."; -#elif L==6 - "Debe especificar la nueva ubicación."; // Okoteve traducción -#elif L==7 - "Devi specificare la nuova posizione."; -#elif L==8 - "Musisz podać nazwę nowej lokalizacji."; -#elif L==9 - "Você deve especificar a nova localização."; -#endif - const char *Txt_You_must_specify_the_short_name_and_the_full_name_of_the_new_banner = #if L==1 "Debe especificar el nombre breve y el nombre completo"