diff --git a/swad_action.c b/swad_action.c index 62d58c467..c8c82b473 100644 --- a/swad_action.c +++ b/swad_action.c @@ -85,7 +85,7 @@ extern struct Globals Gbl; /************************ Internal global variables **************************/ /*****************************************************************************/ /* -1354 actions in one CGI: +1372 actions in one CGI: 0. ActAll Any action (used for statistics) 1. ActUnk Unknown action 2. ActHom Show home menu @@ -426,7 +426,7 @@ Assessment: 289. ActSeeAsg Show assignments 290. ActReqTst Request a test of self-assesment 291. ActSeeAllSvy List all surveys in pages - NEW. ActSeeAllGam Remote control + NEW. ActSeeAllGam Remote control 292. ActSeeAllExaAnn Show the exam announcements 293. ActEdiAss Edit the assessment system @@ -503,6 +503,7 @@ Assessment: NEW. ActHidGam Hide game NEW. ActShoGam Show game NEW. ActEdiOneGamQst Edit a new question for a game + NEW. ActGamLstTstQst List test questions to select one or several questions NEW. ActRcvGamQst Receive a question of a game NEW. ActReqRemGamQst Request the removal of a question of a game NEW. ActRemGamQst Confirm the removal of a question of a game @@ -1979,6 +1980,7 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActHidGam */{1660,-1,TabUnk,ActSeeAllGam ,0x3E0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Rmt_HideGame ,NULL}, /* ActShoGam */{1661,-1,TabUnk,ActSeeAllGam ,0x3E0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Rmt_UnhideGame ,NULL}, /* ActEdiOneGamQst */{1662,-1,TabUnk,ActSeeAllGam ,0x3E0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Rmt_RequestEditQuestion ,NULL}, + /* ActGamLstTstQst */{1666,-1,TabUnk,ActSeeAllGam ,0x3E0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Tst_ListQuestionsToSelect ,NULL}, /* ActRcvGamQst */{1663,-1,TabUnk,ActSeeAllGam ,0x3E0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Rmt_ReceiveQst ,NULL}, /* ActReqRemGamQst */{1664,-1,TabUnk,ActSeeAllGam ,0x3E0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Rmt_RequestRemoveQst ,NULL}, /* ActRemGamQst */{1665,-1,TabUnk,ActSeeAllGam ,0x3E0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Rmt_RemoveQst ,NULL}, @@ -4707,6 +4709,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActRcvGamQst, // #1663 ActReqRemGamQst, // #1664 ActRemGamQst, // #1665 + ActGamLstTstQst, // #1666 }; /*****************************************************************************/ diff --git a/swad_action.h b/swad_action.h index 710ad3135..c32c0d19f 100644 --- a/swad_action.h +++ b/swad_action.h @@ -57,9 +57,9 @@ typedef enum typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action -#define Act_NUM_ACTIONS (1 + 9 + 43 + 17 + 47 + 33 + 24 + 115 + 89 + 416 + 165 + 172 + 42 + 14 + 97) +#define Act_NUM_ACTIONS (1 + 9 + 43 + 17 + 47 + 33 + 24 + 115 + 90 + 416 + 165 + 172 + 42 + 14 + 97) -#define Act_MAX_ACTION_COD 1665 +#define Act_MAX_ACTION_COD 1666 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 12 @@ -515,19 +515,20 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActHidGam (ActChgCalCrs1stDay + 75) #define ActShoGam (ActChgCalCrs1stDay + 76) #define ActEdiOneGamQst (ActChgCalCrs1stDay + 77) -#define ActRcvGamQst (ActChgCalCrs1stDay + 78) -#define ActReqRemGamQst (ActChgCalCrs1stDay + 79) -#define ActRemGamQst (ActChgCalCrs1stDay + 80) +#define ActGamLstTstQst (ActChgCalCrs1stDay + 78) +#define ActRcvGamQst (ActChgCalCrs1stDay + 79) +#define ActReqRemGamQst (ActChgCalCrs1stDay + 80) +#define ActRemGamQst (ActChgCalCrs1stDay + 81) -#define ActSeeOneExaAnn (ActChgCalCrs1stDay + 81) -#define ActSeeDatExaAnn (ActChgCalCrs1stDay + 82) -#define ActEdiExaAnn (ActChgCalCrs1stDay + 83) -#define ActRcvExaAnn (ActChgCalCrs1stDay + 84) -#define ActPrnExaAnn (ActChgCalCrs1stDay + 85) -#define ActReqRemExaAnn (ActChgCalCrs1stDay + 86) -#define ActRemExaAnn (ActChgCalCrs1stDay + 87) -#define ActHidExaAnn (ActChgCalCrs1stDay + 88) -#define ActShoExaAnn (ActChgCalCrs1stDay + 89) +#define ActSeeOneExaAnn (ActChgCalCrs1stDay + 82) +#define ActSeeDatExaAnn (ActChgCalCrs1stDay + 83) +#define ActEdiExaAnn (ActChgCalCrs1stDay + 84) +#define ActRcvExaAnn (ActChgCalCrs1stDay + 85) +#define ActPrnExaAnn (ActChgCalCrs1stDay + 86) +#define ActReqRemExaAnn (ActChgCalCrs1stDay + 87) +#define ActRemExaAnn (ActChgCalCrs1stDay + 88) +#define ActHidExaAnn (ActChgCalCrs1stDay + 89) +#define ActShoExaAnn (ActChgCalCrs1stDay + 90) /*****************************************************************************/ /******************************** Files tab **********************************/ diff --git a/swad_changelog.h b/swad_changelog.h index 96294b7d8..c44e7cc45 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -236,13 +236,35 @@ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 16.249.5 (2017-07-04)" +#define Log_PLATFORM_VERSION "SWAD 16.251 (2017-07-16)" #define CSS_FILE "swad16.235.1.css" #define JS_FILE "swad16.206.3.js" // Number of lines (includes comments but not blank lines) has been got with the following command: // nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*?.h sql/swad*.sql | tail -1 /* + Version 16.251: Jul 16, 2017 Listing games for remote control. Not finished. (226867 lines) + 19 changes necessary in database: +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1648','es','N','Cambiar lugar de centro'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1649','es','N','Ver juegos'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1650','es','N','Ver un juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1651','es','N','Responder juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1652','es','N','Solicitar creación juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1653','es','N','Solicitar edición juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1654','es','N','Crear juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1655','es','N','Modificar juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1656','es','N','Solicitar elim. juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1657','es','N','Eliminar juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1658','es','N','Solicitar puesta a cero juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1659','es','N','Poner a cero juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1660','es','N','Ocultar juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1661','es','N','Mostrar juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1662','es','N','Solicitar selec. tests para juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1663','es','N','Enviar pregunta juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1664','es','N','Preguntar si eliminar pregunta juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1665','es','N','Eliminar pregunta juego'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1666','es','N','Selec. descriptores tests para juego'); + Version 16.250: Jul 09, 2017 Listing games for remote control. Not finished. (226738 lines) 5 changes necessary in database: CREATE TABLE IF NOT EXISTS games (GamCod INT NOT NULL AUTO_INCREMENT,Scope ENUM('Sys','Cty','Ins','Ctr','Deg','Crs') NOT NULL DEFAULT 'Sys',Cod INT NOT NULL DEFAULT -1,Hidden ENUM('N','Y') NOT NULL DEFAULT 'N',NumNotif INT NOT NULL DEFAULT 0,Roles INT NOT NULL DEFAULT 0,UsrCod INT NOT NULL,StartTime DATETIME NOT NULL,EndTime DATETIME NOT NULL,Title VARCHAR(2047) NOT NULL,Txt TEXT NOT NULL,UNIQUE INDEX(GamCod),INDEX(Scope,Cod)); diff --git a/swad_remote_control.c b/swad_remote_control.c index f9e81895a..0cd04f4a3 100644 --- a/swad_remote_control.c +++ b/swad_remote_control.c @@ -41,6 +41,7 @@ #include "swad_remote_control.h" #include "swad_role.h" #include "swad_table.h" +#include "swad_test.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ @@ -111,8 +112,6 @@ static void Rmt_SetAllowedAndHiddenScopes (unsigned *ScopesAllowed, unsigned *HiddenAllowed); static void Rmt_GetGameTxtFromDB (long GamCod,char Txt[Cns_MAX_BYTES_TEXT + 1]); -static void Rmt_PutParamGameCod (long GamCod); -static long Rmt_GetParamGameCod (void); static void Rmt_PutButtonToResetGame (void); @@ -130,8 +129,6 @@ static void Rmt_GetAndWriteNamesOfGrpsAssociatedToGame (struct Game *Game); static bool Rmt_CheckIfICanDoThisGameBasedOnGrps (long GamCod); static unsigned Rmt_GetNumQstsGame (long GamCod); -static void Rmt_ShowFormEditOneQst (long GamCod,struct GameQuestion *GameQst, - char Txt[Cns_MAX_BYTES_TEXT + 1]); static void Rmt_InitQst (struct GameQuestion *GameQst); static void Rmt_PutParamQstCod (long QstCod); static long Rmt_GetParamQstCod (void); @@ -169,8 +166,6 @@ void Rmt_SeeAllGames (void) { struct GameQuestion GameQst; - Ale_ShowAlert (Ale_INFO,"Under development."); - /***** Get parameters *****/ Rmt_GetParamGameOrder (); Grp_GetParamWhichGrps (); @@ -1461,7 +1456,7 @@ void Rmt_GetNotifGame (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1], /******************* Write parameter with code of game *********************/ /*****************************************************************************/ -static void Rmt_PutParamGameCod (long GamCod) +void Rmt_PutParamGameCod (long GamCod) { Par_PutHiddenParamLong ("GamCod",GamCod); } @@ -1470,7 +1465,7 @@ static void Rmt_PutParamGameCod (long GamCod) /******************** Get parameter with code of game **********************/ /*****************************************************************************/ -static long Rmt_GetParamGameCod (void) +long Rmt_GetParamGameCod (void) { /***** Get code of game *****/ return Par_GetParToLong ("GamCod"); @@ -1534,19 +1529,19 @@ void Rmt_RemoveGame (void) Lay_ShowErrorAndExit ("You can not remove this game."); /***** Remove all the users in this game *****/ - sprintf (Query,"DELETE FROM game_users WHERE GamCod=%ld", + sprintf (Query,"DELETE FROM gam_users WHERE GamCod=%ld", Game.GamCod); DB_QueryDELETE (Query,"can not remove users who are answered a game"); /***** Remove all the answers in this game *****/ - sprintf (Query,"DELETE FROM gam_answers USING game_questions,gam_answers" - " WHERE game_questions.GamCod=%ld" - " AND game_questions.QstCod=gam_answers.QstCod", + sprintf (Query,"DELETE FROM gam_answers USING gam_questions,gam_answers" + " WHERE gam_questions.GamCod=%ld" + " AND gam_questions.QstCod=gam_answers.QstCod", Game.GamCod); DB_QueryDELETE (Query,"can not remove answers of a game"); /***** Remove all the questions in this game *****/ - sprintf (Query,"DELETE FROM game_questions" + sprintf (Query,"DELETE FROM gam_questions" " WHERE GamCod=%ld", Game.GamCod); DB_QueryDELETE (Query,"can not remove questions of a game"); @@ -1643,14 +1638,14 @@ void Rmt_ResetGame (void) Lay_ShowErrorAndExit ("You can not reset this game."); /***** Remove all the users in this game *****/ - sprintf (Query,"DELETE FROM game_users WHERE GamCod=%ld", + sprintf (Query,"DELETE FROM gam_users WHERE GamCod=%ld", Game.GamCod); DB_QueryDELETE (Query,"can not remove users who are answered a game"); /***** Reset all the answers in this game *****/ - sprintf (Query,"UPDATE gam_answers,game_questions SET gam_answers.NumUsrs=0" - " WHERE game_questions.GamCod=%ld" - " AND game_questions.QstCod=gam_answers.QstCod", + sprintf (Query,"UPDATE gam_answers,gam_questions SET gam_answers.NumUsrs=0" + " WHERE gam_questions.GamCod=%ld" + " AND gam_questions.QstCod=gam_answers.QstCod", Game.GamCod); DB_QueryUPDATE (Query,"can not reset answers of a game"); @@ -2474,28 +2469,28 @@ void Rmt_RemoveGames (Sco_Scope_t Scope,long Cod) char Query[512]; /***** Remove all the users in course games *****/ - sprintf (Query,"DELETE FROM game_users" - " USING games,game_users" + sprintf (Query,"DELETE FROM gam_users" + " USING games,gam_users" " WHERE games.Scope='%s' AND games.Cod=%ld" - " AND games.GamCod=game_users.GamCod", + " AND games.GamCod=gam_users.GamCod", Sco_ScopeDB[Scope],Cod); DB_QueryDELETE (Query,"can not remove users" " who had answered games in a place on the hierarchy"); /***** Remove all the answers in course games *****/ sprintf (Query,"DELETE FROM gam_answers" - " USING games,game_questions,gam_answers" + " USING games,gam_questions,gam_answers" " WHERE games.Scope='%s' AND games.Cod=%ld" - " AND games.GamCod=game_questions.GamCod" - " AND game_questions.QstCod=gam_answers.QstCod", + " AND games.GamCod=gam_questions.GamCod" + " AND gam_questions.QstCod=gam_answers.QstCod", Sco_ScopeDB[Scope],Cod); DB_QueryDELETE (Query,"can not remove answers of games in a place on the hierarchy"); /***** Remove all the questions in course games *****/ - sprintf (Query,"DELETE FROM game_questions" - " USING games,game_questions" + sprintf (Query,"DELETE FROM gam_questions" + " USING games,gam_questions" " WHERE games.Scope='%s' AND games.Cod=%ld" - " AND games.GamCod=game_questions.GamCod", + " AND games.GamCod=gam_questions.GamCod", Sco_ScopeDB[Scope],Cod); DB_QueryDELETE (Query,"can not remove questions of games in a place on the hierarchy"); @@ -2543,7 +2538,7 @@ static unsigned Rmt_GetNumQstsGame (long GamCod) char Query[128]; /***** Get data of questions from database *****/ - sprintf (Query,"SELECT COUNT(*) FROM game_questions WHERE GamCod=%ld", + sprintf (Query,"SELECT COUNT(*) FROM gam_questions WHERE GamCod=%ld", GamCod); return (unsigned) DB_QueryCOUNT (Query,"can not get number of questions of a game"); } @@ -2556,11 +2551,9 @@ void Rmt_RequestEditQuestion (void) { long GamCod; struct GameQuestion GameQst; - char Txt[Cns_MAX_BYTES_TEXT + 1]; /***** Initialize question to zero *****/ Rmt_InitQst (&GameQst); - Txt[0] = '\0'; /***** Get game code *****/ if ((GamCod = Rmt_GetParamGameCod ()) == -1L) @@ -2575,201 +2568,12 @@ void Rmt_RequestEditQuestion (void) Gbl.Games.CurrentPage = Pag_GetParamPagNum (Pag_SURVEYS); /***** Show form to create a new question in this game *****/ - Rmt_ShowFormEditOneQst (GamCod,&GameQst,Txt); + Tst_ShowFormAskSelectTstsForGame (GamCod); /***** Show current game *****/ Rmt_ShowOneGame (GamCod,&GameQst,true); } -/*****************************************************************************/ -/******************* Show form to edit one game question *******************/ -/*****************************************************************************/ - -static void Rmt_ShowFormEditOneQst (long GamCod,struct GameQuestion *GameQst, - char Txt[Cns_MAX_BYTES_TEXT + 1]) - { - extern const char *Hlp_ASSESSMENT_Games_questions; - extern const char *The_ClassForm[The_NUM_THEMES]; - extern const char *Txt_Question; - extern const char *Txt_New_question; - extern const char *Txt_Stem; - extern const char *Txt_Type; - extern const char *Txt_SURVEY_STR_ANSWER_TYPES[Rmt_NUM_ANS_TYPES]; - extern const char *Txt_Save; - extern const char *Txt_Create_question; - char Query[256]; - MYSQL_RES *mysql_res; - MYSQL_ROW row; - unsigned NumAns; - unsigned NumAnswers = 0; - Rmt_AnswerType_t AnsType; - - if (Gbl.Action.Act == ActEdiOneGamQst) // If no receiving the question, but editing a new or existing question - { - if ((GameQst->QstCod > 0)) // If parameter QstCod received ==> question already exists in the database - { - /***** Get the type of answer and the stem from the database *****/ - /* Get the question from database */ - sprintf (Query,"SELECT QstInd,AnsType,Stem FROM game_questions" - " WHERE QstCod=%ld AND GamCod=%ld", - GameQst->QstCod,GamCod); - DB_QuerySELECT (Query,&mysql_res,"can not get a question"); - - row = mysql_fetch_row (mysql_res); - - /* Get question index inside game (row[0]) */ - if (sscanf (row[0],"%u",&(GameQst->QstInd)) != 1) - Lay_ShowErrorAndExit ("Error: wrong question index."); - - /* Get the type of answer (row[1]) */ - GameQst->AnswerType = Rmt_ConvertFromStrAnsTypDBToAnsTyp (row[1]); - - /* Get the stem of the question from the database (row[2]) */ - Str_Copy (Txt,row[2], - Cns_MAX_BYTES_TEXT); - - /* Free structure that stores the query result */ - DB_FreeMySQLResult (&mysql_res); - - /***** Get the answers from the database *****/ - NumAnswers = Rmt_GetAnswersQst (GameQst->QstCod,&mysql_res); // Result: AnsInd,NumUsrs,Answer - for (NumAns = 0; - NumAns < NumAnswers; - NumAns++) - { - row = mysql_fetch_row (mysql_res); - - if (NumAnswers > Rmt_MAX_ANSWERS_PER_QUESTION) - Lay_ShowErrorAndExit ("Wrong answer."); - if (!Rmt_AllocateTextChoiceAnswer (GameQst,NumAns)) - Lay_ShowErrorAndExit (Gbl.Alert.Txt); - - Str_Copy (GameQst->AnsChoice[NumAns].Text,row[2], - Rmt_MAX_BYTES_ANSWER); - } - /* Free structure that stores the query result */ - DB_FreeMySQLResult (&mysql_res); - } - } - - /***** Start box *****/ - if (GameQst->QstCod > 0) // If the question already has assigned a code - { - /* Parameters for contextual icon */ - Gbl.Games.GamCodToEdit = GamCod; - Gbl.Games.GamQstCodToEdit = GameQst->QstCod; - - sprintf (Gbl.Title,"%s %u", - Txt_Question,GameQst->QstInd + 1); // Question index may be 0, 1, 2, 3,... - Box_StartBox (NULL,Gbl.Title,Rmt_PutIconToRemoveOneQst, - NULL,Box_NOT_CLOSABLE); - } - else - Box_StartBox (NULL,Txt_New_question,NULL, - Hlp_ASSESSMENT_Games_questions,Box_NOT_CLOSABLE); - - /***** Start form *****/ - Act_FormStart (ActRcvGamQst); - Rmt_PutParamGameCod (GamCod); - if (GameQst->QstCod > 0) // If the question already has assigned a code - Rmt_PutParamQstCod (GameQst->QstCod); - - /***** Start table *****/ - Tbl_StartTableWide (2); - - /***** Stem *****/ - fprintf (Gbl.F.Out,"" - "" - "" - "" - "" - "" - "" - "", - The_ClassForm[Gbl.Prefs.Theme],Txt_Stem, - Txt); - - /***** Type of answer *****/ - fprintf (Gbl.F.Out,"" - "" - "%s:" - "" - "", - The_ClassForm[Gbl.Prefs.Theme], - Txt_Type, - The_ClassForm[Gbl.Prefs.Theme]); - for (AnsType = (Rmt_AnswerType_t) 0; - AnsType < Rmt_NUM_ANS_TYPES; - AnsType++) - { - fprintf (Gbl.F.Out,"
", - Txt_SURVEY_STR_ANSWER_TYPES[AnsType]); - } - fprintf (Gbl.F.Out,"" - ""); - - /***** Answers *****/ - /* Unique or multiple choice answers */ - fprintf (Gbl.F.Out,"" - "" - ""); - Tbl_StartTable (2); - for (NumAns = 0; - NumAns < Rmt_MAX_ANSWERS_PER_QUESTION; - NumAns++) - { - /* Label with the number of the answer */ - fprintf (Gbl.F.Out,"" - "" - "" - "", - NumAns,The_ClassForm[Gbl.Prefs.Theme],NumAns + 1); - - /* Answer text */ - fprintf (Gbl.F.Out,"" - "" - "" - ""); - } - Tbl_EndTable (); - fprintf (Gbl.F.Out,"" - ""); - - /***** End table *****/ - Tbl_EndTable (); - - /***** Send button *****/ - if (GameQst->QstCod > 0) // If the question already has assigned a code - Btn_PutConfirmButton (Txt_Save); - else - Btn_PutCreateButton (Txt_Create_question); - - /***** End form *****/ - Act_FormEnd (); - - /***** End box *****/ - Box_EndBox (); - - /***** Free memory for answers *****/ - Rmt_FreeTextChoiceAnswers (GameQst,NumAnswers); - } - /*****************************************************************************/ /********************* Initialize a new question to zero *********************/ /*****************************************************************************/ @@ -3011,7 +2815,7 @@ void Rmt_ReceiveQst (void) } if (Error) - Rmt_ShowFormEditOneQst (GamCod,&GameQst,Txt); + Tst_ShowFormAskSelectTstsForGame (GamCod); else { /***** Form is received OK ==> insert question and answer in the database *****/ @@ -3020,7 +2824,7 @@ void Rmt_ReceiveQst (void) GameQst.QstInd = Rmt_GetNextQuestionIndexInGame (GamCod); /* Insert question in the table of questions */ - sprintf (Query,"INSERT INTO game_questions" + sprintf (Query,"INSERT INTO gam_questions" " (GamCod,QstInd,AnsType,Stem)" " VALUES" " (%ld,%u,'%s','%s')", @@ -3030,7 +2834,7 @@ void Rmt_ReceiveQst (void) else // It's an existing question { /* Update question */ - sprintf (Query,"UPDATE game_questions SET Stem='%s',AnsType='%s'" + sprintf (Query,"UPDATE gam_questions SET Stem='%s',AnsType='%s'" " WHERE QstCod=%ld AND GamCod=%ld", Txt,Rmt_StrAnswerTypesDB[GameQst.AnswerType], GameQst.QstCod,GamCod); @@ -3098,7 +2902,7 @@ static unsigned Rmt_GetQstIndFromQstCod (long QstCod) unsigned QstInd = 0; /***** Get number of games with a field value from database *****/ - sprintf (Query,"SELECT QstInd FROM game_questions WHERE QstCod=%ld", + sprintf (Query,"SELECT QstInd FROM gam_questions WHERE QstCod=%ld", QstCod); NumRows = DB_QuerySELECT (Query,&mysql_res,"can not get question index"); @@ -3130,7 +2934,7 @@ static unsigned Rmt_GetNextQuestionIndexInGame (long GamCod) unsigned QstInd = 0; /***** Get number of games with a field value from database *****/ - sprintf (Query,"SELECT MAX(QstInd) FROM game_questions WHERE GamCod=%ld", + sprintf (Query,"SELECT MAX(QstInd) FROM gam_questions WHERE GamCod=%ld", GamCod); DB_QuerySELECT (Query,&mysql_res,"can not get last question index"); @@ -3176,7 +2980,7 @@ static void Rmt_ListGameQuestions (struct Game *Game,struct GameQuestion *GameQs /***** Get data of questions from database *****/ sprintf (Query,"SELECT QstCod,QstInd,AnsType,Stem" - " FROM game_questions WHERE GamCod=%ld ORDER BY QstInd", + " FROM gam_questions WHERE GamCod=%ld ORDER BY QstInd", Game->GamCod); NumQsts = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get data of a question"); @@ -3583,14 +3387,14 @@ void Rmt_RemoveQst (void) Rmt_RemAnswersOfAQuestion (GameQst.QstCod); /* Remove the question itself */ - sprintf (Query,"DELETE FROM game_questions WHERE QstCod=%ld", + sprintf (Query,"DELETE FROM gam_questions WHERE QstCod=%ld", GameQst.QstCod); DB_QueryDELETE (Query,"can not remove a question"); if (!mysql_affected_rows (&Gbl.mysql)) Lay_ShowErrorAndExit ("The question to be removed does not exist."); /* Change index of questions greater than this */ - sprintf (Query,"UPDATE game_questions SET QstInd=QstInd-1" + sprintf (Query,"UPDATE gam_questions SET QstInd=QstInd-1" " WHERE GamCod=%ld AND QstInd>%u", GamCod,GameQst.QstInd); DB_QueryUPDATE (Query,"can not update indexes of questions"); @@ -3654,7 +3458,7 @@ static void Rmt_ReceiveAndStoreUserAnswersToAGame (long GamCod) unsigned AnsInd; /***** Get questions of this game from database *****/ - sprintf (Query,"SELECT QstCod FROM game_questions" + sprintf (Query,"SELECT QstCod FROM gam_questions" " WHERE GamCod=%ld ORDER BY QstCod", GamCod); DB_QuerySELECT (Query,&mysql_res,"can not get questions of a game"); @@ -3721,7 +3525,7 @@ static void Rmt_RegisterIHaveAnsweredGame (long GamCod) { char Query[256]; - sprintf (Query,"INSERT INTO game_users" + sprintf (Query,"INSERT INTO gam_users" " (GamCod,UsrCod)" " VALUES" " (%ld,%ld)", @@ -3738,7 +3542,7 @@ static bool Rmt_CheckIfIHaveAnsweredGame (long GamCod) char Query[256]; /***** Get number of games with a field value from database *****/ - sprintf (Query,"SELECT COUNT(*) FROM game_users" + sprintf (Query,"SELECT COUNT(*) FROM gam_users" " WHERE GamCod=%ld AND UsrCod=%ld", GamCod,Gbl.Usrs.Me.UsrDat.UsrCod); return (DB_QueryCOUNT (Query,"can not check if you have answered a game") != 0); @@ -3753,7 +3557,7 @@ static unsigned Rmt_GetNumUsrsWhoHaveAnsweredGame (long GamCod) char Query[128]; /***** Get number of games with a field value from database *****/ - sprintf (Query,"SELECT COUNT(*) FROM game_users WHERE GamCod=%ld", + sprintf (Query,"SELECT COUNT(*) FROM gam_users WHERE GamCod=%ld", GamCod); return (unsigned) DB_QueryCOUNT (Query,"can not get number of users who have answered a game"); } @@ -3963,74 +3767,74 @@ float Rmt_GetNumQstsPerCrsGame (Sco_Scope_t Scope) { case Sco_SCOPE_SYS: sprintf (Query,"SELECT AVG(NumQsts) FROM" - " (SELECT COUNT(game_questions.QstCod) AS NumQsts" - " FROM games,game_questions" + " (SELECT COUNT(gam_questions.QstCod) AS NumQsts" + " FROM games,gam_questions" " WHERE games.Scope='%s'" - " AND games.GamCod=game_questions.GamCod" - " GROUP BY game_questions.GamCod) AS NumQstsTable", + " AND games.GamCod=gam_questions.GamCod" + " GROUP BY gam_questions.GamCod) AS NumQstsTable", Sco_ScopeDB[Sco_SCOPE_CRS]); break; case Sco_SCOPE_CTY: sprintf (Query,"SELECT AVG(NumQsts) FROM" - " (SELECT COUNT(game_questions.QstCod) AS NumQsts" - " FROM institutions,centres,degrees,courses,games,game_questions" + " (SELECT COUNT(gam_questions.QstCod) AS NumQsts" + " FROM institutions,centres,degrees,courses,games,gam_questions" " WHERE institutions.CtyCod=%ld" " AND institutions.InsCod=centres.InsCod" " AND centres.CtrCod=degrees.CtrCod" " AND degrees.DegCod=courses.DegCod" " AND courses.CrsCod=games.Cod" " AND games.Scope='%s'" - " AND games.GamCod=game_questions.GamCod" - " GROUP BY game_questions.GamCod) AS NumQstsTable", + " AND games.GamCod=gam_questions.GamCod" + " GROUP BY gam_questions.GamCod) AS NumQstsTable", Gbl.CurrentCty.Cty.CtyCod, Sco_ScopeDB[Sco_SCOPE_CRS]); break; case Sco_SCOPE_INS: sprintf (Query,"SELECT AVG(NumQsts) FROM" - " (SELECT COUNT(game_questions.QstCod) AS NumQsts" - " FROM centres,degrees,courses,games,game_questions" + " (SELECT COUNT(gam_questions.QstCod) AS NumQsts" + " FROM centres,degrees,courses,games,gam_questions" " WHERE centres.InsCod=%ld" " AND centres.CtrCod=degrees.CtrCod" " AND degrees.DegCod=courses.DegCod" " AND courses.CrsCod=games.Cod" " AND games.Scope='%s'" - " AND games.GamCod=game_questions.GamCod" - " GROUP BY game_questions.GamCod) AS NumQstsTable", + " AND games.GamCod=gam_questions.GamCod" + " GROUP BY gam_questions.GamCod) AS NumQstsTable", Gbl.CurrentIns.Ins.InsCod, Sco_ScopeDB[Sco_SCOPE_CRS]); break; case Sco_SCOPE_CTR: sprintf (Query,"SELECT AVG(NumQsts) FROM" - " (SELECT COUNT(game_questions.QstCod) AS NumQsts" - " FROM degrees,courses,games,game_questions" + " (SELECT COUNT(gam_questions.QstCod) AS NumQsts" + " FROM degrees,courses,games,gam_questions" " WHERE degrees.CtrCod=%ld" " AND degrees.DegCod=courses.DegCod" " AND courses.CrsCod=games.Cod" " AND games.Scope='%s'" - " AND games.GamCod=game_questions.GamCod" - " GROUP BY game_questions.GamCod) AS NumQstsTable", + " AND games.GamCod=gam_questions.GamCod" + " GROUP BY gam_questions.GamCod) AS NumQstsTable", Gbl.CurrentCtr.Ctr.CtrCod, Sco_ScopeDB[Sco_SCOPE_CRS]); break; case Sco_SCOPE_DEG: sprintf (Query,"SELECT AVG(NumQsts) FROM" - " (SELECT COUNT(game_questions.QstCod) AS NumQsts" - " FROM courses,games,game_questions" + " (SELECT COUNT(gam_questions.QstCod) AS NumQsts" + " FROM courses,games,gam_questions" " WHERE courses.DegCod=%ld" " AND courses.CrsCod=games.Cod" " AND games.Scope='%s'" - " AND games.GamCod=game_questions.GamCod" - " GROUP BY game_questions.GamCod) AS NumQstsTable", + " AND games.GamCod=gam_questions.GamCod" + " GROUP BY gam_questions.GamCod) AS NumQstsTable", Gbl.CurrentDeg.Deg.DegCod, Sco_ScopeDB[Sco_SCOPE_CRS]); break; case Sco_SCOPE_CRS: sprintf (Query,"SELECT AVG(NumQsts) FROM" - " (SELECT COUNT(game_questions.QstCod) AS NumQsts" - " FROM games,game_questions" + " (SELECT COUNT(gam_questions.QstCod) AS NumQsts" + " FROM games,gam_questions" " WHERE games.Scope='%s' AND games.Cod=%ld" - " AND games.GamCod=game_questions.GamCod" - " GROUP BY game_questions.GamCod) AS NumQstsTable", + " AND games.GamCod=gam_questions.GamCod" + " GROUP BY gam_questions.GamCod) AS NumQstsTable", Sco_ScopeDB[Sco_SCOPE_CRS],Gbl.CurrentCrs.Crs.CrsCod); break; default: diff --git a/swad_remote_control.h b/swad_remote_control.h index 963f504b1..da33508af 100644 --- a/swad_remote_control.h +++ b/swad_remote_control.h @@ -96,6 +96,8 @@ void Rmt_FreeListGames (void); void Rmt_GetNotifGame (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1], char **ContentStr, long GamCod,bool GetContent); +void Rmt_PutParamGameCod (long GamCod); +long Rmt_GetParamGameCod (void); void Rmt_AskRemGame (void); void Rmt_RemoveGame (void); void Rmt_AskResetGame (void); diff --git a/swad_test.c b/swad_test.c index 498a77294..b57063bc1 100644 --- a/swad_test.c +++ b/swad_test.c @@ -130,6 +130,13 @@ typedef enum Tst_STATUS_ERROR = 2, } Tst_Status_t; +typedef enum + { + Tst_SHOW_QUESTIONS, + Tst_EDIT_QUESTIONS, + Tst_SELECT_QUESTIONS_FOR_GAME, + } Tst_ActionToDoWithQuestions_t; + /*****************************************************************************/ /************** External global variables from others modules ****************/ /*****************************************************************************/ @@ -166,7 +173,6 @@ static void Tst_UpdateMyNumAccessTst (unsigned NumAccessesTst); static void Tst_UpdateLastAccTst (void); static bool Tst_CheckIfICanEditTests (void); static void Tst_PutIconsTests (void); -static void Tst_PutButtonToAddQuestion (void); static long Tst_GetParamTagCode (void); static bool Tst_CheckIfCurrentCrsHasTestTags (void); static unsigned long Tst_GetAllTagsFromCurrentCrs (MYSQL_RES **mysql_res); @@ -184,11 +190,11 @@ static Tst_Pluggable_t Tst_GetPluggableFromForm (void); static Tst_Feedback_t Tst_GetFeedbackTypeFromForm (void); static void Tst_CheckAndCorrectNumbersQst (void); static void Tst_ShowFormAnswerTypes (unsigned NumCols); -static unsigned long Tst_GetQuestionsForEdit (MYSQL_RES **mysql_res); +static unsigned long Tst_GetQuestions (MYSQL_RES **mysql_res); static unsigned long Tst_GetQuestionsForTest (MYSQL_RES **mysql_res); static void Tst_ListOneQstToEdit (void); static bool Tst_GetOneQuestionByCod (long QstCod,MYSQL_RES **mysql_res); -static void Tst_ListOneOrMoreQuestionsToEdit (unsigned long NumRows,MYSQL_RES *mysql_res); +static void Tst_ListOneOrMoreQuestions (unsigned long NumRows,MYSQL_RES *mysql_res); static void Tst_WriteAnswersOfAQstEdit (long QstCod); static void Tst_WriteAnswersOfAQstViewTest (unsigned NumQst,long QstCod,bool Shuffle); @@ -214,7 +220,7 @@ static void Tst_WriteScoreStart (unsigned ColSpan); static void Tst_WriteScoreEnd (void); static void Tst_WriteParamQstCod (unsigned NumQst,long QstCod); static void Tst_GetAndWriteTagsQst (long QstCod); -static bool Tst_GetParamsTst (void); +static bool Tst_GetParamsTst (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions); static unsigned Tst_GetAndCheckParamNumTst (void); static void Tst_GetParamNumQst (void); static bool Tst_GetCreateXMLFromForm (void); @@ -419,7 +425,7 @@ void Tst_ShowNewTest (void) if (Tst_CheckIfNextTstAllowed ()) { /***** Check that all parameters used to generate a test are valid *****/ - if (Tst_GetParamsTst ()) // Get parameters from form + if (Tst_GetParamsTst (Tst_SHOW_QUESTIONS)) // Get parameters from form { /***** Get questions *****/ if ((NumRows = Tst_GetQuestionsForTest (&mysql_res)) == 0) // Query database @@ -1320,6 +1326,263 @@ void Tst_ShowFormAskEditTsts (void) DB_FreeMySQLResult (&mysql_res); } +/*****************************************************************************/ +/************** Show form select test questions for a game *******************/ +/*****************************************************************************/ + +void Tst_ShowFormAskSelectTstsForGame (long GamCod) + { + extern const char *Hlp_ASSESSMENT_Tests; + extern const char *Txt_No_test_questions; + extern const char *Txt_Select_questions; + extern const char *Txt_Show_questions; + MYSQL_RES *mysql_res; + unsigned long NumRows; + + /***** Start box *****/ + Box_StartBox (NULL,Txt_Select_questions,NULL, + Hlp_ASSESSMENT_Tests,Box_NOT_CLOSABLE); + + /***** Get tags already present in the table of questions *****/ + if ((NumRows = Tst_GetAllTagsFromCurrentCrs (&mysql_res))) + { + Act_FormStart (ActGamLstTstQst); + Rmt_PutParamGameCod (GamCod); + + Tbl_StartTable (2); + + /***** Selection of tags *****/ + Tst_ShowFormSelTags (NumRows,mysql_res,false,2); + + /***** Starting and ending dates in the search *****/ + Dat_PutFormStartEndClientLocalDateTimesWithYesterdayToday (false); + + Tbl_EndTable (); + + /***** Send button *****/ + Btn_PutConfirmButton (Txt_Show_questions); + Act_FormEnd (); + } + else // No test questions + { + /***** Warning message *****/ + Ale_ShowAlert (Ale_INFO,Txt_No_test_questions); + + /***** Button to create a new question *****/ + Tst_PutButtonToAddQuestion (); + } + + /***** End box *****/ + Box_EndBox (); + + /* Free structure that stores the query result */ + DB_FreeMySQLResult (&mysql_res); + + + + + + + + + + + + + + + + + + + /* + + + + extern const char *Hlp_ASSESSMENT_Games_questions; + extern const char *The_ClassForm[The_NUM_THEMES]; + extern const char *Txt_Question; + extern const char *Txt_New_question; + extern const char *Txt_Stem; + extern const char *Txt_Type; + extern const char *Txt_SURVEY_STR_ANSWER_TYPES[Rmt_NUM_ANS_TYPES]; + extern const char *Txt_Save; + extern const char *Txt_Create_question; + char Query[256]; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumAns; + unsigned NumAnswers = 0; + Rmt_AnswerType_t AnsType; + + if (Gbl.Action.Act == ActEdiOneGamQst) // If no receiving the question, but editing a new or existing question + { + if ((GameQst->QstCod > 0)) // If parameter QstCod received ==> question already exists in the database + { + ***** Get the type of answer and the stem from the database ***** + * Get the question from database * + sprintf (Query,"SELECT QstInd,AnsType,Stem FROM gam_questions" + " WHERE QstCod=%ld AND GamCod=%ld", + GameQst->QstCod,GamCod); + DB_QuerySELECT (Query,&mysql_res,"can not get a question"); + + row = mysql_fetch_row (mysql_res); + + * Get question index inside game (row[0]) * + if (sscanf (row[0],"%u",&(GameQst->QstInd)) != 1) + Lay_ShowErrorAndExit ("Error: wrong question index."); + + * Get the type of answer (row[1]) * + GameQst->AnswerType = Rmt_ConvertFromStrAnsTypDBToAnsTyp (row[1]); + + * Get the stem of the question from the database (row[2]) * + Str_Copy (Txt,row[2], + Cns_MAX_BYTES_TEXT); + + * Free structure that stores the query result * + DB_FreeMySQLResult (&mysql_res); + + ***** Get the answers from the database ***** + NumAnswers = Rmt_GetAnswersQst (GameQst->QstCod,&mysql_res); // Result: AnsInd,NumUsrs,Answer + for (NumAns = 0; + NumAns < NumAnswers; + NumAns++) + { + row = mysql_fetch_row (mysql_res); + + if (NumAnswers > Rmt_MAX_ANSWERS_PER_QUESTION) + Lay_ShowErrorAndExit ("Wrong answer."); + if (!Rmt_AllocateTextChoiceAnswer (GameQst,NumAns)) + Lay_ShowErrorAndExit (Gbl.Alert.Txt); + + Str_Copy (GameQst->AnsChoice[NumAns].Text,row[2], + Rmt_MAX_BYTES_ANSWER); + } + * Free structure that stores the query result * + DB_FreeMySQLResult (&mysql_res); + } + } + + ***** Start box ***** + if (GameQst->QstCod > 0) // If the question already has assigned a code + { + * Parameters for contextual icon * + Gbl.Games.GamCodToEdit = GamCod; + Gbl.Games.GamQstCodToEdit = GameQst->QstCod; + + sprintf (Gbl.Title,"%s %u", + Txt_Question,GameQst->QstInd + 1); // Question index may be 0, 1, 2, 3,... + Box_StartBox (NULL,Gbl.Title,Rmt_PutIconToRemoveOneQst, + NULL,Box_NOT_CLOSABLE); + } + else + Box_StartBox (NULL,Txt_New_question,NULL, + Hlp_ASSESSMENT_Games_questions,Box_NOT_CLOSABLE); + + ***** Start form ***** + Act_FormStart (ActRcvGamQst); + Rmt_PutParamGameCod (GamCod); + if (GameQst->QstCod > 0) // If the question already has assigned a code + Rmt_PutParamQstCod (GameQst->QstCod); + + ***** Start table ***** + Tbl_StartTableWide (2); + + ***** Stem ***** + fprintf (Gbl.F.Out,"" + "" + "" + "" + "" + "" + "" + "", + The_ClassForm[Gbl.Prefs.Theme],Txt_Stem, + Txt); + + ***** Type of answer ***** + fprintf (Gbl.F.Out,"" + "" + "%s:" + "" + "", + The_ClassForm[Gbl.Prefs.Theme], + Txt_Type, + The_ClassForm[Gbl.Prefs.Theme]); + for (AnsType = (Rmt_AnswerType_t) 0; + AnsType < Rmt_NUM_ANS_TYPES; + AnsType++) + { + fprintf (Gbl.F.Out,"
", + Txt_SURVEY_STR_ANSWER_TYPES[AnsType]); + } + fprintf (Gbl.F.Out,"" + ""); + + ***** Answers ***** + * Unique or multiple choice answers * + fprintf (Gbl.F.Out,"" + "" + ""); + Tbl_StartTable (2); + for (NumAns = 0; + NumAns < Rmt_MAX_ANSWERS_PER_QUESTION; + NumAns++) + { + * Label with the number of the answer * + fprintf (Gbl.F.Out,"" + "" + "" + "", + NumAns,The_ClassForm[Gbl.Prefs.Theme],NumAns + 1); + + * Answer text * + fprintf (Gbl.F.Out,"" + "" + "" + ""); + } + Tbl_EndTable (); + fprintf (Gbl.F.Out,"" + ""); + + ***** End table ***** + Tbl_EndTable (); + + ***** Send button ***** + if (GameQst->QstCod > 0) // If the question already has assigned a code + Btn_PutConfirmButton (Txt_Save); + else + Btn_PutCreateButton (Txt_Create_question); + + ***** End form ***** + Act_FormEnd (); + + ***** End box ***** + Box_EndBox (); + + ***** Free memory for answers ***** + Rmt_FreeTextChoiceAnswers (GameQst,NumAnswers); + + */ + } + /*****************************************************************************/ /************************* Check if I can edit tests *************************/ /*****************************************************************************/ @@ -1369,7 +1632,7 @@ static void Tst_PutIconsTests (void) /**************** Put button to create a new test question *******************/ /*****************************************************************************/ -static void Tst_PutButtonToAddQuestion (void) +void Tst_PutButtonToAddQuestion (void) { extern const char *Txt_New_question; @@ -2319,9 +2582,9 @@ void Tst_ListQuestionsToEdit (void) unsigned long NumRows; /***** Get parameters, query the database and list the questions *****/ - if (Tst_GetParamsTst ()) // Get parameters from the form + if (Tst_GetParamsTst (Tst_EDIT_QUESTIONS)) // Get parameters from the form { - if ((NumRows = Tst_GetQuestionsForEdit (&mysql_res)) != 0) // Query database + if ((NumRows = Tst_GetQuestions (&mysql_res)) != 0) // Query database { /* Buttons for edition */ fprintf (Gbl.F.Out,"
"); @@ -2335,7 +2598,7 @@ void Tst_ListQuestionsToEdit (void) fprintf (Gbl.F.Out,"
"); /* Show the table with the questions */ - Tst_ListOneOrMoreQuestionsToEdit (NumRows,mysql_res); + Tst_ListOneOrMoreQuestions (NumRows,mysql_res); } /***** Free structure that stores the query result *****/ @@ -2349,13 +2612,45 @@ void Tst_ListQuestionsToEdit (void) Tst_FreeTagsList (); } +/*****************************************************************************/ +/**************** List several test questions for selection ******************/ +/*****************************************************************************/ + +void Tst_ListQuestionsToSelect (void) + { + long GamCod; + MYSQL_RES *mysql_res; + unsigned long NumRows; + + /***** Get game code *****/ + if ((GamCod = Rmt_GetParamGameCod ()) == -1L) + Lay_ShowErrorAndExit ("Code of game is missing."); + + /***** Get parameters, query the database and list the questions *****/ + if (Tst_GetParamsTst (Tst_SELECT_QUESTIONS_FOR_GAME)) // Get parameters from the form + { + if ((NumRows = Tst_GetQuestions (&mysql_res)) != 0) // Query database + /* Show the table with the questions */ + Tst_ListOneOrMoreQuestions (NumRows,mysql_res); + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + } + else + /* Show the form again */ + Tst_ShowFormAskSelectTstsForGame (GamCod); + + /***** Free memory used by the list of tags *****/ + Tst_FreeTagsList (); + } + /*****************************************************************************/ /********** Get from the database several test questions for listing *********/ /*****************************************************************************/ #define Tst_MAX_BYTES_QUERY_TEST (16 * 1024 - 1) -static unsigned long Tst_GetQuestionsForEdit (MYSQL_RES **mysql_res) +static unsigned long Tst_GetQuestions (MYSQL_RES **mysql_res) { extern const char *Txt_No_questions_found_matching_your_search_criteria; unsigned long NumRows; @@ -2656,7 +2951,7 @@ static void Tst_ListOneQstToEdit (void) /***** Query database *****/ if (Tst_GetOneQuestionByCod (Gbl.Test.QstCod,&mysql_res)) /***** Show the question ready to edit it *****/ - Tst_ListOneOrMoreQuestionsToEdit (1,mysql_res); + Tst_ListOneOrMoreQuestions (1,mysql_res); else Lay_ShowErrorAndExit ("Can not get question."); @@ -2702,7 +2997,7 @@ static bool Tst_GetOneQuestionByCod (long QstCod,MYSQL_RES **mysql_res) /****************** List for edition one or more test questions **************/ /*****************************************************************************/ -static void Tst_ListOneOrMoreQuestionsToEdit (unsigned long NumRows,MYSQL_RES *mysql_res) +static void Tst_ListOneOrMoreQuestions (unsigned long NumRows,MYSQL_RES *mysql_res) { extern const char *Hlp_ASSESSMENT_Tests; extern const char *Txt_Questions; @@ -4281,7 +4576,7 @@ static void Tst_GetAndWriteTagsQst (long QstCod) /*****************************************************************************/ // Return true (OK) if all parameters are found, or false (error) if any necessary parameter is not found -static bool Tst_GetParamsTst (void) +static bool Tst_GetParamsTst (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions) { extern const char *Txt_You_must_select_one_ore_more_tags; extern const char *Txt_You_must_select_one_ore_more_types_of_answer; @@ -4307,47 +4602,66 @@ static bool Tst_GetParamsTst (void) } /***** Types of answer *****/ - /* Get parameter that indicates if all types of answer are selected */ - Gbl.Test.AllAnsTypes = Par_GetParToBool ("AllAnsTypes"); + switch (ActionToDoWithQuestions) + { + case Tst_SHOW_QUESTIONS: + case Tst_EDIT_QUESTIONS: + /* Get parameter that indicates if all types of answer are selected */ + Gbl.Test.AllAnsTypes = Par_GetParToBool ("AllAnsTypes"); - /* Get types of answer */ - Par_GetParMultiToText ("AnswerType",Gbl.Test.ListAnsTypes,Tst_MAX_BYTES_LIST_ANSWER_TYPES); + /* Get types of answer */ + Par_GetParMultiToText ("AnswerType",Gbl.Test.ListAnsTypes,Tst_MAX_BYTES_LIST_ANSWER_TYPES); - /* Check number of types of answer */ - if (Tst_CountNumAnswerTypesInList () == 0) // If no types of answer selected... - { // ...write warning alert - Ale_ShowAlert (Ale_WARNING,Txt_You_must_select_one_ore_more_types_of_answer); - Error = true; + /* Check number of types of answer */ + if (Tst_CountNumAnswerTypesInList () == 0) // If no types of answer selected... + { // ...write warning alert + Ale_ShowAlert (Ale_WARNING,Txt_You_must_select_one_ore_more_types_of_answer); + Error = true; + } + break; + case Tst_SELECT_QUESTIONS_FOR_GAME: + /* The unique allowed type of answer in a game is unique choice */ + Gbl.Test.AllAnsTypes = false; + sprintf (Gbl.Test.ListAnsTypes,"%u",(unsigned) Tst_ANS_UNIQUE_CHOICE); + break; } /***** Get other parameters, depending on action *****/ - if (Gbl.Action.Act == ActSeeTst) + switch (ActionToDoWithQuestions) { - Tst_GetParamNumQst (); - if (Gbl.Test.NumQsts < Gbl.Test.Config.Min || - Gbl.Test.NumQsts > Gbl.Test.Config.Max) - { - sprintf (Gbl.Alert.Txt,Txt_The_number_of_questions_must_be_in_the_interval_X, - Gbl.Test.Config.Min,Gbl.Test.Config.Max); - Ale_ShowAlert (Ale_WARNING,Gbl.Alert.Txt); - Error = true; - } - } - else - { - /* Get starting and ending dates */ - Dat_GetIniEndDatesFromForm (); + case Tst_SHOW_QUESTIONS: + Tst_GetParamNumQst (); + if (Gbl.Test.NumQsts < Gbl.Test.Config.Min || + Gbl.Test.NumQsts > Gbl.Test.Config.Max) + { + sprintf (Gbl.Alert.Txt,Txt_The_number_of_questions_must_be_in_the_interval_X, + Gbl.Test.Config.Min,Gbl.Test.Config.Max); + Ale_ShowAlert (Ale_WARNING,Gbl.Alert.Txt); + Error = true; + } + break; + case Tst_EDIT_QUESTIONS: + /* Get starting and ending dates */ + Dat_GetIniEndDatesFromForm (); - /* Get ordering criteria */ - Par_GetParMultiToText ("Order",UnsignedStr,10); - if (sscanf (UnsignedStr,"%u",&UnsignedNum) == 1) - Gbl.Test.SelectedOrder = (Tst_QuestionsOrder_t) ((UnsignedNum < Tst_NUM_TYPES_ORDER_QST) ? UnsignedNum : - 0); - else - Gbl.Test.SelectedOrder = (Tst_QuestionsOrder_t) 0; + /* Get ordering criteria */ + Par_GetParMultiToText ("Order",UnsignedStr,10); + if (sscanf (UnsignedStr,"%u",&UnsignedNum) == 1) + Gbl.Test.SelectedOrder = (Tst_QuestionsOrder_t) ((UnsignedNum < Tst_NUM_TYPES_ORDER_QST) ? UnsignedNum : + 0); + else + Gbl.Test.SelectedOrder = (Tst_QuestionsOrder_t) 0; - /* Get whether we must create the XML file or not */ - Gbl.Test.XML.CreateXML = Tst_GetCreateXMLFromForm (); + /* Get whether we must create the XML file or not */ + Gbl.Test.XML.CreateXML = Tst_GetCreateXMLFromForm (); + break; + case Tst_SELECT_QUESTIONS_FOR_GAME: + /* Get starting and ending dates */ + Dat_GetIniEndDatesFromForm (); + + /* Order question by stem */ + Gbl.Test.SelectedOrder = Tst_ORDER_STEM; + break; } return !Error; @@ -5876,7 +6190,7 @@ void Tst_RequestRemoveQst (void) /* Get other parameters */ if (!EditingOnlyThisQst) - if (!Tst_GetParamsTst ()) + if (!Tst_GetParamsTst (Tst_EDIT_QUESTIONS)) Lay_ShowErrorAndExit ("Wrong test parameters."); /***** Show question and button to remove question *****/ diff --git a/swad_test.h b/swad_test.h index bd1d74647..5da130d9f 100644 --- a/swad_test.h +++ b/swad_test.h @@ -136,16 +136,20 @@ void Tst_WriteQstFeedback (const char *Feedback,const char *ClassFeedback); void Tst_SetIniEndDates (void); void Tst_ShowFormAskEditTsts (void); +void Tst_ShowFormAskSelectTstsForGame (long GamCod); void Tst_ListQuestionsToEdit (void); +void Tst_ListQuestionsToSelect (void); void Tst_WriteParamEditQst (void); unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle); void Tst_WriteAnsTF (char AnsTF); void Tst_CheckIfNumberOfAnswersIsOne (void); unsigned long Tst_GetTagsQst (long QstCod,MYSQL_RES **mysql_res); +void Tst_PutButtonToAddQuestion (void); void Tst_ShowFormConfig (void); void Tst_EnableTag (void); void Tst_DisableTag (void); void Tst_RenameTag (void); + void Tst_GetConfigFromRow (MYSQL_ROW row); bool Tst_CheckIfCourseHaveTestsAndPluggableIsUnknown (void); void Tst_ReceiveConfigTst (void); diff --git a/swad_text.c b/swad_text.c index cbdc9df0b..31b0363c9 100644 --- a/swad_text.c +++ b/swad_text.c @@ -17727,7 +17727,7 @@ const char *Txt_List_edit_questions = #elif L==8 "Wyświetlić / edytować pytania"; #elif L==9 - "listar / editar questões"; + "Listar / editar questões"; #endif const char *Txt_List_of_detailed_clicks = @@ -37286,6 +37286,27 @@ const char *Txt_Select_one_or_more_files_from_your_computer_or_drag_and_drop_her "ou arrastar e soltar aqui"; #endif +const char *Txt_Select_questions = +#if L==1 + "Seleccionar preguntes"; +#elif L==2 + "Wählen Sie Fragen"; +#elif L==3 + "Select questions"; +#elif L==4 + "Seleccionar preguntas"; +#elif L==5 + "Choisir questions"; +#elif L==6 + "Seleccionar preguntas"; // Okoteve traducción +#elif L==7 + "Selezionare domande"; +#elif L==8 + "Wybierz pytania"; +#elif L==9 + "Selecionar questões"; +#endif + const char *Txt_Select_the_groups_in_from_which_you_want_to_register_remove_users_ = #if L==1 "Seleccione los grupos en/de los que quiere inscribir/eliminar usuarios."