diff --git a/swad_action.c b/swad_action.c index a6a47972..32e7b6b3 100644 --- a/swad_action.c +++ b/swad_action.c @@ -635,9 +635,11 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = [ActImpTstQst ] = {1008,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_DATA,Act_BRW_1ST_TAB,NULL ,TsI_ImportQstsFromXML ,NULL}, [ActLstTstQst ] = { 132,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_ListQuestionsToEdit ,NULL}, [ActRcvTstQst ] = { 126,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_DATA,Act_BRW_1ST_TAB,NULL ,Tst_ReceiveQst ,NULL}, - [ActReqRemTstQst ] = {1523,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_RequestRemoveQst ,NULL}, - [ActRemTstQst ] = { 133,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_RemoveQst ,NULL}, - [ActShfTstQst ] = { 455,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_ChangeShuffleQst ,NULL}, + [ActReqRemSevTstQst ] = {1835,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_RequestRemoveSelectedQsts ,NULL}, + [ActRemSevTstQst ] = {1836,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_RemoveSelectedQsts ,NULL}, + [ActReqRemOneTstQst ] = {1523,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_RequestRemoveOneQst ,NULL}, + [ActRemOneTstQst ] = { 133,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_RemoveOneQst ,NULL}, + [ActChgShfTstQst ] = { 455,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_ChangeShuffleQst ,NULL}, [ActCfgTst ] = { 451,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_ShowFormConfig ,NULL}, [ActEnableTag ] = { 453,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_EnableTag ,NULL}, @@ -1862,7 +1864,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un -1, // #130 (obsolete action) -1, // #131 (obsolete action) ActLstTstQst, // #132 - ActRemTstQst, // #133 + ActRemOneTstQst, // #133 -1, // #134 (obsolete action) -1, // #135 (obsolete action) -1, // #136 (obsolete action) @@ -2184,7 +2186,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActDisableTag, // #452 ActEnableTag, // #453 ActRcvCfgTst, // #454 - ActShfTstQst, // #455 + ActChgShfTstQst, // #455 -1, // #456 (obsolete action) -1, // #457 (obsolete action) -1, // #458 (obsolete action) @@ -3252,7 +3254,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActSeeSocPrf, // #1520 ActFrmLogIn, // #1521 ActUpdSignUpReq, // #1522 - ActReqRemTstQst, // #1523 + ActReqRemOneTstQst, // #1523 ActReqRemSvyQst, // #1524 ActAdmTchCrsGrp, // #1525 ActChgToAdmTch, // #1526 @@ -3564,6 +3566,8 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActDwnPrgItm, // #1833 ActRgtPrgItm, // #1833 ActLftPrgItm, // #1834 + ActReqRemSevTstQst, // #1835 + ActRemSevTstQst, // #1836 }; /*****************************************************************************/ diff --git a/swad_action.h b/swad_action.h index 0944c3cc..72898c9e 100644 --- a/swad_action.h +++ b/swad_action.h @@ -64,7 +64,7 @@ typedef enum typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action -#define Act_MAX_ACTION_COD 1834 +#define Act_MAX_ACTION_COD 1836 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13 @@ -613,97 +613,99 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActImpTstQst (ActChgCrsTT1stDay + 102) #define ActLstTstQst (ActChgCrsTT1stDay + 103) #define ActRcvTstQst (ActChgCrsTT1stDay + 104) -#define ActReqRemTstQst (ActChgCrsTT1stDay + 105) -#define ActRemTstQst (ActChgCrsTT1stDay + 106) -#define ActShfTstQst (ActChgCrsTT1stDay + 107) -#define ActCfgTst (ActChgCrsTT1stDay + 108) -#define ActEnableTag (ActChgCrsTT1stDay + 109) -#define ActDisableTag (ActChgCrsTT1stDay + 110) -#define ActRenTag (ActChgCrsTT1stDay + 111) -#define ActRcvCfgTst (ActChgCrsTT1stDay + 112) +#define ActReqRemSevTstQst (ActChgCrsTT1stDay + 105) +#define ActRemSevTstQst (ActChgCrsTT1stDay + 106) +#define ActReqRemOneTstQst (ActChgCrsTT1stDay + 107) +#define ActRemOneTstQst (ActChgCrsTT1stDay + 108) +#define ActChgShfTstQst (ActChgCrsTT1stDay + 109) +#define ActCfgTst (ActChgCrsTT1stDay + 110) +#define ActEnableTag (ActChgCrsTT1stDay + 111) +#define ActDisableTag (ActChgCrsTT1stDay + 112) +#define ActRenTag (ActChgCrsTT1stDay + 113) +#define ActRcvCfgTst (ActChgCrsTT1stDay + 114) -#define ActReqSeeMyTstRes (ActChgCrsTT1stDay + 113) -#define ActSeeMyTstRes (ActChgCrsTT1stDay + 114) -#define ActSeeOneTstResMe (ActChgCrsTT1stDay + 115) -#define ActReqSeeUsrTstRes (ActChgCrsTT1stDay + 116) -#define ActSeeUsrTstRes (ActChgCrsTT1stDay + 117) -#define ActSeeOneTstResOth (ActChgCrsTT1stDay + 118) +#define ActReqSeeMyTstRes (ActChgCrsTT1stDay + 115) +#define ActSeeMyTstRes (ActChgCrsTT1stDay + 116) +#define ActSeeOneTstResMe (ActChgCrsTT1stDay + 117) +#define ActReqSeeUsrTstRes (ActChgCrsTT1stDay + 118) +#define ActSeeUsrTstRes (ActChgCrsTT1stDay + 119) +#define ActSeeOneTstResOth (ActChgCrsTT1stDay + 120) -#define ActSeeGam (ActChgCrsTT1stDay + 119) -#define ActReqRemMch (ActChgCrsTT1stDay + 120) -#define ActRemMch (ActChgCrsTT1stDay + 121) -#define ActReqNewMch (ActChgCrsTT1stDay + 122) -#define ActNewMch (ActChgCrsTT1stDay + 123) -#define ActResMch (ActChgCrsTT1stDay + 124) -#define ActBckMch (ActChgCrsTT1stDay + 125) -#define ActPlyPauMch (ActChgCrsTT1stDay + 126) -#define ActFwdMch (ActChgCrsTT1stDay + 127) -#define ActChgNumColMch (ActChgCrsTT1stDay + 128) -#define ActChgVisResMchQst (ActChgCrsTT1stDay + 129) -#define ActMchCntDwn (ActChgCrsTT1stDay + 130) -#define ActRefMchTch (ActChgCrsTT1stDay + 131) +#define ActSeeGam (ActChgCrsTT1stDay + 121) +#define ActReqRemMch (ActChgCrsTT1stDay + 122) +#define ActRemMch (ActChgCrsTT1stDay + 123) +#define ActReqNewMch (ActChgCrsTT1stDay + 124) +#define ActNewMch (ActChgCrsTT1stDay + 125) +#define ActResMch (ActChgCrsTT1stDay + 126) +#define ActBckMch (ActChgCrsTT1stDay + 127) +#define ActPlyPauMch (ActChgCrsTT1stDay + 128) +#define ActFwdMch (ActChgCrsTT1stDay + 129) +#define ActChgNumColMch (ActChgCrsTT1stDay + 130) +#define ActChgVisResMchQst (ActChgCrsTT1stDay + 131) +#define ActMchCntDwn (ActChgCrsTT1stDay + 132) +#define ActRefMchTch (ActChgCrsTT1stDay + 133) -#define ActJoiMch (ActChgCrsTT1stDay + 132) -#define ActSeeMchAnsQstStd (ActChgCrsTT1stDay + 133) -#define ActRemMchAnsQstStd (ActChgCrsTT1stDay + 134) -#define ActAnsMchQstStd (ActChgCrsTT1stDay + 135) -#define ActRefMchStd (ActChgCrsTT1stDay + 136) +#define ActJoiMch (ActChgCrsTT1stDay + 134) +#define ActSeeMchAnsQstStd (ActChgCrsTT1stDay + 135) +#define ActRemMchAnsQstStd (ActChgCrsTT1stDay + 136) +#define ActAnsMchQstStd (ActChgCrsTT1stDay + 137) +#define ActRefMchStd (ActChgCrsTT1stDay + 138) -#define ActSeeMyMchResCrs (ActChgCrsTT1stDay + 137) -#define ActSeeMyMchResGam (ActChgCrsTT1stDay + 138) -#define ActSeeMyMchResMch (ActChgCrsTT1stDay + 139) -#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 140) +#define ActSeeMyMchResCrs (ActChgCrsTT1stDay + 139) +#define ActSeeMyMchResGam (ActChgCrsTT1stDay + 140) +#define ActSeeMyMchResMch (ActChgCrsTT1stDay + 141) +#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 142) -#define ActReqSeeAllMchRes (ActChgCrsTT1stDay + 141) -#define ActSeeAllMchResCrs (ActChgCrsTT1stDay + 142) -#define ActSeeAllMchResGam (ActChgCrsTT1stDay + 143) -#define ActSeeAllMchResMch (ActChgCrsTT1stDay + 144) -#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 145) +#define ActReqSeeAllMchRes (ActChgCrsTT1stDay + 143) +#define ActSeeAllMchResCrs (ActChgCrsTT1stDay + 144) +#define ActSeeAllMchResGam (ActChgCrsTT1stDay + 145) +#define ActSeeAllMchResMch (ActChgCrsTT1stDay + 146) +#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 147) -#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 146) +#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 148) -#define ActFrmNewGam (ActChgCrsTT1stDay + 147) -#define ActEdiOneGam (ActChgCrsTT1stDay + 148) -#define ActNewGam (ActChgCrsTT1stDay + 149) -#define ActChgGam (ActChgCrsTT1stDay + 150) -#define ActReqRemGam (ActChgCrsTT1stDay + 151) -#define ActRemGam (ActChgCrsTT1stDay + 152) -#define ActHidGam (ActChgCrsTT1stDay + 153) -#define ActShoGam (ActChgCrsTT1stDay + 154) -#define ActAddOneGamQst (ActChgCrsTT1stDay + 155) -#define ActGamLstTstQst (ActChgCrsTT1stDay + 156) -#define ActAddTstQstToGam (ActChgCrsTT1stDay + 157) -#define ActReqRemGamQst (ActChgCrsTT1stDay + 158) -#define ActRemGamQst (ActChgCrsTT1stDay + 159) -#define ActUp_GamQst (ActChgCrsTT1stDay + 160) -#define ActDwnGamQst (ActChgCrsTT1stDay + 161) +#define ActFrmNewGam (ActChgCrsTT1stDay + 149) +#define ActEdiOneGam (ActChgCrsTT1stDay + 150) +#define ActNewGam (ActChgCrsTT1stDay + 151) +#define ActChgGam (ActChgCrsTT1stDay + 152) +#define ActReqRemGam (ActChgCrsTT1stDay + 153) +#define ActRemGam (ActChgCrsTT1stDay + 154) +#define ActHidGam (ActChgCrsTT1stDay + 155) +#define ActShoGam (ActChgCrsTT1stDay + 156) +#define ActAddOneGamQst (ActChgCrsTT1stDay + 157) +#define ActGamLstTstQst (ActChgCrsTT1stDay + 158) +#define ActAddTstQstToGam (ActChgCrsTT1stDay + 159) +#define ActReqRemGamQst (ActChgCrsTT1stDay + 160) +#define ActRemGamQst (ActChgCrsTT1stDay + 161) +#define ActUp_GamQst (ActChgCrsTT1stDay + 162) +#define ActDwnGamQst (ActChgCrsTT1stDay + 163) -#define ActSeeSvy (ActChgCrsTT1stDay + 162) -#define ActAnsSvy (ActChgCrsTT1stDay + 163) -#define ActFrmNewSvy (ActChgCrsTT1stDay + 164) -#define ActEdiOneSvy (ActChgCrsTT1stDay + 165) -#define ActNewSvy (ActChgCrsTT1stDay + 166) -#define ActChgSvy (ActChgCrsTT1stDay + 167) -#define ActReqRemSvy (ActChgCrsTT1stDay + 168) -#define ActRemSvy (ActChgCrsTT1stDay + 169) -#define ActReqRstSvy (ActChgCrsTT1stDay + 170) -#define ActRstSvy (ActChgCrsTT1stDay + 171) -#define ActHidSvy (ActChgCrsTT1stDay + 172) -#define ActShoSvy (ActChgCrsTT1stDay + 173) -#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 174) -#define ActRcvSvyQst (ActChgCrsTT1stDay + 175) -#define ActReqRemSvyQst (ActChgCrsTT1stDay + 176) -#define ActRemSvyQst (ActChgCrsTT1stDay + 177) +#define ActSeeSvy (ActChgCrsTT1stDay + 164) +#define ActAnsSvy (ActChgCrsTT1stDay + 165) +#define ActFrmNewSvy (ActChgCrsTT1stDay + 166) +#define ActEdiOneSvy (ActChgCrsTT1stDay + 167) +#define ActNewSvy (ActChgCrsTT1stDay + 168) +#define ActChgSvy (ActChgCrsTT1stDay + 169) +#define ActReqRemSvy (ActChgCrsTT1stDay + 170) +#define ActRemSvy (ActChgCrsTT1stDay + 171) +#define ActReqRstSvy (ActChgCrsTT1stDay + 172) +#define ActRstSvy (ActChgCrsTT1stDay + 173) +#define ActHidSvy (ActChgCrsTT1stDay + 174) +#define ActShoSvy (ActChgCrsTT1stDay + 175) +#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 176) +#define ActRcvSvyQst (ActChgCrsTT1stDay + 177) +#define ActReqRemSvyQst (ActChgCrsTT1stDay + 178) +#define ActRemSvyQst (ActChgCrsTT1stDay + 179) -#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 178) -#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 179) -#define ActEdiExaAnn (ActChgCrsTT1stDay + 180) -#define ActRcvExaAnn (ActChgCrsTT1stDay + 181) -#define ActPrnExaAnn (ActChgCrsTT1stDay + 182) -#define ActReqRemExaAnn (ActChgCrsTT1stDay + 183) -#define ActRemExaAnn (ActChgCrsTT1stDay + 184) -#define ActHidExaAnn (ActChgCrsTT1stDay + 185) -#define ActShoExaAnn (ActChgCrsTT1stDay + 186) +#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 180) +#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 181) +#define ActEdiExaAnn (ActChgCrsTT1stDay + 182) +#define ActRcvExaAnn (ActChgCrsTT1stDay + 183) +#define ActPrnExaAnn (ActChgCrsTT1stDay + 184) +#define ActReqRemExaAnn (ActChgCrsTT1stDay + 185) +#define ActRemExaAnn (ActChgCrsTT1stDay + 186) +#define ActHidExaAnn (ActChgCrsTT1stDay + 187) +#define ActShoExaAnn (ActChgCrsTT1stDay + 188) /*****************************************************************************/ /******************************** Files tab **********************************/ diff --git a/swad_changelog.h b/swad_changelog.h index fed61f22..edf9ddeb 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -497,7 +497,7 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.147 (2020-03-14)" +#define Log_PLATFORM_VERSION "SWAD 19.148 (2020-03-17)" #define CSS_FILE "swad19.146.css" #define JS_FILE "swad19.91.1.js" /* @@ -521,10 +521,13 @@ Param // TODO: No se puede entrar con DNI '1' suponiendo que no tenga password ¿por qué? // TODO: En la lista de conectados central, poner el logo de la institución a la que pertenece el usuario // TODO: Miguel Damas: al principio de los exámenes tendría que poner cuánto resta cada pregunta -// TODO: Si el alumno ha marcado "Permitir que los profesores...", entonces pedir confirmación al pulsar el botón azul, para evitar que se envíe por error antes de tiempo // TODO: Oresti Baños: cambiar ojos por candados en descriptores para prohibir/permitir y dejar los ojos para poder elegir descriptores +// TODO: Si el alumno ha marcado "Permitir que los profesores...", entonces pedir confirmación al pulsar el botón azul, para evitar que se envíe por error antes de tiempo + Version 19.148: Mar 17, 2020 Code refactoring in tests. + New actions to remove several test questions. (282868 lines) Version 19.147: Mar 14, 2020 Change MathJax to version 3.0.1. (282550 lines) +Install MathJax 3.0.1 Copy the following JavaScript file to public directory: sudo cp js/mathjax-config.js /var/www/html/swad/ diff --git a/swad_forum.c b/swad_forum.c index aecdb11d..509d747a 100644 --- a/swad_forum.c +++ b/swad_forum.c @@ -3906,7 +3906,7 @@ void For_ReceiveForumPost (void) Media.Width = For_IMAGE_SAVED_MAX_WIDTH; Media.Height = For_IMAGE_SAVED_MAX_HEIGHT; Media.Quality = For_IMAGE_SAVED_QUALITY; - Med_GetMediaFromForm (-1,&Media,NULL, + Med_GetMediaFromForm (-1L,-1L,-1,&Media,NULL, For_FORUM_POSTS_SECTION_ID); // Alerts will be shown later in posts section /***** Create a new message *****/ diff --git a/swad_game.c b/swad_game.c index 002032d6..19d42044 100644 --- a/swad_game.c +++ b/swad_game.c @@ -156,7 +156,7 @@ static void Gam_ListGameQuestions (struct Game *Game); static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts, MYSQL_RES *mysql_res, bool ICanEditQuestions); -static void Gam_ListQuestionForEdition (const char *StrQstInd); +static void Gam_ListQuestionForEdition (long QstCod,const char *StrQstInd); static void Gam_PutIconToAddNewQuestions (void); static void Gam_PutButtonToAddNewQuestions (void); @@ -1873,6 +1873,7 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts, extern const char *Txt_Movement_not_allowed; unsigned NumQst; MYSQL_ROW row; + long QstCod; unsigned QstInd; unsigned MaxQstInd; char StrQstInd[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; @@ -1915,7 +1916,7 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts, QstInd); /* Get question code (row[1]) */ - Gbl.Test.QstCod = Str_ConvertStrCodToLongCod (row[1]); + QstCod = Str_ConvertStrCodToLongCod (row[1]); /***** Icons *****/ Gam_SetCurrentGamCod (GamCod); // Used to pass parameter @@ -1962,12 +1963,15 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts, /* Put icon to edit the question */ if (ICanEditQuestions) - Ico_PutContextualIconToEdit (ActEdiOneTstQst,NULL,Tst_PutParamQstCod); + { + Tst_SetParamGblQstCod (QstCod); + Ico_PutContextualIconToEdit (ActEdiOneTstQst,NULL,Tst_PutParamGblQstCod); + } HTM_TD_End (); /***** Question *****/ - Gam_ListQuestionForEdition (StrQstInd); + Gam_ListQuestionForEdition (QstCod,StrQstInd); HTM_TR_End (); @@ -1983,7 +1987,7 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts, /********************** List game question for edition ***********************/ /*****************************************************************************/ -static void Gam_ListQuestionForEdition (const char *StrQstInd) +static void Gam_ListQuestionForEdition (long QstCod,const char *StrQstInd) { extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES]; extern const char *Txt_Question_removed; @@ -1992,7 +1996,7 @@ static void Gam_ListQuestionForEdition (const char *StrQstInd) bool QstExists; /***** Get question from database *****/ - QstExists = Tst_GetOneQuestionByCod (Gbl.Test.QstCod,&mysql_res); // Question exists? + QstExists = Tst_GetOneQuestionByCod (QstCod,&mysql_res); // Question exists? if (QstExists) { @@ -2033,13 +2037,13 @@ static void Gam_ListQuestionForEdition (const char *StrQstInd) /***** Write question code *****/ HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd); - HTM_TxtF ("%ld ",Gbl.Test.QstCod); + HTM_TxtF ("%ld ",QstCod); HTM_TD_End (); /***** Write the question tags *****/ HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd); if (QstExists) - Tst_GetAndWriteTagsQst (Gbl.Test.QstCod); + Tst_GetAndWriteTagsQst (QstCod); HTM_TD_End (); /***** Write stem and media (row[4]) *****/ @@ -2063,7 +2067,7 @@ static void Gam_ListQuestionForEdition (const char *StrQstInd) Tst_WriteQstFeedback (row[5],"TEST_EDI_LIGHT"); /* Show answers */ - Tst_WriteAnswersEdit (Gbl.Test.QstCod); + Tst_WriteAnswersEdit (QstCod); } else { diff --git a/swad_global.h b/swad_global.h index 90d6336a..746e40f7 100644 --- a/swad_global.h +++ b/swad_global.h @@ -652,7 +652,6 @@ struct Globals struct { struct Tst_Config Config; - long QstCod; struct { unsigned Num; @@ -690,11 +689,6 @@ struct Globals } Answer; char ListAnsTypes[Tst_MAX_BYTES_LIST_ANSWER_TYPES + 1]; Tst_QuestionsOrder_t SelectedOrder; - struct - { - bool CreateXML; // Create an XML file and Export questions into it? - FILE *FileXML; - } XML; } Test; struct { diff --git a/swad_media.c b/swad_media.c index a704e813..941ec152 100644 --- a/swad_media.c +++ b/swad_media.c @@ -504,11 +504,11 @@ static void Med_PutHiddenFormTypeMediaUploader (const char UniqueId[Frm_MAX_BYTE /******************** Get media (image/video) from form **********************/ /*****************************************************************************/ // Media constructor must be called before calling this function -// If NumMediaInForm < 0, params have no suffix +// If NumMediaInForm < 0, params have no suffix // If NumMediaInForm >= 0, the number is a suffix of the params -void Med_GetMediaFromForm (int NumMediaInForm,struct Media *Media, - void (*GetMediaFromDB) (int NumMediaInForm,struct Media *Media), +void Med_GetMediaFromForm (long CrsCod,long QstCod,int NumMediaInForm,struct Media *Media, + void (*GetMediaFromDB) (long CrsCod,long QstCod,int NumMediaInForm,struct Media *Media), const char *SectionForAlerts) { extern const char *Txt_Error_sending_or_processing_image_video; @@ -581,7 +581,7 @@ void Med_GetMediaFromForm (int NumMediaInForm,struct Media *Media, /***** Get media name *****/ if (GetMediaFromDB != NULL) - GetMediaFromDB (NumMediaInForm,Media); + GetMediaFromDB (CrsCod,QstCod,NumMediaInForm,Media); break; default: // Unknown action Media->Action = Med_ACTION_NO_MEDIA; diff --git a/swad_media.h b/swad_media.h index a7814519..bb05a31e 100644 --- a/swad_media.h +++ b/swad_media.h @@ -141,8 +141,8 @@ void Med_ResetMedia (struct Media *Media); void Med_GetMediaDataByCod (struct Media *Media); void Med_PutMediaUploader (int NumMediaInForm,const char *ClassInput); -void Med_GetMediaFromForm (int NumMediaInForm,struct Media *Media, - void (*GetMediaFromDB) (int NumMediaInForm,struct Media *Media), +void Med_GetMediaFromForm (long CrsCod,long QstCod,int NumMediaInForm,struct Media *Media, + void (*GetMediaFromDB) (long CrsCod,long QstCod,int NumMediaInForm,struct Media *Media), const char *SectionForAlerts); void Med_SetParamNames (struct ParamUploadMedia *ParamUploadMedia,int NumMediaInForm); diff --git a/swad_message.c b/swad_message.c index 4510f279..062b5e35 100644 --- a/swad_message.c +++ b/swad_message.c @@ -755,7 +755,7 @@ void Msg_RecMsgFromUsr (void) Media.Width = Msg_IMAGE_SAVED_MAX_WIDTH; Media.Height = Msg_IMAGE_SAVED_MAX_HEIGHT; Media.Quality = Msg_IMAGE_SAVED_QUALITY; - Med_GetMediaFromForm (-1,&Media,NULL,NULL); + Med_GetMediaFromForm (-1L,-1L,-1,&Media,NULL,NULL); Ale_ShowAlerts (NULL); /***** Loop over the list Gbl.Usrs.Selected.List[Rol_UNK], that holds the list of the diff --git a/swad_test.c b/swad_test.c index b293878d..c94324e2 100644 --- a/swad_test.c +++ b/swad_test.c @@ -124,6 +124,8 @@ extern struct Globals Gbl; /************************* Private global variables **************************/ /*****************************************************************************/ +static long Tst_ParamGblQstCod = -1L; // Used to pass parameter to function + /*****************************************************************************/ /***************************** Private prototypes ****************************/ /*****************************************************************************/ @@ -161,11 +163,16 @@ static void Tst_CheckAndCorrectNumbersQst (void); static void Tst_ShowFormAnswerTypes (void); static unsigned long Tst_GetQuestions (MYSQL_RES **mysql_res); static unsigned long Tst_GetQuestionsForTest (MYSQL_RES **mysql_res); -static void Tst_ListOneQstToEdit (void); +static void Tst_ListOneQstToEdit (long QstCod); static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows, MYSQL_RES *mysql_res); +static void Tst_WriteHeadingRowQuestionsForEdition (unsigned long NumRows); +static void Tst_WriteQuestionRowForEdition (unsigned long NumRows, + unsigned long NumRow, + long QstCod); static void Tst_ListOneOrMoreQuestionsForSelection (unsigned long NumRows, MYSQL_RES *mysql_res); +static void Tst_WriteQuestionRowForSelection (unsigned long NumRow,long QstCod); static void Tst_WriteAnswersTestToAnswer (unsigned NumQst,long QstCod,bool Shuffle); static void Tst_WriteAnswersTestResult (struct UsrData *UsrDat, @@ -210,10 +217,10 @@ static void Tst_WriteParamQstCod (unsigned NumQst,long QstCod); static bool Tst_GetParamsTst (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions); static unsigned Tst_GetAndCheckParamNumTst (void); static void Tst_GetParamNumQst (void); -static bool Tst_GetCreateXMLFromForm (void); static int Tst_CountNumTagsInList (void); static int Tst_CountNumAnswerTypesInList (void); -static void Tst_PutFormEditOneQst (char Stem[Cns_MAX_BYTES_TEXT + 1], +static void Tst_PutFormEditOneQst (long QstCod, + char Stem[Cns_MAX_BYTES_TEXT + 1], char Feedback[Cns_MAX_BYTES_TEXT + 1]); static void Tst_PutFloatInputField (const char *Label,const char *Field, double Value); @@ -225,32 +232,36 @@ static void Tst_FreeTextChoiceAnswer (unsigned NumOpt); static void Tst_ResetMediaOfQuestion (void); static void Tst_FreeMediaOfQuestion (void); -static void Tst_GetQstDataFromDB (char Stem[Cns_MAX_BYTES_TEXT + 1], +static void Tst_GetQstDataFromDB (long QstCod, + char Stem[Cns_MAX_BYTES_TEXT + 1], char Feedback[Cns_MAX_BYTES_TEXT + 1]); -static long Tst_GetMedCodFromDB (int NumOpt); -static void Tst_GetMediaFromDB (int NumOpt,struct Media *Media); +static long Tst_GetMedCodFromDB (long CrsCod,long QstCod,int NumOpt); +static void Tst_GetMediaFromDB (long CrsCod,long QstCod,int NumOpt, + struct Media *Media); static Tst_AnswerType_t Tst_ConvertFromUnsignedStrToAnsTyp (const char *UnsignedStr); -static void Tst_GetQstFromForm (char *Stem,char *Feedback); -static void Tst_MoveMediaToDefinitiveDirectories (void); +static long Tst_GetQstFromForm (char *Stem,char *Feedback); +static void Tst_MoveMediaToDefinitiveDirectories (long QstCod); static long Tst_GetTagCodFromTagTxt (const char *TagTxt); static long Tst_CreateNewTag (long CrsCod,const char *TagTxt); static void Tst_EnableOrDisableTag (long TagCod,bool TagHidden); +static void Tst_PutParamsRemoveSelectedQsts (void); static void Tst_PutIconToRemoveOneQst (void); -static void Tst_PutParamsRemoveOneQst (void); -static void Tst_PutParamsRemoveQst (void); +static void Tst_PutParamsRemoveOnlyThisQst (void); +static void Tst_PutParamsRemoveOneQstWhileEditing (void); +static void Tst_RemoveOneQstFromDB (long CrsCod,long QstCod); static long Tst_GetQstCod (void); -static void Tst_InsertOrUpdateQstIntoDB (void); -static void Tst_InsertTagsIntoDB (void); -static void Tst_InsertAnswersIntoDB (void); +static long Tst_InsertOrUpdateQstIntoDB (long QstCod); +static void Tst_InsertTagsIntoDB (long QstCod); +static void Tst_InsertAnswersIntoDB (long QstCod); -static void Tst_RemAnsFromQst (void); -static void Tst_RemTagsFromQst (void); -static void Tst_RemoveUnusedTagsFromCurrentCrs (void); +static void Tst_RemAnsFromQst (long QstCod); +static void Tst_RemTagsFromQst (long QstCod); +static void Tst_RemoveUnusedTagsFromCrs (long CrsCod); static void Tst_RemoveAllMedFilesFromStemOfAllQstsInCrs (long CrsCod); static void Tst_RemoveMediaFromAllAnsOfQst (long CrsCod,long QstCod); @@ -803,10 +814,8 @@ static void Tst_ShowTestQuestionsWhenSeeing (MYSQL_RES *mysql_res) { Gbl.RowEvenOdd = NumQst % 2; - /***** Get the row next of the result of the query in the database *****/ + /***** Get question code (row[0]) *****/ row = mysql_fetch_row (mysql_res); - - /***** Get the code of question (row[0]) *****/ if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) Lay_ShowErrorAndExit ("Wrong code of question."); @@ -963,7 +972,6 @@ void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestio /***** Create test question *****/ Tst_QstConstructor (); - Gbl.Test.QstCod = QstCod; HTM_TR_Begin (NULL); HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd); @@ -1350,12 +1358,27 @@ static void Tst_PutIconsTests (void) if (Tst_CheckIfICanEditTests ()) { - /***** Put form to edit existing test questions *****/ + switch (Gbl.Action.Act) + { + case ActLstTstQst: // List selected test questions for edition + case ActReqRemSevTstQst: // Request removal of selected questions + case ActReqRemOneTstQst: // Request removal of a question + case ActRemOneTstQst: // Remove a question + case ActChgShfTstQst: // Change shuffle of a question + /***** Put form to remove selected test questions *****/ + Ico_PutContextualIconToRemove (ActReqRemSevTstQst, + Tst_PutParamsRemoveSelectedQsts); + break; + default: + break; + } + if (Gbl.Action.Act != ActEdiTstQst) + /***** Put form to edit existing test questions *****/ Ico_PutContextualIconToEdit (ActEdiTstQst,NULL,NULL); - /***** Put form to create a new test question *****/ if (Gbl.Action.Act != ActEdiOneTstQst) + /***** Put form to create a new test question *****/ Ico_PutContextualIconToAdd (ActEdiOneTstQst,NULL,NULL, Txt_New_question); @@ -2318,11 +2341,13 @@ void Tst_ListQuestionsToEdit (void) /***** Get parameters, query the database and list the questions *****/ if (Tst_GetParamsTst (Tst_EDIT_TEST)) // Get parameters from the form { + /***** Get question codes from database *****/ if ((NumRows = Tst_GetQuestions (&mysql_res)) != 0) // Query database { - /***** Contextual menu *****/ + /* Contextual menu */ Mnu_ContextMenuBegin (); - if (Gbl.Test.XML.CreateXML) + + if (TsI_GetCreateXMLParamFromForm ()) TsI_CreateXML (NumRows,mysql_res); // Create XML file with exported questions... // ...and put a link to download it else @@ -2398,16 +2423,7 @@ static unsigned long Tst_GetQuestions (MYSQL_RES **mysql_res) /***** Select questions *****/ /* Start query */ snprintf (Query,Tst_MAX_BYTES_QUERY_TEST + 1, - "SELECT tst_questions.QstCod," // row[0] - "UNIX_TIMESTAMP(tst_questions.EditTime)," // row[1] - "tst_questions.AnsType," // row[2] - "tst_questions.Shuffle," // row[3] - "tst_questions.Stem," // row[4] - "tst_questions.Feedback," // row[5] - "tst_questions.MedCod," // row[6] - "tst_questions.NumHits," // row[7] - "tst_questions.NumHitsNotBlank," // row[8] - "tst_questions.Score" // row[9] + "SELECT tst_questions.QstCod" // row[0] " FROM tst_questions"); if (!Gbl.Test.Tags.All) Str_Concat (Query,",tst_question_tags,tst_tags", @@ -2667,19 +2683,30 @@ static unsigned long Tst_GetQuestionsForTest (MYSQL_RES **mysql_res) /*********************** List a test question for edition ********************/ /*****************************************************************************/ -static void Tst_ListOneQstToEdit (void) +static void Tst_ListOneQstToEdit (long QstCod) { - MYSQL_RES *mysql_res; + extern const char *Hlp_ASSESSMENT_Tests; + extern const char *Txt_Questions; - /***** Query database *****/ - if (Tst_GetOneQuestionByCod (Gbl.Test.QstCod,&mysql_res)) - /***** Show the question ready to edit it *****/ - Tst_ListOneOrMoreQuestionsForEdition (1,mysql_res); - else - Lay_ShowErrorAndExit ("Can not get question."); + /***** Begin box *****/ + Box_BoxBegin (NULL,Txt_Questions,Tst_PutIconsTests, + Hlp_ASSESSMENT_Tests,Box_NOT_CLOSABLE); - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); + /***** Write the heading *****/ + HTM_TABLE_BeginWideMarginPadding (2); + Tst_WriteHeadingRowQuestionsForEdition (1); + + /***** Write question row *****/ + Tst_WriteQuestionRowForEdition (1,0,QstCod); + + /***** End table *****/ + HTM_TABLE_End (); + + /***** Button to add a new question *****/ + Tst_PutButtonToAddQuestion (); + + /***** End box *****/ + Box_BoxEnd (); } /*****************************************************************************/ @@ -2715,23 +2742,9 @@ static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows, { extern const char *Hlp_ASSESSMENT_Tests; extern const char *Txt_Questions; - extern const char *Txt_No_INDEX; - extern const char *Txt_Code; - extern const char *Txt_Date; - extern const char *Txt_Tags; - extern const char *Txt_TST_STR_ORDER_FULL[Tst_NUM_TYPES_ORDER_QST]; - extern const char *Txt_TST_STR_ORDER_SHORT[Tst_NUM_TYPES_ORDER_QST]; - extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES]; - extern const char *Txt_Shuffle; - Tst_QuestionsOrder_t Order; unsigned long NumRow; MYSQL_ROW row; - unsigned UniqueId; - char *Id; - time_t TimeUTC; - unsigned long NumHitsThisQst; - unsigned long NumHitsNotBlankThisQst; - double TotalScoreThisQst; + long QstCod; /***** Begin box *****/ Box_BoxBegin (NULL,Txt_Questions,Tst_PutIconsTests, @@ -2739,16 +2752,61 @@ static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows, /***** Write the heading *****/ HTM_TABLE_BeginWideMarginPadding (2); + Tst_WriteHeadingRowQuestionsForEdition (NumRows); + + /***** Write rows *****/ + for (NumRow = 0; + NumRow < NumRows; + NumRow++) + { + Gbl.RowEvenOdd = NumRow % 2; + + /***** Get question code (row[0]) *****/ + row = mysql_fetch_row (mysql_res); + if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) + Lay_ShowErrorAndExit ("Wrong code of question."); + + /***** Write question row *****/ + Tst_WriteQuestionRowForEdition (NumRows,NumRow,QstCod); + } + + /***** End table *****/ + HTM_TABLE_End (); + + /***** Button to add a new question *****/ + Tst_PutButtonToAddQuestion (); + + /***** End box *****/ + Box_BoxEnd (); + } + +/*****************************************************************************/ +/*********** Write heading row in listing of questions for edition ***********/ +/*****************************************************************************/ + +static void Tst_WriteHeadingRowQuestionsForEdition (unsigned long NumRows) + { + extern const char *Txt_No_INDEX; + extern const char *Txt_Code; + extern const char *Txt_Date; + extern const char *Txt_Tags; + extern const char *Txt_Shuffle; + extern const char *Txt_TST_STR_ORDER_FULL[Tst_NUM_TYPES_ORDER_QST]; + extern const char *Txt_TST_STR_ORDER_SHORT[Tst_NUM_TYPES_ORDER_QST]; + Tst_QuestionsOrder_t Order; + + /***** Begin row *****/ HTM_TR_Begin (NULL); + /***** First columns *****/ HTM_TH_Empty (1); - HTM_TH (1,1,"CT",Txt_No_INDEX); HTM_TH (1,1,"CT",Txt_Code); HTM_TH (1,1,"CT",Txt_Date); HTM_TH (1,1,"CT",Txt_Tags); HTM_TH (1,1,"CT",Txt_Shuffle); + /***** Columns which data can be ordered *****/ /* Stem and answers of question */ /* Number of times that the question has been answered */ /* Average score */ @@ -2780,15 +2838,32 @@ static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows, HTM_TH_End (); } + /***** End row *****/ HTM_TR_End (); + } - /***** Write rows *****/ - for (NumRow = 0, UniqueId = 1; - NumRow < NumRows; - NumRow++, UniqueId++) +/*****************************************************************************/ +/********** Write question row in listing of questions for edition ***********/ +/*****************************************************************************/ + +static void Tst_WriteQuestionRowForEdition (unsigned long NumRows, + unsigned long NumRow, + long QstCod) + { + extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES]; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + static unsigned UniqueId = 0; + char *Id; + time_t TimeUTC; + unsigned long NumHitsThisQst; + unsigned long NumHitsNotBlankThisQst; + double TotalScoreThisQst; + + /***** Get and show questvoidion data *****/ + if (Tst_GetOneQuestionByCod (QstCod,&mysql_res)) { - Gbl.RowEvenOdd = NumRow % 2; - + /***** Get row from database *****/ row = mysql_fetch_row (mysql_res); /* row[0] QstCod @@ -2802,30 +2877,29 @@ static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows, row[8] NumHitsNotBlank row[9] Score */ + /***** Create test question *****/ Tst_QstConstructor (); - /* row[0] holds the code of the question */ - if ((Gbl.Test.QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) - Lay_ShowErrorAndExit ("Wrong code of question."); - + /***** Begin table row *****/ HTM_TR_Begin (NULL); /***** Icons *****/ HTM_TD_Begin ("class=\"BT%u\"",Gbl.RowEvenOdd); /* Write icon to remove the question */ - Frm_StartForm (ActReqRemTstQst); - Tst_PutParamQstCod (); + Frm_StartForm (ActReqRemOneTstQst); + Tst_PutParamQstCod (QstCod); 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 Dat_WriteParamsIniEndDates (); Tst_WriteParamEditQst (); Ico_PutIconRemove (); Frm_EndForm (); /* Write icon to edit the question */ - Ico_PutContextualIconToEdit (ActEdiOneTstQst,NULL,Tst_PutParamQstCod); + Tst_SetParamGblQstCod (QstCod); + Ico_PutContextualIconToEdit (ActEdiOneTstQst,NULL,Tst_PutParamGblQstCod); HTM_TD_End (); @@ -2846,15 +2920,15 @@ static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows, /* Write question code */ HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd); - HTM_TxtF ("%ld ",Gbl.Test.QstCod); + HTM_TxtF ("%ld ",QstCod); HTM_TD_End (); /* Write the date (row[1] has the UTC date-time) */ TimeUTC = Dat_GetUNIXTimeFromStr (row[1]); - if (asprintf (&Id,"tst_date_%u",UniqueId) < 0) + if (asprintf (&Id,"tst_date_%u",++UniqueId) < 0) Lay_NotEnoughMemoryExit (); HTM_TD_Begin ("id=\"%s\" class=\"DAT_SMALL CT COLOR%u\"", - Id,Gbl.RowEvenOdd); + Id,Gbl.RowEvenOdd); Dat_WriteLocalDateHMSFromUTC (Id,TimeUTC, Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK, true,true,false,0x7); @@ -2863,62 +2937,62 @@ static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows, /* Write the question tags */ HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd); - Tst_GetAndWriteTagsQst (Gbl.Test.QstCod); + Tst_GetAndWriteTagsQst (QstCod); HTM_TD_End (); /* Write if shuffle is enabled (row[3]) */ HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd); if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE || - Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE) - { - Frm_StartForm (ActShfTstQst); - Tst_PutParamQstCod (); - Dat_WriteParamsIniEndDates (); - Tst_WriteParamEditQst (); - if (NumRows == 1) + Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE) + { + Frm_StartForm (ActChgShfTstQst); + Tst_PutParamQstCod (QstCod); + Dat_WriteParamsIniEndDates (); + Tst_WriteParamEditQst (); + if (NumRows == 1) Par_PutHiddenParamChar ("OnlyThisQst",'Y'); // If editing only one question, don't edit others - Par_PutHiddenParamUnsigned (NULL,"Order",(unsigned) Gbl.Test.SelectedOrder); - HTM_INPUT_CHECKBOX ("Shuffle",HTM_SUBMIT_ON_CHANGE, - "value=\"Y\"%s", - row[3][0] == 'Y' ? " checked=\"checked\"" : - ""); - Frm_EndForm (); - } + Par_PutHiddenParamUnsigned (NULL,"Order",(unsigned) Gbl.Test.SelectedOrder); + HTM_INPUT_CHECKBOX ("Shuffle",HTM_SUBMIT_ON_CHANGE, + "value=\"Y\"%s", + row[3][0] == 'Y' ? " checked=\"checked\"" : + ""); + Frm_EndForm (); + } HTM_TD_End (); /* Write stem (row[4]) */ HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd); Tst_WriteQstStem (row[4],"TEST_EDI", - true); // Visible + true); // Visible /***** Get and show media (row[6]) *****/ Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[6]); Med_GetMediaDataByCod (&Gbl.Test.Media); Med_ShowMedia (&Gbl.Test.Media, - "TEST_MED_EDIT_LIST_CONT", - "TEST_MED_EDIT_LIST"); + "TEST_MED_EDIT_LIST_CONT", + "TEST_MED_EDIT_LIST"); /* Write feedback (row[5]) and answers */ Tst_WriteQstFeedback (row[5],"TEST_EDI_LIGHT"); - Tst_WriteAnswersEdit (Gbl.Test.QstCod); + Tst_WriteAnswersEdit (QstCod); HTM_TD_End (); /* Get number of hits - (number of times that the question has been answered, - including blank answers) (row[7]) */ + (number of times that the question has been answered, + including blank answers) (row[7]) */ if (sscanf (row[7],"%lu",&NumHitsThisQst) != 1) - Lay_ShowErrorAndExit ("Wrong number of hits to a question."); + Lay_ShowErrorAndExit ("Wrong number of hits to a question."); /* Get number of hits not blank - (number of times that the question has been answered - with a not blank answer) (row[8]) */ + (number of times that the question has been answered + with a not blank answer) (row[8]) */ if (sscanf (row[8],"%lu",&NumHitsNotBlankThisQst) != 1) - Lay_ShowErrorAndExit ("Wrong number of hits not blank to a question."); + Lay_ShowErrorAndExit ("Wrong number of hits not blank to a question."); /* Get the acumulated score of the question (row[9]) */ Str_SetDecimalPointToUS (); // To get the decimal point as a dot if (sscanf (row[9],"%lf",&TotalScoreThisQst) != 1) - Lay_ShowErrorAndExit ("Wrong score of a question."); + Lay_ShowErrorAndExit ("Wrong score of a question."); Str_SetDecimalPointToLocal (); // Return to local system /* Write number of times this question has been answered */ @@ -2931,7 +3005,7 @@ static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows, if (NumHitsThisQst) HTM_Double2Decimals (TotalScoreThisQst / (double) NumHitsThisQst); else - HTM_Txt ("N.A."); + HTM_Txt ("N.A."); HTM_TD_End (); /* Write number of times this question has been answered (not blank) */ @@ -2942,29 +3016,24 @@ static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows, /* Write average score (not blank) */ HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd); if (NumHitsNotBlankThisQst) - HTM_Double2Decimals (TotalScoreThisQst / (double) NumHitsNotBlankThisQst); + HTM_Double2Decimals (TotalScoreThisQst / (double) NumHitsNotBlankThisQst); else - HTM_Txt ("N.A."); + HTM_Txt ("N.A."); HTM_TD_End (); + /***** End table row *****/ HTM_TR_End (); /***** Destroy test question *****/ Tst_QstDestructor (); } - /***** End table *****/ - HTM_TABLE_End (); - - /***** Button to add a new question *****/ - Tst_PutButtonToAddQuestion (); - - /***** End box *****/ - Box_BoxEnd (); + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); } /*****************************************************************************/ -/****************** List for edition one or more test questions **************/ +/*************** List for selection one or more test questions ***************/ /*****************************************************************************/ static void Tst_ListOneOrMoreQuestionsForSelection (unsigned long NumRows, @@ -2983,9 +3052,7 @@ static void Tst_ListOneOrMoreQuestionsForSelection (unsigned long NumRows, extern const char *Txt_Add_questions; unsigned long NumRow; MYSQL_ROW row; - unsigned UniqueId; - char *Id; - time_t TimeUTC; + long QstCod; /***** Begin box *****/ Box_BoxBegin (NULL,Txt_Questions,NULL, @@ -3012,105 +3079,19 @@ static void Tst_ListOneOrMoreQuestionsForSelection (unsigned long NumRows, HTM_TR_End (); /***** Write rows *****/ - for (NumRow = 0, UniqueId = 1; + for (NumRow = 0; NumRow < NumRows; - NumRow++, UniqueId++) + NumRow++) { Gbl.RowEvenOdd = NumRow % 2; + /***** Get question code (row[0]) *****/ row = mysql_fetch_row (mysql_res); - /* - row[0] QstCod - row[1] UNIX_TIMESTAMP(EditTime) - row[2] AnsType - row[3] Shuffle - row[4] Stem - row[5] Feedback - row[6] MedCod - row[7] NumHits - row[8] NumHitsNotBlank - row[9] Score - */ - /***** Create test question *****/ - Tst_QstConstructor (); - - /* row[0] holds the code of the question */ - if ((Gbl.Test.QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) + if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) Lay_ShowErrorAndExit ("Wrong code of question."); - HTM_TR_Begin (NULL); - - /***** Icons *****/ - HTM_TD_Begin ("class=\"BT%u\"",Gbl.RowEvenOdd); - - /* Write checkbox to select the question */ - HTM_INPUT_CHECKBOX ("QstCods",HTM_DONT_SUBMIT_ON_CHANGE, - "value=\"%ld\"", - Gbl.Test.QstCod); - - /* Write number of question */ - HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd); - HTM_TxtF ("%lu ",NumRow + 1); - HTM_TD_End (); - - /* Write question code */ - HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd); - HTM_TxtF ("%ld ",Gbl.Test.QstCod); - HTM_TD_End (); - - /* Write the date (row[1] has the UTC date-time) */ - TimeUTC = Dat_GetUNIXTimeFromStr (row[1]); - if (asprintf (&Id,"tst_date_%u",UniqueId) < 0) - Lay_NotEnoughMemoryExit (); - HTM_TD_Begin ("id=\"%s\" class=\"DAT_SMALL CT COLOR%u\">", - Id,Gbl.RowEvenOdd); - Dat_WriteLocalDateHMSFromUTC (Id,TimeUTC, - Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK, - true,true,false,0x7); - HTM_TD_End (); - free (Id); - - /* Write the question tags */ - HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd); - Tst_GetAndWriteTagsQst (Gbl.Test.QstCod); - HTM_TD_End (); - - /* Write the question type (row[2]) */ - Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[2]); - HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd); - HTM_TxtF ("%s ",Txt_TST_STR_ANSWER_TYPES[Gbl.Test.AnswerType]); - HTM_TD_End (); - - /* Write if shuffle is enabled (row[3]) */ - HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd); - HTM_INPUT_CHECKBOX ("Shuffle",HTM_DONT_SUBMIT_ON_CHANGE, - "value=\"Y\"%s disabled=\"disabled\"", - row[3][0] == 'Y' ? " checked=\"checked\"" : - ""); - HTM_TD_End (); - - /* Write stem (row[4]) */ - HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd); - Tst_WriteQstStem (row[4],"TEST_EDI", - true); // Visible - - /***** Get and show media (row[6]) *****/ - Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[6]); - Med_GetMediaDataByCod (&Gbl.Test.Media); - Med_ShowMedia (&Gbl.Test.Media, - "TEST_MED_EDIT_LIST_CONT", - "TEST_MED_EDIT_LIST"); - - /* Write feedback (row[5]) */ - Tst_WriteQstFeedback (row[5],"TEST_EDI_LIGHT"); - - /* Write answers */ - Tst_WriteAnswersEdit (Gbl.Test.QstCod); - HTM_TD_End (); - HTM_TR_End (); - - /***** Destroy test question *****/ - Tst_QstDestructor (); + /***** Write question row *****/ + Tst_WriteQuestionRowForSelection (NumRow,QstCod); } /***** End table *****/ @@ -3126,6 +3107,119 @@ static void Tst_ListOneOrMoreQuestionsForSelection (unsigned long NumRows, Box_BoxEnd (); } +/*****************************************************************************/ +/********************** Write question row for selection *********************/ +/*****************************************************************************/ + +static void Tst_WriteQuestionRowForSelection (unsigned long NumRow,long QstCod) + { + extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES]; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + static unsigned UniqueId = 0; + char *Id; + time_t TimeUTC; + + /***** Get and show questvoidion data *****/ + if (Tst_GetOneQuestionByCod (QstCod,&mysql_res)) + { + /***** Get row of the result of the query *****/ + row = mysql_fetch_row (mysql_res); + /* + row[0] QstCod + row[1] UNIX_TIMESTAMP(EditTime) + row[2] AnsType + row[3] Shuffle + row[4] Stem + row[5] Feedback + row[6] MedCod + row[7] NumHits + row[8] NumHitsNotBlank + row[9] Score + */ + + /***** Create test question *****/ + Tst_QstConstructor (); + + /***** Begin table row *****/ + HTM_TR_Begin (NULL); + + /***** Icons *****/ + HTM_TD_Begin ("class=\"BT%u\"",Gbl.RowEvenOdd); + + /* Write checkbox to select the question */ + HTM_INPUT_CHECKBOX ("QstCods",HTM_DONT_SUBMIT_ON_CHANGE, + "value=\"%ld\"", + QstCod); + + /* Write number of question */ + HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd); + HTM_TxtF ("%lu ",NumRow + 1); + HTM_TD_End (); + + /* Write question code */ + HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd); + HTM_TxtF ("%ld ",QstCod); + HTM_TD_End (); + + /* Write the date (row[1] has the UTC date-time) */ + TimeUTC = Dat_GetUNIXTimeFromStr (row[1]); + if (asprintf (&Id,"tst_date_%u",++UniqueId) < 0) + Lay_NotEnoughMemoryExit (); + HTM_TD_Begin ("id=\"%s\" class=\"DAT_SMALL CT COLOR%u\">", + Id,Gbl.RowEvenOdd); + Dat_WriteLocalDateHMSFromUTC (Id,TimeUTC, + Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK, + true,true,false,0x7); + HTM_TD_End (); + free (Id); + + /* Write the question tags */ + HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd); + Tst_GetAndWriteTagsQst (QstCod); + HTM_TD_End (); + + /* Write the question type (row[2]) */ + Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[2]); + HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd); + HTM_TxtF ("%s ",Txt_TST_STR_ANSWER_TYPES[Gbl.Test.AnswerType]); + HTM_TD_End (); + + /* Write if shuffle is enabled (row[3]) */ + HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd); + HTM_INPUT_CHECKBOX ("Shuffle",HTM_DONT_SUBMIT_ON_CHANGE, + "value=\"Y\"%s disabled=\"disabled\"", + row[3][0] == 'Y' ? " checked=\"checked\"" : + ""); + HTM_TD_End (); + + /* Write stem (row[4]) */ + HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd); + Tst_WriteQstStem (row[4],"TEST_EDI", + true); // Visible + + /***** Get and show media (row[6]) *****/ + Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[6]); + Med_GetMediaDataByCod (&Gbl.Test.Media); + Med_ShowMedia (&Gbl.Test.Media, + "TEST_MED_EDIT_LIST_CONT", + "TEST_MED_EDIT_LIST"); + + /* Write feedback (row[5]) */ + Tst_WriteQstFeedback (row[5],"TEST_EDI_LIGHT"); + + /* Write answers */ + Tst_WriteAnswersEdit (QstCod); + HTM_TD_End (); + + /***** End table row *****/ + HTM_TR_End (); + + /***** Destroy test question *****/ + Tst_QstDestructor (); + } + } + /*****************************************************************************/ /*********** Write hidden parameters for edition of test questions ***********/ /*****************************************************************************/ @@ -4869,7 +4963,7 @@ static bool Tst_GetParamsTst (Tst_ActionToDoWithQuestions_t ActionToDoWithQuesti Gbl.Test.SelectedOrder = (Tst_QuestionsOrder_t) 0; /* Get whether we must create the XML file or not */ - Gbl.Test.XML.CreateXML = Tst_GetCreateXMLFromForm (); + // Gbl.Test.XML.CreateXML = Tst_GetCreateXMLFromForm (); break; case Tst_SELECT_QUESTIONS_FOR_GAME: /* Get starting and ending dates */ @@ -4910,15 +5004,6 @@ static void Tst_GetParamNumQst (void) (unsigned long) Gbl.Test.Config.Def); } -/*****************************************************************************/ -/****************** Get whether to create XML file from form *****************/ -/*****************************************************************************/ - -static bool Tst_GetCreateXMLFromForm (void) - { - return Par_GetParToBool ("CreateXML"); - } - /*****************************************************************************/ /***************** Count number of tags in the list of tags ******************/ /*****************************************************************************/ @@ -4983,18 +5068,19 @@ void Tst_FreeTagsList (void) void Tst_ShowFormEditOneQst (void) { + long QstCod; char Stem[Cns_MAX_BYTES_TEXT + 1]; char Feedback[Cns_MAX_BYTES_TEXT + 1]; /***** Create test question *****/ Tst_QstConstructor (); - Gbl.Test.QstCod = Tst_GetQstCod (); + QstCod = Tst_GetQstCod (); Stem[0] = Feedback[0] = '\0'; - if (Gbl.Test.QstCod > 0) // If question already exists in the database - Tst_GetQstDataFromDB (Stem,Feedback); + if (QstCod > 0) // If question already exists in the database + Tst_GetQstDataFromDB (QstCod,Stem,Feedback); /***** Put form to edit question *****/ - Tst_PutFormEditOneQst (Stem,Feedback); + Tst_PutFormEditOneQst (QstCod,Stem,Feedback); /***** Destroy test question *****/ Tst_QstDestructor (); @@ -5009,7 +5095,8 @@ void Tst_ShowFormEditOneQst (void) // 2. By clicking "Edit" icon in a listing of existing questions // 3. From the action associated to reception of a question, on error in the parameters received from the form -static void Tst_PutFormEditOneQst (char Stem[Cns_MAX_BYTES_TEXT + 1], +static void Tst_PutFormEditOneQst (long QstCod, + char Stem[Cns_MAX_BYTES_TEXT + 1], char Feedback[Cns_MAX_BYTES_TEXT + 1]) { extern const char *Hlp_ASSESSMENT_Tests_writing_a_question; @@ -5050,9 +5137,10 @@ static void Tst_PutFormEditOneQst (char Stem[Cns_MAX_BYTES_TEXT + 1], char *Title; /***** Begin box *****/ - if (Gbl.Test.QstCod > 0) // The question already has assigned a code + if (QstCod > 0) // The question already has assigned a code { - Box_BoxBegin (NULL,Str_BuildStringLong (Txt_Question_code_X,Gbl.Test.QstCod), + Tst_SetParamGblQstCod (QstCod); + Box_BoxBegin (NULL,Str_BuildStringLong (Txt_Question_code_X,QstCod), Tst_PutIconToRemoveOneQst, Hlp_ASSESSMENT_Tests_writing_a_question,Box_NOT_CLOSABLE); Str_FreeString (); @@ -5063,8 +5151,8 @@ static void Tst_PutFormEditOneQst (char Stem[Cns_MAX_BYTES_TEXT + 1], /***** Begin form *****/ Frm_StartForm (ActRcvTstQst); - if (Gbl.Test.QstCod > 0) // The question already has assigned a code - Tst_PutParamQstCod (); + if (QstCod > 0) // The question already has assigned a code + Tst_PutParamQstCod (QstCod); /***** Begin table *****/ HTM_TABLE_BeginPadding (2); // Table for this question @@ -5400,7 +5488,7 @@ static void Tst_PutFormEditOneQst (char Stem[Cns_MAX_BYTES_TEXT + 1], HTM_TABLE_End (); // Table for this question /***** Send button *****/ - if (Gbl.Test.QstCod > 0) // The question already has assigned a code + if (QstCod > 0) // The question already has assigned a code Btn_PutConfirmButton (Txt_Save_changes); else Btn_PutCreateButton (Txt_Create_question); @@ -5460,7 +5548,6 @@ void Tst_QstConstructor (void) { unsigned NumOpt; - Gbl.Test.QstCod = -1L; Gbl.Test.Stem.Text = NULL; Gbl.Test.Stem.Length = 0; Gbl.Test.Feedback.Text = NULL; @@ -5596,7 +5683,8 @@ static void Tst_FreeMediaOfQuestion (void) /****************** Get data of a question from database *********************/ /*****************************************************************************/ -static void Tst_GetQstDataFromDB (char Stem[Cns_MAX_BYTES_TEXT + 1], +static void Tst_GetQstDataFromDB (long QstCod, + char Stem[Cns_MAX_BYTES_TEXT + 1], char Feedback[Cns_MAX_BYTES_TEXT + 1]) { MYSQL_RES *mysql_res; @@ -5615,7 +5703,7 @@ static void Tst_GetQstDataFromDB (char Stem[Cns_MAX_BYTES_TEXT + 1], "MedCod" // row[4] " FROM tst_questions" " WHERE QstCod=%ld AND CrsCod=%ld", - Gbl.Test.QstCod,Gbl.Hierarchy.Crs.CrsCod); + QstCod,Gbl.Hierarchy.Crs.CrsCod); row = mysql_fetch_row (mysql_res); /* Get the type of answer */ @@ -5643,7 +5731,7 @@ static void Tst_GetQstDataFromDB (char Stem[Cns_MAX_BYTES_TEXT + 1], DB_FreeMySQLResult (&mysql_res); /***** Get the tags from the database *****/ - NumRows = Tst_GetTagsQst (Gbl.Test.QstCod,&mysql_res); + NumRows = Tst_GetTagsQst (QstCod,&mysql_res); for (NumRow = 0; NumRow < NumRows; NumRow++) @@ -5657,7 +5745,7 @@ static void Tst_GetQstDataFromDB (char Stem[Cns_MAX_BYTES_TEXT + 1], DB_FreeMySQLResult (&mysql_res); /***** Get the answers from the database *****/ - Gbl.Test.Answer.NumOptions = Tst_GetAnswersQst (Gbl.Test.QstCod,&mysql_res,false); + Gbl.Test.Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,false); /* row[0] AnsInd row[1] Answer @@ -5726,14 +5814,14 @@ static void Tst_GetQstDataFromDB (char Stem[Cns_MAX_BYTES_TEXT + 1], // NumOpt < 0 ==> media associated to stem // NumOpt >= 0 ==> media associated to answer -static long Tst_GetMedCodFromDB (int NumOpt) +static long Tst_GetMedCodFromDB (long CrsCod,long QstCod,int NumOpt) { MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned long NumRows; long MedCod = -1L; - if (Gbl.Test.QstCod > 0) // Existing question + if (QstCod > 0) // Existing question { /***** Query depending on NumOpt *****/ if (NumOpt < 0) @@ -5742,14 +5830,14 @@ static long Tst_GetMedCodFromDB (int NumOpt) "SELECT MedCod" // row[0] " FROM tst_questions" " WHERE QstCod=%ld AND CrsCod=%ld", - Gbl.Test.QstCod,Gbl.Hierarchy.Crs.CrsCod); + QstCod,CrsCod); else // Get media associated to answer NumRows = DB_QuerySELECT (&mysql_res,"can not get media", "SELECT MedCod" // row[0] " FROM tst_answers" " WHERE QstCod=%ld AND AnsInd=%u", - Gbl.Test.QstCod,(unsigned) NumOpt); + QstCod,(unsigned) NumOpt); if (NumRows) { @@ -5776,10 +5864,11 @@ static long Tst_GetMedCodFromDB (int NumOpt) // NumOpt < 0 ==> media associated to stem // NumOpt >= 0 ==> media associated to an answer option -static void Tst_GetMediaFromDB (int NumOpt,struct Media *Media) +static void Tst_GetMediaFromDB (long CrsCod,long QstCod,int NumOpt, + struct Media *Media) { /***** Get media *****/ - Media->MedCod = Tst_GetMedCodFromDB (NumOpt); + Media->MedCod = Tst_GetMedCodFromDB (CrsCod,QstCod,NumOpt); Med_GetMediaDataByCod (Media); } @@ -5823,6 +5912,7 @@ static Tst_AnswerType_t Tst_ConvertFromUnsignedStrToAnsTyp (const char *Unsigned void Tst_ReceiveQst (void) { + long QstCod; char Stem[Cns_MAX_BYTES_TEXT + 1]; char Feedback[Cns_MAX_BYTES_TEXT + 1]; @@ -5831,19 +5921,19 @@ void Tst_ReceiveQst (void) /***** Get parameters of the question from form *****/ Stem[0] = Feedback[0] = '\0'; - Tst_GetQstFromForm (Stem,Feedback); + QstCod = Tst_GetQstFromForm (Stem,Feedback); /***** Make sure that tags, text and answer are not empty *****/ if (Tst_CheckIfQstFormatIsCorrectAndCountNumOptions ()) { /***** Move images to definitive directories *****/ - Tst_MoveMediaToDefinitiveDirectories (); + Tst_MoveMediaToDefinitiveDirectories (QstCod); /***** Insert or update question, tags and answer in the database *****/ - Tst_InsertOrUpdateQstTagsAnsIntoDB (); + QstCod = Tst_InsertOrUpdateQstTagsAnsIntoDB (QstCod); /***** Show the question just inserted in the database *****/ - Tst_ListOneQstToEdit (); + Tst_ListOneQstToEdit (QstCod); } else // Question is wrong { @@ -5851,7 +5941,7 @@ void Tst_ReceiveQst (void) Tst_ResetMediaOfQuestion (); /***** Put form to edit question again *****/ - Tst_PutFormEditOneQst (Stem,Feedback); + Tst_PutFormEditOneQst (QstCod,Stem,Feedback); } /***** Destroy test question *****/ @@ -5862,8 +5952,9 @@ void Tst_ReceiveQst (void) /**************** Get parameters of a test question from form ****************/ /*****************************************************************************/ -static void Tst_GetQstFromForm (char *Stem,char *Feedback) +static long Tst_GetQstFromForm (char *Stem,char *Feedback) { + long QstCod; unsigned NumTag; unsigned NumTagRead; unsigned NumOpt; @@ -5877,7 +5968,7 @@ static void Tst_GetQstFromForm (char *Stem,char *Feedback) unsigned NumCorrectAns; /***** Get question code *****/ - Gbl.Test.QstCod = Tst_GetQstCod (); + QstCod = Tst_GetQstCod (); /***** Get answer type *****/ Gbl.Test.AnswerType = (Tst_AnswerType_t) @@ -5924,8 +6015,10 @@ static void Tst_GetQstFromForm (char *Stem,char *Feedback) Gbl.Test.Media.Width = Tst_IMAGE_SAVED_MAX_WIDTH; Gbl.Test.Media.Height = Tst_IMAGE_SAVED_MAX_HEIGHT; Gbl.Test.Media.Quality = Tst_IMAGE_SAVED_QUALITY; - Med_GetMediaFromForm (-1, // < 0 ==> the image associated to the stem - &Gbl.Test.Media,Tst_GetMediaFromDB, + Med_GetMediaFromForm (Gbl.Hierarchy.Crs.CrsCod,QstCod, + -1, // < 0 ==> the image associated to the stem + &Gbl.Test.Media, + Tst_GetMediaFromDB, NULL); Ale_ShowAlerts (NULL); @@ -6001,7 +6094,8 @@ static void Tst_GetQstFromForm (char *Stem,char *Feedback) Gbl.Test.Answer.Options[NumOpt].Media.Width = Tst_IMAGE_SAVED_MAX_WIDTH; Gbl.Test.Answer.Options[NumOpt].Media.Height = Tst_IMAGE_SAVED_MAX_HEIGHT; Gbl.Test.Answer.Options[NumOpt].Media.Quality = Tst_IMAGE_SAVED_QUALITY; - Med_GetMediaFromForm ((int) NumOpt, // >= 0 ==> the image associated to an answer + Med_GetMediaFromForm (Gbl.Hierarchy.Crs.CrsCod,QstCod, + (int) NumOpt, // >= 0 ==> the image associated to an answer &Gbl.Test.Answer.Options[NumOpt].Media, Tst_GetMediaFromDB, NULL); @@ -6053,6 +6147,8 @@ static void Tst_GetQstFromForm (char *Stem,char *Feedback) Gbl.Test.Stem.Length = strlen (Gbl.Test.Stem.Text); Gbl.Test.Feedback.Text = Feedback; Gbl.Test.Feedback.Length = strlen (Gbl.Test.Feedback.Text); + + return QstCod; } /*****************************************************************************/ @@ -6277,6 +6373,7 @@ bool Tst_CheckIfQuestionExistsInDB (void) !IdenticalQuestionFound && NumQst < NumQstsWithThisStem; NumQst++) { + /* Get question code */ row = mysql_fetch_row (mysql_res_qst); if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) Lay_ShowErrorAndExit ("Wrong code of question."); @@ -6349,13 +6446,14 @@ bool Tst_CheckIfQuestionExistsInDB (void) /* Move images associates to a test question to their definitive directories */ /*****************************************************************************/ -static void Tst_MoveMediaToDefinitiveDirectories (void) +static void Tst_MoveMediaToDefinitiveDirectories (long QstCod) { unsigned NumOpt; long CurrentMedCodInDB; /***** Media associated to question stem *****/ - CurrentMedCodInDB = Tst_GetMedCodFromDB (-1L); // Get current media code associated to stem + CurrentMedCodInDB = Tst_GetMedCodFromDB (Gbl.Hierarchy.Crs.CrsCod,QstCod, + -1L); // Get current media code associated to stem Med_RemoveKeepOrStoreMedia (CurrentMedCodInDB,&Gbl.Test.Media); /****** Move media associated to answers *****/ @@ -6365,7 +6463,8 @@ static void Tst_MoveMediaToDefinitiveDirectories (void) NumOpt < Gbl.Test.Answer.NumOptions; NumOpt++) { - CurrentMedCodInDB = Tst_GetMedCodFromDB (NumOpt); // Get current media code associated to this option + CurrentMedCodInDB = Tst_GetMedCodFromDB (Gbl.Hierarchy.Crs.CrsCod,QstCod, + NumOpt); // Get current media code associated to this option Med_RemoveKeepOrStoreMedia (CurrentMedCodInDB,&Gbl.Test.Answer.Options[NumOpt].Media); } } @@ -6460,29 +6559,107 @@ static void Tst_EnableOrDisableTag (long TagCod,bool TagHidden) TagCod,Gbl.Hierarchy.Crs.CrsCod); } +/*****************************************************************************/ +/***************** Request the removal of selected questions *****************/ +/*****************************************************************************/ + +void Tst_RequestRemoveSelectedQsts (void) + { + extern const char *Txt_Do_you_really_want_to_remove_the_selected_questions; + extern const char *Txt_Remove_questions; + + /***** Get parameters *****/ + if (Tst_GetParamsTst (Tst_EDIT_TEST)) // Get parameters from the form + /***** Show question and button to remove question *****/ + Ale_ShowAlertAndButton (ActRemSevTstQst,NULL,NULL, + Tst_PutParamsRemoveSelectedQsts, + Btn_REMOVE_BUTTON,Txt_Remove_questions, + Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_selected_questions); + else + Ale_ShowAlert (Ale_ERROR,"Wrong parameters."); + + /***** Free memory used by the list of tags *****/ + Tst_FreeTagsList (); + + /***** Continue editing questions *****/ + Tst_ListQuestionsToEdit (); + } + +/*****************************************************************************/ +/**************** Put parameters to remove selected questions ****************/ +/*****************************************************************************/ + +static void Tst_PutParamsRemoveSelectedQsts (void) + { + Dat_WriteParamsIniEndDates (); + Tst_WriteParamEditQst (); + } + +/*****************************************************************************/ +/************************** Remove several questions *************************/ +/*****************************************************************************/ + +void Tst_RemoveSelectedQsts (void) + { + extern const char *Txt_Questions_removed_X; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumRows; + unsigned NumRow; + long QstCod; + + /***** Get parameters *****/ + if (Tst_GetParamsTst (Tst_EDIT_TEST)) // Get parameters + { + /***** Get question codes *****/ + NumRows = (unsigned) Tst_GetQuestions (&mysql_res); // Query database + + /***** Remove questions one by one *****/ + for (NumRow = 0; + NumRow < NumRows; + NumRow++) + { + /* Get question code (row[0]) */ + row = mysql_fetch_row (mysql_res); + if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) + Lay_ShowErrorAndExit ("Wrong code of question."); + + /* Remove test question from database */ + Tst_RemoveOneQstFromDB (Gbl.Hierarchy.Crs.CrsCod,QstCod); + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + + /***** Write message *****/ + Ale_ShowAlert (Ale_SUCCESS,Txt_Questions_removed_X,NumRows); + } + } + /*****************************************************************************/ /********************* Put icon to remove one question ***********************/ /*****************************************************************************/ static void Tst_PutIconToRemoveOneQst (void) { - Ico_PutContextualIconToRemove (ActReqRemTstQst,Tst_PutParamsRemoveOneQst); + Ico_PutContextualIconToRemove (ActReqRemOneTstQst,Tst_PutParamsRemoveOnlyThisQst); } /*****************************************************************************/ /******************** Request the removal of a question **********************/ /*****************************************************************************/ -void Tst_RequestRemoveQst (void) +void Tst_RequestRemoveOneQst (void) { extern const char *Txt_Do_you_really_want_to_remove_the_question_X; extern const char *Txt_Remove_question; + long QstCod; bool EditingOnlyThisQst; /***** Get main parameters from form *****/ /* Get the question code */ - Gbl.Test.QstCod = Tst_GetQstCod (); - if (Gbl.Test.QstCod <= 0) + QstCod = Tst_GetQstCod (); + if (QstCod <= 0) Lay_ShowErrorAndExit ("Wrong code of question."); /* Get a parameter that indicates whether it's necessary @@ -6495,16 +6672,17 @@ void Tst_RequestRemoveQst (void) Lay_ShowErrorAndExit ("Wrong test parameters."); /***** Show question and button to remove question *****/ - Ale_ShowAlertAndButton (ActRemTstQst,NULL,NULL, - EditingOnlyThisQst ? Tst_PutParamsRemoveOneQst : - Tst_PutParamsRemoveQst, + Tst_SetParamGblQstCod (QstCod); + Ale_ShowAlertAndButton (ActRemOneTstQst,NULL,NULL, + EditingOnlyThisQst ? Tst_PutParamsRemoveOnlyThisQst : + Tst_PutParamsRemoveOneQstWhileEditing, Btn_REMOVE_BUTTON,Txt_Remove_question, Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_question_X, - Gbl.Test.QstCod); + QstCod); /***** Continue editing questions *****/ if (EditingOnlyThisQst) - Tst_ListOneQstToEdit (); + Tst_ListOneQstToEdit (QstCod); else { Tst_FreeTagsList (); @@ -6513,22 +6691,22 @@ void Tst_RequestRemoveQst (void) } /*****************************************************************************/ -/***** Put parameter to remove question when editing only one question *******/ +/***** Put parameters to remove question when editing only one question ******/ /*****************************************************************************/ -static void Tst_PutParamsRemoveOneQst (void) +static void Tst_PutParamsRemoveOnlyThisQst (void) { - Tst_PutParamQstCod (); + Tst_PutParamGblQstCod (); Par_PutHiddenParamChar ("OnlyThisQst",'Y'); } /*****************************************************************************/ -/***** Put parameter to remove question when editing several questions *******/ +/***** Put parameters to remove question when editing several questions ******/ /*****************************************************************************/ -static void Tst_PutParamsRemoveQst (void) +static void Tst_PutParamsRemoveOneQstWhileEditing (void) { - Tst_PutParamQstCod (); + Tst_PutParamGblQstCod (); Dat_WriteParamsIniEndDates (); Tst_WriteParamEditQst (); } @@ -6537,43 +6715,23 @@ static void Tst_PutParamsRemoveQst (void) /***************************** Remove a question *****************************/ /*****************************************************************************/ -void Tst_RemoveQst (void) +void Tst_RemoveOneQst (void) { extern const char *Txt_Question_removed; + long QstCod; bool EditingOnlyThisQst; - long MedCod; /***** Get the question code *****/ - Gbl.Test.QstCod = Tst_GetQstCod (); - if (Gbl.Test.QstCod <= 0) + QstCod = Tst_GetQstCod (); + if (QstCod <= 0) Lay_ShowErrorAndExit ("Wrong code of question."); /***** Get a parameter that indicates whether it's necessary to continue listing the rest of questions ******/ EditingOnlyThisQst = Par_GetParToBool ("OnlyThisQst"); - /***** Remove media associated to question *****/ - /* Remove media associated to answers */ - Tst_RemoveMediaFromAllAnsOfQst (Gbl.Hierarchy.Crs.CrsCod,Gbl.Test.QstCod); - - /* Remove media associated to stem */ - MedCod = Tst_GetMedCodFromDB (-1L); - Med_RemoveMedia (MedCod); - - /***** Remove the question from all the tables *****/ - /* Remove answers and tags from this test question */ - Tst_RemAnsFromQst (); - Tst_RemTagsFromQst (); - Tst_RemoveUnusedTagsFromCurrentCrs (); - - /* Remove the question itself */ - DB_QueryDELETE ("can not remove a question", - "DELETE FROM tst_questions" - " WHERE QstCod=%ld AND CrsCod=%ld", - Gbl.Test.QstCod,Gbl.Hierarchy.Crs.CrsCod); - - if (!mysql_affected_rows (&Gbl.mysql)) - Lay_ShowErrorAndExit ("Wrong question."); + /***** Remove test question from database *****/ + Tst_RemoveOneQstFromDB (Gbl.Hierarchy.Crs.CrsCod,QstCod); /***** Write message *****/ Ale_ShowAlert (Ale_SUCCESS,Txt_Question_removed); @@ -6583,6 +6741,39 @@ void Tst_RemoveQst (void) Tst_ListQuestionsToEdit (); } +/*****************************************************************************/ +/********************** Remove a question from database **********************/ +/*****************************************************************************/ + +static void Tst_RemoveOneQstFromDB (long CrsCod,long QstCod) + { + long MedCod; + + /***** Remove media associated to question *****/ + /* Remove media associated to answers */ + Tst_RemoveMediaFromAllAnsOfQst (CrsCod,QstCod); + + /* Remove media associated to stem */ + MedCod = Tst_GetMedCodFromDB (CrsCod,QstCod, + -1L); // Get current media code associated to stem + Med_RemoveMedia (MedCod); + + /***** Remove the question from all the tables *****/ + /* Remove answers and tags from this test question */ + Tst_RemAnsFromQst (QstCod); + Tst_RemTagsFromQst (QstCod); + Tst_RemoveUnusedTagsFromCrs (CrsCod); + + /* Remove the question itself */ + DB_QueryDELETE ("can not remove a question", + "DELETE FROM tst_questions" + " WHERE QstCod=%ld AND CrsCod=%ld", + QstCod,CrsCod); + + if (!mysql_affected_rows (&Gbl.mysql)) + Lay_ShowErrorAndExit ("Wrong question."); + } + /*****************************************************************************/ /*********************** Change the shuffle of a question ********************/ /*****************************************************************************/ @@ -6591,12 +6782,13 @@ void Tst_ChangeShuffleQst (void) { extern const char *Txt_The_answers_of_the_question_with_code_X_will_appear_shuffled; extern const char *Txt_The_answers_of_the_question_with_code_X_will_appear_without_shuffling; + long QstCod; bool EditingOnlyThisQst; bool Shuffle; /***** Get the question code *****/ - Gbl.Test.QstCod = Tst_GetQstCod (); - if (Gbl.Test.QstCod <= 0) + QstCod = Tst_GetQstCod (); + if (QstCod <= 0) Lay_ShowErrorAndExit ("Wrong code of question."); /***** Get a parameter that indicates whether it's necessary to continue listing the rest of questions ******/ @@ -6612,16 +6804,16 @@ void Tst_ChangeShuffleQst (void) " WHERE QstCod=%ld AND CrsCod=%ld", Shuffle ? 'Y' : 'N', - Gbl.Test.QstCod,Gbl.Hierarchy.Crs.CrsCod); + QstCod,Gbl.Hierarchy.Crs.CrsCod); /***** Write message *****/ Ale_ShowAlert (Ale_SUCCESS,Shuffle ? Txt_The_answers_of_the_question_with_code_X_will_appear_shuffled : Txt_The_answers_of_the_question_with_code_X_will_appear_without_shuffling, - Gbl.Test.QstCod); + QstCod); /***** Continue editing questions *****/ if (EditingOnlyThisQst) - Tst_ListOneQstToEdit (); + Tst_ListOneQstToEdit (QstCod); else Tst_ListQuestionsToEdit (); } @@ -6640,40 +6832,59 @@ static long Tst_GetQstCod (void) /************ Put parameter with question code to edit, remove... ************/ /*****************************************************************************/ -void Tst_PutParamQstCod (void) +void Tst_SetParamGblQstCod (long QstCod) { - Par_PutHiddenParamLong (NULL,"QstCod",Gbl.Test.QstCod); + Tst_ParamGblQstCod = QstCod; + } + +long Tst_GetParamGblQstCod (void) + { + return Tst_ParamGblQstCod; + } + +void Tst_PutParamGblQstCod (void) + { + Tst_PutParamQstCod (Tst_GetParamGblQstCod ()); + } + +void Tst_PutParamQstCod (long QstCod) + { + Par_PutHiddenParamLong (NULL,"QstCod",QstCod); } /*****************************************************************************/ /******** Insert or update question, tags and anser in the database **********/ /*****************************************************************************/ -void Tst_InsertOrUpdateQstTagsAnsIntoDB (void) +long Tst_InsertOrUpdateQstTagsAnsIntoDB (long QstCod) { /***** Insert or update question in the table of questions *****/ - Tst_InsertOrUpdateQstIntoDB (); + QstCod = Tst_InsertOrUpdateQstIntoDB (QstCod); + if (QstCod > 0) + { + /***** Insert tags in the tags table *****/ + Tst_InsertTagsIntoDB (QstCod); - /***** Insert tags in the tags table *****/ - Tst_InsertTagsIntoDB (); + /***** Remove unused tags in current course *****/ + Tst_RemoveUnusedTagsFromCrs (Gbl.Hierarchy.Crs.CrsCod); - /***** Remove unused tags in current course *****/ - Tst_RemoveUnusedTagsFromCurrentCrs (); + /***** Insert answers in the answers table *****/ + Tst_InsertAnswersIntoDB (QstCod); + } - /***** Insert answers in the answers table *****/ - Tst_InsertAnswersIntoDB (); + return QstCod; } /*****************************************************************************/ /*********** Insert or update question in the table of questions *************/ /*****************************************************************************/ -static void Tst_InsertOrUpdateQstIntoDB (void) +static long Tst_InsertOrUpdateQstIntoDB (long QstCod) { - if (Gbl.Test.QstCod < 0) // It's a new question + if (QstCod < 0) // It's a new question { /***** Insert question in the table of questions *****/ - Gbl.Test.QstCod = + QstCod = DB_QueryINSERTandReturnCode ("can not create question", "INSERT INTO tst_questions" " (CrsCod,EditTime,AnsType,Shuffle," @@ -6691,7 +6902,7 @@ static void Tst_InsertOrUpdateQstIntoDB (void) Gbl.Test.Feedback.Text ? Gbl.Test.Feedback.Text : "", Gbl.Test.Media.MedCod); } - else // It's an existing question + else // It's an existing question { /***** Update existing question *****/ /* Update question in database */ @@ -6706,19 +6917,21 @@ static void Tst_InsertOrUpdateQstIntoDB (void) Gbl.Test.Stem.Text, Gbl.Test.Feedback.Text ? Gbl.Test.Feedback.Text : "", Gbl.Test.Media.MedCod, - Gbl.Test.QstCod,Gbl.Hierarchy.Crs.CrsCod); + QstCod,Gbl.Hierarchy.Crs.CrsCod); /* Remove answers and tags from this test question */ - Tst_RemAnsFromQst (); - Tst_RemTagsFromQst (); + Tst_RemAnsFromQst (QstCod); + Tst_RemTagsFromQst (QstCod); } + + return QstCod; } /*****************************************************************************/ /*********************** Insert tags in the tags table ***********************/ /*****************************************************************************/ -static void Tst_InsertTagsIntoDB (void) +static void Tst_InsertTagsIntoDB (long QstCod) { unsigned NumTag; unsigned TagIdx; @@ -6741,7 +6954,7 @@ static void Tst_InsertTagsIntoDB (void) " (QstCod,TagCod,TagInd)" " VALUES" " (%ld,%ld,%u)", - Gbl.Test.QstCod,TagCod,TagIdx); + QstCod,TagCod,TagIdx); TagIdx++; } @@ -6751,7 +6964,7 @@ static void Tst_InsertTagsIntoDB (void) /******************* Insert answers in the answers table *********************/ /*****************************************************************************/ -static void Tst_InsertAnswersIntoDB (void) +static void Tst_InsertAnswersIntoDB (long QstCod) { unsigned NumOpt; unsigned i; @@ -6765,7 +6978,7 @@ static void Tst_InsertAnswersIntoDB (void) " (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)" " VALUES" " (%ld,0,%ld,'',-1,'Y')", - Gbl.Test.QstCod, + QstCod, Gbl.Test.Answer.Integer); break; case Tst_ANS_FLOAT: @@ -6778,7 +6991,7 @@ static void Tst_InsertAnswersIntoDB (void) " (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)" " VALUES" " (%ld,%u,'%.15lg','',-1,'Y')", - Gbl.Test.QstCod,i, + QstCod,i, Gbl.Test.Answer.FloatingPoint[i]); Str_SetDecimalPointToLocal (); // Return to local system break; @@ -6788,7 +7001,7 @@ static void Tst_InsertAnswersIntoDB (void) " (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)" " VALUES" " (%ld,0,'%c','',-1,'Y')", - Gbl.Test.QstCod, + QstCod, Gbl.Test.Answer.TF); break; case Tst_ANS_UNIQUE_CHOICE: @@ -6805,7 +7018,7 @@ static void Tst_InsertAnswersIntoDB (void) " (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)" " VALUES" " (%ld,%u,'%s','%s',%ld,'%c')", - Gbl.Test.QstCod,NumOpt, + QstCod,NumOpt, Gbl.Test.Answer.Options[NumOpt].Text, Gbl.Test.Answer.Options[NumOpt].Feedback ? Gbl.Test.Answer.Options[NumOpt].Feedback : "", Gbl.Test.Answer.Options[NumOpt].Media.MedCod, @@ -6874,31 +7087,31 @@ void Tst_RemoveCrsTests (long CrsCod) /******************** Remove answers from a test question ********************/ /*****************************************************************************/ -static void Tst_RemAnsFromQst (void) +static void Tst_RemAnsFromQst (long QstCod) { /***** Remove answers *****/ DB_QueryDELETE ("can not remove the answers of a question", "DELETE FROM tst_answers WHERE QstCod=%ld", - Gbl.Test.QstCod); + QstCod); } /*****************************************************************************/ /************************** Remove tags from a test question *****************/ /*****************************************************************************/ -static void Tst_RemTagsFromQst (void) +static void Tst_RemTagsFromQst (long QstCod) { /***** Remove tags *****/ DB_QueryDELETE ("can not remove the tags of a question", "DELETE FROM tst_question_tags WHERE QstCod=%ld", - Gbl.Test.QstCod); + QstCod); } /*****************************************************************************/ -/******************** Remove unused tags in current course *******************/ +/********************** Remove unused tags in a course ***********************/ /*****************************************************************************/ -static void Tst_RemoveUnusedTagsFromCurrentCrs (void) +static void Tst_RemoveUnusedTagsFromCrs (long CrsCod) { /***** Remove unused tags from tst_tags *****/ DB_QueryDELETE ("can not remove unused tags", @@ -6908,8 +7121,8 @@ static void Tst_RemoveUnusedTagsFromCurrentCrs (void) " FROM tst_questions,tst_question_tags" " WHERE tst_questions.CrsCod=%ld" " AND tst_questions.QstCod=tst_question_tags.QstCod)", - Gbl.Hierarchy.Crs.CrsCod, - Gbl.Hierarchy.Crs.CrsCod); + CrsCod, + CrsCod); } /*****************************************************************************/ diff --git a/swad_test.h b/swad_test.h index ad704209..62d0778c 100644 --- a/swad_test.h +++ b/swad_test.h @@ -193,13 +193,20 @@ bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (void); bool Tst_CheckIfQuestionExistsInDB (void); long Tst_GetIntAnsFromStr (char *Str); -void Tst_RequestRemoveQst (void); -void Tst_RemoveQst (void); + +void Tst_RequestRemoveSelectedQsts (void); +void Tst_RemoveSelectedQsts (void); +void Tst_RequestRemoveOneQst (void); +void Tst_RemoveOneQst (void); + void Tst_ChangeShuffleQst (void); -void Tst_PutParamQstCod (void); +void Tst_SetParamGblQstCod (long QstCod); +long Tst_GetParamGblQstCod (void); +void Tst_PutParamGblQstCod (void); +void Tst_PutParamQstCod (long QstCod); -void Tst_InsertOrUpdateQstTagsAnsIntoDB (void); +long Tst_InsertOrUpdateQstTagsAnsIntoDB (long QstCod); void Tst_RemoveCrsTests (long CrsCod); diff --git a/swad_test_import.c b/swad_test_import.c index 39c35a77..69eeb230 100644 --- a/swad_test_import.c +++ b/swad_test_import.c @@ -66,9 +66,12 @@ extern struct Globals Gbl; /*****************************************************************************/ static void TsI_PutParamsExportQsts (void); +static void TsI_PutCreateXMLParam (void); -static void TsI_GetAndWriteTagsXML (long QstCod); -static void TsI_WriteAnswersOfAQstXML (long QstCod); +static void TsI_ExportQuestion (long QstCod,FILE *FileXML); + +static void TsI_GetAndWriteTagsXML (long QstCod,FILE *FileXML); +static void TsI_WriteAnswersOfAQstXML (long QstCod,FILE *FileXML); static void TsI_ReadQuestionsFromXMLFileAndStoreInDB (const char *FileNameXML); static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer); static Tst_AnswerType_t TsI_ConvertFromStrAnsTypXMLToAnsTyp (const char *StrAnsTypeXML); @@ -102,9 +105,23 @@ static void TsI_PutParamsExportQsts (void) Tst_WriteParamEditQst (); Par_PutHiddenParamChar ("OnlyThisQst",'N'); Par_PutHiddenParamUnsigned (NULL,"Order",(unsigned) Gbl.Test.SelectedOrder); + TsI_PutCreateXMLParam (); + } + +/*****************************************************************************/ +/************************ Parameter to create XML file ***********************/ +/*****************************************************************************/ + +static void TsI_PutCreateXMLParam (void) + { Par_PutHiddenParamChar ("CreateXML",'Y'); } +bool TsI_GetCreateXMLParamFromForm (void) + { + return Par_GetParToBool ("CreateXML"); + } + /*****************************************************************************/ /*************** Put a link (form) to import test questions ******************/ /*****************************************************************************/ @@ -157,10 +174,10 @@ void TsI_ShowFormImportQstsFromXML (void) void TsI_CreateXML (unsigned long NumRows,MYSQL_RES *mysql_res) { extern const char *The_ClassFormOutBoxBold[The_NUM_THEMES]; - extern const char *Tst_StrAnswerTypesXML[Tst_NUM_ANS_TYPES]; extern const char *Txt_NEW_LINE; extern const char *Txt_XML_file; char PathPubFile[PATH_MAX + 1]; + FILE *FileXML; unsigned long NumRow; MYSQL_ROW row; long QstCod; @@ -175,77 +192,31 @@ void TsI_CreateXML (unsigned long NumRows,MYSQL_RES *mysql_res) Cfg_PATH_FILE_BROWSER_TMP_PUBLIC, Gbl.FileBrowser.TmpPubDir.L, Gbl.FileBrowser.TmpPubDir.R); - if ((Gbl.Test.XML.FileXML = fopen (PathPubFile,"wb")) == NULL) + if ((FileXML = fopen (PathPubFile,"wb")) == NULL) Lay_ShowErrorAndExit ("Can not open target file."); /***** Start XML file *****/ - XML_WriteStartFile (Gbl.Test.XML.FileXML,"test",false); - fprintf (Gbl.Test.XML.FileXML,"%s",Txt_NEW_LINE); + XML_WriteStartFile (FileXML,"test",false); + fprintf (FileXML,"%s",Txt_NEW_LINE); /***** Write rows *****/ for (NumRow = 0; NumRow < NumRows; NumRow++) { + /* Get question code (row[0]) */ row = mysql_fetch_row (mysql_res); - /* - row[0] QstCod - row[1] UNIX_TIMESTAMP(EditTime) - row[2] AnsType - row[3] Shuffle - row[4] Stem - row[5] Feedback - row[6] MedCod - row[7] NumHits - row[8] NumHitsNotBlank - row[9] Score - */ - /* row[0] holds the code of the question */ if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0) Lay_ShowErrorAndExit ("Wrong code of question."); - /* Write the question type (row[2]) */ - Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[2]); - fprintf (Gbl.Test.XML.FileXML,"%s", - Tst_StrAnswerTypesXML[Gbl.Test.AnswerType],Txt_NEW_LINE); - - /* Write the question tags */ - fprintf (Gbl.Test.XML.FileXML,"%s",Txt_NEW_LINE); - TsI_GetAndWriteTagsXML (QstCod); - fprintf (Gbl.Test.XML.FileXML,"%s",Txt_NEW_LINE); - - /* Write the stem (row[4]), that is in HTML format */ - fprintf (Gbl.Test.XML.FileXML,"%s%s", - row[4],Txt_NEW_LINE); - - /* Write the feedback (row[5]), that is in HTML format */ - if (row[5]) - if (row[5][0]) - fprintf (Gbl.Test.XML.FileXML,"%s%s", - row[5],Txt_NEW_LINE); - - /* Write the answers of this question. - Shuffle can be enabled or disabled (row[3]) */ - fprintf (Gbl.Test.XML.FileXML,""); - TsI_WriteAnswersOfAQstXML (QstCod); - fprintf (Gbl.Test.XML.FileXML,"%s",Txt_NEW_LINE); - - /* End question */ - fprintf (Gbl.Test.XML.FileXML,"%s%s", - Txt_NEW_LINE,Txt_NEW_LINE); + TsI_ExportQuestion (QstCod,FileXML); } /***** End XML file *****/ - XML_WriteEndFile (Gbl.Test.XML.FileXML,"test"); + XML_WriteEndFile (FileXML,"test"); /***** Close the XML file *****/ - fclose (Gbl.Test.XML.FileXML); + fclose (FileXML); /***** Return to start of query result *****/ mysql_data_seek (mysql_res,0); @@ -261,11 +232,77 @@ void TsI_CreateXML (unsigned long NumRows,MYSQL_RES *mysql_res) HTM_A_End (); } +/*****************************************************************************/ +/****************** Write one question into the XML file *********************/ +/*****************************************************************************/ + +static void TsI_ExportQuestion (long QstCod,FILE *FileXML) + { + extern const char *Tst_StrAnswerTypesXML[Tst_NUM_ANS_TYPES]; + extern const char *Txt_NEW_LINE; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + + if (Tst_GetOneQuestionByCod (QstCod,&mysql_res)) + { + /***** Get row *****/ + row = mysql_fetch_row (mysql_res); + /* + row[0] QstCod + row[1] UNIX_TIMESTAMP(EditTime) + row[2] AnsType + row[3] Shuffle + row[4] Stem + row[5] Feedback + row[6] MedCod + row[7] NumHits + row[8] NumHitsNotBlank + row[9] Score + */ + + /***** Write the question type (row[2]) *****/ + Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[2]); + fprintf (FileXML,"%s", + Tst_StrAnswerTypesXML[Gbl.Test.AnswerType],Txt_NEW_LINE); + + /***** Write the question tags *****/ + fprintf (FileXML,"%s",Txt_NEW_LINE); + TsI_GetAndWriteTagsXML (QstCod,FileXML); + fprintf (FileXML,"%s",Txt_NEW_LINE); + + /***** Write the stem (row[4]), that is in HTML format *****/ + fprintf (FileXML,"%s%s", + row[4],Txt_NEW_LINE); + + /***** Write the feedback (row[5]), that is in HTML format *****/ + if (row[5]) + if (row[5][0]) + fprintf (FileXML,"%s%s", + row[5],Txt_NEW_LINE); + + /***** Write the answers of this question. + Shuffle can be enabled or disabled (row[3]) *****/ + fprintf (FileXML,""); + TsI_WriteAnswersOfAQstXML (QstCod,FileXML); + fprintf (FileXML,"%s",Txt_NEW_LINE); + + /***** End question *****/ + fprintf (FileXML,"%s%s", + Txt_NEW_LINE,Txt_NEW_LINE); + } + } + /*****************************************************************************/ /************* Get and write tags of a question into the XML file ************/ /*****************************************************************************/ -static void TsI_GetAndWriteTagsXML (long QstCod) +static void TsI_GetAndWriteTagsXML (long QstCod,FILE *FileXML) { extern const char *Txt_NEW_LINE; unsigned long NumRow; @@ -280,7 +317,7 @@ static void TsI_GetAndWriteTagsXML (long QstCod) NumRow++) { row = mysql_fetch_row (mysql_res); - fprintf (Gbl.Test.XML.FileXML,"%s%s", + fprintf (FileXML,"%s%s", row[0],Txt_NEW_LINE); } @@ -292,7 +329,7 @@ static void TsI_GetAndWriteTagsXML (long QstCod) /**************** Get and write the answers of a test question ***************/ /*****************************************************************************/ -static void TsI_WriteAnswersOfAQstXML (long QstCod) +static void TsI_WriteAnswersOfAQstXML (long QstCod,FILE *FileXML) { extern const char *Txt_NEW_LINE; unsigned NumOpt; @@ -315,7 +352,7 @@ static void TsI_WriteAnswersOfAQstXML (long QstCod) case Tst_ANS_INT: Tst_CheckIfNumberOfAnswersIsOne (); row = mysql_fetch_row (mysql_res); - fprintf (Gbl.Test.XML.FileXML,"%ld", + fprintf (FileXML,"%ld", Tst_GetIntAnsFromStr (row[1])); break; case Tst_ANS_FLOAT: @@ -329,9 +366,9 @@ static void TsI_WriteAnswersOfAQstXML (long QstCod) row = mysql_fetch_row (mysql_res); FloatNum[i] = Str_GetDoubleFromStr (row[1]); } - fprintf (Gbl.Test.XML.FileXML,"%s" - "%.15lg%s" - "%.15lg%s", + fprintf (FileXML,"%s" + "%.15lg%s" + "%.15lg%s", Txt_NEW_LINE, FloatNum[0],Txt_NEW_LINE, FloatNum[1],Txt_NEW_LINE); @@ -339,14 +376,14 @@ static void TsI_WriteAnswersOfAQstXML (long QstCod) case Tst_ANS_TRUE_FALSE: Tst_CheckIfNumberOfAnswersIsOne (); row = mysql_fetch_row (mysql_res); - fprintf (Gbl.Test.XML.FileXML,"%s", + fprintf (FileXML,"%s", row[1][0] == 'T' ? "true" : "false"); break; case Tst_ANS_UNIQUE_CHOICE: case Tst_ANS_MULTIPLE_CHOICE: case Tst_ANS_TEXT: - fprintf (Gbl.Test.XML.FileXML,"%s",Txt_NEW_LINE); + fprintf (FileXML,"%s",Txt_NEW_LINE); for (NumOpt = 0; NumOpt < Gbl.Test.Answer.NumOptions; NumOpt++) @@ -354,28 +391,28 @@ static void TsI_WriteAnswersOfAQstXML (long QstCod) row = mysql_fetch_row (mysql_res); /* Start answer */ - fprintf (Gbl.Test.XML.FileXML,"%s",Txt_NEW_LINE); + fprintf (FileXML,">%s",Txt_NEW_LINE); /* Write the answer (row[1]), that is in HTML */ - fprintf (Gbl.Test.XML.FileXML,"%s%s", + fprintf (FileXML,"%s%s", row[1],Txt_NEW_LINE); /* Write the feedback (row[2]) */ if (row[2]) if (row[2][0]) - fprintf (Gbl.Test.XML.FileXML,"%s%s", + fprintf (FileXML,"%s%s", row[2],Txt_NEW_LINE); /* End answer */ - fprintf (Gbl.Test.XML.FileXML,"%s", + fprintf (FileXML,"%s", Txt_NEW_LINE); } break; @@ -438,17 +475,18 @@ void TsI_ImportQstsFromXML (void) static void TsI_ReadQuestionsFromXMLFileAndStoreInDB (const char *FileNameXML) { + FILE *FileXML; char *XMLBuffer; unsigned long FileSize; /***** Open file *****/ - if ((Gbl.Test.XML.FileXML = fopen (FileNameXML,"rb")) == NULL) + if ((FileXML = fopen (FileNameXML,"rb")) == NULL) Lay_ShowErrorAndExit ("Can not open XML file."); /***** Compute file size *****/ - fseek (Gbl.Test.XML.FileXML,0L,SEEK_END); - FileSize = (unsigned long) ftell (Gbl.Test.XML.FileXML); - fseek (Gbl.Test.XML.FileXML,0L,SEEK_SET); + fseek (FileXML,0L,SEEK_END); + FileSize = (unsigned long) ftell (FileXML); + fseek (FileXML,0L,SEEK_SET); /***** Allocate memory for XML buffer *****/ if ((XMLBuffer = (char *) malloc (FileSize + 1)) == NULL) @@ -456,7 +494,7 @@ static void TsI_ReadQuestionsFromXMLFileAndStoreInDB (const char *FileNameXML) else { /***** Read file contents into XML buffer *****/ - if (fread (XMLBuffer,sizeof (char),(size_t) FileSize,Gbl.Test.XML.FileXML)) + if (fread (XMLBuffer,sizeof (char),(size_t) FileSize,FileXML)) XMLBuffer[FileSize] = '\0'; else XMLBuffer[0] = '\0'; @@ -468,7 +506,7 @@ static void TsI_ReadQuestionsFromXMLFileAndStoreInDB (const char *FileNameXML) } /***** Close file *****/ - fclose (Gbl.Test.XML.FileXML); + fclose (FileXML); } /*****************************************************************************/ @@ -647,10 +685,8 @@ static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer) /***** If a new question ==> insert question, tags and answer in the database *****/ if (!QuestionExists) - { - Gbl.Test.QstCod = -1L; - Tst_InsertOrUpdateQstTagsAnsIntoDB (); - } + if (Tst_InsertOrUpdateQstTagsAnsIntoDB (-1L) <= 0) + Lay_ShowErrorAndExit ("Can not create question."); } /***** Destroy test question *****/ diff --git a/swad_test_import.h b/swad_test_import.h index 2dfa5438..9703d463 100644 --- a/swad_test_import.h +++ b/swad_test_import.h @@ -40,6 +40,7 @@ /*****************************************************************************/ void TsI_PutFormToExportQuestions (void); +bool TsI_GetCreateXMLParamFromForm (void); void TsI_PutFormToImportQuestions (void); void TsI_CreateXML (unsigned long NumRows,MYSQL_RES *mysql_res); void TsI_ShowFormImportQstsFromXML (void); diff --git a/swad_text.c b/swad_text.c index b2a22160..5eaeec26 100644 --- a/swad_text.c +++ b/swad_text.c @@ -1818,7 +1818,7 @@ const char *Txt_Add_questions = #elif L==8 // pl "Dodaj pytania"; #elif L==9 // pt - "Adicionar questões"; + "Adicionar perguntas"; #endif const char *Txt_Add_this_ID = @@ -2496,7 +2496,7 @@ const char *Txt_Average_number_BR_of_questions_BR_per_survey = #elif L==8 // pl "Średnia liczba
pytań
na ankiety"; #elif L==9 // pt - "Nº medio
de questões
por inquérito"; + "Nº medio
de perguntas
por inquérito"; #endif const char *Txt_Average_BR_number_BR_of_test_BR_questions_BR_per_course = @@ -2517,7 +2517,7 @@ const char *Txt_Average_BR_number_BR_of_test_BR_questions_BR_per_course = #elif L==8 // pl "Średnia liczba
pytań
testowych
na kurs"; #elif L==9 // pt - "Nº medio
de questões
de test por
disciplina"; + "Nº medio
de perguntas
de test por
disciplina"; #endif const char *Txt_Average_number_BR_of_surveys_BR_per_course = @@ -6169,7 +6169,7 @@ const char *Txt_Create_question = #elif L==8 // pl "Utwórz pytanie"; #elif L==9 // pt - "Criar questão"; + "Criar pergunta"; #endif const char *Txt_Create_record_field = @@ -9245,7 +9245,28 @@ const char *Txt_Do_you_really_want_to_remove_the_question_X = // Warning: it is #elif L==8 // pl "Czy na pewno chcesz usunac pytanie %ld?"; #elif L==9 // pt - "Você realmente deseja remover a questão %ld?"; + "Você realmente deseja remover a pergunta %ld?"; +#endif + +const char *Txt_Do_you_really_want_to_remove_the_selected_questions = +#if L==1 // ca + "Realment voleu eliminar les preguntes seleccionades?"; +#elif L==2 // de + "Wollen Sie die ausgewählten Fragen wirklich entfernen?"; +#elif L==3 // en + "Do you really want to remove the selected questions?"; +#elif L==4 // es + "¿Realmente desea eliminar las preguntas seleccionadas?"; +#elif L==5 // fr + "Voulez-vous vraiment supprimer les questions sélectionnées?"; +#elif L==6 // gn + "¿Realmente desea eliminar las preguntas seleccionadas?"; // Okoteve traducción +#elif L==7 // it + "Vuoi realmente rimuovere le domande selezionate?"; +#elif L==8 // pl + "Czy na pewno chcesz usunąć wybrane pytania?"; +#elif L==9 // pt + "Você realmente deseja remover as perguntas selecionadas?"; #endif const char *Txt_Do_you_really_want_to_remove_the_survey_X = // Warning: it is very important to include %s in the following sentences @@ -11578,7 +11599,7 @@ const char *Txt_Existing_question = #elif L==8 // pl "Istniejąca pytanie"; #elif L==9 // pt - "Questão existente"; + "Pergunta existente"; #endif const char *Txt_Expand = @@ -11604,9 +11625,9 @@ const char *Txt_Expand = const char *Txt_Export_questions = #if L==1 // ca - "Exportar preguntas"; // Necessita traduccio + "Exporta preguntes"; #elif L==2 // de - "Export questions"; // Need Übersetzung + "Fragen exportieren"; #elif L==3 // en "Export questions"; #elif L==4 // es @@ -11616,9 +11637,9 @@ const char *Txt_Export_questions = #elif L==6 // gn "Exportar preguntas"; // Okoteve traducción #elif L==7 // it - "Export questions"; // Bisogno di traduzione + "Esportare domande"; #elif L==8 // pl - "Export questions"; // Potrzebujesz tlumaczenie + "Eksportuj pytania"; #elif L==9 // pt "Exportar perguntas"; #endif @@ -17775,7 +17796,7 @@ const char *Txt_List_edit_questions = #elif L==8 // pl "Wyświetlić / edytować pytania"; #elif L==9 // pt - "Listar / editar questões"; + "Listar / editar perguntas"; #endif const char *Txt_List_of_detailed_clicks = @@ -22903,7 +22924,7 @@ const char *Txt_Minimum_time_seconds_per_question_between_two_tests = #elif L==8 // pl "Minimalny czas (w sekundach)
na pytanie miedzy
dwoma badaniami"; #elif L==9 // pt - "Tempo mínimo (segundos)
por questão
entre dois testes"; + "Tempo mínimo (segundos)
por pergunta
entre dois testes"; #endif const char *Txt_minute = @@ -24880,7 +24901,7 @@ const char *Txt_New_question = #elif L==8 // pl "Nowe pytanie"; #elif L==9 // pt - "Nova questão"; + "Nova pergunta"; #endif const char *Txt_New_record_field = @@ -26053,7 +26074,7 @@ const char *Txt_No_of_questions = #elif L==8 // pl "Liczba pytań"; #elif L==9 // pt - "Nº de questões"; + "Nº de perguntas"; #endif const char *Txt_No_of_threads = @@ -26200,7 +26221,7 @@ const char *Txt_No_questions_found_matching_your_search_criteria = #elif L==8 // pl "Brak pytań spelniajacych zadane kryteria wyszukiwania."; #elif L==9 // pt - "Não questões com os seus critérios de pesquisa selecionados."; + "Não perguntas com os seus critérios de pesquisa selecionados."; #endif const char *Txt_No_questions_have_been_added = @@ -26347,7 +26368,7 @@ const char *Txt_No_test_questions = #elif L==8 // pl "Brak pytań testowych."; #elif L==9 // pt - "Não existem questões de test."; + "Não existem perguntas de test."; #endif const char *Txt_No_user_has_been_eliminated = @@ -26716,7 +26737,7 @@ const char *Txt_Non_blank_BR_questions = #elif L==8 // pl "Niepustych
pytania"; #elif L==9 // pt - "Questões
respondidas"; + "Perguntas
respondidas"; #endif const char *Txt_Not_applicable = @@ -28183,7 +28204,7 @@ const char *Txt_Number_of_BR_courses_with_BR_exportable_BR_test_BR_questions = #elif L==8 // pl "Liczba
kursów
z eksportowane
pytań
testowych"; #elif L==9 // pt - "Nº de
disciplinas
com
questões
de test
exportáveis"; + "Nº de
disciplinas
com
perguntas
de test
exportáveis"; #endif const char *Txt_Number_of_BR_courses_with_BR_games = @@ -28267,7 +28288,7 @@ const char *Txt_Number_of_BR_courses_BR_with_test_BR_questions = #elif L==8 // pl "Liczba
kursów
z pytań
testowych"; #elif L==9 // pt - "Nº de
disciplinas
com
questões
de test"; + "Nº de
disciplinas
com
perguntas
de test"; #endif const char *Txt_Number_of_BR_courses_with_BR_surveys = @@ -28456,7 +28477,7 @@ const char *Txt_Number_BR_of_test_BR_questions = #elif L==8 // pl "Liczba
pytań
testowych"; #elif L==9 // pt - "Nº de
questões
de test"; + "Nº de
perguntas
de test"; #endif const char *Txt_Number_of_users = @@ -31944,7 +31965,7 @@ const char *Txt_Question = #elif L==8 // pl "Pytanie"; #elif L==9 // pt - "Questão"; + "Pergunta"; #endif const char *Txt_Question_code_X = // Warning: it is very important to include %ld in the following sentences @@ -31965,7 +31986,7 @@ const char *Txt_Question_code_X = // Warning: it is very important to include %l #elif L==8 // pl "Kodeks pytanie %ld"; #elif L==9 // pt - "Questão com código %ld"; + "Pergunta com código %ld"; #endif const char *Txt_Question_modified = @@ -31986,7 +32007,7 @@ const char *Txt_Question_modified = #elif L==8 // pl "Pytanie zmodyfikowane."; #elif L==9 // pt - "Questão modificada."; + "Pergunta modificada."; #endif const char *Txt_Question_removed = @@ -32007,7 +32028,7 @@ const char *Txt_Question_removed = #elif L==8 // pl "Pytanie usuniete."; #elif L==9 // pt - "Questão removioda."; + "Pergunta removida."; #endif const char *Txt_Questions = @@ -32028,7 +32049,7 @@ const char *Txt_Questions = #elif L==8 // pl "Pytań"; #elif L==9 // pt - "Questões"; + "Perguntas"; #endif const char *Txt_Questions_and_problems = @@ -32049,7 +32070,28 @@ const char *Txt_Questions_and_problems = #elif L==8 // pl "Pytania i problemy"; #elif L==9 // pt - "Questões e problemas"; + "Perguntas e problemas"; +#endif + +const char *Txt_Questions_removed_X = // Warning: it is very important to include %u in the following sentences +#if L==1 // ca + "Preguntas eliminadas: %u."; +#elif L==2 // de + "Fragen entfernt: %u."; +#elif L==3 // en + "Questions removed: %u."; +#elif L==4 // es + "Preguntas eliminadas: %u."; +#elif L==5 // fr + "Questions supprimées: %u."; +#elif L==6 // gn + "Preguntas eliminadas: %u."; // Okoteve traducción +#elif L==7 // it + "Domande rimosse: %u."; +#elif L==8 // pl + "Pytania usuniete: %u."; +#elif L==9 // pt + "Perguntas removidas: %u."; #endif const char *Txt_Quota_exceeded = @@ -33394,7 +33436,7 @@ const char *Txt_Remove_question = #if L==1 // ca "Eliminar pregunta"; #elif L==2 // de - "Entfernen Frage"; + "Frage entfernen"; #elif L==3 // en "Remove question"; #elif L==4 // es @@ -33408,7 +33450,28 @@ const char *Txt_Remove_question = #elif L==8 // pl "Usuń pytanie"; #elif L==9 // pt - "Remover questão"; + "Remover pergunta"; +#endif + +const char *Txt_Remove_questions = +#if L==1 // ca + "Eliminar preguntas"; +#elif L==2 // de + "Fragen entfernen"; +#elif L==3 // en + "Remove questions"; +#elif L==4 // es + "Eliminar preguntas"; +#elif L==5 // fr + "Supprimer questions"; +#elif L==6 // gn + "Eliminar preguntas"; // Okoteve traducción +#elif L==7 // it + "Rimuovere domande"; +#elif L==8 // pl + "Usuń pytania"; +#elif L==9 // pt + "Remover perguntas"; #endif const char *Txt_Remove_record_field = @@ -39158,7 +39221,7 @@ const char *Txt_Select_questions = #elif L==8 // pl "Wybierz pytania"; #elif L==9 // pt - "Selecionar questões"; + "Selecionar perguntas"; #endif const char *Txt_Select_the_groups_in_from_which_you_want_to_register_remove_users_ = @@ -40313,7 +40376,7 @@ const char *Txt_Show_questions = #elif L==8 // pl "Show questions"; // Potrzebujesz tlumaczenie #elif L==9 // pt - "Mostrar questões"; + "Mostrar perguntas"; #endif const char *Txt_Show_statistic = @@ -47712,7 +47775,7 @@ const char *Txt_The_question_has_been_moved_down = #elif L==8 // pl "Pytanie zostało przeniesione."; #elif L==9 // pt - "A questão foi movida para baixo."; + "A pergunta foi movida para baixo."; #endif const char *Txt_The_question_has_been_moved_up = @@ -47733,7 +47796,7 @@ const char *Txt_The_question_has_been_moved_up = #elif L==8 // pl "Pytanie zostało poruszone."; #elif L==9 // pt - "A questão foi movida para cima."; + "A pergunta foi movida para cima."; #endif const char *Txt_The_record_field_X_already_exists = // Warning: it is very important to include %s in the following sentences @@ -51578,7 +51641,7 @@ const char *Txt_TST_STR_ORDER_FULL[Tst_NUM_TYPES_ORDER_QST] = #elif L==8 // pl "Sort by stem of the question" // Potrzebujesz tlumaczenie #elif L==9 // pt - "Classificar por formulação da questão" + "Classificar por formulação da pergunta" #endif , [Tst_ORDER_NUM_HITS] = @@ -51599,7 +51662,7 @@ const char *Txt_TST_STR_ORDER_FULL[Tst_NUM_TYPES_ORDER_QST] = #elif L==8 // pl "Sort by number of times the question has been answered" // Potrzebujesz tlumaczenie #elif L==9 // pt - "Classificar por nº de vezes que a questão foi respondida" + "Classificar por nº de vezes que a pergunta foi respondida" #endif , [Tst_ORDER_AVERAGE_SCORE] = @@ -51650,7 +51713,7 @@ const char *Txt_TST_STR_ORDER_FULL[Tst_NUM_TYPES_ORDER_QST] = " has been answered (excluding blank answers)" // Potrzebujesz tlumaczenie #elif L==9 // pt "Classificar por nº de vezes" - " que a questão foi respondida (não em branco)" + " que a pergunta foi respondida (não em branco)" #endif , [Tst_ORDER_AVERAGE_SCORE_NOT_BLANK] = @@ -51695,7 +51758,7 @@ const char *Txt_TST_STR_ORDER_SHORT[Tst_NUM_TYPES_ORDER_QST] = #elif L==8 // pl "Pytanie" #elif L==9 // pt - "Questão" + "Pergunta" #endif , [Tst_ORDER_NUM_HITS] = diff --git a/swad_text_action.c b/swad_text_action.c index 2d940ff2..c513a319 100644 --- a/swad_text_action.c +++ b/swad_text_action.c @@ -9512,15 +9512,15 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "" // Precisa de tradução #endif , - [ActReqRemTstQst] = + [ActReqRemSevTstQst] = #if L==1 // ca "" // Necessita traducció #elif L==2 // de "" // Need Übersetzung #elif L==3 // en - "Request removing a self-assesment test question" + "Request removing several test questions" #elif L==4 // es - "" + "Solicitar eliminación de varias preguntas de test" #elif L==5 // fr "" // Besoin de traduction #elif L==6 // gn @@ -9533,15 +9533,15 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "" // Precisa de tradução #endif , - [ActRemTstQst] = + [ActRemSevTstQst] = #if L==1 // ca "" // Necessita traducció #elif L==2 // de "" // Need Übersetzung #elif L==3 // en - "Remove a self-assesment test question" + "Remove several test questions" #elif L==4 // es - "" + "Eliminar varias preguntas de test" #elif L==5 // fr "" // Besoin de traduction #elif L==6 // gn @@ -9554,7 +9554,49 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "" // Precisa de tradução #endif , - [ActShfTstQst] = + [ActReqRemOneTstQst] = +#if L==1 // ca + "" // Necessita traducció +#elif L==2 // de + "" // Need Übersetzung +#elif L==3 // en + "Request removing one test question" +#elif L==4 // es + "Solicitar eliminación de una pregunta de test" +#elif L==5 // fr + "" // Besoin de traduction +#elif L==6 // gn + "" // Okoteve traducción +#elif L==7 // it + "" // Bisogno di traduzione +#elif L==8 // pl + "" // Potrzebujesz tlumaczenie +#elif L==9 // pt + "" // Precisa de tradução +#endif + , + [ActRemOneTstQst] = +#if L==1 // ca + "" // Necessita traducció +#elif L==2 // de + "" // Need Übersetzung +#elif L==3 // en + "Remove a test question" +#elif L==4 // es + "Eliminar una pregunta de test" +#elif L==5 // fr + "" // Besoin de traduction +#elif L==6 // gn + "" // Okoteve traducción +#elif L==7 // it + "" // Bisogno di traduzione +#elif L==8 // pl + "" // Potrzebujesz tlumaczenie +#elif L==9 // pt + "" // Precisa de tradução +#endif + , + [ActChgShfTstQst] = #if L==1 // ca "" // Necessita traducció #elif L==2 // de diff --git a/swad_timeline.c b/swad_timeline.c index 6ffc6660..f446be4a 100644 --- a/swad_timeline.c +++ b/swad_timeline.c @@ -2474,7 +2474,7 @@ static long TL_ReceivePost (void) Content.Media.Width = TL_IMAGE_SAVED_MAX_WIDTH; Content.Media.Height = TL_IMAGE_SAVED_MAX_HEIGHT; Content.Media.Quality = TL_IMAGE_SAVED_QUALITY; - Med_GetMediaFromForm (-1,&Content.Media,NULL,NULL); + Med_GetMediaFromForm (-1L,-1L,-1,&Content.Media,NULL,NULL); Ale_ShowAlerts (NULL); if (Content.Txt[0] || // Text not empty @@ -3405,7 +3405,7 @@ static long TL_ReceiveComment (void) Content.Media.Width = TL_IMAGE_SAVED_MAX_WIDTH; Content.Media.Height = TL_IMAGE_SAVED_MAX_HEIGHT; Content.Media.Quality = TL_IMAGE_SAVED_QUALITY; - Med_GetMediaFromForm (-1,&Content.Media,NULL,NULL); + Med_GetMediaFromForm (-1L,-1L,-1,&Content.Media,NULL,NULL); Ale_ShowAlerts (NULL); if (Content.Txt[0] || // Text not empty