// For string functions
+
+#include "swad_config.h"
+#include "swad_degree.h"
+#include "swad_global.h"
+#include "swad_logo.h"
+#include "swad_theme.h"
+
+/*****************************************************************************/
+/************** External global variables from others modules ****************/
+/*****************************************************************************/
+
+extern struct Globals Gbl;
+
+/*****************************************************************************/
+/*************************** Public constants ********************************/
+/*****************************************************************************/
+
+/*****************************************************************************/
+/***************************** Private types *********************************/
+/*****************************************************************************/
+
+/*****************************************************************************/
+/**************************** Private constants ******************************/
+/*****************************************************************************/
+
+/*****************************************************************************/
+/**************************** Private prototypes *****************************/
+/*****************************************************************************/
+
+/*****************************************************************************/
+/*** Write menu to select country, institution, centre, degree and course ****/
+/*****************************************************************************/
+
+void Hie_WriteMenuHierarchy (void)
+ {
+ extern const char *The_ClassForm[The_NUM_THEMES];
+ extern const char *Txt_Country;
+ extern const char *Txt_Institution;
+ extern const char *Txt_Centre;
+ extern const char *Txt_Degree;
+ extern const char *Txt_Course;
+
+ /***** Start of table *****/
+ fprintf (Gbl.F.Out,"");
+
+ /***** Write a 1st selector
+ with all the countries *****/
+ fprintf (Gbl.F.Out,""
+ ""
+ "%s:"
+ " | "
+ "",
+ The_ClassForm[Gbl.Prefs.Theme],Txt_Country);
+ Cty_WriteSelectorOfCountry ();
+ fprintf (Gbl.F.Out," | "
+ "
");
+
+ if (Gbl.CurrentCty.Cty.CtyCod > 0)
+ {
+ /***** Write a 2nd selector
+ with the institutions of selected country *****/
+ fprintf (Gbl.F.Out,""
+ ""
+ "%s:"
+ " | "
+ "",
+ The_ClassForm[Gbl.Prefs.Theme],Txt_Institution);
+ Ins_WriteSelectorOfInstitution ();
+ fprintf (Gbl.F.Out," | "
+ "
");
+
+ if (Gbl.CurrentIns.Ins.InsCod > 0)
+ {
+ /***** Write a 3rd selector
+ with all the centres of selected institution *****/
+ fprintf (Gbl.F.Out,""
+ ""
+ "%s:"
+ " | "
+ "",
+ The_ClassForm[Gbl.Prefs.Theme],Txt_Centre);
+ Ctr_WriteSelectorOfCentre ();
+ fprintf (Gbl.F.Out," | "
+ "
");
+
+ if (Gbl.CurrentCtr.Ctr.CtrCod > 0)
+ {
+ /***** Write a 4th selector
+ with all the degrees of selected centre *****/
+ fprintf (Gbl.F.Out,""
+ ""
+ "%s:"
+ " | "
+ "",
+ The_ClassForm[Gbl.Prefs.Theme],Txt_Degree);
+ Deg_WriteSelectorOfDegree ();
+ fprintf (Gbl.F.Out," | "
+ "
");
+
+ if (Gbl.CurrentDeg.Deg.DegCod > 0)
+ {
+ /***** Write a 5th selector
+ with all the courses of selected degree *****/
+ fprintf (Gbl.F.Out,""
+ ""
+ "%s:"
+ " | "
+ "",
+ The_ClassForm[Gbl.Prefs.Theme],Txt_Course);
+ Crs_WriteSelectorOfCourse ();
+ fprintf (Gbl.F.Out," | "
+ "
");
+ }
+ }
+ }
+ }
+
+ /***** End of table *****/
+ fprintf (Gbl.F.Out,"
");
+ }
+
+/*****************************************************************************/
+/************* Write hierarchy breadcrumb in the top of the page *************/
+/*****************************************************************************/
+
+void Hie_WriteHierarchyBreadcrumb (void)
+ {
+ extern const char *The_ClassBreadcrumb[The_NUM_THEMES];
+ extern const char *Txt_System;
+ extern const char *Txt_Country;
+ extern const char *Txt_Institution;
+ extern const char *Txt_Centre;
+ extern const char *Txt_Degree;
+ const char *ClassTxt = The_ClassBreadcrumb[Gbl.Prefs.Theme];
+
+ /***** Form to go to the system *****/
+ fprintf (Gbl.F.Out,"",ClassTxt);
+
+ Act_FormGoToStart (ActMnu);
+ Par_PutHiddenParamUnsigned ("NxtTab",(unsigned) TabSys);
+ Act_LinkFormSubmit (Txt_System,ClassTxt,NULL);
+ fprintf (Gbl.F.Out,"%s",Txt_System);
+ Act_FormEnd ();
+
+ fprintf (Gbl.F.Out,"
");
+
+ if (Gbl.CurrentCty.Cty.CtyCod > 0) // Country selected...
+ {
+ fprintf (Gbl.F.Out,"",ClassTxt);
+
+ /***** Separator *****/
+ fprintf (Gbl.F.Out," > ");
+
+ /***** Form to go to see institutions of this country *****/
+ Act_FormGoToStart (ActSeeIns);
+ Cty_PutParamCtyCod (Gbl.CurrentCty.Cty.CtyCod);
+ Act_LinkFormSubmit (Gbl.CurrentCty.Cty.Name[Gbl.Prefs.Language],ClassTxt,NULL);
+ fprintf (Gbl.F.Out,"%s",Gbl.CurrentCty.Cty.Name[Gbl.Prefs.Language]);
+ Act_FormEnd ();
+
+ fprintf (Gbl.F.Out,"
");
+ }
+ else
+ {
+ fprintf (Gbl.F.Out,"",ClassTxt);
+
+ /***** Separator *****/
+ fprintf (Gbl.F.Out," > ");
+
+ /***** Form to go to select countries *****/
+ Act_FormGoToStart (ActSeeCty);
+ Act_LinkFormSubmit (Txt_Country,ClassTxt,NULL);
+ fprintf (Gbl.F.Out,"%s",Txt_Country);
+ Act_FormEnd ();
+
+ fprintf (Gbl.F.Out,"
");
+ }
+
+ if (Gbl.CurrentIns.Ins.InsCod > 0) // Institution selected...
+ {
+ fprintf (Gbl.F.Out,"",ClassTxt);
+
+ /***** Separator *****/
+ fprintf (Gbl.F.Out," > ");
+
+ /***** Form to see centres of this institution *****/
+ Act_FormGoToStart (ActSeeCtr);
+ Ins_PutParamInsCod (Gbl.CurrentIns.Ins.InsCod);
+ Act_LinkFormSubmit (Gbl.CurrentIns.Ins.FullName,ClassTxt,NULL);
+ fprintf (Gbl.F.Out,"%s",Gbl.CurrentIns.Ins.ShrtName);
+ Act_FormEnd ();
+
+ fprintf (Gbl.F.Out,"
");
+ }
+ else if (Gbl.CurrentCty.Cty.CtyCod > 0)
+ {
+ fprintf (Gbl.F.Out,"",ClassTxt);
+
+ /***** Separator *****/
+ fprintf (Gbl.F.Out," > ");
+
+ /***** Form to go to select institutions *****/
+ Act_FormGoToStart (ActSeeIns);
+ Act_LinkFormSubmit (Txt_Institution,ClassTxt,NULL);
+ fprintf (Gbl.F.Out,"%s",Txt_Institution);
+ Act_FormEnd ();
+
+ fprintf (Gbl.F.Out,"
");
+ }
+ else
+ {
+ fprintf (Gbl.F.Out,"",ClassTxt);
+
+ /***** Separator *****/
+ fprintf (Gbl.F.Out," > ");
+
+ /***** Hidden institution *****/
+ fprintf (Gbl.F.Out,"%s",Txt_Institution);
+
+ fprintf (Gbl.F.Out,"
");
+ }
+
+ if (Gbl.CurrentCtr.Ctr.CtrCod > 0) // Centre selected...
+ {
+ fprintf (Gbl.F.Out,"",ClassTxt);
+
+ /***** Separator *****/
+ fprintf (Gbl.F.Out," > ");
+
+ /***** Form to see degrees of this centre *****/
+ Act_FormGoToStart (ActSeeDeg);
+ Ctr_PutParamCtrCod (Gbl.CurrentCtr.Ctr.CtrCod);
+ Act_LinkFormSubmit (Gbl.CurrentCtr.Ctr.FullName,ClassTxt,NULL);
+ fprintf (Gbl.F.Out,"%s",Gbl.CurrentCtr.Ctr.ShrtName);
+ Act_FormEnd ();
+
+ fprintf (Gbl.F.Out,"
");
+ }
+ else if (Gbl.CurrentIns.Ins.InsCod > 0)
+ {
+ fprintf (Gbl.F.Out,"",ClassTxt);
+
+ /***** Separator *****/
+ fprintf (Gbl.F.Out," > ");
+
+ /***** Form to go to select centres *****/
+ Act_FormGoToStart (ActSeeCtr);
+ Act_LinkFormSubmit (Txt_Centre,ClassTxt,NULL);
+ fprintf (Gbl.F.Out,"%s",Txt_Centre);
+ Act_FormEnd ();
+
+ fprintf (Gbl.F.Out,"
");
+ }
+ else
+ {
+ fprintf (Gbl.F.Out,"",ClassTxt);
+
+ /***** Separator *****/
+ fprintf (Gbl.F.Out," > ");
+
+ /***** Hidden centre *****/
+ fprintf (Gbl.F.Out,"%s",Txt_Centre);
+
+ fprintf (Gbl.F.Out,"
");
+ }
+
+ if (Gbl.CurrentDeg.Deg.DegCod > 0) // Degree selected...
+ {
+ fprintf (Gbl.F.Out,"",ClassTxt);
+
+ /***** Separator *****/
+ fprintf (Gbl.F.Out," > ");
+
+ /***** Form to go to see courses of this degree *****/
+ Act_FormGoToStart (ActSeeCrs);
+ Deg_PutParamDegCod (Gbl.CurrentDeg.Deg.DegCod);
+ Act_LinkFormSubmit (Gbl.CurrentDeg.Deg.FullName,ClassTxt,NULL);
+ fprintf (Gbl.F.Out,"%s",Gbl.CurrentDeg.Deg.ShrtName);
+ Act_FormEnd ();
+
+ fprintf (Gbl.F.Out,"
");
+ }
+ else if (Gbl.CurrentCtr.Ctr.CtrCod > 0)
+ {
+ fprintf (Gbl.F.Out,"",ClassTxt);
+
+ /***** Separator *****/
+ fprintf (Gbl.F.Out," > ");
+
+ /***** Form to go to select degrees *****/
+ Act_FormGoToStart (ActSeeDeg);
+ Act_LinkFormSubmit (Txt_Degree,ClassTxt,NULL);
+ fprintf (Gbl.F.Out,"%s",Txt_Degree);
+ Act_FormEnd ();
+
+ fprintf (Gbl.F.Out,"
");
+ }
+ else
+ {
+ fprintf (Gbl.F.Out,"",ClassTxt);
+
+ /***** Separator *****/
+ fprintf (Gbl.F.Out," > ");
+
+ /***** Hidden degree *****/
+ fprintf (Gbl.F.Out,"%s",Txt_Degree);
+
+ fprintf (Gbl.F.Out,"
");
+ }
+
+ fprintf (Gbl.F.Out,"",
+ (Gbl.CurrentCrs.Crs.CrsCod > 0) ? "" :
+ ((Gbl.CurrentDeg.Deg.DegCod > 0) ? " BC_SEMIOFF" :
+ " BC_OFF"),
+ ClassTxt);
+
+ /***** Separator *****/
+ fprintf (Gbl.F.Out," > ");
+
+ fprintf (Gbl.F.Out,"
");
+ }
+
+/*****************************************************************************/
+/*************** Write course full name in the top of the page ***************/
+/*****************************************************************************/
+
+void Hie_WriteBigNameCtyInsCtrDegCrs (void)
+ {
+ extern const char *The_ClassCourse[The_NUM_THEMES];
+ extern const char *Txt_TAGLINE;
+
+ fprintf (Gbl.F.Out,"",
+ The_ClassCourse[Gbl.Prefs.Theme]);
+
+ /***** Logo *****/
+ if (Gbl.CurrentCrs.Crs.CrsCod > 0 ||
+ Gbl.CurrentDeg.Deg.DegCod > 0)
+ Log_DrawLogo (Sco_SCOPE_DEG,Gbl.CurrentDeg.Deg.DegCod,
+ Gbl.CurrentDeg.Deg.ShrtName,40,"TOP_LOGO",false);
+ else if (Gbl.CurrentCtr.Ctr.CtrCod > 0)
+ Log_DrawLogo (Sco_SCOPE_CTR,Gbl.CurrentCtr.Ctr.CtrCod,
+ Gbl.CurrentCtr.Ctr.ShrtName,40,"TOP_LOGO",false);
+ else if (Gbl.CurrentIns.Ins.InsCod > 0)
+ Log_DrawLogo (Sco_SCOPE_INS,Gbl.CurrentIns.Ins.InsCod,
+ Gbl.CurrentIns.Ins.ShrtName,40,"TOP_LOGO",false);
+ else if (Gbl.CurrentCty.Cty.CtyCod > 0)
+ Cty_DrawCountryMap (&Gbl.CurrentCty.Cty,"COUNTRY_MAP_TITLE");
+ else
+ fprintf (Gbl.F.Out,"",
+ Gbl.Prefs.IconsURL,Cfg_PLATFORM_LOGO_SMALL_FILENAME,
+ Cfg_PLATFORM_SHORT_NAME,Cfg_PLATFORM_FULL_NAME);
+
+ /***** Text *****/
+ fprintf (Gbl.F.Out,"");
+ if (Gbl.CurrentCty.Cty.CtyCod > 0)
+ fprintf (Gbl.F.Out,"
"
+ "%s" // Full name
+ "
"
+ "
"
+ " / " // To separate
+ "
"
+ "
"
+ "%s" // Short name
+ "
",
+ (Gbl.CurrentCrs.Crs.CrsCod > 0) ? Gbl.CurrentCrs.Crs.FullName :
+ ((Gbl.CurrentDeg.Deg.DegCod > 0) ? Gbl.CurrentDeg.Deg.FullName :
+ ((Gbl.CurrentCtr.Ctr.CtrCod > 0) ? Gbl.CurrentCtr.Ctr.FullName :
+ ((Gbl.CurrentIns.Ins.InsCod > 0) ? Gbl.CurrentIns.Ins.FullName :
+ Gbl.CurrentCty.Cty.Name[Gbl.Prefs.Language]))),
+ (Gbl.CurrentCrs.Crs.CrsCod > 0) ? Gbl.CurrentCrs.Crs.ShrtName :
+ ((Gbl.CurrentDeg.Deg.DegCod > 0) ? Gbl.CurrentDeg.Deg.ShrtName :
+ ((Gbl.CurrentCtr.Ctr.CtrCod > 0) ? Gbl.CurrentCtr.Ctr.ShrtName :
+ ((Gbl.CurrentIns.Ins.InsCod > 0) ? Gbl.CurrentIns.Ins.ShrtName :
+ Gbl.CurrentCty.Cty.Name[Gbl.Prefs.Language]))));
+ else // No country specified ==> home page
+ fprintf (Gbl.F.Out,"
"
+ "%s: %s" // Full name
+ "
"
+ "
"
+ " / " // To separate
+ "
"
+ "
"
+ "%s" // Short name
+ "
",
+ Cfg_PLATFORM_SHORT_NAME,Txt_TAGLINE,
+ Cfg_PLATFORM_SHORT_NAME);
+ fprintf (Gbl.F.Out,"
"
+ "
");
+ }
+
+/*****************************************************************************/
+/**** Initialize current country, institution, centre, degree and course *****/
+/*****************************************************************************/
+
+void Hie_InitHierarchy (void)
+ {
+ /***** If course code is available, get course data *****/
+ if (Gbl.CurrentCrs.Crs.CrsCod > 0)
+ {
+ if (Crs_GetDataOfCourseByCod (&Gbl.CurrentCrs.Crs)) // Course found
+ Gbl.CurrentDeg.Deg.DegCod = Gbl.CurrentCrs.Crs.DegCod;
+ else
+ {
+ Gbl.CurrentIns.Ins.InsCod =
+ Gbl.CurrentCtr.Ctr.CtrCod =
+ Gbl.CurrentDeg.Deg.DegCod =
+ Gbl.CurrentCrs.Crs.CrsCod = -1L;
+ }
+ }
+
+ /***** If degree code is available, get degree data *****/
+ if (Gbl.CurrentDeg.Deg.DegCod > 0)
+ {
+ if (Deg_GetDataOfDegreeByCod (&Gbl.CurrentDeg.Deg)) // Degree found
+ {
+ Gbl.CurrentCtr.Ctr.CtrCod = Gbl.CurrentDeg.Deg.CtrCod;
+ Gbl.CurrentDegTyp.DegTyp.DegTypCod = Gbl.CurrentDeg.Deg.DegTypCod;
+ Gbl.CurrentIns.Ins.InsCod = Deg_GetInsCodOfDegreeByCod (Gbl.CurrentDeg.Deg.DegCod);
+
+ /***** Degree type is available, so get degree type data *****/
+ if (!DT_GetDataOfDegreeTypeByCod (&Gbl.CurrentDegTyp.DegTyp)) // Degree type not found
+ {
+ Gbl.CurrentIns.Ins.InsCod =
+ Gbl.CurrentCtr.Ctr.CtrCod =
+ Gbl.CurrentDeg.Deg.DegTypCod =
+ Gbl.CurrentDeg.Deg.DegCod =
+ Gbl.CurrentCrs.Crs.CrsCod = -1L;
+ }
+ }
+ else
+ {
+ Gbl.CurrentIns.Ins.InsCod =
+ Gbl.CurrentCtr.Ctr.CtrCod =
+ Gbl.CurrentDeg.Deg.DegCod =
+ Gbl.CurrentCrs.Crs.CrsCod = -1L;
+ }
+ }
+
+ /***** If centre code is available, get centre data *****/
+ if (Gbl.CurrentCtr.Ctr.CtrCod > 0)
+ {
+ if (Ctr_GetDataOfCentreByCod (&Gbl.CurrentCtr.Ctr)) // Centre found
+ Gbl.CurrentIns.Ins.InsCod = Gbl.CurrentCtr.Ctr.InsCod;
+ else
+ Gbl.CurrentCtr.Ctr.CtrCod = -1L;
+ }
+
+ /***** If institution code is available, get institution data *****/
+ if (Gbl.CurrentIns.Ins.InsCod > 0)
+ {
+ if (Ins_GetDataOfInstitutionByCod (&Gbl.CurrentIns.Ins,Ins_GET_BASIC_DATA)) // Institution found
+ Gbl.CurrentCty.Cty.CtyCod = Gbl.CurrentIns.Ins.CtyCod;
+ else
+ {
+ Gbl.CurrentCty.Cty.CtyCod =
+ Gbl.CurrentIns.Ins.InsCod =
+ Gbl.CurrentCtr.Ctr.CtrCod =
+ Gbl.CurrentDeg.Deg.DegCod =
+ Gbl.CurrentCrs.Crs.CrsCod = -1L;
+ }
+ }
+
+ /***** If country code is available, get country data *****/
+ if (Gbl.CurrentCty.Cty.CtyCod > 0)
+ {
+ if (!Cty_GetDataOfCountryByCod (&Gbl.CurrentCty.Cty,Cty_GET_BASIC_DATA)) // Country not found
+ {
+ Gbl.CurrentCty.Cty.CtyCod =
+ Gbl.CurrentIns.Ins.InsCod =
+ Gbl.CurrentCtr.Ctr.CtrCod =
+ Gbl.CurrentDeg.Deg.DegCod =
+ Gbl.CurrentCrs.Crs.CrsCod = -1L;
+ }
+ }
+
+ /***** Initialize default fields for edition to current values *****/
+ Gbl.Inss.EditingIns.CtyCod = Gbl.CurrentCty.Cty.CtyCod;
+ Gbl.Ctrs.EditingCtr.InsCod =
+ Gbl.Dpts.EditingDpt.InsCod = Gbl.CurrentIns.Ins.InsCod;
+ Gbl.Degs.EditingDeg.CtrCod = Gbl.CurrentCtr.Ctr.CtrCod;
+ Gbl.Degs.EditingDeg.DegTypCod = Gbl.CurrentDegTyp.DegTyp.DegTypCod;
+
+ /***** Initialize paths *****/
+ if (Gbl.CurrentCrs.Crs.CrsCod > 0)
+ {
+ /***** Paths of course directories *****/
+ sprintf (Gbl.CurrentCrs.PathPriv,"%s/%s/%ld",
+ Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_CRS,Gbl.CurrentCrs.Crs.CrsCod);
+ sprintf (Gbl.CurrentCrs.PathRelPubl,"%s/%s/%ld",
+ Cfg_PATH_SWAD_PUBLIC ,Cfg_FOLDER_CRS,Gbl.CurrentCrs.Crs.CrsCod);
+ sprintf (Gbl.CurrentCrs.PathURLPubl,"%s/%s/%ld",
+ Cfg_URL_SWAD_PUBLIC,Cfg_FOLDER_CRS,Gbl.CurrentCrs.Crs.CrsCod);
+
+ /***** If any of the course directories does not exist, create it *****/
+ if (!Fil_CheckIfPathExists (Gbl.CurrentCrs.PathPriv))
+ Fil_CreateDirIfNotExists (Gbl.CurrentCrs.PathPriv);
+ if (!Fil_CheckIfPathExists (Gbl.CurrentCrs.PathRelPubl))
+ Fil_CreateDirIfNotExists (Gbl.CurrentCrs.PathRelPubl);
+
+ /***** Count number of groups in current course
+ (used in some actions) *****/
+ Gbl.CurrentCrs.Grps.NumGrps = Grp_CountNumGrpsInCurrentCrs ();
+ }
+ }
diff --git a/swad_hierarchy.h b/swad_hierarchy.h
new file mode 100644
index 000000000..f30468e50
--- /dev/null
+++ b/swad_hierarchy.h
@@ -0,0 +1,49 @@
+// swad_hierarchy.h: hierarchy (system, institution, centre, degree, course)
+
+#ifndef _SWAD_HIE
+#define _SWAD_HIE
+/*
+ SWAD (Shared Workspace At a Distance in Spanish),
+ 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-2016 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 ***********************************/
+/*****************************************************************************/
+
+/*****************************************************************************/
+/***************************** Public constants ******************************/
+/*****************************************************************************/
+
+/*****************************************************************************/
+/******************************* Public types ********************************/
+/*****************************************************************************/
+
+/*****************************************************************************/
+/***************************** Public prototypes *****************************/
+/*****************************************************************************/
+
+void Hie_WriteMenuHierarchy (void);
+void Hie_WriteHierarchyBreadcrumb (void);
+void Hie_WriteBigNameCtyInsCtrDegCrs (void);
+void Hie_InitHierarchy (void);
+
+void Hie_GetAndWriteInsCtrDegAdminBy (long UsrCod,unsigned ColSpan);
+
+#endif