diff --git a/swad_changelog.h b/swad_changelog.h
index 41cd704f..00cdfdba 100644
--- a/swad_changelog.h
+++ b/swad_changelog.h
@@ -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;
diff --git a/swad_database.c b/swad_database.c
index 8ec59a99..6a9568af 100644
--- a/swad_database.c
+++ b/swad_database.c
@@ -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,"
diff --git a/swad_image.c b/swad_image.c
index 1b93be5c..c09d8f91 100644
--- a/swad_image.c
+++ b/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,"
"
- ""
- "
",
+ "Title)
+ if (Image->Title[0])
+ fprintf (Gbl.F.Out," title=\"%s\"",Image->Title);
+ fprintf (Gbl.F.Out," />"
+ "");
}
else
Lay_ShowAlert (Lay_WARNING,Txt_Image_not_found);
diff --git a/swad_image.h b/swad_image.h
index a2667d96..257dfc3f 100644
--- a/swad_image.h
+++ b/swad_image.h
@@ -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),
diff --git a/swad_test.c b/swad_test.c
index 706a350f..385548b5 100644
--- a/swad_test.c
+++ b/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," "
- "");
+ ParamTitle,ClassTitle,
+ Img_MAX_BYTES_TITLE,Image->Title ? Image->Title : "");
/***** End container *****/
fprintf (Gbl.F.Out,"");
@@ -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,"
",
'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,"
"
"
"
"%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,"