swad-core/swad_setting.c

405 lines
15 KiB
C

// swad_setting.c: user's settings / preferences
/*
SWAD (Shared Workspace At a Distance),
is a web platform developed at the University of Granada (Spain),
and used to support university teaching.
This file is part of SWAD core.
Copyright (C) 1999-2019 Antonio Cañas Vargas
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/********************************** Headers **********************************/
/*****************************************************************************/
#include <linux/stddef.h> // For NULL
#include <stdbool.h> // For boolean type
#include <stdio.h> // For fprintf, etc.
#include <string.h>
#include "swad_box.h"
#include "swad_calendar.h"
#include "swad_config.h"
#include "swad_cookie.h"
#include "swad_database.h"
#include "swad_date.h"
#include "swad_form.h"
#include "swad_global.h"
#include "swad_language.h"
#include "swad_layout.h"
#include "swad_notification.h"
#include "swad_menu.h"
#include "swad_parameter.h"
#include "swad_privacy.h"
#include "swad_setting.h"
/*****************************************************************************/
/*************** External global variables from others modules ***************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
static void Set_PutIconsToSelectSideCols (void);
static void Set_PutIconsSideColumns (void);
static void Set_UpdateSideColsOnUsrDataTable (void);
/*****************************************************************************/
/***************************** Edit settings ******************************/
/*****************************************************************************/
void Set_EditSettings (void)
{
extern const char *Hlp_PROFILE_Settings_internationalization;
extern const char *Hlp_PROFILE_Settings_design;
extern const char *Txt_Internationalization;
extern const char *Txt_Design;
/***** Internationalization: language, first day of week, date format *****/
Box_StartBox (NULL,Txt_Internationalization,NULL,
Hlp_PROFILE_Settings_internationalization,Box_NOT_CLOSABLE);
fprintf (Gbl.F.Out,"<div class=\"FRAME_INLINE\">");
Lan_PutBoxToSelectLanguage (); // 1. Language
fprintf (Gbl.F.Out,"</div>"
"<div class=\"FRAME_INLINE\">");
Cal_PutIconsToSelectFirstDayOfWeek (); // 2. First day of week
fprintf (Gbl.F.Out,"</div>"
"<div class=\"FRAME_INLINE\">");
Dat_PutBoxToSelectDateFormat (); // 3. Date format
fprintf (Gbl.F.Out,"</div>");
Box_EndBox ();
/***** Design: icon set, menu, theme, side columns *****/
Box_StartBox (NULL,Txt_Design,NULL,
Hlp_PROFILE_Settings_design,Box_NOT_CLOSABLE);
fprintf (Gbl.F.Out,"<div class=\"FRAME_INLINE\">");
Ico_PutIconsToSelectIconSet (); // 4. Icon set
fprintf (Gbl.F.Out,"</div>"
"<div class=\"FRAME_INLINE\">");
Mnu_PutIconsToSelectMenu (); // 5. Menu
fprintf (Gbl.F.Out,"</div>"
"<div class=\"FRAME_INLINE\">");
The_PutIconsToSelectTheme (); // 6. Theme
fprintf (Gbl.F.Out,"</div>"
"<div class=\"FRAME_INLINE\">");
Set_PutIconsToSelectSideCols (); // 7. Side columns
fprintf (Gbl.F.Out,"</div>");
Box_EndBox ();
if (Gbl.Usrs.Me.Logged)
{
/***** Form to set my settings on privacy *****/
Pri_EditMyPrivacy ();
/***** Form to set my settings on cookies *****/
Coo_EditMyPrefsOnCookies ();
/***** Automatic email to notify of new events *****/
Ntf_PutFormChangeNotifSentByEMail ();
}
}
/*****************************************************************************/
/******************** Get settings changed from current IP *******************/
/*****************************************************************************/
void Set_GetSettingsFromIP (void)
{
unsigned long NumRows;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
if (Gbl.IP[0])
{
/***** Get settings from database *****/
NumRows = DB_QuerySELECT (&mysql_res,"can not get settings",
"SELECT FirstDayOfWeek,DateFormat,Theme,IconSet,Menu,SideCols"
" FROM IP_prefs WHERE IP='%s'",
Gbl.IP);
if (NumRows)
{
if (NumRows != 1)
Lay_ShowErrorAndExit ("Internal error while getting settings.");
/***** Get settings from database *****/
row = mysql_fetch_row (mysql_res);
/* Get first day of week (row[0]) */
Gbl.Prefs.FirstDayOfWeek = Cal_GetFirstDayOfWeekFromStr (row[0]);
/* Get date format (row[1]) */
Gbl.Prefs.DateFormat = Dat_GetDateFormatFromStr (row[1]);
/* Get theme (row[2]) */
Gbl.Prefs.Theme = The_GetThemeFromStr (row[2]);
/* Get icon set (row[3]) */
Gbl.Prefs.IconSet = Ico_GetIconSetFromStr (row[3]);
/* Get menu (row[4]) */
Gbl.Prefs.Menu = Mnu_GetMenuFromStr (row[4]);
/* Get if user wants to show side columns (row[5]) */
if (sscanf (row[5],"%u",&Gbl.Prefs.SideCols) == 1)
{
if (Gbl.Prefs.SideCols > Lay_SHOW_BOTH_COLUMNS)
Gbl.Prefs.SideCols = Cfg_DEFAULT_COLUMNS;
}
else
Gbl.Prefs.SideCols = Cfg_DEFAULT_COLUMNS;
}
}
}
/*****************************************************************************/
/************************ Set settings from current IP ***********************/
/*****************************************************************************/
void Set_SetSettingsFromIP (void)
{
extern const char *The_ThemeId[The_NUM_THEMES];
extern const char *Ico_IconSetId[Ico_NUM_ICON_SETS];
/***** Update settings from current IP in database *****/
DB_QueryREPLACE ("can not store settings from current IP address",
"REPLACE INTO IP_prefs"
" (IP,UsrCod,LastChange,"
"FirstDayOfWeek,DateFormat,Theme,IconSet,Menu,SideCols)"
" VALUES"
" ('%s',%ld,NOW(),"
"%u,%u,'%s','%s',%u,%u)",
Gbl.IP,Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.Prefs.FirstDayOfWeek,
(unsigned) Gbl.Prefs.DateFormat,
The_ThemeId[Gbl.Prefs.Theme],
Ico_IconSetId[Gbl.Prefs.IconSet],
(unsigned) Gbl.Prefs.Menu,
Gbl.Prefs.SideCols);
/***** If a user is logged, update its settings in database for all its IP's *****/
if (Gbl.Usrs.Me.Logged)
DB_QueryUPDATE ("can not update your settings",
"UPDATE IP_prefs"
" SET FirstDayOfWeek=%u,DateFormat=%u,"
"Theme='%s',IconSet='%s',Menu=%u,SideCols=%u"
" WHERE UsrCod=%ld",
Gbl.Prefs.FirstDayOfWeek,
(unsigned) Gbl.Prefs.DateFormat,
The_ThemeId[Gbl.Prefs.Theme],
Ico_IconSetId[Gbl.Prefs.IconSet],
(unsigned) Gbl.Prefs.Menu,
Gbl.Prefs.SideCols,
Gbl.Usrs.Me.UsrDat.UsrCod);
}
/*****************************************************************************/
/*********************** Remove old settings from IP *************************/
/*****************************************************************************/
void Set_RemoveOldSettingsFromIP (void)
{
/***** Remove old settings *****/
DB_QueryDELETE ("can not remove old settings",
"DELETE LOW_PRIORITY FROM IP_prefs"
" WHERE LastChange<FROM_UNIXTIME(UNIX_TIMESTAMP()-%lu)",
Cfg_TIME_TO_DELETE_IP_PREFS);
}
/*****************************************************************************/
/************ Put icons to select the layout of the side columns *************/
/*****************************************************************************/
static void Set_PutIconsToSelectSideCols (void)
{
extern const char *Hlp_PROFILE_Settings_columns;
extern const char *Txt_Columns;
extern const char *Txt_LAYOUT_SIDE_COLUMNS[4];
unsigned SideCols;
char Icon[32 + 1];
Box_StartBox (NULL,Txt_Columns,Set_PutIconsSideColumns,
Hlp_PROFILE_Settings_columns,Box_NOT_CLOSABLE);
Set_StartSettingsHead ();
Set_StartOneSettingSelector ();
for (SideCols = 0;
SideCols <= Lay_SHOW_BOTH_COLUMNS;
SideCols++)
{
fprintf (Gbl.F.Out,"<div class=\"%s\">",
SideCols == Gbl.Prefs.SideCols ? "PREF_ON" :
"PREF_OFF");
Frm_StartForm (ActChgCol);
Par_PutHiddenParamUnsigned ("SideCols",SideCols);
snprintf (Icon,sizeof (Icon),
"layout%u%u_32x20.gif",
SideCols >> 1,SideCols & 1);
Ico_PutSettingIconLink (Icon,Txt_LAYOUT_SIDE_COLUMNS[SideCols]);
Frm_EndForm ();
fprintf (Gbl.F.Out,"</div>");
}
Set_EndOneSettingSelector ();
Set_EndSettingsHead ();
Box_EndBox ();
}
/*****************************************************************************/
/************** Put contextual icons in side-columns setting *****************/
/*****************************************************************************/
static void Set_PutIconsSideColumns (void)
{
/***** Put icon to show a figure *****/
Gbl.Figures.FigureType = Fig_SIDE_COLUMNS;
Fig_PutIconToShowFigure ();
}
/*****************************************************************************/
/*********************** Change layout of side columns ***********************/
/*****************************************************************************/
void Set_ChangeSideCols (void)
{
/***** Get param side-columns *****/
Gbl.Prefs.SideCols = Set_GetParamSideCols ();
/***** Store side colums in database *****/
if (Gbl.Usrs.Me.Logged)
Set_UpdateSideColsOnUsrDataTable ();
/***** Set settings from current IP *****/
Set_SetSettingsFromIP ();
}
/*****************************************************************************/
/*************************** Hide left side column ***************************/
/*****************************************************************************/
void Set_HideLeftCol (void)
{
Gbl.Prefs.SideCols &= ~Lay_SHOW_LEFT_COLUMN; // And with 1...101 to hide left column
if (Gbl.Usrs.Me.Logged)
Set_UpdateSideColsOnUsrDataTable ();
/***** Set settings from current IP *****/
Set_SetSettingsFromIP ();
}
/*****************************************************************************/
/*************************** Hide right side column **************************/
/*****************************************************************************/
void Set_HideRightCol (void)
{
Gbl.Prefs.SideCols &= ~Lay_SHOW_RIGHT_COLUMN; // And with 1...110 to hide right column
if (Gbl.Usrs.Me.Logged)
Set_UpdateSideColsOnUsrDataTable ();
/***** Set settings from current IP *****/
Set_SetSettingsFromIP ();
}
/*****************************************************************************/
/**************************** Show left side column **************************/
/*****************************************************************************/
void Set_ShowLeftCol (void)
{
Gbl.Prefs.SideCols |= Lay_SHOW_LEFT_COLUMN; // Or with 10 to show left column
if (Gbl.Usrs.Me.Logged)
Set_UpdateSideColsOnUsrDataTable ();
/***** Set settings from current IP *****/
Set_SetSettingsFromIP ();
}
/*****************************************************************************/
/**************************** Show right side column *************************/
/*****************************************************************************/
void Set_ShowRightCol (void)
{
Gbl.Prefs.SideCols |= Lay_SHOW_RIGHT_COLUMN; // Or with 01 to show right column
if (Gbl.Usrs.Me.Logged)
Set_UpdateSideColsOnUsrDataTable ();
/***** Set settings from current IP *****/
Set_SetSettingsFromIP ();
}
/*****************************************************************************/
/************** Update layout of side colums on user data table **************/
/*****************************************************************************/
static void Set_UpdateSideColsOnUsrDataTable (void)
{
DB_QueryUPDATE ("can not update your setting about side columns",
"UPDATE usr_data SET SideCols=%u"
" WHERE UsrCod=%ld",
Gbl.Prefs.SideCols,Gbl.Usrs.Me.UsrDat.UsrCod);
}
/*****************************************************************************/
/************** Get parameter used to show/hide side columns *****************/
/*****************************************************************************/
unsigned Set_GetParamSideCols (void)
{
return (unsigned) Par_GetParToUnsignedLong ("SideCols",
0,
Lay_SHOW_BOTH_COLUMNS,
Cfg_DEFAULT_COLUMNS);
}
/*****************************************************************************/
/*********** Head to select one or several settings using icons **************/
/*****************************************************************************/
/*
+-- Container for several pref. selectors ---+
| +One pref.selector+ +One pref.selector+ |
| | +-----+ +-----+ | | +-----+ +-----+ | |
| | |Icon | |Icon | | | |Icon | |Icon | | |
| | |opt.A| |opt.B| | | |opt.A| |opt.B| | |
| | +-----+ +-----+ | | +-----+ +-----+ | |
| +-----------------+ +-----------------+ |
+--------------------------------------------+
*/
void Set_StartSettingsHead (void)
{
fprintf (Gbl.F.Out,"<div class=\"PREF_CONTAINERS\">");
}
void Set_EndSettingsHead (void)
{
fprintf (Gbl.F.Out,"</div>");
}
void Set_StartOneSettingSelector (void)
{
fprintf (Gbl.F.Out,"<div class=\"PREF_CONTAINER\">");
}
void Set_EndOneSettingSelector (void)
{
fprintf (Gbl.F.Out,"</div>");
}