mirror of
https://github.com/acanas/swad-core.git
synced 2024-09-20 00:02:42 +02:00
Version19.155.6
This commit is contained in:
parent
db492bc66b
commit
67681ff352
|
@ -497,7 +497,7 @@ 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.155.5 (2020-03-27)"
|
#define Log_PLATFORM_VERSION "SWAD 19.155.6 (2020-03-27)"
|
||||||
#define CSS_FILE "swad19.146.css"
|
#define CSS_FILE "swad19.146.css"
|
||||||
#define JS_FILE "swad19.153.js"
|
#define JS_FILE "swad19.153.js"
|
||||||
/*
|
/*
|
||||||
|
@ -526,6 +526,7 @@ Param
|
||||||
|
|
||||||
// TODO: URGENT: Fix bug while playing match.
|
// TODO: URGENT: Fix bug while playing match.
|
||||||
|
|
||||||
|
Version 19.155.6: Mar 26, 2020 Code refactoring in matches. (284479 lines)
|
||||||
Version 19.155.5: Mar 26, 2020 Code refactoring in tests. (284480 lines)
|
Version 19.155.5: Mar 26, 2020 Code refactoring in tests. (284480 lines)
|
||||||
Version 19.155.4: Mar 26, 2020 Code refactoring in tests. (284476 lines)
|
Version 19.155.4: Mar 26, 2020 Code refactoring in tests. (284476 lines)
|
||||||
Version 19.155.3: Mar 27, 2020 Code refactoring in pass to parameters of functions. (284476 lines)
|
Version 19.155.3: Mar 27, 2020 Code refactoring in pass to parameters of functions. (284476 lines)
|
||||||
|
|
132
swad_match.c
132
swad_match.c
|
@ -2988,15 +2988,141 @@ static void Mch_WriteAnswersMatchResult (const struct Match *Match,
|
||||||
{
|
{
|
||||||
/***** Write answer depending on type *****/
|
/***** Write answer depending on type *****/
|
||||||
if (Question->Answer.Type == Tst_ANS_UNIQUE_CHOICE)
|
if (Question->Answer.Type == Tst_ANS_UNIQUE_CHOICE)
|
||||||
Tst_WriteChoiceAnsViewMatch (Match->MchCod,
|
Mch_WriteChoiceAnsViewMatch (Match,
|
||||||
Match->Status.QstInd,
|
|
||||||
Match->Status.NumCols,
|
|
||||||
Question,
|
Question,
|
||||||
Class,ShowResult);
|
Class,ShowResult);
|
||||||
else
|
else
|
||||||
Ale_ShowAlert (Ale_ERROR,"Type of answer not valid in a game.");
|
Ale_ShowAlert (Ale_ERROR,"Type of answer not valid in a game.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/******** Write single or multiple choice answer when viewing a match ********/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void Mch_WriteChoiceAnsViewMatch (const struct Match *Match,
|
||||||
|
struct Tst_Question *Question,
|
||||||
|
const char *Class,bool ShowResult)
|
||||||
|
{
|
||||||
|
unsigned NumOpt;
|
||||||
|
bool RowIsOpen = false;
|
||||||
|
MYSQL_RES *mysql_res;
|
||||||
|
MYSQL_ROW row;
|
||||||
|
unsigned NumRespondersQst;
|
||||||
|
unsigned NumRespondersAns;
|
||||||
|
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; // Indexes of all answers of this question
|
||||||
|
|
||||||
|
/***** Get number of users who have answered this question from database *****/
|
||||||
|
NumRespondersQst = Mch_GetNumUsrsWhoAnsweredQst (Match->MchCod,Match->Status.QstInd);
|
||||||
|
|
||||||
|
/***** Get answers of a question from database *****/
|
||||||
|
Tst_GetAnswersQst (Question,&mysql_res,
|
||||||
|
false); // Don't shuffle
|
||||||
|
/*
|
||||||
|
row[0] AnsInd
|
||||||
|
row[1] Answer
|
||||||
|
row[2] Feedback
|
||||||
|
row[3] MedCod
|
||||||
|
row[4] Correct
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (NumOpt = 0;
|
||||||
|
NumOpt < Question->Answer.NumOptions;
|
||||||
|
NumOpt++)
|
||||||
|
{
|
||||||
|
/* Get next answer */
|
||||||
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
|
||||||
|
/* Allocate memory for text in this choice answer */
|
||||||
|
if (!Tst_AllocateTextChoiceAnswer (Question,NumOpt))
|
||||||
|
/* Abort on error */
|
||||||
|
Ale_ShowAlertsAndExit ();
|
||||||
|
|
||||||
|
/* Copy text (row[1]) and convert it, that is in HTML, to rigorous HTML */
|
||||||
|
Str_Copy (Question->Answer.Options[NumOpt].Text,row[1],
|
||||||
|
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
||||||
|
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||||
|
Question->Answer.Options[NumOpt].Text,
|
||||||
|
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||||
|
|
||||||
|
/* Get media (row[3]) */
|
||||||
|
Question->Answer.Options[NumOpt].Media.MedCod = Str_ConvertStrCodToLongCod (row[3]);
|
||||||
|
Med_GetMediaDataByCod (&Question->Answer.Options[NumOpt].Media);
|
||||||
|
|
||||||
|
/* Get if correct (row[4]) */
|
||||||
|
Question->Answer.Options[NumOpt].Correct = (row[4][0] == 'Y');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free structure that stores the query result */
|
||||||
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
|
||||||
|
/***** Get indexes for this question in match *****/
|
||||||
|
Mch_GetIndexes (Match->MchCod,Match->Status.QstInd,Indexes);
|
||||||
|
|
||||||
|
/***** Begin table *****/
|
||||||
|
HTM_TABLE_BeginWidePadding (0);
|
||||||
|
|
||||||
|
/***** Show options distributed in columns *****/
|
||||||
|
for (NumOpt = 0;
|
||||||
|
NumOpt < Question->Answer.NumOptions;
|
||||||
|
NumOpt++)
|
||||||
|
{
|
||||||
|
/***** Start row? *****/
|
||||||
|
if (NumOpt % Match->Status.NumCols == 0)
|
||||||
|
{
|
||||||
|
HTM_TR_Begin (NULL);
|
||||||
|
RowIsOpen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Write letter for this option *****/
|
||||||
|
HTM_TD_Begin ("class=\"MCH_TCH_BUTTON_TD\"");
|
||||||
|
HTM_DIV_Begin ("class=\"MCH_TCH_BUTTON BT_%c\"",'A' + (char) NumOpt);
|
||||||
|
HTM_TxtF ("%c",'a' + (char) NumOpt);
|
||||||
|
HTM_DIV_End ();
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/***** Write the option text and the result *****/
|
||||||
|
HTM_TD_Begin ("class=\"LT\"");
|
||||||
|
HTM_LABEL_Begin ("for=\"Ans%06u_%u\" class=\"%s\"",Match->Status.QstInd,NumOpt,Class);
|
||||||
|
HTM_Txt (Question->Answer.Options[Indexes[NumOpt]].Text);
|
||||||
|
HTM_LABEL_End ();
|
||||||
|
Med_ShowMedia (&Question->Answer.Options[Indexes[NumOpt]].Media,
|
||||||
|
"TEST_MED_SHOW_CONT",
|
||||||
|
"TEST_MED_SHOW");
|
||||||
|
|
||||||
|
/* Show result (number of users who answered? */
|
||||||
|
if (ShowResult)
|
||||||
|
{
|
||||||
|
/* Get number of users who selected this answer */
|
||||||
|
NumRespondersAns = Mch_GetNumUsrsWhoHaveChosenAns (Match->MchCod,Match->Status.QstInd,Indexes[NumOpt]);
|
||||||
|
|
||||||
|
/* Draw proportional bar for this answer */
|
||||||
|
Mch_DrawBarNumUsrs (NumRespondersAns,NumRespondersQst,
|
||||||
|
Question->Answer.Options[Indexes[NumOpt]].Correct);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* Draw empty bar for this answer
|
||||||
|
in order to show the same layout that the one shown with results */
|
||||||
|
Mch_DrawBarNumUsrs (0,0,
|
||||||
|
false); // Not used when length of bar is 0
|
||||||
|
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
/***** End row? *****/
|
||||||
|
if (NumOpt % Match->Status.NumCols == Match->Status.NumCols - 1)
|
||||||
|
{
|
||||||
|
HTM_TR_End ();
|
||||||
|
RowIsOpen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** End row? *****/
|
||||||
|
if (RowIsOpen)
|
||||||
|
HTM_TR_End ();
|
||||||
|
|
||||||
|
/***** End table *****/
|
||||||
|
HTM_TABLE_End ();
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/***** Show question and its answers when playing a match (as a student) *****/
|
/***** Show question and its answers when playing a match (as a student) *****/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -116,6 +116,11 @@ unsigned Mch_GetNumMchsInGame (long GamCod);
|
||||||
unsigned Mch_GetNumUnfinishedMchsInGame (long GamCod);
|
unsigned Mch_GetNumUnfinishedMchsInGame (long GamCod);
|
||||||
|
|
||||||
bool Mch_CheckIfICanPlayThisMatchBasedOnGrps (const struct Match *Match);
|
bool Mch_CheckIfICanPlayThisMatchBasedOnGrps (const struct Match *Match);
|
||||||
|
|
||||||
|
void Mch_WriteChoiceAnsViewMatch (const struct Match *Match,
|
||||||
|
struct Tst_Question *Question,
|
||||||
|
const char *Class,bool ShowResult);
|
||||||
|
|
||||||
bool Mch_RegisterMeAsPlayerInMatch (struct Match *Match);
|
bool Mch_RegisterMeAsPlayerInMatch (struct Match *Match);
|
||||||
|
|
||||||
void Mch_GetMatchBeingPlayed (void);
|
void Mch_GetMatchBeingPlayed (void);
|
||||||
|
|
128
swad_test.c
128
swad_test.c
|
@ -4194,134 +4194,6 @@ void Tst_ComputeScoreQst (const struct Tst_Question *Question,
|
||||||
*ScoreThisQst = 0.0;
|
*ScoreThisQst = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/******** Write single or multiple choice answer when viewing a match ********/
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
void Tst_WriteChoiceAnsViewMatch (long MchCod,unsigned QstInd,unsigned NumCols,
|
|
||||||
struct Tst_Question *Question,
|
|
||||||
const char *Class,bool ShowResult)
|
|
||||||
{
|
|
||||||
unsigned NumOpt;
|
|
||||||
bool RowIsOpen = false;
|
|
||||||
MYSQL_RES *mysql_res;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
unsigned NumRespondersQst;
|
|
||||||
unsigned NumRespondersAns;
|
|
||||||
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; // Indexes of all answers of this question
|
|
||||||
|
|
||||||
/***** Get number of users who have answered this question from database *****/
|
|
||||||
NumRespondersQst = Mch_GetNumUsrsWhoAnsweredQst (MchCod,QstInd);
|
|
||||||
|
|
||||||
/***** Get answers of a question from database *****/
|
|
||||||
Tst_GetAnswersQst (Question,&mysql_res,
|
|
||||||
false); // Don't shuffle
|
|
||||||
/*
|
|
||||||
row[0] AnsInd
|
|
||||||
row[1] Answer
|
|
||||||
row[2] Feedback
|
|
||||||
row[3] MedCod
|
|
||||||
row[4] Correct
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (NumOpt = 0;
|
|
||||||
NumOpt < Question->Answer.NumOptions;
|
|
||||||
NumOpt++)
|
|
||||||
{
|
|
||||||
/* Get next answer */
|
|
||||||
row = mysql_fetch_row (mysql_res);
|
|
||||||
|
|
||||||
/* Allocate memory for text in this choice answer */
|
|
||||||
if (!Tst_AllocateTextChoiceAnswer (Question,NumOpt))
|
|
||||||
/* Abort on error */
|
|
||||||
Ale_ShowAlertsAndExit ();
|
|
||||||
|
|
||||||
/* Copy text (row[1]) and convert it, that is in HTML, to rigorous HTML */
|
|
||||||
Str_Copy (Question->Answer.Options[NumOpt].Text,row[1],
|
|
||||||
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
|
||||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
|
||||||
Question->Answer.Options[NumOpt].Text,
|
|
||||||
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
|
||||||
|
|
||||||
/* Get media (row[3]) */
|
|
||||||
Question->Answer.Options[NumOpt].Media.MedCod = Str_ConvertStrCodToLongCod (row[3]);
|
|
||||||
Med_GetMediaDataByCod (&Question->Answer.Options[NumOpt].Media);
|
|
||||||
|
|
||||||
/* Get if correct (row[4]) */
|
|
||||||
Question->Answer.Options[NumOpt].Correct = (row[4][0] == 'Y');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free structure that stores the query result */
|
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
|
||||||
|
|
||||||
/***** Get indexes for this question in match *****/
|
|
||||||
Mch_GetIndexes (MchCod,QstInd,Indexes);
|
|
||||||
|
|
||||||
/***** Begin table *****/
|
|
||||||
HTM_TABLE_BeginWidePadding (0);
|
|
||||||
|
|
||||||
/***** Show options distributed in columns *****/
|
|
||||||
for (NumOpt = 0;
|
|
||||||
NumOpt < Question->Answer.NumOptions;
|
|
||||||
NumOpt++)
|
|
||||||
{
|
|
||||||
/***** Start row? *****/
|
|
||||||
if (NumOpt % NumCols == 0)
|
|
||||||
{
|
|
||||||
HTM_TR_Begin (NULL);
|
|
||||||
RowIsOpen = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** Write letter for this option *****/
|
|
||||||
HTM_TD_Begin ("class=\"MCH_TCH_BUTTON_TD\"");
|
|
||||||
HTM_DIV_Begin ("class=\"MCH_TCH_BUTTON BT_%c\"",'A' + (char) NumOpt);
|
|
||||||
HTM_TxtF ("%c",'a' + (char) NumOpt);
|
|
||||||
HTM_DIV_End ();
|
|
||||||
HTM_TD_End ();
|
|
||||||
|
|
||||||
/***** Write the option text and the result *****/
|
|
||||||
HTM_TD_Begin ("class=\"LT\"");
|
|
||||||
HTM_LABEL_Begin ("for=\"Ans%06u_%u\" class=\"%s\"",QstInd,NumOpt,Class);
|
|
||||||
HTM_Txt (Question->Answer.Options[Indexes[NumOpt]].Text);
|
|
||||||
HTM_LABEL_End ();
|
|
||||||
Med_ShowMedia (&Question->Answer.Options[Indexes[NumOpt]].Media,
|
|
||||||
"TEST_MED_SHOW_CONT",
|
|
||||||
"TEST_MED_SHOW");
|
|
||||||
|
|
||||||
/* Show result (number of users who answered? */
|
|
||||||
if (ShowResult)
|
|
||||||
{
|
|
||||||
/* Get number of users who selected this answer */
|
|
||||||
NumRespondersAns = Mch_GetNumUsrsWhoHaveChosenAns (MchCod,QstInd,Indexes[NumOpt]);
|
|
||||||
|
|
||||||
/* Draw proportional bar for this answer */
|
|
||||||
Mch_DrawBarNumUsrs (NumRespondersAns,NumRespondersQst,
|
|
||||||
Question->Answer.Options[Indexes[NumOpt]].Correct);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/* Draw empty bar for this answer
|
|
||||||
in order to show the same layout that the one shown with results */
|
|
||||||
Mch_DrawBarNumUsrs (0,0,
|
|
||||||
false); // Not used when length of bar is 0
|
|
||||||
|
|
||||||
HTM_TD_End ();
|
|
||||||
|
|
||||||
/***** End row? *****/
|
|
||||||
if (NumOpt % NumCols == NumCols - 1)
|
|
||||||
{
|
|
||||||
HTM_TR_End ();
|
|
||||||
RowIsOpen = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** End row? *****/
|
|
||||||
if (RowIsOpen)
|
|
||||||
HTM_TR_End ();
|
|
||||||
|
|
||||||
/***** End table *****/
|
|
||||||
HTM_TABLE_End ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******************** Write text answer when viewing a test ******************/
|
/******************** Write text answer when viewing a test ******************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -194,9 +194,6 @@ void Tst_ComputeScoreQst (const struct Tst_Question *Question,
|
||||||
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION],
|
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION],
|
||||||
bool AnswersUsr[Tst_MAX_OPTIONS_PER_QUESTION],
|
bool AnswersUsr[Tst_MAX_OPTIONS_PER_QUESTION],
|
||||||
double *ScoreThisQst,bool *AnswerIsNotBlank);
|
double *ScoreThisQst,bool *AnswerIsNotBlank);
|
||||||
void Tst_WriteChoiceAnsViewMatch (long MchCod,unsigned QstInd,unsigned NumCols,
|
|
||||||
struct Tst_Question *Question,
|
|
||||||
const char *Class,bool ShowResult);
|
|
||||||
void Tst_CheckIfNumberOfAnswersIsOne (const struct Tst_Question *Question);
|
void Tst_CheckIfNumberOfAnswersIsOne (const struct Tst_Question *Question);
|
||||||
|
|
||||||
unsigned long Tst_GetTagsQst (long QstCod,MYSQL_RES **mysql_res);
|
unsigned long Tst_GetTagsQst (long QstCod,MYSQL_RES **mysql_res);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user