2020-03-21 15:41:25 +01:00
|
|
|
|
// swad_test_config.c: self-assessment tests configuration
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
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.
|
2023-03-10 17:21:04 +01:00
|
|
|
|
Copyright (C) 1999-2023 Antonio Ca<EFBFBD>as Vargas
|
2020-03-21 15:41:25 +01:00
|
|
|
|
|
|
|
|
|
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 <string.h> // For string functions
|
|
|
|
|
|
2022-11-06 18:11:10 +01:00
|
|
|
|
#include "swad_action_list.h"
|
2021-10-27 00:02:29 +02:00
|
|
|
|
#include "swad_alert.h"
|
|
|
|
|
#include "swad_box.h"
|
2020-03-21 15:41:25 +01:00
|
|
|
|
#include "swad_database.h"
|
2021-10-26 09:23:06 +02:00
|
|
|
|
#include "swad_form.h"
|
2020-03-21 15:41:25 +01:00
|
|
|
|
#include "swad_global.h"
|
2021-10-27 00:02:29 +02:00
|
|
|
|
#include "swad_parameter.h"
|
|
|
|
|
#include "swad_question.h"
|
2021-10-26 09:23:06 +02:00
|
|
|
|
#include "swad_tag_database.h"
|
2020-04-14 17:15:17 +02:00
|
|
|
|
#include "swad_test.h"
|
2020-03-21 15:41:25 +01:00
|
|
|
|
#include "swad_test_config.h"
|
2021-10-27 00:02:29 +02:00
|
|
|
|
#include "swad_test_database.h"
|
2020-03-21 15:41:25 +01:00
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************** External global variables from others modules ****************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
extern struct Globals Gbl;
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************************* Private global variables **************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
struct TstCfg_Config
|
|
|
|
|
{
|
|
|
|
|
TstCfg_Pluggable_t Pluggable;
|
|
|
|
|
unsigned Min; // Minimum number of questions
|
|
|
|
|
unsigned Def; // Default number of questions
|
|
|
|
|
unsigned Max; // Maximum number of questions
|
|
|
|
|
unsigned long MinTimeNxtTstPerQst;
|
|
|
|
|
unsigned Visibility; // One bit for each visibility item
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct TstCfg_Config TstCfg_Config;
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************************** Private prototypes ****************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2021-10-26 09:23:06 +02:00
|
|
|
|
static void TstCfg_ShowFormConfig (void);
|
|
|
|
|
static void TstCfg_PutInputFieldNumQsts (const char *Field,const char *Label,
|
|
|
|
|
unsigned Value);
|
|
|
|
|
|
2023-03-22 11:34:06 +01:00
|
|
|
|
static void TstCfg_GetConfigDataFromRow (MYSQL_RES *mysql_res);
|
2021-10-27 00:02:29 +02:00
|
|
|
|
|
2020-03-21 15:41:25 +01:00
|
|
|
|
static TstCfg_Pluggable_t TstCfg_GetPluggableFromForm (void);
|
|
|
|
|
static void TstCfg_CheckAndCorrectMinDefMax (void);
|
|
|
|
|
|
2021-10-26 09:23:06 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************************** Form to rename tags ***************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
void TstCfg_CheckAndShowFormConfig (void)
|
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_Please_specify_if_you_allow_downloading_the_question_bank_from_other_applications;
|
|
|
|
|
|
|
|
|
|
/***** If current course has tests and pluggable is unknown... *****/
|
|
|
|
|
if (TstCfg_CheckIfPluggableIsUnknownAndCrsHasTests ())
|
|
|
|
|
Ale_ShowAlert (Ale_WARNING,Txt_Please_specify_if_you_allow_downloading_the_question_bank_from_other_applications);
|
|
|
|
|
|
|
|
|
|
/***** Form to configure test *****/
|
|
|
|
|
TstCfg_ShowFormConfig ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/*************** Get configuration of test for current course ****************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
// Returns true if course has test tags and pluggable is unknown
|
|
|
|
|
// Return false if course has no test tags or pluggable is known
|
|
|
|
|
|
|
|
|
|
bool TstCfg_CheckIfPluggableIsUnknownAndCrsHasTests (void)
|
|
|
|
|
{
|
2021-10-27 00:02:29 +02:00
|
|
|
|
extern const char *Tst_DB_Pluggable[TstCfg_NUM_OPTIONS_PLUGGABLE];
|
2021-10-26 09:23:06 +02:00
|
|
|
|
MYSQL_RES *mysql_res;
|
|
|
|
|
MYSQL_ROW row;
|
|
|
|
|
unsigned NumRows;
|
|
|
|
|
TstCfg_Pluggable_t Pluggable;
|
|
|
|
|
|
|
|
|
|
/***** Get pluggability of tests for current course from database *****/
|
2021-10-27 00:02:29 +02:00
|
|
|
|
NumRows = Tst_DB_GetPluggableFromConfig (&mysql_res);
|
2021-10-26 09:23:06 +02:00
|
|
|
|
|
|
|
|
|
if (NumRows == 0)
|
|
|
|
|
TstCfg_SetConfigPluggable (TstCfg_PLUGGABLE_UNKNOWN);
|
|
|
|
|
else // NumRows == 1
|
|
|
|
|
{
|
|
|
|
|
/***** Get whether test are visible via plugins or not *****/
|
|
|
|
|
row = mysql_fetch_row (mysql_res);
|
|
|
|
|
|
|
|
|
|
TstCfg_SetConfigPluggable (TstCfg_PLUGGABLE_UNKNOWN);
|
|
|
|
|
for (Pluggable = TstCfg_PLUGGABLE_NO;
|
|
|
|
|
Pluggable <= TstCfg_PLUGGABLE_YES;
|
|
|
|
|
Pluggable++)
|
2021-10-27 00:02:29 +02:00
|
|
|
|
if (!strcmp (row[0],Tst_DB_Pluggable[Pluggable]))
|
2021-10-26 09:23:06 +02:00
|
|
|
|
{
|
|
|
|
|
TstCfg_SetConfigPluggable (Pluggable);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Free structure that stores the query result *****/
|
|
|
|
|
DB_FreeMySQLResult (&mysql_res);
|
|
|
|
|
|
|
|
|
|
/***** Get if current course has tests from database *****/
|
|
|
|
|
if (TstCfg_GetConfigPluggable () == TstCfg_PLUGGABLE_UNKNOWN)
|
|
|
|
|
return Tag_DB_CheckIfCurrentCrsHasTestTags (); // Return true if course has test tags
|
|
|
|
|
|
|
|
|
|
return false; // Pluggable is not unknown
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/********************* Show a form to to configure test **********************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void TstCfg_ShowFormConfig (void)
|
|
|
|
|
{
|
|
|
|
|
extern const char *Hlp_ASSESSMENT_Tests_configuring_tests;
|
|
|
|
|
extern const char *Txt_Configure_tests;
|
|
|
|
|
extern const char *Txt_Plugins;
|
|
|
|
|
extern const char *Txt_TST_PLUGGABLE[TstCfg_NUM_OPTIONS_PLUGGABLE];
|
|
|
|
|
extern const char *Txt_Number_of_questions;
|
|
|
|
|
extern const char *Txt_minimum;
|
|
|
|
|
extern const char *Txt_default;
|
|
|
|
|
extern const char *Txt_maximum;
|
|
|
|
|
extern const char *Txt_Minimum_time_seconds_per_question_between_two_tests;
|
|
|
|
|
extern const char *Txt_Result_visibility;
|
|
|
|
|
extern const char *Txt_Save_changes;
|
|
|
|
|
struct Qst_Questions Questions;
|
|
|
|
|
TstCfg_Pluggable_t Pluggable;
|
|
|
|
|
char StrMinTimeNxtTstPerQst[Cns_MAX_DECIMAL_DIGITS_ULONG + 1];
|
|
|
|
|
|
|
|
|
|
/***** Create test *****/
|
|
|
|
|
Qst_Constructor (&Questions);
|
|
|
|
|
|
|
|
|
|
/***** Read test configuration from database *****/
|
2021-10-26 17:33:20 +02:00
|
|
|
|
TstCfg_GetConfig ();
|
2021-10-26 09:23:06 +02:00
|
|
|
|
|
|
|
|
|
/***** Begin box *****/
|
|
|
|
|
Box_BoxBegin (NULL,Txt_Configure_tests,
|
|
|
|
|
Tst_PutIconsTests,NULL,
|
|
|
|
|
Hlp_ASSESSMENT_Tests_configuring_tests,Box_NOT_CLOSABLE);
|
|
|
|
|
|
|
|
|
|
/***** Begin form *****/
|
|
|
|
|
Frm_BeginForm (ActRcvCfgTst);
|
|
|
|
|
|
|
|
|
|
/***** Tests are visible from plugins? *****/
|
|
|
|
|
HTM_TABLE_BeginCenterPadding (2);
|
|
|
|
|
HTM_TR_Begin (NULL);
|
|
|
|
|
|
2022-03-30 14:08:48 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"RT FORM_IN_%s\"",
|
2022-04-05 01:00:24 +02:00
|
|
|
|
The_GetSuffix ());
|
2021-10-26 09:23:06 +02:00
|
|
|
|
HTM_TxtColon (Txt_Plugins);
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TD_Begin ("class=\"LB\"");
|
|
|
|
|
for (Pluggable = TstCfg_PLUGGABLE_NO;
|
|
|
|
|
Pluggable <= TstCfg_PLUGGABLE_YES;
|
|
|
|
|
Pluggable++)
|
|
|
|
|
{
|
2022-03-29 00:58:40 +02:00
|
|
|
|
HTM_LABEL_Begin ("class=\"DAT_%s\"",
|
2022-04-05 01:00:24 +02:00
|
|
|
|
The_GetSuffix ());
|
2023-03-30 18:30:44 +02:00
|
|
|
|
HTM_INPUT_RADIO ("Pluggable",HTM_DONT_SUBMIT_ON_CLICK,
|
2021-10-26 09:23:06 +02:00
|
|
|
|
"value=\"%u\"%s",
|
|
|
|
|
(unsigned) Pluggable,
|
|
|
|
|
Pluggable == TstCfg_GetConfigPluggable () ? " checked=\"checked\"" :
|
|
|
|
|
"");
|
|
|
|
|
HTM_Txt (Txt_TST_PLUGGABLE[Pluggable]);
|
|
|
|
|
HTM_LABEL_End ();
|
|
|
|
|
HTM_BR ();
|
|
|
|
|
}
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TR_End ();
|
|
|
|
|
|
|
|
|
|
/***** Number of questions *****/
|
|
|
|
|
HTM_TR_Begin (NULL);
|
|
|
|
|
|
2022-03-30 14:08:48 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"RT FORM_IN_%s\"",
|
2022-04-05 01:00:24 +02:00
|
|
|
|
The_GetSuffix ());
|
2021-10-26 09:23:06 +02:00
|
|
|
|
HTM_TxtColon (Txt_Number_of_questions);
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TD_Begin ("class=\"LB\"");
|
|
|
|
|
HTM_TABLE_BeginPadding (2);
|
|
|
|
|
TstCfg_PutInputFieldNumQsts ("NumQstMin",Txt_minimum,
|
|
|
|
|
TstCfg_GetConfigMin ()); // Minimum number of questions
|
|
|
|
|
TstCfg_PutInputFieldNumQsts ("NumQstDef",Txt_default,
|
|
|
|
|
TstCfg_GetConfigDef ()); // Default number of questions
|
|
|
|
|
TstCfg_PutInputFieldNumQsts ("NumQstMax",Txt_maximum,
|
|
|
|
|
TstCfg_GetConfigMax ()); // Maximum number of questions
|
|
|
|
|
HTM_TABLE_End ();
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TR_End ();
|
|
|
|
|
|
|
|
|
|
/***** Minimum time between consecutive tests, per question *****/
|
|
|
|
|
HTM_TR_Begin (NULL);
|
|
|
|
|
|
|
|
|
|
/* Label */
|
|
|
|
|
Frm_LabelColumn ("RT","MinTimeNxtTstPerQst",
|
|
|
|
|
Txt_Minimum_time_seconds_per_question_between_two_tests);
|
|
|
|
|
|
|
|
|
|
/* Data */
|
|
|
|
|
HTM_TD_Begin ("class=\"LB\"");
|
|
|
|
|
snprintf (StrMinTimeNxtTstPerQst,sizeof (StrMinTimeNxtTstPerQst),"%lu",
|
|
|
|
|
TstCfg_GetConfigMinTimeNxtTstPerQst ());
|
|
|
|
|
HTM_INPUT_TEXT ("MinTimeNxtTstPerQst",Cns_MAX_DECIMAL_DIGITS_ULONG,StrMinTimeNxtTstPerQst,
|
|
|
|
|
HTM_DONT_SUBMIT_ON_CHANGE,
|
2021-12-19 20:16:58 +01:00
|
|
|
|
"id=\"MinTimeNxtTstPerQst\" size=\"7\""
|
2022-03-30 00:46:18 +02:00
|
|
|
|
" class=\"INPUT_%s\""
|
2021-12-19 20:16:58 +01:00
|
|
|
|
" required=\"required\"",
|
2022-04-05 01:00:24 +02:00
|
|
|
|
The_GetSuffix ());
|
2021-10-26 09:23:06 +02:00
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TR_End ();
|
|
|
|
|
|
|
|
|
|
/***** Visibility of test prints *****/
|
|
|
|
|
HTM_TR_Begin (NULL);
|
|
|
|
|
|
2022-03-30 14:08:48 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"RT FORM_IN_%s\"",
|
2022-04-05 01:00:24 +02:00
|
|
|
|
The_GetSuffix ());
|
2021-10-26 09:23:06 +02:00
|
|
|
|
HTM_TxtColon (Txt_Result_visibility);
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TD_Begin ("class=\"LB\"");
|
|
|
|
|
TstVis_PutVisibilityCheckboxes (TstCfg_GetConfigVisibility ());
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TR_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TABLE_End ();
|
|
|
|
|
|
|
|
|
|
/***** Send button *****/
|
|
|
|
|
Btn_PutConfirmButton (Txt_Save_changes);
|
|
|
|
|
|
|
|
|
|
/***** End form *****/
|
|
|
|
|
Frm_EndForm ();
|
|
|
|
|
|
|
|
|
|
/***** End box *****/
|
|
|
|
|
Box_BoxEnd ();
|
|
|
|
|
|
|
|
|
|
/***** Destroy test *****/
|
|
|
|
|
Qst_Destructor (&Questions);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/*************** Get configuration of test for current course ****************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void TstCfg_PutInputFieldNumQsts (const char *Field,const char *Label,
|
|
|
|
|
unsigned Value)
|
|
|
|
|
{
|
|
|
|
|
char StrValue[Cns_MAX_DECIMAL_DIGITS_UINT + 1];
|
|
|
|
|
|
|
|
|
|
HTM_TR_Begin (NULL);
|
|
|
|
|
|
|
|
|
|
HTM_TD_Begin ("class=\"RM\"");
|
2022-03-29 00:58:40 +02:00
|
|
|
|
HTM_LABEL_Begin ("for=\"%s\" class=\"DAT_%s\"",
|
2022-04-05 01:00:24 +02:00
|
|
|
|
Field,The_GetSuffix ());
|
2021-10-26 09:23:06 +02:00
|
|
|
|
HTM_Txt (Label);
|
|
|
|
|
HTM_LABEL_End ();
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TD_Begin ("class=\"LM\"");
|
|
|
|
|
snprintf (StrValue,sizeof (StrValue),"%u",Value);
|
|
|
|
|
HTM_INPUT_TEXT (Field,Cns_MAX_DECIMAL_DIGITS_UINT,StrValue,
|
|
|
|
|
HTM_DONT_SUBMIT_ON_CHANGE,
|
2022-03-30 00:46:18 +02:00
|
|
|
|
"id=\"%s\" size=\"3\" class=\"INPUT_%s\""
|
2021-12-19 20:16:58 +01:00
|
|
|
|
" required=\"required\"",
|
2022-04-05 01:00:24 +02:00
|
|
|
|
Field,The_GetSuffix ());
|
2021-10-26 09:23:06 +02:00
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TR_End ();
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-21 15:41:25 +01:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/*************** Get configuration of test for current course ****************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2021-10-26 17:33:20 +02:00
|
|
|
|
void TstCfg_GetConfig (void)
|
2020-03-21 15:41:25 +01:00
|
|
|
|
{
|
|
|
|
|
MYSQL_RES *mysql_res;
|
|
|
|
|
|
|
|
|
|
/***** Get configuration of test for current course from database *****/
|
2021-10-27 00:02:29 +02:00
|
|
|
|
if (Tst_DB_GetConfig (&mysql_res,Gbl.Hierarchy.Crs.CrsCod))
|
2023-03-22 11:34:06 +01:00
|
|
|
|
TstCfg_GetConfigDataFromRow (mysql_res);
|
2021-10-27 00:02:29 +02:00
|
|
|
|
else
|
2020-03-21 15:41:25 +01:00
|
|
|
|
{
|
|
|
|
|
TstCfg_SetConfigPluggable (TstCfg_PLUGGABLE_UNKNOWN);
|
|
|
|
|
TstCfg_SetConfigMin (TstCfg_DEFAULT_MIN_QUESTIONS);
|
|
|
|
|
TstCfg_SetConfigDef (TstCfg_DEFAULT_DEF_QUESTIONS);
|
|
|
|
|
TstCfg_SetConfigMax (TstCfg_DEFAULT_MAX_QUESTIONS);
|
2021-10-27 00:02:29 +02:00
|
|
|
|
TstCfg_SetConfigMinTimeNxtTstPerQst (0UL);
|
|
|
|
|
TstCfg_SetConfigVisibility (TstVis_VISIBILITY_DEFAULT);
|
2020-03-21 15:41:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Free structure that stores the query result *****/
|
|
|
|
|
DB_FreeMySQLResult (&mysql_res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************ Get configuration values from a database table row *************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2023-03-22 11:34:06 +01:00
|
|
|
|
static void TstCfg_GetConfigDataFromRow (MYSQL_RES *mysql_res)
|
2020-03-21 15:41:25 +01:00
|
|
|
|
{
|
2021-10-27 00:02:29 +02:00
|
|
|
|
extern const char *Tst_DB_Pluggable[TstCfg_NUM_OPTIONS_PLUGGABLE];
|
2023-03-22 01:42:27 +01:00
|
|
|
|
MYSQL_ROW row;
|
2020-03-21 15:41:25 +01:00
|
|
|
|
int IntNum;
|
|
|
|
|
long LongNum;
|
|
|
|
|
TstCfg_Pluggable_t Pluggable;
|
|
|
|
|
|
2023-03-23 19:56:18 +01:00
|
|
|
|
/***** Get next row from result *****/
|
2023-03-22 01:42:27 +01:00
|
|
|
|
row = mysql_fetch_row (mysql_res);
|
|
|
|
|
|
2020-03-21 15:41:25 +01:00
|
|
|
|
/***** Get whether test are visible via plugins or not *****/
|
|
|
|
|
TstCfg_SetConfigPluggable (TstCfg_PLUGGABLE_UNKNOWN);
|
2020-04-23 20:24:36 +02:00
|
|
|
|
for (Pluggable = TstCfg_PLUGGABLE_NO;
|
2020-03-21 15:41:25 +01:00
|
|
|
|
Pluggable <= TstCfg_PLUGGABLE_YES;
|
|
|
|
|
Pluggable++)
|
2021-10-27 00:02:29 +02:00
|
|
|
|
if (!strcmp (row[0],Tst_DB_Pluggable[Pluggable]))
|
2020-03-21 15:41:25 +01:00
|
|
|
|
{
|
|
|
|
|
TstCfg_SetConfigPluggable (Pluggable);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Get number of questions *****/
|
|
|
|
|
if (sscanf (row[1],"%d",&IntNum) == 1)
|
|
|
|
|
TstCfg_SetConfigMin ((IntNum < 1) ? 1 :
|
2021-10-27 00:02:29 +02:00
|
|
|
|
(unsigned) IntNum);
|
2020-03-21 15:41:25 +01:00
|
|
|
|
else
|
|
|
|
|
TstCfg_SetConfigMin (TstCfg_DEFAULT_MIN_QUESTIONS);
|
|
|
|
|
|
|
|
|
|
if (sscanf (row[2],"%d",&IntNum) == 1)
|
|
|
|
|
TstCfg_SetConfigDef ((IntNum < 1) ? 1 :
|
2021-10-27 00:02:29 +02:00
|
|
|
|
(unsigned) IntNum);
|
2020-03-21 15:41:25 +01:00
|
|
|
|
else
|
|
|
|
|
TstCfg_SetConfigDef (TstCfg_DEFAULT_DEF_QUESTIONS);
|
|
|
|
|
|
|
|
|
|
if (sscanf (row[3],"%d",&IntNum) == 1)
|
|
|
|
|
TstCfg_SetConfigMax ((IntNum < 1) ? 1 :
|
2021-10-27 00:02:29 +02:00
|
|
|
|
(unsigned) IntNum);
|
2020-03-21 15:41:25 +01:00
|
|
|
|
else
|
|
|
|
|
TstCfg_SetConfigMax (TstCfg_DEFAULT_MAX_QUESTIONS);
|
|
|
|
|
|
|
|
|
|
/***** Check and correct numbers *****/
|
|
|
|
|
TstCfg_CheckAndCorrectMinDefMax ();
|
|
|
|
|
|
|
|
|
|
/***** Get minimum time between consecutive tests, per question (row[4]) *****/
|
|
|
|
|
if (sscanf (row[4],"%ld",&LongNum) == 1)
|
|
|
|
|
TstCfg_SetConfigMinTimeNxtTstPerQst ((LongNum < 1L) ? 0UL :
|
2021-10-27 00:02:29 +02:00
|
|
|
|
(unsigned long) LongNum);
|
2020-03-21 15:41:25 +01:00
|
|
|
|
else
|
|
|
|
|
TstCfg_SetConfigMinTimeNxtTstPerQst (0UL);
|
|
|
|
|
|
|
|
|
|
/***** Get visibility (row[5]) *****/
|
2020-04-02 03:28:08 +02:00
|
|
|
|
TstCfg_SetConfigVisibility (TstVis_GetVisibilityFromStr (row[5]));
|
2020-03-21 15:41:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************* Receive configuration of test for current course **************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
void TstCfg_ReceiveConfigTst (void)
|
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_The_test_configuration_has_been_updated;
|
|
|
|
|
|
|
|
|
|
/***** Get whether test are visible via plugins or not *****/
|
|
|
|
|
TstCfg_SetConfigPluggable (TstCfg_GetPluggableFromForm ());
|
|
|
|
|
|
|
|
|
|
/***** Get number of questions *****/
|
|
|
|
|
/* Get minimum number of questions */
|
|
|
|
|
TstCfg_SetConfigMin ((unsigned)
|
2023-03-10 00:13:55 +01:00
|
|
|
|
Par_GetParUnsignedLong ("NumQstMin",
|
|
|
|
|
1,
|
|
|
|
|
UINT_MAX,
|
|
|
|
|
1));
|
2020-03-21 15:41:25 +01:00
|
|
|
|
|
|
|
|
|
/* Get default number of questions */
|
|
|
|
|
TstCfg_SetConfigDef ((unsigned)
|
2023-03-10 00:13:55 +01:00
|
|
|
|
Par_GetParUnsignedLong ("NumQstDef",
|
|
|
|
|
1,
|
|
|
|
|
UINT_MAX,
|
|
|
|
|
1));
|
2020-03-21 15:41:25 +01:00
|
|
|
|
|
|
|
|
|
/* Get maximum number of questions */
|
|
|
|
|
TstCfg_SetConfigMax ((unsigned)
|
2023-03-10 00:13:55 +01:00
|
|
|
|
Par_GetParUnsignedLong ("NumQstMax",
|
|
|
|
|
1,
|
|
|
|
|
UINT_MAX,
|
|
|
|
|
1));
|
2020-03-21 15:41:25 +01:00
|
|
|
|
|
|
|
|
|
/* Check and correct numbers */
|
|
|
|
|
TstCfg_CheckAndCorrectMinDefMax ();
|
|
|
|
|
|
|
|
|
|
/***** Get minimum time between consecutive tests, per question *****/
|
2023-03-07 09:55:39 +01:00
|
|
|
|
TstCfg_SetConfigMinTimeNxtTstPerQst (Par_GetParUnsignedLong ("MinTimeNxtTstPerQst",
|
2023-03-10 00:13:55 +01:00
|
|
|
|
0,
|
|
|
|
|
ULONG_MAX,
|
|
|
|
|
0));
|
2020-03-21 15:41:25 +01:00
|
|
|
|
|
|
|
|
|
/***** Get visibility from form *****/
|
2020-04-02 03:28:08 +02:00
|
|
|
|
TstCfg_SetConfigVisibility (TstVis_GetVisibilityFromForm ());
|
2020-03-21 15:41:25 +01:00
|
|
|
|
|
|
|
|
|
/***** Update database *****/
|
2021-10-27 00:02:29 +02:00
|
|
|
|
Tst_DB_SaveConfig ();
|
2020-03-21 15:41:25 +01:00
|
|
|
|
|
|
|
|
|
/***** Show confirmation message *****/
|
|
|
|
|
Ale_ShowAlert (Ale_SUCCESS,Txt_The_test_configuration_has_been_updated);
|
|
|
|
|
|
|
|
|
|
/***** Show again the form to configure test *****/
|
2021-10-26 09:23:06 +02:00
|
|
|
|
TstCfg_CheckAndShowFormConfig ();
|
2020-03-21 15:41:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/******************* Get if tests are pluggable from form ********************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static TstCfg_Pluggable_t TstCfg_GetPluggableFromForm (void)
|
|
|
|
|
{
|
|
|
|
|
return (TstCfg_Pluggable_t)
|
2023-03-07 09:55:39 +01:00
|
|
|
|
Par_GetParUnsignedLong ("Pluggable",
|
2023-03-10 00:13:55 +01:00
|
|
|
|
0,
|
|
|
|
|
TstCfg_NUM_OPTIONS_PLUGGABLE - 1,
|
|
|
|
|
(unsigned long) TstCfg_PLUGGABLE_UNKNOWN);
|
2020-03-21 15:41:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/**** Check and correct minimum, default and maximum numbers of questions ****/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void TstCfg_CheckAndCorrectMinDefMax (void)
|
|
|
|
|
{
|
|
|
|
|
/***** Check if minimum is correct *****/
|
|
|
|
|
if (TstCfg_GetConfigMin () < 1)
|
|
|
|
|
TstCfg_SetConfigMin (1);
|
|
|
|
|
else if (TstCfg_GetConfigMin () > TstCfg_MAX_QUESTIONS_PER_TEST)
|
|
|
|
|
TstCfg_SetConfigMin (TstCfg_MAX_QUESTIONS_PER_TEST);
|
|
|
|
|
|
|
|
|
|
/***** Check if maximum is correct *****/
|
|
|
|
|
if (TstCfg_GetConfigMax () < 1)
|
|
|
|
|
TstCfg_SetConfigMax (1);
|
|
|
|
|
else if (TstCfg_GetConfigMax () > TstCfg_MAX_QUESTIONS_PER_TEST)
|
|
|
|
|
TstCfg_SetConfigMax (TstCfg_MAX_QUESTIONS_PER_TEST);
|
|
|
|
|
|
|
|
|
|
/***** Check if minimum is lower than maximum *****/
|
|
|
|
|
if (TstCfg_GetConfigMin () > TstCfg_GetConfigMax ())
|
|
|
|
|
TstCfg_SetConfigMin (TstCfg_GetConfigMax ());
|
|
|
|
|
|
|
|
|
|
/***** Check if default is correct *****/
|
|
|
|
|
if (TstCfg_GetConfigDef () < TstCfg_GetConfigMin ())
|
|
|
|
|
TstCfg_SetConfigDef (TstCfg_GetConfigMin ());
|
|
|
|
|
else if (TstCfg_GetConfigDef () > TstCfg_GetConfigMax ())
|
|
|
|
|
TstCfg_SetConfigDef (TstCfg_GetConfigMax ());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/********* Get fields of current test configuration for this course **********/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
void TstCfg_SetConfigPluggable (TstCfg_Pluggable_t Pluggable)
|
|
|
|
|
{
|
|
|
|
|
TstCfg_Config.Pluggable = Pluggable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TstCfg_Pluggable_t TstCfg_GetConfigPluggable (void)
|
|
|
|
|
{
|
|
|
|
|
return TstCfg_Config.Pluggable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TstCfg_SetConfigMin (unsigned Min)
|
|
|
|
|
{
|
|
|
|
|
TstCfg_Config.Min = Min;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned TstCfg_GetConfigMin (void)
|
|
|
|
|
{
|
|
|
|
|
return TstCfg_Config.Min;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TstCfg_SetConfigDef (unsigned Def)
|
|
|
|
|
{
|
|
|
|
|
TstCfg_Config.Def = Def;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned TstCfg_GetConfigDef (void)
|
|
|
|
|
{
|
|
|
|
|
return TstCfg_Config.Def;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TstCfg_SetConfigMax (unsigned Max)
|
|
|
|
|
{
|
|
|
|
|
TstCfg_Config.Max = Max;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned TstCfg_GetConfigMax (void)
|
|
|
|
|
{
|
|
|
|
|
return TstCfg_Config.Max;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TstCfg_SetConfigMinTimeNxtTstPerQst (unsigned long MinTimeNxtTstPerQst)
|
|
|
|
|
{
|
|
|
|
|
TstCfg_Config.MinTimeNxtTstPerQst = MinTimeNxtTstPerQst;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned long TstCfg_GetConfigMinTimeNxtTstPerQst (void)
|
|
|
|
|
{
|
|
|
|
|
return TstCfg_Config.MinTimeNxtTstPerQst;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TstCfg_SetConfigVisibility (unsigned Visibility)
|
|
|
|
|
{
|
|
|
|
|
TstCfg_Config.Visibility = Visibility;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned TstCfg_GetConfigVisibility (void)
|
|
|
|
|
{
|
|
|
|
|
return TstCfg_Config.Visibility;
|
|
|
|
|
}
|