diff --git a/sql/swad.sql b/sql/swad.sql index 18b7af1e8..ea3aa5e3c 100644 --- a/sql/swad.sql +++ b/sql/swad.sql @@ -598,6 +598,15 @@ CREATE TABLE IF NOT EXISTS links ( WWW VARCHAR(255) NOT NULL, UNIQUE INDEX(LnkCod)); -- +-- Table locations: stores the teachers' locations +-- +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)); +-- -- Table log_banners: stores the log of clicked banners -- CREATE TABLE IF NOT EXISTS log_banners ( diff --git a/swad_action.c b/swad_action.c index 25e23f9ab..943bfc34f 100644 --- a/swad_action.c +++ b/swad_action.c @@ -81,7 +81,7 @@ extern struct Globals Gbl; /************************ Internal global variables **************************/ /*****************************************************************************/ /* -1223 actions in one CGI: +1230 actions in one CGI: 0. ActAll Any action (used for statistics) 1. ActUnk Unknown action 2. ActHom Show home menu @@ -1344,82 +1344,89 @@ Profile: 1155. ActAnnSee Mark announcement as seen 1156. ActChgMyRol Change type of logged user - 1157. ActChkUsrAcc Check if already exists a new account without password associated to a ID - 1158. ActCreUsrAcc Create new user account - 1159. ActRemID_Me Remove one of my user's IDs - 1160. ActNewIDMe Create a new user's ID for me - 1161. ActRemOldNic Remove one of my old nicknames - 1162. ActChgNic Change my nickname - 1163. ActRemMaiMe Remove one of my old emails - 1164. ActNewMaiMe Change my email address - 1165. ActCnfMai Confirm email address - 1166. ActFrmChgMyPwd Show form to the change of the password - 1167. ActChgPwd Change the password - 1168. ActReqRemMyAcc Request the removal of my account - 1169. ActRemMyAcc Remove my account + 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 - 1170. ActChgMyData Update my personal data + 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 - 1171. ActReqMyPho Show form to send my photo - 1172. ActDetMyPho Receive my photo and detect faces on it - 1173. ActUpdMyPho Update my photo - 1174. ActReqRemMyPho Request the removal of my photo - 1175. ActRemMyPho Remove my photo + 1176. ActChgMyData Update my personal data - 1176. ActEdiPri Edit my privacy - 1177. ActChgPriPho Change privacy of my photo - 1178. ActChgPriPrf Change privacy of my public profile + 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. ActReqEdiMyIns Request the edition of my institution, centre and department - 1180. ActChgCtyMyIns Change the country of my institution - 1181. ActChgMyIns Change my institution - 1182. ActChgMyCtr Change my centre - 1183. ActChgMyDpt Change my department - 1184. ActChgMyOff Change my office - 1185. ActChgMyOffPho Change my office phone + 1182. ActEdiPri Edit my privacy + 1183. ActChgPriPho Change privacy of my photo + 1184. ActChgPriPrf Change privacy of my public profile - 1186. ActReqEdiMyNet Request the edition of my social networks - 1187. ActChgMyNet Change my web and social networks + 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 - 1188. ActChgThe Change theme - 1189. ActReqChgLan Ask if change language - 1190. ActChgLan Change language - 1191. ActChg1stDay Change first day of the week - 1192. ActChgCol Change side columns - 1193. ActHidLftCol Hide left side column - 1194. ActHidRgtCol Hide right side column - 1195. ActShoLftCol Show left side column - 1196. ActShoRgtCol Show right side column - 1197. ActChgIco Change icon set - 1198. ActChgMnu Change menu - 1199. ActChgNtfPrf Change whether to notify by email new messages - 1200. ActPrnUsrQR Show my QR code ready to print + 1192. ActReqEdiMyNet Request the edition of my social networks + 1193. ActChgMyNet Change my web and social networks - 1201. ActPrnMyTT Show the timetable listo to impresión of all my courses - 1202. ActEdiTut Edit the timetable of tutorías - 1203. ActChgTut Modify the timetable of tutorías - 1204. ActChgMyTT1stDay Change first day of week and show timetable of the course + 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 - 1205. ActReqRemFilBrf Request removal of a file of the briefcase - 1206. ActRemFilBrf Remove a file of the briefcase - 1207. ActRemFolBrf Remove a folder empty of the briefcase - 1208. ActCopBrf Set source of copy in the briefcase - 1209. ActPasBrf Paste a folder or file in the briefcase - 1210. ActRemTreBrf Remove a folder no empty of the briefcase - 1211. ActFrmCreBrf Form to crear a folder or file in the briefcase - 1212. ActCreFolBrf Create a new folder in the briefcase - 1213. ActCreLnkBrf Create a new link in the briefcase - 1214. ActRenFolBrf Rename a folder of the briefcase - 1215. ActRcvFilBrfDZ Receive a file in the briefcase using Dropzone.js - 1216. ActRcvFilBrfCla Receive a file in the briefcase using the classic way - 1217. ActExpBrf Expand a folder in briefcase - 1218. ActConBrf Contract a folder in briefcase - 1219. ActZIPBrf Compress a folder in briefcase - 1220. ActReqDatBrf Ask for metadata of a file in the briefcase - 1221. ActChgDatBrf Change metadata of a file in the briefcase - 1222. ActDowBrf Download a file in the briefcase - 1223. ActReqRemOldBrf Ask for removing old files in the briefcase - 1224. ActRemOldBrf Remove old files in the briefcase + 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 + + 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 */ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = @@ -2768,7 +2775,7 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActMyCrs */{ 987, 2,TabPrf,ActMyCrs ,0x1FE,0x1FE,0x1FE,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Crs_ReqSelectOneOfMyCourses ,"mygroups64x64.gif" }, /* ActSeeMyTT */{ 408, 3,TabPrf,ActSeeMyTT ,0x1FE,0x1FE,0x1FE,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,TT_ShowClassTimeTable ,"clock64x64.gif" }, /* ActSeeMyAgd */{1581, 4,TabPrf,ActSeeMyAgd ,0x100,0x100,0x100,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Agd_ShowMyAgenda ,"date64x64.gif" }, - /* ActSeeMyLoc */{1602, 5,TabPrf,ActSeeMyLoc ,0x100,0x100,0x100,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_ShowMyLocation ,"mapmarker64x64.png" }, + /* ActSeeMyLoc */{1602, 5,TabPrf,ActSeeMyLoc ,0x100,0x100,0x100,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Loc_SeeLocations ,"mapmarker64x64.png" }, /* ActFrmMyAcc */{ 36, 6,TabPrf,ActFrmMyAcc ,0x1FF,0x1FF,0x1FF,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Acc_ShowFormMyAccount ,"arroba64x64.gif" }, /* ActReqEdiRecCom */{ 285, 7,TabPrf,ActReqEdiRecCom ,0x1FE,0x1FE,0x1FE,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Rec_ShowFormMySharedRecord ,"card64x64.gif" }, /* ActEdiPrf */{ 673, 8,TabPrf,ActEdiPrf ,0x1FF,0x1FF,0x1FF,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Pre_EditPrefs ,"heart64x64.gif" }, @@ -2785,6 +2792,13 @@ 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}, + /* 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}, @@ -4477,6 +4491,12 @@ 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 }; /*****************************************************************************/ diff --git a/swad_action.h b/swad_action.h index 868cde700..482f58dcc 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+86) +#define Act_NUM_ACTIONS (1+9+51+14+93+73+70+249+186+155+172+36+31+92) -#define Act_MAX_ACTION_COD 1602 +#define Act_MAX_ACTION_COD 1608 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 11 @@ -1381,84 +1381,90 @@ 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 ActChkUsrAcc (ActSeeMyUsgRep+19) -#define ActCreUsrAcc (ActSeeMyUsgRep+20) -#define ActRemID_Me (ActSeeMyUsgRep+21) -#define ActNewIDMe (ActSeeMyUsgRep+22) -#define ActRemOldNic (ActSeeMyUsgRep+23) -#define ActChgNic (ActSeeMyUsgRep+24) -#define ActRemMaiMe (ActSeeMyUsgRep+25) -#define ActNewMaiMe (ActSeeMyUsgRep+26) -#define ActCnfMai (ActSeeMyUsgRep+27) -#define ActFrmChgMyPwd (ActSeeMyUsgRep+28) -#define ActChgPwd (ActSeeMyUsgRep+29) -#define ActReqRemMyAcc (ActSeeMyUsgRep+30) -#define ActRemMyAcc (ActSeeMyUsgRep+31) +#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 ActChgMyData (ActSeeMyUsgRep+32) +#define ActChgMyData (ActSeeMyUsgRep+38) -#define ActReqMyPho (ActSeeMyUsgRep+33) -#define ActDetMyPho (ActSeeMyUsgRep+34) -#define ActUpdMyPho (ActSeeMyUsgRep+35) -#define ActReqRemMyPho (ActSeeMyUsgRep+36) -#define ActRemMyPho (ActSeeMyUsgRep+37) +#define ActReqMyPho (ActSeeMyUsgRep+39) +#define ActDetMyPho (ActSeeMyUsgRep+40) +#define ActUpdMyPho (ActSeeMyUsgRep+41) +#define ActReqRemMyPho (ActSeeMyUsgRep+42) +#define ActRemMyPho (ActSeeMyUsgRep+43) -#define ActEdiPri (ActSeeMyUsgRep+38) -#define ActChgPriPho (ActSeeMyUsgRep+39) -#define ActChgPriPrf (ActSeeMyUsgRep+40) +#define ActEdiPri (ActSeeMyUsgRep+44) +#define ActChgPriPho (ActSeeMyUsgRep+45) +#define ActChgPriPrf (ActSeeMyUsgRep+46) -#define ActReqEdiMyIns (ActSeeMyUsgRep+41) -#define ActChgCtyMyIns (ActSeeMyUsgRep+42) -#define ActChgMyIns (ActSeeMyUsgRep+43) -#define ActChgMyCtr (ActSeeMyUsgRep+44) -#define ActChgMyDpt (ActSeeMyUsgRep+45) -#define ActChgMyOff (ActSeeMyUsgRep+46) -#define ActChgMyOffPho (ActSeeMyUsgRep+47) +#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 ActReqEdiMyNet (ActSeeMyUsgRep+48) -#define ActChgMyNet (ActSeeMyUsgRep+49) +#define ActReqEdiMyNet (ActSeeMyUsgRep+54) +#define ActChgMyNet (ActSeeMyUsgRep+55) -#define ActChgThe (ActSeeMyUsgRep+50) -#define ActReqChgLan (ActSeeMyUsgRep+51) -#define ActChgLan (ActSeeMyUsgRep+52) -#define ActChg1stDay (ActSeeMyUsgRep+53) -#define ActChgCol (ActSeeMyUsgRep+54) -#define ActHidLftCol (ActSeeMyUsgRep+55) -#define ActHidRgtCol (ActSeeMyUsgRep+56) -#define ActShoLftCol (ActSeeMyUsgRep+57) -#define ActShoRgtCol (ActSeeMyUsgRep+58) -#define ActChgIco (ActSeeMyUsgRep+59) -#define ActChgMnu (ActSeeMyUsgRep+60) -#define ActChgNtfPrf (ActSeeMyUsgRep+61) +#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 ActPrnUsrQR (ActSeeMyUsgRep+62) +#define ActPrnUsrQR (ActSeeMyUsgRep+68) -#define ActPrnMyTT (ActSeeMyUsgRep+63) -#define ActEdiTut (ActSeeMyUsgRep+64) -#define ActChgTut (ActSeeMyUsgRep+65) -#define ActChgMyTT1stDay (ActSeeMyUsgRep+66) +#define ActPrnMyTT (ActSeeMyUsgRep+69) +#define ActEdiTut (ActSeeMyUsgRep+70) +#define ActChgTut (ActSeeMyUsgRep+71) +#define ActChgMyTT1stDay (ActSeeMyUsgRep+72) -#define ActReqRemFilBrf (ActSeeMyUsgRep+67) -#define ActRemFilBrf (ActSeeMyUsgRep+68) -#define ActRemFolBrf (ActSeeMyUsgRep+69) -#define ActCopBrf (ActSeeMyUsgRep+70) -#define ActPasBrf (ActSeeMyUsgRep+71) -#define ActRemTreBrf (ActSeeMyUsgRep+72) -#define ActFrmCreBrf (ActSeeMyUsgRep+73) -#define ActCreFolBrf (ActSeeMyUsgRep+74) -#define ActCreLnkBrf (ActSeeMyUsgRep+75) -#define ActRenFolBrf (ActSeeMyUsgRep+76) -#define ActRcvFilBrfDZ (ActSeeMyUsgRep+77) -#define ActRcvFilBrfCla (ActSeeMyUsgRep+78) -#define ActExpBrf (ActSeeMyUsgRep+79) -#define ActConBrf (ActSeeMyUsgRep+80) -#define ActZIPBrf (ActSeeMyUsgRep+81) -#define ActReqDatBrf (ActSeeMyUsgRep+82) -#define ActChgDatBrf (ActSeeMyUsgRep+83) -#define ActDowBrf (ActSeeMyUsgRep+84) +#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 ActReqRemOldBrf (ActSeeMyUsgRep+85) -#define ActRemOldBrf (ActSeeMyUsgRep+86) +#define ActReqRemOldBrf (ActSeeMyUsgRep+91) +#define ActRemOldBrf (ActSeeMyUsgRep+92) /*****************************************************************************/ /******************************** Public types *******************************/ diff --git a/swad_changelog.h b/swad_changelog.h index 15b313682..915fcc688 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -176,13 +176,24 @@ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 16.75 (2016-11-28)" +#define Log_PLATFORM_VERSION "SWAD 16.76 (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.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)); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1602','es','N','Ver mis ubicaciones'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1603','es','N','Editar mis ubicaciones'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1604','es','N','Solicitar creación de ubicación'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1605','es','N','Eliminar ubicación'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1606','es','N','Cambiar fecha inicial de ubicación'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1607','es','N','Cambiar fecha final de ubicación'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1608','es','N','Renombrar ubicación'); + Version 16.75: Nov 28, 2016 New option to show my location. (207947 lines) Version 16.74.1: Nov 28, 2016 Changed icon to show places. (207807 lines) Copy icon/mapmarker64x64.png to public icons directory diff --git a/swad_database.c b/swad_database.c index 66ef8b2c1..db8dcbb86 100644 --- a/swad_database.c +++ b/swad_database.c @@ -1297,6 +1297,26 @@ mysql> DESCRIBE links; "WWW VARCHAR(255) NOT NULL," "UNIQUE INDEX(LnkCod))"); + /***** Table locations *****/ +/* +mysql> DESCRIBE locations; ++-----------+--------------+------+-----+---------+----------------+ +| Field | Type | Null | Key | Default | Extra | ++-----------+--------------+------+-----+---------+----------------+ +| LocCod | int(11) | NO | PRI | NULL | auto_increment | +| StartDate | date | NO | | NULL | | +| EndDate | date | NO | | NULL | | +| Location | varchar(255) | NO | | NULL | | ++-----------+--------------+------+-----+---------+----------------+ +4 rows in set (0,01 sec) +*/ + DB_CreateTable ("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))"); + /***** Table log_banners *****/ /* mysql> DESCRIBE log_banners; diff --git a/swad_global.h b/swad_global.h index 1017c37a5..beb6cb0eb 100644 --- a/swad_global.h +++ b/swad_global.h @@ -53,6 +53,7 @@ #include "swad_institution.h" #include "swad_layout.h" #include "swad_link.h" +#include "swad_location.h" #include "swad_mail.h" #include "swad_mark.h" #include "swad_message.h" @@ -354,6 +355,14 @@ struct Globals long DegCod; } Crss[Crs_MAX_COURSES_PER_USR]; } 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; + } Locs; Usr_ShowUsrsType_t ListType; // My preference about user's list type unsigned NumFollowers; // Number of users who follow me unsigned NumFollowing; // Number of users I follow diff --git a/swad_help.c b/swad_help.c index 479cdf312..8a49d7a46 100644 --- a/swad_help.c +++ b/swad_help.c @@ -227,6 +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_Record = WIKI "PROFILE.Record"; const char *Hlp_PROFILE_Institution = WIKI "PROFILE.Institution"; const char *Hlp_PROFILE_Webs = WIKI "PROFILE.Webs"; diff --git a/swad_holiday.c b/swad_holiday.c index 977978b9e..cbf8d8333 100644 --- a/swad_holiday.c +++ b/swad_holiday.c @@ -632,7 +632,7 @@ long Hld_GetParamHldCod (void) void Hld_RemoveHoliday (void) { extern const char *Txt_Holiday_X_removed; - char Query[512]; + char Query[128]; struct Holiday Hld; /***** Get holiday code *****/ diff --git a/swad_location.c b/swad_location.c new file mode 100644 index 000000000..cc1401291 --- /dev/null +++ b/swad_location.c @@ -0,0 +1,775 @@ +// swad_location.c: teacher's location + +/* + SWAD (Shared Workspace At a Distance), + is a web platform developed at the University of Granada (Spain), + and used to support university teaching. + + This file is part of SWAD core. + Copyright (C) 1999-2016 Antonio Cañas Vargas + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General 3 License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +/*****************************************************************************/ +/********************************* Headers ***********************************/ +/*****************************************************************************/ + +#include // For NULL +#include // For calloc +#include // For string functions + +#include "swad_database.h" +#include "swad_global.h" +#include "swad_location.h" +#include "swad_parameter.h" +#include "swad_text.h" + +/*****************************************************************************/ +/************** External global variables from others modules ****************/ +/*****************************************************************************/ + +extern struct Globals Gbl; + +/*****************************************************************************/ +/***************************** Private constants *****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/******************************* Private types *******************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Private variables *****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Private prototypes ****************************/ +/*****************************************************************************/ + +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_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); + +/*****************************************************************************/ +/*************************** List all my locations ***************************/ +/*****************************************************************************/ + +void Loc_SeeLocations (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_Location; + Loc_OrderType_t Order; + 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); + + /***** Write all the locations *****/ + for (NumLoc = 0; + NumLoc < Gbl.Usrs.Me.Locs.Num; + NumLoc++) + { + /* 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" + "" + "", + Gbl.Usrs.Me.Locs.Lst[NumLoc].Location); + } + + /***** End table *****/ + Lay_EndRoundFrameTable (); + + /***** Free list of locations *****/ + Loc_FreeListLocations (); + } + +/*****************************************************************************/ +/********* Get parameter with the type or order in list of locations *********/ +/*****************************************************************************/ + +static void Loc_GetParamLocOrderType (void) + { + char UnsignedStr[10+1]; + unsigned UnsignedNum; + + Par_GetParToText ("Order",UnsignedStr,10); + if (sscanf (UnsignedStr,"%u",&UnsignedNum) == 1) + Gbl.Usrs.Me.Locs.SelectedOrderType = (Loc_OrderType_t) UnsignedNum; + else + Gbl.Usrs.Me.Locs.SelectedOrderType = Loc_DEFAULT_ORDER_TYPE; + } + +/*****************************************************************************/ +/************************* Put icon to edit locations ************************/ +/*****************************************************************************/ + +static void Loc_PutIconToEditLocs (void) + { + extern const char *Txt_Edit; + + Lay_PutContextualLink (ActEdiLoc,NULL, + "edit64x64.png", + Txt_Edit,NULL, + NULL); + } + +/*****************************************************************************/ +/************************ Put forms to edit degree types *********************/ +/*****************************************************************************/ + +void Loc_EditLocations (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 (); + } + +/*****************************************************************************/ +/*************************** List all the locations **************************/ +/*****************************************************************************/ + +void Loc_GetListLocations (void) + { + char OrderBySubQuery[256]; + char Query[512]; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumLoc; + struct Location *Loc; + + if (Gbl.DB.DatabaseIsOpen) + { + 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; + } + } + +/*****************************************************************************/ +/************************* Get location data by code *************************/ +/*****************************************************************************/ + +static void Loc_GetDataOfLocationByCod (struct Location *Loc) + { + char Query[1024]; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + + /***** 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."); + + /***** 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... + { + /* 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 end date (row[1] holds the end date in YYYYMMDD format) */ + if (!(Dat_GetDateFromYYYYMMDD (&(Loc->EndDate),row[1]))) + Lay_ShowErrorAndExit ("Wrong end date."); + + /* Get the location (row[2]) */ + strcpy (Loc->Location,row[2]); + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + } + +/*****************************************************************************/ +/**************************** Free list of locations *************************/ +/*****************************************************************************/ + +void Loc_FreeListLocations (void) + { + if (Gbl.Usrs.Me.Locs.LstIsRead && Gbl.Usrs.Me.Locs.Lst) + { + /***** Free memory used by the list of courses in degree *****/ + free ((void *) Gbl.Usrs.Me.Locs.Lst); + Gbl.Usrs.Me.Locs.Lst = NULL; + Gbl.Usrs.Me.Locs.Num = 0; + Gbl.Usrs.Me.Locs.LstIsRead = false; + } + } + +/*****************************************************************************/ +/********************* List all the locations for edition ********************/ +/*****************************************************************************/ + +static void Loc_ListLocationsForEdition (void) + { + extern const char *Hlp_PROFILE_Location_edit; + extern const char *Txt_Locations; + unsigned NumLoc; + struct Location *Loc; + + Lay_StartRoundFrameTable (NULL,Txt_Locations, + NULL,Hlp_PROFILE_Location_edit,2); + + /***** Table head *****/ + Loc_PutHeadLocations (); + + /***** Write all the locations *****/ + for (NumLoc = 0; + NumLoc < Gbl.Usrs.Me.Locs.Num; + NumLoc++) + { + 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,"" + ""); + } + + Lay_EndRoundFrameTable (); + } + +/*****************************************************************************/ +/******************** Write parameter with code of location ******************/ +/*****************************************************************************/ + +static void Loc_PutParamLocCod (long LocCod) + { + Par_PutHiddenParamLong ("LocCod",LocCod); + } + +/*****************************************************************************/ +/********************* Get parameter with code of location *******************/ +/*****************************************************************************/ + +long Loc_GetParamLocCod (void) + { + char LongStr[1+10+1]; + + /***** Get parameter with code of location *****/ + Par_GetParToText ("LocCod",LongStr,1+10); + return Str_ConvertStrCodToLongCod (LongStr); + } + +/*****************************************************************************/ +/******************************* Remove a location ***************************/ +/*****************************************************************************/ + +void Loc_RemoveLocation (void) + { + extern const char *Txt_Location_removed; + char Query[128]; + 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); + + /***** Remove location *****/ + sprintf (Query,"DELETE FROM locations WHERE LocCod='%ld'",Loc.LocCod); + DB_QueryDELETE (Query,"can not remove a location"); + + /***** Write message to show the change made *****/ + sprintf (Gbl.Message,Txt_Location_removed,Loc.Location); + Lay_ShowAlert (Lay_SUCCESS,Gbl.Message); + + /***** Show the form again *****/ + Loc_EditLocations (); + } + +/*****************************************************************************/ +/******************* Change the start date of a location *********************/ +/*****************************************************************************/ + +void Loc_ChangeStartDate (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; + char Query[512]; + struct Location *Loc; + struct Date NewDate; + struct Date *PtrDate = NULL; // Initialized to avoid warning + const char *StrStartOrEndDate; + char StrDate[11]; + + Loc = &Gbl.Usrs.Me.Locs.EditingLoc; + + /***** Get the code of the location *****/ + if ((Loc->LocCod = Loc_GetParamLocCod ()) == -1L) + Lay_ShowErrorAndExit ("Code of location is missing."); + + /***** Get from the database the data of the location *****/ + Loc_GetDataOfLocationByCod (Loc); + + /***** Get the new date for the location *****/ + switch (StartOrEndDate) + { + 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; + } + + /***** 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"); + + /***** 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); + } + + /***** 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); + + /***** Start of frame *****/ + Lay_StartRoundFrameTable (NULL,Txt_New_location, + NULL,Hlp_PROFILE_Location_edit,2); + + /***** Table head *****/ + Loc_PutHeadLocations (); + + /***** Put disabled icon to remove centre *****/ + 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,"" + "" + "" + "" + "", + Loc_MAX_LENGTH_LOCATION,Loc->Location); + + /***** 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; + + fprintf (Gbl.F.Out,"" + "" + "" + "%s" + "" + "" + "%s" + "" + "" + "%s" + "" + "", + Txt_Start_date, + Txt_End_date, + Txt_Location); + } + +/*****************************************************************************/ +/******************* Receive form to create a new location *******************/ +/*****************************************************************************/ + +void Loc_RecFormNewLocation (void) + { + extern const char *Txt_You_must_specify_the_new_location; + struct Location *Loc; + + Loc = &Gbl.Usrs.Me.Locs.EditingLoc; + + /***** 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); + + /***** 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 location *****/ + Par_GetParToText ("Location",Loc->Location,Loc_MAX_LENGTH_LOCATION); + + /***** 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); + + /***** Show the form again *****/ + Loc_EditLocations (); + } + +/*****************************************************************************/ +/**************************** Create a new location **************************/ +/*****************************************************************************/ + +static void Loc_CreateLocation (struct Location *Loc) + { + extern const char *Txt_Created_new_location; + char Query[256+Loc_MAX_LENGTH_LOCATION]; + + /***** 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); + } diff --git a/swad_location.h b/swad_location.h new file mode 100644 index 000000000..e29dfe247 --- /dev/null +++ b/swad_location.h @@ -0,0 +1,77 @@ +// swad_location.h: teacher's location + +#ifndef _SWAD_LOC +#define _SWAD_LOC +/* + SWAD (Shared Workspace At a Distance in Spanish), + is a web platform developed at the University of Granada (Spain), + and used to support university teaching. + + This file is part of SWAD core. + Copyright (C) 1999-2016 Antonio Cañas Vargas + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +/*****************************************************************************/ +/********************************* Headers ***********************************/ +/*****************************************************************************/ + +#include "swad_date.h" +#include "swad_place.h" + +/*****************************************************************************/ +/************************** Public types and constants ***********************/ +/*****************************************************************************/ + +#define Loc_MAX_LENGTH_LOCATION 255 + +typedef enum + { + LOC_START_DATE, + LOC_END_DATE + } Loc_StartOrEndDate_t; + +struct Location + { + long LocCod; + struct Date StartDate; + struct Date EndDate; + char Location[Loc_MAX_LENGTH_LOCATION+1]; + }; + +typedef enum + { + Loc_ORDER_BY_START_DATE = 0, + Loc_ORDER_BY_END_DATE = 1, + } Loc_OrderType_t; + +#define Loc_DEFAULT_ORDER_TYPE Loc_ORDER_BY_START_DATE + +/*****************************************************************************/ +/***************************** Public prototypes *****************************/ +/*****************************************************************************/ + +void Loc_SeeLocations (void); +void Loc_EditLocations (void); +void Loc_GetListLocations (void); +void Loc_FreeListLocations (void); + +long Loc_GetParamLocCod (void); +void Loc_RemoveLocation (void); +void Loc_ChangeStartDate (void); +void Loc_ChangeEndDate (void); +void Loc_RenameLocation (void); +void Loc_RecFormNewLocation (void); + +#endif diff --git a/swad_text.c b/swad_text.c index 3c2fb78da..42ed3f28f 100644 --- a/swad_text.c +++ b/swad_text.c @@ -6296,6 +6296,27 @@ const char *Txt_Create_link = "Criar ligação"; #endif +const char *Txt_Create_location = +#if L==1 + "Crear ubicació"; +#elif L==2 + "Standort eingeben"; +#elif L==3 + "Create location"; +#elif L==4 + "Crear ubicación"; +#elif L==5 + "Créer emplacement"; +#elif L==6 + "Crear ubicación"; // Okoteve traducción +#elif L==7 + "Crea posizione"; +#elif L==8 + "Tworzenie lokalizację"; +#elif L==9 + "Criar localização"; +#endif + const char *Txt_Create_notice = #if L==1 "Crear avís"; @@ -6821,6 +6842,27 @@ 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 = +#if L==1 + "Creada nova ubicació."; +#elif L==2 + "Neuer Standort eingegeben."; +#elif L==3 + "Created new location."; +#elif L==4 + "Creada nueva ubicación."; +#elif L==5 + "Créé nouvel emplacement."; +#elif L==6 + "Creada nueva ubicación."; // Okoteve traducción +#elif L==7 + "Creata nuova posizione."; +#elif L==8 + "Utworzono nowe lokacja."; +#elif L==9 + "Criado nova localização."; +#endif + const char *Txt_Created_new_place_X = // Warning: it is very important to include %s in the following sentences #if L==1 "Creado nuevo lugar %s."; // Necessita traduccio @@ -17049,25 +17091,153 @@ const char *Txt_Local_address = const char *Txt_Location = #if L==1 - "Lloc"; + "Ubicació"; #elif L==2 "Standort"; #elif L==3 "Location"; #elif L==4 - "Sitio"; + "Ubicación"; #elif L==5 "Emplacement"; #elif L==6 - "Sitio"; // Okoteve traducción + "Ubicación"; // Okoteve traducción #elif L==7 - "Locazione"; + "Posizione"; #elif L==8 - "Lokalizacja"; + "Lokacja"; #elif L==9 - "Site"; + "Localização"; #endif +const char *Txt_Location_removed = +#if L==1 + "Ubicació eliminada."; +#elif L==2 + "Standort entfernt."; +#elif L==3 + "Location removed."; +#elif L==4 + "Ubicación eliminada."; +#elif L==5 + "Emplacement supprimé."; +#elif L==6 + "Ubicación eliminada."; // Okoteve traducción +#elif L==7 + "Posizione rimossa."; +#elif L==8 + "Lokacja usuniete."; +#elif L==9 + "Localização removida."; +#endif + +const char *Txt_Locations = +#if L==1 + "Ubicacions"; +#elif L==2 + "Standorte"; +#elif L==3 + "Locations"; +#elif L==4 + "Ubicaciones"; +#elif L==5 + "Emplacements"; +#elif L==6 + "Ubicación"; // Okoteve traducción +#elif L==7 + "Posizioni"; +#elif L==8 + "Lokalizacje"; +#elif L==9 + "Localizações"; +#endif + +const char *Txt_LOCATIONS_HELP_ORDER[2] = + { +#if L==1 + "Ordenar por fecha inicial" // Necessita traduccio +#elif L==2 + "Sortieren nach Startdatum" +#elif L==3 + "Sort by start date" +#elif L==4 + "Ordenar por fecha inicial" +#elif L==5 + "Trier par date initiale" +#elif L==6 + "Ordenar por fecha inicial" // Okoteve traducción +#elif L==7 + "Ordina per data iniziale" +#elif L==8 + "Sortuj wedlug daty rozpoczecia" +#elif L==9 + "Classificar por data de início" +#endif + , +#if L==1 + "Ordenar por fecha final" // Necessita traduccio +#elif L==2 + "Sortieren nach Enddatum" +#elif L==3 + "Sort by end date" +#elif L==4 + "Ordenar por fecha final" +#elif L==5 + "Trier par date finale" +#elif L==6 + "Ordenar por fecha final" // Okoteve traducción +#elif L==7 + "Ordina per data finale" +#elif L==8 + "Sortuj wedlug daty koncowa" +#elif L==9 + "Classificar por data final" +#endif + }; + +const char *Txt_LOCATIONS_ORDER[2] = + { +#if L==1 + "Data inicial" +#elif L==2 + "Startdatum" +#elif L==3 + "Start date" +#elif L==4 + "Fecha inicial" +#elif L==5 + "Date initiale" +#elif L==6 + "Fecha inicial" // Okoteve traducción +#elif L==7 + "Data iniziale" +#elif L==8 + "Data rozpoczecia" +#elif L==9 + "Data de início" +#endif + , +#if L==1 + "Data final" +#elif L==2 + "Enddatum" +#elif L==3 + "End date" +#elif L==4 + "Fecha final" +#elif L==5 + "Date finale" +#elif L==6 + "Fecha final" // Okoteve traducción +#elif L==7 + "Data finale" +#elif L==8 + "Data koncowa" +#elif L==9 + "Data final" +#endif + }; + const char *Txt_LOG_More_info = #if L==1 "Observaciones"; // Necessita traduccio @@ -23502,6 +23672,27 @@ const char *Txt_New_link = "Nova ligação"; #endif +const char *Txt_New_location = +#if L==1 + "Nova ubicació"; +#elif L==2 + "Neue Standort"; +#elif L==3 + "New location"; +#elif L==4 + "Nueva ubicación"; +#elif L==5 + "Nouvel emplacement"; +#elif L==6 + "Nueva ubicación"; // Okoteve traducción +#elif L==7 + "Nuova posizione"; +#elif L==8 + "Nowe lokacja"; +#elif L==9 + "Nova localização"; +#endif + const char *Txt_New_message = #if L==1 "Nou missatge"; @@ -42096,6 +42287,27 @@ 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 @@ -43119,6 +43331,27 @@ const char *Txt_The_institution_X_already_exists = // Warning: it is very import "The institution %s already exists."; // Necessita de tradução #endif +const char *Txt_The_institution_X_has_been_renamed_as_Y = // Warning: it is very important to include two %s in the following sentences +#if L==1 + "La institución %s ha pasado a denominarse %s."; // Necessita traduccio +#elif L==2 + "The institution %s has been renamed as %s."; // Need Übersetzung +#elif L==3 + "The institution %s has been renamed as %s."; +#elif L==4 + "La institución %s ha pasado a denominarse %s."; +#elif L==5 + "The institution %s has been renamed as %s."; // Besoin de traduction +#elif L==6 + "La institución %s ha pasado a denominarse %s."; // Okoteve traducción +#elif L==7 + "L'istituzione %s è stata rinominata %s."; +#elif L==8 + "The institution %s has been renamed as %s."; // Potrzebujesz tlumaczenie +#elif L==9 + "The institution %s has been renamed as %s."; // Necessita de tradução +#endif + const char *Txt_The_institution_of_the_centre_has_changed = #if L==1 "La institución del centro ha cambiado."; // Necessita traduccio @@ -43347,6 +43580,48 @@ 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" @@ -43782,27 +44057,6 @@ const char *Txt_The_name_of_the_holiday_X_has_not_changed = // Warning: it is ve "The name of the holiday %s has not changed."; // Necessita de tradução #endif -const char *Txt_The_institution_X_has_been_renamed_as_Y = // Warning: it is very important to include two %s in the following sentences -#if L==1 - "La institución %s ha pasado a denominarse %s."; // Necessita traduccio -#elif L==2 - "The institution %s has been renamed as %s."; // Need Übersetzung -#elif L==3 - "The institution %s has been renamed as %s."; -#elif L==4 - "La institución %s ha pasado a denominarse %s."; -#elif L==5 - "The institution %s has been renamed as %s."; // Besoin de traduction -#elif L==6 - "La institución %s ha pasado a denominarse %s."; // Okoteve traducción -#elif L==7 - "L'istituzione %s è stata rinominata %s."; -#elif L==8 - "The institution %s has been renamed as %s."; // Potrzebujesz tlumaczenie -#elif L==9 - "The institution %s has been renamed as %s."; // Necessita de tradução -#endif - const char *Txt_The_name_of_the_institution_X_has_not_changed = // Warning: it is very important to include %s in the following sentences #if L==1 "El nombre de la institución %s no ha cambiado."; // Necessita traduccio @@ -46380,6 +46634,27 @@ 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 @@ -51894,6 +52169,27 @@ 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 @@ -52095,6 +52391,36 @@ const char *Txt_You_can_not_leave_the_name_of_the_department_X_empty = // Warnin " of the department %s empty."; // Necessita de tradução #endif +const char *Txt_You_can_not_leave_the_name_of_the_email_domain_X_empty = // Warning: it is very important to include %s in the following sentences +#if L==1 + "No puede dejar el nombre " + "del dominio de correo %s vacío."; // Necessita traduccio +#elif L==2 + "You can not leave the name" + " of the email domain %s empty."; // Need Übersetzung +#elif L==3 + "You can not leave the name" + " of the email domain %s empty."; +#elif L==4 + "No puede dejar el nombre" + " del dominio de correo %s vacío."; +#elif L==5 + "You can not leave the name" + " of the email domain %s empty."; // Besoin de traduction +#elif L==6 + "No puede dejar el nombre" + " del dominio de correo %s vacío."; // Okoteve traducción +#elif L==7 + "Non puoi lasciare il nome" + " del campo mail %s vuoto."; +#elif L==8 + "You can not leave the name" + " of the email domain %s empty."; // Potrzebujesz tlumaczenie +#elif L==9 + "You can not leave the name" + " of the email domain %s empty."; // Necessita de tradução +#endif + const char *Txt_You_can_not_leave_the_name_of_the_field_X_empty = // Warning: it is very important to include %s in the following sentences #if L==1 "No puede dejar el nombre" @@ -52245,36 +52571,6 @@ const char *Txt_You_can_not_leave_the_name_of_the_link_X_empty = // Warning: it " of the link %s empty."; // Necessita de tradução #endif -const char *Txt_You_can_not_leave_the_name_of_the_email_domain_X_empty = // Warning: it is very important to include %s in the following sentences -#if L==1 - "No puede dejar el nombre " - "del dominio de correo %s vacío."; // Necessita traduccio -#elif L==2 - "You can not leave the name" - " of the email domain %s empty."; // Need Übersetzung -#elif L==3 - "You can not leave the name" - " of the email domain %s empty."; -#elif L==4 - "No puede dejar el nombre" - " del dominio de correo %s vacío."; -#elif L==5 - "You can not leave the name" - " of the email domain %s empty."; // Besoin de traduction -#elif L==6 - "No puede dejar el nombre" - " del dominio de correo %s vacío."; // Okoteve traducción -#elif L==7 - "Non puoi lasciare il nome" - " del campo mail %s vuoto."; -#elif L==8 - "You can not leave the name" - " of the email domain %s empty."; // Potrzebujesz tlumaczenie -#elif L==9 - "You can not leave the name" - " of the email domain %s empty."; // Necessita de tradução -#endif - const char *Txt_You_can_not_leave_the_name_of_the_place_X_empty = // Warning: it is very important to include %s in the following sentences #if L==1 "No puede dejar el nombre" @@ -53796,6 +54092,27 @@ 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"