Version18.111

This commit is contained in:
Antonio Cañas Vargas 2019-04-11 21:37:11 +02:00
parent 073a2f779a
commit 79e5fbc4e1
11 changed files with 251 additions and 230 deletions

View File

@ -1311,9 +1311,10 @@ Messages:
1103. ActReqMsgUsr Write message to several users 1103. ActReqMsgUsr Write message to several users
1104. ActSeeRcvMsg Show the messages received from other users (link in menu) 1104. ActSeeRcvMsg Show the messages received from other users (link in menu)
1105. ActSeeSntMsg Show the messages sent to other users 1105. ActSeeSntMsg Show the messages sent to other users
1106. ActMaiStd Send an email to students 1106. ActReqMaiUsr Select users to send an email to them
1107. ActWriAnn Show form to create a new global announcement 1107. ActMaiUsr Send an email to users
1108. ActRcvAnn Receive and create a new global announcement 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 1110. ActHidAnn Hide a global announcement that was active
1111. ActRevAnn Reveal a global announcement that was hidden 1111. ActRevAnn Reveal a global announcement that was hidden
1112. ActRemAnn Remove global announcement 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" }, /* 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" }, /* 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" }, /* 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: // 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}, /* 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}, /* 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}, /* 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 ****************************************************************** // TabAna ******************************************************************
// Actions in menu: // 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" }, /* 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) -1, // #97 (obsolete action)
ActAssTst, // #98 ActAssTst, // #98
-1, // #99 (obsolete action) -1, // #99 (obsolete action)
ActMaiStd, // #100 ActMaiUsr, // #100
-1, // #101 (obsolete action) -1, // #101 (obsolete action)
-1, // #102 (obsolete action) -1, // #102 (obsolete action)
ActReqTst, // #103 ActReqTst, // #103
@ -4945,6 +4948,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un
ActAllShaSocNotUsr, // #1769 ActAllShaSocNotUsr, // #1769
ActAllFavSocNotUsr, // #1770 ActAllFavSocNotUsr, // #1770
ActAllFavSocComUsr, // #1771 ActAllFavSocComUsr, // #1771
ActReqMaiUsr, // #1772
}; };
/*****************************************************************************/ /*****************************************************************************/

View File

@ -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 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 #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 ActReqMsgUsr (ActUnfSevTch + 5)
#define ActSeeRcvMsg (ActUnfSevTch + 6) #define ActSeeRcvMsg (ActUnfSevTch + 6)
#define ActSeeSntMsg (ActUnfSevTch + 7) #define ActSeeSntMsg (ActUnfSevTch + 7)
#define ActMaiStd (ActUnfSevTch + 8) #define ActReqMaiUsr (ActUnfSevTch + 8)
// Secondary actions // Secondary actions
#define ActWriAnn (ActUnfSevTch + 9) #define ActWriAnn (ActUnfSevTch + 9)
#define ActRcvAnn (ActUnfSevTch + 10) #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 ActUnbUsrMsg (ActUnfSevTch + 167)
#define ActUnbUsrLst (ActUnfSevTch + 168) #define ActUnbUsrLst (ActUnfSevTch + 168)
#define ActMaiUsr (ActUnfSevTch + 169)
/*****************************************************************************/ /*****************************************************************************/
/****************************** Statistics tab *******************************/ /****************************** Statistics tab *******************************/
/*****************************************************************************/ /*****************************************************************************/
// Actions in menu // Actions in menu
#define ActReqUseGbl (ActUnbUsrLst + 1) #define ActReqUseGbl (ActMaiUsr + 1)
#define ActSeePhoDeg (ActUnbUsrLst + 2) #define ActSeePhoDeg (ActMaiUsr + 2)
#define ActReqStaCrs (ActUnbUsrLst + 3) #define ActReqStaCrs (ActMaiUsr + 3)
#define ActReqAccGbl (ActUnbUsrLst + 4) #define ActReqAccGbl (ActMaiUsr + 4)
#define ActReqMyUsgRep (ActUnbUsrLst + 5) #define ActReqMyUsgRep (ActMaiUsr + 5)
#define ActMFUAct (ActUnbUsrLst + 6) #define ActMFUAct (ActMaiUsr + 6)
// Secondary actions // Secondary actions
#define ActSeeUseGbl (ActUnbUsrLst + 7) #define ActSeeUseGbl (ActMaiUsr + 7)
#define ActPrnPhoDeg (ActUnbUsrLst + 8) #define ActPrnPhoDeg (ActMaiUsr + 8)
#define ActCalPhoDeg (ActUnbUsrLst + 9) #define ActCalPhoDeg (ActMaiUsr + 9)
#define ActSeeAccGbl (ActUnbUsrLst + 10) #define ActSeeAccGbl (ActMaiUsr + 10)
#define ActReqAccCrs (ActUnbUsrLst + 11) #define ActReqAccCrs (ActMaiUsr + 11)
#define ActSeeAccCrs (ActUnbUsrLst + 12) #define ActSeeAccCrs (ActMaiUsr + 12)
#define ActSeeAllStaCrs (ActUnbUsrLst + 13) #define ActSeeAllStaCrs (ActMaiUsr + 13)
#define ActLstClk (ActUnbUsrLst + 14) #define ActLstClk (ActMaiUsr + 14)
#define ActSeeMyUsgRep (ActUnbUsrLst + 15) #define ActSeeMyUsgRep (ActMaiUsr + 15)
/*****************************************************************************/ /*****************************************************************************/
/******************************** Profile tab ********************************/ /******************************** Profile tab ********************************/

View File

@ -456,10 +456,14 @@ En OpenSWAD:
ps2pdf source.ps destination.pdf 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 CSS_FILE "swad18.92.css"
#define JS_FILE "swad18.92.js" #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.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.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) Version 18.110.1: Apr 11, 2019 Code refactoring in selection of groups and users. (242553 lines)

View File

@ -3187,9 +3187,6 @@ static void Brw_ShowFileBrowsersAsgWrkCrs (void)
/***** End table and box *****/ /***** End table and box *****/
Box_EndBoxTable (); Box_EndBoxTable ();
/***** Free memory used by list of selected users' codes *****/
Usr_FreeListsSelectedUsrsCods ();
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@ -88,6 +88,8 @@ static void Mai_PutFormToCreateMailDomain (void);
static void Mai_PutHeadMailDomains (void); static void Mai_PutHeadMailDomains (void);
static void Mai_CreateMailDomain (struct Mail *Mai); static void Mai_CreateMailDomain (struct Mail *Mai);
static void Mai_ListEmails (void);
static void Mai_ShowFormChangeUsrEmail (const struct UsrData *UsrDat,bool ItsMe, static void Mai_ShowFormChangeUsrEmail (const struct UsrData *UsrDat,bool ItsMe,
bool IMustFillInEmail,bool IShouldConfirmEmail); bool IMustFillInEmail,bool IShouldConfirmEmail);
@ -874,144 +876,141 @@ static void Mai_CreateMailDomain (struct Mail *Mai)
Mai->Domain,Mai->Info); 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 ******/ /****** List the emails of all the students to creates an email message ******/
/*****************************************************************************/ /*****************************************************************************/
#define Mai_MAX_BYTES_STR_ADDR (256 * 1024 - 1) #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 *Hlp_MESSAGES_Email;
extern const char *The_ClassFormOutBoxBold[The_NUM_THEMES]; extern const char *The_ClassFormOutBoxBold[The_NUM_THEMES];
extern const char *Txt_Students_who_have_accepted_and_who_have_email; extern const char *Txt_Email_addresses;
extern const char *Txt_X_students_who_have_email; extern const char *Txt_X_users_who_have_email;
extern const char *Txt_X_students_who_have_accepted_and_who_have_email; extern const char *Txt_X_users_who_have_accepted_and_who_have_email;
extern const char *Txt_Create_email_message; extern const char *Txt_Create_email_message;
unsigned NumUsr; unsigned NumUsrsWithEmail = 0;
unsigned NumStdsWithEmail; unsigned NumAcceptedUsrsWithEmail = 0;
unsigned NumAcceptedStdsWithEmail;
char StrAddresses[Mai_MAX_BYTES_STR_ADDR + 1]; // TODO: Use malloc depending on the number of students char StrAddresses[Mai_MAX_BYTES_STR_ADDR + 1]; // TODO: Use malloc depending on the number of students
unsigned int LengthStrAddr = 0; unsigned int LengthStrAddr = 0;
struct UsrData UsrDat; struct UsrData UsrDat;
const char *Ptr;
/***** Get groups to show ******/
Grp_GetParCodsSeveralGrpsToShowUsrs ();
/***** Get and order list of students in this course *****/
Usr_GetListUsrs (Hie_CRS,Rol_STD);
/***** Start the box used to list the emails *****/ /***** 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); Hlp_MESSAGES_Email,Box_NOT_CLOSABLE);
/***** Form to select groups *****/ /***** Start list with users' email addresses *****/
Grp_ShowFormToSelectSeveralGroups (NULL, fprintf (Gbl.F.Out,"<div class=\"DAT_SMALL CENTER_MIDDLE\">");
Grp_ONLY_MY_GROUPS);
/***** Start section with user list *****/ /***** Initialize structure with user's data *****/
Lay_StartSection (Usr_USER_LIST_SECTION_ID); 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)) /* Get next user */
{ Par_GetNextStrUntilSeparParamMult (&Ptr,UsrDat.EncryptedUsrCod,
/***** Initialize structure with user's data *****/ Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
Usr_UsrDataConstructor (&UsrDat); Usr_GetUsrCodFromEncryptedUsrCod (&UsrDat);
/***** List the students' email addresses *****/ /* Get user's email */
fprintf (Gbl.F.Out,"<div class=\"DAT_SMALL CENTER_MIDDLE\">"); Mai_GetEmailFromUsrCod (&UsrDat);
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 */ if (UsrDat.Email[0])
Mai_GetEmailFromUsrCod (&UsrDat); {
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++; fprintf (Gbl.F.Out,", ");
if (UsrDat.Accepted) // If student has email and has accepted LengthStrAddr ++;
{ if (LengthStrAddr > Mai_MAX_BYTES_STR_ADDR)
if (NumAcceptedStdsWithEmail > 0) Lay_ShowErrorAndExit ("The space allocated to store email addresses is full.");
{ Str_Concat (StrAddresses,",",
fprintf (Gbl.F.Out,", "); Mai_MAX_BYTES_STR_ADDR);
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,"<a href=\"mailto:%s?subject=%s\">%s</a>",
UsrDat.Email,Gbl.Hierarchy.Crs.FullName,UsrDat.Email);
NumAcceptedStdsWithEmail++;
}
} }
} LengthStrAddr += strlen (UsrDat.Email);
fprintf (Gbl.F.Out,"</div>"); 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,"<a href=\"mailto:%s?subject=%s\">%s</a>",
UsrDat.Email,Gbl.Hierarchy.Crs.FullName,UsrDat.Email);
/***** Free memory used for user's data *****/ NumAcceptedUsrsWithEmail++;
Usr_UsrDataDestructor (&UsrDat); }
}
/***** Show a message with the number of students with email ****/
fprintf (Gbl.F.Out,"<div class=\"DAT CENTER_MIDDLE\">");
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,"</div>");
/***** Show a message with the number of students who have accepted and have email ****/
fprintf (Gbl.F.Out,"<div class=\"DAT CENTER_MIDDLE\">");
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,"</div>");
/***** Icon to open the client email program *****/
fprintf (Gbl.F.Out,"<div class=\"CONTEXT_MENU\">"
"<a href=\"mailto:%s?subject=%s&cc=%s&bcc=%s\""
" title=\"%s\" class=\"%s\">",
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,"</a>"
"</div>");
}
} }
else // Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs == 0
/***** Show warning indicating no students found *****/
Usr_ShowWarningNoUsersFound (Rol_STD);
/***** End section with user list *****/ /***** Free memory used for user's data *****/
Lay_EndSection (); Usr_UsrDataDestructor (&UsrDat);
/***** End list with users' email addresses *****/
fprintf (Gbl.F.Out,"</div>");
/***** Show a message with the number of users with email ****/
fprintf (Gbl.F.Out,"<div class=\"DAT CENTER_MIDDLE\">");
fprintf (Gbl.F.Out,Txt_X_users_who_have_email,
NumUsrsWithEmail);
fprintf (Gbl.F.Out,"</div>");
/***** Show a message with the number of users who have accepted and have email ****/
fprintf (Gbl.F.Out,"<div class=\"DAT CENTER_MIDDLE\">");
fprintf (Gbl.F.Out,Txt_X_users_who_have_accepted_and_who_have_email,
NumAcceptedUsrsWithEmail);
fprintf (Gbl.F.Out,"</div>");
/***** Icon to open the client email program *****/
fprintf (Gbl.F.Out,"<div class=\"CONTEXT_MENU\">"
"<a href=\"mailto:%s?subject=%s&cc=%s&bcc=%s\""
" title=\"%s\" class=\"%s\">",
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,"</a>"
"</div>");
/***** End the box used to list the emails *****/ /***** End the box used to list the emails *****/
Box_EndBox (); Box_EndBox ();
/***** Free memory for students list *****/
Usr_FreeUsrsList (Rol_STD);
/***** Free memory for list of selected groups *****/
Grp_FreeListCodSelectedGrps ();
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@ -72,7 +72,8 @@ void Mai_RenameMailDomainFull (void);
void Mai_ContEditAfterChgMai (void); void Mai_ContEditAfterChgMai (void);
void Mai_RecFormNewMailDomain (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_CheckIfEmailIsValid (const char *Email);
bool Mai_GetEmailFromUsrCod (struct UsrData *UsrDat); bool Mai_GetEmailFromUsrCod (struct UsrData *UsrDat);

View File

@ -255,7 +255,7 @@ const Act_Action_t Mnu_MenuActions[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB
ActReqMsgUsr, // 4 ActReqMsgUsr, // 4
ActSeeRcvMsg, // 5 ActSeeRcvMsg, // 5
ActSeeSntMsg, // 6 ActSeeSntMsg, // 6
ActMaiStd, // 7 ActReqMaiUsr, // 7
0, // 8 0, // 8
0, // 9 0, // 9
0, // 10 0, // 10

View File

@ -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 *****/ /***** Put form to edit project again *****/
Prj_RequestCreatOrEditPrj (PrjCod); Prj_RequestCreatOrEditPrj (PrjCod);
} }

View File

@ -10232,6 +10232,27 @@ const char *Txt_Email =
"Email"; "Email";
#endif #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&ccedil;os de email";
#endif
const char *Txt_Email_domain_X_removed = // Warning: it is very important to include %s in the following sentences const char *Txt_Email_domain_X_removed = // Warning: it is very important to include %s in the following sentences
#if L==1 // ca #if L==1 // ca
"Dominio de correo <strong>%s</strong> eliminado."; // Necessita traduccio "Dominio de correo <strong>%s</strong> eliminado."; // Necessita traduccio
@ -19508,7 +19529,7 @@ const char *Txt_MENU_TITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] =
"Enviadas" "Enviadas"
#endif #endif
, ,
// 7: ActMaiStd // 7: ActReqMaiUsr
#if L==1 // ca #if L==1 // ca
"Correu" "Correu"
#elif L==2 // de #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&aacute;rios" "Mensagens enviadas por mim para outros usu&aacute;rios"
#endif #endif
, ,
// 7: ActMaiStd // 7: ActReqMaiUsr
#if L==1 // ca #if L==1 // ca
"Creaci&oacute; d'un missatge de correu" "Creaci&oacute; 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" " utilitzant el programa client de correu predeterminat en el meu sistema"
#elif L==2 // de #elif L==2 // de
"E-Mail" "E-Mail"
@ -21373,13 +21394,13 @@ const char *Txt_MENU_SUBTITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] =
"Email" "Email"
#elif L==4 // es #elif L==4 // es
"Creaci&oacute;n de un mensaje de correo" "Creaci&oacute;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" " usando el programa cliente de correo predeterminado en mi sistema"
#elif L==5 // fr #elif L==5 // fr
"Courrier &eacute;lectronique" "Courrier &eacute;lectronique"
#elif L==6 // gn #elif L==6 // gn
"Creaci&oacute;n de un mensaje de correo" "Creaci&oacute;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 " usando el programa cliente de correo predeterminado en mi sistema"// Okoteve traducción
#elif L==7 // it #elif L==7 // it
"Email" "Email"
@ -41196,87 +41217,6 @@ const char *Txt_Students_now_are_required_to_read_this_information =
"Os estudantes agora precisam ler essas informa&ccedil;&otilde;es."; "Os estudantes agora precisam ler essas informa&ccedil;&otilde;es.";
#endif #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 &eacute;tudiants qui ont l'email (%.1f%% de %u &eacute;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&ecirc;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&oacute;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&oacute;n"
" y que tienen correo";
#elif L==5 // fr
"&Eacute;tudiants qui ont accept&eacute;"
" et qui ont l'email";
#elif L==6 // gn
"Estudiantes que han aceptado la inscripci&oacute;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&ecirc;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&oacute;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&oacute;n"
" y que tienen correo (%.1f%% de %u estudiantes)";
#elif L==5 // fr
"%u &eacute;tudiants qui ont accept&eacute;"
" et qui ont l'email (%.1f%% de %u &eacute;tudiants)";
#elif L==6 // gn
"%u estudiantes que han aceptado la inscripci&oacute;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&ecirc;m email (%.1f%% dos %u estudantes)";
#endif
const char *Txt_Surname_1 = const char *Txt_Surname_1 =
#if L==1 // ca #if L==1 // ca
"Primer cognom"; "Primer cognom";
@ -52155,6 +52095,57 @@ const char *Txt_users_with_no_group =
"utilizadores com nenhum grupo"; "utilizadores com nenhum grupo";
#endif #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&oacute;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&oacute;n"
" y que tienen correo";
#elif L==5 // fr
"%u utilisateurs qui ont accept&eacute;"
" et qui ont l'email";
#elif L==6 // gn
"%u usuarios que han aceptado la inscripci&oacute;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&zdot;ytkownik&oacute;w who have accepted"
" and who have email"; // Potrzebujesz tlumaczenie
#elif L==9 // pt
"%u utilizadores que aceitaram"
" e que t&ecirc;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&zdot;ytkownik&oacute;w who have email"; // Potrzebujesz tlumaczenie
#elif L==9 // pt
"%u utilizadores que t&ecirc;m email";
#endif
const char *Txt_USR_LIST_TYPES[Usr_NUM_USR_LIST_TYPES] = const char *Txt_USR_LIST_TYPES[Usr_NUM_USR_LIST_TYPES] =
{ {
"" // Usr_LIST_UNKNOWN "" // 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"; "Ver os dados de %s";
#endif #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&ccedil;os de email";
#endif
const char *Txt_View_event = const char *Txt_View_event =
#if L==1 // ca #if L==1 // ca
"Veure esdeveniment"; "Veure esdeveniment";

View File

@ -6115,6 +6115,9 @@ void Usr_PutFormToSelectUsrsToGoToAct (Act_Action_t NextAction,void (*FuncParams
/***** Get groups to show ******/ /***** Get groups to show ******/
Grp_GetParCodsSeveralGrpsToShowUsrs (); Grp_GetParCodsSeveralGrpsToShowUsrs ();
/***** Get lists of the selected users if not already got *****/
Usr_GetListsSelectedUsrsCods ();
/***** Get and order lists of users from this course *****/ /***** Get and order lists of users from this course *****/
Usr_GetListUsrs (Hie_CRS,Rol_STD); Usr_GetListUsrs (Hie_CRS,Rol_STD);
Usr_GetListUsrs (Hie_CRS,Rol_NET); 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)); Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM));
ICanChooseOption[Usr_OPTION_HOMEWORK] = 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_NET ||
Gbl.Usrs.Me.Role.Logged == Rol_TCH || Gbl.Usrs.Me.Role.Logged == Rol_TCH ||
Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)); Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM));
@ -8254,6 +8258,7 @@ static bool Usr_SetOptionsListUsrsAllowed (Rol_Role_t UsrsRole,
case Rol_TCH: case Rol_TCH:
ICanChooseOption[Usr_OPTION_RECORDS] = ICanChooseOption[Usr_OPTION_RECORDS] =
ICanChooseOption[Usr_OPTION_MESSAGE] = ICanChooseOption[Usr_OPTION_MESSAGE] =
ICanChooseOption[Usr_OPTION_EMAIL] =
ICanChooseOption[Usr_OPTION_FOLLOW] = ICanChooseOption[Usr_OPTION_FOLLOW] =
ICanChooseOption[Usr_OPTION_UNFOLLOW] = (Gbl.Scope.Current == Hie_CRS && ICanChooseOption[Usr_OPTION_UNFOLLOW] = (Gbl.Scope.Current == Hie_CRS &&
(Gbl.Usrs.Me.Role.Logged == Rol_STD || (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_homework, // Usr_OPTION_HOMEWORK
Txt_View_attendance, // Usr_OPTION_ATTENDANCE Txt_View_attendance, // Usr_OPTION_ATTENDANCE
Txt_Send_message, // Usr_OPTION_MESSAGE 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_Follow, // Usr_OPTION_FOLLOW
Txt_Unfollow, // Usr_OPTION_UNFOLLOW Txt_Unfollow, // Usr_OPTION_UNFOLLOW
}; };
@ -8431,11 +8436,11 @@ void Usr_DoActionOnSeveralUsrs1 (void)
break; break;
} }
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) switch (Gbl.Action.Act)
{ {
case ActDoActOnSevStd: case ActDoActOnSevStd:
Gbl.Action.Act = ActMaiStd; Gbl.Action.Act = ActMaiUsr;
break; break;
default: default:
break; break;

View File

@ -130,7 +130,7 @@ typedef enum
Usr_OPTION_HOMEWORK = 2, Usr_OPTION_HOMEWORK = 2,
Usr_OPTION_ATTENDANCE = 3, Usr_OPTION_ATTENDANCE = 3,
Usr_OPTION_MESSAGE = 4, 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_FOLLOW = 6,
Usr_OPTION_UNFOLLOW = 7, Usr_OPTION_UNFOLLOW = 7,
} Usr_ListUsrsOption_t; } Usr_ListUsrsOption_t;