diff --git a/swad_action.c b/swad_action.c index 36c7b0a44..9388004f7 100644 --- a/swad_action.c +++ b/swad_action.c @@ -2191,7 +2191,7 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActHidGam */{1660,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_HideGame ,NULL}, /* ActShoGam */{1661,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_UnhideGame ,NULL}, /* ActAddOneGamQst */{1662,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RequestNewQuestion ,NULL}, - /* ActGamLstTstQst */{1666,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_ListQuestionsToSelect ,NULL}, + /* ActGamLstTstQst */{1666,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_ListTstQuestionsToSelect ,NULL}, /* ActAddTstQstToGam */{1667,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_AddTstQuestionsToGame ,NULL}, /* ActReqRemGamQst */{1664,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RequestRemoveQst ,NULL}, /* ActRemGamQst */{1665,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RemoveQst ,NULL}, diff --git a/swad_changelog.h b/swad_changelog.h index c50d036f5..74a1b7aec 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -470,12 +470,11 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.15 (2019-09-26)" +#define Log_PLATFORM_VERSION "SWAD 19.16 (2019-09-26)" #define CSS_FILE "swad19.15.css" #define JS_FILE "swad19.15.js" /* -// Version 19.*: Sep 26, 2019 TODO: Make it impossible to edit (create/delete/move) questions from a game when it has matches. (? lines) - + Version 19.16: Sep 26, 2019 Make it impossible to edit a game when it has matches. (246424 lines) Version 19.15: Sep 26, 2019 Refresh only left part of the teacher's screen when playing a match. (246332 lines) Version 19.14.6: Sep 26, 2019 Code refactoring related to match refreshing. (246294 lines) Version 19.14.5: Sep 26, 2019 Code refactoring related to match playing. (246291 lines) diff --git a/swad_game.c b/swad_game.c index 47e920dc7..b6df26ddc 100644 --- a/swad_game.c +++ b/swad_game.c @@ -582,7 +582,8 @@ static void Gam_PutFormsToRemEditOneGame (const struct Game *Game, Ico_PutContextualIconToUnhide (ActShoGam,Anchor,Gam_PutParams); /***** Put icon to edit game *****/ - Ico_PutContextualIconToEdit (ActEdiOneGam,Gam_PutParams); + if (!Game->NumMchs) // Edit only if match has no matches + Ico_PutContextualIconToEdit (ActEdiOneGam,Gam_PutParams); } /*****************************************************************************/ @@ -734,7 +735,7 @@ void Gam_GetDataOfGameByCod (struct Game *Game) case Rol_STD: Game->Status.ICanViewResults = Game->NumQsts != 0 && Game->Status.Visible; - Game->Status.ICanEdit = false; + Game->Status.ICanEdit = false; break; case Rol_NET: Game->Status.ICanViewResults = Game->NumQsts != 0; @@ -1042,6 +1043,7 @@ void Gam_RequestCreatOrEditGame (void) extern const char *Hlp_ASSESSMENT_Games_new_game; extern const char *Hlp_ASSESSMENT_Games_edit_game; extern const char *The_ClassFormInBox[The_NUM_THEMES]; + extern const char *Txt_You_can_not_edit_a_game_with_matches; extern const char *Txt_New_game; extern const char *Txt_Edit_game; extern const char *Txt_Title; @@ -1058,89 +1060,96 @@ void Gam_RequestCreatOrEditGame (void) Gbl.Games.CurrentPage = Pag_GetParamPagNum (Pag_GAMES); /***** Get the code of the game *****/ - ItsANewGame = ((Game.GamCod = Gam_GetParamGameCod ()) == -1L); + Game.GamCod = Gam_GetParamGameCod (); - /***** Get from the database the data of the game *****/ - if (ItsANewGame) - { - /***** Put link (form) to create new game *****/ - if (!Gam_CheckIfICanEditGames ()) - Lay_ShowErrorAndExit ("You can not create a new game here."); - - /* Initialize to empty game */ - Gam_ResetGame (&Game,Gbl.Usrs.Me.UsrDat.UsrCod); - } + /***** Check if game has matches *****/ + if ((Game.NumMchs = Gam_GetNumMchsGame (Game.GamCod))) + Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_edit_a_game_with_matches); else { - /* Get data of the game from database */ - Gam_GetDataOfGameByCod (&Game); - if (!Game.Status.ICanEdit) - Lay_ShowErrorAndExit ("You can not update this game."); + /***** Get from the database the data of the game *****/ + ItsANewGame = (Game.GamCod < 0); + if (ItsANewGame) + { + /***** Put link (form) to create new game *****/ + if (!Gam_CheckIfICanEditGames ()) + Lay_ShowErrorAndExit ("You can not create a new game here."); - /* Get text of the game from database */ - Gam_GetGameTxtFromDB (Game.GamCod,Txt); + /* Initialize to empty game */ + Gam_ResetGame (&Game,Gbl.Usrs.Me.UsrDat.UsrCod); + } + else + { + /* Get data of the game from database */ + Gam_GetDataOfGameByCod (&Game); + if (!Game.Status.ICanEdit) + Lay_ShowErrorAndExit ("You can not update this game."); + + /* Get text of the game from database */ + Gam_GetGameTxtFromDB (Game.GamCod,Txt); + } + + /***** Start form *****/ + Gam_CurrentGamCod = Game.GamCod; + Frm_StartForm (ItsANewGame ? ActNewGam : + ActChgGam); + Gam_PutParams (); + + /***** Start box and table *****/ + if (ItsANewGame) + Box_StartBoxTable (NULL,Txt_New_game,NULL, + Hlp_ASSESSMENT_Games_new_game,Box_NOT_CLOSABLE,2); + else + Box_StartBoxTable (NULL, + Game.Title[0] ? Game.Title : + Txt_Edit_game, + NULL, + Hlp_ASSESSMENT_Games_edit_game,Box_NOT_CLOSABLE,2); + + /***** Game title *****/ + fprintf (Gbl.F.Out,"" + "" + "" + "" + "" + "" + "" + "", + The_ClassFormInBox[Gbl.Prefs.Theme], + Txt_Title, + Gam_MAX_CHARS_TITLE,Game.Title); + + /***** Game text *****/ + fprintf (Gbl.F.Out,"" + "" + "" + "" + "" + "" + "" + ""); + + /***** End table, send button and end box *****/ + if (ItsANewGame) + Box_EndBoxTableWithButton (Btn_CREATE_BUTTON,Txt_Create_game); + else + Box_EndBoxTableWithButton (Btn_CONFIRM_BUTTON,Txt_Save_changes); + + /***** End form *****/ + Frm_EndForm (); + + /***** Show questions of the game ready to be edited *****/ + if (!ItsANewGame) + Gam_ListGameQuestions (&Game); } - - /***** Start form *****/ - Gam_CurrentGamCod = Game.GamCod; - Frm_StartForm (ItsANewGame ? ActNewGam : - ActChgGam); - Gam_PutParams (); - - /***** Start box and table *****/ - if (ItsANewGame) - Box_StartBoxTable (NULL,Txt_New_game,NULL, - Hlp_ASSESSMENT_Games_new_game,Box_NOT_CLOSABLE,2); - else - Box_StartBoxTable (NULL, - Game.Title[0] ? Game.Title : - Txt_Edit_game, - NULL, - Hlp_ASSESSMENT_Games_edit_game,Box_NOT_CLOSABLE,2); - - /***** Game title *****/ - fprintf (Gbl.F.Out,"" - "" - "" - "" - "" - "" - "" - "", - The_ClassFormInBox[Gbl.Prefs.Theme], - Txt_Title, - Gam_MAX_CHARS_TITLE,Game.Title); - - /***** Game text *****/ - fprintf (Gbl.F.Out,"" - "" - "" - "" - "" - "" - "" - ""); - - /***** End table, send button and end box *****/ - if (ItsANewGame) - Box_EndBoxTableWithButton (Btn_CREATE_BUTTON,Txt_Create_game); - else - Box_EndBoxTableWithButton (Btn_CONFIRM_BUTTON,Txt_Save_changes); - - /***** End form *****/ - Frm_EndForm (); - - /***** Show questions of the game ready to be edited *****/ - if (!ItsANewGame) - Gam_ListGameQuestions (&Game); } /*****************************************************************************/ @@ -1149,6 +1158,7 @@ void Gam_RequestCreatOrEditGame (void) void Gam_RecFormGame (void) { + extern const char *Txt_You_can_not_edit_a_game_with_matches; extern const char *Txt_Already_existed_a_game_with_the_title_X; extern const char *Txt_You_must_specify_the_title_of_the_game; struct Game OldGame; @@ -1158,50 +1168,57 @@ void Gam_RecFormGame (void) char Txt[Cns_MAX_BYTES_TEXT + 1]; /***** Get the code of the game *****/ - ItsANewGame = ((NewGame.GamCod = Gam_GetParamGameCod ()) == -1L); + NewGame.GamCod = Gam_GetParamGameCod (); - if (!ItsANewGame) - { - /* Get data of the old (current) game from database */ - OldGame.GamCod = NewGame.GamCod; - Gam_GetDataOfGameByCod (&OldGame); - if (!OldGame.Status.ICanEdit) - Lay_ShowErrorAndExit ("You can not update this game."); - } - - /***** Get game title *****/ - Par_GetParToText ("Title",NewGame.Title,Gam_MAX_BYTES_TITLE); - - /***** Get game text and insert links *****/ - Par_GetParToHTML ("Txt",Txt,Cns_MAX_BYTES_TEXT); // Store in HTML format (not rigorous) - - /***** Check if title is correct *****/ - if (NewGame.Title[0]) // If there's a game title - { - /* If title of game was in database... */ - if (Gam_CheckIfSimilarGameExists (&NewGame)) - { - NewGameIsCorrect = false; - Ale_ShowAlert (Ale_WARNING,Txt_Already_existed_a_game_with_the_title_X, - NewGame.Title); - } - } - else // If there is not a game title - { - NewGameIsCorrect = false; - Ale_ShowAlert (Ale_WARNING,Txt_You_must_specify_the_title_of_the_game); - } - - /***** Create a new game or update an existing one *****/ - if (NewGameIsCorrect) - { - if (ItsANewGame) - Gam_CreateGame (&NewGame,Txt); // Add new game to database - else - Gam_UpdateGame (&NewGame,Txt); - } + /***** Check if game has matches *****/ + if ((NewGame.NumMchs = Gam_GetNumMchsGame (NewGame.GamCod))) + Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_edit_a_game_with_matches); else - Gam_RequestCreatOrEditGame (); + { + ItsANewGame = (NewGame.GamCod < 0); + if (!ItsANewGame) + { + /* Get data of the old (current) game from database */ + OldGame.GamCod = NewGame.GamCod; + Gam_GetDataOfGameByCod (&OldGame); + if (!OldGame.Status.ICanEdit) + Lay_ShowErrorAndExit ("You can not update this game."); + } + + /***** Get game title *****/ + Par_GetParToText ("Title",NewGame.Title,Gam_MAX_BYTES_TITLE); + + /***** Get game text and insert links *****/ + Par_GetParToHTML ("Txt",Txt,Cns_MAX_BYTES_TEXT); // Store in HTML format (not rigorous) + + /***** Check if title is correct *****/ + if (NewGame.Title[0]) // If there's a game title + { + /* If title of game was in database... */ + if (Gam_CheckIfSimilarGameExists (&NewGame)) + { + NewGameIsCorrect = false; + Ale_ShowAlert (Ale_WARNING,Txt_Already_existed_a_game_with_the_title_X, + NewGame.Title); + } + } + else // If there is not a game title + { + NewGameIsCorrect = false; + Ale_ShowAlert (Ale_WARNING,Txt_You_must_specify_the_title_of_the_game); + } + + /***** Create a new game or update an existing one *****/ + if (NewGameIsCorrect) + { + if (ItsANewGame) + Gam_CreateGame (&NewGame,Txt); // Add new game to database + else + Gam_UpdateGame (&NewGame,Txt); + } + else + Gam_RequestCreatOrEditGame (); + } /***** Show games again *****/ Gam_ListAllGames (); @@ -1378,19 +1395,26 @@ unsigned Gam_GetNumQstsGame (long GamCod) void Gam_RequestNewQuestion (void) { + extern const char *Txt_You_can_not_edit_a_game_with_matches; struct Game Game; /***** Get game code *****/ if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) Lay_ShowErrorAndExit ("Code of game is missing."); - /***** Get other parameters *****/ - Gam_GetParamOrder (); - Grp_GetParamWhichGrps (); - Gbl.Games.CurrentPage = Pag_GetParamPagNum (Pag_GAMES); + /***** Check if game has matches *****/ + if ((Game.NumMchs = Gam_GetNumMchsGame (Game.GamCod))) + Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_edit_a_game_with_matches); + else + { + /***** Get other parameters *****/ + Gam_GetParamOrder (); + Grp_GetParamWhichGrps (); + Gbl.Games.CurrentPage = Pag_GetParamPagNum (Pag_GAMES); - /***** Show form to create a new question in this game *****/ - Tst_ShowFormAskSelectTstsForGame (Game.GamCod); + /***** Show form to create a new question in this game *****/ + Tst_ShowFormAskSelectTstsForGame (Game.GamCod); + } /***** Show current game *****/ Gam_ShowOneGame (Game.GamCod, @@ -1399,6 +1423,27 @@ void Gam_RequestNewQuestion (void) false); // Do not put form to start new match } +/*****************************************************************************/ +/**************** List several test questions for selection ******************/ +/*****************************************************************************/ + +void Gam_ListTstQuestionsToSelect (void) + { + extern const char *Txt_You_can_not_edit_a_game_with_matches; + struct Game Game; + + /***** Get game code *****/ + if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) + Lay_ShowErrorAndExit ("Code of game is missing."); + + /***** Check if game has matches *****/ + if ((Game.NumMchs = Gam_GetNumMchsGame (Game.GamCod))) + Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_edit_a_game_with_matches); + else + /***** List several test questions for selection *****/ + Tst_ListQuestionsToSelect (Game.GamCod); + } + /*****************************************************************************/ /****************** Write parameter with index of question *******************/ /*****************************************************************************/ @@ -1841,6 +1886,7 @@ static void Gam_PutButtonToAddNewQuestions (void) void Gam_AddTstQuestionsToGame (void) { + extern const char *Txt_You_can_not_edit_a_game_with_matches; extern const char *Txt_You_must_select_one_ore_more_questions; struct Game Game; const char *Ptr; @@ -1852,46 +1898,52 @@ void Gam_AddTstQuestionsToGame (void) if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) Lay_ShowErrorAndExit ("Code of game is missing."); - /***** Get selected questions *****/ - /* Allocate space for selected question codes */ - Gam_AllocateListSelectedQuestions (); - - /* Get question codes */ - Par_GetParMultiToText ("QstCods",Gbl.Games.ListQuestions, - Gam_MAX_BYTES_LIST_SELECTED_QUESTIONS); - - /* Check number of questions */ - if (Gam_CountNumQuestionsInList () == 0) // If no questions selected... - { // ...write warning alert - Ale_ShowAlert (Ale_WARNING,Txt_You_must_select_one_ore_more_questions); - - // TODO: Show form again!!! - } - - /***** Insert questions in database *****/ - Ptr = Gbl.Games.ListQuestions; - while (*Ptr) + /***** Check if game has matches *****/ + if ((Game.NumMchs = Gam_GetNumMchsGame (Game.GamCod))) + Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_edit_a_game_with_matches); + else { - /* Get next code */ - Par_GetNextStrUntilSeparParamMult (&Ptr,LongStr,1 + 10); - if (sscanf (LongStr,"%ld",&QstCod) != 1) - Lay_ShowErrorAndExit ("Wrong question code."); + /***** Get selected questions *****/ + /* Allocate space for selected question codes */ + Gam_AllocateListSelectedQuestions (); - /* Get current maximum index */ - MaxQstInd = Gam_GetMaxQuestionIndexInGame (Game.GamCod); // -1 if no questions + /* Get question codes */ + Par_GetParMultiToText ("QstCods",Gbl.Games.ListQuestions, + Gam_MAX_BYTES_LIST_SELECTED_QUESTIONS); - /* Insert question in the table of questions */ - DB_QueryINSERT ("can not create question", - "INSERT INTO gam_questions" - " (GamCod,QstCod,QstInd)" - " VALUES" - " (%ld,%ld,%u)", - Game.GamCod,QstCod,MaxQstInd + 1); + /* Check number of questions */ + if (Gam_CountNumQuestionsInList () == 0) // If no questions selected... + { // ...write warning alert + Ale_ShowAlert (Ale_WARNING,Txt_You_must_select_one_ore_more_questions); + + // TODO: Show form again!!! + } + + /***** Insert questions in database *****/ + Ptr = Gbl.Games.ListQuestions; + while (*Ptr) + { + /* Get next code */ + Par_GetNextStrUntilSeparParamMult (&Ptr,LongStr,1 + 10); + if (sscanf (LongStr,"%ld",&QstCod) != 1) + Lay_ShowErrorAndExit ("Wrong question code."); + + /* Get current maximum index */ + MaxQstInd = Gam_GetMaxQuestionIndexInGame (Game.GamCod); // -1 if no questions + + /* Insert question in the table of questions */ + DB_QueryINSERT ("can not create question", + "INSERT INTO gam_questions" + " (GamCod,QstCod,QstInd)" + " VALUES" + " (%ld,%ld,%u)", + Game.GamCod,QstCod,MaxQstInd + 1); + } + + /***** Free space for selected question codes *****/ + Gam_FreeListsSelectedQuestions (); } - /***** Free space for selected question codes *****/ - Gam_FreeListsSelectedQuestions (); - /***** Show current game *****/ Gam_ShowOneGame (Game.GamCod, true, // Show only this game @@ -1965,26 +2017,32 @@ static void Gam_PutParamsOneQst (void) void Gam_RequestRemoveQst (void) { + extern const char *Txt_You_can_not_edit_a_game_with_matches; extern const char *Txt_Do_you_really_want_to_remove_the_question_X; extern const char *Txt_Remove_question; struct Game Game; unsigned QstInd; - /***** Get parameters *****/ - /* Get game code */ + /***** Get game code *****/ if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) Lay_ShowErrorAndExit ("Code of game is missing."); - /* Get question index */ - QstInd = Gam_GetParamQstInd (); + /***** Check if game has matches *****/ + if ((Game.NumMchs = Gam_GetNumMchsGame (Game.GamCod))) + Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_edit_a_game_with_matches); + else + { + /***** Get question index *****/ + QstInd = Gam_GetParamQstInd (); - /***** Show question and button to remove question *****/ - Gam_CurrentGamCod = Game.GamCod; - Gam_CurrentQstInd = QstInd; - Ale_ShowAlertAndButton (ActRemGamQst,NULL,NULL,Gam_PutParamsOneQst, - Btn_REMOVE_BUTTON,Txt_Remove_question, - Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_question_X, - QstInd); + /***** Show question and button to remove question *****/ + Gam_CurrentGamCod = Game.GamCod; + Gam_CurrentQstInd = QstInd; + Ale_ShowAlertAndButton (ActRemGamQst,NULL,NULL,Gam_PutParamsOneQst, + Btn_REMOVE_BUTTON,Txt_Remove_question, + Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_question_X, + QstInd); + } /***** Show current game *****/ Gam_ShowOneGame (Game.GamCod, @@ -1999,45 +2057,51 @@ void Gam_RequestRemoveQst (void) void Gam_RemoveQst (void) { + extern const char *Txt_You_can_not_edit_a_game_with_matches; extern const char *Txt_Question_removed; struct Game Game; unsigned QstInd; - /***** Get parameters *****/ - /* Get game code */ + /***** Get game code *****/ if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) Lay_ShowErrorAndExit ("Code of game is missing."); - /* Get question index */ - QstInd = Gam_GetParamQstInd (); + /***** Check if game has matches *****/ + if ((Game.NumMchs = Gam_GetNumMchsGame (Game.GamCod))) + Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_edit_a_game_with_matches); + else + { + /***** Get question index *****/ + QstInd = Gam_GetParamQstInd (); - /***** Remove the question from all the tables *****/ - /* Remove answers from this test question */ - Gam_RemAnswersOfAQuestion (Game.GamCod,QstInd); + /***** Remove the question from all the tables *****/ + /* Remove answers from this test question */ + Gam_RemAnswersOfAQuestion (Game.GamCod,QstInd); - /* Remove the question itself */ - DB_QueryDELETE ("can not remove a question", - "DELETE FROM gam_questions" - " WHERE GamCod=%ld AND QstInd=%u", - Game.GamCod,QstInd); - if (!mysql_affected_rows (&Gbl.mysql)) - Lay_ShowErrorAndExit ("The question to be removed does not exist."); + /* Remove the question itself */ + DB_QueryDELETE ("can not remove a question", + "DELETE FROM gam_questions" + " WHERE GamCod=%ld AND QstInd=%u", + Game.GamCod,QstInd); + if (!mysql_affected_rows (&Gbl.mysql)) + Lay_ShowErrorAndExit ("The question to be removed does not exist."); - /* Change index of questions greater than this */ - DB_QueryUPDATE ("can not update indexes of questions in table of answers", - "UPDATE mch_answers,mch_matches" - " SET mch_answers.QstInd=mch_answers.QstInd-1" - " WHERE mch_matches.GamCod=%ld" - " WHERE mch_matches.MchCod=mch_answers.MchCod" - " AND mch_answers.QstInd>%u", - Game.GamCod,QstInd); - DB_QueryUPDATE ("can not update indexes of questions", - "UPDATE gam_questions SET QstInd=QstInd-1" - " WHERE GamCod=%ld AND QstInd>%u", - Game.GamCod,QstInd); + /* Change index of questions greater than this */ + DB_QueryUPDATE ("can not update indexes of questions in table of answers", + "UPDATE mch_answers,mch_matches" + " SET mch_answers.QstInd=mch_answers.QstInd-1" + " WHERE mch_matches.GamCod=%ld" + " WHERE mch_matches.MchCod=mch_answers.MchCod" + " AND mch_answers.QstInd>%u", + Game.GamCod,QstInd); + DB_QueryUPDATE ("can not update indexes of questions", + "UPDATE gam_questions SET QstInd=QstInd-1" + " WHERE GamCod=%ld AND QstInd>%u", + Game.GamCod,QstInd); - /***** Write message *****/ - Ale_ShowAlert (Ale_SUCCESS,Txt_Question_removed); + /***** Write message *****/ + Ale_ShowAlert (Ale_SUCCESS,Txt_Question_removed); + } /***** Show current game *****/ Gam_ShowOneGame (Game.GamCod, @@ -2052,36 +2116,42 @@ void Gam_RemoveQst (void) void Gam_MoveUpQst (void) { + extern const char *Txt_You_can_not_edit_a_game_with_matches; extern const char *Txt_The_question_has_been_moved_up; extern const char *Txt_Movement_not_allowed; struct Game Game; unsigned QstIndTop; unsigned QstIndBottom; - /***** Get parameters *****/ - /* Get game code */ + /***** Get game code *****/ if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) Lay_ShowErrorAndExit ("Code of game is missing."); - /* Get question index */ - QstIndBottom = Gam_GetParamQstInd (); - - /***** Move up question *****/ - if (QstIndBottom > 1) - { - /* Indexes of questions to be exchanged */ - QstIndTop = Gam_GetPrevQuestionIndexInGame (Game.GamCod,QstIndBottom); - if (!QstIndTop) - Lay_ShowErrorAndExit ("Wrong index of question."); - - /* Exchange questions */ - Gam_ExchangeQuestions (Game.GamCod,QstIndTop,QstIndBottom); - - /* Success alert */ - Ale_ShowAlert (Ale_SUCCESS,Txt_The_question_has_been_moved_up); - } + /***** Check if game has matches *****/ + if ((Game.NumMchs = Gam_GetNumMchsGame (Game.GamCod))) + Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_edit_a_game_with_matches); else - Ale_ShowAlert (Ale_WARNING,Txt_Movement_not_allowed); + { + /***** Get question index *****/ + QstIndBottom = Gam_GetParamQstInd (); + + /***** Move up question *****/ + if (QstIndBottom > 1) + { + /* Indexes of questions to be exchanged */ + QstIndTop = Gam_GetPrevQuestionIndexInGame (Game.GamCod,QstIndBottom); + if (!QstIndTop) + Lay_ShowErrorAndExit ("Wrong index of question."); + + /* Exchange questions */ + Gam_ExchangeQuestions (Game.GamCod,QstIndTop,QstIndBottom); + + /* Success alert */ + Ale_ShowAlert (Ale_SUCCESS,Txt_The_question_has_been_moved_up); + } + else + Ale_ShowAlert (Ale_WARNING,Txt_Movement_not_allowed); + } /***** Show current game *****/ Gam_ShowOneGame (Game.GamCod, @@ -2096,6 +2166,7 @@ void Gam_MoveUpQst (void) void Gam_MoveDownQst (void) { + extern const char *Txt_You_can_not_edit_a_game_with_matches; 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; @@ -2104,38 +2175,43 @@ void Gam_MoveDownQst (void) unsigned QstIndBottom; unsigned MaxQstInd; // 0 if no questions - /***** Get parameters *****/ - /* Get game code */ + /***** Get game code *****/ if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) Lay_ShowErrorAndExit ("Code of game is missing."); - /* Get question index */ - QstIndTop = Gam_GetParamQstInd (); - - /* Get maximum question index */ - MaxQstInd = Gam_GetMaxQuestionIndexInGame (Game.GamCod); - - /***** Move down question *****/ - if (MaxQstInd) + /***** Check if game has matches *****/ + if ((Game.NumMchs = Gam_GetNumMchsGame (Game.GamCod))) + Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_edit_a_game_with_matches); + else { - if (QstIndTop < MaxQstInd) + /***** Get question index *****/ + QstIndTop = Gam_GetParamQstInd (); + + /***** Get maximum question index *****/ + MaxQstInd = Gam_GetMaxQuestionIndexInGame (Game.GamCod); + + /***** Move down question *****/ + if (MaxQstInd) { - /* Indexes of questions to be exchanged */ - QstIndBottom = Gam_GetNextQuestionIndexInGame (Game.GamCod,QstIndTop); - if (!QstIndBottom) - Lay_ShowErrorAndExit ("Wrong index of question."); + if (QstIndTop < MaxQstInd) + { + /* Indexes of questions to be exchanged */ + QstIndBottom = Gam_GetNextQuestionIndexInGame (Game.GamCod,QstIndTop); + if (!QstIndBottom) + Lay_ShowErrorAndExit ("Wrong index of question."); - /* Exchange questions */ - Gam_ExchangeQuestions (Game.GamCod,QstIndTop,QstIndBottom); + /* Exchange questions */ + Gam_ExchangeQuestions (Game.GamCod,QstIndTop,QstIndBottom); - /* Success alert */ - Ale_ShowAlert (Ale_SUCCESS,Txt_The_question_has_been_moved_down); + /* Success alert */ + 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_Movement_not_allowed); + Ale_ShowAlert (Ale_WARNING,Txt_This_game_has_no_questions); } - else - Ale_ShowAlert (Ale_WARNING,Txt_This_game_has_no_questions); /***** Show current game *****/ Gam_ShowOneGame (Game.GamCod, diff --git a/swad_game.h b/swad_game.h index 327db4232..e21e8d805 100644 --- a/swad_game.h +++ b/swad_game.h @@ -103,6 +103,8 @@ void Gam_RemoveGamesCrs (long CrsCod); unsigned Gam_GetNumQstsGame (long GamCod); void Gam_RequestNewQuestion (void); +void Gam_ListTstQuestionsToSelect (void); + void Gam_PutParamQstInd (unsigned QstInd); unsigned Gam_GetParamQstInd (void); unsigned Gam_GetQstIndFromStr (const char *UnsignedStr); diff --git a/swad_match.c b/swad_match.c index 9dc515fa1..abd896332 100644 --- a/swad_match.c +++ b/swad_match.c @@ -1946,6 +1946,10 @@ static void Mch_ShowMatchStatusForStd (struct Match *Match) unsigned Gam_GetNumMchsGame (long GamCod) { + /***** Trivial check *****/ + if (GamCod < 0) // A non-existing game... + return 0; // ...has no matches + /***** Get number of matches in a game from database *****/ return (unsigned) DB_QueryCOUNT ("can not get number of matches of a game", diff --git a/swad_test.c b/swad_test.c index 7466ddbc3..4afe8aae2 100644 --- a/swad_test.c +++ b/swad_test.c @@ -2413,16 +2413,11 @@ void Tst_ListQuestionsToEdit (void) /**************** List several test questions for selection ******************/ /*****************************************************************************/ -void Tst_ListQuestionsToSelect (void) +void Tst_ListQuestionsToSelect (long GamCod) { - long GamCod; MYSQL_RES *mysql_res; unsigned long NumRows; - /***** Get game code *****/ - if ((GamCod = Gam_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 { diff --git a/swad_test.h b/swad_test.h index 050f2b504..5cb70b536 100644 --- a/swad_test.h +++ b/swad_test.h @@ -150,7 +150,7 @@ void Tst_WriteQstFeedback (const char *Feedback,const char *ClassFeedback); void Tst_ShowFormAskEditTsts (void); void Tst_ShowFormAskSelectTstsForGame (long GamCod); void Tst_ListQuestionsToEdit (void); -void Tst_ListQuestionsToSelect (void); +void Tst_ListQuestionsToSelect (long GamCod); bool Tst_GetOneQuestionByCod (long QstCod,MYSQL_RES **mysql_res); void Tst_WriteParamEditQst (void); unsigned Tst_GetNumAnswersQst (long QstCod); diff --git a/swad_text.c b/swad_text.c index 094834455..12a6c7c18 100644 --- a/swad_text.c +++ b/swad_text.c @@ -54243,6 +54243,28 @@ const char *Txt_You_can_not_disable_file_uploading_once_folders_have_been_create " uma vez diretórios foram criados."; #endif +const char *Txt_You_can_not_edit_a_game_with_matches = +#if L==1 // ca + "No es pot editar un joc amb partides."; +#elif L==2 // de + "Sie können ein Spiel mit Matche nicht bearbeiten."; +#elif L==3 // en + "You can not edit a game with matches."; +#elif L==4 // es + "No se puede editar un juego con partidas."; +#elif L==5 // fr + "Vous ne pouvez pas éditer un jeu avec des matchs."; +#elif L==6 // gn + "No se puede editar un juego con partidas."; // Okoteve traducción +#elif L==7 // it + "Non è possibile modificare un gioco con i partite."; +#elif L==8 // pl + "Nie można edytować gry za pomocą mecze."; +#elif L==9 // pt + "Você não pode editar um jogo com partidas."; +#endif + + const char *Txt_You_can_not_leave_empty_intermediate_answers = #if L==1 // ca "No puede dejar respuestas intermedias sin rellenar."; // Necessita traduccio