Version 16.253

This commit is contained in:
Antonio Cañas Vargas 2017-09-11 19:06:46 +02:00
parent bfacb95c98
commit 31ca093287
7 changed files with 366 additions and 69 deletions

View File

@ -507,6 +507,8 @@ Assessment:
NEW. ActAddTstQstToGam Add selected test questions to game
NEW. ActReqRemGamQst Request the removal of a question of a game
NEW. ActRemGamQst Confirm the removal of a question of a game
NEW. ActUp_GamQst, Move up a question of a game
NEW. ActDwnGamQst, Move down a question of a game
361. ActSeeOneExaAnn Show one exam announcement
362. ActSeeDatExaAnn Show exam announcements of a given date
@ -1967,6 +1969,8 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
/* ActAddTstQstToGam */{1667,-1,TabUnk,ActSeeAllGam ,0x3E0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Gam_AddTstQuestionsToGame ,NULL},
/* ActReqRemGamQst */{1664,-1,TabUnk,ActSeeAllGam ,0x3E0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Gam_RequestRemoveQst ,NULL},
/* ActRemGamQst */{1665,-1,TabUnk,ActSeeAllGam ,0x3E0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Gam_RemoveQst ,NULL},
/* ActUp_GamQst */{1668,-1,TabUnk,ActSeeAllGam ,0x3E0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Gam_MoveUpQst ,NULL},
/* ActDwnGamQst */{1669,-1,TabUnk,ActSeeAllGam ,0x3E0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Gam_MoveDownQst ,NULL},
/* ActSeeOneSvy */{ 982,-1,TabUnk,ActSeeAllSvy ,0x3F8,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Svy_SeeOneSurvey ,NULL},
/* ActAnsSvy */{ 983,-1,TabUnk,ActSeeAllSvy ,0x3F8,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_THIS_WINDOW,NULL ,Svy_ReceiveSurveyAnswers ,NULL},
@ -4711,6 +4715,8 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un
ActRemGamQst, // #1665
ActGamLstTstQst, // #1666
ActAddTstQstToGam, // #1667
ActUp_GamQst, // #1668
ActDwnGamQst, // #1669
};
/*****************************************************************************/

View File

@ -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 + 90 + 416 + 165 + 172 + 42 + 14 + 97)
#define Act_NUM_ACTIONS (1 + 9 + 43 + 17 + 47 + 33 + 24 + 115 + 92 + 416 + 165 + 172 + 42 + 14 + 97)
#define Act_MAX_ACTION_COD 1667
#define Act_MAX_ACTION_COD 1669
#define Act_MAX_OPTIONS_IN_MENU_PER_TAB 12
@ -502,33 +502,35 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to
#define ActAddTstQstToGam (ActChgCalCrs1stDay + 63)
#define ActReqRemGamQst (ActChgCalCrs1stDay + 64)
#define ActRemGamQst (ActChgCalCrs1stDay + 65)
#define ActUp_GamQst (ActChgCalCrs1stDay + 66)
#define ActDwnGamQst (ActChgCalCrs1stDay + 67)
#define ActSeeOneSvy (ActChgCalCrs1stDay + 66)
#define ActAnsSvy (ActChgCalCrs1stDay + 67)
#define ActFrmNewSvy (ActChgCalCrs1stDay + 68)
#define ActEdiOneSvy (ActChgCalCrs1stDay + 69)
#define ActNewSvy (ActChgCalCrs1stDay + 70)
#define ActChgSvy (ActChgCalCrs1stDay + 71)
#define ActReqRemSvy (ActChgCalCrs1stDay + 72)
#define ActRemSvy (ActChgCalCrs1stDay + 73)
#define ActReqRstSvy (ActChgCalCrs1stDay + 74)
#define ActRstSvy (ActChgCalCrs1stDay + 75)
#define ActHidSvy (ActChgCalCrs1stDay + 76)
#define ActShoSvy (ActChgCalCrs1stDay + 77)
#define ActEdiOneSvyQst (ActChgCalCrs1stDay + 78)
#define ActRcvSvyQst (ActChgCalCrs1stDay + 79)
#define ActReqRemSvyQst (ActChgCalCrs1stDay + 80)
#define ActRemSvyQst (ActChgCalCrs1stDay + 81)
#define ActSeeOneSvy (ActChgCalCrs1stDay + 68)
#define ActAnsSvy (ActChgCalCrs1stDay + 69)
#define ActFrmNewSvy (ActChgCalCrs1stDay + 70)
#define ActEdiOneSvy (ActChgCalCrs1stDay + 71)
#define ActNewSvy (ActChgCalCrs1stDay + 72)
#define ActChgSvy (ActChgCalCrs1stDay + 73)
#define ActReqRemSvy (ActChgCalCrs1stDay + 74)
#define ActRemSvy (ActChgCalCrs1stDay + 75)
#define ActReqRstSvy (ActChgCalCrs1stDay + 76)
#define ActRstSvy (ActChgCalCrs1stDay + 77)
#define ActHidSvy (ActChgCalCrs1stDay + 78)
#define ActShoSvy (ActChgCalCrs1stDay + 79)
#define ActEdiOneSvyQst (ActChgCalCrs1stDay + 80)
#define ActRcvSvyQst (ActChgCalCrs1stDay + 81)
#define ActReqRemSvyQst (ActChgCalCrs1stDay + 82)
#define ActRemSvyQst (ActChgCalCrs1stDay + 83)
#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)
#define ActSeeOneExaAnn (ActChgCalCrs1stDay + 84)
#define ActSeeDatExaAnn (ActChgCalCrs1stDay + 85)
#define ActEdiExaAnn (ActChgCalCrs1stDay + 86)
#define ActRcvExaAnn (ActChgCalCrs1stDay + 87)
#define ActPrnExaAnn (ActChgCalCrs1stDay + 88)
#define ActReqRemExaAnn (ActChgCalCrs1stDay + 89)
#define ActRemExaAnn (ActChgCalCrs1stDay + 90)
#define ActHidExaAnn (ActChgCalCrs1stDay + 91)
#define ActShoExaAnn (ActChgCalCrs1stDay + 92)
/*****************************************************************************/
/******************************** Files tab **********************************/

View File

@ -234,17 +234,26 @@
// TODO: "Solicitar inscripción" como superusuario: "Usted no tiene permiso para realizar esta acción"
// TODO: "Administrar varios profesores no editores" -> debería poder hacerlo un profesor (Perico)
/*****************************************************************************/
/****************************** Public constants *****************************/
/*****************************************************************************/
#define Log_PLATFORM_VERSION "SWAD 16.252.3 (2017-09-11)"
#define Log_PLATFORM_VERSION "SWAD 16.253 (2017-09-11)"
#define CSS_FILE "swad16.252.2.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.253: Sep 11, 2017 Actions to move up and down questions in a game. (227070 lines)
4 changes necessary in database:
UPDATE actions SET Txt='Subir posición item teoría' WHERE ActCod='221' AND Language='es';
UPDATE actions SET Txt='Bajar posición item teoría' WHERE ActCod='220' AND Language='es';
INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1668','es','N','Subir posición pregunta juego');
INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1669','es','N','Bajar posición pregunta juego');
Version 16.252.3: Sep 11, 2017 HTML optimization in icons. (226822 lines)
Version 16.252.2: Sep 10, 2017 Code refactoring in edition of syllabus. (226819 lines)
Version 16.252.1: Sep 09, 2017 Icons to move up and down questions in a game. (226864 lines)

View File

@ -122,8 +122,11 @@ static void Gam_PutParamQstCod (long QstCod);
static long Gam_GetParamQstCod (void);
static void Gam_RemAnswersOfAQuestion (long QstCod);
static unsigned Gam_GetQstIndFromQstCod (long QstCod);
static unsigned Gam_GetNextQuestionIndexInGame (long GamCod);
static unsigned Gam_GetQstIndFromQstCod (long GamCod,long QstCod);
static long Gam_GetQstCodFromQstInd (long GamCod,unsigned QstInd);
static int Gam_GetMaxQuestionIndexInGame (long GamCod);
static unsigned Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd);
static unsigned Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd);
static void Gam_ListGameQuestions (struct Game *Game);
static void Gam_ListOneOrMoreQuestionsForEdition (struct Game *Game,
unsigned NumQsts,
@ -141,6 +144,9 @@ static void Gam_DrawBarNumUsrs (unsigned NumUsrs,unsigned MaxUsrs);
// static void Gam_PutIconToRemoveOneQst (void);
static void Gam_PutParamsOneQst (void);
static void Gam_ExchangeQuestions (long GamCod,
unsigned QstIndTop,unsigned QstIndBottom);
static void Gam_ReceiveAndStoreUserAnswersToAGame (long GamCod);
static void Gam_IncreaseAnswerInDB (long QstCod,unsigned AnsInd);
static void Gam_RegisterIHaveAnsweredGame (long GamCod);
@ -944,7 +950,7 @@ void Gam_GetListGames (void)
{
/* Get next game code */
row = mysql_fetch_row (mysql_res);
if ((Gbl.Games.LstGamCods[NumGame] = Str_ConvertStrCodToLongCod (row[0])) < 0)
if ((Gbl.Games.LstGamCods[NumGame] = Str_ConvertStrCodToLongCod (row[0])) <= 0)
Lay_ShowErrorAndExit ("Error: wrong game code.");
}
}
@ -2571,27 +2577,26 @@ static void Gam_RemAnswersOfAQuestion (long QstCod)
/******************** Get next question index in a game **********************/
/*****************************************************************************/
static unsigned Gam_GetQstIndFromQstCod (long QstCod)
static unsigned Gam_GetQstIndFromQstCod (long GamCod,long QstCod)
{
char Query[128];
char Query[256];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned long NumRows;
unsigned QstInd = 0;
/***** Get number of games with a field value from database *****/
sprintf (Query,"SELECT QstInd FROM gam_questions WHERE QstCod=%ld",
QstCod);
NumRows = DB_QuerySELECT (Query,&mysql_res,"can not get question index");
sprintf (Query,"SELECT QstInd FROM gam_questions"
" WHERE GamCod=%ld AND QstCod=%ld",
GamCod,QstCod);
if (!DB_QuerySELECT (Query,&mysql_res,"can not get question index"))
{
Ale_ShowAlert (Ale_INFO,Query);
Lay_ShowErrorAndExit ("Error when getting question index.");
}
/***** Get number of users *****/
if (NumRows)
{
row = mysql_fetch_row (mysql_res);
if (sscanf (row[0],"%u",&QstInd) != 1)
Lay_ShowErrorAndExit ("Error when getting question index.");
}
else
/***** Get question index (row[0]) *****/
row = mysql_fetch_row (mysql_res);
if (sscanf (row[0],"%u",&QstInd) != 1)
Lay_ShowErrorAndExit ("Error when getting question index.");
/***** Free structure that stores the query result *****/
@ -2601,15 +2606,46 @@ static unsigned Gam_GetQstIndFromQstCod (long QstCod)
}
/*****************************************************************************/
/******************* Get next question index in a game *********************/
/************ Get question code given game and index of question *************/
/*****************************************************************************/
static unsigned Gam_GetNextQuestionIndexInGame (long GamCod)
static long Gam_GetQstCodFromQstInd (long GamCod,unsigned QstInd)
{
char Query[256];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
long QstCod;
/***** Get question code of thw question to be moved up *****/
sprintf (Query,"SELECT QstCod FROM gam_questions"
" WHERE GamCod=%ld AND QstInd=%u",
GamCod,QstInd);
if (!DB_QuerySELECT (Query,&mysql_res,"can not get question code"))
Lay_ShowErrorAndExit ("Error: wrong question code.");
/***** Get question code (row[0]) *****/
row = mysql_fetch_row (mysql_res);
if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) <= 0)
Lay_ShowErrorAndExit ("Error: wrong question code.");
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return QstCod;
}
/*****************************************************************************/
/****************** Get maximum question index in a game *********************/
/*****************************************************************************/
// Question index can be 0, 1, 2,...
// Return -1 if no questions
static int Gam_GetMaxQuestionIndexInGame (long GamCod)
{
char Query[128];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned QstInd = 0;
int QstInd = -1;
/***** Get maximum question index in a game from database *****/
sprintf (Query,"SELECT MAX(QstInd) FROM gam_questions WHERE GamCod=%ld",
@ -2617,11 +2653,8 @@ static unsigned Gam_GetNextQuestionIndexInGame (long GamCod)
DB_QuerySELECT (Query,&mysql_res,"can not get last question index");
row = mysql_fetch_row (mysql_res);
if (row[0]) // There are questions
{
if (sscanf (row[0],"%u",&QstInd) != 1)
if (sscanf (row[0],"%d",&QstInd) != 1)
Lay_ShowErrorAndExit ("Error when getting last question index.");
QstInd++;
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
@ -2629,6 +2662,68 @@ static unsigned Gam_GetNextQuestionIndexInGame (long GamCod)
return QstInd;
}
/*****************************************************************************/
/*********** Get previous question index to a given index in a game **********/
/*****************************************************************************/
static unsigned Gam_GetPrevQuestionIndexInGame (long GamCod,unsigned QstInd)
{
char Query[256];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned PrevQstInd;
/***** Get previous question index in a game from database *****/
// Although indexes are always continuous...
// ...this implementation works even with non continuous indexes
sprintf (Query,"SELECT MAX(QstInd) FROM gam_questions"
" WHERE GamCod=%ld AND QstInd<%u",
GamCod,QstInd);
if (!DB_QuerySELECT (Query,&mysql_res,"can not get previous question index"))
Lay_ShowErrorAndExit ("Error: previous question index not found.");
/***** Get previous question index (row[0]) *****/
row = mysql_fetch_row (mysql_res);
if (sscanf (row[0],"%u",&PrevQstInd) != 1)
Lay_ShowErrorAndExit ("Error when getting previous question index.");
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return PrevQstInd;
}
/*****************************************************************************/
/************* Get next question index to a given index in a game ************/
/*****************************************************************************/
static unsigned Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd)
{
char Query[256];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NextQstInd;
/***** Get next question index in a game from database *****/
// Although indexes are always continuous...
// ...this implementation works even with non continuous indexes
sprintf (Query,"SELECT MIN(QstInd) FROM gam_questions"
" WHERE GamCod=%ld AND QstInd>%u",
GamCod,QstInd);
if (!DB_QuerySELECT (Query,&mysql_res,"can not get next question index"))
Lay_ShowErrorAndExit ("Error: next question index not found.");
/***** Get next question index (row[0]) *****/
row = mysql_fetch_row (mysql_res);
if (sscanf (row[0],"%u",&NextQstInd) != 1)
Lay_ShowErrorAndExit ("Error when getting next question index.");
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return NextQstInd;
}
/*****************************************************************************/
/************************ List the questions of a game ***********************/
/*****************************************************************************/
@ -2780,11 +2875,12 @@ static void Gam_ListOneOrMoreQuestionsForEdition (struct Game *Game,
Tst_QstConstructor ();
/* row[0] holds the code of the question */
if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) <= 0)
Lay_ShowErrorAndExit ("Wrong code of question.");
Gbl.Test.QstCod = QstCod;
/***** Icons *****/
Gbl.Games.CurrentGamCod = Game->GamCod;
Gbl.Games.CurrentQstCod = QstCod;
fprintf (Gbl.F.Out,"<tr>"
"<td class=\"BT%u\">",Gbl.RowEvenOdd);
@ -2795,11 +2891,11 @@ static void Gam_ListOneOrMoreQuestionsForEdition (struct Game *Game,
Ico_PutIconRemove ();
Act_FormEnd ();
/* Write icon to move up the question */
/* Put icon to move up the question */
if (NumQst)
{
sprintf (Gbl.Title,Txt_Move_up_X,StrNumQst);
Lay_PutContextualLink (ActEdiOneTstQst,NULL,Gam_PutParamsOneQst,
Lay_PutContextualLink (ActUp_GamQst,NULL,Gam_PutParamsOneQst,
"up_on16x16.gif",
Gbl.Title,NULL,
NULL);
@ -2807,11 +2903,11 @@ static void Gam_ListOneOrMoreQuestionsForEdition (struct Game *Game,
else
Ico_PutIcon ("up_off16x16.gif",Txt_Movement_not_allowed);
/* Write icon to move down the question */
/* Put icon to move down the question */
if (NumQst + 1 < NumQsts)
{
sprintf (Gbl.Title,Txt_Move_down_X,StrNumQst);
Lay_PutContextualLink (ActEdiOneTstQst,NULL,Gam_PutParamsOneQst,
Lay_PutContextualLink (ActDwnGamQst,NULL,Gam_PutParamsOneQst,
"down_on16x16.gif",
Gbl.Title,NULL,
NULL);
@ -2819,7 +2915,7 @@ static void Gam_ListOneOrMoreQuestionsForEdition (struct Game *Game,
else
Ico_PutIcon ("down_off16x16.gif",Txt_Movement_not_allowed);
/* Write icon to edit the question */
/* Put icon to edit the question */
Gbl.Test.QstCod = QstCod;
Ico_PutContextualIconToEdit (ActEdiOneTstQst,Tst_PutParamQstCod);
@ -2918,7 +3014,7 @@ void Gam_AddTstQuestionsToGame (void)
const char *Ptr;
char LongStr[1 + 10 + 1];
long QstCod;
unsigned QstInd;
int MaxQstInd;
char Query[256];
/***** Get game code *****/
@ -2950,15 +3046,15 @@ void Gam_AddTstQuestionsToGame (void)
if (sscanf (LongStr,"%ld",&QstCod) != 1)
Lay_ShowErrorAndExit ("Wrong question code.");
/* Get next index */
QstInd = Gam_GetNextQuestionIndexInGame (Game.GamCod);
/* Get current maximum index */
MaxQstInd = Gam_GetMaxQuestionIndexInGame (Game.GamCod); // -1 if no questions
/* Insert question in the table of questions */
sprintf (Query,"INSERT INTO gam_questions"
" (GamCod,QstCod,QstInd)"
" VALUES"
" (%ld,%ld,%u)",
Game.GamCod,QstCod,QstInd);
Game.GamCod,QstCod,(unsigned) (MaxQstInd + 1));
DB_QueryINSERT (Query,"can not create question");
}
@ -3141,11 +3237,11 @@ void Gam_RequestRemoveQst (void)
Lay_ShowErrorAndExit ("Code of game is missing.");
/* Get question code */
if ((QstCod = Gam_GetParamQstCod ()) < 0)
if ((QstCod = Gam_GetParamQstCod ()) <= 0)
Lay_ShowErrorAndExit ("Wrong code of question.");
/* Get question index */
QstInd = Gam_GetQstIndFromQstCod (QstCod);
QstInd = Gam_GetQstIndFromQstCod (Game.GamCod,QstCod);
/***** Show question and button to remove question *****/
Gbl.Games.CurrentGamCod = Game.GamCod;
@ -3178,11 +3274,11 @@ void Gam_RemoveQst (void)
Lay_ShowErrorAndExit ("Code of game is missing.");
/* Get question code */
if ((QstCod = Gam_GetParamQstCod ()) < 0)
if ((QstCod = Gam_GetParamQstCod ()) <= 0)
Lay_ShowErrorAndExit ("Wrong code of question.");
/* Get question index */
QstInd = Gam_GetQstIndFromQstCod (QstCod);
QstInd = Gam_GetQstIndFromQstCod (Game.GamCod,QstCod);
/***** Remove the question from all the tables *****/
/* Remove answers from this test question */
@ -3209,6 +3305,145 @@ void Gam_RemoveQst (void)
Gam_ShowOneGame (Game.GamCod,true);
}
/*****************************************************************************/
/***************** Move up position of a question in a game ******************/
/*****************************************************************************/
void Gam_MoveUpQst (void)
{
extern const char *Txt_The_question_has_been_moved_up;
struct Game Game;
long QstCod;
unsigned QstIndTop;
unsigned QstIndBottom;
/***** Get parameters from form *****/
/* Get game code */
if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of game is missing.");
/* Get question code */
if ((QstCod = Gam_GetParamQstCod ()) <= 0)
Lay_ShowErrorAndExit ("Wrong code of question.");
/* Get question index */
QstIndBottom = Gam_GetQstIndFromQstCod (Game.GamCod,QstCod);
/***** Move up question *****/
if (QstIndBottom > 0)
{
/* Indexes of questions to be exchanged */
QstIndTop = Gam_GetPrevQuestionIndexInGame (Game.GamCod,QstIndBottom);
/* Exchange questions */
Gam_ExchangeQuestions (Game.GamCod,
QstIndTop,QstIndBottom);
/* Success alert */
Ale_ShowAlert (Ale_SUCCESS,Txt_The_question_has_been_moved_up);
}
/***** Show current game *****/
Gam_ShowOneGame (Game.GamCod,true);
}
/*****************************************************************************/
/**************** Move down position of a question in a game *****************/
/*****************************************************************************/
void Gam_MoveDownQst (void)
{
extern const char *Txt_The_question_has_been_moved_down;
struct Game Game;
long QstCod;
unsigned QstIndTop;
unsigned QstIndBottom;
int MaxQstInd; // -1 if no questions
/***** Get parameters from form *****/
/* Get game code */
if ((Game.GamCod = Gam_GetParamGameCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of game is missing.");
/* Get question code */
if ((QstCod = Gam_GetParamQstCod ()) <= 0)
Lay_ShowErrorAndExit ("Wrong code of question.");
/* Get question index */
QstIndTop = Gam_GetQstIndFromQstCod (Game.GamCod,QstCod);
/* Get maximum question index */
MaxQstInd = Gam_GetMaxQuestionIndexInGame (Game.GamCod);
/***** Move down question *****/
if (MaxQstInd > 0)
if (QstIndTop < (unsigned) MaxQstInd)
{
/* Indexes of questions to be exchanged */
QstIndBottom = Gam_GetNextQuestionIndexInGame (Game.GamCod,QstIndTop);
/* Exchange questions */
Gam_ExchangeQuestions (Game.GamCod,QstIndTop,QstIndBottom);
/* Success alert */
Ale_ShowAlert (Ale_SUCCESS,Txt_The_question_has_been_moved_down);
}
/***** Show current game *****/
Gam_ShowOneGame (Game.GamCod,true);
}
/*****************************************************************************/
/********* Exchange the order of two consecutive questions in a game *********/
/*****************************************************************************/
static void Gam_ExchangeQuestions (long GamCod,
unsigned QstIndTop,unsigned QstIndBottom)
{
char Query[256];
long QstCodTop;
long QstCodBottom;
/***** Lock table to make the inscription atomic *****/
DB_Query ("LOCK TABLES gam_questions WRITE",
"Can not lock tables to move game question");
Gbl.DB.LockedTables = true;
/***** Get question code of the questions to be moved *****/
QstCodTop = Gam_GetQstCodFromQstInd (GamCod,QstIndTop);
QstCodBottom = Gam_GetQstCodFromQstInd (GamCod,QstIndBottom);
/***** Exchange indexes of questions *****/
/*
Example:
QstIndTop = 0; QstCodTop = 218
QstIndBottom = 1; QstCodBottom = 220
+--------+--------+ +--------+--------+ +--------+--------+
| QstInd | QstCod | | QstInd | QstCod | | QstInd | QstCod |
+--------+--------+ +--------+--------+ +--------+--------+
| 0 | 218 | -----> | 1 | 218 | = | 0 | 220 |
| 1 | 220 | | 0 | 220 | | 1 | 218 |
| 2 | 232 | | 2 | 232 | | 2 | 232 |
+--------+--------+ +--------+--------+ +--------+--------+
*/
sprintf (Query,"UPDATE gam_questions SET QstInd=%u"
" WHERE GamCod=%ld AND QstCod=%ld",
QstIndBottom,
GamCod,QstCodTop);
DB_QueryUPDATE (Query,"can not exchange indexes of questions");
sprintf (Query,"UPDATE gam_questions SET QstInd=%u"
" WHERE GamCod=%ld AND QstCod=%ld",
QstIndTop,
GamCod,QstCodBottom);
DB_QueryUPDATE (Query,"can not exchange indexes of questions");
/***** Unlock table *****/
Gbl.DB.LockedTables = false; // Set to false before the following unlock...
// ...to not retry the unlock if error in unlocking
DB_Query ("UNLOCK TABLES",
"Can not unlock tables after moving game questions");
}
/*****************************************************************************/
/************************ Receive answers of a game ************************/
/*****************************************************************************/

View File

@ -122,6 +122,9 @@ void Gam_AddTstQuestionsToGame (void);
void Gam_RequestRemoveQst (void);
void Gam_RemoveQst (void);
void Gam_MoveUpQst (void);
void Gam_MoveDownQst (void);
void Gam_ReceiveGameAnswers (void);
unsigned Gam_GetNumCoursesWithCrsGames (Sco_Scope_t Scope);

View File

@ -874,7 +874,7 @@ bool Grp_ChangeMyGrpsAtomically (struct ListCodGrps *LstGrpsIWant)
/***** Unlock tables after changes in my groups *****/
Gbl.DB.LockedTables = false; // Set to false before the following unlock...
// ...to not retry the unlock if error in unlocking
// ...to not retry the unlock if error in unlocking
DB_Query ("UNLOCK TABLES",
"Can not unlock tables after changes in user's groups");
@ -947,7 +947,7 @@ void Grp_ChangeGrpsOtherUsrAtomically (struct ListCodGrps *LstGrpsUsrWants)
if (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role == Rol_STD)
{
Gbl.DB.LockedTables = false; // Set to false before the following unlock...
// ...to not retry the unlock if error in unlocking
// ...to not retry the unlock if error in unlocking
DB_Query ("UNLOCK TABLES",
"Can not unlock tables after changes in user's groups");
}

View File

@ -46023,6 +46023,48 @@ const char *Txt_The_properties_of_file_X_have_been_saved = // Warning: it is ver
"The properties of file %s have been saved."; // Necessita de tradução
#endif
const char *Txt_The_question_has_been_moved_down =
#if L==1
"La pregunta ha estat moguda cap avall.";
#elif L==2
"Die Frage wurde nach unten bewegt.";
#elif L==3
"The question has been moved down.";
#elif L==4
"La pregunta se ha movido hacia abajo.";
#elif L==5
"La question a &eacute;t&eacute; d&eacute;plac&eacute;e vers le bas.";
#elif L==6
"La pregunta se ha movido hacia arriba."; // Okoteve traducción
#elif L==7
"La questione &egrave; stata abbattuta.";
#elif L==8
"Pytanie zosta&lstrok;o przeniesione.";
#elif L==9
"A quest&atilde;o foi movida para baixo.";
#endif
const char *Txt_The_question_has_been_moved_up =
#if L==1
"La pregunta ha estat moguda cap amunt.";
#elif L==2
"Die Frage wurde nach oben verschoben.";
#elif L==3
"The question has been moved up.";
#elif L==4
"La pregunta se ha movido hacia arriba.";
#elif L==5
"La question a &eacute;t&eacute; d&eacute;plac&eacute;e vers le haut.";
#elif L==6
"La pregunta se ha movido hacia arriba."; // Okoteve traducción
#elif L==7
"La questione &egrave; stata spostata.";
#elif L==8
"Pytanie zosta&lstrok;o poruszone.";
#elif L==9
"A quest&atilde;o foi movida para cima.";
#endif
const char *Txt_The_record_field_X_already_exists = // Warning: it is very important to include %s in the following sentences
#if L==1
"El campo de ficha <strong>%s</strong> ya existe."; // Necessita traduccio