swad-core/swad_classroom.c

1092 lines
39 KiB
C

// swad_classroom.c: classrooms, laboratories or other classrooms where classes are taught
/*
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 <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/********************************** Headers **********************************/
/*****************************************************************************/
#include <linux/stddef.h> // For NULL
#include <malloc.h> // For calloc, free
#include <string.h> // For string functions
#include "swad_box.h"
#include "swad_database.h"
#include "swad_form.h"
#include "swad_global.h"
#include "swad_classroom.h"
#include "swad_table.h"
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
/*****************************************************************************/
/******************************* Private types *******************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private variables *****************************/
/*****************************************************************************/
static struct Classroom *Cla_EditingCla = NULL; // Static variable to keep the classroom being edited
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
static void Cla_GetParamClaOrder (void);
static bool Cla_CheckIfICanCreateClassrooms (void);
static void Cla_PutIconsListingClassrooms (void);
static void Cla_PutIconToEditClassrooms (void);
static void Cla_PutIconsEditingClassrooms (void);
static void Cla_EditClassroomsInternal (void);
static void Cla_ListClassroomsForEdition (void);
static void Cla_PutParamClaCod (long ClaCod);
static void Cla_RenameClassroom (Cns_ShrtOrFullName_t ShrtOrFullName);
static bool Cla_CheckIfClassroomNameExists (const char *FieldName,const char *Name,long ClaCod);
static void Cla_UpdateClaNameDB (long ClaCod,const char *FieldName,const char *NewClaName);
static void Cla_WriteCapacity (unsigned Capacity);
static void Cla_PutFormToCreateClassroom (void);
static void Cla_PutHeadClassrooms (void);
static void Cla_CreateClassroom (struct Classroom *Cla);
static void Cla_EditingClassroomConstructor (void);
static void Cla_EditingClassroomDestructor (void);
/*****************************************************************************/
/************************* List all the classrooms ***************************/
/*****************************************************************************/
#define A SIZE_MAX
void Cla_SeeClassrooms (void)
{
extern const char *Hlp_CENTRE_Classrooms;
extern const char *Txt_Classrooms;
extern const char *Txt_CLASSROOMS_HELP_ORDER[Cla_NUM_ORDERS];
extern const char *Txt_CLASSROOMS_ORDER[Cla_NUM_ORDERS];
extern const char *Txt_New_classroom;
Cla_Order_t Order;
unsigned NumCla;
unsigned RowEvenOdd;
/***** Trivial check *****/
if (Gbl.Hierarchy.Ctr.CtrCod <= 0) // No centre selected
return;
/***** Get parameter with the type of order in the list of classrooms *****/
Cla_GetParamClaOrder ();
/***** Get list of classrooms *****/
Cla_GetListClassrooms (Cla_ALL_DATA);
/***** Table head *****/
Box_StartBox (NULL,Txt_Classrooms,Cla_PutIconsListingClassrooms,
Hlp_CENTRE_Classrooms,Box_NOT_CLOSABLE);
Tbl_StartTableWideMargin (2);
fprintf (Gbl.F.Out,"<tr>");
for (Order = (Cla_Order_t) 0;
Order <= (Cla_Order_t) (Cla_NUM_ORDERS - 1);
Order++)
{
fprintf (Gbl.F.Out,"<th class=\"LEFT_MIDDLE\">");
Frm_StartForm (ActSeeCla);
Par_PutHiddenParamUnsigned ("Order",(unsigned) Order);
Frm_LinkFormSubmit (Txt_CLASSROOMS_HELP_ORDER[Order],"TIT_TBL",NULL);
if (Order == Gbl.Classrooms.SelectedOrder)
fprintf (Gbl.F.Out,"<u>");
fprintf (Gbl.F.Out,"%s",Txt_CLASSROOMS_ORDER[Order]);
if (Order == Gbl.Classrooms.SelectedOrder)
fprintf (Gbl.F.Out,"</u>");
fprintf (Gbl.F.Out,"</a>");
Frm_EndForm ();
fprintf (Gbl.F.Out,"</th>");
}
fprintf (Gbl.F.Out,"</tr>");
/***** Write list of classrooms *****/
for (NumCla = 0, RowEvenOdd = 1;
NumCla < Gbl.Classrooms.Num;
NumCla++, RowEvenOdd = 1 - RowEvenOdd)
{
/* Short name */
fprintf (Gbl.F.Out,"<tr>"
"<td class=\"DAT LEFT_MIDDLE %s\">"
"%s"
"</td>",
Gbl.ColorRows[RowEvenOdd],
Gbl.Classrooms.Lst[NumCla].ShrtName);
/* Full name */
fprintf (Gbl.F.Out,"<td class=\"DAT LEFT_MIDDLE %s\">"
"%s"
"</td>",
Gbl.ColorRows[RowEvenOdd],
Gbl.Classrooms.Lst[NumCla].FullName);
/* Capacity */
fprintf (Gbl.F.Out,"<td class=\"DAT RIGHT_MIDDLE %s\">",
Gbl.ColorRows[RowEvenOdd]);
Cla_WriteCapacity (Gbl.Classrooms.Lst[NumCla].Capacity);
fprintf (Gbl.F.Out,"</td>");
/* Location */
fprintf (Gbl.F.Out,"<td class=\"DAT LEFT_MIDDLE %s\">"
"%s"
"</td>"
"</tr>",
Gbl.ColorRows[RowEvenOdd],
Gbl.Classrooms.Lst[NumCla].Location);
}
/***** End table *****/
Tbl_EndTable ();
/***** Button to create classroom *****/
if (Cla_CheckIfICanCreateClassrooms ())
{
Frm_StartForm (ActEdiCla);
Btn_PutConfirmButton (Txt_New_classroom);
Frm_EndForm ();
}
/***** End box *****/
Box_EndBox ();
/***** Free list of classrooms *****/
Cla_FreeListClassrooms ();
}
/*****************************************************************************/
/******** Get parameter with the type or order in list of classrooms *********/
/*****************************************************************************/
static void Cla_GetParamClaOrder (void)
{
Gbl.Classrooms.SelectedOrder = (Cla_Order_t)
Par_GetParToUnsignedLong ("Order",
0,
Cla_NUM_ORDERS - 1,
(unsigned long) Cla_ORDER_DEFAULT);
}
/*****************************************************************************/
/******************** Check if I can create classrooms ***********************/
/*****************************************************************************/
static bool Cla_CheckIfICanCreateClassrooms (void)
{
return (bool) (Gbl.Usrs.Me.Role.Logged >= Rol_CTR_ADM);
}
/*****************************************************************************/
/**************** Put contextual icons in list of classrooms *****************/
/*****************************************************************************/
static void Cla_PutIconsListingClassrooms (void)
{
/***** Put icon to edit classrooms *****/
if (Cla_CheckIfICanCreateClassrooms ())
Cla_PutIconToEditClassrooms ();
}
/*****************************************************************************/
/******************** Put a link (form) to edit classrooms *******************/
/*****************************************************************************/
static void Cla_PutIconToEditClassrooms (void)
{
Ico_PutContextualIconToEdit (ActEdiCla,NULL);
}
/*****************************************************************************/
/************************* Put forms to edit classrooms **********************/
/*****************************************************************************/
void Cla_EditClassrooms (void)
{
/***** Classroom constructor *****/
Cla_EditingClassroomConstructor ();
/***** Edit classrooms *****/
Cla_EditClassroomsInternal ();
/***** Classroom destructor *****/
Cla_EditingClassroomDestructor ();
}
static void Cla_EditClassroomsInternal (void)
{
extern const char *Hlp_CENTRE_Classrooms_edit;
extern const char *Txt_Classrooms;
/***** Get list of classrooms *****/
Cla_GetListClassrooms (Cla_ALL_DATA);
/***** Start box *****/
Box_StartBox (NULL,Txt_Classrooms,Cla_PutIconsEditingClassrooms,
Hlp_CENTRE_Classrooms_edit,Box_NOT_CLOSABLE);
/***** Put a form to create a new classroom *****/
Cla_PutFormToCreateClassroom ();
/***** Forms to edit current classrooms *****/
if (Gbl.Classrooms.Num)
Cla_ListClassroomsForEdition ();
/***** End box *****/
Box_EndBox ();
/***** Free list of classrooms *****/
Cla_FreeListClassrooms ();
}
/*****************************************************************************/
/*************** Put contextual icons in edition of classrooms ***************/
/*****************************************************************************/
static void Cla_PutIconsEditingClassrooms (void)
{
/***** Put icon to view classrooms *****/
Cla_PutIconToViewClassrooms ();
}
/*****************************************************************************/
/************************ Put icon to view classrooms ************************/
/*****************************************************************************/
void Cla_PutIconToViewClassrooms (void)
{
extern const char *Txt_Classrooms;
Lay_PutContextualLinkOnlyIcon (ActSeeCla,NULL,NULL,
"classroom.svg",
Txt_Classrooms);
}
/*****************************************************************************/
/************************** List all the classrooms **************************/
/*****************************************************************************/
void Cla_GetListClassrooms (Cla_WhichData_t WhichData)
{
static const char *OrderBySubQuery[Cla_NUM_ORDERS] =
{
"ShortName", // Cla_ORDER_BY_SHRT_NAME
"FullName", // Cla_ORDER_BY_FULL_NAME
"Capacity DESC,ShortName", // Cla_ORDER_BY_CAPACITY
"Location,ShortName", // Cla_ORDER_BY_LOCATION
};
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned long NumRows;
unsigned NumCla;
struct Classroom *Cla;
/***** Get classrooms from database *****/
switch (WhichData)
{
case Cla_ALL_DATA:
NumRows = DB_QuerySELECT (&mysql_res,"can not get classrooms",
"SELECT ClaCod,"
"ShortName,"
"FullName,"
"Capacity,"
"Location"
" FROM classrooms"
" WHERE CtrCod=%ld"
" ORDER BY %s",
Gbl.Hierarchy.Ctr.CtrCod,
OrderBySubQuery[Gbl.Classrooms.SelectedOrder]);
break;
case Cla_ONLY_SHRT_NAME:
default:
NumRows = DB_QuerySELECT (&mysql_res,"can not get classrooms",
"SELECT ClaCod,"
"ShortName"
" FROM classrooms"
" WHERE CtrCod=%ld"
" ORDER BY ShortName",
Gbl.Hierarchy.Ctr.CtrCod);
break;
}
/***** Count number of rows in result *****/
if (NumRows) // Classrooms found...
{
Gbl.Classrooms.Num = (unsigned) NumRows;
/***** Create list with courses in centre *****/
if ((Gbl.Classrooms.Lst = (struct Classroom *) calloc (NumRows,sizeof (struct Classroom))) == NULL)
Lay_NotEnoughMemoryExit ();
/***** Get the classrooms *****/
for (NumCla = 0;
NumCla < Gbl.Classrooms.Num;
NumCla++)
{
Cla = &(Gbl.Classrooms.Lst[NumCla]);
/* Get next classroom */
row = mysql_fetch_row (mysql_res);
/* Get classroom code (row[0]) */
if ((Cla->ClaCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
Lay_ShowErrorAndExit ("Wrong code of classroom.");
/* Get the short name of the classroom (row[1]) */
Str_Copy (Cla->ShrtName,row[1],
Cla_MAX_BYTES_SHRT_NAME);
if (WhichData == Cla_ALL_DATA)
{
/* Get the full name of the classroom (row[2]) */
Str_Copy (Cla->FullName,row[2],
Cla_MAX_BYTES_FULL_NAME);
/* Get seating capacity in this classroom (row[3]) */
if (sscanf (row[3],"%u",&Cla->Capacity) != 1)
Cla->Capacity = Cla_UNLIMITED_CAPACITY;
/* Get the full name of the classroom (row[4]) */
Str_Copy (Cla->Location,row[4],
Cla_MAX_BYTES_LOCATION);
}
}
}
else
Gbl.Classrooms.Num = 0;
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
/************************** Get classroom full name **************************/
/*****************************************************************************/
void Cla_GetDataOfClassroomByCod (struct Classroom *Cla)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned long NumRows;
/***** Clear data *****/
Cla->ShrtName[0] = '\0';
Cla->FullName[0] = '\0';
Cla->Capacity = Cla_UNLIMITED_CAPACITY;
Cla->Location[0] = '\0';
/***** Check if classroom code is correct *****/
if (Cla->ClaCod > 0)
{
/***** Get data of a classroom from database *****/
NumRows = DB_QuerySELECT (&mysql_res,"can not get data of a classroom",
"SELECT ShortName,"
"FullName,"
"Capacity,"
"Location"
" FROM classrooms"
" WHERE ClaCod=%ld",
Cla->ClaCod);
/***** Count number of rows in result *****/
if (NumRows) // Classroom found...
{
/* Get row */
row = mysql_fetch_row (mysql_res);
/* Get the short name of the classroom (row[0]) */
Str_Copy (Cla->ShrtName,row[0],
Cla_MAX_BYTES_SHRT_NAME);
/* Get the full name of the classroom (row[1]) */
Str_Copy (Cla->FullName,row[1],
Cla_MAX_BYTES_FULL_NAME);
/* Get seating capacity in this classroom (row[2]) */
if (sscanf (row[2],"%u",&Cla->Capacity) != 1)
Cla->Capacity = Cla_UNLIMITED_CAPACITY;
/* Get the location of the classroom (row[3]) */
Str_Copy (Cla->Location,row[3],
Cla_MAX_BYTES_LOCATION);
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
}
/*****************************************************************************/
/************************** Free list of classrooms **************************/
/*****************************************************************************/
void Cla_FreeListClassrooms (void)
{
if (Gbl.Classrooms.Lst)
{
/***** Free memory used by the list of classrooms in institution *****/
free ((void *) Gbl.Classrooms.Lst);
Gbl.Classrooms.Lst = NULL;
Gbl.Classrooms.Num = 0;
}
}
/*****************************************************************************/
/************************* List all the classrooms ***************************/
/*****************************************************************************/
static void Cla_ListClassroomsForEdition (void)
{
unsigned NumCla;
struct Classroom *Cla;
/***** Write heading *****/
Tbl_StartTableWide (2);
Cla_PutHeadClassrooms ();
/***** Write all the classrooms *****/
for (NumCla = 0;
NumCla < Gbl.Classrooms.Num;
NumCla++)
{
Cla = &Gbl.Classrooms.Lst[NumCla];
/* Put icon to remove classroom */
fprintf (Gbl.F.Out,"<tr>"
"<td class=\"BM\">");
Frm_StartForm (ActRemCla);
Cla_PutParamClaCod (Cla->ClaCod);
Ico_PutIconRemove ();
Frm_EndForm ();
fprintf (Gbl.F.Out,"</td>");
/* Classroom code */
fprintf (Gbl.F.Out,"<td class=\"DAT RIGHT_MIDDLE\">"
"%ld"
"</td>",
Cla->ClaCod);
/* Classroom short name */
fprintf (Gbl.F.Out,"<td class=\"LEFT_MIDDLE\">");
Frm_StartForm (ActRenClaSho);
Cla_PutParamClaCod (Cla->ClaCod);
fprintf (Gbl.F.Out,"<input type=\"text\" name=\"ShortName\""
" size=\"10\" maxlength=\"%u\" value=\"%s\""
" class=\"INPUT_SHORT_NAME\""
" onchange=\"document.getElementById('%s').submit();\" />",
Cla_MAX_CHARS_SHRT_NAME,Cla->ShrtName,Gbl.Form.Id);
Frm_EndForm ();
fprintf (Gbl.F.Out,"</td>");
/* Classroom full name */
fprintf (Gbl.F.Out,"<td class=\"LEFT_MIDDLE\">");
Frm_StartForm (ActRenClaFul);
Cla_PutParamClaCod (Cla->ClaCod);
fprintf (Gbl.F.Out,"<input type=\"text\" name=\"FullName\""
" size=\"20\" maxlength=\"%u\" value=\"%s\""
" class=\"INPUT_FULL_NAME\""
" onchange=\"document.getElementById('%s').submit();\" />",
Cla_MAX_CHARS_FULL_NAME,Cla->FullName,Gbl.Form.Id);
Frm_EndForm ();
fprintf (Gbl.F.Out,"</td>");
/* Seating capacity */
fprintf (Gbl.F.Out,"<td class=\"LEFT_MIDDLE\">");
Frm_StartForm (ActChgClaMaxStd);
Cla_PutParamClaCod (Cla->ClaCod);
fprintf (Gbl.F.Out,"<input type=\"text\" name=\"Capacity\""
" size=\"3\" maxlength=\"10\" value=\"");
Cla_WriteCapacity (Cla->Capacity);
fprintf (Gbl.F.Out,"\" onchange=\"document.getElementById('%s').submit();\" />",
Gbl.Form.Id);
Frm_EndForm ();
fprintf (Gbl.F.Out,"</td>");
/* Classroom location */
fprintf (Gbl.F.Out,"<td class=\"LEFT_MIDDLE\">");
Frm_StartForm (ActRenClaLoc);
Cla_PutParamClaCod (Cla->ClaCod);
fprintf (Gbl.F.Out,"<input type=\"text\" name=\"Location\""
" size=\"15\" maxlength=\"%u\" value=\"%s\""
" class=\"INPUT_FULL_NAME\""
" onchange=\"document.getElementById('%s').submit();\" />",
Cla_MAX_CHARS_LOCATION,Cla->Location,Gbl.Form.Id);
Frm_EndForm ();
fprintf (Gbl.F.Out,"</td>"
"</tr>");
}
/***** End table *****/
Tbl_EndTable ();
}
/*****************************************************************************/
/****************** Write parameter with code of classroom *******************/
/*****************************************************************************/
static void Cla_PutParamClaCod (long ClaCod)
{
Par_PutHiddenParamLong ("ClaCod",ClaCod);
}
/*****************************************************************************/
/******************* Get parameter with code of classroom ********************/
/*****************************************************************************/
long Cla_GetParamClaCod (void)
{
/***** Get code of classroom *****/
return Par_GetParToLong ("ClaCod");
}
/*****************************************************************************/
/***************************** Remove a classroom ****************************/
/*****************************************************************************/
void Cla_RemoveClassroom (void)
{
extern const char *Txt_Classroom_X_removed;
/***** Classroom constructor *****/
Cla_EditingClassroomConstructor ();
/***** Get classroom code *****/
if ((Cla_EditingCla->ClaCod = Cla_GetParamClaCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of classroom is missing.");
/***** Get data of the classroom from database *****/
Cla_GetDataOfClassroomByCod (Cla_EditingCla);
/***** Update groups assigned to this classroom *****/
DB_QueryUPDATE ("can not update classroom in groups",
"UPDATE crs_grp SET ClaCod=0" // 0 means another classroom
" WHERE ClaCod=%ld",
Cla_EditingCla->ClaCod);
/***** Remove classroom *****/
DB_QueryDELETE ("can not remove a classroom",
"DELETE FROM classrooms WHERE ClaCod=%ld",
Cla_EditingCla->ClaCod);
/***** Create message to show the change made *****/
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_Classroom_X_removed,
Cla_EditingCla->FullName);
}
/*****************************************************************************/
/******************** Remove all classrooms in a centre **********************/
/*****************************************************************************/
void Cla_RemoveAllClassroomsInCtr (long CtrCod)
{
/***** Remove all classrooms in centre *****/
DB_QueryDELETE ("can not remove classrooms",
"DELETE FROM classrooms"
" WHERE CtrCod=%ld",
CtrCod);
}
/*****************************************************************************/
/******************* Change the short name of a classroom ********************/
/*****************************************************************************/
void Cla_RenameClassroomShort (void)
{
/***** Classroom constructor *****/
Cla_EditingClassroomConstructor ();
/***** Rename classroom *****/
Cla_RenameClassroom (Cns_SHRT_NAME);
}
/*****************************************************************************/
/******************* Change the full name of a classroom *********************/
/*****************************************************************************/
void Cla_RenameClassroomFull (void)
{
/***** Classroom constructor *****/
Cla_EditingClassroomConstructor ();
/***** Rename classroom *****/
Cla_RenameClassroom (Cns_FULL_NAME);
}
/*****************************************************************************/
/********************** Change the name of a classroom ***********************/
/*****************************************************************************/
static void Cla_RenameClassroom (Cns_ShrtOrFullName_t ShrtOrFullName)
{
extern const char *Txt_You_can_not_leave_the_name_of_the_classroom_X_empty;
extern const char *Txt_The_classroom_X_already_exists;
extern const char *Txt_The_classroom_X_has_been_renamed_as_Y;
extern const char *Txt_The_name_of_the_classroom_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 *CurrentClaName = NULL; // Initialized to avoid warning
char NewClaName[Cla_MAX_BYTES_FULL_NAME + 1];
switch (ShrtOrFullName)
{
case Cns_SHRT_NAME:
ParamName = "ShortName";
FieldName = "ShortName";
MaxBytes = Cla_MAX_BYTES_SHRT_NAME;
CurrentClaName = Cla_EditingCla->ShrtName;
break;
case Cns_FULL_NAME:
ParamName = "FullName";
FieldName = "FullName";
MaxBytes = Cla_MAX_BYTES_FULL_NAME;
CurrentClaName = Cla_EditingCla->FullName;
break;
}
/***** Get parameters from form *****/
/* Get the code of the classroom */
if ((Cla_EditingCla->ClaCod = Cla_GetParamClaCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of classroom is missing.");
/* Get the new name for the classroom */
Par_GetParToText (ParamName,NewClaName,MaxBytes);
/***** Get from the database the old names of the classroom *****/
Cla_GetDataOfClassroomByCod (Cla_EditingCla);
/***** Check if new name is empty *****/
if (!NewClaName[0])
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_You_can_not_leave_the_name_of_the_classroom_X_empty,
CurrentClaName);
else
{
/***** Check if old and new names are the same
(this happens when return is pressed without changes) *****/
if (strcmp (CurrentClaName,NewClaName)) // Different names
{
/***** If classroom was in database... *****/
if (Cla_CheckIfClassroomNameExists (ParamName,NewClaName,Cla_EditingCla->ClaCod))
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_The_classroom_X_already_exists,
NewClaName);
else
{
/* Update the table changing old name by new name */
Cla_UpdateClaNameDB (Cla_EditingCla->ClaCod,FieldName,NewClaName);
/* Write message to show the change made */
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_The_classroom_X_has_been_renamed_as_Y,
CurrentClaName,NewClaName);
}
}
else // The same name
Ale_CreateAlert (Ale_INFO,NULL,
Txt_The_name_of_the_classroom_X_has_not_changed,
CurrentClaName);
}
/***** Update classroom name *****/
Str_Copy (CurrentClaName,NewClaName,
MaxBytes);
}
/*****************************************************************************/
/******************** Check if the name of classroom exists ******************/
/*****************************************************************************/
static bool Cla_CheckIfClassroomNameExists (const char *FieldName,const char *Name,long ClaCod)
{
/***** Get number of classrooms with a name from database *****/
return (DB_QueryCOUNT ("can not check if the name of a classroom"
" already existed",
"SELECT COUNT(*) FROM classrooms"
" WHERE CtrCod=%ld"
" AND %s='%s' AND ClaCod<>%ld",
Gbl.Hierarchy.Ctr.CtrCod,
FieldName,Name,ClaCod) != 0);
}
/*****************************************************************************/
/************** Update classroom name in table of classrooms *****************/
/*****************************************************************************/
static void Cla_UpdateClaNameDB (long ClaCod,const char *FieldName,const char *NewClaName)
{
/***** Update classroom changing old name by new name */
DB_QueryUPDATE ("can not update the name of a classroom",
"UPDATE classrooms SET %s='%s' WHERE ClaCod=%ld",
FieldName,NewClaName,ClaCod);
}
/*****************************************************************************/
/****************** Change sitting capacity of a classroom *******************/
/*****************************************************************************/
void Cla_ChangeCapacity (void)
{
extern const char *Txt_The_capacity_of_classroom_X_has_not_changed;
extern const char *Txt_The_classroom_X_does_not_have_a_limited_capacity_now;
extern const char *Txt_The_capacity_of_classroom_X_is_now_Y;
unsigned NewCapacity;
/***** Classroom constructor *****/
Cla_EditingClassroomConstructor ();
/***** Get parameters from form *****/
/* Get the code of the classroom */
if ((Cla_EditingCla->ClaCod = Cla_GetParamClaCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of classroom is missing.");
/* Get the seating capacity of the classroom */
NewCapacity = (unsigned)
Par_GetParToUnsignedLong ("Capacity",
0,
Cla_MAX_CAPACITY,
Cla_UNLIMITED_CAPACITY);
/***** Get data of the classroom from database *****/
Cla_GetDataOfClassroomByCod (Cla_EditingCla);
/***** Check if the old capacity equals the new one
(this happens when return is pressed without changes) *****/
if (Cla_EditingCla->Capacity == NewCapacity)
/***** Message to show no changes made *****/
Ale_CreateAlert (Ale_INFO,NULL,
Txt_The_capacity_of_classroom_X_has_not_changed,
Cla_EditingCla->FullName);
else
{
/***** Update the table of groups changing the old capacity to the new *****/
DB_QueryUPDATE ("can not update the capacity of a classroom",
"UPDATE classrooms SET Capacity=%u WHERE ClaCod=%ld",
NewCapacity,Cla_EditingCla->ClaCod);
Cla_EditingCla->Capacity = NewCapacity;
/***** Message to show the change made *****/
if (NewCapacity > Grp_MAX_STUDENTS_IN_A_GROUP)
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_The_classroom_X_does_not_have_a_limited_capacity_now,
Cla_EditingCla->FullName);
else
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_The_capacity_of_classroom_X_is_now_Y,
Cla_EditingCla->FullName,NewCapacity);
}
}
/*****************************************************************************/
/****************** Write seating capacity of a classroom ********************/
/*****************************************************************************/
static void Cla_WriteCapacity (unsigned Capacity)
{
if (Capacity <= Cla_MAX_CAPACITY)
fprintf (Gbl.F.Out,"%u",Capacity);
}
/*****************************************************************************/
/******************** Change the location of a classroom *********************/
/*****************************************************************************/
void Cla_ChangeClassroomLocation (void)
{
extern const char *Txt_The_location_of_the_classroom_X_has_changed_to_Y;
extern const char *Txt_The_location_of_the_classroom_X_has_not_changed;
char NewLocation[Cla_MAX_BYTES_FULL_NAME + 1];
/***** Classroom constructor *****/
Cla_EditingClassroomConstructor ();
/***** Get parameters from form *****/
/* Get the code of the classroom */
if ((Cla_EditingCla->ClaCod = Cla_GetParamClaCod ()) == -1L)
Lay_ShowErrorAndExit ("Code of classroom is missing.");
/* Get the new location for the classroom */
Par_GetParToText ("Location",NewLocation,Cla_MAX_BYTES_LOCATION);
/***** Get from the database the old location of the classroom *****/
Cla_GetDataOfClassroomByCod (Cla_EditingCla);
/***** Check if old and new locations are the same
(this happens when return is pressed without changes) *****/
if (strcmp (Cla_EditingCla->Location,NewLocation)) // Different locations
{
/* Update the table changing old name by new name */
Cla_UpdateClaNameDB (Cla_EditingCla->ClaCod,"Location",NewLocation);
Str_Copy (Cla_EditingCla->Location,NewLocation,
Cla_MAX_BYTES_LOCATION);
/* Write message to show the change made */
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_The_location_of_the_classroom_X_has_changed_to_Y,
Cla_EditingCla->FullName,NewLocation);
}
else // The same location
Ale_CreateAlert (Ale_INFO,NULL,
Txt_The_location_of_the_classroom_X_has_not_changed,
Cla_EditingCla->FullName);
}
/*****************************************************************************/
/******* Show alerts after changing a classroom and continue editing *********/
/*****************************************************************************/
void Cla_ContEditAfterChgCla (void)
{
/***** Write message to show the change made *****/
Ale_ShowAlerts (NULL);
/***** Show the form again *****/
Cla_EditClassroomsInternal ();
/***** Classroom destructor *****/
Cla_EditingClassroomDestructor ();
}
/*****************************************************************************/
/******************* Put a form to create a new classroom ********************/
/*****************************************************************************/
static void Cla_PutFormToCreateClassroom (void)
{
extern const char *Txt_New_classroom;
extern const char *Txt_Create_classroom;
/***** Start form *****/
Frm_StartForm (ActNewCla);
/***** Start box and table *****/
Box_StartBoxTable (NULL,Txt_New_classroom,NULL,
NULL,Box_NOT_CLOSABLE,2);
/***** Write heading *****/
Cla_PutHeadClassrooms ();
/***** Column to remove classroom, disabled here *****/
fprintf (Gbl.F.Out,"<tr>"
"<td class=\"BM\"></td>");
/***** Classroom code *****/
fprintf (Gbl.F.Out,"<td class=\"CODE\"></td>");
/***** Classroom short name *****/
fprintf (Gbl.F.Out,"<td class=\"LEFT_MIDDLE\">"
"<input type=\"text\" name=\"ShortName\""
" size=\"10\" maxlength=\"%u\" value=\"%s\""
" class=\"INPUT_SHORT_NAME\""
" required=\"required\" />"
"</td>",
Cla_MAX_CHARS_SHRT_NAME,Cla_EditingCla->ShrtName);
/***** Classroom full name *****/
fprintf (Gbl.F.Out,"<td class=\"LEFT_MIDDLE\">"
"<input type=\"text\" name=\"FullName\""
" size=\"20\" maxlength=\"%u\" value=\"%s\""
" class=\"INPUT_FULL_NAME\""
" required=\"required\" />"
"</td>",
Cla_MAX_CHARS_FULL_NAME,Cla_EditingCla->FullName);
/***** Seating capacity *****/
fprintf (Gbl.F.Out,"<td class=\"LEFT_MIDDLE\">"
"<input type=\"text\" name=\"Capacity\""
" size=\"3\" maxlength=\"10\" value=\"");
Cla_WriteCapacity (Cla_EditingCla->Capacity);
fprintf (Gbl.F.Out,"\" />"
"</td>");
/***** Classroom location *****/
fprintf (Gbl.F.Out,"<td class=\"LEFT_MIDDLE\">"
"<input type=\"text\" name=\"Location\""
" size=\"15\" maxlength=\"%u\" value=\"%s\""
" class=\"INPUT_FULL_NAME\" />"
"</td>"
"</tr>",
Cla_MAX_CHARS_LOCATION,Cla_EditingCla->Location);
/***** End table, send button and end box *****/
Box_EndBoxTableWithButton (Btn_CREATE_BUTTON,Txt_Create_classroom);
/***** End form *****/
Frm_EndForm ();
}
/*****************************************************************************/
/****************** Write header with fields of a classroom ******************/
/*****************************************************************************/
static void Cla_PutHeadClassrooms (void)
{
extern const char *Txt_Code;
extern const char *Txt_Short_name;
extern const char *Txt_Full_name;
extern const char *Txt_Capacity_OF_A_CLASSROOM;
extern const char *Txt_Location;
fprintf (Gbl.F.Out,"<tr>"
"<th class=\"BM\"></th>"
"<th class=\"RIGHT_MIDDLE\">"
"%s"
"</th>"
"<th class=\"LEFT_MIDDLE\">"
"%s"
"</th>"
"<th class=\"LEFT_MIDDLE\">"
"%s"
"</th>"
"<th class=\"LEFT_MIDDLE\">"
"%s"
"</th>"
"<th class=\"LEFT_MIDDLE\">"
"%s"
"</th>"
"</tr>",
Txt_Code,
Txt_Short_name,
Txt_Full_name,
Txt_Capacity_OF_A_CLASSROOM,
Txt_Location);
}
/*****************************************************************************/
/***************** Receive form to create a new classroom ********************/
/*****************************************************************************/
void Cla_RecFormNewClassroom (void)
{
extern const char *Txt_The_classroom_X_already_exists;
extern const char *Txt_Created_new_classroom_X;
extern const char *Txt_You_must_specify_the_short_name_and_the_full_name_of_the_new_classroom;
/***** Classroom constructor *****/
Cla_EditingClassroomConstructor ();
/***** Get parameters from form *****/
/* Get classroom short name */
Par_GetParToText ("ShortName",Cla_EditingCla->ShrtName,Cla_MAX_BYTES_SHRT_NAME);
/* Get classroom full name */
Par_GetParToText ("FullName",Cla_EditingCla->FullName,Cla_MAX_BYTES_FULL_NAME);
/* Get seating capacity */
Cla_EditingCla->Capacity = (unsigned)
Par_GetParToUnsignedLong ("Capacity",
0,
Cla_MAX_CAPACITY,
Cla_UNLIMITED_CAPACITY);
/* Get classroom location */
Par_GetParToText ("Location",Cla_EditingCla->Location,Cla_MAX_BYTES_LOCATION);
if (Cla_EditingCla->ShrtName[0] &&
Cla_EditingCla->FullName[0]) // If there's a classroom name
{
/***** If name of classroom was in database... *****/
if (Cla_CheckIfClassroomNameExists ("ShortName",Cla_EditingCla->ShrtName,-1L))
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_The_classroom_X_already_exists,
Cla_EditingCla->ShrtName);
else if (Cla_CheckIfClassroomNameExists ("FullName",Cla_EditingCla->FullName,-1L))
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_The_classroom_X_already_exists,
Cla_EditingCla->FullName);
else // Add new classroom to database
{
Cla_CreateClassroom (Cla_EditingCla);
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_Created_new_classroom_X,
Cla_EditingCla->FullName);
}
}
else // If there is not a classroom name
Ale_CreateAlert (Ale_WARNING,NULL,
Txt_You_must_specify_the_short_name_and_the_full_name_of_the_new_classroom);
}
/*****************************************************************************/
/************************** Create a new classroom ***************************/
/*****************************************************************************/
static void Cla_CreateClassroom (struct Classroom *Cla)
{
/***** Create a new classroom *****/
DB_QueryINSERT ("can not create classroom",
"INSERT INTO classrooms"
" (CtrCod,ShortName,FullName,Capacity,Location)"
" VALUES"
" (%ld,'%s','%s',%u,'%s')",
Gbl.Hierarchy.Ctr.CtrCod,
Cla->ShrtName,Cla->FullName,Cla->Capacity,Cla->Location);
}
/*****************************************************************************/
/************************* Classroom constructor/destructor **********************/
/*****************************************************************************/
static void Cla_EditingClassroomConstructor (void)
{
/***** Pointer must be NULL *****/
if (Cla_EditingCla != NULL)
Lay_ShowErrorAndExit ("Error initializing classroom.");
/***** Allocate memory for classroom *****/
if ((Cla_EditingCla = (struct Classroom *) malloc (sizeof (struct Classroom))) == NULL)
Lay_ShowErrorAndExit ("Error allocating memory for classroom.");
/***** Reset classroom *****/
Cla_EditingCla->ClaCod = -1L;
Cla_EditingCla->InsCod = -1L;
Cla_EditingCla->ShrtName[0] = '\0';
Cla_EditingCla->FullName[0] = '\0';
Cla_EditingCla->Capacity = Cla_UNLIMITED_CAPACITY;
Cla_EditingCla->Location[0] = '\0';
}
static void Cla_EditingClassroomDestructor (void)
{
/***** Free memory used for classroom *****/
if (Cla_EditingCla != NULL)
{
free ((void *) Cla_EditingCla);
Cla_EditingCla = NULL;
}
}