swad-core/swad_layout.c

1756 lines
61 KiB
C
Raw Normal View History

2014-12-01 23:55:08 +01:00
// swad_layout.c: page layout
/*
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.
2019-01-07 21:52:19 +01:00
Copyright (C) 1999-2019 Antonio Ca<EFBFBD>as Vargas
2014-12-01 23:55:08 +01:00
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 <stdlib.h> // For exit, system, malloc, calloc, free, etc
#include <string.h> // For string functions
#include "swad_action.h"
2017-06-10 21:38:10 +02:00
#include "swad_box.h"
2015-01-04 14:43:03 +01:00
#include "swad_calendar.h"
2014-12-01 23:55:08 +01:00
#include "swad_changelog.h"
#include "swad_config.h"
#include "swad_connected.h"
#include "swad_database.h"
2015-10-30 22:12:28 +01:00
#include "swad_exam.h"
2019-02-13 13:32:11 +01:00
#include "swad_firewall.h"
2017-02-16 20:22:13 +01:00
#include "swad_follow.h"
2018-11-09 20:47:39 +01:00
#include "swad_form.h"
2014-12-01 23:55:08 +01:00
#include "swad_global.h"
2017-03-02 21:05:09 +01:00
#include "swad_help.h"
2016-11-14 16:47:46 +01:00
#include "swad_hierarchy.h"
2017-05-07 18:06:34 +02:00
#include "swad_language.h"
2015-01-17 20:06:25 +01:00
#include "swad_logo.h"
2016-06-03 13:42:28 +02:00
#include "swad_MFU.h"
2014-12-01 23:55:08 +01:00
#include "swad_notice.h"
#include "swad_notification.h"
#include "swad_parameter.h"
2019-03-26 11:53:21 +01:00
#include "swad_setting.h"
2015-01-04 15:48:24 +01:00
#include "swad_tab.h"
2014-12-01 23:55:08 +01:00
#include "swad_theme.h"
2019-03-12 21:25:55 +01:00
#include "swad_timeline.h"
2014-12-01 23:55:08 +01:00
#include "swad_web_service.h"
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/****************************** Public constants *****************************/
/*****************************************************************************/
/*****************************************************************************/
2015-01-04 15:48:24 +01:00
/***************************** Private constants *****************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/*****************************************************************************/
2017-04-27 15:02:00 +02:00
/******************************* Private types *******************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
static void Lay_WriteEndOfPage (void);
static void Lay_WritePageTitle (void);
2016-12-05 13:26:12 +01:00
static void Lay_WriteRedirToMyLangOnLogIn (void);
static void Lay_WriteRedirToMyLangOnViewUsrAgd (void);
2014-12-01 23:55:08 +01:00
static void Lay_WriteScripts (void);
2017-03-15 22:15:19 +01:00
static void Lay_WriteScriptMathJax (void);
2014-12-01 23:55:08 +01:00
static void Lay_WriteScriptInit (void);
2016-01-09 15:00:14 +01:00
static void Lay_WriteScriptParamsAJAX (void);
2014-12-01 23:55:08 +01:00
static void Lay_WriteScriptCustomDropzone (void);
2015-11-27 12:57:56 +01:00
static void Lay_WritePageTopHeading (void);
2015-12-26 12:08:45 +01:00
static void Lay_WriteBreadcrumb (void);
2015-01-04 15:48:24 +01:00
2014-12-01 23:55:08 +01:00
static void Lay_WriteTitleAction (void);
static void Lay_ShowLeftColumn (void);
static void Lay_ShowRightColumn (void);
2015-12-02 00:32:46 +01:00
static void Lay_WriteAboutZone (void);
2014-12-01 23:55:08 +01:00
static void Lay_WriteFootFromHTMLFile (void);
2015-04-11 02:04:23 +02:00
static void Lay_HelpTextEditor (const char *Text,const char *InlineMath,const char *Equation);
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/*********************** Write the start of the page *************************/
/*****************************************************************************/
void Lay_WriteStartOfPage (void)
{
2018-12-08 16:43:13 +01:00
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
2018-12-09 10:46:57 +01:00
extern const unsigned Txt_Current_CGI_SWAD_Language;
2014-12-01 23:55:08 +01:00
extern const char *The_TabOnBgColors[The_NUM_THEMES];
2015-11-30 01:13:00 +01:00
const char *LayoutMainZone[Mnu_NUM_MENUS] =
{
"main_horizontal", // Mnu_MENU_HORIZONTAL
"main_vertical", // Mnu_MENU_VERTICAL
};
2014-12-01 23:55:08 +01:00
2015-04-12 18:01:06 +02:00
/***** If, when this function is called, the head is being written
or the head is already written ==> don't do anything *****/
2014-12-01 23:55:08 +01:00
if (Gbl.Layout.WritingHTMLStart ||
Gbl.Layout.HTMLStartWritten)
return;
2015-12-20 01:41:07 +01:00
/***** Compute connected users to be displayed in right columns *****/
Con_ComputeConnectedUsrsBelongingToCurrentCrs ();
2014-12-01 23:55:08 +01:00
/***** Send head width the file type for the HTTP protocol *****/
2016-01-17 15:10:54 +01:00
if (Gbl.Action.UsesAJAX)
2016-01-09 15:00:14 +01:00
// Don't generate a full HTML page, only the content of a DIV or similar
2014-12-01 23:55:08 +01:00
{
2015-07-17 00:52:35 +02:00
fprintf (Gbl.F.Out,"Content-Type: text/html; charset=windows-1252\r\n\r\n");
2014-12-01 23:55:08 +01:00
Gbl.Layout.WritingHTMLStart = false;
2015-11-27 21:24:24 +01:00
Gbl.Layout.HTMLStartWritten = Gbl.Layout.DivsEndWritten = true;
2014-12-01 23:55:08 +01:00
return;
}
/***** If serving a web service ==> don't do anything *****/
if (Gbl.WebService.IsWebService)
{
Gbl.Layout.WritingHTMLStart = false;
2015-11-27 21:24:24 +01:00
Gbl.Layout.HTMLStartWritten = Gbl.Layout.DivsEndWritten = true;
2014-12-01 23:55:08 +01:00
return;
}
Gbl.Layout.WritingHTMLStart = true;
/***** Write header to standard output to avoid timeout *****/
// Two \r\n are necessary
2014-12-21 14:47:04 +01:00
fprintf (stdout,"Content-type: text/html; charset=windows-1252\r\n\r\n"
2014-12-20 16:20:51 +01:00
"<!DOCTYPE html>\n");
2014-12-01 23:55:08 +01:00
2014-12-21 14:47:04 +01:00
/***** Write start of HTML code *****/
2015-04-12 18:01:06 +02:00
// WARNING: It is necessary to comment the line 'AddDefaultCharset UTF8'
// in httpd.conf to enable meta tag
2014-12-20 16:20:51 +01:00
fprintf (Gbl.F.Out,"<html lang=\"%s\">\n"
2014-12-01 23:55:08 +01:00
"<head>\n"
2019-02-14 19:22:38 +01:00
// "<meta http-equiv=\"Page-Enter\" content=\"blendTrans(Duration=0)\">\n"
// "<meta http-equiv=\"Page-Exit\" content=\"blendTrans(Duration=0)\">\n"
2015-02-10 17:22:57 +01:00
"<meta http-equiv=\"Content-Type\" content=\"text/html;charset=windows-1252\" />\n"
2015-07-24 11:34:39 +02:00
"<meta name=\"description\" content=\"A free-software, educational, online tool for managing courses and students.\" />\n"
2015-02-10 17:22:57 +01:00
"<meta name=\"keywords\" content=\""
"%s,"
2015-07-24 11:34:39 +02:00
"SWAD,"
"shared workspace at a distance,"
2017-03-15 02:42:31 +01:00
"educational platform,"
2015-07-24 11:34:39 +02:00
"sistema web de apoyo a la docencia,"
2017-03-15 02:42:31 +01:00
"plataforma educativa,"
"campus virtual,"
2015-02-12 21:03:29 +01:00
"SWADroid,"
2015-07-24 11:34:39 +02:00
"LMS,"
"Learning Management System\" />\n",
2018-12-08 16:43:13 +01:00
Lan_STR_LANG_ID[Gbl.Prefs.Language],
2015-02-10 17:22:57 +01:00
Cfg_PLATFORM_SHORT_NAME);
2014-12-01 23:55:08 +01:00
2015-11-27 10:36:40 +01:00
/* Viewport (used for responsive design) */
fprintf (Gbl.F.Out,"<meta name=\"viewport\""
" content=\"width=device-width, initial-scale=1.0\">\n");
2014-12-01 23:55:08 +01:00
/* Title */
Lay_WritePageTitle ();
2015-02-10 17:22:57 +01:00
/* Canonical URL */
fprintf (Gbl.F.Out,"<link rel=\"canonical\""
" href=\"%s\" />\n",
2016-07-08 12:43:48 +02:00
Cfg_URL_SWAD_CGI);
2015-02-10 17:22:57 +01:00
2014-12-01 23:55:08 +01:00
/* Favicon */
fprintf (Gbl.F.Out,"<link type=\"image/x-icon\" href=\"%s/favicon.ico\" rel=\"icon\" />\n"
"<link type=\"image/x-icon\" href=\"%s/favicon.ico\" rel=\"shortcut icon\" />\n",
2019-03-20 01:36:36 +01:00
Cfg_URL_ICON_PUBLIC,
Cfg_URL_ICON_PUBLIC);
2014-12-01 23:55:08 +01:00
/* Style sheet for SWAD */
2015-11-30 11:00:53 +01:00
fprintf (Gbl.F.Out,"<link rel=\"StyleSheet\" href=\"%s/%s\" type=\"text/css\" />\n",
2016-07-08 12:43:48 +02:00
Cfg_URL_SWAD_PUBLIC,CSS_FILE);
2014-12-01 23:55:08 +01:00
/* Style sheet for Dropzone.js (http://www.dropzonejs.com/) */
// The public directory dropzone must hold:
// dropzone.js
// css/dropzone.css
// images/spritemap@2x.png
// images/spritemap.png
2017-02-17 10:30:59 +01:00
switch (Gbl.Action.Act)
{
2017-10-08 00:51:49 +02:00
case ActFrmCreDocIns: // Brw_ADMI_DOC_INS
case ActFrmCreShaIns: // Brw_ADMI_SHR_INS
case ActFrmCreDocCtr: // Brw_ADMI_DOC_CTR
case ActFrmCreShaCtr: // Brw_ADMI_SHR_CTR
case ActFrmCreDocDeg: // Brw_ADMI_DOC_DEG
case ActFrmCreShaDeg: // Brw_ADMI_SHR_DEG
case ActFrmCreDocCrs: // Brw_ADMI_DOC_CRS
case ActFrmCreDocGrp: // Brw_ADMI_DOC_GRP
case ActFrmCreTchCrs: // Brw_ADMI_TCH_CRS
case ActFrmCreTchGrp: // Brw_ADMI_TCH_GRP
case ActFrmCreShaCrs: // Brw_ADMI_SHR_CRS
case ActFrmCreShaGrp: // Brw_ADMI_SHR_GRP
case ActFrmCreAsgUsr: // Brw_ADMI_ASG_USR
case ActFrmCreAsgCrs: // Brw_ADMI_ASG_CRS
case ActFrmCreWrkUsr: // Brw_ADMI_WRK_USR
case ActFrmCreWrkCrs: // Brw_ADMI_WRK_CRS
case ActFrmCreDocPrj: // Brw_ADMI_DOC_PRJ
2017-10-08 16:12:58 +02:00
case ActFrmCreAssPrj: // Brw_ADMI_ASS_PRJ
2017-10-08 00:51:49 +02:00
case ActFrmCreMrkCrs: // Brw_ADMI_MRK_CRS
case ActFrmCreMrkGrp: // Brw_ADMI_MRK_GRP
case ActFrmCreBrf: // Brw_ADMI_BRF_USR
2017-02-17 10:30:59 +01:00
fprintf (Gbl.F.Out,"<link rel=\"StyleSheet\""
" href=\"%s/dropzone/css/dropzone.css\""
" type=\"text/css\" />\n",
Cfg_URL_SWAD_PUBLIC);
break;
default:
break;
}
2014-12-01 23:55:08 +01:00
/* Redirect to correct language */
2016-12-05 13:26:12 +01:00
if (Gbl.Usrs.Me.Logged && // I am logged
2018-12-09 10:46:57 +01:00
Gbl.Usrs.Me.UsrDat.Prefs.Language != Txt_Current_CGI_SWAD_Language) // My language != current language
2016-12-05 13:26:12 +01:00
{
2019-02-14 19:22:38 +01:00
if (Gbl.Action.Original == ActLogIn || // Regular log in
Gbl.Action.Original == ActLogInNew) // Log in when checking account
2016-12-05 13:26:12 +01:00
Lay_WriteRedirToMyLangOnLogIn ();
2019-02-14 19:22:38 +01:00
else if (Gbl.Action.Original == ActLogInUsrAgd) // Log in to view another user's public agenda
2016-12-05 13:26:12 +01:00
Lay_WriteRedirToMyLangOnViewUsrAgd ();
}
2014-12-01 23:55:08 +01:00
/* Write initial scripts depending on the action */
Lay_WriteScripts ();
fprintf (Gbl.F.Out,"</head>\n");
/***** HTML body *****/
2018-04-24 13:21:53 +02:00
if (Act_GetBrowserTab (Gbl.Action.Act) == Act_BRW_1ST_TAB)
2017-03-15 22:15:19 +01:00
fprintf (Gbl.F.Out,"<body onload=\"init();\">\n"
2015-09-29 01:47:32 +02:00
"<div id=\"zoomLyr\" class=\"ZOOM\">"
2016-01-10 23:00:15 +01:00
"<img id=\"zoomImg\" src=\"%s/usr_bl.jpg\""
2015-09-29 01:47:32 +02:00
" alt=\"\" title=\"\""
" class=\"IMG_USR\" />"
"<div id=\"zoomTxt\" class=\"CENTER_MIDDLE\">"
"</div>"
"</div>",
2019-03-20 01:36:36 +01:00
Cfg_URL_ICON_PUBLIC);
2015-09-29 01:47:32 +02:00
else
2014-12-01 23:55:08 +01:00
{
2015-09-29 01:47:32 +02:00
fprintf (Gbl.F.Out,"<body>\n");
2014-12-01 23:55:08 +01:00
Gbl.Layout.WritingHTMLStart = false;
Gbl.Layout.HTMLStartWritten =
2015-11-27 21:24:24 +01:00
Gbl.Layout.DivsEndWritten = true;
2014-12-01 23:55:08 +01:00
return;
}
2017-06-12 14:16:33 +02:00
/***** Start box that contains the whole page except the foot *****/
2015-12-01 22:31:01 +01:00
fprintf (Gbl.F.Out,"<div id=\"whole_page\">");
2015-11-25 01:42:16 +01:00
/***** Header of layout *****/
2015-11-27 12:57:56 +01:00
Lay_WritePageTopHeading ();
2014-12-31 13:30:26 +01:00
2016-12-18 19:50:33 +01:00
/***** 3rd. row (tabs) *****/
Tab_DrawTabs ();
2015-11-25 14:54:46 +01:00
/***** 4th row: main zone *****/
fprintf (Gbl.F.Out,"<div id=\"main_zone\">");
2015-11-25 01:42:16 +01:00
/* Left column */
2015-11-27 12:57:56 +01:00
if (Gbl.Prefs.SideCols & Lay_SHOW_LEFT_COLUMN) // Left column visible
{
2016-12-18 19:50:33 +01:00
fprintf (Gbl.F.Out,"<aside id=\"left_col\">");
2015-11-27 12:57:56 +01:00
Lay_ShowLeftColumn ();
2016-12-18 19:50:33 +01:00
fprintf (Gbl.F.Out,"</aside>");
2015-11-27 12:57:56 +01:00
}
2015-11-25 01:42:16 +01:00
2015-11-27 10:36:40 +01:00
/* Right column */
2015-11-27 21:24:24 +01:00
// Right column is written before central column
// but it must be drawn at right using "position:absolute; right:0".
// The reason to write right column before central column
// is that central column may hold a lot of content drawn slowly.
2015-11-27 12:57:56 +01:00
if (Gbl.Prefs.SideCols & Lay_SHOW_RIGHT_COLUMN) // Right column visible
{
2016-12-18 19:50:33 +01:00
fprintf (Gbl.F.Out,"<aside id=\"right_col\">");
2015-11-27 12:57:56 +01:00
Lay_ShowRightColumn ();
2016-12-18 19:50:33 +01:00
fprintf (Gbl.F.Out,"</aside>");
2015-11-27 12:57:56 +01:00
}
2015-11-27 10:36:40 +01:00
2015-11-27 21:24:24 +01:00
/* Central (main) column */
2015-11-27 10:36:40 +01:00
switch (Gbl.Prefs.SideCols)
{
case 0:
fprintf (Gbl.F.Out,"<div id=\"main_zone_central_none\">");
break;
case Lay_SHOW_LEFT_COLUMN:
fprintf (Gbl.F.Out,"<div id=\"main_zone_central_left\">");
break;
case Lay_SHOW_RIGHT_COLUMN:
fprintf (Gbl.F.Out,"<div id=\"main_zone_central_right\">");
break;
case (Lay_SHOW_LEFT_COLUMN | Lay_SHOW_RIGHT_COLUMN):
fprintf (Gbl.F.Out,"<div id=\"main_zone_central_both\">");
break;
}
2015-11-29 20:03:44 +01:00
fprintf (Gbl.F.Out,"<div id=\"main_zone_central_container\" class=\"%s\">",
2014-12-01 23:55:08 +01:00
The_TabOnBgColors[Gbl.Prefs.Theme]);
2015-11-30 01:13:00 +01:00
/* Layout with horizontal or vertical menu */
fprintf (Gbl.F.Out,"<div id=\"%s\">",LayoutMainZone[Gbl.Prefs.Menu]);
2014-12-01 23:55:08 +01:00
2015-11-29 22:06:22 +01:00
/* Menu */
Mnu_WriteMenuThisTab ();
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/* Start canvas: main zone for actions output */
2015-11-29 22:06:22 +01:00
fprintf (Gbl.F.Out,"<div class=\"MAIN_ZONE_CANVAS\">");
2015-11-27 12:57:56 +01:00
2014-12-31 13:30:26 +01:00
/* If it is mandatory to read any information about course */
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Info.ShowMsgMustBeRead)
2014-12-31 13:30:26 +01:00
Inf_WriteMsgYouMustReadInfo ();
2014-12-01 23:55:08 +01:00
/* Write title of the current action */
2015-11-27 12:57:56 +01:00
if (Gbl.Prefs.Menu == Mnu_MENU_VERTICAL &&
2018-04-24 13:21:53 +02:00
Act_GetIndexInMenu (Gbl.Action.Act) >= 0)
2014-12-01 23:55:08 +01:00
Lay_WriteTitleAction ();
Gbl.Layout.WritingHTMLStart = false;
Gbl.Layout.HTMLStartWritten = true;
/* Write message indicating number of clicks allowed before sending my photo */
Usr_InformAboutNumClicksBeforePhoto ();
}
2017-10-04 12:20:58 +02:00
/*****************************************************************************/
/*********************** Write status 204 No Content *************************/
/*****************************************************************************/
void Lay_WriteHTTPStatus204NoContent (void)
{
/***** The HTTP response is a code status *****/
/* Don't write HTML at all */
Gbl.Layout.HTMLStartWritten =
Gbl.Layout.DivsEndWritten =
Gbl.Layout.HTMLEndWritten = true;
/* Start HTTP response */
fprintf (stdout,"Content-type: text/plain; charset=windows-1252\n");
/* Return HTTP status code 204 No Content:
The server has successfully fulfilled the request
and there is no additional content to send
in the response payload body. */
fprintf (stdout,"Status: 204\r\n\r\n");
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/************************ Write the end of the page **************************/
/*****************************************************************************/
static void Lay_WriteEndOfPage (void)
{
2015-11-27 21:24:24 +01:00
if (!Gbl.Layout.DivsEndWritten)
2014-12-01 23:55:08 +01:00
{
2015-11-27 21:24:24 +01:00
/***** End of central part of main zone *****/
2015-11-30 01:13:00 +01:00
fprintf (Gbl.F.Out,"</div>" // Canvas (main zone to output content of the current action)
"</div>" // Layout with horizontal or vertical menu
2015-11-27 21:24:24 +01:00
"</div>"); // main_zone_central_container
/***** Write page footer *****/
2018-04-24 13:21:53 +02:00
if (Act_GetBrowserTab (Gbl.Action.Act) == Act_BRW_1ST_TAB)
2015-12-02 00:32:46 +01:00
Lay_WriteFootFromHTMLFile ();
2015-11-27 21:24:24 +01:00
/***** End of main zone and page *****/
fprintf (Gbl.F.Out,"</div>" // main_zone_central
2015-11-27 12:57:56 +01:00
"</div>" // main_zone
"</div>\n"); // whole_page_* (box that contains the whole page except the foot)
2015-11-27 21:24:24 +01:00
Gbl.Layout.DivsEndWritten = true;
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
/************************* Write the title of the page ***********************/
/*****************************************************************************/
static void Lay_WritePageTitle (void)
{
2016-03-20 17:47:18 +01:00
extern const char *Txt_TAGLINE;
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"<title>");
2019-04-03 20:57:04 +02:00
if (Gbl.Params.GetMethod && Gbl.Hierarchy.Deg.DegCod > 0)
2014-12-01 23:55:08 +01:00
{
fprintf (Gbl.F.Out,"%s &gt; %s",
2016-03-20 22:31:57 +01:00
Cfg_PLATFORM_SHORT_NAME,
2019-04-03 20:57:04 +02:00
Gbl.Hierarchy.Deg.ShrtName);
if (Gbl.Hierarchy.Level == Hie_CRS)
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out," &gt; %s",
2019-04-04 10:45:15 +02:00
Gbl.Hierarchy.Crs.ShrtName);
2014-12-01 23:55:08 +01:00
}
else
2016-03-20 17:47:18 +01:00
fprintf (Gbl.F.Out,"%s: %s",
2016-03-20 22:31:57 +01:00
Cfg_PLATFORM_SHORT_NAME,Txt_TAGLINE);
2014-12-01 23:55:08 +01:00
2015-02-10 17:22:57 +01:00
fprintf (Gbl.F.Out,"</title>\n");
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************* Write script and meta to redirect to my language **************/
/*****************************************************************************/
2016-12-05 13:26:12 +01:00
static void Lay_WriteRedirToMyLangOnLogIn (void)
2014-12-01 23:55:08 +01:00
{
2018-12-08 16:43:13 +01:00
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
2014-12-01 23:55:08 +01:00
2015-04-12 18:01:06 +02:00
fprintf (Gbl.F.Out,"<meta http-equiv=\"refresh\""
" content=\"0; url='%s/%s?act=%ld&amp;ses=%s'\">",
2016-07-08 12:43:48 +02:00
Cfg_URL_SWAD_CGI,
2018-12-08 16:43:13 +01:00
Lan_STR_LANG_ID[Gbl.Usrs.Me.UsrDat.Prefs.Language],
2018-04-24 13:21:53 +02:00
Act_GetActCod (ActLogInLan),
2014-12-01 23:55:08 +01:00
Gbl.Session.Id);
}
2016-12-05 13:26:12 +01:00
static void Lay_WriteRedirToMyLangOnViewUsrAgd (void)
{
2018-12-08 16:43:13 +01:00
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
2016-12-05 13:26:12 +01:00
fprintf (Gbl.F.Out,"<meta http-equiv=\"refresh\""
" content=\"0; url='%s/%s?act=%ld&amp;ses=%s&amp;agd=@%s'\">",
Cfg_URL_SWAD_CGI,
2018-12-08 16:43:13 +01:00
Lan_STR_LANG_ID[Gbl.Usrs.Me.UsrDat.Prefs.Language],
2018-04-24 13:21:53 +02:00
Act_GetActCod (ActLogInUsrAgdLan),
2016-12-05 13:26:12 +01:00
Gbl.Session.Id,
Gbl.Usrs.Other.UsrDat.Nickname);
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/************ Write some scripts depending on the current action *************/
/*****************************************************************************/
static void Lay_WriteScripts (void)
{
2015-10-30 17:05:33 +01:00
extern const char *Txt_DAYS_CAPS[7];
2016-12-12 23:10:11 +01:00
extern const char *Txt_DAYS_SMALL[7];
2015-10-30 17:05:33 +01:00
extern const char *Txt_Exam_of_X;
unsigned DayOfWeek; /* 0, 1, 2, 3, 4, 5, 6 */
unsigned NumHld;
unsigned NumExamAnnouncement; // Number of exam announcement
2014-12-01 23:55:08 +01:00
/***** General scripts for swad *****/
2015-12-29 11:35:01 +01:00
fprintf (Gbl.F.Out,"<script type=\"text/javascript\" src=\"%s/%s\">"
2014-12-01 23:55:08 +01:00
"</script>\n",
2016-07-08 12:43:48 +02:00
Cfg_URL_SWAD_PUBLIC,JS_FILE);
2015-04-07 21:44:24 +02:00
/***** Script for MathJax *****/
2017-03-16 10:06:44 +01:00
Lay_WriteScriptMathJax ();
2015-04-07 21:44:24 +02:00
2017-09-24 12:31:48 +02:00
/***** Write script with init function executed after loading page *****/
Lay_WriteScriptInit ();
/***** Write script to set parameters needed by AJAX *****/
Lay_WriteScriptParamsAJAX ();
2014-12-01 23:55:08 +01:00
2015-10-30 17:05:33 +01:00
/***** Prepare script to draw months *****/
2019-02-15 10:50:30 +01:00
if ((Gbl.Prefs.SideCols & Lay_SHOW_LEFT_COLUMN) || // Left column visible
2019-04-03 20:57:04 +02:00
(Gbl.Hierarchy.Ins.InsCod > 0 && // Institution selected
2019-02-15 13:39:37 +01:00
(Gbl.Action.Act == ActSeeCal || // Viewing calendar
Gbl.Action.Act == ActPrnCal || // Printing calendar
Gbl.Action.Act == ActChgCal1stDay))) // Changing first day
2015-10-30 17:05:33 +01:00
{
/***** Get list of holidays *****/
if (!Gbl.Hlds.LstIsRead)
{
2017-01-29 12:42:19 +01:00
Gbl.Hlds.SelectedOrder = Hld_ORDER_BY_START_DATE;
2015-10-30 17:05:33 +01:00
Hld_GetListHolidays ();
}
/***** Create list of calls for examination *****/
2016-12-12 02:21:41 +01:00
Exa_CreateListDatesOfExamAnnouncements ();
2015-10-30 17:05:33 +01:00
/***** Write script to initialize variables used to draw months *****/
fprintf (Gbl.F.Out,"<script type=\"text/javascript\">\n"
2017-05-04 20:11:39 +02:00
" var DAYS_CAPS = [");
2015-10-30 17:05:33 +01:00
for (DayOfWeek = 0;
DayOfWeek < 7;
DayOfWeek++)
{
if (DayOfWeek)
fprintf (Gbl.F.Out,",");
fprintf (Gbl.F.Out,"'%c'",Txt_DAYS_CAPS[DayOfWeek][0]);
}
fprintf (Gbl.F.Out,"];\n");
2016-12-12 23:10:11 +01:00
fprintf (Gbl.F.Out," var DAYS = [");
for (DayOfWeek = 0;
DayOfWeek < 7;
DayOfWeek++)
{
if (DayOfWeek)
fprintf (Gbl.F.Out,",");
fprintf (Gbl.F.Out,"'%s'",Txt_DAYS_SMALL[DayOfWeek]);
}
fprintf (Gbl.F.Out,"];\n");
2015-10-30 17:05:33 +01:00
fprintf (Gbl.F.Out," var STR_EXAM = '");
2019-04-04 10:45:15 +02:00
fprintf (Gbl.F.Out,Txt_Exam_of_X,Gbl.Hierarchy.Crs.FullName);
2015-10-30 22:12:28 +01:00
fprintf (Gbl.F.Out,"';\n");
2015-10-30 17:05:33 +01:00
fprintf (Gbl.F.Out," var Hlds = [];\n");
for (NumHld = 0;
NumHld < Gbl.Hlds.Num;
NumHld++)
fprintf (Gbl.F.Out," Hlds.push({ PlcCod: %ld, HldTyp: %u, StartDate: %s, EndDate: %s, Name: '%s' });\n",
Gbl.Hlds.Lst[NumHld].PlcCod,
(unsigned) Gbl.Hlds.Lst[NumHld].HldTyp,
Gbl.Hlds.Lst[NumHld].StartDate.YYYYMMDD,
Gbl.Hlds.Lst[NumHld].EndDate.YYYYMMDD,
Gbl.Hlds.Lst[NumHld].Name);
fprintf (Gbl.F.Out," var LstExamAnnouncements = [];\n");
for (NumExamAnnouncement = 0;
2017-01-15 18:02:52 +01:00
NumExamAnnouncement < Gbl.ExamAnns.NumExaAnns;
2015-10-30 17:05:33 +01:00
NumExamAnnouncement++)
2019-03-25 19:05:10 +01:00
fprintf (Gbl.F.Out," LstExamAnnouncements.push({ ExaCod: %ld, Year: %u, Month: %u, Day: %u });\n",
Gbl.ExamAnns.Lst[NumExamAnnouncement].ExaCod,
Gbl.ExamAnns.Lst[NumExamAnnouncement].ExamDate.Year,
Gbl.ExamAnns.Lst[NumExamAnnouncement].ExamDate.Month,
Gbl.ExamAnns.Lst[NumExamAnnouncement].ExamDate.Day);
2015-10-30 17:05:33 +01:00
2015-10-30 22:12:28 +01:00
fprintf (Gbl.F.Out,"</script>\n");
2016-06-01 13:43:22 +02:00
/***** Free list of dates of exam announcements *****/
Exa_FreeListExamAnnouncements ();
2015-10-30 17:05:33 +01:00
}
2015-10-28 21:47:42 +01:00
/***** Scripts depending on action *****/
2016-01-17 15:10:54 +01:00
switch (Gbl.Action.Act)
2014-12-01 23:55:08 +01:00
{
2015-10-28 21:47:42 +01:00
/***** Script to print world map *****/
case ActSeeCty:
Cty_WriteScriptGoogleGeochart ();
break;
/***** Script for uploading files using Dropzone.js (http://www.dropzonejs.com/) *****/
// The public directory dropzone must hold:
// dropzone.js
// css/dropzone.css
// images/spritemap@2x.png
// images/spritemap.png
2017-10-08 00:51:49 +02:00
case ActFrmCreDocIns: // Brw_ADMI_DOC_INS
case ActFrmCreShaIns: // Brw_ADMI_SHR_INS
case ActFrmCreDocCtr: // Brw_ADMI_DOC_CTR
case ActFrmCreShaCtr: // Brw_ADMI_SHR_CTR
case ActFrmCreDocDeg: // Brw_ADMI_DOC_DEG
case ActFrmCreShaDeg: // Brw_ADMI_SHR_DEG
case ActFrmCreDocCrs: // Brw_ADMI_DOC_CRS
case ActFrmCreDocGrp: // Brw_ADMI_DOC_GRP
case ActFrmCreTchCrs: // Brw_ADMI_TCH_CRS
case ActFrmCreTchGrp: // Brw_ADMI_TCH_GRP
case ActFrmCreShaCrs: // Brw_ADMI_SHR_CRS
case ActFrmCreShaGrp: // Brw_ADMI_SHR_GRP
case ActFrmCreAsgUsr: // Brw_ADMI_ASG_USR
case ActFrmCreAsgCrs: // Brw_ADMI_ASG_CRS
case ActFrmCreWrkUsr: // Brw_ADMI_WRK_USR
case ActFrmCreWrkCrs: // Brw_ADMI_WRK_CRS
case ActFrmCreDocPrj: // Brw_ADMI_DOC_PRJ
2017-10-08 16:12:58 +02:00
case ActFrmCreAssPrj: // Brw_ADMI_ASS_PRJ
2017-10-08 00:51:49 +02:00
case ActFrmCreMrkCrs: // Brw_ADMI_MRK_CRS
case ActFrmCreMrkGrp: // Brw_ADMI_MRK_GRP
case ActFrmCreBrf: // Brw_ADMI_BRF_USR
2015-10-28 21:47:42 +01:00
// Use charset="windows-1252" to force error messages in windows-1252 (default is UTF-8)
fprintf (Gbl.F.Out,"<script type=\"text/javascript\""
" src=\"%s/dropzone/dropzone.js\""
" charset=\"windows-1252\">"
"</script>\n",
2016-07-08 12:43:48 +02:00
Cfg_URL_SWAD_PUBLIC);
2015-10-28 21:47:42 +01:00
Lay_WriteScriptCustomDropzone ();
break;
case ActReqAccGbl:
case ActSeeAccGbl:
case ActReqAccCrs:
case ActSeeAccCrs:
case ActSeeAllStaCrs:
fprintf (Gbl.F.Out,"<script type=\"text/javascript\""
" src=\"%s/jstz/jstz.js\">"
"</script>\n",
2016-07-08 12:43:48 +02:00
Cfg_URL_SWAD_PUBLIC);
2015-10-28 21:47:42 +01:00
break;
default:
break;
2014-12-01 23:55:08 +01:00
}
/***** Script for Google Analytics *****/
fprintf (Gbl.F.Out,"%s",Cfg_GOOGLE_ANALYTICS);
}
// Change page title
//function changeTitle(title) {
// document.title = title;
//}
2017-03-15 22:15:19 +01:00
/*****************************************************************************/
/************ Write some scripts depending on the current action *************/
/*****************************************************************************/
static void Lay_WriteScriptMathJax (void)
{
// MathJax configuration
/*
fprintf (Gbl.F.Out,"<script type=\"text/javascript\">"
" window.MathJax = {"
" tex2jax: {"
" inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],"
" processEscapes: true"
" }"
" };"
"</script>");
*/
#ifdef Cfg_MATHJAX_LOCAL
// Use the local copy of MathJax
fprintf (Gbl.F.Out,"<script type=\"text/javascript\""
" src=\"%s/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML\">"
"</script>\n",
Cfg_URL_SWAD_PUBLIC);
#else
// Use the MathJax Content Delivery Network (CDN)
fprintf (Gbl.F.Out,"<script type=\"text/javascript\""
" src=\"//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML\">"
"</script>\n");
#endif
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/******* Write script with init function executed after loading page *********/
/*****************************************************************************/
static void Lay_WriteScriptInit (void)
{
2018-12-08 16:43:13 +01:00
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
2019-03-13 09:55:23 +01:00
bool RefreshLastClicks = false;
bool RefreshNewTimeline = false;
switch (Gbl.Action.Act)
{
case ActLstClk:
RefreshLastClicks = true;
break;
case ActSeeSocTmlGbl:
case ActRcvSocPstGbl:
case ActRcvSocComGbl:
case ActReqRemSocPubGbl:
case ActRemSocPubGbl:
case ActReqRemSocComGbl:
case ActRemSocComGbl:
RefreshNewTimeline = true;
break;
default:
break;
}
2014-12-01 23:55:08 +01:00
2015-10-27 19:44:31 +01:00
fprintf (Gbl.F.Out,"<script type=\"text/javascript\">\n");
2015-11-27 12:57:56 +01:00
Dat_WriteScriptMonths ();
2015-10-27 19:44:31 +01:00
2019-03-13 09:55:23 +01:00
if (RefreshNewTimeline)
fprintf (Gbl.F.Out,"var delayNewTimeline = %lu;\n",
Cfg_TIME_TO_REFRESH_TIMELINE);
2015-10-27 19:44:31 +01:00
fprintf (Gbl.F.Out,"function init(){\n");
2014-12-01 23:55:08 +01:00
2015-11-27 12:57:56 +01:00
if ((Gbl.Prefs.SideCols & Lay_SHOW_RIGHT_COLUMN)) // Right column visible
2014-12-01 23:55:08 +01:00
Con_WriteScriptClockConnected ();
// Put the focus on login form
2016-12-26 13:09:21 +01:00
fprintf (Gbl.F.Out," ActionAJAX = \"%s\";\n"
2015-09-17 17:49:46 +02:00
" setTimeout(\"refreshConnected()\",%lu);\n",
2018-12-08 16:43:13 +01:00
Lan_STR_LANG_ID[Gbl.Prefs.Language],
2014-12-01 23:55:08 +01:00
Gbl.Usrs.Connected.TimeToRefreshInMs);
2016-01-15 02:41:55 +01:00
2019-03-13 09:55:23 +01:00
if (RefreshLastClicks) // Refresh last clicks via AJAX
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out," setTimeout(\"refreshLastClicks()\",%lu);\n",
Cfg_TIME_TO_REFRESH_LAST_CLICKS);
2019-03-13 09:55:23 +01:00
else if (RefreshNewTimeline) // Refresh timeline via AJAX
fprintf (Gbl.F.Out," setTimeout(\"refreshNewTimeline()\",delayNewTimeline);\n");
2015-09-17 17:49:46 +02:00
fprintf (Gbl.F.Out,"}\n"
"</script>\n");
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2016-01-09 15:00:14 +01:00
/************** Write script to set parameters needed by AJAX ****************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2016-01-09 15:00:14 +01:00
static void Lay_WriteScriptParamsAJAX (void)
2014-12-01 23:55:08 +01:00
{
2016-01-14 01:39:02 +01:00
/***** Start script *****/
fprintf (Gbl.F.Out,"<script type=\"text/javascript\">\n");
/***** Parameter to refresh connected users *****/
fprintf (Gbl.F.Out,"var RefreshParamNxtActCon = \"act=%ld\";\n",
2018-04-24 13:21:53 +02:00
Act_GetActCod (ActRefCon));
2016-01-14 01:39:02 +01:00
/***** Parameter to refresh clicks in realtime *****/
fprintf (Gbl.F.Out,"var RefreshParamNxtActLog = \"act=%ld\";\n",
2018-04-24 13:21:53 +02:00
Act_GetActCod (ActRefLstClk));
2016-01-14 01:39:02 +01:00
2017-10-04 01:12:52 +02:00
/***** Parameters related with expanding/contracting folders in file browsers *****/
if (Gbl.FileBrowser.Type != Brw_UNKNOWN)
/* In all the actions related to file browsers ==>
put parameters used by AJAX */
fprintf (Gbl.F.Out,"var RefreshParamExpand = \"act=%ld\";\n"
"var RefreshParamContract = \"act=%ld\";\n",
2018-04-24 13:21:53 +02:00
Act_GetActCod (Brw_GetActionExpand () ),
Act_GetActCod (Brw_GetActionContract ()));
2017-10-04 01:12:52 +02:00
2017-02-17 10:30:59 +01:00
/***** Parameters related with social timeline refreshing *****/
switch (Gbl.Action.Act)
2016-01-14 01:39:02 +01:00
{
2017-02-17 10:30:59 +01:00
case ActSeeSocTmlGbl:
case ActRcvSocPstGbl:
case ActRcvSocComGbl:
case ActReqRemSocPubGbl:
case ActRemSocPubGbl:
case ActReqRemSocComGbl:
case ActRemSocComGbl:
/* In all the actions related to view or editing global timeline ==>
put parameters used by AJAX */
fprintf (Gbl.F.Out,"var RefreshParamNxtActNewPub = \"act=%ld\";\n"
"var RefreshParamNxtActOldPub = \"act=%ld\";\n"
2017-02-24 03:38:18 +01:00
"var RefreshParamWhichUsrs = \"WhichUsrs=%u\";\n",
2018-04-24 13:21:53 +02:00
Act_GetActCod (ActRefNewSocPubGbl),
Act_GetActCod (ActRefOldSocPubGbl),
2019-03-12 21:25:55 +01:00
(unsigned) Gbl.Timeline.WhichUsrs);
2017-02-17 10:30:59 +01:00
break;
case ActSeeOthPubPrf:
case ActRcvSocPstUsr:
case ActRcvSocComUsr:
case ActReqRemSocPubUsr:
case ActRemSocPubUsr:
case ActReqRemSocComUsr:
case ActRemSocComUsr:
/* In all the actions related to view or editing user's timeline ==>
put parameters used by AJAX */
if (Gbl.Usrs.Other.UsrDat.UsrCod <= 0)
Usr_GetParamOtherUsrCodEncryptedAndGetListIDs ();
if (!Gbl.Usrs.Other.UsrDat.Nickname[0])
Nck_GetNicknameFromUsrCod (Gbl.Usrs.Other.UsrDat.UsrCod,
Gbl.Usrs.Other.UsrDat.Nickname);
fprintf (Gbl.F.Out,"var RefreshParamNxtActOldPub = \"act=%ld\";\n"
"var RefreshParamUsr = \"OtherUsrCod=%s\";\n",
2018-04-24 13:21:53 +02:00
Act_GetActCod (ActRefOldSocPubUsr),
2017-02-17 10:30:59 +01:00
Gbl.Usrs.Other.UsrDat.EncryptedUsrCod);
break;
default:
break;
2016-01-14 01:39:02 +01:00
}
/***** Parameters with code of session and current course code *****/
fprintf (Gbl.F.Out,"var RefreshParamIdSes = \"ses=%s\";\n"
2015-09-17 17:49:46 +02:00
"var RefreshParamCrsCod = \"crs=%ld\";\n"
"</script>\n",
Gbl.Session.Id,
2019-04-04 10:45:15 +02:00
Gbl.Hierarchy.Crs.CrsCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******* Write script to customize upload of files using Dropzone.js *********/
/*****************************************************************************/
// More info: http://www.dropzonejs.com/
static void Lay_WriteScriptCustomDropzone (void)
{
// "myAwesomeDropzone" is the camelized version of the HTML element's ID
// Add a line "forceFallback: true,\n" to test classic upload
2015-09-17 17:49:46 +02:00
fprintf (Gbl.F.Out,"<script type=\"text/javascript\">\n"
"Dropzone.options.myAwesomeDropzone = {\n"
2014-12-01 23:55:08 +01:00
"maxFiles: 100,\n"
"parallelUploads: 100,\n"
"maxFilesize: %lu,\n"
"fallback: function() {\n"
"document.getElementById('dropzone-upload').style.display='none';\n"
"document.getElementById('classic-upload').style.display='block';\n"
"}\n"
2015-09-17 17:49:46 +02:00
"};\n"
"</script>\n",
2014-12-01 23:55:08 +01:00
(unsigned long) (Fil_MAX_FILE_SIZE / (1024ULL * 1024ULL) - 1));
}
/*****************************************************************************/
/************************ Write top heading of the page **********************/
/*****************************************************************************/
2015-11-27 12:57:56 +01:00
static void Lay_WritePageTopHeading (void)
2014-12-01 23:55:08 +01:00
{
2016-03-22 01:26:00 +01:00
extern const char *The_ClassTagline[The_NUM_THEMES];
extern const char *Txt_System;
extern const char *Txt_TAGLINE;
2016-03-22 00:03:43 +01:00
extern const char *Txt_TAGLINE_BR;
2015-11-30 09:44:17 +01:00
const char *ClassHeadRow1[The_NUM_THEMES] =
2015-09-27 19:31:10 +02:00
{
2015-11-30 09:44:17 +01:00
"HEAD_ROW_1_WHITE", // The_THEME_WHITE
"HEAD_ROW_1_GREY", // The_THEME_GREY
2019-02-20 17:18:13 +01:00
"HEAD_ROW_1_PURPLE", // The_THEME_PURPLE
2015-11-30 09:44:17 +01:00
"HEAD_ROW_1_BLUE", // The_THEME_BLUE
"HEAD_ROW_1_YELLOW", // The_THEME_YELLOW
2019-02-20 17:18:13 +01:00
"HEAD_ROW_1_PINK", // The_THEME_PINK
2015-09-27 19:31:10 +02:00
};
2015-12-01 22:31:01 +01:00
const char *ClassHeadRow2[The_NUM_THEMES] =
{
"HEAD_ROW_2_WHITE", // The_THEME_WHITE
"HEAD_ROW_2_GREY", // The_THEME_GREY
2019-02-20 17:18:13 +01:00
"HEAD_ROW_2_PURPLE", // The_THEME_PURPLE
2015-12-01 22:31:01 +01:00
"HEAD_ROW_2_BLUE", // The_THEME_BLUE
"HEAD_ROW_2_YELLOW", // The_THEME_YELLOW
2019-02-20 17:18:13 +01:00
"HEAD_ROW_2_PINK", // The_THEME_PINK
2015-12-01 22:31:01 +01:00
};
2016-12-18 19:50:33 +01:00
/***** Start header *****/
fprintf (Gbl.F.Out,"<header>");
2014-12-01 23:55:08 +01:00
2015-11-24 10:29:07 +01:00
/***** 1st. row *****/
2017-06-12 14:16:33 +02:00
/* Start 1st. row */
2015-11-30 09:44:17 +01:00
fprintf (Gbl.F.Out,"<div id=\"head_row_1\" class=\"%s\">",
ClassHeadRow1[Gbl.Prefs.Theme]);
2015-11-25 01:42:16 +01:00
2016-03-19 02:21:09 +01:00
/* 1st. row, 1st. column: logo, tagline and search */
2015-11-30 19:50:06 +01:00
fprintf (Gbl.F.Out,"<div id=\"head_row_1_left\">");
2016-03-22 01:26:00 +01:00
/* Start form to go to home page */
2018-11-09 20:47:39 +01:00
Frm_StartFormGoTo (ActMnu);
2016-03-22 01:26:00 +01:00
Par_PutHiddenParamUnsigned ("NxtTab",(unsigned) TabSys);
fprintf (Gbl.F.Out,"<div id=\"head_row_1_logo_small\">");
2018-11-09 20:47:39 +01:00
Frm_LinkFormSubmit (Txt_System,NULL,NULL);
2016-03-22 01:26:00 +01:00
fprintf (Gbl.F.Out,"<img src=\"%s/%s\" alt=\"%s\" title=\"%s\""
2015-09-05 11:48:44 +02:00
" class=\"CENTER_MIDDLE\""
2015-09-24 18:02:21 +02:00
" style=\"width:%upx; height:%upx;\" />"
2016-03-22 01:26:00 +01:00
"</a>", // head_row_1_logo_small
2019-03-20 01:36:36 +01:00
Cfg_URL_ICON_PUBLIC,Cfg_PLATFORM_LOGO_SMALL_FILENAME,
2015-07-24 11:34:39 +02:00
Cfg_PLATFORM_SHORT_NAME,Cfg_PLATFORM_FULL_NAME,
2015-11-30 12:58:19 +01:00
Cfg_PLATFORM_LOGO_SMALL_WIDTH,Cfg_PLATFORM_LOGO_SMALL_HEIGHT);
2016-03-22 01:26:00 +01:00
fprintf (Gbl.F.Out,"</div>"
"<div id=\"head_row_1_logo_big\">");
2018-11-09 20:47:39 +01:00
Frm_LinkFormSubmit (Txt_System,NULL,NULL);
2016-03-22 01:26:00 +01:00
fprintf (Gbl.F.Out,"<img src=\"%s/%s\" alt=\"%s\" title=\"%s\""
2015-11-30 12:58:19 +01:00
" class=\"CENTER_MIDDLE\""
" style=\"width:%upx; height:%upx;\" />"
2016-03-22 01:26:00 +01:00
"</a>", // head_row_1_logo_big
2019-03-20 01:36:36 +01:00
Cfg_URL_ICON_PUBLIC,Cfg_PLATFORM_LOGO_BIG_FILENAME,
2015-11-30 12:58:19 +01:00
Cfg_PLATFORM_SHORT_NAME,Cfg_PLATFORM_FULL_NAME,
Cfg_PLATFORM_LOGO_BIG_WIDTH,Cfg_PLATFORM_LOGO_BIG_HEIGHT);
2016-03-22 01:26:00 +01:00
fprintf (Gbl.F.Out,"</div>"
"<div id=\"head_row_1_tagline\">");
2018-11-09 20:47:39 +01:00
Frm_LinkFormSubmit (Txt_TAGLINE,The_ClassTagline[Gbl.Prefs.Theme],NULL);
2016-03-22 01:26:00 +01:00
fprintf (Gbl.F.Out,"%s"
"</a>"
"</div>", // head_row_1_tagline
2016-03-22 00:03:43 +01:00
Txt_TAGLINE_BR);
2016-03-19 02:21:09 +01:00
2016-03-22 01:26:00 +01:00
/* End form to go to home page */
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2016-03-22 01:26:00 +01:00
2016-06-24 20:16:06 +02:00
Sch_PutFormToSearchInPageTopHeading ();
2015-11-30 19:50:06 +01:00
fprintf (Gbl.F.Out,"</div>"); // head_row_1_left
2014-12-01 23:55:08 +01:00
2015-11-30 16:21:56 +01:00
/* 1st. row, 3rd. column: logged user or language selection,
and link to open/close session */
2019-01-12 19:46:33 +01:00
fprintf (Gbl.F.Out,"<div id=\"head_row_1_right\">");
2014-12-01 23:55:08 +01:00
if (Gbl.Usrs.Me.Logged)
Usr_WriteLoggedUsrHead ();
else
2017-05-07 18:06:34 +02:00
Lan_PutSelectorToSelectLanguage ();
2014-12-01 23:55:08 +01:00
2015-12-02 11:33:47 +01:00
fprintf (Gbl.F.Out,"<div id=\"login_box\">");
2014-12-01 23:55:08 +01:00
if (Gbl.Usrs.Me.Logged)
Usr_PutFormLogOut ();
else
Usr_PutFormLogIn ();
2015-12-02 11:33:47 +01:00
fprintf (Gbl.F.Out,"</div>" // login_box
2015-11-30 16:21:56 +01:00
"</div>"); // head_row_1_right
2015-11-25 01:42:16 +01:00
2017-06-12 14:16:33 +02:00
/* End 1st. row */
2015-11-30 16:21:56 +01:00
fprintf (Gbl.F.Out,"</div>"); // head_row_1
2014-12-01 23:55:08 +01:00
/***** 2nd. row *****/
2017-06-12 14:16:33 +02:00
/* Start second row */
2015-12-01 22:31:01 +01:00
fprintf (Gbl.F.Out,"<div id=\"head_row_2\" class=\"%s\">",
ClassHeadRow2[Gbl.Prefs.Theme]);
2015-11-25 01:42:16 +01:00
2015-11-24 10:29:07 +01:00
/* 2nd. row, 1st. column
Clock with hour:minute (server hour is shown) */
2015-11-25 13:33:33 +01:00
fprintf (Gbl.F.Out,"<div id=\"head_row_2_time\">");
2015-11-24 10:29:07 +01:00
Dat_ShowClientLocalTime ();
2017-06-12 14:16:33 +02:00
fprintf (Gbl.F.Out,"</div>"); // End first column
2015-11-24 10:29:07 +01:00
/* 2nd. row, 2nd. column: degree and course */
2015-11-25 13:41:22 +01:00
fprintf (Gbl.F.Out,"<div id=\"head_row_2_hierarchy\">");
2015-12-26 12:08:45 +01:00
Lay_WriteBreadcrumb ();
2016-11-14 16:47:46 +01:00
Hie_WriteBigNameCtyInsCtrDegCrs ();
2015-11-25 13:41:22 +01:00
fprintf (Gbl.F.Out,"</div>");
2015-11-24 10:29:07 +01:00
/* 2nd. row, 3rd. column */
2015-11-25 13:58:45 +01:00
fprintf (Gbl.F.Out,"<div id=\"msg\">"); // Used for AJAX based refresh
2015-11-24 10:29:07 +01:00
if (Gbl.Usrs.Me.Logged)
Ntf_WriteNumberOfNewNtfs ();
2015-11-25 13:58:45 +01:00
fprintf (Gbl.F.Out,"</div>"); // Used for AJAX based refresh
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/* End 2nd. row */
2015-11-25 01:42:16 +01:00
fprintf (Gbl.F.Out,"</div>");
2015-11-24 10:29:07 +01:00
2016-12-18 19:50:33 +01:00
/***** End header *****/
fprintf (Gbl.F.Out,"</header>");
2015-11-24 10:29:07 +01:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2015-12-26 12:08:45 +01:00
/*********** Write breadcrumb with the path to the current location **********/
/*****************************************************************************/
static void Lay_WriteBreadcrumb (void)
{
2016-12-18 19:50:33 +01:00
fprintf (Gbl.F.Out,"<nav id=\"breadcrumb\">");
2018-10-09 17:56:18 +02:00
Crs_PutIconToSelectMyCoursesInBreadcrumb ();
Hie_WriteHierarchyInBreadcrumb ();
Crs_WriteSelectorMyCoursesInBreadcrumb ();
2016-12-18 19:50:33 +01:00
fprintf (Gbl.F.Out,"</nav>");
2015-12-26 12:08:45 +01:00
}
/*****************************************************************************/
2014-12-01 23:55:08 +01:00
/*********** Write icon and title associated to the current action ***********/
/*****************************************************************************/
static void Lay_WriteTitleAction (void)
{
extern const char *The_ClassTitleAction[The_NUM_THEMES];
extern const char *The_ClassSubtitleAction[The_NUM_THEMES];
2016-12-28 17:22:25 +01:00
extern const char *Txt_TABS_TXT[Tab_NUM_TABS];
2014-12-01 23:55:08 +01:00
/***** Container start *****/
fprintf (Gbl.F.Out,"<div id=\"action_title\""
2018-12-27 21:35:49 +01:00
" style=\"background-image:url('%s/%s');\">",
2019-01-09 01:41:54 +01:00
Gbl.Prefs.URLIconSet,
2018-04-24 13:21:53 +02:00
Act_GetIcon (Act_GetSuperAction (Gbl.Action.Act)));
2014-12-01 23:55:08 +01:00
/***** Title *****/
2014-12-20 16:20:51 +01:00
fprintf (Gbl.F.Out,"<div class=\"%s\">%s &gt; %s</div>",
2014-12-01 23:55:08 +01:00
The_ClassTitleAction[Gbl.Prefs.Theme],
2018-04-24 13:21:53 +02:00
Txt_TABS_TXT[Act_GetTab (Gbl.Action.Act)],
2016-01-17 15:10:54 +01:00
Act_GetTitleAction (Gbl.Action.Act));
2014-12-01 23:55:08 +01:00
/***** Subtitle *****/
2014-12-20 16:20:51 +01:00
fprintf (Gbl.F.Out,"<div class=\"%s\">%s</div>",
2014-12-01 23:55:08 +01:00
The_ClassSubtitleAction[Gbl.Prefs.Theme],
2016-01-17 15:10:54 +01:00
Act_GetSubtitleAction (Gbl.Action.Act));
2014-12-01 23:55:08 +01:00
/***** Container end *****/
fprintf (Gbl.F.Out,"</div>");
}
/*****************************************************************************/
/***************************** Show left column ******************************/
/*****************************************************************************/
static void Lay_ShowLeftColumn (void)
{
2016-06-03 13:42:28 +02:00
struct MFU_ListMFUActions ListMFUActions;
2014-12-01 23:55:08 +01:00
2015-11-25 20:50:19 +01:00
fprintf (Gbl.F.Out,"<div style=\"width:160px;\">");
2014-12-01 23:55:08 +01:00
2017-03-24 21:29:13 +01:00
fprintf (Gbl.F.Out,"<div class=\"LEFT_RIGHT_CELL\">");
2014-12-01 23:55:08 +01:00
if (Gbl.Usrs.Me.Logged)
{
2017-03-24 21:29:13 +01:00
/***** Most frequently used actions *****/
2016-06-03 13:42:28 +02:00
MFU_AllocateMFUActions (&ListMFUActions,6);
MFU_GetMFUActions (&ListMFUActions,6);
MFU_WriteSmallMFUActions (&ListMFUActions);
MFU_FreeMFUActions (&ListMFUActions);
2014-12-01 23:55:08 +01:00
}
2017-03-24 21:29:13 +01:00
else
/***** Institutional links *****/
Lnk_WriteMenuWithInstitutionalLinks ();
fprintf (Gbl.F.Out,"</div>");
2014-12-01 23:55:08 +01:00
/***** Month *****/
2015-11-25 21:07:50 +01:00
fprintf (Gbl.F.Out,"<div class=\"LEFT_RIGHT_CELL\">");
2015-01-04 14:43:03 +01:00
Cal_DrawCurrentMonth ();
2015-11-25 20:50:19 +01:00
fprintf (Gbl.F.Out,"</div>");
2014-12-01 23:55:08 +01:00
/***** Notices (yellow notes) *****/
2019-04-03 20:57:04 +02:00
if (Gbl.Hierarchy.Level == Hie_CRS)
2014-12-01 23:55:08 +01:00
{
2015-11-25 21:07:50 +01:00
fprintf (Gbl.F.Out,"<div class=\"LEFT_RIGHT_CELL\">");
2019-03-24 23:17:32 +01:00
Not_ShowNotices (Not_LIST_BRIEF_NOTICES,
-1L); // No notice highlighted
2015-11-25 20:50:19 +01:00
fprintf (Gbl.F.Out,"</div>");
2014-12-01 23:55:08 +01:00
}
2015-11-25 20:50:19 +01:00
fprintf (Gbl.F.Out,"</div>");
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/**************************** Show right column ******************************/
/*****************************************************************************/
static void Lay_ShowRightColumn (void)
{
extern const char *Txt_If_you_have_an_Android_device_try_SWADroid;
2019-03-24 23:17:32 +01:00
// struct timeval tv1,tv2;
// long tv_usecs;
2014-12-01 23:55:08 +01:00
/***** Banners *****/
Ban_WriteMenuWithBanners ();
/***** Number of connected users in the whole platform *****/
2017-06-04 18:18:54 +02:00
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
2017-02-01 19:56:46 +01:00
{
fprintf (Gbl.F.Out,"<div id=\"globalconnected\"" // Used for AJAX based refresh
" class=\"LEFT_RIGHT_CELL\">");
Con_ShowGlobalConnectedUsrs ();
fprintf (Gbl.F.Out,"</div>"); // Used for AJAX based refresh
}
2014-12-01 23:55:08 +01:00
/***** Number of connected users in the current course *****/
2019-04-03 20:57:04 +02:00
if (Gbl.Hierarchy.Level == Hie_CRS) // There is a course selected
2014-12-01 23:55:08 +01:00
{
2016-03-15 19:41:01 +01:00
fprintf (Gbl.F.Out,"<div id=\"courseconnected\"" // Used for AJAX based refresh
" class=\"LEFT_RIGHT_CELL\">");
2019-04-03 20:57:04 +02:00
Gbl.Scope.Current = Hie_CRS;
2016-03-15 22:15:25 +01:00
Con_ShowConnectedUsrsBelongingToCurrentCrs ();
2016-03-15 19:41:01 +01:00
fprintf (Gbl.F.Out,"</div>"); // Used for AJAX based refresh
2014-12-01 23:55:08 +01:00
}
2017-02-17 01:59:58 +01:00
else if (Gbl.Usrs.Me.Logged) // I am logged
2017-02-16 20:22:13 +01:00
{
2019-03-24 23:17:32 +01:00
/*
2019-03-24 19:35:48 +01:00
gettimeofday (&tv1,NULL);
2019-03-24 23:17:32 +01:00
*/
2017-02-16 20:22:13 +01:00
/***** Suggest one user to follow *****/
fprintf (Gbl.F.Out,"<div class=\"LEFT_RIGHT_CELL\">");
Fol_SuggestUsrsToFollowMainZoneOnRightColumn ();
2019-03-24 23:17:32 +01:00
/*
2019-03-24 19:35:48 +01:00
gettimeofday (&tv2,NULL);
tv_usecs = (tv2.tv_sec - tv1.tv_sec ) * 1E6 +
(tv2.tv_usec - tv1.tv_usec);
DB_QueryINSERT ("can not debug",
"INSERT INTO debug"
" (DebugTime,Txt)"
" VALUES"
" (NOW(),'Fol_SuggestUsrsToFollowMainZoneOnRightColumn: %ld us')",
tv_usecs);
2019-03-24 23:17:32 +01:00
*/
2017-02-16 20:22:13 +01:00
fprintf (Gbl.F.Out,"</div>");
}
2014-12-01 23:55:08 +01:00
2017-03-24 21:29:13 +01:00
if (!Gbl.Usrs.Me.Logged)
/***** SWADroid advertisement *****/
2015-11-25 21:07:50 +01:00
fprintf (Gbl.F.Out,"<div class=\"LEFT_RIGHT_CELL\">"
2014-12-23 14:41:10 +01:00
"<a href=\"https://play.google.com/store/apps/details?id=es.ugr.swad.swadroid\""
" target=\"_blank\" title=\"%s\">"
2015-07-22 11:30:21 +02:00
"<img src=\"%s/SWADroid120x200.png\""
" alt=\"SWADroid\" title=\"SWADroid\""
2015-09-28 18:28:29 +02:00
" style=\"width:150px; height:250px;\" />"
2014-12-01 23:55:08 +01:00
"</a>"
2015-11-25 20:50:19 +01:00
"</div>",
2014-12-01 23:55:08 +01:00
Txt_If_you_have_an_Android_device_try_SWADroid,
2019-03-20 01:36:36 +01:00
Cfg_URL_ICON_PUBLIC);
2014-12-01 23:55:08 +01:00
}
2015-12-13 18:32:37 +01:00
/*****************************************************************************/
2016-11-22 10:44:58 +01:00
/**************** Show an icon with a link in contextual menu ****************/
2015-12-13 18:32:37 +01:00
/*****************************************************************************/
2019-01-12 03:00:59 +01:00
void Lay_PutContextualLinkOnlyIcon (Act_Action_t NextAction,const char *Anchor,
void (*FuncParams) (),
const char *Icon,
const char *Title)
{
/***** Start form *****/
Frm_StartFormAnchor (NextAction,Anchor);
if (FuncParams)
FuncParams ();
/***** Put icon with link *****/
Ico_PutIconLink (Icon,Title);
/***** End form *****/
Frm_EndForm ();
}
/*****************************************************************************/
/**************** Show an icon with a link in contextual menu ****************/
/*****************************************************************************/
void Lay_PutContextualLinkIconText (Act_Action_t NextAction,const char *Anchor,
void (*FuncParams) (),
const char *Icon,
const char *Text)
{
2019-02-22 21:47:50 +01:00
extern const char *The_ClassFormOutBoxBold[The_NUM_THEMES];
2019-01-12 03:00:59 +01:00
/***** Separator *****/
fprintf (Gbl.F.Out," "); // This space is necessary to enable
// jumping to the next line on narrow screens
/***** Start form *****/
Frm_StartFormAnchor (NextAction,Anchor);
if (FuncParams)
FuncParams ();
/***** Put icon and text with link *****/
2019-02-22 21:47:50 +01:00
Frm_LinkFormSubmit (Text,The_ClassFormOutBoxBold[Gbl.Prefs.Theme],NULL);
2019-01-12 19:46:33 +01:00
Ico_PutIconTextLink (Icon,Text);
2019-01-12 03:00:59 +01:00
fprintf (Gbl.F.Out,"</a>");
/***** End form *****/
Frm_EndForm ();
/***** Separator *****/
fprintf (Gbl.F.Out," "); // This space is necessary to enable
// jumping to the next line on narrow screens
}
/*****************************************************************************/
/**************** Show an icon with a link in contextual menu ****************/
/*****************************************************************************/
void Lay_PutContextualLinkIconTextOnSubmit (Act_Action_t NextAction,const char *Anchor,
void (*FuncParams) (),
const char *Icon,
const char *Text,
const char *OnSubmit)
2015-12-13 18:32:37 +01:00
{
2019-02-22 21:47:50 +01:00
extern const char *The_ClassFormOutBoxBold[The_NUM_THEMES];
2015-12-13 18:32:37 +01:00
2016-11-22 10:44:58 +01:00
/***** Separator *****/
2019-01-12 03:00:59 +01:00
fprintf (Gbl.F.Out," "); // This space is necessary to enable
2015-12-13 22:45:57 +01:00
// jumping to the next line on narrow screens
2015-12-13 20:24:39 +01:00
2016-11-22 10:44:58 +01:00
/***** Start form *****/
2018-11-09 20:47:39 +01:00
Frm_StartFormAnchor (NextAction,Anchor);
2015-12-13 18:32:37 +01:00
if (FuncParams)
FuncParams ();
2016-11-22 10:44:58 +01:00
/***** Put icon with link *****/
2019-02-22 21:47:50 +01:00
Frm_LinkFormSubmit (Text,The_ClassFormOutBoxBold[Gbl.Prefs.Theme],OnSubmit);
2019-01-12 19:46:33 +01:00
Ico_PutIconTextLink (Icon,Text);
2019-01-12 03:00:59 +01:00
fprintf (Gbl.F.Out,"</a>");
2016-11-22 10:44:58 +01:00
/***** End form *****/
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2016-11-22 10:44:58 +01:00
/***** Separator *****/
2019-01-12 03:00:59 +01:00
fprintf (Gbl.F.Out," "); // This space is necessary to enable
2016-11-22 10:44:58 +01:00
// jumping to the next line on narrow screens
}
/*****************************************************************************/
/******************** Show a checkbox in contextual menu *********************/
/*****************************************************************************/
void Lay_PutContextualCheckbox (Act_Action_t NextAction,
2016-11-22 12:07:29 +01:00
void (*FuncParams) (),
2017-05-22 12:23:08 +02:00
const char *CheckboxName,
bool Checked,bool Disabled,
2016-11-22 10:44:58 +01:00
const char *Title,const char *Text)
{
2019-02-22 21:47:50 +01:00
extern const char *The_ClassFormOutBoxBold[The_NUM_THEMES];
2016-11-22 10:44:58 +01:00
/***** Separator *****/
if (Text)
fprintf (Gbl.F.Out," "); // This space is necessary to enable
// jumping to the next line on narrow screens
/***** Start form *****/
2018-11-09 20:47:39 +01:00
Frm_StartForm (NextAction);
2016-11-22 12:07:29 +01:00
if (FuncParams)
FuncParams ();
2016-11-22 10:44:58 +01:00
2016-12-20 10:03:00 +01:00
/***** Start container and label *****/
fprintf (Gbl.F.Out,"<div class=\"CONTEXT_OPT %s %s\" title=\"%s\">"
"<label>",
2016-11-22 10:44:58 +01:00
Checked ? "CHECKBOX_CHECKED" :
"CHECKBOX_UNCHECKED",
2019-02-22 21:47:50 +01:00
The_ClassFormOutBoxBold[Gbl.Prefs.Theme],
2016-11-22 10:44:58 +01:00
Title);
/****** Checkbox and text *****/
fprintf (Gbl.F.Out,"<input type=\"checkbox\" name=\"%s\" value=\"Y\"",
CheckboxName);
if (Checked)
fprintf (Gbl.F.Out," checked=\"checked\"");
2017-05-22 12:23:08 +02:00
if (Disabled)
fprintf (Gbl.F.Out," disabled=\"disabled\"");
else
fprintf (Gbl.F.Out," onclick=\"document.getElementById('%s').submit();\"",
Gbl.Form.Id);
fprintf (Gbl.F.Out," />");
2016-11-22 10:44:58 +01:00
if (Text)
if (Text[0])
fprintf (Gbl.F.Out,"&nbsp;%s",
Text);
2016-12-20 10:03:00 +01:00
/***** End label and container *****/
fprintf (Gbl.F.Out,"</label>"
"</div>");
2016-11-22 10:44:58 +01:00
/***** End form *****/
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2015-12-13 22:45:57 +01:00
2016-11-22 10:44:58 +01:00
/***** Separator *****/
2015-12-13 22:45:57 +01:00
if (Text)
fprintf (Gbl.F.Out," "); // This space is necessary to enable
// jumping to the next line on narrow screens
2015-12-13 18:32:37 +01:00
}
2017-05-25 13:43:54 +02:00
/*****************************************************************************/
/****************************** Start/end section ****************************/
/*****************************************************************************/
void Lay_StartSection (const char *SectionId)
{
fprintf (Gbl.F.Out,"<section id=\"%s\">",SectionId);
}
void Lay_EndSection (void)
{
fprintf (Gbl.F.Out,"</section>");
}
2019-03-24 23:17:32 +01:00
/*****************************************************************************/
/****************************** Start/end article ****************************/
/*****************************************************************************/
void Lay_StartArticle (const char *ArticleId)
{
fprintf (Gbl.F.Out,"<article id=\"%s\">",ArticleId);
}
void Lay_EndArticle (void)
{
fprintf (Gbl.F.Out,"</article>");
}
2018-10-18 20:06:54 +02:00
/*****************************************************************************/
/********** Write error message and exit when not enough memory **************/
/*****************************************************************************/
void Lay_NotEnoughMemoryExit (void)
{
2018-10-24 23:03:11 +02:00
Lay_ShowErrorAndExit ("Not enough memory.");
}
/*****************************************************************************/
/************* Write error message and exit when wrong scope *****************/
/*****************************************************************************/
void Lay_WrongScopeExit (void)
{
Lay_ShowErrorAndExit ("Wrong scope.");
2018-10-18 20:06:54 +02:00
}
2019-02-16 20:44:31 +01:00
/*****************************************************************************/
/*** Write error message and exit when no permission to perform an action ****/
/*****************************************************************************/
void Lay_NoPermissionExit (void)
{
extern const char *Txt_You_dont_have_permission_to_perform_this_action;
Lay_ShowErrorAndExit (Txt_You_dont_have_permission_to_perform_this_action);
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/******* Write error message, close files, remove lock file, and exit ********/
/*****************************************************************************/
2017-05-10 10:25:01 +02:00
void Lay_ShowErrorAndExit (const char *Txt)
2014-12-01 23:55:08 +01:00
{
/***** Unlock tables if locked *****/
if (Gbl.DB.LockedTables)
{
Gbl.DB.LockedTables = false;
mysql_query (&Gbl.mysql,"UNLOCK TABLES");
}
if (!Gbl.WebService.IsWebService)
{
2017-04-27 15:02:00 +02:00
/****** If start of page is not written yet, do it now ******/
if (!Gbl.Layout.HTMLStartWritten)
Lay_WriteStartOfPage ();
2014-12-01 23:55:08 +01:00
/***** Write possible error message *****/
2017-05-10 10:25:01 +02:00
if (Txt)
2019-02-16 17:20:05 +01:00
Ale_ShowAlert (Ale_ERROR,Txt);
2014-12-01 23:55:08 +01:00
/***** Finish the page, except </body> and </html> *****/
Lay_WriteEndOfPage ();
}
/***** Free memory and close all the open files *****/
Gbl_Cleanup ();
2015-12-02 00:32:46 +01:00
/***** Page is generated (except </body> and </html>).
Compute time to generate page *****/
2017-02-05 22:23:41 +01:00
if (!Gbl.Action.IsAJAXAutoRefresh)
2014-12-01 23:55:08 +01:00
Sta_ComputeTimeToGeneratePage ();
if (Gbl.WebService.IsWebService) // Serving a plugin request
{
/***** Log access *****/
Gbl.TimeSendInMicroseconds = 0L;
2017-05-10 10:25:01 +02:00
Sta_LogAccess (Txt);
2014-12-01 23:55:08 +01:00
}
2015-12-02 00:32:46 +01:00
else
2014-12-01 23:55:08 +01:00
{
2015-12-02 00:32:46 +01:00
/***** Send page.
The HTML output is now in Gbl.F.Out file ==>
==> copy it to standard output *****/
rewind (Gbl.F.Out);
Fil_FastCopyOfOpenFiles (Gbl.F.Out,stdout);
Fil_CloseAndRemoveFileForHTMLOutput ();
2014-12-01 23:55:08 +01:00
2017-02-05 22:23:41 +01:00
if (!Gbl.Action.IsAJAXAutoRefresh)
2015-12-02 00:32:46 +01:00
{
/***** Compute time to send page *****/
Sta_ComputeTimeToSendPage ();
/***** Log access *****/
2017-05-10 10:25:01 +02:00
Sta_LogAccess (Txt);
2015-12-02 00:32:46 +01:00
2019-04-01 13:15:15 +02:00
/***** Update last data for next time *****/
if (Gbl.Usrs.Me.Logged)
{
Usr_UpdateMyLastData ();
Crs_UpdateCrsLast ();
}
2015-12-02 00:32:46 +01:00
/***** End the output *****/
if (!Gbl.Layout.HTMLEndWritten)
{
// Here Gbl.F.Out is stdout
2018-04-24 13:21:53 +02:00
if (Act_GetBrowserTab (Gbl.Action.Act) == Act_BRW_1ST_TAB)
2015-12-02 11:33:47 +01:00
Lay_WriteAboutZone ();
2015-12-02 00:32:46 +01:00
fprintf (Gbl.F.Out,"</body>\n"
"</html>\n");
Gbl.Layout.HTMLEndWritten = true;
}
}
2014-12-01 23:55:08 +01:00
}
/***** Close database connection *****/
DB_CloseDBConnection ();
/***** Exit *****/
if (Gbl.WebService.IsWebService)
2017-05-10 10:25:01 +02:00
Svc_Exit (Txt);
2014-12-01 23:55:08 +01:00
exit (0);
}
2015-12-02 00:32:46 +01:00
/*****************************************************************************/
/***************** Write about zone at the end of the page *******************/
/*****************************************************************************/
static void Lay_WriteAboutZone (void)
{
extern const char *Txt_About_X;
extern const char *Txt_Questions_and_problems;
2016-12-18 19:50:33 +01:00
/***** Start about zone *****/
2016-12-19 02:00:00 +01:00
fprintf (Gbl.F.Out,"<address id=\"about_zone\" class=\"ABOUT\">");
2015-12-02 00:32:46 +01:00
/***** Institution and centre hosting the platform *****/
fprintf (Gbl.F.Out,"<a href=\"%s\" class=\"ABOUT\" target=\"_blank\">"
"<img src=\"%s/%s\""
" alt=\"%s\" title=\"%s\""
" style=\"width:%upx; height:%upx;\" />"
"<div>%s</div>"
"</a>",
Cfg_ABOUT_URL,
2019-03-20 01:36:36 +01:00
Cfg_URL_ICON_PUBLIC,Cfg_ABOUT_LOGO,
2015-12-02 00:32:46 +01:00
Cfg_ABOUT_NAME,Cfg_ABOUT_NAME,
Cfg_ABOUT_LOGO_WIDTH,Cfg_ABOUT_LOGO_HEIGHT,
Cfg_ABOUT_NAME);
/***** Questions and problems *****/
2016-12-19 02:00:00 +01:00
fprintf (Gbl.F.Out,"<div>"
2016-04-18 13:32:46 +02:00
"%s: "
2015-12-02 00:32:46 +01:00
"<a href=\"mailto:%s\" class=\"ABOUT\" target=\"_blank\">%s</a>"
"</div>",
2016-04-18 13:32:46 +02:00
Txt_Questions_and_problems,
2016-11-16 23:19:52 +01:00
Cfg_PLATFORM_RESPONSIBLE_EMAIL,Cfg_PLATFORM_RESPONSIBLE_EMAIL);
2015-12-02 00:32:46 +01:00
/***** About and time to generate and send page *****/
fprintf (Gbl.F.Out,"<div>");
/* About */
fprintf (Gbl.F.Out,"<a href=\"%s\" class=\"ABOUT\" target=\"_blank\">",
Cfg_ABOUT_SWAD_URL);
fprintf (Gbl.F.Out,Txt_About_X,Log_PLATFORM_VERSION);
fprintf (Gbl.F.Out,"</a>"
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
/* Time to generate and send page */
Sta_WriteTimeToGenerateAndSendPage ();
fprintf (Gbl.F.Out,"</div>");
2016-12-18 19:50:33 +01:00
/***** End about zone *****/
2016-12-19 02:00:00 +01:00
fprintf (Gbl.F.Out,"</address>"); // about_zone
2015-12-02 00:32:46 +01:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/*********** Refresh notifications and connected users via AJAX **************/
/*****************************************************************************/
void Lay_RefreshNotifsAndConnected (void)
{
unsigned NumUsr;
2015-11-27 12:57:56 +01:00
bool ShowConnected = (Gbl.Prefs.SideCols & Lay_SHOW_RIGHT_COLUMN) &&
2019-04-03 20:57:04 +02:00
Gbl.Hierarchy.Level == Hie_CRS; // Right column visible && There is a course selected
2014-12-01 23:55:08 +01:00
2019-02-13 13:32:11 +01:00
/***** Sometimes, someone must do this work,
so who best than processes that refresh via AJAX? *****/
2019-03-20 01:36:36 +01:00
// We use (PID % prime-number) to do only one action as much
if (!(Gbl.PID % 11))
2016-11-16 23:19:52 +01:00
Ntf_SendPendingNotifByEMailToAllUsrs (); // Send pending notifications by email
2019-03-20 01:36:36 +01:00
else if (!(Gbl.PID % 19))
FW_PurgeFirewall (); // Remove old clicks from firewall
2019-03-20 13:05:09 +01:00
else if (!(Gbl.PID % 23))
Fil_RemoveOldTmpFiles (Cfg_PATH_FILE_BROWSER_TMP_PUBLIC ,Cfg_TIME_TO_DELETE_BROWSER_TMP_FILES ,false); // Remove the oldest temporary public directories used for downloading
2019-03-20 01:36:36 +01:00
else if (!(Gbl.PID % 101))
2014-12-01 23:55:08 +01:00
Brw_RemoveExpiredExpandedFolders (); // Remove old expanded folders (from all users)
2019-03-20 01:36:36 +01:00
else if (!(Gbl.PID % 103))
2019-03-26 11:53:21 +01:00
Set_RemoveOldSettingsFromIP (); // Remove old settings from IP
2019-03-20 01:36:36 +01:00
else if (!(Gbl.PID % 107))
2014-12-01 23:55:08 +01:00
Sta_RemoveOldEntriesRecentLog (); // Remove old entries in recent log table, it's a slow query
2019-03-20 01:36:36 +01:00
else if (!(Gbl.PID % 109))
Fil_RemoveOldTmpFiles (Cfg_PATH_OUT_PRIVATE ,Cfg_TIME_TO_DELETE_HTML_OUTPUT ,false);
else if (!(Gbl.PID % 113))
Fil_RemoveOldTmpFiles (Cfg_PATH_PHOTO_TMP_PUBLIC ,Cfg_TIME_TO_DELETE_PHOTOS_TMP_FILES ,false);
2019-03-20 13:05:09 +01:00
else if (!(Gbl.PID % 127))
2019-03-20 01:36:36 +01:00
Fil_RemoveOldTmpFiles (Cfg_PATH_PHOTO_TMP_PRIVATE ,Cfg_TIME_TO_DELETE_PHOTOS_TMP_FILES ,false);
2019-03-20 13:05:09 +01:00
else if (!(Gbl.PID % 131))
2019-03-20 01:36:36 +01:00
Fil_RemoveOldTmpFiles (Cfg_PATH_MEDIA_TMP_PRIVATE ,Cfg_TIME_TO_DELETE_MEDIA_TMP_FILES ,false);
2019-03-20 13:05:09 +01:00
else if (!(Gbl.PID % 137))
2019-03-20 01:36:36 +01:00
Fil_RemoveOldTmpFiles (Cfg_PATH_ZIP_PRIVATE ,Cfg_TIME_TO_DELETE_BROWSER_ZIP_FILES ,false);
2019-03-20 13:05:09 +01:00
else if (!(Gbl.PID % 139))
2019-03-20 01:36:36 +01:00
Fil_RemoveOldTmpFiles (Cfg_PATH_MARK_PRIVATE ,Cfg_TIME_TO_DELETE_MARKS_TMP_FILES ,false);
2019-03-20 13:05:09 +01:00
else if (!(Gbl.PID % 149))
2019-03-20 01:36:36 +01:00
Fil_RemoveOldTmpFiles (Cfg_PATH_TEST_PRIVATE ,Cfg_TIME_TO_DELETE_TEST_TMP_FILES ,false);
2014-12-01 23:55:08 +01:00
2019-02-13 13:32:11 +01:00
/***** Send, before the HTML, the refresh time *****/
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"%lu|",Gbl.Usrs.Connected.TimeToRefreshInMs);
if (Gbl.Usrs.Me.Logged)
Ntf_WriteNumberOfNewNtfs ();
fprintf (Gbl.F.Out,"|");
Con_ShowGlobalConnectedUsrs ();
fprintf (Gbl.F.Out,"|");
if (ShowConnected)
{
2019-04-03 20:57:04 +02:00
Gbl.Scope.Current = Hie_CRS;
2016-03-15 22:15:25 +01:00
Con_ShowConnectedUsrsBelongingToCurrentCrs ();
2014-12-01 23:55:08 +01:00
}
fprintf (Gbl.F.Out,"|");
if (ShowConnected)
fprintf (Gbl.F.Out,"%u",Gbl.Usrs.Connected.NumUsrsToList);
fprintf (Gbl.F.Out,"|");
if (ShowConnected)
for (NumUsr = 0;
NumUsr < Gbl.Usrs.Connected.NumUsrsToList;
NumUsr++)
2015-10-26 23:16:21 +01:00
fprintf (Gbl.F.Out,"%ld|",Gbl.Usrs.Connected.Lst[NumUsr].TimeDiff);
2014-12-01 23:55:08 +01:00
/***** All the output is made, so don't write anymore *****/
2015-11-27 21:24:24 +01:00
Gbl.Layout.DivsEndWritten = Gbl.Layout.HTMLEndWritten = true;
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2016-01-09 15:00:14 +01:00
/**************** Refresh last clicks in realtime via AJAX *******************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
void Lay_RefreshLastClicks (void)
{
2017-02-06 01:23:33 +01:00
if (Gbl.Session.IsOpen) // If session has been closed, do not write anything
{
/***** Send, before the HTML, the refresh time *****/
fprintf (Gbl.F.Out,"%lu|",Cfg_TIME_TO_REFRESH_LAST_CLICKS);
/***** Get and show last clicks *****/
2019-01-11 12:32:41 +01:00
Sta_GetAndShowLastClicks ();
2017-02-06 01:23:33 +01:00
}
2014-12-01 23:55:08 +01:00
/***** All the output is made, so don't write anymore *****/
2015-11-27 21:24:24 +01:00
Gbl.Layout.DivsEndWritten = Gbl.Layout.HTMLEndWritten = true;
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************************ Write the end of the page **************************/
/*****************************************************************************/
static void Lay_WriteFootFromHTMLFile (void)
{
FILE *FileHTML;
/***** Open file with the HTML page for the chat *****/
if ((FileHTML = fopen (Cfg_PATH_AND_FILE_REL_HTML_PRIVATE,"rb")))
{
2016-12-18 19:50:33 +01:00
fprintf (Gbl.F.Out,"<footer id=\"foot_zone\">");
2015-12-02 00:32:46 +01:00
2014-12-01 23:55:08 +01:00
/***** Copy HTML to output file *****/
Fil_FastCopyOfOpenFiles (FileHTML,Gbl.F.Out);
fclose (FileHTML);
2015-12-02 00:32:46 +01:00
2016-12-18 19:50:33 +01:00
fprintf (Gbl.F.Out,"</footer>");
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
/****** Write header and footer of the class photo or academic calendar ******/
/*****************************************************************************/
2016-03-18 22:17:35 +01:00
void Lay_WriteHeaderClassPhoto (bool PrintView,bool DrawingClassPhoto,
2014-12-01 23:55:08 +01:00
long InsCod,long DegCod,long CrsCod)
{
2016-10-28 10:03:37 +02:00
struct Instit Ins;
2014-12-01 23:55:08 +01:00
struct Degree Deg;
struct Course Crs;
/***** Get data of institution *****/
Ins.InsCod = InsCod;
2015-12-09 19:51:17 +01:00
Ins_GetDataOfInstitutionByCod (&Ins,Ins_GET_BASIC_DATA);
2014-12-01 23:55:08 +01:00
/***** Get data of degree *****/
Deg.DegCod = DegCod;
Deg_GetDataOfDegreeByCod (&Deg);
/***** Get data of course *****/
Crs.CrsCod = CrsCod;
Crs_GetDataOfCourseByCod (&Crs);
2017-06-12 14:16:33 +02:00
/***** Start table *****/
2016-03-18 22:17:35 +01:00
fprintf (Gbl.F.Out,"<table style=\"width:100%%; padding:12px;\">"
"<tr>");
2014-12-01 23:55:08 +01:00
/***** First column: institution logo *****/
2015-09-28 18:28:29 +02:00
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP\" style=\"width:80px;\">");
2014-12-01 23:55:08 +01:00
if (InsCod > 0)
{
if (!PrintView)
fprintf (Gbl.F.Out,"<a href=\"%s\" target=\"_blank\">",Ins.WWW);
2019-04-03 20:57:04 +02:00
Log_DrawLogo (Hie_INS,Ins.InsCod,Ins.ShrtName,40,NULL,true);
2014-12-01 23:55:08 +01:00
if (!PrintView)
fprintf (Gbl.F.Out,"</a>");
}
fprintf (Gbl.F.Out,"</td>");
/***** Second column: class photo title *****/
2017-03-03 21:06:34 +01:00
fprintf (Gbl.F.Out,"<td class=\"CLASSPHOTO_TITLE CENTER_MIDDLE\">");
2014-12-01 23:55:08 +01:00
if (InsCod > 0)
{
if (!PrintView)
2017-03-03 21:06:34 +01:00
fprintf (Gbl.F.Out,"<a href=\"%s\" target=\"_blank\""
" class=\"CLASSPHOTO_TITLE\">",
2014-12-01 23:55:08 +01:00
Ins.WWW);
fprintf (Gbl.F.Out,"%s",Ins.FullName);
if (!PrintView)
fprintf (Gbl.F.Out,"</a>");
}
if (DegCod > 0)
{
if (Ins.InsCod > 0)
fprintf (Gbl.F.Out," - ");
if (!PrintView)
2017-03-03 21:06:34 +01:00
fprintf (Gbl.F.Out,"<a href=\"%s\" target=\"_blank\""
" class=\"CLASSPHOTO_TITLE\">",
2014-12-01 23:55:08 +01:00
Deg.WWW);
fprintf (Gbl.F.Out,"%s",Deg.FullName);
if (!PrintView)
fprintf (Gbl.F.Out,"</a>");
}
fprintf (Gbl.F.Out,"<br />");
if (CrsCod > 0)
{
fprintf (Gbl.F.Out,"%s",Crs.FullName);
if (DrawingClassPhoto && !Gbl.Usrs.ClassPhoto.AllGroups)
{
fprintf (Gbl.F.Out,"<br />");
Grp_WriteNamesOfSelectedGrps ();
}
}
fprintf (Gbl.F.Out,"</td>");
/***** Third column: degree logo *****/
2015-09-28 18:28:29 +02:00
fprintf (Gbl.F.Out,"<td class=\"RIGHT_TOP\" style=\"width:80px;\">");
2014-12-01 23:55:08 +01:00
if (DegCod > 0)
{
if (!PrintView)
2015-08-06 12:31:05 +02:00
fprintf (Gbl.F.Out,"<a href=\"%s\" target=\"_blank\""
2017-03-03 21:06:34 +01:00
" class=\"CLASSPHOTO_TITLE\">",
2014-12-01 23:55:08 +01:00
Deg.WWW);
2019-04-03 20:57:04 +02:00
Log_DrawLogo (Hie_DEG,Deg.DegCod,Deg.ShrtName,40,NULL,true);
2014-12-01 23:55:08 +01:00
if (!PrintView)
fprintf (Gbl.F.Out,"</a>");
}
fprintf (Gbl.F.Out,"</td>");
2016-03-20 13:47:46 +01:00
/***** End table *****/
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"</tr>"
2016-03-18 22:17:35 +01:00
"</table>");
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/**************** Show advertisement about mobile version ********************/
/*****************************************************************************/
2015-03-27 16:56:48 +01:00
#define Lay_SHOW_ADVERTISEMENT_ONE_TIME_OF_X 5 // n ==> show advertisement 1/n of the times
2014-12-01 23:55:08 +01:00
void Lay_AdvertisementMobile (void)
{
extern const char *Txt_Stay_connected_with_SWADroid;
if (!(rand () % Lay_SHOW_ADVERTISEMENT_ONE_TIME_OF_X))
{
2015-09-28 18:28:29 +02:00
fprintf (Gbl.F.Out,"<div style=\"margin-top:25px;\">");
2015-03-27 16:56:48 +01:00
2017-06-12 14:16:33 +02:00
/***** Start box and table *****/
2017-06-10 21:38:10 +02:00
Box_StartBoxTable (NULL,NULL,NULL,
2017-06-12 15:03:29 +02:00
NULL,Box_NOT_CLOSABLE,8);
2014-12-01 23:55:08 +01:00
/***** Show advertisement *****/
fprintf (Gbl.F.Out,"<tr>"
2015-08-03 22:45:00 +02:00
"<td class=\"DAT CENTER_MIDDLE\">"
2014-12-23 14:41:10 +01:00
"<a href=\"https://play.google.com/store/apps/details?id=es.ugr.swad.swadroid\""
" class=\"DAT\">"
2014-12-01 23:55:08 +01:00
"%s<br /><br />"
2015-07-22 11:30:21 +02:00
"<img src=\"%s/SWADroid200x300.png\""
" alt=\"SWADroid\" title=\"%s\""
2015-09-28 18:28:29 +02:00
" style=\"width:250px; height:375px;\" />"
2014-12-01 23:55:08 +01:00
"</a>"
"</td>"
"</tr>",
Txt_Stay_connected_with_SWADroid,
2019-03-20 01:36:36 +01:00
Cfg_URL_ICON_PUBLIC,
2015-07-22 11:30:21 +02:00
Txt_Stay_connected_with_SWADroid);
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** End table and box *****/
2017-06-10 21:38:10 +02:00
Box_EndBoxTable ();
2015-03-27 16:56:48 +01:00
fprintf (Gbl.F.Out,"</div>");
2014-12-01 23:55:08 +01:00
}
}
2014-12-29 13:26:39 +01:00
/*****************************************************************************/
/*********************** Indent forum or chat title **************************/
/*****************************************************************************/
2017-01-28 15:58:46 +01:00
// IsLastItemInLevel[] is a vector with at least 1 + Level booleans
2014-12-29 13:26:39 +01:00
void Lay_IndentDependingOnLevel (unsigned Level,bool IsLastItemInLevel[])
{
unsigned i;
/***** Indent (from 1 to Level-1) *****/
for (i = 1;
i < Level;
i++)
2015-07-22 11:30:21 +02:00
fprintf (Gbl.F.Out,"<img src=\"%s/%s20x20.gif\""
" alt=\"\" title=\"\""
2016-11-14 10:05:41 +01:00
" class=\"ICO25x25\" />",
2019-03-20 01:36:36 +01:00
Cfg_URL_ICON_PUBLIC,
2014-12-29 13:26:39 +01:00
IsLastItemInLevel[i] ? "tr" :
"subleft");
/***** Level *****/
2017-04-13 23:53:57 +02:00
if (Level)
fprintf (Gbl.F.Out,"<img src=\"%s/%s20x20.gif\""
" alt=\"\" title=\"\""
" class=\"ICO25x25\" />",
2019-03-20 01:36:36 +01:00
Cfg_URL_ICON_PUBLIC,
2017-04-13 23:53:57 +02:00
IsLastItemInLevel[Level] ? "subend" :
"submid");
2014-12-29 13:26:39 +01:00
}
2016-10-03 22:41:45 +02:00
2015-04-11 02:04:23 +02:00
/*****************************************************************************/
/************************** Help for the text editor *************************/
/*****************************************************************************/
void Lay_HelpPlainEditor (void)
{
extern const char *Txt_TEXT_plain;
Lay_HelpTextEditor (Txt_TEXT_plain,
"\\(LaTeX\\)",
2016-01-20 14:07:15 +01:00
"$$LaTeX$$&nbsp;\\[LaTeX\\]");
2015-04-11 02:04:23 +02:00
}
void Lay_HelpRichEditor (void)
{
Lay_HelpTextEditor ("<a href=\"http://johnmacfarlane.net/pandoc/README.html#pandocs-markdown\""
2016-01-17 21:46:01 +01:00
" target=\"_blank\">Markdown+Pandoc</a>",
2015-04-11 02:04:23 +02:00
"$LaTeX$",
"$$LaTeX$$");
}
static void Lay_HelpTextEditor (const char *Text,const char *InlineMath,const char *Equation)
{
extern const char *Txt_Text;
extern const char *Txt_Inline_math;
extern const char *Txt_Equation_centered;
fprintf (Gbl.F.Out,"<div class=\"HELP_EDIT\">"
2016-03-29 01:12:43 +02:00
"%s: %s"
2016-01-17 21:46:01 +01:00
" "
2016-03-29 01:12:43 +02:00
"%s: <code>%s</code>"
2016-01-17 21:46:01 +01:00
" "
2016-03-29 01:12:43 +02:00
"%s: <code>%s</code>"
2015-04-11 02:04:23 +02:00
"</div>",
Txt_Text,Text,
Txt_Inline_math,InlineMath,
Txt_Equation_centered,Equation);
}
2016-10-03 22:41:45 +02:00
/*****************************************************************************/
/************************** Help for the text editor *************************/
/*****************************************************************************/
void Lay_StartHTMLFile (FILE *File,const char *Title)
{
2018-12-08 16:43:13 +01:00
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
2016-10-03 22:41:45 +02:00
fprintf (File,"<!DOCTYPE html>\n"
"<html lang=\"%s\">\n"
"<head>\n"
"<meta http-equiv=\"Content-Type\""
" content=\"text/html;charset=windows-1252\" />\n"
"<title>%s</title>\n"
2016-10-04 01:16:52 +02:00
"</head>\n",
2018-12-08 16:43:13 +01:00
Lan_STR_LANG_ID[Gbl.Prefs.Language], // Language
2016-10-03 22:41:45 +02:00
Title); // Page title
}