diff --git a/Makefile b/Makefile
index 0ba1442a..de86fdcb 100644
--- a/Makefile
+++ b/Makefile
@@ -29,7 +29,7 @@
OBJS = swad_account.o swad_action.o swad_announcement.o swad_assignment.o swad_attendance.o \
swad_banner.o \
swad_calendar.o swad_centre.o swad_chat.o swad_config.o swad_connected.o swad_country.o swad_course.o swad_cryptography.o \
- swad_database.o swad_date.o swad_degree.o swad_department.o \
+ swad_database.o swad_date.o swad_degree.o swad_degree_type.o swad_department.o \
swad_enrollment.o swad_exam.o \
swad_file.o swad_file_browser.o swad_follow.o swad_forum.o \
swad_global.o swad_group.o \
diff --git a/swad_action.c b/swad_action.c
index 821aed0d..67e89833 100644
--- a/swad_action.c
+++ b/swad_action.c
@@ -41,6 +41,7 @@
#include "swad_course.h"
#include "swad_chat.h"
#include "swad_database.h"
+#include "swad_degree_type.h"
#include "swad_exam.h"
#include "swad_enrollment.h"
#include "swad_follow.h"
diff --git a/swad_changelog.h b/swad_changelog.h
index e03a33f4..9238e6a8 100644
--- a/swad_changelog.h
+++ b/swad_changelog.h
@@ -129,19 +129,19 @@
// TODO: Icon to the left in list of forums is not correct when scope is system
// TODO: Move info about number of files to bottom of file browsers
-// TODO: New module swad_degree_type (DeT_*) for degree types.
/*****************************************************************************/
/****************************** Public constants *****************************/
/*****************************************************************************/
-#define Log_PLATFORM_VERSION "SWAD 15.155.7 (2016-03-20)"
+#define Log_PLATFORM_VERSION "SWAD 15.156 (2016-03-20)"
#define CSS_FILE "swad15.152.css"
#define JS_FILE "swad15.131.3.js"
// Number of lines (includes comments but not blank lines) has been got with the following command:
// nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*.h sql/swad*.sql | tail -1
/*
+ Version 15.156: Mar 20, 2016 New module swad_degree_type for degree types. (196137 lines)
Version 15.155.7: Mar 20, 2016 Changes in layout of listing of institutions. (196051 lines)
Version 15.155.6: Mar 20, 2016 Changes in layout of listing of centres. (196055 lines)
Version 15.155.5: Mar 20, 2016 Changes in behaviour of hierarchy breadcrumb.
diff --git a/swad_degree.c b/swad_degree.c
index e0a40087..044dde6e 100644
--- a/swad_degree.c
+++ b/swad_degree.c
@@ -37,6 +37,7 @@
#include "swad_config.h"
#include "swad_database.h"
#include "swad_degree.h"
+#include "swad_degree_type.h"
#include "swad_exam.h"
#include "swad_global.h"
#include "swad_help.h"
@@ -87,45 +88,29 @@ typedef enum
static void Deg_Configuration (bool PrintView);
static void Deg_PutIconToPrint (void);
-static void Deg_ListDegreeTypes (void);
static void Deg_WriteSelectorOfDegree (void);
-static void Deg_EditDegreeTypes (void);
-static void Deg_ListDegreeTypesForSeeing (void);
-static void Deg_PutIconToEditDegTypes (void);
-static void Deg_ListDegreeTypesForEdition (void);
static void Deg_ListDegreesForEdition (void);
static bool Deg_CheckIfICanEdit (struct Degree *Deg);
static Deg_StatusTxt_t Deg_GetStatusTxtFromStatusBits (Deg_Status_t Status);
static Deg_Status_t Deg_GetStatusBitsFromStatusTxt (Deg_StatusTxt_t StatusTxt);
-static void Deg_PutFormToCreateDegType (void);
static void Deg_PutFormToCreateDegree (void);
-static void Deg_PutHeadDegreeTypesForSeeing (void);
-static void Deg_PutHeadDegreeTypesForEdition (void);
static void Deg_PutHeadDegreesForSeeing (void);
static void Deg_PutHeadDegreesForEdition (void);
-static void Deg_CreateDegreeType (struct DegreeType *DegTyp);
static void Deg_CreateDegree (struct Degree *Deg,unsigned Status);
static void Deg_ListDegrees (void);
static void Deg_PutIconToEditDegrees (void);
static void Deg_ListOneDegreeForSeeing (struct Degree *Deg,unsigned NumDeg);
-static void Deg_GetListDegTypes (void);
static void Deg_GetListDegsOfCurrentCtr (void);
static void Deg_FreeListDegsOfCurrentCtr (void);
static void Deg_RecFormRequestOrCreateDeg (unsigned Status);
-static void Deg_PutParamOtherDegTypCod (long DegTypCod);
static void Deg_PutParamOtherDegCod (long DegCod);
-static unsigned Deg_CountNumDegsOfType (long DegTypCod);
static void Deg_GetDataOfDegreeFromRow (struct Degree *Deg,MYSQL_ROW row);
-static void Deg_RemoveDegreeTypeCompletely (long DegTypCod);
-static void Deg_RemoveDegreeCompletely (long DegCod);
static bool Deg_RenameDegree (struct Degree *Deg,Cns_ShortOrFullName_t ShortOrFullName);
-static bool Deg_CheckIfDegreeTypeNameExists (const char *DegTypName,long DegTypCod);
static bool Deg_CheckIfDegreeNameExists (long CtrCod,const char *FieldName,const char *Name,long DegCod);
-static void Deg_PutButtonToGoToDeg (struct Degree *Deg);
/*****************************************************************************/
/********** List pending institutions, centres, degrees and courses **********/
@@ -1011,74 +996,6 @@ void Deg_InitCurrentCourse (void)
}
}
-/*****************************************************************************/
-/************** Show selector of degree types for statistics *****************/
-/*****************************************************************************/
-
-void Deg_WriteSelectorDegTypes (void)
- {
- extern const char *Txt_Any_type_of_degree;
- unsigned NumDegTyp;
-
- /***** Get degree type code *****/
- Gbl.Stat.DegTypCod = Deg_GetParamOtherDegTypCod ();
-
- /***** Get list of degree types *****/
- Deg_GetListDegTypes ();
-
- /***** List degree types *****/
- fprintf (Gbl.F.Out,"");
-
- /***** Free list of degree types *****/
- Deg_FreeListDegTypes ();
- }
-
-/*****************************************************************************/
-/***************************** Show degree types *****************************/
-/*****************************************************************************/
-
-void Deg_SeeDegTypes (void)
- {
- /***** Get list of degree types *****/
- Deg_GetListDegTypes ();
-
- /***** List degree types *****/
- Deg_ListDegreeTypes ();
-
- /***** Free list of degree types *****/
- Deg_FreeListDegTypes ();
- }
-
-/*****************************************************************************/
-/********************** Request edition of degree types **********************/
-/*****************************************************************************/
-
-void Deg_ReqEditDegreeTypes (void)
- {
- /***** Get list of degree types *****/
- Deg_GetListDegTypes ();
-
- /***** Put form to edit degree types *****/
- Deg_EditDegreeTypes ();
-
- /***** Free list of degree types *****/
- Deg_FreeListDegTypes ();
- }
-
/*****************************************************************************/
/************* Show the degrees belonging to the current centre **************/
/*****************************************************************************/
@@ -1103,178 +1020,6 @@ void Deg_ShowDegsOfCurrentCtr (void)
}
}
-/*****************************************************************************/
-/***************************** List degree types *****************************/
-/*****************************************************************************/
-
-static void Deg_ListDegreeTypes (void)
- {
- extern const char *Txt_There_are_no_types_of_degree;
-
- if (Gbl.Degs.DegTypes.Num)
- Deg_ListDegreeTypesForSeeing ();
- else
- Lay_ShowAlert (Lay_INFO,Txt_There_are_no_types_of_degree);
- }
-
-/*****************************************************************************/
-/************************ Put forms to edit degree types *********************/
-/*****************************************************************************/
-
-static void Deg_EditDegreeTypes (void)
- {
- extern const char *Txt_There_are_no_types_of_degree;
-
- if (!Gbl.Degs.DegTypes.Num)
- /***** Help message *****/
- Lay_ShowAlert (Lay_INFO,Txt_There_are_no_types_of_degree);
-
- /***** Put a form to create a new degree type *****/
- Deg_PutFormToCreateDegType ();
-
- /***** Forms to edit current degree types *****/
- if (Gbl.Degs.DegTypes.Num)
- Deg_ListDegreeTypesForEdition ();
- }
-
-/*****************************************************************************/
-/******************* List current degree types for seeing ********************/
-/*****************************************************************************/
-
-static void Deg_ListDegreeTypesForSeeing (void)
- {
- extern const char *Txt_Types_of_degree;
- extern const char *Txt_TYPES_OF_DEGREE_With_degrees;
- extern const char *Txt_TYPES_OF_DEGREE_Without_degrees;
- unsigned NumDegTyp;
- const char *BgColor;
-
- /***** Write heading *****/
- Lay_StartRoundFrame (NULL,Txt_Types_of_degree,
- Gbl.Usrs.Me.LoggedRole == Rol_SYS_ADM ? Deg_PutIconToEditDegTypes :
- NULL);
- fprintf (Gbl.F.Out,"
");
- Deg_PutHeadDegreeTypesForSeeing ();
-
- /***** List degree types with forms for edition *****/
- for (NumDegTyp = 0;
- NumDegTyp < Gbl.Degs.DegTypes.Num;
- NumDegTyp++)
- {
- BgColor = (Gbl.Degs.DegTypes.Lst[NumDegTyp].DegTypCod ==
- Gbl.CurrentDegTyp.DegTyp.DegTypCod) ? "LIGHT_BLUE" :
- Gbl.ColorRows[Gbl.RowEvenOdd];
-
- /* Put green tip if degree type has degrees */
- fprintf (Gbl.F.Out,"
",
- Txt_Code,
- Txt_Type_of_BR_degree,
- Txt_Degrees);
- }
-
/*****************************************************************************/
/******************** Write header with fields of a degree *******************/
/*****************************************************************************/
@@ -1882,26 +1539,6 @@ unsigned Deg_ConvStrToYear (const char *StrYear)
return (unsigned) Year;
}
-/*****************************************************************************/
-/************************** Create a new degree type *************************/
-/*****************************************************************************/
-
-static void Deg_CreateDegreeType (struct DegreeType *DegTyp)
- {
- extern const char *Txt_Created_new_type_of_degree_X;
- char Query[128+Deg_MAX_LENGTH_DEGREE_TYPE_NAME];
-
- /***** Create a new degree type *****/
- sprintf (Query,"INSERT INTO deg_types SET DegTypName='%s'",
- DegTyp->DegTypName);
- DB_QueryINSERT (Query,"can not create a new type of degree");
-
- /***** Write success message *****/
- sprintf (Gbl.Message,Txt_Created_new_type_of_degree_X,
- DegTyp->DegTypName);
- Lay_ShowAlert (Lay_SUCCESS,Gbl.Message);
- }
-
/*****************************************************************************/
/***************************** Create a new degree ***************************/
/*****************************************************************************/
@@ -2133,61 +1770,6 @@ void Deg_EditDegrees (void)
Deg_FreeListDegsOfCurrentCtr ();
}
-/*****************************************************************************/
-/**************** Create a list with all the degree types ********************/
-/*****************************************************************************/
-
-static void Deg_GetListDegTypes (void)
- {
- char Query[1024];
- MYSQL_RES *mysql_res;
- MYSQL_ROW row;
- unsigned long NumRow;
-
- /***** Get types of degree from database *****/
- sprintf (Query,"(SELECT deg_types.DegTypCod,deg_types.DegTypName AS DegTypName,"
- " COUNT(degrees.DegCod)"
- " FROM deg_types,degrees WHERE deg_types.DegTypCod=degrees.DegTypCod"
- " GROUP BY degrees.DegTypCod)"
- " UNION "
- "(SELECT DegTypCod,DegTypName,'0'"
- " FROM deg_types WHERE DegTypCod NOT IN (SELECT DegTypCod FROM degrees))"
- " ORDER BY DegTypName");
- Gbl.Degs.DegTypes.Num = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get types of degree");
-
- /***** Get degree types *****/
- if (Gbl.Degs.DegTypes.Num)
- {
- /***** Create a list of degree types *****/
- if ((Gbl.Degs.DegTypes.Lst = (struct DegreeType *) calloc (Gbl.Degs.DegTypes.Num,sizeof (struct DegreeType))) == NULL)
- Lay_ShowErrorAndExit ("Not enough memory to store types of degree.");
-
- /***** Get degree types *****/
- for (NumRow = 0;
- NumRow < Gbl.Degs.DegTypes.Num;
- NumRow++)
- {
- /* Get next degree type */
- row = mysql_fetch_row (mysql_res);
-
- /* Get degree type code (row[0]) */
- if ((Gbl.Degs.DegTypes.Lst[NumRow].DegTypCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
- Lay_ShowErrorAndExit ("Wrong code of type of degree.");
-
- /* Get degree type name (row[1]) */
- strncpy (Gbl.Degs.DegTypes.Lst[NumRow].DegTypName,row[1],Deg_MAX_LENGTH_DEGREE_TYPE_NAME);
- Gbl.Degs.DegTypes.Lst[NumRow].DegTypName[Deg_MAX_LENGTH_DEGREE_TYPE_NAME] = '\0';
-
- /* Number of degrees of this type (row[2]) */
- if (sscanf (row[2],"%u",&Gbl.Degs.DegTypes.Lst[NumRow].NumDegs) != 1)
- Lay_ShowErrorAndExit ("Error when getting number of degrees of a type");
- }
- }
-
- /***** Free structure that stores the query result *****/
- DB_FreeMySQLResult (&mysql_res);
- }
-
/*****************************************************************************/
/********************* Create a list with all the degrees ********************/
/*****************************************************************************/
@@ -2301,21 +1883,6 @@ static void Deg_FreeListDegsOfCurrentCtr (void)
}
}
-/*****************************************************************************/
-/********* Free list of degree types and list of degrees of each type ********/
-/*****************************************************************************/
-
-void Deg_FreeListDegTypes (void)
- {
- /***** Free memory used by the list of degree types *****/
- if (Gbl.Degs.DegTypes.Lst)
- {
- free ((void *) Gbl.Degs.DegTypes.Lst);
- Gbl.Degs.DegTypes.Lst = NULL;
- Gbl.Degs.DegTypes.Num = 0;
- }
- }
-
/*****************************************************************************/
/*********** Create a list with the degrees administrated by me **************/
/*****************************************************************************/
@@ -2384,44 +1951,6 @@ void Deg_FreeListMyAdminDegs (void)
}
}
-/*****************************************************************************/
-/***************** Receive form to create a new degree type ******************/
-/*****************************************************************************/
-
-void Deg_RecFormNewDegTyp (void)
- {
- extern const char *Txt_The_type_of_degree_X_already_exists;
- extern const char *Txt_You_must_specify_the_name_of_the_new_type_of_degree;
- struct DegreeType *DegTyp;
-
- DegTyp = &Gbl.Degs.EditingDegTyp;
-
- /***** Get parameters from form *****/
- /* Get the name of degree type */
- Par_GetParToText ("DegTypName",DegTyp->DegTypName,Deg_MAX_LENGTH_DEGREE_TYPE_NAME);
-
- if (DegTyp->DegTypName[0]) // If there's a degree type name
- {
- /***** If name of degree type was in database... *****/
- if (Deg_CheckIfDegreeTypeNameExists (DegTyp->DegTypName,-1L))
- {
- sprintf (Gbl.Message,Txt_The_type_of_degree_X_already_exists,
- DegTyp->DegTypName);
- Lay_ShowAlert (Lay_WARNING,Gbl.Message);
- }
- else // Add new degree type to database
- Deg_CreateDegreeType (DegTyp);
- }
- else // If there is not a degree type name
- {
- sprintf (Gbl.Message,"%s",Txt_You_must_specify_the_name_of_the_new_type_of_degree);
- Lay_ShowAlert (Lay_WARNING,Gbl.Message);
- }
-
- /***** Show the form again *****/
- Deg_ReqEditDegreeTypes ();
- }
-
/*****************************************************************************/
/****************** Receive form to request a new degree *********************/
/*****************************************************************************/
@@ -2506,42 +2035,6 @@ static void Deg_RecFormRequestOrCreateDeg (unsigned Status)
Deg_EditDegrees ();
}
-/*****************************************************************************/
-/**************************** Remove a degree type ***************************/
-/*****************************************************************************/
-
-void Deg_RemoveDegreeType (void)
- {
- extern const char *Txt_To_remove_a_type_of_degree_you_must_first_remove_all_degrees_of_that_type;
- extern const char *Txt_Type_of_degree_X_removed;
- struct DegreeType DegTyp;
-
- /***** Get the code of the degree type *****/
- if ((DegTyp.DegTypCod = Deg_GetParamOtherDegTypCod ()) == -1L)
- Lay_ShowErrorAndExit ("Code of type of degree is missing.");
-
- /***** Get data of the degree type from database *****/
- if (!Deg_GetDataOfDegreeTypeByCod (&DegTyp))
- Lay_ShowErrorAndExit ("Code of type of degree not found.");
-
- /***** Check if this degree type has degrees *****/
- if (DegTyp.NumDegs) // Degree type has degrees ==> don't remove
- Lay_ShowAlert (Lay_WARNING,Txt_To_remove_a_type_of_degree_you_must_first_remove_all_degrees_of_that_type);
- else // Degree type has no degrees ==> remove it
- {
- /***** Remove degree type *****/
- Deg_RemoveDegreeTypeCompletely (DegTyp.DegTypCod);
-
- /***** Write message to show the change made *****/
- sprintf (Gbl.Message,Txt_Type_of_degree_X_removed,
- DegTyp.DegTypName);
- Lay_ShowAlert (Lay_SUCCESS,Gbl.Message);
- }
-
- /***** Show the form again *****/
- Deg_ReqEditDegreeTypes ();
- }
-
/*****************************************************************************/
/************************ Request removing of a degree ***********************/
/*****************************************************************************/
@@ -2577,15 +2070,6 @@ void Deg_RemoveDegree (void)
Deg_EditDegrees ();
}
-/*****************************************************************************/
-/***************** Write parameter with code of degree type ******************/
-/*****************************************************************************/
-
-static void Deg_PutParamOtherDegTypCod (long DegTypCod)
- {
- Par_PutHiddenParamLong ("OthDegTypCod",DegTypCod);
- }
-
/*****************************************************************************/
/******************** Write parameter with code of degree ********************/
/*****************************************************************************/
@@ -2604,19 +2088,6 @@ static void Deg_PutParamOtherDegCod (long DegCod)
Par_PutHiddenParamLong ("OthDegCod",DegCod);
}
-/*****************************************************************************/
-/******************* Get parameter with code of degree type ******************/
-/*****************************************************************************/
-
-long Deg_GetParamOtherDegTypCod (void)
- {
- char LongStr[1+10+1];
-
- /***** Get parameter with code of degree type *****/
- Par_GetParToText ("OthDegTypCod",LongStr,1+10);
- return Str_ConvertStrCodToLongCod (LongStr);
- }
-
/*****************************************************************************/
/********************* Get parameter with code of degree *********************/
/*****************************************************************************/
@@ -2630,75 +2101,6 @@ long Deg_GetParamOtherDegCod (void)
return Str_ConvertStrCodToLongCod (LongStr);
}
-/*****************************************************************************/
-/**************** Count number of degrees in a degree type ******************/
-/*****************************************************************************/
-
-static unsigned Deg_CountNumDegsOfType (long DegTypCod)
- {
- char Query[512];
-
- /***** Get number of degrees of a type from database *****/
- sprintf (Query,"SELECT COUNT(*) FROM degrees WHERE DegTypCod='%ld'",
- DegTypCod);
- return (unsigned) DB_QueryCOUNT (Query,"can not get number of degrees of a type");
- }
-
-/*****************************************************************************/
-/****************** Get data of a degree type from its code ******************/
-/*****************************************************************************/
-
-bool Deg_GetDataOfDegreeTypeByCod (struct DegreeType *DegTyp)
- {
- char Query[512];
- MYSQL_RES *mysql_res;
- MYSQL_ROW row;
- unsigned long NumRows;
- bool DegTypFound = false;
-
- if (DegTyp->DegTypCod <= 0)
- {
- DegTyp->DegTypCod = -1L;
- DegTyp->DegTypName[0] = '\0';
- DegTyp->NumDegs = 0;
- return false;
- }
-
- /***** Get the name of a type of degree from database *****/
- sprintf (Query,"SELECT DegTypName FROM deg_types WHERE DegTypCod='%ld'",
- DegTyp->DegTypCod);
- NumRows = DB_QuerySELECT (Query,&mysql_res,"can not get the name of a type of degree");
-
- if (NumRows == 1)
- {
- /***** Get data of degree type *****/
- row = mysql_fetch_row (mysql_res);
-
- /* Get the name of the degree type (row[0]) */
- strcpy (DegTyp->DegTypName,row[0]);
-
- /* Count number of degrees of this type */
- DegTyp->NumDegs = Deg_CountNumDegsOfType (DegTyp->DegTypCod);
-
- /* Set return value */
- DegTypFound = true;
- }
- else if (NumRows == 0)
- {
- DegTyp->DegTypCod = -1L;
- DegTyp->DegTypName[0] = '\0';
- DegTyp->NumDegs = 0;
- return false;
- }
- else // NumRows > 1
- Lay_ShowErrorAndExit ("Type of degree repeated in database.");
-
- /***** Free structure that stores the query result *****/
- DB_FreeMySQLResult (&mysql_res);
-
- return DegTypFound;
- }
-
/*****************************************************************************/
/********************* Get data of a degree from its code ********************/
/*****************************************************************************/
@@ -2891,52 +2293,11 @@ long Deg_GetInsCodOfDegreeByCod (long DegCod)
return InsCod;
}
-/*****************************************************************************/
-/******************** Remove a degree type and its degrees *******************/
-/*****************************************************************************/
-
-static void Deg_RemoveDegreeTypeCompletely (long DegTypCod)
- {
- char Query[512];
- MYSQL_RES *mysql_res;
- MYSQL_ROW row;
- unsigned long NumRow,NumRows;
- long DegCod;
-
- /***** Get degrees of a type from database *****/
- sprintf (Query,"SELECT DegCod FROM degrees WHERE DegTypCod='%ld'",
- DegTypCod);
- NumRows = DB_QuerySELECT (Query,&mysql_res,"can not get degrees of a type");
-
- /* Get degrees of this type */
- for (NumRow = 0;
- NumRow < NumRows;
- NumRow++)
- {
- /* Get next degree */
- row = mysql_fetch_row (mysql_res);
-
- /* Get degree code (row[0]) */
- if ((DegCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
- Lay_ShowErrorAndExit ("Wrong code of degree.");
-
- /* Remove degree */
- Deg_RemoveDegreeCompletely (DegCod);
- }
-
- /* Free structure that stores the query result */
- DB_FreeMySQLResult (&mysql_res);
-
- /***** Remove the degree type *****/
- sprintf (Query,"DELETE FROM deg_types WHERE DegTypCod='%ld'",DegTypCod);
- DB_QueryDELETE (Query,"can not remove a type of degree");
- }
-
/*****************************************************************************/
/***************************** Remove a degree *******************************/
/*****************************************************************************/
-static void Deg_RemoveDegreeCompletely (long DegCod)
+void Deg_RemoveDegreeCompletely (long DegCod)
{
char Query[512];
MYSQL_RES *mysql_res;
@@ -3028,80 +2389,6 @@ static void Deg_RemoveDegreeCompletely (long DegCod)
Pho_RemoveObsoleteStatDegrees ();
}
-/*****************************************************************************/
-/**************************** Rename a degree type ***************************/
-/*****************************************************************************/
-
-void Deg_RenameDegreeType (void)
- {
- extern const char *Txt_You_can_not_leave_the_name_of_the_type_of_degree_X_empty;
- extern const char *Txt_The_type_of_degree_X_already_exists;
- extern const char *Txt_The_type_of_degree_X_has_been_renamed_as_Y;
- extern const char *Txt_The_name_of_the_type_of_degree_X_has_not_changed;
- struct DegreeType *DegTyp;
- char Query[1024];
- char NewNameDegTyp[Deg_MAX_LENGTH_DEGREE_TYPE_NAME+1];
-
- DegTyp = &Gbl.Degs.EditingDegTyp;
-
- /***** Get parameters from form *****/
- /* Get the code of the degree type */
- if ((DegTyp->DegTypCod = Deg_GetParamOtherDegTypCod ()) == -1L)
- Lay_ShowErrorAndExit ("Code of type of degree is missing.");
-
- /* Get the new name for the degree type */
- Par_GetParToText ("DegTypName",NewNameDegTyp,Deg_MAX_LENGTH_DEGREE_TYPE_NAME);
-
- /***** Get from the database the old name of the degree type *****/
- if (!Deg_GetDataOfDegreeTypeByCod (DegTyp))
- Lay_ShowErrorAndExit ("Code of type of degree not found.");
-
- /***** Check if new name is empty *****/
- if (!NewNameDegTyp[0])
- {
- sprintf (Gbl.Message,Txt_You_can_not_leave_the_name_of_the_type_of_degree_X_empty,
- DegTyp->DegTypName);
- Lay_ShowAlert (Lay_WARNING,Gbl.Message);
- }
- else
- {
- /***** Check if old and new names are the same (this happens when user press enter with no changes in the form) *****/
- if (strcmp (DegTyp->DegTypName,NewNameDegTyp)) // Different names
- {
- /***** If degree type was in database... *****/
- if (Deg_CheckIfDegreeTypeNameExists (NewNameDegTyp,DegTyp->DegTypCod))
- {
- sprintf (Gbl.Message,Txt_The_type_of_degree_X_already_exists,
- NewNameDegTyp);
- Lay_ShowAlert (Lay_WARNING,Gbl.Message);
- }
- else
- {
- /* Update the table changing old name by new name */
- sprintf (Query,"UPDATE deg_types SET DegTypName='%s'"
- " WHERE DegTypCod='%ld'",
- NewNameDegTyp,DegTyp->DegTypCod);
- DB_QueryUPDATE (Query,"can not update the type of a degree");
-
- /* Write message to show the change made */
- sprintf (Gbl.Message,Txt_The_type_of_degree_X_has_been_renamed_as_Y,
- DegTyp->DegTypName,NewNameDegTyp);
- Lay_ShowAlert (Lay_SUCCESS,Gbl.Message);
- }
- }
- else // The same name
- {
- sprintf (Gbl.Message,Txt_The_name_of_the_type_of_degree_X_has_not_changed,
- NewNameDegTyp);
- Lay_ShowAlert (Lay_INFO,Gbl.Message);
- }
- }
-
- /***** Show the form again *****/
- strcpy (DegTyp->DegTypName,NewNameDegTyp);
- Deg_ReqEditDegreeTypes ();
- }
-
/*****************************************************************************/
/********************* Change the short name of a degree *********************/
/*****************************************************************************/
@@ -3224,21 +2511,6 @@ static bool Deg_RenameDegree (struct Degree *Deg,Cns_ShortOrFullName_t ShortOrFu
return DegreeHasBeenRenamed;
}
-/*****************************************************************************/
-/****************** Check if name of degree type exists **********************/
-/*****************************************************************************/
-
-static bool Deg_CheckIfDegreeTypeNameExists (const char *DegTypName,long DegTypCod)
- {
- char Query[512];
-
- /***** Get number of degree types with a name from database *****/
- sprintf (Query,"SELECT COUNT(*) FROM deg_types"
- " WHERE DegTypName='%s' AND DegTypCod<>'%ld'",
- DegTypName,DegTypCod);
- return (DB_QueryCOUNT (Query,"can not check if the name of a type of degree already existed") != 0);
- }
-
/*****************************************************************************/
/********************* Check if the name of degree exists ********************/
/*****************************************************************************/
@@ -3254,48 +2526,6 @@ static bool Deg_CheckIfDegreeNameExists (long CtrCod,const char *FieldName,const
return (DB_QueryCOUNT (Query,"can not check if the name of a degree already existed") != 0);
}
-/*****************************************************************************/
-/************************ Change the type of a degree ************************/
-/*****************************************************************************/
-
-void Deg_ChangeDegreeType (void)
- {
- extern const char *Txt_The_type_of_degree_of_the_degree_X_has_changed;
- struct Degree *Deg;
- long NewDegTypCod;
- char Query[512];
-
- Deg = &Gbl.Degs.EditingDeg;
-
- /***** Get parameters from form *****/
- /* Get degree code */
- if ((Deg->DegCod = Deg_GetParamOtherDegCod ()) == -1L)
- Lay_ShowErrorAndExit ("Code of degree is missing.");
-
- /* Get the new degree type */
- NewDegTypCod = Deg_GetParamOtherDegTypCod ();
-
- /***** Get data of degree *****/
- Deg_GetDataOfDegreeByCod (Deg);
-
- /***** Update the table of degrees changing old type by new type *****/
- sprintf (Query,"UPDATE degrees SET DegTypCod='%ld' WHERE DegCod='%ld'",
- NewDegTypCod,Deg->DegCod);
- DB_QueryUPDATE (Query,"can not update the type of a degree");
-
- /***** Write message to show the change made *****/
- sprintf (Gbl.Message,Txt_The_type_of_degree_of_the_degree_X_has_changed,
- Deg->FullName);
- Lay_ShowAlert (Lay_SUCCESS,Gbl.Message);
-
- /***** Put button to go to degree changed *****/
- Deg_PutButtonToGoToDeg (Deg);
-
- /***** Show the form again *****/
- Gbl.Degs.EditingDegTyp.DegTypCod = NewDegTypCod;
- Deg_EditDegrees ();
- }
-
/*****************************************************************************/
/************************ Change the centre of a degree **********************/
/*****************************************************************************/
@@ -3466,7 +2696,7 @@ void Deg_ContEditAfterChgDeg (void)
/************************ Put button to go to degree *************************/
/*****************************************************************************/
-static void Deg_PutButtonToGoToDeg (struct Degree *Deg)
+void Deg_PutButtonToGoToDeg (struct Degree *Deg)
{
extern const char *Txt_Go_to_X;
diff --git a/swad_degree.h b/swad_degree.h
index 8c2607db..17d76e89 100644
--- a/swad_degree.h
+++ b/swad_degree.h
@@ -40,7 +40,6 @@
#define Deg_MAX_DEGREES_PER_USR 20 // Used in list of my degrees
-#define Deg_MAX_LENGTH_DEGREE_TYPE_NAME 32
#define Deg_MAX_LENGTH_DEGREE_SHORT_NAME 32
#define Deg_MAX_LENGTH_DEGREE_FULL_NAME 127
@@ -80,12 +79,6 @@ struct Degree
unsigned NumCrss; // Number of courses in the degree
struct Course *LstCrss; // List of courses in this degree
};
-struct DegreeType
- {
- long DegTypCod; // Degree type code
- char DegTypName[Deg_MAX_LENGTH_DEGREE_TYPE_NAME+1]; // Degree type name
- unsigned NumDegs; // Number of degrees of this type
- };
/*****************************************************************************/
/***************************** Public prototypes *****************************/
@@ -105,9 +98,6 @@ void Deg_WriteHierarchyBreadcrumb (void);
void Deg_WriteBigNameCtyInsCtrDegCrs (void);
void Deg_InitCurrentCourse (void);
-void Deg_WriteSelectorDegTypes (void);
-void Deg_SeeDegTypes (void);
-void Deg_ReqEditDegreeTypes (void);
void Deg_ShowDegsOfCurrentCtr (void);
unsigned Deg_ConvStrToYear (const char *StrYear);
@@ -116,34 +106,30 @@ void Deg_EditDegrees (void);
void Deg_GetListAllDegs (void);
void Deg_FreeListAllDegs (void);
-void Deg_FreeListDegTypes (void);
void Deg_GetListDegsAdminByMe (void);
void Deg_FreeListMyAdminDegs (void);
-void Deg_RecFormNewDegTyp (void);
void Deg_RecFormReqDeg (void);
void Deg_RecFormNewDeg (void);
-void Deg_RemoveDegreeType (void);
void Deg_RemoveDegree (void);
void Deg_PutParamDegCod (long DegCod);
-long Deg_GetParamOtherDegTypCod (void);
long Deg_GetParamOtherDegCod (void);
-bool Deg_GetDataOfDegreeTypeByCod (struct DegreeType *DegTyp);
bool Deg_GetDataOfDegreeByCod (struct Degree *Deg);
void Deg_GetShortNameOfDegreeByCod (struct Degree *Deg);
long Deg_GetCtrCodOfDegreeByCod (long DegCod);
long Deg_GetInsCodOfDegreeByCod (long DegCod);
-void Deg_RenameDegreeType (void);
+void Deg_RemoveDegreeCompletely (long DegCod);
void Deg_RenameDegreeShort (void);
void Deg_RenameDegreeFull (void);
-void Deg_ChangeDegreeType (void);
void Deg_ChangeDegreeCtr (void);
void Deg_ChangeDegWWW (void);
void Deg_ChangeDegStatus (void);
void Deg_ContEditAfterChgDeg (void);
+void Deg_PutButtonToGoToDeg (struct Degree *Deg);
+
void Deg_RequestLogo (void);
void Deg_ReceiveLogo (void);
void Deg_RemoveLogo (void);
diff --git a/swad_degree_type.c b/swad_degree_type.c
new file mode 100644
index 00000000..60243d3d
--- /dev/null
+++ b/swad_degree_type.c
@@ -0,0 +1,835 @@
+// swad_degree_type.c: degree types
+
+/*
+ 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-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 ***********************************/
+/*****************************************************************************/
+
+#include // For isprint, isspace, etc.
+#include // For NULL
+#include // For boolean type
+#include // For fprintf, etc.
+#include // For exit, system, calloc, free, etc.
+#include // For string functions
+#include // To access MySQL databases
+
+#include "swad_config.h"
+#include "swad_database.h"
+#include "swad_degree.h"
+#include "swad_degree_type.h"
+#include "swad_global.h"
+#include "swad_parameter.h"
+
+/*****************************************************************************/
+/************** External global variables from others modules ****************/
+/*****************************************************************************/
+
+extern struct Globals Gbl;
+
+/*****************************************************************************/
+/*************************** Public constants ********************************/
+/*****************************************************************************/
+
+/*****************************************************************************/
+/***************************** Private types *********************************/
+/*****************************************************************************/
+
+/*****************************************************************************/
+/**************************** Private constants ******************************/
+/*****************************************************************************/
+
+/*****************************************************************************/
+/**************************** Private prototypes *****************************/
+/*****************************************************************************/
+
+static void Deg_ListDegreeTypes (void);
+static void Deg_EditDegreeTypes (void);
+static void Deg_ListDegreeTypesForSeeing (void);
+static void Deg_PutIconToEditDegTypes (void);
+static void Deg_ListDegreeTypesForEdition (void);
+
+static void Deg_PutFormToCreateDegType (void);
+static void Deg_PutHeadDegreeTypesForSeeing (void);
+static void Deg_PutHeadDegreeTypesForEdition (void);
+static void Deg_CreateDegreeType (struct DegreeType *DegTyp);
+
+static void Deg_PutParamOtherDegTypCod (long DegTypCod);
+
+static unsigned Deg_CountNumDegsOfType (long DegTypCod);
+static void Deg_RemoveDegreeTypeCompletely (long DegTypCod);
+static bool Deg_CheckIfDegreeTypeNameExists (const char *DegTypName,long DegTypCod);
+
+/*****************************************************************************/
+/************** Show selector of degree types for statistics *****************/
+/*****************************************************************************/
+
+void Deg_WriteSelectorDegTypes (void)
+ {
+ extern const char *Txt_Any_type_of_degree;
+ unsigned NumDegTyp;
+
+ /***** Get degree type code *****/
+ Gbl.Stat.DegTypCod = Deg_GetParamOtherDegTypCod ();
+
+ /***** Get list of degree types *****/
+ Deg_GetListDegTypes ();
+
+ /***** List degree types *****/
+ fprintf (Gbl.F.Out,"");
+
+ /***** Free list of degree types *****/
+ Deg_FreeListDegTypes ();
+ }
+
+/*****************************************************************************/
+/***************************** Show degree types *****************************/
+/*****************************************************************************/
+
+void Deg_SeeDegTypes (void)
+ {
+ /***** Get list of degree types *****/
+ Deg_GetListDegTypes ();
+
+ /***** List degree types *****/
+ Deg_ListDegreeTypes ();
+
+ /***** Free list of degree types *****/
+ Deg_FreeListDegTypes ();
+ }
+
+/*****************************************************************************/
+/********************** Request edition of degree types **********************/
+/*****************************************************************************/
+
+void Deg_ReqEditDegreeTypes (void)
+ {
+ /***** Get list of degree types *****/
+ Deg_GetListDegTypes ();
+
+ /***** Put form to edit degree types *****/
+ Deg_EditDegreeTypes ();
+
+ /***** Free list of degree types *****/
+ Deg_FreeListDegTypes ();
+ }
+
+/*****************************************************************************/
+/***************************** List degree types *****************************/
+/*****************************************************************************/
+
+static void Deg_ListDegreeTypes (void)
+ {
+ extern const char *Txt_There_are_no_types_of_degree;
+
+ if (Gbl.Degs.DegTypes.Num)
+ Deg_ListDegreeTypesForSeeing ();
+ else
+ Lay_ShowAlert (Lay_INFO,Txt_There_are_no_types_of_degree);
+ }
+
+/*****************************************************************************/
+/************************ Put forms to edit degree types *********************/
+/*****************************************************************************/
+
+static void Deg_EditDegreeTypes (void)
+ {
+ extern const char *Txt_There_are_no_types_of_degree;
+
+ if (!Gbl.Degs.DegTypes.Num)
+ /***** Help message *****/
+ Lay_ShowAlert (Lay_INFO,Txt_There_are_no_types_of_degree);
+
+ /***** Put a form to create a new degree type *****/
+ Deg_PutFormToCreateDegType ();
+
+ /***** Forms to edit current degree types *****/
+ if (Gbl.Degs.DegTypes.Num)
+ Deg_ListDegreeTypesForEdition ();
+ }
+
+/*****************************************************************************/
+/******************* List current degree types for seeing ********************/
+/*****************************************************************************/
+
+static void Deg_ListDegreeTypesForSeeing (void)
+ {
+ extern const char *Txt_Types_of_degree;
+ extern const char *Txt_TYPES_OF_DEGREE_With_degrees;
+ extern const char *Txt_TYPES_OF_DEGREE_Without_degrees;
+ unsigned NumDegTyp;
+ const char *BgColor;
+
+ /***** Write heading *****/
+ Lay_StartRoundFrame (NULL,Txt_Types_of_degree,
+ Gbl.Usrs.Me.LoggedRole == Rol_SYS_ADM ? Deg_PutIconToEditDegTypes :
+ NULL);
+ fprintf (Gbl.F.Out,"
");
+ Deg_PutHeadDegreeTypesForSeeing ();
+
+ /***** List degree types with forms for edition *****/
+ for (NumDegTyp = 0;
+ NumDegTyp < Gbl.Degs.DegTypes.Num;
+ NumDegTyp++)
+ {
+ BgColor = (Gbl.Degs.DegTypes.Lst[NumDegTyp].DegTypCod ==
+ Gbl.CurrentDegTyp.DegTyp.DegTypCod) ? "LIGHT_BLUE" :
+ Gbl.ColorRows[Gbl.RowEvenOdd];
+
+ /* Put green tip if degree type has degrees */
+ fprintf (Gbl.F.Out,"
",
+ Txt_Code,
+ Txt_Type_of_BR_degree,
+ Txt_Degrees);
+ }
+
+/*****************************************************************************/
+/************************** Create a new degree type *************************/
+/*****************************************************************************/
+
+static void Deg_CreateDegreeType (struct DegreeType *DegTyp)
+ {
+ extern const char *Txt_Created_new_type_of_degree_X;
+ char Query[128+Deg_MAX_LENGTH_DEGREE_TYPE_NAME];
+
+ /***** Create a new degree type *****/
+ sprintf (Query,"INSERT INTO deg_types SET DegTypName='%s'",
+ DegTyp->DegTypName);
+ DB_QueryINSERT (Query,"can not create a new type of degree");
+
+ /***** Write success message *****/
+ sprintf (Gbl.Message,Txt_Created_new_type_of_degree_X,
+ DegTyp->DegTypName);
+ Lay_ShowAlert (Lay_SUCCESS,Gbl.Message);
+ }
+
+/*****************************************************************************/
+/**************** Create a list with all the degree types ********************/
+/*****************************************************************************/
+
+void Deg_GetListDegTypes (void)
+ {
+ char Query[1024];
+ MYSQL_RES *mysql_res;
+ MYSQL_ROW row;
+ unsigned long NumRow;
+
+ /***** Get types of degree from database *****/
+ sprintf (Query,"(SELECT deg_types.DegTypCod,deg_types.DegTypName AS DegTypName,"
+ " COUNT(degrees.DegCod)"
+ " FROM deg_types,degrees WHERE deg_types.DegTypCod=degrees.DegTypCod"
+ " GROUP BY degrees.DegTypCod)"
+ " UNION "
+ "(SELECT DegTypCod,DegTypName,'0'"
+ " FROM deg_types WHERE DegTypCod NOT IN (SELECT DegTypCod FROM degrees))"
+ " ORDER BY DegTypName");
+ Gbl.Degs.DegTypes.Num = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get types of degree");
+
+ /***** Get degree types *****/
+ if (Gbl.Degs.DegTypes.Num)
+ {
+ /***** Create a list of degree types *****/
+ if ((Gbl.Degs.DegTypes.Lst = (struct DegreeType *) calloc (Gbl.Degs.DegTypes.Num,sizeof (struct DegreeType))) == NULL)
+ Lay_ShowErrorAndExit ("Not enough memory to store types of degree.");
+
+ /***** Get degree types *****/
+ for (NumRow = 0;
+ NumRow < Gbl.Degs.DegTypes.Num;
+ NumRow++)
+ {
+ /* Get next degree type */
+ row = mysql_fetch_row (mysql_res);
+
+ /* Get degree type code (row[0]) */
+ if ((Gbl.Degs.DegTypes.Lst[NumRow].DegTypCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
+ Lay_ShowErrorAndExit ("Wrong code of type of degree.");
+
+ /* Get degree type name (row[1]) */
+ strncpy (Gbl.Degs.DegTypes.Lst[NumRow].DegTypName,row[1],Deg_MAX_LENGTH_DEGREE_TYPE_NAME);
+ Gbl.Degs.DegTypes.Lst[NumRow].DegTypName[Deg_MAX_LENGTH_DEGREE_TYPE_NAME] = '\0';
+
+ /* Number of degrees of this type (row[2]) */
+ if (sscanf (row[2],"%u",&Gbl.Degs.DegTypes.Lst[NumRow].NumDegs) != 1)
+ Lay_ShowErrorAndExit ("Error when getting number of degrees of a type");
+ }
+ }
+
+ /***** Free structure that stores the query result *****/
+ DB_FreeMySQLResult (&mysql_res);
+ }
+
+/*****************************************************************************/
+/********* Free list of degree types and list of degrees of each type ********/
+/*****************************************************************************/
+
+void Deg_FreeListDegTypes (void)
+ {
+ /***** Free memory used by the list of degree types *****/
+ if (Gbl.Degs.DegTypes.Lst)
+ {
+ free ((void *) Gbl.Degs.DegTypes.Lst);
+ Gbl.Degs.DegTypes.Lst = NULL;
+ Gbl.Degs.DegTypes.Num = 0;
+ }
+ }
+
+/*****************************************************************************/
+/***************** Receive form to create a new degree type ******************/
+/*****************************************************************************/
+
+void Deg_RecFormNewDegTyp (void)
+ {
+ extern const char *Txt_The_type_of_degree_X_already_exists;
+ extern const char *Txt_You_must_specify_the_name_of_the_new_type_of_degree;
+ struct DegreeType *DegTyp;
+
+ DegTyp = &Gbl.Degs.EditingDegTyp;
+
+ /***** Get parameters from form *****/
+ /* Get the name of degree type */
+ Par_GetParToText ("DegTypName",DegTyp->DegTypName,Deg_MAX_LENGTH_DEGREE_TYPE_NAME);
+
+ if (DegTyp->DegTypName[0]) // If there's a degree type name
+ {
+ /***** If name of degree type was in database... *****/
+ if (Deg_CheckIfDegreeTypeNameExists (DegTyp->DegTypName,-1L))
+ {
+ sprintf (Gbl.Message,Txt_The_type_of_degree_X_already_exists,
+ DegTyp->DegTypName);
+ Lay_ShowAlert (Lay_WARNING,Gbl.Message);
+ }
+ else // Add new degree type to database
+ Deg_CreateDegreeType (DegTyp);
+ }
+ else // If there is not a degree type name
+ {
+ sprintf (Gbl.Message,"%s",Txt_You_must_specify_the_name_of_the_new_type_of_degree);
+ Lay_ShowAlert (Lay_WARNING,Gbl.Message);
+ }
+
+ /***** Show the form again *****/
+ Deg_ReqEditDegreeTypes ();
+ }
+
+/*****************************************************************************/
+/**************************** Remove a degree type ***************************/
+/*****************************************************************************/
+
+void Deg_RemoveDegreeType (void)
+ {
+ extern const char *Txt_To_remove_a_type_of_degree_you_must_first_remove_all_degrees_of_that_type;
+ extern const char *Txt_Type_of_degree_X_removed;
+ struct DegreeType DegTyp;
+
+ /***** Get the code of the degree type *****/
+ if ((DegTyp.DegTypCod = Deg_GetParamOtherDegTypCod ()) == -1L)
+ Lay_ShowErrorAndExit ("Code of type of degree is missing.");
+
+ /***** Get data of the degree type from database *****/
+ if (!Deg_GetDataOfDegreeTypeByCod (&DegTyp))
+ Lay_ShowErrorAndExit ("Code of type of degree not found.");
+
+ /***** Check if this degree type has degrees *****/
+ if (DegTyp.NumDegs) // Degree type has degrees ==> don't remove
+ Lay_ShowAlert (Lay_WARNING,Txt_To_remove_a_type_of_degree_you_must_first_remove_all_degrees_of_that_type);
+ else // Degree type has no degrees ==> remove it
+ {
+ /***** Remove degree type *****/
+ Deg_RemoveDegreeTypeCompletely (DegTyp.DegTypCod);
+
+ /***** Write message to show the change made *****/
+ sprintf (Gbl.Message,Txt_Type_of_degree_X_removed,
+ DegTyp.DegTypName);
+ Lay_ShowAlert (Lay_SUCCESS,Gbl.Message);
+ }
+
+ /***** Show the form again *****/
+ Deg_ReqEditDegreeTypes ();
+ }
+
+/*****************************************************************************/
+/***************** Write parameter with code of degree type ******************/
+/*****************************************************************************/
+
+static void Deg_PutParamOtherDegTypCod (long DegTypCod)
+ {
+ Par_PutHiddenParamLong ("OthDegTypCod",DegTypCod);
+ }
+
+/*****************************************************************************/
+/******************* Get parameter with code of degree type ******************/
+/*****************************************************************************/
+
+long Deg_GetParamOtherDegTypCod (void)
+ {
+ char LongStr[1+10+1];
+
+ /***** Get parameter with code of degree type *****/
+ Par_GetParToText ("OthDegTypCod",LongStr,1+10);
+ return Str_ConvertStrCodToLongCod (LongStr);
+ }
+
+/*****************************************************************************/
+/**************** Count number of degrees in a degree type ******************/
+/*****************************************************************************/
+
+static unsigned Deg_CountNumDegsOfType (long DegTypCod)
+ {
+ char Query[512];
+
+ /***** Get number of degrees of a type from database *****/
+ sprintf (Query,"SELECT COUNT(*) FROM degrees WHERE DegTypCod='%ld'",
+ DegTypCod);
+ return (unsigned) DB_QueryCOUNT (Query,"can not get number of degrees of a type");
+ }
+
+/*****************************************************************************/
+/****************** Get data of a degree type from its code ******************/
+/*****************************************************************************/
+
+bool Deg_GetDataOfDegreeTypeByCod (struct DegreeType *DegTyp)
+ {
+ char Query[512];
+ MYSQL_RES *mysql_res;
+ MYSQL_ROW row;
+ unsigned long NumRows;
+ bool DegTypFound = false;
+
+ if (DegTyp->DegTypCod <= 0)
+ {
+ DegTyp->DegTypCod = -1L;
+ DegTyp->DegTypName[0] = '\0';
+ DegTyp->NumDegs = 0;
+ return false;
+ }
+
+ /***** Get the name of a type of degree from database *****/
+ sprintf (Query,"SELECT DegTypName FROM deg_types WHERE DegTypCod='%ld'",
+ DegTyp->DegTypCod);
+ NumRows = DB_QuerySELECT (Query,&mysql_res,"can not get the name of a type of degree");
+
+ if (NumRows == 1)
+ {
+ /***** Get data of degree type *****/
+ row = mysql_fetch_row (mysql_res);
+
+ /* Get the name of the degree type (row[0]) */
+ strcpy (DegTyp->DegTypName,row[0]);
+
+ /* Count number of degrees of this type */
+ DegTyp->NumDegs = Deg_CountNumDegsOfType (DegTyp->DegTypCod);
+
+ /* Set return value */
+ DegTypFound = true;
+ }
+ else if (NumRows == 0)
+ {
+ DegTyp->DegTypCod = -1L;
+ DegTyp->DegTypName[0] = '\0';
+ DegTyp->NumDegs = 0;
+ return false;
+ }
+ else // NumRows > 1
+ Lay_ShowErrorAndExit ("Type of degree repeated in database.");
+
+ /***** Free structure that stores the query result *****/
+ DB_FreeMySQLResult (&mysql_res);
+
+ return DegTypFound;
+ }
+
+/*****************************************************************************/
+/******************** Remove a degree type and its degrees *******************/
+/*****************************************************************************/
+
+static void Deg_RemoveDegreeTypeCompletely (long DegTypCod)
+ {
+ char Query[512];
+ MYSQL_RES *mysql_res;
+ MYSQL_ROW row;
+ unsigned long NumRow,NumRows;
+ long DegCod;
+
+ /***** Get degrees of a type from database *****/
+ sprintf (Query,"SELECT DegCod FROM degrees WHERE DegTypCod='%ld'",
+ DegTypCod);
+ NumRows = DB_QuerySELECT (Query,&mysql_res,"can not get degrees of a type");
+
+ /* Get degrees of this type */
+ for (NumRow = 0;
+ NumRow < NumRows;
+ NumRow++)
+ {
+ /* Get next degree */
+ row = mysql_fetch_row (mysql_res);
+
+ /* Get degree code (row[0]) */
+ if ((DegCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
+ Lay_ShowErrorAndExit ("Wrong code of degree.");
+
+ /* Remove degree */
+ Deg_RemoveDegreeCompletely (DegCod);
+ }
+
+ /* Free structure that stores the query result */
+ DB_FreeMySQLResult (&mysql_res);
+
+ /***** Remove the degree type *****/
+ sprintf (Query,"DELETE FROM deg_types WHERE DegTypCod='%ld'",DegTypCod);
+ DB_QueryDELETE (Query,"can not remove a type of degree");
+ }
+
+/*****************************************************************************/
+/**************************** Rename a degree type ***************************/
+/*****************************************************************************/
+
+void Deg_RenameDegreeType (void)
+ {
+ extern const char *Txt_You_can_not_leave_the_name_of_the_type_of_degree_X_empty;
+ extern const char *Txt_The_type_of_degree_X_already_exists;
+ extern const char *Txt_The_type_of_degree_X_has_been_renamed_as_Y;
+ extern const char *Txt_The_name_of_the_type_of_degree_X_has_not_changed;
+ struct DegreeType *DegTyp;
+ char Query[1024];
+ char NewNameDegTyp[Deg_MAX_LENGTH_DEGREE_TYPE_NAME+1];
+
+ DegTyp = &Gbl.Degs.EditingDegTyp;
+
+ /***** Get parameters from form *****/
+ /* Get the code of the degree type */
+ if ((DegTyp->DegTypCod = Deg_GetParamOtherDegTypCod ()) == -1L)
+ Lay_ShowErrorAndExit ("Code of type of degree is missing.");
+
+ /* Get the new name for the degree type */
+ Par_GetParToText ("DegTypName",NewNameDegTyp,Deg_MAX_LENGTH_DEGREE_TYPE_NAME);
+
+ /***** Get from the database the old name of the degree type *****/
+ if (!Deg_GetDataOfDegreeTypeByCod (DegTyp))
+ Lay_ShowErrorAndExit ("Code of type of degree not found.");
+
+ /***** Check if new name is empty *****/
+ if (!NewNameDegTyp[0])
+ {
+ sprintf (Gbl.Message,Txt_You_can_not_leave_the_name_of_the_type_of_degree_X_empty,
+ DegTyp->DegTypName);
+ Lay_ShowAlert (Lay_WARNING,Gbl.Message);
+ }
+ else
+ {
+ /***** Check if old and new names are the same (this happens when user press enter with no changes in the form) *****/
+ if (strcmp (DegTyp->DegTypName,NewNameDegTyp)) // Different names
+ {
+ /***** If degree type was in database... *****/
+ if (Deg_CheckIfDegreeTypeNameExists (NewNameDegTyp,DegTyp->DegTypCod))
+ {
+ sprintf (Gbl.Message,Txt_The_type_of_degree_X_already_exists,
+ NewNameDegTyp);
+ Lay_ShowAlert (Lay_WARNING,Gbl.Message);
+ }
+ else
+ {
+ /* Update the table changing old name by new name */
+ sprintf (Query,"UPDATE deg_types SET DegTypName='%s'"
+ " WHERE DegTypCod='%ld'",
+ NewNameDegTyp,DegTyp->DegTypCod);
+ DB_QueryUPDATE (Query,"can not update the type of a degree");
+
+ /* Write message to show the change made */
+ sprintf (Gbl.Message,Txt_The_type_of_degree_X_has_been_renamed_as_Y,
+ DegTyp->DegTypName,NewNameDegTyp);
+ Lay_ShowAlert (Lay_SUCCESS,Gbl.Message);
+ }
+ }
+ else // The same name
+ {
+ sprintf (Gbl.Message,Txt_The_name_of_the_type_of_degree_X_has_not_changed,
+ NewNameDegTyp);
+ Lay_ShowAlert (Lay_INFO,Gbl.Message);
+ }
+ }
+
+ /***** Show the form again *****/
+ strcpy (DegTyp->DegTypName,NewNameDegTyp);
+ Deg_ReqEditDegreeTypes ();
+ }
+
+/*****************************************************************************/
+/****************** Check if name of degree type exists **********************/
+/*****************************************************************************/
+
+static bool Deg_CheckIfDegreeTypeNameExists (const char *DegTypName,long DegTypCod)
+ {
+ char Query[512];
+
+ /***** Get number of degree types with a name from database *****/
+ sprintf (Query,"SELECT COUNT(*) FROM deg_types"
+ " WHERE DegTypName='%s' AND DegTypCod<>'%ld'",
+ DegTypName,DegTypCod);
+ return (DB_QueryCOUNT (Query,"can not check if the name of a type of degree already existed") != 0);
+ }
+
+/*****************************************************************************/
+/************************ Change the type of a degree ************************/
+/*****************************************************************************/
+
+void Deg_ChangeDegreeType (void)
+ {
+ extern const char *Txt_The_type_of_degree_of_the_degree_X_has_changed;
+ struct Degree *Deg;
+ long NewDegTypCod;
+ char Query[512];
+
+ Deg = &Gbl.Degs.EditingDeg;
+
+ /***** Get parameters from form *****/
+ /* Get degree code */
+ if ((Deg->DegCod = Deg_GetParamOtherDegCod ()) == -1L)
+ Lay_ShowErrorAndExit ("Code of degree is missing.");
+
+ /* Get the new degree type */
+ NewDegTypCod = Deg_GetParamOtherDegTypCod ();
+
+ /***** Get data of degree *****/
+ Deg_GetDataOfDegreeByCod (Deg);
+
+ /***** Update the table of degrees changing old type by new type *****/
+ sprintf (Query,"UPDATE degrees SET DegTypCod='%ld' WHERE DegCod='%ld'",
+ NewDegTypCod,Deg->DegCod);
+ DB_QueryUPDATE (Query,"can not update the type of a degree");
+
+ /***** Write message to show the change made *****/
+ sprintf (Gbl.Message,Txt_The_type_of_degree_of_the_degree_X_has_changed,
+ Deg->FullName);
+ Lay_ShowAlert (Lay_SUCCESS,Gbl.Message);
+
+ /***** Put button to go to degree changed *****/
+ Deg_PutButtonToGoToDeg (Deg);
+
+ /***** Show the form again *****/
+ Gbl.Degs.EditingDegTyp.DegTypCod = NewDegTypCod;
+ Deg_EditDegrees ();
+ }
diff --git a/swad_degree_type.h b/swad_degree_type.h
new file mode 100644
index 00000000..0f712ac9
--- /dev/null
+++ b/swad_degree_type.h
@@ -0,0 +1,67 @@
+// swad_degree_type.h: degree types
+
+#ifndef _SWAD_DT
+#define _SWAD_DT
+/*
+ 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 ******************************/
+/*****************************************************************************/
+
+#define Deg_MAX_LENGTH_DEGREE_TYPE_NAME 32
+
+/*****************************************************************************/
+/******************************* Public types ********************************/
+/*****************************************************************************/
+
+struct DegreeType
+ {
+ long DegTypCod; // Degree type code
+ char DegTypName[Deg_MAX_LENGTH_DEGREE_TYPE_NAME+1]; // Degree type name
+ unsigned NumDegs; // Number of degrees of this type
+ };
+
+/*****************************************************************************/
+/***************************** Public prototypes *****************************/
+/*****************************************************************************/
+
+void Deg_WriteSelectorDegTypes (void);
+void Deg_SeeDegTypes (void);
+void Deg_ReqEditDegreeTypes (void);
+
+void Deg_GetListDegTypes (void);
+void Deg_FreeListDegTypes (void);
+
+void Deg_RecFormNewDegTyp (void);
+void Deg_RemoveDegreeType (void);
+
+long Deg_GetParamOtherDegTypCod (void);
+
+bool Deg_GetDataOfDegreeTypeByCod (struct DegreeType *DegTyp);
+void Deg_RenameDegreeType (void);
+void Deg_ChangeDegreeType (void);
+
+#endif
diff --git a/swad_global.h b/swad_global.h
index 26a543e6..a884c9e4 100644
--- a/swad_global.h
+++ b/swad_global.h
@@ -42,6 +42,7 @@
#include "swad_course.h"
#include "swad_cryptography.h"
#include "swad_department.h"
+#include "swad_degree_type.h"
#include "swad_file.h"
#include "swad_file_browser.h"
#include "swad_forum.h"