mirror of
https://github.com/acanas/swad-core.git
synced 2024-06-09 18:25:23 +02:00
Version 15.184
This commit is contained in:
parent
72c3301506
commit
58ccf23b80
|
@ -1743,12 +1743,12 @@ a:hover img.CENTRE_PHOTO_SHOW
|
||||||
.TEST_EXA_LIGHT {color:#A0A0A0; font-size:12pt;}
|
.TEST_EXA_LIGHT {color:#A0A0A0; font-size:12pt;}
|
||||||
.TEST_EDI {color:#404040; font-size:12pt;}
|
.TEST_EDI {color:#404040; font-size:12pt;}
|
||||||
.TEST_EDI_LIGHT {color:#A0A0A0; font-size:12pt;}
|
.TEST_EDI_LIGHT {color:#A0A0A0; font-size:12pt;}
|
||||||
.TEST_IMG_SHOW_STEM {width:600px; margin:10px 0;}
|
.TEST_IMG_SHOW_STEM {width:600px; border-radius:4px; margin:10px 0;}
|
||||||
.TEST_IMG_SHOW_ANS {width:450px; margin:10px 0;}
|
.TEST_IMG_SHOW_ANS {width:450px; border-radius:4px; margin:10px 0;}
|
||||||
.TEST_IMG_EDIT_LIST_STEM {width:300px; margin:5px 0;}
|
.TEST_IMG_EDIT_LIST_STEM {width:300px; border-radius:2px; margin:5px 0;}
|
||||||
.TEST_IMG_EDIT_LIST_ANS {width:225px; margin:5px 0;}
|
.TEST_IMG_EDIT_LIST_ANS {width:225px; border-radius:2px; margin:5px 0;}
|
||||||
.TEST_IMG_EDIT_ONE_STEM {width:600px;}
|
.TEST_IMG_EDIT_ONE_STEM {width:600px; border-radius:4px;}
|
||||||
.TEST_IMG_EDIT_ONE_ANS {width:450px;}
|
.TEST_IMG_EDIT_ONE_ANS {width:450px; border-radius:4px;}
|
||||||
|
|
||||||
/******************************* Time table **********************************/
|
/******************************* Time table **********************************/
|
||||||
#timetable
|
#timetable
|
||||||
|
|
|
@ -132,13 +132,15 @@
|
||||||
/****************************** Public constants *****************************/
|
/****************************** Public constants *****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
#define Log_PLATFORM_VERSION "SWAD 15.183.1 (2016-04-06)"
|
#define Log_PLATFORM_VERSION "SWAD 15.184 (2016-04-06)"
|
||||||
#define CSS_FILE "swad15.178.2.css"
|
#define CSS_FILE "swad15.178.2.css"
|
||||||
#define JS_FILE "swad15.178.2.js"
|
#define JS_FILE "swad15.178.2.js"
|
||||||
|
|
||||||
// Number of lines (includes comments but not blank lines) has been got with the following command:
|
// Number of lines (includes comments but not blank lines) has been got with the following command:
|
||||||
// nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*.h sql/swad*.sql | tail -1
|
// nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*.h sql/swad*.sql | tail -1
|
||||||
/*
|
/*
|
||||||
|
Version 15.184: Apr 06, 2016 Code refactoring in tests and images.
|
||||||
|
Fixed bugs in test questions. (198682 lines)
|
||||||
Version 15.183.1: Apr 06, 2016 Fix bug in feedback of test question. (198706 lines)
|
Version 15.183.1: Apr 06, 2016 Fix bug in feedback of test question. (198706 lines)
|
||||||
Version 15.183: Apr 06, 2016 Change in length of title/attribution of images. (198704 lines)
|
Version 15.183: Apr 06, 2016 Change in length of title/attribution of images. (198704 lines)
|
||||||
2 changes necessary in database:
|
2 changes necessary in database:
|
||||||
|
|
106
swad_image.c
106
swad_image.c
|
@ -71,45 +71,47 @@ static void Img_ProcessImage (const char *FileNameImgOriginal,
|
||||||
/*************************** Reset image title *******************************/
|
/*************************** Reset image title *******************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Img_ResetImageTitle (struct Image *Image)
|
void Img_FreeImageTitle (struct Image *Image)
|
||||||
{
|
{
|
||||||
|
// Image->Title must be initialized to NULL
|
||||||
if (Image->Title)
|
if (Image->Title)
|
||||||
|
{
|
||||||
free ((void *) Image->Title);
|
free ((void *) Image->Title);
|
||||||
Image->Title = NULL;
|
Image->Title = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/********* Get image name and title from strings and copy to struct **********/
|
/****** Get image name and title from a query result and copy to struct ******/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Img_GetImageNameAndTitle (const char *Name,const char *Title,
|
void Img_GetImageNameAndTitleFromRow (const char *Name,const char *Title,
|
||||||
struct Image *Image)
|
struct Image *Image)
|
||||||
{
|
{
|
||||||
size_t Length;
|
size_t Length;
|
||||||
|
|
||||||
Img_ResetImageTitle (Image);
|
/***** Copy image name to struct *****/
|
||||||
|
strncpy (Image->Name,Name,Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64);
|
||||||
|
Image->Name[Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64] = '\0';
|
||||||
|
|
||||||
if (Name[0])
|
/***** Set status of image file *****/
|
||||||
|
Image->Status = Image->Name[0] ? Img_NAME_STORED_IN_DB :
|
||||||
|
Img_FILE_NONE;
|
||||||
|
|
||||||
|
/***** Copy image title to struct *****/
|
||||||
|
Img_FreeImageTitle (Image);
|
||||||
|
if (Title[0])
|
||||||
{
|
{
|
||||||
strncpy (Image->Name,Name,Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64);
|
/* Get and limit length of the title */
|
||||||
Image->Name[Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64] = '\0';
|
Length = strlen (Title);
|
||||||
|
if (Length > Img_MAX_BYTES_TITLE)
|
||||||
|
Length = Img_MAX_BYTES_TITLE;
|
||||||
|
|
||||||
if (Image->Name[0]) // There is an image
|
if ((Image->Title = (char *) malloc (Length+1)) == NULL)
|
||||||
if (Title[0])
|
Lay_ShowErrorAndExit ("Error allocating memory for image title.");
|
||||||
{
|
strncpy (Image->Title,Title,Length);
|
||||||
/* Get and limit length of the title */
|
Image->Title[Length] = '\0';
|
||||||
Length = strlen (Title);
|
|
||||||
if (Length > Img_MAX_BYTES_TITLE)
|
|
||||||
Length = Img_MAX_BYTES_TITLE;
|
|
||||||
|
|
||||||
if ((Image->Title = (char *) malloc (Length+1)) == NULL)
|
|
||||||
Lay_ShowErrorAndExit ("Error allocating memory for image title.");
|
|
||||||
strncpy (Image->Title,Title,Length);
|
|
||||||
Image->Title[Length] = '\0';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else // No image in this question
|
|
||||||
Image->Name[0] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -117,50 +119,60 @@ void Img_GetImageNameAndTitle (const char *Name,const char *Title,
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Img_GetImageFromForm (unsigned NumOpt,struct Image *Image,
|
void Img_GetImageFromForm (unsigned NumOpt,struct Image *Image,
|
||||||
void (*GetImageNameFromDB) (unsigned NumOpt,struct Image *Image),
|
void (*GetImageFromDB) (unsigned NumOpt,struct Image *Image),
|
||||||
const char *ParamAction,const char *ParamFile,const char *ParamTitle,
|
const char *ParamAction,const char *ParamFile,const char *ParamTitle,
|
||||||
unsigned Width,unsigned Height,unsigned Quality)
|
unsigned Width,unsigned Height,unsigned Quality)
|
||||||
{
|
{
|
||||||
|
char Title[Img_MAX_BYTES_TITLE+1];
|
||||||
|
size_t Length;
|
||||||
|
|
||||||
Image->Action = Img_GetImageActionFromForm (ParamAction);
|
Image->Action = Img_GetImageActionFromForm (ParamAction);
|
||||||
Image->Status = Img_FILE_NONE;
|
Image->Status = Img_FILE_NONE;
|
||||||
|
Img_FreeImageTitle (Image); // Reset to NULL
|
||||||
|
|
||||||
switch (Image->Action)
|
switch (Image->Action)
|
||||||
{
|
{
|
||||||
case Img_ACTION_NO_IMAGE: // Do not use image (remove current image if exists)
|
case Img_ACTION_NO_IMAGE: // Do not use image (remove current image if exists)
|
||||||
/***** Reset image name *****/
|
/***** Reset image name *****/
|
||||||
Image->Name[0] = '\0';
|
Image->Name[0] = '\0';
|
||||||
Img_ResetImageTitle (Image);
|
|
||||||
break;
|
break;
|
||||||
case Img_ACTION_KEEP_IMAGE: // Keep current image unchanged
|
case Img_ACTION_KEEP_IMAGE: // Keep current image unchanged
|
||||||
/***** Get image name *****/
|
/***** Get image name *****/
|
||||||
GetImageNameFromDB (NumOpt,Image);
|
GetImageFromDB (NumOpt,Image);
|
||||||
if (Image->Name[0])
|
|
||||||
Image->Status = Img_NAME_STORED_IN_DB;
|
|
||||||
break;
|
break;
|
||||||
case Img_ACTION_NEW_IMAGE: // Upload new image
|
case Img_ACTION_NEW_IMAGE: // Upload new image
|
||||||
/***** Get new image (if present ==> process and create temporary file) *****/
|
/***** Get new image (if present ==> process and create temporary file) *****/
|
||||||
Img_GetAndProcessImageFileFromForm (Image,ParamFile,ParamTitle,
|
Img_GetAndProcessImageFileFromForm (Image,ParamFile,
|
||||||
Width,Height,Quality);
|
Width,Height,Quality);
|
||||||
if (Image->Status != Img_FILE_PROCESSED) // No new image received-processed successfully
|
if (Image->Status != Img_FILE_PROCESSED) // No new image received-processed successfully
|
||||||
{
|
{
|
||||||
/* Reset image name */
|
/* Reset image name */
|
||||||
Image->Status = Img_FILE_NONE;
|
Image->Status = Img_FILE_NONE;
|
||||||
Image->Name[0] = '\0';
|
Image->Name[0] = '\0';
|
||||||
Img_ResetImageTitle (Image);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Img_ACTION_CHANGE_IMAGE: // Replace old image by new image
|
case Img_ACTION_CHANGE_IMAGE: // Replace old image by new image
|
||||||
/***** Get new image (if present ==> process and create temporary file) *****/
|
/***** Get new image (if present ==> process and create temporary file) *****/
|
||||||
Img_GetAndProcessImageFileFromForm (Image,ParamFile,ParamTitle,
|
Img_GetAndProcessImageFileFromForm (Image,ParamFile,
|
||||||
Width,Height,Quality);
|
Width,Height,Quality);
|
||||||
if (Image->Status != Img_FILE_PROCESSED) // No new image received-processed successfully
|
if (Image->Status != Img_FILE_PROCESSED) // No new image received-processed successfully
|
||||||
{
|
|
||||||
/* Get image name */
|
/* Get image name */
|
||||||
GetImageNameFromDB (NumOpt,Image);
|
GetImageFromDB (NumOpt,Image);
|
||||||
Image->Status = (Image->Name[0] ? Img_NAME_STORED_IN_DB :
|
|
||||||
Img_FILE_NONE);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***** Get image title from form *****/
|
||||||
|
Par_GetParToHTML (ParamTitle,Title,Img_MAX_BYTES_TITLE);
|
||||||
|
if ((Length = strlen (Title)) > 0) // If title comming from the form is not empty
|
||||||
|
{
|
||||||
|
/* Overwrite current title (empty or coming from database)
|
||||||
|
with the title coming from the form */
|
||||||
|
Img_FreeImageTitle (Image);
|
||||||
|
if ((Image->Title = (char *) malloc (Length + 1)) == NULL)
|
||||||
|
Lay_ShowErrorAndExit ("Error allocating memory for image title.");
|
||||||
|
strncpy (Image->Title,Title,Length);
|
||||||
|
Image->Title[Length] = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -183,12 +195,9 @@ Img_Action_t Img_GetImageActionFromForm (const char *ParamAction)
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/**************************** Get image from form ****************************/
|
/**************************** Get image from form ****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
// Return true if image is created
|
|
||||||
|
|
||||||
void Img_GetAndProcessImageFileFromForm (struct Image *Image,
|
void Img_GetAndProcessImageFileFromForm (struct Image *Image,const char *ParamFile,
|
||||||
const char *ParamFile,const char *ParamTitle,
|
unsigned Width,unsigned Height,unsigned Quality)
|
||||||
unsigned Width,unsigned Height,
|
|
||||||
unsigned Quality)
|
|
||||||
{
|
{
|
||||||
struct Param *Param;
|
struct Param *Param;
|
||||||
char FileNameImgSrc[PATH_MAX+1];
|
char FileNameImgSrc[PATH_MAX+1];
|
||||||
|
@ -199,8 +208,6 @@ void Img_GetAndProcessImageFileFromForm (struct Image *Image,
|
||||||
char FileNameImgOrig[PATH_MAX+1]; // Full name of original uploaded file
|
char FileNameImgOrig[PATH_MAX+1]; // Full name of original uploaded file
|
||||||
char FileNameImgTmp[PATH_MAX+1]; // Full name of temporary processed file
|
char FileNameImgTmp[PATH_MAX+1]; // Full name of temporary processed file
|
||||||
bool WrongType = false;
|
bool WrongType = false;
|
||||||
char Title[Img_MAX_BYTES_TITLE+1];
|
|
||||||
size_t Length;
|
|
||||||
|
|
||||||
/***** Rest image file status *****/
|
/***** Rest image file status *****/
|
||||||
Image->Status = Img_FILE_NONE;
|
Image->Status = Img_FILE_NONE;
|
||||||
|
@ -265,17 +272,6 @@ void Img_GetAndProcessImageFileFromForm (struct Image *Image,
|
||||||
|
|
||||||
/***** Remove temporary original file *****/
|
/***** Remove temporary original file *****/
|
||||||
unlink (FileNameImgOrig);
|
unlink (FileNameImgOrig);
|
||||||
|
|
||||||
/***** Get image title from form *****/
|
|
||||||
Par_GetParToHTML (ParamTitle,Title,Img_MAX_BYTES_TITLE); // TODO: Create a function to get only the length of a parameter
|
|
||||||
Length = strlen (Title);
|
|
||||||
if (Length > 0)
|
|
||||||
{
|
|
||||||
if ((Image->Title = (char *) malloc (Length+1)) == NULL)
|
|
||||||
Lay_ShowErrorAndExit ("Error allocating memory for image title.");
|
|
||||||
strncpy (Image->Title,Title,Length);
|
|
||||||
Image->Title[Length] = '\0';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
swad_image.h
14
swad_image.h
|
@ -94,19 +94,17 @@ struct Image
|
||||||
/***************************** Public prototypes *****************************/
|
/***************************** Public prototypes *****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Img_ResetImageTitle (struct Image *Image);
|
void Img_FreeImageTitle (struct Image *Image);
|
||||||
void Img_GetImageNameAndTitle (const char *Name,const char *Title,
|
void Img_GetImageNameAndTitleFromRow (const char *Name,const char *Title,
|
||||||
struct Image *Image);
|
struct Image *Image);
|
||||||
|
|
||||||
void Img_GetImageFromForm (unsigned NumOpt,struct Image *Image,
|
void Img_GetImageFromForm (unsigned NumOpt,struct Image *Image,
|
||||||
void (*GetImageNameFromDB) (unsigned NumOpt,struct Image *Image),
|
void (*GetImageFromDB) (unsigned NumOpt,struct Image *Image),
|
||||||
const char *ParamAction,const char *ParamFile,const char *ParamTitle,
|
const char *ParamAction,const char *ParamFile,const char *ParamTitle,
|
||||||
unsigned Width,unsigned Height,unsigned Quality);
|
unsigned Width,unsigned Height,unsigned Quality);
|
||||||
Img_Action_t Img_GetImageActionFromForm (const char *ParamAction);
|
Img_Action_t Img_GetImageActionFromForm (const char *ParamAction);
|
||||||
void Img_GetAndProcessImageFileFromForm (struct Image *Image,
|
void Img_GetAndProcessImageFileFromForm (struct Image *Image,const char *ParamFile,
|
||||||
const char *ParamFile,const char *ParamTitle,
|
unsigned Width,unsigned Height,unsigned Quality);
|
||||||
unsigned Width,unsigned Height,
|
|
||||||
unsigned Quality);
|
|
||||||
|
|
||||||
void Img_MoveImageToDefinitiveDirectory (struct Image *Image);
|
void Img_MoveImageToDefinitiveDirectory (struct Image *Image);
|
||||||
void Img_ShowImage (struct Image *Image,const char *ClassImg);
|
void Img_ShowImage (struct Image *Image,const char *ClassImg);
|
||||||
|
|
|
@ -2527,7 +2527,7 @@ static unsigned Svy_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res)
|
||||||
|
|
||||||
/***** Count number of rows of result *****/
|
/***** Count number of rows of result *****/
|
||||||
if (NumRows == 0)
|
if (NumRows == 0)
|
||||||
Lay_ShowErrorAndExit ("Error when getting answers of a question.");
|
Lay_ShowAlert (Lay_ERROR,"Error when getting answers of a question.");
|
||||||
|
|
||||||
return (unsigned) NumRows;
|
return (unsigned) NumRows;
|
||||||
}
|
}
|
||||||
|
@ -3024,64 +3024,67 @@ static void Svy_WriteAnswersOfAQst (struct Survey *Svy,struct SurveyQuestion *Sv
|
||||||
NumAnswers = Svy_GetAnswersQst (SvyQst->QstCod,&mysql_res); // Result: AnsInd,NumUsrs,Answer
|
NumAnswers = Svy_GetAnswersQst (SvyQst->QstCod,&mysql_res); // Result: AnsInd,NumUsrs,Answer
|
||||||
|
|
||||||
/***** Write the answers *****/
|
/***** Write the answers *****/
|
||||||
fprintf (Gbl.F.Out,"<table class=\"CELLS_PAD_5\" style=\"width:100%%;\">");
|
if (NumAnswers)
|
||||||
for (NumAns = 0;
|
|
||||||
NumAns < NumAnswers;
|
|
||||||
NumAns++)
|
|
||||||
{
|
{
|
||||||
row = mysql_fetch_row (mysql_res);
|
fprintf (Gbl.F.Out,"<table class=\"CELLS_PAD_5\" style=\"width:100%%;\">");
|
||||||
|
for (NumAns = 0;
|
||||||
|
NumAns < NumAnswers;
|
||||||
|
NumAns++)
|
||||||
|
{
|
||||||
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
|
||||||
/* Get number of users who have marked this answer (row[1]) */
|
/* Get number of users who have marked this answer (row[1]) */
|
||||||
if (sscanf (row[1],"%u",&NumUsrsThisAnswer) != 1)
|
if (sscanf (row[1],"%u",&NumUsrsThisAnswer) != 1)
|
||||||
Lay_ShowErrorAndExit ("Error when getting number of users who have marked an answer.");
|
Lay_ShowErrorAndExit ("Error when getting number of users who have marked an answer.");
|
||||||
|
|
||||||
/* Convert the answer (row[2]), that is in HTML, to rigorous HTML */
|
/* Convert the answer (row[2]), that is in HTML, to rigorous HTML */
|
||||||
AnsLength = strlen (row[2]) * Str_MAX_LENGTH_SPEC_CHAR_HTML;
|
AnsLength = strlen (row[2]) * Str_MAX_LENGTH_SPEC_CHAR_HTML;
|
||||||
if ((Answer = malloc (AnsLength+1)) == NULL)
|
if ((Answer = malloc (AnsLength+1)) == NULL)
|
||||||
Lay_ShowErrorAndExit ("Not enough memory to store answer.");
|
Lay_ShowErrorAndExit ("Not enough memory to store answer.");
|
||||||
strcpy (Answer,row[2]);
|
strcpy (Answer,row[2]);
|
||||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||||
Answer,AnsLength,false);
|
Answer,AnsLength,false);
|
||||||
|
|
||||||
/* Selectors and label with the letter of the answer */
|
/* Selectors and label with the letter of the answer */
|
||||||
fprintf (Gbl.F.Out,"<tr>");
|
fprintf (Gbl.F.Out,"<tr>");
|
||||||
|
|
||||||
if (PutFormAnswerSurvey)
|
if (PutFormAnswerSurvey)
|
||||||
{
|
{
|
||||||
/* Write selector to choice this answer */
|
/* Write selector to choice this answer */
|
||||||
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP\">"
|
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP\">"
|
||||||
"<input type=\"");
|
"<input type=\"");
|
||||||
if (SvyQst->AnswerType == Svy_ANS_UNIQUE_CHOICE)
|
if (SvyQst->AnswerType == Svy_ANS_UNIQUE_CHOICE)
|
||||||
fprintf (Gbl.F.Out,"radio\""
|
fprintf (Gbl.F.Out,"radio\""
|
||||||
" onclick=\"selectUnselectRadio(this,this.form.Ans%010u,%u)\"",
|
" onclick=\"selectUnselectRadio(this,this.form.Ans%010u,%u)\"",
|
||||||
(unsigned) SvyQst->QstCod,NumAnswers);
|
(unsigned) SvyQst->QstCod,NumAnswers);
|
||||||
else // SvyQst->AnswerType == Svy_ANS_MULTIPLE_CHOICE
|
else // SvyQst->AnswerType == Svy_ANS_MULTIPLE_CHOICE
|
||||||
fprintf (Gbl.F.Out,"checkbox\"");
|
fprintf (Gbl.F.Out,"checkbox\"");
|
||||||
fprintf (Gbl.F.Out," name=\"Ans%010u\" value=\"%u\" />"
|
fprintf (Gbl.F.Out," name=\"Ans%010u\" value=\"%u\" />"
|
||||||
"</td>",
|
"</td>",
|
||||||
(unsigned) SvyQst->QstCod,NumAns);
|
(unsigned) SvyQst->QstCod,NumAns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the number of option */
|
/* Write the number of option */
|
||||||
fprintf (Gbl.F.Out,"<td class=\"DAT LEFT_TOP\" style=\"width:50px;\">"
|
fprintf (Gbl.F.Out,"<td class=\"DAT LEFT_TOP\" style=\"width:50px;\">"
|
||||||
"%u)"
|
"%u)"
|
||||||
"</td>",
|
"</td>",
|
||||||
NumAns + 1);
|
NumAns + 1);
|
||||||
|
|
||||||
/* Write the text of the answer */
|
/* Write the text of the answer */
|
||||||
fprintf (Gbl.F.Out,"<td class=\"TEST_EDI LEFT_TOP\">%s</td>",
|
fprintf (Gbl.F.Out,"<td class=\"TEST_EDI LEFT_TOP\">%s</td>",
|
||||||
Answer);
|
Answer);
|
||||||
|
|
||||||
/* Show stats of this answer */
|
/* Show stats of this answer */
|
||||||
if (Svy->Status.ICanViewResults)
|
if (Svy->Status.ICanViewResults)
|
||||||
Svy_DrawBarNumUsrs (NumUsrsThisAnswer,Svy->NumUsrs);
|
Svy_DrawBarNumUsrs (NumUsrsThisAnswer,Svy->NumUsrs);
|
||||||
|
|
||||||
fprintf (Gbl.F.Out,"</tr>");
|
fprintf (Gbl.F.Out,"</tr>");
|
||||||
|
|
||||||
/* Free memory allocated for the answer */
|
/* Free memory allocated for the answer */
|
||||||
free ((void *) Answer);
|
free ((void *) Answer);
|
||||||
|
}
|
||||||
|
fprintf (Gbl.F.Out,"</table>");
|
||||||
}
|
}
|
||||||
fprintf (Gbl.F.Out,"</table>");
|
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
/***** Free structure that stores the query result *****/
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
|
324
swad_test.c
324
swad_test.c
|
@ -219,6 +219,9 @@ static int Tst_CountNumTagsInList (void);
|
||||||
static int Tst_CountNumAnswerTypesInList (void);
|
static int Tst_CountNumAnswerTypesInList (void);
|
||||||
static void Tst_PutFormEditOneQst (char *Stem,char *Feedback);
|
static void Tst_PutFormEditOneQst (char *Stem,char *Feedback);
|
||||||
|
|
||||||
|
static void Tst_FreeTextChoiceAnswers (void);
|
||||||
|
static void Tst_FreeTextChoiceAnswer (unsigned NumOpt);
|
||||||
|
|
||||||
static void Tst_InitImagesOfQuestion (void);
|
static void Tst_InitImagesOfQuestion (void);
|
||||||
static void Tst_FreeImagesOfQuestion (void);
|
static void Tst_FreeImagesOfQuestion (void);
|
||||||
|
|
||||||
|
@ -236,7 +239,7 @@ static void Tst_EnableOrDisableTag (long TagCod,bool TagHidden);
|
||||||
static void Tst_PutIconToRemoveOneQst (void);
|
static void Tst_PutIconToRemoveOneQst (void);
|
||||||
static void Tst_PutParamsRemoveOneQst (void);
|
static void Tst_PutParamsRemoveOneQst (void);
|
||||||
|
|
||||||
static bool Tst_GetQstCod (void);
|
static long Tst_GetQstCod (void);
|
||||||
|
|
||||||
static void Tst_InsertOrUpdateQstIntoDB (void);
|
static void Tst_InsertOrUpdateQstIntoDB (void);
|
||||||
static void Tst_InsertTagsIntoDB (void);
|
static void Tst_InsertTagsIntoDB (void);
|
||||||
|
@ -249,8 +252,6 @@ static void Tst_RemoveUnusedTagsFromCurrentCrs (void);
|
||||||
static void Tst_RemoveImgFilesFromStemOfQsts (long CrsCod,long QstCod);
|
static void Tst_RemoveImgFilesFromStemOfQsts (long CrsCod,long QstCod);
|
||||||
static void Tst_RemoveImgFilesFromAnsOfQsts (long CrsCod,long QstCod,unsigned AnsInd);
|
static void Tst_RemoveImgFilesFromAnsOfQsts (long CrsCod,long QstCod,unsigned AnsInd);
|
||||||
|
|
||||||
static void Tst_FreeTextChoiceAnswer (unsigned NumOpt);
|
|
||||||
|
|
||||||
static unsigned Tst_GetNumTstQuestions (Sco_Scope_t Scope,Tst_AnswerType_t AnsType,struct Tst_Stats *Stats);
|
static unsigned Tst_GetNumTstQuestions (Sco_Scope_t Scope,Tst_AnswerType_t AnsType,struct Tst_Stats *Stats);
|
||||||
static unsigned Tst_GetNumCoursesWithTstQuestions (Sco_Scope_t Scope,Tst_AnswerType_t AnsType);
|
static unsigned Tst_GetNumCoursesWithTstQuestions (Sco_Scope_t Scope,Tst_AnswerType_t AnsType);
|
||||||
static unsigned Tst_GetNumCoursesWithPluggableTstQuestions (Sco_Scope_t Scope,Tst_AnswerType_t AnsType);
|
static unsigned Tst_GetNumCoursesWithPluggableTstQuestions (Sco_Scope_t Scope,Tst_AnswerType_t AnsType);
|
||||||
|
@ -981,6 +982,10 @@ static void Tst_WriteQstAndAnsExam (unsigned NumQst,long QstCod,MYSQL_ROW row,
|
||||||
row[10] Score
|
row[10] Score
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/***** Create test question *****/
|
||||||
|
Tst_QstConstructor ();
|
||||||
|
Gbl.Test.QstCod = QstCod;
|
||||||
|
|
||||||
/***** Write number of question *****/
|
/***** Write number of question *****/
|
||||||
fprintf (Gbl.F.Out,"<tr>"
|
fprintf (Gbl.F.Out,"<tr>"
|
||||||
"<td class=\"RIGHT_TOP COLOR%u\">"
|
"<td class=\"RIGHT_TOP COLOR%u\">"
|
||||||
|
@ -999,12 +1004,9 @@ static void Tst_WriteQstAndAnsExam (unsigned NumQst,long QstCod,MYSQL_ROW row,
|
||||||
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP COLOR%u\">",
|
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP COLOR%u\">",
|
||||||
Gbl.RowEvenOdd);
|
Gbl.RowEvenOdd);
|
||||||
Tst_WriteQstStem (row[4],"TEST_EXA");
|
Tst_WriteQstStem (row[4],"TEST_EXA");
|
||||||
if (row[6][0])
|
Img_GetImageNameAndTitleFromRow (row[6],row[7],&Gbl.Test.Image);
|
||||||
{
|
Img_ShowImage (&Gbl.Test.Image,"TEST_IMG_SHOW_STEM");
|
||||||
Gbl.Test.Image.Status = Img_NAME_STORED_IN_DB;
|
|
||||||
Img_GetImageNameAndTitle (row[6],row[7],&Gbl.Test.Image);
|
|
||||||
Img_ShowImage (&Gbl.Test.Image,"TEST_IMG_SHOW_STEM");
|
|
||||||
}
|
|
||||||
if (Gbl.Action.Act == ActSeeTst)
|
if (Gbl.Action.Act == ActSeeTst)
|
||||||
Tst_WriteAnswersOfAQstSeeExam (NumQst,QstCod,(Str_ConvertToUpperLetter (row[3][0]) == 'Y'));
|
Tst_WriteAnswersOfAQstSeeExam (NumQst,QstCod,(Str_ConvertToUpperLetter (row[3][0]) == 'Y'));
|
||||||
else // Assessing exam / Viewing old exam
|
else // Assessing exam / Viewing old exam
|
||||||
|
@ -1018,9 +1020,8 @@ static void Tst_WriteQstAndAnsExam (unsigned NumQst,long QstCod,MYSQL_ROW row,
|
||||||
fprintf (Gbl.F.Out,"</td>"
|
fprintf (Gbl.F.Out,"</td>"
|
||||||
"</tr>");
|
"</tr>");
|
||||||
|
|
||||||
/***** Free answers and images of this test question *****/
|
/***** Destroy test question *****/
|
||||||
Tst_FreeTextChoiceAnswers ();
|
Tst_QstDestructor ();
|
||||||
Tst_FreeImagesOfQuestion ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -2615,7 +2616,6 @@ static void Tst_ListOneOrMoreQuestionsToEdit (unsigned long NumRows,MYSQL_RES *m
|
||||||
Tst_QuestionsOrder_t Order;
|
Tst_QuestionsOrder_t Order;
|
||||||
unsigned long NumRow;
|
unsigned long NumRow;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
long QstCod;
|
|
||||||
unsigned UniqueId;
|
unsigned UniqueId;
|
||||||
time_t TimeUTC;
|
time_t TimeUTC;
|
||||||
unsigned long NumHitsThisQst;
|
unsigned long NumHitsThisQst;
|
||||||
|
@ -2706,8 +2706,11 @@ static void Tst_ListOneOrMoreQuestionsToEdit (unsigned long NumRows,MYSQL_RES *m
|
||||||
row[ 9] NumHitsNotBlank
|
row[ 9] NumHitsNotBlank
|
||||||
row[10] Score
|
row[10] Score
|
||||||
*/
|
*/
|
||||||
|
/***** Create test question *****/
|
||||||
|
Tst_QstConstructor ();
|
||||||
|
|
||||||
/* row[0] holds the code of the question */
|
/* row[0] holds the code of the question */
|
||||||
if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
|
if ((Gbl.Test.QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
|
||||||
Lay_ShowErrorAndExit ("Wrong code of question.");
|
Lay_ShowErrorAndExit ("Wrong code of question.");
|
||||||
|
|
||||||
/* Write icon to remove the question */
|
/* Write icon to remove the question */
|
||||||
|
@ -2716,7 +2719,7 @@ static void Tst_ListOneOrMoreQuestionsToEdit (unsigned long NumRows,MYSQL_RES *m
|
||||||
Act_FormStart (ActReqRemTstQst);
|
Act_FormStart (ActReqRemTstQst);
|
||||||
Sta_WriteParamsDatesSeeAccesses ();
|
Sta_WriteParamsDatesSeeAccesses ();
|
||||||
Tst_WriteParamEditQst ();
|
Tst_WriteParamEditQst ();
|
||||||
Par_PutHiddenParamLong ("QstCod",QstCod);
|
Par_PutHiddenParamLong ("QstCod",Gbl.Test.QstCod);
|
||||||
if (NumRows == 1)
|
if (NumRows == 1)
|
||||||
Par_PutHiddenParamChar ("OnlyThisQst",'Y'); // If there are only one row, don't list again after removing
|
Par_PutHiddenParamChar ("OnlyThisQst",'Y'); // If there are only one row, don't list again after removing
|
||||||
Lay_PutIconRemove ();
|
Lay_PutIconRemove ();
|
||||||
|
@ -2726,7 +2729,7 @@ static void Tst_ListOneOrMoreQuestionsToEdit (unsigned long NumRows,MYSQL_RES *m
|
||||||
/* Write icon to edit the question */
|
/* Write icon to edit the question */
|
||||||
fprintf (Gbl.F.Out,"<td class=\"BT%u\">",Gbl.RowEvenOdd);
|
fprintf (Gbl.F.Out,"<td class=\"BT%u\">",Gbl.RowEvenOdd);
|
||||||
Act_FormStart (ActEdiOneTstQst);
|
Act_FormStart (ActEdiOneTstQst);
|
||||||
Par_PutHiddenParamLong ("QstCod",QstCod);
|
Par_PutHiddenParamLong ("QstCod",Gbl.Test.QstCod);
|
||||||
fprintf (Gbl.F.Out,"<input type=\"image\" src=\"%s/edit64x64.png\""
|
fprintf (Gbl.F.Out,"<input type=\"image\" src=\"%s/edit64x64.png\""
|
||||||
" alt=\"%s\" title=\"%s\""
|
" alt=\"%s\" title=\"%s\""
|
||||||
" class=\"ICON20x20\" />",
|
" class=\"ICON20x20\" />",
|
||||||
|
@ -2746,7 +2749,7 @@ static void Tst_ListOneOrMoreQuestionsToEdit (unsigned long NumRows,MYSQL_RES *m
|
||||||
fprintf (Gbl.F.Out,"<td class=\"DAT_SMALL CENTER_TOP COLOR%u\">"
|
fprintf (Gbl.F.Out,"<td class=\"DAT_SMALL CENTER_TOP COLOR%u\">"
|
||||||
"%ld "
|
"%ld "
|
||||||
"</td>",
|
"</td>",
|
||||||
Gbl.RowEvenOdd,QstCod);
|
Gbl.RowEvenOdd,Gbl.Test.QstCod);
|
||||||
|
|
||||||
/* Write the date (row[1] has the UTC date-time) */
|
/* Write the date (row[1] has the UTC date-time) */
|
||||||
TimeUTC = Dat_GetUNIXTimeFromStr (row[1]);
|
TimeUTC = Dat_GetUNIXTimeFromStr (row[1]);
|
||||||
|
@ -2762,7 +2765,7 @@ static void Tst_ListOneOrMoreQuestionsToEdit (unsigned long NumRows,MYSQL_RES *m
|
||||||
/* Write the question tags */
|
/* Write the question tags */
|
||||||
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP COLOR%u\">",
|
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP COLOR%u\">",
|
||||||
Gbl.RowEvenOdd);
|
Gbl.RowEvenOdd);
|
||||||
Tst_GetAndWriteTagsQst (QstCod);
|
Tst_GetAndWriteTagsQst (Gbl.Test.QstCod);
|
||||||
fprintf (Gbl.F.Out,"</td>");
|
fprintf (Gbl.F.Out,"</td>");
|
||||||
|
|
||||||
/* Write the question type (row[2]) */
|
/* Write the question type (row[2]) */
|
||||||
|
@ -2780,7 +2783,7 @@ static void Tst_ListOneOrMoreQuestionsToEdit (unsigned long NumRows,MYSQL_RES *m
|
||||||
Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
||||||
{
|
{
|
||||||
Act_FormStart (ActShfTstQst);
|
Act_FormStart (ActShfTstQst);
|
||||||
Par_PutHiddenParamLong ("QstCod",QstCod);
|
Par_PutHiddenParamLong ("QstCod",Gbl.Test.QstCod);
|
||||||
Sta_WriteParamsDatesSeeAccesses ();
|
Sta_WriteParamsDatesSeeAccesses ();
|
||||||
Tst_WriteParamEditQst ();
|
Tst_WriteParamEditQst ();
|
||||||
if (NumRows == 1)
|
if (NumRows == 1)
|
||||||
|
@ -2800,20 +2803,12 @@ static void Tst_ListOneOrMoreQuestionsToEdit (unsigned long NumRows,MYSQL_RES *m
|
||||||
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP COLOR%u\">",
|
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP COLOR%u\">",
|
||||||
Gbl.RowEvenOdd);
|
Gbl.RowEvenOdd);
|
||||||
Tst_WriteQstStem (row[4],"TEST_EDI");
|
Tst_WriteQstStem (row[4],"TEST_EDI");
|
||||||
if (row[6][0])
|
Img_GetImageNameAndTitleFromRow (row[6],row[7],&Gbl.Test.Image);
|
||||||
{
|
Img_ShowImage (&Gbl.Test.Image,"TEST_IMG_EDIT_LIST_STEM");
|
||||||
Gbl.Test.Image.Status = Img_NAME_STORED_IN_DB;
|
|
||||||
Img_GetImageNameAndTitle (row[6],row[7],&Gbl.Test.Image);
|
|
||||||
Img_ShowImage (&Gbl.Test.Image,"TEST_IMG_EDIT_LIST_STEM");
|
|
||||||
}
|
|
||||||
Tst_WriteQstFeedback (row[5],"TEST_EDI_LIGHT");
|
Tst_WriteQstFeedback (row[5],"TEST_EDI_LIGHT");
|
||||||
Tst_WriteAnswersOfAQstEdit (QstCod);
|
Tst_WriteAnswersOfAQstEdit (Gbl.Test.QstCod);
|
||||||
fprintf (Gbl.F.Out,"</td>");
|
fprintf (Gbl.F.Out,"</td>");
|
||||||
|
|
||||||
/* Free answers and images of this test question */
|
|
||||||
Tst_FreeTextChoiceAnswers ();
|
|
||||||
Tst_FreeImagesOfQuestion ();
|
|
||||||
|
|
||||||
/* Get number of hits
|
/* Get number of hits
|
||||||
(number of times that the question has been answered,
|
(number of times that the question has been answered,
|
||||||
including blank answers) (row[8]) */
|
including blank answers) (row[8]) */
|
||||||
|
@ -2865,6 +2860,9 @@ static void Tst_ListOneOrMoreQuestionsToEdit (unsigned long NumRows,MYSQL_RES *m
|
||||||
fprintf (Gbl.F.Out,"N.A.");
|
fprintf (Gbl.F.Out,"N.A.");
|
||||||
fprintf (Gbl.F.Out,"</td>"
|
fprintf (Gbl.F.Out,"</td>"
|
||||||
"</tr>");
|
"</tr>");
|
||||||
|
|
||||||
|
/***** Destroy test question *****/
|
||||||
|
Tst_QstDestructor ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** End table *****/
|
/***** End table *****/
|
||||||
|
@ -2901,7 +2899,7 @@ void Tst_WriteParamEditQst (void)
|
||||||
|
|
||||||
unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle)
|
unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle)
|
||||||
{
|
{
|
||||||
char Query[256];
|
char Query[512];
|
||||||
unsigned long NumRows;
|
unsigned long NumRows;
|
||||||
|
|
||||||
/***** Get answers of a question from database *****/
|
/***** Get answers of a question from database *****/
|
||||||
|
@ -2911,7 +2909,7 @@ unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle)
|
||||||
Shuffle ? "RAND(NOW())" :
|
Shuffle ? "RAND(NOW())" :
|
||||||
"AnsInd");
|
"AnsInd");
|
||||||
if (!(NumRows = DB_QuerySELECT (Query,mysql_res,"can not get answers of a question")))
|
if (!(NumRows = DB_QuerySELECT (Query,mysql_res,"can not get answers of a question")))
|
||||||
Lay_ShowErrorAndExit ("Error when getting answers of a question.");
|
Lay_ShowAlert (Lay_ERROR,"Error when getting answers of a question.");
|
||||||
|
|
||||||
return (unsigned) NumRows;
|
return (unsigned) NumRows;
|
||||||
}
|
}
|
||||||
|
@ -3007,11 +3005,7 @@ static void Tst_WriteAnswersOfAQstEdit (long QstCod)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy image */
|
/* Copy image */
|
||||||
if (row[3][0])
|
Img_GetImageNameAndTitleFromRow (row[3],row[4],&Gbl.Test.Answer.Options[NumOpt].Image);
|
||||||
{
|
|
||||||
Gbl.Test.Answer.Options[NumOpt].Image.Status = Img_NAME_STORED_IN_DB;
|
|
||||||
Img_GetImageNameAndTitle (row[3],row[4],&Gbl.Test.Answer.Options[NumOpt].Image);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Put an icon that indicates whether the answer is correct or wrong */
|
/* Put an icon that indicates whether the answer is correct or wrong */
|
||||||
fprintf (Gbl.F.Out,"<tr>"
|
fprintf (Gbl.F.Out,"<tr>"
|
||||||
|
@ -3037,8 +3031,7 @@ static void Tst_WriteAnswersOfAQstEdit (long QstCod)
|
||||||
"<div class=\"TEST_EDI\">"
|
"<div class=\"TEST_EDI\">"
|
||||||
"%s",
|
"%s",
|
||||||
Answer);
|
Answer);
|
||||||
if (Gbl.Test.Answer.Options[NumOpt].Image.Name[0])
|
Img_ShowImage (&Gbl.Test.Answer.Options[NumOpt].Image,"TEST_IMG_EDIT_LIST_ANS");
|
||||||
Img_ShowImage (&Gbl.Test.Answer.Options[NumOpt].Image,"TEST_IMG_EDIT_LIST_ANS");
|
|
||||||
fprintf (Gbl.F.Out,"</div>");
|
fprintf (Gbl.F.Out,"</div>");
|
||||||
|
|
||||||
/* Write the text of the feedback */
|
/* Write the text of the feedback */
|
||||||
|
@ -3106,6 +3099,10 @@ static void Tst_WriteAnswersOfAQstAssessExam (unsigned NumQst,long QstCod,
|
||||||
{
|
{
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
|
|
||||||
|
/***** Create test question *****/
|
||||||
|
Tst_QstConstructor ();
|
||||||
|
Gbl.Test.QstCod = QstCod;
|
||||||
|
|
||||||
/***** Get answers of a question from database *****/
|
/***** Get answers of a question from database *****/
|
||||||
Gbl.Test.Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,false); // Result: AnsInd,Answer,Correct
|
Gbl.Test.Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,false); // Result: AnsInd,Answer,Correct
|
||||||
/*
|
/*
|
||||||
|
@ -3141,6 +3138,9 @@ static void Tst_WriteAnswersOfAQstAssessExam (unsigned NumQst,long QstCod,
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
/***** Free structure that stores the query result *****/
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
|
||||||
|
/***** Destroy test question *****/
|
||||||
|
Tst_QstDestructor ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -3281,8 +3281,9 @@ static void Tst_WriteChoiceAnsSeeExam (unsigned NumQst,long QstCod,bool Shuffle)
|
||||||
bool ErrorInIndex = false;
|
bool ErrorInIndex = false;
|
||||||
char ParamName[3+6+1];
|
char ParamName[3+6+1];
|
||||||
|
|
||||||
/***** Start of table *****/
|
/***** Create test question *****/
|
||||||
fprintf (Gbl.F.Out,"<table class=\"CELLS_PAD_2\">");
|
Tst_QstConstructor ();
|
||||||
|
Gbl.Test.QstCod = QstCod;
|
||||||
|
|
||||||
/***** Get answers of a question from database *****/
|
/***** Get answers of a question from database *****/
|
||||||
Gbl.Test.Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,Shuffle); // Result: AnsInd,Answer,Correct
|
Gbl.Test.Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,Shuffle); // Result: AnsInd,Answer,Correct
|
||||||
|
@ -3294,6 +3295,10 @@ static void Tst_WriteChoiceAnsSeeExam (unsigned NumQst,long QstCod,bool Shuffle)
|
||||||
row[ 4] ImageTitle
|
row[ 4] ImageTitle
|
||||||
row[ 5] Correct
|
row[ 5] Correct
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/***** Start of table *****/
|
||||||
|
fprintf (Gbl.F.Out,"<table class=\"CELLS_PAD_2\">");
|
||||||
|
|
||||||
for (NumOpt = 0;
|
for (NumOpt = 0;
|
||||||
NumOpt < Gbl.Test.Answer.NumOptions;
|
NumOpt < Gbl.Test.Answer.NumOptions;
|
||||||
NumOpt++)
|
NumOpt++)
|
||||||
|
@ -3324,11 +3329,7 @@ static void Tst_WriteChoiceAnsSeeExam (unsigned NumQst,long QstCod,bool Shuffle)
|
||||||
Gbl.Test.Answer.Options[NumOpt].Text,Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
Gbl.Test.Answer.Options[NumOpt].Text,Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||||
|
|
||||||
/***** Copy image *****/
|
/***** Copy image *****/
|
||||||
if (row[3][0])
|
Img_GetImageNameAndTitleFromRow (row[3],row[4],&Gbl.Test.Answer.Options[NumOpt].Image);
|
||||||
{
|
|
||||||
Gbl.Test.Answer.Options[NumOpt].Image.Status = Img_NAME_STORED_IN_DB;
|
|
||||||
Img_GetImageNameAndTitle (row[3],row[4],&Gbl.Test.Answer.Options[NumOpt].Image);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** Write selectors and letter of this option *****/
|
/***** Write selectors and letter of this option *****/
|
||||||
fprintf (Gbl.F.Out,"<tr>"
|
fprintf (Gbl.F.Out,"<tr>"
|
||||||
|
@ -3351,8 +3352,7 @@ static void Tst_WriteChoiceAnsSeeExam (unsigned NumQst,long QstCod,bool Shuffle)
|
||||||
fprintf (Gbl.F.Out,"<td class=\"TEST_EXA LEFT_TOP\">"
|
fprintf (Gbl.F.Out,"<td class=\"TEST_EXA LEFT_TOP\">"
|
||||||
"%s",
|
"%s",
|
||||||
Gbl.Test.Answer.Options[NumOpt].Text);
|
Gbl.Test.Answer.Options[NumOpt].Text);
|
||||||
if (Gbl.Test.Answer.Options[NumOpt].Image.Name[0])
|
Img_ShowImage (&Gbl.Test.Answer.Options[NumOpt].Image,"TEST_IMG_SHOW_ANS");
|
||||||
Img_ShowImage (&Gbl.Test.Answer.Options[NumOpt].Image,"TEST_IMG_SHOW_ANS");
|
|
||||||
fprintf (Gbl.F.Out,"</td>"
|
fprintf (Gbl.F.Out,"</td>"
|
||||||
"</tr>");
|
"</tr>");
|
||||||
}
|
}
|
||||||
|
@ -3360,12 +3360,11 @@ static void Tst_WriteChoiceAnsSeeExam (unsigned NumQst,long QstCod,bool Shuffle)
|
||||||
/***** End of table *****/
|
/***** End of table *****/
|
||||||
fprintf (Gbl.F.Out,"</table>");
|
fprintf (Gbl.F.Out,"</table>");
|
||||||
|
|
||||||
/***** Free answers and images of this test question *****/
|
|
||||||
Tst_FreeTextChoiceAnswers ();
|
|
||||||
Tst_FreeImagesOfQuestion ();
|
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
/***** Free structure that stores the query result *****/
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
|
||||||
|
/***** Destroy test question *****/
|
||||||
|
Tst_QstDestructor ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -3430,11 +3429,7 @@ static void Tst_WriteChoiceAnsAssessExam (unsigned NumQst,MYSQL_RES *mysql_res,
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Copy image *****/
|
/***** Copy image *****/
|
||||||
if (row[3][0])
|
Img_GetImageNameAndTitleFromRow (row[3],row[4],&Gbl.Test.Answer.Options[NumOpt].Image);
|
||||||
{
|
|
||||||
Gbl.Test.Answer.Options[NumOpt].Image.Status = Img_NAME_STORED_IN_DB;
|
|
||||||
Img_GetImageNameAndTitle (row[3],row[4],&Gbl.Test.Answer.Options[NumOpt].Image);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** Assign correctness (row[5]) of this answer (this option) *****/
|
/***** Assign correctness (row[5]) of this answer (this option) *****/
|
||||||
Gbl.Test.Answer.Options[NumOpt].Correct = (Str_ConvertToUpperLetter (row[5][0]) == 'Y');
|
Gbl.Test.Answer.Options[NumOpt].Correct = (Str_ConvertToUpperLetter (row[5][0]) == 'Y');
|
||||||
|
@ -3526,8 +3521,7 @@ static void Tst_WriteChoiceAnsAssessExam (unsigned NumQst,MYSQL_RES *mysql_res,
|
||||||
"<div class=\"TEST_EXA\">"
|
"<div class=\"TEST_EXA\">"
|
||||||
"%s",
|
"%s",
|
||||||
Gbl.Test.Answer.Options[Indexes[NumOpt]].Text);
|
Gbl.Test.Answer.Options[Indexes[NumOpt]].Text);
|
||||||
if (Gbl.Test.Answer.Options[Indexes[NumOpt]].Image.Name[0])
|
Img_ShowImage (&Gbl.Test.Answer.Options[Indexes[NumOpt]].Image,"TEST_IMG_SHOW_ANS");
|
||||||
Img_ShowImage (&Gbl.Test.Answer.Options[Indexes[NumOpt]].Image,"TEST_IMG_SHOW_ANS");
|
|
||||||
fprintf (Gbl.F.Out,"</div>");
|
fprintf (Gbl.F.Out,"</div>");
|
||||||
if (Gbl.Test.Config.FeedbackType == Tst_FEEDBACK_FULL_FEEDBACK)
|
if (Gbl.Test.Config.FeedbackType == Tst_FEEDBACK_FULL_FEEDBACK)
|
||||||
if (Gbl.Test.Answer.Options[Indexes[NumOpt]].Feedback)
|
if (Gbl.Test.Answer.Options[Indexes[NumOpt]].Feedback)
|
||||||
|
@ -3606,10 +3600,6 @@ static void Tst_WriteChoiceAnsAssessExam (unsigned NumQst,MYSQL_RES *mysql_res,
|
||||||
|
|
||||||
/***** End of table *****/
|
/***** End of table *****/
|
||||||
fprintf (Gbl.F.Out,"</table>");
|
fprintf (Gbl.F.Out,"</table>");
|
||||||
|
|
||||||
/***** Free answers and images of this test question *****/
|
|
||||||
Tst_FreeTextChoiceAnswers ();
|
|
||||||
Tst_FreeImagesOfQuestion ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -3791,9 +3781,6 @@ static void Tst_WriteTextAnsAssessExam (unsigned NumQst,MYSQL_RES *mysql_res,
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (Gbl.F.Out,"</table>");
|
fprintf (Gbl.F.Out,"</table>");
|
||||||
|
|
||||||
/***** Free answers *****/
|
|
||||||
Tst_FreeTextChoiceAnswers ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -4351,8 +4338,18 @@ void Tst_ShowFormEditOneQst (void)
|
||||||
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 *****/
|
||||||
|
Tst_QstConstructor ();
|
||||||
|
Gbl.Test.QstCod = Tst_GetQstCod ();
|
||||||
Stem[0] = Feedback[0] = '\0';
|
Stem[0] = Feedback[0] = '\0';
|
||||||
|
if (Gbl.Test.QstCod > 0) // If question already exists in the database
|
||||||
|
Tst_GetQstDataFromDB (Stem,Feedback);
|
||||||
|
|
||||||
|
/***** Put form to edit question *****/
|
||||||
Tst_PutFormEditOneQst (Stem,Feedback);
|
Tst_PutFormEditOneQst (Stem,Feedback);
|
||||||
|
|
||||||
|
/***** Destroy test question *****/
|
||||||
|
Tst_QstDestructor ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -4398,16 +4395,6 @@ static void Tst_PutFormEditOneQst (char *Stem,char *Feedback)
|
||||||
char ParamFile[32];
|
char ParamFile[32];
|
||||||
char ParamTitle[32];
|
char ParamTitle[32];
|
||||||
|
|
||||||
/***** If no receiving the question, but editing a new or existing question
|
|
||||||
==> init or edit data of question *****/
|
|
||||||
if (Gbl.Action.Act == ActEdiOneTstQst)
|
|
||||||
{
|
|
||||||
Tst_InitQst ();
|
|
||||||
if (Tst_GetQstCod ()) // If parameter QstCod received ==>
|
|
||||||
// ==> question already exists in the database
|
|
||||||
Tst_GetQstDataFromDB (Stem,Feedback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** Start frame *****/
|
/***** Start frame *****/
|
||||||
if (Gbl.Test.QstCod > 0) // The question already has assigned a code
|
if (Gbl.Test.QstCod > 0) // The question already has assigned a code
|
||||||
{
|
{
|
||||||
|
@ -4737,21 +4724,18 @@ static void Tst_PutFormEditOneQst (char *Stem,char *Feedback)
|
||||||
|
|
||||||
/***** End frame *****/
|
/***** End frame *****/
|
||||||
Lay_EndRoundFrame ();
|
Lay_EndRoundFrame ();
|
||||||
|
|
||||||
/***** Free memory for answers *****/
|
|
||||||
Tst_FreeTextChoiceAnswers ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/********************* Initialize a new question to zero *********************/
|
/********************* Initialize a new question to zero *********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Tst_InitQst (void)
|
void Tst_QstConstructor (void)
|
||||||
{
|
{
|
||||||
unsigned NumOpt;
|
unsigned NumOpt;
|
||||||
unsigned NumTag;
|
unsigned NumTag;
|
||||||
|
|
||||||
Gbl.Test.QstCod = -1;
|
Gbl.Test.QstCod = -1L;
|
||||||
for (NumTag = 0;
|
for (NumTag = 0;
|
||||||
NumTag < Tst_MAX_TAGS_PER_QUESTION;
|
NumTag < Tst_MAX_TAGS_PER_QUESTION;
|
||||||
NumTag++)
|
NumTag++)
|
||||||
|
@ -4781,6 +4765,74 @@ void Tst_InitQst (void)
|
||||||
Tst_InitImagesOfQuestion ();
|
Tst_InitImagesOfQuestion ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/***************** Free memory allocated for test question *******************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void Tst_QstDestructor (void)
|
||||||
|
{
|
||||||
|
Tst_FreeTextChoiceAnswers ();
|
||||||
|
Tst_FreeImagesOfQuestion ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/******************* Allocate memory for a choice answer *********************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
int Tst_AllocateTextChoiceAnswer (unsigned NumOpt)
|
||||||
|
{
|
||||||
|
Tst_FreeTextChoiceAnswer (NumOpt);
|
||||||
|
|
||||||
|
if ((Gbl.Test.Answer.Options[NumOpt].Text =
|
||||||
|
malloc (Tst_MAX_BYTES_ANSWER_OR_FEEDBACK + 1)) == NULL)
|
||||||
|
{
|
||||||
|
sprintf (Gbl.Message,"Not enough memory to store answer.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((Gbl.Test.Answer.Options[NumOpt].Feedback =
|
||||||
|
malloc (Tst_MAX_BYTES_ANSWER_OR_FEEDBACK + 1)) == NULL)
|
||||||
|
{
|
||||||
|
sprintf (Gbl.Message,"Not enough memory to store feedback.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Gbl.Test.Answer.Options[NumOpt].Text[0] =
|
||||||
|
Gbl.Test.Answer.Options[NumOpt].Feedback[0] = '\0';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/******************** Free memory of all choice answers **********************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void Tst_FreeTextChoiceAnswers (void)
|
||||||
|
{
|
||||||
|
unsigned NumOpt;
|
||||||
|
|
||||||
|
for (NumOpt = 0;
|
||||||
|
NumOpt < Tst_MAX_OPTIONS_PER_QUESTION;
|
||||||
|
NumOpt++)
|
||||||
|
Tst_FreeTextChoiceAnswer (NumOpt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/********************** Free memory of a choice answer ***********************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void Tst_FreeTextChoiceAnswer (unsigned NumOpt)
|
||||||
|
{
|
||||||
|
if (Gbl.Test.Answer.Options[NumOpt].Text)
|
||||||
|
{
|
||||||
|
free ((void *) Gbl.Test.Answer.Options[NumOpt].Text);
|
||||||
|
Gbl.Test.Answer.Options[NumOpt].Text = NULL;
|
||||||
|
}
|
||||||
|
if (Gbl.Test.Answer.Options[NumOpt].Feedback)
|
||||||
|
{
|
||||||
|
free ((void *) Gbl.Test.Answer.Options[NumOpt].Feedback);
|
||||||
|
Gbl.Test.Answer.Options[NumOpt].Feedback = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/***************** Initialize images of a question to zero *******************/
|
/***************** Initialize images of a question to zero *******************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -4812,11 +4864,11 @@ static void Tst_FreeImagesOfQuestion (void)
|
||||||
{
|
{
|
||||||
unsigned NumOpt;
|
unsigned NumOpt;
|
||||||
|
|
||||||
Img_ResetImageTitle (&Gbl.Test.Image);
|
Img_FreeImageTitle (&Gbl.Test.Image);
|
||||||
for (NumOpt = 0;
|
for (NumOpt = 0;
|
||||||
NumOpt < Tst_MAX_OPTIONS_PER_QUESTION;
|
NumOpt < Tst_MAX_OPTIONS_PER_QUESTION;
|
||||||
NumOpt++)
|
NumOpt++)
|
||||||
Img_ResetImageTitle (&Gbl.Test.Answer.Options[NumOpt].Image);
|
Img_FreeImageTitle (&Gbl.Test.Answer.Options[NumOpt].Image);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -4869,13 +4921,7 @@ static void Tst_GetQstDataFromDB (char *Stem,char *Feedback)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the image name of the question from the database (row[4]) */
|
/* Get the image name of the question from the database (row[4]) */
|
||||||
if (row[4][0])
|
Img_GetImageNameAndTitleFromRow (row[4],row[5],&Gbl.Test.Image);
|
||||||
{
|
|
||||||
Gbl.Test.Image.Status = Img_NAME_STORED_IN_DB;
|
|
||||||
Img_GetImageNameAndTitle (row[4],row[5],&Gbl.Test.Image);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Gbl.Test.Image.Status = Img_FILE_NONE;
|
|
||||||
|
|
||||||
/* Free structure that stores the query result */
|
/* Free structure that stores the query result */
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
@ -4946,11 +4992,7 @@ static void Tst_GetQstDataFromDB (char *Stem,char *Feedback)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy image */
|
/* Copy image */
|
||||||
if (row[3][0])
|
Img_GetImageNameAndTitleFromRow (row[3],row[4],&Gbl.Test.Answer.Options[NumOpt].Image);
|
||||||
{
|
|
||||||
Gbl.Test.Answer.Options[NumOpt].Image.Status = Img_NAME_STORED_IN_DB;
|
|
||||||
Img_GetImageNameAndTitle (row[3],row[4],&Gbl.Test.Answer.Options[NumOpt].Image);
|
|
||||||
}
|
|
||||||
|
|
||||||
Gbl.Test.Answer.Options[NumOpt].Correct = (Str_ConvertToUpperLetter (row[5][0]) == 'Y');
|
Gbl.Test.Answer.Options[NumOpt].Correct = (Str_ConvertToUpperLetter (row[5][0]) == 'Y');
|
||||||
break;
|
break;
|
||||||
|
@ -4991,7 +5033,7 @@ static void Tst_GetImageFromDB (unsigned NumOpt,struct Image *Image)
|
||||||
row = mysql_fetch_row (mysql_res);
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
|
||||||
/***** Get the image name (row[0]) *****/
|
/***** Get the image name (row[0]) *****/
|
||||||
Img_GetImageNameAndTitle (row[0],row[1],Image);
|
Img_GetImageNameAndTitleFromRow (row[0],row[1],Image);
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
/***** Free structure that stores the query result *****/
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
@ -5040,11 +5082,11 @@ void Tst_ReceiveQst (void)
|
||||||
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];
|
||||||
|
|
||||||
/***** Initialize new question to zero *****/
|
/***** Create test question *****/
|
||||||
Tst_InitQst ();
|
Tst_QstConstructor ();
|
||||||
Stem[0] = Feedback[0] = '\0';
|
|
||||||
|
|
||||||
/***** Get parameters of the question from form *****/
|
/***** Get parameters of the question from form *****/
|
||||||
|
Stem[0] = Feedback[0] = '\0';
|
||||||
Tst_GetQstFromForm (Stem,Feedback);
|
Tst_GetQstFromForm (Stem,Feedback);
|
||||||
|
|
||||||
/***** Make sure that tags, text and answer are not empty *****/
|
/***** Make sure that tags, text and answer are not empty *****/
|
||||||
|
@ -5068,8 +5110,8 @@ void Tst_ReceiveQst (void)
|
||||||
Tst_PutFormEditOneQst (Stem,Feedback);
|
Tst_PutFormEditOneQst (Stem,Feedback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Free answers *****/
|
/***** Destroy test question *****/
|
||||||
Tst_FreeTextChoiceAnswers ();
|
Tst_QstDestructor ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -5094,7 +5136,7 @@ static void Tst_GetQstFromForm (char *Stem,char *Feedback)
|
||||||
char ParamTitle[32];
|
char ParamTitle[32];
|
||||||
|
|
||||||
/***** Get question code *****/
|
/***** Get question code *****/
|
||||||
Tst_GetQstCod ();
|
Gbl.Test.QstCod = Tst_GetQstCod ();
|
||||||
|
|
||||||
/***** Get answer type *****/
|
/***** Get answer type *****/
|
||||||
Par_GetParToText ("AnswerType",UnsignedStr,10);
|
Par_GetParToText ("AnswerType",UnsignedStr,10);
|
||||||
|
@ -5645,7 +5687,8 @@ void Tst_RequestRemoveQst (void)
|
||||||
|
|
||||||
/***** Get main parameters from form *****/
|
/***** Get main parameters from form *****/
|
||||||
/* Get the question code */
|
/* Get the question code */
|
||||||
if (!Tst_GetQstCod ())
|
Gbl.Test.QstCod = Tst_GetQstCod ();
|
||||||
|
if (Gbl.Test.QstCod <= 0)
|
||||||
Lay_ShowErrorAndExit ("Wrong code of question.");
|
Lay_ShowErrorAndExit ("Wrong code of question.");
|
||||||
|
|
||||||
/* Get a parameter that indicates whether it's necessary
|
/* Get a parameter that indicates whether it's necessary
|
||||||
|
@ -5697,7 +5740,8 @@ void Tst_RemoveQst (void)
|
||||||
bool EditingOnlyThisQst;
|
bool EditingOnlyThisQst;
|
||||||
|
|
||||||
/***** Get the question code *****/
|
/***** Get the question code *****/
|
||||||
if (!Tst_GetQstCod ())
|
Gbl.Test.QstCod = Tst_GetQstCod ();
|
||||||
|
if (Gbl.Test.QstCod <= 0)
|
||||||
Lay_ShowErrorAndExit ("Wrong code of question.");
|
Lay_ShowErrorAndExit ("Wrong code of question.");
|
||||||
|
|
||||||
/***** Get a parameter that indicates whether it's necessary
|
/***** Get a parameter that indicates whether it's necessary
|
||||||
|
@ -5749,7 +5793,8 @@ void Tst_ChangeShuffleQst (void)
|
||||||
bool Shuffle;
|
bool Shuffle;
|
||||||
|
|
||||||
/***** Get the question code *****/
|
/***** Get the question code *****/
|
||||||
if (!Tst_GetQstCod ())
|
Gbl.Test.QstCod = Tst_GetQstCod ();
|
||||||
|
if (Gbl.Test.QstCod <= 0)
|
||||||
Lay_ShowErrorAndExit ("Wrong code of question.");
|
Lay_ShowErrorAndExit ("Wrong code of question.");
|
||||||
|
|
||||||
/***** Get a parameter that indicates whether it's necessary to continue listing the rest of questions ******/
|
/***** Get a parameter that indicates whether it's necessary to continue listing the rest of questions ******/
|
||||||
|
@ -5787,14 +5832,12 @@ void Tst_ChangeShuffleQst (void)
|
||||||
/************ Get the parameter with the code of a test question *************/
|
/************ Get the parameter with the code of a test question *************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static bool Tst_GetQstCod (void)
|
static long Tst_GetQstCod (void)
|
||||||
{
|
{
|
||||||
char LongStr[1+10+1];
|
char LongStr[1+10+1];
|
||||||
|
|
||||||
Par_GetParToText ("QstCod",LongStr,1+10);
|
Par_GetParToText ("QstCod",LongStr,1+10);
|
||||||
if ((Gbl.Test.QstCod = Str_ConvertStrCodToLongCod (LongStr)) < 0)
|
return Str_ConvertStrCodToLongCod (LongStr);
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -5825,9 +5868,10 @@ static void Tst_InsertOrUpdateQstIntoDB (void)
|
||||||
char *Query;
|
char *Query;
|
||||||
|
|
||||||
/***** Allocate space for query *****/
|
/***** Allocate space for query *****/
|
||||||
if ((Query = malloc (256 +
|
if ((Query = malloc (512 +
|
||||||
Gbl.Test.Stem.Length +
|
Gbl.Test.Stem.Length +
|
||||||
Gbl.Test.Feedback.Length)) == NULL)
|
Gbl.Test.Feedback.Length +
|
||||||
|
Img_MAX_BYTES_TITLE)) == NULL)
|
||||||
Lay_ShowErrorAndExit ("Not enough memory to store database query.");
|
Lay_ShowErrorAndExit ("Not enough memory to store database query.");
|
||||||
|
|
||||||
if (Gbl.Test.QstCod < 0) // It's a new question
|
if (Gbl.Test.QstCod < 0) // It's a new question
|
||||||
|
@ -6144,64 +6188,6 @@ static void Tst_RemoveImgFilesFromAnsOfQsts (long CrsCod,
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/******************* Allocate memory for a choice answer *********************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
int Tst_AllocateTextChoiceAnswer (unsigned NumOpt)
|
|
||||||
{
|
|
||||||
Tst_FreeTextChoiceAnswer (NumOpt);
|
|
||||||
|
|
||||||
if ((Gbl.Test.Answer.Options[NumOpt].Text =
|
|
||||||
malloc (Tst_MAX_BYTES_ANSWER_OR_FEEDBACK + 1)) == NULL)
|
|
||||||
{
|
|
||||||
sprintf (Gbl.Message,"Not enough memory to store answer.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if ((Gbl.Test.Answer.Options[NumOpt].Feedback =
|
|
||||||
malloc (Tst_MAX_BYTES_ANSWER_OR_FEEDBACK + 1)) == NULL)
|
|
||||||
{
|
|
||||||
sprintf (Gbl.Message,"Not enough memory to store feedback.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Gbl.Test.Answer.Options[NumOpt].Text[0] =
|
|
||||||
Gbl.Test.Answer.Options[NumOpt].Feedback[0] = '\0';
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/******************** Free memory of all choice answers **********************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
void Tst_FreeTextChoiceAnswers (void)
|
|
||||||
{
|
|
||||||
unsigned NumOpt;
|
|
||||||
|
|
||||||
for (NumOpt = 0;
|
|
||||||
NumOpt < Tst_MAX_OPTIONS_PER_QUESTION;
|
|
||||||
NumOpt++)
|
|
||||||
Tst_FreeTextChoiceAnswer (NumOpt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/********************** Free memory of a choice answer ***********************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
static void Tst_FreeTextChoiceAnswer (unsigned NumOpt)
|
|
||||||
{
|
|
||||||
if (Gbl.Test.Answer.Options[NumOpt].Text)
|
|
||||||
{
|
|
||||||
free ((void *) Gbl.Test.Answer.Options[NumOpt].Text);
|
|
||||||
Gbl.Test.Answer.Options[NumOpt].Text = NULL;
|
|
||||||
}
|
|
||||||
if (Gbl.Test.Answer.Options[NumOpt].Feedback)
|
|
||||||
{
|
|
||||||
free ((void *) Gbl.Test.Answer.Options[NumOpt].Feedback);
|
|
||||||
Gbl.Test.Answer.Options[NumOpt].Feedback = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*********************** Get stats about test questions **********************/
|
/*********************** Get stats about test questions **********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -141,7 +141,12 @@ void Tst_GetConfigFromRow (MYSQL_ROW row);
|
||||||
bool Tst_CheckIfCourseHaveTestsAndPluggableIsUnknown (void);
|
bool Tst_CheckIfCourseHaveTestsAndPluggableIsUnknown (void);
|
||||||
void Tst_ReceiveConfigTst (void);
|
void Tst_ReceiveConfigTst (void);
|
||||||
void Tst_ShowFormEditOneQst (void);
|
void Tst_ShowFormEditOneQst (void);
|
||||||
void Tst_InitQst (void);
|
|
||||||
|
void Tst_QstConstructor (void);
|
||||||
|
void Tst_QstDestructor (void);
|
||||||
|
|
||||||
|
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 (void);
|
||||||
|
@ -152,8 +157,6 @@ void Tst_RemoveQst (void);
|
||||||
void Tst_ChangeShuffleQst (void);
|
void Tst_ChangeShuffleQst (void);
|
||||||
void Tst_InsertOrUpdateQstTagsAnsIntoDB (void);
|
void Tst_InsertOrUpdateQstTagsAnsIntoDB (void);
|
||||||
|
|
||||||
int Tst_AllocateTextChoiceAnswer (unsigned NumOpt);
|
|
||||||
void Tst_FreeTextChoiceAnswers (void);
|
|
||||||
void Tst_FreeTagsList (void);
|
void Tst_FreeTagsList (void);
|
||||||
|
|
||||||
void Tst_GetTestStats (Tst_AnswerType_t AnsType,struct Tst_Stats *Stats);
|
void Tst_GetTestStats (Tst_AnswerType_t AnsType,struct Tst_Stats *Stats);
|
||||||
|
|
|
@ -533,8 +533,8 @@ static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer)
|
||||||
{
|
{
|
||||||
if (!strcmp (QuestionElem->TagName,"question"))
|
if (!strcmp (QuestionElem->TagName,"question"))
|
||||||
{
|
{
|
||||||
/***** Initialize new question to zero *****/
|
/***** Create test question *****/
|
||||||
Tst_InitQst ();
|
Tst_QstConstructor ();
|
||||||
|
|
||||||
/* Get type of questions (in mandatory attribute "type") */
|
/* Get type of questions (in mandatory attribute "type") */
|
||||||
AnswerTypeFound = false;
|
AnswerTypeFound = false;
|
||||||
|
@ -653,8 +653,8 @@ static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Free answers *****/
|
/***** Destroy test question *****/
|
||||||
Tst_FreeTextChoiceAnswers ();
|
Tst_QstDestructor ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user