// swad_menu.c: menu (horizontal or vertical) selection /* 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-2021 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 . */ /*****************************************************************************/ /********************************* Headers ***********************************/ /*****************************************************************************/ #include "swad_box.h" #include "swad_database.h" #include "swad_figure.h" #include "swad_form.h" #include "swad_global.h" #include "swad_HTML.h" #include "swad_layout.h" #include "swad_menu.h" #include "swad_parameter.h" #include "swad_setting.h" #include "swad_setting_database.h" #include "swad_tab.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ /*****************************************************************************/ extern struct Globals Gbl; /*****************************************************************************/ /******************************* Public constants ****************************/ /*****************************************************************************/ const char *Mnu_MenuIcons[Mnu_NUM_MENUS] = { [Mnu_MENU_HORIZONTAL] = "ellipsis-h.svg", [Mnu_MENU_VERTICAL ] = "ellipsis-v.svg", }; /*****************************************************************************/ /****************************** Private constants ****************************/ /*****************************************************************************/ #define MAX_MENU_ID 16 // Actions not initialized are 0 by default static const Act_Action_t Mnu_MenuActions[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = { [TabUnk] = { }, [TabStr] = { [ 0] = ActFrmLogIn, [ 1] = ActReqSch, [ 2] = ActSeeGblTL, [ 3] = ActSeeSocPrf, [ 4] = ActSeeCal, [ 5] = ActSeeNtf, }, [TabSys] = { [ 0] = ActSeeSysInf, [ 1] = ActSeeCty, [ 2] = ActSeePen, [ 3] = ActSeeLnk, [ 4] = ActLstPlg, [ 5] = ActMtn, }, [TabCty] = { [ 0] = ActSeeCtyInf, [ 1] = ActSeeIns, }, [TabIns] = { [ 0] = ActSeeInsInf, [ 1] = ActSeeCtr, [ 2] = ActSeePlc, [ 3] = ActSeeDpt, [ 4] = ActSeeHld, }, [TabCtr] = { [ 0] = ActSeeCtrInf, [ 1] = ActSeeDeg, [ 2] = ActSeeBld, [ 3] = ActSeeRoo, }, [TabDeg] = { [ 0] = ActSeeDegInf, [ 1] = ActSeeCrs, }, [TabCrs] = { [ 0] = ActSeeCrsInf, [ 1] = ActSeePrg, [ 2] = ActSeeTchGui, [ 3] = ActSeeSyl, [ 4] = ActSeeBib, [ 5] = ActSeeFAQ, [ 6] = ActSeeCrsLnk, [ 7] = ActSeeCrsTT, }, [TabAss] = { [ 0] = ActSeeAss, [ 1] = ActSeeAsg, [ 2] = ActSeePrj, [ 3] = ActSeeAllExaAnn, [ 4] = ActEdiTstQst, [ 5] = ActReqTst, [ 6] = ActSeeAllExa, [ 7] = ActSeeAllGam, [ 8] = ActSeeAllSvy, }, [TabFil] = { [ 0] = ActSeeAdmDocIns, [ 1] = ActAdmShaIns, [ 2] = ActSeeAdmDocCtr, [ 3] = ActAdmShaCtr, [ 4] = ActSeeAdmDocDeg, [ 5] = ActAdmShaDeg, [ 6] = ActSeeAdmDocCrsGrp, [ 7] = ActAdmTchCrsGrp, [ 8] = ActAdmShaCrsGrp, [ 9] = ActAdmAsgWrkUsr, [10] = ActReqAsgWrkCrs, [11] = ActSeeAdmMrk, [12] = ActAdmBrf, }, [TabUsr] = { [ 0] = ActReqSelGrp, [ 1] = ActLstStd, [ 2] = ActLstTch, [ 3] = ActLstOth, [ 4] = ActSeeAtt, [ 5] = ActReqSignUp, [ 6] = ActSeeSignUpReq, [ 7] = ActLstCon, }, [TabMsg] = { [ 0] = ActSeeAnn, [ 1] = ActSeeAllNot, [ 2] = ActSeeFor, [ 3] = ActSeeChtRms, [ 4] = ActSeeRcvMsg, [ 5] = ActReqMaiUsr, }, [TabAna] = { [ 0] = ActReqUseGbl, [ 1] = ActSeePhoDeg, [ 2] = ActReqStaCrs, [ 3] = ActReqAccGbl, [ 4] = ActReqMyUsgRep, [ 5] = ActMFUAct, }, [TabPrf] = { [ 0] = ActFrmRolSes, [ 1] = ActMyCrs, [ 2] = ActSeeMyTT, [ 3] = ActSeeMyAgd, [ 4] = ActFrmMyAcc, [ 5] = ActReqEdiRecSha, [ 6] = ActReqEdiSet, }, }; /*****************************************************************************/ /****************************** Private prototypes ***************************/ /*****************************************************************************/ static void Mnu_PutIconsMenu (__attribute__((unused)) void *Args); /*****************************************************************************/ /******* When I change to another tab, go to the first option allowed ********/ /*****************************************************************************/ Act_Action_t Mnu_GetFirstActionAvailableInCurrentTab (void) { unsigned NumOptInMenu; Act_Action_t Action; /* Change current action to the first allowed action in current tab */ for (NumOptInMenu = 0; NumOptInMenu < Act_MAX_OPTIONS_IN_MENU_PER_TAB; NumOptInMenu++) { if ((Action = Mnu_MenuActions[Gbl.Action.Tab][NumOptInMenu]) == 0) return ActUnk; if (Act_CheckIfIHavePermissionToExecuteAction (Action)) return Action; } return ActUnk; } /*****************************************************************************/ /******************* Write horizontal menu of current tab ********************/ /*****************************************************************************/ void Mnu_WriteMenuThisTab (void) { extern const char *The_ClassTxtMenu[The_NUM_THEMES]; extern const char *Txt_MENU_TITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB]; static const char *ClassIcoMenu[Ico_NUM_ICON_SETS][The_NUM_THEMES] = { [Ico_ICON_SET_AWESOME][The_THEME_WHITE ] = " MENU_ICO_WHITE", [Ico_ICON_SET_AWESOME][The_THEME_GREY ] = " MENU_ICO_GREY", [Ico_ICON_SET_AWESOME][The_THEME_PURPLE] = " MENU_ICO_PURPLE", [Ico_ICON_SET_AWESOME][The_THEME_BLUE ] = " MENU_ICO_BLUE", [Ico_ICON_SET_AWESOME][The_THEME_YELLOW] = " MENU_ICO_YELLOW", [Ico_ICON_SET_AWESOME][The_THEME_PINK ] = " MENU_ICO_PINK", [Ico_ICON_SET_AWESOME][The_THEME_DARK ] = " MENU_ICO_DARK", [Ico_ICON_SET_NUVOLA ][The_THEME_WHITE ] = "", [Ico_ICON_SET_NUVOLA ][The_THEME_GREY ] = "", [Ico_ICON_SET_NUVOLA ][The_THEME_PURPLE] = "", [Ico_ICON_SET_NUVOLA ][The_THEME_BLUE ] = "", [Ico_ICON_SET_NUVOLA ][The_THEME_YELLOW] = "", [Ico_ICON_SET_NUVOLA ][The_THEME_PINK ] = "", [Ico_ICON_SET_NUVOLA ][The_THEME_DARK ] = "", }; unsigned NumOptInMenu; Act_Action_t NumAct; const char *Title; bool IsTheSelectedAction; /***** Begin container *****/ HTM_Txt (""); } /*****************************************************************************/ /************* Put icons to select menu (horizontal or vertical) *************/ /*****************************************************************************/ void Mnu_PutIconsToSelectMenu (void) { extern const char *Hlp_PROFILE_Settings_menu; extern const char *The_ClassPrefOn[The_NUM_THEMES]; extern const char *Txt_Menu; extern const char *Txt_MENU_NAMES[Mnu_NUM_MENUS]; Mnu_Menu_t Menu; Box_BoxBegin (NULL,Txt_Menu, Mnu_PutIconsMenu,NULL, Hlp_PROFILE_Settings_menu,Box_NOT_CLOSABLE); Set_BeginSettingsHead (); Set_BeginOneSettingSelector (); for (Menu = (Mnu_Menu_t) 0; Menu <= (Mnu_Menu_t) (Mnu_NUM_MENUS - 1); Menu++) { if (Menu == Gbl.Prefs.Menu) HTM_DIV_Begin ("class=\"PREF_ON %s\"",The_ClassPrefOn[Gbl.Prefs.Theme]); else HTM_DIV_Begin ("class=\"PREF_OFF\""); Frm_BeginForm (ActChgMnu); Par_PutHiddenParamUnsigned (NULL,"Menu",(unsigned) Menu); Ico_PutSettingIconLink (Mnu_MenuIcons[Menu],Ico_BLACK, Txt_MENU_NAMES[Menu]); Frm_EndForm (); HTM_DIV_End (); } Set_EndOneSettingSelector (); Set_EndSettingsHead (); Box_BoxEnd (); } /*****************************************************************************/ /******************* Put contextual icons in menu setting ********************/ /*****************************************************************************/ static void Mnu_PutIconsMenu (__attribute__((unused)) void *Args) { /***** Put icon to show a figure *****/ Fig_PutIconToShowFigure (Fig_MENUS); } /*****************************************************************************/ /******************************** Change menu ********************************/ /*****************************************************************************/ void Mnu_ChangeMenu (void) { /***** Get param with menu *****/ Gbl.Prefs.Menu = Mnu_GetParamMenu (); /***** Store menu in database *****/ if (Gbl.Usrs.Me.Logged) Set_DB_UpdateMySettingsAboutMenu (Gbl.Prefs.Menu); /***** Set settings from current IP *****/ Set_SetSettingsFromIP (); } /*****************************************************************************/ /************************* Get parameter with menu ***************************/ /*****************************************************************************/ Mnu_Menu_t Mnu_GetParamMenu (void) { return (Mnu_Menu_t) Par_GetParToUnsignedLong ("Menu", 0, Mnu_NUM_MENUS - 1, (unsigned long) Mnu_MENU_DEFAULT); } /*****************************************************************************/ /*************************** Get menu from string ****************************/ /*****************************************************************************/ Mnu_Menu_t Mnu_GetMenuFromStr (const char *Str) { unsigned UnsignedNum; if (sscanf (Str,"%u",&UnsignedNum) == 1) if (UnsignedNum < Mnu_NUM_MENUS) return (Mnu_Menu_t) UnsignedNum; return Mnu_MENU_DEFAULT; } /*****************************************************************************/ /******************************** Context menu *******************************/ /*****************************************************************************/ void Mnu_ContextMenuBegin (void) { HTM_DIV_Begin ("class=\"CONTEXT_MENU\""); } void Mnu_ContextMenuEnd (void) { HTM_DIV_End (); }