mirror of https://github.com/acanas/swad-core.git
Version 15.183
This commit is contained in:
parent
dcd1dd8f53
commit
ed9d37dc91
|
@ -126,18 +126,24 @@
|
|||
// TODO: Do not show e-mails of administrators and teachers in lists openly
|
||||
// TODO: Fix bug in marks reported by Francisco Ocaña
|
||||
// TODO: In Statistics > Degrees, show only degrees with students
|
||||
// TODO: Change PhotoAttribution in table centres from TEXT to VARCHAR(255) (check maximum length first)
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************************** Public constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define Log_PLATFORM_VERSION "SWAD 15.182 (2016-04-06)"
|
||||
#define Log_PLATFORM_VERSION "SWAD 15.183 (2016-04-06)"
|
||||
#define CSS_FILE "swad15.178.2.css"
|
||||
#define JS_FILE "swad15.178.2.js"
|
||||
|
||||
// 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
|
||||
/*
|
||||
Version 15.183: Apr 06, 2016 Change in length of title/attribution of images. (198704 lines)
|
||||
2 changes necessary in database:
|
||||
ALTER TABLE tst_questions CHANGE COLUMN ImageTitle ImageTitle VARCHAR(255) NOT NULL;
|
||||
ALTER TABLE tst_answers CHANGE COLUMN ImageTitle ImageTitle VARCHAR(255) NOT NULL;
|
||||
|
||||
Version 15.182: Apr 06, 2016 Get fields title/attribution of images from form. (198610 lines)
|
||||
4 changes necessary in database:
|
||||
ALTER TABLE tst_questions CHANGE COLUMN Image ImageName VARCHAR(43) NOT NULL;
|
||||
|
|
|
@ -2298,10 +2298,10 @@ mysql> DESCRIBE tst_answers;
|
|||
| Answer | text | NO | | NULL | |
|
||||
| Feedback | text | NO | | NULL | |
|
||||
| ImageName | varchar(43) | NO | | NULL | |
|
||||
| ImageTitle | text | NO | | NULL | |
|
||||
| ImageTitle | varchar(255) | NO | | NULL | |
|
||||
| Correct | enum('N','Y') | NO | | NULL | |
|
||||
+------------+---------------+------+-----+---------+-------+
|
||||
7 rows in set (0.00 sec)
|
||||
7 rows in set (0.01 sec)
|
||||
*/
|
||||
DB_CreateTable ("CREATE TABLE IF NOT EXISTS tst_answers ("
|
||||
"QstCod INT NOT NULL,"
|
||||
|
@ -2309,7 +2309,7 @@ mysql> DESCRIBE tst_answers;
|
|||
"Answer TEXT NOT NULL,"
|
||||
"Feedback TEXT NOT NULL,"
|
||||
"ImageName VARCHAR(43) NOT NULL,"
|
||||
"ImageTitle TEXT NOT NULL,"
|
||||
"ImageTitle VARCHAR(255) NOT NULL,"
|
||||
"Correct ENUM('N','Y') NOT NULL,"
|
||||
"INDEX(QstCod))");
|
||||
|
||||
|
@ -2424,7 +2424,7 @@ mysql> DESCRIBE tst_questions;
|
|||
| Stem | text | NO | | NULL | |
|
||||
| Feedback | text | NO | | NULL | |
|
||||
| ImageName | varchar(43) | NO | | NULL | |
|
||||
| ImageTitle | text | NO | | NULL | |
|
||||
| ImageTitle | varchar(255) | NO | | NULL | |
|
||||
| NumHits | int(11) | NO | | 0 | |
|
||||
| NumHitsNotBlank | int(11) | NO | | 0 | |
|
||||
| Score | double | NO | | 0 | |
|
||||
|
@ -2440,7 +2440,7 @@ mysql> DESCRIBE tst_questions;
|
|||
"Stem TEXT NOT NULL,"
|
||||
"Feedback TEXT NOT NULL,"
|
||||
"ImageName VARCHAR(43) NOT NULL,"
|
||||
"ImageTitle TEXT NOT NULL,"
|
||||
"ImageTitle VARCHAR(255) NOT NULL,"
|
||||
"NumHits INT NOT NULL DEFAULT 0,"
|
||||
"NumHitsNotBlank INT NOT NULL DEFAULT 0,"
|
||||
"Score DOUBLE PRECISION NOT NULL DEFAULT 0,"
|
||||
|
|
22
swad_image.c
22
swad_image.c
|
@ -79,11 +79,11 @@ void Img_ResetImageTitle (struct Image *Image)
|
|||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************ Get image title from a string and copy to struct ***************/
|
||||
/********* Get image name and title from strings and copy to struct **********/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Img_GetImageNameTitle (const char *Name,const char *Title,
|
||||
struct Image *Image)
|
||||
void Img_GetImageNameAndTitle (const char *Name,const char *Title,
|
||||
struct Image *Image)
|
||||
{
|
||||
size_t Length;
|
||||
|
||||
|
@ -97,7 +97,11 @@ void Img_GetImageNameTitle (const char *Name,const char *Title,
|
|||
if (Image->Name[0]) // There is an image
|
||||
if (Title[0])
|
||||
{
|
||||
/* Get and limit length of the title */
|
||||
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);
|
||||
|
@ -195,7 +199,7 @@ void Img_GetAndProcessImageFileFromForm (struct Image *Image,
|
|||
char FileNameImgOrig[PATH_MAX+1]; // Full name of original uploaded file
|
||||
char FileNameImgTmp[PATH_MAX+1]; // Full name of temporary processed file
|
||||
bool WrongType = false;
|
||||
char Title[Cns_MAX_BYTES_TEXT+1];
|
||||
char Title[Img_MAX_BYTES_TITLE+1];
|
||||
size_t Length;
|
||||
|
||||
/***** Rest image file status *****/
|
||||
|
@ -263,7 +267,7 @@ void Img_GetAndProcessImageFileFromForm (struct Image *Image,
|
|||
unlink (FileNameImgOrig);
|
||||
|
||||
/***** Get image title from form *****/
|
||||
Par_GetParToHTML (ParamTitle,Title,Cns_MAX_BYTES_TEXT); // TODO: Create a function to get only the length of a parameter
|
||||
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)
|
||||
{
|
||||
|
@ -386,9 +390,13 @@ void Img_ShowImage (struct Image *Image,const char *ClassImg)
|
|||
|
||||
/***** Show image *****/
|
||||
fprintf (Gbl.F.Out,"<div>"
|
||||
"<img src=\"%s\" alt=\"\" class=\"%s\"/>"
|
||||
"</div>",
|
||||
"<img src=\"%s\" class=\"%s\" alt=\"\"",
|
||||
URL,ClassImg);
|
||||
if (Image->Title)
|
||||
if (Image->Title[0])
|
||||
fprintf (Gbl.F.Out," title=\"%s\"",Image->Title);
|
||||
fprintf (Gbl.F.Out," />"
|
||||
"</div>");
|
||||
}
|
||||
else
|
||||
Lay_ShowAlert (Lay_WARNING,Txt_Image_not_found);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
/***************************** Public constants ******************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define Img_MAX_BYTES_TITLE 255
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************* Public types ********************************/
|
||||
/*****************************************************************************/
|
||||
|
@ -93,8 +95,8 @@ struct Image
|
|||
/*****************************************************************************/
|
||||
|
||||
void Img_ResetImageTitle (struct Image *Image);
|
||||
void Img_GetImageNameTitle (const char *Name,const char *Title,
|
||||
struct Image *Image);
|
||||
void Img_GetImageNameAndTitle (const char *Name,const char *Title,
|
||||
struct Image *Image);
|
||||
|
||||
void Img_GetImageFromForm (unsigned NumOpt,struct Image *Image,
|
||||
void (*GetImageNameFromDB) (unsigned NumOpt,struct Image *Image),
|
||||
|
|
217
swad_test.c
217
swad_test.c
|
@ -155,8 +155,8 @@ static void Tst_ShowTestQuestionsWhenSeeing (MYSQL_RES *mysql_res);
|
|||
static void Tst_ShowTstResultAfterAssess (long TstCod,unsigned *NumQstsNotBlank,double *TotalScore);
|
||||
static void Tst_WriteQstAndAnsExam (unsigned NumQst,long QstCod,MYSQL_ROW row,
|
||||
double *ScoreThisQst,bool *AnswerIsNotBlank);
|
||||
static void Tst_PutFormToEditQstImage (struct Image *Image,const char *ClassImg,
|
||||
const char *TitleAttribution,const char *ClassTitle,
|
||||
static void Tst_PutFormToEditQstImage (struct Image *Image,
|
||||
const char *ClassImg,const char *ClassTitle,
|
||||
const char *ParamAction,
|
||||
const char *ParamFile,
|
||||
const char *ParamTitle,
|
||||
|
@ -1002,7 +1002,7 @@ static void Tst_WriteQstAndAnsExam (unsigned NumQst,long QstCod,MYSQL_ROW row,
|
|||
if (row[6][0])
|
||||
{
|
||||
Gbl.Test.Image.Status = Img_NAME_STORED_IN_DB;
|
||||
Img_GetImageNameTitle (row[6],row[7],&Gbl.Test.Image);
|
||||
Img_GetImageNameAndTitle (row[6],row[7],&Gbl.Test.Image);
|
||||
Img_ShowImage (&Gbl.Test.Image,"TEST_IMG_SHOW_STEM");
|
||||
}
|
||||
if (Gbl.Action.Act == ActSeeTst)
|
||||
|
@ -1053,8 +1053,8 @@ void Tst_WriteQstStem (const char *Stem,const char *ClassStem)
|
|||
/************* Put form to upload a new image for a test question ************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Tst_PutFormToEditQstImage (struct Image *Image,const char *ClassImg,
|
||||
const char *TitleAttribution,const char *ClassTitle,
|
||||
static void Tst_PutFormToEditQstImage (struct Image *Image,
|
||||
const char *ClassImg,const char *ClassTitle,
|
||||
const char *ParamAction,
|
||||
const char *ParamFile,
|
||||
const char *ParamTitle,
|
||||
|
@ -1147,14 +1147,12 @@ static void Tst_PutFormToEditQstImage (struct Image *Image,const char *ClassImg,
|
|||
fprintf (Gbl.F.Out,"<label class=\"%s\">"
|
||||
"%s (%s):"
|
||||
"</label><br />"
|
||||
"<textarea name=\"%s\" class=\"%s\" rows=\"1\">",
|
||||
"<input type=\"text\" name=\"%s\" class=\"%s\""
|
||||
" maxlength=\"%u\" value=\"%s\">",
|
||||
The_ClassForm[Gbl.Prefs.Theme],
|
||||
Txt_Image_title_attribution,Txt_optional,
|
||||
ParamTitle,ClassTitle);
|
||||
if (TitleAttribution)
|
||||
if (TitleAttribution[0])
|
||||
fprintf (Gbl.F.Out,"%s",TitleAttribution);
|
||||
fprintf (Gbl.F.Out,"</textarea>");
|
||||
ParamTitle,ClassTitle,
|
||||
Img_MAX_BYTES_TITLE,Image->Title ? Image->Title : "");
|
||||
|
||||
/***** End container *****/
|
||||
fprintf (Gbl.F.Out,"</div>");
|
||||
|
@ -2803,7 +2801,7 @@ static void Tst_ListOneOrMoreQuestionsToEdit (unsigned long NumRows,MYSQL_RES *m
|
|||
if (row[6][0])
|
||||
{
|
||||
Gbl.Test.Image.Status = Img_NAME_STORED_IN_DB;
|
||||
Img_GetImageNameTitle (row[6],row[7],&Gbl.Test.Image);
|
||||
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");
|
||||
|
@ -2901,13 +2899,12 @@ void Tst_WriteParamEditQst (void)
|
|||
|
||||
unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle)
|
||||
{
|
||||
char Query[512];
|
||||
char Query[256];
|
||||
unsigned long NumRows;
|
||||
|
||||
/***** Get answers of a question from database *****/
|
||||
sprintf (Query,"SELECT AnsInd,Answer,Correct,Feedback,ImageName,ImageTitle"
|
||||
" FROM tst_answers"
|
||||
" WHERE QstCod='%ld' ORDER BY %s",
|
||||
sprintf (Query,"SELECT AnsInd,Answer,Feedback,ImageName,ImageTitle,Correct"
|
||||
" FROM tst_answers WHERE QstCod='%ld' ORDER BY %s",
|
||||
QstCod,
|
||||
Shuffle ? "RAND(NOW())" :
|
||||
"AnsInd");
|
||||
|
@ -2935,7 +2932,14 @@ static void Tst_WriteAnswersOfAQstEdit (long QstCod)
|
|||
double FloatNum[2];
|
||||
|
||||
Gbl.Test.Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,false); // Result: AnsInd,Answer,Correct,Feedback
|
||||
|
||||
/*
|
||||
row[ 0] AnsInd
|
||||
row[ 1] Answer
|
||||
row[ 2] Feedback
|
||||
row[ 3] ImageName
|
||||
row[ 4] ImageTitle
|
||||
row[ 5] Correct
|
||||
*/
|
||||
/***** Write the answers *****/
|
||||
switch (Gbl.Test.AnswerType)
|
||||
{
|
||||
|
@ -2985,33 +2989,33 @@ static void Tst_WriteAnswersOfAQstEdit (long QstCod)
|
|||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
Answer,LengthAnswer,false);
|
||||
|
||||
/* Convert the feedback (row[3]), that is in HTML, to rigorous HTML */
|
||||
/* Convert the feedback (row[2]), that is in HTML, to rigorous HTML */
|
||||
LengthFeedback = 0;
|
||||
Feedback = NULL;
|
||||
if (row[3])
|
||||
if (row[3][0])
|
||||
if (row[2])
|
||||
if (row[2][0])
|
||||
{
|
||||
LengthFeedback = strlen (row[3]) * Str_MAX_LENGTH_SPEC_CHAR_HTML;
|
||||
LengthFeedback = strlen (row[2]) * Str_MAX_LENGTH_SPEC_CHAR_HTML;
|
||||
if ((Feedback = malloc (LengthFeedback+1)) == NULL)
|
||||
Lay_ShowErrorAndExit ("Not enough memory to store feedback.");
|
||||
strncpy (Feedback,row[3],LengthFeedback);
|
||||
strncpy (Feedback,row[2],LengthFeedback);
|
||||
Feedback[LengthFeedback] = '\0';
|
||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
Feedback,LengthFeedback,false);
|
||||
}
|
||||
|
||||
/* Copy image */
|
||||
if (row[4][0])
|
||||
if (row[3][0])
|
||||
{
|
||||
Gbl.Test.Answer.Options[NumOpt].Image.Status = Img_NAME_STORED_IN_DB;
|
||||
Img_GetImageNameTitle (row[4],row[5],&Gbl.Test.Answer.Options[NumOpt].Image);
|
||||
Img_GetImageNameAndTitle (row[3],row[4],&Gbl.Test.Answer.Options[NumOpt].Image);
|
||||
}
|
||||
|
||||
/* Put an icon that indicates whether the answer is correct or wrong */
|
||||
fprintf (Gbl.F.Out,"<tr>"
|
||||
"<td class=\"BT%u\">",
|
||||
Gbl.RowEvenOdd);
|
||||
if (Str_ConvertToUpperLetter (row[2][0]) == 'Y')
|
||||
if (Str_ConvertToUpperLetter (row[5][0]) == 'Y')
|
||||
fprintf (Gbl.F.Out,"<img src=\"%s/ok_on16x16.gif\""
|
||||
" alt=\"%s\" title=\"%s\""
|
||||
" class=\"ICON20x20\" />",
|
||||
|
@ -3026,7 +3030,7 @@ static void Tst_WriteAnswersOfAQstEdit (long QstCod)
|
|||
"</td>",
|
||||
'a' + (char) NumOpt);
|
||||
|
||||
/* Write the text of the answer and the image (row[4]) */
|
||||
/* Write the text of the answer and the image */
|
||||
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP\">"
|
||||
"<div class=\"TEST_EDI\">"
|
||||
"%s",
|
||||
|
@ -3102,7 +3106,14 @@ static void Tst_WriteAnswersOfAQstAssessExam (unsigned NumQst,long QstCod,
|
|||
|
||||
/***** Get answers of a question from database *****/
|
||||
Gbl.Test.Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,false); // Result: AnsInd,Answer,Correct
|
||||
|
||||
/*
|
||||
row[ 0] AnsInd
|
||||
row[ 1] Answer
|
||||
row[ 2] Feedback
|
||||
row[ 3] ImageName
|
||||
row[ 4] ImageTitle
|
||||
row[ 5] Correct
|
||||
*/
|
||||
/***** Write answer depending on type *****/
|
||||
switch (Gbl.Test.AnswerType)
|
||||
{
|
||||
|
@ -3180,7 +3191,14 @@ static void Tst_WriteTFAnsAssessExam (unsigned NumQst,MYSQL_RES *mysql_res,
|
|||
{
|
||||
MYSQL_ROW row;
|
||||
char AnsTF;
|
||||
|
||||
/*
|
||||
row[ 0] AnsInd
|
||||
row[ 1] Answer
|
||||
row[ 2] Feedback
|
||||
row[ 3] ImageName
|
||||
row[ 4] ImageTitle
|
||||
row[ 5] Correct
|
||||
*/
|
||||
/***** Check if number of rows is correct *****/
|
||||
Tst_CheckIfNumberOfAnswersIsOne ();
|
||||
|
||||
|
@ -3266,6 +3284,14 @@ static void Tst_WriteChoiceAnsSeeExam (unsigned NumQst,long QstCod,bool Shuffle)
|
|||
|
||||
/***** Get answers of a question from database *****/
|
||||
Gbl.Test.Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,Shuffle); // Result: AnsInd,Answer,Correct
|
||||
/*
|
||||
row[ 0] AnsInd
|
||||
row[ 1] Answer
|
||||
row[ 2] Feedback
|
||||
row[ 3] ImageName
|
||||
row[ 4] ImageTitle
|
||||
row[ 5] Correct
|
||||
*/
|
||||
for (NumOpt = 0;
|
||||
NumOpt < Gbl.Test.Answer.NumOptions;
|
||||
NumOpt++)
|
||||
|
@ -3296,10 +3322,10 @@ static void Tst_WriteChoiceAnsSeeExam (unsigned NumQst,long QstCod,bool Shuffle)
|
|||
Gbl.Test.Answer.Options[NumOpt].Text,Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||
|
||||
/***** Copy image *****/
|
||||
if (row[4][0])
|
||||
if (row[3][0])
|
||||
{
|
||||
Gbl.Test.Answer.Options[NumOpt].Image.Status = Img_NAME_STORED_IN_DB;
|
||||
Img_GetImageNameTitle (row[4],row[5],&Gbl.Test.Answer.Options[NumOpt].Image);
|
||||
Img_GetImageNameAndTitle (row[3],row[4],&Gbl.Test.Answer.Options[NumOpt].Image);
|
||||
}
|
||||
|
||||
/***** Write selectors and letter of this option *****/
|
||||
|
@ -3364,11 +3390,12 @@ static void Tst_WriteChoiceAnsAssessExam (unsigned NumQst,MYSQL_RES *mysql_res,
|
|||
/***** Get text and correctness of answers for this question
|
||||
from database (one row per answer) *****/
|
||||
/*
|
||||
row[0] AnsInd
|
||||
row[1] Answer
|
||||
row[2] Correct
|
||||
row[3] Feedback
|
||||
row[4] ImageName
|
||||
row[ 0] AnsInd
|
||||
row[ 1] Answer
|
||||
row[ 2] Feedback
|
||||
row[ 3] ImageName
|
||||
row[ 4] ImageTitle
|
||||
row[ 5] Correct
|
||||
*/
|
||||
for (NumOpt = 0;
|
||||
NumOpt < Gbl.Test.Answer.NumOptions;
|
||||
|
@ -3388,27 +3415,27 @@ static void Tst_WriteChoiceAnsAssessExam (unsigned NumQst,MYSQL_RES *mysql_res,
|
|||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
Gbl.Test.Answer.Options[NumOpt].Text,Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||
|
||||
/***** Copy answer feedback (row[3]) and convert it,
|
||||
/***** Copy answer feedback (row[2]) and convert it,
|
||||
that is in HTML, to rigorous HTML ******/
|
||||
if (Gbl.Test.Config.FeedbackType == Tst_FEEDBACK_FULL_FEEDBACK)
|
||||
if (row[3])
|
||||
if (row[3][0])
|
||||
if (row[2])
|
||||
if (row[2][0])
|
||||
{
|
||||
strncpy (Gbl.Test.Answer.Options[NumOpt].Feedback,row[3],Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
||||
strncpy (Gbl.Test.Answer.Options[NumOpt].Feedback,row[2],Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
||||
Gbl.Test.Answer.Options[NumOpt].Feedback[Tst_MAX_BYTES_ANSWER_OR_FEEDBACK] = '\0';
|
||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
Gbl.Test.Answer.Options[NumOpt].Feedback,Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||
}
|
||||
|
||||
/***** Copy image *****/
|
||||
if (row[4][0])
|
||||
if (row[3][0])
|
||||
{
|
||||
Gbl.Test.Answer.Options[NumOpt].Image.Status = Img_NAME_STORED_IN_DB;
|
||||
Img_GetImageNameTitle (row[4],row[5],&Gbl.Test.Answer.Options[NumOpt].Image);
|
||||
Img_GetImageNameAndTitle (row[3],row[4],&Gbl.Test.Answer.Options[NumOpt].Image);
|
||||
}
|
||||
|
||||
/***** Assign correctness (row[2]) of this answer (this option) *****/
|
||||
Gbl.Test.Answer.Options[NumOpt].Correct = (Str_ConvertToUpperLetter (row[2][0]) == 'Y');
|
||||
/***** Assign correctness (row[5]) of this answer (this option) *****/
|
||||
Gbl.Test.Answer.Options[NumOpt].Correct = (Str_ConvertToUpperLetter (row[5][0]) == 'Y');
|
||||
}
|
||||
|
||||
/***** Get indexes for this question from string *****/
|
||||
|
@ -3606,7 +3633,14 @@ static void Tst_WriteTextAnsAssessExam (unsigned NumQst,MYSQL_RES *mysql_res,
|
|||
MYSQL_ROW row;
|
||||
char TextAnsUsr[Tst_MAX_SIZE_ANSWERS_ONE_QST],TextAnsOK[Tst_MAX_SIZE_ANSWERS_ONE_QST];
|
||||
bool Correct = false;
|
||||
|
||||
/*
|
||||
row[ 0] AnsInd
|
||||
row[ 1] Answer
|
||||
row[ 2] Feedback
|
||||
row[ 3] ImageName
|
||||
row[ 4] ImageTitle
|
||||
row[ 5] Correct
|
||||
*/
|
||||
/***** Get text and correctness of answers for this question from database (one row per answer) *****/
|
||||
for (NumOpt = 0;
|
||||
NumOpt < Gbl.Test.Answer.NumOptions;
|
||||
|
@ -3624,19 +3658,19 @@ static void Tst_WriteTextAnsAssessExam (unsigned NumQst,MYSQL_RES *mysql_res,
|
|||
Gbl.Test.Answer.Options[NumOpt].Text[Tst_MAX_BYTES_ANSWER_OR_FEEDBACK] = '\0';
|
||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,Gbl.Test.Answer.Options[NumOpt].Text,Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||
|
||||
/***** Copy answer feedback (row[3]) and convert it, that is in HTML, to rigorous HTML ******/
|
||||
/***** Copy answer feedback (row[2]) and convert it, that is in HTML, to rigorous HTML ******/
|
||||
if (Gbl.Test.Config.FeedbackType == Tst_FEEDBACK_FULL_FEEDBACK)
|
||||
if (row[3])
|
||||
if (row[3][0])
|
||||
if (row[2])
|
||||
if (row[2][0])
|
||||
{
|
||||
strncpy (Gbl.Test.Answer.Options[NumOpt].Feedback,row[3],Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
||||
strncpy (Gbl.Test.Answer.Options[NumOpt].Feedback,row[2],Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
||||
Gbl.Test.Answer.Options[NumOpt].Feedback[Tst_MAX_BYTES_ANSWER_OR_FEEDBACK] = '\0';
|
||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||
Gbl.Test.Answer.Options[NumOpt].Feedback,Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
|
||||
}
|
||||
|
||||
/***** Assign correctness (row[2]) of this answer (this option) *****/
|
||||
Gbl.Test.Answer.Options[NumOpt].Correct = (Str_ConvertToUpperLetter (row[2][0]) == 'Y');
|
||||
/***** Assign correctness (row[5]) of this answer (this option) *****/
|
||||
Gbl.Test.Answer.Options[NumOpt].Correct = (Str_ConvertToUpperLetter (row[5][0]) == 'Y');
|
||||
}
|
||||
|
||||
/***** Header with the title of each column *****/
|
||||
|
@ -3781,7 +3815,14 @@ static void Tst_WriteIntAnsAssessExam (unsigned NumQst,MYSQL_RES *mysql_res,
|
|||
{
|
||||
MYSQL_ROW row;
|
||||
long IntAnswerUsr,IntAnswerCorr;
|
||||
|
||||
/*
|
||||
row[ 0] AnsInd
|
||||
row[ 1] Answer
|
||||
row[ 2] Feedback
|
||||
row[ 3] ImageName
|
||||
row[ 4] ImageTitle
|
||||
row[ 5] Correct
|
||||
*/
|
||||
/***** Check if number of rows is correct *****/
|
||||
Tst_CheckIfNumberOfAnswersIsOne ();
|
||||
|
||||
|
@ -3887,7 +3928,14 @@ static void Tst_WriteFloatAnsAssessExam (unsigned NumQst,MYSQL_RES *mysql_res,
|
|||
unsigned i;
|
||||
double FloatAnsUsr = 0.0,Tmp;
|
||||
double FloatAnsCorr[2];
|
||||
|
||||
/*
|
||||
row[ 0] AnsInd
|
||||
row[ 1] Answer
|
||||
row[ 2] Feedback
|
||||
row[ 3] ImageName
|
||||
row[ 4] ImageTitle
|
||||
row[ 5] Correct
|
||||
*/
|
||||
/***** Check if number of rows is correct *****/
|
||||
if (Gbl.Test.Answer.NumOptions != 2)
|
||||
Lay_ShowErrorAndExit ("Wrong float range.");
|
||||
|
@ -4464,7 +4512,7 @@ static void Tst_PutFormEditOneQst (char *Stem,char *Feedback)
|
|||
Txt_Stem,
|
||||
Stem);
|
||||
Tst_PutFormToEditQstImage (&Gbl.Test.Image,"TEST_IMG_EDIT_ONE_STEM",
|
||||
NULL,"STEM", // Title / attribution
|
||||
"STEM", // Title / attribution
|
||||
"ImgAct","FilImg","TitImg",false);
|
||||
|
||||
/***** Feedback *****/
|
||||
|
@ -4645,7 +4693,7 @@ static void Tst_PutFormEditOneQst (char *Stem,char *Feedback)
|
|||
sprintf (ParamTitle ,"TitImg%u",NumOpt);
|
||||
Tst_PutFormToEditQstImage (&Gbl.Test.Answer.Options[NumOpt].Image,
|
||||
"TEST_IMG_EDIT_ONE_ANS",
|
||||
NULL,"ANS_STR", // Title / attribution
|
||||
"ANS_STR", // Title / attribution
|
||||
ParamAction,ParamFile,ParamTitle,
|
||||
OptionsDisabled);
|
||||
fprintf (Gbl.F.Out,"</td>"
|
||||
|
@ -4791,7 +4839,14 @@ static void Tst_GetQstDataFromDB (char *Stem,char *Feedback)
|
|||
DB_QuerySELECT (Query,&mysql_res,"can not get a question");
|
||||
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/*
|
||||
row[ 0] AnsType
|
||||
row[ 1] Shuffle
|
||||
row[ 2] Stem
|
||||
row[ 3] Feedback
|
||||
row[ 4] ImageName
|
||||
row[ 5] ImageTitle
|
||||
*/
|
||||
/* Get the type of answer */
|
||||
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[0]);
|
||||
|
||||
|
@ -4807,7 +4862,7 @@ static void Tst_GetQstDataFromDB (char *Stem,char *Feedback)
|
|||
if (row[3])
|
||||
if (row[3][0])
|
||||
{
|
||||
strncpy (Feedback,row[4],Cns_MAX_BYTES_TEXT);
|
||||
strncpy (Feedback,row[3],Cns_MAX_BYTES_TEXT);
|
||||
Feedback[Cns_MAX_BYTES_TEXT] = '\0';
|
||||
}
|
||||
|
||||
|
@ -4815,7 +4870,7 @@ static void Tst_GetQstDataFromDB (char *Stem,char *Feedback)
|
|||
if (row[4][0])
|
||||
{
|
||||
Gbl.Test.Image.Status = Img_NAME_STORED_IN_DB;
|
||||
Img_GetImageNameTitle (row[4],row[5],&Gbl.Test.Image);
|
||||
Img_GetImageNameAndTitle (row[4],row[5],&Gbl.Test.Image);
|
||||
}
|
||||
else
|
||||
Gbl.Test.Image.Status = Img_FILE_NONE;
|
||||
|
@ -4839,6 +4894,14 @@ static void Tst_GetQstDataFromDB (char *Stem,char *Feedback)
|
|||
|
||||
/***** Get the answers from the database *****/
|
||||
Gbl.Test.Answer.NumOptions = Tst_GetAnswersQst (Gbl.Test.QstCod,&mysql_res,false); // Result: AnsInd,Answer,Correct,Feedback
|
||||
/*
|
||||
row[ 0] AnsInd
|
||||
row[ 1] Answer
|
||||
row[ 2] Feedback
|
||||
row[ 3] ImageName
|
||||
row[ 4] ImageTitle
|
||||
row[ 5] Correct
|
||||
*/
|
||||
for (NumOpt = 0;
|
||||
NumOpt < Gbl.Test.Answer.NumOptions;
|
||||
NumOpt++)
|
||||
|
@ -4872,22 +4935,22 @@ static void Tst_GetQstDataFromDB (char *Stem,char *Feedback)
|
|||
strncpy (Gbl.Test.Answer.Options[NumOpt].Text,row[1],Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
||||
Gbl.Test.Answer.Options[NumOpt].Text[Tst_MAX_BYTES_ANSWER_OR_FEEDBACK] = '\0';
|
||||
|
||||
// Feedback is initialized to empty string
|
||||
if (row[3])
|
||||
if (row[3][0])
|
||||
// Feedback (row[2]) is initialized to empty string
|
||||
if (row[2])
|
||||
if (row[2][0])
|
||||
{
|
||||
strncpy (Gbl.Test.Answer.Options[NumOpt].Feedback,row[3],Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
||||
strncpy (Gbl.Test.Answer.Options[NumOpt].Feedback,row[2],Tst_MAX_BYTES_ANSWER_OR_FEEDBACK);
|
||||
Gbl.Test.Answer.Options[NumOpt].Feedback[Tst_MAX_BYTES_ANSWER_OR_FEEDBACK] = '\0';
|
||||
}
|
||||
|
||||
/* Copy image */
|
||||
if (row[4][0])
|
||||
if (row[3][0])
|
||||
{
|
||||
Gbl.Test.Answer.Options[NumOpt].Image.Status = Img_NAME_STORED_IN_DB;
|
||||
Img_GetImageNameTitle (row[4],row[5],&Gbl.Test.Image);
|
||||
Img_GetImageNameAndTitle (row[3],row[4],&Gbl.Test.Answer.Options[NumOpt].Image);
|
||||
}
|
||||
|
||||
Gbl.Test.Answer.Options[NumOpt].Correct = (Str_ConvertToUpperLetter (row[2][0]) == 'Y');
|
||||
Gbl.Test.Answer.Options[NumOpt].Correct = (Str_ConvertToUpperLetter (row[5][0]) == 'Y');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -4926,7 +4989,7 @@ static void Tst_GetImageFromDB (unsigned NumOpt,struct Image *Image)
|
|||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/***** Get the image name (row[0]) *****/
|
||||
Img_GetImageNameTitle (row[0],row[1],Image);
|
||||
Img_GetImageNameAndTitle (row[0],row[1],Image);
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
@ -5126,7 +5189,7 @@ static void Tst_GetQstFromForm (char *Stem,char *Feedback)
|
|||
{
|
||||
sprintf (ParamAction,"ImgAct%u",NumOpt);
|
||||
sprintf (ParamFile ,"FilImg%u",NumOpt);
|
||||
sprintf (ParamFile ,"TitImg%u",NumOpt);
|
||||
sprintf (ParamTitle ,"TitImg%u",NumOpt);
|
||||
Img_GetImageFromForm (NumOpt,&Gbl.Test.Answer.Options[NumOpt].Image,
|
||||
Tst_GetImageFromDB,
|
||||
ParamAction,ParamFile,ParamTitle,
|
||||
|
@ -5870,8 +5933,9 @@ static void Tst_InsertAnswersIntoDB (void)
|
|||
switch (Gbl.Test.AnswerType)
|
||||
{
|
||||
case Tst_ANS_INT:
|
||||
sprintf (Query,"INSERT INTO tst_answers (QstCod,AnsInd,Answer,Feedback,Correct)"
|
||||
" VALUES (%ld,0,'%ld','','Y')",
|
||||
sprintf (Query,"INSERT INTO tst_answers"
|
||||
" (QstCod,AnsInd,Answer,Feedback,ImageName,ImageTitle,Correct)"
|
||||
" VALUES (%ld,0,'%ld','','','','Y')",
|
||||
Gbl.Test.QstCod,
|
||||
Gbl.Test.Answer.Integer);
|
||||
DB_QueryINSERT (Query,"can not create answer");
|
||||
|
@ -5882,8 +5946,9 @@ static void Tst_InsertAnswersIntoDB (void)
|
|||
i < 2;
|
||||
i++)
|
||||
{
|
||||
sprintf (Query,"INSERT INTO tst_answers (QstCod,AnsInd,Answer,Feedback,Correct)"
|
||||
" VALUES (%ld,%u,'%lg','','Y')",
|
||||
sprintf (Query,"INSERT INTO tst_answers"
|
||||
" (QstCod,AnsInd,Answer,Feedback,ImageName,ImageTitle,Correct)"
|
||||
" VALUES (%ld,%u,'%lg','','','','Y')",
|
||||
Gbl.Test.QstCod,i,
|
||||
Gbl.Test.Answer.FloatingPoint[i]);
|
||||
DB_QueryINSERT (Query,"can not create answer");
|
||||
|
@ -5891,8 +5956,9 @@ static void Tst_InsertAnswersIntoDB (void)
|
|||
setlocale (LC_NUMERIC,"es_ES.utf8"); // Return to spanish system (TODO: this should be internationalized!!!!!!!)
|
||||
break;
|
||||
case Tst_ANS_TRUE_FALSE:
|
||||
sprintf (Query,"INSERT INTO tst_answers (QstCod,AnsInd,Answer,Feedback,Correct)"
|
||||
" VALUES (%ld,0,'%c','','Y')",
|
||||
sprintf (Query,"INSERT INTO tst_answers"
|
||||
" (QstCod,AnsInd,Answer,Feedback,ImageName,ImageTitle,Correct)"
|
||||
" VALUES (%ld,0,'%c','','','','Y')",
|
||||
Gbl.Test.QstCod,
|
||||
Gbl.Test.Answer.TF);
|
||||
DB_QueryINSERT (Query,"can not create answer");
|
||||
|
@ -5905,10 +5971,9 @@ static void Tst_InsertAnswersIntoDB (void)
|
|||
NumOpt++)
|
||||
if (Gbl.Test.Answer.Options[NumOpt].Text[0])
|
||||
{
|
||||
sprintf (Query,"INSERT INTO tst_answers (QstCod,AnsInd,"
|
||||
"Answer,Feedback,ImageName,ImageTitle,Correct)"
|
||||
" VALUES ('%ld','%u',"
|
||||
"'%s','%s','%s','%s','%c')",
|
||||
sprintf (Query,"INSERT INTO tst_answers"
|
||||
" (QstCod,AnsInd,Answer,Feedback,ImageName,ImageTitle,Correct)"
|
||||
" VALUES ('%ld','%u','%s','%s','%s','%s','%c')",
|
||||
Gbl.Test.QstCod,NumOpt,
|
||||
Gbl.Test.Answer.Options[NumOpt].Text,
|
||||
Gbl.Test.Answer.Options[NumOpt].Feedback ? Gbl.Test.Answer.Options[NumOpt].Feedback : "",
|
||||
|
|
|
@ -306,7 +306,14 @@ static void TsI_WriteAnswersOfAQstXML (long QstCod)
|
|||
double FloatNum[2];
|
||||
|
||||
Gbl.Test.Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,false); // Result: AnsInd,Answer,Correct
|
||||
|
||||
/*
|
||||
row[ 0] AnsInd
|
||||
row[ 1] Answer
|
||||
row[ 2] Feedback
|
||||
row[ 3] ImageName
|
||||
row[ 4] ImageTitle
|
||||
row[ 5] Correct
|
||||
*/
|
||||
/***** Write the answers *****/
|
||||
switch (Gbl.Test.AnswerType)
|
||||
{
|
||||
|
@ -355,16 +362,18 @@ static void TsI_WriteAnswersOfAQstXML (long QstCod)
|
|||
fprintf (Gbl.Test.XML.FileXML,"<option");
|
||||
if (Gbl.Test.AnswerType != Tst_ANS_TEXT)
|
||||
fprintf (Gbl.Test.XML.FileXML," correct=\"%s\"",
|
||||
Str_ConvertToUpperLetter (row[2][0]) == 'Y' ? "yes" :
|
||||
Str_ConvertToUpperLetter (row[5][0]) == 'Y' ? "yes" :
|
||||
"no");
|
||||
fprintf (Gbl.Test.XML.FileXML,">%s"
|
||||
"<text>%s</text>%s",
|
||||
Txt_NEW_LINE,
|
||||
row[1],Txt_NEW_LINE);
|
||||
if (row[3])
|
||||
if (row[3][0])
|
||||
|
||||
/* Write the feedback (row[2]) */
|
||||
if (row[2])
|
||||
if (row[2][0])
|
||||
fprintf (Gbl.Test.XML.FileXML,"<feedback>%s</feedback>%s",
|
||||
row[3],Txt_NEW_LINE);
|
||||
row[2],Txt_NEW_LINE);
|
||||
fprintf (Gbl.Test.XML.FileXML,"</option>%s",
|
||||
Txt_NEW_LINE);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue