From cd4617bad7f113f76514faea985ef846a83caed6 Mon Sep 17 00:00:00 2001 From: acanas Date: Tue, 20 Sep 2022 23:25:33 +0200 Subject: [PATCH] Version 22.13: Sep 20, 2022 Links to course forum threads in program. --- swad_action.c | 3 + swad_action.h | 41 +++++++------- swad_changelog.h | 3 +- swad_forum.c | 121 ++++++++++++++++++++++++++++++++++++++-- swad_forum.h | 6 ++ swad_forum_database.c | 16 ++++++ swad_forum_database.h | 1 + swad_program_resource.c | 6 +- swad_text_action.c | 23 ++++++++ 9 files changed, 192 insertions(+), 28 deletions(-) diff --git a/swad_action.c b/swad_action.c index c1763bc25..6a3140fd6 100644 --- a/swad_action.c +++ b/swad_action.c @@ -1715,6 +1715,8 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = [ActDisPstForSWAUsr ] = { 625,-1,TabUnk,ActSeeFor ,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,For_DisablePost ,NULL}, [ActDisPstForSWATch ] = { 635,-1,TabUnk,ActSeeFor ,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,0x3C0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,For_DisablePost ,NULL}, + [ActReqLnkForCrsUsr ] = {1941,-1,TabUnk,ActSeeFor ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,For_GetLinkToThread ,NULL}, + // [ActCht ] = { 52,-1,TabUnk,ActSeeChtRms ,0x3F8,0x3C4,0x3C4,0x3C4,0x3C4,0x3C4,0x3C4,Act_CONT_NORM,Act_BRW_NEW_TAB,Cht_OpenChatWindow ,NULL ,NULL}, [ActCht ] = { 52,-1,TabUnk,ActSeeChtRms ,0x200,0x200,0x200,0x200,0x200,0x200,0x200,Act_CONT_NORM,Act_BRW_NEW_TAB,Cht_OpenChatWindow ,NULL ,NULL}, @@ -3791,6 +3793,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActReqLnkAtt, // #1938 ActReqLnkSeeMrkCrs, // #1939 ActReqLnkAdmMrkCrs, // #1940 + ActReqLnkForCrsUsr, // #1941 }; /*****************************************************************************/ diff --git a/swad_action.h b/swad_action.h index 1d527540d..ed46ed533 100644 --- a/swad_action.h +++ b/swad_action.h @@ -65,7 +65,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 1940 +#define Act_MAX_ACTION_COD 1941 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13 @@ -1635,29 +1635,30 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActDisPstForGenTch (ActUnfSevTch + 148) #define ActDisPstForSWAUsr (ActUnfSevTch + 149) #define ActDisPstForSWATch (ActUnfSevTch + 150) +#define ActReqLnkForCrsUsr (ActUnfSevTch + 151) -#define ActCht (ActUnfSevTch + 151) +#define ActCht (ActUnfSevTch + 152) -#define ActReqMsgUsr (ActUnfSevTch + 152) -#define ActSeeSntMsg (ActUnfSevTch + 153) +#define ActReqMsgUsr (ActUnfSevTch + 153) +#define ActSeeSntMsg (ActUnfSevTch + 154) -#define ActRcvMsgUsr (ActUnfSevTch + 154) -#define ActReqDelAllSntMsg (ActUnfSevTch + 155) -#define ActReqDelAllRcvMsg (ActUnfSevTch + 156) -#define ActDelAllSntMsg (ActUnfSevTch + 157) -#define ActDelAllRcvMsg (ActUnfSevTch + 158) -#define ActDelSntMsg (ActUnfSevTch + 159) -#define ActDelRcvMsg (ActUnfSevTch + 160) -#define ActExpSntMsg (ActUnfSevTch + 161) -#define ActExpRcvMsg (ActUnfSevTch + 162) -#define ActConSntMsg (ActUnfSevTch + 163) -#define ActConRcvMsg (ActUnfSevTch + 164) -#define ActLstBanUsr (ActUnfSevTch + 165) -#define ActBanUsrMsg (ActUnfSevTch + 166) -#define ActUnbUsrMsg (ActUnfSevTch + 167) -#define ActUnbUsrLst (ActUnfSevTch + 168) +#define ActRcvMsgUsr (ActUnfSevTch + 155) +#define ActReqDelAllSntMsg (ActUnfSevTch + 156) +#define ActReqDelAllRcvMsg (ActUnfSevTch + 157) +#define ActDelAllSntMsg (ActUnfSevTch + 158) +#define ActDelAllRcvMsg (ActUnfSevTch + 159) +#define ActDelSntMsg (ActUnfSevTch + 160) +#define ActDelRcvMsg (ActUnfSevTch + 161) +#define ActExpSntMsg (ActUnfSevTch + 162) +#define ActExpRcvMsg (ActUnfSevTch + 163) +#define ActConSntMsg (ActUnfSevTch + 164) +#define ActConRcvMsg (ActUnfSevTch + 165) +#define ActLstBanUsr (ActUnfSevTch + 166) +#define ActBanUsrMsg (ActUnfSevTch + 167) +#define ActUnbUsrMsg (ActUnfSevTch + 168) +#define ActUnbUsrLst (ActUnfSevTch + 169) -#define ActMaiUsr (ActUnfSevTch + 169) +#define ActMaiUsr (ActUnfSevTch + 170) /*****************************************************************************/ /****************************** Analytics tab ********************************/ diff --git a/swad_changelog.h b/swad_changelog.h index 08fe168ae..ca62b717b 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -606,10 +606,11 @@ TODO: Fix bug: error al enviar un mensaje a dos recipientes, error on duplicate TODO: Attach pdf files in multimedia. */ -#define Log_PLATFORM_VERSION "SWAD 22.12.3 (2022-09-20)" +#define Log_PLATFORM_VERSION "SWAD 22.13 (2022-09-20)" #define CSS_FILE "swad22.7.css" #define JS_FILE "swad21.100.js" /* + Version 22.13: Sep 20, 2022 Links to course forum threads in program. (331234 lines) Version 22.12.3: Sep 20, 2022 Fixed bug in JavaScript related to dates. (331098 lines) Version 22.12.2: Sep 20, 2022 Changes in behaviour of program items. (331097 lines) Version 22.12.1: Sep 20, 2022 Changes in behaviour of program items. (331015 lines) diff --git a/swad_forum.c b/swad_forum.c index 4760d1548..356e0c7e5 100644 --- a/swad_forum.c +++ b/swad_forum.c @@ -57,6 +57,7 @@ #include "swad_parameter.h" #include "swad_profile.h" #include "swad_profile_database.h" +#include "swad_program_database.h" #include "swad_role.h" #include "swad_timeline.h" #include "swad_timeline_database.h" @@ -320,7 +321,7 @@ static void For_RemoveThreadAndItsPsts (long ThrCod); static time_t For_GetThrReadTime (long ThrCod); static void For_ShowPostsOfAThread (struct For_Forums *Forums, Ale_AlertType_t AlertType,const char *Message); -static void For_PutIconNewPost (void *Forums); +static void For_PutIconsOneThread (void *Forums); static void For_PutAllHiddenParamsNewPost (void *Forums); static void For_ShowAForumPost (struct For_Forums *Forums, @@ -708,7 +709,7 @@ static void For_ShowPostsOfAThread (struct For_Forums *Forums, snprintf (FrameTitle,sizeof (FrameTitle),"%s: %s", Txt_Thread,Thread.Subject); Box_BoxBegin (NULL,FrameTitle, - For_PutIconNewPost,Forums, + For_PutIconsOneThread,Forums, Hlp_COMMUNICATION_Forums_posts,Box_NOT_CLOSABLE); /***** Get posts of a thread from database *****/ @@ -831,12 +832,21 @@ static void For_ShowPostsOfAThread (struct For_Forums *Forums, /*********************** Put icon to write a new post ************************/ /*****************************************************************************/ -static void For_PutIconNewPost (void *Forums) +static void For_PutIconsOneThread (void *Forums) { if (Forums) + { + /***** Put icon to write a new post *****/ Ico_PutContextualIconToAdd (For_ActionsSeePstFor[((struct For_Forums *) Forums)->Forum.Type], For_NEW_POST_SECTION_ID, For_PutAllHiddenParamsNewPost,Forums); + + /***** Put icon to get resource link *****/ + if (((struct For_Forums *) Forums)->Forum.Type == For_FORUM_COURSE_USRS && + Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM) // Only if I am superuser // TODO: Include teachers + Ico_PutContextualIconToGetLink (ActReqLnkForCrsUsr,NULL, + For_PutAllHiddenParamsNewPost,Forums); + } } static void For_PutAllHiddenParamsNewPost (void *Forums) @@ -2296,7 +2306,7 @@ static void For_ListForumThrs (struct For_Forums *Forums, free (Id); } else - for (Column = 1; + for (Column = 1; Column <= 2; Column++) { @@ -2576,6 +2586,7 @@ static void For_SetForumType (struct For_Forums *Forums) case ActCutThrForCrsUsr: case ActPasThrForCrsUsr: case ActDelPstForCrsUsr: case ActEnbPstForCrsUsr: case ActDisPstForCrsUsr: + case ActReqLnkForCrsUsr: Forums->Forum.Type = For_FORUM_COURSE_USRS; break; case ActSeeForCrsTch: case ActSeePstForCrsTch: @@ -3502,3 +3513,105 @@ static void For_WriteForumTotalStats (struct For_FiguresForum *FiguresForum) HTM_TR_End (); } + +/*****************************************************************************/ +/**************************** Get link to thread *****************************/ +/*****************************************************************************/ + +void For_GetLinkToThread (void) + { + extern const char *Txt_Link_to_resource_X_copied_into_clipboard; + struct For_Forums Forums; + char Subject[Cns_MAX_BYTES_SUBJECT + 1]; + + /***** Reset forum *****/ + For_ResetForums (&Forums); + + /***** Get parameters related to forums *****/ + For_GetParamsForums (&Forums); + + /***** Get thread subject *****/ + For_DB_GetThreadSubject (Forums.Thread.Current,Subject); + + /***** Copy link to thread into resource clipboard *****/ + Prg_DB_CopyToClipboard (PrgRsc_FORUM_THREAD,Forums.Thread.Current); + + /***** Write sucess message *****/ + Ale_ShowAlert (Ale_SUCCESS,Txt_Link_to_resource_X_copied_into_clipboard, + Subject); + + /***** Show forum list again *****/ + For_ShowForumList (&Forums); + + /***** Show threads again *****/ + For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_SUCCESS,NULL); + + /***** Show the posts of that thread *****/ + For_ShowPostsOfAThread (&Forums,Ale_SUCCESS,NULL); + } + +/*****************************************************************************/ +/***************** Write thread subject in course program ********************/ +/*****************************************************************************/ + +void For_WriteThreadInCrsProgram (long ThrCod,bool PutFormToGo, + const char *Icon,const char *IconTitle) + { + extern const char *Txt_Actions[Act_NUM_ACTIONS]; + struct For_Forums Forums; + char Subject[Cns_MAX_BYTES_SUBJECT + 1]; + + /***** Get thread subject *****/ + For_DB_GetThreadSubject (ThrCod,Subject); + + /***** Begin form to go to survey *****/ + if (PutFormToGo) + { + /***** Set forum and thread *****/ + For_ResetForums (&Forums); + Forums.Forum.Type = For_FORUM_COURSE_USRS; + Forums.Forum.Location = Gbl.Hierarchy.Crs.CrsCod; + Forums.Thread.Current = + Forums.Thread.Selected = ThrCod; + // TODO: In the listing of threads, the page is always the first. + // The page should be that corresponding to the selected thread. + + Frm_BeginForm (ActSeePstForCrsUsr); + For_PutAllHiddenParamsNewPost (&Forums); + HTM_BUTTON_Submit_Begin (Txt_Actions[ActSeePstForCrsUsr], + "class=\"LM BT_LINK PRG_RSC_%s\"", + The_GetSuffix ()); + } + + /***** Icon depending on type ******/ + if (PutFormToGo) + Ico_PutIconLink (Icon,Ico_BLACK,ActSeePstForCrsUsr); + else + Ico_PutIconOn (Icon,Ico_BLACK,IconTitle); + + /***** Write Name of the course and date of exam *****/ + HTM_Txt (Subject); + + /***** End form to download file *****/ + if (PutFormToGo) + { + /* End form */ + HTM_BUTTON_End (); + + Frm_EndForm (); + } + } + +/*****************************************************************************/ +/********************* Get survey title from survey code *********************/ +/*****************************************************************************/ + +void For_GetTitleFromThrCod (long ThrCod,char *Title,size_t TitleSize) + { + char Subject[Cns_MAX_BYTES_SUBJECT + 1]; + + /***** Get thread subject *****/ + For_DB_GetThreadSubject (ThrCod,Subject); + + Str_Copy (Title,Subject,TitleSize); + } diff --git a/swad_forum.h b/swad_forum.h index b21198e8e..02efa38c2 100644 --- a/swad_forum.h +++ b/swad_forum.h @@ -150,4 +150,10 @@ void For_PasteThread (void); //-------------------------------- Figures ------------------------------------ void For_GetAndShowForumStats (void); +//--------------------------- Program resources ------------------------------- +void For_GetLinkToThread (void); +void For_WriteThreadInCrsProgram (long ThrCod,bool PutFormToGo, + const char *Icon,const char *IconTitle); +void For_GetTitleFromThrCod (long ThrCod,char *Title,size_t TitleSize); + #endif diff --git a/swad_forum_database.c b/swad_forum_database.c index b829374c0..1b439e1ce 100644 --- a/swad_forum_database.c +++ b/swad_forum_database.c @@ -519,6 +519,22 @@ unsigned For_DB_GetThreadData (MYSQL_RES **mysql_res,long ThrCod) ThrCod); } +/*****************************************************************************/ +/***************************** Get thread subject ****************************/ +/*****************************************************************************/ + +void For_DB_GetThreadSubject (long ThrCod,char Subject[Cns_MAX_BYTES_SUBJECT + 1]) + { + DB_QuerySELECTString (Subject,Cns_MAX_BYTES_SUBJECT, + "can not get thread subject", + "SELECT for_posts.Subject" // row[0] + " FROM for_threads," + "for_posts" + " WHERE for_threads.ThrCod=%ld" + " AND for_threads.FirstPstCod=for_posts.PstCod", + ThrCod); + } + /*****************************************************************************/ /***************** Get if a thread belongs to current forum ******************/ /*****************************************************************************/ diff --git a/swad_forum_database.h b/swad_forum_database.h index 325fcac70..b078337c0 100644 --- a/swad_forum_database.h +++ b/swad_forum_database.h @@ -66,6 +66,7 @@ void For_DB_UpdateThrLastPst (long ThrCod,long LastPstCod); unsigned For_DB_GetForumThreads (MYSQL_RES **mysql_res, const struct For_Forums *Forums); unsigned For_DB_GetThreadData (MYSQL_RES **mysql_res,long ThrCod); +void For_DB_GetThreadSubject (long ThrCod,char Subject[Cns_MAX_BYTES_SUBJECT + 1]); bool For_DB_CheckIfThrBelongsToForum (long ThrCod,const struct For_Forum *Forum); long For_DB_GetThrLastPst (long ThrCod); void For_DB_GetThrSubject (long ThrCod,char Subject[Cns_MAX_BYTES_SUBJECT + 1]); diff --git a/swad_program_resource.c b/swad_program_resource.c index 9355b7c09..349a40a92 100644 --- a/swad_program_resource.c +++ b/swad_program_resource.c @@ -59,7 +59,7 @@ const char *Prg_ResourceTypesIcons[PrgRsc_NUM_TYPES] = [PrgRsc_EXAM ] = "file-signature.svg", [PrgRsc_GAME ] = "gamepad.svg", [PrgRsc_SURVEY ] = "poll.svg", - [PrgRsc_DOCUMENT ] = "file.svg", + [PrgRsc_DOCUMENT ] = "up-right-from-square.svg", // for links because each file type has its own icon [PrgRsc_MARKS ] = "list-alt.svg", // grp GROUPS // ??? User select groups [PrgRsc_ATTENDANCE_EVENT] = "calendar-check.svg", @@ -1018,7 +1018,7 @@ static void PrgRsc_WriteLinkName (const struct Prg_Link *Link,bool PutFormToGo, [PrgRsc_DOCUMENT ] = Brw_WriteDocFileNameInCrsProgram, [PrgRsc_MARKS ] = Brw_WriteMrkFileNameInCrsProgram, [PrgRsc_ATTENDANCE_EVENT] = Att_WriteAttEventInCrsProgram, - [PrgRsc_FORUM_THREAD ] = NULL, + [PrgRsc_FORUM_THREAD ] = For_WriteThreadInCrsProgram, }; /***** Trivial check: code should be > 0 *****/ @@ -1064,7 +1064,7 @@ static void PrgRsc_GetResourceTitleFromLink (struct Prg_Item *Item) [PrgRsc_DOCUMENT ] = Brw_GetFileNameFromFilCod, [PrgRsc_MARKS ] = Brw_GetFileNameFromFilCod, [PrgRsc_ATTENDANCE_EVENT] = Att_GetTitleFromAttCod, - [PrgRsc_FORUM_THREAD ] = NULL, + [PrgRsc_FORUM_THREAD ] = For_GetTitleFromThrCod, }; /***** Reset title *****/ diff --git a/swad_text_action.c b/swad_text_action.c index 97b54142c..95ce52342 100644 --- a/swad_text_action.c +++ b/swad_text_action.c @@ -31685,6 +31685,29 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "Disable post of forum of teachers of the platform" // Precisa de tradução #elif L==10 // tr "Disable post of forum of teachers of the platform" // Çeviri lazim! +#endif + , + [ActReqLnkForCrsUsr] = +#if L==1 // ca + "Copy link to thread of forum of users of course" // Necessita traducció +#elif L==2 // de + "Copy link to thread of forum of users of course" // Need Übersetzung +#elif L==3 // en + "Copy link to thread of forum of users of course" +#elif L==4 // es + "Copiar enlace a discusión del foro de usuarios de asignatura" +#elif L==5 // fr + "Copy link to thread of forum of users of course" // Besoin de traduction +#elif L==6 // gn + "Copiar enlace a discusión del foro de usuarios de asignatura" // Okoteve traducción +#elif L==7 // it + "Copy link to thread of forum of users of course" // Bisogno di traduzione +#elif L==8 // pl + "Copy link to thread of forum of users of course" // Potrzebujesz tlumaczenie +#elif L==9 // pt + "Copy link to thread of forum of users of course" // Precisa de tradução +#elif L==10 // tr + "Copy link to thread of forum of users of course" // Çeviri lazim! #endif , [ActCht] =