From 4a871a9155eda3bead950d162d0dd4703b5592d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ca=C3=B1as=20Vargas?= Date: Sun, 20 Mar 2016 16:30:52 +0100 Subject: [PATCH] Version 15.156 --- Makefile | 2 +- swad_action.c | 1 + swad_changelog.h | 4 +- swad_degree.c | 776 +---------------------------------------- swad_degree.h | 20 +- swad_degree_type.c | 835 +++++++++++++++++++++++++++++++++++++++++++++ swad_degree_type.h | 67 ++++ swad_global.h | 1 + 8 files changed, 913 insertions(+), 793 deletions(-) create mode 100644 swad_degree_type.c create mode 100644 swad_degree_type.h 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,"" - "", - BgColor, - Gbl.Prefs.IconsURL, - Gbl.Degs.DegTypes.Lst[NumDegTyp].NumDegs ? "ok_green" : - "tr", - Gbl.Degs.DegTypes.Lst[NumDegTyp].NumDegs ? Txt_TYPES_OF_DEGREE_With_degrees : - Txt_TYPES_OF_DEGREE_Without_degrees, - Gbl.Degs.DegTypes.Lst[NumDegTyp].NumDegs ? Txt_TYPES_OF_DEGREE_With_degrees : - Txt_TYPES_OF_DEGREE_Without_degrees); - - /* Name of degree type */ - fprintf (Gbl.F.Out,"", - BgColor,Gbl.Degs.DegTypes.Lst[NumDegTyp].DegTypName); - - /* Number of degrees of this type */ - fprintf (Gbl.F.Out,"" - "", - BgColor,Gbl.Degs.DegTypes.Lst[NumDegTyp].NumDegs); - - Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd; - } - - /***** End table *****/ - fprintf (Gbl.F.Out,"
" - "\"%s\"" - "" - "%s" - "" - "%u" - "
"); - Lay_EndRoundFrame (); - } - -/*****************************************************************************/ -/******************* Put link (form) to edit degree types ********************/ -/*****************************************************************************/ - -static void Deg_PutIconToEditDegTypes (void) - { - extern const char *Txt_Edit; - - Lay_PutContextualLink (ActEdiDegTyp,NULL,"edit64x64.png",Txt_Edit,NULL); - } - -/*****************************************************************************/ -/******************* List current degree types for edition *******************/ -/*****************************************************************************/ - -static void Deg_ListDegreeTypesForEdition (void) - { - extern const char *Txt_Types_of_degree; - unsigned NumDegTyp; - - /***** Write heading *****/ - Lay_StartRoundFrameTable (NULL,2,Txt_Types_of_degree); - Deg_PutHeadDegreeTypesForEdition (); - - /***** List degree types with forms for edition *****/ - for (NumDegTyp = 0; - NumDegTyp < Gbl.Degs.DegTypes.Num; - NumDegTyp++) - { - /* Put icon to remove degree type */ - fprintf (Gbl.F.Out,"" - ""); - if (Gbl.Degs.DegTypes.Lst[NumDegTyp].NumDegs) // Degree type has degrees ==> deletion forbidden - Lay_PutIconRemovalNotAllowed (); - else - { - Act_FormStart (ActRemDegTyp); - Deg_PutParamOtherDegTypCod (Gbl.Degs.DegTypes.Lst[NumDegTyp].DegTypCod); - Lay_PutIconRemove (); - Act_FormEnd (); - } - - /* Degree type code */ - fprintf (Gbl.F.Out,"" - "" - "%ld" - "", - Gbl.Degs.DegTypes.Lst[NumDegTyp].DegTypCod); - - /* Name of degree type */ - fprintf (Gbl.F.Out,""); - Act_FormStart (ActRenDegTyp); - Deg_PutParamOtherDegTypCod (Gbl.Degs.DegTypes.Lst[NumDegTyp].DegTypCod); - fprintf (Gbl.F.Out,"", - Deg_MAX_LENGTH_DEGREE_TYPE_NAME, - Gbl.Degs.DegTypes.Lst[NumDegTyp].DegTypName, - Gbl.Form.Id); - Act_FormEnd (); - fprintf (Gbl.F.Out,""); - - /* Number of degrees of this type */ - fprintf (Gbl.F.Out,"" - "%u" - "" - "", - Gbl.Degs.DegTypes.Lst[NumDegTyp].NumDegs); - } - - Lay_EndRoundFrameTable (); - } - /*****************************************************************************/ /********************* List current degrees for edition **********************/ /*****************************************************************************/ @@ -1559,45 +1304,6 @@ static Deg_Status_t Deg_GetStatusBitsFromStatusTxt (Deg_StatusTxt_t StatusTxt) return (Deg_Status_t) 0; } -/*****************************************************************************/ -/******************** Put a form to create a new degree type *****************/ -/*****************************************************************************/ - -static void Deg_PutFormToCreateDegType (void) - { - extern const char *Txt_New_type_of_degree; - extern const char *Txt_Type_of_BR_degree; - extern const char *Txt_Create_type_of_degree; - - /***** Start form *****/ - Act_FormStart (ActNewDegTyp); - - /***** Start of frame *****/ - Lay_StartRoundFrameTable (NULL,2,Txt_New_type_of_degree); - - /***** Write heading *****/ - fprintf (Gbl.F.Out,"" - "" - "%s" - "" - "", - Txt_Type_of_BR_degree); - - /***** Degree type name *****/ - fprintf (Gbl.F.Out,"" - "" - "" - "", - Deg_MAX_LENGTH_DEGREE_TYPE_NAME,Gbl.Degs.EditingDegTyp.DegTypName); - - /***** Send button and end frame *****/ - Lay_EndRoundFrameTableWithButton (Lay_CREATE_BUTTON,Txt_Create_type_of_degree); - - /***** End form *****/ - Act_FormEnd (); - } - /*****************************************************************************/ /*********************** Put a form to create a new degree *******************/ /*****************************************************************************/ @@ -1725,55 +1431,6 @@ static void Deg_PutFormToCreateDegree (void) Act_FormEnd (); } -/*****************************************************************************/ -/***************** Write header with fields of a degree type *****************/ -/*****************************************************************************/ - -static void Deg_PutHeadDegreeTypesForSeeing (void) - { - extern const char *Txt_Type_of_BR_degree; - extern const char *Txt_Degrees; - - fprintf (Gbl.F.Out,"" - "" - "" - "%s" - "" - "" - "%s" - "" - "", - Txt_Type_of_BR_degree, - Txt_Degrees); - } - -/*****************************************************************************/ -/***************** Write header with fields of a degree type *****************/ -/*****************************************************************************/ - -static void Deg_PutHeadDegreeTypesForEdition (void) - { - extern const char *Txt_Code; - extern const char *Txt_Type_of_BR_degree; - extern const char *Txt_Degrees; - - fprintf (Gbl.F.Out,"" - "" - "" - "%s" - "" - "" - "%s" - "" - "" - "%s" - "" - "", - 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,"" + "", + BgColor, + Gbl.Prefs.IconsURL, + Gbl.Degs.DegTypes.Lst[NumDegTyp].NumDegs ? "ok_green" : + "tr", + Gbl.Degs.DegTypes.Lst[NumDegTyp].NumDegs ? Txt_TYPES_OF_DEGREE_With_degrees : + Txt_TYPES_OF_DEGREE_Without_degrees, + Gbl.Degs.DegTypes.Lst[NumDegTyp].NumDegs ? Txt_TYPES_OF_DEGREE_With_degrees : + Txt_TYPES_OF_DEGREE_Without_degrees); + + /* Name of degree type */ + fprintf (Gbl.F.Out,"", + BgColor,Gbl.Degs.DegTypes.Lst[NumDegTyp].DegTypName); + + /* Number of degrees of this type */ + fprintf (Gbl.F.Out,"" + "", + BgColor,Gbl.Degs.DegTypes.Lst[NumDegTyp].NumDegs); + + Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd; + } + + /***** End table *****/ + fprintf (Gbl.F.Out,"
" + "\"%s\"" + "" + "%s" + "" + "%u" + "
"); + Lay_EndRoundFrame (); + } + +/*****************************************************************************/ +/******************* Put link (form) to edit degree types ********************/ +/*****************************************************************************/ + +static void Deg_PutIconToEditDegTypes (void) + { + extern const char *Txt_Edit; + + Lay_PutContextualLink (ActEdiDegTyp,NULL,"edit64x64.png",Txt_Edit,NULL); + } + +/*****************************************************************************/ +/******************* List current degree types for edition *******************/ +/*****************************************************************************/ + +static void Deg_ListDegreeTypesForEdition (void) + { + extern const char *Txt_Types_of_degree; + unsigned NumDegTyp; + + /***** Write heading *****/ + Lay_StartRoundFrameTable (NULL,2,Txt_Types_of_degree); + Deg_PutHeadDegreeTypesForEdition (); + + /***** List degree types with forms for edition *****/ + for (NumDegTyp = 0; + NumDegTyp < Gbl.Degs.DegTypes.Num; + NumDegTyp++) + { + /* Put icon to remove degree type */ + fprintf (Gbl.F.Out,"" + ""); + if (Gbl.Degs.DegTypes.Lst[NumDegTyp].NumDegs) // Degree type has degrees ==> deletion forbidden + Lay_PutIconRemovalNotAllowed (); + else + { + Act_FormStart (ActRemDegTyp); + Deg_PutParamOtherDegTypCod (Gbl.Degs.DegTypes.Lst[NumDegTyp].DegTypCod); + Lay_PutIconRemove (); + Act_FormEnd (); + } + + /* Degree type code */ + fprintf (Gbl.F.Out,"" + "" + "%ld" + "", + Gbl.Degs.DegTypes.Lst[NumDegTyp].DegTypCod); + + /* Name of degree type */ + fprintf (Gbl.F.Out,""); + Act_FormStart (ActRenDegTyp); + Deg_PutParamOtherDegTypCod (Gbl.Degs.DegTypes.Lst[NumDegTyp].DegTypCod); + fprintf (Gbl.F.Out,"", + Deg_MAX_LENGTH_DEGREE_TYPE_NAME, + Gbl.Degs.DegTypes.Lst[NumDegTyp].DegTypName, + Gbl.Form.Id); + Act_FormEnd (); + fprintf (Gbl.F.Out,""); + + /* Number of degrees of this type */ + fprintf (Gbl.F.Out,"" + "%u" + "" + "", + Gbl.Degs.DegTypes.Lst[NumDegTyp].NumDegs); + } + + Lay_EndRoundFrameTable (); + } + +/*****************************************************************************/ +/******************** Put a form to create a new degree type *****************/ +/*****************************************************************************/ + +static void Deg_PutFormToCreateDegType (void) + { + extern const char *Txt_New_type_of_degree; + extern const char *Txt_Type_of_BR_degree; + extern const char *Txt_Create_type_of_degree; + + /***** Start form *****/ + Act_FormStart (ActNewDegTyp); + + /***** Start of frame *****/ + Lay_StartRoundFrameTable (NULL,2,Txt_New_type_of_degree); + + /***** Write heading *****/ + fprintf (Gbl.F.Out,"" + "" + "%s" + "" + "", + Txt_Type_of_BR_degree); + + /***** Degree type name *****/ + fprintf (Gbl.F.Out,"" + "" + "" + "", + Deg_MAX_LENGTH_DEGREE_TYPE_NAME,Gbl.Degs.EditingDegTyp.DegTypName); + + /***** Send button and end frame *****/ + Lay_EndRoundFrameTableWithButton (Lay_CREATE_BUTTON,Txt_Create_type_of_degree); + + /***** End form *****/ + Act_FormEnd (); + } + +/*****************************************************************************/ +/***************** Write header with fields of a degree type *****************/ +/*****************************************************************************/ + +static void Deg_PutHeadDegreeTypesForSeeing (void) + { + extern const char *Txt_Type_of_BR_degree; + extern const char *Txt_Degrees; + + fprintf (Gbl.F.Out,"" + "" + "" + "%s" + "" + "" + "%s" + "" + "", + Txt_Type_of_BR_degree, + Txt_Degrees); + } + +/*****************************************************************************/ +/***************** Write header with fields of a degree type *****************/ +/*****************************************************************************/ + +static void Deg_PutHeadDegreeTypesForEdition (void) + { + extern const char *Txt_Code; + extern const char *Txt_Type_of_BR_degree; + extern const char *Txt_Degrees; + + fprintf (Gbl.F.Out,"" + "" + "" + "%s" + "" + "" + "%s" + "" + "" + "%s" + "" + "", + 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"