mirror of https://github.com/acanas/swad-core.git
Version19.148.3
This commit is contained in:
parent
3810f664c2
commit
11d934a3cc
|
@ -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.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)
|
||||||
Version 19.148.1: Mar 17, 2020 Code refactoring in tests. (282851 lines)
|
Version 19.148.1: Mar 17, 2020 Code refactoring in tests. (282851 lines)
|
||||||
Version 19.148: Mar 17, 2020 Code refactoring in tests.
|
Version 19.148: Mar 17, 2020 Code refactoring in tests.
|
||||||
|
|
12
swad_game.c
12
swad_game.c
|
@ -1874,6 +1874,7 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
|
||||||
unsigned NumQst;
|
unsigned NumQst;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
long QstCod;
|
long QstCod;
|
||||||
|
struct Tst_Question Question;
|
||||||
unsigned QstInd;
|
unsigned QstInd;
|
||||||
unsigned MaxQstInd;
|
unsigned MaxQstInd;
|
||||||
char StrQstInd[Cns_MAX_DECIMAL_DIGITS_UINT + 1];
|
char StrQstInd[Cns_MAX_DECIMAL_DIGITS_UINT + 1];
|
||||||
|
@ -1907,7 +1908,7 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
|
||||||
row[1] QstCod
|
row[1] QstCod
|
||||||
*/
|
*/
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor ();
|
Tst_QstConstructor (&Question);
|
||||||
|
|
||||||
/* Get question index (row[0]) */
|
/* Get question index (row[0]) */
|
||||||
QstInd = Str_ConvertStrToUnsigned (row[0]);
|
QstInd = Str_ConvertStrToUnsigned (row[0]);
|
||||||
|
@ -1976,7 +1977,7 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
|
||||||
HTM_TR_End ();
|
HTM_TR_End ();
|
||||||
|
|
||||||
/***** Destroy test question *****/
|
/***** Destroy test question *****/
|
||||||
Tst_QstDestructor ();
|
Tst_QstDestructor (&Question);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** End table *****/
|
/***** End table *****/
|
||||||
|
@ -1994,6 +1995,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;
|
||||||
|
struct Media Media;
|
||||||
|
|
||||||
/***** Get question from database *****/
|
/***** Get question from database *****/
|
||||||
QstExists = Tst_GetOneQuestionByCod (QstCod,&mysql_res); // Question exists?
|
QstExists = Tst_GetOneQuestionByCod (QstCod,&mysql_res); // Question exists?
|
||||||
|
@ -2054,11 +2056,11 @@ static void Gam_ListQuestionForEdition (long QstCod,const char *StrQstInd)
|
||||||
true); // Visible
|
true); // Visible
|
||||||
|
|
||||||
/* Get media (row[5]) */
|
/* Get media (row[5]) */
|
||||||
Gbl.Test.Question.Media.MedCod = Str_ConvertStrCodToLongCod (row[5]);
|
Media.MedCod = Str_ConvertStrCodToLongCod (row[5]);
|
||||||
Med_GetMediaDataByCod (&Gbl.Test.Question.Media);
|
Med_GetMediaDataByCod (&Media);
|
||||||
|
|
||||||
/* Show media */
|
/* Show media */
|
||||||
Med_ShowMedia (&Gbl.Test.Question.Media,
|
Med_ShowMedia (&Media,
|
||||||
"TEST_MED_EDIT_LIST_STEM_CONTAINER",
|
"TEST_MED_EDIT_LIST_STEM_CONTAINER",
|
||||||
"TEST_MED_EDIT_LIST_STEM");
|
"TEST_MED_EDIT_LIST_STEM");
|
||||||
|
|
||||||
|
|
|
@ -666,7 +666,6 @@ struct Globals
|
||||||
char StrAnswersOneQst[Tst_MAX_QUESTIONS_PER_TEST][Tst_MAX_BYTES_ANSWERS_ONE_QST + 1]; // Answers selected by user
|
char StrAnswersOneQst[Tst_MAX_QUESTIONS_PER_TEST][Tst_MAX_BYTES_ANSWERS_ONE_QST + 1]; // Answers selected by user
|
||||||
bool AllowTeachers; // Can teachers of this course see the test result?
|
bool AllowTeachers; // Can teachers of this course see the test result?
|
||||||
bool AllAnsTypes;
|
bool AllAnsTypes;
|
||||||
struct Tst_Question Question;
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned NumOptions;
|
unsigned NumOptions;
|
||||||
|
|
|
@ -2863,6 +2863,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;
|
||||||
|
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 *****/
|
||||||
switch (Match->Status.Showing)
|
switch (Match->Status.Showing)
|
||||||
|
@ -2899,11 +2900,11 @@ static void Mch_ShowQuestionAndAnswersTch (const struct Match *Match)
|
||||||
true); // Visible
|
true); // Visible
|
||||||
|
|
||||||
/* Get media (row[2]) */
|
/* Get media (row[2]) */
|
||||||
Gbl.Test.Question.Media.MedCod = Str_ConvertStrCodToLongCod (row[2]);
|
Media.MedCod = Str_ConvertStrCodToLongCod (row[2]);
|
||||||
Med_GetMediaDataByCod (&Gbl.Test.Question.Media);
|
Med_GetMediaDataByCod (&Media);
|
||||||
|
|
||||||
/* Show media */
|
/* Show media */
|
||||||
Med_ShowMedia (&Gbl.Test.Question.Media,
|
Med_ShowMedia (&Media,
|
||||||
"TEST_MED_EDIT_LIST_STEM_CONTAINER",
|
"TEST_MED_EDIT_LIST_STEM_CONTAINER",
|
||||||
"TEST_MED_EDIT_LIST_STEM");
|
"TEST_MED_EDIT_LIST_STEM");
|
||||||
|
|
||||||
|
|
22
swad_media.c
22
swad_media.c
|
@ -161,17 +161,17 @@ static bool Med_MoveTmpFileToDefDir (struct Media *Media,
|
||||||
const char PathMedPriv[PATH_MAX + 1],
|
const char PathMedPriv[PATH_MAX + 1],
|
||||||
const char *Extension);
|
const char *Extension);
|
||||||
|
|
||||||
static void Med_ShowJPG (struct Media *Media,
|
static void Med_ShowJPG (const struct Media *Media,
|
||||||
const char PathMedPriv[PATH_MAX + 1],
|
const char PathMedPriv[PATH_MAX + 1],
|
||||||
const char *ClassMedia);
|
const char *ClassMedia);
|
||||||
static void Med_ShowGIF (struct Media *Media,
|
static void Med_ShowGIF (const struct Media *Media,
|
||||||
const char PathMedPriv[PATH_MAX + 1],
|
const char PathMedPriv[PATH_MAX + 1],
|
||||||
const char *ClassMedia);
|
const char *ClassMedia);
|
||||||
static void Med_ShowVideo (struct Media *Media,
|
static void Med_ShowVideo (const struct Media *Media,
|
||||||
const char PathMedPriv[PATH_MAX + 1],
|
const char PathMedPriv[PATH_MAX + 1],
|
||||||
const char *ClassMedia);
|
const char *ClassMedia);
|
||||||
static void Med_ShowYoutube (struct Media *Media,const char *ClassMedia);
|
static void Med_ShowYoutube (const struct Media *Media,const char *ClassMedia);
|
||||||
static void Med_ShowEmbed (struct Media *Media,const char *ClassMedia);
|
static void Med_ShowEmbed (const struct Media *Media,const char *ClassMedia);
|
||||||
static void Med_AlertThirdPartyCookies (void);
|
static void Med_AlertThirdPartyCookies (void);
|
||||||
|
|
||||||
static Med_Type_t Med_GetTypeFromStrInDB (const char *Str);
|
static Med_Type_t Med_GetTypeFromStrInDB (const char *Str);
|
||||||
|
@ -1426,7 +1426,7 @@ void Med_StoreMediaInDB (struct Media *Media)
|
||||||
/****** Show a user uploaded media (in a test question, timeline, etc.) ******/
|
/****** Show a user uploaded media (in a test question, timeline, etc.) ******/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Med_ShowMedia (struct Media *Media,
|
void Med_ShowMedia (const struct Media *Media,
|
||||||
const char *ClassContainer,const char *ClassMedia)
|
const char *ClassContainer,const char *ClassMedia)
|
||||||
{
|
{
|
||||||
bool PutLink;
|
bool PutLink;
|
||||||
|
@ -1515,7 +1515,7 @@ void Med_ShowMedia (struct Media *Media,
|
||||||
/************************** Show a user uploaded JPG *************************/
|
/************************** Show a user uploaded JPG *************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Med_ShowJPG (struct Media *Media,
|
static void Med_ShowJPG (const struct Media *Media,
|
||||||
const char PathMedPriv[PATH_MAX + 1],
|
const char PathMedPriv[PATH_MAX + 1],
|
||||||
const char *ClassMedia)
|
const char *ClassMedia)
|
||||||
{
|
{
|
||||||
|
@ -1559,7 +1559,7 @@ static void Med_ShowJPG (struct Media *Media,
|
||||||
/************************** Show a user uploaded GIF *************************/
|
/************************** Show a user uploaded GIF *************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Med_ShowGIF (struct Media *Media,
|
static void Med_ShowGIF (const struct Media *Media,
|
||||||
const char PathMedPriv[PATH_MAX + 1],
|
const char PathMedPriv[PATH_MAX + 1],
|
||||||
const char *ClassMedia)
|
const char *ClassMedia)
|
||||||
{
|
{
|
||||||
|
@ -1650,7 +1650,7 @@ static void Med_ShowGIF (struct Media *Media,
|
||||||
/************************ Show a user uploaded video *************************/
|
/************************ Show a user uploaded video *************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Med_ShowVideo (struct Media *Media,
|
static void Med_ShowVideo (const struct Media *Media,
|
||||||
const char PathMedPriv[PATH_MAX + 1],
|
const char PathMedPriv[PATH_MAX + 1],
|
||||||
const char *ClassMedia)
|
const char *ClassMedia)
|
||||||
{
|
{
|
||||||
|
@ -1704,7 +1704,7 @@ static void Med_ShowVideo (struct Media *Media,
|
||||||
/*********************** Show an embed YouTube video *************************/
|
/*********************** Show an embed YouTube video *************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Med_ShowYoutube (struct Media *Media,const char *ClassMedia)
|
static void Med_ShowYoutube (const struct Media *Media,const char *ClassMedia)
|
||||||
{
|
{
|
||||||
/***** Check if YouTube code exists *****/
|
/***** Check if YouTube code exists *****/
|
||||||
if (Media->Name[0]) // YouTube code
|
if (Media->Name[0]) // YouTube code
|
||||||
|
@ -1744,7 +1744,7 @@ static void Med_ShowYoutube (struct Media *Media,const char *ClassMedia)
|
||||||
/*************************** Show an embed media *****************************/
|
/*************************** Show an embed media *****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Med_ShowEmbed (struct Media *Media,const char *ClassMedia)
|
static void Med_ShowEmbed (const struct Media *Media,const char *ClassMedia)
|
||||||
{
|
{
|
||||||
/***** Check if embed URL exists *****/
|
/***** Check if embed URL exists *****/
|
||||||
if (Media->URL[0]) // Embed URL
|
if (Media->URL[0]) // Embed URL
|
||||||
|
|
|
@ -150,7 +150,7 @@ void Med_RemoveKeepOrStoreMedia (long CurrentMedCodInDB,struct Media *Media);
|
||||||
void Med_MoveMediaToDefinitiveDir (struct Media *Media);
|
void Med_MoveMediaToDefinitiveDir (struct Media *Media);
|
||||||
void Med_StoreMediaInDB (struct Media *Media);
|
void Med_StoreMediaInDB (struct Media *Media);
|
||||||
|
|
||||||
void Med_ShowMedia (struct Media *Media,
|
void Med_ShowMedia (const struct Media *Media,
|
||||||
const char *ClassContainer,const char *ClassMedia);
|
const char *ClassContainer,const char *ClassMedia);
|
||||||
|
|
||||||
void Med_RemoveMediaFromAllRows (unsigned NumMedia,MYSQL_RES *mysql_res);
|
void Med_RemoveMediaFromAllRows (unsigned NumMedia,MYSQL_RES *mysql_res);
|
||||||
|
|
231
swad_test.c
231
swad_test.c
|
@ -138,7 +138,7 @@ static unsigned Tst_GetNumAccessesTst (void);
|
||||||
static void Tst_ShowTestQuestionsWhenSeeing (MYSQL_RES *mysql_res);
|
static void Tst_ShowTestQuestionsWhenSeeing (MYSQL_RES *mysql_res);
|
||||||
static void Tst_ShowOneTestQuestionWhenSeeing (unsigned NumQst,long QstCod);
|
static void Tst_ShowOneTestQuestionWhenSeeing (unsigned NumQst,long QstCod);
|
||||||
static void Tst_ShowTestResultAfterAssess (long TstCod,unsigned *NumQstsNotBlank,double *TotalScore);
|
static void Tst_ShowTestResultAfterAssess (long TstCod,unsigned *NumQstsNotBlank,double *TotalScore);
|
||||||
static void Tst_PutFormToEditQstMedia (struct Media *Media,int NumMediaInForm,
|
static void Tst_PutFormToEditQstMedia (const struct Media *Media,int NumMediaInForm,
|
||||||
bool OptionsDisabled);
|
bool OptionsDisabled);
|
||||||
static void Tst_UpdateScoreQst (long QstCod,double ScoreThisQst,bool AnswerIsNotBlank);
|
static void Tst_UpdateScoreQst (long QstCod,double ScoreThisQst,bool AnswerIsNotBlank);
|
||||||
static void Tst_UpdateMyNumAccessTst (unsigned NumAccessesTst);
|
static void Tst_UpdateMyNumAccessTst (unsigned NumAccessesTst);
|
||||||
|
@ -221,6 +221,7 @@ static void Tst_GetParamNumQst (void);
|
||||||
static int Tst_CountNumTagsInList (void);
|
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,
|
||||||
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,
|
||||||
|
@ -230,10 +231,11 @@ static void Tst_PutTFInputField (const char *Label,char Value);
|
||||||
static void Tst_FreeTextChoiceAnswers (void);
|
static void Tst_FreeTextChoiceAnswers (void);
|
||||||
static void Tst_FreeTextChoiceAnswer (unsigned NumOpt);
|
static void Tst_FreeTextChoiceAnswer (unsigned NumOpt);
|
||||||
|
|
||||||
static void Tst_ResetMediaOfQuestion (void);
|
static void Tst_ResetMediaOfQuestion (struct Tst_Question *Question);
|
||||||
static void Tst_FreeMediaOfQuestion (void);
|
static void Tst_FreeMediaOfQuestion (struct Tst_Question *Question);
|
||||||
|
|
||||||
static void Tst_GetQstDataFromDB (long QstCod,
|
static void Tst_GetQstDataFromDB (long QstCod,
|
||||||
|
struct Tst_Question *Question,
|
||||||
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 long Tst_GetMedCodFromDB (long CrsCod,long QstCod,int NumOpt);
|
static long Tst_GetMedCodFromDB (long CrsCod,long QstCod,int NumOpt);
|
||||||
|
@ -241,8 +243,10 @@ static void Tst_GetMediaFromDB (long CrsCod,long QstCod,int NumOpt,
|
||||||
struct Media *Media);
|
struct Media *Media);
|
||||||
|
|
||||||
static Tst_AnswerType_t Tst_ConvertFromUnsignedStrToAnsTyp (const char *UnsignedStr);
|
static Tst_AnswerType_t Tst_ConvertFromUnsignedStrToAnsTyp (const char *UnsignedStr);
|
||||||
static long Tst_GetQstFromForm (char *Stem,char *Feedback);
|
static long Tst_GetQstFromForm (struct Tst_Question *Question,
|
||||||
static void Tst_MoveMediaToDefinitiveDirectories (long QstCod);
|
char *Stem,char *Feedback);
|
||||||
|
static void Tst_MoveMediaToDefinitiveDirectories (long QstCod,
|
||||||
|
struct Tst_Question *Question);
|
||||||
|
|
||||||
static long Tst_GetTagCodFromTagTxt (const char *TagTxt);
|
static long Tst_GetTagCodFromTagTxt (const char *TagTxt);
|
||||||
static long Tst_CreateNewTag (long CrsCod,const char *TagTxt);
|
static long Tst_CreateNewTag (long CrsCod,const char *TagTxt);
|
||||||
|
@ -256,7 +260,8 @@ 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);
|
||||||
static void Tst_InsertTagsIntoDB (long QstCod);
|
static void Tst_InsertTagsIntoDB (long QstCod);
|
||||||
static void Tst_InsertAnswersIntoDB (long QstCod);
|
static void Tst_InsertAnswersIntoDB (long QstCod);
|
||||||
|
|
||||||
|
@ -840,7 +845,9 @@ static void Tst_ShowOneTestQuestionWhenSeeing (unsigned NumQst,long QstCod)
|
||||||
|
|
||||||
Tst_WriteQstAndAnsTest (Tst_SHOW_TEST_TO_ANSWER,
|
Tst_WriteQstAndAnsTest (Tst_SHOW_TEST_TO_ANSWER,
|
||||||
&Gbl.Usrs.Me.UsrDat,
|
&Gbl.Usrs.Me.UsrDat,
|
||||||
NumQst,QstCod,row,
|
NumQst,
|
||||||
|
QstCod,
|
||||||
|
row,
|
||||||
TsV_MAX_VISIBILITY, // All visible here
|
TsV_MAX_VISIBILITY, // All visible here
|
||||||
&ScoreThisQst, // Not used here
|
&ScoreThisQst, // Not used here
|
||||||
&AnswerIsNotBlank); // Not used here
|
&AnswerIsNotBlank); // Not used here
|
||||||
|
@ -921,7 +928,9 @@ static void Tst_ShowTestResultAfterAssess (long TstCod,unsigned *NumQstsNotBlank
|
||||||
/***** Write question and answers *****/
|
/***** Write question and answers *****/
|
||||||
Tst_WriteQstAndAnsTest (Tst_SHOW_TEST_RESULT,
|
Tst_WriteQstAndAnsTest (Tst_SHOW_TEST_RESULT,
|
||||||
&Gbl.Usrs.Me.UsrDat,
|
&Gbl.Usrs.Me.UsrDat,
|
||||||
NumQst,Gbl.Test.QstCodes[NumQst],row,
|
NumQst,
|
||||||
|
Gbl.Test.QstCodes[NumQst],
|
||||||
|
row,
|
||||||
Gbl.Test.Config.Visibility,
|
Gbl.Test.Config.Visibility,
|
||||||
&ScoreThisQst,&AnswerIsNotBlank);
|
&ScoreThisQst,&AnswerIsNotBlank);
|
||||||
|
|
||||||
|
@ -966,11 +975,14 @@ static void Tst_ShowTestResultAfterAssess (long TstCod,unsigned *NumQstsNotBlank
|
||||||
|
|
||||||
void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions,
|
void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions,
|
||||||
struct UsrData *UsrDat,
|
struct UsrData *UsrDat,
|
||||||
unsigned NumQst,long QstCod,MYSQL_ROW row,
|
unsigned NumQst,
|
||||||
|
long QstCod,
|
||||||
|
MYSQL_ROW row,
|
||||||
unsigned Visibility,
|
unsigned Visibility,
|
||||||
double *ScoreThisQst,bool *AnswerIsNotBlank)
|
double *ScoreThisQst,bool *AnswerIsNotBlank)
|
||||||
{
|
{
|
||||||
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;
|
||||||
bool IsVisibleQstAndAnsTxt = TsV_IsVisibleQstAndAnsTxt (Visibility);
|
bool IsVisibleQstAndAnsTxt = TsV_IsVisibleQstAndAnsTxt (Visibility);
|
||||||
/*
|
/*
|
||||||
row[0] UNIX_TIMESTAMP(EditTime)
|
row[0] UNIX_TIMESTAMP(EditTime)
|
||||||
|
@ -985,7 +997,7 @@ void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestio
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor ();
|
Tst_QstConstructor (&Question);
|
||||||
|
|
||||||
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);
|
||||||
|
@ -1010,9 +1022,9 @@ void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestio
|
||||||
/***** Get and show media (row[5]) *****/
|
/***** Get and show media (row[5]) *****/
|
||||||
if (IsVisibleQstAndAnsTxt)
|
if (IsVisibleQstAndAnsTxt)
|
||||||
{
|
{
|
||||||
Gbl.Test.Question.Media.MedCod = Str_ConvertStrCodToLongCod (row[5]);
|
Question.Media.MedCod = Str_ConvertStrCodToLongCod (row[5]);
|
||||||
Med_GetMediaDataByCod (&Gbl.Test.Question.Media);
|
Med_GetMediaDataByCod (&Question.Media);
|
||||||
Med_ShowMedia (&Gbl.Test.Question.Media,
|
Med_ShowMedia (&Question.Media,
|
||||||
"TEST_MED_SHOW_CONT",
|
"TEST_MED_SHOW_CONT",
|
||||||
"TEST_MED_SHOW");
|
"TEST_MED_SHOW");
|
||||||
}
|
}
|
||||||
|
@ -1039,7 +1051,7 @@ void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestio
|
||||||
HTM_TR_End ();
|
HTM_TR_End ();
|
||||||
|
|
||||||
/***** Destroy test question *****/
|
/***** Destroy test question *****/
|
||||||
Tst_QstDestructor ();
|
Tst_QstDestructor (&Question);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -1084,7 +1096,7 @@ void Tst_WriteQstStem (const char *Stem,const char *ClassStem,bool Visible)
|
||||||
/************* Put form to upload a new image for a test question ************/
|
/************* Put form to upload a new image for a test question ************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Tst_PutFormToEditQstMedia (struct Media *Media,int NumMediaInForm,
|
static void Tst_PutFormToEditQstMedia (const struct Media *Media,int NumMediaInForm,
|
||||||
bool OptionsDisabled)
|
bool OptionsDisabled)
|
||||||
{
|
{
|
||||||
extern const char *The_ClassFormInBox[The_NUM_THEMES];
|
extern const char *The_ClassFormInBox[The_NUM_THEMES];
|
||||||
|
@ -2857,6 +2869,7 @@ static void Tst_WriteQuestionRowForEdition (unsigned long NumRows,
|
||||||
extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES];
|
extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES];
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
|
struct Tst_Question Question;
|
||||||
static unsigned UniqueId = 0;
|
static unsigned UniqueId = 0;
|
||||||
char *Id;
|
char *Id;
|
||||||
time_t TimeUTC;
|
time_t TimeUTC;
|
||||||
|
@ -2882,7 +2895,7 @@ static void Tst_WriteQuestionRowForEdition (unsigned long NumRows,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor ();
|
Tst_QstConstructor (&Question);
|
||||||
|
|
||||||
/***** Begin table row *****/
|
/***** Begin table row *****/
|
||||||
HTM_TR_Begin (NULL);
|
HTM_TR_Begin (NULL);
|
||||||
|
@ -2969,9 +2982,9 @@ static void Tst_WriteQuestionRowForEdition (unsigned long NumRows,
|
||||||
true); // Visible
|
true); // Visible
|
||||||
|
|
||||||
/***** Get and show media (row[5]) *****/
|
/***** Get and show media (row[5]) *****/
|
||||||
Gbl.Test.Question.Media.MedCod = Str_ConvertStrCodToLongCod (row[5]);
|
Question.Media.MedCod = Str_ConvertStrCodToLongCod (row[5]);
|
||||||
Med_GetMediaDataByCod (&Gbl.Test.Question.Media);
|
Med_GetMediaDataByCod (&Question.Media);
|
||||||
Med_ShowMedia (&Gbl.Test.Question.Media,
|
Med_ShowMedia (&Question.Media,
|
||||||
"TEST_MED_EDIT_LIST_CONT",
|
"TEST_MED_EDIT_LIST_CONT",
|
||||||
"TEST_MED_EDIT_LIST");
|
"TEST_MED_EDIT_LIST");
|
||||||
|
|
||||||
|
@ -3028,7 +3041,7 @@ static void Tst_WriteQuestionRowForEdition (unsigned long NumRows,
|
||||||
HTM_TR_End ();
|
HTM_TR_End ();
|
||||||
|
|
||||||
/***** Destroy test question *****/
|
/***** Destroy test question *****/
|
||||||
Tst_QstDestructor ();
|
Tst_QstDestructor (&Question);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
/***** Free structure that stores the query result *****/
|
||||||
|
@ -3119,6 +3132,7 @@ static void Tst_WriteQuestionRowForSelection (unsigned long NumRow,long QstCod)
|
||||||
extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES];
|
extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES];
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
|
struct Tst_Question Question;
|
||||||
static unsigned UniqueId = 0;
|
static unsigned UniqueId = 0;
|
||||||
char *Id;
|
char *Id;
|
||||||
time_t TimeUTC;
|
time_t TimeUTC;
|
||||||
|
@ -3141,7 +3155,7 @@ static void Tst_WriteQuestionRowForSelection (unsigned long NumRow,long QstCod)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/***** Create test question *****/
|
/***** Create test question *****/
|
||||||
Tst_QstConstructor ();
|
Tst_QstConstructor (&Question);
|
||||||
|
|
||||||
/***** Begin table row *****/
|
/***** Begin table row *****/
|
||||||
HTM_TR_Begin (NULL);
|
HTM_TR_Begin (NULL);
|
||||||
|
@ -3201,9 +3215,9 @@ static void Tst_WriteQuestionRowForSelection (unsigned long NumRow,long QstCod)
|
||||||
true); // Visible
|
true); // Visible
|
||||||
|
|
||||||
/***** Get and show media (row[5]) *****/
|
/***** Get and show media (row[5]) *****/
|
||||||
Gbl.Test.Question.Media.MedCod = Str_ConvertStrCodToLongCod (row[5]);
|
Question.Media.MedCod = Str_ConvertStrCodToLongCod (row[5]);
|
||||||
Med_GetMediaDataByCod (&Gbl.Test.Question.Media);
|
Med_GetMediaDataByCod (&Question.Media);
|
||||||
Med_ShowMedia (&Gbl.Test.Question.Media,
|
Med_ShowMedia (&Question.Media,
|
||||||
"TEST_MED_EDIT_LIST_CONT",
|
"TEST_MED_EDIT_LIST_CONT",
|
||||||
"TEST_MED_EDIT_LIST");
|
"TEST_MED_EDIT_LIST");
|
||||||
|
|
||||||
|
@ -3218,7 +3232,7 @@ static void Tst_WriteQuestionRowForSelection (unsigned long NumRow,long QstCod)
|
||||||
HTM_TR_End ();
|
HTM_TR_End ();
|
||||||
|
|
||||||
/***** Destroy test question *****/
|
/***** Destroy test question *****/
|
||||||
Tst_QstDestructor ();
|
Tst_QstDestructor (&Question);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5071,21 +5085,22 @@ void Tst_FreeTagsList (void)
|
||||||
void Tst_ShowFormEditOneQst (void)
|
void Tst_ShowFormEditOneQst (void)
|
||||||
{
|
{
|
||||||
long QstCod;
|
long QstCod;
|
||||||
|
struct Tst_Question Question;
|
||||||
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 ();
|
Tst_QstConstructor (&Question);
|
||||||
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,Stem,Feedback);
|
Tst_GetQstDataFromDB (QstCod,&Question,Stem,Feedback);
|
||||||
|
|
||||||
/***** Put form to edit question *****/
|
/***** Put form to edit question *****/
|
||||||
Tst_PutFormEditOneQst (QstCod,Stem,Feedback);
|
Tst_PutFormEditOneQst (QstCod,&Question,Stem,Feedback);
|
||||||
|
|
||||||
/***** Destroy test question *****/
|
/***** Destroy test question *****/
|
||||||
Tst_QstDestructor ();
|
Tst_QstDestructor (&Question);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -5098,6 +5113,7 @@ void Tst_ShowFormEditOneQst (void)
|
||||||
// 3. From the action associated to reception of a question, on error in the parameters received from the form
|
// 3. From the action associated to reception of a question, on error in the parameters received from the form
|
||||||
|
|
||||||
static void Tst_PutFormEditOneQst (long QstCod,
|
static void Tst_PutFormEditOneQst (long QstCod,
|
||||||
|
const struct Tst_Question *Question,
|
||||||
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])
|
||||||
{
|
{
|
||||||
|
@ -5260,7 +5276,7 @@ static void Tst_PutFormEditOneQst (long QstCod,
|
||||||
HTM_Txt (Stem);
|
HTM_Txt (Stem);
|
||||||
HTM_TEXTAREA_End ();
|
HTM_TEXTAREA_End ();
|
||||||
HTM_BR ();
|
HTM_BR ();
|
||||||
Tst_PutFormToEditQstMedia (&Gbl.Test.Question.Media,-1,
|
Tst_PutFormToEditQstMedia (&Question->Media,-1,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
/***** Feedback *****/
|
/***** Feedback *****/
|
||||||
|
@ -5354,8 +5370,8 @@ static void Tst_PutFormEditOneQst (long QstCod,
|
||||||
HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]);
|
HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]);
|
||||||
HTM_INPUT_CHECKBOX ("Shuffle",HTM_DONT_SUBMIT_ON_CHANGE,
|
HTM_INPUT_CHECKBOX ("Shuffle",HTM_DONT_SUBMIT_ON_CHANGE,
|
||||||
"value=\"Y\"%s%s",
|
"value=\"Y\"%s%s",
|
||||||
Gbl.Test.Question.Shuffle ? " checked=\"checked\"" :
|
Question->Shuffle ? " checked=\"checked\"" :
|
||||||
"",
|
"",
|
||||||
Gbl.Test.AnswerType != Tst_ANS_UNIQUE_CHOICE &&
|
Gbl.Test.AnswerType != Tst_ANS_UNIQUE_CHOICE &&
|
||||||
Gbl.Test.AnswerType != Tst_ANS_MULTIPLE_CHOICE ? " disabled=\"disabled\"" :
|
Gbl.Test.AnswerType != Tst_ANS_MULTIPLE_CHOICE ? " disabled=\"disabled\"" :
|
||||||
"");
|
"");
|
||||||
|
@ -5547,21 +5563,22 @@ static void Tst_PutTFInputField (const char *Label,char Value)
|
||||||
/********************* Initialize a new question to zero *********************/
|
/********************* Initialize a new question to zero *********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Tst_QstConstructor (void)
|
void Tst_QstConstructor (struct Tst_Question *Question)
|
||||||
{
|
{
|
||||||
unsigned NumOpt;
|
unsigned NumOpt;
|
||||||
|
|
||||||
Gbl.Test.Question.Stem.Text = NULL;
|
Question->Stem.Text = NULL;
|
||||||
Gbl.Test.Question.Stem.Length = 0;
|
Question->Stem.Length = 0;
|
||||||
Gbl.Test.Question.Feedback.Text = NULL;
|
Question->Feedback.Text = NULL;
|
||||||
Gbl.Test.Question.Feedback.Length = 0;
|
Question->Feedback.Length = 0;
|
||||||
Gbl.Test.Question.Shuffle = false;
|
Question->Shuffle = false;
|
||||||
|
|
||||||
Gbl.Test.AnswerType = Tst_ANS_UNIQUE_CHOICE;
|
Gbl.Test.AnswerType = Tst_ANS_UNIQUE_CHOICE;
|
||||||
Gbl.Test.Answer.NumOptions = 0;
|
Gbl.Test.Answer.NumOptions = 0;
|
||||||
Gbl.Test.Answer.TF = ' ';
|
Gbl.Test.Answer.TF = ' ';
|
||||||
|
|
||||||
/***** Initialize image attached to stem *****/
|
/***** Initialize image attached to stem *****/
|
||||||
Med_MediaConstructor (&Gbl.Test.Question.Media);
|
Med_MediaConstructor (&Question->Media);
|
||||||
|
|
||||||
for (NumOpt = 0;
|
for (NumOpt = 0;
|
||||||
NumOpt < Tst_MAX_OPTIONS_PER_QUESTION;
|
NumOpt < Tst_MAX_OPTIONS_PER_QUESTION;
|
||||||
|
@ -5583,10 +5600,10 @@ void Tst_QstConstructor (void)
|
||||||
/***************** Free memory allocated for test question *******************/
|
/***************** Free memory allocated for test question *******************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Tst_QstDestructor (void)
|
void Tst_QstDestructor (struct Tst_Question *Question)
|
||||||
{
|
{
|
||||||
Tst_FreeTextChoiceAnswers ();
|
Tst_FreeTextChoiceAnswers ();
|
||||||
Tst_FreeMediaOfQuestion ();
|
Tst_FreeMediaOfQuestion (Question);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -5653,12 +5670,12 @@ static void Tst_FreeTextChoiceAnswer (unsigned NumOpt)
|
||||||
/***************** Initialize images of a question to zero *******************/
|
/***************** Initialize images of a question to zero *******************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Tst_ResetMediaOfQuestion (void)
|
static void Tst_ResetMediaOfQuestion (struct Tst_Question *Question)
|
||||||
{
|
{
|
||||||
unsigned NumOpt;
|
unsigned NumOpt;
|
||||||
|
|
||||||
/***** Reset media for stem *****/
|
/***** Reset media for stem *****/
|
||||||
Med_ResetMedia (&Gbl.Test.Question.Media);
|
Med_ResetMedia (&Question->Media);
|
||||||
|
|
||||||
/***** Reset media for every answer option *****/
|
/***** Reset media for every answer option *****/
|
||||||
for (NumOpt = 0;
|
for (NumOpt = 0;
|
||||||
|
@ -5671,11 +5688,11 @@ static void Tst_ResetMediaOfQuestion (void)
|
||||||
/*********************** Free images of a question ***************************/
|
/*********************** Free images of a question ***************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Tst_FreeMediaOfQuestion (void)
|
static void Tst_FreeMediaOfQuestion (struct Tst_Question *Question)
|
||||||
{
|
{
|
||||||
unsigned NumOpt;
|
unsigned NumOpt;
|
||||||
|
|
||||||
Med_MediaDestructor (&Gbl.Test.Question.Media);
|
Med_MediaDestructor (&Question->Media);
|
||||||
for (NumOpt = 0;
|
for (NumOpt = 0;
|
||||||
NumOpt < Tst_MAX_OPTIONS_PER_QUESTION;
|
NumOpt < Tst_MAX_OPTIONS_PER_QUESTION;
|
||||||
NumOpt++)
|
NumOpt++)
|
||||||
|
@ -5687,6 +5704,7 @@ static void Tst_FreeMediaOfQuestion (void)
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Tst_GetQstDataFromDB (long QstCod,
|
static void Tst_GetQstDataFromDB (long QstCod,
|
||||||
|
struct Tst_Question *Question,
|
||||||
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])
|
||||||
{
|
{
|
||||||
|
@ -5713,7 +5731,7 @@ static void Tst_GetQstDataFromDB (long QstCod,
|
||||||
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[0]);
|
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[0]);
|
||||||
|
|
||||||
/* Get shuffle (row[1]) */
|
/* Get shuffle (row[1]) */
|
||||||
Gbl.Test.Question.Shuffle = (row[1][0] == 'Y');
|
Question->Shuffle = (row[1][0] == 'Y');
|
||||||
|
|
||||||
/* Get the stem of the question from the database (row[2]) */
|
/* Get the stem of the question from the database (row[2]) */
|
||||||
Str_Copy (Stem,row[2],
|
Str_Copy (Stem,row[2],
|
||||||
|
@ -5727,8 +5745,8 @@ static void Tst_GetQstDataFromDB (long QstCod,
|
||||||
Cns_MAX_BYTES_TEXT);
|
Cns_MAX_BYTES_TEXT);
|
||||||
|
|
||||||
/* Get media (row[4]) */
|
/* Get media (row[4]) */
|
||||||
Gbl.Test.Question.Media.MedCod = Str_ConvertStrCodToLongCod (row[4]);
|
Question->Media.MedCod = Str_ConvertStrCodToLongCod (row[4]);
|
||||||
Med_GetMediaDataByCod (&Gbl.Test.Question.Media);
|
Med_GetMediaDataByCod (&Question->Media);
|
||||||
|
|
||||||
/* Free structure that stores the query result */
|
/* Free structure that stores the query result */
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
@ -5916,24 +5934,25 @@ static Tst_AnswerType_t Tst_ConvertFromUnsignedStrToAnsTyp (const char *Unsigned
|
||||||
void Tst_ReceiveQst (void)
|
void Tst_ReceiveQst (void)
|
||||||
{
|
{
|
||||||
long QstCod;
|
long QstCod;
|
||||||
|
struct Tst_Question Question;
|
||||||
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 ();
|
Tst_QstConstructor (&Question);
|
||||||
|
|
||||||
/***** 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 (Stem,Feedback);
|
QstCod = Tst_GetQstFromForm (&Question,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 ())
|
if (Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (&Question))
|
||||||
{
|
{
|
||||||
/***** Move images to definitive directories *****/
|
/***** Move images to definitive directories *****/
|
||||||
Tst_MoveMediaToDefinitiveDirectories (QstCod);
|
Tst_MoveMediaToDefinitiveDirectories (QstCod,&Question);
|
||||||
|
|
||||||
/***** Insert or update question, tags and answer in the database *****/
|
/***** Insert or update question, tags and answer in the database *****/
|
||||||
QstCod = Tst_InsertOrUpdateQstTagsAnsIntoDB (QstCod);
|
QstCod = Tst_InsertOrUpdateQstTagsAnsIntoDB (QstCod,&Question);
|
||||||
|
|
||||||
/***** Show the question just inserted in the database *****/
|
/***** Show the question just inserted in the database *****/
|
||||||
Tst_ListOneQstToEdit (QstCod);
|
Tst_ListOneQstToEdit (QstCod);
|
||||||
|
@ -5941,21 +5960,22 @@ void Tst_ReceiveQst (void)
|
||||||
else // Question is wrong
|
else // Question is wrong
|
||||||
{
|
{
|
||||||
/***** Whether images has been received or not, reset images *****/
|
/***** Whether images has been received or not, reset images *****/
|
||||||
Tst_ResetMediaOfQuestion ();
|
Tst_ResetMediaOfQuestion (&Question);
|
||||||
|
|
||||||
/***** Put form to edit question again *****/
|
/***** Put form to edit question again *****/
|
||||||
Tst_PutFormEditOneQst (QstCod,Stem,Feedback);
|
Tst_PutFormEditOneQst (QstCod,&Question,Stem,Feedback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Destroy test question *****/
|
/***** Destroy test question *****/
|
||||||
Tst_QstDestructor ();
|
Tst_QstDestructor (&Question);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/**************** Get parameters of a test question from form ****************/
|
/**************** Get parameters of a test question from form ****************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static long Tst_GetQstFromForm (char *Stem,char *Feedback)
|
static long Tst_GetQstFromForm (struct Tst_Question *Question,
|
||||||
|
char *Stem,char *Feedback)
|
||||||
{
|
{
|
||||||
long QstCod;
|
long QstCod;
|
||||||
unsigned NumTag;
|
unsigned NumTag;
|
||||||
|
@ -6015,18 +6035,18 @@ static long Tst_GetQstFromForm (char *Stem,char *Feedback)
|
||||||
Par_GetParToHTML ("Feedback",Feedback,Cns_MAX_BYTES_TEXT);
|
Par_GetParToHTML ("Feedback",Feedback,Cns_MAX_BYTES_TEXT);
|
||||||
|
|
||||||
/***** Get media associated to the stem (action, file and title) *****/
|
/***** Get media associated to the stem (action, file and title) *****/
|
||||||
Gbl.Test.Question.Media.Width = Tst_IMAGE_SAVED_MAX_WIDTH;
|
Question->Media.Width = Tst_IMAGE_SAVED_MAX_WIDTH;
|
||||||
Gbl.Test.Question.Media.Height = Tst_IMAGE_SAVED_MAX_HEIGHT;
|
Question->Media.Height = Tst_IMAGE_SAVED_MAX_HEIGHT;
|
||||||
Gbl.Test.Question.Media.Quality = Tst_IMAGE_SAVED_QUALITY;
|
Question->Media.Quality = Tst_IMAGE_SAVED_QUALITY;
|
||||||
Med_GetMediaFromForm (Gbl.Hierarchy.Crs.CrsCod,QstCod,
|
Med_GetMediaFromForm (Gbl.Hierarchy.Crs.CrsCod,QstCod,
|
||||||
-1, // < 0 ==> the image associated to the stem
|
-1, // < 0 ==> the image associated to the stem
|
||||||
&Gbl.Test.Question.Media,
|
&Question->Media,
|
||||||
Tst_GetMediaFromDB,
|
Tst_GetMediaFromDB,
|
||||||
NULL);
|
NULL);
|
||||||
Ale_ShowAlerts (NULL);
|
Ale_ShowAlerts (NULL);
|
||||||
|
|
||||||
/***** Get answers *****/
|
/***** Get answers *****/
|
||||||
Gbl.Test.Question.Shuffle = false;
|
Question->Shuffle = false;
|
||||||
switch (Gbl.Test.AnswerType)
|
switch (Gbl.Test.AnswerType)
|
||||||
{
|
{
|
||||||
case Tst_ANS_INT:
|
case Tst_ANS_INT:
|
||||||
|
@ -6059,7 +6079,7 @@ static long Tst_GetQstFromForm (char *Stem,char *Feedback)
|
||||||
case Tst_ANS_UNIQUE_CHOICE:
|
case Tst_ANS_UNIQUE_CHOICE:
|
||||||
case Tst_ANS_MULTIPLE_CHOICE:
|
case Tst_ANS_MULTIPLE_CHOICE:
|
||||||
/* Get shuffle */
|
/* Get shuffle */
|
||||||
Gbl.Test.Question.Shuffle = Par_GetParToBool ("Shuffle");
|
Question->Shuffle = Par_GetParToBool ("Shuffle");
|
||||||
/* falls through */
|
/* falls through */
|
||||||
/* no break */
|
/* no break */
|
||||||
case Tst_ANS_TEXT:
|
case Tst_ANS_TEXT:
|
||||||
|
@ -6146,10 +6166,10 @@ static long Tst_GetQstFromForm (char *Stem,char *Feedback)
|
||||||
NumTag++)
|
NumTag++)
|
||||||
if (Gbl.Test.Tags.Txt[NumTag][0])
|
if (Gbl.Test.Tags.Txt[NumTag][0])
|
||||||
Gbl.Test.Tags.Num++;
|
Gbl.Test.Tags.Num++;
|
||||||
Gbl.Test.Question.Stem.Text = Stem;
|
Question->Stem.Text = Stem;
|
||||||
Gbl.Test.Question.Stem.Length = strlen (Gbl.Test.Question.Stem.Text);
|
Question->Stem.Length = strlen (Question->Stem.Text);
|
||||||
Gbl.Test.Question.Feedback.Text = Feedback;
|
Question->Feedback.Text = Feedback;
|
||||||
Gbl.Test.Question.Feedback.Length = strlen (Gbl.Test.Question.Feedback.Text);
|
Question->Feedback.Length = strlen (Question->Feedback.Text);
|
||||||
|
|
||||||
return QstCod;
|
return QstCod;
|
||||||
}
|
}
|
||||||
|
@ -6161,7 +6181,7 @@ static long Tst_GetQstFromForm (char *Stem,char *Feedback)
|
||||||
// Counts Gbl.Test.Answer.NumOptions
|
// Counts Gbl.Test.Answer.NumOptions
|
||||||
// Computes Gbl.Test.Answer.Integer and Gbl.Test.Answer.FloatingPoint[0..1]
|
// Computes Gbl.Test.Answer.Integer and Gbl.Test.Answer.FloatingPoint[0..1]
|
||||||
|
|
||||||
bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (void)
|
bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (const struct Tst_Question *Question)
|
||||||
{
|
{
|
||||||
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;
|
||||||
extern const char *Txt_You_must_type_the_stem_of_the_question;
|
extern const char *Txt_You_must_type_the_stem_of_the_question;
|
||||||
|
@ -6189,7 +6209,7 @@ bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** A question must have a stem*****/
|
/***** A question must have a stem*****/
|
||||||
if (!Gbl.Test.Question.Stem.Length)
|
if (!Question->Stem.Length)
|
||||||
{
|
{
|
||||||
Ale_ShowAlert (Ale_WARNING,Txt_You_must_type_the_stem_of_the_question);
|
Ale_ShowAlert (Ale_WARNING,Txt_You_must_type_the_stem_of_the_question);
|
||||||
return false;
|
return false;
|
||||||
|
@ -6343,7 +6363,7 @@ bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (void)
|
||||||
/*********** Check if a test question already exists in database *************/
|
/*********** Check if a test question already exists in database *************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
bool Tst_CheckIfQuestionExistsInDB (void)
|
bool Tst_CheckIfQuestionExistsInDB (const struct Tst_Question *Question)
|
||||||
{
|
{
|
||||||
extern const char *Tst_StrAnswerTypesDB[Tst_NUM_ANS_TYPES];
|
extern const char *Tst_StrAnswerTypesDB[Tst_NUM_ANS_TYPES];
|
||||||
MYSQL_RES *mysql_res_qst;
|
MYSQL_RES *mysql_res_qst;
|
||||||
|
@ -6366,7 +6386,7 @@ bool Tst_CheckIfQuestionExistsInDB (void)
|
||||||
" 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[Gbl.Test.AnswerType],
|
||||||
Gbl.Test.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
|
||||||
{
|
{
|
||||||
|
@ -6449,7 +6469,8 @@ bool Tst_CheckIfQuestionExistsInDB (void)
|
||||||
/* Move images associates to a test question to their definitive directories */
|
/* Move images associates to a test question to their definitive directories */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Tst_MoveMediaToDefinitiveDirectories (long QstCod)
|
static void Tst_MoveMediaToDefinitiveDirectories (long QstCod,
|
||||||
|
struct Tst_Question *Question)
|
||||||
{
|
{
|
||||||
unsigned NumOpt;
|
unsigned NumOpt;
|
||||||
long CurrentMedCodInDB;
|
long CurrentMedCodInDB;
|
||||||
|
@ -6457,7 +6478,7 @@ static void Tst_MoveMediaToDefinitiveDirectories (long QstCod)
|
||||||
/***** Media associated to question stem *****/
|
/***** Media associated to question stem *****/
|
||||||
CurrentMedCodInDB = Tst_GetMedCodFromDB (Gbl.Hierarchy.Crs.CrsCod,QstCod,
|
CurrentMedCodInDB = Tst_GetMedCodFromDB (Gbl.Hierarchy.Crs.CrsCod,QstCod,
|
||||||
-1L); // Get current media code associated to stem
|
-1L); // Get current media code associated to stem
|
||||||
Med_RemoveKeepOrStoreMedia (CurrentMedCodInDB,&Gbl.Test.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 ||
|
if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE ||
|
||||||
|
@ -6859,10 +6880,11 @@ void Tst_PutParamQstCod (long QstCod)
|
||||||
/******** Insert or update question, tags and anser in the database **********/
|
/******** Insert or update question, tags and anser in the database **********/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
long Tst_InsertOrUpdateQstTagsAnsIntoDB (long QstCod)
|
long Tst_InsertOrUpdateQstTagsAnsIntoDB (long QstCod,
|
||||||
|
const struct Tst_Question *Question)
|
||||||
{
|
{
|
||||||
/***** Insert or update question in the table of questions *****/
|
/***** Insert or update question in the table of questions *****/
|
||||||
QstCod = Tst_InsertOrUpdateQstIntoDB (QstCod);
|
QstCod = Tst_InsertOrUpdateQstIntoDB (QstCod,Question);
|
||||||
if (QstCod > 0)
|
if (QstCod > 0)
|
||||||
{
|
{
|
||||||
/***** Insert tags in the tags table *****/
|
/***** Insert tags in the tags table *****/
|
||||||
|
@ -6882,7 +6904,8 @@ long Tst_InsertOrUpdateQstTagsAnsIntoDB (long QstCod)
|
||||||
/*********** Insert or update question in the table of questions *************/
|
/*********** Insert or update question in the table of questions *************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static long Tst_InsertOrUpdateQstIntoDB (long QstCod)
|
static long Tst_InsertOrUpdateQstIntoDB (long QstCod,
|
||||||
|
const struct Tst_Question *Question)
|
||||||
{
|
{
|
||||||
if (QstCod < 0) // It's a new question
|
if (QstCod < 0) // It's a new question
|
||||||
{
|
{
|
||||||
|
@ -6890,21 +6913,33 @@ static long Tst_InsertOrUpdateQstIntoDB (long QstCod)
|
||||||
QstCod =
|
QstCod =
|
||||||
DB_QueryINSERTandReturnCode ("can not create question",
|
DB_QueryINSERTandReturnCode ("can not create question",
|
||||||
"INSERT INTO tst_questions"
|
"INSERT INTO tst_questions"
|
||||||
" (CrsCod,EditTime,AnsType,Shuffle,"
|
" (CrsCod,"
|
||||||
"Stem,Feedback,MedCod,"
|
"EditTime,"
|
||||||
"NumHits,Score)"
|
"AnsType,"
|
||||||
|
"Shuffle,"
|
||||||
|
"Stem,"
|
||||||
|
"Feedback,"
|
||||||
|
"MedCod,"
|
||||||
|
"NumHits,"
|
||||||
|
"Score)"
|
||||||
" VALUES"
|
" VALUES"
|
||||||
" (%ld,NOW(),'%s','%c',"
|
" (%ld," // CrsCod
|
||||||
"'%s','%s',%ld,"
|
"NOW()," // EditTime
|
||||||
"0,0)",
|
"'%s'," // AnsType
|
||||||
|
"'%c'," // Shuffle
|
||||||
|
"'%s'," // Stem
|
||||||
|
"'%s'," // Feedback
|
||||||
|
"%ld," // MedCod
|
||||||
|
"0," // NumHits
|
||||||
|
"0)", // Score
|
||||||
Gbl.Hierarchy.Crs.CrsCod,
|
Gbl.Hierarchy.Crs.CrsCod,
|
||||||
Tst_StrAnswerTypesDB[Gbl.Test.AnswerType],
|
Tst_StrAnswerTypesDB[Gbl.Test.AnswerType],
|
||||||
Gbl.Test.Question.Shuffle ? 'Y' :
|
Question->Shuffle ? 'Y' :
|
||||||
'N',
|
'N',
|
||||||
Gbl.Test.Question.Stem.Text,
|
Question->Stem.Text,
|
||||||
Gbl.Test.Question.Feedback.Text ? Gbl.Test.Question.Feedback.Text :
|
Question->Feedback.Text ? Question->Feedback.Text :
|
||||||
"",
|
"",
|
||||||
Gbl.Test.Question.Media.MedCod);
|
Question->Media.MedCod);
|
||||||
}
|
}
|
||||||
else // It's an existing question
|
else // It's an existing question
|
||||||
{
|
{
|
||||||
|
@ -6912,16 +6947,20 @@ static long Tst_InsertOrUpdateQstIntoDB (long QstCod)
|
||||||
/* Update question in database */
|
/* Update question in database */
|
||||||
DB_QueryUPDATE ("can not update question",
|
DB_QueryUPDATE ("can not update question",
|
||||||
"UPDATE tst_questions"
|
"UPDATE tst_questions"
|
||||||
" SET EditTime=NOW(),AnsType='%s',Shuffle='%c',"
|
" SET EditTime=NOW(),"
|
||||||
"Stem='%s',Feedback='%s',MedCod=%ld"
|
"AnsType='%s',"
|
||||||
|
"Shuffle='%c',"
|
||||||
|
"Stem='%s',"
|
||||||
|
"Feedback='%s',"
|
||||||
|
"MedCod=%ld"
|
||||||
" WHERE QstCod=%ld AND CrsCod=%ld",
|
" WHERE QstCod=%ld AND CrsCod=%ld",
|
||||||
Tst_StrAnswerTypesDB[Gbl.Test.AnswerType],
|
Tst_StrAnswerTypesDB[Gbl.Test.AnswerType],
|
||||||
Gbl.Test.Question.Shuffle ? 'Y' :
|
Question->Shuffle ? 'Y' :
|
||||||
'N',
|
'N',
|
||||||
Gbl.Test.Question.Stem.Text,
|
Question->Stem.Text,
|
||||||
Gbl.Test.Question.Feedback.Text ? Gbl.Test.Question.Feedback.Text :
|
Question->Feedback.Text ? Question->Feedback.Text :
|
||||||
"",
|
"",
|
||||||
Gbl.Test.Question.Media.MedCod,
|
Question->Media.MedCod,
|
||||||
QstCod,Gbl.Hierarchy.Crs.CrsCod);
|
QstCod,Gbl.Hierarchy.Crs.CrsCod);
|
||||||
|
|
||||||
/* Remove answers and tags from this test question */
|
/* Remove answers and tags from this test question */
|
||||||
|
|
15
swad_test.h
15
swad_test.h
|
@ -147,7 +147,9 @@ void Tst_ShowTagList (unsigned NumTags,MYSQL_RES *mysql_res);
|
||||||
|
|
||||||
void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions,
|
void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions,
|
||||||
struct UsrData *UsrDat,
|
struct UsrData *UsrDat,
|
||||||
unsigned NumQst,long QstCod,MYSQL_ROW row,
|
unsigned NumQst,
|
||||||
|
long QstCod,
|
||||||
|
MYSQL_ROW row,
|
||||||
unsigned Visibility,
|
unsigned Visibility,
|
||||||
double *ScoreThisQst,bool *AnswerIsNotBlank);
|
double *ScoreThisQst,bool *AnswerIsNotBlank);
|
||||||
void Tst_WriteQstStem (const char *Stem,const char *ClassStem,bool Visible);
|
void Tst_WriteQstStem (const char *Stem,const char *ClassStem,bool Visible);
|
||||||
|
@ -193,16 +195,16 @@ bool Tst_CheckIfCourseHaveTestsAndPluggableIsUnknown (void);
|
||||||
void Tst_ReceiveConfigTst (void);
|
void Tst_ReceiveConfigTst (void);
|
||||||
void Tst_ShowFormEditOneQst (void);
|
void Tst_ShowFormEditOneQst (void);
|
||||||
|
|
||||||
void Tst_QstConstructor (void);
|
void Tst_QstConstructor (struct Tst_Question *Question);
|
||||||
void Tst_QstDestructor (void);
|
void Tst_QstDestructor (struct Tst_Question *Question);
|
||||||
|
|
||||||
int Tst_AllocateTextChoiceAnswer (unsigned NumOpt);
|
int Tst_AllocateTextChoiceAnswer (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 (void);
|
bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (const struct Tst_Question *Question);
|
||||||
|
|
||||||
bool Tst_CheckIfQuestionExistsInDB (void);
|
bool Tst_CheckIfQuestionExistsInDB (const struct Tst_Question *Question);
|
||||||
|
|
||||||
long Tst_GetIntAnsFromStr (char *Str);
|
long Tst_GetIntAnsFromStr (char *Str);
|
||||||
|
|
||||||
|
@ -218,7 +220,8 @@ long Tst_GetParamGblQstCod (void);
|
||||||
void Tst_PutParamGblQstCod (void);
|
void Tst_PutParamGblQstCod (void);
|
||||||
void Tst_PutParamQstCod (long QstCod);
|
void Tst_PutParamQstCod (long QstCod);
|
||||||
|
|
||||||
long Tst_InsertOrUpdateQstTagsAnsIntoDB (long QstCod);
|
long Tst_InsertOrUpdateQstTagsAnsIntoDB (long QstCod,
|
||||||
|
const struct Tst_Question *Question);
|
||||||
|
|
||||||
void Tst_RemoveCrsTests (long CrsCod);
|
void Tst_RemoveCrsTests (long CrsCod);
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ static void TsI_GetAnswerFromXML (struct XMLElement *AnswerElem);
|
||||||
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,
|
||||||
bool QuestionExists);
|
bool QuestionExists);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -528,6 +529,7 @@ static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer)
|
||||||
struct XMLAttribute *Attribute;
|
struct XMLAttribute *Attribute;
|
||||||
bool AnswerTypeFound;
|
bool AnswerTypeFound;
|
||||||
bool QuestionExists;
|
bool QuestionExists;
|
||||||
|
struct Tst_Question Question;
|
||||||
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];
|
||||||
|
|
||||||
|
@ -571,7 +573,7 @@ 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 ();
|
Tst_QstConstructor (&Question);
|
||||||
|
|
||||||
/* Get type of questions (in mandatory attribute "type") */
|
/* Get type of questions (in mandatory attribute "type") */
|
||||||
AnswerTypeFound = false;
|
AnswerTypeFound = false;
|
||||||
|
@ -623,8 +625,8 @@ static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer)
|
||||||
Str_ChangeFormat (Str_FROM_TEXT,Str_TO_HTML,
|
Str_ChangeFormat (Str_FROM_TEXT,Str_TO_HTML,
|
||||||
Stem,Cns_MAX_BYTES_TEXT,true);
|
Stem,Cns_MAX_BYTES_TEXT,true);
|
||||||
|
|
||||||
Gbl.Test.Question.Stem.Text = Stem;
|
Question.Stem.Text = Stem;
|
||||||
Gbl.Test.Question.Stem.Length = strlen (Stem);
|
Question.Stem.Length = strlen (Stem);
|
||||||
}
|
}
|
||||||
break; // Only first element "stem"
|
break; // Only first element "stem"
|
||||||
}
|
}
|
||||||
|
@ -643,14 +645,14 @@ static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer)
|
||||||
Str_ChangeFormat (Str_FROM_TEXT,Str_TO_HTML,
|
Str_ChangeFormat (Str_FROM_TEXT,Str_TO_HTML,
|
||||||
Feedback,Cns_MAX_BYTES_TEXT,true);
|
Feedback,Cns_MAX_BYTES_TEXT,true);
|
||||||
|
|
||||||
Gbl.Test.Question.Feedback.Text = Feedback;
|
Question.Feedback.Text = Feedback;
|
||||||
Gbl.Test.Question.Feedback.Length = strlen (Feedback);
|
Question.Feedback.Length = strlen (Feedback);
|
||||||
}
|
}
|
||||||
break; // Only first element "feedback"
|
break; // Only first element "feedback"
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get shuffle. By default, shuffle is false. */
|
/* Get shuffle. By default, shuffle is false. */
|
||||||
Gbl.Test.Question.Shuffle = false;
|
Question.Shuffle = false;
|
||||||
for (AnswerElem = QuestionElem->FirstChild;
|
for (AnswerElem = QuestionElem->FirstChild;
|
||||||
AnswerElem != NULL;
|
AnswerElem != NULL;
|
||||||
AnswerElem = AnswerElem->NextBrother)
|
AnswerElem = AnswerElem->NextBrother)
|
||||||
|
@ -664,7 +666,7 @@ static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer)
|
||||||
Attribute = Attribute->Next)
|
Attribute = Attribute->Next)
|
||||||
if (!strcmp (Attribute->AttributeName,"shuffle"))
|
if (!strcmp (Attribute->AttributeName,"shuffle"))
|
||||||
{
|
{
|
||||||
Gbl.Test.Question.Shuffle = XML_GetAttributteYesNoFromXMLTree (Attribute);
|
Question.Shuffle = XML_GetAttributteYesNoFromXMLTree (Attribute);
|
||||||
break; // Only first attribute "shuffle"
|
break; // Only first attribute "shuffle"
|
||||||
}
|
}
|
||||||
break; // Only first element "answer"
|
break; // Only first element "answer"
|
||||||
|
@ -674,22 +676,22 @@ static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer)
|
||||||
TsI_GetAnswerFromXML (AnswerElem);
|
TsI_GetAnswerFromXML (AnswerElem);
|
||||||
|
|
||||||
/* Make sure that tags, text and answer are not empty */
|
/* Make sure that tags, text and answer are not empty */
|
||||||
if (Tst_CheckIfQstFormatIsCorrectAndCountNumOptions ())
|
if (Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (&Question))
|
||||||
{
|
{
|
||||||
/* Check if question already exists in database */
|
/* Check if question already exists in database */
|
||||||
QuestionExists = Tst_CheckIfQuestionExistsInDB ();
|
QuestionExists = Tst_CheckIfQuestionExistsInDB (&Question);
|
||||||
|
|
||||||
/* Write row with this imported question */
|
/* Write row with this imported question */
|
||||||
TsI_WriteRowImportedQst (StemElem,FeedbackElem,QuestionExists);
|
TsI_WriteRowImportedQst (StemElem,FeedbackElem,&Question,QuestionExists);
|
||||||
|
|
||||||
/***** If a new question ==> insert question, tags and answer in the database *****/
|
/***** If a new question ==> insert question, tags and answer in the database *****/
|
||||||
if (!QuestionExists)
|
if (!QuestionExists)
|
||||||
if (Tst_InsertOrUpdateQstTagsAnsIntoDB (-1L) <= 0)
|
if (Tst_InsertOrUpdateQstTagsAnsIntoDB (-1L,&Question) <= 0)
|
||||||
Lay_ShowErrorAndExit ("Can not create question.");
|
Lay_ShowErrorAndExit ("Can not create question.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Destroy test question *****/
|
/***** Destroy test question *****/
|
||||||
Tst_QstDestructor ();
|
Tst_QstDestructor (&Question);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -899,6 +901,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,
|
||||||
bool QuestionExists)
|
bool QuestionExists)
|
||||||
{
|
{
|
||||||
extern const char *Txt_Existing_question;
|
extern const char *Txt_Existing_question;
|
||||||
|
@ -986,7 +989,7 @@ static void TsI_WriteRowImportedQst (struct XMLElement *StemElem,
|
||||||
if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE ||
|
if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE ||
|
||||||
Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
Gbl.Test.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 (Gbl.Test.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,
|
||||||
QuestionExists ? "ICO_HIDDEN ICO16x16" :
|
QuestionExists ? "ICO_HIDDEN ICO16x16" :
|
||||||
"ICO16x16");
|
"ICO16x16");
|
||||||
|
|
|
@ -901,7 +901,8 @@ void TsR_ShowTestResult (struct UsrData *UsrDat,
|
||||||
/***** Write questions and answers *****/
|
/***** Write questions and answers *****/
|
||||||
Tst_WriteQstAndAnsTest (Tst_SHOW_TEST_RESULT,
|
Tst_WriteQstAndAnsTest (Tst_SHOW_TEST_RESULT,
|
||||||
UsrDat,
|
UsrDat,
|
||||||
NumQst,Gbl.Test.QstCodes[NumQst],row,
|
NumQst,Gbl.Test.QstCodes[NumQst],
|
||||||
|
row,
|
||||||
Visibility,
|
Visibility,
|
||||||
&ScoreThisQst, // Not used here
|
&ScoreThisQst, // Not used here
|
||||||
&AnswerIsNotBlank); // Not used here
|
&AnswerIsNotBlank); // Not used here
|
||||||
|
|
Loading…
Reference in New Issue