diff --git a/swad_action.c b/swad_action.c index 0f50a4dd..1b90d009 100644 --- a/swad_action.c +++ b/swad_action.c @@ -1311,9 +1311,10 @@ Messages: 1103. ActReqMsgUsr Write message to several users 1104. ActSeeRcvMsg Show the messages received from other users (link in menu) 1105. ActSeeSntMsg Show the messages sent to other users - 1106. ActMaiStd Send an email to students - 1107. ActWriAnn Show form to create a new global announcement - 1108. ActRcvAnn Receive and create a new global announcement + 1106. ActReqMaiUsr Select users to send an email to them + 1107. ActMaiUsr Send an email to users + 1108. ActWriAnn Show form to create a new global announcement + 1109. ActRcvAnn Receive and create a new global announcement 1110. ActHidAnn Hide a global announcement that was active 1111. ActRevAnn Reveal a global announcement that was hidden 1112. ActRemAnn Remove global announcement @@ -2881,7 +2882,7 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActReqMsgUsr */{ 26, 4,TabMsg,ActReqMsgUsr ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Msg_FormMsgUsrs ,"marker" }, /* ActSeeRcvMsg */{ 3, 5,TabMsg,ActSeeRcvMsg ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Msg_ShowRecMsgs ,"inbox" }, /* ActSeeSntMsg */{ 70, 6,TabMsg,ActSeeSntMsg ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Msg_ShowSntMsgs ,"share" }, - /* ActMaiStd */{ 100, 7,TabMsg,ActMaiStd ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Mai_ListEmails ,"envelope" }, + /* ActReqMaiUsr */{1772, 7,TabMsg,ActReqMaiUsr ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Mai_ReqUsrsToListEmails ,"envelope" }, // Actions not in menu: /* ActWriAnn */{1237,-1,TabUnk,ActSeeAnn ,0x200,0x200,0x200,0x200,0x200,0x200,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Ann_ShowFormAnnouncement ,NULL}, @@ -3062,6 +3063,8 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActUnbUsrMsg */{1016,-1,TabUnk,ActSeeRcvMsg ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Msg_UnbanSenderWhenShowingMsgs ,NULL}, /* ActUnbUsrLst */{1018,-1,TabUnk,ActSeeRcvMsg ,0x3F8,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,0x3C6,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Msg_UnbanSenderWhenListingUsrs ,NULL}, + /* ActMaiUsr */{ 100,-1,TabUnk,ActReqMaiUsr ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Mai_GetSelectedUsrsAndListEmails,NULL}, + // TabAna ****************************************************************** // Actions in menu: /* ActReqUseGbl */{ 761, 0,TabAna,ActReqUseGbl ,0x3F8,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,0x3C7,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Fig_ReqShowFigures ,"chart-pie" }, @@ -3273,7 +3276,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un -1, // #97 (obsolete action) ActAssTst, // #98 -1, // #99 (obsolete action) - ActMaiStd, // #100 + ActMaiUsr, // #100 -1, // #101 (obsolete action) -1, // #102 (obsolete action) ActReqTst, // #103 @@ -4945,6 +4948,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActAllShaSocNotUsr, // #1769 ActAllFavSocNotUsr, // #1770 ActAllFavSocComUsr, // #1771 + ActReqMaiUsr, // #1772 }; /*****************************************************************************/ diff --git a/swad_action.h b/swad_action.h index 44ee7c6a..0de63489 100644 --- a/swad_action.h +++ b/swad_action.h @@ -61,9 +61,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 + 8 + 61 + 38 + 12 + 42 + 36 + 19 + 110 + 157 + 437 + 176 + 168 + 15 + 67) +#define Act_NUM_ACTIONS (1 + 8 + 61 + 38 + 12 + 42 + 36 + 19 + 110 + 157 + 437 + 176 + 169 + 15 + 67) -#define Act_MAX_ACTION_COD 1771 +#define Act_MAX_ACTION_COD 1772 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13 @@ -1336,7 +1336,7 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActReqMsgUsr (ActUnfSevTch + 5) #define ActSeeRcvMsg (ActUnfSevTch + 6) #define ActSeeSntMsg (ActUnfSevTch + 7) -#define ActMaiStd (ActUnfSevTch + 8) +#define ActReqMaiUsr (ActUnfSevTch + 8) // Secondary actions #define ActWriAnn (ActUnfSevTch + 9) #define ActRcvAnn (ActUnfSevTch + 10) @@ -1502,29 +1502,31 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to #define ActUnbUsrMsg (ActUnfSevTch + 167) #define ActUnbUsrLst (ActUnfSevTch + 168) +#define ActMaiUsr (ActUnfSevTch + 169) + /*****************************************************************************/ /****************************** Statistics tab *******************************/ /*****************************************************************************/ // Actions in menu -#define ActReqUseGbl (ActUnbUsrLst + 1) -#define ActSeePhoDeg (ActUnbUsrLst + 2) -#define ActReqStaCrs (ActUnbUsrLst + 3) -#define ActReqAccGbl (ActUnbUsrLst + 4) -#define ActReqMyUsgRep (ActUnbUsrLst + 5) -#define ActMFUAct (ActUnbUsrLst + 6) +#define ActReqUseGbl (ActMaiUsr + 1) +#define ActSeePhoDeg (ActMaiUsr + 2) +#define ActReqStaCrs (ActMaiUsr + 3) +#define ActReqAccGbl (ActMaiUsr + 4) +#define ActReqMyUsgRep (ActMaiUsr + 5) +#define ActMFUAct (ActMaiUsr + 6) // Secondary actions -#define ActSeeUseGbl (ActUnbUsrLst + 7) -#define ActPrnPhoDeg (ActUnbUsrLst + 8) -#define ActCalPhoDeg (ActUnbUsrLst + 9) -#define ActSeeAccGbl (ActUnbUsrLst + 10) -#define ActReqAccCrs (ActUnbUsrLst + 11) -#define ActSeeAccCrs (ActUnbUsrLst + 12) -#define ActSeeAllStaCrs (ActUnbUsrLst + 13) +#define ActSeeUseGbl (ActMaiUsr + 7) +#define ActPrnPhoDeg (ActMaiUsr + 8) +#define ActCalPhoDeg (ActMaiUsr + 9) +#define ActSeeAccGbl (ActMaiUsr + 10) +#define ActReqAccCrs (ActMaiUsr + 11) +#define ActSeeAccCrs (ActMaiUsr + 12) +#define ActSeeAllStaCrs (ActMaiUsr + 13) -#define ActLstClk (ActUnbUsrLst + 14) +#define ActLstClk (ActMaiUsr + 14) -#define ActSeeMyUsgRep (ActUnbUsrLst + 15) +#define ActSeeMyUsgRep (ActMaiUsr + 15) /*****************************************************************************/ /******************************** Profile tab ********************************/ diff --git a/swad_changelog.h b/swad_changelog.h index 941a1ce5..4cac1513 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -456,10 +456,14 @@ En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 18.110.3 (2019-04-11)" +#define Log_PLATFORM_VERSION "SWAD 18.111 (2019-04-11)" #define CSS_FILE "swad18.92.css" #define JS_FILE "swad18.92.js" /* + Version 18.111: Apr 11, 2019 New option to select users to compose an email to them. (242541 lines) + 1 change necessary in database: +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1772','es','N','Seleccionar usuarios para envío correo'); + Version 18.110.3: Apr 11, 2019 Code refactoring in attendance events. (242526 lines) Version 18.110.2: Apr 11, 2019 A user can have several roles in the same project. (242527 lines) Version 18.110.1: Apr 11, 2019 Code refactoring in selection of groups and users. (242553 lines) diff --git a/swad_file_browser.c b/swad_file_browser.c index 967b0660..783cfbd7 100644 --- a/swad_file_browser.c +++ b/swad_file_browser.c @@ -3187,9 +3187,6 @@ static void Brw_ShowFileBrowsersAsgWrkCrs (void) /***** End table and box *****/ Box_EndBoxTable (); - - /***** Free memory used by list of selected users' codes *****/ - Usr_FreeListsSelectedUsrsCods (); } /*****************************************************************************/ diff --git a/swad_mail.c b/swad_mail.c index 39302b74..1bfb8357 100644 --- a/swad_mail.c +++ b/swad_mail.c @@ -88,6 +88,8 @@ static void Mai_PutFormToCreateMailDomain (void); static void Mai_PutHeadMailDomains (void); static void Mai_CreateMailDomain (struct Mail *Mai); +static void Mai_ListEmails (void); + static void Mai_ShowFormChangeUsrEmail (const struct UsrData *UsrDat,bool ItsMe, bool IMustFillInEmail,bool IShouldConfirmEmail); @@ -874,144 +876,141 @@ static void Mai_CreateMailDomain (struct Mail *Mai) Mai->Domain,Mai->Info); } +/*****************************************************************************/ +/************** Request edition of works of users of the course **************/ +/*****************************************************************************/ + +void Mai_ReqUsrsToListEmails (void) + { + extern const char *Hlp_MESSAGES_Email; + extern const char *Txt_View_email_addresses; + + /***** List users to select some of them *****/ + Usr_PutFormToSelectUsrsToGoToAct (ActMaiUsr,NULL, + Hlp_MESSAGES_Email, + Txt_View_email_addresses); + } + +/*****************************************************************************/ +/****** Get and check list of selected users, and show users' emails ********/ +/*****************************************************************************/ + +void Mai_GetSelectedUsrsAndListEmails (void) + { + Usr_GetSelectedUsrsAndGoToAct (Mai_ListEmails, // when user(s) selected + Mai_ReqUsrsToListEmails); // when no user selected + } + /*****************************************************************************/ /****** List the emails of all the students to creates an email message ******/ /*****************************************************************************/ #define Mai_MAX_BYTES_STR_ADDR (256 * 1024 - 1) -void Mai_ListEmails (void) +static void Mai_ListEmails (void) { extern const char *Hlp_MESSAGES_Email; extern const char *The_ClassFormOutBoxBold[The_NUM_THEMES]; - extern const char *Txt_Students_who_have_accepted_and_who_have_email; - extern const char *Txt_X_students_who_have_email; - extern const char *Txt_X_students_who_have_accepted_and_who_have_email; + extern const char *Txt_Email_addresses; + extern const char *Txt_X_users_who_have_email; + extern const char *Txt_X_users_who_have_accepted_and_who_have_email; extern const char *Txt_Create_email_message; - unsigned NumUsr; - unsigned NumStdsWithEmail; - unsigned NumAcceptedStdsWithEmail; + unsigned NumUsrsWithEmail = 0; + unsigned NumAcceptedUsrsWithEmail = 0; char StrAddresses[Mai_MAX_BYTES_STR_ADDR + 1]; // TODO: Use malloc depending on the number of students unsigned int LengthStrAddr = 0; struct UsrData UsrDat; - - /***** Get groups to show ******/ - Grp_GetParCodsSeveralGrpsToShowUsrs (); - - /***** Get and order list of students in this course *****/ - Usr_GetListUsrs (Hie_CRS,Rol_STD); + const char *Ptr; /***** Start the box used to list the emails *****/ - Box_StartBox (NULL,Txt_Students_who_have_accepted_and_who_have_email,NULL, + Box_StartBox (NULL,Txt_Email_addresses,NULL, Hlp_MESSAGES_Email,Box_NOT_CLOSABLE); - /***** Form to select groups *****/ - Grp_ShowFormToSelectSeveralGroups (NULL, - Grp_ONLY_MY_GROUPS); + /***** Start list with users' email addresses *****/ + fprintf (Gbl.F.Out,"
"); - /***** Start section with user list *****/ - Lay_StartSection (Usr_USER_LIST_SECTION_ID); + /***** Initialize structure with user's data *****/ + Usr_UsrDataConstructor (&UsrDat); - if (Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs) + /***** Get email addresses of the selected users *****/ + StrAddresses[0] = '\0'; + Ptr = Gbl.Usrs.Selected.List[Rol_UNK]; + while (*Ptr) { - if (Usr_GetIfShowBigList (Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs,NULL,NULL)) - { - /***** Initialize structure with user's data *****/ - Usr_UsrDataConstructor (&UsrDat); + /* Get next user */ + Par_GetNextStrUntilSeparParamMult (&Ptr,UsrDat.EncryptedUsrCod, + Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64); + Usr_GetUsrCodFromEncryptedUsrCod (&UsrDat); - /***** List the students' email addresses *****/ - fprintf (Gbl.F.Out,"
"); - for (NumUsr = 0, NumStdsWithEmail = 0, NumAcceptedStdsWithEmail = 0, - StrAddresses[0] = '\0'; - NumUsr < Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs; - NumUsr++) - { - /* Copy user's basic data from list */ - Usr_CopyBasicUsrDataFromList (&UsrDat,&Gbl.Usrs.LstUsrs[Rol_STD].Lst[NumUsr]); + /* Get user's email */ + Mai_GetEmailFromUsrCod (&UsrDat); - /* Get user's email */ - Mai_GetEmailFromUsrCod (&UsrDat); + if (UsrDat.Email[0]) + { + NumUsrsWithEmail++; - if (UsrDat.Email[0]) + /* Check if users has accepted inscription in current course */ + UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&UsrDat); + + if (UsrDat.Accepted) // If student has email and has accepted + { + if (NumAcceptedUsrsWithEmail > 0) { - NumStdsWithEmail++; - if (UsrDat.Accepted) // If student has email and has accepted - { - if (NumAcceptedStdsWithEmail > 0) - { - fprintf (Gbl.F.Out,", "); - LengthStrAddr ++; - if (LengthStrAddr > Mai_MAX_BYTES_STR_ADDR) - Lay_ShowErrorAndExit ("The space allocated to store email addresses is full."); - Str_Concat (StrAddresses,",", - Mai_MAX_BYTES_STR_ADDR); - } - LengthStrAddr += strlen (UsrDat.Email); - if (LengthStrAddr > Mai_MAX_BYTES_STR_ADDR) - Lay_ShowErrorAndExit ("The space allocated to store email addresses is full."); - Str_Concat (StrAddresses,UsrDat.Email, - Mai_MAX_BYTES_STR_ADDR); - fprintf (Gbl.F.Out,"%s", - UsrDat.Email,Gbl.Hierarchy.Crs.FullName,UsrDat.Email); - - NumAcceptedStdsWithEmail++; - } + fprintf (Gbl.F.Out,", "); + LengthStrAddr ++; + if (LengthStrAddr > Mai_MAX_BYTES_STR_ADDR) + Lay_ShowErrorAndExit ("The space allocated to store email addresses is full."); + Str_Concat (StrAddresses,",", + Mai_MAX_BYTES_STR_ADDR); } - } - fprintf (Gbl.F.Out,"
"); + LengthStrAddr += strlen (UsrDat.Email); + if (LengthStrAddr > Mai_MAX_BYTES_STR_ADDR) + Lay_ShowErrorAndExit ("The space allocated to store email addresses is full."); + Str_Concat (StrAddresses,UsrDat.Email, + Mai_MAX_BYTES_STR_ADDR); + fprintf (Gbl.F.Out,"%s", + UsrDat.Email,Gbl.Hierarchy.Crs.FullName,UsrDat.Email); - /***** Free memory used for user's data *****/ - Usr_UsrDataDestructor (&UsrDat); - - /***** Show a message with the number of students with email ****/ - fprintf (Gbl.F.Out,"
"); - fprintf (Gbl.F.Out,Txt_X_students_who_have_email, - NumStdsWithEmail, - ((float) NumStdsWithEmail / - (float) Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs) * 100.0, - Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs); - fprintf (Gbl.F.Out,"
"); - - /***** Show a message with the number of students who have accepted and have email ****/ - fprintf (Gbl.F.Out,"
"); - fprintf (Gbl.F.Out,Txt_X_students_who_have_accepted_and_who_have_email, - NumAcceptedStdsWithEmail, - ((float) NumAcceptedStdsWithEmail / - (float) Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs) * 100.0, - Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs); - fprintf (Gbl.F.Out,"
"); - - /***** Icon to open the client email program *****/ - fprintf (Gbl.F.Out,"
" - "", - Gbl.Usrs.Me.UsrDat.Email, - Gbl.Hierarchy.Crs.FullName, - Gbl.Usrs.Me.UsrDat.Email, - StrAddresses, - Txt_Create_email_message, - The_ClassFormOutBoxBold[Gbl.Prefs.Theme]); - Ico_PutIconTextLink ("marker.svg", - Txt_Create_email_message); - fprintf (Gbl.F.Out,"" - "
"); - } + NumAcceptedUsrsWithEmail++; + } + } } - else // Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs == 0 - /***** Show warning indicating no students found *****/ - Usr_ShowWarningNoUsersFound (Rol_STD); - /***** End section with user list *****/ - Lay_EndSection (); + /***** Free memory used for user's data *****/ + Usr_UsrDataDestructor (&UsrDat); + + /***** End list with users' email addresses *****/ + fprintf (Gbl.F.Out,"
"); + + /***** Show a message with the number of users with email ****/ + fprintf (Gbl.F.Out,"
"); + fprintf (Gbl.F.Out,Txt_X_users_who_have_email, + NumUsrsWithEmail); + fprintf (Gbl.F.Out,"
"); + + /***** Show a message with the number of users who have accepted and have email ****/ + fprintf (Gbl.F.Out,"
"); + fprintf (Gbl.F.Out,Txt_X_users_who_have_accepted_and_who_have_email, + NumAcceptedUsrsWithEmail); + fprintf (Gbl.F.Out,"
"); + + /***** Icon to open the client email program *****/ + fprintf (Gbl.F.Out,"
" + "", + Gbl.Usrs.Me.UsrDat.Email, + Gbl.Hierarchy.Crs.FullName, + Gbl.Usrs.Me.UsrDat.Email, + StrAddresses, + Txt_Create_email_message, + The_ClassFormOutBoxBold[Gbl.Prefs.Theme]); + Ico_PutIconTextLink ("marker.svg", + Txt_Create_email_message); + fprintf (Gbl.F.Out,"" + "
"); /***** End the box used to list the emails *****/ Box_EndBox (); - - /***** Free memory for students list *****/ - Usr_FreeUsrsList (Rol_STD); - - /***** Free memory for list of selected groups *****/ - Grp_FreeListCodSelectedGrps (); } /*****************************************************************************/ diff --git a/swad_mail.h b/swad_mail.h index cf4e470a..84104942 100644 --- a/swad_mail.h +++ b/swad_mail.h @@ -72,7 +72,8 @@ void Mai_RenameMailDomainFull (void); void Mai_ContEditAfterChgMai (void); void Mai_RecFormNewMailDomain (void); -void Mai_ListEmails (void); // Creates an email message to students +void Mai_ReqUsrsToListEmails (void); +void Mai_GetSelectedUsrsAndListEmails (void); bool Mai_CheckIfEmailIsValid (const char *Email); bool Mai_GetEmailFromUsrCod (struct UsrData *UsrDat); diff --git a/swad_menu.c b/swad_menu.c index 2e86652a..a6d55e56 100644 --- a/swad_menu.c +++ b/swad_menu.c @@ -255,7 +255,7 @@ const Act_Action_t Mnu_MenuActions[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB ActReqMsgUsr, // 4 ActSeeRcvMsg, // 5 ActSeeSntMsg, // 6 - ActMaiStd, // 7 + ActReqMaiUsr, // 7 0, // 8 0, // 9 0, // 10 diff --git a/swad_project.c b/swad_project.c index 6762bff0..2b52a4f9 100644 --- a/swad_project.c +++ b/swad_project.c @@ -1999,9 +1999,6 @@ static void Prj_AddUsrsToProject (Prj_RoleInProject_t RoleInProject) } } - /***** Free memory used by list of selected users' codes *****/ - Usr_FreeListsSelectedUsrsCods (); - /***** Put form to edit project again *****/ Prj_RequestCreatOrEditPrj (PrjCod); } diff --git a/swad_text.c b/swad_text.c index 1e2f2ff8..490b8974 100644 --- a/swad_text.c +++ b/swad_text.c @@ -10232,6 +10232,27 @@ const char *Txt_Email = "Email"; #endif +const char *Txt_Email_addresses = +#if L==1 // ca + "Adreces de correu"; +#elif L==2 // de + "E-Mail-Adressen"; +#elif L==3 // en + "Email addresses"; +#elif L==4 // es + "Direcciones de correo"; +#elif L==5 // fr + "Adresses e-mail"; +#elif L==6 // gn + "Direcciones de correo"; // Okoteve traducción +#elif L==7 // it + "Indirizzi email"; +#elif L==8 // pl + "Adresy e-mail"; +#elif L==9 // pt + "Endereços de email"; +#endif + const char *Txt_Email_domain_X_removed = // Warning: it is very important to include %s in the following sentences #if L==1 // ca "Dominio de correo %s eliminado."; // Necessita traduccio @@ -19508,7 +19529,7 @@ const char *Txt_MENU_TITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = "Enviadas" #endif , - // 7: ActMaiStd + // 7: ActReqMaiUsr #if L==1 // ca "Correu" #elif L==2 // de @@ -21362,10 +21383,10 @@ const char *Txt_MENU_SUBTITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = "Mensagens enviadas por mim para outros usuários" #endif , - // 7: ActMaiStd + // 7: ActReqMaiUsr #if L==1 // ca "Creació d'un missatge de correu" - " per enviar-lo a estudiants d'aquesta assignatura" + " per enviar-lo a usuaris d'aquesta assignatura" " utilitzant el programa client de correu predeterminat en el meu sistema" #elif L==2 // de "E-Mail" @@ -21373,13 +21394,13 @@ const char *Txt_MENU_SUBTITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = "Email" #elif L==4 // es "Creación de un mensaje de correo" - " para enviarlo a estudiantes de esta asignatura" + " para enviarlo a usuarios de esta asignatura" " usando el programa cliente de correo predeterminado en mi sistema" #elif L==5 // fr "Courrier électronique" #elif L==6 // gn "Creación de un mensaje de correo" - " para enviarlo a estudiantes de esta asignatura" + " para enviarlo a esuarios de esta asignatura" " usando el programa cliente de correo predeterminado en mi sistema"// Okoteve traducción #elif L==7 // it "Email" @@ -41196,87 +41217,6 @@ const char *Txt_Students_now_are_required_to_read_this_information = "Os estudantes agora precisam ler essas informações."; #endif -const char *Txt_X_students_who_have_email = // Warning: it is very important to include %u and %f in the following sentences -#if L==1 // ca - "%u estudiantes con correo (%.1f%% de %u estudiantes)"; // Necessita traduccio -#elif L==2 // de - "%u Studenten mit E-Mail (%.1f%% von %u Studenten)"; -#elif L==3 // en - "%u students who have email (%.1f%% of %u students)"; -#elif L==4 // es - "%u estudiantes con correo (%.1f%% de %u estudiantes)"; -#elif L==5 // fr - "%u étudiants qui ont l'email (%.1f%% de %u étudiants)"; -#elif L==6 // gn - "%u estudiantes con correo (%.1f%% de %u estudiantes)"; // Okoteve traducción -#elif L==7 // it - "%u studenti che hanno email (%.1f%% di %u studenti)"; -#elif L==8 // pl - "%u students who have email (%.1f%% of %u students)"; // Potrzebujesz tlumaczenie -#elif L==9 // pt - "%u estudantes que têm email (%.1f%% dos %u estudantes)"; -#endif - -const char *Txt_Students_who_have_accepted_and_who_have_email = -#if L==1 // ca - "Estudiantes que han aceptado la inscripción" - " y que tienen correo"; // Necessita traduccio -#elif L==2 // de - "Studenten die akzeptiert wurden" - " und die E-Mail"; -#elif L==3 // en - "Students who have accepted" - " and who have email"; -#elif L==4 // es - "Estudiantes que han aceptado la inscripción" - " y que tienen correo"; -#elif L==5 // fr - "Étudiants qui ont accepté" - " et qui ont l'email"; -#elif L==6 // gn - "Estudiantes que han aceptado la inscripción" - " y que tienen correo"; // Okoteve traducción -#elif L==7 // it - "Studenti che hanno aderito" - " e che hanno email"; -#elif L==8 // pl - "Students who have accepted" - " and who have email"; // Potrzebujesz tlumaczenie -#elif L==9 // pt - "Estudantes que aceitaram" - " e que têm email"; -#endif - -const char *Txt_X_students_who_have_accepted_and_who_have_email = // Warning: it is very important to include %u and %f in the following sentences -#if L==1 // ca - "%u estudiantes que han aceptado la inscripción" - " y que tienen correo (%.1f%% de %u estudiantes)"; // Necessita traduccio -#elif L==2 // de - "%u Studenten die akzeptiert wurden" - " und die E-Mail (%.1f%% von %u Studenten)"; -#elif L==3 // en - "%u students who have accepted" - " and who have email (%.1f%% of %u students)"; -#elif L==4 // es - "%u estudiantes que han aceptado la inscripción" - " y que tienen correo (%.1f%% de %u estudiantes)"; -#elif L==5 // fr - "%u étudiants qui ont accepté" - " et qui ont l'email (%.1f%% de %u étudiants)"; -#elif L==6 // gn - "%u estudiantes que han aceptado la inscripción" - " y que tienen correo (%.1f%% de %u estudiantes)"; // Okoteve traducción -#elif L==7 // it - "%u studenti che hanno aderito" - " e che hanno email (%.1f%% di %u studenti)"; -#elif L==8 // pl - "%u students who have accepted" - " and who have email (%.1f%% of %u students)"; // Potrzebujesz tlumaczenie -#elif L==9 // pt - "%u estudantes que aceitaram" - " e que têm email (%.1f%% dos %u estudantes)"; -#endif - const char *Txt_Surname_1 = #if L==1 // ca "Primer cognom"; @@ -52155,6 +52095,57 @@ const char *Txt_users_with_no_group = "utilizadores com nenhum grupo"; #endif +const char *Txt_X_users_who_have_accepted_and_who_have_email = // Warning: it is very important to include %u in the following sentences +#if L==1 // ca + "%u usuaris que han aceptado la inscripción" + " y que tienen correo"; // Necessita traduccio +#elif L==2 // de + "%u Benutzer die akzeptiert wurden" + " und die E-Mail"; +#elif L==3 // en + "%u users who have accepted" + " and who have email"; +#elif L==4 // es + "%u usuarios que han aceptado la inscripción" + " y que tienen correo"; +#elif L==5 // fr + "%u utilisateurs qui ont accepté" + " et qui ont l'email"; +#elif L==6 // gn + "%u usuarios que han aceptado la inscripción" + " y que tienen correo"; // Okoteve traducción +#elif L==7 // it + "%u utenti che hanno aderito" + " e che hanno email"; +#elif L==8 // pl + "%u użytkowników who have accepted" + " and who have email"; // Potrzebujesz tlumaczenie +#elif L==9 // pt + "%u utilizadores que aceitaram" + " e que têm email"; +#endif + +const char *Txt_X_users_who_have_email = // Warning: it is very important to include %u in the following sentences +#if L==1 // ca + "%u usuaris con correo"; // Necessita traduccio +#elif L==2 // de + "%u Benutzer mit E-Mail"; +#elif L==3 // en + "%u users who have email"; +#elif L==4 // es + "%u usuarios con correo"; +#elif L==5 // fr + "%u utilisateurs qui ont l'email"; +#elif L==6 // gn + "%u usuarios con correo"; // Okoteve traducción +#elif L==7 // it + "%u utenti che hanno email"; +#elif L==8 // pl + "%u użytkowników who have email"; // Potrzebujesz tlumaczenie +#elif L==9 // pt + "%u utilizadores que têm email"; +#endif + const char *Txt_USR_LIST_TYPES[Usr_NUM_USR_LIST_TYPES] = { "" // Usr_LIST_UNKNOWN @@ -52326,6 +52317,27 @@ const char *Txt_View_data_of_FILE_OR_LINK_X = // Warning: it is very important t "Ver os dados de %s"; #endif +const char *Txt_View_email_addresses = +#if L==1 // ca + "Veure adreces de correu"; +#elif L==2 // de + "E-Mail-Adressen anzeigen"; +#elif L==3 // en + "View email addresses"; +#elif L==4 // es + "Ver direcciones de correo"; +#elif L==5 // fr + "Voir les adresses email"; +#elif L==6 // gn + "Ver asistencia"; // Okoteve traducción +#elif L==7 // it + "Vedi gli indirizzi email"; +#elif L==8 // pl + "Zobacz adresy e-mail"; +#elif L==9 // pt + "Ver endereços de email"; +#endif + const char *Txt_View_event = #if L==1 // ca "Veure esdeveniment"; diff --git a/swad_user.c b/swad_user.c index 00c38d02..4b9fb10f 100644 --- a/swad_user.c +++ b/swad_user.c @@ -6115,6 +6115,9 @@ void Usr_PutFormToSelectUsrsToGoToAct (Act_Action_t NextAction,void (*FuncParams /***** Get groups to show ******/ Grp_GetParCodsSeveralGrpsToShowUsrs (); + /***** Get lists of the selected users if not already got *****/ + Usr_GetListsSelectedUsrsCods (); + /***** Get and order lists of users from this course *****/ Usr_GetListUsrs (Hie_CRS,Rol_STD); Usr_GetListUsrs (Hie_CRS,Rol_NET); @@ -8246,7 +8249,8 @@ static bool Usr_SetOptionsListUsrsAllowed (Rol_Role_t UsrsRole, Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)); ICanChooseOption[Usr_OPTION_HOMEWORK] = - ICanChooseOption[Usr_OPTION_ATTENDANCE] = (Gbl.Scope.Current == Hie_CRS && + ICanChooseOption[Usr_OPTION_ATTENDANCE] = + ICanChooseOption[Usr_OPTION_EMAIL] = (Gbl.Scope.Current == Hie_CRS && (Gbl.Usrs.Me.Role.Logged == Rol_NET || Gbl.Usrs.Me.Role.Logged == Rol_TCH || Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)); @@ -8254,6 +8258,7 @@ static bool Usr_SetOptionsListUsrsAllowed (Rol_Role_t UsrsRole, case Rol_TCH: ICanChooseOption[Usr_OPTION_RECORDS] = ICanChooseOption[Usr_OPTION_MESSAGE] = + ICanChooseOption[Usr_OPTION_EMAIL] = ICanChooseOption[Usr_OPTION_FOLLOW] = ICanChooseOption[Usr_OPTION_UNFOLLOW] = (Gbl.Scope.Current == Hie_CRS && (Gbl.Usrs.Me.Role.Logged == Rol_STD || @@ -8304,7 +8309,7 @@ static void Usr_PutOptionsListUsrs (const bool ICanChooseOption[Usr_LIST_USRS_NU Txt_View_homework, // Usr_OPTION_HOMEWORK Txt_View_attendance, // Usr_OPTION_ATTENDANCE Txt_Send_message, // Usr_OPTION_MESSAGE - Txt_Create_email_message, // Usr_OPTION_EMAIL // TODO: Not activated. Active it when email to users allows selecting individual users + Txt_Create_email_message, // Usr_OPTION_EMAIL Txt_Follow, // Usr_OPTION_FOLLOW Txt_Unfollow, // Usr_OPTION_UNFOLLOW }; @@ -8431,11 +8436,11 @@ void Usr_DoActionOnSeveralUsrs1 (void) break; } break; - case Usr_OPTION_EMAIL: // TODO: Not activated. Active it when email to users allows selecting individual users + case Usr_OPTION_EMAIL: switch (Gbl.Action.Act) { case ActDoActOnSevStd: - Gbl.Action.Act = ActMaiStd; + Gbl.Action.Act = ActMaiUsr; break; default: break; diff --git a/swad_user.h b/swad_user.h index b1c03c07..959f25fb 100644 --- a/swad_user.h +++ b/swad_user.h @@ -130,7 +130,7 @@ typedef enum Usr_OPTION_HOMEWORK = 2, Usr_OPTION_ATTENDANCE = 3, Usr_OPTION_MESSAGE = 4, - Usr_OPTION_EMAIL = 5, // TODO: Not activated. Active it when email to users allows selecting individual users + Usr_OPTION_EMAIL = 5, Usr_OPTION_FOLLOW = 6, Usr_OPTION_UNFOLLOW = 7, } Usr_ListUsrsOption_t;