Version19.250

This commit is contained in:
acanas 2020-06-17 20:20:16 +02:00
parent edc8e30523
commit 070f385157
18 changed files with 420 additions and 4442 deletions

File diff suppressed because it is too large Load Diff

View File

@ -715,6 +715,8 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
[ActAddQstToExa ] = {1887,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaSet_AddQstsToSet ,NULL},
[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},
[ActValSetQst ] = {1909,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaSet_ValidateQst ,NULL},
[ActInvSetQst ] = {1910,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaSet_InvalidateQst ,NULL},
[ActReqNewExaSes ] = {1852,-1,TabUnk,ActSeeAllExa ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaSes_RequestCreatOrEditSession,NULL},
[ActEdiOneExaSes ] = {1902,-1,TabUnk,ActSeeAllExa ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,ExaSes_RequestCreatOrEditSession,NULL},
@ -3718,6 +3720,8 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un
ActAnsExaPrn, // #1906
ActEdiTag, // #1907
ActEndExaPrn, // #1908
ActValSetQst, // #1909
ActInvSetQst, // #1910
};
/*****************************************************************************/

View File

@ -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 1908
#define Act_MAX_ACTION_COD 1910
#define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13
@ -680,96 +680,98 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to
#define ActAddQstToExa (ActChgCrsTT1stDay + 152)
#define ActReqRemSetQst (ActChgCrsTT1stDay + 153)
#define ActRemExaQst (ActChgCrsTT1stDay + 154)
#define ActValSetQst (ActChgCrsTT1stDay + 155)
#define ActInvSetQst (ActChgCrsTT1stDay + 156)
#define ActReqNewExaSes (ActChgCrsTT1stDay + 155)
#define ActEdiOneExaSes (ActChgCrsTT1stDay + 156)
#define ActNewExaSes (ActChgCrsTT1stDay + 157)
#define ActChgExaSes (ActChgCrsTT1stDay + 158)
#define ActReqRemExaSes (ActChgCrsTT1stDay + 159)
#define ActRemExaSes (ActChgCrsTT1stDay + 160)
#define ActHidExaSes (ActChgCrsTT1stDay + 161)
#define ActUnhExaSes (ActChgCrsTT1stDay + 162)
#define ActReqNewExaSes (ActChgCrsTT1stDay + 157)
#define ActEdiOneExaSes (ActChgCrsTT1stDay + 158)
#define ActNewExaSes (ActChgCrsTT1stDay + 159)
#define ActChgExaSes (ActChgCrsTT1stDay + 160)
#define ActReqRemExaSes (ActChgCrsTT1stDay + 161)
#define ActRemExaSes (ActChgCrsTT1stDay + 162)
#define ActHidExaSes (ActChgCrsTT1stDay + 163)
#define ActUnhExaSes (ActChgCrsTT1stDay + 164)
#define ActSeeExaPrn (ActChgCrsTT1stDay + 163)
#define ActAnsExaPrn (ActChgCrsTT1stDay + 164)
#define ActEndExaPrn (ActChgCrsTT1stDay + 165)
#define ActSeeExaPrn (ActChgCrsTT1stDay + 165)
#define ActAnsExaPrn (ActChgCrsTT1stDay + 166)
#define ActEndExaPrn (ActChgCrsTT1stDay + 167)
#define ActSeeMyExaResCrs (ActChgCrsTT1stDay + 166)
#define ActSeeMyExaResExa (ActChgCrsTT1stDay + 167)
#define ActSeeMyExaResSes (ActChgCrsTT1stDay + 168)
#define ActSeeOneExaResMe (ActChgCrsTT1stDay + 169)
#define ActReqSeeUsrExaRes (ActChgCrsTT1stDay + 170)
#define ActSeeUsrExaResCrs (ActChgCrsTT1stDay + 171)
#define ActSeeUsrExaResExa (ActChgCrsTT1stDay + 172)
#define ActSeeUsrExaResSes (ActChgCrsTT1stDay + 173)
#define ActSeeOneExaResOth (ActChgCrsTT1stDay + 174)
#define ActChgVisExaRes (ActChgCrsTT1stDay + 175)
#define ActSeeMyExaResCrs (ActChgCrsTT1stDay + 168)
#define ActSeeMyExaResExa (ActChgCrsTT1stDay + 169)
#define ActSeeMyExaResSes (ActChgCrsTT1stDay + 170)
#define ActSeeOneExaResMe (ActChgCrsTT1stDay + 171)
#define ActReqSeeUsrExaRes (ActChgCrsTT1stDay + 172)
#define ActSeeUsrExaResCrs (ActChgCrsTT1stDay + 173)
#define ActSeeUsrExaResExa (ActChgCrsTT1stDay + 174)
#define ActSeeUsrExaResSes (ActChgCrsTT1stDay + 175)
#define ActSeeOneExaResOth (ActChgCrsTT1stDay + 176)
#define ActChgVisExaRes (ActChgCrsTT1stDay + 177)
#define ActSeeGam (ActChgCrsTT1stDay + 176)
#define ActReqRemMch (ActChgCrsTT1stDay + 177)
#define ActRemMch (ActChgCrsTT1stDay + 178)
#define ActReqNewMch (ActChgCrsTT1stDay + 179)
#define ActNewMch (ActChgCrsTT1stDay + 180)
#define ActResMch (ActChgCrsTT1stDay + 181)
#define ActBckMch (ActChgCrsTT1stDay + 182)
#define ActPlyPauMch (ActChgCrsTT1stDay + 183)
#define ActFwdMch (ActChgCrsTT1stDay + 184)
#define ActChgNumColMch (ActChgCrsTT1stDay + 185)
#define ActChgVisResMchQst (ActChgCrsTT1stDay + 186)
#define ActMchCntDwn (ActChgCrsTT1stDay + 187)
#define ActRefMchTch (ActChgCrsTT1stDay + 188)
#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 + 189)
#define ActSeeMchAnsQstStd (ActChgCrsTT1stDay + 190)
#define ActRemMchAnsQstStd (ActChgCrsTT1stDay + 191)
#define ActAnsMchQstStd (ActChgCrsTT1stDay + 192)
#define ActRefMchStd (ActChgCrsTT1stDay + 193)
#define ActJoiMch (ActChgCrsTT1stDay + 191)
#define ActSeeMchAnsQstStd (ActChgCrsTT1stDay + 192)
#define ActRemMchAnsQstStd (ActChgCrsTT1stDay + 193)
#define ActAnsMchQstStd (ActChgCrsTT1stDay + 194)
#define ActRefMchStd (ActChgCrsTT1stDay + 195)
#define ActSeeMyMchResCrs (ActChgCrsTT1stDay + 194)
#define ActSeeMyMchResGam (ActChgCrsTT1stDay + 195)
#define ActSeeMyMchResMch (ActChgCrsTT1stDay + 196)
#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 197)
#define ActSeeMyMchResCrs (ActChgCrsTT1stDay + 196)
#define ActSeeMyMchResGam (ActChgCrsTT1stDay + 197)
#define ActSeeMyMchResMch (ActChgCrsTT1stDay + 198)
#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 199)
#define ActReqSeeUsrMchRes (ActChgCrsTT1stDay + 198)
#define ActSeeUsrMchResCrs (ActChgCrsTT1stDay + 199)
#define ActSeeUsrMchResGam (ActChgCrsTT1stDay + 200)
#define ActSeeUsrMchResMch (ActChgCrsTT1stDay + 201)
#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 202)
#define ActReqSeeUsrMchRes (ActChgCrsTT1stDay + 200)
#define ActSeeUsrMchResCrs (ActChgCrsTT1stDay + 201)
#define ActSeeUsrMchResGam (ActChgCrsTT1stDay + 202)
#define ActSeeUsrMchResMch (ActChgCrsTT1stDay + 203)
#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 204)
#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 203)
#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 205)
#define ActFrmNewGam (ActChgCrsTT1stDay + 204)
#define ActEdiOneGam (ActChgCrsTT1stDay + 205)
#define ActNewGam (ActChgCrsTT1stDay + 206)
#define ActChgGam (ActChgCrsTT1stDay + 207)
#define ActReqRemGam (ActChgCrsTT1stDay + 208)
#define ActRemGam (ActChgCrsTT1stDay + 209)
#define ActHidGam (ActChgCrsTT1stDay + 210)
#define ActShoGam (ActChgCrsTT1stDay + 211)
#define ActAddOneGamQst (ActChgCrsTT1stDay + 212)
#define ActGamLstTstQst (ActChgCrsTT1stDay + 213)
#define ActAddTstQstToGam (ActChgCrsTT1stDay + 214)
#define ActReqRemGamQst (ActChgCrsTT1stDay + 215)
#define ActRemGamQst (ActChgCrsTT1stDay + 216)
#define ActUp_GamQst (ActChgCrsTT1stDay + 217)
#define ActDwnGamQst (ActChgCrsTT1stDay + 218)
#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 + 219)
#define ActAnsSvy (ActChgCrsTT1stDay + 220)
#define ActFrmNewSvy (ActChgCrsTT1stDay + 221)
#define ActEdiOneSvy (ActChgCrsTT1stDay + 222)
#define ActNewSvy (ActChgCrsTT1stDay + 223)
#define ActChgSvy (ActChgCrsTT1stDay + 224)
#define ActReqRemSvy (ActChgCrsTT1stDay + 225)
#define ActRemSvy (ActChgCrsTT1stDay + 226)
#define ActReqRstSvy (ActChgCrsTT1stDay + 227)
#define ActRstSvy (ActChgCrsTT1stDay + 228)
#define ActHidSvy (ActChgCrsTT1stDay + 229)
#define ActShoSvy (ActChgCrsTT1stDay + 230)
#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 231)
#define ActRcvSvyQst (ActChgCrsTT1stDay + 232)
#define ActReqRemSvyQst (ActChgCrsTT1stDay + 233)
#define ActRemSvyQst (ActChgCrsTT1stDay + 234)
#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)
/*****************************************************************************/
/******************************** Files tab **********************************/

View File

@ -414,7 +414,7 @@ static void Ale_ShowFixAlertAndButton1 (Ale_AlertType_t AlertType,const char *Tx
HTM_DIV_Begin ("class=\"ALERT_CLOSE\"");
HTM_A_Begin ("href=\"\" onclick=\"toggleDisplay('%s');return false;\" /",
IdAlert);
Ico_PutIcon ("close.svg",Txt_Close,"ICO16x16");
Ico_PutIcon ("times.svg",Txt_Close,"ICO16x16");
HTM_A_End ();
HTM_DIV_End ();
}

View File

@ -356,7 +356,7 @@ static void Ann_DrawAnAnnouncement (long AnnCod,Ann_Status_t Status,
/***** Put form to mark announcement as seen *****/
Lay_PutContextualLinkIconText (ActAnnSee,NULL,
Ann_PutParams,&AnnCod,
"close.svg",
"times.svg",
Txt_Do_not_show_again);
HTM_DIV_End ();

View File

@ -182,7 +182,7 @@ static void Box_BoxInternalBegin (const char *Width,const char *Title,
HTM_A_Begin ("href=\"\" onclick=\"toggleDisplay('%s');return false;\"",
Gbl.Box.Ids[Gbl.Box.Nested]);
Ico_PutDivIcon ("CONTEXT_OPT HLP_HIGHLIGHT",
"close.svg",Txt_Close);
"times.svg",Txt_Close);
HTM_A_End ();
}

View File

@ -556,14 +556,22 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
En OpenSWAD:
ps2pdf source.ps destination.pdf
*/
#define Log_PLATFORM_VERSION "SWAD 19.249.1 (2020-06-17)"
#define CSS_FILE "swad19.238.2.css"
#define Log_PLATFORM_VERSION "SWAD 19.250 (2020-06-17)"
#define CSS_FILE "swad19.250.css"
#define JS_FILE "swad19.246.1.js"
/*
TODO: Encarnación Hidalgo Tenorio: Antonio, ¿podría @swad_ugr mandar una notificación cuando el alumnado ha mandado su tarea?
Se trataría de añadir un par de líneas "Nuevos archivos en actividades", "Nuevos archivos en otros trabajos".
TODO: Fix bug: Cuando se pulsa en ver fichas, y luego en una ficha en "Ver trabajos" o "Ver exámenes", o lo que sea, sale dos veces ese estudiante.
Version 19.250: Jun 17, 2020 Exam questions can be invalidated. Not finished. (302974 lines)
1 change necessary in database:
ALTER TABLE exa_set_questions ADD COLUMN Invalid ENUM('N','Y') NOT NULL DEFAULT 'N' AFTER SetCod;
Copy the following 3 icons to icon public directory:
sudo cp icon/times.svg /var/www/html/swad/icon/
sudo cp icon/times-red.svg /var/www/html/swad/icon/
sudo cp icon/check-green.svg /var/www/html/swad/icon/
Version 19.249.1: Jun 17, 2020 Fixed bug removing a course. Reported by Raymon Moreno Colina. (302789 lines)
Version 19.249: Jun 17, 2020 Fixed bug in exams and matches.
Code refactoring in test questions. (302786 lines)
@ -619,7 +627,7 @@ ALTER TABLE exa_log ENGINE=MyISAM;
Bug fixing and code refactoring in tests and exams. (301712 lines)
1 change necessary in database:
CREATE TABLE IF NOT EXISTS exa_log (LogCod INT NOT NULL,PrnCod INT NOT NULL,ActCod INT NOT NULL,ClickTime DATETIME NOT NULL,IP CHAR(15) NOT NULL,SessionId CHAR(43) NOT NULL,UNIQUE INDEX(LogCod),INDEX(PrnCod,ClickTime),INDEX(ClickTime));
--------------
Version 19.240: May 21, 2020 Code refactoring in tests and exams. (301428 lines)
Version 19.239.9: May 21, 2020 Fixed issue in exam sessions: exam prints in sessions of hidden exams are no accesible. (301441 lines)
Version 19.239.8: May 21, 2020 Fixed issue in exam sessions: a student can not see hidden sessions. (301433 lines)

View File

@ -1227,22 +1227,24 @@ mysql> DESCRIBE exa_set_answers;
/***** Table exa_set_questions *****/
/*
mysql> DESCRIBE exa_set_questions;
+----------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------------+------+-----+---------+-------+
| QstCod | int(11) | NO | PRI | NULL | |
| AnsInd | tinyint(4) | NO | PRI | NULL | |
| Answer | text | NO | | NULL | |
| Feedback | text | NO | | NULL | |
| MedCod | int(11) | NO | MUL | -1 | |
| Correct | enum('N','Y') | NO | | NULL | |
+----------+---------------+------+-----+---------+-------+
6 rows in set (0.00 sec)
+----------+---------------------------------------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------------------------------------------------------------------------+------+-----+---------+----------------+
| QstCod | int(11) | NO | PRI | NULL | auto_increment |
| SetCod | int(11) | NO | MUL | NULL | |
| Invalid | enum('N','Y') | NO | | N | |
| AnsType | enum('int','float','true_false','unique_choice','multiple_choice','text') | NO | | NULL | |
| Shuffle | enum('N','Y') | NO | | NULL | |
| Stem | text | NO | | NULL | |
| Feedback | text | NO | | NULL | |
| MedCod | int(11) | NO | MUL | -1 | |
+----------+---------------------------------------------------------------------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS exa_set_questions ("
"QstCod INT NOT NULL AUTO_INCREMENT,"
"SetCod INT NOT NULL,"
"Invalid ENUM('N','Y') NOT NULL DEFAULT 'N',"
"AnsType ENUM ('int','float','true_false','unique_choice','multiple_choice','text') NOT NULL,"
"Shuffle ENUM('N','Y') NOT NULL,"
"Stem TEXT NOT NULL," // Cns_MAX_BYTES_TEXT

View File

@ -730,15 +730,15 @@ static void ExaPrn_WriteQstAndAnsToFill (const struct ExaPrn_Print *Print,
/***** Number of question and answer type *****/
HTM_TD_Begin ("class=\"RT\"");
Tst_WriteNumQst (NumQst + 1);
Tst_WriteAnswerType (Question->Answer.Type);
Tst_WriteNumQst (NumQst + 1,"BIG_INDEX");
Tst_WriteAnswerType (Question->Answer.Type,"DAT_SMALL");
HTM_TD_End ();
/***** Stem, media and answers *****/
HTM_TD_Begin ("class=\"LT\"");
/* Stem */
Tst_WriteQstStem (Question->Stem,"TEST_EXA",true);
Tst_WriteQstStem (Question->Stem,"TEST_TXT",true);
/* Media */
Med_ShowMedia (&Question->Media,
@ -903,14 +903,14 @@ static void ExaPrn_WriteChoAnsToFill (const struct ExaPrn_Print *Print,
HTM_TD_End ();
HTM_TD_Begin ("class=\"LT\"");
HTM_LABEL_Begin ("for=\"Ans%010u_%u\" class=\"ANS_TXT\"",NumQst,NumOpt);
HTM_LABEL_Begin ("for=\"Ans%010u_%u\" class=\"TEST_TXT\"",NumQst,NumOpt);
HTM_TxtF ("%c) ",'a' + (char) NumOpt);
HTM_LABEL_End ();
HTM_TD_End ();
/***** Write the option text *****/
HTM_TD_Begin ("class=\"LT\"");
HTM_LABEL_Begin ("for=\"Ans%010u_%u\" class=\"ANS_TXT\"",NumQst,NumOpt);
HTM_LABEL_Begin ("for=\"Ans%010u_%u\" class=\"TEST_TXT\"",NumQst,NumOpt);
HTM_Txt (Question->Answer.Options[Indexes[NumOpt]].Text);
HTM_LABEL_End ();
Med_ShowMedia (&Question->Answer.Options[Indexes[NumOpt]].Media,

View File

@ -1463,6 +1463,16 @@ static void ExaRes_WriteQstAndAnsExam (struct UsrData *UsrDat,
{
extern const char *Txt_Score;
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY];
static char *ClassTxt[Tst_NUM_VALIDITIES] =
{
[Tst_INVALID_QUESTION] = "TEST_TXT_RED",
[Tst_VALID_QUESTION ] = "TEST_TXT",
};
static char *ClassFeedback[Tst_NUM_VALIDITIES] =
{
[Tst_INVALID_QUESTION] = "TEST_TXT_LIGHT_RED",
[Tst_VALID_QUESTION ] = "TEST_TXT_LIGHT",
};
/***** Check if I can view each part of the question *****/
switch (Gbl.Usrs.Me.Role.Logged)
@ -1497,15 +1507,16 @@ static void ExaRes_WriteQstAndAnsExam (struct UsrData *UsrDat,
/***** Number of question and answer type *****/
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
Tst_WriteNumQst (NumQst + 1);
Tst_WriteAnswerType (Question->Answer.Type);
Tst_WriteNumQst (NumQst + 1,"BIG_INDEX");
Tst_WriteAnswerType (Question->Answer.Type,"DAT_SMALL");
HTM_TD_End ();
/***** Stem, media and answers *****/
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
/* Stem */
Tst_WriteQstStem (Question->Stem,"TEST_EXA",ICanView[TstVis_VISIBLE_QST_ANS_TXT]);
Tst_WriteQstStem (Question->Stem,ClassTxt[Question->Validity],
ICanView[TstVis_VISIBLE_QST_ANS_TXT]);
/* Media */
if (ICanView[TstVis_VISIBLE_QST_ANS_TXT])
@ -1516,7 +1527,9 @@ static void ExaRes_WriteQstAndAnsExam (struct UsrData *UsrDat,
/* Answers */
ExaPrn_ComputeAnswerScore (&Print->PrintedQuestions[NumQst],Question);
TstPrn_WriteAnswersExam (UsrDat,&Print->PrintedQuestions[NumQst],Question,
ICanView);
ICanView,
ClassTxt[Question->Validity],
ClassFeedback[Question->Validity]);
/* Write score retrieved from database */
if (ICanView[TstVis_VISIBLE_EACH_QST_SCORE])
@ -1535,7 +1548,7 @@ static void ExaRes_WriteQstAndAnsExam (struct UsrData *UsrDat,
/* Question feedback */
if (ICanView[TstVis_VISIBLE_FEEDBACK_TXT])
Tst_WriteQstFeedback (Question->Feedback,"TEST_EXA_LIGHT");
Tst_WriteQstFeedback (Question->Feedback,ClassFeedback[Question->Validity]);
HTM_TD_End ();

View File

@ -134,6 +134,8 @@ static void ExaSet_CopyQstFromBankToExamSet (struct ExaSet_Set *Set,long QstCod)
static void ExaSet_RemoveMediaFromStemOfQst (long SetCod,long QstCod);
static void ExaSet_RemoveMediaFromAllAnsOfQst (long SetCod,long QstCod);
static void ExaSet_ChangeValidityQst (Tst_Validity_t Valid);
static void ExaSet_GetAndCheckParameters (struct Exa_Exams *Exams,
struct Exa_Exam *Exam,
struct ExaSet_Set *Set);
@ -312,7 +314,7 @@ static void ExaSet_PutFormNewSet (struct Exa_Exams *Exams,
/***** Index *****/
HTM_TD_Begin ("class=\"RM\"");
Tst_WriteNumQst (MaxSetInd + 1);
Tst_WriteNumQst (MaxSetInd + 1,"BIG_INDEX");
HTM_TD_End ();
/***** Title *****/
@ -1148,7 +1150,7 @@ static void ExaSet_ListOneOrMoreSetsForEdition (struct Exa_Exams *Exams,
/***** Index *****/
HTM_TD_Begin ("rowspan=\"2\" class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
Tst_WriteNumQst (Set.SetInd);
Tst_WriteNumQst (Set.SetInd,"BIG_INDEX");
HTM_TD_End ();
/***** Title *****/
@ -1278,9 +1280,21 @@ static void ExaSet_ListOneOrMoreQuestionsForEdition (struct Exa_Exams *Exams,
MYSQL_ROW row;
struct Tst_Question Question;
char *Anchor;
/***** Build anchor string *****/
Frm_SetAnchorStr (Exams->SetCod,&Anchor);
static Act_Action_t NextAction[Tst_NUM_VALIDITIES] =
{
[Tst_INVALID_QUESTION] = ActValSetQst, // Validate question (set it as valid question)
[Tst_VALID_QUESTION ] = ActInvSetQst, // Invalidated question (set it as canceled question)
};
static const char *Icon[Tst_NUM_VALIDITIES] =
{
[Tst_INVALID_QUESTION] = "times-red.svg",
[Tst_VALID_QUESTION ] = "check-green.svg",
};
static const char *Title[Tst_NUM_VALIDITIES] =
{
[Tst_INVALID_QUESTION] = "Pregunta anulada", // TODO: Need translation!!!!
[Tst_VALID_QUESTION ] = "Pregunta válida", // TODO: Need translation!!!!
};
/***** Write the heading *****/
HTM_TABLE_BeginWideMarginPadding (5);
@ -1310,6 +1324,10 @@ static void ExaSet_ListOneOrMoreQuestionsForEdition (struct Exa_Exams *Exams,
*/
/* Get question code (row[0]) */
Exams->QstCod = Question.QstCod = Str_ConvertStrCodToLongCod (row[0]);
ExaSet_GetQstDataFromDB (&Question);
/***** Build anchor string *****/
Frm_SetAnchorStr (Exams->QstCod,&Anchor);
/***** Begin row *****/
HTM_TR_Begin (NULL);
@ -1328,29 +1346,28 @@ static void ExaSet_ListOneOrMoreQuestionsForEdition (struct Exa_Exams *Exams,
else
Ico_PutIconRemovalNotAllowed ();
/* Put icon to edit the question */
if (ICanEditQuestions)
Ico_PutContextualIconToEdit (ActEdiOneTstQst,NULL,
ExaSet_PutParamQstCod,&Question.QstCod);
/* Put icon to cancel the question */
Lay_PutContextualLinkOnlyIcon (NextAction[Question.Validity],Anchor,
ExaSet_PutParamsOneQst,Exams,
Icon[Question.Validity],
Title[Question.Validity]);
HTM_TD_End ();
/***** Question *****/
ExaSet_GetQstDataFromDB (&Question);
/***** List question *****/
ExaSet_ListQuestionForEdition (&Question,NumQst + 1,Anchor);
/***** End row *****/
HTM_TR_End ();
/***** Free anchor string *****/
Frm_FreeAnchorStr (Anchor);
/***** Destroy test question *****/
Tst_QstDestructor (&Question);
}
/***** End table *****/
HTM_TABLE_End ();
/***** Free anchor string *****/
Frm_FreeAnchorStr (Anchor);
}
/*****************************************************************************/
@ -1394,11 +1411,12 @@ void ExaSet_GetQstDataFromDB (struct Tst_Question *Question)
/***** Get question data from database *****/
QuestionExists = (DB_QuerySELECT (&mysql_res,"can not get a question",
"SELECT AnsType," // row[0]
"Shuffle," // row[1]
"Stem," // row[2]
"Feedback," // row[3]
"MedCod" // row[4]
"SELECT Invalid," // row[0]
"AnsType," // row[1]
"Shuffle," // row[2]
"Stem," // row[3]
"Feedback," // row[4]
"MedCod" // row[5]
" FROM exa_set_questions"
" WHERE QstCod=%ld",
Question->QstCod) != 0);
@ -1407,28 +1425,32 @@ void ExaSet_GetQstDataFromDB (struct Tst_Question *Question)
{
row = mysql_fetch_row (mysql_res);
/* Get the type of answer (row[0]) */
Question->Answer.Type = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[0]);
/* Get whether the question is invalid (row[0]) */
Question->Validity = (row[0][0] == 'Y') ? Tst_INVALID_QUESTION :
Tst_VALID_QUESTION;
/* Get shuffle (row[1]) */
Question->Answer.Shuffle = (row[1][0] == 'Y');
/* Get the type of answer (row[1]) */
Question->Answer.Type = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
/* Get the stem (row[2]) */
/* Get shuffle (row[2]) */
Question->Answer.Shuffle = (row[2][0] == 'Y');
/* Get the stem (row[3]) */
Question->Stem[0] = '\0';
if (row[2])
if (row[2][0])
Str_Copy (Question->Stem,row[2],
Cns_MAX_BYTES_TEXT);
/* Get the feedback (row[3]) */
Question->Feedback[0] = '\0';
if (row[3])
if (row[3][0])
Str_Copy (Question->Feedback,row[3],
Str_Copy (Question->Stem,row[3],
Cns_MAX_BYTES_TEXT);
/* Get media (row[4]) */
Question->Media.MedCod = Str_ConvertStrCodToLongCod (row[4]);
/* Get the feedback (row[4]) */
Question->Feedback[0] = '\0';
if (row[4])
if (row[4][0])
Str_Copy (Question->Feedback,row[4],
Cns_MAX_BYTES_TEXT);
/* Get media (row[5]) */
Question->Media.MedCod = Str_ConvertStrCodToLongCod (row[5]);
Med_GetMediaDataByCod (&Question->Media);
/* Free structure that stores the query result */
@ -1543,10 +1565,31 @@ void ExaSet_GetAnswersQst (struct Tst_Question *Question,MYSQL_RES **mysql_res,
static void ExaSet_ListQuestionForEdition (struct Tst_Question *Question,
unsigned QstInd,const char *Anchor)
{
static char *ClassNumQst[Tst_NUM_VALIDITIES] =
{
[Tst_INVALID_QUESTION] = "BIG_INDEX_RED",
[Tst_VALID_QUESTION ] = "BIG_INDEX",
};
static char *ClassAnswerType[Tst_NUM_VALIDITIES] =
{
[Tst_INVALID_QUESTION] = "DAT_SMALL_RED",
[Tst_VALID_QUESTION ] = "DAT_SMALL",
};
static char *ClassTxt[Tst_NUM_VALIDITIES] =
{
[Tst_INVALID_QUESTION] = "TEST_TXT_RED",
[Tst_VALID_QUESTION ] = "TEST_TXT",
};
static char *ClassFeedback[Tst_NUM_VALIDITIES] =
{
[Tst_INVALID_QUESTION] = "TEST_TXT_LIGHT_RED",
[Tst_VALID_QUESTION ] = "TEST_TXT_LIGHT",
};
/***** Number of question and answer type (row[1]) *****/
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
Tst_WriteNumQst (QstInd);
Tst_WriteAnswerType (Question->Answer.Type);
Tst_WriteNumQst (QstInd,ClassNumQst[Question->Validity]);
Tst_WriteAnswerType (Question->Answer.Type,ClassAnswerType[Question->Validity]);
HTM_TD_End ();
/***** Write stem (row[3]) and media *****/
@ -1554,7 +1597,7 @@ static void ExaSet_ListQuestionForEdition (struct Tst_Question *Question,
HTM_ARTICLE_Begin (Anchor);
/* Write stem */
Tst_WriteQstStem (Question->Stem,"TEST_EDI",
Tst_WriteQstStem (Question->Stem,ClassTxt[Question->Validity],
true); // Visible
/* Show media */
@ -1563,10 +1606,12 @@ static void ExaSet_ListQuestionForEdition (struct Tst_Question *Question,
"TEST_MED_EDIT_LIST");
/* Show feedback */
Tst_WriteQstFeedback (Question->Feedback,"TEST_EDI_LIGHT");
Tst_WriteQstFeedback (Question->Feedback,ClassFeedback[Question->Validity]);
/* Show answers */
Tst_WriteAnswersBank (Question);
Tst_WriteAnswersBank (Question,
ClassTxt[Question->Validity],
ClassFeedback[Question->Validity]);
HTM_ARTICLE_End ();
HTM_TD_End ();
@ -1673,6 +1718,11 @@ static void ExaSet_CopyQstFromBankToExamSet (struct ExaSet_Set *Set,long QstCod)
unsigned NumOpt;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
static char CharInvalid[Tst_NUM_VALIDITIES] =
{
[Tst_INVALID_QUESTION] = 'Y',
[Tst_VALID_QUESTION ] = 'N'
};
/***** Create test question *****/
Tst_QstConstructor (&Question);
@ -1687,10 +1737,11 @@ static void ExaSet_CopyQstFromBankToExamSet (struct ExaSet_Set *Set,long QstCod)
/***** Insert question in table of questions *****/
QstCodInSet = DB_QueryINSERTandReturnCode ("can not add question to set",
"INSERT INTO exa_set_questions"
" (SetCod,AnsType,Shuffle,Stem,Feedback,MedCod)"
" (SetCod,Invalid,AnsType,Shuffle,Stem,Feedback,MedCod)"
" VALUES"
" (%ld,'%s','%c','%s','%s',%ld)",
" (%ld,'%c','%s','%c','%s','%s',%ld)",
Set->SetCod,
CharInvalid[Question.Validity],
Tst_StrAnswerTypesDB[Question.Answer.Type],
Question.Answer.Shuffle ? 'Y' :
'N',
@ -2071,6 +2122,64 @@ static void ExaSet_RemoveMediaFromAllAnsOfQst (long SetCod,long QstCod)
DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
/***************************** Validate a question ***************************/
/*****************************************************************************/
void ExaSet_ValidateQst (void)
{
ExaSet_ChangeValidityQst (Tst_VALID_QUESTION);
}
void ExaSet_InvalidateQst (void)
{
ExaSet_ChangeValidityQst (Tst_INVALID_QUESTION);
}
static void ExaSet_ChangeValidityQst (Tst_Validity_t Validity)
{
struct Exa_Exams Exams;
struct Exa_Exam Exam;
struct ExaSet_Set Set;
long QstCod;
static char CharInvalid[Tst_NUM_VALIDITIES] =
{
[Tst_INVALID_QUESTION] = 'Y',
[Tst_VALID_QUESTION ] = 'N'
};
/***** Reset exams context *****/
Exa_ResetExams (&Exams);
Exa_ResetExam (&Exam);
ExaSet_ResetSet (&Set);
/***** Get and check parameters *****/
ExaSet_GetAndCheckParameters (&Exams,&Exam,&Set);
/***** Get question index *****/
QstCod = ExaSet_GetParamQstCod ();
/***** Validate question *****/
DB_QueryUPDATE ("can not validate question",
"UPDATE exa_set_questions,exa_sets,exa_exams"
" SET exa_set_questions.Invalid='%c'"
" WHERE exa_set_questions.QstCod=%ld"
" AND exa_set_questions.SetCod=%ld" // Extra check
" AND exa_set_questions.SetCod=exa_sets.SetCod"
" AND exa_sets.ExaCod=%ld" // Extra check
" AND exa_sets.ExaCod=exa_exams.ExaCod"
" AND exa_exams.CrsCod=%ld", // Extra check
CharInvalid[Validity],
QstCod,
Set.SetCod,
Exam.ExaCod,
Gbl.Hierarchy.Crs.CrsCod);
/***** Show current exam and its sets *****/
Exa_PutFormsOneExam (&Exams,&Exam,&Set,
false); // It's not a new exam
}
/*****************************************************************************/
/************************** Get and check parameters *************************/
/*****************************************************************************/

View File

@ -77,6 +77,9 @@ void ExaSet_MoveDownSet (void);
void ExaSet_RequestRemoveQstFromSet (void);
void ExaSet_RemoveQstFromSet (void);
void ExaSet_ValidateQst (void);
void ExaSet_InvalidateQst (void);
void ExaSet_WriteSetTitle (const struct ExaSet_Set *Set);
#endif

View File

@ -167,10 +167,18 @@ static void Tst_WriteQuestionRowForSelection (unsigned NumQst,
//-----------------------------------------------------------------------------
static void Tst_WriteIntAnsBank (struct Tst_Question *Question);
static void Tst_WriteFltAnsBank (struct Tst_Question *Question);
static void Tst_WriteTF_AnsBank (struct Tst_Question *Question);
static void Tst_WriteChoAnsBank (struct Tst_Question *Question);
static void Tst_WriteIntAnsBank (struct Tst_Question *Question,
const char *ClassTxt,
__attribute__((unused)) const char *ClassFeedback);
static void Tst_WriteFltAnsBank (struct Tst_Question *Question,
const char *ClassTxt,
__attribute__((unused)) const char *ClassFeedback);
static void Tst_WriteTF_AnsBank (struct Tst_Question *Question,
const char *ClassTxt,
__attribute__((unused)) const char *ClassFeedback);
static void Tst_WriteChoAnsBank (struct Tst_Question *Question,
const char *ClassTxt,
const char *ClassFeedback);
//-----------------------------------------------------------------------------
@ -722,9 +730,9 @@ void Tst_ListQuestionForEdition (struct Tst_Question *Question,
/***** Number of question and answer type (row[1]) *****/
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
Tst_WriteNumQst (QstInd);
Tst_WriteNumQst (QstInd,"BIG_INDEX");
if (QuestionExists)
Tst_WriteAnswerType (Question->Answer.Type);
Tst_WriteAnswerType (Question->Answer.Type,"DAT_SMALL");
HTM_TD_End ();
/***** Write question code *****/
@ -744,7 +752,7 @@ void Tst_ListQuestionForEdition (struct Tst_Question *Question,
if (QuestionExists)
{
/* Write stem */
Tst_WriteQstStem (Question->Stem,"TEST_EDI",
Tst_WriteQstStem (Question->Stem,"TEST_TXT",
true); // Visible
/* Show media */
@ -753,10 +761,10 @@ void Tst_ListQuestionForEdition (struct Tst_Question *Question,
"TEST_MED_EDIT_LIST");
/* Show feedback */
Tst_WriteQstFeedback (Question->Feedback,"TEST_EDI_LIGHT");
Tst_WriteQstFeedback (Question->Feedback,"TEST_TXT_LIGHT");
/* Show answers */
Tst_WriteAnswersBank (Question);
Tst_WriteAnswersBank (Question,"TEST_TXT","TEST_TXT_LIGHT");
}
else
{
@ -773,9 +781,9 @@ void Tst_ListQuestionForEdition (struct Tst_Question *Question,
/*****************************************************************************/
// Number of question should be 1, 2, 3...
void Tst_WriteNumQst (unsigned NumQst)
void Tst_WriteNumQst (unsigned NumQst,const char *Class)
{
HTM_DIV_Begin ("class=\"BIG_INDEX\"");
HTM_DIV_Begin ("class=\"%s\"",Class);
HTM_Unsigned (NumQst);
HTM_DIV_End ();
}
@ -784,11 +792,11 @@ void Tst_WriteNumQst (unsigned NumQst)
/************************** Write the type of answer *************************/
/*****************************************************************************/
void Tst_WriteAnswerType (Tst_AnswerType_t AnswerType)
void Tst_WriteAnswerType (Tst_AnswerType_t AnswerType,const char *Class)
{
extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES];
HTM_DIV_Begin ("class=\"DAT_SMALL\"");
HTM_DIV_Begin ("class=\"%s\"",Class);
HTM_Txt (Txt_TST_STR_ANSWER_TYPES[AnswerType]);
HTM_DIV_End ();
}
@ -2311,8 +2319,8 @@ static void Tst_WriteQuestionListing (struct Tst_Test *Test,unsigned NumQst)
/* Number of question and answer type */
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
Tst_WriteNumQst (NumQst + 1);
Tst_WriteAnswerType (Test->Question.Answer.Type);
Tst_WriteNumQst (NumQst + 1,"BIG_INDEX");
Tst_WriteAnswerType (Test->Question.Answer.Type,"DAT_SMALL");
HTM_TD_End ();
/* Question code */
@ -2358,7 +2366,7 @@ static void Tst_WriteQuestionListing (struct Tst_Test *Test,unsigned NumQst)
/* Stem (row[3]) */
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
Tst_WriteQstStem (Test->Question.Stem,"TEST_EDI",
Tst_WriteQstStem (Test->Question.Stem,"TEST_TXT",
true); // Visible
/***** Get and show media (row[5]) *****/
@ -2367,8 +2375,8 @@ static void Tst_WriteQuestionListing (struct Tst_Test *Test,unsigned NumQst)
"TEST_MED_EDIT_LIST");
/* Feedback (row[4]) and answers */
Tst_WriteQstFeedback (Test->Question.Feedback,"TEST_EDI_LIGHT");
Tst_WriteAnswersBank (&Test->Question);
Tst_WriteQstFeedback (Test->Question.Feedback,"TEST_TXT_LIGHT");
Tst_WriteAnswersBank (&Test->Question,"TEST_TXT","TEST_TXT_LIGHT");
HTM_TD_End ();
/* Number of times this question has been answered */
@ -2658,7 +2666,7 @@ static void Tst_WriteQuestionRowForSelection (unsigned NumQst,
/* Write stem */
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
Tst_WriteQstStem (Question->Stem,"TEST_EDI",
Tst_WriteQstStem (Question->Stem,"TEST_TXT",
true); // Visible
/***** Get and show media *****/
@ -2667,10 +2675,10 @@ static void Tst_WriteQuestionRowForSelection (unsigned NumQst,
"TEST_MED_EDIT_LIST");
/* Write feedback */
Tst_WriteQstFeedback (Question->Feedback,"TEST_EDI_LIGHT");
Tst_WriteQstFeedback (Question->Feedback,"TEST_TXT_LIGHT");
/* Write answers */
Tst_WriteAnswersBank (Question);
Tst_WriteAnswersBank (Question,"TEST_TXT","TEST_TXT_LIGHT");
HTM_TD_End ();
/***** End table row *****/
@ -2766,9 +2774,13 @@ void Tst_ChangeFormatAnswersFeedback (struct Tst_Question *Question)
/**************** Get and write the answers of a test question ***************/
/*****************************************************************************/
void Tst_WriteAnswersBank (struct Tst_Question *Question)
void Tst_WriteAnswersBank (struct Tst_Question *Question,
const char *ClassTxt,
const char *ClassFeedback)
{
void (*Tst_WriteAnsBank[Tst_NUM_ANS_TYPES]) (struct Tst_Question *Question) =
void (*Tst_WriteAnsBank[Tst_NUM_ANS_TYPES]) (struct Tst_Question *Question,
const char *ClassTxt,
const char *ClassFeedback) =
{
[Tst_ANS_INT ] = Tst_WriteIntAnsBank,
[Tst_ANS_FLOAT ] = Tst_WriteFltAnsBank,
@ -2779,7 +2791,7 @@ void Tst_WriteAnswersBank (struct Tst_Question *Question)
};
/***** Write answers *****/
Tst_WriteAnsBank[Question->Answer.Type] (Question);
Tst_WriteAnsBank[Question->Answer.Type] (Question,ClassTxt,ClassFeedback);
}
/*****************************************************************************/
@ -2800,9 +2812,11 @@ bool Tst_CheckIfQuestionIsValidForGame (long QstCod)
/****************** Write integer answer when editing a test *****************/
/*****************************************************************************/
static void Tst_WriteIntAnsBank (struct Tst_Question *Question)
static void Tst_WriteIntAnsBank (struct Tst_Question *Question,
const char *ClassTxt,
__attribute__((unused)) const char *ClassFeedback)
{
HTM_SPAN_Begin ("class=\"TEST_EDI\"");
HTM_SPAN_Begin ("class=\"%s\"",ClassTxt);
HTM_TxtF ("(%ld)",Question->Answer.Integer);
HTM_SPAN_End ();
}
@ -2811,9 +2825,11 @@ static void Tst_WriteIntAnsBank (struct Tst_Question *Question)
/****************** Write float answer when editing a test *******************/
/*****************************************************************************/
static void Tst_WriteFltAnsBank (struct Tst_Question *Question)
static void Tst_WriteFltAnsBank (struct Tst_Question *Question,
const char *ClassTxt,
__attribute__((unused)) const char *ClassFeedback)
{
HTM_SPAN_Begin ("class=\"TEST_EDI\"");
HTM_SPAN_Begin ("class=\"%s\"",ClassTxt);
HTM_Txt ("([");
HTM_Double (Question->Answer.FloatingPoint[0]);
HTM_Txt ("; ");
@ -2826,10 +2842,12 @@ static void Tst_WriteFltAnsBank (struct Tst_Question *Question)
/*********** Write false / true answer when listing test questions ***********/
/*****************************************************************************/
static void Tst_WriteTF_AnsBank (struct Tst_Question *Question)
static void Tst_WriteTF_AnsBank (struct Tst_Question *Question,
const char *ClassTxt,
__attribute__((unused)) const char *ClassFeedback)
{
/***** Write answer *****/
HTM_SPAN_Begin ("class=\"TEST_EDI\"");
HTM_SPAN_Begin ("class=\"%s\"",ClassTxt);
HTM_Txt ("(");
Tst_WriteAnsTF (Question->Answer.TF);
HTM_Txt (")");
@ -2840,7 +2858,9 @@ static void Tst_WriteTF_AnsBank (struct Tst_Question *Question)
/**** Write single or multiple choice answer when listing test questions *****/
/*****************************************************************************/
static void Tst_WriteChoAnsBank (struct Tst_Question *Question)
static void Tst_WriteChoAnsBank (struct Tst_Question *Question,
const char *ClassTxt,
const char *ClassFeedback)
{
extern const char *Txt_TST_Answer_given_by_the_teachers;
unsigned NumOpt;
@ -2865,14 +2885,14 @@ static void Tst_WriteChoAnsBank (struct Tst_Question *Question)
HTM_TD_End ();
/* Write the number of option */
HTM_TD_Begin ("class=\"DAT_SMALL LT\"");
HTM_TD_Begin ("class=\"%s LT\"",ClassTxt);
HTM_TxtF ("%c) ",'a' + (char) NumOpt);
HTM_TD_End ();
HTM_TD_Begin ("class=\"LT\"");
/* Write the text of the answer and the media */
HTM_DIV_Begin ("class=\"TEST_EDI\"");
HTM_DIV_Begin ("class=\"%s\"",ClassTxt);
HTM_Txt (Question->Answer.Options[NumOpt].Text);
Med_ShowMedia (&Question->Answer.Options[NumOpt].Media,
"TEST_MED_EDIT_LIST_CONT",
@ -2880,7 +2900,7 @@ static void Tst_WriteChoAnsBank (struct Tst_Question *Question)
HTM_DIV_End ();
/* Write the text of the feedback */
HTM_DIV_Begin ("class=\"TEST_EDI_LIGHT\"");
HTM_DIV_Begin ("class=\"%s\"",ClassFeedback);
HTM_Txt (Question->Answer.Options[NumOpt].Feedback);
HTM_DIV_End ();
@ -3728,6 +3748,9 @@ void Tst_QstConstructor (struct Tst_Question *Question)
Question->NumHits =
Question->NumHitsNotBlank = 0;
Question->Score = 0.0;
/***** Mark question as valid *****/
Question->Validity = Tst_VALID_QUESTION;
}
/*****************************************************************************/

View File

@ -109,8 +109,8 @@ void Tst_ShowTagList (unsigned NumTags,MYSQL_RES *mysql_res);
void Tst_ListQuestionForEdition (struct Tst_Question *Question,
unsigned QstInd,bool QuestionExists,
const char *Anchor);
void Tst_WriteNumQst (unsigned NumQst);
void Tst_WriteAnswerType (Tst_AnswerType_t AnswerType);
void Tst_WriteNumQst (unsigned NumQst,const char *Class);
void Tst_WriteAnswerType (Tst_AnswerType_t AnswerType,const char *Class);
void Tst_WriteQstStem (const char *Stem,const char *ClassStem,bool Visible);
void Tst_WriteQstFeedback (const char *Feedback,const char *ClassFeedback);
@ -134,7 +134,9 @@ void Tst_GetAnswersQst (struct Tst_Question *Question,MYSQL_RES **mysql_res,
void Tst_ChangeFormatAnswersText (struct Tst_Question *Question);
void Tst_ChangeFormatAnswersFeedback (struct Tst_Question *Question);
void Tst_WriteAnswersBank (struct Tst_Question *Question);
void Tst_WriteAnswersBank (struct Tst_Question *Question,
const char *ClassTxt,
const char *ClassFeedback);
bool Tst_CheckIfQuestionIsValidForGame (long QstCod);
void Tst_WriteAnsTF (char AnsTF);

View File

@ -898,8 +898,8 @@ static void TsI_WriteRowImportedQst (struct XMLElement *StemElem,
size_t AnswerFeedbackLength;
const char *ClassData = QuestionExists ? "DAT_SMALL_LIGHT" :
"DAT_SMALL";
const char *ClassStem = QuestionExists ? "TEST_EDI_LIGHT" :
"TEST_EDI";
const char *ClassStem = QuestionExists ? "TEST_TXT_LIGHT" :
"TEST_TXT";
Gbl.RowEvenOdd = NumQst % 2;
NumQst++;
@ -974,7 +974,7 @@ static void TsI_WriteRowImportedQst (struct XMLElement *StemElem,
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
Tst_WriteQstStem (Stem,ClassStem,
true); // Visible
Tst_WriteQstFeedback (Feedback,"TEST_EDI_LIGHT");
Tst_WriteQstFeedback (Feedback,"TEST_TXT_LIGHT");
switch (Question->Answer.Type)
{
case Tst_ANS_INT:
@ -1057,7 +1057,7 @@ static void TsI_WriteRowImportedQst (struct XMLElement *StemElem,
if (AnswerFeedbackLength)
{
HTM_DIV_Begin ("class=\"TEST_EDI_LIGHT\"");
HTM_DIV_Begin ("class=\"TEST_TXT_LIGHT\"");
HTM_Txt (AnswerFeedback);
HTM_DIV_End ();
}

View File

@ -127,23 +127,33 @@ static void TstPrn_GetCorrectTxtAnswerFromDB (struct Tst_Question *Question);
static void TstPrn_WriteIntAnsPrint (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
struct Tst_Question *Question,
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY]);
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY],
__attribute__((unused)) const char *ClassTxt,
__attribute__((unused)) const char *ClassFeedback);
static void TstPrn_WriteFltAnsPrint (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
struct Tst_Question *Question,
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY]);
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY],
__attribute__((unused)) const char *ClassTxt,
__attribute__((unused)) const char *ClassFeedback);
static void TstPrn_WriteTF_AnsPrint (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
struct Tst_Question *Question,
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY]);
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY],
__attribute__((unused)) const char *ClassTxt,
__attribute__((unused)) const char *ClassFeedback);
static void TstPrn_WriteChoAnsPrint (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
struct Tst_Question *Question,
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY]);
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY],
const char *ClassTxt,
const char *ClassFeedback);
static void TstPrn_WriteTxtAnsPrint (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
struct Tst_Question *Question,
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY]);
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY],
__attribute__((unused)) const char *ClassTxt,
__attribute__((unused)) const char *ClassFeedback);
//-----------------------------------------------------------------------------
static void TstPrn_WriteHeadUserCorrect (struct UsrData *UsrDat);
@ -330,8 +340,8 @@ static void TstPrn_WriteQstAndAnsToFill (struct TstPrn_PrintedQuestion *PrintedQ
/***** Number of question and answer type *****/
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
Tst_WriteNumQst (NumQst + 1);
Tst_WriteAnswerType (Question->Answer.Type);
Tst_WriteNumQst (NumQst + 1,"BIG_INDEX");
Tst_WriteAnswerType (Question->Answer.Type,"DAT_SMALL");
HTM_TD_End ();
/***** Stem, media and answers *****/
@ -341,7 +351,7 @@ static void TstPrn_WriteQstAndAnsToFill (struct TstPrn_PrintedQuestion *PrintedQ
Tst_WriteParamQstCod (NumQst,Question->QstCod);
/* Stem */
Tst_WriteQstStem (Question->Stem,"TEST_EXA",true);
Tst_WriteQstStem (Question->Stem,"TEST_TXT",true);
/* Media */
Med_ShowMedia (&Question->Media,
@ -503,14 +513,14 @@ static void TstPrn_WriteChoAnsToFill (const struct TstPrn_PrintedQuestion *Print
HTM_TD_End ();
HTM_TD_Begin ("class=\"LT\"");
HTM_LABEL_Begin ("for=\"Ans%010u_%u\" class=\"ANS_TXT\"",NumQst,NumOpt);
HTM_LABEL_Begin ("for=\"Ans%010u_%u\" class=\"TEST_TXT\"",NumQst,NumOpt);
HTM_TxtF ("%c) ",'a' + (char) NumOpt);
HTM_LABEL_End ();
HTM_TD_End ();
/***** Write the option text *****/
HTM_TD_Begin ("class=\"LT\"");
HTM_LABEL_Begin ("for=\"Ans%010u_%u\" class=\"ANS_TXT\"",NumQst,NumOpt);
HTM_LABEL_Begin ("for=\"Ans%010u_%u\" class=\"TEST_TXT\"",NumQst,NumOpt);
HTM_Txt (Question->Answer.Options[Indexes[NumOpt]].Text);
HTM_LABEL_End ();
Med_ShowMedia (&Question->Answer.Options[Indexes[NumOpt]].Media,
@ -677,9 +687,9 @@ static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
/***** Number of question and answer type *****/
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
Tst_WriteNumQst (NumQst + 1);
Tst_WriteNumQst (NumQst + 1,"BIG_INDEX");
if (QuestionUneditedAfterExam)
Tst_WriteAnswerType (Question->Answer.Type);
Tst_WriteAnswerType (Question->Answer.Type,"DAT_SMALL");
HTM_TD_End ();
/***** Stem, media and answers *****/
@ -689,7 +699,7 @@ static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
if (QuestionUneditedAfterExam)
{
/* Stem */
Tst_WriteQstStem (Question->Stem,"TEST_EXA",ICanView[TstVis_VISIBLE_QST_ANS_TXT]);
Tst_WriteQstStem (Question->Stem,"TEST_TXT",ICanView[TstVis_VISIBLE_QST_ANS_TXT]);
/* Media */
if (ICanView[TstVis_VISIBLE_QST_ANS_TXT])
@ -700,7 +710,7 @@ static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
/* Answers */
TstPrn_ComputeAnswerScore (&Print->PrintedQuestions[NumQst],Question);
TstPrn_WriteAnswersExam (UsrDat,&Print->PrintedQuestions[NumQst],Question,
ICanView);
ICanView,"TEST_TXT","TEST_TXT_LIGHT");
}
else
Ale_ShowAlert (Ale_WARNING,Txt_Question_modified);
@ -726,7 +736,7 @@ static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
/* Question feedback */
if (QuestionUneditedAfterExam)
if (ICanView[TstVis_VISIBLE_FEEDBACK_TXT])
Tst_WriteQstFeedback (Question->Feedback,"TEST_EXA_LIGHT");
Tst_WriteQstFeedback (Question->Feedback,"TEST_TXT_LIGHT");
HTM_TD_End ();
@ -1271,12 +1281,16 @@ void TstPrn_ShowGrade (double Grade,double MaxGrade)
void TstPrn_WriteAnswersExam (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
struct Tst_Question *Question,
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY])
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY],
const char *ClassTxt,
const char *ClassFeedback)
{
void (*TstPrn_WriteAnsExam[Tst_NUM_ANS_TYPES]) (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
struct Tst_Question *Question,
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY]) =
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY],
const char *ClassTxt,
const char *ClassFeedback) =
{
[Tst_ANS_INT ] = TstPrn_WriteIntAnsPrint,
[Tst_ANS_FLOAT ] = TstPrn_WriteFltAnsPrint,
@ -1288,7 +1302,7 @@ void TstPrn_WriteAnswersExam (struct UsrData *UsrDat,
/***** Get correct answer and compute answer score depending on type *****/
TstPrn_WriteAnsExam[Question->Answer.Type] (UsrDat,PrintedQuestion,Question,
ICanView);
ICanView,ClassTxt,ClassFeedback);
}
/*****************************************************************************/
@ -1298,7 +1312,9 @@ void TstPrn_WriteAnswersExam (struct UsrData *UsrDat,
static void TstPrn_WriteIntAnsPrint (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
struct Tst_Question *Question,
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY])
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY],
__attribute__((unused)) const char *ClassTxt,
__attribute__((unused)) const char *ClassFeedback)
{
long IntAnswerUsr;
@ -1357,7 +1373,9 @@ static void TstPrn_WriteIntAnsPrint (struct UsrData *UsrDat,
static void TstPrn_WriteFltAnsPrint (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
struct Tst_Question *Question,
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY])
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY],
__attribute__((unused)) const char *ClassTxt,
__attribute__((unused)) const char *ClassFeedback)
{
double FloatAnsUsr = 0.0;
@ -1417,7 +1435,9 @@ static void TstPrn_WriteFltAnsPrint (struct UsrData *UsrDat,
static void TstPrn_WriteTF_AnsPrint (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
struct Tst_Question *Question,
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY])
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY],
__attribute__((unused)) const char *ClassTxt,
__attribute__((unused)) const char *ClassFeedback)
{
char AnsTFUsr;
@ -1465,7 +1485,9 @@ static void TstPrn_WriteTF_AnsPrint (struct UsrData *UsrDat,
static void TstPrn_WriteChoAnsPrint (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
struct Tst_Question *Question,
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY])
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY],
const char *ClassTxt,
const char *ClassFeedback)
{
extern const char *Txt_TST_Answer_given_by_the_user;
extern const char *Txt_TST_Answer_given_by_the_teachers;
@ -1556,14 +1578,14 @@ static void TstPrn_WriteChoAnsPrint (struct UsrData *UsrDat,
}
/* Answer letter (a, b, c,...) */
HTM_TD_Begin ("class=\"ANS_TXT LT\"");
HTM_TD_Begin ("class=\"%s LT\"",ClassTxt);
HTM_TxtF ("%c) ",'a' + (char) NumOpt);
HTM_TD_End ();
/* Answer text and feedback */
HTM_TD_Begin ("class=\"LT\"");
HTM_DIV_Begin ("class=\"ANS_TXT\"");
HTM_DIV_Begin ("class=\"%s\"",ClassTxt);
if (ICanView[TstVis_VISIBLE_QST_ANS_TXT])
{
HTM_Txt (Question->Answer.Options[Indexes[NumOpt]].Text);
@ -1579,7 +1601,7 @@ static void TstPrn_WriteChoAnsPrint (struct UsrData *UsrDat,
if (Question->Answer.Options[Indexes[NumOpt]].Feedback)
if (Question->Answer.Options[Indexes[NumOpt]].Feedback[0])
{
HTM_DIV_Begin ("class=\"TEST_EXA_LIGHT\"");
HTM_DIV_Begin ("class=\"%s\"",ClassFeedback);
HTM_Txt (Question->Answer.Options[Indexes[NumOpt]].Feedback);
HTM_DIV_End ();
}
@ -1600,7 +1622,9 @@ static void TstPrn_WriteChoAnsPrint (struct UsrData *UsrDat,
static void TstPrn_WriteTxtAnsPrint (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
struct Tst_Question *Question,
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY])
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY],
__attribute__((unused)) const char *ClassTxt,
__attribute__((unused)) const char *ClassFeedback)
{
unsigned NumOpt;
char TextAnsUsr[Tst_MAX_BYTES_ANSWERS_ONE_QST + 1];
@ -1690,7 +1714,7 @@ static void TstPrn_WriteTxtAnsPrint (struct UsrData *UsrDat,
if (Question->Answer.Options[NumOpt].Feedback)
if (Question->Answer.Options[NumOpt].Feedback[0])
{
HTM_DIV_Begin ("class=\"TEST_EXA_LIGHT\"");
HTM_DIV_Begin ("class=\"TEST_TXT_LIGHT\"");
HTM_Txt (Question->Answer.Options[NumOpt].Feedback);
HTM_DIV_End ();
}

View File

@ -117,7 +117,9 @@ void TstPrn_ShowGrade (double Grade,double MaxGrade);
void TstPrn_WriteAnswersExam (struct UsrData *UsrDat,
const struct TstPrn_PrintedQuestion *PrintedQuestion,
struct Tst_Question *Question,
bool IsVisible[TstVis_NUM_ITEMS_VISIBILITY]);
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY],
const char *ClassTxt,
const char *ClassFeedback);
void TstPrn_SelUsrsToViewUsrsPrints (void);
void TstPrn_SelDatesToSeeMyPrints (void);

View File

@ -49,6 +49,13 @@
/******************************* Public types ********************************/
/*****************************************************************************/
#define Tst_NUM_VALIDITIES 2
typedef enum
{
Tst_INVALID_QUESTION,
Tst_VALID_QUESTION,
} Tst_Validity_t;
#define Tst_NUM_ANS_TYPES 6
#define Tst_MAX_BYTES_LIST_ANSWER_TYPES (Tst_NUM_ANS_TYPES * (Cns_MAX_DECIMAL_DIGITS_UINT + 1))
typedef enum
@ -89,6 +96,7 @@ struct Tst_Question
unsigned long NumHits;
unsigned long NumHitsNotBlank;
double Score;
Tst_Validity_t Validity; // If a question in an exam has been marked as invalid
};
/*****************************************************************************/