diff --git a/sql/swad.sql b/sql/swad.sql index 0e0db93a..12780095 100644 --- a/sql/swad.sql +++ b/sql/swad.sql @@ -512,14 +512,14 @@ CREATE TABLE IF NOT EXISTS exa_participants ( TS TIMESTAMP, UNIQUE INDEX(EvtCod,UsrCod)); -- --- Table exa_questions: stores the questions in the exams +-- Table exa_questions: stores the questions in the set of questions for exams -- CREATE TABLE IF NOT EXISTS exa_questions ( SetCod INT NOT NULL, + QstInd INT NOT NULL, QstCod INT NOT NULL, - QstInd INT NOT NULL DEFAULT 0, - INDEX(SetCod), - INDEX(QstCod)); + UNIQUE INDEX(SetCod,QstInd), + UNIQUE INDEX(SetCod,QstCod)); -- -- Table exa_results: stores exam results -- diff --git a/swad_action.c b/swad_action.c index 3854cfcd..57ce9adf 100644 --- a/swad_action.c +++ b/swad_action.c @@ -727,13 +727,11 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = [ActChgTitExaSet ] = {1897,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaSet_ChangeSetTitle ,NULL}, [ActChgNumQstExaSet ] = {1899,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaSet_ChangeNumQstsToExam ,NULL}, - [ActAddOneExaQst ] = {1885,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Dat_SetIniEndDates ,Exa_RequestNewQuestion ,NULL}, - [ActLstTstQstForExa ] = {1886,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Exa_ListQuestionsToSelect ,NULL}, - [ActAddQstToExa ] = {1887,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Exa_AddQuestionsToExam ,NULL}, + [ActReqAddQstExaSet ] = {1885,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Dat_SetIniEndDates ,ExaSet_ReqSelectQstsToAddToSet ,NULL}, + [ActLstTstQstForSet ] = {1886,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaSet_ListQstsToAddToSet ,NULL}, + [ActAddQstToExa ] = {1887,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaSet_AddQstsToSet ,NULL}, [ActReqRemExaQst ] = {1888,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Exa_RequestRemoveQst ,NULL}, [ActRemExaQst ] = {1889,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Exa_RemoveQst ,NULL}, - [ActUp_ExaQst ] = {1890,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Exa_MoveUpQst ,NULL}, - [ActDwnExaQst ] = {1891,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Exa_MoveDownQst ,NULL}, [ActSeeGam ] = {1650,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_SeeOneGame ,NULL}, @@ -777,9 +775,9 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = [ActRemGam ] = {1657,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RemoveGame ,NULL}, [ActHidGam ] = {1660,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_HideGame ,NULL}, [ActShoGam ] = {1661,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_UnhideGame ,NULL}, - [ActAddOneGamQst ] = {1662,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Dat_SetIniEndDates ,Gam_RequestNewQuestion ,NULL}, - [ActGamLstTstQst ] = {1666,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_ListTstQuestionsToSelect ,NULL}, - [ActAddTstQstToGam ] = {1667,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_AddTstQuestionsToGame ,NULL}, + [ActAddOneGamQst ] = {1662,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Dat_SetIniEndDates ,Gam_ReqSelectQstsToAddToGame ,NULL}, + [ActGamLstTstQst ] = {1666,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_ListQstsToAddToGame ,NULL}, + [ActAddTstQstToGam ] = {1667,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_AddQstsToGame ,NULL}, [ActReqRemGamQst ] = {1664,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RequestRemoveQst ,NULL}, [ActRemGamQst ] = {1665,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RemoveQst ,NULL}, [ActUp_GamQst ] = {1668,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_MoveUpQst ,NULL}, @@ -802,15 +800,15 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = [ActReqRemSvyQst ] = {1524,-1,TabUnk,ActSeeAllSvy ,0x3E0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Svy_RequestRemoveQst ,NULL}, [ActRemSvyQst ] = { 981,-1,TabUnk,ActSeeAllSvy ,0x3E0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Svy_RemoveQst ,NULL}, - [ActSeeOneExaAnn ] = {1572,-1,TabUnk,ActSeeAllExaAnn ,0x3F8,0x3C7, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaAnn_ListExamAnnouncementsCod ,NULL}, - [ActSeeDatExaAnn ] = {1571,-1,TabUnk,ActSeeAllExaAnn ,0x3F8,0x3C7, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaAnn_ListExamAnnouncementsDay ,NULL}, + [ActSeeOneExaAnn ] = {1572,-1,TabUnk,ActSeeAllExaAnn ,0x3F8,0x3C7, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaAnn_ListExamAnnouncementsCod,NULL}, + [ActSeeDatExaAnn ] = {1571,-1,TabUnk,ActSeeAllExaAnn ,0x3F8,0x3C7, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaAnn_ListExamAnnouncementsDay,NULL}, [ActEdiExaAnn ] = { 91,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaAnn_PutFrmEditAExamAnnouncement,NULL}, - [ActRcvExaAnn ] = { 110,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,ExaAnn_ReceiveExamAnnouncement1 ,ExaAnn_ReceiveExamAnnouncement2 ,NULL}, + [ActRcvExaAnn ] = { 110,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,ExaAnn_ReceiveExamAnnouncement1,ExaAnn_ReceiveExamAnnouncement2,NULL}, [ActPrnExaAnn ] = { 179,-1,TabUnk,ActSeeAllExaAnn ,0x3F8,0x3C7, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,ExaAnn_PrintExamAnnouncement ,NULL}, - [ActReqRemExaAnn ] = {1619,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaAnn_ReqRemoveExamAnnouncement ,NULL}, + [ActReqRemExaAnn ] = {1619,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaAnn_ReqRemoveExamAnnouncement,NULL}, [ActRemExaAnn ] = { 187,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,ExaAnn_RemoveExamAnnouncement1 ,ExaAnn_RemoveExamAnnouncement2 ,NULL}, - [ActHidExaAnn ] = {1620,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,ExaAnn_HideExamAnnouncement ,ExaAnn_ListExamAnnouncementsEdit ,NULL}, - [ActShoExaAnn ] = {1621,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,ExaAnn_UnhideExamAnnouncement ,ExaAnn_ListExamAnnouncementsEdit ,NULL}, + [ActHidExaAnn ] = {1620,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,ExaAnn_HideExamAnnouncement ,ExaAnn_ListExamAnnouncementsEdit,NULL}, + [ActShoExaAnn ] = {1621,-1,TabUnk,ActSeeAllExaAnn ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,ExaAnn_UnhideExamAnnouncement ,ExaAnn_ListExamAnnouncementsEdit,NULL}, // TabFil ****************************************************************** // Actions in menu: @@ -3697,13 +3695,13 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActRemExa, // #1882 ActHidExa, // #1883 ActShoExa, // #1884 - ActAddOneExaQst, // #1885 - ActLstTstQstForExa, // #1886 + ActReqAddQstExaSet, // #1885 + ActLstTstQstForSet, // #1886 ActAddQstToExa, // #1887 ActReqRemExaQst, // #1888 ActRemExaQst, // #1889 - ActUp_ExaQst, // #1890 - ActDwnExaQst, // #1891 + -1, // #1890 (obsolete action) + -1, // #1891 (obsolete action) ActFrmNewExaSet, // #1892 ActReqRemExaSet, // #1893 ActRemExaSet, // #1894 diff --git a/swad_action.h b/swad_action.h index 8a3bef2c..2fd15ab9 100644 --- a/swad_action.h +++ b/swad_action.h @@ -692,89 +692,87 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActChgTitExaSet (ActChgCrsTT1stDay + 165) #define ActChgNumQstExaSet (ActChgCrsTT1stDay + 166) -#define ActAddOneExaQst (ActChgCrsTT1stDay + 167) -#define ActLstTstQstForExa (ActChgCrsTT1stDay + 168) +#define ActReqAddQstExaSet (ActChgCrsTT1stDay + 167) +#define ActLstTstQstForSet (ActChgCrsTT1stDay + 168) #define ActAddQstToExa (ActChgCrsTT1stDay + 169) #define ActReqRemExaQst (ActChgCrsTT1stDay + 170) #define ActRemExaQst (ActChgCrsTT1stDay + 171) -#define ActUp_ExaQst (ActChgCrsTT1stDay + 172) -#define ActDwnExaQst (ActChgCrsTT1stDay + 173) -#define ActSeeGam (ActChgCrsTT1stDay + 174) -#define ActReqRemMch (ActChgCrsTT1stDay + 175) -#define ActRemMch (ActChgCrsTT1stDay + 176) -#define ActReqNewMch (ActChgCrsTT1stDay + 177) -#define ActNewMch (ActChgCrsTT1stDay + 178) -#define ActResMch (ActChgCrsTT1stDay + 179) -#define ActBckMch (ActChgCrsTT1stDay + 180) -#define ActPlyPauMch (ActChgCrsTT1stDay + 181) -#define ActFwdMch (ActChgCrsTT1stDay + 182) -#define ActChgNumColMch (ActChgCrsTT1stDay + 183) -#define ActChgVisResMchQst (ActChgCrsTT1stDay + 184) -#define ActMchCntDwn (ActChgCrsTT1stDay + 185) -#define ActRefMchTch (ActChgCrsTT1stDay + 186) +#define ActSeeGam (ActChgCrsTT1stDay + 172) +#define ActReqRemMch (ActChgCrsTT1stDay + 173) +#define ActRemMch (ActChgCrsTT1stDay + 174) +#define ActReqNewMch (ActChgCrsTT1stDay + 175) +#define ActNewMch (ActChgCrsTT1stDay + 176) +#define ActResMch (ActChgCrsTT1stDay + 177) +#define ActBckMch (ActChgCrsTT1stDay + 178) +#define ActPlyPauMch (ActChgCrsTT1stDay + 179) +#define ActFwdMch (ActChgCrsTT1stDay + 180) +#define ActChgNumColMch (ActChgCrsTT1stDay + 181) +#define ActChgVisResMchQst (ActChgCrsTT1stDay + 182) +#define ActMchCntDwn (ActChgCrsTT1stDay + 183) +#define ActRefMchTch (ActChgCrsTT1stDay + 184) -#define ActJoiMch (ActChgCrsTT1stDay + 187) -#define ActSeeMchAnsQstStd (ActChgCrsTT1stDay + 188) -#define ActRemMchAnsQstStd (ActChgCrsTT1stDay + 189) -#define ActAnsMchQstStd (ActChgCrsTT1stDay + 190) -#define ActRefMchStd (ActChgCrsTT1stDay + 191) +#define ActJoiMch (ActChgCrsTT1stDay + 185) +#define ActSeeMchAnsQstStd (ActChgCrsTT1stDay + 186) +#define ActRemMchAnsQstStd (ActChgCrsTT1stDay + 187) +#define ActAnsMchQstStd (ActChgCrsTT1stDay + 188) +#define ActRefMchStd (ActChgCrsTT1stDay + 189) -#define ActSeeMyMchResCrs (ActChgCrsTT1stDay + 192) -#define ActSeeMyMchResGam (ActChgCrsTT1stDay + 193) -#define ActSeeMyMchResMch (ActChgCrsTT1stDay + 194) -#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 195) +#define ActSeeMyMchResCrs (ActChgCrsTT1stDay + 190) +#define ActSeeMyMchResGam (ActChgCrsTT1stDay + 191) +#define ActSeeMyMchResMch (ActChgCrsTT1stDay + 192) +#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 193) -#define ActReqSeeAllMchRes (ActChgCrsTT1stDay + 196) -#define ActSeeAllMchResCrs (ActChgCrsTT1stDay + 197) -#define ActSeeAllMchResGam (ActChgCrsTT1stDay + 198) -#define ActSeeAllMchResMch (ActChgCrsTT1stDay + 199) -#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 200) +#define ActReqSeeAllMchRes (ActChgCrsTT1stDay + 194) +#define ActSeeAllMchResCrs (ActChgCrsTT1stDay + 195) +#define ActSeeAllMchResGam (ActChgCrsTT1stDay + 196) +#define ActSeeAllMchResMch (ActChgCrsTT1stDay + 197) +#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 198) -#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 201) +#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 199) -#define ActFrmNewGam (ActChgCrsTT1stDay + 202) -#define ActEdiOneGam (ActChgCrsTT1stDay + 203) -#define ActNewGam (ActChgCrsTT1stDay + 204) -#define ActChgGam (ActChgCrsTT1stDay + 205) -#define ActReqRemGam (ActChgCrsTT1stDay + 206) -#define ActRemGam (ActChgCrsTT1stDay + 207) -#define ActHidGam (ActChgCrsTT1stDay + 208) -#define ActShoGam (ActChgCrsTT1stDay + 209) -#define ActAddOneGamQst (ActChgCrsTT1stDay + 210) -#define ActGamLstTstQst (ActChgCrsTT1stDay + 211) -#define ActAddTstQstToGam (ActChgCrsTT1stDay + 212) -#define ActReqRemGamQst (ActChgCrsTT1stDay + 213) -#define ActRemGamQst (ActChgCrsTT1stDay + 214) -#define ActUp_GamQst (ActChgCrsTT1stDay + 215) -#define ActDwnGamQst (ActChgCrsTT1stDay + 216) +#define ActFrmNewGam (ActChgCrsTT1stDay + 200) +#define ActEdiOneGam (ActChgCrsTT1stDay + 201) +#define ActNewGam (ActChgCrsTT1stDay + 202) +#define ActChgGam (ActChgCrsTT1stDay + 203) +#define ActReqRemGam (ActChgCrsTT1stDay + 204) +#define ActRemGam (ActChgCrsTT1stDay + 205) +#define ActHidGam (ActChgCrsTT1stDay + 206) +#define ActShoGam (ActChgCrsTT1stDay + 207) +#define ActAddOneGamQst (ActChgCrsTT1stDay + 208) +#define ActGamLstTstQst (ActChgCrsTT1stDay + 209) +#define ActAddTstQstToGam (ActChgCrsTT1stDay + 210) +#define ActReqRemGamQst (ActChgCrsTT1stDay + 211) +#define ActRemGamQst (ActChgCrsTT1stDay + 212) +#define ActUp_GamQst (ActChgCrsTT1stDay + 213) +#define ActDwnGamQst (ActChgCrsTT1stDay + 214) -#define ActSeeSvy (ActChgCrsTT1stDay + 217) -#define ActAnsSvy (ActChgCrsTT1stDay + 218) -#define ActFrmNewSvy (ActChgCrsTT1stDay + 219) -#define ActEdiOneSvy (ActChgCrsTT1stDay + 220) -#define ActNewSvy (ActChgCrsTT1stDay + 221) -#define ActChgSvy (ActChgCrsTT1stDay + 222) -#define ActReqRemSvy (ActChgCrsTT1stDay + 223) -#define ActRemSvy (ActChgCrsTT1stDay + 224) -#define ActReqRstSvy (ActChgCrsTT1stDay + 225) -#define ActRstSvy (ActChgCrsTT1stDay + 226) -#define ActHidSvy (ActChgCrsTT1stDay + 227) -#define ActShoSvy (ActChgCrsTT1stDay + 228) -#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 229) -#define ActRcvSvyQst (ActChgCrsTT1stDay + 230) -#define ActReqRemSvyQst (ActChgCrsTT1stDay + 231) -#define ActRemSvyQst (ActChgCrsTT1stDay + 232) +#define ActSeeSvy (ActChgCrsTT1stDay + 215) +#define ActAnsSvy (ActChgCrsTT1stDay + 216) +#define ActFrmNewSvy (ActChgCrsTT1stDay + 217) +#define ActEdiOneSvy (ActChgCrsTT1stDay + 218) +#define ActNewSvy (ActChgCrsTT1stDay + 219) +#define ActChgSvy (ActChgCrsTT1stDay + 220) +#define ActReqRemSvy (ActChgCrsTT1stDay + 221) +#define ActRemSvy (ActChgCrsTT1stDay + 222) +#define ActReqRstSvy (ActChgCrsTT1stDay + 223) +#define ActRstSvy (ActChgCrsTT1stDay + 224) +#define ActHidSvy (ActChgCrsTT1stDay + 225) +#define ActShoSvy (ActChgCrsTT1stDay + 226) +#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 227) +#define ActRcvSvyQst (ActChgCrsTT1stDay + 228) +#define ActReqRemSvyQst (ActChgCrsTT1stDay + 229) +#define ActRemSvyQst (ActChgCrsTT1stDay + 230) -#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 233) -#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 234) -#define ActEdiExaAnn (ActChgCrsTT1stDay + 235) -#define ActRcvExaAnn (ActChgCrsTT1stDay + 236) -#define ActPrnExaAnn (ActChgCrsTT1stDay + 237) -#define ActReqRemExaAnn (ActChgCrsTT1stDay + 238) -#define ActRemExaAnn (ActChgCrsTT1stDay + 239) -#define ActHidExaAnn (ActChgCrsTT1stDay + 240) -#define ActShoExaAnn (ActChgCrsTT1stDay + 241) +#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 231) +#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 232) +#define ActEdiExaAnn (ActChgCrsTT1stDay + 233) +#define ActRcvExaAnn (ActChgCrsTT1stDay + 234) +#define ActPrnExaAnn (ActChgCrsTT1stDay + 235) +#define ActReqRemExaAnn (ActChgCrsTT1stDay + 236) +#define ActRemExaAnn (ActChgCrsTT1stDay + 237) +#define ActHidExaAnn (ActChgCrsTT1stDay + 238) +#define ActShoExaAnn (ActChgCrsTT1stDay + 239) /*****************************************************************************/ /******************************** Files tab **********************************/ diff --git a/swad_changelog.h b/swad_changelog.h index 06530ac1..ca315e77 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -544,10 +544,18 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.201 (2020-04-27)" +#define Log_PLATFORM_VERSION "SWAD 19.202 (2020-04-27)" #define CSS_FILE "swad19.193.1.css" #define JS_FILE "swad19.193.1.js" /* + Version 19.202: Apr 27, 2020 Form to add questions to set of questions. (300558 lines) + 5 changes necessary in database: +ALTER TABLE exa_questions CHANGE COLUMN QstInd QstInd INT NOT NULL AFTER SetCod; +ALTER TABLE exa_questions DROP INDEX SetCod; +ALTER TABLE exa_questions DROP INDEX QstCod; +ALTER TABLE exa_questions ADD UNIQUE INDEX(SetCod,QstInd); +ALTER TABLE exa_questions ADD UNIQUE INDEX(SetCod,QstCod); + Version 19.201: Apr 27, 2020 Form to change number of questions in exam. Code refactoring in HTML forms. (300755 lines) Version 19.200: Apr 27, 2020 Text of actions related to exams. @@ -560,7 +568,7 @@ ALTER TABLE exa_sets DROP INDEX ExaCod; ALTER TABLE exa_sets ADD UNIQUE INDEX(ExaCod,SetInd); Version 19.199.2: Apr 27, 2020 Changes moving questions in a game up and down. (299345 lines) - 4 changes necessary in database: + 5 changes necessary in database: ALTER TABLE gam_questions CHANGE COLUMN QstInd QstInd INT NOT NULL DEFAULT 0 AFTER GamCod; ALTER TABLE gam_questions DROP INDEX GamCod; ALTER TABLE gam_questions DROP INDEX QstCod; diff --git a/swad_database.c b/swad_database.c index 3f859828..70318d77 100644 --- a/swad_database.c +++ b/swad_database.c @@ -1143,18 +1143,18 @@ mysql> DESCRIBE exa_questions; +--------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+---------+------+-----+---------+-------+ -| SetCod | int(11) | NO | MUL | NULL | | -| QstCod | int(11) | NO | MUL | NULL | | -| QstInd | int(11) | NO | | 0 | | +| SetCod | int(11) | NO | PRI | NULL | | +| QstInd | int(11) | NO | PRI | NULL | | +| QstCod | int(11) | NO | | NULL | | +--------+---------+------+-----+---------+-------+ 3 rows in set (0.00 sec) */ DB_CreateTable ("CREATE TABLE IF NOT EXISTS exa_questions (" "SetCod INT NOT NULL," + "QstInd INT NOT NULL," "QstCod INT NOT NULL," - "QstInd INT NOT NULL DEFAULT 0," - "INDEX(SetCod)," - "INDEX(QstCod))"); + "UNIQUE INDEX(SetCod,QstInd)," + "UNIQUE INDEX(SetCod,QstCod))"); /***** Table exa_results *****/ /* diff --git a/swad_exam.c b/swad_exam.c index b9175b85..bca5ee31 100644 --- a/swad_exam.c +++ b/swad_exam.c @@ -64,8 +64,8 @@ extern struct Globals Gbl; #define Exa_MAX_ANSWERS_PER_QUESTION 10 -#define Exa_MAX_SELECTED_QUESTIONS 10000 -#define Exa_MAX_BYTES_LIST_SELECTED_QUESTIONS (Exa_MAX_SELECTED_QUESTIONS * (Cns_MAX_DECIMAL_DIGITS_LONG + 1)) +#define ExaSet_MAX_SELECTED_QUESTIONS 10000 +#define ExaSet_MAX_BYTES_LIST_SELECTED_QUESTIONS (ExaSet_MAX_SELECTED_QUESTIONS * (Cns_MAX_DECIMAL_DIGITS_LONG + 1)) /* Score range [0...max.score] will be converted to @@ -130,7 +130,6 @@ static void Exa_PutFormsToRemEditOneExam (struct Exa_Exams *Exams, const struct Exa_Exam *Exam, const char *Anchor); -static void ExaSet_PutParamsOneSet (void *Exams); static void Exa_PutParamsOneQst (void *Exams); static void Exa_PutHiddenParamOrder (Exa_Order_t SelectedOrder); static Exa_Order_t Exa_GetParamOrder (void); @@ -182,7 +181,7 @@ static unsigned ExaSet_GetSetIndFromSetCod (long ExaCod,long SetCod); static long ExaSet_GetSetCodFromSetInd (long ExaCod,unsigned SetInd); static unsigned ExaSet_GetMaxSetIndexInExam (long ExaCod); -static unsigned Exa_GetMaxQuestionIndexInExam (long ExaCod); +static unsigned ExaSet_GetMaxQuestionIndexInSet (long SetCod); static unsigned ExaSet_GetPrevSetIndexInExam (long ExaCod,unsigned SetInd); static unsigned ExaSet_GetNextSetIndexInExam (long ExaCod,unsigned SetInd); @@ -210,14 +209,11 @@ static void Exa_ListQuestionForEdition (const struct Tst_Question *Question, static void Exa_PutIconToAddNewQuestions (void *Exams); static void Exa_PutButtonToAddNewQuestions (struct Exa_Exams *Exams); -static void Exa_AllocateListSelectedQuestions (struct Exa_Exams *Exams); -static void Exa_FreeListsSelectedQuestions (struct Exa_Exams *Exams); -static unsigned Exa_CountNumQuestionsInList (const struct Exa_Exams *Exams); +static void ExaSet_AllocateListSelectedQuestions (struct Exa_Exams *Exams); +static void ExaSet_FreeListsSelectedQuestions (struct Exa_Exams *Exams); static void ExaSet_ExchangeSets (long ExaCod, unsigned SetIndTop,unsigned SetIndBottom); -static void Exa_ExchangeQuestions (long ExaCod, - unsigned QstIndTop,unsigned QstIndBottom); static bool Exa_CheckIfEditable (const struct Exa_Exam *Exam); @@ -794,7 +790,7 @@ static void Exa_PutFormsToRemEditOneExam (struct Exa_Exams *Exams, /************ Put parameter to move/remove one set of questions **************/ /*****************************************************************************/ -static void ExaSet_PutParamsOneSet (void *Exams) +void ExaSet_PutParamsOneSet (void *Exams) { if (Exams) { @@ -2280,19 +2276,22 @@ void ExaSet_RequestCreatOrEditSet (void) } /*****************************************************************************/ -/*************** Put a form to edit/create a question in exam ****************/ +/*** Request the selection of questions to be added to a set of questions ****/ /*****************************************************************************/ -void Exa_RequestNewQuestion (void) +void ExaSet_ReqSelectQstsToAddToSet (void) { struct Exa_Exams Exams; struct Exa_Exam Exam; + struct ExaSet_Set Set; + char Txt[Cns_MAX_BYTES_TEXT + 1]; /***** Reset exams context *****/ Exa_ResetExams (&Exams); - /***** Reset exam *****/ + /***** Reset exam and set *****/ Exa_ResetExam (&Exam); + ExaSet_ResetSet (&Set); /***** Get parameters *****/ Exa_GetParams (&Exams); @@ -2300,39 +2299,49 @@ void Exa_RequestNewQuestion (void) Lay_WrongExamExit (); Exam.ExaCod = Exams.ExaCod; + /***** Get parameters *****/ + Exa_GetParams (&Exams); + if (Exams.ExaCod <= 0) + Lay_WrongExamExit (); + Set.ExaCod = Exam.ExaCod = Exams.ExaCod; + Exams.SetCod = Set.SetCod = ExaSet_GetParamSetCod (); + if (Set.SetCod <= 0) + Lay_WrongSetExit (); + /***** Get exam data from database *****/ Exa_GetDataOfExamByCod (&Exam); - - /***** Check if exam has events *****/ - if (Exa_CheckIfEditable (&Exam)) - { - /***** Show form to create a new question in this exam *****/ - Exams.ExaCod = Exam.ExaCod; - Tst_RequestSelectTestsForExam (&Exams); - } - else + Exa_GetExamTxtFromDB (Exam.ExaCod,Txt); + if (!Exa_CheckIfEditable (&Exam)) Lay_NoPermissionExit (); - /***** Show current exam *****/ - Exa_ShowOnlyOneExam (&Exams,&Exam, - true, // List exam questions - false); // Do not put form to start new event + /***** Get set data from database *****/ + ExaSet_GetDataOfSetByCod (&Set); + + /***** Show form to select questions for set *****/ + Tst_RequestSelectTestsForSet (&Exams); + + /***** Show current exam and its sets *****/ + Exa_PutFormsOneExam (&Exams,&Exam,&Set, + false); // It's not a new exam } /*****************************************************************************/ /**************** List several test questions for selection ******************/ /*****************************************************************************/ -void Exa_ListQuestionsToSelect (void) +void ExaSet_ListQstsToAddToSet (void) { struct Exa_Exams Exams; struct Exa_Exam Exam; + struct ExaSet_Set Set; + char Txt[Cns_MAX_BYTES_TEXT + 1]; /***** Reset exams context *****/ Exa_ResetExams (&Exams); - /***** Reset exam *****/ + /***** Reset exam and set *****/ Exa_ResetExam (&Exam); + ExaSet_ResetSet (&Set); /***** Get parameters *****/ Exa_GetParams (&Exams); @@ -2340,18 +2349,30 @@ void Exa_ListQuestionsToSelect (void) Lay_WrongExamExit (); Exam.ExaCod = Exams.ExaCod; + /***** Get parameters *****/ + Exa_GetParams (&Exams); + if (Exams.ExaCod <= 0) + Lay_WrongExamExit (); + Set.ExaCod = Exam.ExaCod = Exams.ExaCod; + Exams.SetCod = Set.SetCod = ExaSet_GetParamSetCod (); + if (Set.SetCod <= 0) + Lay_WrongSetExit (); + /***** Get exam data from database *****/ Exa_GetDataOfExamByCod (&Exam); - - /***** Check if exam has events *****/ - if (Exa_CheckIfEditable (&Exam)) - { - /***** List several test questions for selection *****/ - Exams.ExaCod = Exam.ExaCod; - Tst_ListQuestionsToSelectForExam (&Exams); - } - else + Exa_GetExamTxtFromDB (Exam.ExaCod,Txt); + if (!Exa_CheckIfEditable (&Exam)) Lay_NoPermissionExit (); + + /***** Get set data from database *****/ + ExaSet_GetDataOfSetByCod (&Set); + + /***** List several test questions for selection *****/ + Tst_ListQuestionsToSelectForSet (&Exams); + + /***** Show current exam and its sets *****/ + Exa_PutFormsOneExam (&Exams,&Exam,&Set, + false); // It's not a new exam } /*****************************************************************************/ @@ -2517,23 +2538,23 @@ static unsigned ExaSet_GetMaxSetIndexInExam (long ExaCod) } /*****************************************************************************/ -/****************** Get maximum question index in an exam *********************/ +/************ Get maximum question index in a set of questions ***************/ /*****************************************************************************/ // Question index can be 1, 2, 3... // Return 0 if no questions -static unsigned Exa_GetMaxQuestionIndexInExam (long ExaCod) +static unsigned ExaSet_GetMaxQuestionIndexInSet (long SetCod) { MYSQL_RES *mysql_res; MYSQL_ROW row; - unsigned QstInd = 0; + unsigned QstInd = 0; // Default value if no questions in set /***** Get maximum question index in an exam from database *****/ DB_QuerySELECT (&mysql_res,"can not get max question index", "SELECT MAX(QstInd)" " FROM exa_questions" - " WHERE ExaCod=%ld", - ExaCod); + " WHERE SetCod=%ld", + SetCod); row = mysql_fetch_row (mysql_res); if (row[0]) // There are questions if (sscanf (row[0],"%u",&QstInd) != 1) @@ -2857,11 +2878,11 @@ static void ExaSet_ListOneOrMoreSetsForEdition (struct Exa_Exams *Exams, /***** Build anchor string *****/ Frm_SetAnchorStr (Set.SetCod,&Anchor); - /***** Begin row *****/ + /***** Begin first row *****/ HTM_TR_Begin (NULL); /***** Icons *****/ - HTM_TD_Begin ("class=\"BT%u\"",Gbl.RowEvenOdd); + HTM_TD_Begin ("rowspan=\"2\" class=\"BT%u\"",Gbl.RowEvenOdd); /* Put icon to remove the set */ if (ICanEditSets) @@ -2903,7 +2924,7 @@ static void ExaSet_ListOneOrMoreSetsForEdition (struct Exa_Exams *Exams, HTM_TD_End (); /***** Index *****/ - HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd); + HTM_TD_Begin ("rowspan=\"2\" class=\"RT COLOR%u\"",Gbl.RowEvenOdd); Tst_WriteNumQst (Set.SetInd); HTM_TD_End (); @@ -2935,7 +2956,18 @@ static void ExaSet_ListOneOrMoreSetsForEdition (struct Exa_Exams *Exams, Frm_EndForm (); HTM_TD_End (); - /***** End row *****/ + /***** End first row *****/ + HTM_TR_End (); + + /***** Begin second row *****/ + HTM_TR_Begin (NULL); + + /***** Questions *****/ + HTM_TD_Begin ("colspan=\"3\" class=\"LT COLOR%u\"",Gbl.RowEvenOdd); + Exa_PutButtonToAddNewQuestions (Exams); + HTM_TD_End (); + + /***** End second row *****/ HTM_TR_End (); /***** Free anchor string *****/ @@ -3009,20 +3041,13 @@ static void Exa_ListOneOrMoreQuestionsForEdition (struct Exa_Exams *Exams, extern const char *Txt_Code; extern const char *Txt_Tags; extern const char *Txt_Question; - extern const char *Txt_Move_up_X; - extern const char *Txt_Move_down_X; - extern const char *Txt_Movement_not_allowed; unsigned NumQst; MYSQL_ROW row; struct Tst_Question Question; unsigned QstInd; - unsigned MaxQstInd; char StrQstInd[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; bool QuestionExists; - /***** Get maximum question index *****/ - MaxQstInd = Exa_GetMaxQuestionIndexInExam (ExaCod); - /***** Write the heading *****/ HTM_TABLE_BeginWideMarginPadding (2); HTM_TR_Begin (NULL); @@ -3081,32 +3106,6 @@ static void Exa_ListOneOrMoreQuestionsForEdition (struct Exa_Exams *Exams, else Ico_PutIconRemovalNotAllowed (); - /* Put icon to move up the question */ - if (ICanEditQuestions && QstInd > 1) - { - Lay_PutContextualLinkOnlyIcon (ActUp_ExaQst,NULL, - Exa_PutParamsOneQst,Exams, - "arrow-up.svg", - Str_BuildStringStr (Txt_Move_up_X, - StrQstInd)); - Str_FreeString (); - } - else - Ico_PutIconOff ("arrow-up.svg",Txt_Movement_not_allowed); - - /* Put icon to move down the question */ - if (ICanEditQuestions && QstInd < MaxQstInd) - { - Lay_PutContextualLinkOnlyIcon (ActDwnExaQst,NULL, - Exa_PutParamsOneQst,Exams, - "arrow-down.svg", - Str_BuildStringStr (Txt_Move_down_X, - StrQstInd)); - Str_FreeString (); - } - else - Ico_PutIconOff ("arrow-down.svg",Txt_Movement_not_allowed); - /* Put icon to edit the question */ if (ICanEditQuestions) Ico_PutContextualIconToEdit (ActEdiOneTstQst,NULL, @@ -3192,7 +3191,7 @@ static void Exa_PutIconToAddNewQuestions (void *Exams) extern const char *Txt_Add_questions; /***** Put form to create a new question *****/ - Ico_PutContextualIconToAdd (ActAddOneExaQst,NULL, + Ico_PutContextualIconToAdd (ActReqAddQstExaSet,NULL, Exa_PutParams,Exams, Txt_Add_questions); } @@ -3205,21 +3204,23 @@ static void Exa_PutButtonToAddNewQuestions (struct Exa_Exams *Exams) { extern const char *Txt_Add_questions; - Frm_StartForm (ActAddOneExaQst); - Exa_PutParams (Exams); - Btn_PutConfirmButton (Txt_Add_questions); + Frm_StartForm (ActReqAddQstExaSet); + ExaSet_PutParamsOneSet (Exams); + Btn_PutConfirmButtonInline (Txt_Add_questions); Frm_EndForm (); } /*****************************************************************************/ -/******************** Add selected test questions to exam ********************/ +/************* Add selected test questions to set of questions ***************/ /*****************************************************************************/ -void Exa_AddQuestionsToExam (void) +void ExaSet_AddQstsToSet (void) { extern const char *Txt_No_questions_have_been_added; struct Exa_Exams Exams; struct Exa_Exam Exam; + struct ExaSet_Set Set; + char Txt[Cns_MAX_BYTES_TEXT + 1]; const char *Ptr; char LongStr[Cns_MAX_DECIMAL_DIGITS_LONG + 1]; long QstCod; @@ -3228,8 +3229,9 @@ void Exa_AddQuestionsToExam (void) /***** Reset exams context *****/ Exa_ResetExams (&Exams); - /***** Reset exam *****/ + /***** Reset exam and set *****/ Exa_ResetExam (&Exam); + ExaSet_ResetSet (&Set); /***** Get parameters *****/ Exa_GetParams (&Exams); @@ -3237,68 +3239,76 @@ void Exa_AddQuestionsToExam (void) Lay_WrongExamExit (); Exam.ExaCod = Exams.ExaCod; + /***** Get parameters *****/ + Exa_GetParams (&Exams); + if (Exams.ExaCod <= 0) + Lay_WrongExamExit (); + Set.ExaCod = Exam.ExaCod = Exams.ExaCod; + Exams.SetCod = Set.SetCod = ExaSet_GetParamSetCod (); + if (Set.SetCod <= 0) + Lay_WrongSetExit (); + /***** Get exam data from database *****/ Exa_GetDataOfExamByCod (&Exam); - - /***** Check if exam has events *****/ - if (Exa_CheckIfEditable (&Exam)) - { - /***** Get selected questions *****/ - /* Allocate space for selected question codes */ - Exa_AllocateListSelectedQuestions (&Exams); - - /* Get question codes */ - Par_GetParMultiToText ("QstCods",Exams.ListQuestions, - Exa_MAX_BYTES_LIST_SELECTED_QUESTIONS); - - /* Check number of questions */ - if (Exa_CountNumQuestionsInList (&Exams)) // If questions selected... - { - /***** Insert questions in database *****/ - Ptr = Exams.ListQuestions; - while (*Ptr) - { - /* Get next code */ - Par_GetNextStrUntilSeparParamMult (&Ptr,LongStr,Cns_MAX_DECIMAL_DIGITS_LONG); - if (sscanf (LongStr,"%ld",&QstCod) != 1) - Lay_ShowErrorAndExit ("Wrong question code."); - - /* Get current maximum index */ - MaxQstInd = Exa_GetMaxQuestionIndexInExam (Exam.ExaCod); // -1 if no questions - - /* Insert question in the table of questions */ - DB_QueryINSERT ("can not create question", - "INSERT INTO exa_questions" - " (ExaCod,QstCod,QstInd)" - " VALUES" - " (%ld,%ld,%u)", - Exam.ExaCod,QstCod,MaxQstInd + 1); - } - } - else - Ale_ShowAlert (Ale_WARNING,Txt_No_questions_have_been_added); - - /***** Free space for selected question codes *****/ - Exa_FreeListsSelectedQuestions (&Exams); - } - else + Exa_GetExamTxtFromDB (Exam.ExaCod,Txt); + if (!Exa_CheckIfEditable (&Exam)) Lay_NoPermissionExit (); - /***** Show current exam *****/ - Exa_ShowOnlyOneExam (&Exams,&Exam, - true, // List exam questions - false); // Do not put form to start new event + /***** Get set data from database *****/ + ExaSet_GetDataOfSetByCod (&Set); + + /***** Get selected questions *****/ + /* Allocate space for selected question codes */ + ExaSet_AllocateListSelectedQuestions (&Exams); + + /* Get question codes */ + Par_GetParMultiToText ("QstCods",Exams.ListQuestions, + ExaSet_MAX_BYTES_LIST_SELECTED_QUESTIONS); + + /* Check number of questions */ + if (Tst_CountNumQuestionsInList (Exams.ListQuestions)) // If questions selected... + { + /***** Insert questions in database *****/ + Ptr = Exams.ListQuestions; + while (*Ptr) + { + /* Get next code */ + Par_GetNextStrUntilSeparParamMult (&Ptr,LongStr,Cns_MAX_DECIMAL_DIGITS_LONG); + if (sscanf (LongStr,"%ld",&QstCod) != 1) + Lay_ShowErrorAndExit ("Wrong question code."); + + /* Get current maximum index */ + MaxQstInd = ExaSet_GetMaxQuestionIndexInSet (Set.SetCod); // 0 if no questions + + /* Insert question in the table of questions */ + DB_QueryINSERT ("can not add question to set", + "INSERT INTO exa_questions" + " (SetCod,QstInd,QstCod)" + " VALUES" + " (%ld,%u,%ld)", + Set.SetCod,MaxQstInd + 1,QstCod); + } + } + else + Ale_ShowAlert (Ale_WARNING,Txt_No_questions_have_been_added); + + /***** Free space for selected question codes *****/ + ExaSet_FreeListsSelectedQuestions (&Exams); + + /***** Show current exam and its sets *****/ + Exa_PutFormsOneExam (&Exams,&Exam,&Set, + false); // It's not a new exam } /*****************************************************************************/ /****************** Allocate memory for list of questions ********************/ /*****************************************************************************/ -static void Exa_AllocateListSelectedQuestions (struct Exa_Exams *Exams) +static void ExaSet_AllocateListSelectedQuestions (struct Exa_Exams *Exams) { if (!Exams->ListQuestions) { - if ((Exams->ListQuestions = (char *) malloc (Exa_MAX_BYTES_LIST_SELECTED_QUESTIONS + 1)) == NULL) + if ((Exams->ListQuestions = (char *) malloc (ExaSet_MAX_BYTES_LIST_SELECTED_QUESTIONS + 1)) == NULL) Lay_NotEnoughMemoryExit (); Exams->ListQuestions[0] = '\0'; } @@ -3308,7 +3318,7 @@ static void Exa_AllocateListSelectedQuestions (struct Exa_Exams *Exams) /*********** Free memory used by list of selected question codes *************/ /*****************************************************************************/ -static void Exa_FreeListsSelectedQuestions (struct Exa_Exams *Exams) +static void ExaSet_FreeListsSelectedQuestions (struct Exa_Exams *Exams) { if (Exams->ListQuestions) { @@ -3317,29 +3327,6 @@ static void Exa_FreeListsSelectedQuestions (struct Exa_Exams *Exams) } } -/*****************************************************************************/ -/**** Count the number of questions in the list of selected question codes ***/ -/*****************************************************************************/ - -static unsigned Exa_CountNumQuestionsInList (const struct Exa_Exams *Exams) - { - const char *Ptr; - unsigned NumQuestions = 0; - char LongStr[Cns_MAX_DECIMAL_DIGITS_LONG + 1]; - long QstCod; - - /***** Go over list of questions counting the number of questions *****/ - Ptr = Exams->ListQuestions; - while (*Ptr) - { - Par_GetNextStrUntilSeparParamMult (&Ptr,LongStr,Cns_MAX_DECIMAL_DIGITS_LONG); - if (sscanf (LongStr,"%ld",&QstCod) != 1) - Lay_ShowErrorAndExit ("Wrong question code."); - NumQuestions++; - } - return NumQuestions; - } - /*****************************************************************************/ /***************** Request the removal of a set of questions *****************/ /*****************************************************************************/ @@ -3704,128 +3691,6 @@ void Exa_RemoveQst (void) false); // Do not put form to start new event } -/*****************************************************************************/ -/***************** Move up position of a question in an exam ******************/ -/*****************************************************************************/ - -void Exa_MoveUpQst (void) - { - extern const char *Txt_Movement_not_allowed; - struct Exa_Exams Exams; - struct Exa_Exam Exam; - unsigned QstIndTop; - unsigned QstIndBottom; - - /***** Reset exams context *****/ - Exa_ResetExams (&Exams); - - /***** Reset exam *****/ - Exa_ResetExam (&Exam); - - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Exam.ExaCod = Exams.ExaCod; - - /***** Get exam data from database *****/ - Exa_GetDataOfExamByCod (&Exam); - - /***** Check if exam has events *****/ - if (Exa_CheckIfEditable (&Exam)) - { - /***** Get question index *****/ - QstIndBottom = Exa_GetParamQstInd (); - - /***** Move up question *****/ - if (QstIndBottom > 1) - { - /* Indexes of questions to be exchanged */ - QstIndTop = Exa_GetPrevQuestionIndexInExam (Exam.ExaCod,QstIndBottom); - if (!QstIndTop) - Lay_ShowErrorAndExit ("Wrong index of question."); - - /* Exchange questions */ - Exa_ExchangeQuestions (Exam.ExaCod,QstIndTop,QstIndBottom); - } - else - Ale_ShowAlert (Ale_WARNING,Txt_Movement_not_allowed); - } - else - Lay_NoPermissionExit (); - - /***** Show current exam *****/ - Exa_ShowOnlyOneExam (&Exams,&Exam, - true, // List exam questions - false); // Do not put form to start new event - } - -/*****************************************************************************/ -/**************** Move down position of a question in an exam *****************/ -/*****************************************************************************/ - -void Exa_MoveDownQst (void) - { - extern const char *Txt_Movement_not_allowed; - extern const char *Txt_This_exam_has_no_questions; - struct Exa_Exams Exams; - struct Exa_Exam Exam; - unsigned QstIndTop; - unsigned QstIndBottom; - unsigned MaxQstInd; // 0 if no questions - - /***** Reset exams context *****/ - Exa_ResetExams (&Exams); - - /***** Reset exam *****/ - Exa_ResetExam (&Exam); - - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Exam.ExaCod = Exams.ExaCod; - - /***** Get exam data from database *****/ - Exa_GetDataOfExamByCod (&Exam); - - /***** Check if exam has events *****/ - if (Exa_CheckIfEditable (&Exam)) - { - /***** Get question index *****/ - QstIndTop = Exa_GetParamQstInd (); - - /***** Get maximum question index *****/ - MaxQstInd = Exa_GetMaxQuestionIndexInExam (Exam.ExaCod); - - /***** Move down question *****/ - if (MaxQstInd) - { - if (QstIndTop < MaxQstInd) - { - /* Indexes of questions to be exchanged */ - QstIndBottom = Exa_GetNextQuestionIndexInExam (Exam.ExaCod,QstIndTop); - if (!QstIndBottom) - Lay_ShowErrorAndExit ("Wrong index of question."); - - /* Exchange questions */ - Exa_ExchangeQuestions (Exam.ExaCod,QstIndTop,QstIndBottom); - } - else - Ale_ShowAlert (Ale_WARNING,Txt_Movement_not_allowed); - } - else - Ale_ShowAlert (Ale_WARNING,Txt_This_exam_has_no_questions); - } - else - Lay_NoPermissionExit (); - - /***** Show current exam *****/ - Exa_ShowOnlyOneExam (&Exams,&Exam, - true, // List exam questions - false); // Do not put form to start new event - } - /*****************************************************************************/ /*********** Exchange the order of two consecutive sets in an exam ***********/ /*****************************************************************************/ @@ -3888,57 +3753,6 @@ static void ExaSet_ExchangeSets (long ExaCod, "UNLOCK TABLES"); } -/*****************************************************************************/ -/********* Exchange the order of two consecutive questions in an exam *********/ -/*****************************************************************************/ - -static void Exa_ExchangeQuestions (long ExaCod, - unsigned QstIndTop,unsigned QstIndBottom) - { - long QstCodTop; - long QstCodBottom; - - /***** Lock table to make the move atomic *****/ - DB_Query ("can not lock tables to move exam question", - "LOCK TABLES exa_questions WRITE"); - Gbl.DB.LockedTables = true; - - /***** Get question code of the questions to be moved *****/ - QstCodTop = Exa_GetQstCodFromQstInd (ExaCod,QstIndTop); - QstCodBottom = Exa_GetQstCodFromQstInd (ExaCod,QstIndBottom); - - /***** Exchange indexes of questions *****/ - /* - Example: - QstIndTop = 1; QstCodTop = 218 - QstIndBottom = 2; QstCodBottom = 220 - +--------+--------+ +--------+--------+ +--------+--------+ - | QstInd | QstCod | | QstInd | QstCod | | QstInd | QstCod | - +--------+--------+ +--------+--------+ +--------+--------+ - | 1 | 218 | -----> | 2 | 218 | = | 1 | 220 | - | 2 | 220 | | 1 | 220 | | 2 | 218 | - | 3 | 232 | | 3 | 232 | | 3 | 232 | - +--------+--------+ +--------+--------+ +--------+--------+ - */ - DB_QueryUPDATE ("can not exchange indexes of questions", - "UPDATE exa_questions SET QstInd=%u" - " WHERE ExaCod=%ld AND QstCod=%ld", - QstIndBottom, - ExaCod,QstCodTop); - - DB_QueryUPDATE ("can not exchange indexes of questions", - "UPDATE exa_questions SET QstInd=%u" - " WHERE ExaCod=%ld AND QstCod=%ld", - QstIndTop, - ExaCod,QstCodBottom); - - /***** Unlock table *****/ - Gbl.DB.LockedTables = false; // Set to false before the following unlock... - // ...to not retry the unlock if error in unlocking - DB_Query ("can not unlock tables after moving exam questions", - "UNLOCK TABLES"); - } - /*****************************************************************************/ /*********** Get number of events and check is edition is possible **********/ /*****************************************************************************/ diff --git a/swad_exam.h b/swad_exam.h index 87cd8e5c..2aee1070 100644 --- a/swad_exam.h +++ b/swad_exam.h @@ -130,6 +130,7 @@ void Exa_ShowOnlyOneExamBegin (struct Exa_Exams *Exams, void Exa_ShowOnlyOneExamEnd (void); void Exa_SetCurrentExaCod (long ExaCod); +void ExaSet_PutParamsOneSet (void *Exams); void Exa_PutParams (void *Exams); void Exa_PutParamExamCod (long ExaCod); long Exa_GetParamExamCod (void); @@ -162,8 +163,8 @@ unsigned ExaSet_GetNumSetsExam (long ExaCod); unsigned ExaSet_GetNumQstsExam (long ExaCod); void ExaSet_RequestCreatOrEditSet (void); -void Exa_RequestNewQuestion (void); -void Exa_ListQuestionsToSelect (void); +void ExaSet_ReqSelectQstsToAddToSet (void); +void ExaSet_ListQstsToAddToSet (void); void Exa_PutParamQstInd (unsigned QstInd); unsigned Exa_GetParamQstInd (void); @@ -172,7 +173,7 @@ long Exa_GetQstCodFromQstInd (long ExaCod,unsigned QstInd); unsigned Exa_GetPrevQuestionIndexInExam (long ExaCod,unsigned QstInd); unsigned Exa_GetNextQuestionIndexInExam (long ExaCod,unsigned QstInd); -void Exa_AddQuestionsToExam (void); +void ExaSet_AddQstsToSet (void); void ExaSet_RequestRemoveSet (void); void ExaSet_RemoveSet (void); @@ -183,9 +184,6 @@ void ExaSet_MoveDownSet (void); void Exa_RequestRemoveQst (void); void Exa_RemoveQst (void); -void Exa_MoveUpQst (void); -void Exa_MoveDownQst (void); - void Exa_PutButtonNewEvent (struct Exa_Exams *Exams,long ExaCod); void Exa_RequestNewEvent (void); diff --git a/swad_game.c b/swad_game.c index f5f4a633..394ad5f9 100644 --- a/swad_game.c +++ b/swad_game.c @@ -166,7 +166,6 @@ static void Gam_PutButtonToAddNewQuestions (struct Gam_Games *Games); static void Gam_AllocateListSelectedQuestions (struct Gam_Games *Games); static void Gam_FreeListsSelectedQuestions (struct Gam_Games *Games); -static unsigned Gam_CountNumQuestionsInList (const struct Gam_Games *Games); static void Gam_ExchangeQuestions (long GamCod, unsigned QstIndTop,unsigned QstIndBottom); @@ -1671,7 +1670,7 @@ unsigned Gam_GetNumQstsGame (long GamCod) /*************** Put a form to edit/create a question in game ****************/ /*****************************************************************************/ -void Gam_RequestNewQuestion (void) +void Gam_ReqSelectQstsToAddToGame (void) { struct Gam_Games Games; struct Gam_Game Game; @@ -1705,7 +1704,7 @@ void Gam_RequestNewQuestion (void) /**************** List several test questions for selection ******************/ /*****************************************************************************/ -void Gam_ListTstQuestionsToSelect (void) +void Gam_ListQstsToAddToGame (void) { struct Gam_Games Games; struct Gam_Game Game; @@ -2213,7 +2212,7 @@ static void Gam_PutButtonToAddNewQuestions (struct Gam_Games *Games) /******************** Add selected test questions to game ********************/ /*****************************************************************************/ -void Gam_AddTstQuestionsToGame (void) +void Gam_AddQstsToGame (void) { extern const char *Txt_No_questions_have_been_added; extern const char *Txt_A_question_has_been_added; @@ -2251,7 +2250,7 @@ void Gam_AddTstQuestionsToGame (void) /* Check number of questions */ NumQstsAdded = 0; - if (Gam_CountNumQuestionsInList (&Games)) // If questions selected... + if (Tst_CountNumQuestionsInList (Games.ListQuestions)) // If questions selected... { /***** Insert questions in database *****/ Ptr = Games.ListQuestions; @@ -2269,12 +2268,12 @@ void Gam_AddTstQuestionsToGame (void) MaxQstInd = Gam_GetMaxQuestionIndexInGame (Game.GamCod); // 0 is no questions in game /* Insert question in the table of questions */ - DB_QueryINSERT ("can not create question", + DB_QueryINSERT ("can not add question to game", "INSERT INTO gam_questions" - " (GamCod,QstCod,QstInd)" + " (GamCod,QstInd,QstCod)" " VALUES" - " (%ld,%ld,%u)", - Game.GamCod,QstCod,MaxQstInd + 1); + " (%ld,%u,%ld)", + Game.GamCod,MaxQstInd + 1,QstCod); NumQstsAdded++; } @@ -2325,29 +2324,6 @@ static void Gam_FreeListsSelectedQuestions (struct Gam_Games *Games) } } -/*****************************************************************************/ -/**** Count the number of questions in the list of selected question codes ***/ -/*****************************************************************************/ - -static unsigned Gam_CountNumQuestionsInList (const struct Gam_Games *Games) - { - const char *Ptr; - unsigned NumQuestions = 0; - char LongStr[Cns_MAX_DECIMAL_DIGITS_LONG + 1]; - long QstCod; - - /***** Go over list of questions counting the number of questions *****/ - Ptr = Games->ListQuestions; - while (*Ptr) - { - Par_GetNextStrUntilSeparParamMult (&Ptr,LongStr,Cns_MAX_DECIMAL_DIGITS_LONG); - if (sscanf (LongStr,"%ld",&QstCod) != 1) - Lay_ShowErrorAndExit ("Wrong question code."); - NumQuestions++; - } - return NumQuestions; - } - /*****************************************************************************/ /********************** Request the removal of a question ********************/ /*****************************************************************************/ diff --git a/swad_game.h b/swad_game.h index e511f0aa..ef4b07c7 100644 --- a/swad_game.h +++ b/swad_game.h @@ -138,8 +138,8 @@ bool Mch_CheckIfMatchIsAssociatedToGrp (long MchCod,long GrpCod); unsigned Gam_GetNumQstsGame (long GamCod); -void Gam_RequestNewQuestion (void); -void Gam_ListTstQuestionsToSelect (void); +void Gam_ReqSelectQstsToAddToGame (void); +void Gam_ListQstsToAddToGame (void); void Gam_PutParamQstInd (unsigned QstInd); unsigned Gam_GetParamQstInd (void); @@ -147,7 +147,7 @@ long Gam_GetQstCodFromQstInd (long GamCod,unsigned QstInd); unsigned Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd); unsigned Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd); -void Gam_AddTstQuestionsToGame (void); +void Gam_AddQstsToGame (void); void Gam_RequestRemoveQst (void); void Gam_RemoveQst (void); diff --git a/swad_test.c b/swad_test.c index 6c40656d..657470f6 100644 --- a/swad_test.c +++ b/swad_test.c @@ -150,8 +150,8 @@ static void Tst_IncreaseMyNumAccessTst (void); static void Tst_UpdateLastAccTst (unsigned NumQsts); static void Tst_ShowFormRequestEditTests (struct Tst_Test *Test); -static void Tst_ShowFormRequestSelectTestsForExam (struct Exa_Exams *Exams, - struct Tst_Test *Test); +static void Tst_ShowFormRequestSelectTestsForSet (struct Exa_Exams *Exams, + struct Tst_Test *Test); static void Tst_ShowFormRequestSelectTestsForGame (struct Gam_Games *Games, struct Tst_Test *Test); static bool Tst_CheckIfICanEditTests (void); @@ -186,12 +186,12 @@ static void Tst_ListOneOrMoreQuestionsForEdition (struct Tst_Test *Test, MYSQL_RES *mysql_res); static void Tst_WriteHeadingRowQuestionsForEdition (const struct Tst_Test *Test); static void Tst_WriteQuestionListing (struct Tst_Test *Test,unsigned NumQst); -static void Tst_ListOneOrMoreQuestionsForSelectionForExam (struct Exa_Exams *Exams, +static void Tst_ListOneOrMoreQuestionsForSelectionForSet (struct Exa_Exams *Exams, + unsigned NumQsts, + MYSQL_RES *mysql_res); +static void Tst_ListOneOrMoreQuestionsForSelectionForGame (struct Gam_Games *Games, unsigned NumQsts, MYSQL_RES *mysql_res); -static void Tst_ListOneOrMoreQuestionsForSelectionForGame (struct Gam_Games *Games, - unsigned NumQsts, - MYSQL_RES *mysql_res); static void Tst_WriteQuestionRowForSelection (unsigned NumQst, struct Tst_Question *Question); @@ -1221,7 +1221,7 @@ static void Tst_ShowFormRequestEditTests (struct Tst_Test *Test) /******************* Select test questions for a game ************************/ /*****************************************************************************/ -void Tst_RequestSelectTestsForExam (struct Exa_Exams *Exams) +void Tst_RequestSelectTestsForSet (struct Exa_Exams *Exams) { struct Tst_Test Test; @@ -1229,7 +1229,7 @@ void Tst_RequestSelectTestsForExam (struct Exa_Exams *Exams) Tst_TstConstructor (&Test); /***** Show form to select test for exam *****/ - Tst_ShowFormRequestSelectTestsForExam (Exams,&Test); // No tags selected + Tst_ShowFormRequestSelectTestsForSet (Exams,&Test); // No tags selected /***** Destroy test *****/ Tst_TstDestructor (&Test); @@ -1257,8 +1257,8 @@ void Tst_RequestSelectTestsForGame (struct Gam_Games *Games) /************** Show form to select test questions for a exam ****************/ /*****************************************************************************/ -static void Tst_ShowFormRequestSelectTestsForExam (struct Exa_Exams *Exams, - struct Tst_Test *Test) +static void Tst_ShowFormRequestSelectTestsForSet (struct Exa_Exams *Exams, + struct Tst_Test *Test) { extern const char *Hlp_ASSESSMENT_Exams_questions; extern const char *Txt_No_test_questions; @@ -1279,14 +1279,17 @@ static void Tst_ShowFormRequestSelectTestsForExam (struct Exa_Exams *Exams, /***** Get tags already present in the table of questions *****/ if ((Test->Tags.Num = Tst_GetAllTagsFromCurrentCrs (&mysql_res))) { - Frm_StartForm (ActLstTstQstForExa); - Exa_PutParams (Exams); + Frm_StartForm (ActLstTstQstForSet); + ExaSet_PutParamsOneSet (Exams); HTM_TABLE_BeginPadding (2); /***** Selection of tags *****/ Tst_ShowFormSelTags (&Test->Tags,mysql_res,false); + /***** Selection of types of answers *****/ + Tst_ShowFormAnswerTypes (&Test->AnswerTypes); + /***** Starting and ending dates in the search *****/ Dat_PutFormStartEndClientLocalDateTimesWithYesterdayToday (SetHMS); @@ -2232,7 +2235,7 @@ void Tst_ListQuestionsToEdit (void) /************ List several test questions for selection for exam *************/ /*****************************************************************************/ -void Tst_ListQuestionsToSelectForExam (struct Exa_Exams *Exams) +void Tst_ListQuestionsToSelectForSet (struct Exa_Exams *Exams) { struct Tst_Test Test; MYSQL_RES *mysql_res; @@ -2241,19 +2244,19 @@ void Tst_ListQuestionsToSelectForExam (struct Exa_Exams *Exams) Tst_TstConstructor (&Test); /***** Get parameters, query the database and list the questions *****/ - if (Tst_GetParamsTst (&Test,Tst_SELECT_QUESTIONS_FOR_GAME)) // Get parameters from the form + if (Tst_GetParamsTst (&Test,Tst_SELECT_QUESTIONS_FOR_EXAM)) // Get parameters from the form { Tst_GetQuestions (&Test,&mysql_res); // Query database if (Test.NumQsts) /* Show the table with the questions */ - Tst_ListOneOrMoreQuestionsForSelectionForExam (Exams,Test.NumQsts,mysql_res); + Tst_ListOneOrMoreQuestionsForSelectionForSet (Exams,Test.NumQsts,mysql_res); /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); } else /* Show the form again */ - Tst_ShowFormRequestSelectTestsForExam (Exams,&Test); + Tst_ShowFormRequestSelectTestsForSet (Exams,&Test); /***** Destroy test *****/ Tst_TstDestructor (&Test); @@ -2975,9 +2978,9 @@ static void Tst_WriteQuestionListing (struct Tst_Test *Test,unsigned NumQst) /*************** List for selection one or more test questions ***************/ /*****************************************************************************/ -static void Tst_ListOneOrMoreQuestionsForSelectionForExam (struct Exa_Exams *Exams, - unsigned NumQsts, - MYSQL_RES *mysql_res) +static void Tst_ListOneOrMoreQuestionsForSelectionForSet (struct Exa_Exams *Exams, + unsigned NumQsts, + MYSQL_RES *mysql_res) { extern const char *Hlp_ASSESSMENT_Exams_questions; extern const char *Txt_Questions; @@ -3000,7 +3003,7 @@ static void Tst_ListOneOrMoreQuestionsForSelectionForExam (struct Exa_Exams *Exa /***** Begin form *****/ Frm_StartForm (ActAddQstToExa); - Exa_PutParams (Exams); + ExaSet_PutParamsOneSet (Exams); /***** Write the heading *****/ HTM_TABLE_BeginWideMarginPadding (2); @@ -3827,6 +3830,7 @@ static bool Tst_GetParamsTst (struct Tst_Test *Test, { case Tst_SHOW_TEST_TO_ANSWER: case Tst_EDIT_TEST: + case Tst_SELECT_QUESTIONS_FOR_EXAM: /* Get parameter that indicates if all types of answer are selected */ Test->AnswerTypes.All = Par_GetParToBool ("AllAnsTypes"); @@ -3877,6 +3881,7 @@ static bool Tst_GetParamsTst (struct Tst_Test *Test, else Test->SelectedOrder = (Tst_QuestionsOrder_t) 0; break; + case Tst_SELECT_QUESTIONS_FOR_EXAM: case Tst_SELECT_QUESTIONS_FOR_GAME: /* Get starting and ending dates */ Dat_GetIniEndDatesFromForm (); @@ -3957,6 +3962,29 @@ static int Tst_CountNumAnswerTypesInList (const struct Tst_AnswerTypes *AnswerTy return NumAnsTypes; } +/*****************************************************************************/ +/**** Count the number of questions in the list of selected question codes ***/ +/*****************************************************************************/ + +unsigned Tst_CountNumQuestionsInList (const char *ListQuestions) + { + const char *Ptr; + unsigned NumQuestions = 0; + char LongStr[Cns_MAX_DECIMAL_DIGITS_LONG + 1]; + long QstCod; + + /***** Go over list of questions counting the number of questions *****/ + Ptr = ListQuestions; + while (*Ptr) + { + Par_GetNextStrUntilSeparParamMult (&Ptr,LongStr,Cns_MAX_DECIMAL_DIGITS_LONG); + if (sscanf (LongStr,"%ld",&QstCod) != 1) + Lay_ShowErrorAndExit ("Wrong question code."); + NumQuestions++; + } + return NumQuestions; + } + /*****************************************************************************/ /******************** Show form to edit one test question ********************/ /*****************************************************************************/ diff --git a/swad_test.h b/swad_test.h index dbac0c11..8d48534d 100644 --- a/swad_test.h +++ b/swad_test.h @@ -133,6 +133,7 @@ typedef enum Tst_SHOW_TEST_TO_ANSWER, // Showing a test to a student Tst_SHOW_TEST_RESULT, // Showing the assessment of a test Tst_EDIT_TEST, // Editing test questions + Tst_SELECT_QUESTIONS_FOR_EXAM, // Selecting test questions for a set of questions in an exam Tst_SELECT_QUESTIONS_FOR_GAME, // Selecting test questions for a game } Tst_ActionToDoWithQuestions_t; @@ -166,11 +167,11 @@ void Tst_WriteQstStem (const char *Stem,const char *ClassStem,bool Visible); void Tst_WriteQstFeedback (const char *Feedback,const char *ClassFeedback); void Tst_RequestEditTests (void); -void Tst_RequestSelectTestsForExam (struct Exa_Exams *Exams); +void Tst_RequestSelectTestsForSet (struct Exa_Exams *Exams); void Tst_RequestSelectTestsForGame (struct Gam_Games *Games); void Tst_ListQuestionsToEdit (void); -void Tst_ListQuestionsToSelectForExam (struct Exa_Exams *Exams); +void Tst_ListQuestionsToSelectForSet (struct Exa_Exams *Exams); void Tst_ListQuestionsToSelectForGame (struct Gam_Games *Games); void Tst_WriteParamEditQst (const struct Tst_Test *Test); @@ -193,6 +194,8 @@ void Tst_RenameTag (void); bool Tst_CheckIfCourseHaveTestsAndPluggableIsUnknown (void); +unsigned Tst_CountNumQuestionsInList (const char *ListQuestions); + void Tst_ShowFormEditOneQst (void); void Tst_QstConstructor (struct Tst_Question *Question); diff --git a/swad_text_action.c b/swad_text_action.c index cb479e61..ab3ac310 100644 --- a/swad_text_action.c +++ b/swad_text_action.c @@ -10982,7 +10982,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "" // Precisa de tradução #endif , - [ActAddOneExaQst] = + [ActReqAddQstExaSet] = #if L==1 // ca "" // Necessita traducció #elif L==2 // de @@ -11003,7 +11003,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "" // Precisa de tradução #endif , - [ActLstTstQstForExa] = + [ActLstTstQstForSet] = #if L==1 // ca "" // Necessita traducció #elif L==2 // de @@ -11085,48 +11085,6 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "" // Potrzebujesz tlumaczenie #elif L==9 // pt "" // Precisa de tradução -#endif - , - [ActUp_ExaQst] = -#if L==1 // ca - "" // Necessita traducció -#elif L==2 // de - "" // Need Übersetzung -#elif L==3 // en - "Move up exam question" -#elif L==4 // es - "Mover hacia arriba pregunta de examen" -#elif L==5 // fr - "" // Besoin de traduction -#elif L==6 // gn - "" // Okoteve traducción -#elif L==7 // it - "" // Bisogno di traduzione -#elif L==8 // pl - "" // Potrzebujesz tlumaczenie -#elif L==9 // pt - "" // Precisa de tradução -#endif - , - [ActDwnExaQst] = -#if L==1 // ca - "" // Necessita traducció -#elif L==2 // de - "" // Need Übersetzung -#elif L==3 // en - "Move down exam question" -#elif L==4 // es - "Mover hacia abajo pregunta de examen" -#elif L==5 // fr - "" // Besoin de traduction -#elif L==6 // gn - "" // Okoteve traducción -#elif L==7 // it - "" // Bisogno di traduzione -#elif L==8 // pl - "" // Potrzebujesz tlumaczenie -#elif L==9 // pt - "" // Precisa de tradução #endif , [ActSeeGam] =