diff --git a/Makefile b/Makefile
index aa47c3e4..fe632ed0 100644
--- a/Makefile
+++ b/Makefile
@@ -79,6 +79,7 @@ OBJS = swad_account.o swad_account_database.o swad_action.o swad_admin.o \
swad_plugin_database.o swad_privacy.o swad_profile.o \
swad_profile_database.o swad_program.o swad_program_database.o \
swad_program_resource.o swad_project.o swad_project_database.o \
+ swad_project_resource.o \
swad_question.o swad_question_database.o swad_question_import.o \
swad_QR.o \
swad_record.o swad_record_database.o swad_report.o \
diff --git a/swad_action.c b/swad_action.c
index 0f2829d1..8d36f46e 100644
--- a/swad_action.c
+++ b/swad_action.c
@@ -95,6 +95,7 @@
#include "swad_program.h"
#include "swad_program_resource.h"
#include "swad_project.h"
+#include "swad_project_resource.h"
#include "swad_question_import.h"
#include "swad_QR.h"
#include "swad_report.h"
@@ -647,6 +648,7 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
[ActRemStdPrj ] = {1693,-1,TabUnk,ActSeePrj ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Prj_RemStd ,NULL},
[ActRemTutPrj ] = {1694,-1,TabUnk,ActSeePrj ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Prj_RemTut ,NULL},
[ActRemEvlPrj ] = {1695,-1,TabUnk,ActSeePrj ,0x230,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Prj_RemEvl ,NULL},
+ [ActReqLnkPrj ] = {1948,-1,TabUnk,ActSeePrj ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,PrjRsc_GetLinkToProject ,NULL},
[ActAdmDocPrj ] = {1697,-1,TabUnk,ActSeePrj ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Brw_ShowFileBrowserOrWorks ,NULL},
[ActReqRemFilDocPrj ] = {1698,-1,TabUnk,ActSeePrj ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Brw_AskRemFileFromTree ,NULL},
@@ -3814,6 +3816,7 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un
ActConSeePrgItm, // #1945
ActExpEdiPrgItm, // #1946
ActConEdiPrgItm, // #1947
+ ActReqLnkPrj, // #1948
};
/*****************************************************************************/
diff --git a/swad_action.h b/swad_action.h
index 985f9693..4ca79e45 100644
--- a/swad_action.h
+++ b/swad_action.h
@@ -65,7 +65,7 @@ typedef enum
typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action
-#define Act_MAX_ACTION_COD 1947
+#define Act_MAX_ACTION_COD 1948
#define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13
@@ -598,212 +598,213 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to
#define ActRemStdPrj (ActChgCrsTT1stDay + 60)
#define ActRemTutPrj (ActChgCrsTT1stDay + 61)
#define ActRemEvlPrj (ActChgCrsTT1stDay + 62)
+#define ActReqLnkPrj (ActChgCrsTT1stDay + 63)
-#define ActAdmDocPrj (ActChgCrsTT1stDay + 63)
-#define ActReqRemFilDocPrj (ActChgCrsTT1stDay + 64)
-#define ActRemFilDocPrj (ActChgCrsTT1stDay + 65)
-#define ActRemFolDocPrj (ActChgCrsTT1stDay + 66)
-#define ActCopDocPrj (ActChgCrsTT1stDay + 67)
-#define ActPasDocPrj (ActChgCrsTT1stDay + 68)
-#define ActRemTreDocPrj (ActChgCrsTT1stDay + 69)
-#define ActFrmCreDocPrj (ActChgCrsTT1stDay + 70)
-#define ActCreFolDocPrj (ActChgCrsTT1stDay + 71)
-#define ActCreLnkDocPrj (ActChgCrsTT1stDay + 72)
-#define ActRenFolDocPrj (ActChgCrsTT1stDay + 73)
-#define ActRcvFilDocPrjDZ (ActChgCrsTT1stDay + 74)
-#define ActRcvFilDocPrjCla (ActChgCrsTT1stDay + 75)
-#define ActExpDocPrj (ActChgCrsTT1stDay + 76)
-#define ActConDocPrj (ActChgCrsTT1stDay + 77)
-#define ActZIPDocPrj (ActChgCrsTT1stDay + 78)
-#define ActReqDatDocPrj (ActChgCrsTT1stDay + 79)
-#define ActChgDatDocPrj (ActChgCrsTT1stDay + 80)
-#define ActDowDocPrj (ActChgCrsTT1stDay + 81)
+#define ActAdmDocPrj (ActChgCrsTT1stDay + 64)
+#define ActReqRemFilDocPrj (ActChgCrsTT1stDay + 65)
+#define ActRemFilDocPrj (ActChgCrsTT1stDay + 66)
+#define ActRemFolDocPrj (ActChgCrsTT1stDay + 67)
+#define ActCopDocPrj (ActChgCrsTT1stDay + 68)
+#define ActPasDocPrj (ActChgCrsTT1stDay + 69)
+#define ActRemTreDocPrj (ActChgCrsTT1stDay + 70)
+#define ActFrmCreDocPrj (ActChgCrsTT1stDay + 71)
+#define ActCreFolDocPrj (ActChgCrsTT1stDay + 72)
+#define ActCreLnkDocPrj (ActChgCrsTT1stDay + 73)
+#define ActRenFolDocPrj (ActChgCrsTT1stDay + 74)
+#define ActRcvFilDocPrjDZ (ActChgCrsTT1stDay + 75)
+#define ActRcvFilDocPrjCla (ActChgCrsTT1stDay + 76)
+#define ActExpDocPrj (ActChgCrsTT1stDay + 77)
+#define ActConDocPrj (ActChgCrsTT1stDay + 78)
+#define ActZIPDocPrj (ActChgCrsTT1stDay + 79)
+#define ActReqDatDocPrj (ActChgCrsTT1stDay + 80)
+#define ActChgDatDocPrj (ActChgCrsTT1stDay + 81)
+#define ActDowDocPrj (ActChgCrsTT1stDay + 82)
-#define ActAdmAssPrj (ActChgCrsTT1stDay + 82)
-#define ActReqRemFilAssPrj (ActChgCrsTT1stDay + 83)
-#define ActRemFilAssPrj (ActChgCrsTT1stDay + 84)
-#define ActRemFolAssPrj (ActChgCrsTT1stDay + 85)
-#define ActCopAssPrj (ActChgCrsTT1stDay + 86)
-#define ActPasAssPrj (ActChgCrsTT1stDay + 87)
-#define ActRemTreAssPrj (ActChgCrsTT1stDay + 88)
-#define ActFrmCreAssPrj (ActChgCrsTT1stDay + 89)
-#define ActCreFolAssPrj (ActChgCrsTT1stDay + 90)
-#define ActCreLnkAssPrj (ActChgCrsTT1stDay + 91)
-#define ActRenFolAssPrj (ActChgCrsTT1stDay + 92)
-#define ActRcvFilAssPrjDZ (ActChgCrsTT1stDay + 93)
-#define ActRcvFilAssPrjCla (ActChgCrsTT1stDay + 94)
-#define ActExpAssPrj (ActChgCrsTT1stDay + 95)
-#define ActConAssPrj (ActChgCrsTT1stDay + 96)
-#define ActZIPAssPrj (ActChgCrsTT1stDay + 97)
-#define ActReqDatAssPrj (ActChgCrsTT1stDay + 98)
-#define ActChgDatAssPrj (ActChgCrsTT1stDay + 99)
-#define ActDowAssPrj (ActChgCrsTT1stDay + 100)
+#define ActAdmAssPrj (ActChgCrsTT1stDay + 83)
+#define ActReqRemFilAssPrj (ActChgCrsTT1stDay + 84)
+#define ActRemFilAssPrj (ActChgCrsTT1stDay + 85)
+#define ActRemFolAssPrj (ActChgCrsTT1stDay + 86)
+#define ActCopAssPrj (ActChgCrsTT1stDay + 87)
+#define ActPasAssPrj (ActChgCrsTT1stDay + 88)
+#define ActRemTreAssPrj (ActChgCrsTT1stDay + 89)
+#define ActFrmCreAssPrj (ActChgCrsTT1stDay + 90)
+#define ActCreFolAssPrj (ActChgCrsTT1stDay + 91)
+#define ActCreLnkAssPrj (ActChgCrsTT1stDay + 92)
+#define ActRenFolAssPrj (ActChgCrsTT1stDay + 93)
+#define ActRcvFilAssPrjDZ (ActChgCrsTT1stDay + 94)
+#define ActRcvFilAssPrjCla (ActChgCrsTT1stDay + 95)
+#define ActExpAssPrj (ActChgCrsTT1stDay + 96)
+#define ActConAssPrj (ActChgCrsTT1stDay + 97)
+#define ActZIPAssPrj (ActChgCrsTT1stDay + 98)
+#define ActReqDatAssPrj (ActChgCrsTT1stDay + 99)
+#define ActChgDatAssPrj (ActChgCrsTT1stDay + 100)
+#define ActDowAssPrj (ActChgCrsTT1stDay + 101)
-#define ActSeeOneCfe (ActChgCrsTT1stDay + 101)
-#define ActSeeDatCfe (ActChgCrsTT1stDay + 102)
-#define ActEdiCfe (ActChgCrsTT1stDay + 103)
-#define ActRcvCfe (ActChgCrsTT1stDay + 104)
-#define ActPrnCfe (ActChgCrsTT1stDay + 105)
-#define ActReqRemCfe (ActChgCrsTT1stDay + 106)
-#define ActRemCfe (ActChgCrsTT1stDay + 107)
-#define ActHidCfe (ActChgCrsTT1stDay + 108)
-#define ActUnhCfe (ActChgCrsTT1stDay + 109)
-#define ActReqLnkCfe (ActChgCrsTT1stDay + 110)
+#define ActSeeOneCfe (ActChgCrsTT1stDay + 102)
+#define ActSeeDatCfe (ActChgCrsTT1stDay + 103)
+#define ActEdiCfe (ActChgCrsTT1stDay + 104)
+#define ActRcvCfe (ActChgCrsTT1stDay + 105)
+#define ActPrnCfe (ActChgCrsTT1stDay + 106)
+#define ActReqRemCfe (ActChgCrsTT1stDay + 107)
+#define ActRemCfe (ActChgCrsTT1stDay + 108)
+#define ActHidCfe (ActChgCrsTT1stDay + 109)
+#define ActUnhCfe (ActChgCrsTT1stDay + 110)
+#define ActReqLnkCfe (ActChgCrsTT1stDay + 111)
-#define ActEdiOneTstQst (ActChgCrsTT1stDay + 111)
-#define ActReqImpTstQst (ActChgCrsTT1stDay + 112)
-#define ActImpTstQst (ActChgCrsTT1stDay + 113)
-#define ActLstTstQst (ActChgCrsTT1stDay + 114)
-#define ActRcvTstQst (ActChgCrsTT1stDay + 115)
-#define ActReqRemSevTstQst (ActChgCrsTT1stDay + 116)
-#define ActRemSevTstQst (ActChgCrsTT1stDay + 117)
-#define ActReqRemOneTstQst (ActChgCrsTT1stDay + 118)
-#define ActRemOneTstQst (ActChgCrsTT1stDay + 119)
-#define ActChgShfTstQst (ActChgCrsTT1stDay + 120)
+#define ActEdiOneTstQst (ActChgCrsTT1stDay + 112)
+#define ActReqImpTstQst (ActChgCrsTT1stDay + 113)
+#define ActImpTstQst (ActChgCrsTT1stDay + 114)
+#define ActLstTstQst (ActChgCrsTT1stDay + 115)
+#define ActRcvTstQst (ActChgCrsTT1stDay + 116)
+#define ActReqRemSevTstQst (ActChgCrsTT1stDay + 117)
+#define ActRemSevTstQst (ActChgCrsTT1stDay + 118)
+#define ActReqRemOneTstQst (ActChgCrsTT1stDay + 119)
+#define ActRemOneTstQst (ActChgCrsTT1stDay + 120)
+#define ActChgShfTstQst (ActChgCrsTT1stDay + 121)
-#define ActEdiTag (ActChgCrsTT1stDay + 121)
-#define ActEnaTag (ActChgCrsTT1stDay + 122)
-#define ActDisTag (ActChgCrsTT1stDay + 123)
-#define ActRenTag (ActChgCrsTT1stDay + 124)
+#define ActEdiTag (ActChgCrsTT1stDay + 122)
+#define ActEnaTag (ActChgCrsTT1stDay + 123)
+#define ActDisTag (ActChgCrsTT1stDay + 124)
+#define ActRenTag (ActChgCrsTT1stDay + 125)
-#define ActSeeTst (ActChgCrsTT1stDay + 125)
-#define ActReqAssTst (ActChgCrsTT1stDay + 126)
-#define ActAssTst (ActChgCrsTT1stDay + 127)
-#define ActCfgTst (ActChgCrsTT1stDay + 128)
-#define ActRcvCfgTst (ActChgCrsTT1stDay + 129)
+#define ActSeeTst (ActChgCrsTT1stDay + 126)
+#define ActReqAssTst (ActChgCrsTT1stDay + 127)
+#define ActAssTst (ActChgCrsTT1stDay + 128)
+#define ActCfgTst (ActChgCrsTT1stDay + 129)
+#define ActRcvCfgTst (ActChgCrsTT1stDay + 130)
-#define ActReqSeeMyTstRes (ActChgCrsTT1stDay + 130)
-#define ActSeeMyTstResCrs (ActChgCrsTT1stDay + 131)
-#define ActSeeOneTstResMe (ActChgCrsTT1stDay + 132)
-#define ActReqSeeUsrTstRes (ActChgCrsTT1stDay + 133)
-#define ActSeeUsrTstResCrs (ActChgCrsTT1stDay + 134)
-#define ActSeeOneTstResOth (ActChgCrsTT1stDay + 135)
+#define ActReqSeeMyTstRes (ActChgCrsTT1stDay + 131)
+#define ActSeeMyTstResCrs (ActChgCrsTT1stDay + 132)
+#define ActSeeOneTstResMe (ActChgCrsTT1stDay + 133)
+#define ActReqSeeUsrTstRes (ActChgCrsTT1stDay + 134)
+#define ActSeeUsrTstResCrs (ActChgCrsTT1stDay + 135)
+#define ActSeeOneTstResOth (ActChgCrsTT1stDay + 136)
-#define ActSeeExa (ActChgCrsTT1stDay + 136)
+#define ActSeeExa (ActChgCrsTT1stDay + 137)
-#define ActFrmNewExa (ActChgCrsTT1stDay + 137)
-#define ActEdiOneExa (ActChgCrsTT1stDay + 138)
-#define ActNewExa (ActChgCrsTT1stDay + 139)
-#define ActChgExa (ActChgCrsTT1stDay + 140)
-#define ActReqRemExa (ActChgCrsTT1stDay + 141)
-#define ActRemExa (ActChgCrsTT1stDay + 142)
-#define ActHidExa (ActChgCrsTT1stDay + 143)
-#define ActUnhExa (ActChgCrsTT1stDay + 144)
-#define ActReqLnkExa (ActChgCrsTT1stDay + 145)
+#define ActFrmNewExa (ActChgCrsTT1stDay + 138)
+#define ActEdiOneExa (ActChgCrsTT1stDay + 139)
+#define ActNewExa (ActChgCrsTT1stDay + 140)
+#define ActChgExa (ActChgCrsTT1stDay + 141)
+#define ActReqRemExa (ActChgCrsTT1stDay + 142)
+#define ActRemExa (ActChgCrsTT1stDay + 143)
+#define ActHidExa (ActChgCrsTT1stDay + 144)
+#define ActUnhExa (ActChgCrsTT1stDay + 145)
+#define ActReqLnkExa (ActChgCrsTT1stDay + 146)
-#define ActFrmNewExaSet (ActChgCrsTT1stDay + 146)
-#define ActNewExaSet (ActChgCrsTT1stDay + 147)
-#define ActReqRemExaSet (ActChgCrsTT1stDay + 148)
-#define ActRemExaSet (ActChgCrsTT1stDay + 149)
-#define ActUp_ExaSet (ActChgCrsTT1stDay + 150)
-#define ActDwnExaSet (ActChgCrsTT1stDay + 151)
-#define ActChgTitExaSet (ActChgCrsTT1stDay + 152)
-#define ActChgNumQstExaSet (ActChgCrsTT1stDay + 153)
+#define ActFrmNewExaSet (ActChgCrsTT1stDay + 147)
+#define ActNewExaSet (ActChgCrsTT1stDay + 148)
+#define ActReqRemExaSet (ActChgCrsTT1stDay + 149)
+#define ActRemExaSet (ActChgCrsTT1stDay + 150)
+#define ActUp_ExaSet (ActChgCrsTT1stDay + 151)
+#define ActDwnExaSet (ActChgCrsTT1stDay + 152)
+#define ActChgTitExaSet (ActChgCrsTT1stDay + 153)
+#define ActChgNumQstExaSet (ActChgCrsTT1stDay + 154)
-#define ActReqAddQstExaSet (ActChgCrsTT1stDay + 154)
-#define ActLstTstQstForSet (ActChgCrsTT1stDay + 155)
-#define ActAddQstToExa (ActChgCrsTT1stDay + 156)
-#define ActReqRemSetQst (ActChgCrsTT1stDay + 157)
-#define ActRemExaQst (ActChgCrsTT1stDay + 158)
-#define ActValSetQst (ActChgCrsTT1stDay + 159)
-#define ActInvSetQst (ActChgCrsTT1stDay + 160)
+#define ActReqAddQstExaSet (ActChgCrsTT1stDay + 155)
+#define ActLstTstQstForSet (ActChgCrsTT1stDay + 156)
+#define ActAddQstToExa (ActChgCrsTT1stDay + 157)
+#define ActReqRemSetQst (ActChgCrsTT1stDay + 158)
+#define ActRemExaQst (ActChgCrsTT1stDay + 159)
+#define ActValSetQst (ActChgCrsTT1stDay + 160)
+#define ActInvSetQst (ActChgCrsTT1stDay + 161)
-#define ActReqNewExaSes (ActChgCrsTT1stDay + 161)
-#define ActEdiOneExaSes (ActChgCrsTT1stDay + 162)
-#define ActNewExaSes (ActChgCrsTT1stDay + 163)
-#define ActChgExaSes (ActChgCrsTT1stDay + 164)
-#define ActReqRemExaSes (ActChgCrsTT1stDay + 165)
-#define ActRemExaSes (ActChgCrsTT1stDay + 166)
-#define ActHidExaSes (ActChgCrsTT1stDay + 167)
-#define ActUnhExaSes (ActChgCrsTT1stDay + 168)
+#define ActReqNewExaSes (ActChgCrsTT1stDay + 162)
+#define ActEdiOneExaSes (ActChgCrsTT1stDay + 163)
+#define ActNewExaSes (ActChgCrsTT1stDay + 164)
+#define ActChgExaSes (ActChgCrsTT1stDay + 165)
+#define ActReqRemExaSes (ActChgCrsTT1stDay + 166)
+#define ActRemExaSes (ActChgCrsTT1stDay + 167)
+#define ActHidExaSes (ActChgCrsTT1stDay + 168)
+#define ActUnhExaSes (ActChgCrsTT1stDay + 169)
-#define ActSeeExaPrn (ActChgCrsTT1stDay + 169)
-#define ActAnsExaPrn (ActChgCrsTT1stDay + 170)
-#define ActEndExaPrn (ActChgCrsTT1stDay + 171)
+#define ActSeeExaPrn (ActChgCrsTT1stDay + 170)
+#define ActAnsExaPrn (ActChgCrsTT1stDay + 171)
+#define ActEndExaPrn (ActChgCrsTT1stDay + 172)
-#define ActSeeMyExaResCrs (ActChgCrsTT1stDay + 172)
-#define ActSeeMyExaResExa (ActChgCrsTT1stDay + 173)
-#define ActSeeMyExaResSes (ActChgCrsTT1stDay + 174)
-#define ActSeeOneExaResMe (ActChgCrsTT1stDay + 175)
-#define ActReqSeeUsrExaRes (ActChgCrsTT1stDay + 176)
-#define ActSeeUsrExaResCrs (ActChgCrsTT1stDay + 177)
-#define ActSeeUsrExaResExa (ActChgCrsTT1stDay + 178)
-#define ActSeeUsrExaResSes (ActChgCrsTT1stDay + 179)
-#define ActSeeOneExaResOth (ActChgCrsTT1stDay + 180)
-#define ActChgVisExaRes (ActChgCrsTT1stDay + 181)
+#define ActSeeMyExaResCrs (ActChgCrsTT1stDay + 173)
+#define ActSeeMyExaResExa (ActChgCrsTT1stDay + 174)
+#define ActSeeMyExaResSes (ActChgCrsTT1stDay + 175)
+#define ActSeeOneExaResMe (ActChgCrsTT1stDay + 176)
+#define ActReqSeeUsrExaRes (ActChgCrsTT1stDay + 177)
+#define ActSeeUsrExaResCrs (ActChgCrsTT1stDay + 178)
+#define ActSeeUsrExaResExa (ActChgCrsTT1stDay + 179)
+#define ActSeeUsrExaResSes (ActChgCrsTT1stDay + 180)
+#define ActSeeOneExaResOth (ActChgCrsTT1stDay + 181)
+#define ActChgVisExaRes (ActChgCrsTT1stDay + 182)
-#define ActSeeGam (ActChgCrsTT1stDay + 182)
-#define ActReqRemMch (ActChgCrsTT1stDay + 183)
-#define ActRemMch (ActChgCrsTT1stDay + 184)
-#define ActEdiMch (ActChgCrsTT1stDay + 185)
-#define ActChgMch (ActChgCrsTT1stDay + 186)
-#define ActReqNewMch (ActChgCrsTT1stDay + 187)
-#define ActNewMch (ActChgCrsTT1stDay + 188)
-#define ActResMch (ActChgCrsTT1stDay + 189)
-#define ActBckMch (ActChgCrsTT1stDay + 190)
-#define ActPlyPauMch (ActChgCrsTT1stDay + 191)
-#define ActFwdMch (ActChgCrsTT1stDay + 192)
-#define ActChgNumColMch (ActChgCrsTT1stDay + 193)
-#define ActChgVisResMchQst (ActChgCrsTT1stDay + 194)
-#define ActMchCntDwn (ActChgCrsTT1stDay + 195)
-#define ActRefMchTch (ActChgCrsTT1stDay + 196)
+#define ActSeeGam (ActChgCrsTT1stDay + 183)
+#define ActReqRemMch (ActChgCrsTT1stDay + 184)
+#define ActRemMch (ActChgCrsTT1stDay + 185)
+#define ActEdiMch (ActChgCrsTT1stDay + 186)
+#define ActChgMch (ActChgCrsTT1stDay + 187)
+#define ActReqNewMch (ActChgCrsTT1stDay + 188)
+#define ActNewMch (ActChgCrsTT1stDay + 189)
+#define ActResMch (ActChgCrsTT1stDay + 190)
+#define ActBckMch (ActChgCrsTT1stDay + 191)
+#define ActPlyPauMch (ActChgCrsTT1stDay + 192)
+#define ActFwdMch (ActChgCrsTT1stDay + 193)
+#define ActChgNumColMch (ActChgCrsTT1stDay + 194)
+#define ActChgVisResMchQst (ActChgCrsTT1stDay + 195)
+#define ActMchCntDwn (ActChgCrsTT1stDay + 196)
+#define ActRefMchTch (ActChgCrsTT1stDay + 197)
-#define ActJoiMch (ActChgCrsTT1stDay + 197)
-#define ActSeeMchAnsQstStd (ActChgCrsTT1stDay + 198)
-#define ActRemMchAnsQstStd (ActChgCrsTT1stDay + 199)
-#define ActAnsMchQstStd (ActChgCrsTT1stDay + 200)
-#define ActRefMchStd (ActChgCrsTT1stDay + 201)
+#define ActJoiMch (ActChgCrsTT1stDay + 198)
+#define ActSeeMchAnsQstStd (ActChgCrsTT1stDay + 199)
+#define ActRemMchAnsQstStd (ActChgCrsTT1stDay + 200)
+#define ActAnsMchQstStd (ActChgCrsTT1stDay + 201)
+#define ActRefMchStd (ActChgCrsTT1stDay + 202)
-#define ActSeeMyMchResCrs (ActChgCrsTT1stDay + 202)
-#define ActSeeMyMchResGam (ActChgCrsTT1stDay + 203)
-#define ActSeeMyMchResMch (ActChgCrsTT1stDay + 204)
-#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 205)
+#define ActSeeMyMchResCrs (ActChgCrsTT1stDay + 203)
+#define ActSeeMyMchResGam (ActChgCrsTT1stDay + 204)
+#define ActSeeMyMchResMch (ActChgCrsTT1stDay + 205)
+#define ActSeeOneMchResMe (ActChgCrsTT1stDay + 206)
-#define ActReqSeeUsrMchRes (ActChgCrsTT1stDay + 206)
-#define ActSeeUsrMchResCrs (ActChgCrsTT1stDay + 207)
-#define ActSeeUsrMchResGam (ActChgCrsTT1stDay + 208)
-#define ActSeeUsrMchResMch (ActChgCrsTT1stDay + 209)
-#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 210)
+#define ActReqSeeUsrMchRes (ActChgCrsTT1stDay + 207)
+#define ActSeeUsrMchResCrs (ActChgCrsTT1stDay + 208)
+#define ActSeeUsrMchResGam (ActChgCrsTT1stDay + 209)
+#define ActSeeUsrMchResMch (ActChgCrsTT1stDay + 210)
+#define ActSeeOneMchResOth (ActChgCrsTT1stDay + 211)
-#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 211)
+#define ActChgVisResMchUsr (ActChgCrsTT1stDay + 212)
-#define ActLstOneGam (ActChgCrsTT1stDay + 212)
+#define ActLstOneGam (ActChgCrsTT1stDay + 213)
-#define ActFrmNewGam (ActChgCrsTT1stDay + 213)
-#define ActEdiOneGam (ActChgCrsTT1stDay + 214)
-#define ActNewGam (ActChgCrsTT1stDay + 215)
-#define ActChgGam (ActChgCrsTT1stDay + 216)
-#define ActReqRemGam (ActChgCrsTT1stDay + 217)
-#define ActRemGam (ActChgCrsTT1stDay + 218)
-#define ActHidGam (ActChgCrsTT1stDay + 219)
-#define ActUnhGam (ActChgCrsTT1stDay + 220)
-#define ActAddOneGamQst (ActChgCrsTT1stDay + 221)
-#define ActGamLstTstQst (ActChgCrsTT1stDay + 222)
-#define ActAddTstQstToGam (ActChgCrsTT1stDay + 223)
-#define ActReqRemGamQst (ActChgCrsTT1stDay + 224)
-#define ActRemGamQst (ActChgCrsTT1stDay + 225)
-#define ActUp_GamQst (ActChgCrsTT1stDay + 226)
-#define ActDwnGamQst (ActChgCrsTT1stDay + 227)
-#define ActReqLnkGam (ActChgCrsTT1stDay + 228)
+#define ActFrmNewGam (ActChgCrsTT1stDay + 214)
+#define ActEdiOneGam (ActChgCrsTT1stDay + 215)
+#define ActNewGam (ActChgCrsTT1stDay + 216)
+#define ActChgGam (ActChgCrsTT1stDay + 217)
+#define ActReqRemGam (ActChgCrsTT1stDay + 218)
+#define ActRemGam (ActChgCrsTT1stDay + 219)
+#define ActHidGam (ActChgCrsTT1stDay + 220)
+#define ActUnhGam (ActChgCrsTT1stDay + 221)
+#define ActAddOneGamQst (ActChgCrsTT1stDay + 222)
+#define ActGamLstTstQst (ActChgCrsTT1stDay + 223)
+#define ActAddTstQstToGam (ActChgCrsTT1stDay + 224)
+#define ActReqRemGamQst (ActChgCrsTT1stDay + 225)
+#define ActRemGamQst (ActChgCrsTT1stDay + 226)
+#define ActUp_GamQst (ActChgCrsTT1stDay + 227)
+#define ActDwnGamQst (ActChgCrsTT1stDay + 228)
+#define ActReqLnkGam (ActChgCrsTT1stDay + 229)
-#define ActSeeSvy (ActChgCrsTT1stDay + 229)
-#define ActAnsSvy (ActChgCrsTT1stDay + 230)
-#define ActFrmNewSvy (ActChgCrsTT1stDay + 231)
-#define ActEdiOneSvy (ActChgCrsTT1stDay + 232)
-#define ActNewSvy (ActChgCrsTT1stDay + 233)
-#define ActChgSvy (ActChgCrsTT1stDay + 234)
-#define ActReqRemSvy (ActChgCrsTT1stDay + 235)
-#define ActRemSvy (ActChgCrsTT1stDay + 236)
-#define ActReqRstSvy (ActChgCrsTT1stDay + 237)
-#define ActRstSvy (ActChgCrsTT1stDay + 238)
-#define ActHidSvy (ActChgCrsTT1stDay + 239)
-#define ActUnhSvy (ActChgCrsTT1stDay + 240)
-#define ActReqLnkSvy (ActChgCrsTT1stDay + 241)
+#define ActSeeSvy (ActChgCrsTT1stDay + 230)
+#define ActAnsSvy (ActChgCrsTT1stDay + 231)
+#define ActFrmNewSvy (ActChgCrsTT1stDay + 232)
+#define ActEdiOneSvy (ActChgCrsTT1stDay + 233)
+#define ActNewSvy (ActChgCrsTT1stDay + 234)
+#define ActChgSvy (ActChgCrsTT1stDay + 235)
+#define ActReqRemSvy (ActChgCrsTT1stDay + 236)
+#define ActRemSvy (ActChgCrsTT1stDay + 237)
+#define ActReqRstSvy (ActChgCrsTT1stDay + 238)
+#define ActRstSvy (ActChgCrsTT1stDay + 239)
+#define ActHidSvy (ActChgCrsTT1stDay + 240)
+#define ActUnhSvy (ActChgCrsTT1stDay + 241)
+#define ActReqLnkSvy (ActChgCrsTT1stDay + 242)
-#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 242)
-#define ActRcvSvyQst (ActChgCrsTT1stDay + 243)
-#define ActReqRemSvyQst (ActChgCrsTT1stDay + 244)
-#define ActRemSvyQst (ActChgCrsTT1stDay + 245)
+#define ActEdiOneSvyQst (ActChgCrsTT1stDay + 243)
+#define ActRcvSvyQst (ActChgCrsTT1stDay + 244)
+#define ActReqRemSvyQst (ActChgCrsTT1stDay + 245)
+#define ActRemSvyQst (ActChgCrsTT1stDay + 246)
/*****************************************************************************/
/******************************** Files tab **********************************/
diff --git a/swad_browser.c b/swad_browser.c
index 464cada5..548ccb76 100644
--- a/swad_browser.c
+++ b/swad_browser.c
@@ -5802,7 +5802,7 @@ static void Brw_WriteCurrentClipboard (void)
Grp_MAX_BYTES_GROUP_TYPE_NAME +
Grp_MAX_BYTES_GROUP_NAME +
Usr_MAX_BYTES_FULL_NAME +
- Prj_MAX_BYTES_PROJECT_TITLE];
+ Prj_MAX_BYTES_TITLE];
char FileNameToShow[NAME_MAX + 1];
static const char **TxtFileType[Brw_NUM_FILE_TYPES] =
{
diff --git a/swad_changelog.h b/swad_changelog.h
index 9ce49e94..5bd36dc9 100644
--- a/swad_changelog.h
+++ b/swad_changelog.h
@@ -606,11 +606,19 @@ 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.29 (2022-09-24)"
+#define Log_PLATFORM_VERSION "SWAD 22.30 (2022-09-28)"
#define CSS_FILE "swad22.22.1.css"
#define JS_FILE "swad21.100.js"
/*
- Version 22.29: Sep 24, 2022 New module swad_forum_resource. (? lines)
+ Version 22.31: Sep 28, 2022 TODO: New action to view one project (similar to view project files, but accesible to students). (? lines)
+ Version 22.30: Sep 28, 2022 New module swad_project_resource. (332490 lines)
+ 2 changes necessary in database:
+ALTER TABLE prg_clipboards CHANGE COLUMN Type Type ENUM('non','asg','prj','cfe','exa','gam','svy','doc','mrk','att','for') NOT NULL DEFAULT 'non';
+ALTER TABLE prg_resources CHANGE COLUMN Type Type ENUM('non','asg','prj','cfe','exa','gam','svy','doc','mrk','att','for') NOT NULL DEFAULT 'non';
+Copy the following icon to icon public directory:
+sudo cp icon/file-invoice.svg /var/www/html/swad/icon/
+
+ Version 22.29: Sep 24, 2022 New module swad_forum_resource. (332274 lines)
Version 22.28: Sep 24, 2022 New module swad_attendance_resource. (332236 lines)
Version 22.27: Sep 24, 2022 New module swad_browser_resource. (332157 lines)
Version 22.26: Sep 23, 2022 New module swad_survey_resource. (332095 lines)
diff --git a/swad_database.c b/swad_database.c
index 38ab575d..30b38f12 100644
--- a/swad_database.c
+++ b/swad_database.c
@@ -2453,15 +2453,15 @@ mysql> DESCRIBE plg_plugins;
/***** Table prg_clipboards *****/
/*
mysql> DESCRIBE prg_clipboards;
-+----------+-------------------------------------------------------------------+------+-----+---------+-------+
-| Field | Type | Null | Key | Default | Extra |
-+----------+-------------------------------------------------------------------+------+-----+---------+-------+
-| UsrCod | int | NO | PRI | NULL | |
-| CrsCod | int | NO | PRI | NULL | |
-| Type | enum('non','asg','cfe','exa','gam','svy','doc','mrk','att','for') | NO | PRI | non | |
-| Cod | int | NO | PRI | -1 | |
-| CopyTime | timestamp | YES | MUL | NULL | |
-+----------+-------------------------------------------------------------------+------+-----+---------+-------+
++----------+-------------------------------------------------------------------------+------+-----+---------+-------+
+| Field | Type | Null | Key | Default | Extra |
++----------+-------------------------------------------------------------------------+------+-----+---------+-------+
+| UsrCod | int | NO | PRI | NULL | |
+| CrsCod | int | NO | PRI | NULL | |
+| Type | enum('non','asg','prj','cfe','exa','gam','svy','doc','mrk','att','for') | NO | PRI | non | |
+| Cod | int | NO | PRI | -1 | |
+| CopyTime | timestamp | YES | MUL | NULL | |
++----------+-------------------------------------------------------------------------+------+-----+---------+-------+
5 rows in set (0,00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS prg_clipboards ("
@@ -2470,6 +2470,7 @@ mysql> DESCRIBE prg_clipboards;
"Type ENUM("
"'non',"
"'asg',"
+ "'prj',"
"'cfe',"
"'exa',"
"'gam',"
@@ -2541,17 +2542,17 @@ mysql> DESCRIBE prg_items;
/***** Table prg_resources *****/
/*
mysql> DESCRIBE prg_resources;
-+--------+-------------------------------------------------------------------+------+-----+---------+----------------+
-| Field | Type | Null | Key | Default | Extra |
-+--------+-------------------------------------------------------------------+------+-----+---------+----------------+
-| RscCod | int | NO | PRI | NULL | auto_increment |
-| ItmCod | int | NO | MUL | -1 | |
-| RscInd | int | NO | | 0 | |
-| Hidden | enum('N','Y') | NO | | N | |
-| Type | enum('non','asg','cfe','exa','gam','svy','doc','mrk','att','for') | NO | | non | |
-| Cod | int | NO | | -1 | |
-| Title | varchar(2047) | NO | | NULL | |
-+--------+-------------------------------------------------------------------+------+-----+---------+----------------+
++--------+-------------------------------------------------------------------------+------+-----+---------+----------------+
+| Field | Type | Null | Key | Default | Extra |
++--------+-------------------------------------------------------------------------+------+-----+---------+----------------+
+| RscCod | int | NO | PRI | NULL | auto_increment |
+| ItmCod | int | NO | MUL | -1 | |
+| RscInd | int | NO | | 0 | |
+| Hidden | enum('N','Y') | NO | | N | |
+| Type | enum('non','asg','prj','cfe','exa','gam','svy','doc','mrk','att','for') | NO | | non | |
+| Cod | int | NO | | -1 | |
+| Title | varchar(2047) | NO | | NULL | |
++--------+-------------------------------------------------------------------------+------+-----+---------+----------------+
7 rows in set (0,00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS prg_resources ("
@@ -2562,6 +2563,7 @@ mysql> DESCRIBE prg_resources;
"Type ENUM("
"'non',"
"'asg',"
+ "'prj',"
"'cfe',"
"'exa',"
"'gam',"
diff --git a/swad_game_resource.c b/swad_game_resource.c
index 65704baa..f65f2dfb 100644
--- a/swad_game_resource.c
+++ b/swad_game_resource.c
@@ -96,7 +96,7 @@ void GamRsc_WriteGameInCrsProgram (long GamCod,bool PutFormToGo,
/***** Write game title of exam *****/
HTM_Txt (Title);
- /***** End form to download file *****/
+ /***** End form to go to game *****/
if (PutFormToGo)
{
/* End form */
diff --git a/swad_program.h b/swad_program.h
index ee14b755..67817e0b 100644
--- a/swad_program.h
+++ b/swad_program.h
@@ -47,7 +47,7 @@ struct Prg_ResourceHierarchy
bool Hidden;
};
-#define PrgRsc_NUM_TYPES 10
+#define PrgRsc_NUM_TYPES 11
typedef enum
{
PrgRsc_NONE,
@@ -57,7 +57,7 @@ typedef enum
// lnk LINKS // Link to links
// tmt TIMETABLE // Link to timetable
PrgRsc_ASSIGNMENT,
- // prj PROJECT // A project is only for some students
+ PrgRsc_PROJECT, // A project is only for some students
PrgRsc_CALL_FOR_EXAM,
// tst TEST // User selects tags, teacher should select
PrgRsc_EXAM,
diff --git a/swad_program_database.c b/swad_program_database.c
index 842f9451..ae0df689 100644
--- a/swad_program_database.c
+++ b/swad_program_database.c
@@ -43,7 +43,7 @@ const char *Prg_ResourceTypesDB[PrgRsc_NUM_TYPES] =
// lnk LINKS // Link to links
// tmt TIMETABLE // Link to timetable
[PrgRsc_ASSIGNMENT ] = "asg",
- // prj PROJECT // A project is only for some students
+ [PrgRsc_PROJECT ] = "prj",
[PrgRsc_CALL_FOR_EXAM ] = "cfe",
// tst TEST // User selects tags, teacher should select
[PrgRsc_EXAM ] = "exa",
diff --git a/swad_program_resource.c b/swad_program_resource.c
index f0537f91..f03b7232 100644
--- a/swad_program_resource.c
+++ b/swad_program_resource.c
@@ -43,6 +43,7 @@
#include "swad_program.h"
#include "swad_program_database.h"
#include "swad_program_resource.h"
+#include "swad_project_resource.h"
#include "swad_survey_resource.h"
/*****************************************************************************/
@@ -58,7 +59,7 @@ const char *Prg_ResourceTypesIcons[PrgRsc_NUM_TYPES] =
// lnk LINKS // Link to links
// tmt TIMETABLE // Link to timetable
[PrgRsc_ASSIGNMENT ] = "edit.svg",
- // prj PROJECT // A project is only for some students
+ [PrgRsc_PROJECT ] = "file-invoice.svg",
[PrgRsc_CALL_FOR_EXAM ] = "bullhorn.svg",
// tst TEST // User selects tags, teacher should select
[PrgRsc_EXAM ] = "file-signature.svg",
@@ -984,6 +985,7 @@ static void PrgRsc_WriteLinkName (const struct Prg_Link *Link,bool PutFormToGo,
{
[PrgRsc_NONE ] = PrgRsc_WriteEmptyLinkInCrsProgram,
[PrgRsc_ASSIGNMENT ] = AsgRsc_WriteAssignmentInCrsProgram,
+ [PrgRsc_PROJECT ] = PrjRsc_WriteProjectInCrsProgram,
[PrgRsc_CALL_FOR_EXAM ] = CfeRsc_WriteCallForExamInCrsProgram,
[PrgRsc_EXAM ] = ExaRsc_WriteExamInCrsProgram,
[PrgRsc_GAME ] = GamRsc_WriteGameInCrsProgram,
@@ -1033,6 +1035,7 @@ static void PrgRsc_GetResourceTitleFromLink (struct Prg_Item *Item)
{
[PrgRsc_NONE ] = NULL,
[PrgRsc_ASSIGNMENT ] = AsgRsc_GetTitleFromAsgCod,
+ [PrgRsc_PROJECT ] = PrjRsc_GetTitleFromPrjCod,
[PrgRsc_CALL_FOR_EXAM ] = CfeRsc_GetTitleFromExaCod,
[PrgRsc_EXAM ] = ExaRsc_GetTitleFromExaCod,
[PrgRsc_GAME ] = GamRsc_GetTitleFromGamCod,
diff --git a/swad_project.c b/swad_project.c
index ee41292e..ef33b480 100644
--- a/swad_project.c
+++ b/swad_project.c
@@ -150,11 +150,8 @@ static long Prj_PrjCod = -1L;
/***************************** Private prototypes ****************************/
/*****************************************************************************/
-static void Prj_ResetProjects (struct Prj_Projects *Projects);
-
static void Prj_ReqUsrsToSelect (void *Projects);
static void Prj_GetSelectedUsrsAndShowTheirPrjs (struct Prj_Projects *Projects);
-static void Prj_ShowProjects (struct Prj_Projects *Projects);
static void Prj_ShowPrjsInCurrentPage (void *Projects);
static void Prj_ShowFormToFilterByMy_All (const struct Prj_Projects *Projects);
@@ -172,7 +169,6 @@ static void Prj_GetHiddenParamPreNon (struct Prj_Projects *Projects);
static Prj_HiddenVisibl_t Prj_GetHiddenParamHidVis (void);
static unsigned Prj_GetHiddenParamFaulti (void);
static long Prj_GetHiddenParamDptCod (void);
-static void Prj_GetParams (struct Prj_Projects *Projects);
static Usr_Who_t Prj_GetParamWho (void);
static void Prj_ShowProjectsHead (struct Prj_Projects *Projects,
@@ -283,7 +279,7 @@ long Prj_GetPrjCod (void)
/******************************* Reset projects ******************************/
/*****************************************************************************/
-static void Prj_ResetProjects (struct Prj_Projects *Projects)
+void Prj_ResetProjects (struct Prj_Projects *Projects)
{
Projects->Config.Editable = Prj_EDITABLE_DEFAULT;
Projects->Filter.Who = Prj_FILTER_WHO_DEFAULT;
@@ -358,7 +354,7 @@ void Prj_SeeProjects (void)
/******************************* Show projects *******************************/
/*****************************************************************************/
-static void Prj_ShowProjects (struct Prj_Projects *Projects)
+void Prj_ShowProjects (struct Prj_Projects *Projects)
{
switch (Projects->Filter.Who)
{
@@ -901,7 +897,7 @@ static long Prj_GetHiddenParamDptCod (void)
/***************** Get generic parameters to list projects *******************/
/*****************************************************************************/
-static void Prj_GetParams (struct Prj_Projects *Projects)
+void Prj_GetParams (struct Prj_Projects *Projects)
{
/***** Get filter (which projects to show) *****/
Projects->Filter.Who = Prj_GetParamWho ();
@@ -1277,11 +1273,17 @@ static void Prj_ShowOneProject (struct Prj_Projects *Projects,
case Prj_LIST_PROJECTS:
HTM_TD_Begin ("rowspan=\"3\" class=\"CONTEXT_COL %s\"",
The_GetColorRows ());
- Prj_PutFormsToRemEditOnePrj (Projects,Prj,Anchor,ICanViewProjectFiles);
- HTM_TD_End ();
break;
case Prj_FILE_BROWSER_PROJECT:
HTM_TD_Begin ("rowspan=\"3\" class=\"CONTEXT_COL\"");
+ break;
+ default:
+ break;
+ }
+ switch (ProjectView)
+ {
+ case Prj_LIST_PROJECTS:
+ case Prj_FILE_BROWSER_PROJECT:
Prj_PutFormsToRemEditOnePrj (Projects,Prj,Anchor,ICanViewProjectFiles);
HTM_TD_End ();
break;
@@ -2751,6 +2753,12 @@ static void Prj_PutFormsToRemEditOnePrj (struct Prj_Projects *Projects,
else
/* Icon to inform about locked/unlocked project edition */
Prj_PutIconOffLockedUnlocked (Prj);
+
+ /***** Link to get resource link *****/
+ if (Gbl.Usrs.Me.Role.Logged == Rol_TCH || // Only if I am a teacher
+ Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM) // or a superuser
+ Ico_PutContextualIconToGetLink (ActReqLnkPrj,NULL,
+ Prj_PutCurrentParams,Projects);
}
/*****************************************************************************/
@@ -3332,7 +3340,7 @@ static void Prj_PutFormProject (struct Prj_Projects *Projects,
/* Data */
HTM_TD_Begin ("class=\"LT\"");
- HTM_INPUT_TEXT ("Title",Prj_MAX_CHARS_PROJECT_TITLE,Prj->Title,
+ HTM_INPUT_TEXT ("Title",Prj_MAX_CHARS_TITLE,Prj->Title,
HTM_DONT_SUBMIT_ON_CHANGE,
"id=\"Title\""
" class=\"TITLE_DESCRIPTION_WIDTH INPUT_%s\""
@@ -3579,7 +3587,7 @@ void Prj_ReceiveFormProject (void)
if (ICanEditProject)
{
/* Get project title */
- Par_GetParToText ("Title",Prj.Title,Prj_MAX_BYTES_PROJECT_TITLE);
+ Par_GetParToText ("Title",Prj.Title,Prj_MAX_BYTES_TITLE);
/* Get department */
Prj.DptCod = Par_GetParToLong (Dpt_PARAM_DPT_COD_NAME);
diff --git a/swad_project.h b/swad_project.h
index c0d0f0a9..ec7c865f 100644
--- a/swad_project.h
+++ b/swad_project.h
@@ -108,8 +108,8 @@ typedef enum
#define Prj_ORDER_DEFAULT Prj_ORDER_START_TIME
/***** Project title *****/
-#define Prj_MAX_CHARS_PROJECT_TITLE (256 - 1) // 255
-#define Prj_MAX_BYTES_PROJECT_TITLE ((Prj_MAX_CHARS_PROJECT_TITLE + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 4095
+#define Prj_MAX_CHARS_TITLE (256 - 1) // 255
+#define Prj_MAX_BYTES_TITLE ((Prj_MAX_CHARS_TITLE + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 4095
/***** Type of proposal ******/
#define Prj_NUM_PROPOSAL_TYPES 3
@@ -160,7 +160,7 @@ struct Prj_Project
Prj_Proposal_t Proposal;
time_t CreatTime;
time_t ModifTime;
- char Title[Prj_MAX_BYTES_PROJECT_TITLE + 1];
+ char Title[Prj_MAX_BYTES_TITLE + 1];
long DptCod;
char *Description;
char *Knowledge;
@@ -175,14 +175,18 @@ struct Prj_Project
void Prj_SetPrjCod (long PrjCod);
long Prj_GetPrjCod (void);
+void Prj_ResetProjects (struct Prj_Projects *Projects);
+
void Prj_ListUsrsToSelect (void);
void Prj_SeeProjects (void);
+void Prj_ShowProjects (struct Prj_Projects *Projects);
void Prj_ShowTableSelectedPrjs (void);
void Prj_PutParams (struct Prj_Filter *Filter,
Prj_Order_t Order,
unsigned NumPage,
long PrjCod);
+void Prj_GetParams (struct Prj_Projects *Projects);
void Prj_ShowOneUniqueProject (struct Prj_Project *Prj);
diff --git a/swad_project_database.c b/swad_project_database.c
index baf47641..407c3309 100644
--- a/swad_project_database.c
+++ b/swad_project_database.c
@@ -500,6 +500,21 @@ unsigned Prj_DB_GetDataOfProjectByCod (MYSQL_RES **mysql_res,long PrjCod)
Gbl.Hierarchy.Crs.CrsCod);
}
+/*****************************************************************************/
+/********************* Get project title from database ***********************/
+/*****************************************************************************/
+
+void Prj_DB_GetProjectTitle (long PrjCod,char Title[Prj_MAX_BYTES_TITLE + 1])
+ {
+ DB_QuerySELECTString (Title,Prj_MAX_BYTES_TITLE,"can not get project title",
+ "SELECT Title" // row[0]
+ " FROM prj_projects"
+ " WHERE PrjCod=%ld"
+ " AND CrsCod=%ld", // Extra check
+ PrjCod,
+ Gbl.Hierarchy.Crs.CrsCod);
+ }
+
/*****************************************************************************/
/******************* Get some project data to check faults *******************/
/*****************************************************************************/
diff --git a/swad_project_database.h b/swad_project_database.h
index 9b892118..51eea302 100644
--- a/swad_project_database.h
+++ b/swad_project_database.h
@@ -46,6 +46,7 @@ unsigned Prj_DB_GetListProjects (MYSQL_RES **mysql_res,
const char *UsrsSubQuery); // NULL if no users
unsigned Prj_DB_GetCrsPrjsConfig (MYSQL_RES **mysql_res);
unsigned Prj_DB_GetDataOfProjectByCod (MYSQL_RES **mysql_res,long PrjCod);
+void Prj_DB_GetProjectTitle (long PrjCod,char Title[Prj_MAX_BYTES_TITLE + 1]);
unsigned Prj_DB_GetPrjDataToCheckFaults (MYSQL_RES **mysql_res,long PrjCod);
unsigned Prj_DB_GetNumUsrsInPrj (long PrjCod,Prj_RoleInProject_t RoleInProject);
unsigned Prj_DB_GetUsrsInPrj (MYSQL_RES **mysql_res,
diff --git a/swad_project_resource.c b/swad_project_resource.c
new file mode 100644
index 00000000..da81585a
--- /dev/null
+++ b/swad_project_resource.c
@@ -0,0 +1,123 @@
+// swad_game_resource.c: links to games as program resources
+
+/*
+ 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-2022 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 "swad_alert.h"
+#include "swad_error.h"
+#include "swad_form.h"
+#include "swad_program_database.h"
+#include "swad_project.h"
+#include "swad_project_database.h"
+
+/*****************************************************************************/
+/***************************** Get link to game ******************************/
+/*****************************************************************************/
+
+void PrjRsc_GetLinkToProject (void)
+ {
+ extern const char *Txt_Projects;
+ extern const char *Txt_Link_to_resource_X_copied_into_clipboard;
+ struct Prj_Projects Projects;
+ char Title[Prj_MAX_BYTES_TITLE + 1];
+
+ /***** Reset projects context *****/
+ Prj_ResetProjects (&Projects);
+
+ /***** Get parameters *****/
+ Prj_GetParams (&Projects);
+ Projects.PrjCod = Prj_GetParamPrjCod ();
+
+ /***** Get project title *****/
+ if (Projects.PrjCod > 0)
+ Prj_DB_GetProjectTitle (Projects.PrjCod,Title);
+ else
+ Str_Copy (Title,Txt_Projects,sizeof (Title) - 1);
+
+ /***** Copy link to PROJECT into resource clipboard *****/
+ Prg_DB_CopyToClipboard (PrgRsc_PROJECT,Projects.PrjCod);
+
+ /***** Write sucess message *****/
+ Ale_ShowAlert (Ale_SUCCESS,Txt_Link_to_resource_X_copied_into_clipboard,
+ Title);
+
+ /***** Show projects again *****/
+ Prj_ShowProjects (&Projects);
+ }
+
+/*****************************************************************************/
+/*********************** Write game in course program ************************/
+/*****************************************************************************/
+
+void PrjRsc_WriteProjectInCrsProgram (long PrjCod,bool PutFormToGo,
+ const char *Icon,const char *IconTitle)
+ {
+ extern const char *Txt_Actions[Act_NUM_ACTIONS];
+ char Title[Prj_MAX_BYTES_TITLE + 1];
+
+ /***** Get project title *****/
+ Prj_DB_GetProjectTitle (PrjCod,Title);
+
+ /***** Begin form to go to project *****/
+ if (PutFormToGo)
+ {
+ Frm_BeginForm (ActPrnOnePrj);
+ Prj_PutParamPrjCod (PrjCod);
+ HTM_BUTTON_Submit_Begin (Txt_Actions[ActPrnOnePrj],
+ "class=\"LM BT_LINK PRG_LNK_%s\"",
+ The_GetSuffix ());
+ }
+
+ /***** Icon depending on type ******/
+ if (PutFormToGo)
+ Ico_PutIconLink (Icon,Ico_BLACK,ActSeePrj);
+ else
+ Ico_PutIconOn (Icon,Ico_BLACK,IconTitle);
+
+ /***** Write project title of exam *****/
+ HTM_Txt (Title);
+
+ /***** End form to go to project *****/
+ if (PutFormToGo)
+ {
+ /* End form */
+ HTM_BUTTON_End ();
+
+ Frm_EndForm ();
+ }
+ }
+
+/*****************************************************************************/
+/******************* Get project title from project code *********************/
+/*****************************************************************************/
+
+void PrjRsc_GetTitleFromPrjCod (long PrjCod,char *Title,size_t TitleSize)
+ {
+ char TitleFromDB[Prj_MAX_BYTES_TITLE + 1];
+
+ /***** Get project title *****/
+ Prj_DB_GetProjectTitle (PrjCod,TitleFromDB);
+ Str_Copy (Title,TitleFromDB,TitleSize);
+ }
diff --git a/swad_project_resource.h b/swad_project_resource.h
new file mode 100644
index 00000000..752c9e45
--- /dev/null
+++ b/swad_project_resource.h
@@ -0,0 +1,42 @@
+// swad_project_resource.h: links to projects as program resources
+
+#ifndef _SWAD_PRJ_RSC
+#define _SWAD_PRJ_RSC
+/*
+ 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-2022 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 size_t
+
+/*****************************************************************************/
+/***************************** Public prototypes *****************************/
+/*****************************************************************************/
+
+void PrjRsc_GetLinkToProject (void);
+void PrjRsc_WriteProjectInCrsProgram (long PrjCod,bool PutFormToGo,
+ const char *Icon,const char *IconTitle);
+void PrjRsc_GetTitleFromPrjCod (long PrjCod,char *Title,size_t TitleSize);
+
+#endif
+
diff --git a/swad_text.c b/swad_text.c
index 79e994f0..d86ec455 100644
--- a/swad_text.c
+++ b/swad_text.c
@@ -32214,7 +32214,7 @@ const char *Txt_Project_X_removed = // Warning: it is very important to include
#elif L==9 // pt
"Projeto %s removido.";
#elif L==10 // tr
- "Project %s removed."; // Çeviri lazim!
+ "%s projesi kaldırıldı.";
#endif
const char *Txt_PROJECT_ROLES_SINGUL_Abc[Prj_NUM_ROLES_IN_PROJECT] =
@@ -35741,6 +35741,29 @@ const char *Txt_RESOURCE_TYPES[PrgRsc_NUM_TYPES] =
"Atividade"
#elif L==10 // tr
"Atama"
+#endif
+ ,
+ [PrgRsc_PROJECT] =
+#if L==1 // ca
+ "Projecte"
+#elif L==2 // de
+ "Projekt"
+#elif L==3 // en
+ "Project"
+#elif L==4 // es
+ "Proyecto"
+#elif L==5 // fr
+ "Projet"
+#elif L==6 // gn
+ "Proyecto" // Okoteve traducción
+#elif L==7 // it
+ "Progetto"
+#elif L==8 // pl
+ "Projekt"
+#elif L==9 // pt
+ "Projeto"
+#elif L==10 // tr
+ "Projesi"
#endif
,
[PrgRsc_CALL_FOR_EXAM] =
diff --git a/swad_text_action.c b/swad_text_action.c
index 5d65162e..439a696f 100644
--- a/swad_text_action.c
+++ b/swad_text_action.c
@@ -9310,25 +9310,25 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
,
[ActReqLnkAsg] =
#if L==1 // ca
- "Copy link to assignment" // Necessita traducció
+ "Copy link to assignment" // Necessita traducció
#elif L==2 // de
- "Copy link to assignment" // Need Übersetzung
+ "Copy link to assignment" // Need Übersetzung
#elif L==3 // en
- "Copy link to assignment"
+ "Copy link to assignment"
#elif L==4 // es
"Copiar enlace a actividad"
#elif L==5 // fr
- "Copy link to assignment" // Besoin de traduction
+ "Copy link to assignment" // Besoin de traduction
#elif L==6 // gn
"Copiar enlace a actividad" // Okoteve traducción
#elif L==7 // it
- "Copy link to assignment" // Bisogno di traduzione
+ "Copy link to assignment" // Bisogno di traduzione
#elif L==8 // pl
- "Copy link to assignment" // Potrzebujesz tlumaczenie
+ "Copy link to assignment" // Potrzebujesz tlumaczenie
#elif L==9 // pt
- "Copy link to assignment" // Precisa de tradução
+ "Copy link to assignment" // Precisa de tradução
#elif L==10 // tr
- "Copy link to assignment" // Çeviri lazim!
+ "Copy link to assignment" // Çeviri lazim!
#endif
,
[ActReqUsrPrj] =
@@ -10042,6 +10042,29 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
"Remove evaluator from a project" // Precisa de tradução
#elif L==10 // tr
"Remove evaluator from a project" // Çeviri lazim!
+#endif
+ ,
+ [ActReqLnkPrj] =
+#if L==1 // ca
+ "Copy link to project" // Necessita traducció
+#elif L==2 // de
+ "Copy link to project" // Need Übersetzung
+#elif L==3 // en
+ "Copy link to project"
+#elif L==4 // es
+ "Copiar enlace a proyecto"
+#elif L==5 // fr
+ "Copy link to project" // Besoin de traduction
+#elif L==6 // gn
+ "Copiar enlace a proyecto" // Okoteve traducción
+#elif L==7 // it
+ "Copy link to project" // Bisogno di traduzione
+#elif L==8 // pl
+ "Copy link to project" // Potrzebujesz tlumaczenie
+#elif L==9 // pt
+ "Copy link to project" // Precisa de tradução
+#elif L==10 // tr
+ "Copy link to project" // Çeviri lazim!
#endif
,
[ActAdmDocPrj] =