mirror of https://github.com/acanas/swad-core.git
Version19.149.1
This commit is contained in:
parent
6e9aed2d76
commit
f818cf372d
|
@ -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.149 (2020-03-18)"
|
#define Log_PLATFORM_VERSION "SWAD 19.149.1 (2020-03-18)"
|
||||||
#define CSS_FILE "swad19.146.css"
|
#define CSS_FILE "swad19.146.css"
|
||||||
#define JS_FILE "swad19.91.1.js"
|
#define JS_FILE "swad19.91.1.js"
|
||||||
/*
|
/*
|
||||||
|
@ -524,6 +524,7 @@ Param
|
||||||
// TODO: Oresti Baños: cambiar ojos por candados en descriptores para prohibir/permitir y dejar los ojos para poder elegir descriptores
|
// TODO: Oresti Baños: cambiar ojos por candados en descriptores para prohibir/permitir y dejar los ojos para poder elegir descriptores
|
||||||
// TODO: Si el alumno ha marcado "Permitir que los profesores...", entonces pedir confirmación al pulsar el botón azul, para evitar que se envíe por error antes de tiempo
|
// TODO: Si el alumno ha marcado "Permitir que los profesores...", entonces pedir confirmación al pulsar el botón azul, para evitar que se envíe por error antes de tiempo
|
||||||
|
|
||||||
|
Version 19.149.1: Mar 18, 2020 Code refactoring in tests. (283094 lines)
|
||||||
Version 19.149: Mar 18, 2020 Code refactoring in tests. (283020 lines)
|
Version 19.149: Mar 18, 2020 Code refactoring in tests. (283020 lines)
|
||||||
Version 19.148.3: Mar 17, 2020 Code refactoring in tests. (282916 lines)
|
Version 19.148.3: Mar 17, 2020 Code refactoring in tests. (282916 lines)
|
||||||
Version 19.148.2: Mar 17, 2020 Code refactoring in tests. (282868 lines)
|
Version 19.148.2: Mar 17, 2020 Code refactoring in tests. (282868 lines)
|
||||||
|
|
10
swad_game.c
10
swad_game.c
|
@ -1875,6 +1875,7 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
long QstCod;
|
long QstCod;
|
||||||
struct Tst_Question Question;
|
struct Tst_Question Question;
|
||||||
|
Tst_AnswerType_t AnswerType;
|
||||||
struct Tst_Answer Answer;
|
struct Tst_Answer Answer;
|
||||||
unsigned QstInd;
|
unsigned QstInd;
|
||||||
unsigned MaxQstInd;
|
unsigned MaxQstInd;
|
||||||
|
@ -1909,7 +1910,7 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
|
||||||
row[1] QstCod
|
row[1] QstCod
|
||||||
*/
|
*/
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor (&Question,&Answer);
|
Tst_QstConstructor (&Question,&AnswerType,&Answer);
|
||||||
|
|
||||||
/* Get question index (row[0]) */
|
/* Get question index (row[0]) */
|
||||||
QstInd = Str_ConvertStrToUnsigned (row[0]);
|
QstInd = Str_ConvertStrToUnsigned (row[0]);
|
||||||
|
@ -1996,6 +1997,7 @@ static void Gam_ListQuestionForEdition (long QstCod,const char *StrQstInd)
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
bool QstExists;
|
bool QstExists;
|
||||||
|
Tst_AnswerType_t AnswerType;
|
||||||
struct Media Media;
|
struct Media Media;
|
||||||
|
|
||||||
/***** Get question from database *****/
|
/***** Get question from database *****/
|
||||||
|
@ -2030,8 +2032,8 @@ static void Gam_ListQuestionForEdition (long QstCod,const char *StrQstInd)
|
||||||
HTM_DIV_Begin ("class=\"DAT_SMALL\"");
|
HTM_DIV_Begin ("class=\"DAT_SMALL\"");
|
||||||
if (QstExists)
|
if (QstExists)
|
||||||
{
|
{
|
||||||
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
|
AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
|
||||||
HTM_Txt (Txt_TST_STR_ANSWER_TYPES[Gbl.Test.AnswerType]);
|
HTM_Txt (Txt_TST_STR_ANSWER_TYPES[AnswerType]);
|
||||||
}
|
}
|
||||||
HTM_DIV_End ();
|
HTM_DIV_End ();
|
||||||
|
|
||||||
|
@ -2069,7 +2071,7 @@ static void Gam_ListQuestionForEdition (long QstCod,const char *StrQstInd)
|
||||||
Tst_WriteQstFeedback (row[4],"TEST_EDI_LIGHT");
|
Tst_WriteQstFeedback (row[4],"TEST_EDI_LIGHT");
|
||||||
|
|
||||||
/* Show answers */
|
/* Show answers */
|
||||||
Tst_WriteAnswersEdit (QstCod);
|
Tst_WriteAnswersEdit (QstCod,AnswerType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
24
swad_match.c
24
swad_match.c
|
@ -192,7 +192,8 @@ static void Mch_PutIfAnswered (const struct Match *Match,bool Answered);
|
||||||
static void Mch_PutIconToRemoveMyAnswer (const struct Match *Match);
|
static void Mch_PutIconToRemoveMyAnswer (const struct Match *Match);
|
||||||
static void Mch_ShowQuestionAndAnswersTch (const struct Match *Match);
|
static void Mch_ShowQuestionAndAnswersTch (const struct Match *Match);
|
||||||
static void Mch_WriteAnswersMatchResult (const struct Match *Match,
|
static void Mch_WriteAnswersMatchResult (const struct Match *Match,
|
||||||
const char *Class,bool ShowResult);
|
const char *Class,bool ShowResult,
|
||||||
|
Tst_AnswerType_t AnswerType);
|
||||||
static bool Mch_ShowQuestionAndAnswersStd (const struct Match *Match,
|
static bool Mch_ShowQuestionAndAnswersStd (const struct Match *Match,
|
||||||
const struct Mch_UsrAnswer *UsrAnswer,
|
const struct Mch_UsrAnswer *UsrAnswer,
|
||||||
Mch_Update_t Update);
|
Mch_Update_t Update);
|
||||||
|
@ -2863,6 +2864,7 @@ static void Mch_ShowQuestionAndAnswersTch (const struct Match *Match)
|
||||||
extern const char *Txt_Question_removed;
|
extern const char *Txt_Question_removed;
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
|
Tst_AnswerType_t AnswerType;
|
||||||
struct Media Media;
|
struct Media Media;
|
||||||
|
|
||||||
/***** Trivial check: do not show anything on match start and end *****/
|
/***** Trivial check: do not show anything on match start and end *****/
|
||||||
|
@ -2888,8 +2890,8 @@ static void Mch_ShowQuestionAndAnswersTch (const struct Match *Match)
|
||||||
|
|
||||||
/***** Show question *****/
|
/***** Show question *****/
|
||||||
/* Get answer type (row[0]) */
|
/* Get answer type (row[0]) */
|
||||||
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[0]);
|
AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[0]);
|
||||||
if (Gbl.Test.AnswerType != Tst_ANS_UNIQUE_CHOICE)
|
if (AnswerType != Tst_ANS_UNIQUE_CHOICE)
|
||||||
Lay_ShowErrorAndExit ("Wrong answer type.");
|
Lay_ShowErrorAndExit ("Wrong answer type.");
|
||||||
|
|
||||||
/* Begin container */
|
/* Begin container */
|
||||||
|
@ -2919,15 +2921,17 @@ static void Mch_ShowQuestionAndAnswersTch (const struct Match *Match)
|
||||||
/* Write answers */
|
/* Write answers */
|
||||||
Mch_WriteAnswersMatchResult (Match,
|
Mch_WriteAnswersMatchResult (Match,
|
||||||
"MCH_TCH_ANS",
|
"MCH_TCH_ANS",
|
||||||
false); // Don't show result
|
false, // Don't show result
|
||||||
else // Match is paused, not being played
|
AnswerType);
|
||||||
|
else // Match is paused, not being played
|
||||||
Mch_ShowWaitImage (Txt_MATCH_Paused);
|
Mch_ShowWaitImage (Txt_MATCH_Paused);
|
||||||
break;
|
break;
|
||||||
case Mch_RESULTS:
|
case Mch_RESULTS:
|
||||||
/* Write answers with results */
|
/* Write answers with results */
|
||||||
Mch_WriteAnswersMatchResult (Match,
|
Mch_WriteAnswersMatchResult (Match,
|
||||||
"MCH_TCH_ANS",
|
"MCH_TCH_ANS",
|
||||||
true); // Show result
|
true, // Show result
|
||||||
|
AnswerType);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Don't write anything */
|
/* Don't write anything */
|
||||||
|
@ -2946,10 +2950,11 @@ static void Mch_ShowQuestionAndAnswersTch (const struct Match *Match)
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Mch_WriteAnswersMatchResult (const struct Match *Match,
|
static void Mch_WriteAnswersMatchResult (const struct Match *Match,
|
||||||
const char *Class,bool ShowResult)
|
const char *Class,bool ShowResult,
|
||||||
|
Tst_AnswerType_t AnswerType)
|
||||||
{
|
{
|
||||||
/***** Write answer depending on type *****/
|
/***** Write answer depending on type *****/
|
||||||
if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE)
|
if (AnswerType == Tst_ANS_UNIQUE_CHOICE)
|
||||||
Tst_WriteChoiceAnsViewMatch (Match->MchCod,Match->Status.QstInd,Match->Status.QstCod,
|
Tst_WriteChoiceAnsViewMatch (Match->MchCod,Match->Status.QstInd,Match->Status.QstCod,
|
||||||
Match->Status.NumCols,Class,ShowResult);
|
Match->Status.NumCols,Class,ShowResult);
|
||||||
else
|
else
|
||||||
|
@ -3786,6 +3791,7 @@ static void Mch_RemoveMyAnswerToMatchQuestion (const struct Match *Match)
|
||||||
static double Mch_ComputeScore (unsigned NumQsts)
|
static double Mch_ComputeScore (unsigned NumQsts)
|
||||||
{
|
{
|
||||||
unsigned NumQst;
|
unsigned NumQst;
|
||||||
|
Tst_AnswerType_t AnswerType = Tst_ANS_UNIQUE_CHOICE;
|
||||||
struct Tst_Answer Answer;
|
struct Tst_Answer Answer;
|
||||||
double ScoreThisQst;
|
double ScoreThisQst;
|
||||||
bool AnswerIsNotBlank;
|
bool AnswerIsNotBlank;
|
||||||
|
@ -3807,7 +3813,7 @@ static double Mch_ComputeScore (unsigned NumQsts)
|
||||||
Tst_GetCorrectAnswersFromDB (Gbl.Test.QstCodes[NumQst],&Answer);
|
Tst_GetCorrectAnswersFromDB (Gbl.Test.QstCodes[NumQst],&Answer);
|
||||||
|
|
||||||
/***** Compute the total score of this question *****/
|
/***** Compute the total score of this question *****/
|
||||||
Tst_ComputeScoreQst (&Answer,
|
Tst_ComputeScoreQst (AnswerType,&Answer,
|
||||||
Indexes,AnswersUsr,&ScoreThisQst,&AnswerIsNotBlank);
|
Indexes,AnswersUsr,&ScoreThisQst,&AnswerIsNotBlank);
|
||||||
|
|
||||||
/***** Compute total score *****/
|
/***** Compute total score *****/
|
||||||
|
|
267
swad_test.c
267
swad_test.c
|
@ -175,9 +175,11 @@ static void Tst_ListOneOrMoreQuestionsForSelection (unsigned long NumRows,
|
||||||
MYSQL_RES *mysql_res);
|
MYSQL_RES *mysql_res);
|
||||||
static void Tst_WriteQuestionRowForSelection (unsigned long NumRow,long QstCod);
|
static void Tst_WriteQuestionRowForSelection (unsigned long NumRow,long QstCod);
|
||||||
|
|
||||||
static void Tst_WriteAnswersTestToAnswer (unsigned NumQst,long QstCod,bool Shuffle);
|
static void Tst_WriteAnswersTestToAnswer (unsigned NumQst,long QstCod,
|
||||||
|
Tst_AnswerType_t AnswerType,bool Shuffle);
|
||||||
static void Tst_WriteAnswersTestResult (struct UsrData *UsrDat,
|
static void Tst_WriteAnswersTestResult (struct UsrData *UsrDat,
|
||||||
unsigned NumQst,long QstCod,
|
unsigned NumQst,long QstCod,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
unsigned Visibility,
|
unsigned Visibility,
|
||||||
double *ScoreThisQst,bool *AnswerIsNotBlank);
|
double *ScoreThisQst,bool *AnswerIsNotBlank);
|
||||||
|
|
||||||
|
@ -190,9 +192,12 @@ static void Tst_WriteTFAnsAssessTest (struct UsrData *UsrDat,
|
||||||
double *ScoreThisQst,
|
double *ScoreThisQst,
|
||||||
bool *AnswerIsNotBlank);
|
bool *AnswerIsNotBlank);
|
||||||
|
|
||||||
static void Tst_WriteChoiceAnsViewTest (unsigned NumQst,long QstCod,bool Shuffle);
|
static void Tst_WriteChoiceAnsViewTest (unsigned NumQst,long QstCod,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
|
bool Shuffle);
|
||||||
static void Tst_WriteChoiceAnsAssessTest (struct UsrData *UsrDat,
|
static void Tst_WriteChoiceAnsAssessTest (struct UsrData *UsrDat,
|
||||||
unsigned NumQst,
|
unsigned NumQst,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
struct Tst_Answer *Answer,
|
struct Tst_Answer *Answer,
|
||||||
MYSQL_RES *mysql_res,
|
MYSQL_RES *mysql_res,
|
||||||
unsigned Visibility,
|
unsigned Visibility,
|
||||||
|
@ -237,12 +242,14 @@ static int Tst_CountNumTagsInList (void);
|
||||||
static int Tst_CountNumAnswerTypesInList (void);
|
static int Tst_CountNumAnswerTypesInList (void);
|
||||||
static void Tst_PutFormEditOneQst (long QstCod,
|
static void Tst_PutFormEditOneQst (long QstCod,
|
||||||
const struct Tst_Question *Question,
|
const struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
const struct Tst_Answer *Answer,
|
const struct Tst_Answer *Answer,
|
||||||
char Stem[Cns_MAX_BYTES_TEXT + 1],
|
char Stem[Cns_MAX_BYTES_TEXT + 1],
|
||||||
char Feedback[Cns_MAX_BYTES_TEXT + 1]);
|
char Feedback[Cns_MAX_BYTES_TEXT + 1]);
|
||||||
static void Tst_PutFloatInputField (const char *Label,const char *Field,
|
static void Tst_PutFloatInputField (const char *Label,const char *Field,
|
||||||
double Value);
|
double Value,Tst_AnswerType_t AnswerType);
|
||||||
static void Tst_PutTFInputField (const struct Tst_Answer *Answer,
|
static void Tst_PutTFInputField (Tst_AnswerType_t AnswerType,
|
||||||
|
const struct Tst_Answer *Answer,
|
||||||
const char *Label,char Value);
|
const char *Label,char Value);
|
||||||
|
|
||||||
static void Tst_FreeTextChoiceAnswers (struct Tst_Answer *Answer);
|
static void Tst_FreeTextChoiceAnswers (struct Tst_Answer *Answer);
|
||||||
|
@ -255,6 +262,7 @@ static void Tst_FreeMediaOfQuestion (struct Tst_Question *Question,
|
||||||
|
|
||||||
static void Tst_GetQstDataFromDB (long QstCod,
|
static void Tst_GetQstDataFromDB (long QstCod,
|
||||||
struct Tst_Question *Question,
|
struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t *AnswerType,
|
||||||
struct Tst_Answer *Answer,
|
struct Tst_Answer *Answer,
|
||||||
char Stem[Cns_MAX_BYTES_TEXT + 1],
|
char Stem[Cns_MAX_BYTES_TEXT + 1],
|
||||||
char Feedback[Cns_MAX_BYTES_TEXT + 1]);
|
char Feedback[Cns_MAX_BYTES_TEXT + 1]);
|
||||||
|
@ -264,10 +272,12 @@ static void Tst_GetMediaFromDB (long CrsCod,long QstCod,int NumOpt,
|
||||||
|
|
||||||
static Tst_AnswerType_t Tst_ConvertFromUnsignedStrToAnsTyp (const char *UnsignedStr);
|
static Tst_AnswerType_t Tst_ConvertFromUnsignedStrToAnsTyp (const char *UnsignedStr);
|
||||||
static long Tst_GetQstFromForm (struct Tst_Question *Question,
|
static long Tst_GetQstFromForm (struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t *AnswerType,
|
||||||
struct Tst_Answer *Answer,
|
struct Tst_Answer *Answer,
|
||||||
char *Stem,char *Feedback);
|
char *Stem,char *Feedback);
|
||||||
static void Tst_MoveMediaToDefinitiveDirectories (long QstCod,
|
static void Tst_MoveMediaToDefinitiveDirectories (long QstCod,
|
||||||
struct Tst_Question *Question,
|
struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
struct Tst_Answer *Answer);
|
struct Tst_Answer *Answer);
|
||||||
|
|
||||||
static long Tst_GetTagCodFromTagTxt (const char *TagTxt);
|
static long Tst_GetTagCodFromTagTxt (const char *TagTxt);
|
||||||
|
@ -283,9 +293,12 @@ static void Tst_RemoveOneQstFromDB (long CrsCod,long QstCod);
|
||||||
static long Tst_GetQstCod (void);
|
static long Tst_GetQstCod (void);
|
||||||
|
|
||||||
static long Tst_InsertOrUpdateQstIntoDB (long QstCod,
|
static long Tst_InsertOrUpdateQstIntoDB (long QstCod,
|
||||||
const struct Tst_Question *Question);
|
const struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t AnswerType);
|
||||||
static void Tst_InsertTagsIntoDB (long QstCod);
|
static void Tst_InsertTagsIntoDB (long QstCod);
|
||||||
static void Tst_InsertAnswersIntoDB (long QstCod,struct Tst_Answer *Answer);
|
static void Tst_InsertAnswersIntoDB (long QstCod,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
|
struct Tst_Answer *Answer);
|
||||||
|
|
||||||
static void Tst_RemAnsFromQst (long QstCod);
|
static void Tst_RemAnsFromQst (long QstCod);
|
||||||
static void Tst_RemTagsFromQst (long QstCod);
|
static void Tst_RemTagsFromQst (long QstCod);
|
||||||
|
@ -1004,6 +1017,7 @@ void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestio
|
||||||
{
|
{
|
||||||
extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES];
|
extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES];
|
||||||
struct Tst_Question Question;
|
struct Tst_Question Question;
|
||||||
|
Tst_AnswerType_t AnswerType;
|
||||||
struct Tst_Answer Answer;
|
struct Tst_Answer Answer;
|
||||||
bool IsVisibleQstAndAnsTxt = TsV_IsVisibleQstAndAnsTxt (Visibility);
|
bool IsVisibleQstAndAnsTxt = TsV_IsVisibleQstAndAnsTxt (Visibility);
|
||||||
/*
|
/*
|
||||||
|
@ -1018,7 +1032,7 @@ void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestio
|
||||||
row[8] Score
|
row[8] Score
|
||||||
*/
|
*/
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor (&Question,&Answer);
|
Tst_QstConstructor (&Question,&AnswerType,&Answer);
|
||||||
|
|
||||||
HTM_TR_Begin (NULL);
|
HTM_TR_Begin (NULL);
|
||||||
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
|
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
|
@ -1029,9 +1043,9 @@ void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestio
|
||||||
HTM_DIV_End ();
|
HTM_DIV_End ();
|
||||||
|
|
||||||
/***** Write answer type (row[1]) *****/
|
/***** Write answer type (row[1]) *****/
|
||||||
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
|
AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
|
||||||
HTM_DIV_Begin ("class=\"DAT_SMALL\"");
|
HTM_DIV_Begin ("class=\"DAT_SMALL\"");
|
||||||
HTM_Txt (Txt_TST_STR_ANSWER_TYPES[Gbl.Test.AnswerType]);
|
HTM_Txt (Txt_TST_STR_ANSWER_TYPES[AnswerType]);
|
||||||
HTM_DIV_End ();
|
HTM_DIV_End ();
|
||||||
|
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
@ -1054,10 +1068,10 @@ void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestio
|
||||||
switch (ActionToDoWithQuestions)
|
switch (ActionToDoWithQuestions)
|
||||||
{
|
{
|
||||||
case Tst_SHOW_TEST_TO_ANSWER:
|
case Tst_SHOW_TEST_TO_ANSWER:
|
||||||
Tst_WriteAnswersTestToAnswer (NumQst,QstCod,(row[2][0] == 'Y'));
|
Tst_WriteAnswersTestToAnswer (NumQst,QstCod,AnswerType,(row[2][0] == 'Y'));
|
||||||
break;
|
break;
|
||||||
case Tst_SHOW_TEST_RESULT:
|
case Tst_SHOW_TEST_RESULT:
|
||||||
Tst_WriteAnswersTestResult (UsrDat,NumQst,QstCod,
|
Tst_WriteAnswersTestResult (UsrDat,NumQst,QstCod,AnswerType,
|
||||||
Visibility,
|
Visibility,
|
||||||
ScoreThisQst,AnswerIsNotBlank);
|
ScoreThisQst,AnswerIsNotBlank);
|
||||||
|
|
||||||
|
@ -2891,6 +2905,7 @@ static void Tst_WriteQuestionRowForEdition (unsigned long NumRows,
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
struct Tst_Question Question;
|
struct Tst_Question Question;
|
||||||
|
Tst_AnswerType_t AnswerType;
|
||||||
struct Tst_Answer Answer;
|
struct Tst_Answer Answer;
|
||||||
static unsigned UniqueId = 0;
|
static unsigned UniqueId = 0;
|
||||||
char *Id;
|
char *Id;
|
||||||
|
@ -2900,7 +2915,7 @@ static void Tst_WriteQuestionRowForEdition (unsigned long NumRows,
|
||||||
double TotalScoreThisQst;
|
double TotalScoreThisQst;
|
||||||
|
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor (&Question,&Answer);
|
Tst_QstConstructor (&Question,&AnswerType,&Answer);
|
||||||
|
|
||||||
/***** Get and show questvoidion data *****/
|
/***** Get and show questvoidion data *****/
|
||||||
if (Tst_GetOneQuestionByCod (QstCod,&mysql_res))
|
if (Tst_GetOneQuestionByCod (QstCod,&mysql_res))
|
||||||
|
@ -2949,9 +2964,9 @@ static void Tst_WriteQuestionRowForEdition (unsigned long NumRows,
|
||||||
HTM_DIV_End ();
|
HTM_DIV_End ();
|
||||||
|
|
||||||
/* Write answer type (row[1]) */
|
/* Write answer type (row[1]) */
|
||||||
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
|
AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
|
||||||
HTM_DIV_Begin ("class=\"DAT_SMALL\"");
|
HTM_DIV_Begin ("class=\"DAT_SMALL\"");
|
||||||
HTM_Txt (Txt_TST_STR_ANSWER_TYPES[Gbl.Test.AnswerType]);
|
HTM_Txt (Txt_TST_STR_ANSWER_TYPES[AnswerType]);
|
||||||
HTM_DIV_End ();
|
HTM_DIV_End ();
|
||||||
|
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
@ -2980,8 +2995,8 @@ static void Tst_WriteQuestionRowForEdition (unsigned long NumRows,
|
||||||
|
|
||||||
/* Write if shuffle is enabled (row[2]) */
|
/* Write if shuffle is enabled (row[2]) */
|
||||||
HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd);
|
HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE ||
|
if (AnswerType == Tst_ANS_UNIQUE_CHOICE ||
|
||||||
Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
||||||
{
|
{
|
||||||
Frm_StartForm (ActChgShfTstQst);
|
Frm_StartForm (ActChgShfTstQst);
|
||||||
Tst_PutParamQstCod (QstCod);
|
Tst_PutParamQstCod (QstCod);
|
||||||
|
@ -3012,7 +3027,7 @@ static void Tst_WriteQuestionRowForEdition (unsigned long NumRows,
|
||||||
|
|
||||||
/* Write feedback (row[4]) and answers */
|
/* Write feedback (row[4]) and answers */
|
||||||
Tst_WriteQstFeedback (row[4],"TEST_EDI_LIGHT");
|
Tst_WriteQstFeedback (row[4],"TEST_EDI_LIGHT");
|
||||||
Tst_WriteAnswersEdit (QstCod);
|
Tst_WriteAnswersEdit (QstCod,AnswerType);
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
|
||||||
/* Get number of hits
|
/* Get number of hits
|
||||||
|
@ -3041,7 +3056,8 @@ static void Tst_WriteQuestionRowForEdition (unsigned long NumRows,
|
||||||
/* Write average score */
|
/* Write average score */
|
||||||
HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd);
|
HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
if (NumHitsThisQst)
|
if (NumHitsThisQst)
|
||||||
HTM_Double2Decimals (TotalScoreThisQst / (double) NumHitsThisQst);
|
HTM_Double2Decimals (TotalScoreThisQst /
|
||||||
|
(double) NumHitsThisQst);
|
||||||
else
|
else
|
||||||
HTM_Txt ("N.A.");
|
HTM_Txt ("N.A.");
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
@ -3054,7 +3070,8 @@ static void Tst_WriteQuestionRowForEdition (unsigned long NumRows,
|
||||||
/* Write average score (not blank) */
|
/* Write average score (not blank) */
|
||||||
HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd);
|
HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
if (NumHitsNotBlankThisQst)
|
if (NumHitsNotBlankThisQst)
|
||||||
HTM_Double2Decimals (TotalScoreThisQst / (double) NumHitsNotBlankThisQst);
|
HTM_Double2Decimals (TotalScoreThisQst /
|
||||||
|
(double) NumHitsNotBlankThisQst);
|
||||||
else
|
else
|
||||||
HTM_Txt ("N.A.");
|
HTM_Txt ("N.A.");
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
@ -3155,13 +3172,14 @@ static void Tst_WriteQuestionRowForSelection (unsigned long NumRow,long QstCod)
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
struct Tst_Question Question;
|
struct Tst_Question Question;
|
||||||
|
Tst_AnswerType_t AnswerType;
|
||||||
struct Tst_Answer Answer;
|
struct Tst_Answer Answer;
|
||||||
static unsigned UniqueId = 0;
|
static unsigned UniqueId = 0;
|
||||||
char *Id;
|
char *Id;
|
||||||
time_t TimeUTC;
|
time_t TimeUTC;
|
||||||
|
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor (&Question,&Answer);
|
Tst_QstConstructor (&Question,&AnswerType,&Answer);
|
||||||
|
|
||||||
/***** Get and show questvoidion data *****/
|
/***** Get and show questvoidion data *****/
|
||||||
if (Tst_GetOneQuestionByCod (QstCod,&mysql_res))
|
if (Tst_GetOneQuestionByCod (QstCod,&mysql_res))
|
||||||
|
@ -3219,9 +3237,9 @@ static void Tst_WriteQuestionRowForSelection (unsigned long NumRow,long QstCod)
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
|
||||||
/* Write the question type (row[1]) */
|
/* Write the question type (row[1]) */
|
||||||
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
|
AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
|
||||||
HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd);
|
HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
HTM_TxtF ("%s ",Txt_TST_STR_ANSWER_TYPES[Gbl.Test.AnswerType]);
|
HTM_TxtF ("%s ",Txt_TST_STR_ANSWER_TYPES[AnswerType]);
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
|
||||||
/* Write if shuffle is enabled (row[2]) */
|
/* Write if shuffle is enabled (row[2]) */
|
||||||
|
@ -3248,7 +3266,7 @@ static void Tst_WriteQuestionRowForSelection (unsigned long NumRow,long QstCod)
|
||||||
Tst_WriteQstFeedback (row[4],"TEST_EDI_LIGHT");
|
Tst_WriteQstFeedback (row[4],"TEST_EDI_LIGHT");
|
||||||
|
|
||||||
/* Write answers */
|
/* Write answers */
|
||||||
Tst_WriteAnswersEdit (QstCod);
|
Tst_WriteAnswersEdit (QstCod,AnswerType);
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
|
||||||
/***** End table row *****/
|
/***** End table row *****/
|
||||||
|
@ -3346,7 +3364,7 @@ void Tst_GetCorrectAnswersFromDB (long QstCod,struct Tst_Answer *Answer)
|
||||||
/**************** Get and write the answers of a test question ***************/
|
/**************** Get and write the answers of a test question ***************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Tst_WriteAnswersEdit (long QstCod)
|
void Tst_WriteAnswersEdit (long QstCod,Tst_AnswerType_t AnswerType)
|
||||||
{
|
{
|
||||||
extern const char *Txt_TST_Answer_given_by_the_teachers;
|
extern const char *Txt_TST_Answer_given_by_the_teachers;
|
||||||
struct Tst_Question Question;
|
struct Tst_Question Question;
|
||||||
|
@ -3362,7 +3380,7 @@ void Tst_WriteAnswersEdit (long QstCod)
|
||||||
double FloatNum[2];
|
double FloatNum[2];
|
||||||
|
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor (&Question,&Answer);
|
Tst_QstConstructor (&Question,&AnswerType,&Answer);
|
||||||
|
|
||||||
/***** Get answers *****/
|
/***** Get answers *****/
|
||||||
Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,false);
|
Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,false);
|
||||||
|
@ -3375,7 +3393,7 @@ void Tst_WriteAnswersEdit (long QstCod)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/***** Write answers *****/
|
/***** Write answers *****/
|
||||||
switch (Gbl.Test.AnswerType)
|
switch (AnswerType)
|
||||||
{
|
{
|
||||||
case Tst_ANS_INT:
|
case Tst_ANS_INT:
|
||||||
Tst_CheckIfNumberOfAnswersIsOne (&Answer);
|
Tst_CheckIfNumberOfAnswersIsOne (&Answer);
|
||||||
|
@ -3506,13 +3524,14 @@ void Tst_WriteAnswersEdit (long QstCod)
|
||||||
/************** Write answers of a question when viewing a test **************/
|
/************** Write answers of a question when viewing a test **************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Tst_WriteAnswersTestToAnswer (unsigned NumQst,long QstCod,bool Shuffle)
|
static void Tst_WriteAnswersTestToAnswer (unsigned NumQst,long QstCod,
|
||||||
|
Tst_AnswerType_t AnswerType,bool Shuffle)
|
||||||
{
|
{
|
||||||
/***** Write parameter with question code *****/
|
/***** Write parameter with question code *****/
|
||||||
Tst_WriteParamQstCod (NumQst,QstCod);
|
Tst_WriteParamQstCod (NumQst,QstCod);
|
||||||
|
|
||||||
/***** Write answer depending on type *****/
|
/***** Write answer depending on type *****/
|
||||||
switch (Gbl.Test.AnswerType)
|
switch (AnswerType)
|
||||||
{
|
{
|
||||||
case Tst_ANS_INT:
|
case Tst_ANS_INT:
|
||||||
Tst_WriteIntAnsViewTest (NumQst);
|
Tst_WriteIntAnsViewTest (NumQst);
|
||||||
|
@ -3525,7 +3544,7 @@ static void Tst_WriteAnswersTestToAnswer (unsigned NumQst,long QstCod,bool Shuff
|
||||||
break;
|
break;
|
||||||
case Tst_ANS_UNIQUE_CHOICE:
|
case Tst_ANS_UNIQUE_CHOICE:
|
||||||
case Tst_ANS_MULTIPLE_CHOICE:
|
case Tst_ANS_MULTIPLE_CHOICE:
|
||||||
Tst_WriteChoiceAnsViewTest (NumQst,QstCod,Shuffle);
|
Tst_WriteChoiceAnsViewTest (NumQst,QstCod,AnswerType,Shuffle);
|
||||||
break;
|
break;
|
||||||
case Tst_ANS_TEXT:
|
case Tst_ANS_TEXT:
|
||||||
Tst_WriteTextAnsViewTest (NumQst);
|
Tst_WriteTextAnsViewTest (NumQst);
|
||||||
|
@ -3541,6 +3560,7 @@ static void Tst_WriteAnswersTestToAnswer (unsigned NumQst,long QstCod,bool Shuff
|
||||||
|
|
||||||
static void Tst_WriteAnswersTestResult (struct UsrData *UsrDat,
|
static void Tst_WriteAnswersTestResult (struct UsrData *UsrDat,
|
||||||
unsigned NumQst,long QstCod,
|
unsigned NumQst,long QstCod,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
unsigned Visibility,
|
unsigned Visibility,
|
||||||
double *ScoreThisQst,bool *AnswerIsNotBlank)
|
double *ScoreThisQst,bool *AnswerIsNotBlank)
|
||||||
{
|
{
|
||||||
|
@ -3549,7 +3569,7 @@ static void Tst_WriteAnswersTestResult (struct UsrData *UsrDat,
|
||||||
struct Tst_Answer Answer;
|
struct Tst_Answer Answer;
|
||||||
|
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor (&Question,&Answer);
|
Tst_QstConstructor (&Question,&AnswerType,&Answer);
|
||||||
|
|
||||||
/***** Get answer of a question from database *****/
|
/***** Get answer of a question from database *****/
|
||||||
Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,false);
|
Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,false);
|
||||||
|
@ -3562,7 +3582,7 @@ static void Tst_WriteAnswersTestResult (struct UsrData *UsrDat,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/***** Write answer depending on type *****/
|
/***** Write answer depending on type *****/
|
||||||
switch (Gbl.Test.AnswerType)
|
switch (AnswerType)
|
||||||
{
|
{
|
||||||
case Tst_ANS_INT:
|
case Tst_ANS_INT:
|
||||||
Tst_WriteIntAnsAssessTest (UsrDat,NumQst,&Answer,mysql_res,
|
Tst_WriteIntAnsAssessTest (UsrDat,NumQst,&Answer,mysql_res,
|
||||||
|
@ -3581,7 +3601,7 @@ static void Tst_WriteAnswersTestResult (struct UsrData *UsrDat,
|
||||||
break;
|
break;
|
||||||
case Tst_ANS_UNIQUE_CHOICE:
|
case Tst_ANS_UNIQUE_CHOICE:
|
||||||
case Tst_ANS_MULTIPLE_CHOICE:
|
case Tst_ANS_MULTIPLE_CHOICE:
|
||||||
Tst_WriteChoiceAnsAssessTest (UsrDat,NumQst,&Answer,mysql_res,
|
Tst_WriteChoiceAnsAssessTest (UsrDat,NumQst,AnswerType,&Answer,mysql_res,
|
||||||
Visibility,
|
Visibility,
|
||||||
ScoreThisQst,AnswerIsNotBlank);
|
ScoreThisQst,AnswerIsNotBlank);
|
||||||
break;
|
break;
|
||||||
|
@ -3755,7 +3775,9 @@ static void Tst_WriteTFAnsAssessTest (struct UsrData *UsrDat,
|
||||||
/******** Write single or multiple choice answer when viewing a test *********/
|
/******** Write single or multiple choice answer when viewing a test *********/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Tst_WriteChoiceAnsViewTest (unsigned NumQst,long QstCod,bool Shuffle)
|
static void Tst_WriteChoiceAnsViewTest (unsigned NumQst,long QstCod,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
|
bool Shuffle)
|
||||||
{
|
{
|
||||||
unsigned NumOpt;
|
unsigned NumOpt;
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
|
@ -3768,7 +3790,7 @@ static void Tst_WriteChoiceAnsViewTest (unsigned NumQst,long QstCod,bool Shuffle
|
||||||
char StrAns[32];
|
char StrAns[32];
|
||||||
|
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor (&Question,&Answer);
|
Tst_QstConstructor (&Question,&AnswerType,&Answer);
|
||||||
|
|
||||||
/***** Get answers of a question from database *****/
|
/***** Get answers of a question from database *****/
|
||||||
Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,Shuffle);
|
Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,Shuffle);
|
||||||
|
@ -3830,14 +3852,14 @@ static void Tst_WriteChoiceAnsViewTest (unsigned NumQst,long QstCod,bool Shuffle
|
||||||
snprintf (StrAns,sizeof (StrAns),
|
snprintf (StrAns,sizeof (StrAns),
|
||||||
"Ans%06u",
|
"Ans%06u",
|
||||||
NumQst);
|
NumQst);
|
||||||
if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE)
|
if (AnswerType == Tst_ANS_UNIQUE_CHOICE)
|
||||||
HTM_INPUT_RADIO (StrAns,false,
|
HTM_INPUT_RADIO (StrAns,false,
|
||||||
"id=\"Ans%06u_%u\" value=\"%u\""
|
"id=\"Ans%06u_%u\" value=\"%u\""
|
||||||
" onclick=\"selectUnselectRadio(this,this.form.Ans%06u,%u);\"",
|
" onclick=\"selectUnselectRadio(this,this.form.Ans%06u,%u);\"",
|
||||||
NumQst,NumOpt,
|
NumQst,NumOpt,
|
||||||
Index,
|
Index,
|
||||||
NumQst,Answer.NumOptions);
|
NumQst,Answer.NumOptions);
|
||||||
else // Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE
|
else // AnswerType == Tst_ANS_MULTIPLE_CHOICE
|
||||||
HTM_INPUT_CHECKBOX (StrAns,HTM_DONT_SUBMIT_ON_CHANGE,
|
HTM_INPUT_CHECKBOX (StrAns,HTM_DONT_SUBMIT_ON_CHANGE,
|
||||||
"id=\"Ans%06u_%u\" value=\"%u\"",
|
"id=\"Ans%06u_%u\" value=\"%u\"",
|
||||||
NumQst,NumOpt,
|
NumQst,NumOpt,
|
||||||
|
@ -3879,6 +3901,7 @@ static void Tst_WriteChoiceAnsViewTest (unsigned NumQst,long QstCod,bool Shuffle
|
||||||
|
|
||||||
static void Tst_WriteChoiceAnsAssessTest (struct UsrData *UsrDat,
|
static void Tst_WriteChoiceAnsAssessTest (struct UsrData *UsrDat,
|
||||||
unsigned NumQst,
|
unsigned NumQst,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
struct Tst_Answer *Answer,
|
struct Tst_Answer *Answer,
|
||||||
MYSQL_RES *mysql_res,
|
MYSQL_RES *mysql_res,
|
||||||
unsigned Visibility,
|
unsigned Visibility,
|
||||||
|
@ -3907,7 +3930,7 @@ static void Tst_WriteChoiceAnsAssessTest (struct UsrData *UsrDat,
|
||||||
Tst_GetAnswersFromStr (Gbl.Test.StrAnswersOneQst[NumQst],AnswersUsr);
|
Tst_GetAnswersFromStr (Gbl.Test.StrAnswersOneQst[NumQst],AnswersUsr);
|
||||||
|
|
||||||
/***** Compute the total score of this question *****/
|
/***** Compute the total score of this question *****/
|
||||||
Tst_ComputeScoreQst (Answer,
|
Tst_ComputeScoreQst (AnswerType,Answer,
|
||||||
Indexes,AnswersUsr,ScoreThisQst,AnswerIsNotBlank);
|
Indexes,AnswersUsr,ScoreThisQst,AnswerIsNotBlank);
|
||||||
|
|
||||||
/***** Begin table *****/
|
/***** Begin table *****/
|
||||||
|
@ -4158,7 +4181,8 @@ void Tst_GetAnswersFromStr (const char StrAnswersOneQst[Tst_MAX_BYTES_ANSWERS_ON
|
||||||
/********************* Compute the score of this question ********************/
|
/********************* Compute the score of this question ********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Tst_ComputeScoreQst (const struct Tst_Answer *Answer,
|
void Tst_ComputeScoreQst (Tst_AnswerType_t AnswerType,
|
||||||
|
const struct Tst_Answer *Answer,
|
||||||
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION], // Indexes of all answers of this question
|
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION], // Indexes of all answers of this question
|
||||||
bool AnswersUsr[Tst_MAX_OPTIONS_PER_QUESTION],
|
bool AnswersUsr[Tst_MAX_OPTIONS_PER_QUESTION],
|
||||||
double *ScoreThisQst,bool *AnswerIsNotBlank)
|
double *ScoreThisQst,bool *AnswerIsNotBlank)
|
||||||
|
@ -4192,7 +4216,7 @@ void Tst_ComputeScoreQst (const struct Tst_Answer *Answer,
|
||||||
if (*AnswerIsNotBlank)
|
if (*AnswerIsNotBlank)
|
||||||
{
|
{
|
||||||
/* Compute the score */
|
/* Compute the score */
|
||||||
if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE)
|
if (AnswerType == Tst_ANS_UNIQUE_CHOICE)
|
||||||
{
|
{
|
||||||
if (NumOptTotInQst >= 2) // It should be 2 options at least
|
if (NumOptTotInQst >= 2) // It should be 2 options at least
|
||||||
*ScoreThisQst = (double) NumAnsGood -
|
*ScoreThisQst = (double) NumAnsGood -
|
||||||
|
@ -4200,7 +4224,7 @@ void Tst_ComputeScoreQst (const struct Tst_Answer *Answer,
|
||||||
else // 0 or 1 options (impossible)
|
else // 0 or 1 options (impossible)
|
||||||
*ScoreThisQst = (double) NumAnsGood;
|
*ScoreThisQst = (double) NumAnsGood;
|
||||||
}
|
}
|
||||||
else // Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE
|
else // AnswerType == Tst_ANS_MULTIPLE_CHOICE
|
||||||
{
|
{
|
||||||
if (NumOptCorrInQst) // There are correct options in the question
|
if (NumOptCorrInQst) // There are correct options in the question
|
||||||
{
|
{
|
||||||
|
@ -4231,6 +4255,7 @@ void Tst_WriteChoiceAnsViewMatch (long MchCod,unsigned QstInd,long QstCod,
|
||||||
unsigned NumCols,const char *Class,bool ShowResult)
|
unsigned NumCols,const char *Class,bool ShowResult)
|
||||||
{
|
{
|
||||||
struct Tst_Question Question;
|
struct Tst_Question Question;
|
||||||
|
Tst_AnswerType_t AnswerType;
|
||||||
struct Tst_Answer Answer;
|
struct Tst_Answer Answer;
|
||||||
unsigned NumOpt;
|
unsigned NumOpt;
|
||||||
bool RowIsOpen = false;
|
bool RowIsOpen = false;
|
||||||
|
@ -4241,7 +4266,7 @@ void Tst_WriteChoiceAnsViewMatch (long MchCod,unsigned QstInd,long QstCod,
|
||||||
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; // Indexes of all answers of this question
|
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; // Indexes of all answers of this question
|
||||||
|
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor (&Question,&Answer);
|
Tst_QstConstructor (&Question,&AnswerType,&Answer);
|
||||||
|
|
||||||
/***** Get number of users who have answered this question from database *****/
|
/***** Get number of users who have answered this question from database *****/
|
||||||
NumRespondersQst = Mch_GetNumUsrsWhoAnsweredQst (MchCod,QstInd);
|
NumRespondersQst = Mch_GetNumUsrsWhoAnsweredQst (MchCod,QstInd);
|
||||||
|
@ -5161,21 +5186,22 @@ void Tst_ShowFormEditOneQst (void)
|
||||||
{
|
{
|
||||||
long QstCod;
|
long QstCod;
|
||||||
struct Tst_Question Question;
|
struct Tst_Question Question;
|
||||||
|
Tst_AnswerType_t AnswerType;
|
||||||
struct Tst_Answer Answer;
|
struct Tst_Answer Answer;
|
||||||
char Stem[Cns_MAX_BYTES_TEXT + 1];
|
char Stem[Cns_MAX_BYTES_TEXT + 1];
|
||||||
char Feedback[Cns_MAX_BYTES_TEXT + 1];
|
char Feedback[Cns_MAX_BYTES_TEXT + 1];
|
||||||
|
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor (&Question,&Answer);
|
Tst_QstConstructor (&Question,&AnswerType,&Answer);
|
||||||
|
|
||||||
/***** Get question data *****/
|
/***** Get question data *****/
|
||||||
QstCod = Tst_GetQstCod ();
|
QstCod = Tst_GetQstCod ();
|
||||||
Stem[0] = Feedback[0] = '\0';
|
Stem[0] = Feedback[0] = '\0';
|
||||||
if (QstCod > 0) // If question already exists in the database
|
if (QstCod > 0) // If question already exists in the database
|
||||||
Tst_GetQstDataFromDB (QstCod,&Question,&Answer,Stem,Feedback);
|
Tst_GetQstDataFromDB (QstCod,&Question,&AnswerType,&Answer,Stem,Feedback);
|
||||||
|
|
||||||
/***** Put form to edit question *****/
|
/***** Put form to edit question *****/
|
||||||
Tst_PutFormEditOneQst (QstCod,&Question,&Answer,Stem,Feedback);
|
Tst_PutFormEditOneQst (QstCod,&Question,AnswerType,&Answer,Stem,Feedback);
|
||||||
|
|
||||||
/***** Destroy test question *****/
|
/***** Destroy test question *****/
|
||||||
Tst_QstDestructor (&Question,&Answer);
|
Tst_QstDestructor (&Question,&Answer);
|
||||||
|
@ -5192,6 +5218,7 @@ void Tst_ShowFormEditOneQst (void)
|
||||||
|
|
||||||
static void Tst_PutFormEditOneQst (long QstCod,
|
static void Tst_PutFormEditOneQst (long QstCod,
|
||||||
const struct Tst_Question *Question,
|
const struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
const struct Tst_Answer *Answer,
|
const struct Tst_Answer *Answer,
|
||||||
char Stem[Cns_MAX_BYTES_TEXT + 1],
|
char Stem[Cns_MAX_BYTES_TEXT + 1],
|
||||||
char Feedback[Cns_MAX_BYTES_TEXT + 1])
|
char Feedback[Cns_MAX_BYTES_TEXT + 1])
|
||||||
|
@ -5388,7 +5415,8 @@ static void Tst_PutFormEditOneQst (long QstCod,
|
||||||
HTM_INPUT_RADIO ("AnswerType",false,
|
HTM_INPUT_RADIO ("AnswerType",false,
|
||||||
"value=\"%u\"%s onclick=\"enableDisableAns(this.form);\"",
|
"value=\"%u\"%s onclick=\"enableDisableAns(this.form);\"",
|
||||||
(unsigned) AnsType,
|
(unsigned) AnsType,
|
||||||
AnsType == Gbl.Test.AnswerType ? " checked=\"checked\"" : "");
|
AnsType == AnswerType ? " checked=\"checked\"" :
|
||||||
|
"");
|
||||||
HTM_TxtF ("%s ",Txt_TST_STR_ANSWER_TYPES[AnsType]);
|
HTM_TxtF ("%s ",Txt_TST_STR_ANSWER_TYPES[AnsType]);
|
||||||
HTM_LABEL_End ();
|
HTM_LABEL_End ();
|
||||||
HTM_BR ();
|
HTM_BR ();
|
||||||
|
@ -5413,8 +5441,8 @@ static void Tst_PutFormEditOneQst (long QstCod,
|
||||||
Answer->Integer);
|
Answer->Integer);
|
||||||
HTM_INPUT_TEXT ("AnsInt",Cns_MAX_DECIMAL_DIGITS_LONG,StrInteger,false,
|
HTM_INPUT_TEXT ("AnsInt",Cns_MAX_DECIMAL_DIGITS_LONG,StrInteger,false,
|
||||||
"size=\"11\" required=\"required\"%s",
|
"size=\"11\" required=\"required\"%s",
|
||||||
Gbl.Test.AnswerType == Tst_ANS_INT ? "" :
|
AnswerType == Tst_ANS_INT ? "" :
|
||||||
" disabled=\"disabled\"");
|
" disabled=\"disabled\"");
|
||||||
HTM_LABEL_End ();
|
HTM_LABEL_End ();
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
@ -5425,9 +5453,9 @@ static void Tst_PutFormEditOneQst (long QstCod,
|
||||||
HTM_TD_Empty (1);
|
HTM_TD_Empty (1);
|
||||||
HTM_TD_Begin ("class=\"LT\"");
|
HTM_TD_Begin ("class=\"LT\"");
|
||||||
Tst_PutFloatInputField (Txt_Real_number_between_A_and_B_1,"AnsFloatMin",
|
Tst_PutFloatInputField (Txt_Real_number_between_A_and_B_1,"AnsFloatMin",
|
||||||
Answer->FloatingPoint[0]);
|
Answer->FloatingPoint[0],AnswerType);
|
||||||
Tst_PutFloatInputField (Txt_Real_number_between_A_and_B_2,"AnsFloatMax",
|
Tst_PutFloatInputField (Txt_Real_number_between_A_and_B_2,"AnsFloatMax",
|
||||||
Answer->FloatingPoint[1]);
|
Answer->FloatingPoint[1],AnswerType);
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
HTM_TR_End ();
|
HTM_TR_End ();
|
||||||
|
|
||||||
|
@ -5435,8 +5463,8 @@ static void Tst_PutFormEditOneQst (long QstCod,
|
||||||
HTM_TR_Begin (NULL);
|
HTM_TR_Begin (NULL);
|
||||||
HTM_TD_Empty (1);
|
HTM_TD_Empty (1);
|
||||||
HTM_TD_Begin ("class=\"LT\"");
|
HTM_TD_Begin ("class=\"LT\"");
|
||||||
Tst_PutTFInputField (Answer,Txt_TF_QST[0],'T');
|
Tst_PutTFInputField (AnswerType,Answer,Txt_TF_QST[0],'T');
|
||||||
Tst_PutTFInputField (Answer,Txt_TF_QST[1],'F');
|
Tst_PutTFInputField (AnswerType,Answer,Txt_TF_QST[1],'F');
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
HTM_TR_End ();
|
HTM_TR_End ();
|
||||||
|
|
||||||
|
@ -5451,9 +5479,9 @@ static void Tst_PutFormEditOneQst (long QstCod,
|
||||||
"value=\"Y\"%s%s",
|
"value=\"Y\"%s%s",
|
||||||
Question->Shuffle ? " checked=\"checked\"" :
|
Question->Shuffle ? " checked=\"checked\"" :
|
||||||
"",
|
"",
|
||||||
Gbl.Test.AnswerType != Tst_ANS_UNIQUE_CHOICE &&
|
AnswerType != Tst_ANS_UNIQUE_CHOICE &&
|
||||||
Gbl.Test.AnswerType != Tst_ANS_MULTIPLE_CHOICE ? " disabled=\"disabled\"" :
|
AnswerType != Tst_ANS_MULTIPLE_CHOICE ? " disabled=\"disabled\"" :
|
||||||
"");
|
"");
|
||||||
HTM_Txt (Txt_Shuffle);
|
HTM_Txt (Txt_Shuffle);
|
||||||
HTM_LABEL_End ();
|
HTM_LABEL_End ();
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
@ -5466,9 +5494,9 @@ static void Tst_PutFormEditOneQst (long QstCod,
|
||||||
HTM_TD_Begin ("class=\"LT\"");
|
HTM_TD_Begin ("class=\"LT\"");
|
||||||
HTM_TABLE_BeginPadding (2); // Table with choice answers
|
HTM_TABLE_BeginPadding (2); // Table with choice answers
|
||||||
|
|
||||||
OptionsDisabled = Gbl.Test.AnswerType != Tst_ANS_UNIQUE_CHOICE &&
|
OptionsDisabled = AnswerType != Tst_ANS_UNIQUE_CHOICE &&
|
||||||
Gbl.Test.AnswerType != Tst_ANS_MULTIPLE_CHOICE &&
|
AnswerType != Tst_ANS_MULTIPLE_CHOICE &&
|
||||||
Gbl.Test.AnswerType != Tst_ANS_TEXT;
|
AnswerType != Tst_ANS_TEXT;
|
||||||
for (NumOpt = 0;
|
for (NumOpt = 0;
|
||||||
NumOpt < Tst_MAX_OPTIONS_PER_QUESTION;
|
NumOpt < Tst_MAX_OPTIONS_PER_QUESTION;
|
||||||
NumOpt++)
|
NumOpt++)
|
||||||
|
@ -5493,16 +5521,19 @@ static void Tst_PutFormEditOneQst (long QstCod,
|
||||||
"value=\"%u\"%s%s%s onclick=\"enableDisableAns(this.form);\"",
|
"value=\"%u\"%s%s%s onclick=\"enableDisableAns(this.form);\"",
|
||||||
NumOpt,
|
NumOpt,
|
||||||
Answer->Options[NumOpt].Correct ? " checked=\"checked\"" : "",
|
Answer->Options[NumOpt].Correct ? " checked=\"checked\"" : "",
|
||||||
NumOpt < 2 ? " required=\"required\"" : "", // First or second options required
|
NumOpt < 2 ? " required=\"required\"" : // First or second options required
|
||||||
Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE ? "" : " disabled=\"disabled\"");
|
"",
|
||||||
|
AnswerType == Tst_ANS_UNIQUE_CHOICE ? "" :
|
||||||
|
" disabled=\"disabled\"");
|
||||||
|
|
||||||
/* Checkbox for multiple choice answers */
|
/* Checkbox for multiple choice answers */
|
||||||
HTM_INPUT_CHECKBOX ("AnsMulti",HTM_DONT_SUBMIT_ON_CHANGE,
|
HTM_INPUT_CHECKBOX ("AnsMulti",HTM_DONT_SUBMIT_ON_CHANGE,
|
||||||
"value=\"%u\"%s%s",
|
"value=\"%u\"%s%s",
|
||||||
NumOpt,
|
NumOpt,
|
||||||
Answer->Options[NumOpt].Correct ? " checked=\"checked\"" : "",
|
Answer->Options[NumOpt].Correct ? " checked=\"checked\"" :
|
||||||
Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE ? "" :
|
"",
|
||||||
" disabled=\"disabled\"");
|
AnswerType == Tst_ANS_MULTIPLE_CHOICE ? "" :
|
||||||
|
" disabled=\"disabled\"");
|
||||||
|
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
@ -5603,7 +5634,7 @@ static void Tst_PutFormEditOneQst (long QstCod,
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Tst_PutFloatInputField (const char *Label,const char *Field,
|
static void Tst_PutFloatInputField (const char *Label,const char *Field,
|
||||||
double Value)
|
double Value,Tst_AnswerType_t AnswerType)
|
||||||
{
|
{
|
||||||
extern const char *The_ClassFormInBox[The_NUM_THEMES];
|
extern const char *The_ClassFormInBox[The_NUM_THEMES];
|
||||||
char StrDouble[32];
|
char StrDouble[32];
|
||||||
|
@ -5615,8 +5646,8 @@ static void Tst_PutFloatInputField (const char *Label,const char *Field,
|
||||||
Value);
|
Value);
|
||||||
HTM_INPUT_TEXT (Field,Tst_MAX_BYTES_FLOAT_ANSWER,StrDouble,false,
|
HTM_INPUT_TEXT (Field,Tst_MAX_BYTES_FLOAT_ANSWER,StrDouble,false,
|
||||||
"size=\"11\" required=\"required\"%s",
|
"size=\"11\" required=\"required\"%s",
|
||||||
Gbl.Test.AnswerType == Tst_ANS_FLOAT ? "" :
|
AnswerType == Tst_ANS_FLOAT ? "" :
|
||||||
" disabled=\"disabled\"");
|
" disabled=\"disabled\"");
|
||||||
HTM_LABEL_End ();
|
HTM_LABEL_End ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5624,7 +5655,8 @@ static void Tst_PutFloatInputField (const char *Label,const char *Field,
|
||||||
/*********************** Put input field for T/F answer **********************/
|
/*********************** Put input field for T/F answer **********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Tst_PutTFInputField (const struct Tst_Answer *Answer,
|
static void Tst_PutTFInputField (Tst_AnswerType_t AnswerType,
|
||||||
|
const struct Tst_Answer *Answer,
|
||||||
const char *Label,char Value)
|
const char *Label,char Value)
|
||||||
{
|
{
|
||||||
extern const char *The_ClassFormInBox[The_NUM_THEMES];
|
extern const char *The_ClassFormInBox[The_NUM_THEMES];
|
||||||
|
@ -5635,8 +5667,8 @@ static void Tst_PutTFInputField (const struct Tst_Answer *Answer,
|
||||||
Value,
|
Value,
|
||||||
Answer->TF == Value ? " checked=\"checked\"" :
|
Answer->TF == Value ? " checked=\"checked\"" :
|
||||||
"",
|
"",
|
||||||
Gbl.Test.AnswerType == Tst_ANS_TRUE_FALSE ? "" :
|
AnswerType == Tst_ANS_TRUE_FALSE ? "" :
|
||||||
" disabled=\"disabled\"");
|
" disabled=\"disabled\"");
|
||||||
HTM_Txt (Label);
|
HTM_Txt (Label);
|
||||||
HTM_LABEL_End ();
|
HTM_LABEL_End ();
|
||||||
}
|
}
|
||||||
|
@ -5646,6 +5678,7 @@ static void Tst_PutTFInputField (const struct Tst_Answer *Answer,
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Tst_QstConstructor (struct Tst_Question *Question,
|
void Tst_QstConstructor (struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t *AnswerType,
|
||||||
struct Tst_Answer *Answer)
|
struct Tst_Answer *Answer)
|
||||||
{
|
{
|
||||||
unsigned NumOpt;
|
unsigned NumOpt;
|
||||||
|
@ -5656,7 +5689,7 @@ void Tst_QstConstructor (struct Tst_Question *Question,
|
||||||
Question->Feedback.Length = 0;
|
Question->Feedback.Length = 0;
|
||||||
Question->Shuffle = false;
|
Question->Shuffle = false;
|
||||||
|
|
||||||
Gbl.Test.AnswerType = Tst_ANS_UNIQUE_CHOICE;
|
*AnswerType = Tst_ANS_UNIQUE_CHOICE;
|
||||||
Answer->NumOptions = 0;
|
Answer->NumOptions = 0;
|
||||||
Answer->TF = ' ';
|
Answer->TF = ' ';
|
||||||
|
|
||||||
|
@ -5791,6 +5824,7 @@ static void Tst_FreeMediaOfQuestion (struct Tst_Question *Question,
|
||||||
|
|
||||||
static void Tst_GetQstDataFromDB (long QstCod,
|
static void Tst_GetQstDataFromDB (long QstCod,
|
||||||
struct Tst_Question *Question,
|
struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t *AnswerType,
|
||||||
struct Tst_Answer *Answer,
|
struct Tst_Answer *Answer,
|
||||||
char Stem[Cns_MAX_BYTES_TEXT + 1],
|
char Stem[Cns_MAX_BYTES_TEXT + 1],
|
||||||
char Feedback[Cns_MAX_BYTES_TEXT + 1])
|
char Feedback[Cns_MAX_BYTES_TEXT + 1])
|
||||||
|
@ -5815,7 +5849,7 @@ static void Tst_GetQstDataFromDB (long QstCod,
|
||||||
row = mysql_fetch_row (mysql_res);
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
|
||||||
/* Get the type of answer */
|
/* Get the type of answer */
|
||||||
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[0]);
|
*AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[0]);
|
||||||
|
|
||||||
/* Get shuffle (row[1]) */
|
/* Get shuffle (row[1]) */
|
||||||
Question->Shuffle = (row[1][0] == 'Y');
|
Question->Shuffle = (row[1][0] == 'Y');
|
||||||
|
@ -5866,7 +5900,7 @@ static void Tst_GetQstDataFromDB (long QstCod,
|
||||||
NumOpt++)
|
NumOpt++)
|
||||||
{
|
{
|
||||||
row = mysql_fetch_row (mysql_res);
|
row = mysql_fetch_row (mysql_res);
|
||||||
switch (Gbl.Test.AnswerType)
|
switch (*AnswerType)
|
||||||
{
|
{
|
||||||
case Tst_ANS_INT:
|
case Tst_ANS_INT:
|
||||||
if (Answer->NumOptions != 1)
|
if (Answer->NumOptions != 1)
|
||||||
|
@ -6022,25 +6056,26 @@ void Tst_ReceiveQst (void)
|
||||||
{
|
{
|
||||||
long QstCod;
|
long QstCod;
|
||||||
struct Tst_Question Question;
|
struct Tst_Question Question;
|
||||||
|
Tst_AnswerType_t AnswerType;
|
||||||
struct Tst_Answer Answer;
|
struct Tst_Answer Answer;
|
||||||
char Stem[Cns_MAX_BYTES_TEXT + 1];
|
char Stem[Cns_MAX_BYTES_TEXT + 1];
|
||||||
char Feedback[Cns_MAX_BYTES_TEXT + 1];
|
char Feedback[Cns_MAX_BYTES_TEXT + 1];
|
||||||
|
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor (&Question,&Answer);
|
Tst_QstConstructor (&Question,&AnswerType,&Answer);
|
||||||
|
|
||||||
/***** Get parameters of the question from form *****/
|
/***** Get parameters of the question from form *****/
|
||||||
Stem[0] = Feedback[0] = '\0';
|
Stem[0] = Feedback[0] = '\0';
|
||||||
QstCod = Tst_GetQstFromForm (&Question,&Answer,Stem,Feedback);
|
QstCod = Tst_GetQstFromForm (&Question,&AnswerType,&Answer,Stem,Feedback);
|
||||||
|
|
||||||
/***** Make sure that tags, text and answer are not empty *****/
|
/***** Make sure that tags, text and answer are not empty *****/
|
||||||
if (Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (&Question,&Answer))
|
if (Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (&Question,AnswerType,&Answer))
|
||||||
{
|
{
|
||||||
/***** Move images to definitive directories *****/
|
/***** Move images to definitive directories *****/
|
||||||
Tst_MoveMediaToDefinitiveDirectories (QstCod,&Question,&Answer);
|
Tst_MoveMediaToDefinitiveDirectories (QstCod,&Question,AnswerType,&Answer);
|
||||||
|
|
||||||
/***** Insert or update question, tags and answer in the database *****/
|
/***** Insert or update question, tags and answer in the database *****/
|
||||||
QstCod = Tst_InsertOrUpdateQstTagsAnsIntoDB (QstCod,&Question,&Answer);
|
QstCod = Tst_InsertOrUpdateQstTagsAnsIntoDB (QstCod,&Question,AnswerType,&Answer);
|
||||||
|
|
||||||
/***** Show the question just inserted in the database *****/
|
/***** Show the question just inserted in the database *****/
|
||||||
Tst_ListOneQstToEdit (QstCod);
|
Tst_ListOneQstToEdit (QstCod);
|
||||||
|
@ -6051,7 +6086,7 @@ void Tst_ReceiveQst (void)
|
||||||
Tst_ResetMediaOfQuestion (&Question,&Answer);
|
Tst_ResetMediaOfQuestion (&Question,&Answer);
|
||||||
|
|
||||||
/***** Put form to edit question again *****/
|
/***** Put form to edit question again *****/
|
||||||
Tst_PutFormEditOneQst (QstCod,&Question,&Answer,Stem,Feedback);
|
Tst_PutFormEditOneQst (QstCod,&Question,AnswerType,&Answer,Stem,Feedback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Destroy test question *****/
|
/***** Destroy test question *****/
|
||||||
|
@ -6063,6 +6098,7 @@ void Tst_ReceiveQst (void)
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static long Tst_GetQstFromForm (struct Tst_Question *Question,
|
static long Tst_GetQstFromForm (struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t *AnswerType,
|
||||||
struct Tst_Answer *Answer,
|
struct Tst_Answer *Answer,
|
||||||
char *Stem,char *Feedback)
|
char *Stem,char *Feedback)
|
||||||
{
|
{
|
||||||
|
@ -6083,12 +6119,12 @@ static long Tst_GetQstFromForm (struct Tst_Question *Question,
|
||||||
QstCod = Tst_GetQstCod ();
|
QstCod = Tst_GetQstCod ();
|
||||||
|
|
||||||
/***** Get answer type *****/
|
/***** Get answer type *****/
|
||||||
Gbl.Test.AnswerType = (Tst_AnswerType_t)
|
*AnswerType = (Tst_AnswerType_t)
|
||||||
Par_GetParToUnsignedLong ("AnswerType",
|
Par_GetParToUnsignedLong ("AnswerType",
|
||||||
0,
|
0,
|
||||||
Tst_NUM_ANS_TYPES - 1,
|
Tst_NUM_ANS_TYPES - 1,
|
||||||
(unsigned long) Tst_ANS_ALL);
|
(unsigned long) Tst_ANS_ALL);
|
||||||
if (Gbl.Test.AnswerType == Tst_ANS_ALL)
|
if (*AnswerType == Tst_ANS_ALL)
|
||||||
Lay_ShowErrorAndExit ("Wrong type of answer. 4");
|
Lay_ShowErrorAndExit ("Wrong type of answer. 4");
|
||||||
|
|
||||||
/***** Get question tags *****/
|
/***** Get question tags *****/
|
||||||
|
@ -6136,7 +6172,7 @@ static long Tst_GetQstFromForm (struct Tst_Question *Question,
|
||||||
|
|
||||||
/***** Get answers *****/
|
/***** Get answers *****/
|
||||||
Question->Shuffle = false;
|
Question->Shuffle = false;
|
||||||
switch (Gbl.Test.AnswerType)
|
switch (*AnswerType)
|
||||||
{
|
{
|
||||||
case Tst_ANS_INT:
|
case Tst_ANS_INT:
|
||||||
if (!Tst_AllocateTextChoiceAnswer (Answer,0))
|
if (!Tst_AllocateTextChoiceAnswer (Answer,0))
|
||||||
|
@ -6187,7 +6223,7 @@ static long Tst_GetQstFromForm (struct Tst_Question *Question,
|
||||||
NumOpt);
|
NumOpt);
|
||||||
Par_GetParToHTML (AnsStr,Answer->Options[NumOpt].Text,
|
Par_GetParToHTML (AnsStr,Answer->Options[NumOpt].Text,
|
||||||
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
||||||
if (Gbl.Test.AnswerType == Tst_ANS_TEXT)
|
if (*AnswerType == Tst_ANS_TEXT)
|
||||||
/* In order to compare student answer to stored answer,
|
/* In order to compare student answer to stored answer,
|
||||||
the text answers are stored avoiding two or more consecurive spaces */
|
the text answers are stored avoiding two or more consecurive spaces */
|
||||||
Str_ReplaceSeveralSpacesForOne (Answer->Options[NumOpt].Text);
|
Str_ReplaceSeveralSpacesForOne (Answer->Options[NumOpt].Text);
|
||||||
|
@ -6200,8 +6236,8 @@ static long Tst_GetQstFromForm (struct Tst_Question *Question,
|
||||||
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
||||||
|
|
||||||
/* Get media associated to the answer (action, file and title) */
|
/* Get media associated to the answer (action, file and title) */
|
||||||
if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE ||
|
if (*AnswerType == Tst_ANS_UNIQUE_CHOICE ||
|
||||||
Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
*AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
||||||
{
|
{
|
||||||
Answer->Options[NumOpt].Media.Width = Tst_IMAGE_SAVED_MAX_WIDTH;
|
Answer->Options[NumOpt].Media.Width = Tst_IMAGE_SAVED_MAX_WIDTH;
|
||||||
Answer->Options[NumOpt].Media.Height = Tst_IMAGE_SAVED_MAX_HEIGHT;
|
Answer->Options[NumOpt].Media.Height = Tst_IMAGE_SAVED_MAX_HEIGHT;
|
||||||
|
@ -6216,7 +6252,7 @@ static long Tst_GetQstFromForm (struct Tst_Question *Question,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the numbers of correct answers */
|
/* Get the numbers of correct answers */
|
||||||
if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE)
|
if (*AnswerType == Tst_ANS_UNIQUE_CHOICE)
|
||||||
{
|
{
|
||||||
NumCorrectAns = (unsigned) Par_GetParToUnsignedLong ("AnsUni",
|
NumCorrectAns = (unsigned) Par_GetParToUnsignedLong ("AnsUni",
|
||||||
0,
|
0,
|
||||||
|
@ -6224,7 +6260,7 @@ static long Tst_GetQstFromForm (struct Tst_Question *Question,
|
||||||
0);
|
0);
|
||||||
Answer->Options[NumCorrectAns].Correct = true;
|
Answer->Options[NumCorrectAns].Correct = true;
|
||||||
}
|
}
|
||||||
else if (Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
else if (*AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
||||||
{
|
{
|
||||||
Par_GetParMultiToText ("AnsMulti",StrMultiAns,Tst_MAX_BYTES_ANSWERS_ONE_QST);
|
Par_GetParMultiToText ("AnsMulti",StrMultiAns,Tst_MAX_BYTES_ANSWERS_ONE_QST);
|
||||||
Ptr = StrMultiAns;
|
Ptr = StrMultiAns;
|
||||||
|
@ -6271,6 +6307,7 @@ static long Tst_GetQstFromForm (struct Tst_Question *Question,
|
||||||
// Computes Answer->Integer and Answer->FloatingPoint[0..1]
|
// Computes Answer->Integer and Answer->FloatingPoint[0..1]
|
||||||
|
|
||||||
bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (const struct Tst_Question *Question,
|
bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (const struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
struct Tst_Answer *Answer)
|
struct Tst_Answer *Answer)
|
||||||
{
|
{
|
||||||
extern const char *Txt_You_must_type_at_least_one_tag_for_the_question;
|
extern const char *Txt_You_must_type_at_least_one_tag_for_the_question;
|
||||||
|
@ -6306,7 +6343,7 @@ bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (const struct Tst_Question
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Check answer *****/
|
/***** Check answer *****/
|
||||||
switch (Gbl.Test.AnswerType)
|
switch (AnswerType)
|
||||||
{
|
{
|
||||||
case Tst_ANS_INT:
|
case Tst_ANS_INT:
|
||||||
/* First option should be filled */
|
/* First option should be filled */
|
||||||
|
@ -6454,6 +6491,7 @@ bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (const struct Tst_Question
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
bool Tst_CheckIfQuestionExistsInDB (const struct Tst_Question *Question,
|
bool Tst_CheckIfQuestionExistsInDB (const struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
const struct Tst_Answer *Answer)
|
const struct Tst_Answer *Answer)
|
||||||
{
|
{
|
||||||
extern const char *Tst_StrAnswerTypesDB[Tst_NUM_ANS_TYPES];
|
extern const char *Tst_StrAnswerTypesDB[Tst_NUM_ANS_TYPES];
|
||||||
|
@ -6476,7 +6514,7 @@ bool Tst_CheckIfQuestionExistsInDB (const struct Tst_Question *Question,
|
||||||
"SELECT QstCod FROM tst_questions"
|
"SELECT QstCod FROM tst_questions"
|
||||||
" WHERE CrsCod=%ld AND AnsType='%s' AND Stem='%s'",
|
" WHERE CrsCod=%ld AND AnsType='%s' AND Stem='%s'",
|
||||||
Gbl.Hierarchy.Crs.CrsCod,
|
Gbl.Hierarchy.Crs.CrsCod,
|
||||||
Tst_StrAnswerTypesDB[Gbl.Test.AnswerType],
|
Tst_StrAnswerTypesDB[AnswerType],
|
||||||
Question->Stem.Text);
|
Question->Stem.Text);
|
||||||
|
|
||||||
if (NumQstsWithThisStem) // There are questions in database with the same stem that the one of this question
|
if (NumQstsWithThisStem) // There are questions in database with the same stem that the one of this question
|
||||||
|
@ -6500,7 +6538,7 @@ bool Tst_CheckIfQuestionExistsInDB (const struct Tst_Question *Question,
|
||||||
" WHERE QstCod=%ld ORDER BY AnsInd",
|
" WHERE QstCod=%ld ORDER BY AnsInd",
|
||||||
QstCod);
|
QstCod);
|
||||||
|
|
||||||
switch (Gbl.Test.AnswerType)
|
switch (AnswerType)
|
||||||
{
|
{
|
||||||
case Tst_ANS_INT:
|
case Tst_ANS_INT:
|
||||||
row = mysql_fetch_row (mysql_res_ans);
|
row = mysql_fetch_row (mysql_res_ans);
|
||||||
|
@ -6562,6 +6600,7 @@ bool Tst_CheckIfQuestionExistsInDB (const struct Tst_Question *Question,
|
||||||
|
|
||||||
static void Tst_MoveMediaToDefinitiveDirectories (long QstCod,
|
static void Tst_MoveMediaToDefinitiveDirectories (long QstCod,
|
||||||
struct Tst_Question *Question,
|
struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
struct Tst_Answer *Answer)
|
struct Tst_Answer *Answer)
|
||||||
{
|
{
|
||||||
unsigned NumOpt;
|
unsigned NumOpt;
|
||||||
|
@ -6573,16 +6612,22 @@ static void Tst_MoveMediaToDefinitiveDirectories (long QstCod,
|
||||||
Med_RemoveKeepOrStoreMedia (CurrentMedCodInDB,&Question->Media);
|
Med_RemoveKeepOrStoreMedia (CurrentMedCodInDB,&Question->Media);
|
||||||
|
|
||||||
/****** Move media associated to answers *****/
|
/****** Move media associated to answers *****/
|
||||||
if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE ||
|
switch (AnswerType)
|
||||||
Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
{
|
||||||
for (NumOpt = 0;
|
case Tst_ANS_UNIQUE_CHOICE:
|
||||||
NumOpt < Answer->NumOptions;
|
case Tst_ANS_MULTIPLE_CHOICE:
|
||||||
NumOpt++)
|
for (NumOpt = 0;
|
||||||
{
|
NumOpt < Answer->NumOptions;
|
||||||
CurrentMedCodInDB = Tst_GetMedCodFromDB (Gbl.Hierarchy.Crs.CrsCod,QstCod,
|
NumOpt++)
|
||||||
NumOpt); // Get current media code associated to this option
|
{
|
||||||
Med_RemoveKeepOrStoreMedia (CurrentMedCodInDB,&Answer->Options[NumOpt].Media);
|
CurrentMedCodInDB = Tst_GetMedCodFromDB (Gbl.Hierarchy.Crs.CrsCod,QstCod,
|
||||||
}
|
NumOpt); // Get current media code associated to this option
|
||||||
|
Med_RemoveKeepOrStoreMedia (CurrentMedCodInDB,&Answer->Options[NumOpt].Media);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -6974,10 +7019,11 @@ void Tst_PutParamQstCod (long QstCod)
|
||||||
|
|
||||||
long Tst_InsertOrUpdateQstTagsAnsIntoDB (long QstCod,
|
long Tst_InsertOrUpdateQstTagsAnsIntoDB (long QstCod,
|
||||||
const struct Tst_Question *Question,
|
const struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
struct Tst_Answer *Answer)
|
struct Tst_Answer *Answer)
|
||||||
{
|
{
|
||||||
/***** Insert or update question in the table of questions *****/
|
/***** Insert or update question in the table of questions *****/
|
||||||
QstCod = Tst_InsertOrUpdateQstIntoDB (QstCod,Question);
|
QstCod = Tst_InsertOrUpdateQstIntoDB (QstCod,Question,AnswerType);
|
||||||
if (QstCod > 0)
|
if (QstCod > 0)
|
||||||
{
|
{
|
||||||
/***** Insert tags in the tags table *****/
|
/***** Insert tags in the tags table *****/
|
||||||
|
@ -6987,7 +7033,7 @@ long Tst_InsertOrUpdateQstTagsAnsIntoDB (long QstCod,
|
||||||
Tst_RemoveUnusedTagsFromCrs (Gbl.Hierarchy.Crs.CrsCod);
|
Tst_RemoveUnusedTagsFromCrs (Gbl.Hierarchy.Crs.CrsCod);
|
||||||
|
|
||||||
/***** Insert answers in the answers table *****/
|
/***** Insert answers in the answers table *****/
|
||||||
Tst_InsertAnswersIntoDB (QstCod,Answer);
|
Tst_InsertAnswersIntoDB (QstCod,AnswerType,Answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return QstCod;
|
return QstCod;
|
||||||
|
@ -6998,7 +7044,8 @@ long Tst_InsertOrUpdateQstTagsAnsIntoDB (long QstCod,
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static long Tst_InsertOrUpdateQstIntoDB (long QstCod,
|
static long Tst_InsertOrUpdateQstIntoDB (long QstCod,
|
||||||
const struct Tst_Question *Question)
|
const struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t AnswerType)
|
||||||
{
|
{
|
||||||
if (QstCod < 0) // It's a new question
|
if (QstCod < 0) // It's a new question
|
||||||
{
|
{
|
||||||
|
@ -7026,7 +7073,7 @@ static long Tst_InsertOrUpdateQstIntoDB (long QstCod,
|
||||||
"0," // NumHits
|
"0," // NumHits
|
||||||
"0)", // Score
|
"0)", // Score
|
||||||
Gbl.Hierarchy.Crs.CrsCod,
|
Gbl.Hierarchy.Crs.CrsCod,
|
||||||
Tst_StrAnswerTypesDB[Gbl.Test.AnswerType],
|
Tst_StrAnswerTypesDB[AnswerType],
|
||||||
Question->Shuffle ? 'Y' :
|
Question->Shuffle ? 'Y' :
|
||||||
'N',
|
'N',
|
||||||
Question->Stem.Text,
|
Question->Stem.Text,
|
||||||
|
@ -7047,7 +7094,7 @@ static long Tst_InsertOrUpdateQstIntoDB (long QstCod,
|
||||||
"Feedback='%s',"
|
"Feedback='%s',"
|
||||||
"MedCod=%ld"
|
"MedCod=%ld"
|
||||||
" WHERE QstCod=%ld AND CrsCod=%ld",
|
" WHERE QstCod=%ld AND CrsCod=%ld",
|
||||||
Tst_StrAnswerTypesDB[Gbl.Test.AnswerType],
|
Tst_StrAnswerTypesDB[AnswerType],
|
||||||
Question->Shuffle ? 'Y' :
|
Question->Shuffle ? 'Y' :
|
||||||
'N',
|
'N',
|
||||||
Question->Stem.Text,
|
Question->Stem.Text,
|
||||||
|
@ -7101,13 +7148,15 @@ static void Tst_InsertTagsIntoDB (long QstCod)
|
||||||
/******************* Insert answers in the answers table *********************/
|
/******************* Insert answers in the answers table *********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Tst_InsertAnswersIntoDB (long QstCod,struct Tst_Answer *Answer)
|
static void Tst_InsertAnswersIntoDB (long QstCod,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
|
struct Tst_Answer *Answer)
|
||||||
{
|
{
|
||||||
unsigned NumOpt;
|
unsigned NumOpt;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
/***** Insert answers in the answers table *****/
|
/***** Insert answers in the answers table *****/
|
||||||
switch (Gbl.Test.AnswerType)
|
switch (AnswerType)
|
||||||
{
|
{
|
||||||
case Tst_ANS_INT:
|
case Tst_ANS_INT:
|
||||||
DB_QueryINSERT ("can not create answer",
|
DB_QueryINSERT ("can not create answer",
|
||||||
|
|
|
@ -179,7 +179,7 @@ void Tst_WriteParamEditQst (void);
|
||||||
unsigned Tst_GetNumAnswersQst (long QstCod);
|
unsigned Tst_GetNumAnswersQst (long QstCod);
|
||||||
unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle);
|
unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle);
|
||||||
void Tst_GetCorrectAnswersFromDB (long QstCod,struct Tst_Answer *Answer);
|
void Tst_GetCorrectAnswersFromDB (long QstCod,struct Tst_Answer *Answer);
|
||||||
void Tst_WriteAnswersEdit (long QstCod);
|
void Tst_WriteAnswersEdit (long QstCod,Tst_AnswerType_t AnswerType);
|
||||||
bool Tst_CheckIfQuestionIsValidForGame (long QstCod);
|
bool Tst_CheckIfQuestionIsValidForGame (long QstCod);
|
||||||
void Tst_WriteAnsTF (char AnsTF);
|
void Tst_WriteAnsTF (char AnsTF);
|
||||||
void Tst_GetChoiceAns (MYSQL_RES *mysql_res,struct Tst_Answer *Answer);
|
void Tst_GetChoiceAns (MYSQL_RES *mysql_res,struct Tst_Answer *Answer);
|
||||||
|
@ -187,7 +187,8 @@ void Tst_GetIndexesFromStr (const char StrIndexesOneQst[Tst_MAX_BYTES_INDEXES_ON
|
||||||
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]);
|
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]);
|
||||||
void Tst_GetAnswersFromStr (const char StrAnswersOneQst[Tst_MAX_BYTES_ANSWERS_ONE_QST + 1],
|
void Tst_GetAnswersFromStr (const char StrAnswersOneQst[Tst_MAX_BYTES_ANSWERS_ONE_QST + 1],
|
||||||
bool AnswersUsr[Tst_MAX_OPTIONS_PER_QUESTION]);
|
bool AnswersUsr[Tst_MAX_OPTIONS_PER_QUESTION]);
|
||||||
void Tst_ComputeScoreQst (const struct Tst_Answer *Answer,
|
void Tst_ComputeScoreQst (Tst_AnswerType_t AnswerType,
|
||||||
|
const struct Tst_Answer *Answer,
|
||||||
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);
|
||||||
|
@ -212,6 +213,7 @@ void Tst_ReceiveConfigTst (void);
|
||||||
void Tst_ShowFormEditOneQst (void);
|
void Tst_ShowFormEditOneQst (void);
|
||||||
|
|
||||||
void Tst_QstConstructor (struct Tst_Question *Question,
|
void Tst_QstConstructor (struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t *AnswerType,
|
||||||
struct Tst_Answer *Answer);
|
struct Tst_Answer *Answer);
|
||||||
void Tst_QstDestructor (struct Tst_Question *Question,
|
void Tst_QstDestructor (struct Tst_Question *Question,
|
||||||
struct Tst_Answer *Answer);
|
struct Tst_Answer *Answer);
|
||||||
|
@ -221,9 +223,11 @@ int Tst_AllocateTextChoiceAnswer (struct Tst_Answer *Answer,unsigned NumOpt);
|
||||||
Tst_AnswerType_t Tst_ConvertFromStrAnsTypDBToAnsTyp (const char *StrAnsTypeBD);
|
Tst_AnswerType_t Tst_ConvertFromStrAnsTypDBToAnsTyp (const char *StrAnsTypeBD);
|
||||||
void Tst_ReceiveQst (void);
|
void Tst_ReceiveQst (void);
|
||||||
bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (const struct Tst_Question *Question,
|
bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (const struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
struct Tst_Answer *Answer);
|
struct Tst_Answer *Answer);
|
||||||
|
|
||||||
bool Tst_CheckIfQuestionExistsInDB (const struct Tst_Question *Question,
|
bool Tst_CheckIfQuestionExistsInDB (const struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
const struct Tst_Answer *Answer);
|
const struct Tst_Answer *Answer);
|
||||||
|
|
||||||
long Tst_GetIntAnsFromStr (char *Str);
|
long Tst_GetIntAnsFromStr (char *Str);
|
||||||
|
@ -242,6 +246,7 @@ void Tst_PutParamQstCod (long QstCod);
|
||||||
|
|
||||||
long Tst_InsertOrUpdateQstTagsAnsIntoDB (long QstCod,
|
long Tst_InsertOrUpdateQstTagsAnsIntoDB (long QstCod,
|
||||||
const struct Tst_Question *Question,
|
const struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
struct Tst_Answer *Answer);
|
struct Tst_Answer *Answer);
|
||||||
|
|
||||||
void Tst_RemoveCrsTests (long CrsCod);
|
void Tst_RemoveCrsTests (long CrsCod);
|
||||||
|
|
|
@ -71,16 +71,19 @@ static void TsI_PutCreateXMLParam (void);
|
||||||
static void TsI_ExportQuestion (long QstCod,FILE *FileXML);
|
static void TsI_ExportQuestion (long QstCod,FILE *FileXML);
|
||||||
|
|
||||||
static void TsI_GetAndWriteTagsXML (long QstCod,FILE *FileXML);
|
static void TsI_GetAndWriteTagsXML (long QstCod,FILE *FileXML);
|
||||||
static void TsI_WriteAnswersOfAQstXML (long QstCod,FILE *FileXML);
|
static void TsI_WriteAnswersOfAQstXML (long QstCod,Tst_AnswerType_t AnswerType,
|
||||||
|
FILE *FileXML);
|
||||||
static void TsI_ReadQuestionsFromXMLFileAndStoreInDB (const char *FileNameXML);
|
static void TsI_ReadQuestionsFromXMLFileAndStoreInDB (const char *FileNameXML);
|
||||||
static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer);
|
static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer);
|
||||||
static Tst_AnswerType_t TsI_ConvertFromStrAnsTypXMLToAnsTyp (const char *StrAnsTypeXML);
|
static Tst_AnswerType_t TsI_ConvertFromStrAnsTypXMLToAnsTyp (const char *StrAnsTypeXML);
|
||||||
static void TsI_GetAnswerFromXML (struct XMLElement *AnswerElem,
|
static void TsI_GetAnswerFromXML (struct XMLElement *AnswerElem,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
struct Tst_Answer *Answer);
|
struct Tst_Answer *Answer);
|
||||||
static void TsI_WriteHeadingListImportedQst (void);
|
static void TsI_WriteHeadingListImportedQst (void);
|
||||||
static void TsI_WriteRowImportedQst (struct XMLElement *StemElem,
|
static void TsI_WriteRowImportedQst (struct XMLElement *StemElem,
|
||||||
struct XMLElement *FeedbackElem,
|
struct XMLElement *FeedbackElem,
|
||||||
const struct Tst_Question *Question,
|
const struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
const struct Tst_Answer *Answer,
|
const struct Tst_Answer *Answer,
|
||||||
bool QuestionExists);
|
bool QuestionExists);
|
||||||
|
|
||||||
|
@ -245,6 +248,7 @@ static void TsI_ExportQuestion (long QstCod,FILE *FileXML)
|
||||||
extern const char *Txt_NEW_LINE;
|
extern const char *Txt_NEW_LINE;
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
|
Tst_AnswerType_t AnswerType;
|
||||||
|
|
||||||
if (Tst_GetOneQuestionByCod (QstCod,&mysql_res))
|
if (Tst_GetOneQuestionByCod (QstCod,&mysql_res))
|
||||||
{
|
{
|
||||||
|
@ -263,9 +267,9 @@ static void TsI_ExportQuestion (long QstCod,FILE *FileXML)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/***** Write the answer type (row[1]) *****/
|
/***** Write the answer type (row[1]) *****/
|
||||||
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
|
AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
|
||||||
fprintf (FileXML,"<question type=\"%s\">%s",
|
fprintf (FileXML,"<question type=\"%s\">%s",
|
||||||
Tst_StrAnswerTypesXML[Gbl.Test.AnswerType],Txt_NEW_LINE);
|
Tst_StrAnswerTypesXML[AnswerType],Txt_NEW_LINE);
|
||||||
|
|
||||||
/***** Write the question tags *****/
|
/***** Write the question tags *****/
|
||||||
fprintf (FileXML,"<tags>%s",Txt_NEW_LINE);
|
fprintf (FileXML,"<tags>%s",Txt_NEW_LINE);
|
||||||
|
@ -285,13 +289,13 @@ static void TsI_ExportQuestion (long QstCod,FILE *FileXML)
|
||||||
/***** Write the answers of this question.
|
/***** Write the answers of this question.
|
||||||
Shuffle can be enabled or disabled (row[2]) *****/
|
Shuffle can be enabled or disabled (row[2]) *****/
|
||||||
fprintf (FileXML,"<answer");
|
fprintf (FileXML,"<answer");
|
||||||
if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE ||
|
if (AnswerType == Tst_ANS_UNIQUE_CHOICE ||
|
||||||
Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
||||||
fprintf (FileXML," shuffle=\"%s\"",
|
fprintf (FileXML," shuffle=\"%s\"",
|
||||||
(row[2][0] == 'Y') ? "yes" :
|
(row[2][0] == 'Y') ? "yes" :
|
||||||
"no");
|
"no");
|
||||||
fprintf (FileXML,">");
|
fprintf (FileXML,">");
|
||||||
TsI_WriteAnswersOfAQstXML (QstCod,FileXML);
|
TsI_WriteAnswersOfAQstXML (QstCod,AnswerType,FileXML);
|
||||||
fprintf (FileXML,"</answer>%s",Txt_NEW_LINE);
|
fprintf (FileXML,"</answer>%s",Txt_NEW_LINE);
|
||||||
|
|
||||||
/***** End question *****/
|
/***** End question *****/
|
||||||
|
@ -331,7 +335,8 @@ static void TsI_GetAndWriteTagsXML (long QstCod,FILE *FileXML)
|
||||||
/**************** Get and write the answers of a test question ***************/
|
/**************** Get and write the answers of a test question ***************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void TsI_WriteAnswersOfAQstXML (long QstCod,FILE *FileXML)
|
static void TsI_WriteAnswersOfAQstXML (long QstCod,Tst_AnswerType_t AnswerType,
|
||||||
|
FILE *FileXML)
|
||||||
{
|
{
|
||||||
extern const char *Txt_NEW_LINE;
|
extern const char *Txt_NEW_LINE;
|
||||||
struct Tst_Answer Answer;
|
struct Tst_Answer Answer;
|
||||||
|
@ -352,7 +357,7 @@ static void TsI_WriteAnswersOfAQstXML (long QstCod,FILE *FileXML)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/***** Write answers *****/
|
/***** Write answers *****/
|
||||||
switch (Gbl.Test.AnswerType)
|
switch (AnswerType)
|
||||||
{
|
{
|
||||||
case Tst_ANS_INT:
|
case Tst_ANS_INT:
|
||||||
Tst_CheckIfNumberOfAnswersIsOne (&Answer);
|
Tst_CheckIfNumberOfAnswersIsOne (&Answer);
|
||||||
|
@ -399,7 +404,7 @@ static void TsI_WriteAnswersOfAQstXML (long QstCod,FILE *FileXML)
|
||||||
fprintf (FileXML,"<option");
|
fprintf (FileXML,"<option");
|
||||||
|
|
||||||
/* Write whether the answer is correct or not (row[4]) */
|
/* Write whether the answer is correct or not (row[4]) */
|
||||||
if (Gbl.Test.AnswerType != Tst_ANS_TEXT)
|
if (AnswerType != Tst_ANS_TEXT)
|
||||||
fprintf (FileXML," correct=\"%s\"",
|
fprintf (FileXML," correct=\"%s\"",
|
||||||
(row[4][0] == 'Y') ? "yes" :
|
(row[4][0] == 'Y') ? "yes" :
|
||||||
"no");
|
"no");
|
||||||
|
@ -535,6 +540,7 @@ static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer)
|
||||||
bool AnswerTypeFound;
|
bool AnswerTypeFound;
|
||||||
bool QuestionExists;
|
bool QuestionExists;
|
||||||
struct Tst_Question Question;
|
struct Tst_Question Question;
|
||||||
|
Tst_AnswerType_t AnswerType;
|
||||||
struct Tst_Answer Answer;
|
struct Tst_Answer Answer;
|
||||||
char Stem[Cns_MAX_BYTES_TEXT + 1];
|
char Stem[Cns_MAX_BYTES_TEXT + 1];
|
||||||
char Feedback[Cns_MAX_BYTES_TEXT + 1];
|
char Feedback[Cns_MAX_BYTES_TEXT + 1];
|
||||||
|
@ -579,124 +585,127 @@ static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer)
|
||||||
if (!strcmp (QuestionElem->TagName,"question"))
|
if (!strcmp (QuestionElem->TagName,"question"))
|
||||||
{
|
{
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor (&Question,&Answer);
|
Tst_QstConstructor (&Question,&AnswerType,&Answer);
|
||||||
|
|
||||||
/* Get type of questions (in mandatory attribute "type") */
|
/* Get answer type (in mandatory attribute "type") */
|
||||||
AnswerTypeFound = false;
|
AnswerTypeFound = false;
|
||||||
for (Attribute = QuestionElem->FirstAttribute;
|
for (Attribute = QuestionElem->FirstAttribute;
|
||||||
Attribute != NULL;
|
Attribute != NULL;
|
||||||
Attribute = Attribute->Next)
|
Attribute = Attribute->Next)
|
||||||
if (!strcmp (Attribute->AttributeName,"type"))
|
if (!strcmp (Attribute->AttributeName,"type"))
|
||||||
{
|
{
|
||||||
Gbl.Test.AnswerType = TsI_ConvertFromStrAnsTypXMLToAnsTyp (Attribute->Content);
|
AnswerType = TsI_ConvertFromStrAnsTypXMLToAnsTyp (Attribute->Content);
|
||||||
AnswerTypeFound = true;
|
AnswerTypeFound = true;
|
||||||
break; // Only first attribute "type"
|
break; // Only first attribute "type"
|
||||||
}
|
}
|
||||||
if (!AnswerTypeFound)
|
|
||||||
Lay_ShowErrorAndExit ("Wrong type of answer.");
|
|
||||||
|
|
||||||
/* Get tags */
|
if (AnswerTypeFound)
|
||||||
for (TagsElem = QuestionElem->FirstChild, Gbl.Test.Tags.Num = 0;
|
|
||||||
TagsElem != NULL;
|
|
||||||
TagsElem = TagsElem->NextBrother)
|
|
||||||
if (!strcmp (TagsElem->TagName,"tags"))
|
|
||||||
{
|
|
||||||
for (TagElem = TagsElem->FirstChild;
|
|
||||||
TagElem != NULL && Gbl.Test.Tags.Num < Tst_MAX_TAGS_PER_QUESTION;
|
|
||||||
TagElem = TagElem->NextBrother)
|
|
||||||
if (!strcmp (TagElem->TagName,"tag"))
|
|
||||||
{
|
|
||||||
if (TagElem->Content)
|
|
||||||
{
|
|
||||||
Str_Copy (Gbl.Test.Tags.Txt[Gbl.Test.Tags.Num],
|
|
||||||
TagElem->Content,
|
|
||||||
Tst_MAX_BYTES_TAG);
|
|
||||||
Gbl.Test.Tags.Num++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break; // Only first element "tags"
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get stem (mandatory) */
|
|
||||||
for (StemElem = QuestionElem->FirstChild;
|
|
||||||
StemElem != NULL;
|
|
||||||
StemElem = StemElem->NextBrother)
|
|
||||||
if (!strcmp (StemElem->TagName,"stem"))
|
|
||||||
{
|
|
||||||
if (StemElem->Content)
|
|
||||||
{
|
|
||||||
/* Convert stem from text to HTML (in database stem is stored in HTML) */
|
|
||||||
Str_Copy (Stem,StemElem->Content,
|
|
||||||
Cns_MAX_BYTES_TEXT);
|
|
||||||
Str_ChangeFormat (Str_FROM_TEXT,Str_TO_HTML,
|
|
||||||
Stem,Cns_MAX_BYTES_TEXT,true);
|
|
||||||
|
|
||||||
Question.Stem.Text = Stem;
|
|
||||||
Question.Stem.Length = strlen (Stem);
|
|
||||||
}
|
|
||||||
break; // Only first element "stem"
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get feedback (optional) */
|
|
||||||
for (FeedbackElem = QuestionElem->FirstChild;
|
|
||||||
FeedbackElem != NULL;
|
|
||||||
FeedbackElem = FeedbackElem->NextBrother)
|
|
||||||
if (!strcmp (FeedbackElem->TagName,"feedback"))
|
|
||||||
{
|
|
||||||
if (FeedbackElem->Content)
|
|
||||||
{
|
|
||||||
/* Convert feedback from text to HTML (in database feedback is stored in HTML) */
|
|
||||||
Str_Copy (Feedback,FeedbackElem->Content,
|
|
||||||
Cns_MAX_BYTES_TEXT);
|
|
||||||
Str_ChangeFormat (Str_FROM_TEXT,Str_TO_HTML,
|
|
||||||
Feedback,Cns_MAX_BYTES_TEXT,true);
|
|
||||||
|
|
||||||
Question.Feedback.Text = Feedback;
|
|
||||||
Question.Feedback.Length = strlen (Feedback);
|
|
||||||
}
|
|
||||||
break; // Only first element "feedback"
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get shuffle. By default, shuffle is false. */
|
|
||||||
Question.Shuffle = false;
|
|
||||||
for (AnswerElem = QuestionElem->FirstChild;
|
|
||||||
AnswerElem != NULL;
|
|
||||||
AnswerElem = AnswerElem->NextBrother)
|
|
||||||
if (!strcmp (AnswerElem->TagName,"answer"))
|
|
||||||
{
|
|
||||||
if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE ||
|
|
||||||
Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
|
||||||
/* Get whether shuffle answers (in attribute "shuffle") */
|
|
||||||
for (Attribute = AnswerElem->FirstAttribute;
|
|
||||||
Attribute != NULL;
|
|
||||||
Attribute = Attribute->Next)
|
|
||||||
if (!strcmp (Attribute->AttributeName,"shuffle"))
|
|
||||||
{
|
|
||||||
Question.Shuffle = XML_GetAttributteYesNoFromXMLTree (Attribute);
|
|
||||||
break; // Only first attribute "shuffle"
|
|
||||||
}
|
|
||||||
break; // Only first element "answer"
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get answer (mandatory) */
|
|
||||||
TsI_GetAnswerFromXML (AnswerElem,&Answer);
|
|
||||||
|
|
||||||
/* Make sure that tags, text and answer are not empty */
|
|
||||||
if (Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (&Question,&Answer))
|
|
||||||
{
|
{
|
||||||
/* Check if question already exists in database */
|
/* Get tags */
|
||||||
QuestionExists = Tst_CheckIfQuestionExistsInDB (&Question,&Answer);
|
for (TagsElem = QuestionElem->FirstChild, Gbl.Test.Tags.Num = 0;
|
||||||
|
TagsElem != NULL;
|
||||||
|
TagsElem = TagsElem->NextBrother)
|
||||||
|
if (!strcmp (TagsElem->TagName,"tags"))
|
||||||
|
{
|
||||||
|
for (TagElem = TagsElem->FirstChild;
|
||||||
|
TagElem != NULL && Gbl.Test.Tags.Num < Tst_MAX_TAGS_PER_QUESTION;
|
||||||
|
TagElem = TagElem->NextBrother)
|
||||||
|
if (!strcmp (TagElem->TagName,"tag"))
|
||||||
|
{
|
||||||
|
if (TagElem->Content)
|
||||||
|
{
|
||||||
|
Str_Copy (Gbl.Test.Tags.Txt[Gbl.Test.Tags.Num],
|
||||||
|
TagElem->Content,
|
||||||
|
Tst_MAX_BYTES_TAG);
|
||||||
|
Gbl.Test.Tags.Num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break; // Only first element "tags"
|
||||||
|
}
|
||||||
|
|
||||||
/* Write row with this imported question */
|
/* Get stem (mandatory) */
|
||||||
TsI_WriteRowImportedQst (StemElem,FeedbackElem,
|
for (StemElem = QuestionElem->FirstChild;
|
||||||
&Question,&Answer,
|
StemElem != NULL;
|
||||||
QuestionExists);
|
StemElem = StemElem->NextBrother)
|
||||||
|
if (!strcmp (StemElem->TagName,"stem"))
|
||||||
|
{
|
||||||
|
if (StemElem->Content)
|
||||||
|
{
|
||||||
|
/* Convert stem from text to HTML (in database stem is stored in HTML) */
|
||||||
|
Str_Copy (Stem,StemElem->Content,
|
||||||
|
Cns_MAX_BYTES_TEXT);
|
||||||
|
Str_ChangeFormat (Str_FROM_TEXT,Str_TO_HTML,
|
||||||
|
Stem,Cns_MAX_BYTES_TEXT,true);
|
||||||
|
|
||||||
/***** If a new question ==> insert question, tags and answer in the database *****/
|
Question.Stem.Text = Stem;
|
||||||
if (!QuestionExists)
|
Question.Stem.Length = strlen (Stem);
|
||||||
if (Tst_InsertOrUpdateQstTagsAnsIntoDB (-1L,&Question,&Answer) <= 0)
|
}
|
||||||
Lay_ShowErrorAndExit ("Can not create question.");
|
break; // Only first element "stem"
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get feedback (optional) */
|
||||||
|
for (FeedbackElem = QuestionElem->FirstChild;
|
||||||
|
FeedbackElem != NULL;
|
||||||
|
FeedbackElem = FeedbackElem->NextBrother)
|
||||||
|
if (!strcmp (FeedbackElem->TagName,"feedback"))
|
||||||
|
{
|
||||||
|
if (FeedbackElem->Content)
|
||||||
|
{
|
||||||
|
/* Convert feedback from text to HTML (in database feedback is stored in HTML) */
|
||||||
|
Str_Copy (Feedback,FeedbackElem->Content,
|
||||||
|
Cns_MAX_BYTES_TEXT);
|
||||||
|
Str_ChangeFormat (Str_FROM_TEXT,Str_TO_HTML,
|
||||||
|
Feedback,Cns_MAX_BYTES_TEXT,true);
|
||||||
|
|
||||||
|
Question.Feedback.Text = Feedback;
|
||||||
|
Question.Feedback.Length = strlen (Feedback);
|
||||||
|
}
|
||||||
|
break; // Only first element "feedback"
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get shuffle. By default, shuffle is false. */
|
||||||
|
Question.Shuffle = false;
|
||||||
|
for (AnswerElem = QuestionElem->FirstChild;
|
||||||
|
AnswerElem != NULL;
|
||||||
|
AnswerElem = AnswerElem->NextBrother)
|
||||||
|
if (!strcmp (AnswerElem->TagName,"answer"))
|
||||||
|
{
|
||||||
|
if (AnswerType == Tst_ANS_UNIQUE_CHOICE ||
|
||||||
|
AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
||||||
|
/* Get whether shuffle answers (in attribute "shuffle") */
|
||||||
|
for (Attribute = AnswerElem->FirstAttribute;
|
||||||
|
Attribute != NULL;
|
||||||
|
Attribute = Attribute->Next)
|
||||||
|
if (!strcmp (Attribute->AttributeName,"shuffle"))
|
||||||
|
{
|
||||||
|
Question.Shuffle = XML_GetAttributteYesNoFromXMLTree (Attribute);
|
||||||
|
break; // Only first attribute "shuffle"
|
||||||
|
}
|
||||||
|
break; // Only first element "answer"
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get answer (mandatory) */
|
||||||
|
TsI_GetAnswerFromXML (AnswerElem,AnswerType,&Answer);
|
||||||
|
|
||||||
|
/* Make sure that tags, text and answer are not empty */
|
||||||
|
if (Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (&Question,AnswerType,&Answer))
|
||||||
|
{
|
||||||
|
/* Check if question already exists in database */
|
||||||
|
QuestionExists = Tst_CheckIfQuestionExistsInDB (&Question,AnswerType,&Answer);
|
||||||
|
|
||||||
|
/* Write row with this imported question */
|
||||||
|
TsI_WriteRowImportedQst (StemElem,FeedbackElem,
|
||||||
|
&Question,AnswerType,&Answer,
|
||||||
|
QuestionExists);
|
||||||
|
|
||||||
|
/***** If a new question ==> insert question, tags and answer in the database *****/
|
||||||
|
if (!QuestionExists)
|
||||||
|
if (Tst_InsertOrUpdateQstTagsAnsIntoDB (-1L,&Question,AnswerType,&Answer) <= 0)
|
||||||
|
Lay_ShowErrorAndExit ("Can not create question.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else // Answer type not found
|
||||||
|
Lay_ShowErrorAndExit ("Wrong type of answer.");
|
||||||
|
|
||||||
/***** Destroy test question *****/
|
/***** Destroy test question *****/
|
||||||
Tst_QstDestructor (&Question,&Answer);
|
Tst_QstDestructor (&Question,&Answer);
|
||||||
|
@ -742,6 +751,7 @@ static Tst_AnswerType_t TsI_ConvertFromStrAnsTypXMLToAnsTyp (const char *StrAnsT
|
||||||
// Answer is mandatory
|
// Answer is mandatory
|
||||||
|
|
||||||
static void TsI_GetAnswerFromXML (struct XMLElement *AnswerElem,
|
static void TsI_GetAnswerFromXML (struct XMLElement *AnswerElem,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
struct Tst_Answer *Answer)
|
struct Tst_Answer *Answer)
|
||||||
{
|
{
|
||||||
struct XMLElement *OptionElem;
|
struct XMLElement *OptionElem;
|
||||||
|
@ -751,7 +761,7 @@ static void TsI_GetAnswerFromXML (struct XMLElement *AnswerElem,
|
||||||
struct XMLAttribute *Attribute;
|
struct XMLAttribute *Attribute;
|
||||||
unsigned NumOpt;
|
unsigned NumOpt;
|
||||||
|
|
||||||
switch (Gbl.Test.AnswerType)
|
switch (AnswerType)
|
||||||
{
|
{
|
||||||
case Tst_ANS_INT:
|
case Tst_ANS_INT:
|
||||||
if (!Tst_AllocateTextChoiceAnswer (Answer,0))
|
if (!Tst_AllocateTextChoiceAnswer (Answer,0))
|
||||||
|
@ -859,7 +869,7 @@ static void TsI_GetAnswerFromXML (struct XMLElement *AnswerElem,
|
||||||
break; // Only first element "feedback"
|
break; // Only first element "feedback"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Gbl.Test.AnswerType == Tst_ANS_TEXT)
|
if (AnswerType == Tst_ANS_TEXT)
|
||||||
Answer->Options[NumOpt].Correct = true;
|
Answer->Options[NumOpt].Correct = true;
|
||||||
else
|
else
|
||||||
/* Check if option is correct or wrong */
|
/* Check if option is correct or wrong */
|
||||||
|
@ -911,6 +921,7 @@ static void TsI_WriteHeadingListImportedQst (void)
|
||||||
static void TsI_WriteRowImportedQst (struct XMLElement *StemElem,
|
static void TsI_WriteRowImportedQst (struct XMLElement *StemElem,
|
||||||
struct XMLElement *FeedbackElem,
|
struct XMLElement *FeedbackElem,
|
||||||
const struct Tst_Question *Question,
|
const struct Tst_Question *Question,
|
||||||
|
Tst_AnswerType_t AnswerType,
|
||||||
const struct Tst_Answer *Answer,
|
const struct Tst_Answer *Answer,
|
||||||
bool QuestionExists)
|
bool QuestionExists)
|
||||||
{
|
{
|
||||||
|
@ -991,13 +1002,13 @@ static void TsI_WriteRowImportedQst (struct XMLElement *StemElem,
|
||||||
|
|
||||||
/***** Write the question type *****/
|
/***** Write the question type *****/
|
||||||
HTM_TD_Begin ("class=\"%s CT COLOR%u\"",ClassData,Gbl.RowEvenOdd);
|
HTM_TD_Begin ("class=\"%s CT COLOR%u\"",ClassData,Gbl.RowEvenOdd);
|
||||||
HTM_TxtF ("%s ",Txt_TST_STR_ANSWER_TYPES[Gbl.Test.AnswerType]);
|
HTM_TxtF ("%s ",Txt_TST_STR_ANSWER_TYPES[AnswerType]);
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
|
||||||
/***** Write if shuffle is enabled *****/
|
/***** Write if shuffle is enabled *****/
|
||||||
HTM_TD_Begin ("class=\"CT COLOR%u\"",Gbl.RowEvenOdd);
|
HTM_TD_Begin ("class=\"CT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE ||
|
if (AnswerType == Tst_ANS_UNIQUE_CHOICE ||
|
||||||
Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
||||||
/* Put an icon that indicates whether shuffle is enabled or not */
|
/* Put an icon that indicates whether shuffle is enabled or not */
|
||||||
if (Question->Shuffle)
|
if (Question->Shuffle)
|
||||||
Ico_PutIcon ("check.svg",Txt_TST_Answer_given_by_the_teachers,
|
Ico_PutIcon ("check.svg",Txt_TST_Answer_given_by_the_teachers,
|
||||||
|
@ -1010,7 +1021,7 @@ static void TsI_WriteRowImportedQst (struct XMLElement *StemElem,
|
||||||
Tst_WriteQstStem (Stem,ClassStem,
|
Tst_WriteQstStem (Stem,ClassStem,
|
||||||
true); // Visible
|
true); // Visible
|
||||||
Tst_WriteQstFeedback (Feedback,"TEST_EDI_LIGHT");
|
Tst_WriteQstFeedback (Feedback,"TEST_EDI_LIGHT");
|
||||||
switch (Gbl.Test.AnswerType)
|
switch (AnswerType)
|
||||||
{
|
{
|
||||||
case Tst_ANS_INT:
|
case Tst_ANS_INT:
|
||||||
HTM_SPAN_Begin ("class=\"%s\"",ClassStem);
|
HTM_SPAN_Begin ("class=\"%s\"",ClassStem);
|
||||||
|
|
Loading…
Reference in New Issue