diff --git a/sql/swad.sql b/sql/swad.sql index 43231428..33a3522b 100644 --- a/sql/swad.sql +++ b/sql/swad.sql @@ -530,6 +530,7 @@ CREATE TABLE IF NOT EXISTS exa_print_questions ( PrnCod INT NOT NULL, QstCod INT NOT NULL, QstInd INT NOT NULL, + SetCod INT NOT NULL, Score DOUBLE PRECISION NOT NULL DEFAULT 0, Indexes TEXT NOT NULL, Answers TEXT NOT NULL, diff --git a/swad_action.c b/swad_action.c index f0375b6f..b17e3855 100644 --- a/swad_action.c +++ b/swad_action.c @@ -740,7 +740,8 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = [ActReqRemSetQst ] = {1888,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaSet_RequestRemoveQstFromSet ,NULL}, [ActRemExaQst ] = {1889,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaSet_RemoveQstFromSet ,NULL}, - [ActSeeExaPrn ] = {1904,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaPrn_ShowNewExamPrint ,NULL}, + [ActSeeExaPrn ] = {1904,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaPrn_ShowExamPrint ,NULL}, + [ActReqAssExaPrn ] = {1905,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaPrn_ReceivePrintAnswer ,NULL}, [ActSeeGam ] = {1650,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_SeeOneGame ,NULL}, @@ -1818,7 +1819,7 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = }; Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse unique action codes! - { + { ActSeeAdmDocCrsGrp, // #0 -1, // #1 (obsolete action) ActMnu, // #2 @@ -3724,7 +3725,8 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActEdiOneExaEvt, // #1902 ActChgExaEvt, // #1903 ActSeeExaPrn, // #1904 - }; + ActReqAssExaPrn, // #1905 + }; /*****************************************************************************/ /**************************** Private prototypes *****************************/ diff --git a/swad_action.h b/swad_action.h index 48cb5a20..25da3605 100644 --- a/swad_action.h +++ b/swad_action.h @@ -64,7 +64,7 @@ typedef enum typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action -#define Act_MAX_ACTION_COD 1904 +#define Act_MAX_ACTION_COD 1905 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13 @@ -705,82 +705,83 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActRemExaQst (ActChgCrsTT1stDay + 175) #define ActSeeExaPrn (ActChgCrsTT1stDay + 176) +#define ActReqAssExaPrn (ActChgCrsTT1stDay + 177) -#define ActSeeGam (ActChgCrsTT1stDay + 177) -#define ActReqRemMch (ActChgCrsTT1stDay + 178) -#define ActRemMch (ActChgCrsTT1stDay + 179) -#define ActReqNewMch (ActChgCrsTT1stDay + 180) -#define ActNewMch (ActChgCrsTT1stDay + 181) -#define ActResMch (ActChgCrsTT1stDay + 182) -#define ActBckMch (ActChgCrsTT1stDay + 183) -#define ActPlyPauMch (ActChgCrsTT1stDay + 184) -#define ActFwdMch (ActChgCrsTT1stDay + 185) -#define ActChgNumColMch (ActChgCrsTT1stDay + 186) -#define ActChgVisResMchQst (ActChgCrsTT1stDay + 187) -#define ActMchCntDwn (ActChgCrsTT1stDay + 188) -#define ActRefMchTch (ActChgCrsTT1stDay + 189) +#define ActSeeGam (ActChgCrsTT1stDay + 178) +#define ActReqRemMch (ActChgCrsTT1stDay + 179) +#define ActRemMch (ActChgCrsTT1stDay + 180) +#define ActReqNewMch (ActChgCrsTT1stDay + 181) +#define ActNewMch (ActChgCrsTT1stDay + 182) +#define ActResMch (ActChgCrsTT1stDay + 183) +#define ActBckMch (ActChgCrsTT1stDay + 184) +#define ActPlyPauMch (ActChgCrsTT1stDay + 185) +#define ActFwdMch (ActChgCrsTT1stDay + 186) +#define ActChgNumColMch (ActChgCrsTT1stDay + 187) +#define ActChgVisResMchQst (ActChgCrsTT1stDay + 188) +#define ActMchCntDwn (ActChgCrsTT1stDay + 189) +#define ActRefMchTch (ActChgCrsTT1stDay + 190) -#define ActJoiMch (ActChgCrsTT1stDay + 190) -#define ActSeeMchAnsQstStd (ActChgCrsTT1stDay + 191) -#define ActRemMchAnsQstStd (ActChgCrsTT1stDay + 192) -#define ActAnsMchQstStd (ActChgCrsTT1stDay + 193) -#define ActRefMchStd (ActChgCrsTT1stDay + 194) +#define ActJoiMch (ActChgCrsTT1stDay + 191) +#define ActSeeMchAnsQstStd (ActChgCrsTT1stDay + 192) +#define ActRemMchAnsQstStd (ActChgCrsTT1stDay + 193) +#define ActAnsMchQstStd (ActChgCrsTT1stDay + 194) +#define ActRefMchStd (ActChgCrsTT1stDay + 195) -#define ActSeeMyMchResCrs (ActChgCrsTT1stDay + 195) -#define ActSeeMyMchResGam (ActChgCrsTT1stDay + 196) -#define ActSeeMyMchResMch (ActChgCrsTT1stDay + 197) -#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 198) +#define ActSeeMyMchResCrs (ActChgCrsTT1stDay + 196) +#define ActSeeMyMchResGam (ActChgCrsTT1stDay + 197) +#define ActSeeMyMchResMch (ActChgCrsTT1stDay + 198) +#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 199) -#define ActReqSeeAllMchRes (ActChgCrsTT1stDay + 199) -#define ActSeeAllMchResCrs (ActChgCrsTT1stDay + 200) -#define ActSeeAllMchResGam (ActChgCrsTT1stDay + 201) -#define ActSeeAllMchResMch (ActChgCrsTT1stDay + 202) -#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 203) +#define ActReqSeeAllMchRes (ActChgCrsTT1stDay + 200) +#define ActSeeAllMchResCrs (ActChgCrsTT1stDay + 201) +#define ActSeeAllMchResGam (ActChgCrsTT1stDay + 202) +#define ActSeeAllMchResMch (ActChgCrsTT1stDay + 203) +#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 204) -#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 204) +#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 205) -#define ActFrmNewGam (ActChgCrsTT1stDay + 205) -#define ActEdiOneGam (ActChgCrsTT1stDay + 206) -#define ActNewGam (ActChgCrsTT1stDay + 207) -#define ActChgGam (ActChgCrsTT1stDay + 208) -#define ActReqRemGam (ActChgCrsTT1stDay + 209) -#define ActRemGam (ActChgCrsTT1stDay + 210) -#define ActHidGam (ActChgCrsTT1stDay + 211) -#define ActShoGam (ActChgCrsTT1stDay + 212) -#define ActAddOneGamQst (ActChgCrsTT1stDay + 213) -#define ActGamLstTstQst (ActChgCrsTT1stDay + 214) -#define ActAddTstQstToGam (ActChgCrsTT1stDay + 215) -#define ActReqRemGamQst (ActChgCrsTT1stDay + 216) -#define ActRemGamQst (ActChgCrsTT1stDay + 217) -#define ActUp_GamQst (ActChgCrsTT1stDay + 218) -#define ActDwnGamQst (ActChgCrsTT1stDay + 219) +#define ActFrmNewGam (ActChgCrsTT1stDay + 206) +#define ActEdiOneGam (ActChgCrsTT1stDay + 207) +#define ActNewGam (ActChgCrsTT1stDay + 208) +#define ActChgGam (ActChgCrsTT1stDay + 209) +#define ActReqRemGam (ActChgCrsTT1stDay + 210) +#define ActRemGam (ActChgCrsTT1stDay + 211) +#define ActHidGam (ActChgCrsTT1stDay + 212) +#define ActShoGam (ActChgCrsTT1stDay + 213) +#define ActAddOneGamQst (ActChgCrsTT1stDay + 214) +#define ActGamLstTstQst (ActChgCrsTT1stDay + 215) +#define ActAddTstQstToGam (ActChgCrsTT1stDay + 216) +#define ActReqRemGamQst (ActChgCrsTT1stDay + 217) +#define ActRemGamQst (ActChgCrsTT1stDay + 218) +#define ActUp_GamQst (ActChgCrsTT1stDay + 219) +#define ActDwnGamQst (ActChgCrsTT1stDay + 220) -#define ActSeeSvy (ActChgCrsTT1stDay + 220) -#define ActAnsSvy (ActChgCrsTT1stDay + 221) -#define ActFrmNewSvy (ActChgCrsTT1stDay + 222) -#define ActEdiOneSvy (ActChgCrsTT1stDay + 223) -#define ActNewSvy (ActChgCrsTT1stDay + 224) -#define ActChgSvy (ActChgCrsTT1stDay + 225) -#define ActReqRemSvy (ActChgCrsTT1stDay + 226) -#define ActRemSvy (ActChgCrsTT1stDay + 227) -#define ActReqRstSvy (ActChgCrsTT1stDay + 228) -#define ActRstSvy (ActChgCrsTT1stDay + 229) -#define ActHidSvy (ActChgCrsTT1stDay + 230) -#define ActShoSvy (ActChgCrsTT1stDay + 231) -#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 232) -#define ActRcvSvyQst (ActChgCrsTT1stDay + 233) -#define ActReqRemSvyQst (ActChgCrsTT1stDay + 234) -#define ActRemSvyQst (ActChgCrsTT1stDay + 235) +#define ActSeeSvy (ActChgCrsTT1stDay + 221) +#define ActAnsSvy (ActChgCrsTT1stDay + 222) +#define ActFrmNewSvy (ActChgCrsTT1stDay + 223) +#define ActEdiOneSvy (ActChgCrsTT1stDay + 224) +#define ActNewSvy (ActChgCrsTT1stDay + 225) +#define ActChgSvy (ActChgCrsTT1stDay + 226) +#define ActReqRemSvy (ActChgCrsTT1stDay + 227) +#define ActRemSvy (ActChgCrsTT1stDay + 228) +#define ActReqRstSvy (ActChgCrsTT1stDay + 229) +#define ActRstSvy (ActChgCrsTT1stDay + 230) +#define ActHidSvy (ActChgCrsTT1stDay + 231) +#define ActShoSvy (ActChgCrsTT1stDay + 232) +#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 233) +#define ActRcvSvyQst (ActChgCrsTT1stDay + 234) +#define ActReqRemSvyQst (ActChgCrsTT1stDay + 235) +#define ActRemSvyQst (ActChgCrsTT1stDay + 236) -#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 236) -#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 237) -#define ActEdiExaAnn (ActChgCrsTT1stDay + 238) -#define ActRcvExaAnn (ActChgCrsTT1stDay + 239) -#define ActPrnExaAnn (ActChgCrsTT1stDay + 240) -#define ActReqRemExaAnn (ActChgCrsTT1stDay + 241) -#define ActRemExaAnn (ActChgCrsTT1stDay + 242) -#define ActHidExaAnn (ActChgCrsTT1stDay + 243) -#define ActShoExaAnn (ActChgCrsTT1stDay + 244) +#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 237) +#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 238) +#define ActEdiExaAnn (ActChgCrsTT1stDay + 239) +#define ActRcvExaAnn (ActChgCrsTT1stDay + 240) +#define ActPrnExaAnn (ActChgCrsTT1stDay + 241) +#define ActReqRemExaAnn (ActChgCrsTT1stDay + 242) +#define ActRemExaAnn (ActChgCrsTT1stDay + 243) +#define ActHidExaAnn (ActChgCrsTT1stDay + 244) +#define ActShoExaAnn (ActChgCrsTT1stDay + 245) /*****************************************************************************/ /******************************** Files tab **********************************/ diff --git a/swad_changelog.h b/swad_changelog.h index ba8267c7..aae95184 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -548,10 +548,14 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.219.3 (2020-05-09)" +#define Log_PLATFORM_VERSION "SWAD 19.220 (2020-05-09)" #define CSS_FILE "swad19.217.css" #define JS_FILE "swad19.193.1.js" /* + Version 19.220: May 09, 2020 Exam prints. (302480 lines) + 1 change necessary in database: +ALTER TABLE exa_print_questions ADD COLUMN SetCod INT NOT NULL AFTER QstInd; + Version 19.219.3: May 09, 2020 Code refactoring in projects. (302366 lines) Version 19.219.2: May 09, 2020 Fixed bug in roles. Reported by Francisco Ocaņa Lara. (302354 lines) 1 change necessary in database: diff --git a/swad_database.c b/swad_database.c index ab930485..7e89b57e 100644 --- a/swad_database.c +++ b/swad_database.c @@ -1161,22 +1161,25 @@ mysql> DESCRIBE exa_participants; /***** Table exa_print_questions *****/ /* -mysql> DESCRIBE exa_print_questions; +---------+---------+------+-----+---------+-------+ +mysql> DESCRIBE exa_print_questions; ++---------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+---------+------+-----+---------+-------+ | PrnCod | int(11) | NO | PRI | NULL | | | QstCod | int(11) | NO | PRI | NULL | | | QstInd | int(11) | NO | | NULL | | +| SetCod | int(11) | NO | | NULL | | | Score | double | NO | | 0 | | | Indexes | text | NO | | NULL | | | Answers | text | NO | | NULL | | +---------+---------+------+-----+---------+-------+ -6 rows in set (0.00 sec) +7 rows in set (0.01 sec) */ DB_CreateTable ("CREATE TABLE IF NOT EXISTS exa_print_questions (" "PrnCod INT NOT NULL," "QstCod INT NOT NULL," "QstInd INT NOT NULL," + "SetCod INT NOT NULL," "Score DOUBLE PRECISION NOT NULL DEFAULT 0," "Indexes TEXT NOT NULL," // Tst_MAX_BYTES_INDEXES_ONE_QST "Answers TEXT NOT NULL," // Tst_MAX_BYTES_ANSWERS_ONE_QST diff --git a/swad_exam_print.c b/swad_exam_print.c index 292c0b9f..dc6b6ea7 100644 --- a/swad_exam_print.c +++ b/swad_exam_print.c @@ -39,6 +39,7 @@ #include "swad_exam_result.h" #include "swad_exam_set.h" #include "swad_exam_type.h" +#include "swad_form.h" #include "swad_global.h" /*****************************************************************************/ @@ -84,6 +85,7 @@ struct ExaPrn_Print static void ExaPrn_ResetPrint (struct ExaPrn_Print *Print); static void ExaPrn_ResetPrintExceptPrnCod (struct ExaPrn_Print *Print); +static bool ExaPrn_CheckIfMyPrintExists (const struct ExaEvt_Event *Event); static void ExaPrn_GetQuestionsForNewPrintFromDB (struct Exa_Exam *Exam, struct ExaPrn_Print *Print); static unsigned ExaPrn_GetSomeQstsFromSetToPrint (struct ExaPrn_Print *Print, @@ -95,6 +97,11 @@ static void ExaPrn_ComputeScoresAndStoreQuestionsOfPrint (struct ExaPrn_Print *P bool UpdateQstScore); static void ExaPrn_StoreOneQstOfPrintInDB (const struct ExaPrn_Print *Print, unsigned NumQst); +static void ExaPrn_ShowExamPrintToFillIt (struct Exa_Exam *Exam, + struct ExaPrn_Print *Print); + +static void ExaPrn_PutParamPrnCod (long ExaCod); +static long ExaPrn_GetParamPrnCod (void); /*****************************************************************************/ /**************************** Reset exam print *******************************/ @@ -117,16 +124,17 @@ static void ExaPrn_ResetPrintExceptPrnCod (struct ExaPrn_Print *Print) } /*****************************************************************************/ -/******************* Generate print of an exam in an event *******************/ +/********************** Show print of an exam in an event ********************/ /*****************************************************************************/ -void ExaPrn_ShowNewExamPrint (void) +void ExaPrn_ShowExamPrint (void) { extern const char *Hlp_ASSESSMENT_Exams; struct Exa_Exams Exams; struct Exa_Exam Exam; struct ExaEvt_Event Event; struct ExaPrn_Print Print; + bool PrintExists; /***** Reset exams context *****/ Exa_ResetExams (&Exams); @@ -149,29 +157,47 @@ void ExaPrn_ShowNewExamPrint (void) /***** Begin table *****/ HTM_TABLE_BeginWideMarginPadding (10); - /***** Get questions from database *****/ - ExaPrn_GetQuestionsForNewPrintFromDB (&Exam,&Print); + /***** Check if already exists exam in database *****/ + PrintExists = ExaPrn_CheckIfMyPrintExists (&Event); - if (Print.NumQsts) + if (PrintExists) { - /***** Create new exam print in database *****/ - ExaPrn_CreatePrintInDB (&Event,&Print); - ExaPrn_ComputeScoresAndStoreQuestionsOfPrint (&Print, - false); // Don't update question score - - /***** Show test exam to be answered *****/ - // Tst_ShowTestExamToFillIt (&Print,NumExamsGeneratedByMe,Tst_REQUEST); + Ale_ShowAlert (Ale_INFO,"El examen ya existe."); } - // else // No questions found - // { - // Ale_ShowAlert (Ale_INFO,Txt_No_questions_found_matching_your_search_criteria); - // Tst_ShowFormRequestTest (&Test); // Show the form again - // } + else + { + /***** Get questions from database *****/ + ExaPrn_GetQuestionsForNewPrintFromDB (&Exam,&Print); + + if (Print.NumQsts) + { + /***** Create/update new exam print in database *****/ + ExaPrn_CreatePrintInDB (&Event,&Print); + ExaPrn_ComputeScoresAndStoreQuestionsOfPrint (&Print, + false); // Don't update question score + } + } + + /***** Show test exam to be answered *****/ + ExaPrn_ShowExamPrintToFillIt (&Exam,&Print); /***** End table *****/ HTM_TABLE_End (); } +/*****************************************************************************/ +/********* Check if my exam print associated to a given event exists *********/ +/*****************************************************************************/ +// Return true if print exists + +static bool ExaPrn_CheckIfMyPrintExists (const struct ExaEvt_Event *Event) + { + return (DB_QueryCOUNT ("can not check if exam print exists", + "SELECT COUNT(*) FROM exa_prints" + " WHERE EvtCod=%ld AND UsrCod=%ld", + Event->EvtCod,Gbl.Usrs.Me.UsrDat.UsrCod) != 0); + } + /*****************************************************************************/ /*********** Get questions for a new exam print from the database ************/ /*****************************************************************************/ @@ -312,6 +338,12 @@ static unsigned ExaPrn_GetSomeQstsFromSetToPrint (struct ExaPrn_Print *Print, /* Get question code (row[0]) */ Print->PrintedQuestions[*NumQstInPrint].QstCod = Str_ConvertStrCodToLongCod (row[0]); + /* Set set of questions */ + Print->PrintedQuestions[*NumQstInPrint].SetCod = Set->SetCod; + + Ale_ShowAlert (Ale_INFO,"DEBUG: ExaPrn_GetSomeQstsFromSetToPrint Print->PrintedQuestions[*NumQstInPrint].SetCod = %ld", + Print->PrintedQuestions[*NumQstInPrint].SetCod); + /* Get answer type (row[1]) */ AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]); @@ -439,17 +471,113 @@ static void ExaPrn_StoreOneQstOfPrintInDB (const struct ExaPrn_Print *Print, Par_ReplaceSeparatorMultipleByComma (Print->PrintedQuestions[NumQst].StrIndexes,StrIndexes); Par_ReplaceSeparatorMultipleByComma (Print->PrintedQuestions[NumQst].StrAnswers,StrAnswers); + Ale_ShowAlert (Ale_INFO,"DEBUG: ExaPrn_StoreOneQstOfPrintInDB Print->PrintedQuestions[NumQst].SetCod = %ld", + Print->PrintedQuestions[NumQst].SetCod); + /***** Insert question and user's answers into database *****/ Str_SetDecimalPointToUS (); // To print the floating point as a dot DB_QueryREPLACE ("can not update a question in an exam print", "REPLACE INTO exa_print_questions" - " (PrnCod,QstCod,QstInd,Score,Indexes,Answers)" + " (PrnCod,QstCod,QstInd,SetCod,Score,Indexes,Answers)" " VALUES" - " (%ld,%ld,%u,'%.15lg','%s','%s')", + " (%ld,%ld,%u,%ld,'%.15lg','%s','%s')", Print->PrnCod,Print->PrintedQuestions[NumQst].QstCod, NumQst, // 0, 1, 2, 3... + Print->PrintedQuestions[NumQst].SetCod, Print->PrintedQuestions[NumQst].Score, StrIndexes, StrAnswers); Str_SetDecimalPointToLocal (); // Return to local system } + +/*****************************************************************************/ +/****************** Show a test exam print to be answered ********************/ +/*****************************************************************************/ + +static void ExaPrn_ShowExamPrintToFillIt (struct Exa_Exam *Exam, + struct ExaPrn_Print *Print) + { + extern const char *Hlp_ASSESSMENT_Exams; + extern const char *Txt_Send; + unsigned NumQst; + struct Tst_Question Question; + + /***** Begin box *****/ + Box_BoxBegin (NULL,Exam->Title, + NULL,NULL, + Hlp_ASSESSMENT_Exams,Box_NOT_CLOSABLE); + Lay_WriteHeaderClassPhoto (false,false, + Gbl.Hierarchy.Ins.InsCod, + Gbl.Hierarchy.Deg.DegCod, + Gbl.Hierarchy.Crs.CrsCod); + + if (Print->NumQsts) + { + /***** Begin form *****/ + Frm_StartForm (ActReqAssExaPrn); + ExaPrn_PutParamPrnCod (Print->PrnCod); + + /***** Begin table *****/ + HTM_TABLE_BeginWideMarginPadding (10); + + /***** Write one row for each question *****/ + for (NumQst = 0; + NumQst < Print->NumQsts; + NumQst++) + { + Gbl.RowEvenOdd = NumQst % 2; + + /* Create test question */ + Tst_QstConstructor (&Question); + Question.QstCod = Print->PrintedQuestions[NumQst].QstCod; + + /* Show question */ + if (!Tst_GetQstDataFromDB (&Question)) // Question exists + Lay_ShowErrorAndExit ("Wrong question."); + + /* Write question and answers */ + Tst_WriteQstAndAnsSeeing (&Print->PrintedQuestions[NumQst],NumQst,&Question); + + /* Destroy test question */ + Tst_QstDestructor (&Question); + } + + /***** End table *****/ + HTM_TABLE_End (); + + /***** Send buttona and end form *****/ + Btn_PutCreateButton (Txt_Send); + Frm_EndForm (); + } + + /***** End box *****/ + Box_BoxEnd (); + } + +/*****************************************************************************/ +/********************** Receive answer to an exam print **********************/ +/*****************************************************************************/ + +void ExaPrn_ReceivePrintAnswer (void) + { + Ale_ShowAlert (Ale_INFO,"Recepción del examen contestado."); + } + +/*****************************************************************************/ +/***************** Write parameter with code of exam print *******************/ +/*****************************************************************************/ + +static void ExaPrn_PutParamPrnCod (long ExaCod) + { + Par_PutHiddenParamLong (NULL,"PrnCod",ExaCod); + } + +/*****************************************************************************/ +/***************** Get parameter with code of exam print *********************/ +/*****************************************************************************/ + +static long ExaPrn_GetParamPrnCod (void) + { + /***** Get code of exam print *****/ + return Par_GetParToLong ("PrnCod"); + } diff --git a/swad_exam_print.h b/swad_exam_print.h index 6047104b..be556339 100644 --- a/swad_exam_print.h +++ b/swad_exam_print.h @@ -35,6 +35,9 @@ /***************************** Public prototypes *****************************/ /*****************************************************************************/ -void ExaPrn_ShowNewExamPrint (void); +void ExaPrn_ShowExamPrint (void); + +void ExaPrn_ReceivePrintAnswer (void); + #endif diff --git a/swad_test.c b/swad_test.c index 325c86ef..b7918d56 100644 --- a/swad_test.c +++ b/swad_test.c @@ -137,14 +137,10 @@ static void Tst_GetAnswersFromForm (struct TstPrn_Print *Print); static bool Tst_CheckIfNextTstAllowed (void); static unsigned Tst_GetNumExamsGeneratedByMe (void); -static void Tst_ShowTestExamToFillIt (struct TstPrn_Print *Print, +static void Tst_ShowTestPrintToFillIt (struct TstPrn_Print *Print, unsigned NumExamsGeneratedByMe, Tst_RequestOrConfirm_t RequestOrConfirm); -static void Tst_WriteQstAndAnsSeeing (const struct TstPrn_Print *Print, - unsigned NumQst, - const struct Tst_Question *Question); - static void Tst_PutFormToEditQstMedia (const struct Media *Media,int NumMediaInForm, bool OptionsDisabled); static void Tst_IncreaseMyNumAccessTst (void); @@ -193,28 +189,28 @@ static void Tst_ListOneOrMoreQuestionsForSelectionForGame (struct Gam_Games *Gam static void Tst_WriteQuestionRowForSelection (unsigned NumQst, struct Tst_Question *Question); -static void Tst_WriteAnswersSeeing (const struct TstPrn_Print *Print, +static void Tst_WriteAnswersSeeing (const struct TstPrn_PrintedQuestion *PrintedQuestion, unsigned NumQst, const struct Tst_Question *Question); static void Tst_WriteIntAnsListing (const struct Tst_Question *Question); -static void Tst_WriteIntAnsSeeing (const struct TstPrn_Print *Print, +static void Tst_WriteIntAnsSeeing (const struct TstPrn_PrintedQuestion *PrintedQuestion, unsigned NumQst); static void Tst_WriteFloatAnsEdit (const struct Tst_Question *Question); -static void Tst_WriteFloatAnsSeeing (const struct TstPrn_Print *Print, +static void Tst_WriteFloatAnsSeeing (const struct TstPrn_PrintedQuestion *PrintedQuestion, unsigned NumQst); static void Tst_WriteTFAnsListing (const struct Tst_Question *Question); -static void Tst_WriteTFAnsSeeing (const struct TstPrn_Print *Print, +static void Tst_WriteTFAnsSeeing (const struct TstPrn_PrintedQuestion *PrintedQuestion, unsigned NumQst); static void Tst_WriteChoiceAnsListing (const struct Tst_Question *Question); -static void Tst_WriteChoiceAnsSeeing (const struct TstPrn_Print *Print, +static void Tst_WriteChoiceAnsSeeing (const struct TstPrn_PrintedQuestion *PrintedQuestion, unsigned NumQst, const struct Tst_Question *Question); -static void Tst_WriteTextAnsSeeing (const struct TstPrn_Print *Print, +static void Tst_WriteTextAnsSeeing (const struct TstPrn_PrintedQuestion *PrintedQuestion, unsigned NumQst); static void Tst_WriteParamQstCod (unsigned NumQst,long QstCod); @@ -472,7 +468,7 @@ void Tst_ShowNewTest (void) false); // Don't update question score /***** Show test exam to be answered *****/ - Tst_ShowTestExamToFillIt (&Print,NumExamsGeneratedByMe,Tst_REQUEST); + Tst_ShowTestPrintToFillIt (&Print,NumExamsGeneratedByMe,Tst_REQUEST); /***** Update date-time of my next allowed access to test *****/ if (Gbl.Usrs.Me.Role.Logged == Rol_STD) @@ -530,7 +526,7 @@ void Tst_ReceiveTestDraft (void) /***** Get basic parameters of the exam *****/ /* Get test exam code from form */ TstPrn_ResetResult (&Print); - if ((Print.PrnCod = TstPrn_GetParamExaCod ()) <= 0) + if ((Print.PrnCod = TstPrn_GetParamPrnCod ()) <= 0) Lay_ShowErrorAndExit ("Wrong test exam."); /* Get number of this test from form */ @@ -561,7 +557,7 @@ void Tst_ReceiveTestDraft (void) Ale_ShowAlert (Ale_WARNING,Txt_Please_review_your_answers_before_submitting_the_exam); /* Show the same test exam to be answered */ - Tst_ShowTestExamToFillIt (&Print,NumTst,Tst_CONFIRM); + Tst_ShowTestPrintToFillIt (&Print,NumTst,Tst_CONFIRM); } } @@ -586,7 +582,7 @@ void Tst_AssessTest (void) /***** Get basic parameters of the exam *****/ /* Get test exam code from form */ TstPrn_ResetResult (&Print); - if ((Print.PrnCod = TstPrn_GetParamExaCod ()) <= 0) + if ((Print.PrnCod = TstPrn_GetParamPrnCod ()) <= 0) Lay_ShowErrorAndExit ("Wrong test exam."); /* Get number of this test from form */ @@ -783,12 +779,12 @@ static unsigned Tst_GetNumExamsGeneratedByMe (void) } /*****************************************************************************/ -/************************ Show a test exam to be answered ********************/ +/****************** Show a test exam print to be answered ********************/ /*****************************************************************************/ -static void Tst_ShowTestExamToFillIt (struct TstPrn_Print *Print, - unsigned NumExamsGeneratedByMe, - Tst_RequestOrConfirm_t RequestOrConfirm) +static void Tst_ShowTestPrintToFillIt (struct TstPrn_Print *Print, + unsigned NumExamsGeneratedByMe, + Tst_RequestOrConfirm_t RequestOrConfirm) { extern const char *Hlp_ASSESSMENT_Tests; extern const char *Txt_Test; @@ -815,7 +811,7 @@ static void Tst_ShowTestExamToFillIt (struct TstPrn_Print *Print, { /***** Begin form *****/ Frm_StartForm (Action[RequestOrConfirm]); - TstPrn_PutParamExaCod (Print->PrnCod); + TstPrn_PutParamPrnCod (Print->PrnCod); Par_PutHiddenParamUnsigned (NULL,"NumTst",NumExamsGeneratedByMe); /***** Begin table *****/ @@ -837,7 +833,7 @@ static void Tst_ShowTestExamToFillIt (struct TstPrn_Print *Print, Lay_ShowErrorAndExit ("Wrong question."); /* Write question and answers */ - Tst_WriteQstAndAnsSeeing (Print,NumQst,&Question); + Tst_WriteQstAndAnsSeeing (&Print->PrintedQuestions[NumQst],NumQst,&Question); /* Destroy test question */ Tst_QstDestructor (&Question); @@ -901,9 +897,9 @@ void Tst_ShowTagList (unsigned NumTags,MYSQL_RES *mysql_res) /********** Write a row of a test, with one question and its answer **********/ /*****************************************************************************/ -static void Tst_WriteQstAndAnsSeeing (const struct TstPrn_Print *Print, - unsigned NumQst, - const struct Tst_Question *Question) +void Tst_WriteQstAndAnsSeeing (struct TstPrn_PrintedQuestion *PrintedQuestion, + unsigned NumQst, + const struct Tst_Question *Question) { /***** Begin row *****/ HTM_TR_Begin (NULL); @@ -929,7 +925,7 @@ static void Tst_WriteQstAndAnsSeeing (const struct TstPrn_Print *Print, "TEST_MED_SHOW"); /* Answers */ - Tst_WriteAnswersSeeing (Print,NumQst,Question); + Tst_WriteAnswersSeeing (PrintedQuestion,NumQst,Question); HTM_TD_End (); @@ -3357,7 +3353,7 @@ void Tst_WriteAnswersListing (const struct Tst_Question *Question) /************** Write answers of a question when seeing a test ***************/ /*****************************************************************************/ -static void Tst_WriteAnswersSeeing (const struct TstPrn_Print *Print, +static void Tst_WriteAnswersSeeing (const struct TstPrn_PrintedQuestion *PrintedQuestion, unsigned NumQst, const struct Tst_Question *Question) { @@ -3365,20 +3361,20 @@ static void Tst_WriteAnswersSeeing (const struct TstPrn_Print *Print, switch (Question->Answer.Type) { case Tst_ANS_INT: - Tst_WriteIntAnsSeeing (Print,NumQst); + Tst_WriteIntAnsSeeing (PrintedQuestion,NumQst); break; case Tst_ANS_FLOAT: - Tst_WriteFloatAnsSeeing (Print,NumQst); + Tst_WriteFloatAnsSeeing (PrintedQuestion,NumQst); break; case Tst_ANS_TRUE_FALSE: - Tst_WriteTFAnsSeeing (Print,NumQst); + Tst_WriteTFAnsSeeing (PrintedQuestion,NumQst); break; case Tst_ANS_UNIQUE_CHOICE: case Tst_ANS_MULTIPLE_CHOICE: - Tst_WriteChoiceAnsSeeing (Print,NumQst,Question); + Tst_WriteChoiceAnsSeeing (PrintedQuestion,NumQst,Question); break; case Tst_ANS_TEXT: - Tst_WriteTextAnsSeeing (Print,NumQst); + Tst_WriteTextAnsSeeing (PrintedQuestion,NumQst); break; default: break; @@ -3414,7 +3410,7 @@ static void Tst_WriteIntAnsListing (const struct Tst_Question *Question) /****************** Write integer answer when seeing a test ******************/ /*****************************************************************************/ -static void Tst_WriteIntAnsSeeing (const struct TstPrn_Print *Print, +static void Tst_WriteIntAnsSeeing (const struct TstPrn_PrintedQuestion *PrintedQuestion, unsigned NumQst) { char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x" @@ -3423,7 +3419,7 @@ static void Tst_WriteIntAnsSeeing (const struct TstPrn_Print *Print, snprintf (StrAns,sizeof (StrAns), "Ans%010u", NumQst); - HTM_INPUT_TEXT (StrAns,11,Print->PrintedQuestions[NumQst].StrAnswers, + HTM_INPUT_TEXT (StrAns,11,PrintedQuestion->StrAnswers, HTM_DONT_SUBMIT_ON_CHANGE, "size=\"11\""); } @@ -3447,7 +3443,7 @@ static void Tst_WriteFloatAnsEdit (const struct Tst_Question *Question) /****************** Write float answer when seeing a test ********************/ /*****************************************************************************/ -static void Tst_WriteFloatAnsSeeing (const struct TstPrn_Print *Print, +static void Tst_WriteFloatAnsSeeing (const struct TstPrn_PrintedQuestion *PrintedQuestion, unsigned NumQst) { char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x" @@ -3456,7 +3452,7 @@ static void Tst_WriteFloatAnsSeeing (const struct TstPrn_Print *Print, snprintf (StrAns,sizeof (StrAns), "Ans%010u", NumQst); - HTM_INPUT_TEXT (StrAns,Tst_MAX_BYTES_FLOAT_ANSWER,Print->PrintedQuestions[NumQst].StrAnswers, + HTM_INPUT_TEXT (StrAns,Tst_MAX_BYTES_FLOAT_ANSWER,PrintedQuestion->StrAnswers, HTM_DONT_SUBMIT_ON_CHANGE, "size=\"11\""); } @@ -3479,7 +3475,7 @@ static void Tst_WriteTFAnsListing (const struct Tst_Question *Question) /************** Write false / true answer when seeing a test ****************/ /*****************************************************************************/ -static void Tst_WriteTFAnsSeeing (const struct TstPrn_Print *Print, +static void Tst_WriteTFAnsSeeing (const struct TstPrn_PrintedQuestion *PrintedQuestion, unsigned NumQst) { extern const char *Txt_TF_QST[2]; @@ -3490,9 +3486,9 @@ static void Tst_WriteTFAnsSeeing (const struct TstPrn_Print *Print, ==> the exam may be half filled ==> the answers displayed will be those selected by the user. */ HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, "name=\"Ans%010u\"",NumQst); - HTM_OPTION (HTM_Type_STRING,"" ,Print->PrintedQuestions[NumQst].StrAnswers[0] == '\0',false," "); - HTM_OPTION (HTM_Type_STRING,"T",Print->PrintedQuestions[NumQst].StrAnswers[0] == 'T' ,false,"%s",Txt_TF_QST[0]); - HTM_OPTION (HTM_Type_STRING,"F",Print->PrintedQuestions[NumQst].StrAnswers[0] == 'F' ,false,"%s",Txt_TF_QST[1]); + HTM_OPTION (HTM_Type_STRING,"" ,PrintedQuestion->StrAnswers[0] == '\0',false," "); + HTM_OPTION (HTM_Type_STRING,"T",PrintedQuestion->StrAnswers[0] == 'T' ,false,"%s",Txt_TF_QST[0]); + HTM_OPTION (HTM_Type_STRING,"F",PrintedQuestion->StrAnswers[0] == 'F' ,false,"%s",Txt_TF_QST[1]); HTM_SELECT_End (); } @@ -3612,7 +3608,7 @@ static void Tst_WriteChoiceAnsListing (const struct Tst_Question *Question) /******** Write single or multiple choice answer when seeing a test **********/ /*****************************************************************************/ -static void Tst_WriteChoiceAnsSeeing (const struct TstPrn_Print *Print, +static void Tst_WriteChoiceAnsSeeing (const struct TstPrn_PrintedQuestion *PrintedQuestion, unsigned NumQst, const struct Tst_Question *Question) { @@ -3622,10 +3618,10 @@ static void Tst_WriteChoiceAnsSeeing (const struct TstPrn_Print *Print, char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x" /***** Get indexes for this question from string *****/ - TstPrn_GetIndexesFromStr (Print->PrintedQuestions[NumQst].StrIndexes,Indexes); + TstPrn_GetIndexesFromStr (PrintedQuestion->StrIndexes,Indexes); /***** Get the user's answers for this question from string *****/ - TstPrn_GetAnswersFromStr (Print->PrintedQuestions[NumQst].StrAnswers,UsrAnswers); + TstPrn_GetAnswersFromStr (PrintedQuestion->StrAnswers,UsrAnswers); /***** Begin table *****/ HTM_TABLE_BeginPadding (2); @@ -3753,7 +3749,7 @@ void Tst_GetChoiceAns (struct Tst_Question *Question,MYSQL_RES *mysql_res) /******************** Write text answer when seeing a test *******************/ /*****************************************************************************/ -static void Tst_WriteTextAnsSeeing (const struct TstPrn_Print *Print, +static void Tst_WriteTextAnsSeeing (const struct TstPrn_PrintedQuestion *PrintedQuestion, unsigned NumQst) { char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x" @@ -3762,7 +3758,7 @@ static void Tst_WriteTextAnsSeeing (const struct TstPrn_Print *Print, snprintf (StrAns,sizeof (StrAns), "Ans%010u", NumQst); - HTM_INPUT_TEXT (StrAns,Tst_MAX_CHARS_ANSWERS_ONE_QST,Print->PrintedQuestions[NumQst].StrAnswers, + HTM_INPUT_TEXT (StrAns,Tst_MAX_CHARS_ANSWERS_ONE_QST,PrintedQuestion->StrAnswers, HTM_DONT_SUBMIT_ON_CHANGE, "size=\"40\""); } diff --git a/swad_test.h b/swad_test.h index 7e94e711..0f90788c 100644 --- a/swad_test.h +++ b/swad_test.h @@ -106,6 +106,10 @@ void Tst_AssessTest (void); void Tst_ShowTagList (unsigned NumTags,MYSQL_RES *mysql_res); +void Tst_WriteQstAndAnsSeeing (struct TstPrn_PrintedQuestion *PrintedQuestion, + unsigned NumQst, + const struct Tst_Question *Question); + void Tst_ListQuestionForEdition (const struct Tst_Question *Question, unsigned QstInd,bool QuestionExists, const char *Anchor); diff --git a/swad_test_print.c b/swad_test_print.c index f29790b1..c3f2a34a 100644 --- a/swad_test_print.c +++ b/swad_test_print.c @@ -1764,7 +1764,7 @@ static void TstPrn_ShowExams (struct UsrData *UsrDat) { Frm_StartForm (Gbl.Action.Act == ActSeeMyTstRes ? ActSeeOneTstResMe : ActSeeOneTstResOth); - TstPrn_PutParamExaCod (Print.PrnCod); + TstPrn_PutParamPrnCod (Print.PrnCod); Ico_PutIconLink ("tasks.svg",Txt_View_test); Frm_EndForm (); } @@ -1793,22 +1793,22 @@ static void TstPrn_ShowExams (struct UsrData *UsrDat) } /*****************************************************************************/ -/****************** Write parameter with code of test exam *******************/ +/*************** Write parameter with code of test exam print ****************/ /*****************************************************************************/ -void TstPrn_PutParamExaCod (long ExaCod) +void TstPrn_PutParamPrnCod (long ExaCod) { - Par_PutHiddenParamLong (NULL,"ExaCod",ExaCod); + Par_PutHiddenParamLong (NULL,"PrnCod",ExaCod); } /*****************************************************************************/ -/****************** Get parameter with code of test exam *********************/ +/*************** Get parameter with code of test exam print ******************/ /*****************************************************************************/ -long TstPrn_GetParamExaCod (void) +long TstPrn_GetParamPrnCod (void) { - /***** Get code of exam *****/ - return Par_GetParToLong ("ExaCod"); + /***** Get code of test exam print *****/ + return Par_GetParToLong ("PrnCod"); } /*****************************************************************************/ @@ -1922,7 +1922,7 @@ void TstPrn_ShowOneExam (void) /***** Get the code of the test *****/ TstPrn_ResetResult (&Print); - if ((Print.PrnCod = TstPrn_GetParamExaCod ()) == -1L) + if ((Print.PrnCod = TstPrn_GetParamPrnCod ()) == -1L) Lay_ShowErrorAndExit ("Code of test is missing."); /***** Get test exam data *****/ diff --git a/swad_test_print.h b/swad_test_print.h index e65f78b3..f8b75ec5 100644 --- a/swad_test_print.h +++ b/swad_test_print.h @@ -42,6 +42,7 @@ struct TstPrn_PrintedQuestion { long QstCod; // Question code + long SetCod; // Only for exams char StrIndexes[Tst_MAX_BYTES_INDEXES_ONE_QST + 1]; // 0 1 2 3, 3 0 2 1, etc. char StrAnswers[Tst_MAX_BYTES_ANSWERS_ONE_QST + 1]; // Answers selected by user double Score; // Question score @@ -91,8 +92,8 @@ void TstPrn_SelDatesToSeeMyExams (void); void TstPrn_ShowMyExams (void); void TstPrn_GetUsrsAndShowExams (void); -void TstPrn_PutParamExaCod (long ExaCod); -long TstPrn_GetParamExaCod (void); +void TstPrn_PutParamPrnCod (long ExaCod); +long TstPrn_GetParamPrnCod (void); void TstPrn_ShowOneExam (void); void TstPrn_ShowExamAnswers (struct UsrData *UsrDat,