Version19.16

This commit is contained in:
Antonio Cañas Vargas 2019-09-26 21:27:36 +02:00
parent 84bd388258
commit cf2a210545
8 changed files with 353 additions and 255 deletions

View File

@ -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}, /* 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}, /* 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}, /* 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}, /* 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}, /* 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}, /* ActRemGamQst */{1665,-1,TabUnk,ActSeeAllGam ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Gam_RemoveQst ,NULL},

View File

@ -470,12 +470,11 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
En OpenSWAD: En OpenSWAD:
ps2pdf source.ps destination.pdf 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 CSS_FILE "swad19.15.css"
#define JS_FILE "swad19.15.js" #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.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.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) Version 19.14.5: Sep 26, 2019 Code refactoring related to match playing. (246291 lines)

View File

@ -582,7 +582,8 @@ static void Gam_PutFormsToRemEditOneGame (const struct Game *Game,
Ico_PutContextualIconToUnhide (ActShoGam,Anchor,Gam_PutParams); Ico_PutContextualIconToUnhide (ActShoGam,Anchor,Gam_PutParams);
/***** Put icon to edit game *****/ /***** 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: case Rol_STD:
Game->Status.ICanViewResults = Game->NumQsts != 0 && Game->Status.ICanViewResults = Game->NumQsts != 0 &&
Game->Status.Visible; Game->Status.Visible;
Game->Status.ICanEdit = false; Game->Status.ICanEdit = false;
break; break;
case Rol_NET: case Rol_NET:
Game->Status.ICanViewResults = Game->NumQsts != 0; 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_new_game;
extern const char *Hlp_ASSESSMENT_Games_edit_game; extern const char *Hlp_ASSESSMENT_Games_edit_game;
extern const char *The_ClassFormInBox[The_NUM_THEMES]; 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_New_game;
extern const char *Txt_Edit_game; extern const char *Txt_Edit_game;
extern const char *Txt_Title; extern const char *Txt_Title;
@ -1058,89 +1060,96 @@ void Gam_RequestCreatOrEditGame (void)
Gbl.Games.CurrentPage = Pag_GetParamPagNum (Pag_GAMES); Gbl.Games.CurrentPage = Pag_GetParamPagNum (Pag_GAMES);
/***** Get the code of the game *****/ /***** 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 *****/ /***** Check if game has matches *****/
if (ItsANewGame) if ((Game.NumMchs = Gam_GetNumMchsGame (Game.GamCod)))
{ Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_edit_a_game_with_matches);
/***** 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);
}
else else
{ {
/* Get data of the game from database */ /***** Get from the database the data of the game *****/
Gam_GetDataOfGameByCod (&Game); ItsANewGame = (Game.GamCod < 0);
if (!Game.Status.ICanEdit) if (ItsANewGame)
Lay_ShowErrorAndExit ("You can not update this game."); {
/***** 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 */ /* Initialize to empty game */
Gam_GetGameTxtFromDB (Game.GamCod,Txt); 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,"<tr>"
"<td class=\"RIGHT_MIDDLE\">"
"<label for=\"Title\" class=\"%s\">%s:</label>"
"</td>"
"<td class=\"LEFT_MIDDLE\">"
"<input type=\"text\" id=\"Title\" name=\"Title\""
" size=\"45\" maxlength=\"%u\" value=\"%s\""
" required=\"required\" />"
"</td>"
"</tr>",
The_ClassFormInBox[Gbl.Prefs.Theme],
Txt_Title,
Gam_MAX_CHARS_TITLE,Game.Title);
/***** Game text *****/
fprintf (Gbl.F.Out,"<tr>"
"<td class=\"RIGHT_TOP\">"
"<label for=\"Txt\" class=\"%s\">%s:</label>"
"</td>"
"<td class=\"LEFT_TOP\">"
"<textarea id=\"Txt\" name=\"Txt\""
" cols=\"60\" rows=\"10\">",
The_ClassFormInBox[Gbl.Prefs.Theme],
Txt_Description);
if (!ItsANewGame)
fprintf (Gbl.F.Out,"%s",Txt);
fprintf (Gbl.F.Out,"</textarea>"
"</td>"
"</tr>");
/***** 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,"<tr>"
"<td class=\"RIGHT_MIDDLE\">"
"<label for=\"Title\" class=\"%s\">%s:</label>"
"</td>"
"<td class=\"LEFT_MIDDLE\">"
"<input type=\"text\" id=\"Title\" name=\"Title\""
" size=\"45\" maxlength=\"%u\" value=\"%s\""
" required=\"required\" />"
"</td>"
"</tr>",
The_ClassFormInBox[Gbl.Prefs.Theme],
Txt_Title,
Gam_MAX_CHARS_TITLE,Game.Title);
/***** Game text *****/
fprintf (Gbl.F.Out,"<tr>"
"<td class=\"RIGHT_TOP\">"
"<label for=\"Txt\" class=\"%s\">%s:</label>"
"</td>"
"<td class=\"LEFT_TOP\">"
"<textarea id=\"Txt\" name=\"Txt\""
" cols=\"60\" rows=\"10\">",
The_ClassFormInBox[Gbl.Prefs.Theme],
Txt_Description);
if (!ItsANewGame)
fprintf (Gbl.F.Out,"%s",Txt);
fprintf (Gbl.F.Out,"</textarea>"
"</td>"
"</tr>");
/***** 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) 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_Already_existed_a_game_with_the_title_X;
extern const char *Txt_You_must_specify_the_title_of_the_game; extern const char *Txt_You_must_specify_the_title_of_the_game;
struct Game OldGame; struct Game OldGame;
@ -1158,50 +1168,57 @@ void Gam_RecFormGame (void)
char Txt[Cns_MAX_BYTES_TEXT + 1]; char Txt[Cns_MAX_BYTES_TEXT + 1];
/***** Get the code of the game *****/ /***** Get the code of the game *****/
ItsANewGame = ((NewGame.GamCod = Gam_GetParamGameCod ()) == -1L); NewGame.GamCod = Gam_GetParamGameCod ();
if (!ItsANewGame) /***** Check if game has matches *****/
{ if ((NewGame.NumMchs = Gam_GetNumMchsGame (NewGame.GamCod)))
/* Get data of the old (current) game from database */ Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_edit_a_game_with_matches);
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 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 *****/ /***** Show games again *****/
Gam_ListAllGames (); Gam_ListAllGames ();
@ -1378,19 +1395,26 @@ unsigned Gam_GetNumQstsGame (long GamCod)
void Gam_RequestNewQuestion (void) void Gam_RequestNewQuestion (void)
{ {
extern const char *Txt_You_can_not_edit_a_game_with_matches;
struct Game Game; struct Game Game;
/***** Get game code *****/ /***** Get game code *****/
if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of game is missing."); Lay_ShowErrorAndExit ("Code of game is missing.");
/***** Get other parameters *****/ /***** Check if game has matches *****/
Gam_GetParamOrder (); if ((Game.NumMchs = Gam_GetNumMchsGame (Game.GamCod)))
Grp_GetParamWhichGrps (); Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_edit_a_game_with_matches);
Gbl.Games.CurrentPage = Pag_GetParamPagNum (Pag_GAMES); 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 *****/ /***** Show form to create a new question in this game *****/
Tst_ShowFormAskSelectTstsForGame (Game.GamCod); Tst_ShowFormAskSelectTstsForGame (Game.GamCod);
}
/***** Show current game *****/ /***** Show current game *****/
Gam_ShowOneGame (Game.GamCod, Gam_ShowOneGame (Game.GamCod,
@ -1399,6 +1423,27 @@ void Gam_RequestNewQuestion (void)
false); // Do not put form to start new match 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 *******************/ /****************** Write parameter with index of question *******************/
/*****************************************************************************/ /*****************************************************************************/
@ -1841,6 +1886,7 @@ static void Gam_PutButtonToAddNewQuestions (void)
void Gam_AddTstQuestionsToGame (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; extern const char *Txt_You_must_select_one_ore_more_questions;
struct Game Game; struct Game Game;
const char *Ptr; const char *Ptr;
@ -1852,46 +1898,52 @@ void Gam_AddTstQuestionsToGame (void)
if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of game is missing."); Lay_ShowErrorAndExit ("Code of game is missing.");
/***** Get selected questions *****/ /***** Check if game has matches *****/
/* Allocate space for selected question codes */ if ((Game.NumMchs = Gam_GetNumMchsGame (Game.GamCod)))
Gam_AllocateListSelectedQuestions (); Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_edit_a_game_with_matches);
else
/* 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)
{ {
/* Get next code */ /***** Get selected questions *****/
Par_GetNextStrUntilSeparParamMult (&Ptr,LongStr,1 + 10); /* Allocate space for selected question codes */
if (sscanf (LongStr,"%ld",&QstCod) != 1) Gam_AllocateListSelectedQuestions ();
Lay_ShowErrorAndExit ("Wrong question code.");
/* Get current maximum index */ /* Get question codes */
MaxQstInd = Gam_GetMaxQuestionIndexInGame (Game.GamCod); // -1 if no questions Par_GetParMultiToText ("QstCods",Gbl.Games.ListQuestions,
Gam_MAX_BYTES_LIST_SELECTED_QUESTIONS);
/* Insert question in the table of questions */ /* Check number of questions */
DB_QueryINSERT ("can not create question", if (Gam_CountNumQuestionsInList () == 0) // If no questions selected...
"INSERT INTO gam_questions" { // ...write warning alert
" (GamCod,QstCod,QstInd)" Ale_ShowAlert (Ale_WARNING,Txt_You_must_select_one_ore_more_questions);
" VALUES"
" (%ld,%ld,%u)", // TODO: Show form again!!!
Game.GamCod,QstCod,MaxQstInd + 1); }
/***** 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 *****/ /***** Show current game *****/
Gam_ShowOneGame (Game.GamCod, Gam_ShowOneGame (Game.GamCod,
true, // Show only this game true, // Show only this game
@ -1965,26 +2017,32 @@ static void Gam_PutParamsOneQst (void)
void Gam_RequestRemoveQst (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_Do_you_really_want_to_remove_the_question_X;
extern const char *Txt_Remove_question; extern const char *Txt_Remove_question;
struct Game Game; struct Game Game;
unsigned QstInd; unsigned QstInd;
/***** Get parameters *****/ /***** Get game code *****/
/* Get game code */
if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of game is missing."); Lay_ShowErrorAndExit ("Code of game is missing.");
/* Get question index */ /***** Check if game has matches *****/
QstInd = Gam_GetParamQstInd (); 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 *****/ /***** Show question and button to remove question *****/
Gam_CurrentGamCod = Game.GamCod; Gam_CurrentGamCod = Game.GamCod;
Gam_CurrentQstInd = QstInd; Gam_CurrentQstInd = QstInd;
Ale_ShowAlertAndButton (ActRemGamQst,NULL,NULL,Gam_PutParamsOneQst, Ale_ShowAlertAndButton (ActRemGamQst,NULL,NULL,Gam_PutParamsOneQst,
Btn_REMOVE_BUTTON,Txt_Remove_question, Btn_REMOVE_BUTTON,Txt_Remove_question,
Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_question_X, Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_question_X,
QstInd); QstInd);
}
/***** Show current game *****/ /***** Show current game *****/
Gam_ShowOneGame (Game.GamCod, Gam_ShowOneGame (Game.GamCod,
@ -1999,45 +2057,51 @@ void Gam_RequestRemoveQst (void)
void Gam_RemoveQst (void) void Gam_RemoveQst (void)
{ {
extern const char *Txt_You_can_not_edit_a_game_with_matches;
extern const char *Txt_Question_removed; extern const char *Txt_Question_removed;
struct Game Game; struct Game Game;
unsigned QstInd; unsigned QstInd;
/***** Get parameters *****/ /***** Get game code *****/
/* Get game code */
if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of game is missing."); Lay_ShowErrorAndExit ("Code of game is missing.");
/* Get question index */ /***** Check if game has matches *****/
QstInd = Gam_GetParamQstInd (); 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 the question from all the tables *****/
/* Remove answers from this test question */ /* Remove answers from this test question */
Gam_RemAnswersOfAQuestion (Game.GamCod,QstInd); Gam_RemAnswersOfAQuestion (Game.GamCod,QstInd);
/* Remove the question itself */ /* Remove the question itself */
DB_QueryDELETE ("can not remove a question", DB_QueryDELETE ("can not remove a question",
"DELETE FROM gam_questions" "DELETE FROM gam_questions"
" WHERE GamCod=%ld AND QstInd=%u", " WHERE GamCod=%ld AND QstInd=%u",
Game.GamCod,QstInd); Game.GamCod,QstInd);
if (!mysql_affected_rows (&Gbl.mysql)) if (!mysql_affected_rows (&Gbl.mysql))
Lay_ShowErrorAndExit ("The question to be removed does not exist."); Lay_ShowErrorAndExit ("The question to be removed does not exist.");
/* Change index of questions greater than this */ /* Change index of questions greater than this */
DB_QueryUPDATE ("can not update indexes of questions in table of answers", DB_QueryUPDATE ("can not update indexes of questions in table of answers",
"UPDATE mch_answers,mch_matches" "UPDATE mch_answers,mch_matches"
" SET mch_answers.QstInd=mch_answers.QstInd-1" " SET mch_answers.QstInd=mch_answers.QstInd-1"
" WHERE mch_matches.GamCod=%ld" " WHERE mch_matches.GamCod=%ld"
" WHERE mch_matches.MchCod=mch_answers.MchCod" " WHERE mch_matches.MchCod=mch_answers.MchCod"
" AND mch_answers.QstInd>%u", " AND mch_answers.QstInd>%u",
Game.GamCod,QstInd); Game.GamCod,QstInd);
DB_QueryUPDATE ("can not update indexes of questions", DB_QueryUPDATE ("can not update indexes of questions",
"UPDATE gam_questions SET QstInd=QstInd-1" "UPDATE gam_questions SET QstInd=QstInd-1"
" WHERE GamCod=%ld AND QstInd>%u", " WHERE GamCod=%ld AND QstInd>%u",
Game.GamCod,QstInd); Game.GamCod,QstInd);
/***** Write message *****/ /***** Write message *****/
Ale_ShowAlert (Ale_SUCCESS,Txt_Question_removed); Ale_ShowAlert (Ale_SUCCESS,Txt_Question_removed);
}
/***** Show current game *****/ /***** Show current game *****/
Gam_ShowOneGame (Game.GamCod, Gam_ShowOneGame (Game.GamCod,
@ -2052,36 +2116,42 @@ void Gam_RemoveQst (void)
void Gam_MoveUpQst (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_The_question_has_been_moved_up;
extern const char *Txt_Movement_not_allowed; extern const char *Txt_Movement_not_allowed;
struct Game Game; struct Game Game;
unsigned QstIndTop; unsigned QstIndTop;
unsigned QstIndBottom; unsigned QstIndBottom;
/***** Get parameters *****/ /***** Get game code *****/
/* Get game code */
if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of game is missing."); Lay_ShowErrorAndExit ("Code of game is missing.");
/* Get question index */ /***** Check if game has matches *****/
QstIndBottom = Gam_GetParamQstInd (); if ((Game.NumMchs = Gam_GetNumMchsGame (Game.GamCod)))
Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_edit_a_game_with_matches);
/***** 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 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 *****/ /***** Show current game *****/
Gam_ShowOneGame (Game.GamCod, Gam_ShowOneGame (Game.GamCod,
@ -2096,6 +2166,7 @@ void Gam_MoveUpQst (void)
void Gam_MoveDownQst (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_The_question_has_been_moved_down;
extern const char *Txt_Movement_not_allowed; extern const char *Txt_Movement_not_allowed;
extern const char *Txt_This_game_has_no_questions; extern const char *Txt_This_game_has_no_questions;
@ -2104,38 +2175,43 @@ void Gam_MoveDownQst (void)
unsigned QstIndBottom; unsigned QstIndBottom;
unsigned MaxQstInd; // 0 if no questions unsigned MaxQstInd; // 0 if no questions
/***** Get parameters *****/ /***** Get game code *****/
/* Get game code */
if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L) if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of game is missing."); Lay_ShowErrorAndExit ("Code of game is missing.");
/* Get question index */ /***** Check if game has matches *****/
QstIndTop = Gam_GetParamQstInd (); if ((Game.NumMchs = Gam_GetNumMchsGame (Game.GamCod)))
Ale_ShowAlert (Ale_WARNING,Txt_You_can_not_edit_a_game_with_matches);
/* Get maximum question index */ else
MaxQstInd = Gam_GetMaxQuestionIndexInGame (Game.GamCod);
/***** Move down question *****/
if (MaxQstInd)
{ {
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 */ if (QstIndTop < MaxQstInd)
QstIndBottom = Gam_GetNextQuestionIndexInGame (Game.GamCod,QstIndTop); {
if (!QstIndBottom) /* Indexes of questions to be exchanged */
Lay_ShowErrorAndExit ("Wrong index of question."); QstIndBottom = Gam_GetNextQuestionIndexInGame (Game.GamCod,QstIndTop);
if (!QstIndBottom)
Lay_ShowErrorAndExit ("Wrong index of question.");
/* Exchange questions */ /* Exchange questions */
Gam_ExchangeQuestions (Game.GamCod,QstIndTop,QstIndBottom); Gam_ExchangeQuestions (Game.GamCod,QstIndTop,QstIndBottom);
/* Success alert */ /* Success alert */
Ale_ShowAlert (Ale_SUCCESS,Txt_The_question_has_been_moved_down); Ale_ShowAlert (Ale_SUCCESS,Txt_The_question_has_been_moved_down);
}
else
Ale_ShowAlert (Ale_WARNING,Txt_Movement_not_allowed);
} }
else 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 *****/ /***** Show current game *****/
Gam_ShowOneGame (Game.GamCod, Gam_ShowOneGame (Game.GamCod,

View File

@ -103,6 +103,8 @@ void Gam_RemoveGamesCrs (long CrsCod);
unsigned Gam_GetNumQstsGame (long GamCod); unsigned Gam_GetNumQstsGame (long GamCod);
void Gam_RequestNewQuestion (void); void Gam_RequestNewQuestion (void);
void Gam_ListTstQuestionsToSelect (void);
void Gam_PutParamQstInd (unsigned QstInd); void Gam_PutParamQstInd (unsigned QstInd);
unsigned Gam_GetParamQstInd (void); unsigned Gam_GetParamQstInd (void);
unsigned Gam_GetQstIndFromStr (const char *UnsignedStr); unsigned Gam_GetQstIndFromStr (const char *UnsignedStr);

View File

@ -1946,6 +1946,10 @@ static void Mch_ShowMatchStatusForStd (struct Match *Match)
unsigned Gam_GetNumMchsGame (long GamCod) 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 *****/ /***** Get number of matches in a game from database *****/
return return
(unsigned) DB_QueryCOUNT ("can not get number of matches of a game", (unsigned) DB_QueryCOUNT ("can not get number of matches of a game",

View File

@ -2413,16 +2413,11 @@ void Tst_ListQuestionsToEdit (void)
/**************** List several test questions for selection ******************/ /**************** List several test questions for selection ******************/
/*****************************************************************************/ /*****************************************************************************/
void Tst_ListQuestionsToSelect (void) void Tst_ListQuestionsToSelect (long GamCod)
{ {
long GamCod;
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
unsigned long NumRows; 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 *****/ /***** Get parameters, query the database and list the questions *****/
if (Tst_GetParamsTst (Tst_SELECT_QUESTIONS_FOR_GAME)) // Get parameters from the form if (Tst_GetParamsTst (Tst_SELECT_QUESTIONS_FOR_GAME)) // Get parameters from the form
{ {

View File

@ -150,7 +150,7 @@ void Tst_WriteQstFeedback (const char *Feedback,const char *ClassFeedback);
void Tst_ShowFormAskEditTsts (void); void Tst_ShowFormAskEditTsts (void);
void Tst_ShowFormAskSelectTstsForGame (long GamCod); void Tst_ShowFormAskSelectTstsForGame (long GamCod);
void Tst_ListQuestionsToEdit (void); void Tst_ListQuestionsToEdit (void);
void Tst_ListQuestionsToSelect (void); void Tst_ListQuestionsToSelect (long GamCod);
bool Tst_GetOneQuestionByCod (long QstCod,MYSQL_RES **mysql_res); bool Tst_GetOneQuestionByCod (long QstCod,MYSQL_RES **mysql_res);
void Tst_WriteParamEditQst (void); void Tst_WriteParamEditQst (void);
unsigned Tst_GetNumAnswersQst (long QstCod); unsigned Tst_GetNumAnswersQst (long QstCod);

View File

@ -54243,6 +54243,28 @@ const char *Txt_You_can_not_disable_file_uploading_once_folders_have_been_create
" uma vez diret&oacute;rios foram criados."; " uma vez diret&oacute;rios foram criados.";
#endif #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&ouml;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 &eacute;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 &egrave; possibile modificare un gioco con i partite.";
#elif L==8 // pl
"Nie mo&zdot;na edytowa&cacute; gry za pomoc&aogon; mecze.";
#elif L==9 // pt
"Voc&ecirc; n&atilde;o pode editar um jogo com partidas.";
#endif
const char *Txt_You_can_not_leave_empty_intermediate_answers = const char *Txt_You_can_not_leave_empty_intermediate_answers =
#if L==1 // ca #if L==1 // ca
"No puede dejar respuestas intermedias sin rellenar."; // Necessita traduccio "No puede dejar respuestas intermedias sin rellenar."; // Necessita traduccio