diff --git a/icon/backward64x64.png b/icon/backward64x64.png new file mode 100644 index 000000000..c71d36257 Binary files /dev/null and b/icon/backward64x64.png differ diff --git a/icon/forward64x64.png b/icon/forward64x64.png new file mode 100644 index 000000000..21d00a028 Binary files /dev/null and b/icon/forward64x64.png differ diff --git a/swad_agenda.c b/swad_agenda.c index b740d665f..e1682200f 100644 --- a/swad_agenda.c +++ b/swad_agenda.c @@ -75,6 +75,13 @@ typedef enum /***************************** Private prototypes ****************************/ /*****************************************************************************/ +static void Agd_ShowFormToSelPastFutureEvents (void); +static void Agd_ShowFormToSelPrivatePublicEvents (void); +static void Agd_ShowFormToSelHiddenVisibleEvents (void); +static void Agd_PutHiddenParamsPastFutureEvents (unsigned PastFutureEvents); +static void Agd_PutHiddenParamsPrivatePublicEvents (unsigned PrivatePublicEvents); +static void Agd_PutHiddenParamsHiddenVisibleEvents (unsigned HiddenVisibleEvents); + static void Agd_ShowEvents (Agd_AgendaType_t AgendaType); static void Agd_ShowEventsToday (Agd_AgendaType_t AgendaType); static void Agd_WriteHeaderListEvents (Agd_AgendaType_t AgendaType); @@ -134,6 +141,11 @@ void Agd_ShowMyAgenda (void) Lay_StartRoundFrame ("100%",Txt_My_agenda, Agd_PutIconsMyFullAgenda,Hlp_PROFILE_Agenda); + /***** Put forms to choice which events to show *****/ + Agd_ShowFormToSelPastFutureEvents (); + Agd_ShowFormToSelPrivatePublicEvents (); + Agd_ShowFormToSelHiddenVisibleEvents (); + /***** Show the current events in the user's agenda *****/ Agd_ShowEventsToday (Agd_MY_FULL_AGENDA_TODAY); @@ -144,6 +156,186 @@ void Agd_ShowMyAgenda (void) Lay_EndRoundFrame (); } +/*****************************************************************************/ +/*************** Show form to select past / future events ********************/ +/*****************************************************************************/ + +static void Agd_ShowFormToSelPastFutureEvents (void) + { + extern const char *Txt_AGENDA_PAST_FUTURE_EVENTS[2]; + Agd_PastFutureEvents_t PstFut; + static const char *Image[2] = + { + "backward64x64.png", // Agd_PAST_EVENTS + "forward64x64.png", // Agd_FUTURE_EVENTS + }; + + fprintf (Gbl.F.Out,"
"); + for (PstFut = Agd_PAST_EVENTS; + PstFut <= Agd_FUTURE_EVENTS; + PstFut++) + { + fprintf (Gbl.F.Out,"
", + (Gbl.Agenda.PastFutureEvents & (1 << PstFut)) ? "PREF_ON" : + "PREF_OFF"); + Act_FormStart (ActSeeMyAgd); + Agd_PutHiddenParamsPastFutureEvents (1 << PstFut); + Agd_PutHiddenParamsPrivatePublicEvents (Gbl.Agenda.PrivatePublicEvents); + Agd_PutHiddenParamsHiddenVisibleEvents (Gbl.Agenda.HiddenVisibleEvents); + + fprintf (Gbl.F.Out,"", + Gbl.Prefs.IconsURL, + Image[PstFut], + Txt_AGENDA_PAST_FUTURE_EVENTS[PstFut], + Txt_AGENDA_PAST_FUTURE_EVENTS[PstFut]); + Act_FormEnd (); + fprintf (Gbl.F.Out,"
"); + } + fprintf (Gbl.F.Out,"
"); + } + +/*****************************************************************************/ +/************** Show form to select private / public events ******************/ +/*****************************************************************************/ + +static void Agd_ShowFormToSelPrivatePublicEvents (void) + { + extern const char *Txt_AGENDA_PRIVATE_PUBLIC_EVENTS[2]; + Agd_PastFutureEvents_t PrvPub; + static const char *Image[2] = + { + "lock-on64x64.png", // Agd_PRIVATE_EVENTS + "unlock-on64x64.png", // Agd_PUBLIC_EVENTS + }; + + fprintf (Gbl.F.Out,"
"); + for (PrvPub = Agd_PAST_EVENTS; + PrvPub <= Agd_FUTURE_EVENTS; + PrvPub++) + { + fprintf (Gbl.F.Out,"
", + (Gbl.Agenda.PastFutureEvents & (1 << PrvPub)) ? "PREF_ON" : + "PREF_OFF"); + Act_FormStart (ActSeeMyAgd); + Agd_PutHiddenParamsPastFutureEvents (1 << PrvPub); + Agd_PutHiddenParamsPrivatePublicEvents (Gbl.Agenda.PrivatePublicEvents); + Agd_PutHiddenParamsHiddenVisibleEvents (Gbl.Agenda.HiddenVisibleEvents); + + fprintf (Gbl.F.Out,"", + Gbl.Prefs.IconsURL, + Image[PrvPub], + Txt_AGENDA_PRIVATE_PUBLIC_EVENTS[PrvPub], + Txt_AGENDA_PRIVATE_PUBLIC_EVENTS[PrvPub]); + Act_FormEnd (); + fprintf (Gbl.F.Out,"
"); + } + fprintf (Gbl.F.Out,"
"); + } + +/*****************************************************************************/ +/************* Show form to select hidden / visible events *******************/ +/*****************************************************************************/ + +static void Agd_ShowFormToSelHiddenVisibleEvents (void) + { + extern const char *Txt_AGENDA_HIDDEN_VISIBLE_EVENTS[2]; + Agd_PastFutureEvents_t HidVis; + static const char *Image[2] = + { + "eye-slash-on64x64.png", // Agd_HIDDEN_EVENTS + "eye-on64x64.png", // Agd_VISIBLE_EVENTS + }; + + fprintf (Gbl.F.Out,"
"); + for (HidVis = Agd_PAST_EVENTS; + HidVis <= Agd_FUTURE_EVENTS; + HidVis++) + { + fprintf (Gbl.F.Out,"
", + (Gbl.Agenda.PastFutureEvents & (1 << HidVis)) ? "PREF_ON" : + "PREF_OFF"); + Act_FormStart (ActSeeMyAgd); + Agd_PutHiddenParamsPastFutureEvents (1 << HidVis); + Agd_PutHiddenParamsPrivatePublicEvents (Gbl.Agenda.PrivatePublicEvents); + Agd_PutHiddenParamsHiddenVisibleEvents (Gbl.Agenda.HiddenVisibleEvents); + + fprintf (Gbl.F.Out,"", + Gbl.Prefs.IconsURL, + Image[HidVis], + Txt_AGENDA_HIDDEN_VISIBLE_EVENTS[HidVis], + Txt_AGENDA_HIDDEN_VISIBLE_EVENTS[HidVis]); + Act_FormEnd (); + fprintf (Gbl.F.Out,"
"); + } + fprintf (Gbl.F.Out,"
"); + } + +/*****************************************************************************/ +/**************** Put hidden params for past / future events *****************/ +/*****************************************************************************/ + +static void Agd_PutHiddenParamsPastFutureEvents (unsigned PastFutureEvents) + { + Agd_PastFutureEvents_t PstFut; + static const char *ParamName[2] = + { + "Past", // Agd_PAST_EVENTS + "Future", // Agd_FUTURE_EVENTS + }; + + for (PstFut = Agd_PAST_EVENTS; + PstFut <= Agd_FUTURE_EVENTS; + PstFut++) + if (PastFutureEvents & (1 << PstFut)) // Booleans stored as bits in PastFutureEvents + Par_PutHiddenParamChar (ParamName[PstFut],'Y'); + } + +/*****************************************************************************/ +/************** Put hidden params for private / public events ****************/ +/*****************************************************************************/ + +static void Agd_PutHiddenParamsPrivatePublicEvents (unsigned PrivatePublicEvents) + { + Agd_PrivatePublicEvents_t PrvPub; + static const char *ParamName[2] = + { + "Private", // Agd_PRIVATE_EVENTS + "Public", // Agd_PUBLIC_EVENTS + }; + + for (PrvPub = Agd_PRIVATE_EVENTS; + PrvPub <= Agd_PUBLIC_EVENTS; + PrvPub++) + if (PrivatePublicEvents & (1 << PrvPub)) // Booleans stored as bits in PrivatePublicEvents + Par_PutHiddenParamChar (ParamName[PrvPub],'Y'); + } + +/*****************************************************************************/ +/************** Put hidden params for hidden / visible events ****************/ +/*****************************************************************************/ + +static void Agd_PutHiddenParamsHiddenVisibleEvents (unsigned HiddenVisibleEvents) + { + Agd_HiddenVisibleEvents_t HidVis; + static const char *ParamName[2] = + { + "Hidden", // Agd_HIDDEN_EVENTS + "Visible", // Agd_VISIBLE_EVENTS + }; + + for (HidVis = Agd_HIDDEN_EVENTS; + HidVis <= Agd_VISIBLE_EVENTS; + HidVis++) + if (HiddenVisibleEvents & (1 << HidVis)) // Booleans stored as bits in HiddenVisibleEvents + Par_PutHiddenParamChar (ParamName[HidVis],'Y'); + } + /*****************************************************************************/ /*************************** Show my public agenda ***************************/ /*****************************************************************************/ diff --git a/swad_agenda.h b/swad_agenda.h index b2fa193a7..0c3b97359 100644 --- a/swad_agenda.h +++ b/swad_agenda.h @@ -61,9 +61,19 @@ struct AgendaEvent typedef enum { - Agd_ALL_EVENTS, - Agd_ONLY_PUBLIC_EVENTS, - } Agd_WhichEvents_t; + Agd_PAST_EVENTS, // Events until yesterday (included) + Agd_FUTURE_EVENTS, // Events from today (included) onwards + } Agd_PastFutureEvents_t; +typedef enum + { + Agd_PRIVATE_EVENTS, + Agd_PUBLIC_EVENTS, + } Agd_PrivatePublicEvents_t; +typedef enum + { + Agd_HIDDEN_EVENTS, + Agd_VISIBLE_EVENTS, + } Agd_HiddenVisibleEvents_t; #define Agd_NUM_ORDERS 2 typedef enum diff --git a/swad_changelog.h b/swad_changelog.h index 83b49e93f..d21bc4433 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -210,13 +210,19 @@ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 16.157.3 (2017-03-20)" +#define Log_PLATFORM_VERSION "SWAD 16.158 (2017-03-21)" #define CSS_FILE "swad16.157.css" #define JS_FILE "swad16.144.js" // Number of lines (includes comments but not blank lines) has been got with the following command: // nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*?.h sql/swad*.sql | tail -1 /* + Version 16.158: Mar 21, 2017 Changes in agenda. No finished. + Fixed bug in user enrollment. (217394 lines) +Copy the following icons to icon public directory: +sudo cp -a backward64x64.png /var/www/html/swad/icon/ +sudo cp -a forward64x64.png /var/www/html/swad/icon/ + Version 16.157.3: Mar 20, 2017 Contextual help in edition of custom record card fields. (217046 lines) Version 16.157.2: Mar 20, 2017 Some help URLs translated to spanish. (217041 lines) Version 16.157.1: Mar 20, 2017 Some help URLs translated to spanish. (217040 lines) diff --git a/swad_enrollment.c b/swad_enrollment.c index 5e62032b4..653d660b9 100644 --- a/swad_enrollment.c +++ b/swad_enrollment.c @@ -1685,7 +1685,7 @@ static void Enr_RegisterUsr (struct UsrData *UsrDat,Rol_Role_t RegRemRole, /***** Check if I can register this user *****/ if (Gbl.Usrs.Me.LoggedRole == Rol_TEACHER && RegRemRole != Rol_STUDENT) - Lay_ShowErrorAndExit ("A teacher only can register new users if they are students."); + Lay_ShowErrorAndExit ("A teacher only can register several users as students."); /***** Check if the record of the user exists and get the type of user *****/ if (UsrDat->UsrCod > 0) // User exists in database @@ -3574,9 +3574,6 @@ void Enr_CreateNewUsr1 (void) /***** Get new role *****/ NewRole = Rec_GetRoleFromRecordForm (); - if (Gbl.Usrs.Me.LoggedRole == Rol_TEACHER && - NewRole != Rol_STUDENT) - Lay_ShowErrorAndExit ("A teacher only can create new users as students."); /***** Get user's name from form *****/ Rec_GetUsrNameFromRecordForm (&Gbl.Usrs.Other.UsrDat); diff --git a/swad_global.c b/swad_global.c index dfd09a539..5d59dc70a 100644 --- a/swad_global.c +++ b/swad_global.c @@ -422,6 +422,13 @@ void Gbl_InitializeGlobals (void) Gbl.FileBrowser.FileType = Brw_IS_UNKNOWN; Gbl.FileBrowser.UploadingWithDropzone = false; + /* Agenda */ + Gbl.Agenda.PastFutureEvents = (1 << Agd_FUTURE_EVENTS); + Gbl.Agenda.PrivatePublicEvents = (1 << Agd_PRIVATE_EVENTS) & + (1 << Agd_PUBLIC_EVENTS); + Gbl.Agenda.HiddenVisibleEvents = (1 << Agd_VISIBLE_EVENTS); + Gbl.Agenda.SelectedOrder = Agd_ORDER_DEFAULT; + /* To alternate colors where listing rows */ Gbl.RowEvenOdd = 0; Gbl.ColorRows[0] = "COLOR0"; // Darker diff --git a/swad_global.h b/swad_global.h index a2230556e..408be9bee 100644 --- a/swad_global.h +++ b/swad_global.h @@ -414,6 +414,9 @@ struct Globals bool LstIsRead; // Is the list already read from database, or it needs to be read? unsigned Num; // Number of events long *LstAgdCods; // List of agenda codes + unsigned PastFutureEvents; + unsigned PrivatePublicEvents; + unsigned HiddenVisibleEvents; Agd_Order_t SelectedOrder; long AgdCodToEdit; // Used as parameter in contextual links } Agenda; diff --git a/swad_group.c b/swad_group.c index b67366e65..5633eb3ec 100644 --- a/swad_group.c +++ b/swad_group.c @@ -4263,7 +4263,7 @@ void Grp_PutParamWhichGrpsAllGrps (void) void Grp_ShowFormToSelWhichGrps (Act_Action_t Action,void (*FuncParams) ()) { - extern const char *Txt_Show_WHICH_groups[2]; + extern const char *Txt_GROUP_WHICH_GROUPS[2]; Grp_WhichGroups_t WhichGrps; fprintf (Gbl.F.Out,"
"); @@ -4284,8 +4284,8 @@ void Grp_ShowFormToSelWhichGrps (Act_Action_t Action,void (*FuncParams) ()) Gbl.Prefs.IconsURL, WhichGrps == Grp_ONLY_MY_GROUPS ? "myhierarchy64x64.png" : "hierarchy64x64.png", - Txt_Show_WHICH_groups[WhichGrps], - Txt_Show_WHICH_groups[WhichGrps]); + Txt_GROUP_WHICH_GROUPS[WhichGrps], + Txt_GROUP_WHICH_GROUPS[WhichGrps]); Act_FormEnd (); fprintf (Gbl.F.Out,"
"); } diff --git a/swad_text.c b/swad_text.c index 1adcd2764..ea2e8b6b5 100644 --- a/swad_text.c +++ b/swad_text.c @@ -66,6 +66,7 @@ #include // For NULL +#include "swad_agenda.h" #include "swad_assignment.h" #include "swad_attendance.h" #include "swad_config.h" @@ -2104,6 +2105,208 @@ const char *Txt_Administer_user = "Gerenciar utilizador"; #endif +const char *Txt_AGENDA_PAST_FUTURE_EVENTS[2] = + { + // Agd_PAST_EVENTS +#if L==1 + "Esdeveniments passats" +#elif L==2 + "Vergangene Ereignisse" +#elif L==3 + "Past events" +#elif L==4 + "Eventos pasados" +#elif L==5 + "Événements passés" +#elif L==6 + "Eventos pasados" // Okoteve traducción +#elif L==7 + "Eventi passati" +#elif L==8 + "Minione wydarzenia" +#elif L==9 + "Eventos passados" +#endif + , + // Agd_FUTURE_EVENTS +#if L==1 + "Esdeveniments actuals i futurs" +#elif L==2 + "Aktuelle und zukünftige Ereignisse" +#elif L==3 + "Current and future events" +#elif L==4 + "Eventos actuales y futuros" +#elif L==5 + "Événements actuels et futurs" +#elif L==6 + "Eventos actuales y futuros" // Okoteve traducción +#elif L==7 + "Eventi attuali e futuri" +#elif L==8 + "Obecne i przyszłe wydarzenia" +#elif L==9 + "Eventos atuais e futuros" +#endif + }; + +const char *Txt_AGENDA_PRIVATE_PUBLIC_EVENTS[2] = + { + // Agd_PRIVATE_EVENTS +#if L==1 + "Esdeveniments passats" +#elif L==2 + "Vergangene Ereignisse" +#elif L==3 + "Past events" +#elif L==4 + "Eventos pasados" +#elif L==5 + "Événements passés" +#elif L==6 + "Eventos pasados" // Okoteve traducción +#elif L==7 + "Eventi passati" +#elif L==8 + "Minione wydarzenia" +#elif L==9 + "Eventos passados" +#endif + , + // Agd_PUBLIC_EVENTS +#if L==1 + "Esdeveniments actuals i futurs" +#elif L==2 + "Aktuelle und zukünftige Ereignisse" +#elif L==3 + "Current and future events" +#elif L==4 + "Eventos actuales y futuros" +#elif L==5 + "Événements actuels et futurs" +#elif L==6 + "Eventos actuales y futuros" // Okoteve traducción +#elif L==7 + "Eventi attuali e futuri" +#elif L==8 + "Obecne i przyszłe wydarzenia" +#elif L==9 + "Eventos atuais e futuros" +#endif + }; + +const char *Txt_AGENDA_HIDDEN_VISIBLE_EVENTS[2] = + { + // Agd_HIDDEN_EVENTS +#if L==1 + "Esdeveniments passats" +#elif L==2 + "Vergangene Ereignisse" +#elif L==3 + "Past events" +#elif L==4 + "Eventos pasados" +#elif L==5 + "Événements passés" +#elif L==6 + "Eventos pasados" // Okoteve traducción +#elif L==7 + "Eventi passati" +#elif L==8 + "Minione wydarzenia" +#elif L==9 + "Eventos passados" +#endif + , + // Agd_VISIBLE_EVENTS +#if L==1 + "Esdeveniments actuals i futurs" +#elif L==2 + "Aktuelle und zukünftige Ereignisse" +#elif L==3 + "Current and future events" +#elif L==4 + "Eventos actuales y futuros" +#elif L==5 + "Événements actuels et futurs" +#elif L==6 + "Eventos actuales y futuros" // Okoteve traducción +#elif L==7 + "Eventi attuali e futuri" +#elif L==8 + "Obecne i przyszłe wydarzenia" +#elif L==9 + "Eventos atuais e futuros" +#endif + }; + +/* +const char *Txt_AGENDA_WHICH_EVENTS[Agd_NUM_WHICH_EVENTS] = + { + // Agd_ALL_EVENTS +#if L==1 + "Tots els esdeveniments" +#elif L==2 + "Alle Ereignisse" +#elif L==3 + "All events" +#elif L==4 + "Todos los eventos" +#elif L==5 + "Tous les événements" +#elif L==6 + "Todos los eventos" // Okoteve traducción +#elif L==7 + "Tutti i eventi" +#elif L==8 + "Wszystkie imprezy" +#elif L==9 + "Todos os eventos" +#endif + , + // Agd_ONLY_TODAY_AND_FUTURE_EVENTS +#if L==1 + "Esdeveniments actuals i futurs" +#elif L==2 + "Aktuelle und zukünftige Ereignisse" +#elif L==3 + "Current and future events" +#elif L==4 + "Eventos actuales y futuros" +#elif L==5 + "Événements actuels et futurs" +#elif L==6 + "Eventos actuales y futuros" // Okoteve traducción +#elif L==7 + "Eventi attuali e futuri" +#elif L==8 + "Obecne i przyszłe wydarzenia" +#elif L==9 + "Eventos atuais e futuros" +#endif + , + // Agd_ONLY_PUBLIC_EVENTS +#if L==1 + "Esdeveniments públics i visibles" +#elif L==2 + "Öffentliche und sichtbare Ereignisse" +#elif L==3 + "Public, visible events" +#elif L==4 + "Eventos públicos y visibles" +#elif L==5 + "Événements publics et visibles" +#elif L==6 + "Eventos públicos y visibles" // Okoteve traducción +#elif L==7 + "Eventi pubblici e visibili" +#elif L==8 + "Wydarzenia publiczne i widoczne" +#elif L==9 + "Eventos públicos e visíveis" +#endif + }; +*/ const char *Txt_all = #if L==1 "tot"; @@ -13976,6 +14179,49 @@ const char *Txt_Group_X_removed = // Warning: it is very important to include %s "Group %s removed."; // Necessita de tradução #endif +const char *Txt_GROUP_WHICH_GROUPS[2] = + { +#if L==1 + "Només els meus grups" +#elif L==2 + "Nur meine Gruppen" +#elif L==3 + "Only my groups" +#elif L==4 + "Solo mis grupos" +#elif L==5 + "Uniquement mes groupes" +#elif L==6 + "Solo mis grupos" // Okoteve traducción +#elif L==7 + "Solo i miei gruppi" +#elif L==8 + "Tylko moje grupy" +#elif L==9 + "Apenas os meus grupos" +#endif + , +#if L==1 + "Tots els grups" +#elif L==2 + "Alle Gruppen" +#elif L==3 + "All groups" +#elif L==4 + "Todos los grupos" +#elif L==5 + "Tous les groupes" +#elif L==6 + "Todos los grupos" // Okoteve traducción +#elif L==7 + "Tutti i gruppi" +#elif L==8 + "Wszystkie grupy" +#elif L==9 + "Todos os grupos" +#endif + }; + const char *Txt_Groups = #if L==1 "Grups"; @@ -37329,92 +37575,6 @@ const char *Txt_Show_list = "Mostrar lista"; #endif -const char *Txt_Show_WHICH_events[2] = - { -#if L==1 - "Tots els esdeveniments" -#elif L==2 - "Alle Ereignisse" -#elif L==3 - "All events" -#elif L==4 - "Todos los eventos" -#elif L==5 - "Tous les événements" -#elif L==6 - "Todos los eventos" // Okoteve traducción -#elif L==7 - "Tutti i eventi" -#elif L==8 - "Wszystkie imprezy" -#elif L==9 - "Todos os eventos" -#endif - , -#if L==1 - "Només els esdeveniments públics i visibles" -#elif L==2 - "Nur öffentliche und sichtbare Ereignisse" -#elif L==3 - "Only public, visible events" -#elif L==4 - "Solo eventos públicos y visibles" -#elif L==5 - "Uniquement les événements publics et visibles" -#elif L==6 - "Solo eventos públicos y visibles" // Okoteve traducción -#elif L==7 - "Solo eventi pubblici e visibili" -#elif L==8 - "Tylko wydarzenia publiczne i widoczne" -#elif L==9 - "Apenas eventos públicos e visíveis" -#endif - }; - -const char *Txt_Show_WHICH_groups[2] = - { -#if L==1 - "Només els meus grups" -#elif L==2 - "Nur meine Gruppen" -#elif L==3 - "Only my groups" -#elif L==4 - "Solo mis grupos" -#elif L==5 - "Uniquement mes groupes" -#elif L==6 - "Solo mis grupos" // Okoteve traducción -#elif L==7 - "Solo i miei gruppi" -#elif L==8 - "Only my groups" // Potrzebujesz tlumaczenie -#elif L==9 - "Apenas os meus grupos" -#endif - , -#if L==1 - "Tots els grups" -#elif L==2 - "Alle Gruppen" -#elif L==3 - "All groups" -#elif L==4 - "Todos los grupos" -#elif L==5 - "Tous les groupes" -#elif L==6 - "Todos los grupos" // Okoteve traducción -#elif L==7 - "Tutti i gruppi" -#elif L==8 - "All groups" // Potrzebujesz tlumaczenie -#elif L==9 - "Todos os grupos" -#endif - }; - const char *Txt_Show_more_details = #if L==1 "Mostra més detalls";