diff --git a/swad_changelog.h b/swad_changelog.h index aa698afa..2145f933 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -132,13 +132,15 @@ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 15.184 (2016-04-06)" +#define Log_PLATFORM_VERSION "SWAD 15.184.1 (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.184.1: Apr 06, 2016 Fixed bug when removing a test question. + Code refactoring in tests. (198680 lines) 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) diff --git a/swad_global.c b/swad_global.c index 8d9610cd..5bad6f16 100644 --- a/swad_global.c +++ b/swad_global.c @@ -386,6 +386,7 @@ void Gbl_InitializeGlobals (void) Gbl.Usrs.ClassPhoto.Cols = Usr_CLASS_PHOTO_COLS_DEF; + /* Statistics */ Gbl.Stat.ClicksGroupedBy = Sta_CLICKS_CRS_PER_USR; Gbl.Stat.CountType = Sta_TOTAL_CLICKS; Gbl.Stat.Role = Sta_IDENTIFIED_USRS; @@ -397,19 +398,24 @@ void Gbl_InitializeGlobals (void) Gbl.Usrs.Connected.TimeToRefreshInMs = Con_MAX_TIME_TO_REFRESH_CONNECTED_IN_MS; + /* Tests */ Gbl.Test.Config.Pluggable = Tst_PLUGGABLE_UNKNOWN; Gbl.Test.NumQsts = Tst_CONFIG_DEFAULT_DEF_QUESTIONS; Gbl.Test.AllowTeachers = false; // Must the exam be saved? - Gbl.Test.AllTags = Gbl.Test.AllAnsTypes = false; - Gbl.Test.TagsList = NULL; + Gbl.Test.AllAnsTypes = false; Gbl.Test.ListAnsTypes[0] = '\0'; + Gbl.Test.Tags.Num = 0; + Gbl.Test.Tags.All = false; + Gbl.Test.Tags.List = NULL; + + /* Forums */ Gbl.Forum.ForumType = (For_ForumType_t) 0; Gbl.Forum.WhichForums = For_DEFAULT_WHICH_FORUMS; Gbl.Forum.SelectedOrderType = For_DEFAULT_ORDER; Gbl.Forum.ThreadToMove = -1L; - /* Related to user nickname */ + /* User nickname */ Gbl.Usrs.Me.UsrDat.Nickname[0] = '\0'; /* File browser */ @@ -423,7 +429,7 @@ void Gbl_InitializeGlobals (void) Gbl.ColorRows[0] = "COLOR0"; // Darker Gbl.ColorRows[1] = "COLOR1"; // Lighter - /* Related to imported data from external site */ + /* Imported data from external site */ Gbl.Imported.ExternalUsrId[0] = '\0'; Gbl.Imported.ExternalSesId[0] = '\0'; Gbl.Imported.ExternalRole = Rol_UNKNOWN; diff --git a/swad_global.h b/swad_global.h index 559c8b0b..87a5e496 100644 --- a/swad_global.h +++ b/swad_global.h @@ -643,17 +643,20 @@ struct Globals { struct Tst_Config Config; long QstCod; + struct + { + unsigned Num; + bool All; + char *List; + char Txt[Tst_MAX_TAGS_PER_QUESTION][Tst_MAX_BYTES_TAG+1]; + } Tags; Tst_AnswerType_t AnswerType; - char TagText[Tst_MAX_TAGS_PER_QUESTION][Tst_MAX_BYTES_TAG+1]; unsigned NumQsts; long QstCodes[Tst_MAX_QUESTIONS_PER_EXAM]; // Codes of the sent/received questions in a test char StrIndexesOneQst[Tst_MAX_QUESTIONS_PER_EXAM][Tst_MAX_SIZE_INDEXES_ONE_QST+1]; // 0 1 2 3, 3 0 2 1, etc. char StrAnswersOneQst[Tst_MAX_QUESTIONS_PER_EXAM][Tst_MAX_SIZE_ANSWERS_ONE_QST+1]; // Answers selected by user bool AllowTeachers; // Can teachers of this course see the exam? - bool AllTags; bool AllAnsTypes; - unsigned NumTags; - char *TagsList; struct { char *Text; diff --git a/swad_test.c b/swad_test.c index 56d32596..621c65da 100644 --- a/swad_test.c +++ b/swad_test.c @@ -1601,7 +1601,7 @@ static void Tst_ShowFormSelTags (unsigned long NumRows,MYSQL_RES *mysql_res, fprintf (Gbl.F.Out,"" "" " %s" @@ -1636,9 +1636,9 @@ static void Tst_ShowFormSelTags (unsigned long NumRows,MYSQL_RES *mysql_res, fprintf (Gbl.F.Out,"" "%s",row[1]); } /* If it's a new tag received from the form */ - if (TagNotFound && Gbl.Test.TagText[NumTag][0]) + if (TagNotFound && Gbl.Test.Tags.Txt[NumTag][0]) fprintf (Gbl.F.Out,"", - Gbl.Test.TagText[NumTag],Gbl.Test.TagText[NumTag]); + Gbl.Test.Tags.Txt[NumTag],Gbl.Test.Tags.Txt[NumTag]); fprintf (Gbl.F.Out,"" "" "", @@ -4475,7 +4469,7 @@ static void Tst_PutFormEditOneQst (char *Stem,char *Feedback) " class=\"TAG_TXT\" maxlength=\"%u\" value=\"%s\"" " onchange=\"changeSelTag('%u')\" />" "", - NumTag,NumTag,Tst_MAX_TAG_LENGTH,Gbl.Test.TagText[NumTag],NumTag); + NumTag,NumTag,Tst_MAX_TAG_LENGTH,Gbl.Test.Tags.Txt[NumTag],NumTag); fprintf (Gbl.F.Out,""); } @@ -4733,15 +4727,8 @@ static void Tst_PutFormEditOneQst (char *Stem,char *Feedback) void Tst_QstConstructor (void) { unsigned NumOpt; - unsigned NumTag; Gbl.Test.QstCod = -1L; - for (NumTag = 0; - NumTag < Tst_MAX_TAGS_PER_QUESTION; - NumTag++) - Gbl.Test.TagText[NumTag][0] = '\0'; - Gbl.Test.NumTags = 0; - Gbl.Test.TagsList = NULL; Gbl.Test.Stem.Text = NULL; Gbl.Test.Stem.Length = 0; Gbl.Test.Feedback.Text = NULL; @@ -4933,8 +4920,8 @@ static void Tst_GetQstDataFromDB (char *Stem,char *Feedback) NumRow++) { row = mysql_fetch_row (mysql_res); - strncpy (Gbl.Test.TagText[NumRow],row[0],Tst_MAX_BYTES_TAG); - Gbl.Test.TagText[NumRow][Tst_MAX_BYTES_TAG] = '\0'; + strncpy (Gbl.Test.Tags.Txt[NumRow],row[0],Tst_MAX_BYTES_TAG); + Gbl.Test.Tags.Txt[NumRow][Tst_MAX_BYTES_TAG] = '\0'; } /* Free structure that stores the query result */ @@ -5148,19 +5135,19 @@ static void Tst_GetQstFromForm (char *Stem,char *Feedback) NumTag++) { sprintf (TagStr,"TagTxt%u",NumTag); - Par_GetParToText (TagStr,Gbl.Test.TagText[NumTag],Tst_MAX_BYTES_TAG); + Par_GetParToText (TagStr,Gbl.Test.Tags.Txt[NumTag],Tst_MAX_BYTES_TAG); - if (Gbl.Test.TagText[NumTag][0]) + if (Gbl.Test.Tags.Txt[NumTag][0]) { Str_ChangeFormat (Str_FROM_FORM,Str_TO_TEXT, - Gbl.Test.TagText[NumTag],Tst_MAX_BYTES_TAG,true); + Gbl.Test.Tags.Txt[NumTag],Tst_MAX_BYTES_TAG,true); /* Check if not repeated */ for (NumTagRead = 0; NumTagRead < NumTag; NumTagRead++) - if (!strcmp (Gbl.Test.TagText[NumTagRead],Gbl.Test.TagText[NumTag])) + if (!strcmp (Gbl.Test.Tags.Txt[NumTagRead],Gbl.Test.Tags.Txt[NumTag])) { - Gbl.Test.TagText[NumTag][0] = '\0'; + Gbl.Test.Tags.Txt[NumTag][0] = '\0'; break; } } @@ -5282,11 +5269,11 @@ static void Tst_GetQstFromForm (char *Stem,char *Feedback) } /***** Adjust global variables related to this test question *****/ - for (NumTag = 0, Gbl.Test.NumTags = 0; + for (NumTag = 0, Gbl.Test.Tags.Num = 0; NumTag < Tst_MAX_TAGS_PER_QUESTION; NumTag++) - if (Gbl.Test.TagText[NumTag][0]) - Gbl.Test.NumTags++; + if (Gbl.Test.Tags.Txt[NumTag][0]) + Gbl.Test.Tags.Num++; Gbl.Test.Stem.Text = Stem; Gbl.Test.Stem.Length = strlen (Gbl.Test.Stem.Text); Gbl.Test.Feedback.Text = Feedback; @@ -5330,7 +5317,7 @@ bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (void) Gbl.Test.Answer.NumOptions = 0; /***** A question must have at least one tag *****/ - if (!Gbl.Test.NumTags) // There are no tags with text + if (!Gbl.Test.Tags.Num) // There are no tags with text { Lay_ShowAlert (Lay_WARNING,Txt_You_must_type_at_least_one_tag_for_the_question); return false; @@ -5942,14 +5929,14 @@ static void Tst_InsertTagsIntoDB (void) /***** For each tag... *****/ for (NumTag = 0, TagIdx = 0; - TagIdx < Gbl.Test.NumTags; + TagIdx < Gbl.Test.Tags.Num; NumTag++) - if (Gbl.Test.TagText[NumTag][0]) + if (Gbl.Test.Tags.Txt[NumTag][0]) { /***** Check if this tag exists for current course *****/ - if ((TagCod = Tst_GetTagCodFromTagTxt (Gbl.Test.TagText[NumTag])) < 0) + if ((TagCod = Tst_GetTagCodFromTagTxt (Gbl.Test.Tags.Txt[NumTag])) < 0) /* This tag is new for current course. Add it to tags table */ - TagCod = Tst_CreateNewTag (Gbl.CurrentCrs.Crs.CrsCod,Gbl.Test.TagText[NumTag]); + TagCod = Tst_CreateNewTag (Gbl.CurrentCrs.Crs.CrsCod,Gbl.Test.Tags.Txt[NumTag]); /***** Insert tag in tst_question_tags *****/ sprintf (Query,"INSERT INTO tst_question_tags (QstCod,TagCod,TagInd)" diff --git a/swad_test_import.c b/swad_test_import.c index d0d350dc..98fb0c64 100644 --- a/swad_test_import.c +++ b/swad_test_import.c @@ -551,22 +551,21 @@ static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer) Lay_ShowErrorAndExit ("Wrong type of answer."); /* Get tags */ - Gbl.Test.NumTags = 0; - for (TagsElem = QuestionElem->FirstChild; + for (TagsElem = QuestionElem->FirstChild, Gbl.Test.Tags.Num = 0; TagsElem != NULL; TagsElem = TagsElem->NextBrother) if (!strcmp (TagsElem->TagName,"tags")) { for (TagElem = TagsElem->FirstChild; - TagElem != NULL && Gbl.Test.NumTags < Tst_MAX_TAGS_PER_QUESTION; + TagElem != NULL && Gbl.Test.Tags.Num < Tst_MAX_TAGS_PER_QUESTION; TagElem = TagElem->NextBrother) if (!strcmp (TagElem->TagName,"tag")) { if (TagElem->Content) { - strncpy (Gbl.Test.TagText[Gbl.Test.NumTags],TagElem->Content,Tst_MAX_BYTES_TAG); - Gbl.Test.TagText[Gbl.Test.NumTags][Tst_MAX_BYTES_TAG] = '\0'; - Gbl.Test.NumTags++; + strncpy (Gbl.Test.Tags.Txt[Gbl.Test.Tags.Num],TagElem->Content,Tst_MAX_BYTES_TAG); + Gbl.Test.Tags.Txt[Gbl.Test.Tags.Num][Tst_MAX_BYTES_TAG] = '\0'; + Gbl.Test.Tags.Num++; } } break; // Only first element "tags" @@ -1051,12 +1050,12 @@ static void TsI_WriteRowImportedQst (struct XMLElement *StemElem, /***** Write the question tags *****/ fprintf (Gbl.F.Out,"", Gbl.RowEvenOdd); - if (Gbl.Test.NumTags) + if (Gbl.Test.Tags.Num) { /***** Write the tags *****/ fprintf (Gbl.F.Out,""); for (NumTag = 0; - NumTag < Gbl.Test.NumTags; + NumTag < Gbl.Test.Tags.Num; NumTag++) fprintf (Gbl.F.Out,"" "" "", ClassData, - ClassData,Gbl.Test.TagText[NumTag]); + ClassData,Gbl.Test.Tags.Txt[NumTag]); fprintf (Gbl.F.Out,"
" @@ -1067,7 +1066,7 @@ static void TsI_WriteRowImportedQst (struct XMLElement *StemElem, "
"); } else // no tags for this question