From 27e4653e5a2d4878d43163348f12215a4b21f3df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ca=C3=B1as=20Vargas?= Date: Tue, 3 Dec 2019 02:46:46 +0100 Subject: [PATCH] Version19.82 --- css/{swad19.78.1.css => swad19.82.css} | 24 ++- swad_action.c | 6 + swad_action.h | 102 +++++------ swad_changelog.h | 11 +- swad_layout.c | 4 + swad_match.c | 238 ++++++++++++++++++++----- swad_match.h | 1 + 7 files changed, 277 insertions(+), 109 deletions(-) rename css/{swad19.78.1.css => swad19.82.css} (99%) diff --git a/css/swad19.78.1.css b/css/swad19.82.css similarity index 99% rename from css/swad19.78.1.css rename to css/swad19.82.css index e5178b3e7..b7480b105 100644 --- a/css/swad19.78.1.css +++ b/css/swad19.82.css @@ -1503,7 +1503,7 @@ a:hover /* Default ==> underlined */ { padding:10px 0; background-color:#ddecf1; - animation: fadein 2s linear forwards; + animation:fadein 2s linear forwards; } @keyframes fadein { @@ -1791,7 +1791,7 @@ a:hover /* Default ==> underlined */ text-align:center; overflow:hidden; background-color:#ddecf1; - animation: fadein 2s linear forwards; + animation:fadein 2s linear forwards; } @keyframes fadein { @@ -2758,7 +2758,7 @@ a:hover img.CENTRE_PHOTO_SHOW display:table; width:100%; height:64px; - font-size:32pt; + font-size:28pt; padding:2px; } .MCH_BUTTON_CONTAINER a @@ -2870,8 +2870,7 @@ a:hover img.CENTRE_PHOTO_SHOW border-radius:4px; border-width:1px; border-style:solid; - box-shadow:0 1px 0 rgba(255,255,255,0.15) inset; - color:white; + color:rgba(255,255,255,0.75); font-size:36pt; font-weight:bold; line-height:normal; @@ -2882,26 +2881,33 @@ a:hover img.CENTRE_PHOTO_SHOW text-align:center; vertical-align:middle; } + .MCH_STD_BUTTON { box-sizing:border-box; - width:80%; + width:75%; margin:10px auto; padding:20px; border-radius:4px; border-width:1px; border-style:solid; - box-shadow:0 1px 0 rgba(255,255,255,0.15) inset; - color:white; + color:rgba(255,255,255,0.75); font-size:44pt; font-weight:bold; line-height:normal; white-space:nowrap; } + .MCH_STD_ANSWER_SELECTED { box-shadow: 0px 0px 18px 12px rgba(0,128,0,1); + animation:fadeinshadow 2s linear forwards; } +@keyframes fadeinshadow + { + from {box-shadow:0px 0px 18px 12px rgba(0,128,0,1);} + to {box-shadow:none;} + } .MCH_RESULT { @@ -3298,7 +3304,7 @@ a:hover img.CENTRE_PHOTO_SHOW .TL_NEW_PUB { background-color:#ddecf1; - animation: fadein 2s linear forwards; + animation:fadein 2s linear forwards; } @keyframes fadein { diff --git a/swad_action.c b/swad_action.c index 224cc5766..d7d0c97b5 100644 --- a/swad_action.c +++ b/swad_action.c @@ -626,6 +626,8 @@ Assessment: 476. ActRefMchTch Refresh current question when playing a match (as teacher) 477. ActJoiMch Show current question when playing a game (as student) + NEW. ActSeeMchAnsQstStd View my answer to a match question (as student) + NEW. ActRemMchAnsQstStd Remove my answer to a match question (as student) 478. ActAnsMchQstStd Answer a match question (as student) 479. ActRefMchStd Refresh current question when playing a game (as student) @@ -2158,6 +2160,8 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = [ActRefMchTch ] = {1788,-1,TabUnk,ActSeeAllGam ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_AJAX_RFRESH,Mch_GetMatchBeingPlayed ,Mch_RefreshMatchTch ,NULL}, [ActJoiMch ] = {1780,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,Mch_GetMatchBeingPlayed ,Mch_JoinMatchAsStd ,NULL}, + [ActSeeMchAnsQstStd ] = {1808,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_JoinMatchAsStd ,NULL}, + [ActRemMchAnsQstStd ] = {1809,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_RemoveQuestionAnswer ,NULL}, [ActAnsMchQstStd ] = {1651,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_2ND_TAB,Mch_GetMatchBeingPlayed ,Mch_ReceiveQuestionAnswer ,NULL}, [ActRefMchStd ] = {1782,-1,TabUnk,ActSeeAllGam ,0x008, 0, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_AJAX_RFRESH,Mch_GetMatchBeingPlayed ,Mch_RefreshMatchStd ,NULL}, @@ -5025,6 +5029,8 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActReqUsrPrj, // #1805 ActShoHidSocComGbl, // #1806 ActShoHidSocComUsr, // #1807 + ActSeeMchAnsQstStd, // #1808 + ActRemMchAnsQstStd, // #1809 }; /*****************************************************************************/ diff --git a/swad_action.h b/swad_action.h index 1b854c32a..1d593e151 100644 --- a/swad_action.h +++ b/swad_action.h @@ -64,9 +64,9 @@ typedef enum typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action -#define Act_NUM_ACTIONS (1 + 4 + 66 + 38 + 12 + 42 + 36 + 19 + 110 + 179 + 437 + 176 + 169 + 16 + 68) +#define Act_NUM_ACTIONS (1 + 4 + 66 + 38 + 12 + 42 + 36 + 19 + 110 + 181 + 437 + 176 + 169 + 16 + 68) -#define Act_MAX_ACTION_COD 1807 +#define Act_MAX_ACTION_COD 1809 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13 @@ -625,59 +625,61 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActRefMchTch (ActChgCrsTT1stDay + 130) #define ActJoiMch (ActChgCrsTT1stDay + 131) -#define ActAnsMchQstStd (ActChgCrsTT1stDay + 132) -#define ActRefMchStd (ActChgCrsTT1stDay + 133) +#define ActSeeMchAnsQstStd (ActChgCrsTT1stDay + 132) +#define ActRemMchAnsQstStd (ActChgCrsTT1stDay + 133) +#define ActAnsMchQstStd (ActChgCrsTT1stDay + 134) +#define ActRefMchStd (ActChgCrsTT1stDay + 135) -#define ActSeeMyMchRes (ActChgCrsTT1stDay + 134) -#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 135) +#define ActSeeMyMchRes (ActChgCrsTT1stDay + 136) +#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 137) -#define ActReqSeeUsrMchRes (ActChgCrsTT1stDay + 136) -#define ActSeeUsrMchRes (ActChgCrsTT1stDay + 137) -#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 138) -#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 139) +#define ActReqSeeUsrMchRes (ActChgCrsTT1stDay + 138) +#define ActSeeUsrMchRes (ActChgCrsTT1stDay + 139) +#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 140) +#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 141) -#define ActFrmNewGam (ActChgCrsTT1stDay + 140) -#define ActEdiOneGam (ActChgCrsTT1stDay + 141) -#define ActNewGam (ActChgCrsTT1stDay + 142) -#define ActChgGam (ActChgCrsTT1stDay + 143) -#define ActReqRemGam (ActChgCrsTT1stDay + 144) -#define ActRemGam (ActChgCrsTT1stDay + 145) -#define ActHidGam (ActChgCrsTT1stDay + 146) -#define ActShoGam (ActChgCrsTT1stDay + 147) -#define ActAddOneGamQst (ActChgCrsTT1stDay + 148) -#define ActGamLstTstQst (ActChgCrsTT1stDay + 149) -#define ActAddTstQstToGam (ActChgCrsTT1stDay + 150) -#define ActReqRemGamQst (ActChgCrsTT1stDay + 151) -#define ActRemGamQst (ActChgCrsTT1stDay + 152) -#define ActUp_GamQst (ActChgCrsTT1stDay + 153) -#define ActDwnGamQst (ActChgCrsTT1stDay + 154) +#define ActFrmNewGam (ActChgCrsTT1stDay + 142) +#define ActEdiOneGam (ActChgCrsTT1stDay + 143) +#define ActNewGam (ActChgCrsTT1stDay + 144) +#define ActChgGam (ActChgCrsTT1stDay + 145) +#define ActReqRemGam (ActChgCrsTT1stDay + 146) +#define ActRemGam (ActChgCrsTT1stDay + 147) +#define ActHidGam (ActChgCrsTT1stDay + 148) +#define ActShoGam (ActChgCrsTT1stDay + 149) +#define ActAddOneGamQst (ActChgCrsTT1stDay + 150) +#define ActGamLstTstQst (ActChgCrsTT1stDay + 151) +#define ActAddTstQstToGam (ActChgCrsTT1stDay + 152) +#define ActReqRemGamQst (ActChgCrsTT1stDay + 153) +#define ActRemGamQst (ActChgCrsTT1stDay + 154) +#define ActUp_GamQst (ActChgCrsTT1stDay + 155) +#define ActDwnGamQst (ActChgCrsTT1stDay + 156) -#define ActSeeSvy (ActChgCrsTT1stDay + 155) -#define ActAnsSvy (ActChgCrsTT1stDay + 156) -#define ActFrmNewSvy (ActChgCrsTT1stDay + 157) -#define ActEdiOneSvy (ActChgCrsTT1stDay + 158) -#define ActNewSvy (ActChgCrsTT1stDay + 159) -#define ActChgSvy (ActChgCrsTT1stDay + 160) -#define ActReqRemSvy (ActChgCrsTT1stDay + 161) -#define ActRemSvy (ActChgCrsTT1stDay + 162) -#define ActReqRstSvy (ActChgCrsTT1stDay + 163) -#define ActRstSvy (ActChgCrsTT1stDay + 164) -#define ActHidSvy (ActChgCrsTT1stDay + 165) -#define ActShoSvy (ActChgCrsTT1stDay + 166) -#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 167) -#define ActRcvSvyQst (ActChgCrsTT1stDay + 168) -#define ActReqRemSvyQst (ActChgCrsTT1stDay + 169) -#define ActRemSvyQst (ActChgCrsTT1stDay + 170) +#define ActSeeSvy (ActChgCrsTT1stDay + 157) +#define ActAnsSvy (ActChgCrsTT1stDay + 158) +#define ActFrmNewSvy (ActChgCrsTT1stDay + 159) +#define ActEdiOneSvy (ActChgCrsTT1stDay + 160) +#define ActNewSvy (ActChgCrsTT1stDay + 161) +#define ActChgSvy (ActChgCrsTT1stDay + 162) +#define ActReqRemSvy (ActChgCrsTT1stDay + 163) +#define ActRemSvy (ActChgCrsTT1stDay + 164) +#define ActReqRstSvy (ActChgCrsTT1stDay + 165) +#define ActRstSvy (ActChgCrsTT1stDay + 166) +#define ActHidSvy (ActChgCrsTT1stDay + 167) +#define ActShoSvy (ActChgCrsTT1stDay + 168) +#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 169) +#define ActRcvSvyQst (ActChgCrsTT1stDay + 170) +#define ActReqRemSvyQst (ActChgCrsTT1stDay + 171) +#define ActRemSvyQst (ActChgCrsTT1stDay + 172) -#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 171) -#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 172) -#define ActEdiExaAnn (ActChgCrsTT1stDay + 173) -#define ActRcvExaAnn (ActChgCrsTT1stDay + 174) -#define ActPrnExaAnn (ActChgCrsTT1stDay + 175) -#define ActReqRemExaAnn (ActChgCrsTT1stDay + 176) -#define ActRemExaAnn (ActChgCrsTT1stDay + 177) -#define ActHidExaAnn (ActChgCrsTT1stDay + 178) -#define ActShoExaAnn (ActChgCrsTT1stDay + 179) +#define ActSeeOneExaAnn (ActChgCrsTT1stDay + 173) +#define ActSeeDatExaAnn (ActChgCrsTT1stDay + 174) +#define ActEdiExaAnn (ActChgCrsTT1stDay + 175) +#define ActRcvExaAnn (ActChgCrsTT1stDay + 176) +#define ActPrnExaAnn (ActChgCrsTT1stDay + 177) +#define ActReqRemExaAnn (ActChgCrsTT1stDay + 178) +#define ActRemExaAnn (ActChgCrsTT1stDay + 179) +#define ActHidExaAnn (ActChgCrsTT1stDay + 180) +#define ActShoExaAnn (ActChgCrsTT1stDay + 181) /*****************************************************************************/ /******************************** Files tab **********************************/ diff --git a/swad_changelog.h b/swad_changelog.h index b8530351c..76e118063 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -490,15 +490,20 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.81.1 (2019-12-01)" -#define CSS_FILE "swad19.78.1.css" +#define Log_PLATFORM_VERSION "SWAD 19.82 (2019-12-03)" +#define CSS_FILE "swad19.82.css" #define JS_FILE "swad19.70.js" /* // TODO: Hacer un nuevo rol en los TFG: tutor externo (profesor de áreas no vinculadas con el centro, profesionales de empresas, etc.) // TODO: Impedir la creación y edición de proyectos si no son editables. // TODO: En cada juego, poder listar los resultados en una tabla como la de resultados globales - Version 19.81.1: Dec 01, 2019 API function playMatch finished. (247620 lines) + Version 19.82: Dec 03, 2019 Changes in feedback in matches. (247758 lines) + 2 changes necessary in database: +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1808','es','N','Ver mi respuesta a pregunta en partida'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1809','es','N','Eliminar mi respuesta a pregunta en partida'); + + Version 19.81.1: Dec 02, 2019 API function playMatch finished. (247620 lines) Version 19.81: Dec 01, 2019 New (some unfinished) API functions related to games and matches. (247540 lines) Version 19.80.7: Nov 29, 2019 Changes in match results. (247242 lines) Version 19.80.6: Nov 28, 2019 Changes in match results and test results. (247245 lines) diff --git a/swad_layout.c b/swad_layout.c index 64d564dfa..9171a9bf2 100644 --- a/swad_layout.c +++ b/swad_layout.c @@ -678,6 +678,8 @@ static void Lay_WriteScriptInit (void) RefreshNewTimeline = true; break; case ActJoiMch: + case ActSeeMchAnsQstStd: + case ActRemMchAnsQstStd: case ActAnsMchQstStd: RefreshMatchStd = true; break; @@ -811,6 +813,8 @@ static void Lay_WriteScriptParamsAJAX (void) break; /* Parameters related with match refreshing (for students) */ case ActJoiMch: + case ActSeeMchAnsQstStd: + case ActRemMchAnsQstStd: case ActAnsMchQstStd: // Refresh parameters HTM_TxtF ("var RefreshParamNxtActMch = \"act=%ld\";\n" diff --git a/swad_match.c b/swad_match.c index 33e36ad7b..cbc740cf5 100644 --- a/swad_match.c +++ b/swad_match.c @@ -65,6 +65,12 @@ extern struct Globals Gbl; /******************************* Private types *******************************/ /*****************************************************************************/ +typedef enum + { + Mch_CHANGE_STATUS_BY_STUDENT, + Mch_REFRESH_STATUS_BY_SERVER, + } Mch_Update_t; + /*****************************************************************************/ /***************************** Private constants *****************************/ /*****************************************************************************/ @@ -149,13 +155,16 @@ static void Mch_SetMatchStatusToNextQst (struct Match *Match); static void Mch_SetMatchStatusToEnd (struct Match *Match); static void Mch_ShowMatchStatusForTch (struct Match *Match); -static void Mch_ShowMatchStatusForStd (struct Match *Match); +static void Mch_ShowMatchStatusForStd (struct Match *Match,Mch_Update_t Update); static void Mch_ShowLeftColumnTch (struct Match *Match); static void Mch_ShowRefreshablePartTch (struct Match *Match); static void Mch_ShowRightColumnTch (struct Match *Match); -static void Mch_ShowLeftColumnStd (struct Match *Match); -static void Mch_ShowRightColumnStd (struct Match *Match); +static void Mch_ShowLeftColumnStd (struct Match *Match, + const struct Mch_UsrAnswer *UsrAnswer); +static void Mch_ShowRightColumnStd (struct Match *Match, + const struct Mch_UsrAnswer *UsrAnswer, + Mch_Update_t Update); static void Mch_ShowNumQstInMatch (struct Match *Match); static void Mch_PutMatchControlButtons (struct Match *Match); @@ -164,10 +173,14 @@ static void Mch_PutParamNumCols (unsigned NumCols); static void Mch_ShowMatchTitle (struct Match *Match); static void Mch_PutCheckboxResult (struct Match *Match); +static void Mch_PutIfAnswered (const struct Match *Match,bool Answered); +static void Mch_PutIconToRemoveMyAnswer (struct Match *Match); static void Mch_ShowQuestionAndAnswersTch (struct Match *Match); static void Mch_WriteAnswersMatchResult (struct Match *Match, const char *Class,bool ShowResult); -static void Mch_ShowQuestionAndAnswersStd (struct Match *Match); +static void Mch_ShowQuestionAndAnswersStd (struct Match *Match, + const struct Mch_UsrAnswer *UsrAnswer, + Mch_Update_t Update); static void Mch_ShowMatchScore (struct Match *Match); static void Mch_DrawEmptyRowScore (unsigned NumRow,double MinScore,double MaxScore); @@ -191,6 +204,8 @@ static void Mch_SetMatchAsNotBeingPlayed (long MchCod); static bool Mch_GetIfMatchIsBeingPlayed (long MchCod); static void Mch_GetNumPlayers (struct Match *Match); +static void Mch_RemoveAnswerToMatchQuestion (const struct Match *Match); + static double Mch_ComputeScore (unsigned NumQsts); static unsigned Mch_GetNumUsrsWhoHaveChosenAns (long MchCod,unsigned QstInd,unsigned AnsInd); @@ -2029,20 +2044,28 @@ static void Mch_ShowMatchStatusForTch (struct Match *Match) /************ Show current question being played for a student ***************/ /*****************************************************************************/ -static void Mch_ShowMatchStatusForStd (struct Match *Match) +static void Mch_ShowMatchStatusForStd (struct Match *Match,Mch_Update_t Update) { bool ICanPlayThisMatchBasedOnGrps; + struct Mch_UsrAnswer UsrAnswer; /***** Can I play this match? *****/ ICanPlayThisMatchBasedOnGrps = Mch_CheckIfICanPlayThisMatchBasedOnGrps (Match->MchCod); if (!ICanPlayThisMatchBasedOnGrps) Lay_NoPermissionExit (); + /***** Get student's answer to this question + (<0 ==> no answer) *****/ + Mch_GetQstAnsFromDB (Match->MchCod, + Gbl.Usrs.Me.UsrDat.UsrCod, + Match->Status.QstInd, + &UsrAnswer); + /***** Left column *****/ - Mch_ShowLeftColumnStd (Match); + Mch_ShowLeftColumnStd (Match,&UsrAnswer); /***** Right column *****/ - Mch_ShowRightColumnStd (Match); + Mch_ShowRightColumnStd (Match,&UsrAnswer,Update); } /*****************************************************************************/ @@ -2204,8 +2227,11 @@ static void Mch_ShowRightColumnTch (struct Match *Match) /*********** Show left column when playing a match (as a student) ************/ /*****************************************************************************/ -static void Mch_ShowLeftColumnStd (struct Match *Match) +static void Mch_ShowLeftColumnStd (struct Match *Match, + const struct Mch_UsrAnswer *UsrAnswer) { + bool Answered = UsrAnswer->NumOpt >= 0; + /***** Start left container *****/ HTM_DIV_Begin ("class=\"MCH_LEFT\""); @@ -2216,6 +2242,14 @@ static void Mch_ShowLeftColumnStd (struct Match *Match) /***** Write number of question *****/ Mch_ShowNumQstInMatch (Match); + /***** Write if question is answered *****/ + Mch_PutIfAnswered (Match,Answered); + + if (Match->Status.Showing == Mch_ANSWERS && + Answered) + /***** Put icon to view *****/ + Mch_PutIconToRemoveMyAnswer (Match); + /***** End left container *****/ HTM_DIV_End (); } @@ -2224,7 +2258,9 @@ static void Mch_ShowLeftColumnStd (struct Match *Match) /********** Show right column when playing a match (as a student) ************/ /*****************************************************************************/ -static void Mch_ShowRightColumnStd (struct Match *Match) +static void Mch_ShowRightColumnStd (struct Match *Match, + const struct Mch_UsrAnswer *UsrAnswer, + Mch_Update_t Update) { extern const char *Txt_Please_wait_; @@ -2244,7 +2280,7 @@ static void Mch_ShowRightColumnStd (struct Match *Match) /***** Update players ******/ if (Mch_RegisterMeAsPlayerInMatch (Match)) /* Show current question and possible answers */ - Mch_ShowQuestionAndAnswersStd (Match); + Mch_ShowQuestionAndAnswersStd (Match,UsrAnswer,Update); else Ale_ShowAlert (Ale_ERROR,"You can not join this match."); @@ -2434,6 +2470,88 @@ static void Mch_PutCheckboxResult (struct Match *Match) HTM_DIV_End (); } +/*****************************************************************************/ +/***************** Put checkbox to select if show results ********************/ +/*****************************************************************************/ + +static void Mch_PutIfAnswered (const struct Match *Match,bool Answered) + { + extern const char *Txt_View_results; + + /***** Start container *****/ + HTM_DIV_Begin ("class=\"MCH_SHOW_RESULTS\""); + + /***** Put icon with link *****/ + if (Match->Status.Showing == Mch_ANSWERS && + Answered) + { + /* Start form */ + Frm_StartForm (ActSeeMchAnsQstStd); + Mch_PutParamMchCod (Match->MchCod); // Current match being played + + HTM_A_Begin ("href=\"\" class=\"DAT_SMALL\" title=\"%s\" " + " onclick=\"document.getElementById('%s').submit();return false;\"", + "Ver mi respuesta", // TODO: Need translation!!!! + Gbl.Form.Id); + HTM_TxtF ("", + "fas fa-check-circle", + "Respondida"); // TODO: Need translation!!!! + HTM_TxtF (" %s","Respondida"); // TODO: Need translation!!!! + HTM_A_End (); + + /* End form */ + Frm_EndForm (); + } + else + { + HTM_DIV_Begin ("class=\"DAT_SMALL\""); + HTM_TxtF ("", + Answered ? "fas fa-check-circle" : + "fas fa-exclamation-circle", + Answered ? "Respondida" : + "No respondida"); // TODO: Need translation!!!! + HTM_TxtF (" %s",Answered ? "Respondida" : + "No respondida"); // TODO: Need translation!!!! + HTM_DIV_End (); + } + + /***** End container *****/ + HTM_DIV_End (); + } + +/*****************************************************************************/ +/***************** Put checkbox to select if show results ********************/ +/*****************************************************************************/ + +static void Mch_PutIconToRemoveMyAnswer (struct Match *Match) + { + extern const char *Txt_View_results; + + /***** Start container *****/ + HTM_DIV_Begin ("class=\"MCH_SHOW_RESULTS\""); + + /***** Start form *****/ + Frm_StartForm (ActRemMchAnsQstStd); + Mch_PutParamMchCod (Match->MchCod); // Current match being played + Gam_PutParamQstInd (Match->Status.QstInd); // Current question index shown + + /***** Put icon with link *****/ + HTM_DIV_Begin ("class=\"MCH_BUTTON_CONTAINER\""); + HTM_A_Begin ("href=\"\" class=\"MCH_BUTTON_ON\" title=\"%s\" " + " onclick=\"document.getElementById('%s').submit();return false;\"", + "Eliminar mi respuesta", // TODO: Need translation!!!! + Gbl.Form.Id); + HTM_Txt (""); + HTM_A_End (); + HTM_DIV_End (); + + /***** End form *****/ + Frm_EndForm (); + + /***** End container *****/ + HTM_DIV_End (); + } + /*****************************************************************************/ /***************************** Show match title ******************************/ /*****************************************************************************/ @@ -2541,9 +2659,10 @@ static void Mch_WriteAnswersMatchResult (struct Match *Match, /***** Show question and its answers when playing a match (as a student) *****/ /*****************************************************************************/ -static void Mch_ShowQuestionAndAnswersStd (struct Match *Match) +static void Mch_ShowQuestionAndAnswersStd (struct Match *Match, + const struct Mch_UsrAnswer *UsrAnswer, + Mch_Update_t Update) { - struct Mch_UsrAnswer UsrAnswer; unsigned NumOptions; unsigned NumOpt; char *Class; @@ -2554,13 +2673,6 @@ static void Mch_ShowQuestionAndAnswersStd (struct Match *Match) { if (Tst_CheckIfQuestionIsValidForGame (Match->Status.QstCod)) { - /***** Get student's answer to this question - (<0 ==> no answer) *****/ - Mch_GetQstAnsFromDB (Match->MchCod, - Gbl.Usrs.Me.UsrDat.UsrCod, - Match->Status.QstInd, - &UsrAnswer); - /***** Get number of options in this question *****/ NumOptions = Tst_GetNumAnswersQst (Match->Status.QstCod); @@ -2583,21 +2695,16 @@ static void Mch_ShowQuestionAndAnswersStd (struct Match *Match) is necessary in order to be fast and not lose clicks due to refresh */ Frm_StartForm (ActAnsMchQstStd); - Mch_PutParamMchCod (Match->MchCod); // Current match being played + Mch_PutParamMchCod (Match->MchCod); // Current match being played Gam_PutParamQstInd (Match->Status.QstInd); // Current question index shown Mch_PutParamNumOpt (NumOpt); // Number of button - if (UsrAnswer.NumOpt == (int) NumOpt) // Student's answer - { - if (asprintf (&Class,"MCH_STD_ANSWER_SELECTED " - "MCH_STD_BUTTON BT_%c",'A' + (char) NumOpt) < 0) - Lay_NotEnoughMemoryExit (); - } - else - { - if (asprintf (&Class,"MCH_STD_BUTTON BT_%c",'A' + (char) NumOpt) < 0) - Lay_NotEnoughMemoryExit (); - } + if (asprintf (&Class,"MCH_STD_BUTTON%s BT_%c", + UsrAnswer->NumOpt == (int) NumOpt && // Student's answer + Update == Mch_CHANGE_STATUS_BY_STUDENT ? " MCH_STD_ANSWER_SELECTED" : + "", + 'A' + (char) NumOpt) < 0) + Lay_NotEnoughMemoryExit (); HTM_BUTTON_OnMouseDown_Begin (Class); HTM_TxtF ("%c",'a' + (char) NumOpt); HTM_BUTTON_End (); @@ -3030,7 +3137,7 @@ void Mch_GetMatchBeingPlayed (void) } /*****************************************************************************/ -/********* Show game being played to me as student in a new window ***********/ +/********************* Show match being played as student ********************/ /*****************************************************************************/ void Mch_JoinMatchAsStd (void) @@ -3043,7 +3150,36 @@ void Mch_JoinMatchAsStd (void) /***** Show current match status *****/ HTM_DIV_Begin ("id=\"match\" class=\"MCH_CONT\""); - Mch_ShowMatchStatusForStd (&Match); + Mch_ShowMatchStatusForStd (&Match,Mch_CHANGE_STATUS_BY_STUDENT); + HTM_DIV_End (); + } + +/*****************************************************************************/ +/****** Remove student's answer to a question and show match as student ******/ +/*****************************************************************************/ + +void Mch_RemoveQuestionAnswer (void) + { + struct Match Match; + unsigned QstInd; + + /***** Get data of the match from database *****/ + Match.MchCod = Gbl.Games.MchCodBeingPlayed; + Mch_GetDataOfMatchByCod (&Match); + + /***** Get question index from form *****/ + QstInd = Gam_GetParamQstInd (); + + /***** Check that teacher's screen is showing answers + and question index is the current one being played *****/ + if (Match.Status.Showing == Mch_ANSWERS && // Teacher's screen is showing answers + QstInd == Match.Status.QstInd) // Removing answer to the current question being played + /***** Remove answer to this question *****/ + Mch_RemoveAnswerToMatchQuestion (&Match); + + /***** Show current match status *****/ + HTM_DIV_Begin ("id=\"match\" class=\"MCH_CONT\""); + Mch_ShowMatchStatusForStd (&Match,Mch_CHANGE_STATUS_BY_STUDENT); HTM_DIV_End (); } @@ -3093,7 +3229,7 @@ void Mch_RefreshMatchStd (void) Mch_GetDataOfMatchByCod (&Match); /***** Show current match status *****/ - Mch_ShowMatchStatusForStd (&Match); + Mch_ShowMatchStatusForStd (&Match,Mch_REFRESH_STATUS_BY_SERVER); } /*****************************************************************************/ @@ -3159,14 +3295,14 @@ void Mch_ReceiveQuestionAnswer (void) /***** Get question index from form *****/ QstInd = Gam_GetParamQstInd (); - /***** Get indexes for this question from database *****/ - Mch_GetIndexes (Match.MchCod,QstInd,Indexes); - /***** Check that teacher's screen is showing answers and question index is the current one being played *****/ if (Match.Status.Showing == Mch_ANSWERS && // Teacher's screen is showing answers QstInd == Match.Status.QstInd) // Receiving an answer to the current question being played { + /***** Get indexes for this question from database *****/ + Mch_GetIndexes (Match.MchCod,Match.Status.QstInd,Indexes); + /***** Get answer index *****/ /* Indexes[4] = {0,3,1,2} @@ -3188,23 +3324,19 @@ void Mch_ReceiveQuestionAnswer (void) /***** Get previous student's answer to this question (<0 ==> no answer) *****/ - Mch_GetQstAnsFromDB (Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,QstInd, + Mch_GetQstAnsFromDB (Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,Match.Status.QstInd, &PreviousUsrAnswer); /***** Store student's answer *****/ - if (PreviousUsrAnswer.AnsInd == UsrAnswer.AnsInd) - DB_QueryDELETE ("can not remove your answer to the match question", - "DELETE FROM mch_answers" - " WHERE MchCod=%ld AND UsrCod=%ld AND QstInd=%u", - Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,QstInd); - else if (UsrAnswer.NumOpt >= 0 && - UsrAnswer.AnsInd >= 0) + if (UsrAnswer.NumOpt >= 0 && + UsrAnswer.AnsInd >= 0 && + UsrAnswer.AnsInd != PreviousUsrAnswer.AnsInd) DB_QueryREPLACE ("can not register your answer to the match question", "REPLACE mch_answers" " (MchCod,UsrCod,QstInd,NumOpt,AnsInd)" " VALUES" " (%ld,%ld,%u,%d,%d)", - Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,QstInd, + Match.MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,Match.Status.QstInd, UsrAnswer.NumOpt, UsrAnswer.AnsInd); @@ -3248,10 +3380,22 @@ void Mch_ReceiveQuestionAnswer (void) /***** Show current match status *****/ HTM_DIV_Begin ("id=\"match\" class=\"MCH_CONT\""); - Mch_ShowMatchStatusForStd (&Match); + Mch_ShowMatchStatusForStd (&Match,Mch_CHANGE_STATUS_BY_STUDENT); HTM_DIV_End (); } +/*****************************************************************************/ +/********************* Remove answer to match question ***********************/ +/*****************************************************************************/ + +static void Mch_RemoveAnswerToMatchQuestion (const struct Match *Match) + { + DB_QueryDELETE ("can not remove your answer to the match question", + "DELETE FROM mch_answers" + " WHERE MchCod=%ld AND UsrCod=%ld AND QstInd=%u", + Match->MchCod,Gbl.Usrs.Me.UsrDat.UsrCod,Match->Status.QstInd); + } + /*****************************************************************************/ /******************** Compute match score for a student **********************/ /*****************************************************************************/ diff --git a/swad_match.h b/swad_match.h index d74426b81..43c9b1e72 100644 --- a/swad_match.h +++ b/swad_match.h @@ -115,6 +115,7 @@ bool Mch_RegisterMeAsPlayerInMatch (struct Match *Match); void Mch_GetMatchBeingPlayed (void); void Mch_JoinMatchAsStd (void); +void Mch_RemoveQuestionAnswer (void); void Mch_RefreshMatchTch (void); void Mch_RefreshMatchStd (void);