swad-core/swad_country.c

1823 lines
63 KiB
C
Raw Permalink Normal View History

2014-12-01 23:55:08 +01:00
// swad_country.c: countries
/*
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-2024 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 ***********************************/
/*****************************************************************************/
2018-10-20 01:07:58 +02:00
#define _GNU_SOURCE // For asprintf
2019-12-29 19:07:59 +01:00
#include <stdbool.h> // For boolean type
2019-12-29 12:39:00 +01:00
#include <stddef.h> // For NULL
2018-10-20 01:07:58 +02:00
#include <stdio.h> // For asprintf
2020-01-03 22:16:51 +01:00
#include <stdlib.h> // For free
2014-12-01 23:55:08 +01:00
#include <string.h> // For string functions
#include "swad_action_list.h"
#include "swad_alert.h"
#include "swad_box.h"
2019-12-29 19:07:59 +01:00
#include "swad_country_config.h"
#include "swad_country_database.h"
2014-12-01 23:55:08 +01:00
#include "swad_database.h"
#include "swad_error.h"
2020-04-14 17:15:17 +02:00
#include "swad_figure.h"
2020-05-02 13:39:59 +02:00
#include "swad_figure_cache.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"
2021-02-11 22:57:09 +01:00
#include "swad_hierarchy.h"
#include "swad_hierarchy_type.h"
2019-10-23 19:05:05 +02:00
#include "swad_HTML.h"
#include "swad_parameter.h"
#include "swad_parameter_code.h"
2020-04-14 17:15:17 +02:00
#include "swad_survey.h"
#include "swad_www.h"
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/***************************** Private variables *****************************/
/*****************************************************************************/
static struct Hie_Node *Cty_EditingCty = NULL; // Static variable to keep the country being edited
2019-12-23 22:13:02 +01:00
long Cty_CurrentCtyCod = -1L; // Used as parameter in contextual links
2019-04-08 21:10:12 +02:00
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
2017-02-28 00:59:01 +01:00
static void Cty_PutHeadCountriesForSeeing (bool OrderSelectable);
static void Cty_ListOneCountryForSeeing (struct Hie_Node *Cty,unsigned NumCty);
2017-02-28 00:59:01 +01:00
2020-04-08 13:40:21 +02:00
static void Cty_PutIconsListingCountries (__attribute__((unused)) void *Args);
2016-03-16 22:40:35 +01:00
static void Cty_PutIconToEditCountries (void);
2016-03-16 12:11:59 +01:00
2019-04-08 21:10:12 +02:00
static void Cty_EditCountriesInternal (void);
2020-04-08 13:40:21 +02:00
static void Cty_PutIconsEditingCountries (__attribute__((unused)) void *Args);
2017-04-30 20:20:25 +02:00
static void Cty_GetFullListOfCountries (void);
2014-12-01 23:55:08 +01:00
static void Cty_ListCountriesForEdition (void);
static void Cty_PutParOthCtyCod (void *CtyCod);
2016-10-23 19:40:14 +02:00
static void Cty_UpdateCtyName (long CtyCod,const char *FldName,const char *NewCtyName);
2017-03-10 02:40:01 +01:00
2019-04-08 21:10:12 +02:00
static void Cty_ShowAlertAndButtonToGoToCty (void);
static void Cty_PutParGoToCty (void *CtyCod);
2019-04-08 21:10:12 +02:00
2014-12-01 23:55:08 +01:00
static void Cty_PutFormToCreateCountry (void);
2017-02-28 00:59:01 +01:00
static void Cty_PutHeadCountriesForEdition (void);
2014-12-01 23:55:08 +01:00
2019-04-08 21:10:12 +02:00
static void Cty_EditingCountryConstructor (void);
static void Cty_EditingCountryDestructor (void);
2019-04-04 11:22:08 +02:00
static void Cty_FormToGoToMap (struct Hie_Node *Cty);
2020-01-14 13:30:18 +01:00
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/***************** List countries with pending institutions ******************/
/*****************************************************************************/
void Cty_SeeCtyWithPendingInss (void)
{
extern bool (*Hie_GetDataByCod[Hie_NUM_LEVELS]) (struct Hie_Node *Node);
2020-01-30 20:47:00 +01:00
extern const char *Hlp_SYSTEM_Pending;
2014-12-01 23:55:08 +01:00
extern const char *Txt_Countries_with_pending_institutions;
extern const char *Txt_HIERARCHY_SINGUL_Abc[Hie_NUM_LEVELS];
2015-12-09 19:51:17 +01:00
extern const char *Txt_Institutions_ABBREVIATION;
2014-12-01 23:55:08 +01:00
extern const char *Txt_There_are_no_countries_with_requests_for_institutions_to_be_confirmed;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumCtys;
unsigned NumCty;
struct Hie_Node Cty;
2015-09-04 19:26:08 +02:00
const char *BgColor;
2014-12-01 23:55:08 +01:00
/***** Trivial check: only system admins can see countries with pending institutions *****/
2017-06-04 18:18:54 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
2014-12-01 23:55:08 +01:00
{
2015-04-07 21:44:24 +02:00
case Rol_SYS_ADM:
2014-12-01 23:55:08 +01:00
break;
default: // Forbidden for other users
return;
}
/***** Get countries with pending institutions *****/
if ((NumCtys = Cty_DB_GetCtysWithPendingInss (&mysql_res)))
2014-12-01 23:55:08 +01:00
{
2019-10-26 02:19:42 +02:00
/***** Begin box and table *****/
Box_BoxTableBegin (Txt_Countries_with_pending_institutions,NULL,NULL,
2020-01-30 20:47:00 +01:00
Hlp_SYSTEM_Pending,Box_NOT_CLOSABLE,2);
2017-06-12 14:16:33 +02:00
/***** Write heading *****/
HTM_TR_Begin (NULL);
HTM_TH (Txt_HIERARCHY_SINGUL_Abc[Hie_CTY] ,HTM_HEAD_LEFT );
HTM_TH (Txt_Institutions_ABBREVIATION,HTM_HEAD_RIGHT);
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
/***** List the countries *****/
for (NumCty = 0, The_ResetRowColor ();
NumCty < NumCtys;
NumCty++, The_ChangeRowColor ())
{
/* Get next country */
row = mysql_fetch_row (mysql_res);
/* Get country code (row[0]) */
Cty.HieCod = Str_ConvertStrCodToLongCod (row[0]);
BgColor = (Cty.HieCod == Gbl.Hierarchy.Node[Hie_CTY].HieCod) ? "BG_HIGHLIGHT" :
The_GetColorRows ();
/* Get data of country */
Hie_GetDataByCod[Hie_CTY] (&Cty);
/* Begin row for this country */
HTM_TR_Begin (NULL);
/* Country map */
HTM_TD_Begin ("class=\"LM DAT_%s %s\"",
The_GetSuffix (),BgColor);
Cty_DrawCountryMapAndNameWithLink (&Cty,ActSeeIns,
"COUNTRY_SMALL",
"COUNTRY_MAP_SMALL");
HTM_TD_End ();
/* Number of pending institutions (row[1]) */
HTM_TD_Begin ("class=\"RM DAT_%s %s\"",
The_GetSuffix (),BgColor);
HTM_Txt (row[1]);
HTM_TD_End ();
/* End row for this country */
HTM_TR_End ();
}
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** End table and box *****/
2019-11-25 23:18:08 +01:00
Box_BoxTableEnd ();
2014-12-01 23:55:08 +01:00
}
else
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_INFO,Txt_There_are_no_countries_with_requests_for_institutions_to_be_confirmed);
2014-12-01 23:55:08 +01:00
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
/****************************** List all countries ***************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
void Cty_ListCountries (void)
{
Cty_ListCountries1 ();
Cty_ListCountries2 ();
}
/*****************************************************************************/
/****************************** List all countries ***************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
void Cty_ListCountries1 (void)
{
/***** Get parameter with the type of order in the list of countries *****/
Gbl.Hierarchy.List[Hie_CTY].SelectedOrder = Hie_GetParHieOrder ();
2014-12-01 23:55:08 +01:00
/***** Get list of countries *****/
2020-01-07 22:07:06 +01:00
Cty_GetFullListOfCountries ();
2014-12-01 23:55:08 +01:00
}
void Cty_ListCountries2 (void)
{
2016-11-13 14:55:01 +01:00
extern const char *Hlp_SYSTEM_Countries;
extern const char *Txt_HIERARCHY_PLURAL_Abc[Hie_NUM_LEVELS];
2014-12-01 23:55:08 +01:00
extern const char *Txt_Other_countries;
extern const char *Txt_Country_unspecified;
unsigned NumCty;
2018-11-16 01:05:56 +01:00
/***** Write menu to select country *****/
Hie_WriteMenuHierarchy ();
/***** Div for Google Geochart *****/
if (Gbl.Action.Act == ActSeeCty)
{
HTM_DIV_Begin ("id=\"chart_div\"");
HTM_DIV_End ();
}
2019-10-26 02:19:42 +02:00
/***** Begin box and table *****/
Box_BoxBegin (Txt_HIERARCHY_PLURAL_Abc[Hie_CTY],
Cty_PutIconsListingCountries,NULL,
Hlp_SYSTEM_Countries,Box_NOT_CLOSABLE);
HTM_TABLE_Begin ("TBL_SCROLL");
2017-06-12 14:16:33 +02:00
/***** Heading *****/
Cty_PutHeadCountriesForSeeing (true); // Order selectable
2014-12-01 23:55:08 +01:00
/***** Write all countries and their number of users and institutions *****/
for (NumCty = 0;
NumCty < Gbl.Hierarchy.List[Hie_SYS].Num;
NumCty++)
Cty_ListOneCountryForSeeing (&Gbl.Hierarchy.List[Hie_SYS].Lst[NumCty],NumCty + 1);
2014-12-01 23:55:08 +01:00
/***** Separation row *****/
HTM_TR_Begin (NULL);
HTM_TD_Begin ("colspan=\"8\" class=\"CM DAT_%s\"",
The_GetSuffix ());
HTM_NBSP ();
HTM_TD_End ();
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
/***** Write users and institutions in other countries *****/
HTM_TR_Begin (NULL);
2019-10-07 00:05:24 +02:00
HTM_TD_Empty (1);
HTM_TD_Begin ("class=\"LM DAT_%s\"",The_GetSuffix ());
HTM_Txt (Txt_Other_countries);
HTM_TD_End ();
/* Number of users who claim to belong to another country */
HTM_TD_Unsigned (Cty_GetCachedNumUsrsWhoClaimToBelongToAnotherCty ());
/* Number of institutions in other countries */
HTM_TD_Unsigned (Hie_GetCachedNumNodesInHieLvl (Hie_INS, // Number of institutions...
Hie_CTY,0)); // ...in other countries
/* Number of centers in other countries */
HTM_TD_Unsigned (Hie_GetCachedNumNodesInHieLvl (Hie_CTR, // Number of centers...
Hie_CTY,0)); // ...in other countries
/* Number of degrees in other countries */
HTM_TD_Unsigned (Hie_GetCachedNumNodesInHieLvl (Hie_DEG, // Number of degrees...
Hie_CTY,0)); // ...in other countries
/* Number of courses in other countries */
HTM_TD_Unsigned (Hie_GetCachedNumNodesInHieLvl (Hie_CRS, // Number of courses...
Hie_CTY,0)); // ...in other countries
/* Number of users in courses of other countries */
HTM_TD_Unsigned (Enr_GetCachedNumUsrsInCrss (Hie_CTY,0,
1 << Rol_STD |
1 << Rol_NET |
1 << Rol_TCH)); // Any user
2019-10-07 00:05:24 +02:00
HTM_TR_End ();
2015-11-17 01:22:57 +01:00
/***** Write users and institutions with unknown country *****/
HTM_TR_Begin (NULL);
2019-10-07 00:05:24 +02:00
HTM_TD_Empty (1);
HTM_TD_Txt_Left (Txt_Country_unspecified);
2019-10-07 00:05:24 +02:00
/* Number of users who do not claim to belong to any country */
HTM_TD_Unsigned (Cty_GetCachedNumUsrsWhoDontClaimToBelongToAnyCty ());
2019-10-07 00:05:24 +02:00
/* Number of institutions with unknown country */
HTM_TD_Unsigned (Hie_GetCachedNumNodesInHieLvl (Hie_INS, // Number of institutions...
Hie_CTY,-1L)); // ...with unknown country
2019-10-07 00:05:24 +02:00
/* Number of centers with unknown country */
HTM_TD_Unsigned (Hie_GetCachedNumNodesInHieLvl (Hie_CTR, // Number of centers...
Hie_CTY,-1L)); // ...with unknown country
2019-10-07 00:05:24 +02:00
/* Number of degrees with unknown country */
HTM_TD_Unsigned (Hie_GetCachedNumNodesInHieLvl (Hie_DEG, // Number of degrees...
Hie_CTY,-1L)); // ...with unknown country
2019-10-07 00:05:24 +02:00
/* Number of courses with unknown country */
HTM_TD_Unsigned (Hie_GetCachedNumNodesInHieLvl (Hie_CRS, // Number of courses...
Hie_CTY,-1L)); // ...with unknown country
2019-10-07 00:05:24 +02:00
HTM_TD_Unsigned (0);
2019-10-07 00:05:24 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** End table and box *****/
HTM_TABLE_End ();
Box_BoxEnd ();
2014-12-01 23:55:08 +01:00
/***** Free list of countries *****/
Hie_FreeList (Hie_SYS);
2014-12-01 23:55:08 +01:00
}
2017-02-28 00:59:01 +01:00
/*****************************************************************************/
/******************* Write header with fields of a country *******************/
/*****************************************************************************/
static void Cty_PutHeadCountriesForSeeing (bool OrderSelectable)
{
extern const char *Txt_COUNTRIES_HELP_ORDER[2];
extern const char *Txt_COUNTRIES_ORDER[2];
extern const char *Txt_Institutions_ABBREVIATION;
extern const char *Txt_Centers_ABBREVIATION;
2017-02-28 00:59:01 +01:00
extern const char *Txt_Degrees_ABBREVIATION;
extern const char *Txt_Courses_ABBREVIATION;
2017-05-30 21:43:05 +02:00
extern const char *Txt_ROLES_PLURAL_BRIEF_Abc[Rol_NUM_ROLES];
Hie_Order_t Order;
static HTM_HeadAlign Align[Hie_NUM_ORDERS] =
{
[Hie_ORDER_BY_NAME ] = HTM_HEAD_LEFT,
[Hie_ORDER_BY_NUM_USRS] = HTM_HEAD_RIGHT
};
2017-02-28 00:59:01 +01:00
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-07 00:05:24 +02:00
HTM_TH_Empty (1);
for (Order = (Hie_Order_t) 0;
Order <= (Hie_Order_t) (Hie_NUM_ORDERS - 1);
Order++)
2017-02-28 00:59:01 +01:00
{
HTM_TH_Begin (Align[Order]);
if (OrderSelectable)
{
Frm_BeginForm (ActSeeCty);
Par_PutParUnsigned (NULL,"Order",(unsigned) Order);
HTM_BUTTON_Submit_Begin (Txt_COUNTRIES_HELP_ORDER[Order],
"class=\"BT_LINK\"");
if (Order == Gbl.Hierarchy.List[Hie_SYS].SelectedOrder)
HTM_U_Begin ();
}
HTM_Txt (Txt_COUNTRIES_ORDER[Order]);
if (OrderSelectable)
{
if (Order == Gbl.Hierarchy.List[Hie_SYS].SelectedOrder)
HTM_U_End ();
HTM_BUTTON_End ();
Frm_EndForm ();
}
HTM_TH_End ();
2017-02-28 00:59:01 +01:00
}
HTM_TH (Txt_Institutions_ABBREVIATION,HTM_HEAD_RIGHT);
HTM_TH (Txt_Centers_ABBREVIATION ,HTM_HEAD_RIGHT);
HTM_TH (Txt_Degrees_ABBREVIATION ,HTM_HEAD_RIGHT);
HTM_TH (Txt_Courses_ABBREVIATION ,HTM_HEAD_RIGHT);
HTM_TH_Begin (HTM_HEAD_RIGHT);
HTM_TxtF ("%s+",Txt_ROLES_PLURAL_BRIEF_Abc[Rol_TCH]);
HTM_BR ();
HTM_Txt (Txt_ROLES_PLURAL_BRIEF_Abc[Rol_STD]);
HTM_TH_End ();
2019-10-07 00:05:24 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2017-02-28 00:59:01 +01:00
}
/*****************************************************************************/
/************************ List one country for seeing ************************/
/*****************************************************************************/
static void Cty_ListOneCountryForSeeing (struct Hie_Node *Cty,unsigned NumCty)
2017-02-28 00:59:01 +01:00
{
const char *BgColor;
BgColor = (Cty->HieCod == Gbl.Hierarchy.Node[Hie_CTY].HieCod) ? "BG_HIGHLIGHT" :
The_GetColorRows ();
2017-02-28 00:59:01 +01:00
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-07 00:05:24 +02:00
/***** Number of country in this list *****/
HTM_TD_Begin ("class=\"RM DAT_%s %s\"",
The_GetSuffix (),BgColor);
HTM_Unsigned (NumCty);
HTM_TD_End ();
/***** Country map (and link to WWW if exists) *****/
HTM_TD_Begin ("class=\"LM DAT_STRONG_%s %s\"",
The_GetSuffix (),BgColor);
Cty_DrawCountryMapAndNameWithLink (Cty,ActSeeIns,
"COUNTRY_SMALL",
"COUNTRY_MAP_SMALL");
HTM_TD_End ();
/***** Number of users who claim to belong to this country *****/
HTM_TD_Begin ("class=\"RM DAT_%s %s\"",
The_GetSuffix (),BgColor);
HTM_Unsigned (Hie_GetCachedNumUsrsWhoClaimToBelongTo (Hie_CTY,Cty));
HTM_TD_End ();
/***** Number of institutions *****/
HTM_TD_Begin ("class=\"RM DAT_%s %s\"",
The_GetSuffix (),BgColor);
HTM_Unsigned (Hie_GetCachedNumNodesInHieLvl (Hie_INS, // Number of institutions...
Hie_CTY, // ...in country
Cty->HieCod));
HTM_TD_End ();
/***** Number of centers *****/
HTM_TD_Begin ("class=\"RM DAT_%s %s\"",
The_GetSuffix (),BgColor);
HTM_Unsigned (Hie_GetCachedNumNodesInHieLvl (Hie_CTR, // Number of centers...
Hie_CTY, // ...in country
Cty->HieCod));
HTM_TD_End ();
/***** Number of degrees *****/
HTM_TD_Begin ("class=\"RM DAT_%s %s\"",
The_GetSuffix (),BgColor);
HTM_Unsigned (Hie_GetCachedNumNodesInHieLvl (Hie_DEG, // Number of degrees...
Hie_CTY, // ...in country
Cty->HieCod));
HTM_TD_End ();
/***** Number of courses *****/
HTM_TD_Begin ("class=\"RM DAT_%s %s\"",
The_GetSuffix (),BgColor);
HTM_Unsigned (Hie_GetCachedNumNodesInHieLvl (Hie_CRS, // Number of courses...
Hie_CTY, // ...in country
Cty->HieCod));
HTM_TD_End ();
/***** Number of users in courses *****/
HTM_TD_Begin ("class=\"RM DAT_%s %s\"",
The_GetSuffix (),BgColor);
HTM_Unsigned (Enr_GetCachedNumUsrsInCrss (Hie_CTY,Cty->HieCod,
1 << Rol_STD |
1 << Rol_NET |
1 << Rol_TCH)); // Any user
HTM_TD_End ();
2019-10-07 00:05:24 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2017-02-28 00:59:01 +01:00
}
2016-11-06 21:19:25 +01:00
/*****************************************************************************/
/***************** Put contextual icons in list of countries *****************/
/*****************************************************************************/
2020-04-08 13:40:21 +02:00
static void Cty_PutIconsListingCountries (__attribute__((unused)) void *Args)
2016-11-06 21:19:25 +01:00
{
2020-04-08 13:40:21 +02:00
/***** Put icon to edit countries *****/
if (Cty_CheckIfICanEditCountries () == Usr_CAN)
2020-04-08 13:40:21 +02:00
Cty_PutIconToEditCountries ();
2016-11-06 21:19:25 +01:00
2020-04-08 13:40:21 +02:00
/***** Put icon to show a figure *****/
Fig_PutIconToShowFigure (Fig_HIERARCHY);
2016-11-06 21:19:25 +01:00
}
2019-12-29 19:07:59 +01:00
/*****************************************************************************/
/********************** Check if I can edit countries ************************/
/*****************************************************************************/
Usr_Can_t Cty_CheckIfICanEditCountries (void)
2019-12-29 19:07:59 +01:00
{
return (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM) ? Usr_CAN :
Usr_CAN_NOT;
2019-12-29 19:07:59 +01:00
}
2016-03-16 12:11:59 +01:00
/*****************************************************************************/
2018-11-15 22:33:21 +01:00
/************************ Put icon to edit countries *************************/
2016-03-16 12:11:59 +01:00
/*****************************************************************************/
2016-03-16 22:40:35 +01:00
static void Cty_PutIconToEditCountries (void)
2016-03-16 12:11:59 +01:00
{
Ico_PutContextualIconToEdit (ActEdiCty,NULL,NULL,NULL);
2016-03-16 12:11:59 +01:00
}
2015-01-16 01:28:42 +01:00
/*****************************************************************************/
2015-11-19 18:33:16 +01:00
/********************* Draw country map and name with link *******************/
2015-01-16 22:02:21 +01:00
/*****************************************************************************/
void Cty_DrawCountryMapAndNameWithLink (struct Hie_Node *Cty,Act_Action_t Action,
2017-03-04 19:46:46 +01:00
const char *ClassContainer,
const char *ClassMap)
2015-01-16 22:02:21 +01:00
{
2019-10-20 22:00:28 +02:00
/***** Begin form *****/
Frm_BeginFormGoTo (Action);
ParCod_PutPar (ParCod_Cty,Cty->HieCod);
2015-11-11 21:14:33 +01:00
/***** Begin container *****/
HTM_DIV_Begin ("class=\"%s\"",ClassContainer);
2015-11-11 21:14:33 +01:00
/***** Link to action *****/
HTM_BUTTON_Submit_Begin (Str_BuildGoToTitle (Cty->FullName),
"class=\"BT_LINK\"");
Str_FreeGoToTitle ();
/***** Draw country map *****/
Cty_DrawCountryMap (Cty,ClassMap);
/***** Write country name *****/
HTM_TxtF ("&nbsp;%s&nbsp;(%s)",Cty->FullName,Cty->ShrtName);
2015-11-11 21:14:33 +01:00
/***** End link *****/
HTM_BUTTON_End ();
2019-10-28 13:56:04 +01:00
/***** End container *****/
HTM_DIV_End ();
2015-11-11 21:14:33 +01:00
/***** End form *****/
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2020-01-14 13:30:18 +01:00
/***** Map *****/
Cty_FormToGoToMap (Cty);
2015-01-16 22:02:21 +01:00
}
/*****************************************************************************/
/***************************** Draw country map ******************************/
2015-01-16 01:28:42 +01:00
/*****************************************************************************/
void Cty_DrawCountryMap (const struct Hie_Node *Cty,const char *Class)
2015-01-16 01:28:42 +01:00
{
2019-10-30 22:31:03 +01:00
char *URL;
char *Icon;
2019-10-30 22:31:03 +01:00
2015-01-16 01:28:42 +01:00
/***** Draw country map *****/
2020-01-03 21:15:54 +01:00
if (Cty_CheckIfCountryPhotoExists (Cty))
2019-10-30 22:31:03 +01:00
{
if (asprintf (&URL,"%s/%s",Cfg_URL_ICON_COUNTRIES_PUBLIC,Cty->ShrtName) < 0)
Err_NotEnoughMemoryExit ();
if (asprintf (&Icon,"%s.png",Cty->ShrtName) < 0)
Err_NotEnoughMemoryExit ();
HTM_IMG (URL,Icon,Cty->FullName,"class=\"%s\"",Class);
free (Icon);
2019-11-06 19:45:20 +01:00
free (URL);
2019-10-30 22:31:03 +01:00
}
2015-11-11 21:14:33 +01:00
else
Ico_PutIcon ("tr16x16.gif",Ico_UNCHANGED,
Cty->FullName,Class);
2015-01-16 01:28:42 +01:00
}
2015-11-11 21:14:33 +01:00
/*****************************************************************************/
/*********************** Check if country map exists *************************/
/*****************************************************************************/
bool Cty_CheckIfCountryPhotoExists (const struct Hie_Node *Cty)
2015-11-11 21:14:33 +01:00
{
2017-01-28 15:58:46 +01:00
char PathMap[PATH_MAX + 1];
2015-11-11 21:14:33 +01:00
snprintf (PathMap,sizeof (PathMap),"%s/%s/%s.png",
2019-03-20 01:36:36 +01:00
Cfg_PATH_ICON_COUNTRIES_PUBLIC,
Cty->ShrtName,
Cty->ShrtName);
2015-11-11 21:14:33 +01:00
return Fil_CheckIfPathExists (PathMap);
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/********************** Write script for Google Geochart *********************/
/*****************************************************************************/
void Cty_WriteScriptGoogleGeochart (void)
{
extern const char *Txt_Country_NO_HTML;
extern const char *Txt_Users_NO_HTML;
extern const char *Txt_Institutions_NO_HTML;
unsigned NumCty;
2020-05-03 20:58:03 +02:00
unsigned NumUsrsCty;
unsigned NumInss;
2016-02-06 12:50:05 +01:00
unsigned MaxUsrsInCountry = 0;
2014-12-01 23:55:08 +01:00
unsigned NumCtysWithUsrs = 0;
/***** Write start of the script *****/
2019-11-01 17:35:26 +01:00
HTM_SCRIPT_Begin ("https://www.google.com/jsapi",NULL);
HTM_SCRIPT_End ();
HTM_SCRIPT_Begin (NULL,NULL);
HTM_TxtF (" google.load('visualization', '1', {'packages': ['geochart']});\n"
" google.setOnLoadCallback(drawRegionsMap);\n"
" function drawRegionsMap() {\n"
" var data = new google.visualization.DataTable();\n"
" data.addColumn('string', '%s');\n"
" data.addColumn('number', '%s');\n"
" data.addColumn('number', '%s');\n"
" data.addRows([\n",
Txt_Country_NO_HTML,
Txt_Users_NO_HTML,
Txt_Institutions_NO_HTML);
/***** Write all countries and their number of users and institutions *****/
for (NumCty = 0;
NumCty < Gbl.Hierarchy.List[Hie_SYS].Num;
NumCty++)
{
NumUsrsCty = Hie_GetCachedNumUsrsWhoClaimToBelongTo (Hie_CTY,
&Gbl.Hierarchy.List[Hie_SYS].Lst[NumCty]);
if (NumUsrsCty)
{
NumInss = Hie_GetCachedNumNodesInHieLvl (Hie_INS, // Number of institutions...
Hie_CTY, // ...in country
Gbl.Hierarchy.List[Hie_SYS].Lst[NumCty].HieCod);
/* Write data of this country */
HTM_TxtF (" ['%s', %u, %u],\n",
Gbl.Hierarchy.List[Hie_SYS].Lst[NumCty].ShrtName,
NumUsrsCty,NumInss);
if (NumUsrsCty > MaxUsrsInCountry)
MaxUsrsInCountry = NumUsrsCty;
NumCtysWithUsrs++;
}
}
2014-12-01 23:55:08 +01:00
/***** Write end of the script *****/
HTM_TxtF (" ]);\n"
" var options = {\n"
" width:300,\n"
" backgroundColor:'white',\n"
" datalessRegionColor:'white',\n"
" colorAxis:{colors:['#EAF1F4','#4D88A1'],minValue:0,maxValue:%u}};\n"
" var chart = new google.visualization.GeoChart(document.getElementById('chart_div'));\n"
" chart.draw(data, options);\n"
" };\n",
NumCtysWithUsrs ? MaxUsrsInCountry :
0);
2019-11-01 17:35:26 +01:00
HTM_SCRIPT_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******************** Put forms to edit institution types ********************/
/*****************************************************************************/
void Cty_EditCountries (void)
2019-04-08 21:10:12 +02:00
{
/***** Country constructor *****/
Cty_EditingCountryConstructor ();
/***** Edit countries *****/
Cty_EditCountriesInternal ();
/***** Country destructor *****/
Cty_EditingCountryDestructor ();
}
static void Cty_EditCountriesInternal (void)
2014-12-01 23:55:08 +01:00
{
2017-04-30 20:20:25 +02:00
extern const char *Hlp_SYSTEM_Countries;
extern const char *Txt_HIERARCHY_PLURAL_Abc[Hie_NUM_LEVELS];
2014-12-01 23:55:08 +01:00
/***** Get list of countries *****/
Gbl.Hierarchy.List[Hie_SYS].SelectedOrder = Hie_ORDER_BY_NAME;
2020-01-07 22:07:06 +01:00
Cty_GetFullListOfCountries ();
2014-12-01 23:55:08 +01:00
2018-11-16 01:05:56 +01:00
/***** Write menu to select country *****/
Hie_WriteMenuHierarchy ();
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
Box_BoxBegin (Txt_HIERARCHY_PLURAL_Abc[Hie_CTY],
2020-04-08 13:40:21 +02:00
Cty_PutIconsEditingCountries,NULL,
2017-06-12 15:03:29 +02:00
Hlp_SYSTEM_Countries,Box_NOT_CLOSABLE);
2014-12-01 23:55:08 +01:00
/***** Put a form to create a new country *****/
Cty_PutFormToCreateCountry ();
2014-12-01 23:55:08 +01:00
/***** Forms to edit current countries *****/
if (Gbl.Hierarchy.List[Hie_SYS].Num)
Cty_ListCountriesForEdition ();
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2017-04-30 20:20:25 +02:00
2014-12-01 23:55:08 +01:00
/***** Free list of countries *****/
Hie_FreeList (Hie_SYS);
2014-12-01 23:55:08 +01:00
}
2017-04-30 20:20:25 +02:00
/*****************************************************************************/
/*************** Put contextual icons in edition of countries ****************/
/*****************************************************************************/
2020-04-08 13:40:21 +02:00
static void Cty_PutIconsEditingCountries (__attribute__((unused)) void *Args)
2018-11-15 22:33:21 +01:00
{
2020-04-08 13:40:21 +02:00
/***** Put icon to view countries *****/
Ico_PutContextualIconToView (ActSeeCty,NULL,NULL,NULL);
2018-11-15 22:33:21 +01:00
2020-04-08 13:40:21 +02:00
/***** Put icon to show a figure *****/
Fig_PutIconToShowFigure (Fig_HIERARCHY);
2018-11-15 22:33:21 +01:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2020-01-07 22:07:06 +01:00
/********** Get basic list of countries ordered by name of country ***********/
/*****************************************************************************/
void Cty_GetBasicListOfCountries (void)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumCty;
struct Hie_Node *Cty;
// Lan_Language_t Lan;
2020-01-07 22:07:06 +01:00
/***** Trivial check: if list is already got, nothing to do *****/
if (Gbl.Hierarchy.List[Hie_SYS].Num)
return;
2020-01-07 22:07:06 +01:00
/***** Get countries from database *****/
if ((Gbl.Hierarchy.List[Hie_SYS].Num = Cty_DB_GetCtysBasic (&mysql_res))) // Countries found...
2020-01-07 22:07:06 +01:00
{
/***** Create list with countries *****/
if ((Gbl.Hierarchy.List[Hie_SYS].Lst = calloc ((size_t) Gbl.Hierarchy.List[Hie_SYS].Num,
sizeof (*Gbl.Hierarchy.List[Hie_SYS].Lst))) == NULL)
Err_NotEnoughMemoryExit ();
2020-01-07 22:07:06 +01:00
/***** Get the countries *****/
for (NumCty = 0;
NumCty < Gbl.Hierarchy.List[Hie_SYS].Num;
2020-01-07 22:07:06 +01:00
NumCty++)
{
Cty = &(Gbl.Hierarchy.List[Hie_SYS].Lst[NumCty]);
2020-01-07 22:07:06 +01:00
/* Get next country */
row = mysql_fetch_row (mysql_res);
/* Get numerical country code (row[0]) */
if ((Cty->HieCod = Str_ConvertStrCodToLongCod (row[0])) <= 0)
Err_WrongCountrExit ();
2020-01-07 22:07:06 +01:00
/* Get the name of the country in current language */
Str_Copy (Cty->FullName,row[1],sizeof (Cty->FullName) - 1);
2020-01-07 22:07:06 +01:00
2020-01-08 00:47:10 +01:00
/* Reset number of users who claim to belong to country */
Cty->NumUsrsWhoClaimToBelong.Valid = false;
2020-01-07 22:07:06 +01:00
}
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
/********** Get full list of countries with names in all languages ***********/
/********** and number of users who claim to belong to them ***********/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
static void Cty_GetFullListOfCountries (void)
2014-12-01 23:55:08 +01:00
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumCty;
struct Hie_Node *Cty;
2014-12-01 23:55:08 +01:00
/***** Trivial check: if list is already got, nothing to do *****/
if (Gbl.Hierarchy.List[Hie_SYS].Num)
return;
2018-10-30 14:47:31 +01:00
/***** Get countries from database *****/
if ((Gbl.Hierarchy.List[Hie_SYS].Num = Cty_DB_GetCtysFull (&mysql_res))) // Countries found...
2014-12-01 23:55:08 +01:00
{
/***** Create list with countries *****/
if ((Gbl.Hierarchy.List[Hie_SYS].Lst = calloc ((size_t) Gbl.Hierarchy.List[Hie_SYS].Num,
sizeof (*Gbl.Hierarchy.List[Hie_SYS].Lst))) == NULL)
Err_NotEnoughMemoryExit ();
2014-12-01 23:55:08 +01:00
/***** Get the countries *****/
for (NumCty = 0;
NumCty < Gbl.Hierarchy.List[Hie_SYS].Num;
2014-12-01 23:55:08 +01:00
NumCty++)
{
Cty = &(Gbl.Hierarchy.List[Hie_SYS].Lst[NumCty]);
2014-12-01 23:55:08 +01:00
/* Get next country */
row = mysql_fetch_row (mysql_res);
/* Get numerical country code (row[0]) */
if ((Cty->HieCod = Str_ConvertStrCodToLongCod (row[0])) <= 0)
Err_WrongCountrExit ();
2014-12-01 23:55:08 +01:00
/* Get Alpha-2 country code (row[1]) */
Str_Copy (Cty->ShrtName,row[1],sizeof (Cty->ShrtName) - 1);
2014-12-01 23:55:08 +01:00
/* Get the name and the web of the country in the current language */
Str_Copy (Cty->FullName,row[2],sizeof (Cty->FullName) - 1);
Str_Copy (Cty->WWW ,row[3],sizeof (Cty->WWW ) - 1);
2020-01-07 22:07:06 +01:00
/* Get number of users who claim to belong to this country */
Cty->NumUsrsWhoClaimToBelong.Valid = false;
if (sscanf (row[4],"%u",
&(Cty->NumUsrsWhoClaimToBelong.NumUsrs)) == 1)
Cty->NumUsrsWhoClaimToBelong.Valid = true;
2014-12-01 23:55:08 +01:00
}
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
/************************** Write selector of country ************************/
/*****************************************************************************/
2015-07-25 20:20:07 +02:00
void Cty_WriteSelectorOfCountry (void)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_HIERARCHY_SINGUL_Abc[Hie_NUM_LEVELS];
2014-12-01 23:55:08 +01:00
unsigned NumCty;
const struct Hie_Node *Cty;
/***** Get list of countries *****/
Cty_GetBasicListOfCountries ();
2014-12-01 23:55:08 +01:00
2019-10-20 22:00:28 +02:00
/***** Begin form *****/
Frm_BeginFormGoTo (ActSeeIns);
2014-12-01 23:55:08 +01:00
/***** Begin selector of country *****/
HTM_SELECT_Begin (HTM_SUBMIT_ON_CHANGE,NULL,
"id=\"cty\" name=\"cty\" class=\"HIE_SEL INPUT_%s\"",
The_GetSuffix ());
2014-12-01 23:55:08 +01:00
/***** Initial disabled option *****/
HTM_OPTION (HTM_Type_STRING,"",
Gbl.Hierarchy.Node[Hie_CTY].HieCod < 0 ? HTM_OPTION_SELECTED :
HTM_OPTION_UNSELECTED,
HTM_OPTION_DISABLED,
"[%s]",Txt_HIERARCHY_SINGUL_Abc[Hie_CTY]);
2014-12-01 23:55:08 +01:00
/***** List countries *****/
for (NumCty = 0;
NumCty < Gbl.Hierarchy.List[Hie_SYS].Num;
NumCty++)
{
Cty = &Gbl.Hierarchy.List[Hie_SYS].Lst[NumCty];
HTM_OPTION (HTM_Type_LONG,&Cty->HieCod,
Cty->HieCod == Gbl.Hierarchy.Node[Hie_CTY].HieCod ? HTM_OPTION_SELECTED :
HTM_OPTION_UNSELECTED,
HTM_OPTION_ENABLED,
"%s",Cty->FullName);
}
2014-12-01 23:55:08 +01:00
/***** End selector of country *****/
HTM_SELECT_End ();
2014-12-01 23:55:08 +01:00
/***** End form *****/
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
// Do not free list of countries here, because it can be reused
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2017-03-02 00:53:34 +01:00
/***************************** Write country name ****************************/
2015-12-08 00:25:56 +01:00
/*****************************************************************************/
2017-03-01 14:53:18 +01:00
// If ClassLink == NULL ==> do not put link
2015-12-08 00:25:56 +01:00
void Cty_WriteCountryName (long CtyCod)
2015-12-08 00:25:56 +01:00
{
2017-03-10 02:40:01 +01:00
char CtyName[Cty_MAX_BYTES_NAME + 1];
Frm_PutForm_t PutForm = (!Frm_CheckIfInside () && // Only if not inside another form
Act_GetBrowserTab (Gbl.Action.Act) == Act_1ST) ? Frm_PUT_FORM : // Only in main browser tab
Frm_DONT_PUT_FORM;
2015-12-08 00:25:56 +01:00
/***** Get country name *****/
Cty_GetCountryNameInLanguage (CtyCod,Gbl.Prefs.Language,CtyName);
2015-12-08 00:25:56 +01:00
switch (PutForm)
2015-12-15 01:33:09 +01:00
{
case Frm_DONT_PUT_FORM:
/***** Write country name without link *****/
HTM_Txt (CtyName);
break;
case Frm_PUT_FORM:
/***** Write country name with link to country information *****/
Frm_BeginForm (ActSeeCtyInf);
ParCod_PutPar (ParCod_Cty,CtyCod);
HTM_BUTTON_Submit_Begin (Act_GetActionText (ActSeeCtyInf),
"class=\"BT_LINK\"");
HTM_Txt (CtyName);
HTM_BUTTON_End ();
Frm_EndForm ();
break;
2015-12-15 01:33:09 +01:00
}
2015-12-08 00:25:56 +01:00
}
/*****************************************************************************/
2015-12-09 19:51:17 +01:00
/***************** Get basic data of country given its code ******************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
bool Cty_GetCountrDataByCod (struct Hie_Node *Node)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_Another_country;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
bool Found;
2014-12-01 23:55:08 +01:00
if (Node->HieCod < 0)
2014-12-01 23:55:08 +01:00
return false;
/***** Clear data *****/
Node->ShrtName[0] = '\0';
Node->FullName[0] = '\0';
Node->WWW[0] = '\0';
Node->NumUsrsWhoClaimToBelong.Valid = false;
2014-12-01 23:55:08 +01:00
/***** If another country *****/
if (Node->HieCod == 0)
2014-12-01 23:55:08 +01:00
{
Str_Copy (Node->FullName,Txt_Another_country,sizeof (Node->FullName) - 1);
2014-12-01 23:55:08 +01:00
return false;
}
2015-12-09 19:51:17 +01:00
// Here Cty->CtyCod > 0
2014-12-01 23:55:08 +01:00
/***** Get data of a country from database *****/
Found = (Cty_DB_GetBasicCountryDataByCod (&mysql_res,Node->HieCod) != 0);
if (Found) // Country found...
2014-12-01 23:55:08 +01:00
{
/* Get row */
row = mysql_fetch_row (mysql_res);
/* Get Alpha-2 country code (row[0]) */
Str_Copy (Node->ShrtName,row[0],sizeof (Node->ShrtName) - 1);
2014-12-01 23:55:08 +01:00
2020-01-07 22:07:06 +01:00
/* Get name and WWW of the country in current language */
Str_Copy (Node->FullName,row[1],sizeof (Node->FullName) - 1);
Str_Copy (Node->WWW ,row[2],sizeof (Node->WWW ) - 1);
2014-12-01 23:55:08 +01:00
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return Found;
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*********** Get all names and WWWs of a country given its code **************/
/*****************************************************************************/
void Cty_GetNamesAndWWWsByCod (struct Hie_Node *Cty,
char NameInSeveralLanguages[1 + Lan_NUM_LANGUAGES][Cty_MAX_BYTES_NAME + 1],
char WWWInSeveralLanguages [1 + Lan_NUM_LANGUAGES][WWW_MAX_BYTES_WWW + 1])
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
Lan_Language_t Lan;
/***** Get data of a country from database *****/
if (Cty_DB_GetNamesAndWWWsByCod (&mysql_res,Cty->HieCod) != 0) // Country found...
{
/* Get row */
row = mysql_fetch_row (mysql_res);
/* Get names and webs of the country in several languages */
for (Lan = (Lan_Language_t) 1;
Lan <= (Lan_Language_t) Lan_NUM_LANGUAGES;
Lan++)
{
Str_Copy (NameInSeveralLanguages[Lan],row[Lan - 1],
Cty_MAX_BYTES_NAME);
Str_Copy (WWWInSeveralLanguages[Lan],row[Lan_NUM_LANGUAGES + Lan - 1],
WWW_MAX_BYTES_WWW - 1);
}
}
else
for (Lan = (Lan_Language_t) 1;
Lan <= (Lan_Language_t) Lan_NUM_LANGUAGES;
Lan++)
{
NameInSeveralLanguages[Lan][0] = '\0';
WWWInSeveralLanguages[Lan][0] = '\0';
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/***************************** Get country name ******************************/
/*****************************************************************************/
2017-06-20 14:43:26 +02:00
void Cty_FlushCacheCountryName (void)
{
Gbl.Cache.CountryName.Valid = false;
2017-06-20 14:43:26 +02:00
}
void Cty_GetCountryNameInLanguage (long CtyCod,Lan_Language_t Language,
char CtyName[Cty_MAX_BYTES_NAME + 1])
2014-12-01 23:55:08 +01:00
{
2017-06-20 14:43:26 +02:00
/***** 1. Fast check: Trivial case *****/
2017-03-01 15:23:30 +01:00
if (CtyCod <= 0)
2014-12-01 23:55:08 +01:00
{
2017-06-20 14:43:26 +02:00
CtyName[0] = '\0'; // Empty name
return;
}
2014-12-01 23:55:08 +01:00
2017-06-20 14:43:26 +02:00
/***** 2. Fast check: If cached... *****/
if (Gbl.Cache.CountryName.Valid &&
CtyCod == Gbl.Cache.CountryName.HieCod &&
2020-01-07 22:07:06 +01:00
Language == Gbl.Cache.CountryName.Language)
2017-06-20 14:43:26 +02:00
{
Str_Copy (CtyName,Gbl.Cache.CountryName.CtyName,Cty_MAX_BYTES_NAME);
2017-06-20 14:43:26 +02:00
return;
}
2017-03-01 15:23:30 +01:00
2017-06-20 14:43:26 +02:00
/***** 3. Slow: get country name from database *****/
Cty_DB_GetCountryName (CtyCod,Language,CtyName);
Gbl.Cache.CountryName.HieCod = CtyCod;
2020-01-07 22:07:06 +01:00
Gbl.Cache.CountryName.Language = Language;
Str_Copy (Gbl.Cache.CountryName.CtyName,CtyName,Cty_MAX_BYTES_NAME);
Gbl.Cache.CountryName.Valid = true;
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/***************************** List all countries ****************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
static void Cty_ListCountriesForEdition (void)
{
2018-12-08 16:43:13 +01:00
extern const char *Txt_STR_LANG_NAME[1 + Lan_NUM_LANGUAGES];
2014-12-01 23:55:08 +01:00
unsigned NumCty;
struct Hie_Node *Cty;
2020-05-03 20:58:03 +02:00
unsigned NumInss;
unsigned NumUsrsCty;
2018-12-08 16:43:13 +01:00
Lan_Language_t Lan;
char NameInSeveralLanguages[1 + Lan_NUM_LANGUAGES][Cty_MAX_BYTES_NAME + 1];
char WWWInSeveralLanguages [1 + Lan_NUM_LANGUAGES][WWW_MAX_BYTES_WWW + 1];
2014-12-01 23:55:08 +01:00
/***** Begin table *****/
HTM_TABLE_Begin ("TBL_SCROLL");
2014-12-01 23:55:08 +01:00
/***** Write heading *****/
Cty_PutHeadCountriesForEdition ();
2014-12-01 23:55:08 +01:00
/***** Write all countries *****/
for (NumCty = 0;
NumCty < Gbl.Hierarchy.List[Hie_SYS].Num;
NumCty++)
{
Cty = &Gbl.Hierarchy.List[Hie_SYS].Lst[NumCty];
NumInss = Hie_GetNumNodesInHieLvl (Hie_INS, // Number of institutions...
Hie_CTY, // ...in country
Cty->HieCod);
NumUsrsCty = Hie_GetNumUsrsWhoClaimToBelongTo (Hie_CTY,Cty);
2019-10-05 13:27:58 +02:00
HTM_TR_Begin (NULL);
/* Put icon to remove country */
HTM_TD_Begin ("rowspan=\"%u\" class=\"BT\"",1 + Lan_NUM_LANGUAGES);
if (NumInss || // Country has institutions
NumUsrsCty) // Country has users
// Deletion forbidden
Ico_PutIconRemovalNotAllowed ();
else if (Enr_GetNumUsrsInCrss (Hie_CTY,Cty->HieCod,
1 << Rol_STD |
1 << Rol_NET |
1 << Rol_TCH)) // Country has users
// Deletion forbidden
Ico_PutIconRemovalNotAllowed ();
else
Ico_PutContextualIconToRemove (ActRemCty,NULL,
Cty_PutParOthCtyCod,&Cty->HieCod);
HTM_TD_End ();
/* Numerical country code (ISO 3166-1) */
HTM_TD_Begin ("rowspan=\"%u\" class=\"RT DAT_%s\"",
1 + Lan_NUM_LANGUAGES,The_GetSuffix ());
HTM_TxtF ("%03ld",Cty->HieCod);
HTM_TD_End ();
/* Alphabetic country code with 2 letters (ISO 3166-1) */
HTM_TD_Begin ("rowspan=\"%u\" class=\"RT DAT_%s\"",
1 + Lan_NUM_LANGUAGES,The_GetSuffix ());
HTM_Txt (Cty->ShrtName);
HTM_TD_End ();
HTM_TD_Empty (3);
/* Number of users */
HTM_TD_Begin ("rowspan=\"%u\" class=\"RT DAT_%s\"",
1 + Lan_NUM_LANGUAGES,The_GetSuffix ());
HTM_Unsigned (NumUsrsCty);
HTM_TD_End ();
2019-10-05 13:27:58 +02:00
/* Number of institutions */
HTM_TD_Begin ("rowspan=\"%u\" class=\"RT DAT_%s\"",
1 + Lan_NUM_LANGUAGES,The_GetSuffix ());
HTM_Unsigned (NumInss);
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
HTM_TR_End ();
2019-10-05 13:27:58 +02:00
/* Country name in several languages */
Cty_GetNamesAndWWWsByCod (Cty,
NameInSeveralLanguages,
WWWInSeveralLanguages);
for (Lan = (Lan_Language_t) 1;
Lan <= (Lan_Language_t) Lan_NUM_LANGUAGES;
Lan++)
{
HTM_TR_Begin (NULL);
/* Language */
HTM_TD_Begin ("class=\"RM DAT_%s\"",The_GetSuffix ());
HTM_TxtColon (Txt_STR_LANG_NAME[Lan]);
HTM_TD_End ();
/* Name */
HTM_TD_Begin ("class=\"LT\"");
Frm_BeginForm (ActRenCty);
ParCod_PutPar (ParCod_OthCty,Cty->HieCod);
Par_PutParUnsigned (NULL,"Lan",(unsigned) Lan);
HTM_INPUT_TEXT ("Name",Cty_MAX_CHARS_NAME,NameInSeveralLanguages[Lan],
HTM_SUBMIT_ON_CHANGE,
"size=\"15\" class=\"INPUT_%s\"",
The_GetSuffix ());
Frm_EndForm ();
HTM_TD_End ();
2019-10-05 13:27:58 +02:00
/* WWW */
HTM_TD_Begin ("class=\"LT\"");
Frm_BeginForm (ActChgCtyWWW);
ParCod_PutPar (ParCod_OthCty,Cty->HieCod);
Par_PutParUnsigned (NULL,"Lan",(unsigned) Lan);
HTM_INPUT_URL ("WWW",WWWInSeveralLanguages[Lan],HTM_SUBMIT_ON_CHANGE,
"class=\"INPUT_WWW INPUT_%s\""
" required=\"required\"",
The_GetSuffix ());
Frm_EndForm ();
HTM_TD_End ();
HTM_TR_End ();
}
}
2014-12-01 23:55:08 +01:00
2017-04-30 20:20:25 +02:00
/***** End table *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******************** Write parameter with code of country *******************/
/*****************************************************************************/
static void Cty_PutParOthCtyCod (void *CtyCod)
2014-12-01 23:55:08 +01:00
{
2020-10-13 22:34:31 +02:00
if (CtyCod)
ParCod_PutPar (ParCod_OthCty,*((long *) CtyCod));
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/****************************** Remove a country *****************************/
/*****************************************************************************/
void Cty_RemoveCountry (void)
{
extern bool (*Hie_GetDataByCod[Hie_NUM_LEVELS]) (struct Hie_Node *Node);
2014-12-01 23:55:08 +01:00
extern const char *Txt_You_can_not_remove_a_country_with_institutions_or_users;
extern const char *Txt_Country_X_removed;
2019-04-08 21:10:12 +02:00
/***** Country constructor *****/
Cty_EditingCountryConstructor ();
2014-12-01 23:55:08 +01:00
/***** Get country code *****/
Cty_EditingCty->HieCod = ParCod_GetAndCheckPar (ParCod_OthCty);
2014-12-01 23:55:08 +01:00
/***** Get data of the country from database *****/
Hie_GetDataByCod[Hie_CTY] (Cty_EditingCty);
2014-12-01 23:55:08 +01:00
/***** Check if this country has users *****/
if (Hie_GetNumNodesInHieLvl (Hie_INS, // Number of institutions...
Hie_CTY, // ...in country
Cty_EditingCty->HieCod)) // Country has institutions ==> don't remove
2020-01-07 13:14:42 +01:00
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_You_can_not_remove_a_country_with_institutions_or_users);
else if (Hie_GetNumUsrsWhoClaimToBelongTo (Hie_CTY,Cty_EditingCty)) // Country has users ==> don't remove
2020-01-07 00:42:24 +01:00
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_You_can_not_remove_a_country_with_institutions_or_users);
else if (Enr_GetNumUsrsInCrss (Hie_CTY,Cty_EditingCty->HieCod,
2020-01-08 23:49:04 +01:00
1 << Rol_STD |
1 << Rol_NET |
1 << Rol_TCH)) // Country has users
2019-04-08 21:10:12 +02:00
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_You_can_not_remove_a_country_with_institutions_or_users);
2014-12-01 23:55:08 +01:00
else // Country has no users ==> remove it
{
2016-10-28 00:30:18 +02:00
/***** Remove surveys of the country *****/
Svy_RemoveSurveys (Hie_CTY,Cty_EditingCty->HieCod);
2016-10-28 00:30:18 +02:00
2014-12-01 23:55:08 +01:00
/***** Remove country *****/
Cty_DB_RemoveCty (Cty_EditingCty->HieCod);
2014-12-01 23:55:08 +01:00
2017-06-20 14:43:26 +02:00
/***** Flush cache *****/
Cty_FlushCacheCountryName ();
Hie_FlushCachedNumNodesInHieLvl (Hie_INS,Hie_CTY); // Number of institutions in country
Hie_FlushCachedNumNodesInHieLvl (Hie_CTR,Hie_CTY); // Number of centers in country
Hie_FlushCachedNumNodesInHieLvl (Hie_DEG,Hie_CTY); // Number of degrees in country
Hie_FlushCachedNumNodesInHieLvl (Hie_CRS,Hie_CTY); // Number of courses in country
Hie_FlushCacheNumUsrsWhoClaimToBelongTo (Hie_CTY);
2017-06-20 14:43:26 +02:00
2014-12-01 23:55:08 +01:00
/***** Write message to show the change made *****/
2019-04-08 21:10:12 +02:00
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_Country_X_removed,
Cty_EditingCty->FullName);
2019-06-13 10:14:05 +02:00
Cty_EditingCty->HieCod = -1L; // To not showing button to go to country
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
/************************ Change the name of a country ***********************/
/*****************************************************************************/
void Cty_RenameCountry (void)
{
extern bool (*Hie_GetDataByCod[Hie_NUM_LEVELS]) (struct Hie_Node *Node);
2014-12-01 23:55:08 +01:00
extern const char *Txt_The_country_X_already_exists;
extern const char *Txt_The_country_X_has_been_renamed_as_Y;
2018-12-08 16:43:13 +01:00
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
extern const char *Txt_The_name_X_has_not_changed;
char OldCtyName[Cty_MAX_BYTES_NAME + 1];
2017-03-10 02:40:01 +01:00
char NewCtyName[Cty_MAX_BYTES_NAME + 1];
2018-12-08 16:43:13 +01:00
Lan_Language_t Language;
char FldName[4 + 1 + 2 + 1]; // Example: "Name_en"
2014-12-01 23:55:08 +01:00
2019-04-04 11:22:08 +02:00
/***** Country constructor *****/
2019-04-08 21:10:12 +02:00
Cty_EditingCountryConstructor ();
2014-12-01 23:55:08 +01:00
2017-05-31 21:05:59 +02:00
/***** Get the code of the country *****/
Cty_EditingCty->HieCod = ParCod_GetAndCheckPar (ParCod_OthCty);
2014-12-01 23:55:08 +01:00
2017-05-31 21:05:59 +02:00
/***** Get the lenguage *****/
Language = Lan_GetParLanguage ();
2014-12-01 23:55:08 +01:00
2017-05-31 21:05:59 +02:00
/***** Get the new name for the country *****/
Par_GetParText ("Name",NewCtyName,Cty_MAX_BYTES_NAME);
2014-12-01 23:55:08 +01:00
/***** Get from the database the data of the country *****/
Hie_GetDataByCod[Hie_CTY] (Cty_EditingCty);
2014-12-01 23:55:08 +01:00
/***** Check if new name is empty *****/
2019-12-20 00:30:54 +01:00
if (NewCtyName[0])
2014-12-01 23:55:08 +01:00
{
2019-01-02 15:10:51 +01:00
/***** Check if old and new names are the same
(this happens when return is pressed without changes) *****/
Cty_GetCountryNameInLanguage (Cty_EditingCty->HieCod,Language,OldCtyName);
if (strcmp (OldCtyName,NewCtyName)) // Different names
2017-05-31 21:05:59 +02:00
{
/***** If country was in database... *****/
if (Cty_DB_CheckIfCountryNameExists (Language,NewCtyName,Cty_EditingCty->HieCod))
2019-04-08 21:10:12 +02:00
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_The_country_X_already_exists,
NewCtyName);
2017-05-31 21:05:59 +02:00
else
{
/* Update the table changing old name by new name */
snprintf (FldName,sizeof (FldName),"Name_%s",
2018-12-08 16:43:13 +01:00
Lan_STR_LANG_ID[Language]);
Cty_UpdateCtyName (Cty_EditingCty->HieCod,FldName,NewCtyName);
2017-05-31 21:05:59 +02:00
/* Write message to show the change made */
2019-04-08 21:10:12 +02:00
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_The_country_X_has_been_renamed_as_Y,
OldCtyName,NewCtyName);
2017-05-31 21:05:59 +02:00
}
}
2014-12-01 23:55:08 +01:00
else // The same name
2019-04-08 21:10:12 +02:00
Ale_CreateAlert (Ale_INFO,NULL,
Txt_The_name_X_has_not_changed,
OldCtyName);
2014-12-01 23:55:08 +01:00
}
2019-12-20 00:30:54 +01:00
else
Ale_CreateAlertYouCanNotLeaveFieldEmpty ();
2014-12-01 23:55:08 +01:00
}
2017-03-10 02:40:01 +01:00
/*****************************************************************************/
/************ Update institution name in table of institutions ***************/
/*****************************************************************************/
static void Cty_UpdateCtyName (long CtyCod,const char *FldName,const char *NewCtyName)
2017-03-10 02:40:01 +01:00
{
/***** Update country changing old name by new name */
Cty_DB_UpdateCtyField (CtyCod,FldName,NewCtyName);
2017-06-20 14:43:26 +02:00
/***** Flush cache *****/
Cty_FlushCacheCountryName ();
2017-03-10 02:40:01 +01:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/************************ Change the URL of a country ************************/
/*****************************************************************************/
void Cty_ChangeCtyWWW (void)
{
extern bool (*Hie_GetDataByCod[Hie_NUM_LEVELS]) (struct Hie_Node *Node);
2018-12-08 16:43:13 +01:00
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
extern const char *Txt_The_new_web_address_is_X;
char NewWWW[WWW_MAX_BYTES_WWW + 1];
2018-12-08 16:43:13 +01:00
Lan_Language_t Language;
char FldName[3 + 1 + 2 + 1]; // Example: "WWW_en"
2014-12-01 23:55:08 +01:00
2019-04-04 11:22:08 +02:00
/***** Country constructor *****/
2019-04-08 21:10:12 +02:00
Cty_EditingCountryConstructor ();
2014-12-01 23:55:08 +01:00
2017-05-31 21:05:59 +02:00
/***** Get the code of the country *****/
Cty_EditingCty->HieCod = ParCod_GetAndCheckPar (ParCod_OthCty);
2014-12-01 23:55:08 +01:00
2017-05-31 21:05:59 +02:00
/***** Get the lenguage *****/
Language = Lan_GetParLanguage ();
2014-12-01 23:55:08 +01:00
2017-05-31 21:05:59 +02:00
/***** Get the new WWW for the country *****/
Par_GetParText ("WWW",NewWWW,WWW_MAX_BYTES_WWW);
2014-12-01 23:55:08 +01:00
/***** Get from the database the data of the country *****/
Hie_GetDataByCod[Hie_CTY] (Cty_EditingCty);
2014-12-01 23:55:08 +01:00
/***** Update the table changing old WWW by new WWW *****/
snprintf (FldName,sizeof (FldName),"WWW_%s",
Lan_STR_LANG_ID[Language]);
Cty_DB_UpdateCtyField (Cty_EditingCty->HieCod,FldName,NewWWW);
2014-12-01 23:55:08 +01:00
/***** Write message to show the change made *****/
2019-04-08 21:10:12 +02:00
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_The_new_web_address_is_X,
NewWWW);
2014-12-01 23:55:08 +01:00
}
2019-04-08 21:10:12 +02:00
/*****************************************************************************/
/********* Show alerts after changing a country and continue editing *********/
/*****************************************************************************/
void Cty_ContEditAfterChgCty (void)
{
/***** Write message to show the change made
and put button to go to country changed *****/
Cty_ShowAlertAndButtonToGoToCty ();
/***** Show the form again *****/
Cty_EditCountriesInternal ();
/***** Country destructor *****/
Cty_EditingCountryDestructor ();
}
/*****************************************************************************/
/***************** Write message to show the change made *******************/
/***************** and put button to go to country changed *******************/
/*****************************************************************************/
static void Cty_ShowAlertAndButtonToGoToCty (void)
{
2019-04-08 23:34:58 +02:00
// If the country being edited is different to the current one...
if (Cty_EditingCty->HieCod != Gbl.Hierarchy.Node[Hie_CTY].HieCod)
2019-04-08 21:10:12 +02:00
{
/***** Alert with button to go to couuntry *****/
2020-03-26 02:54:30 +01:00
Ale_ShowLastAlertAndButton (ActSeeIns,NULL,NULL,
Cty_PutParGoToCty,&Cty_EditingCty->HieCod,
2019-12-30 12:25:45 +01:00
Btn_CONFIRM_BUTTON,
Str_BuildGoToTitle (Cty_EditingCty->FullName));
Str_FreeGoToTitle ();
2019-04-08 21:10:12 +02:00
}
else
/***** Alert *****/
Ale_ShowAlerts (NULL);
}
static void Cty_PutParGoToCty (void *CtyCod)
2019-04-08 21:10:12 +02:00
{
2020-04-08 13:40:21 +02:00
if (CtyCod)
ParCod_PutPar (ParCod_Cty,*((long *) CtyCod));
2019-04-08 21:10:12 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/********************* Put a form to create a new country ********************/
/*****************************************************************************/
static void Cty_PutFormToCreateCountry (void)
{
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
extern const char *Par_CodeStr[Par_NUM_PAR_COD];
2018-12-08 16:43:13 +01:00
extern const char *Txt_STR_LANG_NAME[1 + Lan_NUM_LANGUAGES];
Lan_Language_t Lan;
2019-11-08 01:10:32 +01:00
char StrCtyCod[Cns_MAX_DECIMAL_DIGITS_LONG + 1];
2019-11-03 18:22:11 +01:00
char StrName[32];
2014-12-01 23:55:08 +01:00
/***** Begin form to create *****/
Frm_BeginFormTable (ActNewCty,NULL,NULL,NULL,"TBL_SCROLL");
2019-10-05 13:27:58 +02:00
/***** Write heading *****/
Cty_PutHeadCountriesForEdition ();
2014-12-01 23:55:08 +01:00
HTM_TR_Begin (NULL);
/***** Column to remove country, disabled here *****/
HTM_TD_Begin ("rowspan=\"%u\" class=\"BT\"",1 + Lan_NUM_LANGUAGES);
HTM_TD_End ();
/***** Numerical country code (ISO 3166-1) *****/
HTM_TD_Begin ("rowspan=\"%u\" class=\"RT\"",1 + Lan_NUM_LANGUAGES);
if (Cty_EditingCty->HieCod > 0)
snprintf (StrCtyCod,sizeof (StrCtyCod),"%03ld",Cty_EditingCty->HieCod);
else
StrCtyCod[0] = '\0';
HTM_INPUT_TEXT (Par_CodeStr[ParCod_OthCty],3,StrCtyCod,HTM_DONT_SUBMIT_ON_CHANGE,
"size=\"3\" class=\"INPUT_%s\""
" required=\"required\"",
The_GetSuffix ());
HTM_TD_End ();
/***** Alphabetic country code with 2 letters (ISO 3166-1) *****/
HTM_TD_Begin ("rowspan=\"%u\" class=\"RT\"",1 + Lan_NUM_LANGUAGES);
HTM_INPUT_TEXT ("Alpha2",2,Cty_EditingCty->ShrtName,HTM_DONT_SUBMIT_ON_CHANGE,
"size=\"2\" class=\"INPUT_%s\""
" required=\"required\"",
The_GetSuffix ());
HTM_TD_End ();
HTM_TD_Empty (3);
/***** Number of users *****/
HTM_TD_Begin ("rowspan=\"%u\" class=\"RT DAT_%s\"",
1 + Lan_NUM_LANGUAGES,The_GetSuffix ());
HTM_Unsigned (0);
HTM_TD_End ();
/***** Number of institutions *****/
HTM_TD_Begin ("rowspan=\"%u\" class=\"RT DAT_%s\"",
1 + Lan_NUM_LANGUAGES,The_GetSuffix ());
HTM_Unsigned (0);
HTM_TD_End ();
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
/***** Country name in several languages *****/
for (Lan = (Lan_Language_t) 1;
Lan <= (Lan_Language_t) Lan_NUM_LANGUAGES;
Lan++)
{
HTM_TR_Begin (NULL);
2014-12-01 23:55:08 +01:00
/* Language */
HTM_TD_Begin ("class=\"RT DAT_%s\"",The_GetSuffix ());
HTM_Txt (Txt_STR_LANG_NAME[Lan]);
HTM_TD_End ();
/* Name */
HTM_TD_Begin ("class=\"LM\"");
snprintf (StrName,sizeof (StrName),"Name_%s",Lan_STR_LANG_ID[Lan]);
HTM_INPUT_TEXT (StrName,Cty_MAX_CHARS_NAME,"",
HTM_DONT_SUBMIT_ON_CHANGE,
"size=\"15\" class=\"INPUT_%s\""
" required=\"required\"",
The_GetSuffix ());
HTM_TD_End ();
/* WWW */
HTM_TD_Begin ("class=\"LM\"");
snprintf (StrName,sizeof (StrName),"WWW_%s",Lan_STR_LANG_ID[Lan]);
HTM_INPUT_URL (StrName,"",HTM_DONT_SUBMIT_ON_CHANGE,
"class=\"INPUT_WWW INPUT_%s\""
" required=\"required\"",
The_GetSuffix ());
HTM_TD_End ();
HTM_TR_End ();
}
/***** End form to create *****/
Frm_EndFormTable (Btn_CREATE_BUTTON);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******************* Write header with fields of a country *******************/
/*****************************************************************************/
2017-02-28 00:59:01 +01:00
static void Cty_PutHeadCountriesForEdition (void)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_Numeric_BR_code_BR_ISO_3166_1;
extern const char *Txt_Alphabetic_BR_code_BR_ISO_3166_1;
extern const char *Txt_Name;
extern const char *Txt_WWW;
extern const char *Txt_Users;
2015-12-09 19:51:17 +01:00
extern const char *Txt_Institutions_ABBREVIATION;
2014-12-01 23:55:08 +01:00
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-07 00:05:24 +02:00
HTM_TH_Span (NULL ,HTM_HEAD_CENTER,1,1,"BT");
HTM_TH (Txt_Numeric_BR_code_BR_ISO_3166_1 ,HTM_HEAD_RIGHT );
HTM_TH (Txt_Alphabetic_BR_code_BR_ISO_3166_1,HTM_HEAD_RIGHT );
HTM_TH_Empty (1);
HTM_TH (Txt_Name ,HTM_HEAD_LEFT );
HTM_TH (Txt_WWW ,HTM_HEAD_LEFT );
HTM_TH (Txt_Users ,HTM_HEAD_RIGHT );
HTM_TH (Txt_Institutions_ABBREVIATION ,HTM_HEAD_RIGHT );
2019-10-07 00:05:24 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******************* Receive form to create a new country ********************/
/*****************************************************************************/
void Cty_ReceiveNewCountry (void)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_You_must_specify_the_numerical_code_of_the_new_country;
extern const char *Txt_The_numerical_code_X_already_exists;
extern const char *Txt_The_alphabetical_code_X_is_not_correct;
extern const char *Txt_The_alphabetical_code_X_already_exists;
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
extern const char *Txt_The_country_X_already_exists;
extern const char *Txt_You_must_specify_the_name;
2019-04-08 21:10:12 +02:00
extern const char *Txt_Created_new_country_X;
char ParName[32];
2014-12-01 23:55:08 +01:00
bool CreateCountry = true;
2018-12-08 16:43:13 +01:00
Lan_Language_t Lan;
char NameInSeveralLanguages[1 + Lan_NUM_LANGUAGES][Cty_MAX_BYTES_NAME + 1];
char WWWInSeveralLanguages [1 + Lan_NUM_LANGUAGES][WWW_MAX_BYTES_WWW + 1];
2014-12-01 23:55:08 +01:00
unsigned i;
2019-04-04 11:22:08 +02:00
/***** Country constructoor *****/
2019-04-08 21:10:12 +02:00
Cty_EditingCountryConstructor ();
for (Lan = (Lan_Language_t) 1;
Lan <= (Lan_Language_t) Lan_NUM_LANGUAGES;
Lan++)
{
NameInSeveralLanguages[Lan][0] = '\0';
WWWInSeveralLanguages [Lan][0] = '\0';
}
2014-12-01 23:55:08 +01:00
/***** Get parameters from form *****/
/* Get numeric country code */
if ((Cty_EditingCty->HieCod = ParCod_GetPar (ParCod_OthCty)) < 0)
2014-12-01 23:55:08 +01:00
{
2019-04-08 21:10:12 +02:00
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_You_must_specify_the_numerical_code_of_the_new_country);
2014-12-01 23:55:08 +01:00
CreateCountry = false;
}
else if (Cty_DB_CheckIfNumericCountryCodeExists (Cty_EditingCty->HieCod))
2014-12-01 23:55:08 +01:00
{
2019-04-08 21:10:12 +02:00
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_The_numerical_code_X_already_exists,
Cty_EditingCty->HieCod);
2014-12-01 23:55:08 +01:00
CreateCountry = false;
}
else // Numeric code correct
{
/* Get alphabetic-2 country code */
Par_GetParText ("Alpha2",Cty_EditingCty->ShrtName,2);
Str_ConvertToUpperText (Cty_EditingCty->ShrtName);
2014-12-01 23:55:08 +01:00
for (i = 0;
i < 2 && CreateCountry;
i++)
if (Cty_EditingCty->ShrtName[i] < 'A' ||
Cty_EditingCty->ShrtName[i] > 'Z')
2014-12-01 23:55:08 +01:00
{
2019-04-08 21:10:12 +02:00
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_The_alphabetical_code_X_is_not_correct,
Cty_EditingCty->ShrtName);
2014-12-01 23:55:08 +01:00
CreateCountry = false;
}
if (CreateCountry)
{
if (Cty_DB_CheckIfAlpha2CountryCodeExists (Cty_EditingCty->ShrtName))
2014-12-01 23:55:08 +01:00
{
2019-04-08 21:10:12 +02:00
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_The_alphabetical_code_X_already_exists,
Cty_EditingCty->ShrtName);
2014-12-01 23:55:08 +01:00
CreateCountry = false;
}
else // Alphabetic code correct
{
/* Get country name and WWW in different languages */
2019-12-15 01:10:36 +01:00
for (Lan = (Lan_Language_t) 1;
Lan <= (Lan_Language_t) Lan_NUM_LANGUAGES;
2014-12-01 23:55:08 +01:00
Lan++)
{
snprintf (ParName,sizeof (ParName),"Name_%s",Lan_STR_LANG_ID[Lan]);
Par_GetParText (ParName,NameInSeveralLanguages[Lan],Cty_MAX_BYTES_NAME);
2014-12-01 23:55:08 +01:00
if (NameInSeveralLanguages[Lan][0]) // If there's a country name
2014-12-01 23:55:08 +01:00
{
/***** If name of country was in database... *****/
if (Cty_DB_CheckIfCountryNameExists (Lan,NameInSeveralLanguages[Lan],-1L))
2014-12-01 23:55:08 +01:00
{
2019-04-08 21:10:12 +02:00
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_The_country_X_already_exists,
NameInSeveralLanguages[Lan]);
2014-12-01 23:55:08 +01:00
CreateCountry = false;
break;
}
}
else // If there is not a country name
{
2019-04-08 21:10:12 +02:00
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_You_must_specify_the_name);
2014-12-01 23:55:08 +01:00
CreateCountry = false;
break;
}
snprintf (ParName,sizeof (ParName),"WWW_%s",Lan_STR_LANG_ID[Lan]);
Par_GetParText (ParName,WWWInSeveralLanguages[Lan],WWW_MAX_BYTES_WWW);
2014-12-01 23:55:08 +01:00
}
}
}
}
if (CreateCountry)
2019-04-08 21:10:12 +02:00
{
Cty_DB_CreateCountry (Cty_EditingCty, // Add new country to database
NameInSeveralLanguages,
WWWInSeveralLanguages);
2019-04-08 21:10:12 +02:00
Ale_ShowAlert (Ale_SUCCESS,Txt_Created_new_country_X,
Cty_EditingCty->FullName);
2019-04-08 21:10:12 +02:00
}
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******************* Get number of countries with users **********************/
/*****************************************************************************/
unsigned Cty_GetCachedNumCtysWithUsrs (Rol_Role_t Role)
2014-12-01 23:55:08 +01:00
{
2020-05-03 20:58:03 +02:00
static const FigCch_FigureCached_t FigureCtys[Rol_NUM_ROLES] =
{
[Rol_STD] = FigCch_NUM_CTYS_WITH_STDS, // Students
[Rol_NET] = FigCch_NUM_CTYS_WITH_NETS, // Non-editing teachers
[Rol_TCH] = FigCch_NUM_CTYS_WITH_TCHS, // Teachers
};
unsigned NumCtysWithUsrs;
long Cod = Hie_GetCurrentCod ();
2020-05-03 20:58:03 +02:00
/***** Get number of countries with users from cache *****/
if (!FigCch_GetFigureFromCache (FigureCtys[Role],Gbl.Scope.Current,Cod,
2020-05-03 20:58:03 +02:00
FigCch_UNSIGNED,&NumCtysWithUsrs))
{
/***** Get current number of countries with users from database and update cache *****/
NumCtysWithUsrs = Cty_DB_GetNumCtysWithUsrs (Role,Gbl.Scope.Current,Cod);
FigCch_UpdateFigureIntoCache (FigureCtys[Role],Gbl.Scope.Current,Cod,
2020-05-03 20:58:03 +02:00
FigCch_UNSIGNED,&NumCtysWithUsrs);
}
return NumCtysWithUsrs;
2014-12-01 23:55:08 +01:00
}
2017-02-28 00:59:01 +01:00
/*****************************************************************************/
/***************************** List countries found **************************/
/*****************************************************************************/
2018-10-30 14:47:31 +01:00
void Cty_ListCtysFound (MYSQL_RES **mysql_res,unsigned NumCtys)
2017-02-28 00:59:01 +01:00
{
extern bool (*Hie_GetDataByCod[Hie_NUM_LEVELS]) (struct Hie_Node *Node);
extern const char *Txt_HIERARCHY_SINGUL_abc[Hie_NUM_LEVELS];
extern const char *Txt_HIERARCHY_PLURAL_abc[Hie_NUM_LEVELS];
char *Title;
2017-02-28 00:59:01 +01:00
unsigned NumCty;
struct Hie_Node Cty;
2017-02-28 00:59:01 +01:00
/***** Query database *****/
2018-10-30 14:47:31 +01:00
if (NumCtys)
2017-02-28 00:59:01 +01:00
{
2019-10-26 02:19:42 +02:00
/***** Begin box and table *****/
2017-02-28 00:59:01 +01:00
/* Number of countries found */
if (asprintf (&Title,"%u %s",NumCtys,
NumCtys == 1 ? Txt_HIERARCHY_SINGUL_abc[Hie_CTY] :
Txt_HIERARCHY_PLURAL_abc[Hie_CTY]) < 0)
Err_NotEnoughMemoryExit ();
Box_BoxTableBegin (Title,NULL,NULL,NULL,Box_NOT_CLOSABLE,2);
free (Title);
2017-06-12 14:16:33 +02:00
/***** Write heading *****/
Cty_PutHeadCountriesForSeeing (false); // Order not selectable
2017-02-28 00:59:01 +01:00
/***** List the countries (one row per country) *****/
for (NumCty = 1, The_ResetRowColor ();
NumCty <= NumCtys;
NumCty++, The_ChangeRowColor ())
{
/* Get next country */
Cty.HieCod = DB_GetNextCode (*mysql_res);
2017-02-28 00:59:01 +01:00
/* Get data of country */
Hie_GetDataByCod[Hie_CTY] (&Cty);
2017-02-28 00:59:01 +01:00
/* Write data of this country */
Cty_ListOneCountryForSeeing (&Cty,NumCty);
}
2017-02-28 00:59:01 +01:00
2017-06-12 14:16:33 +02:00
/***** End table and box *****/
2019-11-25 23:18:08 +01:00
Box_BoxTableEnd ();
2017-02-28 00:59:01 +01:00
}
/***** Free structure that stores the query result *****/
2018-10-30 14:47:31 +01:00
DB_FreeMySQLResult (mysql_res);
2017-02-28 00:59:01 +01:00
}
2019-04-04 11:22:08 +02:00
/*****************************************************************************/
/*********************** Country constructor/destructor **********************/
/*****************************************************************************/
2019-04-08 21:10:12 +02:00
static void Cty_EditingCountryConstructor (void)
2019-04-04 11:22:08 +02:00
{
2019-04-08 21:10:12 +02:00
/***** Pointer must be NULL *****/
if (Cty_EditingCty != NULL)
Err_WrongCountrExit ();
2019-04-04 11:22:08 +02:00
/***** Allocate memory for country *****/
if ((Cty_EditingCty = malloc (sizeof (*Cty_EditingCty))) == NULL)
Err_NotEnoughMemoryExit ();
2019-04-04 11:22:08 +02:00
/***** Reset country *****/
Cty_EditingCty->HieCod = -1L;
Cty_EditingCty->ShrtName[0] = '\0';
Cty_EditingCty->FullName[0] = '\0';
Cty_EditingCty->WWW[0] = '\0';
Cty_EditingCty->NumUsrsWhoClaimToBelong.Valid = false;
2019-04-04 11:22:08 +02:00
}
2019-04-08 21:10:12 +02:00
static void Cty_EditingCountryDestructor (void)
2019-04-04 11:22:08 +02:00
{
/***** Free memory used for country *****/
2019-04-08 21:10:12 +02:00
if (Cty_EditingCty != NULL)
2019-04-04 11:22:08 +02:00
{
2019-11-06 19:45:20 +01:00
free (Cty_EditingCty);
2019-04-08 21:10:12 +02:00
Cty_EditingCty = NULL;
2019-04-04 11:22:08 +02:00
}
}
2020-01-09 15:36:12 +01:00
/*****************************************************************************/
2020-01-14 13:30:18 +01:00
/************************ Form to go to country map **************************/
/*****************************************************************************/
static void Cty_FormToGoToMap (struct Hie_Node *Cty)
2020-01-14 13:30:18 +01:00
{
if (Cty_DB_CheckIfMapIsAvailable (Cty->HieCod))
2020-01-14 13:30:18 +01:00
{
Cty_EditingCty = Cty; // Used to pass parameter with the code of the country
2020-03-26 02:54:30 +01:00
Lay_PutContextualLinkOnlyIcon (ActSeeCtyInf,NULL,
Cty_PutParGoToCty,&Cty_EditingCty->HieCod,
"map-marker-alt.svg",Ico_BLACK);
2020-01-14 13:30:18 +01:00
}
}
/*****************************************************************************/
/******* Get number of users who don't claim to belong to any country ********/
/*****************************************************************************/
void Cty_FlushCacheNumUsrsWhoDontClaimToBelongToAnyCty (void)
{
Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.Valid = false;
}
unsigned Cty_GetCachedNumUsrsWhoDontClaimToBelongToAnyCty (void)
{
unsigned NumUsrs;
/***** Get number of user who don't claim to belong to any country from cache *****/
if (!FigCch_GetFigureFromCache (FigCch_NUM_USRS_BELONG_CTY,Hie_CTY,-1L,
FigCch_UNSIGNED,&NumUsrs))
/***** Get current number of user who don't claim to belong to any country from database and update cache *****/
NumUsrs = Cty_GetNumUsrsWhoDontClaimToBelongToAnyCty ();
return NumUsrs;
}
unsigned Cty_GetNumUsrsWhoDontClaimToBelongToAnyCty (void)
{
/***** 1. Fast check: If cached... *****/
if (Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.Valid)
return Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.NumUsrs;
/***** 2. Slow: number of users who don't claim to belong to any country
from database *****/
Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.NumUsrs = Cty_DB_GetNumUsrsWhoDontClaimToBelongToAnyCty ();
Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.Valid = true;
FigCch_UpdateFigureIntoCache (FigCch_NUM_USRS_BELONG_CTY,Hie_CTY,-1L,
FigCch_UNSIGNED,&Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.NumUsrs);
return Gbl.Cache.NumUsrsWhoDontClaimToBelongToAnyCty.NumUsrs;
}
/*****************************************************************************/
/******** Get number of users who claim to belong to another country *********/
/*****************************************************************************/
void Cty_FlushCacheNumUsrsWhoClaimToBelongToAnotherCty (void)
{
Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.Valid = false;
}
unsigned Cty_GetCachedNumUsrsWhoClaimToBelongToAnotherCty (void)
{
unsigned NumUsrsCty;
/***** Get number of users who claim to belong to another country form cache *****/
if (!FigCch_GetFigureFromCache (FigCch_NUM_USRS_BELONG_CTY,Hie_CTY,0,
FigCch_UNSIGNED,&NumUsrsCty))
/***** Get current number of users who claim to belong to another country from database and update cache *****/
NumUsrsCty = Cty_GetNumUsrsWhoClaimToBelongToAnotherCty ();
return NumUsrsCty;
}
unsigned Cty_GetNumUsrsWhoClaimToBelongToAnotherCty (void)
{
/***** 1. Fast check: If cached... *****/
if (Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.Valid)
return Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.NumUsrs;
/***** 2. Slow: number of users who claim to belong to another country
from database *****/
Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.NumUsrs = Cty_DB_GetNumUsrsWhoClaimToBelongToAnotherCty ();
Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.Valid = true;
FigCch_UpdateFigureIntoCache (FigCch_NUM_USRS_BELONG_CTY,Hie_CTY,0,
FigCch_UNSIGNED,&Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.NumUsrs);
return Gbl.Cache.NumUsrsWhoClaimToBelongToAnotherCty.NumUsrs;
}