// 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.
Copyright (C) 1999-2017 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 // For NULL
#include // For exit, system, malloc, calloc, free, etc
#include // For string functions
#include "swad_action.h"
#include "swad_box.h"
#include "swad_calendar.h"
#include "swad_changelog.h"
#include "swad_config.h"
#include "swad_connected.h"
#include "swad_database.h"
#include "swad_exam.h"
#include "swad_follow.h"
#include "swad_global.h"
#include "swad_help.h"
#include "swad_hierarchy.h"
#include "swad_language.h"
#include "swad_logo.h"
#include "swad_MFU.h"
#include "swad_notice.h"
#include "swad_notification.h"
#include "swad_parameter.h"
#include "swad_preference.h"
#include "swad_social.h"
#include "swad_tab.h"
#include "swad_theme.h"
#include "swad_web_service.h"
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/****************************** Public constants *****************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
/*****************************************************************************/
/******************************* Private types *******************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
static void Lay_WriteEndOfPage (void);
static void Lay_WritePageTitle (void);
static void Lay_WriteRedirToMyLangOnLogIn (void);
static void Lay_WriteRedirToMyLangOnViewUsrAgd (void);
static void Lay_WriteScripts (void);
static void Lay_WriteScriptMathJax (void);
static void Lay_WriteScriptInit (void);
static void Lay_WriteScriptParamsAJAX (void);
static void Lay_WriteScriptCustomDropzone (void);
static void Lay_WritePageTopHeading (void);
static void Lay_WriteBreadcrumb (void);
static void Lay_WriteTitleAction (void);
static void Lay_ShowLeftColumn (void);
static void Lay_ShowRightColumn (void);
static void Lay_WriteAboutZone (void);
static void Lay_WriteFootFromHTMLFile (void);
static void Lay_HelpTextEditor (const char *Text,const char *InlineMath,const char *Equation);
/*****************************************************************************/
/*********************** Write the start of the page *************************/
/*****************************************************************************/
void Lay_WriteStartOfPage (void)
{
extern struct Act_Actions Act_Actions[Act_NUM_ACTIONS];
extern const char *Txt_STR_LANG_ID[1 + Txt_NUM_LANGUAGES];
extern const unsigned Txt_Current_CGI_SWAD_Language;
extern const char *The_TabOnBgColors[The_NUM_THEMES];
extern const char *Txt_NEW_YEAR_GREETING;
const char *LayoutMainZone[Mnu_NUM_MENUS] =
{
"main_horizontal", // Mnu_MENU_HORIZONTAL
"main_vertical", // Mnu_MENU_VERTICAL
};
/***** If, when this function is called, the head is being written
or the head is already written ==> don't do anything *****/
if (Gbl.Layout.WritingHTMLStart ||
Gbl.Layout.HTMLStartWritten)
return;
/***** Compute connected users to be displayed in right columns *****/
Con_ComputeConnectedUsrsBelongingToCurrentCrs ();
/***** Send head width the file type for the HTTP protocol *****/
if (Gbl.Action.UsesAJAX)
// Don't generate a full HTML page, only the content of a DIV or similar
{
fprintf (Gbl.F.Out,"Content-Type: text/html; charset=windows-1252\r\n\r\n");
Gbl.Layout.WritingHTMLStart = false;
Gbl.Layout.HTMLStartWritten = Gbl.Layout.DivsEndWritten = true;
return;
}
/***** If serving a web service ==> don't do anything *****/
if (Gbl.WebService.IsWebService)
{
Gbl.Layout.WritingHTMLStart = false;
Gbl.Layout.HTMLStartWritten = Gbl.Layout.DivsEndWritten = true;
return;
}
Gbl.Layout.WritingHTMLStart = true;
/***** Write header to standard output to avoid timeout *****/
// Two \r\n are necessary
fprintf (stdout,"Content-type: text/html; charset=windows-1252\r\n\r\n"
"\n");
/***** Write start of HTML code *****/
// WARNING: It is necessary to comment the line 'AddDefaultCharset UTF8'
// in httpd.conf to enable meta tag
fprintf (Gbl.F.Out,"\n"
"\n"
"\n"
"\n"
"\n"
"\n"
"\n",
Txt_STR_LANG_ID[Gbl.Prefs.Language],
Cfg_PLATFORM_SHORT_NAME);
/* Viewport (used for responsive design) */
fprintf (Gbl.F.Out,"\n");
/* Title */
Lay_WritePageTitle ();
/* Canonical URL */
fprintf (Gbl.F.Out,"\n",
Cfg_URL_SWAD_CGI);
/* Favicon */
fprintf (Gbl.F.Out,"\n"
"\n",
Gbl.Prefs.IconsURL,
Gbl.Prefs.IconsURL);
/* Style sheet for SWAD */
fprintf (Gbl.F.Out,"\n",
Cfg_URL_SWAD_PUBLIC,CSS_FILE);
/* 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
switch (Gbl.Action.Act)
{
case ActFrmCreDocIns: // Brw_ADMI_DOCUM_INS
case ActFrmCreShaIns: // Brw_ADMI_SHARE_INS
case ActFrmCreDocCtr: // Brw_ADMI_DOCUM_CTR
case ActFrmCreShaCtr: // Brw_ADMI_SHARE_CTR
case ActFrmCreDocDeg: // Brw_ADMI_DOCUM_DEG
case ActFrmCreShaDeg: // Brw_ADMI_SHARE_DEG
case ActFrmCreDocCrs: // Brw_ADMI_DOCUM_CRS
case ActFrmCreDocGrp: // Brw_ADMI_DOCUM_GRP
case ActFrmCreTchCrs: // Brw_ADMI_TEACH_CRS
case ActFrmCreTchGrp: // Brw_ADMI_TEACH_GRP
case ActFrmCreShaCrs: // Brw_ADMI_SHARE_CRS
case ActFrmCreShaGrp: // Brw_ADMI_SHARE_GRP
case ActFrmCreAsgUsr: // Brw_ADMI_ASSIG_USR
case ActFrmCreAsgCrs: // Brw_ADMI_ASSIG_CRS
case ActFrmCreWrkUsr: // Brw_ADMI_WORKS_USR
case ActFrmCreWrkCrs: // Brw_ADMI_WORKS_CRS
case ActFrmCreMrkCrs: // Brw_ADMI_MARKS_CRS
case ActFrmCreMrkGrp: // Brw_ADMI_MARKS_GRP
case ActFrmCreBrf: // Brw_ADMI_BRIEF_USR
fprintf (Gbl.F.Out,"\n",
Cfg_URL_SWAD_PUBLIC);
break;
default:
break;
}
/* Redirect to correct language */
if (Gbl.Usrs.Me.Logged && // I am logged
Gbl.Usrs.Me.UsrDat.Prefs.Language != Txt_Current_CGI_SWAD_Language) // My language != current language
{
if (Gbl.Action.Act == ActLogIn || // Regular log in
Gbl.Action.Act == ActLogInNew) // Log in when checking account
Lay_WriteRedirToMyLangOnLogIn ();
else if (Gbl.Action.Act == ActLogInUsrAgd) // Log in to view another user's public agenda
Lay_WriteRedirToMyLangOnViewUsrAgd ();
}
/* Write initial scripts depending on the action */
Lay_WriteScripts ();
fprintf (Gbl.F.Out,"\n");
/***** HTML body *****/
if (Act_Actions[Gbl.Action.Act].BrowserWindow == Act_THIS_WINDOW)
fprintf (Gbl.F.Out,"\n"
"
"
""
"
"
"
"
"
",
Gbl.Prefs.IconsURL);
else
{
fprintf (Gbl.F.Out,"\n");
Gbl.Layout.WritingHTMLStart = false;
Gbl.Layout.HTMLStartWritten =
Gbl.Layout.DivsEndWritten = true;
return;
}
/***** Start box that contains the whole page except the foot *****/
fprintf (Gbl.F.Out,"
");
/***** Header of layout *****/
Lay_WritePageTopHeading ();
/***** 3rd. row (tabs) *****/
Tab_DrawTabs ();
/***** 4th row: main zone *****/
fprintf (Gbl.F.Out,"
");
/* Left column */
if (Gbl.Prefs.SideCols & Lay_SHOW_LEFT_COLUMN) // Left column visible
{
fprintf (Gbl.F.Out,"");
}
/* Right column */
// 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.
if (Gbl.Prefs.SideCols & Lay_SHOW_RIGHT_COLUMN) // Right column visible
{
fprintf (Gbl.F.Out,"");
}
/* Central (main) column */
switch (Gbl.Prefs.SideCols)
{
case 0:
fprintf (Gbl.F.Out,"
");
break;
case Lay_SHOW_LEFT_COLUMN:
fprintf (Gbl.F.Out,"
");
break;
case Lay_SHOW_RIGHT_COLUMN:
fprintf (Gbl.F.Out,"
");
break;
case (Lay_SHOW_LEFT_COLUMN | Lay_SHOW_RIGHT_COLUMN):
fprintf (Gbl.F.Out,"
");
break;
}
fprintf (Gbl.F.Out,"
",
The_TabOnBgColors[Gbl.Prefs.Theme]);
/* Layout with horizontal or vertical menu */
fprintf (Gbl.F.Out,"
",LayoutMainZone[Gbl.Prefs.Menu]);
/* Menu */
Mnu_WriteMenuThisTab ();
/* Start canvas: main zone for actions output */
fprintf (Gbl.F.Out,"
");
/* If it is mandatory to read any information about course */
if (Gbl.CurrentCrs.Info.ShowMsgMustBeRead)
Inf_WriteMsgYouMustReadInfo ();
/* Write title of the current action */
if (Gbl.Prefs.Menu == Mnu_MENU_VERTICAL &&
Act_Actions[Act_Actions[Gbl.Action.Act].SuperAction].IndexInMenu >= 0)
Lay_WriteTitleAction ();
Gbl.Layout.WritingHTMLStart = false;
Gbl.Layout.HTMLStartWritten = true;
/* Write new year greeting */
if (Gbl.Action.Act == ActLogIn ||
Gbl.Action.Act == ActLogInNew ||
Gbl.Action.Act == ActLogInLan)
if (Gbl.Now.Date.Month == 1 &&
Gbl.Now.Date.Day == 1)
{
fprintf (Gbl.F.Out,"
");
}
/* Write message indicating number of clicks allowed before sending my photo */
Usr_InformAboutNumClicksBeforePhoto ();
}
/*****************************************************************************/
/************************ Write the end of the page **************************/
/*****************************************************************************/
static void Lay_WriteEndOfPage (void)
{
extern struct Act_Actions Act_Actions[Act_NUM_ACTIONS];
if (!Gbl.Layout.DivsEndWritten)
{
/***** End of central part of main zone *****/
fprintf (Gbl.F.Out,"
" // Canvas (main zone to output content of the current action)
"
" // Layout with horizontal or vertical menu
"
"); // main_zone_central_container
/***** Write page footer *****/
if (Act_Actions[Gbl.Action.Act].BrowserWindow == Act_THIS_WINDOW)
Lay_WriteFootFromHTMLFile ();
/***** End of main zone and page *****/
fprintf (Gbl.F.Out,"
" // main_zone_central
"
" // main_zone
"
\n"); // whole_page_* (box that contains the whole page except the foot)
Gbl.Layout.DivsEndWritten = true;
}
}
/*****************************************************************************/
/************************* Write the title of the page ***********************/
/*****************************************************************************/
static void Lay_WritePageTitle (void)
{
extern const char *Txt_TAGLINE;
fprintf (Gbl.F.Out,"");
if (Gbl.Params.GetMethod && Gbl.CurrentDeg.Deg.DegCod > 0)
{
fprintf (Gbl.F.Out,"%s > %s",
Cfg_PLATFORM_SHORT_NAME,
Gbl.CurrentDeg.Deg.ShrtName);
if (Gbl.CurrentCrs.Crs.CrsCod > 0)
fprintf (Gbl.F.Out," > %s",
Gbl.CurrentCrs.Crs.ShrtName);
}
else
fprintf (Gbl.F.Out,"%s: %s",
Cfg_PLATFORM_SHORT_NAME,Txt_TAGLINE);
fprintf (Gbl.F.Out,"\n");
}
/*****************************************************************************/
/************* Write script and meta to redirect to my language **************/
/*****************************************************************************/
static void Lay_WriteRedirToMyLangOnLogIn (void)
{
extern struct Act_Actions Act_Actions[Act_NUM_ACTIONS];
extern const char *Txt_STR_LANG_ID[1 + Txt_NUM_LANGUAGES];
fprintf (Gbl.F.Out,"",
Cfg_URL_SWAD_CGI,
Txt_STR_LANG_ID[Gbl.Usrs.Me.UsrDat.Prefs.Language],
Act_Actions[ActLogInLan].ActCod,
Gbl.Session.Id);
}
static void Lay_WriteRedirToMyLangOnViewUsrAgd (void)
{
extern struct Act_Actions Act_Actions[Act_NUM_ACTIONS];
extern const char *Txt_STR_LANG_ID[1 + Txt_NUM_LANGUAGES];
fprintf (Gbl.F.Out,"",
Cfg_URL_SWAD_CGI,
Txt_STR_LANG_ID[Gbl.Usrs.Me.UsrDat.Prefs.Language],
Act_Actions[ActLogInUsrAgdLan].ActCod,
Gbl.Session.Id,
Gbl.Usrs.Other.UsrDat.Nickname);
}
/*****************************************************************************/
/************ Write some scripts depending on the current action *************/
/*****************************************************************************/
static void Lay_WriteScripts (void)
{
extern struct Act_Actions Act_Actions[Act_NUM_ACTIONS];
extern const char *Txt_DAYS_CAPS[7];
extern const char *Txt_DAYS_SMALL[7];
extern const char *Txt_Exam_of_X;
unsigned DayOfWeek; /* 0, 1, 2, 3, 4, 5, 6 */
unsigned NumHld;
unsigned NumExamAnnouncement; // Number of exam announcement
/***** General scripts for swad *****/
fprintf (Gbl.F.Out,"\n",
Cfg_URL_SWAD_PUBLIC,JS_FILE);
/***** Script for MathJax *****/
Lay_WriteScriptMathJax ();
/***** Scripts used only in main window *****/
if (Act_Actions[Gbl.Action.Act].BrowserWindow == Act_THIS_WINDOW)
{
Lay_WriteScriptInit ();
Lay_WriteScriptParamsAJAX ();
}
/***** Prepare script to draw months *****/
if ((Gbl.Prefs.SideCols & Lay_SHOW_LEFT_COLUMN) || // Left column visible
Gbl.Action.Act == ActSeeCalIns || Gbl.Action.Act == ActPrnCalIns ||
Gbl.Action.Act == ActSeeCalCtr || Gbl.Action.Act == ActPrnCalCtr ||
Gbl.Action.Act == ActSeeCalDeg || Gbl.Action.Act == ActPrnCalDeg ||
Gbl.Action.Act == ActSeeCalCrs || Gbl.Action.Act == ActPrnCalCrs)
{
/***** Get list of holidays *****/
if (!Gbl.Hlds.LstIsRead)
{
Gbl.Hlds.SelectedOrder = Hld_ORDER_BY_START_DATE;
Hld_GetListHolidays ();
}
/***** Create list of calls for examination *****/
Exa_CreateListDatesOfExamAnnouncements ();
/***** Write script to initialize variables used to draw months *****/
fprintf (Gbl.F.Out,"\n");
/***** Free list of dates of exam announcements *****/
Exa_FreeListExamAnnouncements ();
}
/***** Scripts depending on action *****/
switch (Gbl.Action.Act)
{
/***** 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
case ActFrmCreDocIns: // Brw_ADMI_DOCUM_INS
case ActFrmCreShaIns: // Brw_ADMI_SHARE_INS
case ActFrmCreDocCtr: // Brw_ADMI_DOCUM_CTR
case ActFrmCreShaCtr: // Brw_ADMI_SHARE_CTR
case ActFrmCreDocDeg: // Brw_ADMI_DOCUM_DEG
case ActFrmCreShaDeg: // Brw_ADMI_SHARE_DEG
case ActFrmCreDocCrs: // Brw_ADMI_DOCUM_CRS
case ActFrmCreDocGrp: // Brw_ADMI_DOCUM_GRP
case ActFrmCreTchCrs: // Brw_ADMI_TEACH_CRS
case ActFrmCreTchGrp: // Brw_ADMI_TEACH_GRP
case ActFrmCreShaCrs: // Brw_ADMI_SHARE_CRS
case ActFrmCreShaGrp: // Brw_ADMI_SHARE_GRP
case ActFrmCreAsgUsr: // Brw_ADMI_ASSIG_USR
case ActFrmCreAsgCrs: // Brw_ADMI_ASSIG_CRS
case ActFrmCreWrkUsr: // Brw_ADMI_WORKS_USR
case ActFrmCreWrkCrs: // Brw_ADMI_WORKS_CRS
case ActFrmCreMrkCrs: // Brw_ADMI_MARKS_CRS
case ActFrmCreMrkGrp: // Brw_ADMI_MARKS_GRP
case ActFrmCreBrf: // Brw_ADMI_BRIEF_USR
// Use charset="windows-1252" to force error messages in windows-1252 (default is UTF-8)
fprintf (Gbl.F.Out,"\n",
Cfg_URL_SWAD_PUBLIC);
Lay_WriteScriptCustomDropzone ();
break;
case ActReqAccGbl:
case ActSeeAccGbl:
case ActReqAccCrs:
case ActSeeAccCrs:
case ActSeeAllStaCrs:
fprintf (Gbl.F.Out,"\n",
Cfg_URL_SWAD_PUBLIC);
break;
default:
break;
}
/***** Script for Google Analytics *****/
fprintf (Gbl.F.Out,"%s",Cfg_GOOGLE_ANALYTICS);
}
// Change page title
//function changeTitle(title) {
// document.title = title;
//}
/*****************************************************************************/
/************ Write some scripts depending on the current action *************/
/*****************************************************************************/
static void Lay_WriteScriptMathJax (void)
{
// MathJax configuration
/*
fprintf (Gbl.F.Out,"");
*/
#ifdef Cfg_MATHJAX_LOCAL
// Use the local copy of MathJax
fprintf (Gbl.F.Out,"\n",
Cfg_URL_SWAD_PUBLIC);
#else
// Use the MathJax Content Delivery Network (CDN)
fprintf (Gbl.F.Out,"\n");
#endif
}
/*****************************************************************************/
/******* Write script with init function executed after loading page *********/
/*****************************************************************************/
static void Lay_WriteScriptInit (void)
{
extern const char *Txt_STR_LANG_ID[1 + Txt_NUM_LANGUAGES];
fprintf (Gbl.F.Out,"\n");
}
/*****************************************************************************/
/************** Write script to set parameters needed by AJAX ****************/
/*****************************************************************************/
static void Lay_WriteScriptParamsAJAX (void)
{
extern struct Act_Actions Act_Actions[Act_NUM_ACTIONS];
/***** Start script *****/
fprintf (Gbl.F.Out,"\n",
Gbl.Session.Id,
Gbl.CurrentCrs.Crs.CrsCod);
}
/*****************************************************************************/
/******* 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
fprintf (Gbl.F.Out,"\n",
(unsigned long) (Fil_MAX_FILE_SIZE / (1024ULL * 1024ULL) - 1));
}
/*****************************************************************************/
/************************ Write top heading of the page **********************/
/*****************************************************************************/
static void Lay_WritePageTopHeading (void)
{
extern const char *The_ClassHead[The_NUM_THEMES];
extern const char *The_ClassTagline[The_NUM_THEMES];
extern const char *Txt_System;
extern const char *Txt_TAGLINE;
extern const char *Txt_TAGLINE_BR;
const char *ClassHeadRow1[The_NUM_THEMES] =
{
"HEAD_ROW_1_WHITE", // The_THEME_WHITE
"HEAD_ROW_1_GREY", // The_THEME_GREY
"HEAD_ROW_1_BLUE", // The_THEME_BLUE
"HEAD_ROW_1_YELLOW", // The_THEME_YELLOW
};
const char *ClassHeadRow2[The_NUM_THEMES] =
{
"HEAD_ROW_2_WHITE", // The_THEME_WHITE
"HEAD_ROW_2_GREY", // The_THEME_GREY
"HEAD_ROW_2_BLUE", // The_THEME_BLUE
"HEAD_ROW_2_YELLOW", // The_THEME_YELLOW
};
/***** Start header *****/
fprintf (Gbl.F.Out,"");
/***** 1st. row *****/
/* Start 1st. row */
fprintf (Gbl.F.Out,"
", // head_row_1_tagline
Txt_TAGLINE_BR);
/* End form to go to home page */
Act_FormEnd ();
Sch_PutFormToSearchInPageTopHeading ();
fprintf (Gbl.F.Out,"
"); // head_row_1_left
/* 1st. row, 3rd. column: logged user or language selection,
and link to open/close session */
fprintf (Gbl.F.Out,"
"); // Used for AJAX based refresh
}
/***** Number of connected users in the current course *****/
if (Gbl.CurrentCrs.Crs.CrsCod > 0) // There is a course selected
{
fprintf (Gbl.F.Out,"
",
Txt_If_you_have_an_Android_device_try_SWADroid,
Gbl.Prefs.IconsURL);
}
/*****************************************************************************/
/**************** Show an icon with a link in contextual menu ****************/
/*****************************************************************************/
void Lay_PutContextualLink (Act_Action_t NextAction,const char *Anchor,
void (*FuncParams) (),
const char *Icon,
const char *Title,const char *Text,
const char *OnSubmit)
{
extern const char *The_ClassFormBold[The_NUM_THEMES];
/***** Separator *****/
if (Text)
fprintf (Gbl.F.Out," "); // This space is necessary to enable
// jumping to the next line on narrow screens
/***** Start form *****/
Act_FormStartAnchor (NextAction,Anchor);
if (FuncParams)
FuncParams ();
/***** Put icon with link *****/
Ico_PutIconLink (Icon,Title,Text,
Text ? The_ClassFormBold[Gbl.Prefs.Theme] :
NULL,
OnSubmit);
/***** End form *****/
Act_FormEnd ();
/***** Separator *****/
if (Text)
fprintf (Gbl.F.Out," "); // This space is necessary to enable
// jumping to the next line on narrow screens
}
/*****************************************************************************/
/******************** Show a checkbox in contextual menu *********************/
/*****************************************************************************/
void Lay_PutContextualCheckbox (Act_Action_t NextAction,
void (*FuncParams) (),
const char *CheckboxName,
bool Checked,bool Disabled,
const char *Title,const char *Text)
{
extern const char *The_ClassFormBold[The_NUM_THEMES];
/***** Separator *****/
if (Text)
fprintf (Gbl.F.Out," "); // This space is necessary to enable
// jumping to the next line on narrow screens
/***** Start form *****/
Act_FormStart (NextAction);
if (FuncParams)
FuncParams ();
/***** Start container and label *****/
fprintf (Gbl.F.Out,"
"
""
"
");
/***** End form *****/
Act_FormEnd ();
/***** Separator *****/
if (Text)
fprintf (Gbl.F.Out," "); // This space is necessary to enable
// jumping to the next line on narrow screens
}
/*****************************************************************************/
/****************************** Start/end section ****************************/
/*****************************************************************************/
void Lay_StartSection (const char *SectionId)
{
fprintf (Gbl.F.Out,"",SectionId);
}
void Lay_EndSection (void)
{
fprintf (Gbl.F.Out,"");
}
/*****************************************************************************/
/******* Write error message, close files, remove lock file, and exit ********/
/*****************************************************************************/
void Lay_ShowErrorAndExit (const char *Txt)
{
extern struct Act_Actions Act_Actions[Act_NUM_ACTIONS];
/***** Unlock tables if locked *****/
if (Gbl.DB.LockedTables)
{
Gbl.DB.LockedTables = false;
mysql_query (&Gbl.mysql,"UNLOCK TABLES");
}
if (!Gbl.WebService.IsWebService)
{
/****** If start of page is not written yet, do it now ******/
if (!Gbl.Layout.HTMLStartWritten)
Lay_WriteStartOfPage ();
/***** Write possible error message *****/
if (Txt)
Ale_ShowAlert (Ale_ERROR,Txt);
/***** Finish the page, except and *****/
Lay_WriteEndOfPage ();
}
/***** Free memory and close all the open files *****/
Gbl_Cleanup ();
/***** Page is generated (except and