Version19.156

This commit is contained in:
acanas 2020-03-30 00:30:08 +02:00
parent 67681ff352
commit 536d042416
12 changed files with 481 additions and 301 deletions

View File

@ -13157,4 +13157,110 @@ SELECT LogCod,ActCod,UNIX_TIMESTAMP()-UNIX_TIMESTAMP(ClickTime),Role,CtyCod,InsC
-----------------
CREATE TABLE IF NOT EXISTS log (
LogCod INT NOT NULL AUTO_INCREMENT,
ActCod INT NOT NULL DEFAULT -1,
CtyCod INT NOT NULL DEFAULT -1,
InsCod INT NOT NULL DEFAULT -1,
CtrCod INT NOT NULL DEFAULT -1,
DegCod INT NOT NULL DEFAULT -1,
CrsCod INT NOT NULL DEFAULT -1,
UsrCod INT NOT NULL DEFAULT -1,
Role TINYINT NOT NULL,
ClickTime DATETIME NOT NULL,
TimeToGenerate INT NOT NULL,
TimeToSend INT NOT NULL,
IP CHAR(15) NOT NULL,
PRIMARY KEY(LogCod,ClickTime),
INDEX(ActCod),
INDEX(CtyCod),
INDEX(InsCod),
INDEX(CtrCod),
INDEX(DegCod),
INDEX(CrsCod),
INDEX(UsrCod),
INDEX(ClickTime,Role)
) ENGINE=InnoDB
PARTITION BY RANGE (YEAR(ClickTime))
(
PARTITION p2004 VALUES LESS THAN (2005),
PARTITION p2005 VALUES LESS THAN (2006),
PARTITION p2006 VALUES LESS THAN (2007),
PARTITION p2007 VALUES LESS THAN (2008),
PARTITION p2008 VALUES LESS THAN (2009),
PARTITION p2009 VALUES LESS THAN (2010),
PARTITION p2010 VALUES LESS THAN (2011),
PARTITION p2011 VALUES LESS THAN (2012),
PARTITION p2012 VALUES LESS THAN (2013),
PARTITION p2013 VALUES LESS THAN (2014),
PARTITION p2014 VALUES LESS THAN (2015),
PARTITION p2015 VALUES LESS THAN (2016),
PARTITION p2016 VALUES LESS THAN (2017),
PARTITION p2017 VALUES LESS THAN (2018),
PARTITION p2018 VALUES LESS THAN (2019),
PARTITION p2019 VALUES LESS THAN (2020),
PARTITION p2020 VALUES LESS THAN (2021),
PARTITION p2021 VALUES LESS THAN (2022),
PARTITION p2022 VALUES LESS THAN (2023),
PARTITION p2023 VALUES LESS THAN (2024),
PARTITION p2024 VALUES LESS THAN (2025),
PARTITION p2025 VALUES LESS THAN (2026),
PARTITION p2026 VALUES LESS THAN (2027),
PARTITION p2027 VALUES LESS THAN (2028),
PARTITION p2028 VALUES LESS THAN (2029),
PARTITION p2029 VALUES LESS THAN (2030),
PARTITION p2030 VALUES LESS THAN (2031),
PARTITION p2031 VALUES LESS THAN (2032),
PARTITION p2032 VALUES LESS THAN (2033),
PARTITION p2033 VALUES LESS THAN (2034),
PARTITION p2034 VALUES LESS THAN (2035),
PARTITION p2035 VALUES LESS THAN (2036),
PARTITION p2036 VALUES LESS THAN (2037),
PARTITION p2037 VALUES LESS THAN (2038),
PARTITION p2038 VALUES LESS THAN (2039),
PARTITION p2039 VALUES LESS THAN (2040),
PARTITION p2040 VALUES LESS THAN (2041),
PARTITION p2041 VALUES LESS THAN (2042),
PARTITION p2042 VALUES LESS THAN (2043),
PARTITION p2043 VALUES LESS THAN (2044),
PARTITION p2044 VALUES LESS THAN (2045),
PARTITION p2045 VALUES LESS THAN (2046),
PARTITION p2046 VALUES LESS THAN (2047),
PARTITION p2047 VALUES LESS THAN (2048),
PARTITION p2048 VALUES LESS THAN (2049),
PARTITION p2049 VALUES LESS THAN (2050),
PARTITION p2050 VALUES LESS THAN MAXVALUE
);
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) < 2005; Hecho
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2005; Hecho
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2006; Hecho
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2007; Hecho
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2008; Hecho
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2009; Hecho
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2010; Hecho
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2011; Hecho
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2012; Hecho
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2013;
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2014;
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2015;
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2016;
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2017;
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2018;
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2019;
# hasta aquí ya hecho en openswad.org, aún no en swad.ugr.es
# Actualizar los últimos antes de dar el cambiazo:
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) = 2020;
INSERT INTO log SELECT * FROM log_full WHERE YEAR(ClickTime) > 2020;

View File

@ -1318,12 +1318,14 @@ CREATE TABLE IF NOT EXISTS tst_exams (
TstCod INT NOT NULL AUTO_INCREMENT,
CrsCod INT NOT NULL,
UsrCod INT NOT NULL,
AllowTeachers ENUM('N','Y') NOT NULL DEFAULT 'N',
TstTime DATETIME NOT NULL,
StartTime DATETIME NOT NULL,
EndTime DATETIME NOT NULL,
NumQsts INT NOT NULL DEFAULT 0,
NumQstsNotBlank INT NOT NULL DEFAULT 0,
AllowTeachers ENUM('N','Y') NOT NULL DEFAULT 'N',
Score DOUBLE PRECISION NOT NULL DEFAULT 0,
UNIQUE INDEX(TstCod),INDEX(CrsCod,UsrCod));
UNIQUE INDEX(TstCod),
INDEX(CrsCod,UsrCod));
--
-- Table tst_question_tags: stores the tags associated to each test question
--

View File

@ -627,6 +627,7 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
[ActDowAssPrj ] = {1734,-1,TabUnk,ActSeePrj ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_DOWNLD_FILE,Brw_DownloadFile ,NULL ,NULL},
[ActSeeTst ] = { 29,-1,TabUnk,ActReqTst ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_ShowNewTest ,NULL},
[ActReqAssTst ] = {1837,-1,TabUnk,ActReqTst ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_RequestAssessTest ,NULL},
[ActAssTst ] = { 98,-1,TabUnk,ActReqTst ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_AssessTest ,NULL},
[ActEdiTstQst ] = { 104,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Dat_SetIniEndDates ,Tst_RequestEditTests ,NULL},
@ -3568,6 +3569,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un
ActLftPrgItm, // #1834
ActReqRemSevTstQst, // #1835
ActRemSevTstQst, // #1836
ActReqAssTst, // #1837
};
/*****************************************************************************/

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 1836
#define Act_MAX_ACTION_COD 1837
#define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13
@ -606,106 +606,107 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to
#define ActDowAssPrj (ActChgCrsTT1stDay + 96)
#define ActSeeTst (ActChgCrsTT1stDay + 97)
#define ActAssTst (ActChgCrsTT1stDay + 98)
#define ActEdiTstQst (ActChgCrsTT1stDay + 99)
#define ActEdiOneTstQst (ActChgCrsTT1stDay + 100)
#define ActReqImpTstQst (ActChgCrsTT1stDay + 101)
#define ActImpTstQst (ActChgCrsTT1stDay + 102)
#define ActLstTstQst (ActChgCrsTT1stDay + 103)
#define ActRcvTstQst (ActChgCrsTT1stDay + 104)
#define ActReqRemSevTstQst (ActChgCrsTT1stDay + 105)
#define ActRemSevTstQst (ActChgCrsTT1stDay + 106)
#define ActReqRemOneTstQst (ActChgCrsTT1stDay + 107)
#define ActRemOneTstQst (ActChgCrsTT1stDay + 108)
#define ActChgShfTstQst (ActChgCrsTT1stDay + 109)
#define ActCfgTst (ActChgCrsTT1stDay + 110)
#define ActEnableTag (ActChgCrsTT1stDay + 111)
#define ActDisableTag (ActChgCrsTT1stDay + 112)
#define ActRenTag (ActChgCrsTT1stDay + 113)
#define ActRcvCfgTst (ActChgCrsTT1stDay + 114)
#define ActReqAssTst (ActChgCrsTT1stDay + 98)
#define ActAssTst (ActChgCrsTT1stDay + 99)
#define ActEdiTstQst (ActChgCrsTT1stDay + 100)
#define ActEdiOneTstQst (ActChgCrsTT1stDay + 101)
#define ActReqImpTstQst (ActChgCrsTT1stDay + 102)
#define ActImpTstQst (ActChgCrsTT1stDay + 103)
#define ActLstTstQst (ActChgCrsTT1stDay + 104)
#define ActRcvTstQst (ActChgCrsTT1stDay + 105)
#define ActReqRemSevTstQst (ActChgCrsTT1stDay + 106)
#define ActRemSevTstQst (ActChgCrsTT1stDay + 107)
#define ActReqRemOneTstQst (ActChgCrsTT1stDay + 108)
#define ActRemOneTstQst (ActChgCrsTT1stDay + 109)
#define ActChgShfTstQst (ActChgCrsTT1stDay + 110)
#define ActCfgTst (ActChgCrsTT1stDay + 111)
#define ActEnableTag (ActChgCrsTT1stDay + 112)
#define ActDisableTag (ActChgCrsTT1stDay + 113)
#define ActRenTag (ActChgCrsTT1stDay + 114)
#define ActRcvCfgTst (ActChgCrsTT1stDay + 115)
#define ActReqSeeMyTstRes (ActChgCrsTT1stDay + 115)
#define ActSeeMyTstRes (ActChgCrsTT1stDay + 116)
#define ActSeeOneTstResMe (ActChgCrsTT1stDay + 117)
#define ActReqSeeUsrTstRes (ActChgCrsTT1stDay + 118)
#define ActSeeUsrTstRes (ActChgCrsTT1stDay + 119)
#define ActSeeOneTstResOth (ActChgCrsTT1stDay + 120)
#define ActReqSeeMyTstRes (ActChgCrsTT1stDay + 116)
#define ActSeeMyTstRes (ActChgCrsTT1stDay + 117)
#define ActSeeOneTstResMe (ActChgCrsTT1stDay + 118)
#define ActReqSeeUsrTstRes (ActChgCrsTT1stDay + 119)
#define ActSeeUsrTstRes (ActChgCrsTT1stDay + 120)
#define ActSeeOneTstResOth (ActChgCrsTT1stDay + 121)
#define ActSeeGam (ActChgCrsTT1stDay + 121)
#define ActReqRemMch (ActChgCrsTT1stDay + 122)
#define ActRemMch (ActChgCrsTT1stDay + 123)
#define ActReqNewMch (ActChgCrsTT1stDay + 124)
#define ActNewMch (ActChgCrsTT1stDay + 125)
#define ActResMch (ActChgCrsTT1stDay + 126)
#define ActBckMch (ActChgCrsTT1stDay + 127)
#define ActPlyPauMch (ActChgCrsTT1stDay + 128)
#define ActFwdMch (ActChgCrsTT1stDay + 129)
#define ActChgNumColMch (ActChgCrsTT1stDay + 130)
#define ActChgVisResMchQst (ActChgCrsTT1stDay + 131)
#define ActMchCntDwn (ActChgCrsTT1stDay + 132)
#define ActRefMchTch (ActChgCrsTT1stDay + 133)
#define ActSeeGam (ActChgCrsTT1stDay + 122)
#define ActReqRemMch (ActChgCrsTT1stDay + 123)
#define ActRemMch (ActChgCrsTT1stDay + 124)
#define ActReqNewMch (ActChgCrsTT1stDay + 125)
#define ActNewMch (ActChgCrsTT1stDay + 126)
#define ActResMch (ActChgCrsTT1stDay + 127)
#define ActBckMch (ActChgCrsTT1stDay + 128)
#define ActPlyPauMch (ActChgCrsTT1stDay + 129)
#define ActFwdMch (ActChgCrsTT1stDay + 130)
#define ActChgNumColMch (ActChgCrsTT1stDay + 131)
#define ActChgVisResMchQst (ActChgCrsTT1stDay + 132)
#define ActMchCntDwn (ActChgCrsTT1stDay + 133)
#define ActRefMchTch (ActChgCrsTT1stDay + 134)
#define ActJoiMch (ActChgCrsTT1stDay + 134)
#define ActSeeMchAnsQstStd (ActChgCrsTT1stDay + 135)
#define ActRemMchAnsQstStd (ActChgCrsTT1stDay + 136)
#define ActAnsMchQstStd (ActChgCrsTT1stDay + 137)
#define ActRefMchStd (ActChgCrsTT1stDay + 138)
#define ActJoiMch (ActChgCrsTT1stDay + 135)
#define ActSeeMchAnsQstStd (ActChgCrsTT1stDay + 136)
#define ActRemMchAnsQstStd (ActChgCrsTT1stDay + 137)
#define ActAnsMchQstStd (ActChgCrsTT1stDay + 138)
#define ActRefMchStd (ActChgCrsTT1stDay + 139)
#define ActSeeMyMchResCrs (ActChgCrsTT1stDay + 139)
#define ActSeeMyMchResGam (ActChgCrsTT1stDay + 140)
#define ActSeeMyMchResMch (ActChgCrsTT1stDay + 141)
#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 142)
#define ActSeeMyMchResCrs (ActChgCrsTT1stDay + 140)
#define ActSeeMyMchResGam (ActChgCrsTT1stDay + 141)
#define ActSeeMyMchResMch (ActChgCrsTT1stDay + 142)
#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 143)
#define ActReqSeeAllMchRes (ActChgCrsTT1stDay + 143)
#define ActSeeAllMchResCrs (ActChgCrsTT1stDay + 144)
#define ActSeeAllMchResGam (ActChgCrsTT1stDay + 145)
#define ActSeeAllMchResMch (ActChgCrsTT1stDay + 146)
#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 147)
#define ActReqSeeAllMchRes (ActChgCrsTT1stDay + 144)
#define ActSeeAllMchResCrs (ActChgCrsTT1stDay + 145)
#define ActSeeAllMchResGam (ActChgCrsTT1stDay + 146)
#define ActSeeAllMchResMch (ActChgCrsTT1stDay + 147)
#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 148)
#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 148)
#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 149)
#define ActFrmNewGam (ActChgCrsTT1stDay + 149)
#define ActEdiOneGam (ActChgCrsTT1stDay + 150)
#define ActNewGam (ActChgCrsTT1stDay + 151)
#define ActChgGam (ActChgCrsTT1stDay + 152)
#define ActReqRemGam (ActChgCrsTT1stDay + 153)
#define ActRemGam (ActChgCrsTT1stDay + 154)
#define ActHidGam (ActChgCrsTT1stDay + 155)
#define ActShoGam (ActChgCrsTT1stDay + 156)
#define ActAddOneGamQst (ActChgCrsTT1stDay + 157)
#define ActGamLstTstQst (ActChgCrsTT1stDay + 158)
#define ActAddTstQstToGam (ActChgCrsTT1stDay + 159)
#define ActReqRemGamQst (ActChgCrsTT1stDay + 160)
#define ActRemGamQst (ActChgCrsTT1stDay + 161)
#define ActUp_GamQst (ActChgCrsTT1stDay + 162)
#define ActDwnGamQst (ActChgCrsTT1stDay + 163)
#define ActFrmNewGam (ActChgCrsTT1stDay + 150)
#define ActEdiOneGam (ActChgCrsTT1stDay + 151)
#define ActNewGam (ActChgCrsTT1stDay + 152)
#define ActChgGam (ActChgCrsTT1stDay + 153)
#define ActReqRemGam (ActChgCrsTT1stDay + 154)
#define ActRemGam (ActChgCrsTT1stDay + 155)
#define ActHidGam (ActChgCrsTT1stDay + 156)
#define ActShoGam (ActChgCrsTT1stDay + 157)
#define ActAddOneGamQst (ActChgCrsTT1stDay + 158)
#define ActGamLstTstQst (ActChgCrsTT1stDay + 159)
#define ActAddTstQstToGam (ActChgCrsTT1stDay + 160)
#define ActReqRemGamQst (ActChgCrsTT1stDay + 161)
#define ActRemGamQst (ActChgCrsTT1stDay + 162)
#define ActUp_GamQst (ActChgCrsTT1stDay + 163)
#define ActDwnGamQst (ActChgCrsTT1stDay + 164)
#define ActSeeSvy (ActChgCrsTT1stDay + 164)
#define ActAnsSvy (ActChgCrsTT1stDay + 165)
#define ActFrmNewSvy (ActChgCrsTT1stDay + 166)
#define ActEdiOneSvy (ActChgCrsTT1stDay + 167)
#define ActNewSvy (ActChgCrsTT1stDay + 168)
#define ActChgSvy (ActChgCrsTT1stDay + 169)
#define ActReqRemSvy (ActChgCrsTT1stDay + 170)
#define ActRemSvy (ActChgCrsTT1stDay + 171)
#define ActReqRstSvy (ActChgCrsTT1stDay + 172)
#define ActRstSvy (ActChgCrsTT1stDay + 173)
#define ActHidSvy (ActChgCrsTT1stDay + 174)
#define ActShoSvy (ActChgCrsTT1stDay + 175)
#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 176)
#define ActRcvSvyQst (ActChgCrsTT1stDay + 177)
#define ActReqRemSvyQst (ActChgCrsTT1stDay + 178)
#define ActRemSvyQst (ActChgCrsTT1stDay + 179)
#define ActSeeSvy (ActChgCrsTT1stDay + 165)
#define ActAnsSvy (ActChgCrsTT1stDay + 166)
#define ActFrmNewSvy (ActChgCrsTT1stDay + 167)
#define ActEdiOneSvy (ActChgCrsTT1stDay + 168)
#define ActNewSvy (ActChgCrsTT1stDay + 169)
#define ActChgSvy (ActChgCrsTT1stDay + 170)
#define ActReqRemSvy (ActChgCrsTT1stDay + 171)
#define ActRemSvy (ActChgCrsTT1stDay + 172)
#define ActReqRstSvy (ActChgCrsTT1stDay + 173)
#define ActRstSvy (ActChgCrsTT1stDay + 174)
#define ActHidSvy (ActChgCrsTT1stDay + 175)
#define ActShoSvy (ActChgCrsTT1stDay + 176)
#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 177)
#define ActRcvSvyQst (ActChgCrsTT1stDay + 178)
#define ActReqRemSvyQst (ActChgCrsTT1stDay + 179)
#define ActRemSvyQst (ActChgCrsTT1stDay + 180)
#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 180)
#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 181)
#define ActEdiExaAnn (ActChgCrsTT1stDay + 182)
#define ActRcvExaAnn (ActChgCrsTT1stDay + 183)
#define ActPrnExaAnn (ActChgCrsTT1stDay + 184)
#define ActReqRemExaAnn (ActChgCrsTT1stDay + 185)
#define ActRemExaAnn (ActChgCrsTT1stDay + 186)
#define ActHidExaAnn (ActChgCrsTT1stDay + 187)
#define ActShoExaAnn (ActChgCrsTT1stDay + 188)
#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 181)
#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 182)
#define ActEdiExaAnn (ActChgCrsTT1stDay + 183)
#define ActRcvExaAnn (ActChgCrsTT1stDay + 184)
#define ActPrnExaAnn (ActChgCrsTT1stDay + 185)
#define ActReqRemExaAnn (ActChgCrsTT1stDay + 186)
#define ActRemExaAnn (ActChgCrsTT1stDay + 187)
#define ActHidExaAnn (ActChgCrsTT1stDay + 188)
#define ActShoExaAnn (ActChgCrsTT1stDay + 189)
/*****************************************************************************/
/******************************** Files tab **********************************/

View File

@ -523,8 +523,19 @@ Param
// TODO: Miguel Damas: al principio de los exámenes tendría que poner cuánto resta cada pregunta
// TODO: Oresti Baños: cambiar ojos por candados en descriptores para prohibir/permitir y dejar los ojos para poder elegir descriptores
// TODO: Si el alumno ha marcado "Permitir que los profesores...", entonces pedir confirmación al pulsar el botón azul, para evitar que se envíe por error antes de tiempo
// TODO: Tener en cuenta en los resultados de test (exámenes) el tiempo de inicio y el tiempo de fin
Cuando el alumno ve un test, se crea un examen (en la base de datos), aunque no se conteste, a partir de los datos del formulario.
El examen se muestra en pantalla tomándolo del examen en la base de datos, no del formulario.
Cuando el alumno pulsa en "He terminado" se le pregunta si está seguro y se vuelve a mostrar el examen cogiéndolo de la base de datos.
// TODO: URGENT: Fix bug while playing match.
Version 19.156: Mar 28, 2020 New action to confirm assessment of test exam.
Code refactoring in test and matches. (284544 lines)
5 changes necessary in database:
ALTER TABLE tst_exams CHANGE COLUMN AllowTeachers AllowTeachers ENUM('N','Y') NOT NULL DEFAULT 'N' AFTER NumQstsNotBlank;
ALTER TABLE tst_exams CHANGE COLUMN TstTime StartTime DATETIME NOT NULL;
ALTER TABLE tst_exams ADD COLUMN EndTime DATETIME NOT NULL DEFAULT '1970-01-01 01:00:00' AFTER StartTime;
UPDATE tst_exams SET EndTime=StartTime;
ALTER TABLE tst_exams CHANGE COLUMN EndTime EndTime DATETIME NOT NULL;
Version 19.155.6: Mar 26, 2020 Code refactoring in matches. (284479 lines)
Version 19.155.5: Mar 26, 2020 Code refactoring in tests. (284480 lines)

View File

@ -2795,22 +2795,24 @@ mysql> DESCRIBE tst_exams;
| TstCod | int(11) | NO | PRI | NULL | auto_increment |
| CrsCod | int(11) | NO | MUL | NULL | |
| UsrCod | int(11) | NO | | NULL | |
| AllowTeachers | enum('N','Y') | NO | | N | |
| TstTime | datetime | NO | | NULL | |
| StartTime | datetime | NO | | NULL | |
| EndTime | datetime | NO | | NULL | |
| NumQsts | int(11) | NO | | 0 | |
| NumQstsNotBlank | int(11) | NO | | 0 | |
| AllowTeachers | enum('N','Y') | NO | | N | |
| Score | double | NO | | 0 | |
+-----------------+---------------+------+-----+---------+----------------+
8 rows in set (0.05 sec)
9 rows in set (0.00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS tst_exams ("
"TstCod INT NOT NULL AUTO_INCREMENT,"
"CrsCod INT NOT NULL,"
"UsrCod INT NOT NULL,"
"AllowTeachers ENUM('N','Y') NOT NULL DEFAULT 'N',"
"TstTime DATETIME NOT NULL,"
"StartTime DATETIME NOT NULL,"
"EndTime DATETIME NOT NULL,"
"NumQsts INT NOT NULL DEFAULT 0,"
"NumQstsNotBlank INT NOT NULL DEFAULT 0,"
"AllowTeachers ENUM('N','Y') NOT NULL DEFAULT 'N',"
"Score DOUBLE PRECISION NOT NULL DEFAULT 0,"
"UNIQUE INDEX(TstCod),"
"INDEX(CrsCod,UsrCod))");

View File

@ -95,7 +95,6 @@ static void McR_ShowMchResultsSummaryRow (unsigned NumResults,
double TotalScoreOfAllResults,
double TotalGrade);
static void McR_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
time_t TimeUTC[Dat_NUM_START_END_TIME],
struct TsR_Result *Result);
static bool McR_CheckIfICanSeeMatchResult (struct Match *Match,long UsrCod);
@ -1004,7 +1003,6 @@ void McR_ShowOneMchResult (void)
struct Match Match;
Usr_MeOrOther_t MeOrOther;
struct UsrData *UsrDat;
time_t TimeUTC[Dat_NUM_START_END_TIME]; // Match result UTC date-time
Dat_StartEndTime_t StartEndTime;
char *Id;
struct TsR_Result Result;
@ -1033,7 +1031,6 @@ void McR_ShowOneMchResult (void)
/***** Get match result data *****/
McR_GetMatchResultDataByMchCod (Match.MchCod,UsrDat->UsrCod,
TimeUTC,
&Result);
/***** Check if I can view this match result *****/
@ -1123,7 +1120,7 @@ void McR_ShowOneMchResult (void)
if (asprintf (&Id,"match_%u",(unsigned) StartEndTime) < 0)
Lay_NotEnoughMemoryExit ();
HTM_TD_Begin ("id=\"%s\" class=\"DAT LT\"",Id);
Dat_WriteLocalDateHMSFromUTC (Id,TimeUTC[StartEndTime],
Dat_WriteLocalDateHMSFromUTC (Id,Result.TimeUTC[StartEndTime],
Gbl.Prefs.DateFormat,Dat_SEPARATOR_COMMA,
true,true,true,0x7);
HTM_TD_End ();
@ -1195,8 +1192,7 @@ void McR_ShowOneMchResult (void)
HTM_TR_End ();
/***** Write answers and solutions *****/
TsR_ShowTestResult (UsrDat,&Result,TimeUTC[Dat_START_TIME],
Game.Visibility);
TsR_ShowTestResult (UsrDat,&Result,Game.Visibility);
/***** End table *****/
HTM_TABLE_End ();
@ -1293,7 +1289,6 @@ void McR_GetMatchResultQuestionsFromDB (long MchCod,long UsrCod,
/*****************************************************************************/
static void McR_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
time_t TimeUTC[Dat_NUM_START_END_TIME],
struct TsR_Result *Result)
{
MYSQL_RES *mysql_res;
@ -1323,7 +1318,7 @@ static void McR_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
for (StartEndTime = (Dat_StartEndTime_t) 0;
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
StartEndTime++)
TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[StartEndTime]);
Result->TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[StartEndTime]);
/* Get number of questions (row[2]) */
if (sscanf (row[2],"%u",&Result->NumQsts) != 1)

View File

@ -564,6 +564,55 @@ void Tst_ShowNewTest (void)
Tst_TstDestructor (&Test);
}
/*****************************************************************************/
/********************* Request the assessment of a test **********************/
/*****************************************************************************/
void Tst_RequestAssessTest (void)
{
extern const char *Txt_The_test_X_has_already_been_assessed_previously;
extern const char *Txt_There_was_an_error_in_assessing_the_test_X;
unsigned NumTst;
// long TstCod = -1L; // Initialized to avoid warning
struct TsR_Result Result;
/***** Read test configuration from database *****/
TstCfg_GetConfigFromDB ();
/***** Get number of this test from form *****/
NumTst = Tst_GetAndCheckParamNumTst ();
/****** Get test status in database for this session-course-num.test *****/
switch (Tst_GetTstStatus (NumTst))
{
case Tst_STATUS_SHOWN_BUT_NOT_ASSESSED:
/***** Get parameters from the form *****/
/* Get questions and answers from form to assess a test */
Tst_GetQuestionsAndAnswersFromForm (&Result);
/***** Show question and button to send the test *****/
/* Start alert */
Ale_ShowAlertAndButton1 (Ale_INFO,"Por favor, revise el test antes de enviarlo");
/* Show test again */
/* End alert */
Ale_ShowAlertAndButton2 (ActAssTst,NULL,NULL,
NULL,NULL,
Btn_CONFIRM_BUTTON,"Enviar test");
break;
case Tst_STATUS_ASSESSED:
Ale_ShowAlert (Ale_WARNING,Txt_The_test_X_has_already_been_assessed_previously,
NumTst);
break;
case Tst_STATUS_ERROR:
Ale_ShowAlert (Ale_WARNING,Txt_There_was_an_error_in_assessing_the_test_X,
NumTst);
break;
}
}
/*****************************************************************************/
/******************************** Assess a test ******************************/
/*****************************************************************************/
@ -578,7 +627,6 @@ void Tst_AssessTest (void)
extern const char *Txt_The_test_X_has_already_been_assessed_previously;
extern const char *Txt_There_was_an_error_in_assessing_the_test_X;
unsigned NumTst;
bool AllowTeachers; // Can teachers of this course see the test result?
long TstCod = -1L; // Initialized to avoid warning
struct TsR_Result Result;
@ -592,18 +640,12 @@ void Tst_AssessTest (void)
switch (Tst_GetTstStatus (NumTst))
{
case Tst_STATUS_SHOWN_BUT_NOT_ASSESSED:
/***** Get the parameters of the form *****/
/* Get number of questions */
Result.NumQsts = Tst_GetParamNumQsts ();
/***** Get if test will be visible by teachers *****/
AllowTeachers = Par_GetParToBool ("AllowTchs");
/***** Get questions and answers from form to assess a test *****/
/***** Get parameters from the form *****/
/* Get questions and answers from form to assess a test */
Tst_GetQuestionsAndAnswersFromForm (&Result);
/***** Create new test in database to store the result *****/
TstCod = TsR_CreateTestResultInDB (AllowTeachers,Result.NumQsts);
TstCod = TsR_CreateTestResultInDB (&Result);
/***** Begin box *****/
Box_BoxBegin (NULL,Txt_Test_result,
@ -670,6 +712,9 @@ static void Tst_GetQuestionsAndAnswersFromForm (struct TsR_Result *Result)
unsigned NumQst;
char StrQstIndOrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Qstxx...x", "Indxx...x" or "Ansxx...x"
/***** Get number of questions *****/
Result->NumQsts = Tst_GetParamNumQsts ();
/***** Get questions and answers *****/
for (NumQst = 0;
NumQst < Result->NumQsts;
@ -677,25 +722,28 @@ static void Tst_GetQuestionsAndAnswersFromForm (struct TsR_Result *Result)
{
/* Get question code */
snprintf (StrQstIndOrAns,sizeof (StrQstIndOrAns),
"Qst%03u",
"Qst%010u",
NumQst);
if ((Result->QstCodes[NumQst] = Par_GetParToLong (StrQstIndOrAns)) <= 0)
Lay_ShowErrorAndExit ("Code of question is missing.");
/* Get indexes for this question */
snprintf (StrQstIndOrAns,sizeof (StrQstIndOrAns),
"Ind%03u",
"Ind%010u",
NumQst);
Par_GetParMultiToText (StrQstIndOrAns,Result->StrIndexes[NumQst],
Tst_MAX_BYTES_INDEXES_ONE_QST); /* If choice ==> "0", "1", "2",... */
/* Get answers selected by user for this question */
snprintf (StrQstIndOrAns,sizeof (StrQstIndOrAns),
"Ans%03u",
"Ans%010u",
NumQst);
Par_GetParMultiToText (StrQstIndOrAns,Result->StrAnswers[NumQst],
Tst_MAX_BYTES_ANSWERS_ONE_QST); /* If answer type == T/F ==> " ", "T", "F"; if choice ==> "0", "2",... */
}
/***** Get if test result will be visible by teachers *****/
Result->AllowTeachers = Par_GetParToBool ("AllowTchs");
}
/*****************************************************************************/
@ -3601,7 +3649,7 @@ static void Tst_WriteTFAnsViewTest (unsigned NumQst)
/***** Write selector for the answer *****/
HTM_SELECT_Begin (false,
"name=\"Ans%03u\"",NumQst);
"name=\"Ans%010u\"",NumQst);
HTM_OPTION (HTM_Type_STRING,"" ,true ,false,"&nbsp;");
HTM_OPTION (HTM_Type_STRING,"T",false,false,"%s",Txt_TF_QST[0]);
HTM_OPTION (HTM_Type_STRING,"F",false,false,"%s",Txt_TF_QST[1]);
@ -3741,8 +3789,7 @@ static void Tst_WriteChoiceAnsViewTest (unsigned NumQst,
MYSQL_ROW row;
unsigned Index;
bool ErrorInIndex = false;
char ParamName[3 + 6 + 1];
char StrAns[32];
char StrQstIndOrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Qstxx...x", "Indxx...x" or "Ansxx...x"
/***** Get answers of a question from database *****/
Tst_GetAnswersQst (Question,&mysql_res,Shuffle);
@ -3797,36 +3844,36 @@ static void Tst_WriteChoiceAnsViewTest (unsigned NumQst,
/***** Write selectors and letter of this option *****/
HTM_TD_Begin ("class=\"LT\"");
snprintf (ParamName,sizeof (ParamName),
"Ind%03u",
snprintf (StrQstIndOrAns,sizeof (StrQstIndOrAns),
"Ind%010u",
NumQst);
Par_PutHiddenParamUnsigned (NULL,ParamName,Index);
snprintf (StrAns,sizeof (StrAns),
"Ans%03u",
Par_PutHiddenParamUnsigned (NULL,StrQstIndOrAns,Index);
snprintf (StrQstIndOrAns,sizeof (StrQstIndOrAns),
"Ans%010u",
NumQst);
if (Question->Answer.Type == Tst_ANS_UNIQUE_CHOICE)
HTM_INPUT_RADIO (StrAns,false,
"id=\"Ans%06u_%u\" value=\"%u\""
" onclick=\"selectUnselectRadio(this,this.form.Ans%03u,%u);\"",
HTM_INPUT_RADIO (StrQstIndOrAns,false,
"id=\"Ans%010u_%u\" value=\"%u\""
" onclick=\"selectUnselectRadio(this,this.form.Ans%010u,%u);\"",
NumQst,NumOpt,
Index,
NumQst,Question->Answer.NumOptions);
else // Answer.Type == Tst_ANS_MULTIPLE_CHOICE
HTM_INPUT_CHECKBOX (StrAns,HTM_DONT_SUBMIT_ON_CHANGE,
"id=\"Ans%06u_%u\" value=\"%u\"",
HTM_INPUT_CHECKBOX (StrQstIndOrAns,HTM_DONT_SUBMIT_ON_CHANGE,
"id=\"Ans%010u_%u\" value=\"%u\"",
NumQst,NumOpt,
Index);
HTM_TD_End ();
HTM_TD_Begin ("class=\"LT\"");
HTM_LABEL_Begin ("for=\"Ans%06u_%u\" class=\"ANS_TXT\"",NumQst,NumOpt);
HTM_LABEL_Begin ("for=\"Ans%010u_%u\" class=\"ANS_TXT\"",NumQst,NumOpt);
HTM_TxtF ("%c)&nbsp;",'a' + (char) NumOpt);
HTM_LABEL_End ();
HTM_TD_End ();
/***** Write the option text *****/
HTM_TD_Begin ("class=\"LT\"");
HTM_LABEL_Begin ("for=\"Ans%06u_%u\" class=\"ANS_TXT\"",NumQst,NumOpt);
HTM_LABEL_Begin ("for=\"Ans%010u_%u\" class=\"ANS_TXT\"",NumQst,NumOpt);
HTM_Txt (Question->Answer.Options[NumOpt].Text);
HTM_LABEL_End ();
Med_ShowMedia (&Question->Answer.Options[NumOpt].Media,
@ -4200,13 +4247,13 @@ void Tst_ComputeScoreQst (const struct Tst_Question *Question,
static void Tst_WriteTextAnsViewTest (unsigned NumQst)
{
char StrAns[3 + 6 + 1];
char StrQstIndOrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Qstxx...x", "Indxx...x" or "Ansxx...x"
/***** Write input field for the answer *****/
snprintf (StrAns,sizeof (StrAns),
"Ans%03u",
snprintf (StrQstIndOrAns,sizeof (StrQstIndOrAns),
"Ans%010u",
NumQst);
HTM_INPUT_TEXT (StrAns,Tst_MAX_BYTES_ANSWERS_ONE_QST,"",false,
HTM_INPUT_TEXT (StrQstIndOrAns,Tst_MAX_BYTES_ANSWERS_ONE_QST,"",false,
"size=\"40\"");
}
@ -4416,13 +4463,13 @@ static void Tst_WriteTextAnsAssessTest (struct UsrData *UsrDat,
static void Tst_WriteIntAnsViewTest (unsigned NumQst)
{
char StrAns[3 + 6 + 1];
char StrQstIndOrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Qstxx...x", "Indxx...x" or "Ansxx...x"
/***** Write input field for the answer *****/
snprintf (StrAns,sizeof (StrAns),
"Ans%03u",
snprintf (StrQstIndOrAns,sizeof (StrQstIndOrAns),
"Ans%010u",
NumQst);
HTM_INPUT_TEXT (StrAns,11,"",false,
HTM_INPUT_TEXT (StrQstIndOrAns,11,"",false,
"size=\"11\"");
}
@ -4546,13 +4593,13 @@ static void Tst_WriteIntAnsAssessTest (struct UsrData *UsrDat,
static void Tst_WriteFloatAnsViewTest (unsigned NumQst)
{
char StrAns[3 + 6 + 1];
char StrQstIndOrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Qstxx...x", "Indxx...x" or "Ansxx...x"
/***** Write input field for the answer *****/
snprintf (StrAns,sizeof (StrAns),
"Ans%03u",
snprintf (StrQstIndOrAns,sizeof (StrQstIndOrAns),
"Ans%010u",
NumQst);
HTM_INPUT_TEXT (StrAns,Tst_MAX_BYTES_FLOAT_ANSWER,"",false,
HTM_INPUT_TEXT (StrQstIndOrAns,Tst_MAX_BYTES_FLOAT_ANSWER,"",false,
"size=\"11\"");
}
@ -4736,12 +4783,12 @@ static void Tst_WriteScoreEnd (void)
static void Tst_WriteParamQstCod (unsigned NumQst,long QstCod)
{
char ParamName[3 + 6 + 1];
char StrQstIndOrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Qstxx...x", "Indxx...x" or "Ansxx...x"
snprintf (ParamName,sizeof (ParamName),
"Qst%03u",
snprintf (StrQstIndOrAns,sizeof (StrQstIndOrAns),
"Qst%010u",
NumQst);
Par_PutHiddenParamLong (NULL,ParamName,QstCod);
Par_PutHiddenParamLong (NULL,StrQstIndOrAns,QstCod);
}
/*****************************************************************************/

View File

@ -152,6 +152,7 @@ struct Tst_Stats
void Tst_RequestTest (void);
void Tst_ShowNewTest (void);
void Tst_RequestAssessTest (void);
void Tst_AssessTest (void);
void Tst_ComputeAndShowGrade (unsigned NumQsts,double Score,double MaxGrade);

View File

@ -86,10 +86,7 @@ static void TsR_ShowTestResultsSummaryRow (bool ItsMe,
unsigned NumTotalQstsNotBlank,
double TotalScoreOfAllTests);
static void TsR_ShowTstTagsPresentInATestResult (long TstCod);
static void TsR_GetTestResultDataByTstCod (long TstCod,
bool *AllowTeachers,
time_t *TstTimeUTC,
struct TsR_Result *Result);
static void TsR_GetTestResultDataByTstCod (long TstCod,struct TsR_Result *Result);
static void TsR_GetTestResultQuestionsFromDB (long TstCod,struct TsR_Result *Result);
/*****************************************************************************/
@ -174,20 +171,20 @@ void TsR_ShowMyTstResults (void)
/********************* Store test result in database *************************/
/*****************************************************************************/
long TsR_CreateTestResultInDB (bool AllowTeachers,unsigned NumQsts)
long TsR_CreateTestResultInDB (const struct TsR_Result *Result)
{
/***** Insert new test result into table *****/
return
DB_QueryINSERTandReturnCode ("can not create new test result",
"INSERT INTO tst_exams"
" (CrsCod,UsrCod,AllowTeachers,TstTime,NumQsts)"
" (CrsCod,UsrCod,StartTime,EndTime,NumQsts,AllowTeachers)"
" VALUES"
" (%ld,%ld,'%c',NOW(),%u)",
" (%ld,%ld,NOW(),NOW(),%u,'%c')",
Gbl.Hierarchy.Crs.CrsCod,
Gbl.Usrs.Me.UsrDat.UsrCod,
AllowTeachers ? 'Y' :
'N',
NumQsts);
Result->NumQsts,
Result->AllowTeachers ? 'Y' :
'N');
}
/*****************************************************************************/
@ -199,7 +196,7 @@ void TsR_StoreScoreOfTestResultInDB (long TstCod,
{
/***** Update score in test result *****/
Str_SetDecimalPointToUS (); // To print the floating point as a dot
DB_QueryUPDATE ("can not update result of test result",
DB_QueryUPDATE ("can not update test result",
"UPDATE tst_exams"
" SET NumQstsNotBlank=%u,"
"Score='%.15lg'"
@ -304,29 +301,26 @@ static void TsR_ShowTstResults (struct UsrData *UsrDat)
static unsigned UniqueId = 0;
char *Id;
long TstCod;
unsigned NumQstsInThisTest;
unsigned NumQstsNotBlankInThisTest;
struct TsR_Result Result;
unsigned NumTotalQsts = 0;
unsigned NumTotalQstsNotBlank = 0;
double ScoreInThisTest;
double TotalScoreOfAllTests = 0.0;
unsigned NumExamsVisibleByTchs = 0;
bool AllowTeachers; // Can teachers of this course see the test result?
bool ItsMe = Usr_ItsMe (UsrDat->UsrCod);
bool ICanViewTest;
bool ICanViewScore;
time_t TimeUTC;
char *ClassDat;
/***** Make database query *****/
NumExams =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get test exams of a user",
"SELECT TstCod," // row[0]
"AllowTeachers," // row[1]
"UNIX_TIMESTAMP(TstTime)," // row[2]
"NumQsts," // row[3]
"NumQstsNotBlank," // row[4]
"Score" // row[5]
"SELECT TstCod," // row[0]
"UNIX_TIMESTAMP(StartTime)," // row[1]
"UNIX_TIMESTAMP(EndTime)," // row[2]
"NumQsts," // row[3]
"NumQstsNotBlank," // row[4]
"AllowTeachers," // row[5]
"Score" // row[6]
" FROM tst_exams"
" WHERE CrsCod=%ld AND UsrCod=%ld"
" AND TstTime>=FROM_UNIXTIME(%ld)"
@ -354,10 +348,10 @@ static void TsR_ShowTstResults (struct UsrData *UsrDat)
if ((TstCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
Lay_ShowErrorAndExit ("Wrong code of test result.");
/* Get if teachers are allowed to see this test result (row[1]) */
AllowTeachers = (row[1][0] == 'Y');
ClassDat = AllowTeachers ? "DAT" :
"DAT_LIGHT";
/* Get if teachers are allowed to see this test result (row[5]) */
Result.AllowTeachers = (row[5][0] == 'Y');
ClassDat = Result.AllowTeachers ? "DAT" :
"DAT_LIGHT";
switch (Gbl.Usrs.Me.Role.Logged)
{
@ -373,7 +367,7 @@ static void TsR_ShowTstResults (struct UsrData *UsrDat)
case Rol_INS_ADM:
ICanViewTest =
ICanViewScore = ItsMe ||
AllowTeachers;
Result.AllowTeachers;
break;
case Rol_SYS_ADM:
ICanViewTest =
@ -388,70 +382,71 @@ static void TsR_ShowTstResults (struct UsrData *UsrDat)
if (NumTest)
HTM_TR_Begin (NULL);
/* Write date and time (row[2] holds UTC date-time) */
TimeUTC = Dat_GetUNIXTimeFromStr (row[2]);
/* Write date and time (row[1] and row[2] hold UTC date-times) */
Result.TimeUTC[Dat_START_TIME] = Dat_GetUNIXTimeFromStr (row[1]);
Result.TimeUTC[Dat_END_TIME ] = Dat_GetUNIXTimeFromStr (row[2]);
UniqueId++;
if (asprintf (&Id,"tst_date_%u",UniqueId) < 0)
Lay_NotEnoughMemoryExit ();
HTM_TD_Begin ("id=\"%s\" class=\"%s RT COLOR%u\"",
Id,ClassDat,Gbl.RowEvenOdd);
Dat_WriteLocalDateHMSFromUTC (Id,TimeUTC,
Dat_WriteLocalDateHMSFromUTC (Id,Result.TimeUTC[Dat_END_TIME],
Gbl.Prefs.DateFormat,Dat_SEPARATOR_COMMA,
true,true,false,0x7);
HTM_TD_End ();
free (Id);
/* Get number of questions (row[3]) */
if (sscanf (row[3],"%u",&NumQstsInThisTest) != 1)
NumQstsInThisTest = 0;
if (AllowTeachers)
NumTotalQsts += NumQstsInThisTest;
if (sscanf (row[3],"%u",&Result.NumQsts) != 1)
Result.NumQsts = 0;
if (Result.AllowTeachers)
NumTotalQsts += Result.NumQsts;
/* Get number of questions not blank (row[4]) */
if (sscanf (row[4],"%u",&NumQstsNotBlankInThisTest) != 1)
NumQstsNotBlankInThisTest = 0;
if (AllowTeachers)
NumTotalQstsNotBlank += NumQstsNotBlankInThisTest;
if (sscanf (row[4],"%u",&Result.NumQstsNotBlank) != 1)
Result.NumQstsNotBlank = 0;
if (Result.AllowTeachers)
NumTotalQstsNotBlank += Result.NumQstsNotBlank;
/* Get score (row[5]) */
Str_SetDecimalPointToUS (); // To get the decimal point as a dot
if (sscanf (row[5],"%lf",&ScoreInThisTest) != 1)
ScoreInThisTest = 0.0;
/* Get score (row[6]) */
Str_SetDecimalPointToUS (); // To get the decimal point as a dot
if (sscanf (row[6],"%lf",&Result.Score) != 1)
Result.Score = 0.0;
Str_SetDecimalPointToLocal (); // Return to local system
if (AllowTeachers)
TotalScoreOfAllTests += ScoreInThisTest;
if (Result.AllowTeachers)
TotalScoreOfAllTests += Result.Score;
/* Write number of questions */
HTM_TD_Begin ("class=\"%s RT COLOR%u\"",ClassDat,Gbl.RowEvenOdd);
if (ICanViewTest)
HTM_Unsigned (NumQstsInThisTest);
HTM_Unsigned (Result.NumQsts);
HTM_TD_End ();
/* Write number of questions not blank */
HTM_TD_Begin ("class=\"%s RT COLOR%u\"",ClassDat,Gbl.RowEvenOdd);
if (ICanViewTest)
HTM_Unsigned (NumQstsNotBlankInThisTest);
HTM_Unsigned (Result.NumQstsNotBlank);
HTM_TD_End ();
/* Write score */
HTM_TD_Begin ("class=\"%s RT COLOR%u\"",ClassDat,Gbl.RowEvenOdd);
if (ICanViewScore)
HTM_Double2Decimals (ScoreInThisTest);
HTM_Double2Decimals (Result.Score);
HTM_TD_End ();
/* Write average score per question */
HTM_TD_Begin ("class=\"%s RT COLOR%u\"",ClassDat,Gbl.RowEvenOdd);
if (ICanViewScore)
HTM_Double2Decimals (NumQstsInThisTest ? ScoreInThisTest /
(double) NumQstsInThisTest :
0.0);
HTM_Double2Decimals (Result.NumQsts ? Result.Score /
(double) Result.NumQsts :
0.0);
HTM_TD_End ();
/* Write grade */
HTM_TD_Begin ("class=\"%s RT COLOR%u\"",ClassDat,Gbl.RowEvenOdd);
if (ICanViewScore)
Tst_ComputeAndShowGrade (NumQstsInThisTest,
ScoreInThisTest,
Tst_ComputeAndShowGrade (Result.NumQsts,
Result.Score,
TsR_SCORE_MAX);
HTM_TD_End ();
@ -468,7 +463,7 @@ static void TsR_ShowTstResults (struct UsrData *UsrDat)
HTM_TD_End ();
HTM_TR_End ();
if (AllowTeachers)
if (Result.AllowTeachers)
NumExamsVisibleByTchs++;
}
@ -610,8 +605,6 @@ void TsR_ShowOneTstResult (void)
extern const char *Txt_Grade;
extern const char *Txt_Tags;
long TstCod;
bool AllowTeachers = false; // Initialized to avoid warning
time_t TstTimeUTC = 0; // Test result UTC date-time, initialized to avoid warning
struct TsR_Result Result;
bool ShowPhoto;
char PhotoURL[PATH_MAX + 1];
@ -624,10 +617,7 @@ void TsR_ShowOneTstResult (void)
Lay_ShowErrorAndExit ("Code of test is missing.");
/***** Get test result data *****/
TsR_GetTestResultDataByTstCod (TstCod,
&AllowTeachers,
&TstTimeUTC,
&Result);
TsR_GetTestResultDataByTstCod (TstCod,&Result);
TstCfg_SetConfigVisibility (TsV_MAX_VISIBILITY);
/***** Check if I can view this test result *****/
@ -657,7 +647,7 @@ void TsR_ShowOneTstResult (void)
case ActSeeOneTstResOth:
ICanViewTest =
ICanViewScore = ItsMe ||
AllowTeachers;
Result.AllowTeachers;
break;
default:
ICanViewTest =
@ -730,7 +720,7 @@ void TsR_ShowOneTstResult (void)
HTM_TD_End ();
HTM_TD_Begin ("id=\"test\" class=\"DAT LT\"");
Dat_WriteLocalDateHMSFromUTC ("test",TstTimeUTC,
Dat_WriteLocalDateHMSFromUTC ("test",Result.TimeUTC[Dat_END_TIME],
Gbl.Prefs.DateFormat,Dat_SEPARATOR_COMMA,
true,true,true,0x7);
HTM_TD_End ();
@ -800,7 +790,6 @@ void TsR_ShowOneTstResult (void)
/***** Write answers and solutions *****/
TsR_ShowTestResult (&Gbl.Usrs.Other.UsrDat,
&Result,
TstTimeUTC,
TstCfg_GetConfigVisibility ());
/***** End table *****/
@ -862,7 +851,6 @@ static void TsR_ShowTstTagsPresentInATestResult (long TstCod)
void TsR_ShowTestResult (struct UsrData *UsrDat,
const struct TsR_Result *Result,
time_t TstTimeUTC,
unsigned Visibility)
{
extern const char *Txt_Question_modified;
@ -891,7 +879,7 @@ void TsR_ShowTestResult (struct UsrData *UsrDat,
==> don't show question ****/
EditTimeUTC = Dat_GetUNIXTimeFromStr (row[0]);
ThisQuestionHasBeenEdited = false;
if (EditTimeUTC > TstTimeUTC)
if (EditTimeUTC > Result->TimeUTC[Dat_START_TIME])
ThisQuestionHasBeenEdited = true;
if (ThisQuestionHasBeenEdited)
@ -944,10 +932,7 @@ void TsR_ShowTestResult (struct UsrData *UsrDat,
/********* Get data of a test result using its test result code **************/
/*****************************************************************************/
static void TsR_GetTestResultDataByTstCod (long TstCod,
bool *AllowTeachers,
time_t *TstTimeUTC,
struct TsR_Result *Result)
static void TsR_GetTestResultDataByTstCod (long TstCod,struct TsR_Result *Result)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
@ -956,11 +941,12 @@ static void TsR_GetTestResultDataByTstCod (long TstCod,
if (DB_QuerySELECT (&mysql_res,"can not get data"
" of a test result of a user",
"SELECT UsrCod," // row[0]
"AllowTeachers," // row[1]
"UNIX_TIMESTAMP(TstTime)," // row[2]
"UNIX_TIMESTAMP(StartTime)," // row[1]
"UNIX_TIMESTAMP(EndTime)," // row[2]
"NumQsts," // row[3]
"NumQstsNotBlank," // row[4]
"Score" // row[5]
"AllowTeachers," // row[5]
"Score" // row[6]
" FROM tst_exams"
" WHERE TstCod=%ld AND CrsCod=%ld",
TstCod,
@ -971,11 +957,9 @@ static void TsR_GetTestResultDataByTstCod (long TstCod,
/* Get user code (row[0]) */
Gbl.Usrs.Other.UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0]);
/* Get if teachers are allowed to see this test result (row[1]) */
*AllowTeachers = (row[1][0] == 'Y');
/* Get date-time (row[2] holds UTC date-time) */
*TstTimeUTC = Dat_GetUNIXTimeFromStr (row[2]);
/* Get date-time (row[1] and row[2] hold UTC date-time) */
Result->TimeUTC[Dat_START_TIME] = Dat_GetUNIXTimeFromStr (row[1]);
Result->TimeUTC[Dat_END_TIME ] = Dat_GetUNIXTimeFromStr (row[2]);
/* Get number of questions (row[3]) */
if (sscanf (row[3],"%u",&Result->NumQsts) != 1)
@ -985,17 +969,23 @@ static void TsR_GetTestResultDataByTstCod (long TstCod,
if (sscanf (row[4],"%u",&Result->NumQstsNotBlank) != 1)
Result->NumQstsNotBlank = 0;
/* Get score (row[5]) */
/* Get if teachers are allowed to see this test result (row[5]) */
Result->AllowTeachers = (row[5][0] == 'Y');
/* Get score (row[6]) */
Str_SetDecimalPointToUS (); // To get the decimal point as a dot
if (sscanf (row[5],"%lf",&Result->Score) != 1)
if (sscanf (row[6],"%lf",&Result->Score) != 1)
Result->Score = 0.0;
Str_SetDecimalPointToLocal (); // Return to local system
}
else
{
Result->NumQsts = 0;
Result->NumQstsNotBlank = 0;
Result->Score = 0.0;
Result->TimeUTC[Dat_START_TIME] =
Result->TimeUTC[Dat_END_TIME ] = 0;
Result->NumQsts = 0;
Result->NumQstsNotBlank = 0;
Result->AllowTeachers = false;
Result->Score = 0.0;
}
/***** Free structure that stores the query result *****/
@ -1051,7 +1041,8 @@ static void TsR_GetTestResultQuestionsFromDB (long TstCod,struct TsR_Result *Res
"Indexes," // row[1]
"Answers" // row[2]
" FROM tst_exam_questions"
" WHERE TstCod=%ld ORDER BY QstInd",
" WHERE TstCod=%ld"
" ORDER BY QstInd",
TstCod);
/***** Get questions codes *****/

View File

@ -45,14 +45,16 @@
struct TsR_Result
{
time_t TimeUTC[Dat_NUM_START_END_TIME];
unsigned NumQsts;
unsigned NumQstsNotBlank;
double Score;
long QstCodes[TstCfg_MAX_QUESTIONS_PER_TEST]; // Codes of the sent/received questions in a test
char StrIndexes[TstCfg_MAX_QUESTIONS_PER_TEST]
[Tst_MAX_BYTES_INDEXES_ONE_QST + 1]; // 0 1 2 3, 3 0 2 1, etc.
char StrAnswers[TstCfg_MAX_QUESTIONS_PER_TEST]
[Tst_MAX_BYTES_ANSWERS_ONE_QST + 1]; // Answers selected by user
bool AllowTeachers; // Are teachers allowed to see this test result?
double Score; // Total score of the test result
};
/*****************************************************************************/
@ -62,14 +64,13 @@ struct TsR_Result
void TsR_SelUsrsToViewUsrsTstResults (void);
void TsR_SelDatesToSeeMyTstResults (void);
void TsR_ShowMyTstResults (void);
long TsR_CreateTestResultInDB (bool AllowTeachers,unsigned NumQsts);
long TsR_CreateTestResultInDB (const struct TsR_Result *Result);
void TsR_StoreScoreOfTestResultInDB (long TstCod,
const struct TsR_Result *Result);
void TsR_GetUsrsAndShowTstResults (void);
void TsR_ShowOneTstResult (void);
void TsR_ShowTestResult (struct UsrData *UsrDat,
const struct TsR_Result *Result,
time_t TstTimeUTC,
unsigned Visibility);
void TsR_StoreOneTestResultQstInDB (long TstCod,
const struct TsR_Result *Result,

View File

@ -9350,9 +9350,30 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Show the seft-assessment test"
"See a test"
#elif L==4 // es
""
"Ver un test"
#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
,
[ActReqAssTst] =
#if L==1 // ca
"" // Necessita traducció
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Request assessment of a test"
#elif L==4 // es
"Solicitar evaluaci&oacute;n de un test"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9371,9 +9392,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Assess a self-assessment test"
"Assess a test"
#elif L==4 // es
""
"Evaluar un test"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9392,9 +9413,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Request the edition of self-assessment questions"
"Request the edition of test questions"
#elif L==4 // es
""
"Solicitar la edici&oacute;n de preguntas de test"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9413,9 +9434,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Edit one self-assesment test question"
"Edit a test question"
#elif L==4 // es
""
"Editar una pregunta de test"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9434,9 +9455,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Put form to ask for an XML with test questions to import"
"Request an XML file with test questions to import"
#elif L==4 // es
""
"Solicitar un archivo XML con preguntas de test para importar"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9457,7 +9478,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==3 // en
"Import test questions from XML file"
#elif L==4 // es
""
"Importar preguntas de test de un archivo XML"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9476,9 +9497,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"List for edition several self-assessment test questions"
"List test questions for edition"
#elif L==4 // es
""
"Listar preguntas de test para edici&oacute;n"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9497,9 +9518,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Receive a question of self-assessment"
"Create/Modify a test question"
#elif L==4 // es
""
"Crear/Modificar una pregunta de test"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9602,9 +9623,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Change shuffle of of a question of self-assessment"
"Change shuffle of a test question"
#elif L==4 // es
""
"Cambiar baraje de una pregunta de test"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9623,9 +9644,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Request renaming of tags of questions of self-assesment"
"See test configuration"
#elif L==4 // es
""
"Ver configuraci&oacute;n de test"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9644,9 +9665,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Enable a tag"
"Enable a test tag"
#elif L==4 // es
""
"Habilitar un descriptor de test"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9665,9 +9686,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Disable a tag"
"Disable a test tag"
#elif L==4 // es
""
"Inhabilitar un descriptor de test"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9686,9 +9707,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Rename a tag"
"Rename a test tag"
#elif L==4 // es
""
"Renombrar un descriptor de test"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9707,9 +9728,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Receive configuration of test"
"Modify test configuration"
#elif L==4 // es
""
"Modificar configuraci&oacute;n de test"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9728,9 +9749,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Select range of dates to see my test results"
"Request to see my test results"
#elif L==4 // es
""
"Solicitar ver mis resultados de test"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9749,9 +9770,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Show my test results"
"See my test results"
#elif L==4 // es
""
"Ver mis resultados de test"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9770,9 +9791,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Select users and range of dates to see test results"
"See one of my test results"
#elif L==4 // es
""
"Ver uno de mis resultados de test"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9791,9 +9812,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Show test results of several users"
"Request test results of several users"
#elif L==4 // es
""
"Solicitar resultados de test de varios usuarios"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9812,9 +9833,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Show one test result of me as student"
"See test results of several users"
#elif L==4 // es
""
"Ver resultados de test de varios usuarios"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9833,9 +9854,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Show one test result of other user"
"See one test result of another user"
#elif L==4 // es
""
"Ver un resultado de test de otro usuario"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9854,9 +9875,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Show one game"
"See a game"
#elif L==4 // es
""
"Ver un juego"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9877,7 +9898,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==3 // en
"Request the removal of a match"
#elif L==4 // es
""
"Solicitar eliminaci&oacute;n de una partida"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9898,7 +9919,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==3 // en
"Confirm the removal of a match"
#elif L==4 // es
""
"Confirmar la eliminaci&oacute;n de una partida"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9917,9 +9938,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Put form to create a new match"
"Request the creation of a new match"
#elif L==4 // es
""
"Solicitar la creaci&oacute;n de una nueva partida"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9938,9 +9959,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Create a new match showing first question in a new browser tab"
"Create a new match show it in a new tab"
#elif L==4 // es
""
"Crear una nueva partida y mostrarla en una nueva pesta&ntilde;a"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9959,9 +9980,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Resume an unfinished match showing current question in a new browser tab"
"Resume a match showing current question in a new tab"
#elif L==4 // es
""
"Reanudar una partida mostrando la pregunta actual en una nueva pesta&ntilde;a"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -9982,7 +10003,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==3 // en
"Go back when playing a match"
#elif L==4 // es
""
"Ir atr&aacute;s mientras se juega una partida"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -10003,7 +10024,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==3 // en
"Play/pause current match"
#elif L==4 // es
""
"Jugar/pausar partida actual"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -10024,7 +10045,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==3 // en
"Go forward when playing a match"
#elif L==4 // es
""
"Ir adelante mientras se juega una partida"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -10045,7 +10066,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==3 // en
"Change number of columns when playing a match"
#elif L==4 // es
""
"Cambiar n&uacute;mero de columnas mientras se juega una partida"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -10066,7 +10087,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==3 // en
"Change visibility of question results when playing a match"
#elif L==4 // es
""
"Cambiar visibilidad de los resultados de una pregunta mientras se juega una partida"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -10087,7 +10108,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==3 // en
"Start match countdown"
#elif L==4 // es
""
"Comenzar la cuenta atr&aacute;s en una partida"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -10108,7 +10129,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==3 // en
"Refresh current question when playing a match (as teacher)"
#elif L==4 // es
""
"Refrescar pregunta actual mientras se juega una partida (como profesor)"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -10129,7 +10150,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==3 // en
"Show current question when playing a game (as student)"
#elif L==4 // es
""
"Refrescar pregunta actual mientras se juega una partida (como estudiante)"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -10148,9 +10169,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"View my answer to a match question (as student)"
"View my answer to a match question"
#elif L==4 // es
""
"Ver mi respuesta a una pregunta en una partida"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -10169,9 +10190,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Remove my answer to a match question (as student)"
"Remove my answer to a match question"
#elif L==4 // es
""
"Eliminar mi respuesta a una pregunta de una partida"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn
@ -10190,9 +10211,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
#elif L==2 // de
"" // Need Übersetzung
#elif L==3 // en
"Answer a match question (as student)"
"Answer a match question"
#elif L==4 // es
""
"Responder una pregunta de una partida"
#elif L==5 // fr
"" // Besoin de traduction
#elif L==6 // gn