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