Version18.126.1

This commit is contained in:
Antonio Cañas Vargas 2019-05-30 12:57:31 +02:00
parent a9903731f4
commit 03d23f968f
11 changed files with 325 additions and 281 deletions

View File

@ -613,14 +613,14 @@ CREATE TABLE IF NOT EXISTS games (
UNIQUE INDEX(GamCod), UNIQUE INDEX(GamCod),
INDEX(CrsCod)); INDEX(CrsCod));
-- --
-- Table gam_answers: stores the answers to the games -- Table gam_answers: stores the answers to the matches
-- --
CREATE TABLE IF NOT EXISTS gam_answers ( CREATE TABLE IF NOT EXISTS gam_answers (
GamCod INT NOT NULL, GamCod INT NOT NULL,
QstCod INT NOT NULL, QstInd INT NOT NULL,
AnsInd TINYINT NOT NULL, AnsInd TINYINT NOT NULL,
NumUsrs INT NOT NULL DEFAULT 0, NumUsrs INT NOT NULL DEFAULT 0,
UNIQUE INDEX(GamCod,QstCod,AnsInd)); UNIQUE INDEX(GamCod,QstInd,AnsInd));
-- --
-- Table gam_grp: stores the groups associated to each match in a game -- Table gam_grp: stores the groups associated to each match in a game
-- --

View File

@ -608,10 +608,11 @@ Assessment:
455. ActFrmNewMch Put form to create a new match (by a teacher) 455. ActFrmNewMch Put form to create a new match (by a teacher)
NEW. ActReqRemMch Request the removal of a match (by a teacher) NEW. ActReqRemMch Request the removal of a match (by a teacher)
NEW. ActRemMch Confirm the removal of a match (by a teacher) NEW. ActRemMch Confirm the removal of a match (by a teacher)
456. ActGamTch1stQst Show first question when playing a game (by a teacher) 456. ActNewMch Create a new match showing first question in a new browser tab (by a teacher)
NEW. ActResMch Resume an unfinished match showing current question in a new browser tab (by a teacher)
457. ActGamTchNxtQst Show next question when playing a game (by a teacher) 457. ActGamTchNxtQst Show next question when playing a game (by a teacher)
458. ActGamTchAns Show answers of current question when playing a game (by a teacher) 458. ActGamTchAns Show answers of current question when playing a game (by a teacher)
NEW. ActGamTchEnd End playing a game (by a teacher) NEW. ActEndMch Finish a match (by a teacher)
NEW. ActPlyMchStd Play a game (by a student) NEW. ActPlyMchStd Play a game (by a student)
NEW. ActGamStdCurQst Show current question when playing a game (by a student) NEW. ActGamStdCurQst Show current question when playing a game (by a student)
@ -2146,10 +2147,11 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
/* ActFrmNewMch */{1670,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RequestNewMatch ,NULL}, /* ActFrmNewMch */{1670,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RequestNewMatch ,NULL},
/* ActReqRemMch */{1783,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RequestRemoveMatch ,NULL}, /* ActReqRemMch */{1783,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RequestRemoveMatch ,NULL},
/* ActRemMch */{1784,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RemoveMatch ,NULL}, /* ActRemMch */{1784,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RemoveMatch ,NULL},
/* ActGamTch1stQst */{1671,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Gam_CreateAndStartNewMatch ,NULL}, /* ActNewMch */{1671,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Gam_CreateAndStartNewMatch ,NULL},
/* ActResMch */{1785,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Gam_ResumeUnfinishedMatch ,NULL},
/* ActGamTchNxtQst */{1672,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_MatchTchNextQuestion ,NULL}, /* ActGamTchNxtQst */{1672,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_MatchTchNextQuestion ,NULL},
/* ActGamTchAns */{1673,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_MatchTchShowAnswers ,NULL}, /* ActGamTchAns */{1673,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_MatchTchShowAnswers ,NULL},
/* ActGamTchEnd */{1781,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_MatchTchEnd ,NULL}, /* ActEndMch */{1781,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,NULL ,Gam_MatchTchEnd ,NULL},
/* ActPlyMchStd */{1779,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_PlayMatchStd ,NULL}, /* ActPlyMchStd */{1779,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_PlayMatchStd ,NULL},
/* ActGamStdCurQst */{1780,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,Gam_GetMatchBeingPlayed ,Gam_ShowNewMatchToMeAsStd ,NULL}, /* ActGamStdCurQst */{1780,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,Gam_GetMatchBeingPlayed ,Gam_ShowNewMatchToMeAsStd ,NULL},
@ -4876,7 +4878,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un
ActUp_GamQst, // #1668 ActUp_GamQst, // #1668
ActDwnGamQst, // #1669 ActDwnGamQst, // #1669
ActFrmNewMch, // #1670 ActFrmNewMch, // #1670
ActGamTch1stQst, // #1671 ActNewMch, // #1671
ActGamTchNxtQst, // #1672 ActGamTchNxtQst, // #1672
ActGamTchAns, // #1673 ActGamTchAns, // #1673
ActSeePrj, // #1674 ActSeePrj, // #1674
@ -4986,10 +4988,11 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un
ActUnlAllPrj, // #1778 ActUnlAllPrj, // #1778
ActPlyMchStd, // #1779 ActPlyMchStd, // #1779
ActGamStdCurQst, // #1780 ActGamStdCurQst, // #1780
ActGamTchEnd, // #1781 ActEndMch, // #1781
ActRefGamStd, // #1782 ActRefGamStd, // #1782
ActReqRemMch, // #1783 ActReqRemMch, // #1783
ActRemMch, // #1784 ActRemMch, // #1784
ActResMch, // #1785
}; };
/*****************************************************************************/ /*****************************************************************************/

View File

@ -64,9 +64,9 @@ typedef enum
typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action
#define Act_NUM_ACTIONS (1 + 4 + 64 + 38 + 12 + 42 + 36 + 19 + 110 + 169 + 437 + 176 + 169 + 16 + 67) #define Act_NUM_ACTIONS (1 + 4 + 64 + 38 + 12 + 42 + 36 + 19 + 110 + 170 + 437 + 176 + 169 + 16 + 67)
#define Act_MAX_ACTION_COD 1784 #define Act_MAX_ACTION_COD 1785
#define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13
@ -610,58 +610,59 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to
#define ActFrmNewMch (ActChgCrsTT1stDay + 117) #define ActFrmNewMch (ActChgCrsTT1stDay + 117)
#define ActReqRemMch (ActChgCrsTT1stDay + 118) #define ActReqRemMch (ActChgCrsTT1stDay + 118)
#define ActRemMch (ActChgCrsTT1stDay + 119) #define ActRemMch (ActChgCrsTT1stDay + 119)
#define ActGamTch1stQst (ActChgCrsTT1stDay + 120) #define ActNewMch (ActChgCrsTT1stDay + 120)
#define ActGamTchNxtQst (ActChgCrsTT1stDay + 121) #define ActResMch (ActChgCrsTT1stDay + 121)
#define ActGamTchAns (ActChgCrsTT1stDay + 122) #define ActGamTchNxtQst (ActChgCrsTT1stDay + 122)
#define ActGamTchEnd (ActChgCrsTT1stDay + 123) #define ActGamTchAns (ActChgCrsTT1stDay + 123)
#define ActPlyMchStd (ActChgCrsTT1stDay + 124) #define ActEndMch (ActChgCrsTT1stDay + 124)
#define ActGamStdCurQst (ActChgCrsTT1stDay + 125) #define ActPlyMchStd (ActChgCrsTT1stDay + 125)
#define ActRefGamStd (ActChgCrsTT1stDay + 126) #define ActGamStdCurQst (ActChgCrsTT1stDay + 126)
#define ActAnsGam (ActChgCrsTT1stDay + 127) #define ActRefGamStd (ActChgCrsTT1stDay + 127)
#define ActFrmNewGam (ActChgCrsTT1stDay + 128) #define ActAnsGam (ActChgCrsTT1stDay + 128)
#define ActEdiOneGam (ActChgCrsTT1stDay + 129) #define ActFrmNewGam (ActChgCrsTT1stDay + 129)
#define ActNewGam (ActChgCrsTT1stDay + 130) #define ActEdiOneGam (ActChgCrsTT1stDay + 130)
#define ActChgGam (ActChgCrsTT1stDay + 131) #define ActNewGam (ActChgCrsTT1stDay + 131)
#define ActReqRemGam (ActChgCrsTT1stDay + 132) #define ActChgGam (ActChgCrsTT1stDay + 132)
#define ActRemGam (ActChgCrsTT1stDay + 133) #define ActReqRemGam (ActChgCrsTT1stDay + 133)
#define ActReqRstGam (ActChgCrsTT1stDay + 134) #define ActRemGam (ActChgCrsTT1stDay + 134)
#define ActRstGam (ActChgCrsTT1stDay + 135) #define ActReqRstGam (ActChgCrsTT1stDay + 135)
#define ActHidGam (ActChgCrsTT1stDay + 136) #define ActRstGam (ActChgCrsTT1stDay + 136)
#define ActShoGam (ActChgCrsTT1stDay + 137) #define ActHidGam (ActChgCrsTT1stDay + 137)
#define ActAddOneGamQst (ActChgCrsTT1stDay + 138) #define ActShoGam (ActChgCrsTT1stDay + 138)
#define ActGamLstTstQst (ActChgCrsTT1stDay + 139) #define ActAddOneGamQst (ActChgCrsTT1stDay + 139)
#define ActAddTstQstToGam (ActChgCrsTT1stDay + 140) #define ActGamLstTstQst (ActChgCrsTT1stDay + 140)
#define ActReqRemGamQst (ActChgCrsTT1stDay + 141) #define ActAddTstQstToGam (ActChgCrsTT1stDay + 141)
#define ActRemGamQst (ActChgCrsTT1stDay + 142) #define ActReqRemGamQst (ActChgCrsTT1stDay + 142)
#define ActUp_GamQst (ActChgCrsTT1stDay + 143) #define ActRemGamQst (ActChgCrsTT1stDay + 143)
#define ActDwnGamQst (ActChgCrsTT1stDay + 144) #define ActUp_GamQst (ActChgCrsTT1stDay + 144)
#define ActDwnGamQst (ActChgCrsTT1stDay + 145)
#define ActSeeSvy (ActChgCrsTT1stDay + 145) #define ActSeeSvy (ActChgCrsTT1stDay + 146)
#define ActAnsSvy (ActChgCrsTT1stDay + 146) #define ActAnsSvy (ActChgCrsTT1stDay + 147)
#define ActFrmNewSvy (ActChgCrsTT1stDay + 147) #define ActFrmNewSvy (ActChgCrsTT1stDay + 148)
#define ActEdiOneSvy (ActChgCrsTT1stDay + 148) #define ActEdiOneSvy (ActChgCrsTT1stDay + 149)
#define ActNewSvy (ActChgCrsTT1stDay + 149) #define ActNewSvy (ActChgCrsTT1stDay + 150)
#define ActChgSvy (ActChgCrsTT1stDay + 150) #define ActChgSvy (ActChgCrsTT1stDay + 151)
#define ActReqRemSvy (ActChgCrsTT1stDay + 151) #define ActReqRemSvy (ActChgCrsTT1stDay + 152)
#define ActRemSvy (ActChgCrsTT1stDay + 152) #define ActRemSvy (ActChgCrsTT1stDay + 153)
#define ActReqRstSvy (ActChgCrsTT1stDay + 153) #define ActReqRstSvy (ActChgCrsTT1stDay + 154)
#define ActRstSvy (ActChgCrsTT1stDay + 154) #define ActRstSvy (ActChgCrsTT1stDay + 155)
#define ActHidSvy (ActChgCrsTT1stDay + 155) #define ActHidSvy (ActChgCrsTT1stDay + 156)
#define ActShoSvy (ActChgCrsTT1stDay + 156) #define ActShoSvy (ActChgCrsTT1stDay + 157)
#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 157) #define ActEdiOneSvyQst (ActChgCrsTT1stDay + 158)
#define ActRcvSvyQst (ActChgCrsTT1stDay + 158) #define ActRcvSvyQst (ActChgCrsTT1stDay + 159)
#define ActReqRemSvyQst (ActChgCrsTT1stDay + 159) #define ActReqRemSvyQst (ActChgCrsTT1stDay + 160)
#define ActRemSvyQst (ActChgCrsTT1stDay + 160) #define ActRemSvyQst (ActChgCrsTT1stDay + 161)
#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 161) #define ActSeeOneExaAnn (ActChgCrsTT1stDay + 162)
#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 162) #define ActSeeDatExaAnn (ActChgCrsTT1stDay + 163)
#define ActEdiExaAnn (ActChgCrsTT1stDay + 163) #define ActEdiExaAnn (ActChgCrsTT1stDay + 164)
#define ActRcvExaAnn (ActChgCrsTT1stDay + 164) #define ActRcvExaAnn (ActChgCrsTT1stDay + 165)
#define ActPrnExaAnn (ActChgCrsTT1stDay + 165) #define ActPrnExaAnn (ActChgCrsTT1stDay + 166)
#define ActReqRemExaAnn (ActChgCrsTT1stDay + 166) #define ActReqRemExaAnn (ActChgCrsTT1stDay + 167)
#define ActRemExaAnn (ActChgCrsTT1stDay + 167) #define ActRemExaAnn (ActChgCrsTT1stDay + 168)
#define ActHidExaAnn (ActChgCrsTT1stDay + 168) #define ActHidExaAnn (ActChgCrsTT1stDay + 169)
#define ActShoExaAnn (ActChgCrsTT1stDay + 169) #define ActShoExaAnn (ActChgCrsTT1stDay + 170)
/*****************************************************************************/ /*****************************************************************************/
/******************************** Files tab **********************************/ /******************************** Files tab **********************************/

View File

@ -432,6 +432,8 @@ Lo de mutear anuncios, en principio prefiero hacer una opci
// TODO: En Actividades, en Juegos, en Encuestas, en Asistencia poner filtros de Pasados (rojo), Actuales (verde), Futuros (azul). // TODO: En Actividades, en Juegos, en Encuestas, en Asistencia poner filtros de Pasados (rojo), Actuales (verde), Futuros (azul).
// Pensar si en Agenda se puede poner igual. // Pensar si en Agenda se puede poner igual.
// TODO: Cambiar QstInd al rango 1,2,3... (código especial 0 en lugar de -1) en swad_survey
/*****************************************************************************/ /*****************************************************************************/
/****************************** Public constants *****************************/ /****************************** Public constants *****************************/
/*****************************************************************************/ /*****************************************************************************/
@ -451,10 +453,31 @@ En OpenSWAD:
ps2pdf source.ps destination.pdf ps2pdf source.ps destination.pdf
*/ */
#define Log_PLATFORM_VERSION "SWAD 18.125 (2019-05-29)" #define Log_PLATFORM_VERSION "SWAD 18.126.1 (2019-05-29)"
#define CSS_FILE "swad18.123.css" #define CSS_FILE "swad18.123.css"
#define JS_FILE "swad18.123.js" #define JS_FILE "swad18.123.js"
/* /*
Version 18.126.1: May 30, 2019 New option to resume an unfinished match. (243415 lines)
11 changes necessary in database:
UPDATE actions SET Txt='Preparar partida (como profesor)' WHERE ActCod='1670' AND Language='es';
UPDATE actions SET Txt='Comenzar partida (como profesor)' WHERE ActCod='1671' AND Language='es';
UPDATE actions SET Txt='Mostrar siguiente pregunta en partida (como profesor)' WHERE ActCod='1672' AND Language='es';
UPDATE actions SET Txt='Mostrar respuestas de pregunta en partida (como profesor)' WHERE ActCod='1673' AND Language='es';
UPDATE actions SET Txt='Prepararse a jugar (como estudiante)' WHERE ActCod='1779' AND Language='es';
UPDATE actions SET Txt='Unirse a partida (como estudiante)' WHERE ActCod='1780' AND Language='es';
UPDATE actions SET Txt='Finalizar partida (como profesor)' WHERE ActCod='1781' AND Language='es';
INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1782','es','N','Refrescar partida (como estudiante)');
INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1783','es','N','Solicitar eliminar partida (como profesor)');
INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1784','es','N','Eliminar partida (como profesor)');
INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1785','es','N','Reanudar partida (como profesor)');
Version 18.126: May 30, 2019 Question index range changes from 0,1,2... to 1,2,3... (? lines)
2 changes necessary in database:
UPDATE gam_questions SET QstInd=QstInd+1;
UPDATE gam_matches SET QstInd=QstInd+1;
DROP TABLE gam_answers;
CREATE TABLE IF NOT EXISTS gam_answers (GamCod INT NOT NULL,QstInd INT NOT NULL,AnsInd TINYINT NOT NULL,NumUsrs INT NOT NULL DEFAULT 0,UNIQUE INDEX(GamCod,QstInd,AnsInd));
Version 18.125: May 29, 2019 Unification of tables of matches (saved and current) into one table. (243371 lines) Version 18.125: May 29, 2019 Unification of tables of matches (saved and current) into one table. (243371 lines)
2 changes necessary in database: 2 changes necessary in database:
DROP TABLE gam_matches; DROP TABLE gam_matches;

View File

@ -1341,18 +1341,18 @@ mysql> DESCRIBE gam_answers;
| Field | Type | Null | Key | Default | Extra | | Field | Type | Null | Key | Default | Extra |
+---------+------------+------+-----+---------+-------+ +---------+------------+------+-----+---------+-------+
| GamCod | int(11) | NO | PRI | NULL | | | GamCod | int(11) | NO | PRI | NULL | |
| QstCod | int(11) | NO | PRI | NULL | | | QstInd | int(11) | NO | PRI | NULL | |
| AnsInd | tinyint(4) | NO | PRI | NULL | | | AnsInd | tinyint(4) | NO | PRI | NULL | |
| NumUsrs | int(11) | NO | | 0 | | | NumUsrs | int(11) | NO | | 0 | |
+---------+------------+------+-----+---------+-------+ +---------+------------+------+-----+---------+-------+
4 rows in set (0,00 sec) 4 rows in set (0.00 sec)
*/ */
DB_CreateTable ("CREATE TABLE IF NOT EXISTS gam_answers (" DB_CreateTable ("CREATE TABLE IF NOT EXISTS gam_answers ("
"GamCod INT NOT NULL," "GamCod INT NOT NULL,"
"QstCod INT NOT NULL," "QstInd INT NOT NULL,"
"AnsInd TINYINT NOT NULL," "AnsInd TINYINT NOT NULL,"
"NumUsrs INT NOT NULL DEFAULT 0," "NumUsrs INT NOT NULL DEFAULT 0,"
"UNIQUE INDEX(GamCod,QstCod,AnsInd))"); "UNIQUE INDEX(GamCod,QstInd,AnsInd))");
/***** Table gam_grp *****/ /***** Table gam_grp *****/
/* /*

View File

@ -87,7 +87,7 @@ struct Match
char Title[Gam_MAX_BYTES_TITLE + 1]; char Title[Gam_MAX_BYTES_TITLE + 1];
struct struct
{ {
int QstInd; unsigned QstInd; // 0 means that the game has not started. First question has index 0.
long QstCod; long QstCod;
time_t QstStartTimeUTC; time_t QstStartTimeUTC;
bool ShowAnswers; bool ShowAnswers;
@ -100,8 +100,8 @@ struct Match
/*****************************************************************************/ /*****************************************************************************/
long Gam_CurrentGamCod = -1L; // Used as parameter in contextual links long Gam_CurrentGamCod = -1L; // Used as parameter in contextual links
long Gam_CurrentQstCod = -1L; // Used as parameter in contextual links
long Gam_CurrentMchCod = -1L; // Used as parameter in contextual links long Gam_CurrentMchCod = -1L; // Used as parameter in contextual links
unsigned Gam_CurrentQstInd = 0; // Used as parameter in contextual links
/*****************************************************************************/ /*****************************************************************************/
/***************************** Private prototypes ****************************/ /***************************** Private prototypes ****************************/
@ -139,17 +139,15 @@ static void Gam_GetAndWriteNamesOfGrpsAssociatedToMatch (struct Match *Match);
static bool Gam_CheckIfIPlayThisMatchBasedOnGrps (long GamCod); static bool Gam_CheckIfIPlayThisMatchBasedOnGrps (long GamCod);
static unsigned Gam_GetNumQstsGame (long GamCod); static unsigned Gam_GetNumQstsGame (long GamCod);
static void Gam_PutParamQstCod (long QstCod);
static long Gam_GetParamQstCod (void);
static void Gam_PutParamQstInd (unsigned QstInd); static void Gam_PutParamQstInd (unsigned QstInd);
static unsigned Gam_GetParamQstInd (void); static unsigned Gam_GetParamQstInd (void);
static void Gam_RemAnswersOfAQuestion (long QstCod); static unsigned Gam_GetQstIndFromStr (const char *UnsignedStr);
static void Gam_RemAnswersOfAQuestion (long GamCod,unsigned QstInd);
static int Gam_GetQstIndFromQstCod (long GamCod,long QstCod); // TODO: Remove this function because a question code can be repeated
static long Gam_GetQstCodFromQstInd (long GamCod,unsigned QstInd); static long Gam_GetQstCodFromQstInd (long GamCod,unsigned QstInd);
static int Gam_GetMaxQuestionIndexInGame (long GamCod); static unsigned Gam_GetMaxQuestionIndexInGame (long GamCod);
static int Gam_GetPrevQuestionIndexInGame (long GamCod,int QstInd); static unsigned Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd);
static int Gam_GetNextQuestionIndexInGame (long GamCod,int QstInd); static unsigned Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd);
static void Gam_ListGameQuestions (struct Game *Game); static void Gam_ListGameQuestions (struct Game *Game);
static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts, static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
MYSQL_RES *mysql_res); MYSQL_RES *mysql_res);
@ -160,7 +158,7 @@ static void Gam_AllocateListSelectedQuestions (void);
static void Gam_FreeListsSelectedQuestions (void); static void Gam_FreeListsSelectedQuestions (void);
static unsigned Gam_CountNumQuestionsInList (void); static unsigned Gam_CountNumQuestionsInList (void);
static unsigned Gam_GetNumUsrsWhoAnswered (long GamCod,long QstCod,unsigned AnsInd); static unsigned Gam_GetNumUsrsWhoAnswered (long GamCod,unsigned QstInd,unsigned AnsInd);
static void Gam_DrawBarNumUsrs (unsigned NumUsrs,unsigned MaxUsrs); static void Gam_DrawBarNumUsrs (unsigned NumUsrs,unsigned MaxUsrs);
static void Gam_PutParamsOneQst (void); static void Gam_PutParamsOneQst (void);
@ -188,7 +186,7 @@ static void Gam_PlayGameShowQuestionAndAnswers (long MchCod,
bool ShowAnswers); bool ShowAnswers);
static void Gam_PutBigButtonToContinue (Act_Action_t NextAction, static void Gam_PutBigButtonToContinue (Act_Action_t NextAction,
long MchCod,unsigned QstInd); long MchCod,unsigned QstInd);
static void Gam_PutBigButtonToEnd (long GamCod); static void Gam_PutBigButtonToFinishMatch (long GamCod);
static void Gam_ShowQuestionBeingPlayed (struct Match *Match); static void Gam_ShowQuestionBeingPlayed (struct Match *Match);
@ -1944,24 +1942,6 @@ void Gam_RequestNewQuestion (void)
false); // Do not put button to play false); // Do not put button to play
} }
/*****************************************************************************/
/****************** Write parameter with code of question ********************/
/*****************************************************************************/
static void Gam_PutParamQstCod (long QstCod)
{
Par_PutHiddenParamLong ("QstCod",QstCod);
}
/*****************************************************************************/
/******************* Get parameter with code of question *********************/
/*****************************************************************************/
static long Gam_GetParamQstCod (void)
{
return Par_GetParToLong ("QstCod");
}
/*****************************************************************************/ /*****************************************************************************/
/****************** Write parameter with index of question *******************/ /****************** Write parameter with index of question *******************/
/*****************************************************************************/ /*****************************************************************************/
@ -1977,55 +1957,39 @@ static void Gam_PutParamQstInd (unsigned QstInd)
static unsigned Gam_GetParamQstInd (void) static unsigned Gam_GetParamQstInd (void)
{ {
long LongInt; long LongNum;
LongInt = Par_GetParToLong ("QstInd"); LongNum = Par_GetParToLong ("QstInd");
if (LongInt < 0) if (LongNum < 0)
Lay_ShowErrorAndExit ("Wrong question index."); Lay_ShowErrorAndExit ("Wrong question index.");
return (unsigned) LongInt; return (unsigned) LongNum;
}
/*****************************************************************************/
/******************* Get parameter with index of question ********************/
/*****************************************************************************/
static unsigned Gam_GetQstIndFromStr (const char *UnsignedStr)
{
long LongNum;
LongNum = Str_ConvertStrCodToLongCod (UnsignedStr);
return (LongNum > 0) ? (unsigned) LongNum :
0;
} }
/*****************************************************************************/ /*****************************************************************************/
/********************** Remove answers of a game question ********************/ /********************** Remove answers of a game question ********************/
/*****************************************************************************/ /*****************************************************************************/
static void Gam_RemAnswersOfAQuestion (long QstCod) static void Gam_RemAnswersOfAQuestion (long GamCod,unsigned QstInd)
{ {
/***** Remove answers *****/ /***** Remove answers *****/
DB_QueryDELETE ("can not remove the answers of a question", DB_QueryDELETE ("can not remove the answers of a question",
"DELETE FROM gam_answers WHERE QstCod=%ld", "DELETE FROM gam_answers"
QstCod); " WHERE GamCod=%ld AND QstInd=%u",
} GamCod,QstInd);
/*****************************************************************************/
/******************** Get next question index in a game **********************/
/*****************************************************************************/
// TODO: Remove this function because a question code can be repeated
static int Gam_GetQstIndFromQstCod (long GamCod,long QstCod)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
int QstInd = -1;
/***** Get number of games with a field value from database *****/
if (!DB_QuerySELECT (&mysql_res,"can not get question index",
"SELECT QstInd FROM gam_questions"
" WHERE GamCod=%ld AND QstCod=%ld",
GamCod,QstCod))
Lay_ShowErrorAndExit ("Error when getting question index.");
/***** Get question index (row[0]) *****/
row = mysql_fetch_row (mysql_res);
if (row[0])
if (sscanf (row[0],"%d",&QstInd) != 1)
Lay_ShowErrorAndExit ("Error when getting question index.");
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return QstInd;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -2059,14 +2023,14 @@ static long Gam_GetQstCodFromQstInd (long GamCod,unsigned QstInd)
/*****************************************************************************/ /*****************************************************************************/
/****************** Get maximum question index in a game *********************/ /****************** Get maximum question index in a game *********************/
/*****************************************************************************/ /*****************************************************************************/
// Question index can be 0, 1, 2,... // Question index can be 1, 2, 3...
// Return -1 if no questions // Return 0 if no questions
static int Gam_GetMaxQuestionIndexInGame (long GamCod) static unsigned Gam_GetMaxQuestionIndexInGame (long GamCod)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
int QstInd = -1; unsigned QstInd = 0;
/***** Get maximum question index in a game from database *****/ /***** Get maximum question index in a game from database *****/
DB_QuerySELECT (&mysql_res,"can not get last question index", DB_QuerySELECT (&mysql_res,"can not get last question index",
@ -2074,7 +2038,7 @@ static int Gam_GetMaxQuestionIndexInGame (long GamCod)
GamCod); GamCod);
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
if (row[0]) // There are questions if (row[0]) // There are questions
if (sscanf (row[0],"%d",&QstInd) != 1) if (sscanf (row[0],"%u",&QstInd) != 1)
Lay_ShowErrorAndExit ("Error when getting last question index."); Lay_ShowErrorAndExit ("Error when getting last question index.");
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
@ -2086,28 +2050,28 @@ static int Gam_GetMaxQuestionIndexInGame (long GamCod)
/*****************************************************************************/ /*****************************************************************************/
/*********** Get previous question index to a given index in a game **********/ /*********** Get previous question index to a given index in a game **********/
/*****************************************************************************/ /*****************************************************************************/
// Question index can be 0, 1, 2,... // Question index can be 1, 2, 3...
// Return -1 if no previous question // Return 0 if no previous question
static int Gam_GetPrevQuestionIndexInGame (long GamCod,int QstInd) static unsigned Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
int PrevQstInd = -1; unsigned PrevQstInd = 0;
/***** Get previous question index in a game from database *****/ /***** Get previous question index in a game from database *****/
// Although indexes are always continuous... // Although indexes are always continuous...
// ...this implementation works even with non continuous indexes // ...this implementation works even with non continuous indexes
if (!DB_QuerySELECT (&mysql_res,"can not get previous question index", if (!DB_QuerySELECT (&mysql_res,"can not get previous question index",
"SELECT MAX(QstInd) FROM gam_questions" "SELECT MAX(QstInd) FROM gam_questions"
" WHERE GamCod=%ld AND QstInd<%d", " WHERE GamCod=%ld AND QstInd<%u",
GamCod,QstInd)) GamCod,QstInd))
Lay_ShowErrorAndExit ("Error: previous question index not found."); Lay_ShowErrorAndExit ("Error: previous question index not found.");
/***** Get previous question index (row[0]) *****/ /***** Get previous question index (row[0]) *****/
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
if (row[0]) if (row[0])
if (sscanf (row[0],"%d",&PrevQstInd) != 1) if (sscanf (row[0],"%u",&PrevQstInd) != 1)
Lay_ShowErrorAndExit ("Error when getting previous question index."); Lay_ShowErrorAndExit ("Error when getting previous question index.");
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
@ -2119,28 +2083,28 @@ static int Gam_GetPrevQuestionIndexInGame (long GamCod,int QstInd)
/*****************************************************************************/ /*****************************************************************************/
/************* Get next question index to a given index in a game ************/ /************* Get next question index to a given index in a game ************/
/*****************************************************************************/ /*****************************************************************************/
// Question index can be 0, 1, 2,... // Question index can be 1, 2, 3...
// Return -1 if no next question // Return 0 if no next question
static int Gam_GetNextQuestionIndexInGame (long GamCod,int QstInd) static unsigned Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
int NextQstInd = -1; unsigned NextQstInd = 0;
/***** Get next question index in a game from database *****/ /***** Get next question index in a game from database *****/
// Although indexes are always continuous... // Although indexes are always continuous...
// ...this implementation works even with non continuous indexes // ...this implementation works even with non continuous indexes
if (!DB_QuerySELECT (&mysql_res,"can not get next question index", if (!DB_QuerySELECT (&mysql_res,"can not get next question index",
"SELECT MIN(QstInd) FROM gam_questions" "SELECT MIN(QstInd) FROM gam_questions"
" WHERE GamCod=%ld AND QstInd>%d", " WHERE GamCod=%ld AND QstInd>%u",
GamCod,QstInd)) GamCod,QstInd))
Lay_ShowErrorAndExit ("Error: next question index not found."); Lay_ShowErrorAndExit ("Error: next question index not found.");
/***** Get next question index (row[0]) *****/ /***** Get next question index (row[0]) *****/
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
if (row[0]) if (row[0])
if (sscanf (row[0],"%d",&NextQstInd) != 1) if (sscanf (row[0],"%u",&NextQstInd) != 1)
Lay_ShowErrorAndExit ("Error when getting next question index."); Lay_ShowErrorAndExit ("Error when getting next question index.");
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
@ -2173,11 +2137,12 @@ static void Gam_ListGameQuestions (struct Game *Game)
/***** Get data of questions from database *****/ /***** Get data of questions from database *****/
NumQsts = (unsigned) DB_QuerySELECT (&mysql_res,"can not get data of a question", NumQsts = (unsigned) DB_QuerySELECT (&mysql_res,"can not get data of a question",
"SELECT tst_questions.QstCod," // row[0] "SELECT gam_questions.QstInd," // row[0]
"tst_questions.AnsType," // row[1] "gam_questions.QstCod," // row[1]
"tst_questions.Stem," // row[2] "tst_questions.AnsType," // row[2]
"tst_questions.Feedback," // row[3] "tst_questions.Stem," // row[3]
"tst_questions.MedCod" // row[4] "tst_questions.Feedback," // row[4]
"tst_questions.MedCod" // row[5]
" FROM gam_questions,tst_questions" " FROM gam_questions,tst_questions"
" WHERE gam_questions.GamCod=%ld" " WHERE gam_questions.GamCod=%ld"
" AND gam_questions.QstCod=tst_questions.QstCod" " AND gam_questions.QstCod=tst_questions.QstCod"
@ -2238,9 +2203,13 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES]; extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES];
unsigned NumQst; unsigned NumQst;
MYSQL_ROW row; MYSQL_ROW row;
unsigned UniqueId; unsigned QstInd;
unsigned MaxQstInd;
long QstCod; long QstCod;
char StrNumQst[10 + 1]; char StrQstInd[10 + 1];
/***** Get maximum question index *****/
MaxQstInd = Gam_GetMaxQuestionIndexInGame (GamCod);
/***** Write the heading *****/ /***** Write the heading *****/
Tbl_StartTableWideMargin (2); Tbl_StartTableWideMargin (2);
@ -2265,50 +2234,52 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
Txt_Question); Txt_Question);
/***** Write rows *****/ /***** Write rows *****/
for (NumQst = 0, UniqueId = 1; for (NumQst = 0;
NumQst < NumQsts; NumQst < NumQsts;
NumQst++, UniqueId++) NumQst++)
{ {
Gbl.RowEvenOdd = NumQst % 2; Gbl.RowEvenOdd = NumQst % 2;
snprintf (StrNumQst,sizeof (StrNumQst),
"%u",
NumQst + 1);
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
/* /*
row[0] QstCod row[0] QstInd
row[1] AnsType row[1] QstCod
row[2] Stem row[2] AnsType
row[3] Feedback row[3] Stem
row[4] MedCod row[4] Feedback
row[5] MedCod
*/ */
/***** Create test question *****/ /***** Create test question *****/
Tst_QstConstructor (); Tst_QstConstructor ();
/* row[0] holds the code of the question */ /* Get question index (row[0]) */
if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) <= 0) QstInd = Gam_GetQstIndFromStr (row[0]);
Lay_ShowErrorAndExit ("Wrong code of question."); snprintf (StrQstInd,sizeof (StrQstInd),
"%u",
QstInd);
/* Get question code (row[1]) */
QstCod = Str_ConvertStrCodToLongCod (row[1]);
/***** Icons *****/ /***** Icons *****/
Gam_CurrentGamCod = GamCod; Gam_CurrentGamCod = GamCod;
Gam_CurrentQstCod = QstCod; Gam_CurrentQstInd = QstInd;
fprintf (Gbl.F.Out,"<tr>" fprintf (Gbl.F.Out,"<tr>"
"<td class=\"BT%u\">",Gbl.RowEvenOdd); "<td class=\"BT%u\">",Gbl.RowEvenOdd);
/* Put icon to remove the question */ /* Put icon to remove the question */
Frm_StartForm (ActReqRemGamQst); Frm_StartForm (ActReqRemGamQst);
Gam_PutParamGameCod (GamCod); Gam_PutParamGameCod (GamCod);
Gam_PutParamQstCod (QstCod); Gam_PutParamQstInd (QstInd);
Ico_PutIconRemove (); Ico_PutIconRemove ();
Frm_EndForm (); Frm_EndForm ();
/* Put icon to move up the question */ /* Put icon to move up the question */
if (NumQst) if (QstInd > 1)
{ {
snprintf (Gbl.Title,sizeof (Gbl.Title), snprintf (Gbl.Title,sizeof (Gbl.Title),
Txt_Move_up_X, Txt_Move_up_X,
StrNumQst); StrQstInd);
Lay_PutContextualLinkOnlyIcon (ActUp_GamQst,NULL,Gam_PutParamsOneQst, Lay_PutContextualLinkOnlyIcon (ActUp_GamQst,NULL,Gam_PutParamsOneQst,
"arrow-up.svg", "arrow-up.svg",
Gbl.Title); Gbl.Title);
@ -2317,11 +2288,11 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
Ico_PutIconOff ("arrow-up.svg",Txt_Movement_not_allowed); Ico_PutIconOff ("arrow-up.svg",Txt_Movement_not_allowed);
/* Put icon to move down the question */ /* Put icon to move down the question */
if (NumQst + 1 < NumQsts) if (QstInd < MaxQstInd)
{ {
snprintf (Gbl.Title,sizeof (Gbl.Title), snprintf (Gbl.Title,sizeof (Gbl.Title),
Txt_Move_down_X, Txt_Move_down_X,
StrNumQst); StrQstInd);
Lay_PutContextualLinkOnlyIcon (ActDwnGamQst,NULL,Gam_PutParamsOneQst, Lay_PutContextualLinkOnlyIcon (ActDwnGamQst,NULL,Gam_PutParamsOneQst,
"arrow-down.svg", "arrow-down.svg",
Gbl.Title); Gbl.Title);
@ -2339,10 +2310,10 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
fprintf (Gbl.F.Out,"<td class=\"RIGHT_TOP COLOR%u\">" fprintf (Gbl.F.Out,"<td class=\"RIGHT_TOP COLOR%u\">"
"<div class=\"BIG_INDEX\">%s</div>", "<div class=\"BIG_INDEX\">%s</div>",
Gbl.RowEvenOdd, Gbl.RowEvenOdd,
StrNumQst); StrQstInd);
/* Write answer type (row[1]) */ /* Write answer type (row[2]) */
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]); Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[2]);
fprintf (Gbl.F.Out,"<div class=\"DAT_SMALL\">%s</div>" fprintf (Gbl.F.Out,"<div class=\"DAT_SMALL\">%s</div>"
"</td>", "</td>",
Txt_TST_STR_ANSWER_TYPES[Gbl.Test.AnswerType]); Txt_TST_STR_ANSWER_TYPES[Gbl.Test.AnswerType]);
@ -2359,13 +2330,13 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
Tst_GetAndWriteTagsQst (Gbl.Test.QstCod); Tst_GetAndWriteTagsQst (Gbl.Test.QstCod);
fprintf (Gbl.F.Out,"</td>"); fprintf (Gbl.F.Out,"</td>");
/* Write stem (row[2]) */ /* Write stem (row[3]) */
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP COLOR%u\">", fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP COLOR%u\">",
Gbl.RowEvenOdd); Gbl.RowEvenOdd);
Tst_WriteQstStem (row[2],"TEST_EDI"); Tst_WriteQstStem (row[3],"TEST_EDI");
/* Get media (row[4]) */ /* Get media (row[5]) */
Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[4]); Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[5]);
Med_GetMediaDataByCod (&Gbl.Test.Media); Med_GetMediaDataByCod (&Gbl.Test.Media);
/* Show media */ /* Show media */
@ -2373,11 +2344,11 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
"TEST_MED_EDIT_LIST_STEM_CONTAINER", "TEST_MED_EDIT_LIST_STEM_CONTAINER",
"TEST_MED_EDIT_LIST_STEM"); "TEST_MED_EDIT_LIST_STEM");
/* Show feedback (row[3]) */ /* Show feedback (row[4]) */
Tst_WriteQstFeedback (row[3],"TEST_EDI_LIGHT"); Tst_WriteQstFeedback (row[4],"TEST_EDI_LIGHT");
/* Show answers */ /* Show answers */
Tst_WriteAnswersGameResult (GamCod,NumQst,QstCod, Tst_WriteAnswersGameResult (GamCod,QstInd,QstCod,
"TEST_EDI",true); // Show result "TEST_EDI",true); // Show result
fprintf (Gbl.F.Out,"</td>" fprintf (Gbl.F.Out,"</td>"
@ -2435,7 +2406,7 @@ void Gam_AddTstQuestionsToGame (void)
const char *Ptr; const char *Ptr;
char LongStr[1 + 10 + 1]; char LongStr[1 + 10 + 1];
long QstCod; long QstCod;
int MaxQstInd; unsigned MaxQstInd;
/***** Get game code *****/ /***** Get game code *****/
if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L)
@ -2475,7 +2446,7 @@ void Gam_AddTstQuestionsToGame (void)
" (GamCod,QstCod,QstInd)" " (GamCod,QstCod,QstInd)"
" VALUES" " VALUES"
" (%ld,%ld,%u)", " (%ld,%ld,%u)",
Game.GamCod,QstCod,(unsigned) (MaxQstInd + 1)); Game.GamCod,QstCod,MaxQstInd + 1);
} }
/***** Free space for selected question codes *****/ /***** Free space for selected question codes *****/
@ -2543,12 +2514,12 @@ static unsigned Gam_CountNumQuestionsInList (void)
/*** Get number of users who selected this answer and draw proportional bar **/ /*** Get number of users who selected this answer and draw proportional bar **/
/*****************************************************************************/ /*****************************************************************************/
void Gam_GetAndDrawBarNumUsrsWhoAnswered (long GamCod,long QstCod,unsigned AnsInd,unsigned NumUsrs) void Gam_GetAndDrawBarNumUsrsWhoAnswered (long GamCod,unsigned QstInd,unsigned AnsInd,unsigned NumUsrs)
{ {
unsigned NumUsrsThisAnswer; unsigned NumUsrsThisAnswer;
/***** Get number of users who selected this answer *****/ /***** Get number of users who selected this answer *****/
NumUsrsThisAnswer = Gam_GetNumUsrsWhoAnswered (GamCod,QstCod,AnsInd); NumUsrsThisAnswer = Gam_GetNumUsrsWhoAnswered (GamCod,QstInd,AnsInd);
/***** Show stats of this answer *****/ /***** Show stats of this answer *****/
Gam_DrawBarNumUsrs (NumUsrsThisAnswer,NumUsrs); Gam_DrawBarNumUsrs (NumUsrsThisAnswer,NumUsrs);
@ -2558,7 +2529,7 @@ void Gam_GetAndDrawBarNumUsrsWhoAnswered (long GamCod,long QstCod,unsigned AnsIn
/**** Get number of users who selected a given answer of a game question *****/ /**** Get number of users who selected a given answer of a game question *****/
/*****************************************************************************/ /*****************************************************************************/
static unsigned Gam_GetNumUsrsWhoAnswered (long GamCod,long QstCod,unsigned AnsInd) static unsigned Gam_GetNumUsrsWhoAnswered (long GamCod,unsigned QstInd,unsigned AnsInd)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
@ -2567,8 +2538,8 @@ static unsigned Gam_GetNumUsrsWhoAnswered (long GamCod,long QstCod,unsigned AnsI
/***** Get answers of a question from database *****/ /***** Get answers of a question from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get number of users who answered", if (DB_QuerySELECT (&mysql_res,"can not get number of users who answered",
"SELECT NumUsrs FROM gam_answers" "SELECT NumUsrs FROM gam_answers"
" WHERE GamCod=%ld AND QstCod=%ld AND AnsInd=%u", " WHERE GamCod=%ld AND QstInd=%u AND AnsInd=%u",
GamCod,QstCod,AnsInd)) GamCod,QstInd,AnsInd))
{ {
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
if (row[0]) // There are users who selected this answer if (row[0]) // There are users who selected this answer
@ -2629,7 +2600,7 @@ static void Gam_DrawBarNumUsrs (unsigned NumUsrs,unsigned MaxUsrs)
static void Gam_PutParamsOneQst (void) static void Gam_PutParamsOneQst (void)
{ {
Gam_PutParamGameCod (Gam_CurrentGamCod); Gam_PutParamGameCod (Gam_CurrentGamCod);
Gam_PutParamQstCod (Gam_CurrentQstCod); Gam_PutParamQstInd (Gam_CurrentQstInd);
} }
/*****************************************************************************/ /*****************************************************************************/
@ -2641,7 +2612,6 @@ void Gam_RequestRemoveQst (void)
extern const char *Txt_Do_you_really_want_to_remove_the_question_X; extern const char *Txt_Do_you_really_want_to_remove_the_question_X;
extern const char *Txt_Remove_question; extern const char *Txt_Remove_question;
struct Game Game; struct Game Game;
long QstCod;
unsigned QstInd; unsigned QstInd;
/***** Get parameters *****/ /***** Get parameters *****/
@ -2649,20 +2619,16 @@ void Gam_RequestRemoveQst (void)
if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of game is missing."); Lay_ShowErrorAndExit ("Code of game is missing.");
/* Get question code */
if ((QstCod = Gam_GetParamQstCod ()) <= 0)
Lay_ShowErrorAndExit ("Wrong code of question.");
/* Get question index */ /* Get question index */
QstInd = (unsigned) Gam_GetQstIndFromQstCod (Game.GamCod,QstCod); // TODO: Remove this function because a question code can be repeated QstInd = Gam_GetParamQstInd ();
/***** Show question and button to remove question *****/ /***** Show question and button to remove question *****/
Gam_CurrentGamCod = Game.GamCod; Gam_CurrentGamCod = Game.GamCod;
Gam_CurrentQstCod = QstCod; Gam_CurrentQstInd = QstInd;
Ale_ShowAlertAndButton (ActRemGamQst,NULL,NULL,Gam_PutParamsOneQst, Ale_ShowAlertAndButton (ActRemGamQst,NULL,NULL,Gam_PutParamsOneQst,
Btn_REMOVE_BUTTON,Txt_Remove_question, Btn_REMOVE_BUTTON,Txt_Remove_question,
Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_question_X, Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_question_X,
(unsigned long) (QstInd + 1)); QstInd);
/***** Show current game *****/ /***** Show current game *****/
Gam_ShowOneGame (Game.GamCod, Gam_ShowOneGame (Game.GamCod,
@ -2680,7 +2646,6 @@ void Gam_RemoveQst (void)
{ {
extern const char *Txt_Question_removed; extern const char *Txt_Question_removed;
struct Game Game; struct Game Game;
long QstCod;
unsigned QstInd; unsigned QstInd;
/***** Get parameters *****/ /***** Get parameters *****/
@ -2688,25 +2653,26 @@ void Gam_RemoveQst (void)
if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of game is missing."); Lay_ShowErrorAndExit ("Code of game is missing.");
/* Get question code */
if ((QstCod = Gam_GetParamQstCod ()) <= 0)
Lay_ShowErrorAndExit ("Wrong code of question.");
/* Get question index */ /* Get question index */
QstInd = (unsigned) Gam_GetQstIndFromQstCod (Game.GamCod,QstCod); // TODO: Remove this function because a question code can be repeated QstInd = Gam_GetParamQstInd ();
/***** Remove the question from all the tables *****/ /***** Remove the question from all the tables *****/
/* Remove answers from this test question */ /* Remove answers from this test question */
Gam_RemAnswersOfAQuestion (QstCod); Gam_RemAnswersOfAQuestion (Game.GamCod,QstInd);
/* Remove the question itself */ /* Remove the question itself */
DB_QueryDELETE ("can not remove a question", DB_QueryDELETE ("can not remove a question",
"DELETE FROM gam_questions WHERE QstCod=%ld", "DELETE FROM gam_questions"
QstCod); " WHERE GamCod=%ld AND QstInd=%u",
Game.GamCod,QstInd);
if (!mysql_affected_rows (&Gbl.mysql)) if (!mysql_affected_rows (&Gbl.mysql))
Lay_ShowErrorAndExit ("The question to be removed does not exist."); Lay_ShowErrorAndExit ("The question to be removed does not exist.");
/* Change index of questions greater than this */ /* Change index of questions greater than this */
DB_QueryUPDATE ("can not update indexes of questions in table of answers",
"UPDATE gam_answers SET QstInd=QstInd-1"
" WHERE GamCod=%ld AND QstInd>%u",
Game.GamCod,QstInd);
DB_QueryUPDATE ("can not update indexes of questions", DB_QueryUPDATE ("can not update indexes of questions",
"UPDATE gam_questions SET QstInd=QstInd-1" "UPDATE gam_questions SET QstInd=QstInd-1"
" WHERE GamCod=%ld AND QstInd>%u", " WHERE GamCod=%ld AND QstInd>%u",
@ -2730,38 +2696,35 @@ void Gam_RemoveQst (void)
void Gam_MoveUpQst (void) void Gam_MoveUpQst (void)
{ {
extern const char *Txt_The_question_has_been_moved_up; extern const char *Txt_The_question_has_been_moved_up;
extern const char *Txt_Movement_not_allowed;
struct Game Game; struct Game Game;
long QstCod; unsigned QstIndTop;
int QstIndTop; unsigned QstIndBottom;
int QstIndBottom;
/***** Get parameters *****/ /***** Get parameters *****/
/* Get game code */ /* Get game code */
if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of game is missing."); Lay_ShowErrorAndExit ("Code of game is missing.");
/* Get question code */
if ((QstCod = Gam_GetParamQstCod ()) <= 0)
Lay_ShowErrorAndExit ("Wrong code of question.");
/* Get question index */ /* Get question index */
QstIndBottom = Gam_GetQstIndFromQstCod (Game.GamCod,QstCod); // TODO: Remove this function because a question code can be repeated QstIndBottom = Gam_GetParamQstInd ();
/***** Move up question *****/ /***** Move up question *****/
if (QstIndBottom > 0) if (QstIndBottom > 1)
{ {
/* Indexes of questions to be exchanged */ /* Indexes of questions to be exchanged */
QstIndTop = Gam_GetPrevQuestionIndexInGame (Game.GamCod,QstIndBottom); QstIndTop = Gam_GetPrevQuestionIndexInGame (Game.GamCod,QstIndBottom);
if (QstIndTop < 0) if (!QstIndTop)
Lay_ShowErrorAndExit ("Wrong index of question."); Lay_ShowErrorAndExit ("Wrong index of question.");
/* Exchange questions */ /* Exchange questions */
Gam_ExchangeQuestions (Game.GamCod, Gam_ExchangeQuestions (Game.GamCod,QstIndTop,QstIndBottom);
(unsigned) QstIndTop,(unsigned) QstIndBottom);
/* Success alert */ /* Success alert */
Ale_ShowAlert (Ale_SUCCESS,Txt_The_question_has_been_moved_up); Ale_ShowAlert (Ale_SUCCESS,Txt_The_question_has_been_moved_up);
} }
else
Ale_ShowAlert (Ale_WARNING,Txt_Movement_not_allowed);
/***** Show current game *****/ /***** Show current game *****/
Gam_ShowOneGame (Game.GamCod, Gam_ShowOneGame (Game.GamCod,
@ -2778,43 +2741,45 @@ void Gam_MoveUpQst (void)
void Gam_MoveDownQst (void) void Gam_MoveDownQst (void)
{ {
extern const char *Txt_The_question_has_been_moved_down; extern const char *Txt_The_question_has_been_moved_down;
extern const char *Txt_Movement_not_allowed;
extern const char *Txt_This_game_has_no_questions;
struct Game Game; struct Game Game;
long QstCod; unsigned QstIndTop;
int QstIndTop; unsigned QstIndBottom;
int QstIndBottom; unsigned MaxQstInd; // 0 if no questions
int MaxQstInd; // -1 if no questions
/***** Get parameters *****/ /***** Get parameters *****/
/* Get game code */ /* Get game code */
if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of game is missing."); Lay_ShowErrorAndExit ("Code of game is missing.");
/* Get question code */
if ((QstCod = Gam_GetParamQstCod ()) <= 0)
Lay_ShowErrorAndExit ("Wrong code of question.");
/* Get question index */ /* Get question index */
QstIndTop = Gam_GetQstIndFromQstCod (Game.GamCod,QstCod); // TODO: Remove this function because a question code can be repeated QstIndTop = Gam_GetParamQstInd ();
/* Get maximum question index */ /* Get maximum question index */
MaxQstInd = Gam_GetMaxQuestionIndexInGame (Game.GamCod); MaxQstInd = Gam_GetMaxQuestionIndexInGame (Game.GamCod);
/***** Move down question *****/ /***** Move down question *****/
if (MaxQstInd > 0) if (MaxQstInd)
{
if (QstIndTop < MaxQstInd) if (QstIndTop < MaxQstInd)
{ {
/* Indexes of questions to be exchanged */ /* Indexes of questions to be exchanged */
QstIndBottom = Gam_GetNextQuestionIndexInGame (Game.GamCod,QstIndTop); QstIndBottom = Gam_GetNextQuestionIndexInGame (Game.GamCod,QstIndTop);
if (QstIndBottom < 0) if (!QstIndBottom)
Lay_ShowErrorAndExit ("Wrong index of question."); Lay_ShowErrorAndExit ("Wrong index of question.");
/* Exchange questions */ /* Exchange questions */
Gam_ExchangeQuestions (Game.GamCod, Gam_ExchangeQuestions (Game.GamCod,QstIndTop,QstIndBottom);
(unsigned) QstIndTop,(unsigned) QstIndBottom);
/* Success alert */ /* Success alert */
Ale_ShowAlert (Ale_SUCCESS,Txt_The_question_has_been_moved_down); Ale_ShowAlert (Ale_SUCCESS,Txt_The_question_has_been_moved_down);
} }
else
Ale_ShowAlert (Ale_WARNING,Txt_Movement_not_allowed);
}
else
Ale_ShowAlert (Ale_WARNING,Txt_This_game_has_no_questions);
/***** Show current game *****/ /***** Show current game *****/
Gam_ShowOneGame (Game.GamCod, Gam_ShowOneGame (Game.GamCod,
@ -2846,14 +2811,14 @@ static void Gam_ExchangeQuestions (long GamCod,
/***** Exchange indexes of questions *****/ /***** Exchange indexes of questions *****/
/* /*
Example: Example:
QstIndTop = 0; QstCodTop = 218 QstIndTop = 1; QstCodTop = 218
QstIndBottom = 1; QstCodBottom = 220 QstIndBottom = 2; QstCodBottom = 220
+--------+--------+ +--------+--------+ +--------+--------+ +--------+--------+ +--------+--------+ +--------+--------+
| QstInd | QstCod | | QstInd | QstCod | | QstInd | QstCod | | QstInd | QstCod | | QstInd | QstCod | | QstInd | QstCod |
+--------+--------+ +--------+--------+ +--------+--------+ +--------+--------+ +--------+--------+ +--------+--------+
| 0 | 218 | -----> | 1 | 218 | = | 0 | 220 | | 1 | 218 | -----> | 2 | 218 | = | 1 | 220 |
| 1 | 220 | | 0 | 220 | | 1 | 218 | | 2 | 220 | | 1 | 220 | | 2 | 218 |
| 2 | 232 | | 2 | 232 | | 2 | 232 | | 3 | 232 | | 3 | 232 | | 3 | 232 |
+--------+--------+ +--------+--------+ +--------+--------+ +--------+--------+ +--------+--------+ +--------+--------+
*/ */
DB_QueryUPDATE ("can not exchange indexes of questions", DB_QueryUPDATE ("can not exchange indexes of questions",
@ -2996,7 +2961,7 @@ void Gam_GetDataOfMatchByCod (struct Match *Match)
Match->TimeUTC[Gam_START_TIME] = Match->TimeUTC[Gam_START_TIME] =
Match->TimeUTC[Gam_END_TIME ] = (time_t) 0; Match->TimeUTC[Gam_END_TIME ] = (time_t) 0;
Match->Title[0] = '\0'; Match->Title[0] = '\0';
Match->Status.QstInd = -1; Match->Status.QstInd = 0;
Match->Status.QstCod = -1L; Match->Status.QstCod = -1L;
Match->Status.QstStartTimeUTC = (time_t) 0; Match->Status.QstStartTimeUTC = (time_t) 0;
Match->Status.ShowAnswers = false; Match->Status.ShowAnswers = false;
@ -3031,7 +2996,7 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches,
extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS]; extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME]; extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME];
extern const char *Txt_Match; extern const char *Txt_Match;
extern const char *Txt_Continue; extern const char *Txt_Resume;
extern const char *Txt_Today; extern const char *Txt_Today;
unsigned NumMatch; unsigned NumMatch;
unsigned UniqueId; unsigned UniqueId;
@ -3083,14 +3048,14 @@ static void Gam_ListOneOrMoreMatchesForEdition (unsigned NumMatches,
Ico_PutIconRemove (); Ico_PutIconRemove ();
Frm_EndForm (); Frm_EndForm ();
/* Put icon to continue playing the match */ /* Put icon to continue playing an unfinished match */
if (!Match.Status.Finished) if (!Match.Status.Finished)
{ {
Gam_CurrentMchCod = Match.MchCod; Gam_CurrentMchCod = Match.MchCod;
Lay_PutContextualLinkOnlyIcon (ActGamTchNxtQst,NULL, // TODO: Continue on a new tab!!!! Lay_PutContextualLinkOnlyIcon (ActResMch,NULL,
Gam_PutParamCurrentMchCod, Gam_PutParamCurrentMchCod,
"play.svg", "play.svg",
Txt_Continue); Txt_Resume);
} }
fprintf (Gbl.F.Out,"</td>"); fprintf (Gbl.F.Out,"</td>");
@ -3211,7 +3176,7 @@ static void Gam_GetMatchDataFromRow (MYSQL_RES *mysql_res,
row[10] Finished row[10] Finished
*/ */
/* Current question index (row[6]) */ /* Current question index (row[6]) */
Match->Status.QstInd = (int) Str_ConvertStrCodToLongCod (row[6]); Match->Status.QstInd = Gam_GetQstIndFromStr (row[6]);
/* Current question code (row[7]) */ /* Current question code (row[7]) */
Match->Status.QstCod = Str_ConvertStrCodToLongCod (row[7]); Match->Status.QstCod = Str_ConvertStrCodToLongCod (row[7]);
@ -3395,7 +3360,7 @@ static void Gam_PutBigButtonToPlayMatchTch (struct Game *Game)
Lay_StartSection (Gam_NEW_MATCH_SECTION_ID); Lay_StartSection (Gam_NEW_MATCH_SECTION_ID);
/***** Start form *****/ /***** Start form *****/
Frm_StartForm (ActGamTch1stQst); Frm_StartForm (ActNewMch);
Gam_PutParamGameCod (Game->GamCod); Gam_PutParamGameCod (Game->GamCod);
Gam_PutParamQstInd (0); // Start by first question in game Gam_PutParamQstInd (0); // Start by first question in game
@ -3513,7 +3478,7 @@ static long Gam_CreateMatch (struct Match *Match)
"QstInd,QstCod,QstStartTime,ShowingAnswers,Finished)" "QstInd,QstCod,QstStartTime,ShowingAnswers,Finished)"
" VALUES" " VALUES"
" (%ld,%ld,NOW(),NOW(),'%s'," " (%ld,%ld,NOW(),NOW(),'%s',"
"-1,-1,FROM_UNIXTIME(0),'N','N')", "0,-1,FROM_UNIXTIME(0),'N','N')",
Match->GamCod, Match->GamCod,
Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Me.UsrDat.UsrCod,
Match->Title); Match->Title);
@ -3525,6 +3490,37 @@ static long Gam_CreateMatch (struct Match *Match)
return MchCod; return MchCod;
} }
/*****************************************************************************/
/**** Resume an unfinished match and show current question (by a teacher) ****/
/*****************************************************************************/
void Gam_ResumeUnfinishedMatch (void)
{
struct Match Match;
/***** Get parameters *****/
/* Get match code */
if ((Match.MchCod = Gam_GetParamMatchCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of match is missing.");
/***** Get data of the match from database *****/
Gam_GetDataOfMatchByCod (&Match);
if (Match.Status.Finished)
{
/***** Show alert *****/
Ale_ShowAlert (Ale_WARNING,"Partida finalizada."); // TODO: Need translation!!!!!
/***** Button to close browser tab *****/
Btn_PutCloseButton ("Cerrar"); // TODO: Need translation!!!!!
}
else // Unfinished match
/***** Show questions and possible answers *****/
Gam_PlayGameShowQuestionAndAnswers (Match.MchCod,
Match.Status.QstInd, // Resume last question index shown
Match.Status.ShowAnswers); // Show answers?
}
/*****************************************************************************/ /*****************************************************************************/
/***************** Insert/update a game match being played *******************/ /***************** Insert/update a game match being played *******************/
/*****************************************************************************/ /*****************************************************************************/
@ -3546,7 +3542,7 @@ static void Gam_UpdateMatchBeingPlayed (long MchCod,unsigned QstInd,long QstCod,
DB_QueryUPDATE ("can not update match being played", DB_QueryUPDATE ("can not update match being played",
"UPDATE gam_matches,games" "UPDATE gam_matches,games"
" SET gam_matches.EndTime=NOW()," " SET gam_matches.EndTime=NOW(),"
"gam_matches.QstInd=%d," "gam_matches.QstInd=%u,"
"gam_matches.QstCod=%ld," "gam_matches.QstCod=%ld,"
"gam_matches.ShowingAnswers='N'," "gam_matches.ShowingAnswers='N',"
"gam_matches.QstStartTime=NOW()" "gam_matches.QstStartTime=NOW()"
@ -3611,7 +3607,7 @@ static void Gam_PlayGameShowQuestionAndAnswers (long MchCod,
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
int NxtQstInd; unsigned NxtQstInd;
long QstCod; long QstCod;
struct Match Match; struct Match Match;
@ -3638,8 +3634,7 @@ static void Gam_PlayGameShowQuestionAndAnswers (long MchCod,
fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_CONTAINER\">"); fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_CONTAINER\">");
/* Write number of question */ /* Write number of question */
fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_NUM_QST\">%u</div>", fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_NUM_QST\">%u</div>",QstInd);
QstInd + 1);
fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_QST_CONTAINER\">"); fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_TCH_QST_CONTAINER\">");
@ -3678,12 +3673,12 @@ static void Gam_PlayGameShowQuestionAndAnswers (long MchCod,
{ {
/* Get index of the next question */ /* Get index of the next question */
NxtQstInd = Gam_GetNextQuestionIndexInGame (Match.GamCod,Match.Status.QstInd); NxtQstInd = Gam_GetNextQuestionIndexInGame (Match.GamCod,Match.Status.QstInd);
if (NxtQstInd >= 0) // Not last question if (NxtQstInd) // Not last question
/* Put button to show next question */ /* Put button to show next question */
Gam_PutBigButtonToContinue (ActGamTchNxtQst,Match.MchCod,(unsigned) NxtQstInd); Gam_PutBigButtonToContinue (ActGamTchNxtQst,Match.MchCod,(unsigned) NxtQstInd);
else // Last question else // Last question
/* Put button to end */ /* Put button to end */
Gam_PutBigButtonToEnd (Match.MchCod); Gam_PutBigButtonToFinishMatch (Match.MchCod);
} }
else else
/* Put button to show answers */ /* Put button to show answers */
@ -3733,10 +3728,10 @@ static void Gam_PutBigButtonToContinue (Act_Action_t NextAction,
} }
/*****************************************************************************/ /*****************************************************************************/
/********************* Put a big button to end a match ***********************/ /******************** Put a big button to finish a match *********************/
/*****************************************************************************/ /*****************************************************************************/
static void Gam_PutBigButtonToEnd (long MchCod) static void Gam_PutBigButtonToFinishMatch (long MchCod)
{ {
extern const char *Txt_Finish; extern const char *Txt_Finish;
@ -3744,7 +3739,7 @@ static void Gam_PutBigButtonToEnd (long MchCod)
fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_CONTINUE_CONTAINER\">"); fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_CONTINUE_CONTAINER\">");
/***** Start form *****/ /***** Start form *****/
Frm_StartForm (ActGamTchEnd); Frm_StartForm (ActEndMch);
Gam_PutParamMatchCod (MchCod); Gam_PutParamMatchCod (MchCod);
/***** Put icon with link *****/ /***** Put icon with link *****/
@ -3864,7 +3859,7 @@ static void Gam_ShowQuestionBeingPlayed (struct Match *Match)
/***** Show question *****/ /***** Show question *****/
/* Write number of question */ /* Write number of question */
fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_STD_NUM_QST\">%u</div>", fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_STD_NUM_QST\">%u</div>",
Match->Status.QstInd + 1); Match->Status.QstInd);
fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_STD_QST_CONTAINER\">"); fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_STD_QST_CONTAINER\">");

View File

@ -109,7 +109,7 @@ void Gam_RemoveGames (Hie_Level_t Scope,long Cod);
void Gam_RequestNewQuestion (void); void Gam_RequestNewQuestion (void);
void Gam_GetAndDrawBarNumUsrsWhoAnswered (long GamCod,long QstCod,unsigned AnsInd,unsigned NumUsrs); void Gam_GetAndDrawBarNumUsrsWhoAnswered (long GamCod,unsigned QstInd,unsigned AnsInd,unsigned NumUsrs);
void Gam_AddTstQuestionsToGame (void); void Gam_AddTstQuestionsToGame (void);
@ -127,6 +127,7 @@ void Gam_PlayMatchStd (void);
void Gam_ReceiveGameAnswers (void); void Gam_ReceiveGameAnswers (void);
void Gam_CreateAndStartNewMatch (void); void Gam_CreateAndStartNewMatch (void);
void Gam_ResumeUnfinishedMatch (void);
void Gam_MatchTchNextQuestion (void); void Gam_MatchTchNextQuestion (void);
void Gam_MatchTchShowAnswers (void); void Gam_MatchTchShowAnswers (void);
void Gam_MatchTchEnd (void); void Gam_MatchTchEnd (void);

View File

@ -3530,12 +3530,12 @@ void Svy_RequestRemoveQst (void)
SvyQst.QstInd = Svy_GetQstIndFromQstCod (SvyQst.QstCod); SvyQst.QstInd = Svy_GetQstIndFromQstCod (SvyQst.QstCod);
/***** Show question and button to remove question *****/ /***** Show question and button to remove question *****/
Svy_CurrentSvyCod = SvyCod; Svy_CurrentSvyCod = SvyCod;
Svy_CurrentQstCod = SvyQst.QstCod; Svy_CurrentQstCod = SvyQst.QstCod;
Ale_ShowAlertAndButton (ActRemSvyQst,NULL,NULL,Svy_PutParamsRemoveOneQst, Ale_ShowAlertAndButton (ActRemSvyQst,NULL,NULL,Svy_PutParamsRemoveOneQst,
Btn_REMOVE_BUTTON,Txt_Remove_question, Btn_REMOVE_BUTTON,Txt_Remove_question,
Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_question_X, Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_question_X,
(unsigned long) (SvyQst.QstInd + 1)); (long) SvyQst.QstInd + 1);
/***** Show current survey *****/ /***** Show current survey *****/
Svy_ShowOneSurvey (SvyCod,&SvyQst,true); Svy_ShowOneSurvey (SvyCod,&SvyQst,true);

View File

@ -209,7 +209,7 @@ static void Tst_WriteChoiceAnsViewTest (unsigned NumQst,long QstCod,bool Shuffle
static void Tst_WriteChoiceAnsAssessTest (struct UsrData *UsrDat, static void Tst_WriteChoiceAnsAssessTest (struct UsrData *UsrDat,
unsigned NumQst,MYSQL_RES *mysql_res, unsigned NumQst,MYSQL_RES *mysql_res,
double *ScoreThisQst,bool *AnswerIsNotBlank); double *ScoreThisQst,bool *AnswerIsNotBlank);
static void Tst_WriteChoiceAnsViewGame (long GamCod,unsigned NumQst,long QstCod, static void Tst_WriteChoiceAnsViewGame (long GamCod,unsigned QstInd,long QstCod,
const char *Class, const char *Class,
bool ShowResult); bool ShowResult);
@ -3525,12 +3525,12 @@ static void Tst_WriteAnswersTestResult (struct UsrData *UsrDat,
/************** Write answers of a question when viewing a game **************/ /************** Write answers of a question when viewing a game **************/
/*****************************************************************************/ /*****************************************************************************/
void Tst_WriteAnswersGameResult (long GamCod,unsigned NumQst,long QstCod, void Tst_WriteAnswersGameResult (long GamCod,unsigned QstInd,long QstCod,
const char *Class,bool ShowResult) const char *Class,bool ShowResult)
{ {
/***** Write answer depending on type *****/ /***** Write answer depending on type *****/
if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE) if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE)
Tst_WriteChoiceAnsViewGame (GamCod,NumQst,QstCod, Tst_WriteChoiceAnsViewGame (GamCod,QstInd,QstCod,
Class,ShowResult); Class,ShowResult);
else else
Ale_ShowAlert (Ale_ERROR,"Type of answer not valid in a game."); Ale_ShowAlert (Ale_ERROR,"Type of answer not valid in a game.");
@ -4044,7 +4044,7 @@ static void Tst_WriteChoiceAnsAssessTest (struct UsrData *UsrDat,
/******** Write single or multiple choice answer when viewing a test *********/ /******** Write single or multiple choice answer when viewing a test *********/
/*****************************************************************************/ /*****************************************************************************/
static void Tst_WriteChoiceAnsViewGame (long GamCod,unsigned NumQst,long QstCod, static void Tst_WriteChoiceAnsViewGame (long GamCod,unsigned QstInd,long QstCod,
const char *Class, const char *Class,
bool ShowResult) bool ShowResult)
{ {
@ -4125,7 +4125,7 @@ static void Tst_WriteChoiceAnsViewGame (long GamCod,unsigned NumQst,long QstCod,
"<label for=\"Ans%06u_%u\" class=\"%s\">" "<label for=\"Ans%06u_%u\" class=\"%s\">"
"%s" "%s"
"</label>", "</label>",
NumQst,NumOpt, QstInd,NumOpt,
Class, Class,
Gbl.Test.Answer.Options[NumOpt].Text); Gbl.Test.Answer.Options[NumOpt].Text);
Med_ShowMedia (&Gbl.Test.Answer.Options[NumOpt].Media, Med_ShowMedia (&Gbl.Test.Answer.Options[NumOpt].Media,
@ -4142,7 +4142,7 @@ static void Tst_WriteChoiceAnsViewGame (long GamCod,unsigned NumQst,long QstCod,
"<td class=\"DAT LEFT_TOP\">"); "<td class=\"DAT LEFT_TOP\">");
/* Get number of users who selected this answer /* Get number of users who selected this answer
and draw proportional bar */ and draw proportional bar */
Gam_GetAndDrawBarNumUsrsWhoAnswered (GamCod,QstCod,AnsInd, Gam_GetAndDrawBarNumUsrsWhoAnswered (GamCod,QstInd,AnsInd,
0); // TODO: NumUsrs 0); // TODO: NumUsrs
fprintf (Gbl.F.Out,"</td>" fprintf (Gbl.F.Out,"</td>"
"</tr>"); "</tr>");
@ -6338,7 +6338,7 @@ void Tst_RequestRemoveQst (void)
Tst_PutParamsRemoveQst, Tst_PutParamsRemoveQst,
Btn_REMOVE_BUTTON,Txt_Remove_question, Btn_REMOVE_BUTTON,Txt_Remove_question,
Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_question_X, Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_question_X,
(unsigned long) Gbl.Test.QstCod); Gbl.Test.QstCod);
/***** Continue editing questions *****/ /***** Continue editing questions *****/
if (EditingOnlyThisQst) if (EditingOnlyThisQst)

View File

@ -154,7 +154,7 @@ bool Tst_GetOneQuestionByCod (long QstCod,MYSQL_RES **mysql_res);
void Tst_WriteParamEditQst (void); void Tst_WriteParamEditQst (void);
unsigned Tst_GetNumAnswersQst (long QstCod); unsigned Tst_GetNumAnswersQst (long QstCod);
unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle); unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle);
void Tst_WriteAnswersGameResult (long GamCod,unsigned NumQst,long QstCod, void Tst_WriteAnswersGameResult (long GamCod,unsigned QstInd,long QstCod,
const char *Class,bool ShowResult); const char *Class,bool ShowResult);
bool Tst_CheckIfQuestionIsValidForGame (long QstCod); bool Tst_CheckIfQuestionIsValidForGame (long QstCod);
void Tst_WriteAnsTF (char AnsTF); void Tst_WriteAnsTF (char AnsTF);

View File

@ -8952,25 +8952,25 @@ const char *Txt_Do_you_really_want_to_remove_the_project_X = // Warning: it is v
"Voc&ecirc; realmente deseja remover o projeto <strong>%s</strong>?"; "Voc&ecirc; realmente deseja remover o projeto <strong>%s</strong>?";
#endif #endif
const char *Txt_Do_you_really_want_to_remove_the_question_X = // Warning: it is very important to include %lu in the following sentences const char *Txt_Do_you_really_want_to_remove_the_question_X = // Warning: it is very important to include %ld in the following sentences
#if L==1 // ca #if L==1 // ca
"De veres voleu eliminar pregunta <strong>%lu</strong>?"; "De veres voleu eliminar pregunta <strong>%ld</strong>?";
#elif L==2 // de #elif L==2 // de
"Wollen Sie die Frage <strong>%lu</strong> wirklich entfernen?"; "Wollen Sie die Frage <strong>%ld</strong> wirklich entfernen?";
#elif L==3 // en #elif L==3 // en
"Do you really want to remove the question <strong>%lu</strong>?"; "Do you really want to remove the question <strong>%ld</strong>?";
#elif L==4 // es #elif L==4 // es
"&iquest;Realmente desea eliminar la pregunta <strong>%lu</strong>?"; "&iquest;Realmente desea eliminar la pregunta <strong>%ld</strong>?";
#elif L==5 // fr #elif L==5 // fr
"Voulez-vous vraiment supprimer la question <strong>%lu</strong>?"; "Voulez-vous vraiment supprimer la question <strong>%ld</strong>?";
#elif L==6 // gn #elif L==6 // gn
"&iquest;Realmente desea eliminar la pregunta <strong>%lu</strong>?"; // Okoteve traducción "&iquest;Realmente desea eliminar la pregunta <strong>%ld</strong>?"; // Okoteve traducción
#elif L==7 // it #elif L==7 // it
"Vuoi realmente rimuovere la domanda <strong>%lu</strong>?"; "Vuoi realmente rimuovere la domanda <strong>%ld</strong>?";
#elif L==8 // pl #elif L==8 // pl
"Czy na pewno chcesz usunac pytanie <strong>%lu</strong>?"; "Czy na pewno chcesz usunac pytanie <strong>%ld</strong>?";
#elif L==9 // pt #elif L==9 // pt
"Voc&ecirc; realmente deseja remover a quest&atilde;o <strong>%lu</strong>?"; "Voc&ecirc; realmente deseja remover a quest&atilde;o <strong>%ld</strong>?";
#endif #endif
const char *Txt_Do_you_really_want_to_remove_the_survey_X = // Warning: it is very important to include %s in the following sentences const char *Txt_Do_you_really_want_to_remove_the_survey_X = // Warning: it is very important to include %s in the following sentences
@ -33012,6 +33012,27 @@ const char *Txt_results_per_page =
"resultados por p&aacute;gina"; "resultados por p&aacute;gina";
#endif #endif
const char *Txt_Resume = // Resume a game match
#if L==1 // ca
"Reprendre";
#elif L==2 // de
"Fortsetzen";
#elif L==3 // en
"Resume";
#elif L==4 // es
"Reanudar";
#elif L==5 // fr
"Reprendre";
#elif L==6 // gn
"Reanudar"; // Okoteve traducción
#elif L==7 // it
"Riprendi";
#elif L==8 // pl
"Wzn&oacute;w";
#elif L==9 // pt
"Retomar";
#endif
const char *Txt_Retype_new_password = const char *Txt_Retype_new_password =
#if L==1 // ca #if L==1 // ca
"Reescriviu la nova contrasenya"; "Reescriviu la nova contrasenya";