// swad_place.c: places /* 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-2019 Antonio Caņas Vargas This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ /*****************************************************************************/ /********************************** Headers **********************************/ /*****************************************************************************/ #include // For NULL #include // For calloc #include // For string functions #include "swad_box.h" #include "swad_constant.h" #include "swad_database.h" #include "swad_form.h" #include "swad_global.h" #include "swad_language.h" #include "swad_parameter.h" #include "swad_place.h" #include "swad_table.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ /*****************************************************************************/ extern struct Globals Gbl; /*****************************************************************************/ /***************************** Private constants *****************************/ /*****************************************************************************/ /*****************************************************************************/ /******************************* Private types *******************************/ /*****************************************************************************/ /*****************************************************************************/ /***************************** Private variables *****************************/ /*****************************************************************************/ static struct Place *Plc_EditingPlc = NULL; // Static variable to keep the place being edited /*****************************************************************************/ /***************************** Private prototypes ****************************/ /*****************************************************************************/ static void Plc_GetParamPlcOrder (void); static bool Plc_CheckIfICanCreatePlaces (void); static void Plc_PutIconsListingPlaces (void); static void Plc_PutIconToEditPlaces (void); static void Plc_EditPlacesInternal (void); static void Plc_PutIconsEditingPlaces (void); static void Plc_ListPlacesForEdition (void); static void Plc_PutParamPlcCod (long PlcCod); static void Plc_RenamePlace (Cns_ShrtOrFullName_t ShrtOrFullName); static bool Plc_CheckIfPlaceNameExists (const char *FieldName,const char *Name,long PlcCod); static void Plc_UpdatePlcNameDB (long PlcCod,const char *FieldName,const char *NewPlcName); static void Plc_PutFormToCreatePlace (void); static void Plc_PutHeadPlaces (void); static void Plc_CreatePlace (struct Place *Plc); static void Plc_EditingPlaceConstructor (void); static void Plc_EditingPlaceDestructor (void); /*****************************************************************************/ /*************************** List all the places *****************************/ /*****************************************************************************/ void Plc_SeePlaces (void) { extern const char *Hlp_INSTITUTION_Places; extern const char *Txt_Places; extern const char *Txt_PLACES_HELP_ORDER[2]; extern const char *Txt_PLACES_ORDER[2]; extern const char *Txt_Other_places; extern const char *Txt_Place_unspecified; extern const char *Txt_New_place; Plc_Order_t Order; unsigned NumPlc; unsigned NumCtrsWithPlc = 0; unsigned NumCtrsInOtherPlcs; if (Gbl.Hierarchy.Ins.InsCod > 0) { /***** Get parameter with the type of order in the list of places *****/ Plc_GetParamPlcOrder (); /***** Get list of places *****/ Plc_GetListPlaces (); /***** Table head *****/ Box_StartBox (NULL,Txt_Places,Plc_PutIconsListingPlaces, Hlp_INSTITUTION_Places,Box_NOT_CLOSABLE); Tbl_StartTableWideMargin (2); fprintf (Gbl.F.Out,""); for (Order = Plc_ORDER_BY_PLACE; Order <= Plc_ORDER_BY_NUM_CTRS; Order++) { fprintf (Gbl.F.Out,""); Frm_StartForm (ActSeePlc); Par_PutHiddenParamUnsigned ("Order",(unsigned) Order); Frm_LinkFormSubmit (Txt_PLACES_HELP_ORDER[Order],"TIT_TBL",NULL); if (Order == Gbl.Plcs.SelectedOrder) fprintf (Gbl.F.Out,""); fprintf (Gbl.F.Out,"%s",Txt_PLACES_ORDER[Order]); if (Order == Gbl.Plcs.SelectedOrder) fprintf (Gbl.F.Out,""); fprintf (Gbl.F.Out,""); Frm_EndForm (); fprintf (Gbl.F.Out,""); } fprintf (Gbl.F.Out,""); /***** Write all places and their nuber of centres *****/ for (NumPlc = 0; NumPlc < Gbl.Plcs.Num; NumPlc++) { /* Write data of this place */ fprintf (Gbl.F.Out,"" "" "%s" "" "" "%u" "" "", Gbl.Plcs.Lst[NumPlc].FullName, Gbl.Plcs.Lst[NumPlc].NumCtrs); NumCtrsWithPlc += Gbl.Plcs.Lst[NumPlc].NumCtrs; } /***** Separation row *****/ fprintf (Gbl.F.Out,"" "" " " "" ""); /***** Write centres (of the current institution) with other place *****/ NumCtrsInOtherPlcs = Ctr_GetNumCtrsInPlc (0); fprintf (Gbl.F.Out,"" "" "%s" "" "" "%u" "" "", Txt_Other_places,NumCtrsInOtherPlcs); NumCtrsWithPlc += NumCtrsInOtherPlcs; /***** Write centres (of the current institution) with no place *****/ fprintf (Gbl.F.Out,"" "" "%s" "" "" "%u" "" "", Txt_Place_unspecified, Ctr_GetNumCtrsInIns (Gbl.Hierarchy.Ins.InsCod) - NumCtrsWithPlc); /***** End table *****/ Tbl_EndTable (); /***** Button to create place *****/ if (Plc_CheckIfICanCreatePlaces ()) { Frm_StartForm (ActEdiPlc); Btn_PutConfirmButton (Txt_New_place); Frm_EndForm (); } /***** End box *****/ Box_EndBox (); /***** Free list of places *****/ Plc_FreeListPlaces (); } } /*****************************************************************************/ /********** Get parameter with the type or order in list of places ***********/ /*****************************************************************************/ static void Plc_GetParamPlcOrder (void) { Gbl.Plcs.SelectedOrder = (Plc_Order_t) Par_GetParToUnsignedLong ("Order", 0, Plc_NUM_ORDERS - 1, (unsigned long) Plc_ORDER_DEFAULT); } /*****************************************************************************/ /********************** Check if I can create places *************************/ /*****************************************************************************/ static bool Plc_CheckIfICanCreatePlaces (void) { return (bool) (Gbl.Usrs.Me.Role.Logged >= Rol_INS_ADM); } /*****************************************************************************/ /****************** Put contextual icons in list of places *******************/ /*****************************************************************************/ static void Plc_PutIconsListingPlaces (void) { /***** Put icon to edit places *****/ if (Plc_CheckIfICanCreatePlaces ()) Plc_PutIconToEditPlaces (); /***** Put icon to view centres *****/ Ctr_PutIconToViewCentres (); } /*****************************************************************************/ /********************** Put a link (form) to edit places *********************/ /*****************************************************************************/ static void Plc_PutIconToEditPlaces (void) { Ico_PutContextualIconToEdit (ActEdiPlc,NULL); } /*****************************************************************************/ /*************************** Put forms to edit places ************************/ /*****************************************************************************/ void Plc_EditPlaces (void) { /***** Place constructor *****/ Plc_EditingPlaceConstructor (); /***** Edit places *****/ Plc_EditPlacesInternal (); /***** Place destructor *****/ Plc_EditingPlaceDestructor (); } static void Plc_EditPlacesInternal (void) { extern const char *Hlp_INSTITUTION_Places_edit; extern const char *Txt_Places; /***** Get list of places *****/ Plc_GetListPlaces (); /***** Start box *****/ Box_StartBox (NULL,Txt_Places,Plc_PutIconsEditingPlaces, Hlp_INSTITUTION_Places_edit,Box_NOT_CLOSABLE); /***** Put a form to create a new place *****/ Plc_PutFormToCreatePlace (); /***** Forms to edit current places *****/ if (Gbl.Plcs.Num) Plc_ListPlacesForEdition (); /***** End box *****/ Box_EndBox (); /***** Free list of places *****/ Plc_FreeListPlaces (); } /*****************************************************************************/ /**************** Put contextual icons in edition of places *****************/ /*****************************************************************************/ static void Plc_PutIconsEditingPlaces (void) { /***** Put icon to view places *****/ Plc_PutIconToViewPlaces (); /***** Put icon to view centres *****/ Ctr_PutIconToViewCentres (); } /*****************************************************************************/ /************************** Put icon to view places **************************/ /*****************************************************************************/ void Plc_PutIconToViewPlaces (void) { extern const char *Txt_Places; Lay_PutContextualLinkOnlyIcon (ActSeePlc,NULL,NULL, "map-marker-alt.svg", Txt_Places); } /*****************************************************************************/ /**************************** List all the places ****************************/ /*****************************************************************************/ void Plc_GetListPlaces (void) { static const char *OrderBySubQuery[Plc_NUM_ORDERS] = { "FullName", // Plc_ORDER_BY_PLACE "NumCtrs DESC,FullName", // Plc_ORDER_BY_NUM_CTRS }; MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned long NumRows; unsigned NumPlc; struct Place *Plc; /***** Get places from database *****/ NumRows = DB_QuerySELECT (&mysql_res,"can not get places", "(SELECT places.PlcCod," "places.ShortName," "places.FullName," "COUNT(*) AS NumCtrs" " FROM places,centres" " WHERE places.InsCod=%ld" " AND places.PlcCod=centres.PlcCod" " AND centres.InsCod=%ld" " GROUP BY places.PlcCod)" " UNION " "(SELECT PlcCod," "ShortName," "FullName," "0 AS NumCtrs" " FROM places" " WHERE InsCod=%ld" " AND PlcCod NOT IN" " (SELECT DISTINCT PlcCod FROM centres" " WHERE InsCod=%ld))" " ORDER BY %s", Gbl.Hierarchy.Ins.InsCod, Gbl.Hierarchy.Ins.InsCod, Gbl.Hierarchy.Ins.InsCod, Gbl.Hierarchy.Ins.InsCod, OrderBySubQuery[Gbl.Plcs.SelectedOrder]); /***** Count number of rows in result *****/ if (NumRows) // Places found... { Gbl.Plcs.Num = (unsigned) NumRows; /***** Create list with courses in centre *****/ if ((Gbl.Plcs.Lst = (struct Place *) calloc (NumRows,sizeof (struct Place))) == NULL) Lay_NotEnoughMemoryExit (); /***** Get the places *****/ for (NumPlc = 0; NumPlc < Gbl.Plcs.Num; NumPlc++) { Plc = &(Gbl.Plcs.Lst[NumPlc]); /* Get next place */ row = mysql_fetch_row (mysql_res); /* Get place code (row[0]) */ if ((Plc->PlcCod = Str_ConvertStrCodToLongCod (row[0])) < 0) Lay_ShowErrorAndExit ("Wrong code of place."); /* Get the short name of the place (row[1]) */ Str_Copy (Plc->ShrtName,row[1], Plc_MAX_BYTES_PLACE_SHRT_NAME); /* Get the full name of the place (row[2]) */ Str_Copy (Plc->FullName,row[2], Plc_MAX_BYTES_PLACE_FULL_NAME); /* Get number of centres in this place (row[3]) */ if (sscanf (row[3],"%u",&Plc->NumCtrs) != 1) Plc->NumCtrs = 0; } } else Gbl.Plcs.Num = 0; /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); } /*****************************************************************************/ /**************************** Get place full name ****************************/ /*****************************************************************************/ void Plc_GetDataOfPlaceByCod (struct Place *Plc) { extern const char *Txt_Place_unspecified; extern const char *Txt_Another_place; MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned long NumRows; /***** Clear data *****/ Plc->ShrtName[0] = '\0'; Plc->FullName[0] = '\0'; Plc->NumCtrs = 0; /***** Check if place code is correct *****/ if (Plc->PlcCod < 0) { Str_Copy (Plc->ShrtName,Txt_Place_unspecified, Plc_MAX_BYTES_PLACE_SHRT_NAME); Str_Copy (Plc->FullName,Txt_Place_unspecified, Plc_MAX_BYTES_PLACE_FULL_NAME); } else if (Plc->PlcCod == 0) { Str_Copy (Plc->ShrtName,Txt_Another_place, Plc_MAX_BYTES_PLACE_SHRT_NAME); Str_Copy (Plc->FullName,Txt_Another_place, Plc_MAX_BYTES_PLACE_FULL_NAME); } else if (Plc->PlcCod > 0) { /***** Get data of a place from database *****/ NumRows = DB_QuerySELECT (&mysql_res,"can not get data of a place", "(SELECT places.ShortName," "places.FullName," "COUNT(*)" " FROM places,centres" " WHERE places.PlcCod=%ld" " AND places.PlcCod=centres.PlcCod" " AND centres.PlcCod=%ld" " GROUP BY places.PlcCod)" " UNION " "(SELECT ShortName," "FullName," "0" " FROM places" " WHERE PlcCod=%ld" " AND PlcCod NOT IN" " (SELECT DISTINCT PlcCod FROM centres))", Plc->PlcCod, Plc->PlcCod, Plc->PlcCod); /***** Count number of rows in result *****/ if (NumRows) // Place found... { /* Get row */ row = mysql_fetch_row (mysql_res); /* Get the short name of the place (row[0]) */ Str_Copy (Plc->ShrtName,row[0], Plc_MAX_BYTES_PLACE_SHRT_NAME); /* Get the full name of the place (row[1]) */ Str_Copy (Plc->FullName,row[1], Plc_MAX_BYTES_PLACE_FULL_NAME); /* Get number of centres in this place (row[2]) */ if (sscanf (row[2],"%u",&Plc->NumCtrs) != 1) Plc->NumCtrs = 0; } /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); } } /*****************************************************************************/ /**************************** Free list of places ****************************/ /*****************************************************************************/ void Plc_FreeListPlaces (void) { if (Gbl.Plcs.Lst) { /***** Free memory used by the list of places in institution *****/ free ((void *) Gbl.Plcs.Lst); Gbl.Plcs.Lst = NULL; Gbl.Plcs.Num = 0; } } /*****************************************************************************/ /*************************** List all the places *****************************/ /*****************************************************************************/ static void Plc_ListPlacesForEdition (void) { unsigned NumPlc; struct Place *Plc; /***** Write heading *****/ Tbl_StartTableWide (2); Plc_PutHeadPlaces (); /***** Write all the places *****/ for (NumPlc = 0; NumPlc < Gbl.Plcs.Num; NumPlc++) { Plc = &Gbl.Plcs.Lst[NumPlc]; /* Put icon to remove place */ fprintf (Gbl.F.Out,"" ""); if (Plc->NumCtrs) // Place has centres ==> deletion forbidden Ico_PutIconRemovalNotAllowed (); else { Frm_StartForm (ActRemPlc); Plc_PutParamPlcCod (Plc->PlcCod); Ico_PutIconRemove (); Frm_EndForm (); } fprintf (Gbl.F.Out,""); /* Place code */ fprintf (Gbl.F.Out,"" "%ld" "", Plc->PlcCod); /* Place short name */ fprintf (Gbl.F.Out,""); Frm_StartForm (ActRenPlcSho); Plc_PutParamPlcCod (Plc->PlcCod); fprintf (Gbl.F.Out,"", Plc_MAX_CHARS_PLACE_SHRT_NAME,Plc->ShrtName,Gbl.Form.Id); Frm_EndForm (); fprintf (Gbl.F.Out,""); /* Place full name */ fprintf (Gbl.F.Out,""); Frm_StartForm (ActRenPlcFul); Plc_PutParamPlcCod (Plc->PlcCod); fprintf (Gbl.F.Out,"", Plc_MAX_CHARS_PLACE_FULL_NAME,Plc->FullName,Gbl.Form.Id); Frm_EndForm (); fprintf (Gbl.F.Out,""); /* Number of centres */ fprintf (Gbl.F.Out,"" "%u" "" "", Plc->NumCtrs); } /***** End table *****/ Tbl_EndTable (); } /*****************************************************************************/ /******************** Write parameter with code of place *********************/ /*****************************************************************************/ static void Plc_PutParamPlcCod (long PlcCod) { Par_PutHiddenParamLong ("PlcCod",PlcCod); } /*****************************************************************************/ /********************* Get parameter with code of place **********************/ /*****************************************************************************/ long Plc_GetParamPlcCod (void) { /***** Get code of place *****/ return Par_GetParToLong ("PlcCod"); } /*****************************************************************************/ /******************************* Remove a place ******************************/ /*****************************************************************************/ void Plc_RemovePlace (void) { extern const char *Txt_To_remove_a_place_you_must_first_remove_all_centres_of_that_place; extern const char *Txt_Place_X_removed; /***** Place constructor *****/ Plc_EditingPlaceConstructor (); /***** Get place code *****/ if ((Plc_EditingPlc->PlcCod = Plc_GetParamPlcCod ()) == -1L) Lay_ShowErrorAndExit ("Code of place is missing."); /***** Get data of the place from database *****/ Plc_GetDataOfPlaceByCod (Plc_EditingPlc); /***** Check if this place has centres *****/ if (Plc_EditingPlc->NumCtrs) // Place has centres ==> don't remove Ale_CreateAlert (Ale_WARNING,NULL, Txt_To_remove_a_place_you_must_first_remove_all_centres_of_that_place); else // Place has no centres ==> remove it { /***** Remove place *****/ DB_QueryDELETE ("can not remove a place", "DELETE FROM places WHERE PlcCod=%ld", Plc_EditingPlc->PlcCod); /***** Write message to show the change made *****/ Ale_CreateAlert (Ale_SUCCESS,NULL, Txt_Place_X_removed, Plc_EditingPlc->FullName); } } /*****************************************************************************/ /********************* Change the short name of a place **********************/ /*****************************************************************************/ void Plc_RenamePlaceShort (void) { /***** Place constructor *****/ Plc_EditingPlaceConstructor (); /***** Rename place *****/ Plc_RenamePlace (Cns_SHRT_NAME); } /*****************************************************************************/ /********************* Change the full name of a place ***********************/ /*****************************************************************************/ void Plc_RenamePlaceFull (void) { /***** Place constructor *****/ Plc_EditingPlaceConstructor (); /***** Rename place *****/ Plc_RenamePlace (Cns_FULL_NAME); } /*****************************************************************************/ /************************ Change the name of a place *************************/ /*****************************************************************************/ static void Plc_RenamePlace (Cns_ShrtOrFullName_t ShrtOrFullName) { extern const char *Txt_You_can_not_leave_the_name_of_the_place_X_empty; extern const char *Txt_The_place_X_already_exists; extern const char *Txt_The_place_X_has_been_renamed_as_Y; extern const char *Txt_The_name_of_the_place_X_has_not_changed; const char *ParamName = NULL; // Initialized to avoid warning const char *FieldName = NULL; // Initialized to avoid warning unsigned MaxBytes = 0; // Initialized to avoid warning char *CurrentPlcName = NULL; // Initialized to avoid warning char NewPlcName[Plc_MAX_BYTES_PLACE_FULL_NAME + 1]; switch (ShrtOrFullName) { case Cns_SHRT_NAME: ParamName = "ShortName"; FieldName = "ShortName"; MaxBytes = Plc_MAX_BYTES_PLACE_SHRT_NAME; CurrentPlcName = Plc_EditingPlc->ShrtName; break; case Cns_FULL_NAME: ParamName = "FullName"; FieldName = "FullName"; MaxBytes = Plc_MAX_BYTES_PLACE_FULL_NAME; CurrentPlcName = Plc_EditingPlc->FullName; break; } /***** Get parameters from form *****/ /* Get the code of the place */ if ((Plc_EditingPlc->PlcCod = Plc_GetParamPlcCod ()) == -1L) Lay_ShowErrorAndExit ("Code of place is missing."); /* Get the new name for the place */ Par_GetParToText (ParamName,NewPlcName,MaxBytes); /***** Get from the database the old names of the place *****/ Plc_GetDataOfPlaceByCod (Plc_EditingPlc); /***** Check if new name is empty *****/ if (!NewPlcName[0]) Ale_CreateAlert (Ale_WARNING,NULL, Txt_You_can_not_leave_the_name_of_the_place_X_empty, CurrentPlcName); else { /***** Check if old and new names are the same (this happens when return is pressed without changes) *****/ if (strcmp (CurrentPlcName,NewPlcName)) // Different names { /***** If place was in database... *****/ if (Plc_CheckIfPlaceNameExists (ParamName,NewPlcName,Plc_EditingPlc->PlcCod)) Ale_CreateAlert (Ale_WARNING,NULL, Txt_The_place_X_already_exists, NewPlcName); else { /* Update the table changing old name by new name */ Plc_UpdatePlcNameDB (Plc_EditingPlc->PlcCod,FieldName,NewPlcName); /* Write message to show the change made */ Ale_CreateAlert (Ale_SUCCESS,NULL, Txt_The_place_X_has_been_renamed_as_Y, CurrentPlcName,NewPlcName); } } else // The same name Ale_CreateAlert (Ale_INFO,NULL, Txt_The_name_of_the_place_X_has_not_changed, CurrentPlcName); } /***** Update place name *****/ Str_Copy (CurrentPlcName,NewPlcName, MaxBytes); } /*****************************************************************************/ /********************** Check if the name of place exists ********************/ /*****************************************************************************/ static bool Plc_CheckIfPlaceNameExists (const char *FieldName,const char *Name,long PlcCod) { /***** Get number of places with a name from database *****/ return (DB_QueryCOUNT ("can not check if the name of a place" " already existed", "SELECT COUNT(*) FROM places" " WHERE InsCod=%ld" " AND %s='%s' AND PlcCod<>%ld", Gbl.Hierarchy.Ins.InsCod, FieldName,Name,PlcCod) != 0); } /*****************************************************************************/ /****************** Update place name in table of places *********************/ /*****************************************************************************/ static void Plc_UpdatePlcNameDB (long PlcCod,const char *FieldName,const char *NewPlcName) { /***** Update place changing old name by new name */ DB_QueryUPDATE ("can not update the name of a place", "UPDATE places SET %s='%s' WHERE PlcCod=%ld", FieldName,NewPlcName,PlcCod); } /*****************************************************************************/ /********** Show alerts after changing a place and continue editing **********/ /*****************************************************************************/ void Plc_ContEditAfterChgPlc (void) { /***** Write message to show the change made *****/ Ale_ShowAlerts (NULL); /***** Show the form again *****/ Plc_EditPlacesInternal (); /***** Place destructor *****/ Plc_EditingPlaceDestructor (); } /*****************************************************************************/ /********************* Put a form to create a new place **********************/ /*****************************************************************************/ static void Plc_PutFormToCreatePlace (void) { extern const char *Txt_New_place; extern const char *Txt_Create_place; /***** Start form *****/ Frm_StartForm (ActNewPlc); /***** Start box and table *****/ Box_StartBoxTable (NULL,Txt_New_place,NULL, NULL,Box_NOT_CLOSABLE,2); /***** Write heading *****/ Plc_PutHeadPlaces (); /***** Column to remove place, disabled here *****/ fprintf (Gbl.F.Out,"" ""); /***** Place code *****/ fprintf (Gbl.F.Out,""); /***** Place short name *****/ fprintf (Gbl.F.Out,"" "" "", Plc_MAX_CHARS_PLACE_SHRT_NAME,Plc_EditingPlc->ShrtName); /***** Place full name *****/ fprintf (Gbl.F.Out,"" "" "", Plc_MAX_CHARS_PLACE_FULL_NAME,Plc_EditingPlc->FullName); /***** Number of centres *****/ fprintf (Gbl.F.Out,"" "0" "" ""); /***** End table, send button and end box *****/ Box_EndBoxTableWithButton (Btn_CREATE_BUTTON,Txt_Create_place); /***** End form *****/ Frm_EndForm (); } /*****************************************************************************/ /******************** Write header with fields of a place ********************/ /*****************************************************************************/ static void Plc_PutHeadPlaces (void) { extern const char *Txt_Code; extern const char *Txt_Short_name; extern const char *Txt_Full_name; extern const char *Txt_Centres; fprintf (Gbl.F.Out,"" "" "" "%s" "" "" "%s" "" "" "%s" "" "" "%s" "" "", Txt_Code, Txt_Short_name, Txt_Full_name, Txt_Centres); } /*****************************************************************************/ /******************* Receive form to create a new place **********************/ /*****************************************************************************/ void Plc_RecFormNewPlace (void) { extern const char *Txt_The_place_X_already_exists; extern const char *Txt_Created_new_place_X; extern const char *Txt_You_must_specify_the_short_name_and_the_full_name_of_the_new_place; /***** Place constructor *****/ Plc_EditingPlaceConstructor (); /***** Get parameters from form *****/ /* Get place short name */ Par_GetParToText ("ShortName",Plc_EditingPlc->ShrtName,Plc_MAX_BYTES_PLACE_SHRT_NAME); /* Get place full name */ Par_GetParToText ("FullName",Plc_EditingPlc->FullName,Plc_MAX_BYTES_PLACE_FULL_NAME); if (Plc_EditingPlc->ShrtName[0] && Plc_EditingPlc->FullName[0]) // If there's a place name { /***** If name of place was in database... *****/ if (Plc_CheckIfPlaceNameExists ("ShortName",Plc_EditingPlc->ShrtName,-1L)) Ale_CreateAlert (Ale_WARNING,NULL, Txt_The_place_X_already_exists, Plc_EditingPlc->ShrtName); else if (Plc_CheckIfPlaceNameExists ("FullName",Plc_EditingPlc->FullName,-1L)) Ale_CreateAlert (Ale_WARNING,NULL, Txt_The_place_X_already_exists, Plc_EditingPlc->FullName); else // Add new place to database { Plc_CreatePlace (Plc_EditingPlc); Ale_CreateAlert (Ale_SUCCESS,NULL,Txt_Created_new_place_X, Plc_EditingPlc->FullName); } } else // If there is not a place name Ale_CreateAlert (Ale_WARNING,NULL, Txt_You_must_specify_the_short_name_and_the_full_name_of_the_new_place); } /*****************************************************************************/ /**************************** Create a new place *****************************/ /*****************************************************************************/ static void Plc_CreatePlace (struct Place *Plc) { /***** Create a new place *****/ DB_QueryINSERT ("can not create place", "INSERT INTO places" " (InsCod,ShortName,FullName)" " VALUES" " (%ld,'%s','%s')", Gbl.Hierarchy.Ins.InsCod,Plc->ShrtName,Plc->FullName); } /*****************************************************************************/ /************************* Place constructor/destructor **********************/ /*****************************************************************************/ static void Plc_EditingPlaceConstructor (void) { /***** Pointer must be NULL *****/ if (Plc_EditingPlc != NULL) Lay_ShowErrorAndExit ("Error initializing place."); /***** Allocate memory for place *****/ if ((Plc_EditingPlc = (struct Place *) malloc (sizeof (struct Place))) == NULL) Lay_ShowErrorAndExit ("Error allocating memory for place."); /***** Reset place *****/ Plc_EditingPlc->PlcCod = -1L; Plc_EditingPlc->InsCod = -1L; Plc_EditingPlc->ShrtName[0] = '\0'; Plc_EditingPlc->FullName[0] = '\0'; Plc_EditingPlc->NumCtrs = 0; } static void Plc_EditingPlaceDestructor (void) { /***** Free memory used for place *****/ if (Plc_EditingPlc != NULL) { free ((void *) Plc_EditingPlc); Plc_EditingPlc = NULL; } }