mirror of https://github.com/acanas/swad-core.git
Version19.249
This commit is contained in:
parent
f5ba387847
commit
07078d4504
|
@ -1779,7 +1779,9 @@ static void HTM_SPTxt (const char *Txt)
|
|||
|
||||
void HTM_Txt (const char *Txt)
|
||||
{
|
||||
fputs (Txt,Gbl.F.Out);
|
||||
if (Txt)
|
||||
if (Txt[0])
|
||||
fputs (Txt,Gbl.F.Out);
|
||||
}
|
||||
|
||||
void HTM_TxtColonNBSP (const char *Txt)
|
||||
|
|
|
@ -556,10 +556,16 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
|
|||
En OpenSWAD:
|
||||
ps2pdf source.ps destination.pdf
|
||||
*/
|
||||
#define Log_PLATFORM_VERSION "SWAD 19.248.4 (2020-05-25)"
|
||||
#define Log_PLATFORM_VERSION "SWAD 19.249 (2020-06-17)"
|
||||
#define CSS_FILE "swad19.238.2.css"
|
||||
#define JS_FILE "swad19.246.1.js"
|
||||
/*
|
||||
TODO: Encarnación Hidalgo Tenorio: Antonio, ¿podría @swad_ugr mandar una notificación cuando el alumnado ha mandado su tarea?
|
||||
Se trataría de añadir un par de líneas "Nuevos archivos en actividades", "Nuevos archivos en otros trabajos".
|
||||
TODO: Fix bug: Cuando se pulsa en ver fichas, y luego en una ficha en "Ver trabajos" o "Ver exámenes", o lo que sea, sale dos veces ese estudiante.
|
||||
|
||||
Version 19.249: Jun 17, 2020 Fixed bug in exams and matches.
|
||||
Code refactoring in test questions. (302786 lines)
|
||||
Version 19.248.4: May 30, 2020 Code refactoring in selection of questions. (302867 lines)
|
||||
Version 19.248.3: May 30, 2020 Selection of all questions to add to a game. (302863 lines)
|
||||
Version 19.248.2: May 30, 2020 Selection of all questions to add to a set. Suggested by Nuria Torres Rosell. (302854 lines)
|
||||
|
|
|
@ -84,25 +84,27 @@ static void ExaPrn_ShowTableWithQstsToFill (struct Exa_Exams *Exams,
|
|||
const struct ExaPrn_Print *Print);
|
||||
static void ExaPrn_WriteQstAndAnsToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst,
|
||||
const struct Tst_Question *Question);
|
||||
struct Tst_Question *Question);
|
||||
static void ExaPrn_WriteAnswersToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst,
|
||||
const struct Tst_Question *Question);
|
||||
struct Tst_Question *Question);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void ExaPrn_WriteIntAnsToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst);
|
||||
static void ExaPrn_WriteFloAnsToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst);
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question);
|
||||
static void ExaPrn_WriteFltAnsToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question);
|
||||
static void ExaPrn_WriteTF_AnsToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst);
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question);
|
||||
static void ExaPrn_WriteChoAnsToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst,
|
||||
const struct Tst_Question *Question);
|
||||
struct Tst_Question *Question);
|
||||
static void ExaPrn_WriteTxtAnsToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst);
|
||||
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question);
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void ExaPrn_WriteJSToUpdateExamPrint (const struct ExaPrn_Print *Print,
|
||||
|
@ -117,7 +119,6 @@ static void ExaPrn_ComputeScoreAndStoreQuestionOfPrint (struct ExaPrn_Print *Pri
|
|||
unsigned NumQst);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void ExaPrn_GetCorrectAndComputeIntAnsScore (struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
struct Tst_Question *Question);
|
||||
static void ExaPrn_GetCorrectAndComputeFltAnsScore (struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
|
@ -128,15 +129,12 @@ static void ExaPrn_GetCorrectAndComputeChoAnsScore (struct TstPrn_PrintedQuestio
|
|||
struct Tst_Question *Question);
|
||||
static void ExaPrn_GetCorrectAndComputeTxtAnsScore (struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
struct Tst_Question *Question);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void ExaPrn_GetCorrectIntAnswerFromDB (struct Tst_Question *Question);
|
||||
static void ExaPrn_GetCorrectFltAnswerFromDB (struct Tst_Question *Question);
|
||||
static void ExaPrn_GetCorrectTF_AnswerFromDB (struct Tst_Question *Question);
|
||||
static void ExaPrn_GetCorrectChoAnswerFromDB (struct Tst_Question *Question);
|
||||
static void ExaPrn_GetCorrectTxtAnswerFromDB (struct Tst_Question *Question);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void ExaPrn_GetAnswerFromDB (struct ExaPrn_Print *Print,long QstCod,
|
||||
|
@ -702,7 +700,7 @@ static void ExaPrn_ShowTableWithQstsToFill (struct Exa_Exams *Exams,
|
|||
|
||||
static void ExaPrn_WriteQstAndAnsToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst,
|
||||
const struct Tst_Question *Question)
|
||||
struct Tst_Question *Question)
|
||||
{
|
||||
static struct ExaSet_Set CurrentSet =
|
||||
{
|
||||
|
@ -764,30 +762,22 @@ static void ExaPrn_WriteQstAndAnsToFill (const struct ExaPrn_Print *Print,
|
|||
|
||||
static void ExaPrn_WriteAnswersToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst,
|
||||
const struct Tst_Question *Question)
|
||||
struct Tst_Question *Question)
|
||||
{
|
||||
/***** Write answer depending on type *****/
|
||||
switch (Question->Answer.Type)
|
||||
{
|
||||
case Tst_ANS_INT:
|
||||
ExaPrn_WriteIntAnsToFill (Print,NumQst);
|
||||
break;
|
||||
case Tst_ANS_FLOAT:
|
||||
ExaPrn_WriteFloAnsToFill (Print,NumQst);
|
||||
break;
|
||||
case Tst_ANS_TRUE_FALSE:
|
||||
ExaPrn_WriteTF_AnsToFill (Print,NumQst);
|
||||
break;
|
||||
case Tst_ANS_UNIQUE_CHOICE:
|
||||
case Tst_ANS_MULTIPLE_CHOICE:
|
||||
ExaPrn_WriteChoAnsToFill (Print,NumQst,Question);
|
||||
break;
|
||||
case Tst_ANS_TEXT:
|
||||
ExaPrn_WriteTxtAnsToFill (Print,NumQst);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
void (*ExaPrn_WriteAnsToFill[Tst_NUM_ANS_TYPES]) (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst,
|
||||
struct Tst_Question *Question) =
|
||||
{
|
||||
[Tst_ANS_INT ] = ExaPrn_WriteIntAnsToFill,
|
||||
[Tst_ANS_FLOAT ] = ExaPrn_WriteFltAnsToFill,
|
||||
[Tst_ANS_TRUE_FALSE ] = ExaPrn_WriteTF_AnsToFill,
|
||||
[Tst_ANS_UNIQUE_CHOICE ] = ExaPrn_WriteChoAnsToFill,
|
||||
[Tst_ANS_MULTIPLE_CHOICE] = ExaPrn_WriteChoAnsToFill,
|
||||
[Tst_ANS_TEXT ] = ExaPrn_WriteTxtAnsToFill,
|
||||
};
|
||||
|
||||
/***** Write answers *****/
|
||||
ExaPrn_WriteAnsToFill[Question->Answer.Type] (Print,NumQst,Question);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -795,7 +785,8 @@ static void ExaPrn_WriteAnswersToFill (const struct ExaPrn_Print *Print,
|
|||
/*****************************************************************************/
|
||||
|
||||
static void ExaPrn_WriteIntAnsToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst)
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question)
|
||||
{
|
||||
char Id[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
|
||||
|
||||
|
@ -815,8 +806,9 @@ static void ExaPrn_WriteIntAnsToFill (const struct ExaPrn_Print *Print,
|
|||
/****************** Write float answer when seeing a test ********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void ExaPrn_WriteFloAnsToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst)
|
||||
static void ExaPrn_WriteFltAnsToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question)
|
||||
{
|
||||
char Id[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
|
||||
|
||||
|
@ -837,7 +829,8 @@ static void ExaPrn_WriteFloAnsToFill (const struct ExaPrn_Print *Print,
|
|||
/*****************************************************************************/
|
||||
|
||||
static void ExaPrn_WriteTF_AnsToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst)
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question)
|
||||
{
|
||||
extern const char *Txt_TF_QST[2];
|
||||
char Id[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
|
||||
|
@ -864,13 +857,16 @@ static void ExaPrn_WriteTF_AnsToFill (const struct ExaPrn_Print *Print,
|
|||
|
||||
static void ExaPrn_WriteChoAnsToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst,
|
||||
const struct Tst_Question *Question)
|
||||
struct Tst_Question *Question)
|
||||
{
|
||||
unsigned NumOpt;
|
||||
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; // Indexes of all answers of this question
|
||||
bool UsrAnswers[Tst_MAX_OPTIONS_PER_QUESTION];
|
||||
char Id[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
|
||||
|
||||
/***** Change format of answers text *****/
|
||||
Tst_ChangeFormatAnswersText (Question);
|
||||
|
||||
/***** Get indexes for this question from string *****/
|
||||
TstPrn_GetIndexesFromStr (Print->PrintedQuestions[NumQst].StrIndexes,Indexes);
|
||||
|
||||
|
@ -934,7 +930,8 @@ static void ExaPrn_WriteChoAnsToFill (const struct ExaPrn_Print *Print,
|
|||
/*****************************************************************************/
|
||||
|
||||
static void ExaPrn_WriteTxtAnsToFill (const struct ExaPrn_Print *Print,
|
||||
unsigned NumQst)
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question)
|
||||
{
|
||||
char Id[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
|
||||
|
||||
|
@ -1354,14 +1351,14 @@ static void ExaPrn_GetCorrectTxtAnswerFromDB (struct Tst_Question *Question)
|
|||
/* Abort on error */
|
||||
Ale_ShowAlertsAndExit ();
|
||||
|
||||
/***** Copy answer text (row[0]) and convert it, that is in HTML, to rigorous HTML ******/
|
||||
/***** Copy answer text (row[0]) ******/
|
||||
Str_Copy (Question->Answer.Options[NumOpt].Text,row[0],
|
||||
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);
|
||||
}
|
||||
|
||||
/***** Change format of answers text *****/
|
||||
Tst_ChangeFormatAnswersText (Question);
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ static void ExaSet_ListOneOrMoreQuestionsForEdition (struct Exa_Exams *Exams,
|
|||
unsigned NumQsts,
|
||||
MYSQL_RES *mysql_res,
|
||||
bool ICanEditQuestions);
|
||||
static void ExaSet_ListQuestionForEdition (const struct Tst_Question *Question,
|
||||
static void ExaSet_ListQuestionForEdition (struct Tst_Question *Question,
|
||||
unsigned QstInd,const char *Anchor);
|
||||
|
||||
static void ExaSet_AllocateListSelectedQuestions (struct Exa_Exams *Exams);
|
||||
|
@ -1540,7 +1540,7 @@ void ExaSet_GetAnswersQst (struct Tst_Question *Question,MYSQL_RES **mysql_res,
|
|||
/********************* List question in set for edition **********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void ExaSet_ListQuestionForEdition (const struct Tst_Question *Question,
|
||||
static void ExaSet_ListQuestionForEdition (struct Tst_Question *Question,
|
||||
unsigned QstInd,const char *Anchor)
|
||||
{
|
||||
/***** Number of question and answer type (row[1]) *****/
|
||||
|
|
15
swad_match.c
15
swad_match.c
|
@ -200,7 +200,7 @@ static void Mch_PutIfAnswered (const struct Mch_Match *Match,bool Answered);
|
|||
static void Mch_PutIconToRemoveMyAnswer (const struct Mch_Match *Match);
|
||||
static void Mch_ShowQuestionAndAnswersTch (const struct Mch_Match *Match);
|
||||
static void Mch_WriteAnswersMatchResult (const struct Mch_Match *Match,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
const char *Class,bool ShowResult);
|
||||
static bool Mch_ShowQuestionAndAnswersStd (const struct Mch_Match *Match,
|
||||
const struct Mch_UsrAnswer *UsrAnswer,
|
||||
|
@ -3078,7 +3078,7 @@ static void Mch_ShowQuestionAndAnswersTch (const struct Mch_Match *Match)
|
|||
/*****************************************************************************/
|
||||
|
||||
static void Mch_WriteAnswersMatchResult (const struct Mch_Match *Match,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
const char *Class,bool ShowResult)
|
||||
{
|
||||
/***** Write answer depending on type *****/
|
||||
|
@ -3095,7 +3095,7 @@ static void Mch_WriteAnswersMatchResult (const struct Mch_Match *Match,
|
|||
/*****************************************************************************/
|
||||
|
||||
void Mch_WriteChoiceAnsViewMatch (const struct Mch_Match *Match,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
const char *Class,bool ShowResult)
|
||||
{
|
||||
unsigned NumOpt;
|
||||
|
@ -3107,6 +3107,9 @@ void Mch_WriteChoiceAnsViewMatch (const struct Mch_Match *Match,
|
|||
/***** Get number of users who have answered this question from database *****/
|
||||
NumRespondersQst = Mch_GetNumUsrsWhoAnsweredQst (Match->MchCod,Match->Status.QstInd);
|
||||
|
||||
/***** Change format of answers text *****/
|
||||
Tst_ChangeFormatAnswersText (Question);
|
||||
|
||||
/***** Get indexes for this question in match *****/
|
||||
Mch_GetIndexes (Match->MchCod,Match->Status.QstInd,Indexes);
|
||||
|
||||
|
@ -3135,13 +3138,7 @@ void Mch_WriteChoiceAnsViewMatch (const struct Mch_Match *Match,
|
|||
/***** 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);
|
||||
|
||||
/* Convert text, that is in HTML, to rigorous HTML */
|
||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
Question->Answer.Options[NumOpt].Text,
|
||||
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||
HTM_Txt (Question->Answer.Options[Indexes[NumOpt]].Text);
|
||||
|
||||
HTM_LABEL_End ();
|
||||
Med_ShowMedia (&Question->Answer.Options[Indexes[NumOpt]].Media,
|
||||
"TEST_MED_SHOW_CONT",
|
||||
|
|
|
@ -128,7 +128,7 @@ unsigned Mch_GetNumUnfinishedMchsInGame (long GamCod);
|
|||
bool Mch_CheckIfICanPlayThisMatchBasedOnGrps (const struct Mch_Match *Match);
|
||||
|
||||
void Mch_WriteChoiceAnsViewMatch (const struct Mch_Match *Match,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
const char *Class,bool ShowResult);
|
||||
|
||||
bool Mch_RegisterMeAsPlayerInMatch (struct Mch_Match *Match);
|
||||
|
|
552
swad_test.c
552
swad_test.c
|
@ -100,13 +100,6 @@ const char *Tst_StrAnswerTypesDB[Tst_NUM_ANS_TYPES] =
|
|||
/******************************* Private types *******************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define Tst_NUM_REQUEST_OR_CONFIRM 2
|
||||
typedef enum
|
||||
{
|
||||
Tst_REQUEST,
|
||||
Tst_CONFIRM,
|
||||
} Tst_RequestOrConfirm_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
/************** External global variables from others modules ****************/
|
||||
/*****************************************************************************/
|
||||
|
@ -126,18 +119,10 @@ static void Tst_TstDestructor (struct Tst_Test *Test);
|
|||
|
||||
static void Tst_ShowFormRequestTest (struct Tst_Test *Test);
|
||||
|
||||
static void Tst_PutCheckBoxAllowTeachers (bool AllowTeachers);
|
||||
|
||||
static void TstPrn_GetAnswersFromForm (struct TstPrn_Print *Print);
|
||||
|
||||
static bool Tst_CheckIfNextTstAllowed (void);
|
||||
static unsigned Tst_GetNumExamsGeneratedByMe (void);
|
||||
static void Tst_ShowTestPrintToFillIt (struct TstPrn_Print *Print,
|
||||
unsigned NumExamsGeneratedByMe,
|
||||
Tst_RequestOrConfirm_t RequestOrConfirm);
|
||||
static void TstPrn_WriteQstAndAnsToFill (struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
const struct Tst_Question *Question);
|
||||
|
||||
static void Tst_PutFormToEditQstMedia (const struct Media *Media,int NumMediaInForm,
|
||||
bool OptionsDisabled);
|
||||
|
@ -180,34 +165,12 @@ static void Tst_PutCheckboxToSelectAllQuestions (void);
|
|||
static void Tst_WriteQuestionRowForSelection (unsigned NumQst,
|
||||
struct Tst_Question *Question);
|
||||
|
||||
static void TstPrn_WriteAnswersToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
const struct Tst_Question *Question);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void Tst_WriteIntAnsBank (const struct Tst_Question *Question);
|
||||
static void Tst_WriteFltAnsBank (const struct Tst_Question *Question);
|
||||
static void Tst_WriteTF_AnsBank (const struct Tst_Question *Question);
|
||||
static void Tst_WriteChoAnsBank (const struct Tst_Question *Question);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void TstPrn_WriteIntAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) const struct Tst_Question *Question);
|
||||
static void TstPrn_WriteFltAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) const struct Tst_Question *Question);
|
||||
static void TstPrn_WriteTF_AnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) const struct Tst_Question *Question);
|
||||
static void TstPrn_WriteChoAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
const struct Tst_Question *Question);
|
||||
static void TstPrn_WriteTxtAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) const struct Tst_Question *Question);
|
||||
static void Tst_WriteIntAnsBank (struct Tst_Question *Question);
|
||||
static void Tst_WriteFltAnsBank (struct Tst_Question *Question);
|
||||
static void Tst_WriteTF_AnsBank (struct Tst_Question *Question);
|
||||
static void Tst_WriteChoAnsBank (struct Tst_Question *Question);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -428,7 +391,7 @@ void Tst_ShowNewTest (void)
|
|||
false); // Don't update question score
|
||||
|
||||
/***** Show test exam to be answered *****/
|
||||
Tst_ShowTestPrintToFillIt (&Print,NumExamsGeneratedByMe,Tst_REQUEST);
|
||||
TstPrn_ShowTestPrintToFillIt (&Print,NumExamsGeneratedByMe,TstPrn_REQUEST);
|
||||
|
||||
/***** Update date-time of my next allowed access to test *****/
|
||||
if (Gbl.Usrs.Me.Role.Logged == Rol_STD)
|
||||
|
@ -448,27 +411,6 @@ void Tst_ShowNewTest (void)
|
|||
Tst_TstDestructor (&Test);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************* Put checkbox to allow teachers to see test exam ***************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Tst_PutCheckBoxAllowTeachers (bool AllowTeachers)
|
||||
{
|
||||
extern const char *The_ClassFormInBox[The_NUM_THEMES];
|
||||
extern const char *Txt_Allow_teachers_to_consult_this_test;
|
||||
|
||||
/***** Test exam will be available for teachers? *****/
|
||||
HTM_DIV_Begin ("class=\"CM\"");
|
||||
HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]);
|
||||
HTM_INPUT_CHECKBOX ("AllowTchs",HTM_DONT_SUBMIT_ON_CHANGE,
|
||||
"value=\"Y\"%s",
|
||||
AllowTeachers ? " checked=\"checked\"" : // Teachers can see test exam
|
||||
"");
|
||||
HTM_TxtF (" %s",Txt_Allow_teachers_to_consult_this_test);
|
||||
HTM_LABEL_End ();
|
||||
HTM_DIV_End ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/** Receive the draft of a test exam already (total or partially) answered ***/
|
||||
/*****************************************************************************/
|
||||
|
@ -517,7 +459,7 @@ void Tst_ReceiveTestDraft (void)
|
|||
Ale_ShowAlert (Ale_WARNING,Txt_Please_review_your_answers_before_submitting_the_exam);
|
||||
|
||||
/* Show the same test exam to be answered */
|
||||
Tst_ShowTestPrintToFillIt (&Print,NumTst,Tst_CONFIRM);
|
||||
TstPrn_ShowTestPrintToFillIt (&Print,NumTst,TstPrn_CONFIRM);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -739,92 +681,6 @@ static unsigned Tst_GetNumExamsGeneratedByMe (void)
|
|||
return NumExamsGeneratedByMe;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************** Show a test exam print to be answered ********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Tst_ShowTestPrintToFillIt (struct TstPrn_Print *Print,
|
||||
unsigned NumExamsGeneratedByMe,
|
||||
Tst_RequestOrConfirm_t RequestOrConfirm)
|
||||
{
|
||||
extern const char *Hlp_ASSESSMENT_Tests;
|
||||
extern const char *Txt_Test;
|
||||
extern const char *Txt_Continue;
|
||||
extern const char *Txt_Send;
|
||||
unsigned NumQst;
|
||||
struct Tst_Question Question;
|
||||
static const Act_Action_t Action[Tst_NUM_REQUEST_OR_CONFIRM] =
|
||||
{
|
||||
[Tst_REQUEST] = ActReqAssTst,
|
||||
[Tst_CONFIRM] = ActAssTst,
|
||||
};
|
||||
|
||||
/***** Begin box *****/
|
||||
Box_BoxBegin (NULL,Txt_Test,
|
||||
NULL,NULL,
|
||||
Hlp_ASSESSMENT_Tests,Box_NOT_CLOSABLE);
|
||||
Lay_WriteHeaderClassPhoto (false,false,
|
||||
Gbl.Hierarchy.Ins.InsCod,
|
||||
Gbl.Hierarchy.Deg.DegCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod);
|
||||
|
||||
if (Print->NumQsts)
|
||||
{
|
||||
/***** Begin form *****/
|
||||
Frm_StartForm (Action[RequestOrConfirm]);
|
||||
TstPrn_PutParamPrnCod (Print->PrnCod);
|
||||
Par_PutHiddenParamUnsigned (NULL,"NumTst",NumExamsGeneratedByMe);
|
||||
|
||||
/***** Begin table *****/
|
||||
HTM_TABLE_BeginWideMarginPadding (10);
|
||||
|
||||
/***** Write one row for each question *****/
|
||||
for (NumQst = 0;
|
||||
NumQst < Print->NumQsts;
|
||||
NumQst++)
|
||||
{
|
||||
Gbl.RowEvenOdd = NumQst % 2;
|
||||
|
||||
/* Create test question */
|
||||
Tst_QstConstructor (&Question);
|
||||
Question.QstCod = Print->PrintedQuestions[NumQst].QstCod;
|
||||
|
||||
/* Show question */
|
||||
if (!Tst_GetQstDataFromDB (&Question)) // Question exists
|
||||
Lay_ShowErrorAndExit ("Wrong question.");
|
||||
|
||||
/* Write question and answers */
|
||||
TstPrn_WriteQstAndAnsToFill (&Print->PrintedQuestions[NumQst],NumQst,&Question);
|
||||
|
||||
/* Destroy test question */
|
||||
Tst_QstDestructor (&Question);
|
||||
}
|
||||
|
||||
/***** End table *****/
|
||||
HTM_TABLE_End ();
|
||||
|
||||
/***** End form *****/
|
||||
switch (RequestOrConfirm)
|
||||
{
|
||||
case Tst_REQUEST:
|
||||
/* Send button */
|
||||
Btn_PutConfirmButton (Txt_Continue);
|
||||
break;
|
||||
case Tst_CONFIRM:
|
||||
/* Will the test exam be visible by teachers? */
|
||||
Tst_PutCheckBoxAllowTeachers (true);
|
||||
|
||||
/* Send button */
|
||||
Btn_PutCreateButton (Txt_Send);
|
||||
break;
|
||||
}
|
||||
Frm_EndForm ();
|
||||
}
|
||||
|
||||
/***** End box *****/
|
||||
Box_BoxEnd ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************** Show list of test tags ***************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -854,51 +710,11 @@ void Tst_ShowTagList (unsigned NumTags,MYSQL_RES *mysql_res)
|
|||
HTM_Txt (Txt_no_tags);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********** Write a row of a test, with one question and its answer **********/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TstPrn_WriteQstAndAnsToFill (struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
const struct Tst_Question *Question)
|
||||
{
|
||||
/***** Begin row *****/
|
||||
HTM_TR_Begin (NULL);
|
||||
|
||||
/***** Number of question and answer type *****/
|
||||
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
|
||||
Tst_WriteNumQst (NumQst + 1);
|
||||
Tst_WriteAnswerType (Question->Answer.Type);
|
||||
HTM_TD_End ();
|
||||
|
||||
/***** Stem, media and answers *****/
|
||||
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||
|
||||
/* Write parameter with question code */
|
||||
Tst_WriteParamQstCod (NumQst,Question->QstCod);
|
||||
|
||||
/* Stem */
|
||||
Tst_WriteQstStem (Question->Stem,"TEST_EXA",true);
|
||||
|
||||
/* Media */
|
||||
Med_ShowMedia (&Question->Media,
|
||||
"TEST_MED_SHOW_CONT",
|
||||
"TEST_MED_SHOW");
|
||||
|
||||
/* Answers */
|
||||
TstPrn_WriteAnswersToFill (PrintedQuestion,NumQst,Question);
|
||||
|
||||
HTM_TD_End ();
|
||||
|
||||
/***** End row *****/
|
||||
HTM_TR_End ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************* List game question for edition ************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Tst_ListQuestionForEdition (const struct Tst_Question *Question,
|
||||
void Tst_ListQuestionForEdition (struct Tst_Question *Question,
|
||||
unsigned QstInd,bool QuestionExists,
|
||||
const char *Anchor)
|
||||
{
|
||||
|
@ -2911,13 +2727,48 @@ void Tst_GetAnswersQst (struct Tst_Question *Question,MYSQL_RES **mysql_res,
|
|||
Ale_ShowAlert (Ale_ERROR,"Error when getting answers of a question.");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************** Change format of answers text / feedback ******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Tst_ChangeFormatAnswersText (struct Tst_Question *Question)
|
||||
{
|
||||
unsigned NumOpt;
|
||||
|
||||
/***** Change format of answers text *****/
|
||||
for (NumOpt = 0;
|
||||
NumOpt < Question->Answer.NumOptions;
|
||||
NumOpt++)
|
||||
/* Convert answer text, that is in HTML, to rigorous HTML */
|
||||
if (Question->Answer.Options[NumOpt].Text[0])
|
||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
Question->Answer.Options[NumOpt].Text,
|
||||
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||
}
|
||||
|
||||
void Tst_ChangeFormatAnswersFeedback (struct Tst_Question *Question)
|
||||
{
|
||||
unsigned NumOpt;
|
||||
|
||||
/***** Change format of answers text and feedback *****/
|
||||
for (NumOpt = 0;
|
||||
NumOpt < Question->Answer.NumOptions;
|
||||
NumOpt++)
|
||||
/* Convert answer feedback, that is in HTML, to rigorous HTML */
|
||||
if (Question->Answer.Options[NumOpt].Feedback)
|
||||
if (Question->Answer.Options[NumOpt].Feedback[0])
|
||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
Question->Answer.Options[NumOpt].Feedback,
|
||||
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**************** Get and write the answers of a test question ***************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Tst_WriteAnswersBank (const struct Tst_Question *Question)
|
||||
void Tst_WriteAnswersBank (struct Tst_Question *Question)
|
||||
{
|
||||
void (*TstPrn_WriteAnsBank[Tst_NUM_ANS_TYPES]) (const struct Tst_Question *Question) =
|
||||
void (*Tst_WriteAnsBank[Tst_NUM_ANS_TYPES]) (struct Tst_Question *Question) =
|
||||
{
|
||||
[Tst_ANS_INT ] = Tst_WriteIntAnsBank,
|
||||
[Tst_ANS_FLOAT ] = Tst_WriteFltAnsBank,
|
||||
|
@ -2928,31 +2779,7 @@ void Tst_WriteAnswersBank (const struct Tst_Question *Question)
|
|||
};
|
||||
|
||||
/***** Write answers *****/
|
||||
TstPrn_WriteAnsBank[Question->Answer.Type] (Question);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************** Write answers of a question to fill them ******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TstPrn_WriteAnswersToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
const struct Tst_Question *Question)
|
||||
{
|
||||
void (*TstPrn_WriteAnsBank[Tst_NUM_ANS_TYPES]) (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
const struct Tst_Question *Question) =
|
||||
{
|
||||
[Tst_ANS_INT ] = TstPrn_WriteIntAnsToFill,
|
||||
[Tst_ANS_FLOAT ] = TstPrn_WriteFltAnsToFill,
|
||||
[Tst_ANS_TRUE_FALSE ] = TstPrn_WriteTF_AnsToFill,
|
||||
[Tst_ANS_UNIQUE_CHOICE ] = TstPrn_WriteChoAnsToFill,
|
||||
[Tst_ANS_MULTIPLE_CHOICE] = TstPrn_WriteChoAnsToFill,
|
||||
[Tst_ANS_TEXT ] = TstPrn_WriteTxtAnsToFill,
|
||||
};
|
||||
|
||||
/***** Write answers *****/
|
||||
TstPrn_WriteAnsBank[Question->Answer.Type] (PrintedQuestion,NumQst,Question);
|
||||
Tst_WriteAnsBank[Question->Answer.Type] (Question);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -2973,7 +2800,7 @@ bool Tst_CheckIfQuestionIsValidForGame (long QstCod)
|
|||
/****************** Write integer answer when editing a test *****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Tst_WriteIntAnsBank (const struct Tst_Question *Question)
|
||||
static void Tst_WriteIntAnsBank (struct Tst_Question *Question)
|
||||
{
|
||||
HTM_SPAN_Begin ("class=\"TEST_EDI\"");
|
||||
HTM_TxtF ("(%ld)",Question->Answer.Integer);
|
||||
|
@ -2984,7 +2811,7 @@ static void Tst_WriteIntAnsBank (const struct Tst_Question *Question)
|
|||
/****************** Write float answer when editing a test *******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Tst_WriteFltAnsBank (const struct Tst_Question *Question)
|
||||
static void Tst_WriteFltAnsBank (struct Tst_Question *Question)
|
||||
{
|
||||
HTM_SPAN_Begin ("class=\"TEST_EDI\"");
|
||||
HTM_Txt ("([");
|
||||
|
@ -2999,7 +2826,7 @@ static void Tst_WriteFltAnsBank (const struct Tst_Question *Question)
|
|||
/*********** Write false / true answer when listing test questions ***********/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Tst_WriteTF_AnsBank (const struct Tst_Question *Question)
|
||||
static void Tst_WriteTF_AnsBank (struct Tst_Question *Question)
|
||||
{
|
||||
/***** Write answer *****/
|
||||
HTM_SPAN_Begin ("class=\"TEST_EDI\"");
|
||||
|
@ -3013,50 +2840,22 @@ static void Tst_WriteTF_AnsBank (const struct Tst_Question *Question)
|
|||
/**** Write single or multiple choice answer when listing test questions *****/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Tst_WriteChoAnsBank (const struct Tst_Question *Question)
|
||||
static void Tst_WriteChoAnsBank (struct Tst_Question *Question)
|
||||
{
|
||||
extern const char *Txt_TST_Answer_given_by_the_teachers;
|
||||
unsigned NumOpt;
|
||||
char *AnswerTxt;
|
||||
char *Feedback;
|
||||
size_t LengthAnswerTxt;
|
||||
size_t LengthFeedback;
|
||||
|
||||
/***** Change format of answers text *****/
|
||||
Tst_ChangeFormatAnswersText (Question);
|
||||
|
||||
/***** Change format of answers feedback *****/
|
||||
Tst_ChangeFormatAnswersFeedback (Question);
|
||||
|
||||
HTM_TABLE_BeginPadding (2);
|
||||
for (NumOpt = 0;
|
||||
NumOpt < Question->Answer.NumOptions;
|
||||
NumOpt++)
|
||||
{
|
||||
/* Convert the answer, that is in HTML, to rigorous HTML */
|
||||
LengthAnswerTxt = 0;
|
||||
AnswerTxt = NULL;
|
||||
if (Question->Answer.Options[NumOpt].Text)
|
||||
if (Question->Answer.Options[NumOpt].Text[0])
|
||||
{
|
||||
LengthAnswerTxt = strlen (Question->Answer.Options[NumOpt].Text) * Str_MAX_BYTES_PER_CHAR;
|
||||
if ((AnswerTxt = (char *) malloc (LengthAnswerTxt + 1)) == NULL)
|
||||
Lay_NotEnoughMemoryExit ();
|
||||
Str_Copy (AnswerTxt,Question->Answer.Options[NumOpt].Text,
|
||||
LengthAnswerTxt);
|
||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
AnswerTxt,LengthAnswerTxt,false);
|
||||
}
|
||||
|
||||
/* Convert the feedback, that is in HTML, to rigorous HTML */
|
||||
LengthFeedback = 0;
|
||||
Feedback = NULL;
|
||||
if (Question->Answer.Options[NumOpt].Feedback)
|
||||
if (Question->Answer.Options[NumOpt].Feedback[0])
|
||||
{
|
||||
LengthFeedback = strlen (Question->Answer.Options[NumOpt].Feedback) * Str_MAX_BYTES_PER_CHAR;
|
||||
if ((Feedback = (char *) malloc (LengthFeedback + 1)) == NULL)
|
||||
Lay_NotEnoughMemoryExit ();
|
||||
Str_Copy (Feedback,Question->Answer.Options[NumOpt].Feedback,
|
||||
LengthFeedback);
|
||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
Feedback,LengthFeedback,false);
|
||||
}
|
||||
|
||||
HTM_TR_Begin (NULL);
|
||||
|
||||
/* Put an icon that indicates whether the answer is correct or wrong */
|
||||
|
@ -3074,8 +2873,7 @@ static void Tst_WriteChoAnsBank (const struct Tst_Question *Question)
|
|||
|
||||
/* Write the text of the answer and the media */
|
||||
HTM_DIV_Begin ("class=\"TEST_EDI\"");
|
||||
if (LengthAnswerTxt)
|
||||
HTM_Txt (AnswerTxt);
|
||||
HTM_Txt (Question->Answer.Options[NumOpt].Text);
|
||||
Med_ShowMedia (&Question->Answer.Options[NumOpt].Media,
|
||||
"TEST_MED_EDIT_LIST_CONT",
|
||||
"TEST_MED_EDIT_LIST");
|
||||
|
@ -3083,192 +2881,16 @@ static void Tst_WriteChoAnsBank (const struct Tst_Question *Question)
|
|||
|
||||
/* Write the text of the feedback */
|
||||
HTM_DIV_Begin ("class=\"TEST_EDI_LIGHT\"");
|
||||
if (LengthFeedback)
|
||||
HTM_Txt (Feedback);
|
||||
HTM_Txt (Question->Answer.Options[NumOpt].Feedback);
|
||||
HTM_DIV_End ();
|
||||
|
||||
HTM_TD_End ();
|
||||
|
||||
HTM_TR_End ();
|
||||
|
||||
/* Free memory allocated for the answer and the feedback */
|
||||
free (AnswerTxt);
|
||||
if (LengthFeedback)
|
||||
free (Feedback);
|
||||
}
|
||||
HTM_TABLE_End ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************** Write integer answer when seeing a test ******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TstPrn_WriteIntAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) const struct Tst_Question *Question)
|
||||
{
|
||||
char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
|
||||
|
||||
/***** Write input field for the answer *****/
|
||||
snprintf (StrAns,sizeof (StrAns),
|
||||
"Ans%010u",
|
||||
NumQst);
|
||||
HTM_INPUT_TEXT (StrAns,11,PrintedQuestion->StrAnswers,
|
||||
HTM_DONT_SUBMIT_ON_CHANGE,
|
||||
"size=\"11\"");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************** Write float answer when seeing a test ********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TstPrn_WriteFltAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) const struct Tst_Question *Question)
|
||||
{
|
||||
char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
|
||||
|
||||
/***** Write input field for the answer *****/
|
||||
snprintf (StrAns,sizeof (StrAns),
|
||||
"Ans%010u",
|
||||
NumQst);
|
||||
HTM_INPUT_TEXT (StrAns,Tst_MAX_BYTES_FLOAT_ANSWER,PrintedQuestion->StrAnswers,
|
||||
HTM_DONT_SUBMIT_ON_CHANGE,
|
||||
"size=\"11\"");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************** Write false / true answer when seeing a test ****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TstPrn_WriteTF_AnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) const struct Tst_Question *Question)
|
||||
{
|
||||
extern const char *Txt_TF_QST[2];
|
||||
|
||||
/***** Write selector for the answer *****/
|
||||
/* Initially user has not answered the question ==> initially all the answers will be blank.
|
||||
If the user does not confirm the submission of their exam ==>
|
||||
==> the exam may be half filled ==> the answers displayed will be those selected by the user. */
|
||||
HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE,
|
||||
"name=\"Ans%010u\"",NumQst);
|
||||
HTM_OPTION (HTM_Type_STRING,"" ,PrintedQuestion->StrAnswers[0] == '\0',false," ");
|
||||
HTM_OPTION (HTM_Type_STRING,"T",PrintedQuestion->StrAnswers[0] == 'T' ,false,"%s",Txt_TF_QST[0]);
|
||||
HTM_OPTION (HTM_Type_STRING,"F",PrintedQuestion->StrAnswers[0] == 'F' ,false,"%s",Txt_TF_QST[1]);
|
||||
HTM_SELECT_End ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******** Write single or multiple choice answer when seeing a test **********/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TstPrn_WriteChoAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
const struct Tst_Question *Question)
|
||||
{
|
||||
unsigned NumOpt;
|
||||
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; // Indexes of all answers of this question
|
||||
bool UsrAnswers[Tst_MAX_OPTIONS_PER_QUESTION];
|
||||
char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
|
||||
|
||||
/***** Change format of answers text *****/
|
||||
for (NumOpt = 0;
|
||||
NumOpt < Question->Answer.NumOptions;
|
||||
NumOpt++)
|
||||
/* Convert answer text, that is in HTML, to rigorous HTML */
|
||||
if (Question->Answer.Options[NumOpt].Text[0])
|
||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
Question->Answer.Options[NumOpt].Text,
|
||||
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||
|
||||
/***** Get indexes for this question from string *****/
|
||||
TstPrn_GetIndexesFromStr (PrintedQuestion->StrIndexes,Indexes);
|
||||
|
||||
/***** Get the user's answers for this question from string *****/
|
||||
TstPrn_GetAnswersFromStr (PrintedQuestion->StrAnswers,UsrAnswers);
|
||||
|
||||
/***** Begin table *****/
|
||||
HTM_TABLE_BeginPadding (2);
|
||||
|
||||
for (NumOpt = 0;
|
||||
NumOpt < Question->Answer.NumOptions;
|
||||
NumOpt++)
|
||||
{
|
||||
/***** Indexes are 0 1 2 3... if no shuffle
|
||||
or 3 1 0 2... (example) if shuffle *****/
|
||||
HTM_TR_Begin (NULL);
|
||||
|
||||
/***** Write selectors and letter of this option *****/
|
||||
/* Initially user has not answered the question ==> initially all the answers will be blank.
|
||||
If the user does not confirm the submission of their exam ==>
|
||||
==> the exam may be half filled ==> the answers displayed will be those selected by the user. */
|
||||
HTM_TD_Begin ("class=\"LT\"");
|
||||
|
||||
snprintf (StrAns,sizeof (StrAns),
|
||||
"Ans%010u",
|
||||
NumQst);
|
||||
if (Question->Answer.Type == Tst_ANS_UNIQUE_CHOICE)
|
||||
HTM_INPUT_RADIO (StrAns,false,
|
||||
"id=\"Ans%010u_%u\" value=\"%u\"%s"
|
||||
" onclick=\"selectUnselectRadio(this,this.form.Ans%010u,%u);\"",
|
||||
NumQst,NumOpt,
|
||||
Indexes[NumOpt],
|
||||
UsrAnswers[Indexes[NumOpt]] ? " checked=\"checked\"" :
|
||||
"",
|
||||
NumQst,Question->Answer.NumOptions);
|
||||
else // Answer.Type == Tst_ANS_MULTIPLE_CHOICE
|
||||
HTM_INPUT_CHECKBOX (StrAns,HTM_DONT_SUBMIT_ON_CHANGE,
|
||||
"id=\"Ans%010u_%u\" value=\"%u\"%s",
|
||||
NumQst,NumOpt,
|
||||
Indexes[NumOpt],
|
||||
UsrAnswers[Indexes[NumOpt]] ? " checked=\"checked\"" :
|
||||
"");
|
||||
|
||||
HTM_TD_End ();
|
||||
|
||||
HTM_TD_Begin ("class=\"LT\"");
|
||||
HTM_LABEL_Begin ("for=\"Ans%010u_%u\" class=\"ANS_TXT\"",NumQst,NumOpt);
|
||||
HTM_TxtF ("%c) ",'a' + (char) NumOpt);
|
||||
HTM_LABEL_End ();
|
||||
HTM_TD_End ();
|
||||
|
||||
/***** Write the option text *****/
|
||||
HTM_TD_Begin ("class=\"LT\"");
|
||||
HTM_LABEL_Begin ("for=\"Ans%010u_%u\" class=\"ANS_TXT\"",NumQst,NumOpt);
|
||||
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");
|
||||
HTM_TD_End ();
|
||||
|
||||
HTM_TR_End ();
|
||||
}
|
||||
|
||||
/***** End table *****/
|
||||
HTM_TABLE_End ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************** Write text answer when seeing a test *******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TstPrn_WriteTxtAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) const struct Tst_Question *Question)
|
||||
{
|
||||
char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
|
||||
|
||||
/***** Write input field for the answer *****/
|
||||
snprintf (StrAns,sizeof (StrAns),
|
||||
"Ans%010u",
|
||||
NumQst);
|
||||
HTM_INPUT_TEXT (StrAns,Tst_MAX_CHARS_ANSWERS_ONE_QST,PrintedQuestion->StrAnswers,
|
||||
HTM_DONT_SUBMIT_ON_CHANGE,
|
||||
"size=\"40\"");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************** Write false / true answer when seeing a test *****************/
|
||||
/*****************************************************************************/
|
||||
|
@ -3291,66 +2913,6 @@ void Tst_WriteAnsTF (char AnsTF)
|
|||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************ Get choice answer from row *************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Tst_GetChoiceAns (struct Tst_Question *Question,MYSQL_RES *mysql_res)
|
||||
{
|
||||
unsigned NumOpt;
|
||||
MYSQL_ROW row;
|
||||
|
||||
/***** Get text and correctness of answers for this question
|
||||
from database (one row per answer) *****/
|
||||
/*
|
||||
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 option *****/
|
||||
if (!Tst_AllocateTextChoiceAnswer (Question,NumOpt))
|
||||
/* Abort on error */
|
||||
Ale_ShowAlertsAndExit ();
|
||||
|
||||
/***** Copy answer 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);
|
||||
|
||||
/***** Copy answer feedback (row[2]) and convert it,
|
||||
that is in HTML, to rigorous HTML ******/
|
||||
if (TstVis_IsVisibleFeedbackTxt (TstCfg_GetConfigVisibility ()))
|
||||
if (row[2])
|
||||
if (row[2][0])
|
||||
{
|
||||
Str_Copy (Question->Answer.Options[NumOpt].Feedback,row[2],
|
||||
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
Question->Answer.Options[NumOpt].Feedback,
|
||||
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);
|
||||
|
||||
/***** Assign correctness (row[4]) of this answer (this option) *****/
|
||||
Question->Answer.Options[NumOpt].Correct = (row[4][0] == 'Y');
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*************** Write parameter with the code of a question *****************/
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -106,7 +106,7 @@ void Tst_AssessTest (void);
|
|||
|
||||
void Tst_ShowTagList (unsigned NumTags,MYSQL_RES *mysql_res);
|
||||
|
||||
void Tst_ListQuestionForEdition (const struct Tst_Question *Question,
|
||||
void Tst_ListQuestionForEdition (struct Tst_Question *Question,
|
||||
unsigned QstInd,bool QuestionExists,
|
||||
const char *Anchor);
|
||||
void Tst_WriteNumQst (unsigned NumQst);
|
||||
|
@ -130,10 +130,13 @@ void Tst_WriteParamEditQst (const struct Tst_Test *Test);
|
|||
unsigned Tst_GetNumAnswersQst (long QstCod);
|
||||
void Tst_GetAnswersQst (struct Tst_Question *Question,MYSQL_RES **mysql_res,
|
||||
bool Shuffle);
|
||||
void Tst_WriteAnswersBank (const struct Tst_Question *Question);
|
||||
|
||||
void Tst_ChangeFormatAnswersText (struct Tst_Question *Question);
|
||||
void Tst_ChangeFormatAnswersFeedback (struct Tst_Question *Question);
|
||||
|
||||
void Tst_WriteAnswersBank (struct Tst_Question *Question);
|
||||
bool Tst_CheckIfQuestionIsValidForGame (long QstCod);
|
||||
void Tst_WriteAnsTF (char AnsTF);
|
||||
void Tst_GetChoiceAns (struct Tst_Question *Question,MYSQL_RES *mysql_res);
|
||||
|
||||
void Tst_WriteParamQstCod (unsigned NumQst,long QstCod);
|
||||
|
||||
|
|
|
@ -72,6 +72,33 @@ extern struct Globals Gbl;
|
|||
|
||||
static void TstPrn_ResetPrintExceptPrnCod (struct TstPrn_Print *Print);
|
||||
|
||||
static void TstPrn_WriteQstAndAnsToFill (struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
struct Tst_Question *Question);
|
||||
static void TstPrn_WriteAnswersToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
struct Tst_Question *Question);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
static void TstPrn_WriteIntAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question);
|
||||
static void TstPrn_WriteFltAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question);
|
||||
static void TstPrn_WriteTF_AnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question);
|
||||
static void TstPrn_WriteChoAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
struct Tst_Question *Question);
|
||||
static void TstPrn_WriteTxtAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question);
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void TstPrn_PutCheckBoxAllowTeachers (bool AllowTeachers);
|
||||
|
||||
static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
|
||||
struct TstPrn_Print *Print,
|
||||
unsigned NumQst,
|
||||
|
@ -80,7 +107,6 @@ static void TstPrn_WriteQstAndAnsExam (struct UsrData *UsrDat,
|
|||
unsigned Visibility);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void TstPrn_GetCorrectAndComputeIntAnsScore (struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
struct Tst_Question *Question);
|
||||
static void TstPrn_GetCorrectAndComputeFltAnsScore (struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
|
@ -91,38 +117,33 @@ static void TstPrn_GetCorrectAndComputeChoAnsScore (struct TstPrn_PrintedQuestio
|
|||
struct Tst_Question *Question);
|
||||
static void TstPrn_GetCorrectAndComputeTxtAnsScore (struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
struct Tst_Question *Question);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void TstPrn_GetCorrectIntAnswerFromDB (struct Tst_Question *Question);
|
||||
static void TstPrn_GetCorrectFltAnswerFromDB (struct Tst_Question *Question);
|
||||
static void TstPrn_GetCorrectTF_AnswerFromDB (struct Tst_Question *Question);
|
||||
static void TstPrn_GetCorrectChoAnswerFromDB (struct Tst_Question *Question);
|
||||
static void TstPrn_GetCorrectTxtAnswerFromDB (struct Tst_Question *Question);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void TstPrn_WriteIntAnsPrint (struct UsrData *UsrDat,
|
||||
const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY]);
|
||||
static void TstPrn_WriteFltAnsPrint (struct UsrData *UsrDat,
|
||||
const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY]);
|
||||
static void TstPrn_WriteTF_AnsPrint (struct UsrData *UsrDat,
|
||||
const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY]);
|
||||
static void TstPrn_WriteChoAnsPrint (struct UsrData *UsrDat,
|
||||
const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY]);
|
||||
static void TstPrn_WriteTxtAnsPrint (struct UsrData *UsrDat,
|
||||
const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY]);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void TstPrn_WriteHeadUserCorrect (struct UsrData *UsrDat);
|
||||
|
@ -210,6 +231,340 @@ void TstPrn_UpdatePrintInDB (const struct TstPrn_Print *Print)
|
|||
Str_SetDecimalPointToLocal (); // Return to local system
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************** Show a test exam print to be answered ********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void TstPrn_ShowTestPrintToFillIt (struct TstPrn_Print *Print,
|
||||
unsigned NumExamsGeneratedByMe,
|
||||
TstPrn_RequestOrConfirm_t RequestOrConfirm)
|
||||
{
|
||||
extern const char *Hlp_ASSESSMENT_Tests;
|
||||
extern const char *Txt_Test;
|
||||
extern const char *Txt_Continue;
|
||||
extern const char *Txt_Send;
|
||||
unsigned NumQst;
|
||||
struct Tst_Question Question;
|
||||
static const Act_Action_t Action[Tst_NUM_REQUEST_OR_CONFIRM] =
|
||||
{
|
||||
[TstPrn_REQUEST] = ActReqAssTst,
|
||||
[TstPrn_CONFIRM] = ActAssTst,
|
||||
};
|
||||
|
||||
/***** Begin box *****/
|
||||
Box_BoxBegin (NULL,Txt_Test,
|
||||
NULL,NULL,
|
||||
Hlp_ASSESSMENT_Tests,Box_NOT_CLOSABLE);
|
||||
Lay_WriteHeaderClassPhoto (false,false,
|
||||
Gbl.Hierarchy.Ins.InsCod,
|
||||
Gbl.Hierarchy.Deg.DegCod,
|
||||
Gbl.Hierarchy.Crs.CrsCod);
|
||||
|
||||
if (Print->NumQsts)
|
||||
{
|
||||
/***** Begin form *****/
|
||||
Frm_StartForm (Action[RequestOrConfirm]);
|
||||
TstPrn_PutParamPrnCod (Print->PrnCod);
|
||||
Par_PutHiddenParamUnsigned (NULL,"NumTst",NumExamsGeneratedByMe);
|
||||
|
||||
/***** Begin table *****/
|
||||
HTM_TABLE_BeginWideMarginPadding (10);
|
||||
|
||||
/***** Write one row for each question *****/
|
||||
for (NumQst = 0;
|
||||
NumQst < Print->NumQsts;
|
||||
NumQst++)
|
||||
{
|
||||
Gbl.RowEvenOdd = NumQst % 2;
|
||||
|
||||
/* Create test question */
|
||||
Tst_QstConstructor (&Question);
|
||||
Question.QstCod = Print->PrintedQuestions[NumQst].QstCod;
|
||||
|
||||
/* Show question */
|
||||
if (!Tst_GetQstDataFromDB (&Question)) // Question exists
|
||||
Lay_ShowErrorAndExit ("Wrong question.");
|
||||
|
||||
/* Write question and answers */
|
||||
TstPrn_WriteQstAndAnsToFill (&Print->PrintedQuestions[NumQst],NumQst,&Question);
|
||||
|
||||
/* Destroy test question */
|
||||
Tst_QstDestructor (&Question);
|
||||
}
|
||||
|
||||
/***** End table *****/
|
||||
HTM_TABLE_End ();
|
||||
|
||||
/***** End form *****/
|
||||
switch (RequestOrConfirm)
|
||||
{
|
||||
case TstPrn_REQUEST:
|
||||
/* Send button */
|
||||
Btn_PutConfirmButton (Txt_Continue);
|
||||
break;
|
||||
case TstPrn_CONFIRM:
|
||||
/* Will the test exam be visible by teachers? */
|
||||
TstPrn_PutCheckBoxAllowTeachers (true);
|
||||
|
||||
/* Send button */
|
||||
Btn_PutCreateButton (Txt_Send);
|
||||
break;
|
||||
}
|
||||
Frm_EndForm ();
|
||||
}
|
||||
|
||||
/***** End box *****/
|
||||
Box_BoxEnd ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********** Write a row of a test, with one question and its answer **********/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TstPrn_WriteQstAndAnsToFill (struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
struct Tst_Question *Question)
|
||||
{
|
||||
/***** Begin row *****/
|
||||
HTM_TR_Begin (NULL);
|
||||
|
||||
/***** Number of question and answer type *****/
|
||||
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
|
||||
Tst_WriteNumQst (NumQst + 1);
|
||||
Tst_WriteAnswerType (Question->Answer.Type);
|
||||
HTM_TD_End ();
|
||||
|
||||
/***** Stem, media and answers *****/
|
||||
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||
|
||||
/* Write parameter with question code */
|
||||
Tst_WriteParamQstCod (NumQst,Question->QstCod);
|
||||
|
||||
/* Stem */
|
||||
Tst_WriteQstStem (Question->Stem,"TEST_EXA",true);
|
||||
|
||||
/* Media */
|
||||
Med_ShowMedia (&Question->Media,
|
||||
"TEST_MED_SHOW_CONT",
|
||||
"TEST_MED_SHOW");
|
||||
|
||||
/* Answers */
|
||||
TstPrn_WriteAnswersToFill (PrintedQuestion,NumQst,Question);
|
||||
|
||||
HTM_TD_End ();
|
||||
|
||||
/***** End row *****/
|
||||
HTM_TR_End ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************** Write answers of a question to fill them ******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TstPrn_WriteAnswersToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
struct Tst_Question *Question)
|
||||
{
|
||||
void (*TstPrn_WriteAnsBank[Tst_NUM_ANS_TYPES]) (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
struct Tst_Question *Question) =
|
||||
{
|
||||
[Tst_ANS_INT ] = TstPrn_WriteIntAnsToFill,
|
||||
[Tst_ANS_FLOAT ] = TstPrn_WriteFltAnsToFill,
|
||||
[Tst_ANS_TRUE_FALSE ] = TstPrn_WriteTF_AnsToFill,
|
||||
[Tst_ANS_UNIQUE_CHOICE ] = TstPrn_WriteChoAnsToFill,
|
||||
[Tst_ANS_MULTIPLE_CHOICE] = TstPrn_WriteChoAnsToFill,
|
||||
[Tst_ANS_TEXT ] = TstPrn_WriteTxtAnsToFill,
|
||||
};
|
||||
|
||||
/***** Write answers *****/
|
||||
TstPrn_WriteAnsBank[Question->Answer.Type] (PrintedQuestion,NumQst,Question);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************** Write integer answer when seeing a test ******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TstPrn_WriteIntAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question)
|
||||
{
|
||||
char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
|
||||
|
||||
/***** Write input field for the answer *****/
|
||||
snprintf (StrAns,sizeof (StrAns),
|
||||
"Ans%010u",
|
||||
NumQst);
|
||||
HTM_INPUT_TEXT (StrAns,11,PrintedQuestion->StrAnswers,
|
||||
HTM_DONT_SUBMIT_ON_CHANGE,
|
||||
"size=\"11\"");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************** Write float answer when seeing a test ********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TstPrn_WriteFltAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question)
|
||||
{
|
||||
char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
|
||||
|
||||
/***** Write input field for the answer *****/
|
||||
snprintf (StrAns,sizeof (StrAns),
|
||||
"Ans%010u",
|
||||
NumQst);
|
||||
HTM_INPUT_TEXT (StrAns,Tst_MAX_BYTES_FLOAT_ANSWER,PrintedQuestion->StrAnswers,
|
||||
HTM_DONT_SUBMIT_ON_CHANGE,
|
||||
"size=\"11\"");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************** Write false / true answer when seeing a test ****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TstPrn_WriteTF_AnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question)
|
||||
{
|
||||
extern const char *Txt_TF_QST[2];
|
||||
|
||||
/***** Write selector for the answer *****/
|
||||
/* Initially user has not answered the question ==> initially all the answers will be blank.
|
||||
If the user does not confirm the submission of their exam ==>
|
||||
==> the exam may be half filled ==> the answers displayed will be those selected by the user. */
|
||||
HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE,
|
||||
"name=\"Ans%010u\"",NumQst);
|
||||
HTM_OPTION (HTM_Type_STRING,"" ,PrintedQuestion->StrAnswers[0] == '\0',false," ");
|
||||
HTM_OPTION (HTM_Type_STRING,"T",PrintedQuestion->StrAnswers[0] == 'T' ,false,"%s",Txt_TF_QST[0]);
|
||||
HTM_OPTION (HTM_Type_STRING,"F",PrintedQuestion->StrAnswers[0] == 'F' ,false,"%s",Txt_TF_QST[1]);
|
||||
HTM_SELECT_End ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******** Write single or multiple choice answer when seeing a test **********/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TstPrn_WriteChoAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
struct Tst_Question *Question)
|
||||
{
|
||||
unsigned NumOpt;
|
||||
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; // Indexes of all answers of this question
|
||||
bool UsrAnswers[Tst_MAX_OPTIONS_PER_QUESTION];
|
||||
char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
|
||||
|
||||
/***** Change format of answers text *****/
|
||||
Tst_ChangeFormatAnswersText (Question);
|
||||
|
||||
/***** Get indexes for this question from string *****/
|
||||
TstPrn_GetIndexesFromStr (PrintedQuestion->StrIndexes,Indexes);
|
||||
|
||||
/***** Get the user's answers for this question from string *****/
|
||||
TstPrn_GetAnswersFromStr (PrintedQuestion->StrAnswers,UsrAnswers);
|
||||
|
||||
/***** Begin table *****/
|
||||
HTM_TABLE_BeginPadding (2);
|
||||
|
||||
for (NumOpt = 0;
|
||||
NumOpt < Question->Answer.NumOptions;
|
||||
NumOpt++)
|
||||
{
|
||||
/***** Indexes are 0 1 2 3... if no shuffle
|
||||
or 3 1 0 2... (example) if shuffle *****/
|
||||
HTM_TR_Begin (NULL);
|
||||
|
||||
/***** Write selectors and letter of this option *****/
|
||||
/* Initially user has not answered the question ==> initially all the answers will be blank.
|
||||
If the user does not confirm the submission of their exam ==>
|
||||
==> the exam may be half filled ==> the answers displayed will be those selected by the user. */
|
||||
HTM_TD_Begin ("class=\"LT\"");
|
||||
|
||||
snprintf (StrAns,sizeof (StrAns),
|
||||
"Ans%010u",
|
||||
NumQst);
|
||||
if (Question->Answer.Type == Tst_ANS_UNIQUE_CHOICE)
|
||||
HTM_INPUT_RADIO (StrAns,false,
|
||||
"id=\"Ans%010u_%u\" value=\"%u\"%s"
|
||||
" onclick=\"selectUnselectRadio(this,this.form.Ans%010u,%u);\"",
|
||||
NumQst,NumOpt,
|
||||
Indexes[NumOpt],
|
||||
UsrAnswers[Indexes[NumOpt]] ? " checked=\"checked\"" :
|
||||
"",
|
||||
NumQst,Question->Answer.NumOptions);
|
||||
else // Answer.Type == Tst_ANS_MULTIPLE_CHOICE
|
||||
HTM_INPUT_CHECKBOX (StrAns,HTM_DONT_SUBMIT_ON_CHANGE,
|
||||
"id=\"Ans%010u_%u\" value=\"%u\"%s",
|
||||
NumQst,NumOpt,
|
||||
Indexes[NumOpt],
|
||||
UsrAnswers[Indexes[NumOpt]] ? " checked=\"checked\"" :
|
||||
"");
|
||||
|
||||
HTM_TD_End ();
|
||||
|
||||
HTM_TD_Begin ("class=\"LT\"");
|
||||
HTM_LABEL_Begin ("for=\"Ans%010u_%u\" class=\"ANS_TXT\"",NumQst,NumOpt);
|
||||
HTM_TxtF ("%c) ",'a' + (char) NumOpt);
|
||||
HTM_LABEL_End ();
|
||||
HTM_TD_End ();
|
||||
|
||||
/***** Write the option text *****/
|
||||
HTM_TD_Begin ("class=\"LT\"");
|
||||
HTM_LABEL_Begin ("for=\"Ans%010u_%u\" class=\"ANS_TXT\"",NumQst,NumOpt);
|
||||
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");
|
||||
HTM_TD_End ();
|
||||
|
||||
HTM_TR_End ();
|
||||
}
|
||||
|
||||
/***** End table *****/
|
||||
HTM_TABLE_End ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************** Write text answer when seeing a test *******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TstPrn_WriteTxtAnsToFill (const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
unsigned NumQst,
|
||||
__attribute__((unused)) struct Tst_Question *Question)
|
||||
{
|
||||
char StrAns[3 + Cns_MAX_DECIMAL_DIGITS_UINT + 1]; // "Ansxx...x"
|
||||
|
||||
/***** Write input field for the answer *****/
|
||||
snprintf (StrAns,sizeof (StrAns),
|
||||
"Ans%010u",
|
||||
NumQst);
|
||||
HTM_INPUT_TEXT (StrAns,Tst_MAX_CHARS_ANSWERS_ONE_QST,PrintedQuestion->StrAnswers,
|
||||
HTM_DONT_SUBMIT_ON_CHANGE,
|
||||
"size=\"40\"");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************* Put checkbox to allow teachers to see test exam ***************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TstPrn_PutCheckBoxAllowTeachers (bool AllowTeachers)
|
||||
{
|
||||
extern const char *The_ClassFormInBox[The_NUM_THEMES];
|
||||
extern const char *Txt_Allow_teachers_to_consult_this_test;
|
||||
|
||||
/***** Test exam will be available for teachers? *****/
|
||||
HTM_DIV_Begin ("class=\"CM\"");
|
||||
HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]);
|
||||
HTM_INPUT_CHECKBOX ("AllowTchs",HTM_DONT_SUBMIT_ON_CHANGE,
|
||||
"value=\"Y\"%s",
|
||||
AllowTeachers ? " checked=\"checked\"" : // Teachers can see test exam
|
||||
"");
|
||||
HTM_TxtF (" %s",Txt_Allow_teachers_to_consult_this_test);
|
||||
HTM_LABEL_End ();
|
||||
HTM_DIV_End ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************* Show test exam after assessing it *********************/
|
||||
/*****************************************************************************/
|
||||
|
@ -640,14 +995,14 @@ static void TstPrn_GetCorrectTxtAnswerFromDB (struct Tst_Question *Question)
|
|||
/* Abort on error */
|
||||
Ale_ShowAlertsAndExit ();
|
||||
|
||||
/***** Copy answer text (row[0]) and convert it, that is in HTML, to rigorous HTML ******/
|
||||
/***** Copy answer text (row[0]) ******/
|
||||
Str_Copy (Question->Answer.Options[NumOpt].Text,row[0],
|
||||
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);
|
||||
}
|
||||
|
||||
/***** Change format of answers text *****/
|
||||
Tst_ChangeFormatAnswersText (Question);
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
}
|
||||
|
@ -915,12 +1270,12 @@ void TstPrn_ShowGrade (double Grade,double MaxGrade)
|
|||
|
||||
void TstPrn_WriteAnswersExam (struct UsrData *UsrDat,
|
||||
const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY])
|
||||
{
|
||||
void (*TstPrn_WriteAnsExam[Tst_NUM_ANS_TYPES]) (struct UsrData *UsrDat,
|
||||
const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY]) =
|
||||
{
|
||||
[Tst_ANS_INT ] = TstPrn_WriteIntAnsPrint,
|
||||
|
@ -942,7 +1297,7 @@ void TstPrn_WriteAnswersExam (struct UsrData *UsrDat,
|
|||
|
||||
static void TstPrn_WriteIntAnsPrint (struct UsrData *UsrDat,
|
||||
const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY])
|
||||
{
|
||||
long IntAnswerUsr;
|
||||
|
@ -1001,7 +1356,7 @@ static void TstPrn_WriteIntAnsPrint (struct UsrData *UsrDat,
|
|||
|
||||
static void TstPrn_WriteFltAnsPrint (struct UsrData *UsrDat,
|
||||
const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY])
|
||||
{
|
||||
double FloatAnsUsr = 0.0;
|
||||
|
@ -1061,7 +1416,7 @@ static void TstPrn_WriteFltAnsPrint (struct UsrData *UsrDat,
|
|||
|
||||
static void TstPrn_WriteTF_AnsPrint (struct UsrData *UsrDat,
|
||||
const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY])
|
||||
{
|
||||
char AnsTFUsr;
|
||||
|
@ -1109,7 +1464,7 @@ static void TstPrn_WriteTF_AnsPrint (struct UsrData *UsrDat,
|
|||
|
||||
static void TstPrn_WriteChoAnsPrint (struct UsrData *UsrDat,
|
||||
const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY])
|
||||
{
|
||||
extern const char *Txt_TST_Answer_given_by_the_user;
|
||||
|
@ -1123,25 +1478,12 @@ static void TstPrn_WriteChoAnsPrint (struct UsrData *UsrDat,
|
|||
char *Str;
|
||||
} Ans;
|
||||
|
||||
/***** Change format of answers text and feedback *****/
|
||||
for (NumOpt = 0;
|
||||
NumOpt < Question->Answer.NumOptions;
|
||||
NumOpt++)
|
||||
{
|
||||
/* Convert answer text, that is in HTML, to rigorous HTML */
|
||||
if (Question->Answer.Options[NumOpt].Text[0])
|
||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
Question->Answer.Options[NumOpt].Text,
|
||||
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||
/***** Change format of answers text *****/
|
||||
Tst_ChangeFormatAnswersText (Question);
|
||||
|
||||
/* Convert answer feedback, that is in HTML, to rigorous HTML */
|
||||
if (ICanView[TstVis_VISIBLE_FEEDBACK_TXT])
|
||||
if (Question->Answer.Options[NumOpt].Feedback)
|
||||
if (Question->Answer.Options[NumOpt].Feedback[0])
|
||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
Question->Answer.Options[NumOpt].Feedback,
|
||||
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||
}
|
||||
/***** Change format of answers feedback *****/
|
||||
if (ICanView[TstVis_VISIBLE_FEEDBACK_TXT])
|
||||
Tst_ChangeFormatAnswersFeedback (Question);
|
||||
|
||||
/***** Get indexes for this question from string *****/
|
||||
TstPrn_GetIndexesFromStr (PrintedQuestion->StrIndexes,Indexes);
|
||||
|
@ -1257,7 +1599,7 @@ static void TstPrn_WriteChoAnsPrint (struct UsrData *UsrDat,
|
|||
|
||||
static void TstPrn_WriteTxtAnsPrint (struct UsrData *UsrDat,
|
||||
const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
bool ICanView[TstVis_NUM_ITEMS_VISIBILITY])
|
||||
{
|
||||
unsigned NumOpt;
|
||||
|
@ -1265,25 +1607,12 @@ static void TstPrn_WriteTxtAnsPrint (struct UsrData *UsrDat,
|
|||
char TextAnsOK[Tst_MAX_BYTES_ANSWERS_ONE_QST + 1];
|
||||
bool Correct = false;
|
||||
|
||||
/***** Change format of answers text and feedback *****/
|
||||
for (NumOpt = 0;
|
||||
NumOpt < Question->Answer.NumOptions;
|
||||
NumOpt++)
|
||||
{
|
||||
/* Convert answer text, that is in HTML, to rigorous HTML */
|
||||
if (Question->Answer.Options[NumOpt].Text[0])
|
||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
Question->Answer.Options[NumOpt].Text,
|
||||
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||
/***** Change format of answers text *****/
|
||||
Tst_ChangeFormatAnswersText (Question);
|
||||
|
||||
/* Convert answer feedback, that is in HTML, to rigorous HTML */
|
||||
if (ICanView[TstVis_VISIBLE_FEEDBACK_TXT])
|
||||
if (Question->Answer.Options[NumOpt].Feedback)
|
||||
if (Question->Answer.Options[NumOpt].Feedback[0])
|
||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
Question->Answer.Options[NumOpt].Feedback,
|
||||
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||
}
|
||||
/***** Change format of answers feedback *****/
|
||||
if (ICanView[TstVis_VISIBLE_FEEDBACK_TXT])
|
||||
Tst_ChangeFormatAnswersFeedback (Question);
|
||||
|
||||
/***** Header with the title of each column *****/
|
||||
HTM_TABLE_BeginPadding (2);
|
||||
|
|
|
@ -62,6 +62,13 @@ struct TstPrn_Print
|
|||
struct TstPrn_PrintedQuestion PrintedQuestions[TstCfg_MAX_QUESTIONS_PER_TEST];
|
||||
};
|
||||
|
||||
#define Tst_NUM_REQUEST_OR_CONFIRM 2
|
||||
typedef enum
|
||||
{
|
||||
TstPrn_REQUEST,
|
||||
TstPrn_CONFIRM,
|
||||
} TstPrn_RequestOrConfirm_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Public prototypes *****************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -70,6 +77,10 @@ void TstPrn_ResetPrint (struct TstPrn_Print *Print);
|
|||
void TstPrn_CreatePrintInDB (struct TstPrn_Print *Print);
|
||||
void TstPrn_UpdatePrintInDB (const struct TstPrn_Print *Print);
|
||||
|
||||
void TstPrn_ShowTestPrintToFillIt (struct TstPrn_Print *Print,
|
||||
unsigned NumExamsGeneratedByMe,
|
||||
TstPrn_RequestOrConfirm_t RequestOrConfirm);
|
||||
|
||||
void TstPrn_ShowPrintAfterAssess (struct TstPrn_Print *Print);
|
||||
|
||||
void TstPrn_ComputeScoresAndStoreQuestionsOfPrint (struct TstPrn_Print *Print,
|
||||
|
@ -91,6 +102,9 @@ void TstPrn_ComputeTxtAnsScore (struct TstPrn_PrintedQuestion *PrintedQuestion,
|
|||
const struct Tst_Question *Question);
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Tst_ChangeFormatAnswersText (struct Tst_Question *Question);
|
||||
void Tst_ChangeFormatAnswersFeedback (struct Tst_Question *Question);
|
||||
|
||||
void TstPrn_GetIndexesFromStr (const char StrIndexesOneQst[Tst_MAX_BYTES_INDEXES_ONE_QST + 1], // 0 1 2 3, 3 0 2 1, etc.
|
||||
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]);
|
||||
void TstPrn_GetAnswersFromStr (const char StrAnswersOneQst[Tst_MAX_BYTES_ANSWERS_ONE_QST + 1],
|
||||
|
@ -102,7 +116,7 @@ void TstPrn_ShowGrade (double Grade,double MaxGrade);
|
|||
|
||||
void TstPrn_WriteAnswersExam (struct UsrData *UsrDat,
|
||||
const struct TstPrn_PrintedQuestion *PrintedQuestion,
|
||||
const struct Tst_Question *Question,
|
||||
struct Tst_Question *Question,
|
||||
bool IsVisible[TstVis_NUM_ITEMS_VISIBILITY]);
|
||||
|
||||
void TstPrn_SelUsrsToViewUsrsPrints (void);
|
||||
|
|
Loading…
Reference in New Issue