From 6e3cea9ba1448b36404218630f0ceec408a5c73e Mon Sep 17 00:00:00 2001 From: acanas Date: Tue, 11 Oct 2022 23:30:47 +0200 Subject: [PATCH] Version 22.43: Oct 11, 2022 Review of projects (not finished). --- icon/file-circle-check.svg | 1 + icon/file-circle-exclamation.svg | 1 + icon/file-circle-question.svg | 1 + swad_changelog.h | 14 ++-- swad_project.c | 114 +++++++++++++++++++++++++------ swad_project.h | 4 ++ swad_project_database.c | 56 +++++++++++---- swad_text.c | 99 ++++++++++++++++++++++++++- 8 files changed, 249 insertions(+), 41 deletions(-) create mode 100644 icon/file-circle-check.svg create mode 100644 icon/file-circle-exclamation.svg create mode 100644 icon/file-circle-question.svg diff --git a/icon/file-circle-check.svg b/icon/file-circle-check.svg new file mode 100644 index 00000000..83ed1259 --- /dev/null +++ b/icon/file-circle-check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icon/file-circle-exclamation.svg b/icon/file-circle-exclamation.svg new file mode 100644 index 00000000..93e0b823 --- /dev/null +++ b/icon/file-circle-exclamation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icon/file-circle-question.svg b/icon/file-circle-question.svg new file mode 100644 index 00000000..9a2fed89 --- /dev/null +++ b/icon/file-circle-question.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/swad_changelog.h b/swad_changelog.h index 96199837..fa2afd3f 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -606,19 +606,23 @@ TODO: Fix bug: error al enviar un mensaje a dos recipientes, error on duplicate TODO: Attach pdf files in multimedia. */ -#define Log_PLATFORM_VERSION "SWAD 22.42 (2022-10-11)" +#define Log_PLATFORM_VERSION "SWAD 22.43 (2022-10-11)" #define CSS_FILE "swad22.40.css" #define JS_FILE "swad21.100.js" /* - Version 22.42: Oct 11, 2022 Review of projects (not finished). (? lines) + Version 22.43: Oct 11, 2022 Review of projects (not finished). (332930 lines) + Version 22.42: Oct 11, 2022 Review of projects (not finished). (332738 lines) 3 changes necessary in database: ALTER TABLE prj_projects ADD COLUMN ReviewStatus ENUM('unreviewed','unapproved','approved') NOT NULL DEFAULT 'unreviewed' AFTER URL,ADD INDEX (CrsCod,ReviewStatus); ALTER TABLE prj_projects ADD COLUMN ReviewTime DATETIME NOT NULL DEFAULT '1970-01-01 01:00:00' AFTER ReviewStatus; ALTER TABLE prj_projects ADD COLUMN ReviewTxt TEXT NOT NULL AFTER ReviewTime; Copy the following icons to icon public directory: -sudo cp icon/comment-slash.svg /var/www/html/swad/icon/ -sudo cp icon/thumbs-down.svg /var/www/html/swad/icon/ -sudo cp icon/thumbs-up.svg /var/www/html/swad/icon/ +// sudo cp icon/comment-slash.svg /var/www/html/swad/icon/ +sudo cp icon/file-circle-check.svg /var/www/html/swad/icon/ +sudo cp icon/file-circle-exclamation.svg /var/www/html/swad/icon/ +sudo cp icon/file-circle-question.svg /var/www/html/swad/icon/ +// sudo cp icon/thumbs-down.svg /var/www/html/swad/icon/ +// sudo cp icon/thumbs-up.svg /var/www/html/swad/icon/ Version 22.41.1: Oct 07, 2022 Fixed issue in main title. (332512 lines) Version 22.41: Oct 06, 2022 Changes in the behavior of the expansion/contraction of program items. (332511 lines) diff --git a/swad_project.c b/swad_project.c index fcd8fa19..0567456a 100644 --- a/swad_project.c +++ b/swad_project.c @@ -91,12 +91,24 @@ static const unsigned Brw_NUM_ROLES_TO_SHOW = sizeof (Prj_RolesToShow) / sizeof (Prj_RolesToShow[0]); /***** Assigned/non-assigned project *****/ -static const char *AssignedNonassigImage[Prj_NUM_ASSIGNED_NONASSIG] = +static const char *AssignedNonassigIcon[Prj_NUM_ASSIGNED_NONASSIG] = { [Prj_ASSIGNED] = "user.svg", [Prj_NONASSIG] = "user-slash.svg", }; +/***** Review status *****/ +static struct + { + const char *Icon; + Ico_Color_t Color; + } ReviewIcon[Prj_NUM_REVIEW_STATUS] = + { + [Prj_UNREVIEWED] = {"file-circle-question.svg" ,Ico_BLACK}, + [Prj_UNAPPROVED] = {"file-circle-exclamation.svg",Ico_RED }, + [Prj_APPROVED ] = {"file-circle-check.svg" ,Ico_GREEN}, + }; + /***** Locked/unlocked project edition *****/ static const struct { @@ -622,7 +634,7 @@ static void Prj_ShowFormToFilterByAssign (const struct Prj_Projects *Projects) Projects->SelectedOrder, Projects->CurrentPage, -1L); - Ico_PutSettingIconLink (AssignedNonassigImage[Assign],Ico_BLACK, + Ico_PutSettingIconLink (AssignedNonassigIcon[Assign],Ico_BLACK, Txt_PROJECT_ASSIGNED_NONASSIGNED_PLURAL[Assign]); Frm_EndForm (); Set_EndPref (); @@ -726,19 +738,9 @@ static void Prj_ShowFormToFilterByWarning (const struct Prj_Projects *Projects) static void Prj_ShowFormToFilterByReview (const struct Prj_Projects *Projects) { - extern const char *Txt_PROJECT_REVIEWED_PROJECTS[Prj_NUM_REVIEW_STATUS]; + extern const char *Txt_PROJECT_REVIEW_PLURAL[Prj_NUM_REVIEW_STATUS]; struct Prj_Filter Filter; Prj_ReviewStatus_t ReviewStatus; - struct - { - const char *Icon; - Ico_Color_t Color; - } ReviewIcon[Prj_NUM_REVIEW_STATUS] = - { - [Prj_UNREVIEWED] = {"comment-slash.svg",Ico_BLACK}, - [Prj_UNAPPROVED] = {"thumbs-down.svg" ,Ico_RED }, - [Prj_APPROVED ] = {"thumbs-up.svg" ,Ico_GREEN}, - }; Set_BeginOneSettingSelector (); for (ReviewStatus = (Prj_ReviewStatus_t) 0; @@ -759,7 +761,7 @@ static void Prj_ShowFormToFilterByReview (const struct Prj_Projects *Projects) -1L); Ico_PutSettingIconLink (ReviewIcon[ReviewStatus].Icon, ReviewIcon[ReviewStatus].Color, - Txt_PROJECT_REVIEWED_PROJECTS[ReviewStatus]); + Txt_PROJECT_REVIEW_PLURAL[ReviewStatus]); Frm_EndForm (); Set_EndPref (); } @@ -1352,6 +1354,8 @@ static void Prj_ShowProjectRow (struct Prj_Projects *Projects, Prj_ProjectView_t ProjectView) { extern const char *Txt_Actions[Act_NUM_ACTIONS]; + extern const char *Txt_Review; + extern const char *Txt_PROJECT_REVIEW_SINGUL[Prj_NUM_REVIEW_STATUS]; extern const char *Txt_Assigned_QUESTION; extern const char *Txt_Yes; extern const char *Txt_No; @@ -1395,7 +1399,7 @@ static void Prj_ShowProjectRow (struct Prj_Projects *Projects, switch (ProjectView) { case Prj_LIST_PROJECTS: - HTM_TD_Begin ("rowspan=\"3\" class=\"RT BIG_INDEX_%s %s\"", + HTM_TD_Begin ("rowspan=\"4\" class=\"RT BIG_INDEX_%s %s\"", The_GetSuffix (), The_GetColorRows ()); HTM_Unsigned (NumIndex); @@ -1414,7 +1418,7 @@ static void Prj_ShowProjectRow (struct Prj_Projects *Projects, switch (ProjectView) { case Prj_LIST_PROJECTS: - HTM_TD_Begin ("rowspan=\"3\" class=\"CONTEXT_COL %s\"", + HTM_TD_Begin ("rowspan=\"4\" class=\"CONTEXT_COL %s\"", The_GetColorRows ()); Prj_PutIconsToRemEditOnePrj (Projects,Anchor); HTM_TD_End (); @@ -1505,8 +1509,51 @@ static void Prj_ShowProjectRow (struct Prj_Projects *Projects, /* Department */ Prj_ShowOneProjectDepartment (&Projects->Prj,ProjectView); - /***** Assigned? *****/ - HTM_TR_Begin (NULL); + HTM_TR_End (); + + /***** Review status *****/ + HTM_TR_Begin (NULL); + + switch (ProjectView) + { + case Prj_LIST_PROJECTS: + HTM_TD_Begin ("colspan=\"2\" class=\"RT %s_%s %s\"", + ClassLabel,The_GetSuffix (),The_GetColorRows ()); + break; + default: + HTM_TD_Begin ("colspan=\"2\" class=\"RT %s_%s\"", + ClassLabel,The_GetSuffix ()); + break; + } + HTM_TxtColon (Txt_Review); + HTM_TD_End (); + + switch (ProjectView) + { + case Prj_LIST_PROJECTS: + HTM_TD_Begin ("colspan=\"2\" class=\"LT %s_%s %s\"", + ClassData,The_GetSuffix (),The_GetColorRows ()); + break; + default: + HTM_TD_Begin ("colspan=\"2\" class=\"LT %s_%s\"", + ClassData,The_GetSuffix ()); + break; + } + HTM_TxtF ("%s ",Txt_PROJECT_REVIEW_SINGUL[Projects->Prj.ReviewStatus]); + Ico_PutIconOff (ReviewIcon[Projects->Prj.ReviewStatus].Icon, + ReviewIcon[Projects->Prj.ReviewStatus].Color, + Txt_PROJECT_REVIEW_SINGUL[Projects->Prj.ReviewStatus]); + /* + if (Faults.WrongAssigned) + Prj_PutWarningIcon (); + */ + + HTM_TD_End (); + + HTM_TR_End (); + + /***** Assigned? *****/ + HTM_TR_Begin (NULL); switch (ProjectView) { @@ -1535,7 +1582,7 @@ static void Prj_ShowProjectRow (struct Prj_Projects *Projects, } HTM_TxtF ("%s ",Projects->Prj.Assigned == Prj_ASSIGNED ? Txt_Yes : Txt_No); - Ico_PutIconOff (AssignedNonassigImage[Projects->Prj.Assigned],Ico_BLACK, + Ico_PutIconOff (AssignedNonassigIcon[Projects->Prj.Assigned],Ico_BLACK, Txt_PROJECT_ASSIGNED_NONASSIGNED_SINGUL[Projects->Prj.Assigned]); if (Faults.WrongAssigned) @@ -1924,7 +1971,6 @@ static void Prj_ShowOneProjectDepartment (const struct Prj_Project *Prj, if (PutLink) HTM_A_End (); HTM_TD_End (); - HTM_TR_End (); } static void Prj_ShowTableAllProjectsDepartment (const struct Prj_Project *Prj) @@ -2999,9 +3045,11 @@ static void Prj_GetListProjects (struct Prj_Projects *Projects) void Prj_GetDataOfProjectByCod (struct Prj_Project *Prj) { extern const char *Prj_Proposal_DB[Prj_NUM_PROPOSAL_TYPES]; + extern const char *Prj_ReviewStatus_DB[Prj_NUM_REVIEW_STATUS]; MYSQL_RES *mysql_res; MYSQL_ROW row; Prj_Proposal_t Proposal; + Prj_ReviewStatus_t ReviewStatus; if (Prj->PrjCod > 0) { @@ -3057,6 +3105,20 @@ void Prj_GetDataOfProjectByCod (struct Prj_Project *Prj) Str_Copy (Prj->Knowledge ,row[12],Cns_MAX_BYTES_TEXT); Str_Copy (Prj->Materials ,row[13],Cns_MAX_BYTES_TEXT); Str_Copy (Prj->URL ,row[14],sizeof (Prj->URL ) - 1); + + /* Get review status (row[15]), review time (row[16]) + and review text (row[17]) */ + Prj->ReviewStatus = Prj_REVIEW_STATUS_DEFAULT; + for (ReviewStatus = (Prj_ReviewStatus_t) 0; + ReviewStatus <= (Prj_ReviewStatus_t) (Prj_NUM_REVIEW_STATUS - 1); + ReviewStatus++) + if (!strcmp (Prj_ReviewStatus_DB[Proposal],row[15])) + { + Prj->ReviewStatus = ReviewStatus; + break; + } + Prj->ReviewTime = Dat_GetUNIXTimeFromStr (row[16]); + Str_Copy (Prj->ReviewTxt ,row[17],Cns_MAX_BYTES_TEXT); } /***** Free structure that stores the query result *****/ @@ -3092,6 +3154,10 @@ static void Prj_ResetProject (struct Prj_Project *Prj) Prj->Knowledge[0] = '\0'; Prj->Materials[0] = '\0'; Prj->URL[0] = '\0'; + + Prj->ReviewStatus = Prj_REVIEW_STATUS_DEFAULT; + Prj->ReviewTime = (time_t) 0; + Prj->ReviewTxt[0] = '\0'; } /*****************************************************************************/ @@ -3620,6 +3686,9 @@ void Prj_AllocMemProject (struct Prj_Project *Prj) if ((Prj->Materials = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) Err_NotEnoughMemoryExit (); + + if ((Prj->ReviewTxt = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL) + Err_NotEnoughMemoryExit (); } /*****************************************************************************/ @@ -3643,6 +3712,11 @@ void Prj_FreeMemProject (struct Prj_Project *Prj) free (Prj->Materials); Prj->Materials = NULL; } + if (Prj->ReviewTxt) + { + free (Prj->ReviewTxt); + Prj->ReviewTxt = NULL; + } } /*****************************************************************************/ diff --git a/swad_project.h b/swad_project.h index b05ff994..0c48c708 100644 --- a/swad_project.h +++ b/swad_project.h @@ -91,6 +91,7 @@ typedef enum Prj_UNAPPROVED = 1, Prj_APPROVED = 2, } Prj_ReviewStatus_t; +#define Prj_REVIEW_STATUS_DEFAULT Prj_UNREVIEWED #define Prj_FILTER_UNREVIEWED_DEFAULT (1 << Prj_UNREVIEWED) // on #define Prj_FILTER_UNAPPROVED_DEFAULT (1 << Prj_UNAPPROVED) // on #define Prj_FILTER_APPROVED_DEFAULT (1 << Prj_APPROVED) // on @@ -163,6 +164,9 @@ struct Prj_Project char *Knowledge; char *Materials; char URL[Cns_MAX_BYTES_WWW + 1]; + Prj_ReviewStatus_t ReviewStatus; + time_t ReviewTime; + char *ReviewTxt; }; /***** Struct to store context/status of projects *****/ diff --git a/swad_project_database.c b/swad_project_database.c index 06a33b0a..a4909134 100644 --- a/swad_project_database.c +++ b/swad_project_database.c @@ -52,6 +52,14 @@ const char *Prj_Proposal_DB[Prj_NUM_PROPOSAL_TYPES] = [Prj_PROPOSAL_UNMODIFIED] = "unmodified", }; +/***** Enum field in database for review status *****/ +const char *Prj_ReviewStatus_DB[Prj_NUM_REVIEW_STATUS] = + { + [Prj_UNREVIEWED] = "unreviewed", + [Prj_UNAPPROVED] = "unapproved", + [Prj_APPROVED ] = "approved", + }; + /*****************************************************************************/ /************ Update configuration of projects for current course ************/ /*****************************************************************************/ @@ -109,11 +117,13 @@ long Prj_DB_CreateProject (const struct Prj_Project *Prj) "INSERT INTO prj_projects" " (CrsCod,DptCod,Hidden,Assigned,NumStds,Proposal," "CreatTime,ModifTime," - "Title,Description,Knowledge,Materials,URL)" + "Title,Description,Knowledge,Materials,URL," + "ReviewStatus,ReviewTime,ReviewTxt)" " VALUES" " (%ld,%ld,'%c','%c',%u,'%s'," "FROM_UNIXTIME(%ld),FROM_UNIXTIME(%ld)," - "'%s','%s','%s','%s','%s')", + "'%s','%s','%s','%s','%s'," + "'%s',FROM_UNIXTIME(%ld),'%s')", Gbl.Hierarchy.Crs.CrsCod, Prj->DptCod, Prj->Hidden == Prj_HIDDEN ? 'Y' : @@ -128,7 +138,10 @@ long Prj_DB_CreateProject (const struct Prj_Project *Prj) Prj->Description, Prj->Knowledge, Prj->Materials, - Prj->URL); + Prj->URL, + Prj_ReviewStatus_DB[Prj->ReviewStatus], + Prj->ReviewTime, + Prj->ReviewTxt); } /*****************************************************************************/ @@ -283,30 +296,42 @@ unsigned Prj_DB_GetListProjects (MYSQL_RES **mysql_res, switch (Projects->Filter.Review) { case (1 << Prj_UNREVIEWED): // Unreviewed projects - if (asprintf (&AssignSubQuery," AND prj_projects.ReviewStatus='unreviewed'") < 0) + if (asprintf (&AssignSubQuery," AND prj_projects.ReviewStatus='%s'", + Prj_ReviewStatus_DB[Prj_UNREVIEWED]) < 0) Err_NotEnoughMemoryExit (); break; case (1 << Prj_UNAPPROVED): // Unapproved projects - if (asprintf (&AssignSubQuery," AND prj_projects.ReviewStatus='unapproved'") < 0) + if (asprintf (&AssignSubQuery," AND prj_projects.ReviewStatus='%s'", + Prj_ReviewStatus_DB[Prj_UNAPPROVED]) < 0) Err_NotEnoughMemoryExit (); break; case (1 << Prj_APPROVED): // Approved projects - if (asprintf (&AssignSubQuery," AND prj_projects.ReviewStatus='approved'") < 0) + if (asprintf (&AssignSubQuery," AND prj_projects.ReviewStatus='%s'", + Prj_ReviewStatus_DB[Prj_APPROVED ]) < 0) Err_NotEnoughMemoryExit (); break; - case (1 << Prj_UNREVIEWED | 1 << Prj_UNAPPROVED): // Unreviewed and unapproved projects - if (asprintf (&AssignSubQuery," AND prj_projects.ReviewStatus IN ('unreviewed','unapproved')") < 0) + case (1 << Prj_UNREVIEWED | + 1 << Prj_UNAPPROVED): // Unreviewed and unapproved projects + if (asprintf (&AssignSubQuery," AND prj_projects.ReviewStatus IN ('%s','%s')", + Prj_ReviewStatus_DB[Prj_UNREVIEWED], + Prj_ReviewStatus_DB[Prj_UNAPPROVED]) < 0) Err_NotEnoughMemoryExit (); break; - case (1 << Prj_UNREVIEWED | 1 << Prj_APPROVED): // Unreviewed and approved projects - if (asprintf (&AssignSubQuery," AND prj_projects.ReviewStatus IN ('unreviewed','approved')") < 0) + case (1 << Prj_UNREVIEWED | + 1 << Prj_APPROVED): // Unreviewed and approved projects + if (asprintf (&AssignSubQuery," AND prj_projects.ReviewStatus IN ('%s','%s')", + Prj_ReviewStatus_DB[Prj_UNREVIEWED], + Prj_ReviewStatus_DB[Prj_APPROVED ]) < 0) Err_NotEnoughMemoryExit (); break; - case (1 << Prj_UNAPPROVED | 1 << Prj_APPROVED): // Unapproved and approved projects - if (asprintf (&AssignSubQuery," AND prj_projects.ReviewStatus IN ('unapproved','approved')") < 0) + case (1 << Prj_UNAPPROVED | + 1 << Prj_APPROVED): // Unapproved and approved projects + if (asprintf (&AssignSubQuery," AND prj_projects.ReviewStatus IN ('%s','%s')", + Prj_ReviewStatus_DB[Prj_UNAPPROVED], + Prj_ReviewStatus_DB[Prj_APPROVED ]) < 0) Err_NotEnoughMemoryExit (); break; - default: // All projects + default: // All projects if (asprintf (&AssignSubQuery,"%s","") < 0) Err_NotEnoughMemoryExit (); break; @@ -525,7 +550,10 @@ unsigned Prj_DB_GetDataOfProjectByCod (MYSQL_RES **mysql_res,long PrjCod) "Description," // row[11] "Knowledge," // row[12] "Materials," // row[13] - "URL" // row[14] + "URL," // row[14] + "ReviewStatus," // row[15] + "UNIX_TIMESTAMP(ReviewTime)," // row[16] + "ReviewTxt" // row[17] " FROM prj_projects" " WHERE PrjCod=%ld" " AND CrsCod=%ld", // Extra check diff --git a/swad_text.c b/swad_text.c index 14a5af84..6ee26416 100644 --- a/swad_text.c +++ b/swad_text.c @@ -2469,7 +2469,7 @@ const char *Txt_Assigned_QUESTION = #elif L==9 // pt "Atribuído?"; #elif L==10 // tr - "Assigned?"; // Çeviri lazim! + "Atandı mı?"; #endif const char *Txt_Assignment = @@ -32970,7 +32970,79 @@ const char *Txt_PROJECT_FAULTY_FAULTLESS_PROJECTS[Prj_NUM_FAULTINESS] = #endif }; -const char *Txt_PROJECT_REVIEWED_PROJECTS[Prj_NUM_REVIEW_STATUS] = +const char *Txt_PROJECT_REVIEW_PLURAL[Prj_NUM_REVIEW_STATUS] = + { + [Prj_UNREVIEWED] = +#if L==1 // ca + "Projectes sense revisar" +#elif L==2 // de + "Ungeprüfte Projekte" +#elif L==3 // en + "Unreviewed projects" +#elif L==4 // es + "Proyectos sin revisar" +#elif L==5 // fr + "Projets non revus" +#elif L==6 // gn + "Proyectos sin revisar" // Okoteve traducción +#elif L==7 // it + "Progetti non recensiti" +#elif L==8 // pl + "Niesprawdzone projekty" +#elif L==9 // pt + "Projetos não revisados" +#elif L==10 // tr + "İncelenmemiş projeler" +#endif + , + [Prj_UNAPPROVED] = +#if L==1 // ca + "Projectes sense aprovar" +#elif L==2 // de + "Nicht genehmigte Projekte" +#elif L==3 // en + "Unapproved projects" +#elif L==4 // es + "Proyectos sin aprobar" +#elif L==5 // fr + "Projets non approuvés" +#elif L==6 // gn + "Proyectos sin aprobar" // Okoteve traducción +#elif L==7 // it + "Progetti non approvati" +#elif L==8 // pl + "Niezatwierdzone projekty" +#elif L==9 // pt + "Projetos não aprovados" +#elif L==10 // tr + "Onaylanmamış projeler" +#endif + , + [Prj_APPROVED] = +#if L==1 // ca + "Projectes aprovats" +#elif L==2 // de + "Genehmigte Projekte" +#elif L==3 // en + "Approved projects" +#elif L==4 // es + "Proyectos aprobados" +#elif L==5 // fr + "Projets approuvés" +#elif L==6 // gn + "Proyectos aprobados" // Okoteve traducción +#elif L==7 // it + "Progetti approvati" +#elif L==8 // pl + "Zatwierdzone projekty" +#elif L==9 // pt + "Projetos aprovados" +#elif L==10 // tr + "Onaylanmış projeler" +#endif + }; + +const char *Txt_PROJECT_REVIEW_SINGUL[Prj_NUM_REVIEW_STATUS] = { [Prj_UNREVIEWED] = #if L==1 // ca @@ -36252,6 +36324,29 @@ const char *Txt_Retype_new_password = "Yeni şifrenizi tekrar yazınız"; #endif +const char *Txt_Review = +#if L==1 // ca + "Revisió"; +#elif L==2 // de + "Überprüfungs"; +#elif L==3 // en + "Review"; +#elif L==4 // es + "Revisión"; +#elif L==5 // fr + "Examen"; +#elif L==6 // gn + "Revisión"; // Okoteve traducción +#elif L==7 // it + "Revisione"; +#elif L==8 // pl + "Recenzja"; +#elif L==9 // pt + "Revisão"; +#elif L==10 // tr + "Gözden geçir"; +#endif + const char *Txt_Role = #if L==1 // ca "Rol";