// swad_browser.c: file browsers /* 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-2023 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 ***********************************/ /*****************************************************************************/ #define _GNU_SOURCE // For asprintf #include // For scandir, etc. #include // For errno #include // For PATH_MAX #include // For NULL #include // For asprintf #include // For exit, system, free, etc #include // For string functions #include // For lstat, time_t #include // For lstat #include // For time #include // For access, lstat, getpid, chdir, symlink #include "swad_action_list.h" #include "swad_alert.h" #include "swad_box.h" #include "swad_browser.h" #include "swad_browser_database.h" #include "swad_browser_size.h" #include "swad_config.h" #include "swad_course_database.h" #include "swad_database.h" #include "swad_enrolment_database.h" #include "swad_error.h" #include "swad_figure.h" #include "swad_file_extension.h" #include "swad_file_MIME.h" #include "swad_form.h" #include "swad_global.h" #include "swad_group_database.h" #include "swad_hierarchy.h" #include "swad_hierarchy_level.h" #include "swad_HTML.h" #include "swad_ID.h" #include "swad_logo.h" #include "swad_mark.h" #include "swad_mark_database.h" #include "swad_notification.h" #include "swad_notification_database.h" #include "swad_parameter_code.h" #include "swad_photo.h" #include "swad_profile.h" #include "swad_profile_database.h" #include "swad_project.h" #include "swad_project_database.h" #include "swad_resource.h" #include "swad_role.h" #include "swad_setting.h" #include "swad_setting_database.h" #include "swad_string.h" #include "swad_timeline.h" #include "swad_timeline_note.h" #include "swad_user_database.h" #include "swad_zip.h" /*****************************************************************************/ /******************** Global variables from other modules ********************/ /*****************************************************************************/ extern struct Globals Gbl; /*****************************************************************************/ /******************************* Private types *******************************/ /*****************************************************************************/ typedef enum { Brw_ICON_TREE_NOTHING, // No icon to expand/contract a subtree Brw_ICON_TREE_EXPAND, // Icon to expand a contracted subtree Brw_ICON_TREE_CONTRACT, // Icon to contract a expanded subtree } Brw_IconTree_t; struct Brw_NumObjects { unsigned NumFiles; unsigned NumFolds; unsigned NumLinks; }; /*****************************************************************************/ /***************************** Public constants ******************************/ /*****************************************************************************/ // Names of root folders const char *Brw_RootFolderInternalNames[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = "", [Brw_SHOW_DOC_CRS] = Brw_INTERNAL_NAME_ROOT_FOLDER_DOWNLOAD, [Brw_SHOW_MRK_CRS] = Brw_INTERNAL_NAME_ROOT_FOLDER_MARKS, [Brw_ADMI_DOC_CRS] = Brw_INTERNAL_NAME_ROOT_FOLDER_DOWNLOAD, [Brw_ADMI_SHR_CRS] = Brw_INTERNAL_NAME_ROOT_FOLDER_SHARED, [Brw_ADMI_SHR_GRP] = Brw_INTERNAL_NAME_ROOT_FOLDER_SHARED, [Brw_ADMI_WRK_USR] = Brw_INTERNAL_NAME_ROOT_FOLDER_WORKS, [Brw_ADMI_WRK_CRS] = Brw_INTERNAL_NAME_ROOT_FOLDER_WORKS, [Brw_ADMI_MRK_CRS] = Brw_INTERNAL_NAME_ROOT_FOLDER_MARKS, [Brw_ADMI_BRF_USR] = Brw_INTERNAL_NAME_ROOT_FOLDER_BRIEF, [Brw_SHOW_DOC_GRP] = Brw_INTERNAL_NAME_ROOT_FOLDER_DOWNLOAD, [Brw_ADMI_DOC_GRP] = Brw_INTERNAL_NAME_ROOT_FOLDER_DOWNLOAD, [Brw_SHOW_MRK_GRP] = Brw_INTERNAL_NAME_ROOT_FOLDER_MARKS, [Brw_ADMI_MRK_GRP] = Brw_INTERNAL_NAME_ROOT_FOLDER_MARKS, [Brw_ADMI_ASG_USR] = Brw_INTERNAL_NAME_ROOT_FOLDER_ASSIGNMENTS, [Brw_ADMI_ASG_CRS] = Brw_INTERNAL_NAME_ROOT_FOLDER_ASSIGNMENTS, [Brw_SHOW_DOC_DEG] = Brw_INTERNAL_NAME_ROOT_FOLDER_DOCUMENTS, [Brw_ADMI_DOC_DEG] = Brw_INTERNAL_NAME_ROOT_FOLDER_DOCUMENTS, [Brw_SHOW_DOC_CTR] = Brw_INTERNAL_NAME_ROOT_FOLDER_DOCUMENTS, [Brw_ADMI_DOC_CTR] = Brw_INTERNAL_NAME_ROOT_FOLDER_DOCUMENTS, [Brw_SHOW_DOC_INS] = Brw_INTERNAL_NAME_ROOT_FOLDER_DOCUMENTS, [Brw_ADMI_DOC_INS] = Brw_INTERNAL_NAME_ROOT_FOLDER_DOCUMENTS, [Brw_ADMI_SHR_DEG] = Brw_INTERNAL_NAME_ROOT_FOLDER_SHARED_FILES, [Brw_ADMI_SHR_CTR] = Brw_INTERNAL_NAME_ROOT_FOLDER_SHARED_FILES, [Brw_ADMI_SHR_INS] = Brw_INTERNAL_NAME_ROOT_FOLDER_SHARED_FILES, [Brw_ADMI_TCH_CRS] = Brw_INTERNAL_NAME_ROOT_FOLDER_TEACHERS, [Brw_ADMI_TCH_GRP] = Brw_INTERNAL_NAME_ROOT_FOLDER_TEACHERS, [Brw_ADMI_DOC_PRJ] = Brw_INTERNAL_NAME_ROOT_FOLDER_PROJECT_DOCUMENTS, [Brw_ADMI_ASS_PRJ] = Brw_INTERNAL_NAME_ROOT_FOLDER_PROJECT_ASSESSMENT, }; /*****************************************************************************/ /***************************** Private constants *****************************/ /*****************************************************************************/ static const char *Brw_FileTypeParName[Brw_NUM_FILE_TYPES] = { [Brw_IS_UNKNOWN] = "BrwFFL", [Brw_IS_FILE ] = "BrwFil", // Do not use Fil_NAME_OF_PARAM_FILENAME_ORG [Brw_IS_FOLDER ] = "BrwFol", [Brw_IS_LINK ] = "BrwLnk", }; // Browsers viewable shown in search for documents static const Brw_FileBrowser_t Brw_FileBrowserForFoundDocs[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = Brw_UNKNOWN, [Brw_SHOW_DOC_CRS] = Brw_SHOW_DOC_CRS, [Brw_SHOW_MRK_CRS] = Brw_SHOW_MRK_CRS, [Brw_ADMI_DOC_CRS] = Brw_SHOW_DOC_CRS, [Brw_ADMI_SHR_CRS] = Brw_ADMI_SHR_CRS, [Brw_ADMI_SHR_GRP] = Brw_ADMI_SHR_GRP, [Brw_ADMI_WRK_USR] = Brw_ADMI_WRK_USR, [Brw_ADMI_WRK_CRS] = Brw_ADMI_WRK_USR, [Brw_ADMI_MRK_CRS] = Brw_ADMI_MRK_CRS, [Brw_ADMI_BRF_USR] = Brw_ADMI_BRF_USR, [Brw_SHOW_DOC_GRP] = Brw_SHOW_DOC_GRP, [Brw_ADMI_DOC_GRP] = Brw_SHOW_DOC_GRP, [Brw_SHOW_MRK_GRP] = Brw_SHOW_MRK_GRP, [Brw_ADMI_MRK_GRP] = Brw_SHOW_MRK_GRP, [Brw_ADMI_ASG_USR] = Brw_ADMI_ASG_USR, [Brw_ADMI_ASG_CRS] = Brw_ADMI_ASG_USR, [Brw_SHOW_DOC_DEG] = Brw_SHOW_DOC_DEG, [Brw_ADMI_DOC_DEG] = Brw_SHOW_DOC_DEG, [Brw_SHOW_DOC_CTR] = Brw_SHOW_DOC_CTR, [Brw_ADMI_DOC_CTR] = Brw_SHOW_DOC_CTR, [Brw_SHOW_DOC_INS] = Brw_SHOW_DOC_INS, [Brw_ADMI_DOC_INS] = Brw_SHOW_DOC_INS, [Brw_ADMI_SHR_DEG] = Brw_ADMI_SHR_DEG, [Brw_ADMI_SHR_CTR] = Brw_ADMI_SHR_CTR, [Brw_ADMI_SHR_INS] = Brw_ADMI_SHR_INS, [Brw_ADMI_TCH_CRS] = Brw_ADMI_TCH_CRS, [Brw_ADMI_TCH_GRP] = Brw_ADMI_TCH_GRP, [Brw_ADMI_DOC_PRJ] = Brw_ADMI_DOC_PRJ, [Brw_ADMI_ASS_PRJ] = Brw_ADMI_ASS_PRJ, }; // Browsers types for database "clipboard" table static const Brw_FileBrowser_t Brw_FileBrowserForDB_clipboard[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = Brw_UNKNOWN, [Brw_SHOW_DOC_CRS] = Brw_ADMI_DOC_CRS, [Brw_SHOW_MRK_CRS] = Brw_ADMI_MRK_CRS, [Brw_ADMI_DOC_CRS] = Brw_ADMI_DOC_CRS, [Brw_ADMI_SHR_CRS] = Brw_ADMI_SHR_CRS, [Brw_ADMI_SHR_GRP] = Brw_ADMI_SHR_GRP, [Brw_ADMI_WRK_USR] = Brw_ADMI_WRK_USR, [Brw_ADMI_WRK_CRS] = Brw_ADMI_WRK_CRS, [Brw_ADMI_MRK_CRS] = Brw_ADMI_MRK_CRS, [Brw_ADMI_BRF_USR] = Brw_ADMI_BRF_USR, [Brw_SHOW_DOC_GRP] = Brw_ADMI_DOC_GRP, [Brw_ADMI_DOC_GRP] = Brw_ADMI_DOC_GRP, [Brw_SHOW_MRK_GRP] = Brw_ADMI_MRK_GRP, [Brw_ADMI_MRK_GRP] = Brw_ADMI_MRK_GRP, [Brw_ADMI_ASG_USR] = Brw_ADMI_ASG_USR, [Brw_ADMI_ASG_CRS] = Brw_ADMI_ASG_CRS, [Brw_SHOW_DOC_DEG] = Brw_ADMI_DOC_DEG, [Brw_ADMI_DOC_DEG] = Brw_ADMI_DOC_DEG, [Brw_SHOW_DOC_CTR] = Brw_ADMI_DOC_CTR, [Brw_ADMI_DOC_CTR] = Brw_ADMI_DOC_CTR, [Brw_SHOW_DOC_INS] = Brw_ADMI_DOC_INS, [Brw_ADMI_DOC_INS] = Brw_ADMI_DOC_INS, [Brw_ADMI_SHR_DEG] = Brw_ADMI_SHR_DEG, [Brw_ADMI_SHR_CTR] = Brw_ADMI_SHR_CTR, [Brw_ADMI_SHR_INS] = Brw_ADMI_SHR_INS, [Brw_ADMI_TCH_CRS] = Brw_ADMI_TCH_CRS, [Brw_ADMI_TCH_GRP] = Brw_ADMI_TCH_GRP, [Brw_ADMI_DOC_PRJ] = Brw_ADMI_DOC_PRJ, [Brw_ADMI_ASS_PRJ] = Brw_ADMI_ASS_PRJ, }; static const Act_Action_t Brw_ActSeeAdm[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActSeeDocCrs, [Brw_SHOW_MRK_CRS] = ActSeeMrkCrs, [Brw_ADMI_DOC_CRS] = ActAdmDocCrs, [Brw_ADMI_SHR_CRS] = ActAdmShaCrs, [Brw_ADMI_SHR_GRP] = ActAdmShaGrp, [Brw_ADMI_WRK_USR] = ActAdmAsgWrkUsr, [Brw_ADMI_WRK_CRS] = ActAdmAsgWrkCrs, [Brw_ADMI_MRK_CRS] = ActAdmMrkCrs, [Brw_ADMI_BRF_USR] = ActAdmBrf, [Brw_SHOW_DOC_GRP] = ActSeeDocGrp, [Brw_ADMI_DOC_GRP] = ActAdmDocGrp, [Brw_SHOW_MRK_GRP] = ActSeeMrkGrp, [Brw_ADMI_MRK_GRP] = ActAdmMrkGrp, [Brw_ADMI_ASG_USR] = ActAdmAsgWrkUsr, [Brw_ADMI_ASG_CRS] = ActAdmAsgWrkCrs, [Brw_SHOW_DOC_DEG] = ActSeeDocDeg, [Brw_ADMI_DOC_DEG] = ActAdmDocDeg, [Brw_SHOW_DOC_CTR] = ActSeeDocCtr, [Brw_ADMI_DOC_CTR] = ActAdmDocCtr, [Brw_SHOW_DOC_INS] = ActSeeDocIns, [Brw_ADMI_DOC_INS] = ActAdmDocIns, [Brw_ADMI_SHR_DEG] = ActAdmShaDeg, [Brw_ADMI_SHR_CTR] = ActAdmShaCtr, [Brw_ADMI_SHR_INS] = ActAdmShaIns, [Brw_ADMI_TCH_CRS] = ActAdmTchCrs, [Brw_ADMI_TCH_GRP] = ActAdmTchGrp, [Brw_ADMI_DOC_PRJ] = ActAdmDocPrj, [Brw_ADMI_ASS_PRJ] = ActAdmAssPrj, }; static const Act_Action_t Brw_ActFromSeeToAdm[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActAdmDocCrs, [Brw_SHOW_MRK_CRS] = ActAdmMrkCrs, [Brw_ADMI_DOC_CRS] = ActUnk, [Brw_ADMI_SHR_CRS] = ActUnk, [Brw_ADMI_SHR_GRP] = ActUnk, [Brw_ADMI_WRK_USR] = ActUnk, [Brw_ADMI_WRK_CRS] = ActUnk, [Brw_ADMI_MRK_CRS] = ActUnk, [Brw_ADMI_BRF_USR] = ActUnk, [Brw_SHOW_DOC_GRP] = ActAdmDocGrp, [Brw_ADMI_DOC_GRP] = ActUnk, [Brw_SHOW_MRK_GRP] = ActAdmMrkGrp, [Brw_ADMI_MRK_GRP] = ActUnk, [Brw_ADMI_ASG_USR] = ActUnk, [Brw_ADMI_ASG_CRS] = ActUnk, [Brw_SHOW_DOC_DEG] = ActAdmDocDeg, [Brw_ADMI_DOC_DEG] = ActUnk, [Brw_SHOW_DOC_CTR] = ActAdmDocCtr, [Brw_ADMI_DOC_CTR] = ActUnk, [Brw_SHOW_DOC_INS] = ActAdmDocIns, [Brw_ADMI_DOC_INS] = ActUnk, [Brw_ADMI_SHR_DEG] = ActUnk, [Brw_ADMI_SHR_CTR] = ActUnk, [Brw_ADMI_SHR_INS] = ActUnk, [Brw_ADMI_TCH_CRS] = ActUnk, [Brw_ADMI_TCH_GRP] = ActUnk, [Brw_ADMI_DOC_PRJ] = ActUnk, [Brw_ADMI_ASS_PRJ] = ActUnk, }; static const Act_Action_t Brw_ActFromAdmToSee[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActUnk, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActSeeDocCrs, [Brw_ADMI_SHR_CRS] = ActUnk, [Brw_ADMI_SHR_GRP] = ActUnk, [Brw_ADMI_WRK_USR] = ActUnk, [Brw_ADMI_WRK_CRS] = ActUnk, [Brw_ADMI_MRK_CRS] = ActSeeMrkCrs, [Brw_ADMI_BRF_USR] = ActUnk, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActSeeDocGrp, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActSeeMrkGrp, [Brw_ADMI_ASG_USR] = ActUnk, [Brw_ADMI_ASG_CRS] = ActUnk, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActSeeDocDeg, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActSeeDocCtr, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActSeeDocIns, [Brw_ADMI_SHR_DEG] = ActUnk, [Brw_ADMI_SHR_CTR] = ActUnk, [Brw_ADMI_SHR_INS] = ActUnk, [Brw_ADMI_TCH_CRS] = ActUnk, [Brw_ADMI_TCH_GRP] = ActUnk, [Brw_ADMI_DOC_PRJ] = ActUnk, [Brw_ADMI_ASS_PRJ] = ActUnk, }; static const Act_Action_t Brw_ActChgZone[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActChgToSeeDocCrs, [Brw_SHOW_MRK_CRS] = ActChgToSeeMrk, [Brw_ADMI_DOC_CRS] = ActChgToAdmDocCrs, [Brw_ADMI_SHR_CRS] = ActChgToAdmSha, [Brw_ADMI_SHR_GRP] = ActChgToAdmSha, [Brw_ADMI_WRK_USR] = ActUnk, [Brw_ADMI_WRK_CRS] = ActUnk, [Brw_ADMI_MRK_CRS] = ActChgToAdmMrk, [Brw_ADMI_BRF_USR] = ActUnk, [Brw_SHOW_DOC_GRP] = ActChgToSeeDocCrs, [Brw_ADMI_DOC_GRP] = ActChgToAdmDocCrs, [Brw_SHOW_MRK_GRP] = ActChgToSeeMrk, [Brw_ADMI_MRK_GRP] = ActChgToAdmMrk, [Brw_ADMI_ASG_USR] = ActUnk, [Brw_ADMI_ASG_CRS] = ActUnk, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActUnk, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActUnk, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActUnk, [Brw_ADMI_SHR_DEG] = ActUnk, [Brw_ADMI_SHR_CTR] = ActUnk, [Brw_ADMI_SHR_INS] = ActUnk, [Brw_ADMI_TCH_CRS] = ActChgToAdmTch, [Brw_ADMI_TCH_GRP] = ActChgToAdmTch, [Brw_ADMI_DOC_PRJ] = ActUnk, [Brw_ADMI_ASS_PRJ] = ActUnk, }; static const Act_Action_t Brw_ActHideUnhide[Brw_NUM_TYPES_FILE_BROWSER][2] = { [Brw_UNKNOWN ] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_SHOW_DOC_CRS] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_SHOW_MRK_CRS] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_DOC_CRS] = {[false] = ActHidDocCrs ,[true] = ActUnhDocCrs }, [Brw_ADMI_SHR_CRS] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_SHR_GRP] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_WRK_USR] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_WRK_CRS] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_MRK_CRS] = {[false] = ActHidMrkCrs ,[true] = ActUnhMrkCrs }, [Brw_ADMI_BRF_USR] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_SHOW_DOC_GRP] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_DOC_GRP] = {[false] = ActHidDocGrp ,[true] = ActUnhDocGrp }, [Brw_SHOW_MRK_GRP] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_MRK_GRP] = {[false] = ActHidMrkGrp ,[true] = ActUnhMrkGrp }, [Brw_ADMI_ASG_USR] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_ASG_CRS] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_SHOW_DOC_DEG] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_DOC_DEG] = {[false] = ActHidDocDeg ,[true] = ActUnhDocDeg }, [Brw_SHOW_DOC_CTR] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_DOC_CTR] = {[false] = ActHidDocCtr ,[true] = ActUnhDocCtr }, [Brw_SHOW_DOC_INS] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_DOC_INS] = {[false] = ActHidDocIns ,[true] = ActUnhDocIns }, [Brw_ADMI_SHR_DEG] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_SHR_CTR] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_SHR_INS] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_TCH_CRS] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_TCH_GRP] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_DOC_PRJ] = {[false] = ActUnk ,[true] = ActUnk }, [Brw_ADMI_ASS_PRJ] = {[false] = ActUnk ,[true] = ActUnk }, }; static const Act_Action_t Brw_ActReqDatFile[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActReqDatSeeDocCrs, [Brw_SHOW_MRK_CRS] = ActReqDatSeeMrkCrs, [Brw_ADMI_DOC_CRS] = ActReqDatAdmDocCrs, [Brw_ADMI_SHR_CRS] = ActReqDatShaCrs, [Brw_ADMI_SHR_GRP] = ActReqDatShaGrp, [Brw_ADMI_WRK_USR] = ActReqDatWrkUsr, [Brw_ADMI_WRK_CRS] = ActReqDatWrkCrs, [Brw_ADMI_MRK_CRS] = ActReqDatAdmMrkCrs, [Brw_ADMI_BRF_USR] = ActReqDatBrf, [Brw_SHOW_DOC_GRP] = ActReqDatSeeDocGrp, [Brw_ADMI_DOC_GRP] = ActReqDatAdmDocGrp, [Brw_SHOW_MRK_GRP] = ActReqDatSeeMrkGrp, [Brw_ADMI_MRK_GRP] = ActReqDatAdmMrkGrp, [Brw_ADMI_ASG_USR] = ActReqDatAsgUsr, [Brw_ADMI_ASG_CRS] = ActReqDatAsgCrs, [Brw_SHOW_DOC_DEG] = ActReqDatSeeDocDeg, [Brw_ADMI_DOC_DEG] = ActReqDatAdmDocDeg, [Brw_SHOW_DOC_CTR] = ActReqDatSeeDocCtr, [Brw_ADMI_DOC_CTR] = ActReqDatAdmDocCtr, [Brw_SHOW_DOC_INS] = ActReqDatSeeDocIns, [Brw_ADMI_DOC_INS] = ActReqDatAdmDocIns, [Brw_ADMI_SHR_DEG] = ActReqDatShaDeg, [Brw_ADMI_SHR_CTR] = ActReqDatShaCtr, [Brw_ADMI_SHR_INS] = ActReqDatShaIns, [Brw_ADMI_TCH_CRS] = ActReqDatTchCrs, [Brw_ADMI_TCH_GRP] = ActReqDatTchGrp, [Brw_ADMI_DOC_PRJ] = ActReqDatDocPrj, [Brw_ADMI_ASS_PRJ] = ActReqDatAssPrj, }; static const Act_Action_t Brw_ActReqLnk[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActReqLnkSeeDocCrs, [Brw_SHOW_MRK_CRS] = ActReqLnkSeeMrkCrs, [Brw_ADMI_DOC_CRS] = ActReqLnkAdmDocCrs, [Brw_ADMI_SHR_CRS] = ActUnk, [Brw_ADMI_SHR_GRP] = ActUnk, [Brw_ADMI_WRK_USR] = ActUnk, [Brw_ADMI_WRK_CRS] = ActUnk, [Brw_ADMI_MRK_CRS] = ActReqLnkAdmMrkCrs, [Brw_ADMI_BRF_USR] = ActUnk, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActUnk, [Brw_SHOW_MRK_GRP] = ActUnk, // ActReqLnkSeeMrkGrp, [Brw_ADMI_MRK_GRP] = ActUnk, // ActReqLnkAdmMrkGrp, [Brw_ADMI_ASG_USR] = ActUnk, [Brw_ADMI_ASG_CRS] = ActUnk, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActUnk, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActUnk, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActUnk, [Brw_ADMI_SHR_DEG] = ActUnk, [Brw_ADMI_SHR_CTR] = ActUnk, [Brw_ADMI_SHR_INS] = ActUnk, [Brw_ADMI_TCH_CRS] = ActUnk, [Brw_ADMI_TCH_GRP] = ActUnk, [Brw_ADMI_DOC_PRJ] = ActUnk, [Brw_ADMI_ASS_PRJ] = ActUnk, }; static const Act_Action_t Brw_ActDowFile[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActDowSeeDocCrs, [Brw_SHOW_MRK_CRS] = ActSeeMyMrkCrs, [Brw_ADMI_DOC_CRS] = ActDowAdmDocCrs, [Brw_ADMI_SHR_CRS] = ActDowShaCrs, [Brw_ADMI_SHR_GRP] = ActDowShaGrp, [Brw_ADMI_WRK_USR] = ActDowWrkUsr, [Brw_ADMI_WRK_CRS] = ActDowWrkCrs, [Brw_ADMI_MRK_CRS] = ActDowAdmMrkCrs, [Brw_ADMI_BRF_USR] = ActDowBrf, [Brw_SHOW_DOC_GRP] = ActDowSeeDocGrp, [Brw_ADMI_DOC_GRP] = ActDowAdmDocGrp, [Brw_SHOW_MRK_GRP] = ActSeeMyMrkGrp, [Brw_ADMI_MRK_GRP] = ActDowAdmMrkGrp, [Brw_ADMI_ASG_USR] = ActDowAsgUsr, [Brw_ADMI_ASG_CRS] = ActDowAsgCrs, [Brw_SHOW_DOC_DEG] = ActDowSeeDocDeg, [Brw_ADMI_DOC_DEG] = ActDowAdmDocDeg, [Brw_SHOW_DOC_CTR] = ActDowSeeDocCtr, [Brw_ADMI_DOC_CTR] = ActDowAdmDocCtr, [Brw_SHOW_DOC_INS] = ActDowSeeDocIns, [Brw_ADMI_DOC_INS] = ActDowAdmDocIns, [Brw_ADMI_SHR_DEG] = ActDowShaDeg, [Brw_ADMI_SHR_CTR] = ActDowShaCtr, [Brw_ADMI_SHR_INS] = ActDowShaIns, [Brw_ADMI_TCH_CRS] = ActDowTchCrs, [Brw_ADMI_TCH_GRP] = ActDowTchGrp, [Brw_ADMI_DOC_PRJ] = ActDowDocPrj, [Brw_ADMI_ASS_PRJ] = ActDowAssPrj, }; static const Act_Action_t Brw_ActAskRemoveFile[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActUnk, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActReqRemFilDocCrs, [Brw_ADMI_SHR_CRS] = ActReqRemFilShaCrs, [Brw_ADMI_SHR_GRP] = ActReqRemFilShaGrp, [Brw_ADMI_WRK_USR] = ActReqRemFilWrkUsr, [Brw_ADMI_WRK_CRS] = ActReqRemFilWrkCrs, [Brw_ADMI_MRK_CRS] = ActReqRemFilMrkCrs, [Brw_ADMI_BRF_USR] = ActReqRemFilBrf, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActReqRemFilDocGrp, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActReqRemFilMrkGrp, [Brw_ADMI_ASG_USR] = ActReqRemFilAsgUsr, [Brw_ADMI_ASG_CRS] = ActReqRemFilAsgCrs, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActReqRemFilDocDeg, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActReqRemFilDocCtr, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActReqRemFilDocIns, [Brw_ADMI_SHR_DEG] = ActReqRemFilShaDeg, [Brw_ADMI_SHR_CTR] = ActReqRemFilShaCtr, [Brw_ADMI_SHR_INS] = ActReqRemFilShaIns, [Brw_ADMI_TCH_CRS] = ActReqRemFilTchCrs, [Brw_ADMI_TCH_GRP] = ActReqRemFilTchGrp, [Brw_ADMI_DOC_PRJ] = ActReqRemFilDocPrj, [Brw_ADMI_ASS_PRJ] = ActReqRemFilAssPrj, }; static const Act_Action_t Brw_ActRemoveFile[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActUnk, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActRemFilDocCrs, [Brw_ADMI_SHR_CRS] = ActRemFilShaCrs, [Brw_ADMI_SHR_GRP] = ActRemFilShaGrp, [Brw_ADMI_WRK_USR] = ActRemFilWrkUsr, [Brw_ADMI_WRK_CRS] = ActRemFilWrkCrs, [Brw_ADMI_MRK_CRS] = ActRemFilMrkCrs, [Brw_ADMI_BRF_USR] = ActRemFilBrf, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActRemFilDocGrp, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActRemFilMrkGrp, [Brw_ADMI_ASG_USR] = ActRemFilAsgUsr, [Brw_ADMI_ASG_CRS] = ActRemFilAsgCrs, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActRemFilDocDeg, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActRemFilDocCtr, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActRemFilDocIns, [Brw_ADMI_SHR_DEG] = ActRemFilShaDeg, [Brw_ADMI_SHR_CTR] = ActRemFilShaCtr, [Brw_ADMI_SHR_INS] = ActRemFilShaIns, [Brw_ADMI_TCH_CRS] = ActRemFilTchCrs, [Brw_ADMI_TCH_GRP] = ActRemFilTchGrp, [Brw_ADMI_DOC_PRJ] = ActRemFilDocPrj, [Brw_ADMI_ASS_PRJ] = ActRemFilAssPrj, }; static const Act_Action_t Brw_ActRemoveFolder[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActUnk, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActRemFolDocCrs, [Brw_ADMI_SHR_CRS] = ActRemFolShaCrs, [Brw_ADMI_SHR_GRP] = ActRemFolShaGrp, [Brw_ADMI_WRK_USR] = ActRemFolWrkUsr, [Brw_ADMI_WRK_CRS] = ActRemFolWrkCrs, [Brw_ADMI_MRK_CRS] = ActRemFolMrkCrs, [Brw_ADMI_BRF_USR] = ActRemFolBrf, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActRemFolDocGrp, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActRemFolMrkGrp, [Brw_ADMI_ASG_USR] = ActRemFolAsgUsr, [Brw_ADMI_ASG_CRS] = ActRemFolAsgCrs, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActRemFolDocDeg, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActRemFolDocCtr, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActRemFolDocIns, [Brw_ADMI_SHR_DEG] = ActRemFolShaDeg, [Brw_ADMI_SHR_CTR] = ActRemFolShaCtr, [Brw_ADMI_SHR_INS] = ActRemFolShaIns, [Brw_ADMI_TCH_CRS] = ActRemFolTchCrs, [Brw_ADMI_TCH_GRP] = ActRemFolTchGrp, [Brw_ADMI_DOC_PRJ] = ActRemFolDocPrj, [Brw_ADMI_ASS_PRJ] = ActRemFolAssPrj, }; static const Act_Action_t Brw_ActRemoveFolderNotEmpty[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActUnk, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActRemTreDocCrs, [Brw_ADMI_SHR_CRS] = ActRemTreShaCrs, [Brw_ADMI_SHR_GRP] = ActRemTreShaGrp, [Brw_ADMI_WRK_USR] = ActRemTreWrkUsr, [Brw_ADMI_WRK_CRS] = ActRemTreWrkCrs, [Brw_ADMI_MRK_CRS] = ActRemTreMrkCrs, [Brw_ADMI_BRF_USR] = ActRemTreBrf, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActRemTreDocGrp, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActRemTreMrkGrp, [Brw_ADMI_ASG_USR] = ActRemTreAsgUsr, [Brw_ADMI_ASG_CRS] = ActRemTreAsgCrs, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActRemTreDocDeg, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActRemTreDocCtr, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActRemTreDocIns, [Brw_ADMI_SHR_DEG] = ActRemTreShaDeg, [Brw_ADMI_SHR_CTR] = ActRemTreShaCtr, [Brw_ADMI_SHR_INS] = ActRemTreShaIns, [Brw_ADMI_TCH_CRS] = ActRemTreTchCrs, [Brw_ADMI_TCH_GRP] = ActRemTreTchGrp, [Brw_ADMI_DOC_PRJ] = ActRemTreDocPrj, [Brw_ADMI_ASS_PRJ] = ActRemTreAssPrj, }; static const Act_Action_t Brw_ActCopy[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActUnk, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActCopDocCrs, [Brw_ADMI_SHR_CRS] = ActCopShaCrs, [Brw_ADMI_SHR_GRP] = ActCopShaGrp, [Brw_ADMI_WRK_USR] = ActCopWrkUsr, [Brw_ADMI_WRK_CRS] = ActCopWrkCrs, [Brw_ADMI_MRK_CRS] = ActCopMrkCrs, [Brw_ADMI_BRF_USR] = ActCopBrf, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActCopDocGrp, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActCopMrkGrp, [Brw_ADMI_ASG_USR] = ActCopAsgUsr, [Brw_ADMI_ASG_CRS] = ActCopAsgCrs, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActCopDocDeg, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActCopDocCtr, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActCopDocIns, [Brw_ADMI_SHR_DEG] = ActCopShaDeg, [Brw_ADMI_SHR_CTR] = ActCopShaCtr, [Brw_ADMI_SHR_INS] = ActCopShaIns, [Brw_ADMI_TCH_CRS] = ActCopTchCrs, [Brw_ADMI_TCH_GRP] = ActCopTchGrp, [Brw_ADMI_DOC_PRJ] = ActCopDocPrj, [Brw_ADMI_ASS_PRJ] = ActCopAssPrj, }; static const Act_Action_t Brw_ActPaste[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActUnk, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActPasDocCrs, [Brw_ADMI_SHR_CRS] = ActPasShaCrs, [Brw_ADMI_SHR_GRP] = ActPasShaGrp, [Brw_ADMI_WRK_USR] = ActPasWrkUsr, [Brw_ADMI_WRK_CRS] = ActPasWrkCrs, [Brw_ADMI_MRK_CRS] = ActPasMrkCrs, [Brw_ADMI_BRF_USR] = ActPasBrf, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActPasDocGrp, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActPasMrkGrp, [Brw_ADMI_ASG_USR] = ActPasAsgUsr, [Brw_ADMI_ASG_CRS] = ActPasAsgCrs, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActPasDocDeg, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActPasDocCtr, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActPasDocIns, [Brw_ADMI_SHR_DEG] = ActPasShaDeg, [Brw_ADMI_SHR_CTR] = ActPasShaCtr, [Brw_ADMI_SHR_INS] = ActPasShaIns, [Brw_ADMI_TCH_CRS] = ActPasTchCrs, [Brw_ADMI_TCH_GRP] = ActPasTchGrp, [Brw_ADMI_DOC_PRJ] = ActPasDocPrj, [Brw_ADMI_ASS_PRJ] = ActPasAssPrj, }; static const Act_Action_t Brw_ActFormCreate[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActUnk, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActFrmCreDocCrs, [Brw_ADMI_SHR_CRS] = ActFrmCreShaCrs, [Brw_ADMI_SHR_GRP] = ActFrmCreShaGrp, [Brw_ADMI_WRK_USR] = ActFrmCreWrkUsr, [Brw_ADMI_WRK_CRS] = ActFrmCreWrkCrs, [Brw_ADMI_MRK_CRS] = ActFrmCreMrkCrs, [Brw_ADMI_BRF_USR] = ActFrmCreBrf, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActFrmCreDocGrp, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActFrmCreMrkGrp, [Brw_ADMI_ASG_USR] = ActFrmCreAsgUsr, [Brw_ADMI_ASG_CRS] = ActFrmCreAsgCrs, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActFrmCreDocDeg, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActFrmCreDocCtr, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActFrmCreDocIns, [Brw_ADMI_SHR_DEG] = ActFrmCreShaDeg, [Brw_ADMI_SHR_CTR] = ActFrmCreShaCtr, [Brw_ADMI_SHR_INS] = ActFrmCreShaIns, [Brw_ADMI_TCH_CRS] = ActFrmCreTchCrs, [Brw_ADMI_TCH_GRP] = ActFrmCreTchGrp, [Brw_ADMI_DOC_PRJ] = ActFrmCreDocPrj, [Brw_ADMI_ASS_PRJ] = ActFrmCreAssPrj, }; static const Act_Action_t Brw_ActCreateFolder[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActUnk, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActCreFolDocCrs, [Brw_ADMI_SHR_CRS] = ActCreFolShaCrs, [Brw_ADMI_SHR_GRP] = ActCreFolShaGrp, [Brw_ADMI_WRK_USR] = ActCreFolWrkUsr, [Brw_ADMI_WRK_CRS] = ActCreFolWrkCrs, [Brw_ADMI_MRK_CRS] = ActCreFolMrkCrs, [Brw_ADMI_BRF_USR] = ActCreFolBrf, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActCreFolDocGrp, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActCreFolMrkGrp, [Brw_ADMI_ASG_USR] = ActCreFolAsgUsr, [Brw_ADMI_ASG_CRS] = ActCreFolAsgCrs, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActCreFolDocDeg, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActCreFolDocCtr, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActCreFolDocIns, [Brw_ADMI_SHR_DEG] = ActCreFolShaDeg, [Brw_ADMI_SHR_CTR] = ActCreFolShaCtr, [Brw_ADMI_SHR_INS] = ActCreFolShaIns, [Brw_ADMI_TCH_CRS] = ActCreFolTchCrs, [Brw_ADMI_TCH_GRP] = ActCreFolTchGrp, [Brw_ADMI_DOC_PRJ] = ActCreFolDocPrj, [Brw_ADMI_ASS_PRJ] = ActCreFolAssPrj, }; static const Act_Action_t Brw_ActCreateLink[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActUnk, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActCreLnkDocCrs, [Brw_ADMI_SHR_CRS] = ActCreLnkShaCrs, [Brw_ADMI_SHR_GRP] = ActCreLnkShaGrp, [Brw_ADMI_WRK_USR] = ActCreLnkWrkUsr, [Brw_ADMI_WRK_CRS] = ActCreLnkWrkCrs, [Brw_ADMI_MRK_CRS] = ActUnk, [Brw_ADMI_BRF_USR] = ActCreLnkBrf, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActCreLnkDocGrp, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActUnk, [Brw_ADMI_ASG_USR] = ActCreLnkAsgUsr, [Brw_ADMI_ASG_CRS] = ActCreLnkAsgCrs, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActCreLnkDocDeg, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActCreLnkDocCtr, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActCreLnkDocIns, [Brw_ADMI_SHR_DEG] = ActCreLnkShaDeg, [Brw_ADMI_SHR_CTR] = ActCreLnkShaCtr, [Brw_ADMI_SHR_INS] = ActCreLnkShaIns, [Brw_ADMI_TCH_CRS] = ActCreLnkTchCrs, [Brw_ADMI_TCH_GRP] = ActCreLnkTchGrp, [Brw_ADMI_DOC_PRJ] = ActCreLnkDocPrj, [Brw_ADMI_ASS_PRJ] = ActCreLnkAssPrj, }; static const Act_Action_t Brw_ActRenameFolder[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActUnk, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActRenFolDocCrs, [Brw_ADMI_SHR_CRS] = ActRenFolShaCrs, [Brw_ADMI_SHR_GRP] = ActRenFolShaGrp, [Brw_ADMI_WRK_USR] = ActRenFolWrkUsr, [Brw_ADMI_WRK_CRS] = ActRenFolWrkCrs, [Brw_ADMI_MRK_CRS] = ActRenFolMrkCrs, [Brw_ADMI_BRF_USR] = ActRenFolBrf, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActRenFolDocGrp, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActRenFolMrkGrp, [Brw_ADMI_ASG_USR] = ActRenFolAsgUsr, [Brw_ADMI_ASG_CRS] = ActRenFolAsgCrs, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActRenFolDocDeg, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActRenFolDocCtr, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActRenFolDocIns, [Brw_ADMI_SHR_DEG] = ActRenFolShaDeg, [Brw_ADMI_SHR_CTR] = ActRenFolShaCtr, [Brw_ADMI_SHR_INS] = ActRenFolShaIns, [Brw_ADMI_TCH_CRS] = ActRenFolTchCrs, [Brw_ADMI_TCH_GRP] = ActRenFolTchGrp, [Brw_ADMI_DOC_PRJ] = ActRenFolDocPrj, [Brw_ADMI_ASS_PRJ] = ActRenFolAssPrj, }; static const Act_Action_t Brw_ActUploadFileDropzone[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActUnk, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActRcvFilDocCrsDZ, [Brw_ADMI_SHR_CRS] = ActRcvFilShaCrsDZ, [Brw_ADMI_SHR_GRP] = ActRcvFilShaGrpDZ, [Brw_ADMI_WRK_USR] = ActRcvFilWrkUsrDZ, [Brw_ADMI_WRK_CRS] = ActRcvFilWrkCrsDZ, [Brw_ADMI_MRK_CRS] = ActRcvFilMrkCrsDZ, [Brw_ADMI_BRF_USR] = ActRcvFilBrfDZ, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActRcvFilDocGrpDZ, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActRcvFilMrkGrpDZ, [Brw_ADMI_ASG_USR] = ActRcvFilAsgUsrDZ, [Brw_ADMI_ASG_CRS] = ActRcvFilAsgCrsDZ, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActRcvFilDocDegDZ, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActRcvFilDocCtrDZ, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActRcvFilDocInsDZ, [Brw_ADMI_SHR_DEG] = ActRcvFilShaDegDZ, [Brw_ADMI_SHR_CTR] = ActRcvFilShaCtrDZ, [Brw_ADMI_SHR_INS] = ActRcvFilShaInsDZ, [Brw_ADMI_TCH_CRS] = ActRcvFilTchCrsDZ, [Brw_ADMI_TCH_GRP] = ActRcvFilTchGrpDZ, [Brw_ADMI_DOC_PRJ] = ActRcvFilDocPrjDZ, [Brw_ADMI_ASS_PRJ] = ActRcvFilAssPrjDZ, }; static const Act_Action_t Brw_ActUploadFileClassic[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActUnk, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActRcvFilDocCrsCla, [Brw_ADMI_SHR_CRS] = ActRcvFilShaCrsCla, [Brw_ADMI_SHR_GRP] = ActRcvFilShaGrpCla, [Brw_ADMI_WRK_USR] = ActRcvFilWrkUsrCla, [Brw_ADMI_WRK_CRS] = ActRcvFilWrkCrsCla, [Brw_ADMI_MRK_CRS] = ActRcvFilMrkCrsCla, [Brw_ADMI_BRF_USR] = ActRcvFilBrfCla, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActRcvFilDocGrpCla, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActRcvFilMrkGrpCla, [Brw_ADMI_ASG_USR] = ActRcvFilAsgUsrCla, [Brw_ADMI_ASG_CRS] = ActRcvFilAsgCrsCla, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActRcvFilDocDegCla, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActRcvFilDocCtrCla, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActRcvFilDocInsCla, [Brw_ADMI_SHR_DEG] = ActRcvFilShaDegCla, [Brw_ADMI_SHR_CTR] = ActRcvFilShaCtrCla, [Brw_ADMI_SHR_INS] = ActRcvFilShaInsCla, [Brw_ADMI_TCH_CRS] = ActRcvFilTchCrsCla, [Brw_ADMI_TCH_GRP] = ActRcvFilTchGrpCla, [Brw_ADMI_DOC_PRJ] = ActRcvFilDocPrjCla, [Brw_ADMI_ASS_PRJ] = ActRcvFilAssPrjCla, }; static const Act_Action_t Brw_ActRefreshAfterUploadFiles[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActUnk, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActAdmDocCrs, [Brw_ADMI_SHR_CRS] = ActAdmShaCrs, [Brw_ADMI_SHR_GRP] = ActAdmShaGrp, [Brw_ADMI_WRK_USR] = ActAdmAsgWrkUsr, [Brw_ADMI_WRK_CRS] = ActAdmAsgWrkCrs, [Brw_ADMI_MRK_CRS] = ActAdmMrkCrs, [Brw_ADMI_BRF_USR] = ActAdmBrf, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActAdmDocGrp, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActAdmMrkGrp, [Brw_ADMI_ASG_USR] = ActAdmAsgWrkUsr, [Brw_ADMI_ASG_CRS] = ActAdmAsgWrkCrs, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActAdmDocDeg, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActAdmDocCtr, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActAdmDocIns, [Brw_ADMI_SHR_DEG] = ActAdmShaDeg, [Brw_ADMI_SHR_CTR] = ActAdmShaCtr, [Brw_ADMI_SHR_INS] = ActAdmShaIns, [Brw_ADMI_TCH_CRS] = ActAdmTchCrs, [Brw_ADMI_TCH_GRP] = ActAdmTchGrp, [Brw_ADMI_DOC_PRJ] = ActAdmDocPrj, [Brw_ADMI_ASS_PRJ] = ActAdmAssPrj, }; static const Act_Action_t Brw_ActExpandFolder[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActExpSeeDocCrs, [Brw_SHOW_MRK_CRS] = ActExpSeeMrkCrs, [Brw_ADMI_DOC_CRS] = ActExpAdmDocCrs, [Brw_ADMI_SHR_CRS] = ActExpShaCrs, [Brw_ADMI_SHR_GRP] = ActExpShaGrp, [Brw_ADMI_WRK_USR] = ActExpWrkUsr, [Brw_ADMI_WRK_CRS] = ActExpWrkCrs, [Brw_ADMI_MRK_CRS] = ActExpAdmMrkCrs, [Brw_ADMI_BRF_USR] = ActExpBrf, [Brw_SHOW_DOC_GRP] = ActExpSeeDocGrp, [Brw_ADMI_DOC_GRP] = ActExpAdmDocGrp, [Brw_SHOW_MRK_GRP] = ActExpSeeMrkGrp, [Brw_ADMI_MRK_GRP] = ActExpAdmMrkGrp, [Brw_ADMI_ASG_USR] = ActExpAsgUsr, [Brw_ADMI_ASG_CRS] = ActExpAsgCrs, [Brw_SHOW_DOC_DEG] = ActExpSeeDocDeg, [Brw_ADMI_DOC_DEG] = ActExpAdmDocDeg, [Brw_SHOW_DOC_CTR] = ActExpSeeDocCtr, [Brw_ADMI_DOC_CTR] = ActExpAdmDocCtr, [Brw_SHOW_DOC_INS] = ActExpSeeDocIns, [Brw_ADMI_DOC_INS] = ActExpAdmDocIns, [Brw_ADMI_SHR_DEG] = ActExpShaDeg, [Brw_ADMI_SHR_CTR] = ActExpShaCtr, [Brw_ADMI_SHR_INS] = ActExpShaIns, [Brw_ADMI_TCH_CRS] = ActExpTchCrs, [Brw_ADMI_TCH_GRP] = ActExpTchGrp, [Brw_ADMI_DOC_PRJ] = ActExpDocPrj, [Brw_ADMI_ASS_PRJ] = ActExpAssPrj, }; static const Act_Action_t Brw_ActContractFolder[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActConSeeDocCrs, [Brw_SHOW_MRK_CRS] = ActConSeeMrkCrs, [Brw_ADMI_DOC_CRS] = ActConAdmDocCrs, [Brw_ADMI_SHR_CRS] = ActConShaCrs, [Brw_ADMI_SHR_GRP] = ActConShaGrp, [Brw_ADMI_WRK_USR] = ActConWrkUsr, [Brw_ADMI_WRK_CRS] = ActConWrkCrs, [Brw_ADMI_MRK_CRS] = ActConAdmMrkCrs, [Brw_ADMI_BRF_USR] = ActConBrf, [Brw_SHOW_DOC_GRP] = ActConSeeDocGrp, [Brw_ADMI_DOC_GRP] = ActConAdmDocGrp, [Brw_SHOW_MRK_GRP] = ActConSeeMrkGrp, [Brw_ADMI_MRK_GRP] = ActConAdmMrkGrp, [Brw_ADMI_ASG_USR] = ActConAsgUsr, [Brw_ADMI_ASG_CRS] = ActConAsgCrs, [Brw_SHOW_DOC_DEG] = ActConSeeDocDeg, [Brw_ADMI_DOC_DEG] = ActConAdmDocDeg, [Brw_SHOW_DOC_CTR] = ActConSeeDocCtr, [Brw_ADMI_DOC_CTR] = ActConAdmDocCtr, [Brw_SHOW_DOC_INS] = ActConSeeDocIns, [Brw_ADMI_DOC_INS] = ActConAdmDocIns, [Brw_ADMI_SHR_DEG] = ActConShaDeg, [Brw_ADMI_SHR_CTR] = ActConShaCtr, [Brw_ADMI_SHR_INS] = ActConShaIns, [Brw_ADMI_TCH_CRS] = ActConTchCrs, [Brw_ADMI_TCH_GRP] = ActConTchGrp, [Brw_ADMI_DOC_PRJ] = ActConDocPrj, [Brw_ADMI_ASS_PRJ] = ActConAssPrj, }; static const Act_Action_t Brw_ActRecDatFile[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActUnk, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActChgDatAdmDocCrs, [Brw_ADMI_SHR_CRS] = ActChgDatShaCrs, [Brw_ADMI_SHR_GRP] = ActChgDatShaGrp, [Brw_ADMI_WRK_USR] = ActChgDatWrkUsr, [Brw_ADMI_WRK_CRS] = ActChgDatWrkCrs, [Brw_ADMI_MRK_CRS] = ActChgDatAdmMrkCrs, [Brw_ADMI_BRF_USR] = ActChgDatBrf, [Brw_SHOW_DOC_GRP] = ActUnk, [Brw_ADMI_DOC_GRP] = ActChgDatAdmDocGrp, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActChgDatAdmMrkGrp, [Brw_ADMI_ASG_USR] = ActChgDatAsgUsr, [Brw_ADMI_ASG_CRS] = ActChgDatAsgCrs, [Brw_SHOW_DOC_DEG] = ActUnk, [Brw_ADMI_DOC_DEG] = ActChgDatAdmDocDeg, [Brw_SHOW_DOC_CTR] = ActUnk, [Brw_ADMI_DOC_CTR] = ActChgDatAdmDocCtr, [Brw_SHOW_DOC_INS] = ActUnk, [Brw_ADMI_DOC_INS] = ActChgDatAdmDocIns, [Brw_ADMI_SHR_DEG] = ActChgDatShaDeg, [Brw_ADMI_SHR_CTR] = ActChgDatShaCtr, [Brw_ADMI_SHR_INS] = ActChgDatShaIns, [Brw_ADMI_TCH_CRS] = ActChgDatTchCrs, [Brw_ADMI_TCH_GRP] = ActChgDatTchGrp, [Brw_ADMI_DOC_PRJ] = ActChgDatDocPrj, [Brw_ADMI_ASS_PRJ] = ActChgDatAssPrj, }; static const Act_Action_t Brw_ActZIPFolder[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = ActUnk, [Brw_SHOW_DOC_CRS] = ActZIPSeeDocCrs, [Brw_SHOW_MRK_CRS] = ActUnk, [Brw_ADMI_DOC_CRS] = ActZIPAdmDocCrs, [Brw_ADMI_SHR_CRS] = ActZIPShaCrs, [Brw_ADMI_SHR_GRP] = ActZIPShaGrp, [Brw_ADMI_WRK_USR] = ActZIPWrkUsr, [Brw_ADMI_WRK_CRS] = ActZIPWrkCrs, [Brw_ADMI_MRK_CRS] = ActZIPAdmMrkCrs, [Brw_ADMI_BRF_USR] = ActZIPBrf, [Brw_SHOW_DOC_GRP] = ActZIPSeeDocGrp, [Brw_ADMI_DOC_GRP] = ActZIPAdmDocGrp, [Brw_SHOW_MRK_GRP] = ActUnk, [Brw_ADMI_MRK_GRP] = ActZIPAdmMrkGrp, [Brw_ADMI_ASG_USR] = ActZIPAsgUsr, [Brw_ADMI_ASG_CRS] = ActZIPAsgCrs, [Brw_SHOW_DOC_DEG] = ActZIPSeeDocDeg, [Brw_ADMI_DOC_DEG] = ActZIPAdmDocDeg, [Brw_SHOW_DOC_CTR] = ActZIPSeeDocCtr, [Brw_ADMI_DOC_CTR] = ActZIPAdmDocCtr, [Brw_SHOW_DOC_INS] = ActZIPSeeDocIns, [Brw_ADMI_DOC_INS] = ActZIPAdmDocIns, [Brw_ADMI_SHR_DEG] = ActZIPShaDeg, [Brw_ADMI_SHR_CTR] = ActZIPShaCtr, [Brw_ADMI_SHR_INS] = ActZIPShaIns, [Brw_ADMI_TCH_CRS] = ActZIPTchCrs, [Brw_ADMI_TCH_GRP] = ActZIPTchGrp, [Brw_ADMI_DOC_PRJ] = ActZIPDocPrj, [Brw_ADMI_ASS_PRJ] = ActZIPAssPrj, }; /*****************************************************************************/ /***************************** Private variables *****************************/ /*****************************************************************************/ bool Brw_ICanEditFileOrFolder; // Can I modify (remove, rename, create inside, etc.) a file or folder? /*****************************************************************************/ /**************************** Private prototypes *****************************/ /*****************************************************************************/ static long Brw_GetGrpSettings (void); static void Brw_GetDataCurrentGrp (void); static void Brw_GetParsPathInTreeAndFileName (void); static void Brw_SetPathFileBrowser (void); static void Brw_CreateFoldersAssignmentsIfNotExist (long ZoneUsrCod); static void Brw_AskEditWorksCrsInternal (__attribute__((unused)) void *Args); static void Brw_ShowFileBrowserNormal (void); static void Brw_ShowFileBrowsersAsgWrkCrs (void); static void Brw_ShowFileBrowsersAsgWrkUsr (void); static void Brw_FormToChangeCrsGrpZone (void); static void Brw_GetSelectedGroupData (struct GroupData *GrpDat,bool AbortOnError); static void Brw_ShowDataOwnerAsgWrk (struct Usr_Data *UsrDat); static void Brw_ShowFileBrowserOrWorksInternal (__attribute__((unused)) void *Args); static void Brw_ShowFileBrowser (void); static void Brw_PutIconsFileBrowser (__attribute__((unused)) void *Args); static void Brw_PutIconShowFigure (__attribute__((unused)) void *Args); static void Brw_PutButtonToShowEdit (void); static void Brw_WriteTopBeforeShowingFileBrowser (void); static void Brw_UpdateLastAccess (void); static void Brw_WriteSubtitleOfFileBrowser (void); static void Brw_InitHiddenLevels (void); static void Brw_PutCheckboxFullTree (void); static void Brw_PutParsFullTree (void); static bool Brw_GetFullTreeFromForm (void); static bool Brw_GetIfGroupFileBrowser (void); static bool Brw_GetIfProjectFileBrowser (void); static bool Brw_GetIfBriefcaseFileBrowser (void); static bool Brw_GetIfUsrAssigWorksFileBrowser (void); static bool Brw_GetIfCrsAssigWorksFileBrowser (void); static void Brw_GetAndUpdateDateLastAccFileBrowser (void); static long Brw_GetGrpLastAccZone (const char *FieldNameDB); static void Brw_ListDir (unsigned Level,const char *RowId, bool TreeContracted, const char Path[PATH_MAX + 1], const char PathInTree[PATH_MAX + 1]); static bool Brw_WriteRowFileBrowser (unsigned Level,const char *RowId, bool TreeContracted, Brw_IconTree_t IconThisRow); static bool Brw_CheckIfCanPasteIn (unsigned Level); static void Brw_PutIconRemove (void); static void Brw_PutIconCopy (void); static void Brw_PutIconPaste (unsigned Level); static void Brw_IndentAndWriteIconExpandContract (unsigned Level, const char *FileBrowserId,const char *RowId, Brw_IconTree_t IconThisRow); static void Brw_IndentDependingOnLevel (unsigned Level); static void Brw_PutIconToExpandFolder (const char *FileBrowserId,const char *RowId, bool Hidden); static void Brw_PutIconToContractFolder (const char *FileBrowserId,const char *RowId, bool Hidden); static void Brw_PutIconHideUnhide (const char *Anchor,bool RowSetAsHidden); static bool Brw_CheckIfAnyHigherLevelIsHidden (unsigned CurrentLevel); static void Brw_PutIconFolder (unsigned Level, const char *FileBrowserId,const char *RowId, Brw_IconTree_t IconSubtree); static void Brw_PutIconFolderWithoutPlus (const char *FileBrowserId,const char *RowId, bool Open,bool Hidden); static void Brw_PutIconFolderWithPlus (const char *FileBrowserId,const char *RowId, bool Open,bool Hidden); static void Brw_PutIconNewFileOrFolder (void); static void Brw_PutIconFileWithLinkToViewMetadata (const struct Brw_FileMetadata *FileMetadata); static void Brw_PutButtonToDownloadZIPOfAFolder (void); static void Brw_WriteFileName (unsigned Level,bool IsPublic); static void Brw_GetFileNameToShowDependingOnLevel (Brw_FileBrowser_t FileBrowser, unsigned Level, Brw_FileType_t FileType, const char *FileName, char *FileNameToShow); static void Brw_GetFileNameToShow (Brw_FileType_t FileType, const char FileName[NAME_MAX + 1], char FileNameToShow[NAME_MAX + 1]); static void Brw_WriteDatesAssignment (void); static void Brw_WriteFileSizeAndDate (struct Brw_FileMetadata *FileMetadata); static void Brw_WriteFileOrFolderPublisher (unsigned Level,long UsrCod); static void Brw_AskConfirmRemoveFolderNotEmpty (void); static void Brw_WriteCurrentClipboard (void); static bool Brw_GetMyClipboard (void); static bool Brw_CheckIfClipboardIsInThisTree (void); static void Brw_InsFoldersInPathAndUpdOtherFoldersInExpandedFolders (const char Path[PATH_MAX + 1]); static void Brw_RemThisFolderAndUpdOtherFoldersFromExpandedFolders (const char Path[PATH_MAX + 1]); static void Brw_PasteClipboard (struct BrwSiz_BrowserSize *Size); static unsigned Brw_NumLevelsInPath (const char Path[PATH_MAX + 1]); static bool Brw_PasteTreeIntoFolder (struct BrwSiz_BrowserSize *Size, unsigned LevelOrg, const char PathOrg[PATH_MAX + 1], const char PathDstInTree[PATH_MAX + 1], struct Brw_NumObjects *Pasted, long *FirstFilCod); static void Brw_PutFormToCreateAFolder (const char FileNameToShow[NAME_MAX + 1]); static void Brw_PutFormToUploadFilesUsingDropzone (const char *FileNameToShow); static void Brw_PutFormToUploadOneFileClassic (const char *FileNameToShow); static void Brw_PutFormToPasteAFileOrFolder (const char *FileNameToShow); static void Brw_PutFormToCreateALink (const char *FileNameToShow); static bool Brw_RcvFileInFileBrw (struct BrwSiz_BrowserSize *Size, Brw_UploadType_t UploadType); static bool Brw_CheckIfUploadIsAllowed (const char *FileType); static void Brw_PutIconToGetLinkToFile (void *FileMetadata); static void Brw_PutParsToGetLinkToFile (void *FileMetadata); static bool Brw_CheckIfICanEditFileMetadata (long IAmTheOwner); static bool Brw_CheckIfIAmOwnerOfFile (long PublisherUsrCod); static void Brw_WriteBigLinkToDownloadFile (const char *URL, struct Brw_FileMetadata *FileMetadata, const char *FileNameToShow); static void Brw_WriteSmallLinkToDownloadFile (const char *URL, struct Brw_FileMetadata *FileMetadata, const char *FileNameToShow); static bool Brw_GetParPublicFile (void); static Brw_License_t Brw_GetParLicense (void); static void Brw_ResetFileMetadata (struct Brw_FileMetadata *FileMetadata); static void Brw_GetFileMetadataFromRow (MYSQL_RES *mysql_res, struct Brw_FileMetadata *FileMetadata); static void Brw_GetFileViewsFromLoggedUsrs (struct Brw_FileMetadata *FileMetadata); static unsigned Brw_GetFileViewsFromMe (long FilCod); static void Brw_RemoveOneFileOrFolderFromDB (const char Path[PATH_MAX + 1]); static void Brw_RemoveChildrenOfFolderFromDB (const char Path[PATH_MAX + 1]); static void Brw_SetIfICanEditFileOrFolder (bool Value); static bool Brw_GetIfICanEditFileOrFolder (void); static bool Brw_CheckIfICanEditFileOrFolder (unsigned Level); static bool Brw_CheckIfICanCreateIntoFolder (unsigned Level); static bool Brw_CheckIfICanModifySharedFileOrFolder (void); static bool Brw_CheckIfICanModifyPrivateFileOrFolder (void); static bool Brw_CheckIfICanModifyPrjDocFileOrFolder (void); static bool Brw_CheckIfICanModifyPrjAssFileOrFolder (void); static void Brw_WriteRowDocData (unsigned *NumDocsNotHidden,MYSQL_ROW row); static void Brw_PutLinkToAskRemOldFiles (void); static void Brw_RemoveOldFilesInBrowser (unsigned Months,struct Brw_NumObjects *Removed); static void Brw_ScanDirRemovingOldFiles (unsigned Level, const char Path[PATH_MAX + 1], const char PathInTree[PATH_MAX + 1], time_t TimeRemoveFilesOlder, struct Brw_NumObjects *Removed); static void Brw_RemoveFileFromDiskAndDB (const char Path[PATH_MAX + 1], const char FullPathInTree[PATH_MAX + 1]); static int Brw_RemoveFolderFromDiskAndDB (const char Path[PATH_MAX + 1], const char FullPathInTree[PATH_MAX + 1]); static void Brw_WriteStatsFileZonesTableHead1 (void); static void Brw_WriteStatsFileZonesTableHead2 (void); static void Brw_WriteStatsFileZonesTableHead3 (void); static void Brw_WriteRowStatsFileBrowsers1 (const char *NameOfFileZones, Brw_FileBrowser_t FileZone, struct BrwSiz_SizeOfFileZone *SizeOfFileZone); static void Brw_WriteRowStatsFileBrowsers2 (const char *NameOfFileZones, Brw_FileBrowser_t FileZone, struct BrwSiz_SizeOfFileZone *SizeOfFileZone); static void Brw_WriteRowStatsFileBrowsers3 (const char *NameOfFileZones, Brw_FileBrowser_t FileZone, struct BrwSiz_SizeOfFileZone *SizeOfFileZone); static void Brw_GetNumberOfOERs (Brw_License_t License, unsigned long NumFiles[2]); /*****************************************************************************/ /***************** Get parameters related to file browser ********************/ /*****************************************************************************/ void Brw_GetParAndInitFileBrowser (void) { /***** If a group is selected, get its data *****/ if ((Gbl.Crs.Grps.GrpCod = Brw_GetGrpSettings ()) > 0) Brw_GetDataCurrentGrp (); /***** Get type of file browser *****/ switch (Gbl.Action.Act) { /***** Documents of institution *****/ case ActSeeAdmDocIns: // Access to a documents zone from menu case ActChgToSeeDocIns: // Access to see a documents zone case ActSeeDocIns: case ActExpSeeDocIns: case ActConSeeDocIns: case ActZIPSeeDocIns: case ActReqDatSeeDocIns: case ActDowSeeDocIns: Gbl.FileBrowser.Type = Brw_SHOW_DOC_INS; break; case ActChgToAdmDocIns: // Access to admin a documents zone case ActAdmDocIns: case ActReqRemFilDocIns: case ActRemFilDocIns: case ActRemFolDocIns: case ActCopDocIns: case ActPasDocIns: case ActRemTreDocIns: case ActFrmCreDocIns: case ActCreFolDocIns: case ActCreLnkDocIns: case ActRenFolDocIns: case ActRcvFilDocInsDZ: case ActRcvFilDocInsCla: case ActExpAdmDocIns: case ActConAdmDocIns: case ActZIPAdmDocIns: case ActUnhDocIns: case ActHidDocIns: case ActReqDatAdmDocIns: case ActChgDatAdmDocIns: case ActDowAdmDocIns: Gbl.FileBrowser.Type = Brw_ADMI_DOC_INS; break; /***** Shared files of institution *****/ case ActAdmShaIns: case ActReqRemFilShaIns: case ActRemFilShaIns: case ActRemFolShaIns: case ActCopShaIns: case ActPasShaIns: case ActRemTreShaIns: case ActFrmCreShaIns: case ActCreFolShaIns: case ActCreLnkShaIns: case ActRenFolShaIns: case ActRcvFilShaInsDZ: case ActRcvFilShaInsCla: case ActExpShaIns: case ActConShaIns: case ActZIPShaIns: case ActReqDatShaIns: case ActChgDatShaIns: case ActDowShaIns: Gbl.FileBrowser.Type = Brw_ADMI_SHR_INS; break; /***** Documents of center *****/ case ActSeeAdmDocCtr: // Access to a documents zone from menu case ActChgToSeeDocCtr: // Access to see a documents zone case ActSeeDocCtr: case ActExpSeeDocCtr: case ActConSeeDocCtr: case ActZIPSeeDocCtr: case ActReqDatSeeDocCtr: case ActDowSeeDocCtr: Gbl.FileBrowser.Type = Brw_SHOW_DOC_CTR; break; case ActChgToAdmDocCtr: // Access to admin a documents zone case ActAdmDocCtr: case ActReqRemFilDocCtr: case ActRemFilDocCtr: case ActRemFolDocCtr: case ActCopDocCtr: case ActPasDocCtr: case ActRemTreDocCtr: case ActFrmCreDocCtr: case ActCreFolDocCtr: case ActCreLnkDocCtr: case ActRenFolDocCtr: case ActRcvFilDocCtrDZ: case ActRcvFilDocCtrCla: case ActExpAdmDocCtr: case ActConAdmDocCtr: case ActZIPAdmDocCtr: case ActUnhDocCtr: case ActHidDocCtr: case ActReqDatAdmDocCtr: case ActChgDatAdmDocCtr: case ActDowAdmDocCtr: Gbl.FileBrowser.Type = Brw_ADMI_DOC_CTR; break; /***** Shared files of center *****/ case ActAdmShaCtr: case ActReqRemFilShaCtr: case ActRemFilShaCtr: case ActRemFolShaCtr: case ActCopShaCtr: case ActPasShaCtr: case ActRemTreShaCtr: case ActFrmCreShaCtr: case ActCreFolShaCtr: case ActCreLnkShaCtr: case ActRenFolShaCtr: case ActRcvFilShaCtrDZ: case ActRcvFilShaCtrCla: case ActExpShaCtr: case ActConShaCtr: case ActZIPShaCtr: case ActReqDatShaCtr: case ActChgDatShaCtr: case ActDowShaCtr: Gbl.FileBrowser.Type = Brw_ADMI_SHR_CTR; break; /***** Documents of degree *****/ case ActSeeAdmDocDeg: // Access to a documents zone from menu case ActChgToSeeDocDeg: // Access to see a documents zone case ActSeeDocDeg: case ActExpSeeDocDeg: case ActConSeeDocDeg: case ActZIPSeeDocDeg: case ActReqDatSeeDocDeg: case ActDowSeeDocDeg: Gbl.FileBrowser.Type = Brw_SHOW_DOC_DEG; break; case ActChgToAdmDocDeg: // Access to admin a documents zone case ActAdmDocDeg: case ActReqRemFilDocDeg: case ActRemFilDocDeg: case ActRemFolDocDeg: case ActCopDocDeg: case ActPasDocDeg: case ActRemTreDocDeg: case ActFrmCreDocDeg: case ActCreFolDocDeg: case ActCreLnkDocDeg: case ActRenFolDocDeg: case ActRcvFilDocDegDZ: case ActRcvFilDocDegCla: case ActExpAdmDocDeg: case ActConAdmDocDeg: case ActZIPAdmDocDeg: case ActUnhDocDeg: case ActHidDocDeg: case ActReqDatAdmDocDeg: case ActChgDatAdmDocDeg: case ActDowAdmDocDeg: Gbl.FileBrowser.Type = Brw_ADMI_DOC_DEG; break; /***** Shared files of degree *****/ case ActAdmShaDeg: case ActReqRemFilShaDeg: case ActRemFilShaDeg: case ActRemFolShaDeg: case ActCopShaDeg: case ActPasShaDeg: case ActRemTreShaDeg: case ActFrmCreShaDeg: case ActCreFolShaDeg: case ActCreLnkShaDeg: case ActRenFolShaDeg: case ActRcvFilShaDegDZ: case ActRcvFilShaDegCla: case ActExpShaDeg: case ActConShaDeg: case ActZIPShaDeg: case ActReqDatShaDeg: case ActChgDatShaDeg: case ActDowShaDeg: Gbl.FileBrowser.Type = Brw_ADMI_SHR_DEG; break; /***** Documents of course/group *****/ case ActSeeAdmDocCrsGrp: // Access to a documents zone from menu case ActChgToSeeDocCrs: // Access to see a documents zone /* Set file browser type acording to last group accessed */ Gbl.FileBrowser.Type = (Gbl.Crs.Grps.GrpCod > 0) ? Brw_SHOW_DOC_GRP : Brw_SHOW_DOC_CRS; break; case ActSeeDocCrs: case ActExpSeeDocCrs: case ActConSeeDocCrs: case ActZIPSeeDocCrs: case ActReqDatSeeDocCrs: case ActReqLnkSeeDocCrs: case ActDowSeeDocCrs: Gbl.FileBrowser.Type = Brw_SHOW_DOC_CRS; break; case ActSeeDocGrp: case ActExpSeeDocGrp: case ActConSeeDocGrp: case ActZIPSeeDocGrp: case ActReqDatSeeDocGrp: case ActDowSeeDocGrp: Gbl.FileBrowser.Type = Brw_SHOW_DOC_GRP; break; case ActChgToAdmDocCrs: // Access to admin a documents zone /* Set file browser type acording to last group accessed */ Gbl.FileBrowser.Type = (Gbl.Crs.Grps.GrpCod > 0) ? Brw_ADMI_DOC_GRP : Brw_ADMI_DOC_CRS; break; case ActAdmDocCrs: case ActReqRemFilDocCrs: case ActRemFilDocCrs: case ActRemFolDocCrs: case ActCopDocCrs: case ActPasDocCrs: case ActRemTreDocCrs: case ActFrmCreDocCrs: case ActCreFolDocCrs: case ActCreLnkDocCrs: case ActRenFolDocCrs: case ActRcvFilDocCrsDZ: case ActRcvFilDocCrsCla: case ActExpAdmDocCrs: case ActConAdmDocCrs: case ActZIPAdmDocCrs: case ActUnhDocCrs: case ActHidDocCrs: case ActReqDatAdmDocCrs: case ActChgDatAdmDocCrs: case ActReqLnkAdmDocCrs: case ActDowAdmDocCrs: Gbl.FileBrowser.Type = Brw_ADMI_DOC_CRS; break; case ActAdmDocGrp: case ActReqRemFilDocGrp: case ActRemFilDocGrp: case ActRemFolDocGrp: case ActCopDocGrp: case ActPasDocGrp: case ActRemTreDocGrp: case ActFrmCreDocGrp: case ActCreFolDocGrp: case ActCreLnkDocGrp: case ActRenFolDocGrp: case ActRcvFilDocGrpDZ: case ActRcvFilDocGrpCla: case ActExpAdmDocGrp: case ActConAdmDocGrp: case ActZIPAdmDocGrp: case ActUnhDocGrp: case ActHidDocGrp: case ActReqDatAdmDocGrp: case ActChgDatAdmDocGrp: case ActDowAdmDocGrp: Gbl.FileBrowser.Type = Brw_ADMI_DOC_GRP; break; /***** Teachers' private files of course/group *****/ case ActAdmTchCrsGrp: case ActChgToAdmTch: // Access to a teachers zone from menu /* Set file browser type acording to last group accessed */ Gbl.FileBrowser.Type = (Gbl.Crs.Grps.GrpCod > 0) ? Brw_ADMI_TCH_GRP : Brw_ADMI_TCH_CRS; break; case ActAdmTchCrs: case ActReqRemFilTchCrs: case ActRemFilTchCrs: case ActRemFolTchCrs: case ActCopTchCrs: case ActPasTchCrs: case ActRemTreTchCrs: case ActFrmCreTchCrs: case ActCreFolTchCrs: case ActCreLnkTchCrs: case ActRenFolTchCrs: case ActRcvFilTchCrsDZ: case ActRcvFilTchCrsCla: case ActExpTchCrs: case ActConTchCrs: case ActZIPTchCrs: case ActReqDatTchCrs: case ActChgDatTchCrs: case ActDowTchCrs: Gbl.FileBrowser.Type = Brw_ADMI_TCH_CRS; break; case ActAdmTchGrp: case ActReqRemFilTchGrp: case ActRemFilTchGrp: case ActRemFolTchGrp: case ActCopTchGrp: case ActPasTchGrp: case ActRemTreTchGrp: case ActFrmCreTchGrp: case ActCreFolTchGrp: case ActCreLnkTchGrp: case ActRenFolTchGrp: case ActRcvFilTchGrpDZ: case ActRcvFilTchGrpCla: case ActExpTchGrp: case ActConTchGrp: case ActZIPTchGrp: case ActReqDatTchGrp: case ActChgDatTchGrp: case ActDowTchGrp: Gbl.FileBrowser.Type = Brw_ADMI_TCH_GRP; break; /***** Shared files of course/group *****/ case ActAdmShaCrsGrp: case ActChgToAdmSha: // Access to a shared zone from menu /* Set file browser type acording to last group accessed */ Gbl.FileBrowser.Type = (Gbl.Crs.Grps.GrpCod > 0) ? Brw_ADMI_SHR_GRP : Brw_ADMI_SHR_CRS; break; case ActAdmShaCrs: case ActReqRemFilShaCrs: case ActRemFilShaCrs: case ActRemFolShaCrs: case ActCopShaCrs: case ActPasShaCrs: case ActRemTreShaCrs: case ActFrmCreShaCrs: case ActCreFolShaCrs: case ActCreLnkShaCrs: case ActRenFolShaCrs: case ActRcvFilShaCrsDZ: case ActRcvFilShaCrsCla: case ActExpShaCrs: case ActConShaCrs: case ActZIPShaCrs: case ActReqDatShaCrs: case ActChgDatShaCrs: case ActDowShaCrs: Gbl.FileBrowser.Type = Brw_ADMI_SHR_CRS; break; case ActAdmShaGrp: case ActReqRemFilShaGrp: case ActRemFilShaGrp: case ActRemFolShaGrp: case ActCopShaGrp: case ActPasShaGrp: case ActRemTreShaGrp: case ActFrmCreShaGrp: case ActCreFolShaGrp: case ActCreLnkShaGrp: case ActRenFolShaGrp: case ActRcvFilShaGrpDZ: case ActRcvFilShaGrpCla: case ActExpShaGrp: case ActConShaGrp: case ActZIPShaGrp: case ActReqDatShaGrp: case ActChgDatShaGrp: case ActDowShaGrp: Gbl.FileBrowser.Type = Brw_ADMI_SHR_GRP; break; /***** My assignments *****/ case ActReqRemFilAsgUsr: case ActRemFilAsgUsr: case ActRemFolAsgUsr: case ActCopAsgUsr: case ActPasAsgUsr: case ActRemTreAsgUsr: case ActFrmCreAsgUsr: case ActCreFolAsgUsr: case ActCreLnkAsgUsr: case ActRenFolAsgUsr: case ActRcvFilAsgUsrDZ: case ActRcvFilAsgUsrCla: case ActExpAsgUsr: case ActConAsgUsr: case ActZIPAsgUsr: case ActReqDatAsgUsr: case ActChgDatAsgUsr: case ActDowAsgUsr: Gbl.FileBrowser.Type = Brw_ADMI_ASG_USR; break; /***** Another users' assignments *****/ case ActAdmAsgWrkCrs: case ActReqRemFilAsgCrs: case ActRemFilAsgCrs: case ActRemFolAsgCrs: case ActCopAsgCrs: case ActPasAsgCrs: case ActRemTreAsgCrs: case ActFrmCreAsgCrs: case ActCreFolAsgCrs: case ActCreLnkAsgCrs: case ActRenFolAsgCrs: case ActRcvFilAsgCrsDZ: case ActRcvFilAsgCrsCla: case ActExpAsgCrs: case ActConAsgCrs: case ActZIPAsgCrs: case ActReqDatAsgCrs: case ActChgDatAsgCrs: case ActDowAsgCrs: Gbl.FileBrowser.Type = Brw_ADMI_ASG_CRS; break; /***** My works *****/ case ActAdmAsgWrkUsr: case ActReqRemFilWrkUsr: case ActRemFilWrkUsr: case ActRemFolWrkUsr: case ActCopWrkUsr: case ActPasWrkUsr: case ActRemTreWrkUsr: case ActFrmCreWrkUsr: case ActCreFolWrkUsr: case ActCreLnkWrkUsr: case ActRenFolWrkUsr: case ActRcvFilWrkUsrDZ: case ActRcvFilWrkUsrCla: case ActExpWrkUsr: case ActConWrkUsr: case ActZIPWrkUsr: case ActReqDatWrkUsr: case ActChgDatWrkUsr: case ActDowWrkUsr: Gbl.FileBrowser.Type = Brw_ADMI_WRK_USR; break; /***** Another users' works *****/ case ActReqRemFilWrkCrs: case ActRemFilWrkCrs: case ActRemFolWrkCrs: case ActCopWrkCrs: case ActPasWrkCrs: case ActRemTreWrkCrs: case ActFrmCreWrkCrs: case ActCreFolWrkCrs: case ActCreLnkWrkCrs: case ActRenFolWrkCrs: case ActRcvFilWrkCrsDZ: case ActRcvFilWrkCrsCla: case ActExpWrkCrs: case ActConWrkCrs: case ActZIPWrkCrs: case ActReqDatWrkCrs: case ActChgDatWrkCrs: case ActDowWrkCrs: Gbl.FileBrowser.Type = Brw_ADMI_WRK_CRS; break; /***** Documents in project *****/ case ActSeeOnePrj: case ActAdmDocPrj: case ActReqRemFilDocPrj: case ActRemFilDocPrj: case ActRemFolDocPrj: case ActCopDocPrj: case ActPasDocPrj: case ActRemTreDocPrj: case ActFrmCreDocPrj: case ActCreFolDocPrj: case ActCreLnkDocPrj: case ActRenFolDocPrj: case ActRcvFilDocPrjDZ: case ActRcvFilDocPrjCla: case ActExpDocPrj: case ActConDocPrj: case ActZIPDocPrj: case ActReqDatDocPrj: case ActChgDatDocPrj: case ActDowDocPrj: Gbl.FileBrowser.Type = Brw_ADMI_DOC_PRJ; break; /***** Assessment of project *****/ case ActAdmAssPrj: case ActReqRemFilAssPrj: case ActRemFilAssPrj: case ActRemFolAssPrj: case ActCopAssPrj: case ActPasAssPrj: case ActRemTreAssPrj: case ActFrmCreAssPrj: case ActCreFolAssPrj: case ActCreLnkAssPrj: case ActRenFolAssPrj: case ActRcvFilAssPrjDZ: case ActRcvFilAssPrjCla: case ActExpAssPrj: case ActConAssPrj: case ActZIPAssPrj: case ActReqDatAssPrj: case ActChgDatAssPrj: case ActDowAssPrj: Gbl.FileBrowser.Type = Brw_ADMI_ASS_PRJ; break; /***** Marks *****/ case ActSeeAdmMrk: // Access to a marks zone from menu /* Set file browser type acording to last group accessed */ switch (Gbl.Usrs.Me.Role.Logged) { case Rol_STD: case Rol_NET: Gbl.FileBrowser.Type = (Gbl.Crs.Grps.GrpCod > 0) ? Brw_SHOW_MRK_GRP : Brw_SHOW_MRK_CRS; break; case Rol_TCH: case Rol_SYS_ADM: Gbl.FileBrowser.Type = (Gbl.Crs.Grps.GrpCod > 0) ? Brw_ADMI_MRK_GRP : Brw_ADMI_MRK_CRS; break; default: Err_WrongRoleExit (); break; } break; case ActChgToSeeMrk: // Access to see a marks zone /* Set file browser type acording to last group accessed */ Gbl.FileBrowser.Type = (Gbl.Crs.Grps.GrpCod > 0) ? Brw_SHOW_MRK_GRP : Brw_SHOW_MRK_CRS; break; case ActSeeMrkCrs: case ActExpSeeMrkCrs: case ActConSeeMrkCrs: case ActReqDatSeeMrkCrs: case ActReqLnkSeeMrkCrs: case ActSeeMyMrkCrs: Gbl.FileBrowser.Type = Brw_SHOW_MRK_CRS; break; case ActSeeMrkGrp: case ActExpSeeMrkGrp: case ActConSeeMrkGrp: case ActReqDatSeeMrkGrp: case ActSeeMyMrkGrp: Gbl.FileBrowser.Type = Brw_SHOW_MRK_GRP; break; case ActChgToAdmMrk: // Access to admin a marks zone /* Set file browser type acording to last group accessed */ Gbl.FileBrowser.Type = (Gbl.Crs.Grps.GrpCod > 0) ? Brw_ADMI_MRK_GRP : Brw_ADMI_MRK_CRS; break; case ActAdmMrkCrs: case ActReqRemFilMrkCrs: case ActRemFilMrkCrs: case ActRemFolMrkCrs: case ActCopMrkCrs: case ActPasMrkCrs: case ActRemTreMrkCrs: case ActFrmCreMrkCrs: case ActCreFolMrkCrs: case ActRenFolMrkCrs: case ActRcvFilMrkCrsDZ: case ActRcvFilMrkCrsCla: case ActExpAdmMrkCrs: case ActConAdmMrkCrs: case ActZIPAdmMrkCrs: case ActUnhMrkCrs: case ActHidMrkCrs: case ActReqDatAdmMrkCrs: case ActChgDatAdmMrkCrs: case ActReqLnkAdmMrkCrs: case ActDowAdmMrkCrs: case ActChgNumRowHeaCrs: case ActChgNumRowFooCrs: Gbl.FileBrowser.Type = Brw_ADMI_MRK_CRS; break; case ActAdmMrkGrp: case ActReqRemFilMrkGrp: case ActRemFilMrkGrp: case ActRemFolMrkGrp: case ActCopMrkGrp: case ActPasMrkGrp: case ActRemTreMrkGrp: case ActFrmCreMrkGrp: case ActCreFolMrkGrp: case ActRenFolMrkGrp: case ActRcvFilMrkGrpDZ: case ActRcvFilMrkGrpCla: case ActExpAdmMrkGrp: case ActConAdmMrkGrp: case ActZIPAdmMrkGrp: case ActUnhMrkGrp: case ActHidMrkGrp: case ActReqDatAdmMrkGrp: case ActChgDatAdmMrkGrp: case ActDowAdmMrkGrp: case ActChgNumRowHeaGrp: case ActChgNumRowFooGrp: Gbl.FileBrowser.Type = Brw_ADMI_MRK_GRP; break; /***** Briefcase *****/ case ActAdmBrf: case ActReqRemFilBrf: case ActRemFilBrf: case ActRemFolBrf: case ActCopBrf: case ActPasBrf: case ActRemTreBrf: case ActFrmCreBrf: case ActCreFolBrf: case ActCreLnkBrf: case ActRenFolBrf: case ActRcvFilBrfDZ: case ActRcvFilBrfCla: case ActExpBrf: case ActConBrf: case ActZIPBrf: case ActReqDatBrf: case ActChgDatBrf: case ActDowBrf: case ActReqRemOldBrf: // Ask for removing old files in briefcase case ActRemOldBrf: // Remove old files in briefcase Gbl.FileBrowser.Type = Brw_ADMI_BRF_USR; break; default: Err_ShowErrorAndExit ("The type of file browser can not be determined."); break; } /***** Get the path in the file browser and the name of the file or folder *****/ Brw_GetParsPathInTreeAndFileName (); Brw_SetFullPathInTree (); /***** Get other parameters *****/ if (Brw_GetIfProjectFileBrowser ()) /* Get project code */ Prj_SetPrjCod (ParCod_GetPar (ParCod_Prj)); else if (Brw_GetIfCrsAssigWorksFileBrowser ()) { /* Get lists of the selected users if not already got */ Usr_GetListsSelectedEncryptedUsrsCods (&Gbl.Usrs.Selected); /* Get user whose folder will be used to make any operation */ Usr_GetParOtherUsrCodEncryptedAndGetListIDs (); /* Get whether we must create the zip file or not */ Gbl.FileBrowser.ZIP.CreateZIP = ZIP_GetCreateZIPFromForm (); } switch (Gbl.Action.Act) { case ActCreFolDocIns: case ActRenFolDocIns: case ActCreFolShaIns: case ActRenFolShaIns: case ActCreFolDocCtr: case ActRenFolDocCtr: case ActCreFolShaCtr: case ActRenFolShaCtr: case ActCreFolDocDeg: case ActRenFolDocDeg: case ActCreFolShaDeg: case ActRenFolShaDeg: case ActCreFolDocCrs: case ActRenFolDocCrs: case ActCreFolDocGrp: case ActRenFolDocGrp: case ActCreFolTchCrs: case ActRenFolTchCrs: case ActCreFolTchGrp: case ActRenFolTchGrp: case ActCreFolShaCrs: case ActRenFolShaCrs: case ActCreFolShaGrp: case ActRenFolShaGrp: case ActCreFolMrkCrs: case ActRenFolMrkCrs: case ActCreFolMrkGrp: case ActRenFolMrkGrp: case ActCreFolAsgCrs: case ActRenFolAsgCrs: case ActCreFolWrkCrs: case ActRenFolWrkCrs: case ActCreFolAsgUsr: case ActRenFolAsgUsr: case ActCreFolWrkUsr: case ActRenFolWrkUsr: case ActCreFolDocPrj: case ActRenFolDocPrj: case ActCreFolAssPrj: case ActRenFolAssPrj: case ActCreFolBrf: case ActRenFolBrf: /* Get the name of the new folder */ Par_GetParText ("NewFolderName",Gbl.FileBrowser.NewFilFolLnkName,NAME_MAX); break; case ActCreLnkDocIns: case ActCreLnkShaIns: case ActCreLnkDocCtr: case ActCreLnkShaCtr: case ActCreLnkDocDeg: case ActCreLnkShaDeg: case ActCreLnkDocCrs: case ActCreLnkDocGrp: case ActCreLnkTchCrs: case ActCreLnkTchGrp: case ActCreLnkShaCrs: case ActCreLnkShaGrp: case ActCreLnkAsgCrs: case ActCreLnkWrkCrs: case ActCreLnkAsgUsr: case ActCreLnkWrkUsr: case ActCreLnkDocPrj: case ActCreLnkBrf: /* Get the name of the new link */ Par_GetParText ("NewLinkName",Gbl.FileBrowser.NewFilFolLnkName,NAME_MAX); break; default: break; } /***** Get whether to show full tree *****/ // If I belong to the current course or I am superuser, or file browser is briefcase ==> get whether show full tree from form // Else ==> show full tree (only public files) Gbl.FileBrowser.ShowOnlyPublicFiles = false; if (Gbl.Usrs.Me.Role.Logged != Rol_SYS_ADM) switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_INS: case Brw_ADMI_DOC_INS: case Brw_ADMI_SHR_INS: Gbl.FileBrowser.ShowOnlyPublicFiles = !Gbl.Usrs.Me.IBelongToCurrentIns; break; case Brw_SHOW_DOC_CTR: case Brw_ADMI_DOC_CTR: case Brw_ADMI_SHR_CTR: Gbl.FileBrowser.ShowOnlyPublicFiles = !Gbl.Usrs.Me.IBelongToCurrentCtr; break; case Brw_SHOW_DOC_DEG: case Brw_ADMI_DOC_DEG: case Brw_ADMI_SHR_DEG: Gbl.FileBrowser.ShowOnlyPublicFiles = !Gbl.Usrs.Me.IBelongToCurrentDeg; break; case Brw_SHOW_DOC_CRS: case Brw_ADMI_DOC_CRS: case Brw_ADMI_SHR_CRS: Gbl.FileBrowser.ShowOnlyPublicFiles = !Gbl.Usrs.Me.IBelongToCurrentCrs; break; default: break; } Gbl.FileBrowser.FullTree = Gbl.FileBrowser.ShowOnlyPublicFiles ? true : Brw_GetFullTreeFromForm (); /***** Initialize file browser *****/ Brw_InitializeFileBrowser (); } /*****************************************************************************/ /******* Get group code from last access to current zone or from form ********/ /*****************************************************************************/ static long Brw_GetGrpSettings (void) { long GrpCod; if ((GrpCod = ParCod_GetPar (ParCod_Grp)) > 0) return GrpCod; else /***** Try to get group code from database *****/ switch (Gbl.Action.Act) { case ActSeeAdmDocCrsGrp: // Access to a documents zone from menu case ActSeeDocGrp: case ActAdmDocGrp: case ActAdmTchCrsGrp: // Access to a documents zone from menu case ActAdmTchGrp: return Brw_GetGrpLastAccZone ("LastDowGrpCod"); case ActAdmShaCrsGrp: // Access to a shared documents zone from menu case ActAdmShaGrp: return Brw_GetGrpLastAccZone ("LastComGrpCod"); case ActSeeAdmMrk: // Access to a marks zone from menu case ActSeeMrkGrp: case ActAdmMrkGrp: return Brw_GetGrpLastAccZone ("LastAssGrpCod"); default: return -1L; } } /*****************************************************************************/ /******************* If a group is selected, get its data ********************/ /*****************************************************************************/ static void Brw_GetDataCurrentGrp (void) { struct GroupData GrpDat; if (Gbl.Crs.Grps.GrpCod > 0) { GrpDat.GrpCod = Gbl.Crs.Grps.GrpCod; Grp_GetGroupDataByCod (&GrpDat); switch (Gbl.Action.Act) { case ActSeeAdmDocCrsGrp: // Access to see/admin a documents zone from menu case ActChgToSeeDocCrs: // Access to see a documents zone case ActSeeDocGrp: // Access to see a documents zone case ActChgToAdmDocCrs: // Access to admin a documents zone case ActAdmDocGrp: // Access to admin a documents zone case ActAdmTchCrsGrp: // Access to admin a teachers' zone from menu case ActChgToAdmTch: // Access to admin a teachers' zone case ActAdmTchGrp: // Access to admin a teachers' zone case ActAdmShaCrsGrp: // Access to admin a shared zone from menu case ActChgToAdmSha: // Access to admin a shared zone case ActAdmShaGrp: // Access to admin a shared zone case ActSeeAdmMrk: // Access to see/admin a marks zone from menu case ActChgToSeeMrk: // Access to see a marks zone case ActSeeMrkGrp: // Access to see a marks zone case ActChgToAdmMrk: // Access to admin a marks zone case ActAdmMrkGrp: // Access to admin a marks zone /***** For security, check if group file zones are enabled, and check if I belongs to the selected group *****/ if (GrpDat.FileZones) { if (!Grp_GetIfIBelongToGrp (Gbl.Crs.Grps.GrpCod)) Gbl.Crs.Grps.GrpCod = -1L; // Go to course zone } else Gbl.Crs.Grps.GrpCod = -1L; // Go to course zone break; default: /***** For security, check if group file zones are enabled, and check if I belongs to the selected group *****/ if (!GrpDat.FileZones) Err_ShowErrorAndExit ("The group has no file zones."); else if (!Grp_GetIfIBelongToGrp (Gbl.Crs.Grps.GrpCod)) Err_ShowErrorAndExit ("You don't have access to the group."); break; } /***** Get data of the current group *****/ if (Gbl.Crs.Grps.GrpCod > 0) { Gbl.Crs.Grps.GrpTyp.GrpTypCod = GrpDat.GrpTypCod; Str_Copy (Gbl.Crs.Grps.GrpTyp.GrpTypName,GrpDat.GrpTypName, sizeof (Gbl.Crs.Grps.GrpTyp.GrpTypName) - 1); Str_Copy (Gbl.Crs.Grps.GrpName,GrpDat.GrpName, sizeof (Gbl.Crs.Grps.GrpName) - 1); Gbl.Crs.Grps.MaxStudents = GrpDat.MaxStudents; Gbl.Crs.Grps.Open = GrpDat.Open; Gbl.Crs.Grps.FileZones = GrpDat.FileZones; Gbl.Crs.Grps.GrpTyp.MultipleEnrolment = GrpDat.MultipleEnrolment; } } } /*****************************************************************************/ /**************** Write parameters related with file browser *****************/ /*****************************************************************************/ void Brw_PutImplicitParsFileBrowser (void *FilFolLnk) { if (FilFolLnk) Brw_PutParsFileBrowser (((struct Brw_FilFolLnk *) FilFolLnk)->Path, ((struct Brw_FilFolLnk *) FilFolLnk)->Name, ((struct Brw_FilFolLnk *) FilFolLnk)->Type, -1L); // Not used } void Brw_PutParsFileBrowser (const char *PathInTree,const char *FilFolLnkName, Brw_FileType_t FileType,long FilCod) { if (Brw_GetIfGroupFileBrowser ()) // This file browser needs specify a group /***** Group code *****/ ParCod_PutPar (ParCod_Grp,Gbl.Crs.Grps.GrpCod); else if (Brw_GetIfProjectFileBrowser ()) // This file browser needs specify a project /***** Project code *****/ ParCod_PutPar (ParCod_Prj,Prj_GetPrjCod ()); else if (Brw_GetIfCrsAssigWorksFileBrowser ()) { /***** Users selected *****/ Usr_PutParSelectedUsrsCods (&Gbl.Usrs.Selected); Usr_PutParOtherUsrCodEncrypted (Gbl.Usrs.Other.UsrDat.EnUsrCod); } /***** If full tree selected? *****/ Brw_PutParFullTreeIfSelected (&Gbl.FileBrowser.FullTree); /***** Path and file *****/ if (PathInTree) Par_PutParString (NULL,"Path",PathInTree); if (FilFolLnkName) Par_PutParString (NULL,Brw_FileTypeParName[FileType],FilFolLnkName); ParCod_PutPar (ParCod_Fil,FilCod); } /*****************************************************************************/ /************** Get parameters path and file in file browser *****************/ /*****************************************************************************/ static void Brw_GetParsPathInTreeAndFileName (void) { const char *Ptr; unsigned i; Brw_FileType_t FileType; char FileNameToShow[NAME_MAX + 1]; /***** Get the path inside the tree (this path does not include the name of the file or folder at the end) *****/ Par_GetParText ("Path",Gbl.FileBrowser.FilFolLnk.Path,PATH_MAX); /* Check if path contains ".." */ if (strstr (Gbl.FileBrowser.FilFolLnk.Path,"..")) // ".." is not allowed in path Err_ShowErrorAndExit ("Wrong path."); /***** Get the name of the file, folder or link *****/ Gbl.FileBrowser.FilFolLnk.Type = Brw_IS_UNKNOWN; for (FileType = (Brw_FileType_t) 0; FileType <= (Brw_FileType_t) (Brw_NUM_FILE_TYPES - 1); FileType++) // File names with heading and trailing spaces are allowed if (Par_GetParAndChangeFormat (Brw_FileTypeParName[FileType], Gbl.FileBrowser.FilFolLnk.Name, NAME_MAX,Str_TO_TEXT,false)) { Gbl.FileBrowser.FilFolLnk.Type = FileType; /* Check if filename contains ".." */ Brw_GetFileNameToShow (Gbl.FileBrowser.FilFolLnk.Type, Gbl.FileBrowser.FilFolLnk.Name, FileNameToShow); if (strstr (FileNameToShow,"..")) // ".." is not allowed in filename Err_ShowErrorAndExit ("Wrong file name."); break; } /***** Set level of this file or folder inside file browser *****/ if (!strcmp (Gbl.FileBrowser.FilFolLnk.Name,".")) Gbl.FileBrowser.Level = 0; else { // Level == number-of-slashes-in-path-except-file-or-folder + 1 Gbl.FileBrowser.Level = 1; for (Ptr = Gbl.FileBrowser.FilFolLnk.Path; *Ptr; Ptr++) if (*Ptr == '/') Gbl.FileBrowser.Level++; } /***** Get data of assignment *****/ if (Gbl.FileBrowser.Level && (Gbl.FileBrowser.Type == Brw_ADMI_ASG_USR || Gbl.FileBrowser.Type == Brw_ADMI_ASG_CRS)) { if (Gbl.FileBrowser.Level == 1) // We are in this case: assignments/assignment-folder Str_Copy (Gbl.FileBrowser.Asg.Folder,Gbl.FileBrowser.FilFolLnk.Name, sizeof (Gbl.FileBrowser.Asg.Folder) - 1); else { // We are in this case: assignments/assignment-folder/rest-of-path for (Ptr = Gbl.FileBrowser.FilFolLnk.Path; *Ptr && *Ptr != '/'; Ptr++); // Go to first '/' if (*Ptr == '/') Ptr++; // Skip '/' for (i = 0; i < Brw_MAX_BYTES_FOLDER && *Ptr && *Ptr != '/'; i++, Ptr++) Gbl.FileBrowser.Asg.Folder[i] = *Ptr; // Copy assignment folder Gbl.FileBrowser.Asg.Folder[i] = '\0'; } Asg_GetAssignmentDataByFolder (&Gbl.FileBrowser.Asg); } } /*****************************************************************************/ /************************* Initialize file browser ***************************/ /*****************************************************************************/ // Gbl.FileBrowser.Type must be set to a valid file browser void Brw_InitializeFileBrowser (void) { struct BrwSiz_BrowserSize *Size = BrwSiz_GetSize (); /***** Construct the relative path to the folder of file browser *****/ Brw_SetPathFileBrowser (); /***** Other initializations *****/ BrwSiz_ResetFileBrowserSize (Size); } /*****************************************************************************/ /********* Construct the paths to the top folders of file browser ************/ /*****************************************************************************/ static void Brw_SetPathFileBrowser (void) { long PrjCod; char Path[PATH_MAX * 2 + 128]; /***** Reset paths. An empty path means that we don't have to create that directory *****/ Gbl.FileBrowser.Priv.PathAboveRootFolder[0] = '\0'; Gbl.FileBrowser.Priv.PathRootFolder[0] = '\0'; /***** Set paths depending on file browser *****/ switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_INS: case Brw_ADMI_DOC_INS: case Brw_ADMI_SHR_INS: /* Create a directory for institutions */ Fil_CreateDirIfNotExists (Cfg_PATH_INS_PRIVATE); /* Create a directory for all institutions which codes end in institution-code mod 100 */ snprintf (Path,sizeof (Path),"%s/%02u", Cfg_PATH_INS_PRIVATE, (unsigned) (Gbl.Hierarchy.Ins.InsCod % 100)); Fil_CreateDirIfNotExists (Path); /* Create path to the current institution */ snprintf (Gbl.FileBrowser.Priv.PathAboveRootFolder, sizeof (Gbl.FileBrowser.Priv.PathAboveRootFolder), "%s/%02u/%u", Cfg_PATH_INS_PRIVATE, (unsigned) (Gbl.Hierarchy.Ins.InsCod % 100), (unsigned) Gbl.Hierarchy.Ins.InsCod); break; case Brw_SHOW_DOC_CTR: case Brw_ADMI_DOC_CTR: case Brw_ADMI_SHR_CTR: /* Create a directory for centers */ Fil_CreateDirIfNotExists (Cfg_PATH_CTR_PRIVATE); /* Create a directory for all centers which codes end in center-code mod 100 */ snprintf (Path,sizeof (Path),"%s/%02u", Cfg_PATH_CTR_PRIVATE, (unsigned) (Gbl.Hierarchy.Ctr.CtrCod % 100)); Fil_CreateDirIfNotExists (Path); /* Create path to the current center */ snprintf (Gbl.FileBrowser.Priv.PathAboveRootFolder, sizeof (Gbl.FileBrowser.Priv.PathAboveRootFolder), "%s/%02u/%u", Cfg_PATH_CTR_PRIVATE, (unsigned) (Gbl.Hierarchy.Ctr.CtrCod % 100), (unsigned) Gbl.Hierarchy.Ctr.CtrCod); break; case Brw_SHOW_DOC_DEG: case Brw_ADMI_DOC_DEG: case Brw_ADMI_SHR_DEG: /* Create a directory for degrees */ Fil_CreateDirIfNotExists (Cfg_PATH_DEG_PRIVATE); /* Create a directory for all degrees which codes end in degree-code mod 100 */ snprintf (Path,sizeof (Path),"%s/%02u", Cfg_PATH_DEG_PRIVATE, (unsigned) (Gbl.Hierarchy.Deg.DegCod % 100)); Fil_CreateDirIfNotExists (Path); /* Create path to the current degree */ snprintf (Gbl.FileBrowser.Priv.PathAboveRootFolder, sizeof (Gbl.FileBrowser.Priv.PathAboveRootFolder), "%s/%02u/%u", Cfg_PATH_DEG_PRIVATE, (unsigned) (Gbl.Hierarchy.Deg.DegCod % 100), (unsigned) Gbl.Hierarchy.Deg.DegCod); break; case Brw_SHOW_DOC_CRS: case Brw_ADMI_DOC_CRS: case Brw_ADMI_TCH_CRS: case Brw_ADMI_SHR_CRS: case Brw_SHOW_MRK_CRS: case Brw_ADMI_MRK_CRS: /* Create path to the current course */ Str_Copy (Gbl.FileBrowser.Priv.PathAboveRootFolder,Gbl.Crs.PathPriv, sizeof (Gbl.FileBrowser.Priv.PathAboveRootFolder) - 1); break; case Brw_SHOW_DOC_GRP: case Brw_ADMI_DOC_GRP: case Brw_ADMI_TCH_GRP: case Brw_ADMI_SHR_GRP: case Brw_SHOW_MRK_GRP: case Brw_ADMI_MRK_GRP: /* Create a directory for groups inside the current course */ snprintf (Path,sizeof (Path),"%s/%s", Gbl.Crs.PathPriv,Cfg_FOLDER_GRP); Fil_CreateDirIfNotExists (Path); /* Create path to this group */ snprintf (Path,sizeof (Path),"%s/%s/%ld", Gbl.Crs.PathPriv,Cfg_FOLDER_GRP, Gbl.Crs.Grps.GrpCod); Str_Copy (Gbl.FileBrowser.Priv.PathAboveRootFolder,Path, sizeof (Gbl.FileBrowser.Priv.PathAboveRootFolder) - 1); break; case Brw_ADMI_ASG_USR: case Brw_ADMI_WRK_USR: /* Create a directory for me inside the current course */ snprintf (Path,sizeof (Path),"%s/%s", Gbl.Crs.PathPriv,Cfg_FOLDER_USR); Fil_CreateDirIfNotExists (Path); /* Create a directory for all users whose codes end in my-user-code mod 100 */ snprintf (Path,sizeof (Path),"%s/%s/%02u", Gbl.Crs.PathPriv,Cfg_FOLDER_USR, (unsigned) (Gbl.Usrs.Me.UsrDat.UsrCod % 100)); Fil_CreateDirIfNotExists (Path); /* Create path to me */ snprintf (Path,sizeof (Path),"%s/%s/%02u/%ld", Gbl.Crs.PathPriv,Cfg_FOLDER_USR, (unsigned) (Gbl.Usrs.Me.UsrDat.UsrCod % 100), Gbl.Usrs.Me.UsrDat.UsrCod); Str_Copy (Gbl.FileBrowser.Priv.PathAboveRootFolder,Path, sizeof (Gbl.FileBrowser.Priv.PathAboveRootFolder) - 1); break; case Brw_ADMI_ASG_CRS: case Brw_ADMI_WRK_CRS: if (Gbl.Usrs.Other.UsrDat.UsrCod > 0) { /* Create a directory for this user inside the current course */ snprintf (Path,sizeof (Path),"%s/%s", Gbl.Crs.PathPriv,Cfg_FOLDER_USR); Fil_CreateDirIfNotExists (Path); /* Create a directory for all users whose codes end in user-code mod 100 */ snprintf (Path,sizeof (Path),"%s/%s/%02u", Gbl.Crs.PathPriv,Cfg_FOLDER_USR, (unsigned) (Gbl.Usrs.Other.UsrDat.UsrCod % 100)); Fil_CreateDirIfNotExists (Path); /* Create path to user */ snprintf (Path,sizeof (Path),"%s/%s/%02u/%ld", Gbl.Crs.PathPriv,Cfg_FOLDER_USR, (unsigned) (Gbl.Usrs.Other.UsrDat.UsrCod % 100), Gbl.Usrs.Other.UsrDat.UsrCod); Str_Copy (Gbl.FileBrowser.Priv.PathAboveRootFolder,Path, sizeof (Gbl.FileBrowser.Priv.PathAboveRootFolder) - 1); } break; case Brw_ADMI_DOC_PRJ: case Brw_ADMI_ASS_PRJ: PrjCod = Prj_GetPrjCod (); /* Create a directory for projects inside the current course */ snprintf (Path,sizeof (Path),"%s/%s", Gbl.Crs.PathPriv,Cfg_FOLDER_PRJ); Fil_CreateDirIfNotExists (Path); /* Create a directory for all projects which codes end in project-code mod 100 */ snprintf (Path,sizeof (Path),"%s/%s/%02u", Gbl.Crs.PathPriv,Cfg_FOLDER_PRJ, (unsigned) (PrjCod % 100)); Fil_CreateDirIfNotExists (Path); /* Create path to the current project */ snprintf (Path,sizeof (Path),"%s/%s/%02u/%ld", Gbl.Crs.PathPriv,Cfg_FOLDER_PRJ, (unsigned) (PrjCod % 100), PrjCod); Str_Copy (Gbl.FileBrowser.Priv.PathAboveRootFolder,Path, sizeof (Gbl.FileBrowser.Priv.PathAboveRootFolder) - 1); break; case Brw_ADMI_BRF_USR: Str_Copy (Gbl.FileBrowser.Priv.PathAboveRootFolder,Gbl.Usrs.Me.PathDir, sizeof (Gbl.FileBrowser.Priv.PathAboveRootFolder) - 1); break; default: return; } /***** Create directories that not exist *****/ if (Gbl.FileBrowser.Priv.PathAboveRootFolder[0]) { Fil_CreateDirIfNotExists (Gbl.FileBrowser.Priv.PathAboveRootFolder); snprintf (Path,sizeof (Path),"%s/%s", Gbl.FileBrowser.Priv.PathAboveRootFolder, Brw_RootFolderInternalNames[Gbl.FileBrowser.Type]); Str_Copy (Gbl.FileBrowser.Priv.PathRootFolder,Path, sizeof (Gbl.FileBrowser.Priv.PathRootFolder) - 1); Fil_CreateDirIfNotExists (Gbl.FileBrowser.Priv.PathRootFolder); /***** If file browser is for assignments, create folders of assignments if not exist *****/ if (Gbl.FileBrowser.Type == Brw_ADMI_ASG_USR) Brw_CreateFoldersAssignmentsIfNotExist (Gbl.Usrs.Me.UsrDat.UsrCod); else if (Gbl.FileBrowser.Type == Brw_ADMI_ASG_CRS) Brw_CreateFoldersAssignmentsIfNotExist (Gbl.Usrs.Other.UsrDat.UsrCod); } } /*****************************************************************************/ /****** Check if exists a folder of assignments for any user in course *******/ /*****************************************************************************/ // Folders are in level 1, just under root folder bool Brw_CheckIfExistsFolderAssigmentForAnyUsr (const char *FolderName) { MYSQL_RES *mysql_res; unsigned NumUsrs; unsigned NumUsr; long UsrCod; char PathFolder[PATH_MAX * 2 + 128]; bool FolderExists = false; /***** Get all users belonging to current course *****/ NumUsrs = Enr_DB_GetUsrsFromCurrentCrs (&mysql_res); /***** Check folders *****/ for (NumUsr = 0; NumUsr < NumUsrs && !FolderExists; NumUsr++) { /* Get next user */ UsrCod = DB_GetNextCode (mysql_res); /* Check if folder exists */ snprintf (PathFolder,sizeof (PathFolder),"%s/usr/%02u/%ld/%s/%s", Gbl.Crs.PathPriv, (unsigned) (UsrCod % 100), UsrCod, // User's code Brw_INTERNAL_NAME_ROOT_FOLDER_ASSIGNMENTS, FolderName); FolderExists = Fil_CheckIfPathExists (PathFolder); } /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); return FolderExists; } /*****************************************************************************/ /********* Create folders of assignments if not exist for one user ***********/ /*****************************************************************************/ // Folders are created in level 1, just under root folder // Create a folder of an assignment when: // 1. The assignment is visible (not hidden) // 2. ...and the folder name is not empty (the teacher has set that the user must send work(s) for that assignment) // 3. ...the assignment is not restricted to groups or (if restricted to groups), the owner of zone belong to any of the groups static void Brw_CreateFoldersAssignmentsIfNotExist (long ZoneUsrCod) { MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned NumFolders; unsigned NumFolder; char PathFolderAsg[PATH_MAX + 1 + PATH_MAX + 1]; /***** Get assignment folders from database *****/ NumFolders = Brw_DB_GetFoldersAssignments (&mysql_res,ZoneUsrCod); /***** Create one folder for each assignment *****/ for (NumFolder = 0; NumFolder < NumFolders; NumFolder++) { /* Get next assignment with folder */ row = mysql_fetch_row (mysql_res); if (row) if (row[0]) // Not necessary, because folder name is checked in query to be not empty { /* Create folder if not exists */ snprintf (PathFolderAsg,sizeof (PathFolderAsg),"%s/%s", Gbl.FileBrowser.Priv.PathRootFolder,row[0]); Fil_CreateDirIfNotExists (PathFolderAsg); } } /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); } /*****************************************************************************/ /****** Update folders of assignments if exist for all users in course *******/ /*****************************************************************************/ // Folders are in level 1, just under root folder bool Brw_UpdateFoldersAssigmentsIfExistForAllUsrs (const char *OldFolderName, const char *NewFolderName) { extern const char *Txt_Can_not_rename_a_folder_of_assignment; extern const char *Txt_Users; extern const char *Txt_Folders_renamed; extern const char *Txt_Folders_not_renamed; MYSQL_RES *mysql_res; unsigned NumUsrs; unsigned NumUsr; long UsrCod; char OldPath[PATH_MAX + 1]; char NewPath[PATH_MAX + 1]; char PathOldFolder[PATH_MAX * 2 + 128]; char PathNewFolder[PATH_MAX * 2 + 128]; bool RenamingIsPossible = true; unsigned NumUsrsError = 0; unsigned NumUsrsSuccess = 0; /***** Get all users belonging to current course *****/ NumUsrs = Enr_DB_GetUsrsFromCurrentCrs (&mysql_res); /***** Check if there exist folders with the new name *****/ for (NumUsr = 0; NumUsr < NumUsrs && RenamingIsPossible; NumUsr++) { /* Get next user */ UsrCod = DB_GetNextCode (mysql_res); /* Rename folder if exists */ snprintf (PathOldFolder,sizeof (PathOldFolder),"%s/usr/%02u/%ld/%s/%s", Gbl.Crs.PathPriv, (unsigned) (UsrCod % 100), UsrCod, // User's code Brw_INTERNAL_NAME_ROOT_FOLDER_ASSIGNMENTS, OldFolderName); snprintf (PathNewFolder,sizeof (PathNewFolder),"%s/usr/%02u/%ld/%s/%s", Gbl.Crs.PathPriv, (unsigned) (UsrCod % 100), UsrCod, // User's code Brw_INTERNAL_NAME_ROOT_FOLDER_ASSIGNMENTS, NewFolderName); if (Fil_CheckIfPathExists (PathOldFolder) && Fil_CheckIfPathExists (PathNewFolder)) RenamingIsPossible = false; } /***** Rename folder for each user *****/ if (RenamingIsPossible) { mysql_data_seek (mysql_res,0); for (NumUsr = 0; NumUsr < NumUsrs; NumUsr++) { /* Get next user */ UsrCod = DB_GetNextCode (mysql_res); /* Rename folder if exists */ snprintf (PathOldFolder,sizeof (PathOldFolder),"%s/usr/%02u/%ld/%s/%s", Gbl.Crs.PathPriv, (unsigned) (UsrCod % 100), UsrCod, // User's code Brw_INTERNAL_NAME_ROOT_FOLDER_ASSIGNMENTS, OldFolderName); if (Fil_CheckIfPathExists (PathOldFolder)) { snprintf (PathNewFolder,sizeof (PathNewFolder),"%s/usr/%02u/%ld/%s/%s", Gbl.Crs.PathPriv, (unsigned) (UsrCod % 100), UsrCod, // User's code Brw_INTERNAL_NAME_ROOT_FOLDER_ASSIGNMENTS, NewFolderName); if (rename (PathOldFolder,PathNewFolder)) // Fail { Ale_ShowAlert (Ale_ERROR,Txt_Can_not_rename_a_folder_of_assignment); NumUsrsError++; } else // Success { /* Remove affected clipboards */ Brw_DB_RemoveAffectedClipboards (Brw_ADMI_ASG_USR,UsrCod,-1L); Brw_DB_RemoveAffectedClipboards (Brw_ADMI_ASG_CRS,-1L,UsrCod); /* Rename affected expanded folders */ snprintf (OldPath,sizeof (OldPath),"%s/%s", Brw_INTERNAL_NAME_ROOT_FOLDER_ASSIGNMENTS,OldFolderName); snprintf (NewPath,sizeof (NewPath),"%s/%s", Brw_INTERNAL_NAME_ROOT_FOLDER_ASSIGNMENTS,NewFolderName); Brw_DB_RenameAffectedExpandedFolders (Brw_ADMI_ASG_USR,UsrCod,-1L, OldPath,NewPath); Brw_DB_RenameAffectedExpandedFolders (Brw_ADMI_ASG_CRS,-1L,UsrCod, OldPath,NewPath); NumUsrsSuccess++; } } } /***** Summary message *****/ Ale_ShowAlert (Ale_INFO,"%s: %u
" "%s: %u
" "%s: %u.", Txt_Users,NumUsrs, Txt_Folders_renamed,NumUsrsSuccess, Txt_Folders_not_renamed,NumUsrsError); } else /***** Warning message *****/ Ale_ShowAlert (Ale_WARNING,Txt_Can_not_rename_a_folder_of_assignment); /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); return RenamingIsPossible; } /*****************************************************************************/ /******* Remove folders of assignments if exist for all users in course ******/ /*****************************************************************************/ // Folders are in level 1, just under root folder void Brw_RemoveFoldersAssignmentsIfExistForAllUsrs (const char *FolderName) { MYSQL_RES *mysql_res; unsigned NumUsrs; unsigned NumUsr; long UsrCod; char PathFolder[PATH_MAX * 2 + 128]; /***** Get all users belonging to current course *****/ NumUsrs = Enr_DB_GetUsrsFromCurrentCrs (&mysql_res); /***** Remove folders *****/ for (NumUsr = 0; NumUsr < NumUsrs; NumUsr++) { /* Get next user */ UsrCod = DB_GetNextCode (mysql_res); /* Remove tree if exists */ snprintf (PathFolder,sizeof (PathFolder),"%s/usr/%02u/%ld/%s/%s", Gbl.Crs.PathPriv, (unsigned) (UsrCod % 100), UsrCod, // User's code Brw_INTERNAL_NAME_ROOT_FOLDER_ASSIGNMENTS, FolderName); Fil_RemoveTree (PathFolder); } /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); } /*****************************************************************************/ /************** Request edition of works of users of the course **************/ /*****************************************************************************/ void Brw_AskEditWorksCrs (void) { Brw_AskEditWorksCrsInternal (NULL); } static void Brw_AskEditWorksCrsInternal (__attribute__((unused)) void *Args) { extern const char *Hlp_FILES_Homework_for_teachers; extern const char *Txt_Assignments_and_other_works; extern const char *Txt_View_homework; /***** List users to select some of them *****/ Usr_PutFormToSelectUsrsToGoToAct (&Gbl.Usrs.Selected, ActAdmAsgWrkCrs, NULL,NULL, Txt_Assignments_and_other_works, Hlp_FILES_Homework_for_teachers, Txt_View_homework, false); // Do not put form with date range } /*****************************************************************************/ /*********** Show normal file browser (not for assignments-works) ************/ /*****************************************************************************/ static void Brw_ShowFileBrowserNormal (void) { /***** Write top before showing file browser *****/ Brw_WriteTopBeforeShowingFileBrowser (); /****** Show the file browser *****/ Brw_ShowFileBrowser (); } /*****************************************************************************/ /************* Show file browser with the documents of a project *************/ /*****************************************************************************/ void Brw_ShowFileBrowserProject (long PrjCod) { Brw_WriteTopBeforeShowingFileBrowser (); if (Prj_CheckIfICanViewProjectDocuments (PrjCod)) { /***** Show the tree with the project documents *****/ Gbl.FileBrowser.Type = Brw_ADMI_DOC_PRJ; Brw_InitializeFileBrowser (); Brw_ShowFileBrowser (); } if (Prj_CheckIfICanViewProjectAssessment (PrjCod)) { /***** Show the tree with the project assessment *****/ Gbl.FileBrowser.Type = Brw_ADMI_ASS_PRJ; Brw_InitializeFileBrowser (); Brw_ShowFileBrowser (); } } /*****************************************************************************/ /*** Show file browsers with works files of several users of current course **/ /*****************************************************************************/ static void Brw_ShowFileBrowsersAsgWrkCrs (void) { extern const char *Hlp_FILES_Homework_for_teachers; extern const char *Txt_Assignments_and_other_works; const char *Ptr; /***** Create the zip file and put a link to download it *****/ if (Gbl.FileBrowser.ZIP.CreateZIP) ZIP_CreateZIPAsgWrk (); /***** Write top before showing file browser *****/ Brw_WriteTopBeforeShowingFileBrowser (); /***** Begin box and table *****/ Box_BoxTableBegin ("100%",Txt_Assignments_and_other_works, Brw_PutIconShowFigure,NULL, Hlp_FILES_Homework_for_teachers,Box_NOT_CLOSABLE,0); /***** List the assignments and works of the selected users *****/ Ptr = Gbl.Usrs.Selected.List[Rol_UNK]; while (*Ptr) { Par_GetNextStrUntilSeparParMult (&Ptr,Gbl.Usrs.Other.UsrDat.EnUsrCod, Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64); Usr_GetUsrCodFromEncryptedUsrCod (&Gbl.Usrs.Other.UsrDat); if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat, Usr_DONT_GET_PREFS, Usr_GET_ROLE_IN_CURRENT_CRS)) if (Usr_CheckIfICanViewAsgWrk (&Gbl.Usrs.Other.UsrDat)) { Gbl.Usrs.Other.UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); /***** Show a row with the data of the owner of the works *****/ HTM_TR_Begin (NULL); Brw_ShowDataOwnerAsgWrk (&Gbl.Usrs.Other.UsrDat); HTM_TD_Begin ("class=\"LT\""); /* Show the tree with the assignments */ Gbl.FileBrowser.Type = Brw_ADMI_ASG_CRS; Brw_InitializeFileBrowser (); Brw_ShowFileBrowser (); /* Show the tree with the works */ Gbl.FileBrowser.Type = Brw_ADMI_WRK_CRS; Brw_InitializeFileBrowser (); Brw_ShowFileBrowser (); HTM_TD_End (); HTM_TR_End (); } } /***** End table and box *****/ Box_BoxTableEnd (); } /*****************************************************************************/ /************ Show file browsers with works files of one user ****************/ /*****************************************************************************/ static void Brw_ShowFileBrowsersAsgWrkUsr (void) { /***** Write top before showing file browser *****/ Brw_WriteTopBeforeShowingFileBrowser (); /***** Show the tree with the assignments *****/ Gbl.FileBrowser.Type = Brw_ADMI_ASG_USR; Brw_InitializeFileBrowser (); Brw_ShowFileBrowser (); /***** Show the tree with the works *****/ Gbl.FileBrowser.Type = Brw_ADMI_WRK_USR; Brw_InitializeFileBrowser (); Brw_ShowFileBrowser (); } /*****************************************************************************/ /**************** Form to change file zone (course or group) *****************/ /*****************************************************************************/ static void Brw_FormToChangeCrsGrpZone (void) { extern const char *Par_CodeStr[]; struct ListCodGrps LstMyGrps; unsigned NumGrp; struct GroupData GrpDat; bool IsCourseZone = Gbl.FileBrowser.Type == Brw_SHOW_DOC_CRS || Gbl.FileBrowser.Type == Brw_ADMI_DOC_CRS || Gbl.FileBrowser.Type == Brw_ADMI_TCH_CRS || Gbl.FileBrowser.Type == Brw_ADMI_SHR_CRS || Gbl.FileBrowser.Type == Brw_SHOW_MRK_CRS || Gbl.FileBrowser.Type == Brw_ADMI_MRK_CRS; bool IsGroupZone = Gbl.FileBrowser.Type == Brw_SHOW_DOC_GRP || Gbl.FileBrowser.Type == Brw_ADMI_DOC_GRP || Gbl.FileBrowser.Type == Brw_ADMI_TCH_GRP || Gbl.FileBrowser.Type == Brw_ADMI_SHR_GRP || Gbl.FileBrowser.Type == Brw_SHOW_MRK_GRP || Gbl.FileBrowser.Type == Brw_ADMI_MRK_GRP; /***** Get list of groups to show *****/ if (Gbl.Crs.Grps.NumGrps) // This course has groups? /* Get list of group with file zones which I belong to */ Grp_GetLstCodGrpsWithFileZonesIBelong (&LstMyGrps); /***** Begin form *****/ Frm_BeginForm (Brw_ActChgZone[Gbl.FileBrowser.Type]); Brw_PutParFullTreeIfSelected (&Gbl.FileBrowser.FullTree); /***** List start *****/ HTM_UL_Begin ("class=\"LIST_LEFT\""); /***** Select the complete course, not a group *****/ HTM_LI_Begin ("class=\"%s\"",IsCourseZone ? "BROWSER_TITLE" : "BROWSER_TITLE_LIGHT"); HTM_LABEL_Begin (NULL); HTM_INPUT_RADIO (Par_CodeStr[ParCod_Grp],true, "value=\"-1\"%s", IsCourseZone ? " checked=\"checked\"" : ""); HTM_Txt (Gbl.Hierarchy.Crs.FullName); HTM_LABEL_End (); HTM_LI_End (); /***** List my groups for unique selection *****/ if (Gbl.Crs.Grps.NumGrps) // This course has groups? { for (NumGrp = 0; NumGrp < LstMyGrps.NumGrps; NumGrp++) { /* Get next group */ GrpDat.GrpCod = LstMyGrps.GrpCods[NumGrp]; Grp_GetGroupDataByCod (&GrpDat); /* Select this group */ HTM_LI_Begin ("class=\"%s\"", (IsGroupZone && GrpDat.GrpCod == Gbl.Crs.Grps.GrpCod) ? "BROWSER_TITLE" : "BROWSER_TITLE_LIGHT"); HTM_IMG (Cfg_URL_ICON_PUBLIC, NumGrp < LstMyGrps.NumGrps - 1 ? "submid20x20.gif" : "subend20x20.gif", NULL, "class=\"ICO25x25\" style=\"margin-left:6px;\""); HTM_LABEL_Begin (NULL); HTM_INPUT_RADIO (Par_CodeStr[ParCod_Grp],true, "value=\"%ld\"%s", GrpDat.GrpCod, (IsGroupZone && GrpDat.GrpCod == Gbl.Crs.Grps.GrpCod) ? " checked=\"checked\"" : ""); HTM_TxtF ("%s %s",GrpDat.GrpTypName,GrpDat.GrpName); HTM_LABEL_End (); HTM_LI_End (); } /***** Free memory with the list of groups I belong to *****/ Grp_FreeListCodGrp (&LstMyGrps); } /***** End list and form *****/ HTM_UL_End (); Frm_EndForm (); } /*****************************************************************************/ /*** Get the data of the selected group in order to enter its common zone ****/ /*****************************************************************************/ static void Brw_GetSelectedGroupData (struct GroupData *GrpDat,bool AbortOnError) { if (GrpDat->GrpCod > 0) { /***** Get the data of the selected group *****/ Grp_GetGroupDataByCod (GrpDat); /***** For security, check if group file zones are enabled, and check if I belongs to the selected group *****/ if (!GrpDat->FileZones) { if (AbortOnError) Err_ShowErrorAndExit ("The file browser is disabled."); GrpDat->GrpCod = -1L; } else if (!Grp_GetIfIBelongToGrp (GrpDat->GrpCod)) { if (AbortOnError) Err_NoPermissionExit (); GrpDat->GrpCod = -1L; } } } /*****************************************************************************/ /******** Show a row with the data of the owner of assignments/works *********/ /*****************************************************************************/ static void Brw_ShowDataOwnerAsgWrk (struct Usr_Data *UsrDat) { extern const char *Txt_View_record_for_this_course; static const Act_Action_t NextAction[Rol_NUM_ROLES] = { [Rol_STD] = ActSeeRecOneStd, [Rol_NET] = ActSeeRecOneTch, [Rol_TCH] = ActSeeRecOneTch, }; static const char *ClassPhoto[PhoSha_NUM_SHAPES] = { [PhoSha_SHAPE_CIRCLE ] = "PHOTOC60x80", [PhoSha_SHAPE_ELLIPSE ] = "PHOTOE60x80", [PhoSha_SHAPE_OVAL ] = "PHOTOO60x80", [PhoSha_SHAPE_RECTANGLE] = "PHOTOR60x80", }; /***** Show user's photo *****/ HTM_TD_Begin ("class=\"OWNER_WORKS_PHOTO\""); Pho_ShowUsrPhotoIfAllowed (UsrDat, ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM); HTM_TD_End (); /***** Begin form to send a message to this user *****/ HTM_TD_Begin ("class=\"LT\""); HTM_DIV_Begin ("class=\"OWNER_WORKS_DATA MSG_AUT_%s\"",The_GetSuffix ()); if (!NextAction[UsrDat->Roles.InCurrentCrs]) Err_WrongRoleExit (); Frm_BeginForm (NextAction[UsrDat->Roles.InCurrentCrs]); Usr_PutParUsrCodEncrypted (UsrDat->EnUsrCod); /***** Show user's ID *****/ ID_WriteUsrIDs (UsrDat,NULL); /***** Show user's name *****/ HTM_BR (); HTM_BUTTON_Submit_Begin (Txt_View_record_for_this_course, "class=\"BT_LINK\""); HTM_Txt (UsrDat->Surname1); if (UsrDat->Surname2[0]) HTM_TxtF (" %s",UsrDat->Surname2); if (UsrDat->FrstName[0]) HTM_TxtF (", %s",UsrDat->FrstName); HTM_BUTTON_End (); /***** Show user's email *****/ if (UsrDat->Email[0]) { HTM_BR (); HTM_A_Begin ("href=\"mailto:%s\" target=\"_blank\"" " class=\"MSG_AUT_%s\"", UsrDat->Email,The_GetSuffix ()); HTM_Txt (UsrDat->Email); HTM_A_End (); } Frm_EndForm (); HTM_DIV_End (); HTM_TD_End (); } /*****************************************************************************/ /******* Get and check list of selected users, and show users' works ********/ /*****************************************************************************/ void Brw_GetSelectedUsrsAndShowWorks (void) { Usr_GetSelectedUsrsAndGoToAct (&Gbl.Usrs.Selected, Brw_ShowFileBrowserOrWorksInternal,NULL, // when user(s) selected Brw_AskEditWorksCrsInternal,NULL); // when no user selected } /*****************************************************************************/ /******************** Show a file browser or users' works *******************/ /*****************************************************************************/ void Brw_ShowFileBrowserOrWorks (void) { Brw_ShowFileBrowserOrWorksInternal (NULL); } static void Brw_ShowFileBrowserOrWorksInternal (__attribute__((unused)) void *Args) { /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); /***** Show the file browser or works *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /******************* Show a file browser or users' works ********************/ /*****************************************************************************/ void Brw_ShowAgainFileBrowserOrWorks (void) { extern const char *Txt_Files_of_marks_must_contain_a_table_in_HTML_format_; extern const char *Txt_Disclaimer_the_files_hosted_here_; if (Brw_GetIfUsrAssigWorksFileBrowser ()) Brw_ShowFileBrowsersAsgWrkUsr (); else if (Brw_GetIfCrsAssigWorksFileBrowser ()) Brw_ShowFileBrowsersAsgWrkCrs (); else if (Brw_GetIfProjectFileBrowser ()) Prj_ShowOneProject (); else Brw_ShowFileBrowserNormal (); /***** Help *****/ switch (Gbl.FileBrowser.Type) { case Brw_ADMI_MRK_CRS: case Brw_ADMI_MRK_GRP: Ale_ShowAlert (Ale_INFO,Txt_Files_of_marks_must_contain_a_table_in_HTML_format_); break; default: break; } /***** Legal notice *****/ Ale_ShowAlert (Ale_INFO,Txt_Disclaimer_the_files_hosted_here_, Cfg_PLATFORM_SHORT_NAME, Cfg_PLATFORM_RESPONSIBLE_EMAIL); } /*****************************************************************************/ /**************************** Show a file browser ****************************/ /*****************************************************************************/ static void Brw_ShowFileBrowser (void) { extern const char *Hlp_FILES_Documents; extern const char *Hlp_FILES_Shared; extern const char *Hlp_FILES_Documents; extern const char *Hlp_FILES_Shared; extern const char *Hlp_FILES_Documents; extern const char *Hlp_FILES_Shared; extern const char *Hlp_FILES_Documents; extern const char *Hlp_FILES_Private; extern const char *Hlp_FILES_Shared; extern const char *Hlp_FILES_Homework_for_students; extern const char *Hlp_FILES_Homework_for_teachers; extern const char *Hlp_FILES_Marks; extern const char *Hlp_FILES_Briefcase; extern const char *Hlp_ASSESSMENT_Projects; extern const char *Txt_Documents_area; extern const char *Txt_Documents_management_area; extern const char *Txt_Teachers_files_area; extern const char *Txt_Shared_files_area; extern const char *Txt_Marks_area; extern const char *Txt_Marks_management_area; extern const char *Txt_Assignments_area; extern const char *Txt_Works_area; extern const char *Txt_Temporary_private_storage_area; extern const char *Txt_Project_documents; extern const char *Txt_Project_assessment; static const char **Brw_TitleOfFileBrowser[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = NULL, [Brw_SHOW_DOC_CRS] = &Txt_Documents_area, [Brw_SHOW_MRK_CRS] = &Txt_Marks_area, [Brw_ADMI_DOC_CRS] = &Txt_Documents_management_area, [Brw_ADMI_SHR_CRS] = &Txt_Shared_files_area, [Brw_ADMI_SHR_GRP] = &Txt_Shared_files_area, [Brw_ADMI_WRK_USR] = &Txt_Works_area, [Brw_ADMI_WRK_CRS] = &Txt_Works_area, [Brw_ADMI_MRK_CRS] = &Txt_Marks_management_area, [Brw_ADMI_BRF_USR] = &Txt_Temporary_private_storage_area, [Brw_SHOW_DOC_GRP] = &Txt_Documents_area, [Brw_ADMI_DOC_GRP] = &Txt_Documents_management_area, [Brw_SHOW_MRK_GRP] = &Txt_Marks_area, [Brw_ADMI_MRK_GRP] = &Txt_Marks_management_area, [Brw_ADMI_ASG_USR] = &Txt_Assignments_area, [Brw_ADMI_ASG_CRS] = &Txt_Assignments_area, [Brw_SHOW_DOC_DEG] = &Txt_Documents_area, [Brw_ADMI_DOC_DEG] = &Txt_Documents_management_area, [Brw_SHOW_DOC_CTR] = &Txt_Documents_area, [Brw_ADMI_DOC_CTR] = &Txt_Documents_management_area, [Brw_SHOW_DOC_INS] = &Txt_Documents_area, [Brw_ADMI_DOC_INS] = &Txt_Documents_management_area, [Brw_ADMI_SHR_DEG] = &Txt_Shared_files_area, [Brw_ADMI_SHR_CTR] = &Txt_Shared_files_area, [Brw_ADMI_SHR_INS] = &Txt_Shared_files_area, [Brw_ADMI_TCH_CRS] = &Txt_Teachers_files_area, [Brw_ADMI_TCH_GRP] = &Txt_Teachers_files_area, [Brw_ADMI_DOC_PRJ] = &Txt_Project_documents, [Brw_ADMI_ASS_PRJ] = &Txt_Project_assessment, }; static const char **Brw_HelpOfFileBrowser[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = NULL, [Brw_SHOW_DOC_CRS] = &Hlp_FILES_Documents, [Brw_SHOW_MRK_CRS] = &Hlp_FILES_Marks, [Brw_ADMI_DOC_CRS] = &Hlp_FILES_Documents, [Brw_ADMI_SHR_CRS] = &Hlp_FILES_Shared, [Brw_ADMI_SHR_GRP] = &Hlp_FILES_Shared, [Brw_ADMI_WRK_USR] = &Hlp_FILES_Homework_for_students, [Brw_ADMI_WRK_CRS] = &Hlp_FILES_Homework_for_teachers, [Brw_ADMI_MRK_CRS] = &Hlp_FILES_Marks, [Brw_ADMI_BRF_USR] = &Hlp_FILES_Briefcase, [Brw_SHOW_DOC_GRP] = &Hlp_FILES_Documents, [Brw_ADMI_DOC_GRP] = &Hlp_FILES_Documents, [Brw_SHOW_MRK_GRP] = &Hlp_FILES_Marks, [Brw_ADMI_MRK_GRP] = &Hlp_FILES_Marks, [Brw_ADMI_ASG_USR] = &Hlp_FILES_Homework_for_students, [Brw_ADMI_ASG_CRS] = &Hlp_FILES_Homework_for_teachers, [Brw_SHOW_DOC_DEG] = &Hlp_FILES_Documents, [Brw_ADMI_DOC_DEG] = &Hlp_FILES_Documents, [Brw_SHOW_DOC_CTR] = &Hlp_FILES_Documents, [Brw_ADMI_DOC_CTR] = &Hlp_FILES_Documents, [Brw_SHOW_DOC_INS] = &Hlp_FILES_Documents, [Brw_ADMI_DOC_INS] = &Hlp_FILES_Documents, [Brw_ADMI_SHR_DEG] = &Hlp_FILES_Shared, [Brw_ADMI_SHR_CTR] = &Hlp_FILES_Shared, [Brw_ADMI_SHR_INS] = &Hlp_FILES_Shared, [Brw_ADMI_TCH_CRS] = &Hlp_FILES_Private, [Brw_ADMI_TCH_GRP] = &Hlp_FILES_Private, [Brw_ADMI_DOC_PRJ] = &Hlp_ASSESSMENT_Projects, [Brw_ADMI_ASS_PRJ] = &Hlp_ASSESSMENT_Projects, }; struct Brw_NumObjects Removed; char FileBrowserSectionId[32]; bool IAmTeacherOrSysAdm = Gbl.Usrs.Me.Role.Logged == Rol_TCH || Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM; struct BrwSiz_BrowserSize *Size = BrwSiz_GetSize (); /***** Set contextual icon in box *****/ Gbl.FileBrowser.IconViewEdit = Brw_ICON_NONE; switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_INS: if (Gbl.Usrs.Me.Role.Logged >= Rol_INS_ADM) Gbl.FileBrowser.IconViewEdit = Brw_ICON_EDIT; break; case Brw_ADMI_DOC_INS: if (Gbl.Usrs.Me.Role.Logged >= Rol_INS_ADM) Gbl.FileBrowser.IconViewEdit = Brw_ICON_VIEW; break; case Brw_SHOW_DOC_CTR: if (Gbl.Usrs.Me.Role.Logged >= Rol_CTR_ADM) Gbl.FileBrowser.IconViewEdit = Brw_ICON_EDIT; break; case Brw_ADMI_DOC_CTR: if (Gbl.Usrs.Me.Role.Logged >= Rol_CTR_ADM) Gbl.FileBrowser.IconViewEdit = Brw_ICON_VIEW; break; case Brw_SHOW_DOC_DEG: if (Gbl.Usrs.Me.Role.Logged >= Rol_DEG_ADM) Gbl.FileBrowser.IconViewEdit = Brw_ICON_EDIT; break; case Brw_ADMI_DOC_DEG: if (Gbl.Usrs.Me.Role.Logged >= Rol_DEG_ADM) Gbl.FileBrowser.IconViewEdit = Brw_ICON_VIEW; break; case Brw_SHOW_DOC_CRS: case Brw_SHOW_DOC_GRP: case Brw_SHOW_MRK_CRS: case Brw_SHOW_MRK_GRP: if (IAmTeacherOrSysAdm) Gbl.FileBrowser.IconViewEdit = Brw_ICON_EDIT; break; case Brw_ADMI_DOC_CRS: case Brw_ADMI_DOC_GRP: case Brw_ADMI_MRK_CRS: case Brw_ADMI_MRK_GRP: if (IAmTeacherOrSysAdm) Gbl.FileBrowser.IconViewEdit = Brw_ICON_VIEW; break; default: break; } /***** Every time user clicks in menu option to view his/her (temporary) briefcase ==> remove old files *****/ if (Gbl.Action.Act == ActAdmBrf) /* There are two reasons to not remove old files on any action in briefcase: 1) To avoid wasting time unnecessarily 2) To allow copying of files from briefcase, because the clipboard is deleted every time file browswer changes */ Brw_RemoveOldFilesInBrowser (Brw_MAX_MONTHS_IN_BRIEFCASE, &Removed); // Not used here /***** Check if the maximum quota has been exceeded *****/ if (Brw_CheckIfFileBrowserIsEditable (Gbl.FileBrowser.Type)) BrwSiz_SetAndCheckQuota (Size); /***** Check if the clipboard is in this tree *****/ Gbl.FileBrowser.Clipboard.IsThisTree = Brw_CheckIfClipboardIsInThisTree (); /***** Begin box *****/ Gbl.FileBrowser.Id++; snprintf (FileBrowserSectionId,sizeof (FileBrowserSectionId), "file_browser_%u",Gbl.FileBrowser.Id); HTM_SECTION_Begin (FileBrowserSectionId); Box_BoxBegin ("100%",*Brw_TitleOfFileBrowser[Gbl.FileBrowser.Type], Brw_PutIconsFileBrowser,NULL, *Brw_HelpOfFileBrowser[Gbl.FileBrowser.Type],Box_NOT_CLOSABLE); /***** Subtitle *****/ Brw_WriteSubtitleOfFileBrowser (); /***** List recursively the directory *****/ HTM_TABLE_Begin ("BROWSER_TABLE"); Str_Copy (Gbl.FileBrowser.FilFolLnk.Path, Brw_RootFolderInternalNames[Gbl.FileBrowser.Type], sizeof (Gbl.FileBrowser.FilFolLnk.Path) - 1); Str_Copy (Gbl.FileBrowser.FilFolLnk.Name,".", sizeof (Gbl.FileBrowser.FilFolLnk.Name) - 1); Brw_SetFullPathInTree (); Gbl.FileBrowser.FilFolLnk.Type = Brw_IS_FOLDER; if (Brw_WriteRowFileBrowser (0,"1", false, // Tree not contracted Brw_ICON_TREE_NOTHING)) Brw_ListDir (1,"1", false, // Tree not contracted Gbl.FileBrowser.Priv.PathRootFolder, Brw_RootFolderInternalNames[Gbl.FileBrowser.Type]); HTM_TABLE_End (); /***** Show and store number of documents found *****/ BrwSiz_ShowAndStoreSizeOfFileBrowser (Size); /***** Put button to show / edit *****/ Brw_PutButtonToShowEdit (); /***** End box *****/ Box_BoxEnd (); HTM_SECTION_End (); } /*****************************************************************************/ /******************* Put contextual icons in file browser ********************/ /*****************************************************************************/ static void Brw_PutIconsFileBrowser (__attribute__((unused)) void *Args) { /***** Put icon to view / edit file browser *****/ switch (Gbl.FileBrowser.IconViewEdit) { case Brw_ICON_NONE: break; case Brw_ICON_VIEW: Ico_PutContextualIconToView (Brw_ActFromAdmToSee[Gbl.FileBrowser.Type],NULL, Brw_PutParFullTreeIfSelected,&Gbl.FileBrowser.FullTree); break; case Brw_ICON_EDIT: Ico_PutContextualIconToEdit (Brw_ActFromSeeToAdm[Gbl.FileBrowser.Type],NULL, Brw_PutParFullTreeIfSelected,&Gbl.FileBrowser.FullTree); break; } /***** Put icon to get resource link *****/ if (Brw_ActReqLnk[Gbl.FileBrowser.Type] != ActUnk && Rsc_CheckIfICanGetLink ()) Ico_PutContextualIconToGetLink (Brw_ActReqLnk[Gbl.FileBrowser.Type],NULL, NULL,NULL); /***** Put icon to show a figure *****/ switch (Gbl.FileBrowser.Type) { case Brw_ADMI_WRK_CRS: case Brw_ADMI_ASG_CRS: case Brw_ADMI_DOC_PRJ: case Brw_ADMI_ASS_PRJ: break; default: Brw_PutIconShowFigure (NULL); break; } } static void Brw_PutIconShowFigure (__attribute__((unused)) void *Args) { /***** Put icon to show a figure *****/ Fig_PutIconToShowFigure (Fig_FOLDERS_AND_FILES); } /*****************************************************************************/ /***************** Put button to view / edit file browser ********************/ /*****************************************************************************/ static void Brw_PutButtonToShowEdit (void) { switch (Gbl.FileBrowser.IconViewEdit) { case Brw_ICON_NONE: break; case Brw_ICON_VIEW: if (Brw_ActFromAdmToSee[Gbl.FileBrowser.Type] != ActUnk) { Frm_BeginForm (Brw_ActFromAdmToSee[Gbl.FileBrowser.Type]); Brw_PutParFullTreeIfSelected (&Gbl.FileBrowser.FullTree); Btn_PutConfirmButton (Act_GetActionText (Brw_ActFromAdmToSee[Gbl.FileBrowser.Type])); Frm_EndForm (); } break; case Brw_ICON_EDIT: if (Brw_ActFromSeeToAdm[Gbl.FileBrowser.Type] != ActUnk) { Frm_BeginForm (Brw_ActFromSeeToAdm[Gbl.FileBrowser.Type]); Brw_PutParFullTreeIfSelected (&Gbl.FileBrowser.FullTree); Btn_PutConfirmButton (Act_GetActionText (Brw_ActFromSeeToAdm[Gbl.FileBrowser.Type])); Frm_EndForm (); } break; } } /*****************************************************************************/ /********************** Write title of a file browser ************************/ /*****************************************************************************/ static void Brw_WriteTopBeforeShowingFileBrowser (void) { /***** Update last access to this file browser *****/ Brw_UpdateLastAccess (); /***** Contextual menu *****/ Mnu_ContextMenuBegin (); Brw_PutCheckboxFullTree (); // Checkbox to show the full tree if (Brw_GetIfBriefcaseFileBrowser ()) { if (Gbl.Action.Act != ActReqRemOldBrf) Brw_PutLinkToAskRemOldFiles (); // Remove old files } else if (Brw_GetIfCrsAssigWorksFileBrowser ()) { if (!Gbl.FileBrowser.ZIP.CreateZIP) ZIP_PutLinkToCreateZIPAsgWrk (); // Create a zip file with the // works of the selected users } Mnu_ContextMenuEnd (); /***** Initialize hidden levels *****/ switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_INS: case Brw_ADMI_DOC_INS: case Brw_SHOW_DOC_CTR: case Brw_ADMI_DOC_CTR: case Brw_SHOW_DOC_DEG: case Brw_ADMI_DOC_DEG: case Brw_SHOW_DOC_CRS: case Brw_ADMI_DOC_CRS: case Brw_SHOW_DOC_GRP: case Brw_ADMI_DOC_GRP: case Brw_SHOW_MRK_CRS: case Brw_ADMI_MRK_CRS: case Brw_SHOW_MRK_GRP: case Brw_ADMI_MRK_GRP: Brw_InitHiddenLevels (); break; default: break; } /***** If browser is editable, get and write current clipboard *****/ if (Brw_CheckIfFileBrowserIsEditable (Gbl.FileBrowser.Type)) if (Brw_GetMyClipboard ()) Brw_WriteCurrentClipboard (); } /*****************************************************************************/ /******************* Update last access to a file browser ********************/ /*****************************************************************************/ static void Brw_UpdateLastAccess (void) { /***** Get and update date and hour of last access to file browser *****/ Brw_GetAndUpdateDateLastAccFileBrowser (); switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_CRS: case Brw_ADMI_DOC_CRS: case Brw_ADMI_TCH_CRS: if (Gbl.Action.Act == ActChgToSeeDocCrs || Gbl.Action.Act == ActChgToAdmDocCrs || Gbl.Action.Act == ActChgToAdmTch) // Update group of last access to a documents/teachers zone only when user changes zone Set_DB_UpdateGrpMyLastAccZone ("LastDowGrpCod",-1L); break; case Brw_SHOW_DOC_GRP: case Brw_ADMI_DOC_GRP: case Brw_ADMI_TCH_GRP: if (Gbl.Action.Act == ActChgToSeeDocCrs || Gbl.Action.Act == ActChgToAdmDocCrs || Gbl.Action.Act == ActChgToAdmTch) // Update group of last access to a documents/teachers zone only when user changes zone Set_DB_UpdateGrpMyLastAccZone ("LastDowGrpCod",Gbl.Crs.Grps.GrpCod); break; case Brw_ADMI_SHR_CRS: if (Gbl.Action.Act == ActChgToAdmSha) // Update group of last access to a shared files zone only when user changes zone Set_DB_UpdateGrpMyLastAccZone ("LastComGrpCod",-1L); break; case Brw_ADMI_SHR_GRP: if (Gbl.Action.Act == ActChgToAdmSha) // Update group of last access to a shared files zone only when user changes zone Set_DB_UpdateGrpMyLastAccZone ("LastComGrpCod",Gbl.Crs.Grps.GrpCod); break; case Brw_SHOW_MRK_CRS: case Brw_ADMI_MRK_CRS: if (Gbl.Action.Act == ActChgToSeeMrk || Gbl.Action.Act == ActChgToAdmMrk) // Update group of last access to a marks zone only when user changes zone Set_DB_UpdateGrpMyLastAccZone ("LastAssGrpCod",-1L); break; case Brw_SHOW_MRK_GRP: case Brw_ADMI_MRK_GRP: if (Gbl.Action.Act == ActChgToSeeMrk || Gbl.Action.Act == ActChgToAdmMrk) // Update group of last access to a marks zone only when user changes zone Set_DB_UpdateGrpMyLastAccZone ("LastAssGrpCod",Gbl.Crs.Grps.GrpCod); break; default: break; } } /*****************************************************************************/ /*********************** Write title of a file browser ***********************/ /*****************************************************************************/ static void Brw_WriteSubtitleOfFileBrowser (void) { extern const char *Txt_accessible_only_for_reading_by_students_and_teachers_of_the_institution; extern const char *Txt_accessible_for_reading_and_writing_by_administrators_of_the_institution; extern const char *Txt_accessible_for_reading_and_writing_by_students_and_teachers_of_the_institution; extern const char *Txt_accessible_only_for_reading_by_students_and_teachers_of_the_center; extern const char *Txt_accessible_for_reading_and_writing_by_administrators_of_the_center; extern const char *Txt_accessible_for_reading_and_writing_by_students_and_teachers_of_the_center; extern const char *Txt_accessible_only_for_reading_by_students_and_teachers_of_the_degree; extern const char *Txt_accessible_for_reading_and_writing_by_administrators_of_the_degree; extern const char *Txt_accessible_for_reading_and_writing_by_students_and_teachers_of_the_degree; extern const char *Txt_accessible_only_for_reading_by_students_and_teachers_of_the_course; extern const char *Txt_accessible_only_for_reading_by_students_of_the_group_and_teachers_of_the_course; extern const char *Txt_accessible_for_reading_and_writing_by_teachers_of_the_course; extern const char *Txt_accessible_for_reading_and_writing_by_students_and_teachers_of_the_course; extern const char *Txt_accessible_for_reading_and_writing_by_students_of_the_group_and_teachers_of_the_course; extern const char *Txt_accessible_for_reading_and_writing_by_you_and_the_teachers_of_the_course; extern const char *Txt_accessible_only_for_reading_by_you_and_the_teachers_of_the_course; extern const char *Txt_the_marks_of_a_student_chosen_at_random_; extern const char *Txt_accessible_for_reading_and_writing_by_project_members; extern const char *Txt_accessible_for_reading_and_writing_by_project_tutors_and_evaluators; extern const char *Txt_nobody_else_can_access_this_content; char Subtitle[1024 + Usr_MAX_BYTES_FULL_NAME]; /***** Form to change zone (course and group browsers) *****/ switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_CRS: case Brw_ADMI_DOC_CRS: case Brw_SHOW_DOC_GRP: case Brw_ADMI_DOC_GRP: case Brw_ADMI_TCH_CRS: case Brw_ADMI_TCH_GRP: case Brw_ADMI_SHR_CRS: case Brw_ADMI_SHR_GRP: case Brw_SHOW_MRK_CRS: case Brw_ADMI_MRK_CRS: case Brw_SHOW_MRK_GRP: case Brw_ADMI_MRK_GRP: Brw_FormToChangeCrsGrpZone (); break; default: break; } /***** Write subtitle *****/ switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_INS: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_only_for_reading_by_students_and_teachers_of_the_institution); break; case Brw_ADMI_DOC_INS: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_for_reading_and_writing_by_administrators_of_the_institution); break; case Brw_ADMI_SHR_INS: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_for_reading_and_writing_by_students_and_teachers_of_the_institution); break; case Brw_SHOW_DOC_CTR: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_only_for_reading_by_students_and_teachers_of_the_center); break; case Brw_ADMI_DOC_CTR: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_for_reading_and_writing_by_administrators_of_the_center); break; case Brw_ADMI_SHR_CTR: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_for_reading_and_writing_by_students_and_teachers_of_the_center); break; case Brw_SHOW_DOC_DEG: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_only_for_reading_by_students_and_teachers_of_the_degree); break; case Brw_ADMI_DOC_DEG: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_for_reading_and_writing_by_administrators_of_the_degree); break; case Brw_ADMI_SHR_DEG: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_for_reading_and_writing_by_students_and_teachers_of_the_degree); break; case Brw_SHOW_DOC_CRS: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_only_for_reading_by_students_and_teachers_of_the_course); break; case Brw_SHOW_DOC_GRP: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_only_for_reading_by_students_of_the_group_and_teachers_of_the_course); break; case Brw_ADMI_DOC_CRS: case Brw_ADMI_DOC_GRP: case Brw_ADMI_TCH_CRS: case Brw_ADMI_TCH_GRP: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_for_reading_and_writing_by_teachers_of_the_course); break; case Brw_ADMI_SHR_CRS: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_for_reading_and_writing_by_students_and_teachers_of_the_course); break; case Brw_ADMI_SHR_GRP: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_for_reading_and_writing_by_students_of_the_group_and_teachers_of_the_course); break; case Brw_SHOW_MRK_CRS: case Brw_SHOW_MRK_GRP: switch (Gbl.Usrs.Me.Role.Logged) { case Rol_STD: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_only_for_reading_by_you_and_the_teachers_of_the_course); break; case Rol_NET: case Rol_TCH: case Rol_SYS_ADM: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_the_marks_of_a_student_chosen_at_random_); break; default: Subtitle[0] = '\0'; Err_WrongRoleExit (); break; } break; case Brw_ADMI_MRK_CRS: case Brw_ADMI_MRK_GRP: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_for_reading_and_writing_by_teachers_of_the_course); break; case Brw_ADMI_ASG_USR: case Brw_ADMI_WRK_USR: snprintf (Subtitle,sizeof (Subtitle),"%s
(%s)", Gbl.Usrs.Me.UsrDat.FullName, Txt_accessible_for_reading_and_writing_by_you_and_the_teachers_of_the_course); break; case Brw_ADMI_ASG_CRS: case Brw_ADMI_WRK_CRS: snprintf (Subtitle,sizeof (Subtitle),"%s", Gbl.Usrs.Other.UsrDat.FullName); break; case Brw_ADMI_DOC_PRJ: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_for_reading_and_writing_by_project_members); break; case Brw_ADMI_ASS_PRJ: snprintf (Subtitle,sizeof (Subtitle),"(%s)", Txt_accessible_for_reading_and_writing_by_project_tutors_and_evaluators); break; case Brw_ADMI_BRF_USR: snprintf (Subtitle,sizeof (Subtitle),"%s
(%s)", Gbl.Usrs.Me.UsrDat.FullName, Txt_nobody_else_can_access_this_content); break; case Brw_UNKNOWN: return; } if (Subtitle[0]) { HTM_DIV_Begin ("class=\"BROWSER_SUBTITLE\""); HTM_Txt (Subtitle); HTM_DIV_End (); } } /*****************************************************************************/ /************ Initialize hidden levels of file browser to false **************/ /*****************************************************************************/ static void Brw_InitHiddenLevels (void) { unsigned Level; for (Level = 0; Level <= BrwSiz_MAX_DIR_LEVELS; Level++) Gbl.FileBrowser.HiddenLevels[Level] = false; } /*****************************************************************************/ /************** Write a form to select whether show full tree ****************/ /*****************************************************************************/ static void Brw_PutCheckboxFullTree (void) { extern const char *Txt_Show_all_files; Lay_PutContextualCheckbox (Brw_ActSeeAdm[Gbl.FileBrowser.Type], Brw_PutParsFullTree, "FullTree", Gbl.FileBrowser.FullTree,false, Txt_Show_all_files,Txt_Show_all_files); } static void Brw_PutParsFullTree (void) { if (Brw_GetIfGroupFileBrowser ()) ParCod_PutPar (ParCod_Grp,Gbl.Crs.Grps.GrpCod); else if (Brw_GetIfProjectFileBrowser ()) // This file browser needs specify a project ParCod_PutPar (ParCod_Prj,Prj_GetPrjCod ()); else if (Brw_GetIfCrsAssigWorksFileBrowser ()) Usr_PutParSelectedUsrsCods (&Gbl.Usrs.Selected); } /*****************************************************************************/ /********* Put hidden parameter "full tree" if full tree is selected *********/ /*****************************************************************************/ void Brw_PutParFullTreeIfSelected (void *FullTree) { if (FullTree) if (*((bool *) FullTree)) // Put hidden parameter only if full tree selected Par_PutParChar ("FullTree",'Y'); } /*****************************************************************************/ /******************* Get whether to show full tree from form *****************/ /*****************************************************************************/ static bool Brw_GetFullTreeFromForm (void) { return Par_GetParBool ("FullTree"); } /*****************************************************************************/ /********* Get if the current file browser is a group file browser ***********/ /*****************************************************************************/ static bool Brw_GetIfGroupFileBrowser (void) { switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_GRP: case Brw_ADMI_DOC_GRP: case Brw_ADMI_TCH_GRP: case Brw_ADMI_SHR_GRP: case Brw_SHOW_MRK_GRP: case Brw_ADMI_MRK_GRP: return true; default: return false; } } /*****************************************************************************/ /******** Get if the current file browser is a project file browser **********/ /*****************************************************************************/ static bool Brw_GetIfProjectFileBrowser (void) { switch (Gbl.FileBrowser.Type) { case Brw_ADMI_DOC_PRJ: // Project documents case Brw_ADMI_ASS_PRJ: // Project assessment return true; default: return false; } } /*****************************************************************************/ /****** Get if the current file browser is course assignments or works *******/ /*****************************************************************************/ static bool Brw_GetIfBriefcaseFileBrowser (void) { return (Gbl.FileBrowser.Type == Brw_ADMI_BRF_USR); } /*****************************************************************************/ /****** Get if the current file browser is course assignments or works *******/ /*****************************************************************************/ static bool Brw_GetIfUsrAssigWorksFileBrowser (void) { switch (Gbl.FileBrowser.Type) { case Brw_ADMI_ASG_USR: // My assignments case Brw_ADMI_WRK_USR: // My works return true; default: return false; } } /*****************************************************************************/ /****** Get if the current file browser is course assignments or works *******/ /*****************************************************************************/ static bool Brw_GetIfCrsAssigWorksFileBrowser (void) { switch (Gbl.FileBrowser.Type) { case Brw_ADMI_ASG_CRS: // Course assignments case Brw_ADMI_WRK_CRS: // Course works return true; default: return false; } } /*****************************************************************************/ /******** Create a temporary public directory used to download files *********/ /*****************************************************************************/ void Brw_CreateDirDownloadTmp (void) { static unsigned NumDir = 0; // When this function is called several times in the same execution of the program, each time a new directory is created // This happens when the trees of assignments and works of several users are being listed char PathUniqueDirL[PATH_MAX + 1]; char PathUniqueDirR[PATH_MAX + 1 + NAME_MAX + 1]; const char *UniqueNameEncrypted = Cry_GetUniqueNameEncrypted (); /* Example: /var/www/html/swad/tmp/SS/ujCNWsy4ZOdmgMKYBe0sKPAJu6szaZOQlIlJs_QIY */ /***** If the public directory does not exist, create it *****/ Fil_CreateDirIfNotExists (Cfg_PATH_FILE_BROWSER_TMP_PUBLIC); /***** Unique temporary directory. Important: number of directories inside a directory is limited to 32K in Linux ==> create directories in two levels *****/ /* 1. Build the name of the directory, splitted in two parts: */ /* 1a: 2 leftmost chars */ Gbl.FileBrowser.TmpPubDir.L[0] = UniqueNameEncrypted[0]; Gbl.FileBrowser.TmpPubDir.L[1] = UniqueNameEncrypted[1]; Gbl.FileBrowser.TmpPubDir.L[2] = '\0'; /* 1b: rest of chars */ if (NumDir) snprintf (Gbl.FileBrowser.TmpPubDir.R,sizeof (Gbl.FileBrowser.TmpPubDir.R), "%s_%u",&UniqueNameEncrypted[2],NumDir); else Str_Copy (Gbl.FileBrowser.TmpPubDir.R,&UniqueNameEncrypted[2], sizeof (Gbl.FileBrowser.TmpPubDir.R) - 1); /* 2. Create the left directory */ snprintf (PathUniqueDirL,sizeof (PathUniqueDirL),"%s/%s", Cfg_PATH_FILE_BROWSER_TMP_PUBLIC,Gbl.FileBrowser.TmpPubDir.L); Fil_CreateDirIfNotExists (PathUniqueDirL); /* 3. Create the right directory inside the left one */ snprintf (PathUniqueDirR,sizeof (PathUniqueDirR),"%s/%s", PathUniqueDirL,Gbl.FileBrowser.TmpPubDir.R); if (mkdir (PathUniqueDirR,(mode_t) 0xFFF)) Err_ShowErrorAndExit ("Can not create a temporary folder for download."); /* 4. Increase number of directory for next call */ NumDir++; } /*****************************************************************************/ /* Get and update the date of my last access to file browser in this course **/ /*****************************************************************************/ static void Brw_GetAndUpdateDateLastAccFileBrowser (void) { MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned NumRows; /***** Get date of last accesss to a file browser from database *****/ NumRows = Brw_DB_GetDateMyLastAccFileBrowser (&mysql_res); if (NumRows == 0) // May be an administrator not belonging to this course Gbl.Usrs.Me.TimeLastAccToThisFileBrowser = LONG_MAX; // Initialize to a big value in order to show files as old else if (NumRows == 1) { /* Get the date of the last access to file browser (row[0]) */ row = mysql_fetch_row (mysql_res); if (row[0] == NULL) Gbl.Usrs.Me.TimeLastAccToThisFileBrowser = 0; else if (sscanf (row[0],"%ld",&Gbl.Usrs.Me.TimeLastAccToThisFileBrowser) != 1) Err_ShowErrorAndExit ("Error when reading date-time of last access to a file browser."); } else Err_ShowErrorAndExit ("Error when getting date-time of last access to a file browser."); /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); /***** Update date of my last access to file browser in this course *****/ Brw_DB_UpdateDateMyLastAccFileBrowser (); } /*****************************************************************************/ /************* Get the group of my last access to a file browser *************/ /*****************************************************************************/ long Brw_GetGrpLastAccZone (const char *FieldNameDB) { MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned NumGrps; long GrpCod = -1L; /***** Get the group of my last access to a file browser *****/ NumGrps = Brw_DB_GetGrpLastAccFileBrowser (&mysql_res,FieldNameDB); if (NumGrps == 0) // May be an administrator not belonging to this course GrpCod = -1L; else if (NumGrps == 1) { /* Get the group code (row[0]) */ row = mysql_fetch_row (mysql_res); if (row[0]) { if (sscanf (row[0],"%ld",&GrpCod) != 1) Err_ShowErrorAndExit ("Error when reading the group of your last access to a file browser."); } else GrpCod = -1L; } else Err_ShowErrorAndExit ("Error when getting the group of your last access to a file browser."); /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); /***** Check if group exists (it's possible that this group has been removed after my last access to it) *****/ if (GrpCod >= 0) if (Grp_DB_CheckIfGrpExists (GrpCod)) /* Check if I belong to this group (it's possible that I have been removed from this group after my last access to it) */ if (Grp_GetIfIBelongToGrp (GrpCod)) return GrpCod; return -1L; // To indicate course zone } /*****************************************************************************/ /************************ List a directory recursively ***********************/ /*****************************************************************************/ static void Brw_ListDir (unsigned Level,const char *ParentRowId, bool TreeContracted, const char Path[PATH_MAX + 1], const char PathInTree[PATH_MAX + 1]) { struct dirent **FileList; struct dirent **SubdirFileList; int NumFile; int NumFiles; int NumFileInSubdir; int NumFilesInSubdir; unsigned NumRow; char RowId[Brw_MAX_ROW_ID + 1]; char PathFileRel[PATH_MAX + 1]; char PathFileInExplTree[PATH_MAX + 1]; struct stat FileStatus; Brw_IconTree_t IconSubtree = Brw_ICON_TREE_NOTHING; // Initialized to avoid warning /***** Scan directory *****/ if ((NumFiles = scandir (Path,&FileList,NULL,alphasort)) >= 0) // No error { /***** List files *****/ for (NumFile = 0, NumRow = 0; NumFile < NumFiles; NumFile++) { if (strcmp (FileList[NumFile]->d_name,".") && strcmp (FileList[NumFile]->d_name,"..")) // Skip directories "." and ".." { /***** Construct the full path of the file or folder *****/ snprintf (PathFileRel ,sizeof (PathFileRel ),"%s/%s", Path ,FileList[NumFile]->d_name); snprintf (PathFileInExplTree,sizeof (PathFileInExplTree),"%s/%s", PathInTree,FileList[NumFile]->d_name); Str_Copy (Gbl.FileBrowser.FilFolLnk.Path,PathInTree, sizeof (Gbl.FileBrowser.FilFolLnk.Path) - 1); Str_Copy (Gbl.FileBrowser.FilFolLnk.Name,FileList[NumFile]->d_name, sizeof (Gbl.FileBrowser.FilFolLnk.Name) - 1); Brw_SetFullPathInTree (); /***** Add number of row to parent row id *****/ NumRow++; snprintf (RowId,sizeof (RowId),"%s_%u",ParentRowId,NumRow); /***** Get file or folder status *****/ if (lstat (PathFileRel,&FileStatus)) // On success ==> 0 is returned Err_ShowErrorAndExit ("Can not get information about a file or folder."); else if (S_ISDIR (FileStatus.st_mode)) // It's a directory { Gbl.FileBrowser.FilFolLnk.Type = Brw_IS_FOLDER; if (Gbl.FileBrowser.FullTree) IconSubtree = Brw_ICON_TREE_NOTHING; else { /***** Check if this subdirectory has files or folders in it *****/ if ((NumFilesInSubdir = scandir (PathFileRel,&SubdirFileList,NULL,NULL)) >= 0) // No error { if (NumFilesInSubdir <= 2) IconSubtree = Brw_ICON_TREE_NOTHING; else /***** Check if the tree starting at this subdirectory must be expanded *****/ IconSubtree = Brw_DB_GetIfExpandedFolder (Gbl.FileBrowser.FilFolLnk.Full) ? Brw_ICON_TREE_CONTRACT : Brw_ICON_TREE_EXPAND; for (NumFileInSubdir = 0; NumFileInSubdir < NumFilesInSubdir; NumFileInSubdir++) free (SubdirFileList[NumFileInSubdir]); free (SubdirFileList); } else Err_ShowErrorAndExit ("Error while scanning directory."); } /***** Write a row for the subdirectory *****/ if (Brw_WriteRowFileBrowser (Level,RowId, TreeContracted, IconSubtree)) if (Level < BrwSiz_MAX_DIR_LEVELS) /* List subtree starting at this this directory */ Brw_ListDir (Level + 1,RowId, TreeContracted || IconSubtree == Brw_ICON_TREE_EXPAND, PathFileRel,PathFileInExplTree); } else if (S_ISREG (FileStatus.st_mode)) // It's a regular file { Gbl.FileBrowser.FilFolLnk.Type = Str_FileIs (Gbl.FileBrowser.FilFolLnk.Name,"url") ? Brw_IS_LINK : Brw_IS_FILE; Brw_WriteRowFileBrowser (Level,RowId, TreeContracted, Brw_ICON_TREE_NOTHING); } } free (FileList[NumFile]); } free (FileList); } else Err_ShowErrorAndExit ("Error while scanning directory."); } /*****************************************************************************/ /*********************** Write a row of a file browser ***********************/ /*****************************************************************************/ // If it is the first row (root folder), always show it // If it is not the first row, it is shown or not depending on whether it is hidden or not // If the row is visible, return true. If it is hidden, return false static bool Brw_WriteRowFileBrowser (unsigned Level,const char *RowId, bool TreeContracted, Brw_IconTree_t IconThisRow) { char *Anchor; bool RowSetAsHidden = false; bool RowSetAsPublic = false; bool LightStyle = false; bool IsRecent = false; struct Brw_FileMetadata FileMetadata; char FileBrowserId[32]; bool SeeDocsZone = Gbl.FileBrowser.Type == Brw_SHOW_DOC_INS || Gbl.FileBrowser.Type == Brw_SHOW_DOC_CTR || Gbl.FileBrowser.Type == Brw_SHOW_DOC_DEG || Gbl.FileBrowser.Type == Brw_SHOW_DOC_CRS || Gbl.FileBrowser.Type == Brw_SHOW_DOC_GRP; bool AdminDocsZone = Gbl.FileBrowser.Type == Brw_ADMI_DOC_INS || Gbl.FileBrowser.Type == Brw_ADMI_DOC_CTR || Gbl.FileBrowser.Type == Brw_ADMI_DOC_DEG || Gbl.FileBrowser.Type == Brw_ADMI_DOC_CRS || Gbl.FileBrowser.Type == Brw_ADMI_DOC_GRP; bool SharedZone = Gbl.FileBrowser.Type == Brw_ADMI_SHR_INS || Gbl.FileBrowser.Type == Brw_ADMI_SHR_CTR || Gbl.FileBrowser.Type == Brw_ADMI_SHR_DEG || Gbl.FileBrowser.Type == Brw_ADMI_SHR_CRS || Gbl.FileBrowser.Type == Brw_ADMI_SHR_GRP; bool AssignmentsZone = Gbl.FileBrowser.Type == Brw_ADMI_ASG_USR || Gbl.FileBrowser.Type == Brw_ADMI_ASG_CRS; bool SeeMarks = Gbl.FileBrowser.Type == Brw_SHOW_MRK_CRS || Gbl.FileBrowser.Type == Brw_SHOW_MRK_GRP; bool AdminMarks = Gbl.FileBrowser.Type == Brw_ADMI_MRK_CRS || Gbl.FileBrowser.Type == Brw_ADMI_MRK_GRP; /***** Initializations *****/ Gbl.FileBrowser.Clipboard.IsThisFile = false; snprintf (FileBrowserId,sizeof (FileBrowserId),"fil_brw_%u", Gbl.FileBrowser.Id); /***** Is this row hidden or visible? *****/ if (SeeDocsZone || AdminDocsZone || SeeMarks || AdminMarks) { RowSetAsHidden = Brw_CheckIfFileOrFolderIsSetAsHiddenInDB (Gbl.FileBrowser.FilFolLnk.Type, Gbl.FileBrowser.FilFolLnk.Full); if (RowSetAsHidden && Level && (SeeDocsZone || SeeMarks)) return false; if (AdminDocsZone || AdminMarks) { if (Gbl.FileBrowser.FilFolLnk.Type == Brw_IS_FOLDER) Gbl.FileBrowser.HiddenLevels[Level] = RowSetAsHidden; if (RowSetAsHidden) // this row is marked as hidden LightStyle = true; else // this row is not marked as hidden LightStyle = Brw_CheckIfAnyHigherLevelIsHidden (Level); } } /***** Get file metadata *****/ Brw_GetFileMetadataByPath (&FileMetadata); Brw_GetFileTypeSizeAndDate (&FileMetadata); if (FileMetadata.FilCod <= 0) // No entry for this file in database table of files /* Add entry to the table of files/folders */ FileMetadata.FilCod = Brw_DB_AddPath (-1L,FileMetadata.FilFolLnk.Type, Gbl.FileBrowser.FilFolLnk.Full,false,Brw_LICENSE_DEFAULT); /***** Is this row public or private? *****/ if (SeeDocsZone || AdminDocsZone || SharedZone) { RowSetAsPublic = (Gbl.FileBrowser.FilFolLnk.Type == Brw_IS_FOLDER) ? Brw_DB_GetIfFolderHasPublicFiles (Gbl.FileBrowser.FilFolLnk.Full) : FileMetadata.IsPublic; if (Gbl.FileBrowser.ShowOnlyPublicFiles && !RowSetAsPublic) return false; } /***** Check if is a recent file or folder *****/ // If less than a week since last modify ==> indicate the file is recent by writting its name in green if (Dat_GetStartExecutionTimeUTC () < FileMetadata.Time + (7L * 24L * 60L * 60L)) IsRecent = true; /* Style of the text in this row */ snprintf (Gbl.FileBrowser.TxtStyle,sizeof (Gbl.FileBrowser.TxtStyle), "%s_%s", LightStyle ? (Gbl.FileBrowser.FilFolLnk.Type == Brw_IS_FOLDER || !IsRecent ? "LST_HID" : "LST_REC_HID") : (Gbl.FileBrowser.FilFolLnk.Type == Brw_IS_FOLDER || !IsRecent ? "LST" : "LST_REC"), The_GetSuffix ()); Gbl.FileBrowser.InputStyle = (LightStyle ? (Gbl.FileBrowser.FilFolLnk.Type == Brw_IS_FOLDER || !IsRecent ? "LST_EDIT_HID" : "LST_EDIT_REC_HID") : (Gbl.FileBrowser.FilFolLnk.Type == Brw_IS_FOLDER || !IsRecent ? "LST_EDIT" : "LST_EDIT_REC")); /***** Get data of assignment using the name of the folder *****/ if (AssignmentsZone) { if (Level == 1) // Main folder of the assignment { Str_Copy (Gbl.FileBrowser.Asg.Folder,Gbl.FileBrowser.FilFolLnk.Name, sizeof (Gbl.FileBrowser.Asg.Folder) - 1); Asg_GetAssignmentDataByFolder (&Gbl.FileBrowser.Asg); // The data of this assignment remains in Gbl.FileBrowser.Asg // for all subsequent rows with Level > 1 (files or folders inside this folder), // and they are overwritten on the next row with level == 1 (next assignment) } } else // Not an assignment zone Gbl.FileBrowser.Asg.AsgCod = -1L; /***** Begin this row *****/ if (asprintf (&Anchor,"fil_brw_%u_%s", Gbl.FileBrowser.Id,RowId) < 0) Err_NotEnoughMemoryExit (); switch (IconThisRow) { case Brw_ICON_TREE_NOTHING: if (TreeContracted) // This row is inside a contracted subtree HTM_TR_Begin ("id=\"%s\"" " style=\"display:none;\"", Anchor); else HTM_TR_Begin ("id=\"%s\"", Anchor); break; case Brw_ICON_TREE_EXPAND: if (TreeContracted) // This row is inside a contracted subtree HTM_TR_Begin ("id=\"%s\" data-folder=\"contracted\"" " style=\"display:none;\"", Anchor); else HTM_TR_Begin ("id=\"%s\" data-folder=\"contracted\"", Anchor); break; case Brw_ICON_TREE_CONTRACT: if (TreeContracted) // This row is inside a contracted subtree HTM_TR_Begin ("id=\"%s\" data-folder=\"expanded\"" " style=\"display:none;\"", Anchor); else HTM_TR_Begin ("id=\"%s\" data-folder=\"expanded\"", Anchor); break; } /****** If current action allows file administration... ******/ Brw_SetIfICanEditFileOrFolder (false); if (Brw_CheckIfFileBrowserIsEditable (Gbl.FileBrowser.Type) && !Gbl.FileBrowser.ShowOnlyPublicFiles) { if (Gbl.FileBrowser.Clipboard.IsThisTree && Level != 0) // Never copy root folder // If path in the clipboard is equal to complete path in tree... // ...or is the start of complete path in tree... if (Str_Path1BeginsByPath2 (Gbl.FileBrowser.FilFolLnk.Full, Gbl.FileBrowser.Clipboard.FilFolLnk.Full)) Gbl.FileBrowser.Clipboard.IsThisFile = true; /* Check if I can modify (remove, rename, etc.) this file or folder */ Brw_SetIfICanEditFileOrFolder (Brw_CheckIfICanEditFileOrFolder (Level)); /* Icon to remove folder, file or link */ Brw_PutIconRemove (); /* Icon to copy */ Brw_PutIconCopy (); /* Icon to paste */ Brw_PutIconPaste (Level); } /***** Indentation depending on level, icon, and file/folder name *****/ /* Begin column */ HTM_TD_Begin ("class=\"NO_BR LM %s\" style=\"width:99%%;\"", The_GetColorRows ()); HTM_TABLE_Begin (NULL); HTM_TR_Begin (NULL); /* Indent depending on level */ if (Level) Brw_IndentAndWriteIconExpandContract (Level,FileBrowserId,RowId,IconThisRow); /* Put icon to hide/unhide file or folder */ if (AdminDocsZone || AdminMarks) Brw_PutIconHideUnhide (Anchor,RowSetAsHidden); /***** File or folder icon *****/ switch (Gbl.FileBrowser.FilFolLnk.Type) { case Brw_IS_FILE: case Brw_IS_LINK: /* Icon with file type or link */ Brw_PutIconFileWithLinkToViewMetadata (&FileMetadata); break; case Brw_IS_FOLDER: /* Icon with folder */ Brw_PutIconFolder (Level,FileBrowserId,RowId,IconThisRow); break; default: break; } /* Check if is a new file or folder */ // If our last access was before the last modify ==> // indicate the file is new by putting a blinking star if (Gbl.Usrs.Me.TimeLastAccToThisFileBrowser < FileMetadata.Time) Brw_PutIconNewFileOrFolder (); /* File or folder name */ Brw_WriteFileName (Level,FileMetadata.IsPublic); HTM_TR_End (); HTM_TABLE_End (); /* End column */ HTM_TD_End (); if (AdminMarks) /***** Header and footer rows *****/ Mrk_GetAndWriteNumRowsHeaderAndFooter (); if (AssignmentsZone && Level == 1) /***** Start and end dates of assignment *****/ Brw_WriteDatesAssignment (); else /***** File date and size *****/ Brw_WriteFileSizeAndDate (&FileMetadata); if (Gbl.FileBrowser.FilFolLnk.Type == Brw_IS_FOLDER) { /***** Put icon to download ZIP of folder *****/ HTM_TD_Begin ("class=\"BM %s\"",The_GetColorRows ()); if (Gbl.Usrs.Me.Role.Logged >= Rol_STD && // Only ZIP folders if I am student, teacher... !SeeMarks && // Do not ZIP folders when seeing marks !(SeeDocsZone && RowSetAsHidden)) // When seeing docs, if folder is not hidden (this could happen for Level == 0) Brw_PutButtonToDownloadZIPOfAFolder (); HTM_TD_End (); } else // File or link /***** User who created the file or folder *****/ Brw_WriteFileOrFolderPublisher (Level,FileMetadata.PublisherUsrCod); /***** End this row *****/ free (Anchor); HTM_TR_End (); The_ChangeRowColor (); if (RowSetAsHidden && (SeeDocsZone || SeeMarks)) return false; return true; } /*****************************************************************************/ /*************** Construct full path in tree of file browser *****************/ /*****************************************************************************/ // If, for example, Path is "descarga/teoria" and Name is "tema1.pdf" // then FullPathInTree will be "descarga/teoria/tema1.pdf" // If Name is ".", then FullPathInTree will be equal to Path void Brw_SetFullPathInTree (void) { char FullPath[PATH_MAX + 1 + NAME_MAX + 1]; if (!Gbl.FileBrowser.FilFolLnk.Path[0]) Gbl.FileBrowser.FilFolLnk.Full[0] = '\0'; else if (strcmp (Gbl.FileBrowser.FilFolLnk.Name,".")) { snprintf (FullPath,sizeof (FullPath),"%s/%s", Gbl.FileBrowser.FilFolLnk.Path,Gbl.FileBrowser.FilFolLnk.Name); Str_Copy (Gbl.FileBrowser.FilFolLnk.Full,FullPath, sizeof (Gbl.FileBrowser.FilFolLnk.Full) - 1); } else // It's the root folder Str_Copy (Gbl.FileBrowser.FilFolLnk.Full,Gbl.FileBrowser.FilFolLnk.Path, sizeof (Gbl.FileBrowser.FilFolLnk.Full) - 1); } /*****************************************************************************/ /******* Check if the clipboard can be pasted into the current folder ********/ /*****************************************************************************/ // Return true if Gbl.FileBrowser.Clipboard.FilFolLnk.Full can be pasted into Gbl.FileBrowser.FilFolLnk.Full static bool Brw_CheckIfCanPasteIn (unsigned Level) { char PathDstWithFile[PATH_MAX + 1 + NAME_MAX + 1]; /***** If not in a folder... *****/ if (Gbl.FileBrowser.FilFolLnk.Type != Brw_IS_FOLDER) return false; /***** If there is nothing in clipboard... *****/ if (Gbl.FileBrowser.Clipboard.FileBrowser == Brw_UNKNOWN) return false; /***** Do not paste a link in marks... *****/ if (Gbl.FileBrowser.Clipboard.FilFolLnk.Type == Brw_IS_LINK && (Gbl.FileBrowser.Type == Brw_ADMI_MRK_CRS || Gbl.FileBrowser.Type == Brw_ADMI_MRK_GRP)) return false; /**** If I can not create elements into this folder... *****/ if (!Brw_CheckIfICanCreateIntoFolder (Level)) return false; // Pasting into top level of assignments is forbidden /**** If we are in the same tree of the clipboard... *****/ if (Gbl.FileBrowser.Clipboard.IsThisTree) // We are in the same tree of the clipboard ==> // we can paste or not depending on the subtree { /***** Construct the name of the file or folder destination *****/ snprintf (PathDstWithFile,sizeof (PathDstWithFile),"%s/%s", Gbl.FileBrowser.FilFolLnk.Full, Gbl.FileBrowser.Clipboard.FilFolLnk.Name); return !Str_Path1BeginsByPath2 (PathDstWithFile, Gbl.FileBrowser.Clipboard.FilFolLnk.Full); } return true; // I can paste } /*****************************************************************************/ /********** Write link and icon to remove a file, link or folder *************/ /*****************************************************************************/ static void Brw_PutIconRemove (void) { HTM_TD_Begin ("class=\"BM %s\"",The_GetColorRows ()); if (Brw_GetIfICanEditFileOrFolder ()) // Can I remove this? switch (Gbl.FileBrowser.FilFolLnk.Type) { case Brw_IS_FILE: case Brw_IS_LINK: /***** Form to remove a file or link *****/ Ico_PutContextualIconToRemove (Brw_ActAskRemoveFile[Gbl.FileBrowser.Type],NULL, Brw_PutImplicitParsFileBrowser,&Gbl.FileBrowser.FilFolLnk); break; case Brw_IS_FOLDER: /***** Form to remove a folder *****/ Ico_PutContextualIconToRemove (Brw_ActRemoveFolder[Gbl.FileBrowser.Type],NULL, Brw_PutImplicitParsFileBrowser,&Gbl.FileBrowser.FilFolLnk); break; default: break; } else Ico_PutIconRemovalNotAllowed (); HTM_TD_End (); } /*****************************************************************************/ /************* Write link and icon to copy a file o a folder *****************/ /*****************************************************************************/ static void Brw_PutIconCopy (void) { HTM_TD_Begin ("class=\"BM %s\"",The_GetColorRows ()); /***** Form to copy into the clipboard *****/ Ico_PutContextualIconToCopy (Brw_ActCopy[Gbl.FileBrowser.Type], Brw_PutImplicitParsFileBrowser,&Gbl.FileBrowser.FilFolLnk); HTM_TD_End (); } /*****************************************************************************/ /************* Write link and icon to paste a file or a folder ***************/ /*****************************************************************************/ static void Brw_PutIconPaste (unsigned Level) { extern const char *Txt_Copy_not_allowed; HTM_TD_Begin ("class=\"BM %s\"",The_GetColorRows ()); if (Gbl.FileBrowser.FilFolLnk.Type == Brw_IS_FOLDER) // Can't paste in a file or link { /* Icon to paste */ if (Brw_CheckIfCanPasteIn (Level)) { /***** Form to paste the content of the clipboard *****/ Ico_PutContextualIconToPaste (Brw_ActPaste[Gbl.FileBrowser.Type], Brw_PutImplicitParsFileBrowser,&Gbl.FileBrowser.FilFolLnk); } else /* Icon to paste inactive */ Ico_PutIconOff ("paste.svg",Ico_BLACK,Txt_Copy_not_allowed); } HTM_TD_End (); } /*****************************************************************************/ /*************** Indent and write icon to expand/contract folder *************/ /*****************************************************************************/ static void Brw_IndentAndWriteIconExpandContract (unsigned Level, const char *FileBrowserId,const char *RowId, Brw_IconTree_t IconThisRow) { HTM_TD_Begin ("class=\"LM\""); HTM_TABLE_Begin (NULL); HTM_TR_Begin (NULL); Brw_IndentDependingOnLevel (Level); /***** Icon to expand/contract *****/ HTM_TD_Begin ("class=\"BM %s\"",The_GetColorRows ()); switch (IconThisRow) { case Brw_ICON_TREE_NOTHING: Ico_PutIcon ("tr16x16.gif",Ico_UNCHANGED,"","ICO20x20"); break; case Brw_ICON_TREE_EXPAND: /***** Visible icon to expand folder *****/ Brw_PutIconToExpandFolder (FileBrowserId,RowId, false); // Visible /***** Hidden icon to contract folder *****/ Brw_PutIconToContractFolder (FileBrowserId,RowId, true); // Hidden break; case Brw_ICON_TREE_CONTRACT: /***** Hidden icon to expand folder *****/ Brw_PutIconToExpandFolder (FileBrowserId,RowId, true); // Hidden /***** Visible icon to contract folder *****/ Brw_PutIconToContractFolder (FileBrowserId,RowId, false); // Visible break; } HTM_TD_End (); HTM_TR_End (); HTM_TABLE_End (); HTM_TD_End (); } /*****************************************************************************/ /************************* Indent depending on level *************************/ /*****************************************************************************/ static void Brw_IndentDependingOnLevel (unsigned Level) { unsigned i; for (i = 1; i < Level; i++) { HTM_TD_Begin ("class=\"BM %s\"",The_GetColorRows ()); Ico_PutIcon ("tr16x16.gif",Ico_UNCHANGED,"","ICO20x20"); HTM_TD_End (); } } /*****************************************************************************/ /************************ Put icon to expand a folder ************************/ /*****************************************************************************/ static void Brw_PutIconToExpandFolder (const char *FileBrowserId,const char *RowId, bool Hidden) { char JavaScriptFuncToExpandFolder[256 + Brw_MAX_ROW_ID]; /***** Begin container *****/ if (Hidden) HTM_DIV_Begin ("id=\"expand_%s_%s\" style=\"display:none;\"", FileBrowserId,RowId); else HTM_DIV_Begin ("id=\"expand_%s_%s\"", FileBrowserId,RowId); /***** Form and icon *****/ snprintf (JavaScriptFuncToExpandFolder,sizeof (JavaScriptFuncToExpandFolder), "ExpandFolder('%s_%s')", FileBrowserId,RowId); Frm_BeginFormAnchorOnSubmit (Brw_ActExpandFolder[Gbl.FileBrowser.Type], FileBrowserId, JavaScriptFuncToExpandFolder); // JavaScript function to unhide rows Brw_PutImplicitParsFileBrowser (&Gbl.FileBrowser.FilFolLnk); Ico_PutIconLink ("caret-right.svg",Ico_BLACK, Brw_ActExpandFolder[Gbl.FileBrowser.Type]); Frm_EndForm (); /***** End container *****/ HTM_DIV_End (); } /*****************************************************************************/ /*********************** Put icon to contract a folder ***********************/ /*****************************************************************************/ static void Brw_PutIconToContractFolder (const char *FileBrowserId,const char *RowId, bool Hidden) { char JavaScriptFuncToContractFolder[256 + Brw_MAX_ROW_ID]; /***** Begin container *****/ if (Hidden) HTM_DIV_Begin ("id=\"contract_%s_%s\" style=\"display:none;\"", FileBrowserId,RowId); else HTM_DIV_Begin ("id=\"contract_%s_%s\"", FileBrowserId,RowId); /***** Form and icon *****/ snprintf (JavaScriptFuncToContractFolder,sizeof (JavaScriptFuncToContractFolder), "ContractFolder('%s_%s')", FileBrowserId,RowId); Frm_BeginFormAnchorOnSubmit (Brw_ActContractFolder[Gbl.FileBrowser.Type], FileBrowserId, JavaScriptFuncToContractFolder); // JavaScript function to hide rows Brw_PutImplicitParsFileBrowser (&Gbl.FileBrowser.FilFolLnk); Ico_PutIconLink ("caret-down.svg",Ico_BLACK, Brw_ActContractFolder[Gbl.FileBrowser.Type]); Frm_EndForm (); /***** End container *****/ HTM_DIV_End (); } /*****************************************************************************/ /************* Put link and icon to hide/unhide file or folder ***************/ /*****************************************************************************/ static void Brw_PutIconHideUnhide (const char *Anchor,bool RowSetAsHidden) { HTM_TD_Begin ("class=\"BM %s\"",The_GetColorRows ()); Ico_PutContextualIconToHideUnhide (Brw_ActHideUnhide[Gbl.FileBrowser.Type],Anchor, Brw_PutImplicitParsFileBrowser,&Gbl.FileBrowser.FilFolLnk, RowSetAsHidden); HTM_TD_End (); } /*****************************************************************************/ /********* Check if any level higher than the current one is hidden **********/ /*****************************************************************************/ static bool Brw_CheckIfAnyHigherLevelIsHidden (unsigned CurrentLevel) { unsigned Level; for (Level = 0; Level < CurrentLevel; Level++) if (Gbl.FileBrowser.HiddenLevels[Level]) // Hidden return true; return false; // None is hidden. All are visible. } /*****************************************************************************/ /** Write link e icon to upload or paste files, or to create folder or link **/ /*****************************************************************************/ static void Brw_PutIconFolder (unsigned Level, const char *FileBrowserId,const char *RowId, Brw_IconTree_t IconSubtree) { bool ICanCreate; /***** Begin cell *****/ HTM_TD_Begin ("class=\"BM %s\"",The_GetColorRows ()); /***** Put icon to create a new file or folder *****/ if ((ICanCreate = Brw_CheckIfICanCreateIntoFolder (Level))) // I can create a new file or folder { if (IconSubtree == Brw_ICON_TREE_EXPAND) { /***** Visible icon with folder closed *****/ Brw_PutIconFolderWithPlus (FileBrowserId,RowId, false, // Closed false); // Visible /***** Hidden icon with folder open *****/ Brw_PutIconFolderWithPlus (FileBrowserId,RowId, true, // Open true); // Hidden } else { /***** Hidden icon with folder closed *****/ Brw_PutIconFolderWithPlus (FileBrowserId,RowId, false, // Closed true); // Hidden /***** Visible icon with folder open *****/ Brw_PutIconFolderWithPlus (FileBrowserId,RowId, true, // Open false); // Visible } } else // I can't create a new file or folder { if (IconSubtree == Brw_ICON_TREE_EXPAND) { /***** Visible icon with folder closed *****/ Brw_PutIconFolderWithoutPlus (FileBrowserId,RowId, false, // Closed false); // Visible /***** Hidden icon with folder open *****/ Brw_PutIconFolderWithoutPlus (FileBrowserId,RowId, true, // Open true); // Hidden } else { /***** Hidden icon with folder closed *****/ Brw_PutIconFolderWithoutPlus (FileBrowserId,RowId, false, // Closed true); // Hidden /***** Visible icon with folder open *****/ Brw_PutIconFolderWithoutPlus (FileBrowserId,RowId, true, // Open false); // Visible } } /***** End cell *****/ HTM_TD_End (); } /*****************************************************************************/ /******** Put icon to expand a folder without form to create inside **********/ /*****************************************************************************/ static void Brw_PutIconFolderWithoutPlus (const char *FileBrowserId,const char *RowId, bool Open,bool Hidden) { extern const char *Txt_Folder; /***** Begin container *****/ HTM_DIV_Begin ("id=\"folder_%s_%s_%s\" class=\"%s\" %s", Open ? "open" : "closed", FileBrowserId,RowId, The_GetColorRows (), Hidden ? " style=\"display:none;\"" : ""); /***** Icon *****/ Ico_PutIcon (Open ? "folder-open-yellow.png" : "folder-yellow.png", Ico_UNCHANGED, Txt_Folder,"CONTEXT_OPT CONTEXT_ICO16x16"); /***** End container *****/ HTM_DIV_End (); } /*****************************************************************************/ /********** Put icon to expand a folder with form to create inside ***********/ /*****************************************************************************/ static void Brw_PutIconFolderWithPlus (const char *FileBrowserId,const char *RowId, bool Open,bool Hidden) { /***** Begin container *****/ HTM_DIV_Begin ("id=\"folder_%s_%s_%s\" class=\"%s\" %s", Open ? "open" : "closed", FileBrowserId,RowId, The_GetColorRows (), Hidden ? " style=\"display:none;\"" : ""); /***** Form and icon *****/ Ico_PutContextualIconToCreateInFolder (Brw_ActFormCreate[Gbl.FileBrowser.Type], Brw_PutImplicitParsFileBrowser,&Gbl.FileBrowser.FilFolLnk, Open); /***** End container *****/ HTM_DIV_End (); } /*****************************************************************************/ /**************** Write icon to indicate that the file is new ****************/ /*****************************************************************************/ static void Brw_PutIconNewFileOrFolder (void) { extern const char *Txt_New_FILE_OR_FOLDER; /***** Icon that indicates new file *****/ HTM_TD_Begin ("class=\"BM %s\"",The_GetColorRows ()); Ico_PutIcon ("star16x16.gif",Ico_UNCHANGED,Txt_New_FILE_OR_FOLDER,"ICO20x20"); HTM_TD_End (); } /*****************************************************************************/ /***************************** Put icon of a file ****************************/ /*****************************************************************************/ static void Brw_PutIconFileWithLinkToViewMetadata (const struct Brw_FileMetadata *FileMetadata) { /***** Begin cell *****/ HTM_TD_Begin ("class=\"BM %s\"",The_GetColorRows ()); /***** Begin form *****/ Frm_BeginForm (Brw_ActReqDatFile[Gbl.FileBrowser.Type]); Brw_PutParsFileBrowser (NULL, // Not used NULL, // Not used Brw_IS_UNKNOWN, // Not used FileMetadata->FilCod); /***** Icon depending on the file extension *****/ if (FileMetadata->FilFolLnk.Type == Brw_IS_FILE) Brw_PutIconFile (FileMetadata->FilFolLnk.Name, "CONTEXT_OPT ICO_HIGHLIGHT CONTEXT_ICO16x16", true); // Put link to view metadata else /* HTM_INPUT_IMAGE (Cfg_URL_ICON_PUBLIC,"up-right-from-square.svg",Txt_Link, "class=\"CONTEXT_OPT ICO_HIGHLIGHT CONTEXT_ICO16x16 ICO_%s_%s\"", Ico_GetPreffix (Ico_BLACK),The_GetSuffix ()); */ Ico_PutIconLink ("up-right-from-square.svg",Ico_BLACK, Brw_ActReqDatFile[Gbl.FileBrowser.Type]); /***** End form *****/ Frm_EndForm (); /***** End cell *****/ HTM_TD_End (); } /*****************************************************************************/ /***************************** Put icon of a file ****************************/ /*****************************************************************************/ void Brw_PutIconFile (const char *FileName, const char *Class,bool PutLinkToViewMetadata) { extern const unsigned Ext_NUM_FILE_EXT_ALLOWED; extern const char *Ext_FileExtensionsAllowed[]; extern const char *Txt_X_file; char *URL; char *Icon; char *Title; unsigned DocType; bool NotFound; if (asprintf (&URL,"%s32x32", CfG_URL_ICON_FILEXT_PUBLIC) < 0) Err_NotEnoughMemoryExit (); for (DocType = 0, NotFound = true; DocType < Ext_NUM_FILE_EXT_ALLOWED && NotFound; DocType++) if (Str_FileIs (FileName,Ext_FileExtensionsAllowed[DocType])) { if (asprintf (&Icon,"%s32x32.gif", Ext_FileExtensionsAllowed[DocType]) < 0) Err_NotEnoughMemoryExit (); if (asprintf (&Title,Txt_X_file, Ext_FileExtensionsAllowed[DocType]) < 0) Err_NotEnoughMemoryExit (); NotFound = false; } if (NotFound) { if (asprintf (&Icon,"xxx32x32.gif") < 0) Err_NotEnoughMemoryExit (); if (asprintf (&Title,"%s","") < 0) Err_NotEnoughMemoryExit (); } if (PutLinkToViewMetadata) HTM_INPUT_IMAGE (URL,Icon,Title,"class=\"%s\"",Class); else HTM_IMG (URL,Icon,Title,"class=\"%s\"",Class); free (Title); free (Icon); free (URL); } /*****************************************************************************/ /***************** Put button to create ZIP file of a folder *****************/ /*****************************************************************************/ static void Brw_PutButtonToDownloadZIPOfAFolder (void) { /***** Form to zip and download folder *****/ Ico_PutContextualIconToZIP (Brw_ActZIPFolder[Gbl.FileBrowser.Type], Brw_PutImplicitParsFileBrowser,&Gbl.FileBrowser.FilFolLnk); } /*****************************************************************************/ /********** Write central part with the name of a file or folder *************/ /*****************************************************************************/ static void Brw_WriteFileName (unsigned Level,bool IsPublic) { extern const char *Txt_Check_marks_in_the_file; extern const char *Txt_Download; extern const char *Txt_Public_open_educational_resource_OER_for_everyone; char FileNameToShow[NAME_MAX + 1]; /***** Get the name of the file to show *****/ Brw_GetFileNameToShowDependingOnLevel (Gbl.FileBrowser.Type, Level, Gbl.FileBrowser.FilFolLnk.Type, Gbl.FileBrowser.FilFolLnk.Name, FileNameToShow); /***** Name and link of the folder, file or link *****/ switch (Gbl.FileBrowser.FilFolLnk.Type) { case Brw_IS_FOLDER: /***** Begin cell *****/ HTM_TD_Begin (Gbl.FileBrowser.Clipboard.IsThisFile ? "class=\"%s LM LIGHT_GREEN\" style=\"width:99%%;\"" : "class=\"%s LM\" style=\"width:99%%;\"", Gbl.FileBrowser.TxtStyle); HTM_DIV_Begin ("class=\"FILENAME\""); HTM_NBSP (); if (Brw_GetIfICanEditFileOrFolder ()) // Can I rename this folder? { /***** Form to rename folder *****/ Frm_BeginForm (Brw_ActRenameFolder[Gbl.FileBrowser.Type]); Brw_PutImplicitParsFileBrowser (&Gbl.FileBrowser.FilFolLnk); HTM_INPUT_TEXT ("NewFolderName",Brw_MAX_CHARS_FOLDER,Gbl.FileBrowser.FilFolLnk.Name, HTM_SUBMIT_ON_CHANGE, "class=\"LST_EDIT %s_%s %s\"", Gbl.FileBrowser.InputStyle, The_GetSuffix (), Gbl.FileBrowser.Clipboard.IsThisFile ? "LIGHT_GREEN" : The_GetColorRows ()); Frm_EndForm (); } else { /***** Write name of the folder *****/ if ((Level == 1) && (Gbl.FileBrowser.Type == Brw_ADMI_ASG_USR || Gbl.FileBrowser.Type == Brw_ADMI_ASG_CRS)) HTM_SPAN_Begin ("title=\"%s\"",Gbl.FileBrowser.Asg.Title); HTM_STRONG_Begin (); HTM_Txt (FileNameToShow); HTM_STRONG_End (); HTM_NBSP (); if ((Level == 1) && (Gbl.FileBrowser.Type == Brw_ADMI_ASG_USR || Gbl.FileBrowser.Type == Brw_ADMI_ASG_CRS)) HTM_SPAN_End (); } /***** End cell *****/ HTM_DIV_End (); HTM_TD_End (); break; case Brw_IS_FILE: case Brw_IS_LINK: HTM_TD_Begin (Gbl.FileBrowser.Clipboard.IsThisFile ? "class=\"%s LM LIGHT_GREEN\" style=\"width:99%%;\"" : "class=\"%s LM\" style=\"width:99%%;\"", Gbl.FileBrowser.TxtStyle); HTM_NBSP (); Frm_BeginForm (Brw_ActDowFile[Gbl.FileBrowser.Type]); Brw_PutImplicitParsFileBrowser (&Gbl.FileBrowser.FilFolLnk); /* Link to the form and to the file */ HTM_BUTTON_Submit_Begin ((Gbl.FileBrowser.Type == Brw_SHOW_MRK_CRS || Gbl.FileBrowser.Type == Brw_SHOW_MRK_GRP) ? Txt_Check_marks_in_the_file : Txt_Download, "class=\"LM BT_LINK FILENAME\""); HTM_Txt (FileNameToShow); HTM_BUTTON_End (); Frm_EndForm (); /* Put icon to make public/private file */ if (IsPublic) Ico_PutIconOff ("unlock.svg",Ico_GREEN, Txt_Public_open_educational_resource_OER_for_everyone); HTM_TD_End (); break; default: break; } } /*****************************************************************************/ /*********************** Which filename must be shown? ***********************/ /*****************************************************************************/ static void Brw_GetFileNameToShowDependingOnLevel (Brw_FileBrowser_t FileBrowser, unsigned Level, Brw_FileType_t FileType, const char *FileName, char *FileNameToShow) { extern const char *Txt_ROOT_FOLDER_EXTERNAL_NAMES[Brw_NUM_TYPES_FILE_BROWSER]; Brw_GetFileNameToShow (FileType, Level ? FileName : Txt_ROOT_FOLDER_EXTERNAL_NAMES[FileBrowser], FileNameToShow); } static void Brw_GetFileNameToShow (Brw_FileType_t FileType, const char FileName[NAME_MAX + 1], char FileNameToShow[NAME_MAX + 1]) { /***** Copy file name *****/ Str_Copy (FileNameToShow,FileName,NAME_MAX); /***** Remove .url if link *****/ if (FileType == Brw_IS_LINK) // It's a link (URL inside a .url file) FileNameToShow[strlen (FileNameToShow) - 4] = '\0'; // Remove .url } /*****************************************************************************/ /****** Create a link in public temporary directory to a private file ********/ /*****************************************************************************/ void Brw_CreateTmpPublicLinkToPrivateFile (const char *FullPathIncludingFile, const char *FileName) { char Link[PATH_MAX + 1]; /***** Create, into temporary public directory, a symbolic link to file *****/ snprintf (Link,sizeof (Link),"%s/%s/%s/%s", Cfg_PATH_FILE_BROWSER_TMP_PUBLIC, Gbl.FileBrowser.TmpPubDir.L, Gbl.FileBrowser.TmpPubDir.R, FileName); if (symlink (FullPathIncludingFile,Link) != 0) Err_ShowErrorAndExit ("Can not create temporary link."); } /*****************************************************************************/ /************ Write start and end dates of a folder of assignment ************/ /*****************************************************************************/ static void Brw_WriteDatesAssignment (void) { extern const char *Txt_unknown_assignment; static unsigned UniqueId = 0; char *Id; /***** Begin table cell *****/ HTM_TD_Begin ("colspan=\"2\" class=\"RM %s_%s %s\"", Gbl.FileBrowser.Asg.Open ? "ASG_LST_DATE_GREEN" : "ASG_LST_DATE_RED", The_GetSuffix (), The_GetColorRows ()); if (Gbl.FileBrowser.Asg.AsgCod > 0) { UniqueId++; /***** Write start date *****/ if (asprintf (&Id,"asg_start_date_%u",UniqueId) < 0) Err_NotEnoughMemoryExit (); HTM_SPAN_Begin ("id=\"%s\"",Id); Dat_WriteLocalDateHMSFromUTC (Id,Gbl.FileBrowser.Asg.TimeUTC[Dat_STR_TIME], Gbl.Prefs.DateFormat,Dat_SEPARATOR_COMMA, true,true,false,0x7); HTM_SPAN_End (); free (Id); /***** Arrow *****/ HTM_Txt ("→"); /***** Write end date *****/ if (asprintf (&Id,"asg_end_date_%u",UniqueId) < 0) Err_NotEnoughMemoryExit (); HTM_SPAN_Begin ("id=\"%s\"",Id); Dat_WriteLocalDateHMSFromUTC (Id,Gbl.FileBrowser.Asg.TimeUTC[Dat_END_TIME], Gbl.Prefs.DateFormat,Dat_SEPARATOR_COMMA, true,false,false,0x7); HTM_SPAN_End (); free (Id); } else HTM_TxtF (" (%s)",Txt_unknown_assignment); /***** End table cell *****/ HTM_TD_End (); } /*****************************************************************************/ /****************** Write size and date of a file or folder ******************/ /*****************************************************************************/ static void Brw_WriteFileSizeAndDate (struct Brw_FileMetadata *FileMetadata) { static unsigned UniqueId = 0; char *Id; char FileSizeStr[Fil_MAX_BYTES_FILE_SIZE_STRING + 1]; /***** Write the file size *****/ if (Gbl.FileBrowser.FilFolLnk.Type == Brw_IS_FILE) Fil_WriteFileSizeBrief ((double) FileMetadata->Size,FileSizeStr); else FileSizeStr[0] = '\0'; HTM_TD_Begin ("class=\"%s RM %s\"", Gbl.FileBrowser.TxtStyle,The_GetColorRows ()); HTM_TxtF (" %s",FileSizeStr); HTM_TD_End (); /***** Write the date *****/ HTM_TD_Begin ("class=\"%s RM %s\"", Gbl.FileBrowser.TxtStyle,The_GetColorRows ()); HTM_NBSP (); if (Gbl.FileBrowser.FilFolLnk.Type == Brw_IS_FILE || Gbl.FileBrowser.FilFolLnk.Type == Brw_IS_LINK) { UniqueId++; if (asprintf (&Id,"filedate%u",UniqueId) < 0) Err_NotEnoughMemoryExit (); HTM_SPAN_Begin ("id=\"%s\"",Id); HTM_SPAN_End (); Dat_WriteLocalDateHMSFromUTC (Id,FileMetadata->Time, Gbl.Prefs.DateFormat,Dat_SEPARATOR_COMMA, true,true,false,0x6); free (Id); } HTM_TD_End (); } /*****************************************************************************/ /************** Write the user who published the file or folder **************/ /*****************************************************************************/ static void Brw_WriteFileOrFolderPublisher (unsigned Level,long UsrCod) { extern const char *Txt_Unknown_or_without_photo; static const char *ClassPhoto[PhoSha_NUM_SHAPES] = { [PhoSha_SHAPE_CIRCLE ] = "PHOTOC15x20B", [PhoSha_SHAPE_ELLIPSE ] = "PHOTOE15x20B", [PhoSha_SHAPE_OVAL ] = "PHOTOO15x20B", [PhoSha_SHAPE_RECTANGLE] = "PHOTOR15x20B", }; bool ShowUsr = false; struct Usr_Data UsrDat; if (Level && UsrCod > 0) { /***** Initialize structure with user's data *****/ Usr_UsrDataConstructor (&UsrDat); /***** Get data of file/folder publisher *****/ UsrDat.UsrCod = UsrCod; ShowUsr = Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat, Usr_DONT_GET_PREFS, Usr_DONT_GET_ROLE_IN_CURRENT_CRS); } HTM_TD_Begin ("class=\"BM %s\"",The_GetColorRows ()); if (ShowUsr) /***** Show photo *****/ Pho_ShowUsrPhotoIfAllowed (&UsrDat, ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM); else Ico_PutIcon ("usr_bl.jpg",Ico_UNCHANGED,Txt_Unknown_or_without_photo, ClassPhoto[Gbl.Prefs.PhotoShape]); HTM_TD_End (); if (Level && UsrCod > 0) /***** Free memory used for user's data *****/ Usr_UsrDataDestructor (&UsrDat); } /*****************************************************************************/ /************** Ask for confirmation of removing a file or link **************/ /*****************************************************************************/ void Brw_AskRemFileFromTree (void) { extern const char *Txt_Do_you_really_want_to_remove_FILE_OR_LINK_X; extern const char *Txt_Remove_file; extern const char *Txt_Remove_link; extern const char *Txt_You_can_not_remove_this_file_or_link; char FileNameToShow[NAME_MAX + 1]; /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); /***** Button of confirmation of removing *****/ if (Brw_CheckIfICanEditFileOrFolder (Gbl.FileBrowser.Level)) // Can I remove this file? { /***** Show question and button to remove file/link *****/ Brw_GetFileNameToShowDependingOnLevel (Gbl.FileBrowser.Type, Gbl.FileBrowser.Level, Gbl.FileBrowser.FilFolLnk.Type, Gbl.FileBrowser.FilFolLnk.Name, FileNameToShow); Ale_ShowAlertAndButton (Brw_ActRemoveFile[Gbl.FileBrowser.Type],NULL,NULL, Brw_PutImplicitParsFileBrowser,&Gbl.FileBrowser.FilFolLnk, Btn_REMOVE_BUTTON, Gbl.FileBrowser.FilFolLnk.Type == Brw_IS_FILE ? Txt_Remove_file : Txt_Remove_link, Ale_QUESTION,Txt_Do_you_really_want_to_remove_FILE_OR_LINK_X, FileNameToShow); } else Err_ShowErrorAndExit (Txt_You_can_not_remove_this_file_or_link); /***** Show again file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /************************ Remove a file of a file browser ********************/ /*****************************************************************************/ void Brw_RemFileFromTree (void) { extern const char *Txt_FILE_X_removed; extern const char *Txt_You_can_not_remove_this_file_or_link; char Path[PATH_MAX + 1 + PATH_MAX + 1]; struct stat FileStatus; char FileNameToShow[NAME_MAX + 1]; /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); if (Brw_CheckIfICanEditFileOrFolder (Gbl.FileBrowser.Level)) // Can I remove this file? { snprintf (Path,sizeof (Path),"%s/%s", Gbl.FileBrowser.Priv.PathAboveRootFolder, Gbl.FileBrowser.FilFolLnk.Full); /***** Check if is a file/link or a folder *****/ if (lstat (Path,&FileStatus)) // On success ==> 0 is returned Err_ShowErrorAndExit ("Can not get information about a file or folder."); else if (S_ISREG (FileStatus.st_mode)) // It's a file or a link { /* Name of the file/link to be shown */ Brw_GetFileNameToShow (Str_FileIs (Gbl.FileBrowser.FilFolLnk.Name,"url") ? Brw_IS_LINK : Brw_IS_FILE, Gbl.FileBrowser.FilFolLnk.Name,FileNameToShow); /* Remove file/link from disk and database */ Brw_RemoveFileFromDiskAndDB (Path, Gbl.FileBrowser.FilFolLnk.Full); /* Remove affected clipboards */ Brw_DB_RemoveAffectedClipboards (Gbl.FileBrowser.Type, Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Other.UsrDat.UsrCod); /* Message of confirmation of removing */ Ale_ShowAlert (Ale_SUCCESS,Txt_FILE_X_removed, FileNameToShow); } else // File / link not found Err_FileFolderNotFoundExit (); } else Err_ShowErrorAndExit (Txt_You_can_not_remove_this_file_or_link); /***** Show again file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /******************* Remove a folder of a file browser ***********************/ /*****************************************************************************/ void Brw_RemFolderFromTree (void) { extern const char *Txt_Folder_X_removed; extern const char *Txt_You_can_not_remove_this_folder; char Path[PATH_MAX + 1 + PATH_MAX + 1]; struct stat FileStatus; /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); if (Brw_CheckIfICanEditFileOrFolder (Gbl.FileBrowser.Level)) // Can I remove this folder? { snprintf (Path,sizeof (Path),"%s/%s", Gbl.FileBrowser.Priv.PathAboveRootFolder, Gbl.FileBrowser.FilFolLnk.Full); /***** Check if it's a file or a folder *****/ if (lstat (Path,&FileStatus)) // On success ==> 0 is returned Err_ShowErrorAndExit ("Can not get information about a file or folder."); else if (S_ISDIR (FileStatus.st_mode)) // It's a directory if (Brw_RemoveFolderFromDiskAndDB (Path, Gbl.FileBrowser.FilFolLnk.Full)) { if (errno == ENOTEMPTY) // The directory is not empty Brw_AskConfirmRemoveFolderNotEmpty (); else // The directory is empty Err_ShowErrorAndExit ("Can not remove folder."); } else { /* Remove affected clipboards */ Brw_DB_RemoveAffectedClipboards (Gbl.FileBrowser.Type, Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Other.UsrDat.UsrCod); /* Message of confirmation of successfull removing */ Ale_ShowAlert (Ale_SUCCESS,Txt_Folder_X_removed, Gbl.FileBrowser.FilFolLnk.Name); } else // Folder not found Err_FileFolderNotFoundExit (); } else Err_ShowErrorAndExit (Txt_You_can_not_remove_this_folder); /***** Show again file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /*********** Ask for confirmation of removing of a folder no empty ***********/ /*****************************************************************************/ static void Brw_AskConfirmRemoveFolderNotEmpty (void) { extern const char *Txt_Do_you_really_want_to_remove_the_folder_X; extern const char *Txt_Remove_folder; /***** Show question and button to remove not empty folder *****/ Ale_ShowAlertAndButton (Brw_ActRemoveFolderNotEmpty[Gbl.FileBrowser.Type],NULL,NULL, Brw_PutImplicitParsFileBrowser,&Gbl.FileBrowser.FilFolLnk, Btn_REMOVE_BUTTON,Txt_Remove_folder, Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_folder_X, Gbl.FileBrowser.FilFolLnk.Name); } /*****************************************************************************/ /********* Complete removing of a not empty folder in a file browser *********/ /*****************************************************************************/ void Brw_RemSubtreeInFileBrowser (void) { extern const char *Txt_Folder_X_and_all_its_contents_removed; char Path[PATH_MAX + 1 + PATH_MAX + 1]; /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); if (Brw_CheckIfICanEditFileOrFolder (Gbl.FileBrowser.Level)) // Can I remove this subtree? { snprintf (Path,sizeof (Path),"%s/%s", Gbl.FileBrowser.Priv.PathAboveRootFolder, Gbl.FileBrowser.FilFolLnk.Full); /***** Remove the whole tree *****/ Fil_RemoveTree (Path); /* If a folder is removed, it is necessary to remove it from the database and all files or folders under that folder */ Brw_RemoveOneFileOrFolderFromDB (Gbl.FileBrowser.FilFolLnk.Full); Brw_RemoveChildrenOfFolderFromDB (Gbl.FileBrowser.FilFolLnk.Full); /* Remove affected clipboards */ Brw_DB_RemoveAffectedClipboards (Gbl.FileBrowser.Type, Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Other.UsrDat.UsrCod); /* Remove affected expanded folders */ Brw_DB_RemoveAffectedExpandedFolders (Gbl.FileBrowser.FilFolLnk.Full); /***** Write message of confirmation *****/ Ale_ShowAlert (Ale_SUCCESS,Txt_Folder_X_and_all_its_contents_removed, Gbl.FileBrowser.FilFolLnk.Name); } /***** Show again file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /********************* Expand a folder in a file browser *********************/ /*****************************************************************************/ // A priori function. Changes database. No HTML output. void Brw_ExpandFileTree (void) { /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); /***** Add path to table of expanded folders *****/ Brw_InsFoldersInPathAndUpdOtherFoldersInExpandedFolders (Gbl.FileBrowser.FilFolLnk.Full); } /*****************************************************************************/ /******************* Contract a folder in a file browser *********************/ /*****************************************************************************/ // A priori function. Changes database. No HTML output. void Brw_ContractFileTree (void) { /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); /***** Remove path where the user has clicked from table of expanded folders *****/ Brw_RemThisFolderAndUpdOtherFoldersFromExpandedFolders (Gbl.FileBrowser.FilFolLnk.Full); } /*****************************************************************************/ /****** Copy the path of a file/folder of a file browser in clipboard ********/ /*****************************************************************************/ void Brw_CopyFromFileBrowser (void) { /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); /***** Remove old clipboards (from all users) *****/ Brw_DB_RemoveExpiredClipboards (); // Someone must do this work. Let's do it whenever a user click in a copy button /***** Put the path in the clipboard *****/ if (Brw_GetMyClipboard ()) Brw_DB_UpdatePathInClipboard (); else Brw_DB_AddPathToClipboards (); /***** Show again file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /********* Write a title with the content of the current clipboard ***********/ /*****************************************************************************/ static void Brw_WriteCurrentClipboard (void) { extern const char *Txt_Copy_source; extern const char *Txt_documents_management_area; extern const char *Txt_teachers_files_area; extern const char *Txt_shared_files_area; extern const char *Txt_assignments_area; extern const char *Txt_works_area; extern const char *Txt_project_documents; extern const char *Txt_project_assessment; extern const char *Txt_marks_management_area; extern const char *Txt_temporary_private_storage_area; extern const char *Txt_institution; extern const char *Txt_center; extern const char *Txt_degree; extern const char *Txt_course; extern const char *Txt_group; extern const char *Txt_project; extern const char *Txt_user[Usr_NUM_SEXS]; extern const char *Txt_file_folder; extern const char *Txt_file; extern const char *Txt_folder; extern const char *Txt_link; extern const char *Txt_all_files_inside_the_root_folder; struct Hie_Hierarchy Hie; struct GroupData GrpDat; struct Prj_Project Prj; struct Usr_Data UsrDat; char TxtClipboardZone[1024 + Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + Grp_MAX_BYTES_GROUP_TYPE_NAME + Grp_MAX_BYTES_GROUP_NAME + Usr_MAX_BYTES_FULL_NAME + Prj_MAX_BYTES_TITLE]; char FileNameToShow[NAME_MAX + 1]; static const char **TxtFileType[Brw_NUM_FILE_TYPES] = { [Brw_IS_UNKNOWN] = &Txt_file_folder, [Brw_IS_FILE ] = &Txt_file, [Brw_IS_FOLDER ] = &Txt_folder, [Brw_IS_LINK ] = &Txt_link, }; switch (Gbl.FileBrowser.Clipboard.FileBrowser) { case Brw_ADMI_DOC_INS: Hie.Ins.InsCod = Gbl.FileBrowser.Clipboard.Cod; Ins_GetInstitDataByCod (&Hie.Ins); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s", Txt_documents_management_area, Txt_institution,Hie.Ins.ShrtName); break; case Brw_ADMI_SHR_INS: Hie.Ins.InsCod = Gbl.FileBrowser.Clipboard.Cod; Ins_GetInstitDataByCod (&Hie.Ins); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s", Txt_shared_files_area, Txt_institution,Hie.Ins.ShrtName); break; case Brw_ADMI_DOC_CTR: Hie.Ctr.CtrCod = Gbl.FileBrowser.Clipboard.Cod; Ctr_GetCenterDataByCod (&Hie.Ctr); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s", Txt_documents_management_area, Txt_center,Hie.Ctr.ShrtName); break; case Brw_ADMI_SHR_CTR: Hie.Ctr.CtrCod = Gbl.FileBrowser.Clipboard.Cod; Ctr_GetCenterDataByCod (&Hie.Ctr); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s", Txt_shared_files_area, Txt_center,Hie.Ctr.ShrtName); break; case Brw_ADMI_DOC_DEG: Hie.Deg.DegCod = Gbl.FileBrowser.Clipboard.Cod; Deg_GetDegreeDataByCod (&Hie.Deg); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s", Txt_documents_management_area, Txt_degree,Hie.Deg.ShrtName); break; case Brw_ADMI_SHR_DEG: Hie.Deg.DegCod = Gbl.FileBrowser.Clipboard.Cod; Deg_GetDegreeDataByCod (&Hie.Deg); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s", Txt_shared_files_area, Txt_degree,Hie.Deg.ShrtName); break; case Brw_ADMI_DOC_CRS: Hie.Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs_GetCourseDataByCod (&Hie.Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s", Txt_documents_management_area, Txt_course,Hie.Crs.ShrtName); break; case Brw_ADMI_DOC_GRP: GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; Grp_GetGroupDataByCod (&GrpDat); Hie.Crs.CrsCod = GrpDat.CrsCod; Crs_GetCourseDataByCod (&Hie.Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s %s", Txt_documents_management_area, Txt_course,Hie.Crs.ShrtName, Txt_group,GrpDat.GrpTypName,GrpDat.GrpName); break; case Brw_ADMI_TCH_CRS: Hie.Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs_GetCourseDataByCod (&Hie.Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s", Txt_teachers_files_area, Txt_course,Hie.Crs.ShrtName); break; case Brw_ADMI_TCH_GRP: GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; Grp_GetGroupDataByCod (&GrpDat); Hie.Crs.CrsCod = GrpDat.CrsCod; Crs_GetCourseDataByCod (&Hie.Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s %s", Txt_teachers_files_area, Txt_course,Hie.Crs.ShrtName, Txt_group,GrpDat.GrpTypName,GrpDat.GrpName); break; case Brw_ADMI_SHR_CRS: Hie.Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs_GetCourseDataByCod (&Hie.Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s", Txt_shared_files_area, Txt_course,Hie.Crs.ShrtName); break; case Brw_ADMI_SHR_GRP: GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; Grp_GetGroupDataByCod (&GrpDat); Hie.Crs.CrsCod = GrpDat.CrsCod; Crs_GetCourseDataByCod (&Hie.Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s %s", Txt_shared_files_area, Txt_course,Hie.Crs.ShrtName, Txt_group,GrpDat.GrpTypName,GrpDat.GrpName); break; case Brw_ADMI_ASG_USR: Hie.Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs_GetCourseDataByCod (&Hie.Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s", Txt_assignments_area, Txt_course,Hie.Crs.ShrtName, Txt_user[Gbl.Usrs.Me.UsrDat.Sex],Gbl.Usrs.Me.UsrDat.FullName); break; case Brw_ADMI_WRK_USR: Hie.Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs_GetCourseDataByCod (&Hie.Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s", Txt_works_area, Txt_course,Hie.Crs.ShrtName, Txt_user[Gbl.Usrs.Me.UsrDat.Sex],Gbl.Usrs.Me.UsrDat.FullName); break; case Brw_ADMI_ASG_CRS: Hie.Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs_GetCourseDataByCod (&Hie.Crs); Usr_UsrDataConstructor (&UsrDat); UsrDat.UsrCod = Gbl.FileBrowser.Clipboard.WorksUsrCod; Usr_GetAllUsrDataFromUsrCod (&UsrDat, Usr_DONT_GET_PREFS, Usr_DONT_GET_ROLE_IN_CURRENT_CRS); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s", Txt_assignments_area, Txt_course,Hie.Crs.ShrtName, Txt_user[UsrDat.Sex],UsrDat.FullName); Usr_UsrDataDestructor (&UsrDat); break; case Brw_ADMI_WRK_CRS: Hie.Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs_GetCourseDataByCod (&Hie.Crs); Usr_UsrDataConstructor (&UsrDat); UsrDat.UsrCod = Gbl.FileBrowser.Clipboard.WorksUsrCod; Usr_GetAllUsrDataFromUsrCod (&UsrDat, Usr_DONT_GET_PREFS, Usr_DONT_GET_ROLE_IN_CURRENT_CRS); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s", Txt_works_area, Txt_course,Hie.Crs.ShrtName, Txt_user[UsrDat.Sex],UsrDat.FullName); Usr_UsrDataDestructor (&UsrDat); break; case Brw_ADMI_DOC_PRJ: case Brw_ADMI_ASS_PRJ: Prj_AllocMemProject (&Prj); Prj.PrjCod = Gbl.FileBrowser.Clipboard.Cod; Prj_GetProjectDataByCod (&Prj); Hie.Crs.CrsCod = Prj.CrsCod; Crs_GetCourseDataByCod (&Hie.Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s", Gbl.FileBrowser.Clipboard.FileBrowser == Brw_ADMI_DOC_PRJ ? Txt_project_documents : Txt_project_assessment, Txt_course,Hie.Crs.ShrtName, Txt_project,Prj.Title); Prj_FreeMemProject (&Prj); break; case Brw_ADMI_MRK_CRS: Hie.Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; Crs_GetCourseDataByCod (&Hie.Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s", Txt_marks_management_area, Txt_course,Hie.Crs.ShrtName); break; case Brw_ADMI_MRK_GRP: GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; Grp_GetGroupDataByCod (&GrpDat); Hie.Crs.CrsCod = GrpDat.CrsCod; Crs_GetCourseDataByCod (&Hie.Crs); snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s, %s %s %s", Txt_marks_management_area, Txt_course,Hie.Crs.ShrtName, Txt_group,GrpDat.GrpTypName,GrpDat.GrpName); break; case Brw_ADMI_BRF_USR: snprintf (TxtClipboardZone,sizeof (TxtClipboardZone), "%s, %s %s", Txt_temporary_private_storage_area, Txt_user[Gbl.Usrs.Me.UsrDat.Sex],Gbl.Usrs.Me.UsrDat.FullName); break; default: break; } if (Gbl.FileBrowser.Clipboard.Level) // Is the root folder? { // Not the root folder Brw_GetFileNameToShowDependingOnLevel (Gbl.FileBrowser.Clipboard.FileBrowser, Gbl.FileBrowser.Clipboard.Level, Gbl.FileBrowser.Clipboard.FilFolLnk.Type, Gbl.FileBrowser.Clipboard.FilFolLnk.Name, FileNameToShow); Ale_ShowAlert (Ale_CLIPBOARD,"%s: %s, %s %s.", Txt_Copy_source,TxtClipboardZone, *TxtFileType[Gbl.FileBrowser.Clipboard.FilFolLnk.Type], FileNameToShow); } else // The root folder Ale_ShowAlert (Ale_CLIPBOARD,"%s: %s, %s.", Txt_Copy_source,TxtClipboardZone, Txt_all_files_inside_the_root_folder); } /*****************************************************************************/ /********************** Get data of my current clipboard *********************/ /*****************************************************************************/ // Returns true if something found // Returns false and void data if nothing found static bool Brw_GetMyClipboard (void) { MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned NumRows; unsigned UnsignedNum; /***** Clear clipboard data *****/ Gbl.FileBrowser.Clipboard.FileBrowser = Brw_UNKNOWN; Gbl.FileBrowser.Clipboard.Cod = -1L; Gbl.FileBrowser.Clipboard.WorksUsrCod = -1L; Gbl.FileBrowser.Clipboard.FilFolLnk.Type = Brw_IS_UNKNOWN; Gbl.FileBrowser.Clipboard.FilFolLnk.Full[0] = '\0'; Gbl.FileBrowser.Clipboard.FilFolLnk.Name[0] = '\0'; Gbl.FileBrowser.Clipboard.Level = 0; /***** Get my current clipboard from database *****/ if ((NumRows = Brw_DB_GetMyClipboard (&mysql_res)) == 1) { /***** Get clipboard data *****/ row = mysql_fetch_row (mysql_res); /* Get file browser type (row[0]) */ if (sscanf (row[0],"%u",&UnsignedNum) == 1) { Gbl.FileBrowser.Clipboard.FileBrowser = (Brw_FileBrowser_t) UnsignedNum; /* Get institution/center/degree/course/group code (row[1]) */ Gbl.FileBrowser.Clipboard.Cod = Str_ConvertStrCodToLongCod (row[1]); /* Get works user's code (row[2]) */ Gbl.FileBrowser.Clipboard.WorksUsrCod = Str_ConvertStrCodToLongCod (row[2]); /* Get file type (row[3]) */ Gbl.FileBrowser.Clipboard.FilFolLnk.Type = Brw_IS_UNKNOWN; // default if (sscanf (row[3],"%u",&UnsignedNum) == 1) if (UnsignedNum < Brw_NUM_FILE_TYPES) Gbl.FileBrowser.Clipboard.FilFolLnk.Type = (Brw_FileType_t) UnsignedNum; /* Get file path (row[4]) */ Str_Copy (Gbl.FileBrowser.Clipboard.FilFolLnk.Full,row[4], sizeof (Gbl.FileBrowser.Clipboard.FilFolLnk.Full) - 1); Str_SplitFullPathIntoPathAndFileName (Gbl.FileBrowser.Clipboard.FilFolLnk.Full, Gbl.FileBrowser.Clipboard.FilFolLnk.Path, Gbl.FileBrowser.Clipboard.FilFolLnk.Name); /* Set clipboard level (number of slashes in full path, including file or folder) */ Gbl.FileBrowser.Clipboard.Level = Brw_NumLevelsInPath (Gbl.FileBrowser.Clipboard.FilFolLnk.Full); } } /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); if (NumRows > 1) Err_WrongCopySrcExit (); return NumRows == 1; } /*****************************************************************************/ /********* Check if the clipboard is in the current file browser *************/ /*****************************************************************************/ static bool Brw_CheckIfClipboardIsInThisTree (void) { if (Gbl.FileBrowser.Clipboard.FileBrowser == Brw_FileBrowserForDB_clipboard[Gbl.FileBrowser.Type]) { switch (Gbl.FileBrowser.Clipboard.FileBrowser) { case Brw_ADMI_DOC_INS: case Brw_ADMI_SHR_INS: if (Gbl.FileBrowser.Clipboard.Cod == Gbl.Hierarchy.Ins.InsCod) return true; // I am in the institution of the clipboard break; case Brw_ADMI_DOC_CTR: case Brw_ADMI_SHR_CTR: if (Gbl.FileBrowser.Clipboard.Cod == Gbl.Hierarchy.Ctr.CtrCod) return true; // I am in the center of the clipboard break; case Brw_ADMI_DOC_DEG: case Brw_ADMI_SHR_DEG: if (Gbl.FileBrowser.Clipboard.Cod == Gbl.Hierarchy.Deg.DegCod) return true; // I am in the degree of the clipboard break; case Brw_ADMI_DOC_CRS: case Brw_ADMI_TCH_CRS: case Brw_ADMI_SHR_CRS: case Brw_ADMI_MRK_CRS: case Brw_ADMI_ASG_USR: case Brw_ADMI_WRK_USR: if (Gbl.FileBrowser.Clipboard.Cod == Gbl.Hierarchy.Crs.CrsCod) return true; // I am in the course of the clipboard break; case Brw_ADMI_ASG_CRS: case Brw_ADMI_WRK_CRS: if (Gbl.FileBrowser.Clipboard.Cod == Gbl.Hierarchy.Crs.CrsCod && Gbl.FileBrowser.Clipboard.WorksUsrCod == Gbl.Usrs.Other.UsrDat.UsrCod) return true; // I am in the course of the clipboard // I am in the student's works of the clipboard break; case Brw_ADMI_DOC_GRP: case Brw_ADMI_TCH_GRP: case Brw_ADMI_SHR_GRP: case Brw_ADMI_MRK_GRP: if (Gbl.FileBrowser.Clipboard.Cod == Gbl.Crs.Grps.GrpCod) return true; // I am in the group of the clipboard break; case Brw_ADMI_DOC_PRJ: case Brw_ADMI_ASS_PRJ: if (Gbl.FileBrowser.Clipboard.Cod == Prj_GetPrjCod ()) return true; // I am in the project of the clipboard break; case Brw_ADMI_BRF_USR: return true; default: break; } } return false; } /*****************************************************************************/ /* Get code of institution, degree, course, group depending on file browser **/ /*****************************************************************************/ long Brw_GetCodForFileBrowser (void) { switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_INS: case Brw_ADMI_DOC_INS: case Brw_ADMI_SHR_INS: return Gbl.Hierarchy.Ins.InsCod; case Brw_SHOW_DOC_CTR: case Brw_ADMI_DOC_CTR: case Brw_ADMI_SHR_CTR: return Gbl.Hierarchy.Ctr.CtrCod; case Brw_SHOW_DOC_DEG: case Brw_ADMI_DOC_DEG: case Brw_ADMI_SHR_DEG: return Gbl.Hierarchy.Deg.DegCod; case Brw_SHOW_DOC_CRS: case Brw_ADMI_DOC_CRS: case Brw_ADMI_TCH_CRS: case Brw_ADMI_SHR_CRS: case Brw_SHOW_MRK_CRS: case Brw_ADMI_MRK_CRS: case Brw_ADMI_ASG_USR: case Brw_ADMI_ASG_CRS: case Brw_ADMI_WRK_USR: case Brw_ADMI_WRK_CRS: return Gbl.Hierarchy.Crs.CrsCod; case Brw_SHOW_DOC_GRP: case Brw_ADMI_DOC_GRP: case Brw_ADMI_TCH_GRP: case Brw_ADMI_SHR_GRP: case Brw_SHOW_MRK_GRP: case Brw_ADMI_MRK_GRP: return Gbl.Crs.Grps.GrpCod; case Brw_ADMI_DOC_PRJ: case Brw_ADMI_ASS_PRJ: return Prj_GetPrjCod (); case Brw_ADMI_BRF_USR: return -1L; default: return -1L; } } /*****************************************************************************/ /******** Get code of user in assignment / works for expanded folders ********/ /*****************************************************************************/ long Brw_GetZoneUsrCodForFileBrowser (void) { if (Brw_GetIfBriefcaseFileBrowser ()) // Briefcase return Gbl.Usrs.Me.UsrDat.UsrCod; if (Brw_GetIfUsrAssigWorksFileBrowser ()) // My assignments or works return Gbl.Usrs.Me.UsrDat.UsrCod; if (Brw_GetIfCrsAssigWorksFileBrowser ()) // Course assignments or works return Gbl.Usrs.Other.UsrDat.UsrCod; return -1L; } /*****************************************************************************/ /***** Insert folders until specified folder to table of expanded folders ****/ /***** and update click time of the other folders in the expl. tree ****/ /*****************************************************************************/ // Important: parameter Path must end in a folder, not in a file static void Brw_InsFoldersInPathAndUpdOtherFoldersInExpandedFolders (const char Path[PATH_MAX + 1]) { char *Ptr; char CopyOfPath[PATH_MAX + 1]; /* Example: Path = root_folder/folder1/folder2/folder3 1. Try to insert CopyOfPath = "root_folder/folder1/folder2/folder3" 2. Try to insert CopyOfPath = "root_folder/folder1/folder2" 3. Try to insert CopyOfPath = "root_folder/folder1" Only insert paths with '/', so "root_folder" is not inserted */ /***** Make a copy to keep Path unchanged *****/ Str_Copy (CopyOfPath,Path,sizeof (CopyOfPath) - 1); /***** Insert paths in table of expanded folders if they are not yet there *****/ do { if ((Ptr = strrchr (CopyOfPath,'/'))) // If '/' found (backwards from the end) { if (!Brw_DB_GetIfExpandedFolder (CopyOfPath)) Brw_DB_InsertFolderInExpandedFolders (CopyOfPath); // Now Ptr points to the last '/' in SubPath *Ptr = '\0'; // Substitute '/' for '\0' to shorten CopyOfPath } } while (Ptr); /***** Update paths of the current file browser in table of expanded folders *****/ Brw_DB_UpdateClickTimeOfThisFileBrowserInExpandedFolders (); } /*****************************************************************************/ /******* Remove specified folder from table of expanded folders ********/ /******* and update click time of the other folders in the expl. tree ********/ /*****************************************************************************/ static void Brw_RemThisFolderAndUpdOtherFoldersFromExpandedFolders (const char Path[PATH_MAX + 1]) { /***** Remove Path from expanded folders table *****/ Brw_DB_RemoveFolderFromExpandedFolders (Path); /***** Update paths of the current file browser in table of expanded folders *****/ Brw_DB_UpdateClickTimeOfThisFileBrowserInExpandedFolders (); } /*****************************************************************************/ /**** Paste the arch/carp indicado in the portapapelesde in file browser *****/ /*****************************************************************************/ void Brw_PasteIntoFileBrowser (void) { extern const char *Txt_Nothing_has_been_pasted_because_the_clipboard_is_empty_; struct GroupData GrpDat; struct BrwSiz_BrowserSize *Size = BrwSiz_GetSize (); /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); if (Brw_GetMyClipboard ()) { switch (Gbl.FileBrowser.Clipboard.FileBrowser) { case Brw_ADMI_DOC_GRP: case Brw_ADMI_TCH_GRP: case Brw_ADMI_SHR_GRP: case Brw_ADMI_MRK_GRP: // Clipboard in a group zone GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; Brw_GetSelectedGroupData (&GrpDat,true); break; default: break; } /***** Copy files recursively *****/ Brw_PasteClipboard (Size); /***** Remove the affected clipboards *****/ Brw_DB_RemoveAffectedClipboards (Gbl.FileBrowser.Type, Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Other.UsrDat.UsrCod); } else /***** Write message ******/ Ale_ShowAlert (Ale_WARNING,Txt_Nothing_has_been_pasted_because_the_clipboard_is_empty_); /***** Show again file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /************* Paste all clipboard content at current location ***************/ /*****************************************************************************/ // Source: // Type of file browser: Gbl.FileBrowser.Clipboard.FileBrowser // Possible institution: Gbl.FileBrowser.Clipboard.InsCod // Possible center: Gbl.FileBrowser.Clipboard.CtrCod // Possible degree: Gbl.FileBrowser.Clipboard.DegCod // Possible course: Gbl.FileBrowser.Clipboard.CrsCod // Possible student in works: Gbl.FileBrowser.Clipboard.WorksUsrCod // Path (file or folder): Gbl.FileBrowser.Clipboard.FilFolLnk.Full // Destination: // Type of file browser: Gbl.FileBrowser.Type // Possible institution: Gbl.Hierarchy.Ins.InsCod // Possible center: Gbl.Hierarchy.Ctr.CtrCod // Possible degree: Gbl.Hierarchy.Deg.DegCod // Possible course: Gbl.Hierarchy.Crs.CrsCod // Possible student in works: Gbl.Usrs.Other.UsrDat.UsrCod // Path (should be a folder): Gbl.FileBrowser.FilFolLnk.Full // Returns the number of files pasted static void Brw_PasteClipboard (struct BrwSiz_BrowserSize *Size) { extern const char *Txt_The_copy_has_been_successful; extern const char *Txt_Files_copied; extern const char *Txt_Links_copied; extern const char *Txt_Folders_copied; extern const char *Txt_You_can_not_paste_file_or_folder_here; struct Hie_Hierarchy Hie; struct GroupData GrpDat; struct Usr_Data UsrDat; long PrjCod; char PathOrg[PATH_MAX + NAME_MAX + PATH_MAX + 128]; struct Brw_NumObjects Pasted; long FirstFilCod = -1L; // First file code of the first file or link pasted. Important: initialize here to -1L struct Brw_FileMetadata FileMetadata; Pasted.NumFiles = Pasted.NumLinks = Pasted.NumFolds = 0; Gbl.FileBrowser.Clipboard.IsThisTree = Brw_CheckIfClipboardIsInThisTree (); if (Brw_CheckIfCanPasteIn (Gbl.FileBrowser.Level)) { /***** Construct the relative path of the origin file or folder *****/ switch (Gbl.FileBrowser.Clipboard.FileBrowser) { case Brw_ADMI_DOC_INS: case Brw_ADMI_SHR_INS: Hie.Ins.InsCod = Gbl.FileBrowser.Clipboard.Cod; if (Ins_GetInstitDataByCod (&Hie.Ins)) snprintf (PathOrg,sizeof (PathOrg),"%s/%02u/%u/%s", Cfg_PATH_INS_PRIVATE, (unsigned) (Hie.Ins.InsCod % 100), (unsigned) Hie.Ins.InsCod, Gbl.FileBrowser.Clipboard.FilFolLnk.Full); else Err_WrongCopySrcExit (); break; case Brw_ADMI_DOC_CTR: case Brw_ADMI_SHR_CTR: Hie.Ctr.CtrCod = Gbl.FileBrowser.Clipboard.Cod; if (Ctr_GetCenterDataByCod (&Hie.Ctr)) snprintf (PathOrg,sizeof (PathOrg),"%s/%02u/%u/%s", Cfg_PATH_CTR_PRIVATE, (unsigned) (Hie.Ctr.CtrCod % 100), (unsigned) Hie.Ctr.CtrCod, Gbl.FileBrowser.Clipboard.FilFolLnk.Full); else Err_WrongCopySrcExit (); break; case Brw_ADMI_DOC_DEG: case Brw_ADMI_SHR_DEG: Hie.Deg.DegCod = Gbl.FileBrowser.Clipboard.Cod; if (Deg_GetDegreeDataByCod (&Hie.Deg)) snprintf (PathOrg,sizeof (PathOrg),"%s/%02u/%u/%s", Cfg_PATH_DEG_PRIVATE, (unsigned) (Hie.Deg.DegCod % 100), (unsigned) Hie.Deg.DegCod, Gbl.FileBrowser.Clipboard.FilFolLnk.Full); else Err_WrongCopySrcExit (); break; case Brw_ADMI_DOC_CRS: case Brw_ADMI_TCH_CRS: case Brw_ADMI_SHR_CRS: case Brw_ADMI_MRK_CRS: Hie.Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; if (Crs_GetCourseDataByCod (&Hie.Crs)) snprintf (PathOrg,sizeof (PathOrg),"%s/%ld/%s", Cfg_PATH_CRS_PRIVATE,Hie.Crs.CrsCod, Gbl.FileBrowser.Clipboard.FilFolLnk.Full); else Err_WrongCopySrcExit (); break; case Brw_ADMI_DOC_GRP: case Brw_ADMI_TCH_GRP: case Brw_ADMI_SHR_GRP: case Brw_ADMI_MRK_GRP: GrpDat.GrpCod = Gbl.FileBrowser.Clipboard.Cod; Grp_GetGroupDataByCod (&GrpDat); Hie.Crs.CrsCod = GrpDat.CrsCod; if (Crs_GetCourseDataByCod (&Hie.Crs)) snprintf (PathOrg,sizeof (PathOrg),"%s/%ld/%s/%ld/%s", Cfg_PATH_CRS_PRIVATE,Hie.Crs.CrsCod,Cfg_FOLDER_GRP, GrpDat.GrpCod, Gbl.FileBrowser.Clipboard.FilFolLnk.Full); else Err_WrongCopySrcExit (); break; case Brw_ADMI_ASG_CRS: case Brw_ADMI_WRK_CRS: Hie.Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; if (Crs_GetCourseDataByCod (&Hie.Crs)) { Usr_UsrDataConstructor (&UsrDat); if (Usr_DB_ChkIfUsrCodExists (Gbl.FileBrowser.Clipboard.WorksUsrCod)) UsrDat.UsrCod = Gbl.FileBrowser.Clipboard.WorksUsrCod; Usr_GetAllUsrDataFromUsrCod (&UsrDat, Usr_DONT_GET_PREFS, Usr_DONT_GET_ROLE_IN_CURRENT_CRS); // Check that user exists snprintf (PathOrg,sizeof (PathOrg),"%s/%ld/%s/%02u/%ld/%s", Cfg_PATH_CRS_PRIVATE,Hie.Crs.CrsCod,Cfg_FOLDER_USR, (unsigned) (Gbl.FileBrowser.Clipboard.WorksUsrCod % 100), Gbl.FileBrowser.Clipboard.WorksUsrCod, Gbl.FileBrowser.Clipboard.FilFolLnk.Full); Usr_UsrDataDestructor (&UsrDat); } else Err_WrongCopySrcExit (); break; case Brw_ADMI_ASG_USR: case Brw_ADMI_WRK_USR: Hie.Crs.CrsCod = Gbl.FileBrowser.Clipboard.Cod; if (Crs_GetCourseDataByCod (&Hie.Crs)) snprintf (PathOrg,sizeof (PathOrg),"%s/%ld/%s/%02u/%ld/%s", Cfg_PATH_CRS_PRIVATE,Hie.Crs.CrsCod,Cfg_FOLDER_USR, (unsigned) (Gbl.Usrs.Me.UsrDat.UsrCod % 100), Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.FileBrowser.Clipboard.FilFolLnk.Full); else Err_WrongCopySrcExit (); break; case Brw_ADMI_DOC_PRJ: case Brw_ADMI_ASS_PRJ: PrjCod = Gbl.FileBrowser.Clipboard.Cod; Hie.Crs.CrsCod = Prj_DB_GetCrsOfPrj (PrjCod); if (Crs_GetCourseDataByCod (&Hie.Crs)) snprintf (PathOrg,sizeof (PathOrg),"%s/%ld/%s/%02u/%ld/%s", Cfg_PATH_CRS_PRIVATE,Hie.Crs.CrsCod,Cfg_FOLDER_PRJ, (unsigned) (PrjCod % 100), PrjCod, Gbl.FileBrowser.Clipboard.FilFolLnk.Full); else Err_WrongCopySrcExit (); break; case Brw_ADMI_BRF_USR: snprintf (PathOrg,sizeof (PathOrg),"%s/%s", Gbl.Usrs.Me.PathDir, Gbl.FileBrowser.Clipboard.FilFolLnk.Full); break; default: Err_WrongFileBrowserExit (); break; } /***** Paste tree (path in clipboard) into folder *****/ BrwSiz_CalcSizeOfDir (Size,Gbl.FileBrowser.Priv.PathRootFolder); BrwSiz_SetMaxQuota (Size); if (Brw_PasteTreeIntoFolder (Size, Gbl.FileBrowser.Clipboard.Level, PathOrg, Gbl.FileBrowser.FilFolLnk.Full, &Pasted, &FirstFilCod)) { /***** Write message of success *****/ Ale_ShowAlert (Ale_SUCCESS,"%s
" "%s: %u
" "%s: %u
" "%s: %u", Txt_The_copy_has_been_successful, Txt_Files_copied ,Pasted.NumFiles, Txt_Links_copied ,Pasted.NumLinks, Txt_Folders_copied,Pasted.NumFolds); /***** Notify new files *****/ if (Pasted.NumFiles || Pasted.NumLinks) { FileMetadata.FilCod = FirstFilCod; Brw_GetFileMetadataByCod (&FileMetadata); /* Notify only is destination folder is visible */ if (!Brw_DB_CheckIfFileOrFolderIsSetAsHiddenUsingMetadata (&FileMetadata)) switch (Gbl.FileBrowser.Type) { case Brw_ADMI_DOC_CRS: case Brw_ADMI_DOC_GRP: Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_DOCUMENT_FILE,FirstFilCod); break; case Brw_ADMI_TCH_CRS: case Brw_ADMI_TCH_GRP: Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_TEACHERS_FILE,FirstFilCod); break; case Brw_ADMI_SHR_CRS: case Brw_ADMI_SHR_GRP: Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_SHARED_FILE,FirstFilCod); break; case Brw_ADMI_MRK_CRS: case Brw_ADMI_MRK_GRP: Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_MARKS_FILE,FirstFilCod); break; default: break; } } } /***** Add path where new tree is pasted to table of expanded folders *****/ Brw_InsFoldersInPathAndUpdOtherFoldersInExpandedFolders (Gbl.FileBrowser.FilFolLnk.Full); } else Err_ShowErrorAndExit (Txt_You_can_not_paste_file_or_folder_here); // It's difficult, but not impossible that a user sees this message } /*****************************************************************************/ /****************** Compute number of levels in a path ***********************/ /*****************************************************************************/ static unsigned Brw_NumLevelsInPath (const char Path[PATH_MAX + 1]) { unsigned NumLevls = 0; while (*Path) if (*Path++ == '/') NumLevls++; return NumLevls; } /*****************************************************************************/ /********** Copy a source file or tree in the destination folder *************/ /*****************************************************************************/ // Return true if the copy has been made successfully, and false if not static bool Brw_PasteTreeIntoFolder (struct BrwSiz_BrowserSize *Size, unsigned LevelOrg, const char PathOrg[PATH_MAX + 1], const char PathDstInTree[PATH_MAX + 1], struct Brw_NumObjects *Pasted, long *FirstFilCod) { extern const char *Txt_The_copy_has_stopped_when_trying_to_paste_the_file_X_because_it_would_exceed_the_disk_quota; extern const char *Txt_The_copy_has_stopped_when_trying_to_paste_the_folder_X_because_it_would_exceed_the_disk_quota; extern const char *Txt_The_copy_has_stopped_when_trying_to_paste_the_link_X_because_it_would_exceed_the_disk_quota; extern const char *Txt_The_copy_has_stopped_when_trying_to_paste_the_file_X_because_it_would_exceed_the_maximum_allowed_number_of_levels; extern const char *Txt_The_copy_has_stopped_when_trying_to_paste_the_folder_X_because_it_would_exceed_the_maximum_allowed_number_of_levels; extern const char *Txt_The_copy_has_stopped_when_trying_to_paste_the_link_X_because_it_would_exceed_the_maximum_allowed_number_of_levels; extern const char *Txt_The_copy_has_stopped_when_trying_to_paste_the_file_X_because_there_is_already_an_object_with_that_name; extern const char *Txt_The_copy_has_stopped_when_trying_to_paste_the_link_X_because_there_is_already_an_object_with_that_name; extern const char *Txt_The_copy_has_stopped_when_trying_to_paste_the_file_X_because_you_can_not_paste_a_file_here_of_a_type_other_than_HTML; Brw_FileType_t FileType; char PathUntilFileNameOrg[PATH_MAX + 1]; char FileNameOrg[NAME_MAX + 1]; char FileNameToShow[NAME_MAX + 1]; char PathInFolderOrg[PATH_MAX + 1]; char PathDstInTreeWithFile[PATH_MAX + 1 + NAME_MAX + 1]; char PathDstWithFile[PATH_MAX + 1 + PATH_MAX + 1 + NAME_MAX + 1]; struct stat FileStatus; struct dirent **FileList; bool AdminMarks; struct Mrk_Properties Marks; int NumFile; int NumFiles; unsigned NumLevls; long FilCod; // File code of the file pasted bool CopyIsGoingSuccessful = true; /***** Get the name (only the name) of the origin file or folder *****/ Str_SplitFullPathIntoPathAndFileName (PathOrg, PathUntilFileNameOrg, FileNameOrg); /***** Is it a file or a folder? *****/ FileType = Brw_IS_UNKNOWN; if (lstat (PathOrg,&FileStatus)) // On success ==> 0 is returned Err_ShowErrorAndExit ("Can not get information about a file or folder."); else if (S_ISDIR (FileStatus.st_mode)) // It's a directory FileType = Brw_IS_FOLDER; else if (S_ISREG (FileStatus.st_mode)) // It's a regular file FileType = Str_FileIs (FileNameOrg,"url") ? Brw_IS_LINK : // It's a link (URL inside a .url file) Brw_IS_FILE; // It's a file /***** Name of the file/folder/link to be shown ****/ Brw_GetFileNameToShow (FileType,FileNameOrg,FileNameToShow); /***** Construct the name of the destination file or folder *****/ if (LevelOrg == 0) // Origin of copy is the root folder, // for example "sha" // ==> do not copy the root folder itself into destination Str_Copy (PathDstInTreeWithFile,PathDstInTree, sizeof (PathDstInTreeWithFile) - 1); else // Origin of copy is a file or folder inside the root folder // for example "sha/folder1/file1" snprintf (PathDstInTreeWithFile,sizeof (PathDstInTreeWithFile),"%s/%s", PathDstInTree,FileNameOrg); /***** Construct the relative path of the destination file or folder *****/ snprintf (PathDstWithFile,sizeof (PathDstWithFile),"%s/%s", Gbl.FileBrowser.Priv.PathAboveRootFolder, PathDstInTreeWithFile); /***** Update and check number of levels *****/ // The number of levels is counted starting on the root folder raíz, not included. // Example: If PathDstInTreeWithFile is "root-folder/1/2/3/4/FileNameOrg", then NumLevls=5 if ((NumLevls = Brw_NumLevelsInPath (PathDstInTreeWithFile)) > Size->NumLevls) Size->NumLevls = NumLevls; if (BrwSiz_CheckIfQuotaExceded (Size)) { switch (FileType) { case Brw_IS_FILE: Ale_ShowAlert (Ale_WARNING,Txt_The_copy_has_stopped_when_trying_to_paste_the_file_X_because_it_would_exceed_the_maximum_allowed_number_of_levels, FileNameToShow); break; case Brw_IS_FOLDER: Ale_ShowAlert (Ale_WARNING,Txt_The_copy_has_stopped_when_trying_to_paste_the_folder_X_because_it_would_exceed_the_maximum_allowed_number_of_levels, FileNameToShow); break; case Brw_IS_LINK: Ale_ShowAlert (Ale_WARNING,Txt_The_copy_has_stopped_when_trying_to_paste_the_link_X_because_it_would_exceed_the_maximum_allowed_number_of_levels, FileNameToShow); break; default: Err_ShowErrorAndExit ("Can not paste unknown file type."); } CopyIsGoingSuccessful = false; } else // Quota not exceeded { /***** Copy file or folder *****/ if (FileType == Brw_IS_FILE || FileType == Brw_IS_LINK) // It's a regular file { /***** Check if exists the destination file */ if (Fil_CheckIfPathExists (PathDstWithFile)) { Ale_ShowAlert (Ale_WARNING,FileType == Brw_IS_FILE ? Txt_The_copy_has_stopped_when_trying_to_paste_the_file_X_because_there_is_already_an_object_with_that_name : Txt_The_copy_has_stopped_when_trying_to_paste_the_link_X_because_there_is_already_an_object_with_that_name, FileNameToShow); CopyIsGoingSuccessful = false; } else // Destination file does not exist { /***** If the target file browser is that of marks, only HTML files are allowed *****/ AdminMarks = Gbl.FileBrowser.Type == Brw_ADMI_MRK_CRS || Gbl.FileBrowser.Type == Brw_ADMI_MRK_GRP; if (AdminMarks) { /* Check extension of the file */ if (Str_FileIsHTML (FileNameOrg)) Mrk_CheckFileOfMarks (PathOrg,&Marks); else { Ale_ShowAlert (Ale_WARNING,Txt_The_copy_has_stopped_when_trying_to_paste_the_file_X_because_you_can_not_paste_a_file_here_of_a_type_other_than_HTML, FileNameToShow); CopyIsGoingSuccessful = false; } } if (CopyIsGoingSuccessful) { /***** Update and check the quota before copying the file *****/ Size->NumFiles++; Size->TotalSiz += (unsigned long long) FileStatus.st_size; if (BrwSiz_CheckIfQuotaExceded (Size)) { Ale_ShowAlert (Ale_WARNING,FileType == Brw_IS_FILE ? Txt_The_copy_has_stopped_when_trying_to_paste_the_file_X_because_it_would_exceed_the_disk_quota : Txt_The_copy_has_stopped_when_trying_to_paste_the_link_X_because_it_would_exceed_the_disk_quota, FileNameToShow); CopyIsGoingSuccessful = false; } else // Quota not exceeded { /***** Quota will not be exceeded ==> copy the origin file to the destination file *****/ Fil_FastCopyOfFiles (PathOrg,PathDstWithFile); /***** Add entry to the table of files/folders *****/ FilCod = Brw_DB_AddPath (Gbl.Usrs.Me.UsrDat.UsrCod,FileType, PathDstInTreeWithFile,false,Brw_LICENSE_DEFAULT); if (*FirstFilCod <= 0) *FirstFilCod = FilCod; /* Add a new entry of marks into database */ if (AdminMarks) Mrk_DB_AddMarks (FilCod,&Marks); if (FileType == Brw_IS_FILE) (Pasted->NumFiles)++; else // FileType == Brw_IS_LINK (Pasted->NumLinks)++; } } } } else if (FileType == Brw_IS_FOLDER) // It's a directory { /***** Scan the source directory *****/ if ((NumFiles = scandir (PathOrg,&FileList,NULL,alphasort)) >= 0) // No error { /***** Create the folder in the destination *****/ if (!Fil_CheckIfPathExists (PathDstWithFile)) // If already exists, don't overwrite { /* The directory does not exist ==> create it. First, update and check the quota */ Size->NumFolds++; Size->TotalSiz += (unsigned long long) FileStatus.st_size; if (BrwSiz_CheckIfQuotaExceded (Size)) { Ale_ShowAlert (Ale_WARNING,Txt_The_copy_has_stopped_when_trying_to_paste_the_folder_X_because_it_would_exceed_the_disk_quota, FileNameToShow); CopyIsGoingSuccessful = false; } else // Quota not exceded { /* Create directory */ if (mkdir (PathDstWithFile,(mode_t) 0xFFF) != 0) Err_ShowErrorAndExit ("Can not create folder."); /* Add entry to the table of files/folders */ Brw_DB_AddPath (Gbl.Usrs.Me.UsrDat.UsrCod,FileType, PathDstInTreeWithFile,false,Brw_LICENSE_DEFAULT); } } /***** Copy each of the files and folders from the origin to the destination *****/ for (NumFile = 0; NumFile < NumFiles; NumFile++) { if (CopyIsGoingSuccessful && strcmp (FileList[NumFile]->d_name,".") && strcmp (FileList[NumFile]->d_name,"..")) // Skip directories "." and ".." { snprintf (PathInFolderOrg,sizeof (PathInFolderOrg),"%s/%s", PathOrg,FileList[NumFile]->d_name); /* Recursive call to this function */ if (!Brw_PasteTreeIntoFolder (Size, LevelOrg + 1, PathInFolderOrg, PathDstInTreeWithFile, Pasted, FirstFilCod)) CopyIsGoingSuccessful = false; } free (FileList[NumFile]); } free (FileList); } else Err_ShowErrorAndExit ("Error while scanning directory."); if (CopyIsGoingSuccessful && LevelOrg != 0) // When copying all files inside root folder, // do not count the root folder itself (Pasted->NumFolds)++; } } return CopyIsGoingSuccessful; } /*****************************************************************************/ /************** Form to add a file or folder to a file browser ***************/ /*****************************************************************************/ void Brw_ShowFormFileBrowser (void) { extern const char *Txt_You_can_not_create_folders_files_or_links_here; char FileNameToShow[NAME_MAX + 1]; /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); /***** Check if creating a new folder or file is allowed *****/ if (Brw_CheckIfICanCreateIntoFolder (Gbl.FileBrowser.Level)) { /***** Name of the folder to be shown ****/ Brw_GetFileNameToShowDependingOnLevel (Gbl.FileBrowser.Type, Gbl.FileBrowser.Level, Gbl.FileBrowser.FilFolLnk.Type, Gbl.FileBrowser.FilFolLnk.Name, FileNameToShow); /***** 1. Form to create a new folder *****/ Brw_PutFormToCreateAFolder (FileNameToShow); /***** 2. Form to send a file *****/ Brw_PutFormToUploadFilesUsingDropzone (FileNameToShow); /***** 3. Form to send a file *****/ Brw_PutFormToUploadOneFileClassic (FileNameToShow); /***** 4. Form to paste the content of the clipboard *****/ if (Brw_GetMyClipboard ()) { /***** Check if we can paste in this folder *****/ Gbl.FileBrowser.Clipboard.IsThisTree = Brw_CheckIfClipboardIsInThisTree (); if (Brw_CheckIfCanPasteIn (Gbl.FileBrowser.Level)) Brw_PutFormToPasteAFileOrFolder (FileNameToShow); } /***** 5. Form to create a link *****/ if (Gbl.FileBrowser.Type != Brw_ADMI_MRK_CRS && Gbl.FileBrowser.Type != Brw_ADMI_MRK_GRP) // Do not create links in marks Brw_PutFormToCreateALink (FileNameToShow); } else { Err_ShowErrorAndExit (Txt_You_can_not_create_folders_files_or_links_here); // It's difficult, but not impossible that a user sees this message /***** Show again file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } } /*****************************************************************************/ /************* Put form to create a new folder in a file browser *************/ /*****************************************************************************/ static void Brw_PutFormToCreateAFolder (const char FileNameToShow[NAME_MAX + 1]) { extern const char *Txt_Create_folder; extern const char *Txt_You_can_create_a_new_folder_inside_the_folder_X; extern const char *Txt_Folder; /***** Begin form *****/ Frm_BeginForm (Brw_ActCreateFolder[Gbl.FileBrowser.Type]); Brw_PutImplicitParsFileBrowser (&Gbl.FileBrowser.FilFolLnk); /***** Begin box *****/ Box_BoxBegin (NULL,Txt_Create_folder, NULL,NULL, NULL,Box_NOT_CLOSABLE); /* Alert */ Ale_ShowAlert (Ale_INFO,Txt_You_can_create_a_new_folder_inside_the_folder_X, FileNameToShow); /* Folder */ HTM_LABEL_Begin ("class=\"FORM_IN_%s\"",The_GetSuffix ()); HTM_TxtColonNBSP (Txt_Folder); HTM_INPUT_TEXT ("NewFolderName",Brw_MAX_CHARS_FOLDER,"", HTM_DONT_SUBMIT_ON_CHANGE, "size=\"30\" class=\"INPUT_%s\"" " required=\"required\"", The_GetSuffix ()); HTM_LABEL_End (); /***** Send button and end box *****/ Box_BoxWithButtonEnd (Btn_CREATE_BUTTON,Txt_Create_folder); /***** End form *****/ Frm_EndForm (); } /*****************************************************************************/ /*** Put form to upload several files to a file browser using Dropzone.js ****/ /*****************************************************************************/ static void Brw_PutFormToUploadFilesUsingDropzone (const char *FileNameToShow) { extern const char *Txt_Upload_files; extern const char *Txt_or_you_can_upload_new_files_to_the_folder_X; extern const char *Txt_Select_one_or_more_files_from_your_computer_or_drag_and_drop_here; extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES]; extern const char *Txt_Done; /***** Begin box *****/ HTM_DIV_Begin ("id=\"dropzone-upload\""); Box_BoxBegin ("95%",Txt_Upload_files, NULL,NULL, NULL,Box_NOT_CLOSABLE); /***** Help message *****/ Ale_ShowAlert (Ale_INFO,Txt_or_you_can_upload_new_files_to_the_folder_X, FileNameToShow); /***** Form to upload files using the library Dropzone.js *****/ // Use min-height:125px; or other number to stablish the height? HTM_TxtF ("
", Cfg_URL_SWAD_CGI, Lan_STR_LANG_ID[Gbl.Prefs.Language], Cfg_URL_ICON_PUBLIC); Par_PutParLong (NULL,"act",Act_GetActCod (Brw_ActUploadFileDropzone[Gbl.FileBrowser.Type])); Par_PutParString (NULL,"ses",Gbl.Session.Id); Brw_PutImplicitParsFileBrowser (&Gbl.FileBrowser.FilFolLnk); HTM_DIV_Begin ("class=\"dz-message\""); HTM_SPAN_Begin ("class=\"DAT_LIGHT_%s\"", The_GetSuffix ()); HTM_Txt (Txt_Select_one_or_more_files_from_your_computer_or_drag_and_drop_here); HTM_SPAN_End (); HTM_DIV_End (); HTM_Txt ("
"); /***** Put button to refresh file browser after upload *****/ Frm_BeginForm (Brw_ActRefreshAfterUploadFiles[Gbl.FileBrowser.Type]); Brw_PutParsFileBrowser (NULL, // Not used NULL, // Not used Brw_IS_UNKNOWN, // Not used -1L); // Not used /***** Button to send *****/ Btn_PutConfirmButton (Txt_Done); /***** End form *****/ Frm_EndForm (); /***** End box *****/ Box_BoxEnd (); HTM_DIV_End (); } /*****************************************************************************/ /*** Put form to upload several files to a file browser using Dropzone.js ****/ /*****************************************************************************/ static void Brw_PutFormToUploadOneFileClassic (const char *FileNameToShow) { extern const char *Txt_Upload_file; extern const char *Txt_or_you_can_upload_a_new_file_to_the_folder_X; /***** Begin box *****/ HTM_DIV_Begin ("id=\"classic-upload\" style=\"display:none;\""); Box_BoxBegin (NULL,Txt_Upload_file, NULL,NULL, NULL,Box_NOT_CLOSABLE); /***** Help message *****/ Ale_ShowAlert (Ale_INFO,Txt_or_you_can_upload_a_new_file_to_the_folder_X, FileNameToShow); /***** Form to upload one files using the classic way *****/ Frm_BeginForm (Brw_ActUploadFileClassic[Gbl.FileBrowser.Type]); Brw_PutImplicitParsFileBrowser (&Gbl.FileBrowser.FilFolLnk); /* File */ HTM_INPUT_FILE (Fil_NAME_OF_PARAM_FILENAME_ORG,"*", HTM_DONT_SUBMIT_ON_CHANGE, NULL); /* Button to send */ Btn_PutCreateButton (Txt_Upload_file); Frm_EndForm (); /***** End box *****/ Box_BoxEnd (); HTM_DIV_End (); } /*****************************************************************************/ /********* Put form to paste a file or a folder into a file browser **********/ /*****************************************************************************/ static void Brw_PutFormToPasteAFileOrFolder (const char *FileNameToShow) { extern const char *Txt_Paste; extern const char *Txt_or_you_can_make_a_file_copy_to_the_folder_X; /***** Begin form *****/ Frm_BeginForm (Brw_ActPaste[Gbl.FileBrowser.Type]); Brw_PutImplicitParsFileBrowser (&Gbl.FileBrowser.FilFolLnk); /***** Begin box *****/ Box_BoxBegin (NULL,Txt_Paste, NULL,NULL, NULL,Box_NOT_CLOSABLE); /***** Help message *****/ Ale_ShowAlert (Ale_INFO,Txt_or_you_can_make_a_file_copy_to_the_folder_X, FileNameToShow); /***** Send button and end box *****/ Box_BoxWithButtonEnd (Btn_CREATE_BUTTON,Txt_Paste); /***** End form *****/ Frm_EndForm (); } /*****************************************************************************/ /************** Put form to create a new link in a file browser **************/ /*****************************************************************************/ static void Brw_PutFormToCreateALink (const char *FileNameToShow) { extern const char *Txt_Create_link; extern const char *Txt_or_you_can_create_a_new_link_inside_the_folder_X; extern const char *Txt_URL; extern const char *Txt_Save_as; extern const char *Txt_optional; char *Label; /***** Begin form *****/ Frm_BeginForm (Brw_ActCreateLink[Gbl.FileBrowser.Type]); Brw_PutImplicitParsFileBrowser (&Gbl.FileBrowser.FilFolLnk); /***** Begin box *****/ Box_BoxBegin (NULL,Txt_Create_link, NULL,NULL, NULL,Box_NOT_CLOSABLE); /***** Help message *****/ Ale_ShowAlert (Ale_INFO,Txt_or_you_can_create_a_new_link_inside_the_folder_X, FileNameToShow); /***** URL *****/ HTM_TABLE_Begin (NULL); HTM_TR_Begin (NULL); /* Label */ Frm_LabelColumn ("RT","NewLinkURL",Txt_URL); /* Data */ HTM_TD_Begin ("class=\"LT\""); HTM_INPUT_URL ("NewLinkURL","",HTM_DONT_SUBMIT_ON_CHANGE, "size=\"30\" class=\"INPUT_%s\"" " required=\"required\"", The_GetSuffix ()); HTM_TD_End (); HTM_TR_End (); /***** Link name *****/ HTM_TR_Begin (NULL); /* Label */ if (asprintf (&Label,"%s (%s): ",Txt_Save_as,Txt_optional) < 0) Err_NotEnoughMemoryExit (); Frm_LabelColumn ("RT","NewLinkName",Label); free (Label); /* Data */ HTM_TD_Begin ("class=\"LM\""); HTM_INPUT_TEXT ("NewLinkName",Brw_MAX_CHARS_FOLDER,"", HTM_DONT_SUBMIT_ON_CHANGE, "id=\"NewLinkName\" size=\"30\"" " class=\"INPUT_%s\"", The_GetSuffix ()); HTM_TD_End (); HTM_TR_End (); HTM_TABLE_End (); /***** Send button and end box *****/ Box_BoxWithButtonEnd (Btn_CREATE_BUTTON,Txt_Create_link); /***** End form *****/ Frm_EndForm (); } /*****************************************************************************/ /*********** Receive the name of a new folder in a file browser **************/ /*****************************************************************************/ void Brw_RecFolderFileBrowser (void) { extern const char *Txt_Can_not_create_the_folder_X_because_it_would_exceed_the_disk_quota; extern const char *Txt_Can_not_create_the_folder_X_because_there_is_already_a_folder_or_a_file_with_that_name; extern const char *Txt_The_folder_X_has_been_created_inside_the_folder_Y; extern const char *Txt_You_can_not_create_folders_here; char Path[PATH_MAX + 1 + PATH_MAX + 1]; char PathCompleteInTreeIncludingFolder[PATH_MAX + 1 + NAME_MAX + 1]; char FileNameToShow[NAME_MAX + 1]; struct BrwSiz_BrowserSize *Size = BrwSiz_GetSize (); /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); /***** Check if creating a new folder is allowed *****/ if (Brw_CheckIfICanCreateIntoFolder (Gbl.FileBrowser.Level)) { if (Str_ConvertFilFolLnkNameToValid (Gbl.FileBrowser.NewFilFolLnkName)) { /* In Gbl.FileBrowser.NewFilFolLnkName is the name of the new folder */ snprintf (Path,sizeof (Path),"%s/%s", Gbl.FileBrowser.Priv.PathAboveRootFolder, Gbl.FileBrowser.FilFolLnk.Full); if (strlen (Path) + 1 + strlen (Gbl.FileBrowser.NewFilFolLnkName) > PATH_MAX) Err_ShowErrorAndExit ("Path is too long."); Str_Concat (Path,"/",sizeof (Path) - 1); Str_Concat (Path,Gbl.FileBrowser.NewFilFolLnkName,sizeof (Path) - 1); /* Create the new directory */ if (mkdir (Path,(mode_t) 0xFFF) == 0) { /* Check if quota has been exceeded */ BrwSiz_CalcSizeOfDir (Size,Gbl.FileBrowser.Priv.PathRootFolder); BrwSiz_SetMaxQuota (Size); if (BrwSiz_CheckIfQuotaExceded (Size)) { Fil_RemoveTree (Path); Ale_ShowAlert (Ale_WARNING,Txt_Can_not_create_the_folder_X_because_it_would_exceed_the_disk_quota, Gbl.FileBrowser.NewFilFolLnkName); } else { /* Remove affected clipboards */ Brw_DB_RemoveAffectedClipboards (Gbl.FileBrowser.Type, Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Other.UsrDat.UsrCod); /* Add path where new file is created to table of expanded folders */ Brw_InsFoldersInPathAndUpdOtherFoldersInExpandedFolders (Gbl.FileBrowser.FilFolLnk.Full); /* Add entry to the table of files/folders */ snprintf (PathCompleteInTreeIncludingFolder, sizeof (PathCompleteInTreeIncludingFolder), "%s/%s", Gbl.FileBrowser.FilFolLnk.Full, Gbl.FileBrowser.NewFilFolLnkName); Brw_DB_AddPath (Gbl.Usrs.Me.UsrDat.UsrCod,Brw_IS_FOLDER, PathCompleteInTreeIncludingFolder,false,Brw_LICENSE_DEFAULT); /* The folder has been created sucessfully */ Brw_GetFileNameToShowDependingOnLevel (Gbl.FileBrowser.Type, Gbl.FileBrowser.Level, Brw_IS_FOLDER, Gbl.FileBrowser.FilFolLnk.Name, FileNameToShow); Ale_ShowAlert (Ale_SUCCESS,Txt_The_folder_X_has_been_created_inside_the_folder_Y, Gbl.FileBrowser.NewFilFolLnkName,FileNameToShow); } } else { switch (errno) { case EEXIST: Ale_ShowAlert (Ale_WARNING,Txt_Can_not_create_the_folder_X_because_there_is_already_a_folder_or_a_file_with_that_name, Gbl.FileBrowser.NewFilFolLnkName); break; case EACCES: Err_ShowErrorAndExit ("Write forbidden."); break; default: Err_ShowErrorAndExit ("Can not create folder."); break; } } } else // Folder name not valid Ale_ShowAlerts (NULL); } else Err_ShowErrorAndExit (Txt_You_can_not_create_folders_here); // It's difficult, but not impossible that a user sees this message /***** Show again the file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /**************** Rename an existing folder in a file browser ****************/ /*****************************************************************************/ void Brw_RenFolderFileBrowser (void) { extern const char *Txt_The_folder_X_has_been_renamed_as_Y; extern const char *Txt_The_name_X_has_not_changed; extern const char *Txt_The_folder_name_X_has_not_changed_because_there_is_already_a_folder_or_a_file_with_the_name_Y; extern const char *Txt_You_can_not_rename_this_folder; char OldPathInTree[PATH_MAX + 1 + NAME_MAX + 1]; char NewPathInTree[PATH_MAX + 1 + NAME_MAX + 1]; char OldPath[PATH_MAX + 1 + PATH_MAX + 1 + NAME_MAX + 1]; char NewPath[PATH_MAX + 1 + PATH_MAX + 1 + NAME_MAX + 1]; /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); if (Brw_CheckIfICanEditFileOrFolder (Gbl.FileBrowser.Level)) // Can I rename this folder? { if (Str_ConvertFilFolLnkNameToValid (Gbl.FileBrowser.NewFilFolLnkName)) { if (strcmp (Gbl.FileBrowser.FilFolLnk.Name,Gbl.FileBrowser.NewFilFolLnkName)) // The name has changed { /* Gbl.FileBrowser.FilFolLnk.Name holds the new name of the folder */ snprintf (OldPathInTree,sizeof (OldPathInTree),"%s/%s", Gbl.FileBrowser.FilFolLnk.Path, Gbl.FileBrowser.FilFolLnk.Name); snprintf (OldPath,sizeof (OldPath),"%s/%s", Gbl.FileBrowser.Priv.PathAboveRootFolder,OldPathInTree); /* Gbl.FileBrowser.NewFilFolLnkName holds the new name of the folder */ if (strlen (Gbl.FileBrowser.Priv.PathAboveRootFolder) + 1 + strlen (Gbl.FileBrowser.FilFolLnk.Path) + 1 + strlen (Gbl.FileBrowser.NewFilFolLnkName) > PATH_MAX) Err_ShowErrorAndExit ("Path is too long."); snprintf (NewPathInTree,sizeof (NewPathInTree),"%s/%s", Gbl.FileBrowser.FilFolLnk.Path, Gbl.FileBrowser.NewFilFolLnkName); snprintf (NewPath,sizeof (NewPath),"%s/%s", Gbl.FileBrowser.Priv.PathAboveRootFolder,NewPathInTree); /* We should check here that a folder with the same name does not exist. but we leave this work to the system */ /* Rename the directory. If a empty folder existed with the name new, overwrite it! */ if (rename (OldPath,NewPath)) // Fail { switch (errno) { case ENOTEMPTY: case EEXIST: case ENOTDIR: Ale_ShowAlert (Ale_WARNING,Txt_The_folder_name_X_has_not_changed_because_there_is_already_a_folder_or_a_file_with_the_name_Y, Gbl.FileBrowser.FilFolLnk.Name,Gbl.FileBrowser.NewFilFolLnkName); break; case EACCES: Err_ShowErrorAndExit ("Write forbidden."); break; default: Err_ShowErrorAndExit ("Can not rename folder."); break; } } else // Success { /* If a folder is renamed, it is necessary to rename all entries in the tables of files that belong to the subtree starting at that folder */ Brw_DB_RenameOneFolder (OldPathInTree, NewPathInTree); Brw_DB_RenameChildrenFilesOrFolders (OldPathInTree, NewPathInTree); /* Remove affected clipboards */ Brw_DB_RemoveAffectedClipboards (Gbl.FileBrowser.Type, Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Other.UsrDat.UsrCod); /* Remove affected expanded folders */ Brw_DB_RenameAffectedExpandedFolders (Gbl.FileBrowser.Type, Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Other.UsrDat.UsrCod, OldPathInTree, NewPathInTree); /* Write message of confirmation */ Ale_ShowAlert (Ale_SUCCESS,Txt_The_folder_X_has_been_renamed_as_Y, Gbl.FileBrowser.FilFolLnk.Name, Gbl.FileBrowser.NewFilFolLnkName); } } else // Names are equal. // This may happens if we have press... // ...INTRO without changing the name Ale_ShowAlert (Ale_INFO,Txt_The_name_X_has_not_changed, Gbl.FileBrowser.FilFolLnk.Name); } else // Folder name not valid Ale_ShowAlerts (NULL); } else Err_ShowErrorAndExit (Txt_You_can_not_rename_this_folder); /***** Show again file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /****** Receive a new file in a file browser unsigned Dropzone.js ************/ /*****************************************************************************/ void Brw_RcvFileInFileBrwDropzone (void) { bool UploadSucessful; struct BrwSiz_BrowserSize *Size = BrwSiz_GetSize (); /***** Receive file *****/ UploadSucessful = Brw_RcvFileInFileBrw (Size,Brw_DROPZONE_UPLOAD); /***** When a file is uploaded, the HTTP response is a code status and a message for Dropzone.js *****/ /* Don't write HTML at all */ Gbl.Layout.HTMLStartWritten = Gbl.Layout.DivsEndWritten = Gbl.Layout.HTMLEndWritten = true; /* Begin HTTP response */ fprintf (stdout,"Content-type: text/plain; charset=windows-1252\n"); /* Status code and message */ if (UploadSucessful) fprintf (stdout,"Status: 200\r\n\r\n"); else fprintf (stdout,"Status: 501 Not Implemented\r\n\r\n" "%s\n", Ale_GetTextOfLastAlert ()); } /*****************************************************************************/ /******** Receive a new file in a file browser using the classic way *********/ /*****************************************************************************/ void Brw_RcvFileInFileBrwClassic (void) { struct BrwSiz_BrowserSize *Size = BrwSiz_GetSize (); /***** Receive file and show feedback message *****/ Brw_RcvFileInFileBrw (Size,Brw_CLASSIC_UPLOAD); /***** Show possible alert *****/ Ale_ShowAlerts (NULL); /***** Show again file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /****************** Receive a new file in a file browser *********************/ /*****************************************************************************/ static bool Brw_RcvFileInFileBrw (struct BrwSiz_BrowserSize *Size, Brw_UploadType_t UploadType) { extern const char *Txt_UPLOAD_FILE_X_file_already_exists_NO_HTML; extern const char *Txt_UPLOAD_FILE_could_not_create_file_NO_HTML; extern const char *Txt_UPLOAD_FILE_X_quota_exceeded_NO_HTML; extern const char *Txt_The_file_X_has_been_placed_inside_the_folder_Y; extern const char *Txt_UPLOAD_FILE_You_must_specify_the_file_NO_HTML; extern const char *Txt_UPLOAD_FILE_Forbidden_NO_HTML; struct Par_Param *Par; char SrcFileName[PATH_MAX + 1]; char PathUntilFileName[PATH_MAX + 1]; char Path[PATH_MAX + 1 + PATH_MAX + 1]; char PathTmp[PATH_MAX + 1 + PATH_MAX + 4 + 1]; char PathCompleteInTreeIncludingFile[PATH_MAX + 1 + NAME_MAX + 1]; char MIMEType[Brw_MAX_BYTES_MIME_TYPE + 1]; bool AdminMarks; bool FileIsValid = true; long FilCod = -1L; // Code of new file in database struct Brw_FileMetadata FileMetadata; struct Mrk_Properties Marks; char FileNameToShow[NAME_MAX + 1]; bool UploadSucessful = false; /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); AdminMarks = Gbl.FileBrowser.Type == Brw_ADMI_MRK_CRS || Gbl.FileBrowser.Type == Brw_ADMI_MRK_GRP; /***** Check if creating a new file is allowed *****/ if (Brw_CheckIfICanCreateIntoFolder (Gbl.FileBrowser.Level)) { /***** First, we save in disk the file received *****/ Par = Fil_StartReceptionOfFile (Fil_NAME_OF_PARAM_FILENAME_ORG, SrcFileName,MIMEType); /***** Get filename from path *****/ // Spaces at start or end are allowed Str_SplitFullPathIntoPathAndFileName (SrcFileName, PathUntilFileName, Gbl.FileBrowser.NewFilFolLnkName); if (Gbl.FileBrowser.NewFilFolLnkName[0]) { /***** Check if uploading this kind of file is allowed *****/ if (Brw_CheckIfUploadIsAllowed (MIMEType)) { if (Str_ConvertFilFolLnkNameToValid (Gbl.FileBrowser.NewFilFolLnkName)) { /* Gbl.FileBrowser.NewFilFolLnkName holds the name of the new file */ snprintf (Path,sizeof (Path),"%s/%s", Gbl.FileBrowser.Priv.PathAboveRootFolder, Gbl.FileBrowser.FilFolLnk.Full); if (strlen (Path) + 1 + strlen (Gbl.FileBrowser.NewFilFolLnkName) + strlen (".tmp") > PATH_MAX) Err_ShowErrorAndExit ("Path is too long."); Str_Concat (Path,"/",sizeof (Path) - 1); Str_Concat (Path,Gbl.FileBrowser.NewFilFolLnkName,sizeof (Path) - 1); /* Check if the destination file exists */ if (Fil_CheckIfPathExists (Path)) Ale_CreateAlert (Ale_WARNING,NULL, Txt_UPLOAD_FILE_X_file_already_exists_NO_HTML, Gbl.FileBrowser.NewFilFolLnkName); else // Destination file does not exist { /* End receiving the file */ snprintf (PathTmp,sizeof (PathTmp),"%s.tmp",Path); FileIsValid = Fil_EndReceptionOfFile (PathTmp,Par); /* Check if the content of the file of marks is valid */ if (FileIsValid) if (AdminMarks) if (!Mrk_CheckFileOfMarks (PathTmp,&Marks)) FileIsValid = false; if (FileIsValid) { /* Rename the temporary */ if (rename (PathTmp,Path)) // Fail { Fil_RemoveTree (PathTmp); Ale_CreateAlert (Ale_WARNING,NULL, Txt_UPLOAD_FILE_could_not_create_file_NO_HTML, Gbl.FileBrowser.NewFilFolLnkName); } else // Success { /* Check if quota has been exceeded */ BrwSiz_CalcSizeOfDir (Size,Gbl.FileBrowser.Priv.PathRootFolder); BrwSiz_SetMaxQuota (Size); if (BrwSiz_CheckIfQuotaExceded (Size)) { Fil_RemoveTree (Path); Ale_CreateAlert (Ale_WARNING,NULL, Txt_UPLOAD_FILE_X_quota_exceeded_NO_HTML, Gbl.FileBrowser.NewFilFolLnkName); } else { /* Remove affected clipboards */ Brw_DB_RemoveAffectedClipboards (Gbl.FileBrowser.Type, Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Other.UsrDat.UsrCod); /* Add path where new file is created to table of expanded folders */ Brw_InsFoldersInPathAndUpdOtherFoldersInExpandedFolders (Gbl.FileBrowser.FilFolLnk.Full); /* Add entry to the table of files/folders */ snprintf (PathCompleteInTreeIncludingFile, sizeof (PathCompleteInTreeIncludingFile), "%s/%s", Gbl.FileBrowser.FilFolLnk.Full, Gbl.FileBrowser.NewFilFolLnkName); FilCod = Brw_DB_AddPath (Gbl.Usrs.Me.UsrDat.UsrCod,Brw_IS_FILE, PathCompleteInTreeIncludingFile,false,Brw_LICENSE_DEFAULT); /* Show message of confirmation */ if (UploadType == Brw_CLASSIC_UPLOAD) { Brw_GetFileNameToShowDependingOnLevel (Gbl.FileBrowser.Type, Gbl.FileBrowser.Level, Brw_IS_FOLDER, Gbl.FileBrowser.FilFolLnk.Name, FileNameToShow); // Folder name Ale_CreateAlert (Ale_SUCCESS,NULL, Txt_The_file_X_has_been_placed_inside_the_folder_Y, Gbl.FileBrowser.NewFilFolLnkName, FileNameToShow); } UploadSucessful = true; FileMetadata.FilCod = FilCod; Brw_GetFileMetadataByCod (&FileMetadata); /* Add a new entry of marks into database */ if (AdminMarks) Mrk_DB_AddMarks (FileMetadata.FilCod,&Marks); /* Notify new file */ if (!Brw_DB_CheckIfFileOrFolderIsSetAsHiddenUsingMetadata (&FileMetadata)) switch (Gbl.FileBrowser.Type) { case Brw_ADMI_DOC_CRS: case Brw_ADMI_DOC_GRP: Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_DOCUMENT_FILE,FilCod); break; case Brw_ADMI_TCH_CRS: case Brw_ADMI_TCH_GRP: Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_TEACHERS_FILE,FilCod); break; case Brw_ADMI_SHR_CRS: case Brw_ADMI_SHR_GRP: Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_SHARED_FILE,FilCod); break; case Brw_ADMI_MRK_CRS: case Brw_ADMI_MRK_GRP: Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_MARKS_FILE,FilCod); break; default: break; } } } } else // Error in file reception. File probably too big Fil_RemoveTree (PathTmp); } } } } else // Empty filename Ale_CreateAlert (Ale_WARNING,NULL, Txt_UPLOAD_FILE_You_must_specify_the_file_NO_HTML); } else // I do not have permission to create files here Ale_CreateAlert (Ale_WARNING,NULL, Txt_UPLOAD_FILE_Forbidden_NO_HTML); return UploadSucessful; } /*****************************************************************************/ /******************* Receive a new link in a file browser ********************/ /*****************************************************************************/ void Brw_RecLinkFileBrowser (void) { extern const char *Txt_Can_not_create_the_link_X_because_there_is_already_a_folder_or_a_link_with_that_name; extern const char *Txt_Can_not_create_the_link_X_because_it_would_exceed_the_disk_quota; extern const char *Txt_The_link_X_has_been_placed_inside_the_folder_Y; extern const char *Txt_UPLOAD_FILE_Invalid_link; extern const char *Txt_You_can_not_create_links_here; char URL[PATH_MAX + 1]; char URLWithoutEndingSlash[PATH_MAX + 1]; size_t LengthURL; char URLUntilLastFilename[PATH_MAX + 1]; char FileName[NAME_MAX + 1]; char Path[PATH_MAX + 1 + PATH_MAX + 1]; FILE *FileURL; char PathCompleteInTreeIncludingFile[PATH_MAX + 1 + NAME_MAX + 4 + 1]; long FilCod = -1L; // Code of new file in database char FileNameToShow[NAME_MAX + 1]; struct Brw_FileMetadata FileMetadata; struct BrwSiz_BrowserSize *Size = BrwSiz_GetSize (); /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); /***** Check if creating a new link is allowed *****/ if (Brw_CheckIfICanCreateIntoFolder (Gbl.FileBrowser.Level)) { /***** Create a new file to store URL ****/ Par_GetParText ("NewLinkURL",URL,PATH_MAX); if ((LengthURL = strlen (URL))) { if (Gbl.FileBrowser.NewFilFolLnkName[0]) /* Gbl.FileBrowser.NewFilFolLnkName holds the name given by me in the form Example: Name given by me: intel-architectures.pdf File in swad: intel-architectures.pdf.url */ Str_Copy (URLWithoutEndingSlash,Gbl.FileBrowser.NewFilFolLnkName, sizeof (URLWithoutEndingSlash) - 1); else /* Gbl.FileBrowser.NewFilFolLnkName is empty URL holds the URL given by me in the form Example: URL: http://www.intel.es/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-manual-325462.pdf File in swad: 64-ia-32-architectures-software-developer-manual-325462.pdf.url */ Str_Copy (URLWithoutEndingSlash,URL, sizeof (URLWithoutEndingSlash) - 1); /* Remove possible final '/' from URL */ if (URLWithoutEndingSlash[LengthURL - 1] == '/') URLWithoutEndingSlash[LengthURL - 1] = '\0'; /* Get the last name in URL-without-ending-slash */ Str_SplitFullPathIntoPathAndFileName (URLWithoutEndingSlash, URLUntilLastFilename, FileName); /* Convert the last name in URL to a valid filename */ if (Str_ConvertFilFolLnkNameToValid (FileName)) { /* The name of the file with the link will be the FileName.url */ snprintf (Path,sizeof (Path),"%s/%s", Gbl.FileBrowser.Priv.PathAboveRootFolder, Gbl.FileBrowser.FilFolLnk.Full); if (strlen (Path) + 1 + strlen (FileName) + strlen (".url") > PATH_MAX) Err_ShowErrorAndExit ("Path is too long."); Str_Concat (Path,"/",sizeof (Path) - 1); Str_Concat (Path,FileName,sizeof (Path) - 1); Str_Concat (Path,".url",sizeof (Path) - 1); /* Check if the URL file exists */ if (Fil_CheckIfPathExists (Path)) Ale_ShowAlert (Ale_WARNING,Txt_Can_not_create_the_link_X_because_there_is_already_a_folder_or_a_link_with_that_name, FileName); else // URL file does not exist { /***** Create the new file with the URL *****/ if ((FileURL = fopen (Path,"wb")) != NULL) { /* Write URL */ fprintf (FileURL,"%s",URL); /* Close file */ fclose (FileURL); /* Check if quota has been exceeded */ BrwSiz_CalcSizeOfDir (Size,Gbl.FileBrowser.Priv.PathRootFolder); BrwSiz_SetMaxQuota (Size); if (BrwSiz_CheckIfQuotaExceded (Size)) { Fil_RemoveTree (Path); Ale_ShowAlert (Ale_WARNING,Txt_Can_not_create_the_link_X_because_it_would_exceed_the_disk_quota, FileName); } else { /* Remove affected clipboards */ Brw_DB_RemoveAffectedClipboards (Gbl.FileBrowser.Type, Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Other.UsrDat.UsrCod); /* Add path where new file is created to table of expanded folders */ Brw_InsFoldersInPathAndUpdOtherFoldersInExpandedFolders (Gbl.FileBrowser.FilFolLnk.Full); /* Add entry to the table of files/folders */ snprintf (PathCompleteInTreeIncludingFile, sizeof (PathCompleteInTreeIncludingFile), "%s/%s.url", Gbl.FileBrowser.FilFolLnk.Full,FileName); FilCod = Brw_DB_AddPath (Gbl.Usrs.Me.UsrDat.UsrCod,Brw_IS_LINK, PathCompleteInTreeIncludingFile,false,Brw_LICENSE_DEFAULT); /* Show message of confirmation */ Brw_GetFileNameToShowDependingOnLevel (Gbl.FileBrowser.Type, Gbl.FileBrowser.Level, Brw_IS_FOLDER, Gbl.FileBrowser.FilFolLnk.Name, FileNameToShow); // Folder name Ale_ShowAlert (Ale_SUCCESS,Txt_The_link_X_has_been_placed_inside_the_folder_Y, FileName,FileNameToShow); FileMetadata.FilCod = FilCod; Brw_GetFileMetadataByCod (&FileMetadata); /* Notify new file */ if (!Brw_DB_CheckIfFileOrFolderIsSetAsHiddenUsingMetadata (&FileMetadata)) switch (Gbl.FileBrowser.Type) { case Brw_ADMI_DOC_CRS: case Brw_ADMI_DOC_GRP: Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_DOCUMENT_FILE,FilCod); break; case Brw_ADMI_TCH_CRS: case Brw_ADMI_TCH_GRP: Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_TEACHERS_FILE,FilCod); break; case Brw_ADMI_SHR_CRS: case Brw_ADMI_SHR_GRP: Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_SHARED_FILE,FilCod); break; case Brw_ADMI_MRK_CRS: case Brw_ADMI_MRK_GRP: Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_MARKS_FILE,FilCod); break; default: break; } } } } } else // Link URL not valid Ale_ShowAlert (Ale_WARNING,Txt_UPLOAD_FILE_Invalid_link); } else // Link URL not valid Ale_ShowAlert (Ale_WARNING,Txt_UPLOAD_FILE_Invalid_link); } else Err_ShowErrorAndExit (Txt_You_can_not_create_links_here); // It's difficult, but not impossible that a user sees this message /***** Show again the file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /****************** Check if it is allowed to upload a file ******************/ /*****************************************************************************/ // Returns true if file type is allowed // Returns false if MIME type or extension are not allowed // On error, delayed alerts will contain feedback text static bool Brw_CheckIfUploadIsAllowed (const char *MIMEType) { extern const char *Txt_UPLOAD_FILE_X_MIME_type_Y_not_allowed_NO_HTML; extern const char *Txt_UPLOAD_FILE_X_not_HTML_NO_HTML; extern const char *Txt_UPLOAD_FILE_X_extension_not_allowed_NO_HTML; switch (Gbl.FileBrowser.Type) { case Brw_ADMI_MRK_CRS: case Brw_ADMI_MRK_GRP: /* Check file extension */ if (!Str_FileIsHTML (Gbl.FileBrowser.NewFilFolLnkName)) { Ale_CreateAlert (Ale_WARNING,NULL, Txt_UPLOAD_FILE_X_not_HTML_NO_HTML, Gbl.FileBrowser.NewFilFolLnkName); return false; } /* Check MIME type*/ if (strcmp (MIMEType,"text/html")) if (strcmp (MIMEType,"text/plain")) if (strcmp (MIMEType,"application/octet-stream")) if (strcmp (MIMEType,"application/octetstream")) if (strcmp (MIMEType,"application/octet")) { // MIME type forbidden Ale_CreateAlert (Ale_WARNING,NULL, Txt_UPLOAD_FILE_X_MIME_type_Y_not_allowed_NO_HTML, Gbl.FileBrowser.NewFilFolLnkName,MIMEType); return false; } break; default: /* Check file extension */ if (!Ext_CheckIfFileExtensionIsAllowed (Gbl.FileBrowser.NewFilFolLnkName)) { Ale_CreateAlert (Ale_WARNING,NULL, Txt_UPLOAD_FILE_X_extension_not_allowed_NO_HTML, Gbl.FileBrowser.NewFilFolLnkName); return false; } /* Check MIME type*/ if (!MIM_CheckIfMIMETypeIsAllowed (MIMEType)) { Ale_CreateAlert (Ale_WARNING,NULL, Txt_UPLOAD_FILE_X_MIME_type_Y_not_allowed_NO_HTML, Gbl.FileBrowser.NewFilFolLnkName,MIMEType); return false; } break; } return true; } /*****************************************************************************/ /******************* Show file or folder in a file browser *******************/ /*****************************************************************************/ void Brw_SetDocumentAsVisible (void) { /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); /***** Change file to visible *****/ if (Brw_CheckIfFileOrFolderIsSetAsHiddenInDB (Gbl.FileBrowser.FilFolLnk.Type, Gbl.FileBrowser.FilFolLnk.Full)) Brw_DB_HideOrUnhideFileOrFolder (Gbl.FileBrowser.FilFolLnk.Full,false); /***** Remove the affected clipboards *****/ Brw_DB_RemoveAffectedClipboards (Gbl.FileBrowser.Type, Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Other.UsrDat.UsrCod); /***** Show again the file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /***************** Hide file or folder in a file browser *********************/ /*****************************************************************************/ void Brw_SetDocumentAsHidden (void) { /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); /***** If the file or folder is not already set as hidden in database, set it as hidden *****/ if (!Brw_CheckIfFileOrFolderIsSetAsHiddenInDB (Gbl.FileBrowser.FilFolLnk.Type, Gbl.FileBrowser.FilFolLnk.Full)) Brw_DB_HideOrUnhideFileOrFolder (Gbl.FileBrowser.FilFolLnk.Full,true); /***** Remove the affected clipboards *****/ Brw_DB_RemoveAffectedClipboards (Gbl.FileBrowser.Type, Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Other.UsrDat.UsrCod); /***** Show again the file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /** Check if a file / folder from the documents zone is set as hidden in DB **/ /*****************************************************************************/ bool Brw_CheckIfFileOrFolderIsSetAsHiddenInDB (Brw_FileType_t FileType,const char *Path) { MYSQL_RES *mysql_res; MYSQL_ROW row; bool IsHidden = false; /***** Get if a file or folder is hidden from database *****/ if (Brw_DB_CheckIfFileOrFolderIsSetAsHiddenUsingPath (&mysql_res,Path)) { /* Get row */ row = mysql_fetch_row (mysql_res); /* File is hidden? (row[0]) */ IsHidden = (row[0][0] == 'Y'); } else Brw_DB_AddPath (-1L,FileType, Gbl.FileBrowser.FilFolLnk.Full,false,Brw_LICENSE_DEFAULT); /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); return IsHidden; } /*****************************************************************************/ /***************** Show metadata of a file in a file browser *****************/ /*****************************************************************************/ void Brw_ShowFileMetadata (void) { extern const char *Txt_The_file_of_folder_no_longer_exists_or_is_now_hidden; extern const char *Txt_Filename; extern const char *Txt_File_size; extern const char *Txt_Uploaded_by; extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS]; extern const char *Txt_Date_of_creation; extern const char *Txt_Availability; extern const char *Txt_Private_available_to_certain_users_identified; extern const char *Txt_Public_open_educational_resource_OER_for_everyone; extern const char *Txt_License; extern const char *Txt_LICENSES[Brw_NUM_LICENSES]; extern const char *Txt_My_views; extern const char *Txt_Identified_views; extern const char *Txt_Public_views; extern const char *Txt_user[Usr_NUM_SEXS]; extern const char *Txt_users[Usr_NUM_SEXS]; extern const char *Txt_Save_file_properties; static const char *ClassPhoto[PhoSha_NUM_SHAPES] = { [PhoSha_SHAPE_CIRCLE ] = "PHOTOC15x20", [PhoSha_SHAPE_ELLIPSE ] = "PHOTOE15x20", [PhoSha_SHAPE_OVAL ] = "PHOTOO15x20", [PhoSha_SHAPE_RECTANGLE] = "PHOTOR15x20", }; struct Brw_FileMetadata FileMetadata; struct Usr_Data PublisherUsrDat; char FileNameToShow[NAME_MAX + 1]; char URL[PATH_MAX + 1]; char FileSizeStr[Fil_MAX_BYTES_FILE_SIZE_STRING + 1]; bool Found; bool ICanView = false; bool IAmTheOwner; bool ICanEdit; bool ICanChangePublic = false; bool FileHasPublisher; Brw_License_t License; unsigned LicenseUnsigned; /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); /***** Get file metadata *****/ FileMetadata.FilCod = ParCod_GetAndCheckPar (ParCod_Fil); Brw_GetFileMetadataByCod (&FileMetadata); Found = Brw_GetFileTypeSizeAndDate (&FileMetadata); if (Found) { if (FileMetadata.FilCod <= 0) // No entry for this file in database table of files /* Add entry to the table of files/folders */ FileMetadata.FilCod = Brw_DB_AddPath (-1L,FileMetadata.FilFolLnk.Type, FileMetadata.FilFolLnk.Full, false,Brw_LICENSE_DEFAULT); /***** Check if I can view this file. It could be marked as hidden or in a hidden folder *****/ ICanView = true; switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_INS: if (Gbl.Usrs.Me.Role.Logged < Rol_INS_ADM) ICanView = !Brw_DB_CheckIfFileOrFolderIsSetAsHiddenUsingMetadata (&FileMetadata); break; case Brw_SHOW_DOC_CTR: if (Gbl.Usrs.Me.Role.Logged < Rol_CTR_ADM) ICanView = !Brw_DB_CheckIfFileOrFolderIsSetAsHiddenUsingMetadata (&FileMetadata); break; case Brw_SHOW_DOC_DEG: if (Gbl.Usrs.Me.Role.Logged < Rol_DEG_ADM) ICanView = !Brw_DB_CheckIfFileOrFolderIsSetAsHiddenUsingMetadata (&FileMetadata); break; case Brw_SHOW_DOC_CRS: case Brw_SHOW_DOC_GRP: if (Gbl.Usrs.Me.Role.Logged < Rol_TCH) ICanView = !Brw_DB_CheckIfFileOrFolderIsSetAsHiddenUsingMetadata (&FileMetadata); break; default: break; } } if (ICanView) { if (FileMetadata.FilFolLnk.Type == Brw_IS_FILE || FileMetadata.FilFolLnk.Type == Brw_IS_LINK) { /***** Update number of views *****/ Brw_GetAndUpdateFileViews (&FileMetadata); /***** Get data of file/folder publisher *****/ if (FileMetadata.PublisherUsrCod > 0) { /***** Initialize structure with publisher's data *****/ Usr_UsrDataConstructor (&PublisherUsrDat); PublisherUsrDat.UsrCod = FileMetadata.PublisherUsrCod; FileHasPublisher = Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&PublisherUsrDat, Usr_DONT_GET_PREFS, Usr_DONT_GET_ROLE_IN_CURRENT_CRS); } else FileHasPublisher = false; // Get user's data from database /***** Get link to download the file *****/ if (Gbl.FileBrowser.Type == Brw_SHOW_MRK_CRS || Gbl.FileBrowser.Type == Brw_SHOW_MRK_GRP) URL[0] = '\0'; else Brw_GetLinkToDownloadFile (FileMetadata.FilFolLnk.Path, FileMetadata.FilFolLnk.Name, URL); /***** Can I edit the properties of the file? *****/ IAmTheOwner = Brw_CheckIfIAmOwnerOfFile (FileMetadata.PublisherUsrCod); ICanEdit = Brw_CheckIfICanEditFileMetadata (IAmTheOwner); /***** Name of the file/link to be shown *****/ Brw_GetFileNameToShow (FileMetadata.FilFolLnk.Type, FileMetadata.FilFolLnk.Name, FileNameToShow); /***** Begin box *****/ // Put icon to get link? if (Brw_ActReqLnk[Gbl.FileBrowser.Type] != ActUnk && (FileMetadata.FilFolLnk.Type == Brw_IS_FILE || // Only files or links FileMetadata.FilFolLnk.Type == Brw_IS_LINK) && Rsc_CheckIfICanGetLink ()) Box_BoxShadowBegin (NULL,NULL, Brw_PutIconToGetLinkToFile,&FileMetadata, NULL); else Box_BoxShadowBegin (NULL,NULL, NULL,NULL, NULL); /***** Begin form to update the metadata of a file *****/ if (ICanEdit) // I can edit file properties { /* Can the file be public? */ switch (Gbl.FileBrowser.Type) { case Brw_ADMI_DOC_INS: case Brw_ADMI_SHR_INS: case Brw_ADMI_DOC_CTR: case Brw_ADMI_SHR_CTR: case Brw_ADMI_DOC_DEG: case Brw_ADMI_SHR_DEG: case Brw_ADMI_DOC_CRS: case Brw_ADMI_SHR_CRS: ICanChangePublic = true; break; default: ICanChangePublic = false; break; } Frm_BeginForm (Brw_ActRecDatFile[Gbl.FileBrowser.Type]); Brw_PutParsFileBrowser (NULL, // Not used NULL, // Not used Brw_IS_UNKNOWN, // Not used FileMetadata.FilCod); } /***** Begin table *****/ HTM_TABLE_BeginWidePadding (2); /***** Link to download the file *****/ HTM_TR_Begin (NULL); HTM_TD_Begin ("colspan=\"2\" class=\"CM\""); Brw_WriteBigLinkToDownloadFile (URL,&FileMetadata,FileNameToShow); HTM_TD_End (); HTM_TR_End (); /***** Filename *****/ HTM_TR_Begin (NULL); Frm_LabelColumn ("RT",NULL,Txt_Filename); HTM_TD_Begin ("class=\"LB DAT_STRONG_%s\"", The_GetSuffix ()); Brw_WriteSmallLinkToDownloadFile (URL,&FileMetadata,FileNameToShow); HTM_TD_End (); HTM_TR_End (); /***** Publisher's data *****/ HTM_TR_Begin (NULL); Frm_LabelColumn ("RT",NULL,Txt_Uploaded_by); HTM_TD_Begin ("class=\"LB DAT_STRONG_%s\"", The_GetSuffix ()); if (FileHasPublisher) { /* Show photo */ Pho_ShowUsrPhotoIfAllowed (&PublisherUsrDat, ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM); /* Write name */ HTM_NBSP (); HTM_Txt (PublisherUsrDat.FullName); } else /* Unknown publisher */ HTM_Txt (Txt_ROLES_SINGUL_Abc[Rol_UNK][Usr_SEX_UNKNOWN]); HTM_TD_End (); HTM_TR_End (); /***** Free memory used for publisher's data *****/ if (FileMetadata.PublisherUsrCod > 0) Usr_UsrDataDestructor (&PublisherUsrDat); /***** Write the file size *****/ Fil_WriteFileSizeFull ((double) FileMetadata.Size,FileSizeStr); HTM_TR_Begin (NULL); Frm_LabelColumn ("RT",NULL,Txt_File_size); HTM_TD_Begin ("class=\"LB DAT_STRONG_%s\"", The_GetSuffix ()); HTM_Txt (FileSizeStr); HTM_TD_End (); HTM_TR_End (); /***** Write the date *****/ HTM_TR_Begin (NULL); Frm_LabelColumn ("RT",NULL,Txt_Date_of_creation); HTM_TD_Begin ("id=\"filedate\" class=\"LB DAT_STRONG_%s\"", The_GetSuffix ()); Dat_WriteLocalDateHMSFromUTC ("filedate",FileMetadata.Time, Gbl.Prefs.DateFormat,Dat_SEPARATOR_COMMA, true,true,true,0x7); HTM_TD_End (); HTM_TR_End (); /***** Private or public? *****/ HTM_TR_Begin (NULL); /* Label */ Frm_LabelColumn ("RT",ICanChangePublic ? "PublicFile" : NULL, Txt_Availability); /* Data */ HTM_TD_Begin ("class=\"LT DAT_STRONG_%s\"", The_GetSuffix ()); if (ICanChangePublic) // I can change file to public { HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, "id=\"PublicFile\" name=\"PublicFile\" class=\"PUBLIC_FILE\""); HTM_OPTION (HTM_Type_STRING,"N", !FileMetadata.IsPublic,false, "%s",Txt_Private_available_to_certain_users_identified); HTM_OPTION (HTM_Type_STRING,"Y", FileMetadata.IsPublic,false, "%s",Txt_Public_open_educational_resource_OER_for_everyone); HTM_SELECT_End (); } else // I can not edit file properties HTM_Txt (FileMetadata.IsPublic ? Txt_Public_open_educational_resource_OER_for_everyone : Txt_Private_available_to_certain_users_identified); HTM_TD_End (); HTM_TR_End (); /***** License *****/ HTM_TR_Begin (NULL); /* Label */ Frm_LabelColumn ("RT",ICanEdit ? "License" : NULL, Txt_License); /* Data */ HTM_TD_Begin ("class=\"LT DAT_STRONG_%s\"", The_GetSuffix ()); if (ICanEdit) // I can edit file properties { HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, "id=\"License\" name=\"License\" class=\"LICENSE\""); for (License = (Brw_License_t) 0; License <= (Brw_License_t) (Brw_NUM_LICENSES - 1); License++) { LicenseUnsigned = (unsigned) License; HTM_OPTION (HTM_Type_UNSIGNED,&LicenseUnsigned, License == FileMetadata.License,false, "%s",Txt_LICENSES[License]); } HTM_SELECT_End (); } else // I can not edit file properties HTM_Txt (Txt_LICENSES[FileMetadata.License]); HTM_TD_End (); HTM_TR_End (); /***** Write my number of views *****/ if (Gbl.Usrs.Me.Logged) { HTM_TR_Begin (NULL); Frm_LabelColumn ("RT",NULL,Txt_My_views); HTM_TD_Begin ("class=\"LB DAT_STRONG_%s\"", The_GetSuffix ()); HTM_Unsigned (FileMetadata.NumMyViews); HTM_TD_End (); HTM_TR_End (); } /***** Write number of identificated views *****/ HTM_TR_Begin (NULL); Frm_LabelColumn ("RT",NULL,Txt_Identified_views); HTM_TD_Begin ("class=\"LB DAT_STRONG_%s\"", The_GetSuffix ()); HTM_TxtF ("%u ",FileMetadata.NumViewsFromLoggedUsrs); HTM_TxtF ("(%u %s)", FileMetadata.NumLoggedUsrs, FileMetadata.NumLoggedUsrs == 1 ? Txt_user[Usr_SEX_UNKNOWN] : Txt_users[Usr_SEX_UNKNOWN]); HTM_TD_End (); HTM_TR_End (); /***** Write number of public views *****/ HTM_TR_Begin (NULL); Frm_LabelColumn ("RT",NULL,Txt_Public_views); HTM_TD_Begin ("class=\"LB DAT_STRONG_%s\"", The_GetSuffix ()); HTM_Unsigned (FileMetadata.NumPublicViews); HTM_TD_End (); HTM_TR_End (); /***** End table *****/ HTM_TABLE_End (); /***** End form *****/ if (ICanEdit) // I can edit file properties { Btn_PutButton (Btn_CONFIRM_BUTTON,Txt_Save_file_properties); Frm_EndForm (); } /***** End box *****/ Box_BoxEnd (); /***** Mark possible notifications as seen *****/ switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_CRS: case Brw_SHOW_DOC_GRP: case Brw_ADMI_DOC_CRS: case Brw_ADMI_DOC_GRP: Ntf_DB_MarkNotifAsSeenUsingCod (Ntf_EVENT_DOCUMENT_FILE, FileMetadata.FilCod); break; case Brw_ADMI_TCH_CRS: case Brw_ADMI_TCH_GRP: Ntf_DB_MarkNotifAsSeenUsingCod (Ntf_EVENT_TEACHERS_FILE, FileMetadata.FilCod); break; case Brw_ADMI_SHR_CRS: case Brw_ADMI_SHR_GRP: Ntf_DB_MarkNotifAsSeenUsingCod (Ntf_EVENT_SHARED_FILE, FileMetadata.FilCod); break; case Brw_SHOW_MRK_CRS: case Brw_SHOW_MRK_GRP: case Brw_ADMI_MRK_CRS: case Brw_ADMI_MRK_GRP: Ntf_DB_MarkNotifAsSeenUsingCod (Ntf_EVENT_MARKS_FILE, FileMetadata.FilCod); break; default: break; } } /***** Add paths until file to table of expanded folders *****/ Brw_InsFoldersInPathAndUpdOtherFoldersInExpandedFolders (Gbl.FileBrowser.FilFolLnk.Path); } else // !ICanView { /***** Mark possible notifications about non visible file as removed *****/ switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_CRS: case Brw_SHOW_DOC_GRP: case Brw_ADMI_DOC_CRS: case Brw_ADMI_DOC_GRP: Ntf_DB_MarkNotifAsRemoved (Ntf_EVENT_DOCUMENT_FILE, FileMetadata.FilCod); break; case Brw_ADMI_TCH_CRS: case Brw_ADMI_TCH_GRP: Ntf_DB_MarkNotifAsRemoved (Ntf_EVENT_TEACHERS_FILE, FileMetadata.FilCod); break; case Brw_ADMI_SHR_CRS: case Brw_ADMI_SHR_GRP: Ntf_DB_MarkNotifAsRemoved (Ntf_EVENT_SHARED_FILE, FileMetadata.FilCod); break; case Brw_SHOW_MRK_CRS: case Brw_SHOW_MRK_GRP: case Brw_ADMI_MRK_CRS: case Brw_ADMI_MRK_GRP: Ntf_DB_MarkNotifAsRemoved (Ntf_EVENT_MARKS_FILE, FileMetadata.FilCod); break; default: break; } Ale_ShowAlert (Ale_WARNING,Txt_The_file_of_folder_no_longer_exists_or_is_now_hidden); } /***** Show again the file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /*********************** Put icon to get link to file ************************/ /*****************************************************************************/ static void Brw_PutIconToGetLinkToFile (void *FileMetadata) { Ico_PutContextualIconToGetLink (Brw_ActReqLnk[Gbl.FileBrowser.Type],NULL, Brw_PutParsToGetLinkToFile,FileMetadata); } static void Brw_PutParsToGetLinkToFile (void *FileMetadata) { if (FileMetadata) Brw_PutParsFileBrowser (NULL, // Not used NULL, // Not used Brw_IS_UNKNOWN, // Not used ((struct Brw_FileMetadata *) FileMetadata)->FilCod); } /*****************************************************************************/ /************************ Get link to download a file ************************/ /*****************************************************************************/ void Brw_GetLinkToDownloadFile (const char *PathInTree,const char *FileName,char *URL) { char FullPathIncludingFile[PATH_MAX + 1 + PATH_MAX + 1 + NAME_MAX + 1]; FILE *FileURL; char URLWithSpaces[PATH_MAX + 1]; /***** Construct absolute path to file in the private directory *****/ snprintf (FullPathIncludingFile,sizeof (FullPathIncludingFile),"%s/%s/%s", Gbl.FileBrowser.Priv.PathAboveRootFolder,PathInTree,FileName); if (Str_FileIs (FileName,"url")) // It's a link (URL inside a .url file) { /***** Open .url file *****/ if ((FileURL = fopen (FullPathIncludingFile,"rb"))) { if (fgets (URLWithSpaces,PATH_MAX,FileURL) == NULL) URLWithSpaces[0] = '\0'; /* File is not longer needed ==> close it */ fclose (FileURL); } } else { /***** Create a temporary public directory used to download files *****/ Brw_CreateDirDownloadTmp (); /***** Create symbolic link from temporary public directory to private file in order to gain access to it for downloading *****/ Brw_CreateTmpPublicLinkToPrivateFile (FullPathIncludingFile,FileName); /***** Create URL pointing to symbolic link *****/ snprintf (URLWithSpaces,sizeof (URLWithSpaces),"%s/%s/%s/%s", Cfg_URL_FILE_BROWSER_TMP_PUBLIC, Gbl.FileBrowser.TmpPubDir.L, Gbl.FileBrowser.TmpPubDir.R, FileName); } Str_CopyStrChangingSpaces (URLWithSpaces,URL,PATH_MAX); // In HTML, URL must have no spaces } /*****************************************************************************/ /******************* Download a file from a file browser *********************/ /*****************************************************************************/ void Brw_DownloadFile (void) { extern const char *Txt_The_file_of_folder_no_longer_exists_or_is_now_hidden; struct Brw_FileMetadata FileMetadata; char URL[PATH_MAX + 1]; bool Found; bool ICanView = false; /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); /***** Get file metadata *****/ Brw_GetFileMetadataByPath (&FileMetadata); Found = Brw_GetFileTypeSizeAndDate (&FileMetadata); if (Found) { if (FileMetadata.FilCod <= 0) // No entry for this file in database table of files /* Add entry to the table of files/folders */ FileMetadata.FilCod = Brw_DB_AddPath (-1L,FileMetadata.FilFolLnk.Type, Gbl.FileBrowser.FilFolLnk.Full, false,Brw_LICENSE_DEFAULT); /***** Check if I can view this file. It could be marked as hidden or in a hidden folder *****/ ICanView = true; switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_INS: if (Gbl.Usrs.Me.Role.Logged < Rol_INS_ADM) ICanView = !Brw_DB_CheckIfFileOrFolderIsSetAsHiddenUsingMetadata (&FileMetadata); break; case Brw_SHOW_DOC_CTR: if (Gbl.Usrs.Me.Role.Logged < Rol_CTR_ADM) ICanView = !Brw_DB_CheckIfFileOrFolderIsSetAsHiddenUsingMetadata (&FileMetadata); break; case Brw_SHOW_DOC_DEG: if (Gbl.Usrs.Me.Role.Logged < Rol_DEG_ADM) ICanView = !Brw_DB_CheckIfFileOrFolderIsSetAsHiddenUsingMetadata (&FileMetadata); break; case Brw_SHOW_DOC_CRS: case Brw_SHOW_DOC_GRP: if (Gbl.Usrs.Me.Role.Logged < Rol_TCH) ICanView = !Brw_DB_CheckIfFileOrFolderIsSetAsHiddenUsingMetadata (&FileMetadata); break; default: break; } } if (ICanView) { if (FileMetadata.FilFolLnk.Type == Brw_IS_FILE || FileMetadata.FilFolLnk.Type == Brw_IS_LINK) { /***** Update number of views *****/ Brw_GetAndUpdateFileViews (&FileMetadata); /***** Get link to download the file *****/ if (Gbl.FileBrowser.Type == Brw_SHOW_MRK_CRS || Gbl.FileBrowser.Type == Brw_SHOW_MRK_GRP) URL[0] = '\0'; else Brw_GetLinkToDownloadFile (Gbl.FileBrowser.FilFolLnk.Path, Gbl.FileBrowser.FilFolLnk.Name, URL); /***** Mark possible notifications as seen *****/ switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_CRS: case Brw_SHOW_DOC_GRP: case Brw_ADMI_DOC_CRS: case Brw_ADMI_DOC_GRP: Ntf_DB_MarkNotifAsSeenUsingCod (Ntf_EVENT_DOCUMENT_FILE, FileMetadata.FilCod); break; case Brw_ADMI_TCH_CRS: case Brw_ADMI_TCH_GRP: Ntf_DB_MarkNotifAsSeenUsingCod (Ntf_EVENT_TEACHERS_FILE, FileMetadata.FilCod); break; case Brw_ADMI_SHR_CRS: case Brw_ADMI_SHR_GRP: Ntf_DB_MarkNotifAsSeenUsingCod (Ntf_EVENT_SHARED_FILE, FileMetadata.FilCod); break; case Brw_SHOW_MRK_CRS: case Brw_SHOW_MRK_GRP: case Brw_ADMI_MRK_CRS: case Brw_ADMI_MRK_GRP: Ntf_DB_MarkNotifAsSeenUsingCod (Ntf_EVENT_MARKS_FILE, FileMetadata.FilCod); break; default: break; } } /***** Add paths until file to table of expanded folders *****/ Brw_InsFoldersInPathAndUpdOtherFoldersInExpandedFolders (Gbl.FileBrowser.FilFolLnk.Path); /***** Download the file *****/ fprintf (stdout,"Location: %s\n\n",URL); // TODO: Put headers Content-type and Content-disposition: // See: http://stackoverflow.com/questions/381954/how-do-i-fix-firefox-trying-to-save-image-as-htm // http://elouai.com/force-download.php Gbl.Layout.HTMLStartWritten = Gbl.Layout.DivsEndWritten = Gbl.Layout.HTMLEndWritten = true; // Don't write HTML at all } else // !ICanView { /***** Mark possible notifications about non visible file as removed *****/ switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_CRS: case Brw_SHOW_DOC_GRP: case Brw_ADMI_DOC_CRS: case Brw_ADMI_DOC_GRP: Ntf_DB_MarkNotifAsRemoved (Ntf_EVENT_DOCUMENT_FILE, FileMetadata.FilCod); break; case Brw_ADMI_TCH_CRS: case Brw_ADMI_TCH_GRP: Ntf_DB_MarkNotifAsRemoved (Ntf_EVENT_TEACHERS_FILE, FileMetadata.FilCod); break; case Brw_ADMI_SHR_CRS: case Brw_ADMI_SHR_GRP: Ntf_DB_MarkNotifAsRemoved (Ntf_EVENT_SHARED_FILE, FileMetadata.FilCod); break; case Brw_SHOW_MRK_CRS: case Brw_SHOW_MRK_GRP: case Brw_ADMI_MRK_CRS: case Brw_ADMI_MRK_GRP: Ntf_DB_MarkNotifAsRemoved (Ntf_EVENT_MARKS_FILE, FileMetadata.FilCod); break; default: break; } Ale_ShowAlert (Ale_WARNING,Txt_The_file_of_folder_no_longer_exists_or_is_now_hidden); /***** Show again the file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } } /*****************************************************************************/ /*********** Check if I have permission to change file metadata **************/ /*****************************************************************************/ static bool Brw_CheckIfICanEditFileMetadata (long IAmTheOwner) { switch (Gbl.Action.Act) // Only in actions where edition is allowed { case ActReqDatAdmDocIns: case ActChgDatAdmDocIns: case ActReqDatShaIns: case ActChgDatShaIns: case ActReqDatAdmDocCtr: case ActChgDatAdmDocCtr: case ActReqDatShaCtr: case ActChgDatShaCtr: case ActReqDatAdmDocDeg: case ActChgDatAdmDocDeg: case ActReqDatShaDeg: case ActChgDatShaDeg: case ActReqDatAdmDocCrs: case ActChgDatAdmDocCrs: case ActReqDatAdmDocGrp: case ActChgDatAdmDocGrp: case ActReqDatTchCrs: case ActChgDatTchCrs: case ActReqDatTchGrp: case ActChgDatTchGrp: case ActReqDatShaCrs: case ActChgDatShaCrs: case ActReqDatShaGrp: case ActChgDatShaGrp: case ActReqDatAsgUsr: case ActChgDatAsgUsr: case ActReqDatAsgCrs: case ActChgDatAsgCrs: case ActReqDatWrkCrs: case ActChgDatWrkCrs: case ActReqDatWrkUsr: case ActChgDatWrkUsr: case ActReqDatBrf: case ActChgDatBrf: return IAmTheOwner; default: return false; } } static bool Brw_CheckIfIAmOwnerOfFile (long PublisherUsrCod) { long ZoneUsrCod; if (Gbl.Usrs.Me.Logged) // I am logged { if (PublisherUsrCod > 0) // The file has publisher { if (PublisherUsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // I am the publisher return true; } else // The file has no publisher { ZoneUsrCod = Brw_GetZoneUsrCodForFileBrowser (); if ((ZoneUsrCod <= 0 && Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM) || // It's a zone without owner and I am a superuser (I may be the future owner) ZoneUsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // I am the owner return true; } } return false; } /*****************************************************************************/ /****************** Write link to download a file or link ********************/ /*****************************************************************************/ // FileType can be Brw_IS_FILE or Brw_IS_LINK static void Brw_WriteBigLinkToDownloadFile (const char *URL, struct Brw_FileMetadata *FileMetadata, const char *FileNameToShow) { extern const char *Txt_Check_marks_in_the_file; extern const char *Txt_Download; extern const char *Txt_Link; const char *Title; /***** On the screen a link will be shown to download the file *****/ if (Gbl.FileBrowser.Type == Brw_SHOW_MRK_CRS || Gbl.FileBrowser.Type == Brw_SHOW_MRK_GRP) { /* Form to see marks */ Frm_BeginForm (Gbl.FileBrowser.Type == Brw_SHOW_MRK_CRS ? ActSeeMyMrkCrs : ActSeeMyMrkGrp); Str_Copy (Gbl.FileBrowser.FilFolLnk.Path,FileMetadata->FilFolLnk.Path, sizeof (Gbl.FileBrowser.FilFolLnk.Path) - 1); Str_Copy (Gbl.FileBrowser.FilFolLnk.Name,FileMetadata->FilFolLnk.Name, sizeof (Gbl.FileBrowser.FilFolLnk.Name) - 1); Gbl.FileBrowser.FilFolLnk.Type = FileMetadata->FilFolLnk.Type; Brw_PutImplicitParsFileBrowser (&Gbl.FileBrowser.FilFolLnk); /* Begin link */ HTM_BUTTON_Submit_Begin (Txt_Check_marks_in_the_file, "class=\"BT_LINK ICO_HIGHLIGHT FILENAME_BIG_%s\"", The_GetSuffix ()); if (FileMetadata->FilFolLnk.Type == Brw_IS_FILE) Brw_PutIconFile (FileMetadata->FilFolLnk.Name, "ICO40x40", false); // Don't put link to view metadata else Ico_PutIcon ("up-right-from-square.svg",Ico_BLACK,Txt_Link,"ICO40x40"); /* Name of the file of marks, link end and form end */ HTM_TxtF (" %s ",FileNameToShow); Ico_PutIcon ("list-alt.svg",Ico_UNCHANGED,Txt_Check_marks_in_the_file,"ICO40x40"); /* End link */ HTM_BUTTON_End (); Frm_EndForm (); } else { Title = (FileMetadata->FilFolLnk.Type == Brw_IS_LINK) ? URL : // If it's a link, show full URL in title Txt_Download; /* Put anchor and filename */ HTM_A_Begin ("href=\"%s\" title=\"%s\" target=\"_blank\"" " class=\"FILENAME_BIG_%s\"", URL,Title,The_GetSuffix ()); if (FileMetadata->FilFolLnk.Type == Brw_IS_FILE) Brw_PutIconFile (FileMetadata->FilFolLnk.Name, "ICO40x40", false); // Don't put link to view metadata else Ico_PutIcon ("up-right-from-square.svg",Ico_BLACK,Txt_Link,"ICO40x40"); HTM_TxtF (" %s ",FileNameToShow); Ico_PutIcon ("download.svg",Ico_BLACK,Title,"ICO40x40"); HTM_A_End (); } } /*****************************************************************************/ /*********************** Write link to download a file ***********************/ /*****************************************************************************/ static void Brw_WriteSmallLinkToDownloadFile (const char *URL, struct Brw_FileMetadata *FileMetadata, const char *FileNameToShow) { extern const char *Txt_Check_marks_in_the_file; /***** On the screen a link will be shown to download the file *****/ if (Gbl.FileBrowser.Type == Brw_SHOW_MRK_CRS || Gbl.FileBrowser.Type == Brw_SHOW_MRK_GRP) { /* Form to see marks */ Frm_BeginForm (Gbl.FileBrowser.Type == Brw_SHOW_MRK_CRS ? ActSeeMyMrkCrs : ActSeeMyMrkGrp); Str_Copy (Gbl.FileBrowser.FilFolLnk.Path,FileMetadata->FilFolLnk.Path, sizeof (Gbl.FileBrowser.FilFolLnk.Path) - 1); Str_Copy (Gbl.FileBrowser.FilFolLnk.Name,FileMetadata->FilFolLnk.Name, sizeof (Gbl.FileBrowser.FilFolLnk.Name) - 1); Gbl.FileBrowser.FilFolLnk.Type = FileMetadata->FilFolLnk.Type; Brw_PutImplicitParsFileBrowser (&Gbl.FileBrowser.FilFolLnk); /* Begin link */ HTM_BUTTON_Submit_Begin (Txt_Check_marks_in_the_file, "class=\"BT_LINK\""); /* Name of the file of marks */ HTM_Txt (FileNameToShow); /* End link */ HTM_BUTTON_End (); /* End form */ Frm_EndForm (); } else { /* Put anchor and filename */ HTM_A_Begin ("href=\"%s\" class=\"DAT_STRONG_%s\"" " title=\"%s\" target=\"_blank\"", URL,The_GetSuffix (),FileNameToShow); HTM_Txt (FileNameToShow); HTM_A_End (); } } /*****************************************************************************/ /**************** Change metadata of a file in a file browser ****************/ /*****************************************************************************/ void Brw_ChgFileMetadata (void) { extern const char *Txt_The_properties_of_file_X_have_been_saved; struct Brw_FileMetadata FileMetadata; bool Found; bool IAmTheOwner; bool PublicFileBeforeEdition; bool PublicFileAfterEdition; Brw_License_t License; /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); /***** Get file metadata *****/ FileMetadata.FilCod = ParCod_GetAndCheckPar (ParCod_Fil); Brw_GetFileMetadataByCod (&FileMetadata); Found = Brw_GetFileTypeSizeAndDate (&FileMetadata); if (Found) { /***** Check if I can change file metadata *****/ IAmTheOwner = Brw_CheckIfIAmOwnerOfFile (FileMetadata.PublisherUsrCod); if (Brw_CheckIfICanEditFileMetadata (IAmTheOwner)) { /* Check if the file was public before the edition */ PublicFileBeforeEdition = FileMetadata.IsPublic; /***** Get the new file privacy and license from form *****/ switch (Gbl.FileBrowser.Type) { case Brw_ADMI_DOC_INS: case Brw_ADMI_SHR_INS: case Brw_ADMI_DOC_CTR: case Brw_ADMI_SHR_CTR: case Brw_ADMI_DOC_DEG: case Brw_ADMI_SHR_DEG: case Brw_ADMI_DOC_CRS: case Brw_ADMI_SHR_CRS: PublicFileAfterEdition = Brw_GetParPublicFile (); License = Brw_GetParLicense (); break; case Brw_ADMI_DOC_GRP: case Brw_ADMI_TCH_CRS: case Brw_ADMI_TCH_GRP: case Brw_ADMI_SHR_GRP: case Brw_ADMI_ASG_USR: case Brw_ADMI_ASG_CRS: case Brw_ADMI_WRK_USR: case Brw_ADMI_WRK_CRS: case Brw_ADMI_DOC_PRJ: case Brw_ADMI_ASS_PRJ: case Brw_ADMI_BRF_USR: PublicFileAfterEdition = false; // Files in these zones can not be public License = Brw_GetParLicense (); break; default: PublicFileAfterEdition = false; // Files in other zones can not be public License = Brw_LICENSE_DEFAULT; break; } /***** Change file metadata *****/ Brw_DB_ChangeFilePublic (&FileMetadata,PublicFileAfterEdition,License); /***** Remove the affected clipboards *****/ Brw_DB_RemoveAffectedClipboards (Gbl.FileBrowser.Type, Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Other.UsrDat.UsrCod); /***** Insert file into public social activity *****/ if (!PublicFileBeforeEdition && PublicFileAfterEdition) // Only if file has changed from private to public switch (Gbl.FileBrowser.Type) { case Brw_ADMI_DOC_INS: TmlNot_StoreAndPublishNote (TmlNot_INS_DOC_PUB_FILE,FileMetadata.FilCod); break; case Brw_ADMI_SHR_INS: TmlNot_StoreAndPublishNote (TmlNot_INS_SHA_PUB_FILE,FileMetadata.FilCod); break; case Brw_ADMI_DOC_CTR: TmlNot_StoreAndPublishNote (TmlNot_CTR_DOC_PUB_FILE,FileMetadata.FilCod); break; case Brw_ADMI_SHR_CTR: TmlNot_StoreAndPublishNote (TmlNot_CTR_SHA_PUB_FILE,FileMetadata.FilCod); break; case Brw_ADMI_DOC_DEG: TmlNot_StoreAndPublishNote (TmlNot_DEG_DOC_PUB_FILE,FileMetadata.FilCod); break; case Brw_ADMI_SHR_DEG: TmlNot_StoreAndPublishNote (TmlNot_DEG_SHA_PUB_FILE,FileMetadata.FilCod); break; case Brw_ADMI_DOC_CRS: TmlNot_StoreAndPublishNote (TmlNot_CRS_DOC_PUB_FILE,FileMetadata.FilCod); break; case Brw_ADMI_SHR_CRS: TmlNot_StoreAndPublishNote (TmlNot_CRS_SHA_PUB_FILE,FileMetadata.FilCod); break; default: break; } /***** Write sucess message *****/ Ale_ShowAlert (Ale_SUCCESS,Txt_The_properties_of_file_X_have_been_saved, FileMetadata.FilFolLnk.Name); } else /***** Write error message and exit *****/ Err_NoPermissionExit (); } /***** Show again the file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /*********** Get parameter with public / private file from form *************/ /*****************************************************************************/ static bool Brw_GetParPublicFile (void) { return Par_GetParBool ("PublicFile"); } /*****************************************************************************/ /******************** Get parameter with file license ***********************/ /*****************************************************************************/ static Brw_License_t Brw_GetParLicense (void) { return (Brw_License_t) Par_GetParUnsignedLong ("License", 0, Brw_NUM_LICENSES - 1, (unsigned long) Brw_LICENSE_UNKNOWN); } /*****************************************************************************/ /********************* Get file metadata using its path **********************/ /*****************************************************************************/ // This function only gets metadata stored in table files, // does not get size, time, numviews... void Brw_GetFileMetadataByPath (struct Brw_FileMetadata *FileMetadata) { MYSQL_RES *mysql_res; /***** Get metadata of a file from database *****/ if (Brw_DB_GetFileMetadataByPath (&mysql_res,Gbl.FileBrowser.FilFolLnk.Full)) { Brw_ResetFileMetadata (FileMetadata); Brw_GetFileMetadataFromRow (mysql_res,FileMetadata); } else Brw_ResetFileMetadata (FileMetadata); } /*****************************************************************************/ /********************* Get file metadata using its code **********************/ /*****************************************************************************/ // FileMetadata.FilCod must be filled // This function only gets metadata stored in table files, // does not get size, time, numviews... void Brw_GetFileMetadataByCod (struct Brw_FileMetadata *FileMetadata) { MYSQL_RES *mysql_res; /***** Get metadata of a file from database *****/ if (Brw_DB_GetFileMetadataByCod (&mysql_res,FileMetadata->FilCod)) { Brw_ResetFileMetadata (FileMetadata); Brw_GetFileMetadataFromRow (mysql_res,FileMetadata); } else Brw_ResetFileMetadata (FileMetadata); /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); } /*****************************************************************************/ /*************************** Reset file metadata *****************************/ /*****************************************************************************/ static void Brw_ResetFileMetadata (struct Brw_FileMetadata *FileMetadata) { FileMetadata->FilCod = -1L; FileMetadata->FileBrowser = Brw_UNKNOWN; FileMetadata->Cod = -1L; FileMetadata->ZoneUsrCod = -1L; FileMetadata->PublisherUsrCod = -1L; FileMetadata->FilFolLnk.Type = Brw_IS_UNKNOWN; FileMetadata->FilFolLnk.Full[0] = '\0'; FileMetadata->FilFolLnk.Path[0] = '\0'; FileMetadata->FilFolLnk.Name[0] = '\0'; FileMetadata->IsHidden = false; FileMetadata->IsPublic = false; FileMetadata->License = Brw_LICENSE_DEFAULT; FileMetadata->Size = (off_t) 0; FileMetadata->Time = (time_t) 0; FileMetadata->NumMyViews = FileMetadata->NumPublicViews = FileMetadata->NumViewsFromLoggedUsrs = FileMetadata->NumLoggedUsrs = 0; } /*****************************************************************************/ /********************* Get file metadata using its code **********************/ /*****************************************************************************/ static void Brw_GetFileMetadataFromRow (MYSQL_RES *mysql_res, struct Brw_FileMetadata *FileMetadata) { MYSQL_ROW row; unsigned UnsignedNum; /***** Get next row from result *****/ row = mysql_fetch_row (mysql_res); /***** Get file code (row[0]) *****/ FileMetadata->FilCod = Str_ConvertStrCodToLongCod (row[0]); /***** Get file browser type in database (row[1]) *****/ FileMetadata->FileBrowser = Brw_UNKNOWN; if (sscanf (row[1],"%u",&UnsignedNum) == 1) if (UnsignedNum < Brw_NUM_TYPES_FILE_BROWSER) FileMetadata->FileBrowser = (Brw_FileBrowser_t) UnsignedNum; /***** Get institution/center/degree/course/group code (row[2]) *****/ FileMetadata->Cod = Str_ConvertStrCodToLongCod (row[2]); /***** Get the user's code of the owner of a zone of files (row[3]) *****/ FileMetadata->ZoneUsrCod = Str_ConvertStrCodToLongCod (row[3]); /***** Get publisher's code (row[4]) *****/ FileMetadata->PublisherUsrCod = Str_ConvertStrCodToLongCod (row[4]); /***** Get file type (row[5]) *****/ FileMetadata->FilFolLnk.Type = Brw_IS_UNKNOWN; // default if (sscanf (row[5],"%u",&UnsignedNum) == 1) if (UnsignedNum < Brw_NUM_FILE_TYPES) FileMetadata->FilFolLnk.Type = (Brw_FileType_t) UnsignedNum; /***** Get path (row[6]) *****/ Str_Copy (FileMetadata->FilFolLnk.Full,row[6], sizeof (FileMetadata->FilFolLnk.Full) - 1); Str_SplitFullPathIntoPathAndFileName (FileMetadata->FilFolLnk.Full, FileMetadata->FilFolLnk.Path, FileMetadata->FilFolLnk.Name); /***** File is hidden? (row[7]) *****/ switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_INS: case Brw_ADMI_DOC_INS: case Brw_SHOW_DOC_CTR: case Brw_ADMI_DOC_CTR: case Brw_SHOW_DOC_DEG: case Brw_ADMI_DOC_DEG: case Brw_SHOW_DOC_CRS: case Brw_ADMI_DOC_CRS: FileMetadata->IsHidden = (row[7][0] == 'Y'); break; default: FileMetadata->IsHidden = false; break; } /***** Is a public file? (row[8]) *****/ switch (Gbl.FileBrowser.Type) { case Brw_SHOW_DOC_INS: case Brw_ADMI_DOC_INS: case Brw_ADMI_SHR_INS: case Brw_SHOW_DOC_CTR: case Brw_ADMI_DOC_CTR: case Brw_ADMI_SHR_CTR: case Brw_SHOW_DOC_DEG: case Brw_ADMI_DOC_DEG: case Brw_ADMI_SHR_DEG: case Brw_SHOW_DOC_CRS: case Brw_ADMI_DOC_CRS: case Brw_ADMI_SHR_CRS: FileMetadata->IsPublic = (row[8][0] == 'Y'); break; default: FileMetadata->IsPublic = false; break; } /***** Get license (row[9]) *****/ FileMetadata->License = Brw_LICENSE_UNKNOWN; if (sscanf (row[9],"%u",&UnsignedNum) == 1) if (UnsignedNum < Brw_NUM_LICENSES) FileMetadata->License = (Brw_License_t) UnsignedNum; } /*****************************************************************************/ /*********************** Get file name using its code ************************/ /*****************************************************************************/ // FileMetadata.FilCod must be filled // This function only gets file name stored in table files, // The rest of the fields are not filled void Brw_GetFileNameByCod (struct Brw_FileMetadata *FileMetadata) { MYSQL_RES *mysql_res; MYSQL_ROW row; /***** Get metadata of a file from database *****/ if (Brw_DB_GetFileNameByCod (&mysql_res,FileMetadata->FilCod)) { /* Get row */ row = mysql_fetch_row (mysql_res); /* Get path (row[0]) */ Str_Copy (FileMetadata->FilFolLnk.Full,row[0], sizeof (FileMetadata->FilFolLnk.Full) - 1); Str_SplitFullPathIntoPathAndFileName (FileMetadata->FilFolLnk.Full, FileMetadata->FilFolLnk.Path, FileMetadata->FilFolLnk.Name); } /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); } /*****************************************************************************/ /********************** Get file type, size and date *************************/ /*****************************************************************************/ // Return true if file exists bool Brw_GetFileTypeSizeAndDate (struct Brw_FileMetadata *FileMetadata) { char Path[PATH_MAX + 1 + PATH_MAX + 1]; struct stat FileStatus; snprintf (Path,sizeof (Path),"%s/%s", Gbl.FileBrowser.Priv.PathAboveRootFolder, FileMetadata->FilFolLnk.Full); if (lstat (Path,&FileStatus)) // On success ==> 0 is returned { // Error on lstat FileMetadata->FilFolLnk.Type = Brw_IS_UNKNOWN; FileMetadata->Size = (off_t) 0; FileMetadata->Time = (time_t) 0; return false; } else { if (S_ISDIR (FileStatus.st_mode)) FileMetadata->FilFolLnk.Type = Brw_IS_FOLDER; else if (S_ISREG (FileStatus.st_mode)) FileMetadata->FilFolLnk.Type = Str_FileIs (FileMetadata->FilFolLnk.Full,"url") ? Brw_IS_LINK : Brw_IS_FILE; else FileMetadata->FilFolLnk.Type = Brw_IS_UNKNOWN; FileMetadata->Size = FileStatus.st_size; FileMetadata->Time = FileStatus.st_mtime; return true; } } /*****************************************************************************/ /*********************** Get and update views of a file **********************/ /*****************************************************************************/ /* Input: FileMetadata->FilCod Output: FileMetadata->NumMyViews FileMetadata->NumPublicViews FileMetadata->NumViewsFromLoggedUsrs FileMetadata->NumLoggedUsrs */ void Brw_GetAndUpdateFileViews (struct Brw_FileMetadata *FileMetadata) { if (FileMetadata->FilCod > 0) { /***** Get file views from logged users *****/ Brw_GetFileViewsFromLoggedUsrs (FileMetadata); /***** Get file views from non logged users *****/ FileMetadata->NumPublicViews = Brw_DB_GetFileViewsFromNonLoggedUsrs (FileMetadata->FilCod); /***** Get number of my views *****/ if (Gbl.Usrs.Me.Logged) { if (FileMetadata->NumViewsFromLoggedUsrs) FileMetadata->NumMyViews = Brw_GetFileViewsFromMe (FileMetadata->FilCod); else FileMetadata->NumMyViews = 0; } else FileMetadata->NumMyViews = FileMetadata->NumPublicViews; /***** Update number of my views *****/ Brw_DB_UpdateFileViews (FileMetadata->NumMyViews,FileMetadata->FilCod); /***** Increment number of file views in my user's figures *****/ if (Gbl.Usrs.Me.Logged) Prf_DB_IncrementNumFileViewsUsr (Gbl.Usrs.Me.UsrDat.UsrCod); } else FileMetadata->NumMyViews = FileMetadata->NumPublicViews = FileMetadata->NumViewsFromLoggedUsrs = FileMetadata->NumLoggedUsrs = 0; } /*****************************************************************************/ /************************** Update my views of a file ************************/ /*****************************************************************************/ void Brw_UpdateMyFileViews (long FilCod) { /***** Update number of my views *****/ Brw_DB_UpdateFileViews (Brw_GetFileViewsFromMe (FilCod),FilCod); } /*****************************************************************************/ /******************** Get file views from logged users ***********************/ /*****************************************************************************/ /* Input: FileMetadata->FilCod Output: FileMetadata->NumViewsFromLoggedUsrs FileMetadata->NumLoggedUsrs */ static void Brw_GetFileViewsFromLoggedUsrs (struct Brw_FileMetadata *FileMetadata) { MYSQL_RES *mysql_res; MYSQL_ROW row; /***** Get number total of views from logged users *****/ if (Brw_DB_GetFileViewsFromLoggedUsrs (&mysql_res,FileMetadata->FilCod)) { row = mysql_fetch_row (mysql_res); /* Get number of distinct users (row[0]) */ if (sscanf (row[0],"%u",&(FileMetadata->NumLoggedUsrs)) != 1) FileMetadata->NumLoggedUsrs = 0; /* Get number of views (row[1]) */ if (row[1]) { if (sscanf (row[1],"%u",&(FileMetadata->NumViewsFromLoggedUsrs)) != 1) FileMetadata->NumViewsFromLoggedUsrs = 0; } else FileMetadata->NumViewsFromLoggedUsrs = 0; } else FileMetadata->NumViewsFromLoggedUsrs = FileMetadata->NumLoggedUsrs = 0; /* Free structure that stores the query result */ DB_FreeMySQLResult (&mysql_res); } /*****************************************************************************/ /************************** Get file views from me ***************************/ /*****************************************************************************/ static unsigned Brw_GetFileViewsFromMe (long FilCod) { MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned NumMyViews; /***** Get number of my views *****/ if (Brw_DB_GetFileViewsFromMe (&mysql_res,FilCod)) { /* Get number of my views */ row = mysql_fetch_row (mysql_res); if (sscanf (row[0],"%u",&NumMyViews) != 1) NumMyViews = 0; } else NumMyViews = 0; /* Free structure that stores the query result */ DB_FreeMySQLResult (&mysql_res); return NumMyViews; } /*****************************************************************************/ /******** Get code of user in assignment / works for expanded folders ********/ /*****************************************************************************/ void Brw_GetCrsGrpFromFileMetadata (Brw_FileBrowser_t FileBrowser,long Cod, long *InsCod, long *CtrCod, long *DegCod, long *CrsCod, long *GrpCod) { struct Ctr_Center Ctr; struct Deg_Degree Deg; struct Crs_Course Crs; struct GroupData GrpDat; switch (FileBrowser) { case Brw_ADMI_DOC_INS: case Brw_ADMI_SHR_INS: /* Cod stores the institution code */ *GrpCod = -1L; *CrsCod = -1L; *DegCod = -1L; *CtrCod = -1L; *InsCod = Cod; break; case Brw_ADMI_DOC_CTR: case Brw_ADMI_SHR_CTR: /* Cod stores the center code */ *GrpCod = -1L; *CrsCod = -1L; *DegCod = -1L; *CtrCod = Ctr.CtrCod = Cod; Ctr_GetCenterDataByCod (&Ctr); *InsCod = Ctr.InsCod; break; case Brw_ADMI_DOC_DEG: case Brw_ADMI_SHR_DEG: /* Cod stores the degree code */ *GrpCod = -1L; *CrsCod = -1L; *DegCod = Deg.DegCod = Cod; Deg_GetDegreeDataByCod (&Deg); *CtrCod = Ctr.CtrCod = Deg.CtrCod; Ctr_GetCenterDataByCod (&Ctr); *InsCod = Ctr.InsCod; break; case Brw_ADMI_DOC_CRS: case Brw_ADMI_TCH_CRS: case Brw_ADMI_SHR_CRS: case Brw_ADMI_ASG_USR: case Brw_ADMI_WRK_USR: case Brw_ADMI_MRK_CRS: /* Cod stores the course code */ *GrpCod = -1L; *CrsCod = Crs.CrsCod = Cod; Crs_GetCourseDataByCod (&Crs); *DegCod = Deg.DegCod = Crs.DegCod; Deg_GetDegreeDataByCod (&Deg); *CtrCod = Ctr.CtrCod = Deg.CtrCod; Ctr_GetCenterDataByCod (&Ctr); *InsCod = Ctr.InsCod; break; case Brw_ADMI_DOC_GRP: case Brw_ADMI_TCH_GRP: case Brw_ADMI_SHR_GRP: case Brw_ADMI_MRK_GRP: /* Cod stores the group code */ *GrpCod = GrpDat.GrpCod = Cod; Grp_GetGroupDataByCod (&GrpDat); *CrsCod = Crs.CrsCod = GrpDat.CrsCod; Crs_GetCourseDataByCod (&Crs); *DegCod = Deg.DegCod = Crs.DegCod; Deg_GetDegreeDataByCod (&Deg); *CtrCod = Ctr.CtrCod = Deg.CtrCod; Ctr_GetCenterDataByCod (&Ctr); *InsCod = Ctr.InsCod; break; case Brw_ADMI_DOC_PRJ: case Brw_ADMI_ASS_PRJ: /* Cod stores the project code */ *GrpCod = -1L; *CrsCod = Crs.CrsCod = Prj_DB_GetCrsOfPrj (Cod); Crs_GetCourseDataByCod (&Crs); *DegCod = Deg.DegCod = Crs.DegCod; Deg_GetDegreeDataByCod (&Deg); *CtrCod = Ctr.CtrCod = Deg.CtrCod; Ctr_GetCenterDataByCod (&Ctr); *InsCod = Ctr.InsCod; break; default: *GrpCod = -1L; *CrsCod = -1L; *DegCod = -1L; *CtrCod = -1L; *InsCod = -1L; break; } } /*****************************************************************************/ /**************** Remove a file or folder from the database ******************/ /*****************************************************************************/ static void Brw_RemoveOneFileOrFolderFromDB (const char Path[PATH_MAX + 1]) { /***** Set possible notifications as removed. Set possible social note as unavailable. Important: do this before removing from files *****/ Ntf_MarkNotifOneFileAsRemoved (Path); TmlNot_MarkNoteOneFileAsUnavailable (Path); /***** Remove from database the entries that store the marks properties, file views and file data *****/ Brw_DB_RemoveOneFileOrFolder (Path); } /*****************************************************************************/ /*************** Remove children of a folder from the database ***************/ /*****************************************************************************/ static void Brw_RemoveChildrenOfFolderFromDB (const char Path[PATH_MAX + 1]) { /***** Set possible notifications as removed. Set possible social notes as unavailable. Important: do this before removing from files *****/ Ntf_MarkNotifChildrenOfFolderAsRemoved (Path); TmlNot_MarkNotesChildrenOfFolderAsUnavailable (Path); /***** Remove from database the entries that store the marks properties, file views and file data *****/ Brw_DB_RemoveChildrenOfFolder (Path); } /*****************************************************************************/ /********** Check if I have permission to modify a file or folder ************/ /*****************************************************************************/ static void Brw_SetIfICanEditFileOrFolder (bool Value) { Brw_ICanEditFileOrFolder = Value; } static bool Brw_GetIfICanEditFileOrFolder (void) { return Brw_ICanEditFileOrFolder; } static bool Brw_CheckIfICanEditFileOrFolder (unsigned Level) { /***** Level 0 (root folder) can not be removed/renamed *****/ if (Level == 0) return false; /***** I must be student or a superior role to edit *****/ if (Gbl.Usrs.Me.Role.Max < Rol_STD) return false; /***** Set depending on browser, level, logged role... *****/ switch (Gbl.FileBrowser.Type) { case Brw_ADMI_DOC_CRS: return Gbl.Usrs.Me.Role.Logged >= Rol_TCH; case Brw_ADMI_DOC_GRP: if (Gbl.Usrs.Me.Role.Logged == Rol_TCH) // A teacher... // ...can edit only if he/she belongs to group return Grp_GetIfIBelongToGrp (Gbl.Crs.Grps.GrpCod); // An administrator can edit return (Gbl.Usrs.Me.Role.Logged > Rol_TCH); case Brw_ADMI_TCH_CRS: case Brw_ADMI_TCH_GRP: // Check if I am the publisher of the file/folder return Brw_CheckIfICanModifyPrivateFileOrFolder (); case Brw_ADMI_SHR_CRS: case Brw_ADMI_SHR_GRP: // Check if I am the publisher of the file/folder return Brw_CheckIfICanModifySharedFileOrFolder (); case Brw_ADMI_ASG_USR: case Brw_ADMI_ASG_CRS: if (Gbl.FileBrowser.Asg.AsgCod <= 0) // If folder does not correspond to any assignment return true; // Folder can be removed or renamed if (Gbl.FileBrowser.Asg.Hidden) // If assignment is hidden return false; // Do not edit anything in hidden assigments if (Gbl.FileBrowser.FilFolLnk.Type == Brw_IS_FOLDER && // The main folder of an assignment Level == 1) return false; // Do not remove / rename main folder of assigment if (!Gbl.FileBrowser.Asg.IBelongToCrsOrGrps) // If I do not belong to course / groups of this assignment return false; // I can not edit this assignment switch (Gbl.Usrs.Me.Role.Logged) { case Rol_STD: // Students... case Rol_NET: // ...and non-editing teachers... return Gbl.FileBrowser.Asg.Open; // ...can edit inside open assignments case Rol_TCH: // Teachers... return true; // ...can edit inside open or closed assignments default: break; } return false; case Brw_ADMI_DOC_PRJ: return Brw_CheckIfICanModifyPrjDocFileOrFolder (); case Brw_ADMI_ASS_PRJ: return Brw_CheckIfICanModifyPrjAssFileOrFolder (); default: return Brw_CheckIfFileBrowserIsEditable (Gbl.FileBrowser.Type); } return false; } /*****************************************************************************/ /**** Check if I have permission to create a file or folder into a folder ****/ /*****************************************************************************/ static bool Brw_CheckIfICanCreateIntoFolder (unsigned Level) { /***** If not in a folder... *****/ if (Gbl.FileBrowser.FilFolLnk.Type != Brw_IS_FOLDER) return false; /***** I must be student, teacher, admin or superuser to edit *****/ if (Gbl.Usrs.Me.Role.Max < Rol_STD) return false; /***** If maximum level is reached, I can not create/paste *****/ if (Level >= BrwSiz_MAX_DIR_LEVELS) return false; /***** Have I permission to create/paste a new file or folder into the folder? *****/ switch (Gbl.FileBrowser.Type) { case Brw_ADMI_DOC_CRS: return Gbl.Usrs.Me.Role.Logged >= Rol_TCH; case Brw_ADMI_DOC_GRP: if (Gbl.Usrs.Me.Role.Logged == Rol_TCH) // A teacher // ...can create/paste only if he/she belongs to group return Grp_GetIfIBelongToGrp (Gbl.Crs.Grps.GrpCod); // An administrator can create/paste return (Gbl.Usrs.Me.Role.Logged > Rol_TCH); case Brw_ADMI_TCH_CRS: return Gbl.Usrs.Me.Role.Logged >= Rol_NET; case Brw_ADMI_TCH_GRP: if (Gbl.Usrs.Me.Role.Logged == Rol_NET || // A non-editing teacher... Gbl.Usrs.Me.Role.Logged == Rol_TCH) // ...or a teacher // ...can create/paste only if he/she belongs to group return Grp_GetIfIBelongToGrp (Gbl.Crs.Grps.GrpCod); // An administrator can create/paste return (Gbl.Usrs.Me.Role.Logged > Rol_TCH); case Brw_ADMI_SHR_CRS: return Gbl.Usrs.Me.Role.Logged >= Rol_STD; case Brw_ADMI_SHR_GRP: if (Gbl.Usrs.Me.Role.Logged >= Rol_STD && // A student, non-editing teacher... Gbl.Usrs.Me.Role.Logged <= Rol_TCH) // ...or a teacher // ...can create/paste only if he/she belongs to group return Grp_GetIfIBelongToGrp (Gbl.Crs.Grps.GrpCod); // An administrator can create/paste return Gbl.Usrs.Me.Role.Logged >= Rol_STD; case Brw_ADMI_ASG_USR: case Brw_ADMI_ASG_CRS: if (Level == 0) // If root folder return false; // Folders of assigments (level 1) // can only be created automatically if (Gbl.FileBrowser.Asg.AsgCod <= 0) // If folder does not correspond to any assignment return false; // Do not create anything out of assignments if (Gbl.FileBrowser.Asg.Hidden) // If assignment is hidden return false; // Do not create anything in hidden assigments if (!Gbl.FileBrowser.Asg.IBelongToCrsOrGrps) // If I do not belong to course / groups of this assignment return false; // I can not create anything inside this assignment switch (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs) { case Rol_STD: // Students... case Rol_NET: // ...and non-editing teachers... return Gbl.FileBrowser.Asg.Open; // ...can create inside open assignments case Rol_TCH: // Teachers... return true; // ...can create inside open or closed assignments default: break; } return false; default: return Brw_CheckIfFileBrowserIsEditable (Gbl.FileBrowser.Type); } return false; } /*****************************************************************************/ /********************* Check if file browser is editable *********************/ /*****************************************************************************/ bool Brw_CheckIfFileBrowserIsEditable (Brw_FileBrowser_t FileBrowser) { static const bool Brw_FileBrowserIsEditable[Brw_NUM_TYPES_FILE_BROWSER] = { [Brw_UNKNOWN ] = false, [Brw_SHOW_DOC_CRS] = false, [Brw_SHOW_MRK_CRS] = false, [Brw_ADMI_DOC_CRS] = true, [Brw_ADMI_SHR_CRS] = true, [Brw_ADMI_SHR_GRP] = true, [Brw_ADMI_WRK_USR] = true, [Brw_ADMI_WRK_CRS] = true, [Brw_ADMI_MRK_CRS] = true, [Brw_ADMI_BRF_USR] = true, [Brw_SHOW_DOC_GRP] = false, [Brw_ADMI_DOC_GRP] = true, [Brw_SHOW_MRK_GRP] = false, [Brw_ADMI_MRK_GRP] = true, [Brw_ADMI_ASG_USR] = true, [Brw_ADMI_ASG_CRS] = true, [Brw_SHOW_DOC_DEG] = false, [Brw_ADMI_DOC_DEG] = true, [Brw_SHOW_DOC_CTR] = false, [Brw_ADMI_DOC_CTR] = true, [Brw_SHOW_DOC_INS] = false, [Brw_ADMI_DOC_INS] = true, [Brw_ADMI_SHR_DEG] = true, [Brw_ADMI_SHR_CTR] = true, [Brw_ADMI_SHR_INS] = true, [Brw_ADMI_TCH_CRS] = true, [Brw_ADMI_TCH_GRP] = true, [Brw_ADMI_DOC_PRJ] = true, [Brw_ADMI_ASS_PRJ] = true, }; return Brw_FileBrowserIsEditable[FileBrowser]; } /*****************************************************************************/ /********** Check if I have permission to modify a file or folder ************/ /********** in the current shared or private zone ************/ /*****************************************************************************/ // Returns true if I can remove or rename Gbl.FileBrowser.FilFolLnk.Full, and false if I have not permission // I can remove or rename a file if I am the publisher // I can remove or rename a folder if I am the unique publisher of all files and folders in the subtree starting there static bool Brw_CheckIfICanModifySharedFileOrFolder (void) { switch (Gbl.Usrs.Me.Role.Logged) { case Rol_STD: // If I am a student or a non-editing teacher... case Rol_NET: // ...I can modify the file/folder if I am the publisher return (Gbl.Usrs.Me.UsrDat.UsrCod == Brw_DB_GetPublisherOfSubtree (Gbl.FileBrowser.FilFolLnk.Full)); // Am I the publisher of subtree? case Rol_TCH: case Rol_DEG_ADM: case Rol_CTR_ADM: case Rol_INS_ADM: case Rol_SYS_ADM: return true; default: return false; } return false; } static bool Brw_CheckIfICanModifyPrivateFileOrFolder (void) { switch (Gbl.Usrs.Me.Role.Logged) { case Rol_NET: // If I am a student or a non-editing teacher... // ...I can modify the file/folder if I am the publisher return (Gbl.Usrs.Me.UsrDat.UsrCod == Brw_DB_GetPublisherOfSubtree (Gbl.FileBrowser.FilFolLnk.Full)); // Am I the publisher of subtree? case Rol_TCH: case Rol_DEG_ADM: case Rol_CTR_ADM: case Rol_INS_ADM: case Rol_SYS_ADM: return true; default: return false; } return false; } /*****************************************************************************/ /********** Check if I have permission to modify a file or folder ************/ /********** in the current project documents zone ************/ /*****************************************************************************/ // Returns true if I can remove or rename Gbl.FileBrowser.FilFolLnk.Full, and false if I have not permission // I can remove or rename a file if I am the publisher // I can remove or rename a folder if I am the unique publisher of all files and folders in the subtree starting there static bool Brw_CheckIfICanModifyPrjDocFileOrFolder (void) { switch (Gbl.Usrs.Me.Role.Logged) { case Rol_STD: case Rol_NET: if (Prj_GetMyRolesInProject (Prj_GetPrjCod ())) // I am a member return (Gbl.Usrs.Me.UsrDat.UsrCod == Brw_DB_GetPublisherOfSubtree (Gbl.FileBrowser.FilFolLnk.Full)); // Am I the publisher of subtree? return false; case Rol_TCH: // Editing teachers in a course can access to all files case Rol_SYS_ADM: return true; default: return false; } return false; } /*****************************************************************************/ /********** Check if I have permission to modify a file or folder ************/ /********** in the current project assessment zone ************/ /*****************************************************************************/ // Returns true if I can remove or rename Gbl.FileBrowser.FilFolLnk.Full, and false if I have not permission // I can remove or rename a file if I am the publisher // I can remove or rename a folder if I am the unique publisher of all files and folders in the subtree starting there static bool Brw_CheckIfICanModifyPrjAssFileOrFolder (void) { switch (Gbl.Usrs.Me.Role.Logged) { case Rol_STD: case Rol_NET: if ((Prj_GetMyRolesInProject (Prj_GetPrjCod ()) & (1 << Prj_ROLE_TUT | // Tutor... 1 << Prj_ROLE_EVL))) // ...or evaluator return (Gbl.Usrs.Me.UsrDat.UsrCod == Brw_DB_GetPublisherOfSubtree (Gbl.FileBrowser.FilFolLnk.Full)); // Am I the publisher of subtree? return false; case Rol_TCH: // Editing teachers in a course can access to all files case Rol_SYS_ADM: return true; default: return false; } return false; } /*****************************************************************************/ /************* Remove common zones of all groups of a type ***************/ /*****************************************************************************/ void Brw_RemoveZonesOfGroupsOfType (long GrpTypCod) { MYSQL_RES *mysql_res; unsigned NumGrps; unsigned NumGrp; long GrpCod; /***** Query database *****/ NumGrps = Grp_DB_GetGrpsOfType (&mysql_res,GrpTypCod); for (NumGrp = 0; NumGrp < NumGrps; NumGrp++) { /* Get next group */ GrpCod = DB_GetNextCode (mysql_res); /* Remove file zones of this group */ Brw_RemoveGrpZones (Gbl.Hierarchy.Crs.CrsCod,GrpCod); } /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); } /*****************************************************************************/ /*********************** Remove file zones of a group ************************/ /*****************************************************************************/ void Brw_RemoveGrpZones (long CrsCod,long GrpCod) { char PathGrpFileZones[PATH_MAX + 1]; /***** Set notifications about files in this group zone as removed *****/ Ntf_DB_MarkNotifFilesInGroupAsRemoved (GrpCod); /***** Remove files in the group from database *****/ Brw_DB_RemoveGrpFiles (GrpCod); /***** Remove group zones *****/ snprintf (PathGrpFileZones,sizeof (PathGrpFileZones),"%s/%ld/grp/%ld", Cfg_PATH_CRS_PRIVATE,CrsCod,GrpCod); Fil_RemoveTree (PathGrpFileZones); } /*****************************************************************************/ /***************** Remove the works of a user in a course ********************/ /*****************************************************************************/ void Brw_RemoveUsrWorksInCrs (struct Usr_Data *UsrDat,struct Crs_Course *Crs) { char PathUsrInCrs[PATH_MAX + 1]; /***** Remove user's works in the course from database *****/ Brw_DB_RemoveWrkFiles (Crs->CrsCod,UsrDat->UsrCod); /***** Remove the folder for this user inside the course *****/ snprintf (PathUsrInCrs,sizeof (PathUsrInCrs),"%s/%ld/usr/%02u/%ld", Cfg_PATH_CRS_PRIVATE,Crs->CrsCod, (unsigned) (UsrDat->UsrCod % 100),UsrDat->UsrCod); Fil_RemoveTree (PathUsrInCrs); // If this was the last user in his/her subfolder ==> the subfolder will be empty } /*****************************************************************************/ /************* Remove the works of a user in all of his courses **************/ /*****************************************************************************/ void Brw_RemoveUsrWorksInAllCrss (struct Usr_Data *UsrDat) { MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned NumCrss; unsigned NumCrs; unsigned NumCrssWorksRemoved = 0; struct Crs_Course Crs; /***** Query database *****/ NumCrss = Crs_DB_GetCrssFromUsr (&mysql_res,UsrDat->UsrCod,-1L); /***** Remove the zone of works of the user in the courses he/she belongs to *****/ for (NumCrs = 0; NumCrs < NumCrss; NumCrs++) { /* Get the next course */ row = mysql_fetch_row (mysql_res); Crs.CrsCod = Str_ConvertStrCodToLongCod (row[0]); /* Get data of course */ Crs_GetCourseDataByCod (&Crs); Brw_RemoveUsrWorksInCrs (UsrDat,&Crs); NumCrssWorksRemoved++; } /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); } /*****************************************************************************/ /******************** Get summary and content of a file **********************/ /*****************************************************************************/ void Brw_GetSummaryAndContentOfFile (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1], char **ContentStr, long FilCod,bool GetContent) { extern const char *Txt_Filename; extern const char *Txt_Folder; extern const char *Txt_Uploaded_by; extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS]; struct Brw_FileMetadata FileMetadata; bool FileHasPublisher; struct Usr_Data PublisherUsrDat; /***** Return nothing on error *****/ SummaryStr[0] = '\0'; // Return nothing on error if (GetContent && ContentStr) *ContentStr = NULL; /***** Get file metadata *****/ FileMetadata.FilCod = FilCod; Brw_GetFileMetadataByCod (&FileMetadata); /***** Copy file name into summary string *****/ Str_Copy (SummaryStr,FileMetadata.FilFolLnk.Name,Ntf_MAX_BYTES_SUMMARY); /***** Copy some file metadata into content string *****/ if (GetContent && ContentStr) { /* Get publisher */ if (FileMetadata.PublisherUsrCod > 0) { /* Initialize structure with publisher's data */ Usr_UsrDataConstructor (&PublisherUsrDat); PublisherUsrDat.UsrCod = FileMetadata.PublisherUsrCod; FileHasPublisher = Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&PublisherUsrDat, Usr_DONT_GET_PREFS, Usr_DONT_GET_ROLE_IN_CURRENT_CRS); } else /* Unknown publisher */ FileHasPublisher = false; if (asprintf (ContentStr,"%s: %s
" // File name "%s: %s
" // File path "%s: %s", // Publisher Txt_Filename,FileMetadata.FilFolLnk.Name, Txt_Folder,FileMetadata.FilFolLnk.Path, // TODO: Fix bug: do not write internal name (for example "comun") Txt_Uploaded_by, FileHasPublisher ? PublisherUsrDat.FullName : Txt_ROLES_SINGUL_Abc[Rol_UNK][Usr_SEX_UNKNOWN]) < 0) Err_NotEnoughMemoryExit (); /* Free memory used for publisher's data */ if (FileMetadata.PublisherUsrCod > 0) Usr_UsrDataDestructor (&PublisherUsrDat); } } /*****************************************************************************/ /**************************** List documents found ***************************/ /*****************************************************************************/ void Brw_ListDocsFound (MYSQL_RES **mysql_res,unsigned NumDocs, const char *TitleSingular,const char *TitlePlural) { extern const char *Txt_Institution; extern const char *Txt_Center; extern const char *Txt_Degree; extern const char *Txt_Course; extern const char *Txt_File_zone; extern const char *Txt_Document; extern const char *Txt_hidden_document; extern const char *Txt_hidden_documents; MYSQL_ROW row; char *Title; unsigned NumDoc; unsigned NumDocsNotHidden = 0; unsigned NumDocsHidden; /***** Query database *****/ if (NumDocs) { /***** Begin box and table *****/ /* Number of documents found */ if (asprintf (&Title,"%u %s",NumDocs,NumDocs == 1 ? TitleSingular : TitlePlural) < 0) Err_NotEnoughMemoryExit (); Box_BoxTableBegin (NULL,Title,NULL,NULL,NULL,Box_NOT_CLOSABLE,2); free (Title); /***** Write heading *****/ HTM_TR_Begin (NULL); HTM_TH_Span (NULL ,HTM_HEAD_CENTER,1,1,"BT"); HTM_TH (Txt_Institution,HTM_HEAD_LEFT ); HTM_TH (Txt_Center ,HTM_HEAD_LEFT ); HTM_TH (Txt_Degree ,HTM_HEAD_LEFT ); HTM_TH (Txt_Course ,HTM_HEAD_LEFT ); HTM_TH (Txt_File_zone ,HTM_HEAD_LEFT ); HTM_TH (Txt_Document ,HTM_HEAD_LEFT ); HTM_TR_End (); /***** List documents found *****/ for (NumDoc = 1; NumDoc <= NumDocs; NumDoc++) { /* Get next course */ row = mysql_fetch_row (*mysql_res); /* Write data of this course */ Brw_WriteRowDocData (&NumDocsNotHidden,row); } /***** Write footer *****/ HTM_TR_Begin (NULL); /* Number of documents not hidden found */ HTM_TH_Span_Begin (HTM_HEAD_CENTER,1,7,NULL); HTM_Txt ("("); NumDocsHidden = NumDocs - NumDocsNotHidden; HTM_TxtF ("%u %s", NumDocsHidden,NumDocsHidden == 1 ? Txt_hidden_document : Txt_hidden_documents); HTM_Txt (")"); HTM_TH_End (); HTM_TR_End (); /***** End table and box *****/ Box_BoxTableEnd (); } /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (mysql_res); } /*****************************************************************************/ /************ Write the data of a document (result of a query) ***************/ /*****************************************************************************/ static void Brw_WriteRowDocData (unsigned *NumDocsNotHidden,MYSQL_ROW row) { extern const char *Txt_Documents_area; extern const char *Txt_Teachers_files_area; extern const char *Txt_Shared_files_area; extern const char *Txt_Assignments_area; extern const char *Txt_Works_area; extern const char *Txt_Project_documents; extern const char *Txt_Project_assessment; extern const char *Txt_Marks_area; extern const char *Txt_Temporary_private_storage_area; extern const char *Txt_Folder; extern const char *Txt_Link; struct Brw_FileMetadata FileMetadata; long InsCod; long CtrCod; long DegCod; long CrsCod; long GrpCod; Act_Action_t Action; const char *InsShortName; const char *CtrShortName; const char *DegShortName; const char *CrsShortName; const char *BgColor; const char *Title; char FileNameToShow[NAME_MAX + 1]; /* row[ 0] = FilCod row[ 1] = PathFromRoot row[ 2] = InsCod row[ 3] = InsShortName row[ 4] = CtrCod row[ 5] = CtrShortName row[ 6] = DegCod row[ 7] = DegShortName row[ 8] = CrsCod row[ 9] = CrsShortName row[10] = GrpCod */ /***** Get file code (row[0]) and metadata *****/ FileMetadata.FilCod = Str_ConvertStrCodToLongCod (row[0]); Brw_GetFileMetadataByCod (&FileMetadata); if (!Brw_DB_CheckIfFileOrFolderIsSetAsHiddenUsingMetadata (&FileMetadata)) { /***** Get institution code (row[2]) *****/ InsCod = Str_ConvertStrCodToLongCod (row[2]); InsShortName = row[3]; /***** Get center code (row[4]) *****/ CtrCod = Str_ConvertStrCodToLongCod (row[4]); CtrShortName = row[5]; /***** Get degree code (row[6]) *****/ DegCod = Str_ConvertStrCodToLongCod (row[6]); DegShortName = row[7]; /***** Get course code (row[8]) *****/ CrsCod = Str_ConvertStrCodToLongCod (row[8]); CrsShortName = row[9]; /***** Get group code (row[8]) *****/ GrpCod = Str_ConvertStrCodToLongCod (row[10]); /***** Set row color *****/ BgColor = (CrsCod > 0 && CrsCod == Gbl.Hierarchy.Crs.CrsCod) ? "BG_HIGHLIGHT" : The_GetColorRows (); HTM_TR_Begin (NULL); /***** Write number of document in this search *****/ HTM_TD_Begin ("class=\"RT DAT_%s %s\"", The_GetSuffix (),BgColor); HTM_Unsigned (++(*NumDocsNotHidden)); HTM_TD_End (); /***** Write institution logo, institution short name *****/ HTM_TD_Begin ("class=\"LT DAT_%s %s\"", The_GetSuffix (),BgColor); if (InsCod > 0) { Frm_BeginFormGoTo (ActSeeInsInf); ParCod_PutPar (ParCod_Ins,InsCod); HTM_BUTTON_Submit_Begin (Str_BuildGoToTitle (InsShortName), "class=\"LT BT_LINK\""); Str_FreeGoToTitle (); Lgo_DrawLogo (HieLvl_INS,InsCod,InsShortName,20,"BT_LINK LT",true); HTM_TxtF (" %s",InsShortName); HTM_BUTTON_End (); Frm_EndForm (); } HTM_TD_End (); /***** Write center logo, center short name *****/ HTM_TD_Begin ("class=\"LT DAT_%s %s\"", The_GetSuffix (),BgColor); if (CtrCod > 0) { Frm_BeginFormGoTo (ActSeeCtrInf); ParCod_PutPar (ParCod_Ctr,CtrCod); HTM_BUTTON_Submit_Begin (Str_BuildGoToTitle (CtrShortName), "class=\"LT BT_LINK\""); Str_FreeGoToTitle (); Lgo_DrawLogo (HieLvl_CTR,CtrCod,CtrShortName,20,"LT",true); HTM_TxtF (" %s",CtrShortName); HTM_BUTTON_End (); Frm_EndForm (); } HTM_TD_End (); /***** Write degree logo, degree short name *****/ HTM_TD_Begin ("class=\"LT DAT_%s %s\"", The_GetSuffix (),BgColor); if (DegCod > 0) { Frm_BeginFormGoTo (ActSeeDegInf); ParCod_PutPar (ParCod_Deg,DegCod); HTM_BUTTON_Submit_Begin (Str_BuildGoToTitle (DegShortName), "class=\"LT BT_LINK\""); Str_FreeGoToTitle (); Lgo_DrawLogo (HieLvl_DEG,DegCod,DegShortName,20,"LT",true); HTM_TxtF (" %s",DegShortName); HTM_BUTTON_End (); Frm_EndForm (); } HTM_TD_End (); /***** Write course short name *****/ HTM_TD_Begin ("class=\"LT DAT_%s %s\"", The_GetSuffix (),BgColor); if (CrsCod > 0) { Frm_BeginFormGoTo (ActSeeCrsInf); ParCod_PutPar (ParCod_Crs,CrsCod); HTM_BUTTON_Submit_Begin (Str_BuildGoToTitle (CrsShortName), "class=\"LT BT_LINK\""); Str_FreeGoToTitle (); HTM_Txt (CrsShortName); HTM_BUTTON_End (); Frm_EndForm (); } HTM_TD_End (); /***** Write file zone *****/ switch (FileMetadata.FileBrowser) { case Brw_ADMI_DOC_INS: case Brw_ADMI_DOC_CTR: case Brw_ADMI_DOC_DEG: case Brw_ADMI_DOC_CRS: case Brw_ADMI_DOC_GRP: Title = Txt_Documents_area; break; case Brw_ADMI_TCH_CRS: case Brw_ADMI_TCH_GRP: Title = Txt_Teachers_files_area; break; case Brw_ADMI_SHR_INS: case Brw_ADMI_SHR_CTR: case Brw_ADMI_SHR_DEG: case Brw_ADMI_SHR_CRS: case Brw_ADMI_SHR_GRP: Title = Txt_Shared_files_area; break; case Brw_ADMI_ASG_USR: Title = Txt_Assignments_area; break; case Brw_ADMI_WRK_USR: Title = Txt_Works_area; break; case Brw_ADMI_DOC_PRJ: Title = Txt_Project_documents; break; case Brw_ADMI_ASS_PRJ: Title = Txt_Project_assessment; break; case Brw_ADMI_MRK_CRS: case Brw_ADMI_MRK_GRP: Title = Txt_Marks_area; break; case Brw_ADMI_BRF_USR: Title = Txt_Temporary_private_storage_area; break; default: Title = ""; break; } HTM_TD_Begin ("class=\"LT DAT_%s %s\"", The_GetSuffix (),BgColor); HTM_Txt (Title); HTM_TD_End (); /***** Get the name of the file to show *****/ Brw_GetFileNameToShow (FileMetadata.FilFolLnk.Type, FileMetadata.FilFolLnk.Name, FileNameToShow); /***** Write file name using path (row[1]) *****/ HTM_TD_Begin ("class=\"LT DAT_STRONG_%s %s\"", The_GetSuffix (),BgColor); /* Begin form */ Action = Brw_ActReqDatFile[Brw_FileBrowserForFoundDocs[FileMetadata.FileBrowser]]; if (CrsCod > 0) { Frm_BeginFormGoTo (Action); ParCod_PutPar (ParCod_Crs,CrsCod); // Go to course if (GrpCod > 0) ParCod_PutPar (ParCod_Grp,GrpCod); } else if (DegCod > 0) { Frm_BeginFormGoTo (Action); ParCod_PutPar (ParCod_Deg,DegCod); // Go to degree } else if (CtrCod > 0) { Frm_BeginFormGoTo (Action); ParCod_PutPar (ParCod_Ctr,CtrCod); // Go to center } else if (InsCod > 0) { Frm_BeginFormGoTo (Action); ParCod_PutPar (ParCod_Ins,InsCod); // Go to institution } else Frm_BeginForm (Action); /* Parameters to go to file / folder */ if (FileMetadata.FilFolLnk.Type == Brw_IS_FOLDER) Brw_PutImplicitParsFileBrowser (&Gbl.FileBrowser.FilFolLnk); else Brw_PutParsFileBrowser (NULL, // Not used NULL, // Not used Brw_IS_UNKNOWN, // Not used FileMetadata.FilCod); /* File or folder icon */ HTM_BUTTON_Submit_Begin (FileNameToShow,"class=\"LT BT_LINK\""); switch (FileMetadata.FilFolLnk.Type) { case Brw_IS_FILE: Brw_PutIconFile (FileMetadata.FilFolLnk.Name, "CONTEXT_ICO16x16", false); // Don't put link to view metadata break; case Brw_IS_FOLDER: Ico_PutIcon ("folder-yellow.png",Ico_UNCHANGED, Txt_Folder,"CONTEXT_ICO16x16"); break; case Brw_IS_LINK: Ico_PutIcon ("up-right-from-square.svg",Ico_BLACK, Txt_Link,"CONTEXT_ICO16x16"); break; default: break; } HTM_TxtF (" %s",FileNameToShow); HTM_BUTTON_End (); /* End form */ Frm_EndForm (); HTM_TD_End (); HTM_TR_End (); The_ChangeRowColor (); } } /*****************************************************************************/ /***************** Write a form (link) to remove old files *******************/ /*****************************************************************************/ static void Brw_PutLinkToAskRemOldFiles (void) { extern const char *Txt_Remove_old_files; Lay_PutContextualLinkIconText (ActReqRemOldBrf,NULL, Brw_PutParFullTreeIfSelected,&Gbl.FileBrowser.FullTree, "trash.svg",Ico_RED, Txt_Remove_old_files,NULL); } /*****************************************************************************/ /************** Write a form fo confirm removing of old files ****************/ /*****************************************************************************/ void Brw_AskRemoveOldFiles (void) { extern const char *Txt_Remove_old_files; extern const char *Txt_Remove_files_older_than_PART_1_OF_2; extern const char *Txt_Remove_files_older_than_PART_2_OF_2; unsigned Months; /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); /***** Begin form *****/ Frm_BeginForm (ActRemOldBrf); Brw_PutParFullTreeIfSelected (&Gbl.FileBrowser.FullTree); /***** Begin box *****/ Box_BoxBegin (NULL,Txt_Remove_old_files, NULL,NULL, NULL,Box_NOT_CLOSABLE); /***** Form to request number of months (to remove files older) *****/ HTM_LABEL_Begin ("class=\"FORM_IN_%s\"",The_GetSuffix ()); HTM_TxtF ("%s ",Txt_Remove_files_older_than_PART_1_OF_2); HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, "name=\"Months\" class=\"INPUT_%s\"", The_GetSuffix ()); for (Months = Brw_MIN_MONTHS_TO_REMOVE_OLD_FILES; Months <= Brw_MAX_MONTHS_IN_BRIEFCASE; Months++) HTM_OPTION (HTM_Type_UNSIGNED,&Months, Months == Brw_DEF_MONTHS_TO_REMOVE_OLD_FILES,false, "%u",Months); HTM_SELECT_End (); HTM_NBSP (); HTM_TxtF (Txt_Remove_files_older_than_PART_2_OF_2, Cfg_PLATFORM_SHORT_NAME); HTM_LABEL_End (); /***** Send button and end box *****/ Box_BoxWithButtonEnd (Btn_REMOVE_BUTTON,Act_GetActionText (ActRemOldBrf)); /***** End form *****/ Frm_EndForm (); /***** Show again the file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /*********************** Remove old files in briefcase ***********************/ /*****************************************************************************/ void Brw_RemoveOldFilesBriefcase (void) { extern const char *Txt_Files_removed; extern const char *Txt_Links_removed; extern const char *Txt_Folders_removed; unsigned Months; struct Brw_NumObjects Removed; /***** Get parameters related to file browser *****/ Brw_GetParAndInitFileBrowser (); if (Brw_GetIfCrsAssigWorksFileBrowser ()) { /***** Get parameter with number of months without access *****/ Months = (unsigned) Par_GetParUnsignedLong ("Months", Brw_MIN_MONTHS_TO_REMOVE_OLD_FILES, Brw_MAX_MONTHS_IN_BRIEFCASE, Brw_DEF_MONTHS_TO_REMOVE_OLD_FILES); /***** Remove old files *****/ Brw_RemoveOldFilesInBrowser (Months,&Removed); /***** Success message *****/ Ale_ShowAlert (Ale_SUCCESS,"%s: %u
" "%s: %u
" "%s: %u", Txt_Files_removed ,Removed.NumFiles, Txt_Links_removed ,Removed.NumLinks, Txt_Folders_removed,Removed.NumFolds); } /***** Show again the file browser *****/ Brw_ShowAgainFileBrowserOrWorks (); } /*****************************************************************************/ /******************************* Remove old files ****************************/ /*****************************************************************************/ static void Brw_RemoveOldFilesInBrowser (unsigned Months,struct Brw_NumObjects *Removed) { time_t TimeRemoveFilesOlder; /***** Compute time in seconds (files older than this time will be removed) *****/ TimeRemoveFilesOlder = Dat_GetStartExecutionTimeUTC () - (time_t) Months * Dat_SECONDS_IN_ONE_MONTH; /***** Remove old files recursively *****/ Removed->NumFiles = Removed->NumLinks = Removed->NumFolds = 0; Brw_ScanDirRemovingOldFiles (1,Gbl.FileBrowser.Priv.PathRootFolder, Brw_RootFolderInternalNames[Gbl.FileBrowser.Type], TimeRemoveFilesOlder,Removed); /***** Remove affected clipboards *****/ if (Removed->NumFiles || Removed->NumLinks || Removed->NumFolds) // If anything has been changed Brw_DB_RemoveAffectedClipboards (Gbl.FileBrowser.Type, Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Other.UsrDat.UsrCod); } /*****************************************************************************/ /************* Scan a directory recursively removing old files ***************/ /*****************************************************************************/ static void Brw_ScanDirRemovingOldFiles (unsigned Level, const char Path[PATH_MAX + 1], const char PathInTree[PATH_MAX + 1], time_t TimeRemoveFilesOlder, struct Brw_NumObjects *Removed) { struct dirent **FileList; int NumFile; int NumFiles; char PathFileRel[PATH_MAX + 1]; char PathFileInExplTree[PATH_MAX + 1]; struct stat FolderStatus; struct stat FileStatus; /***** Save folder status *****/ // Folder st_mtime must be saved before remove files inside it // because st_mtime is updated by the deletion if (lstat (Path,&FolderStatus)) // On success ==> 0 is returned Err_ShowErrorAndExit ("Can not get information about a file or folder."); /***** Scan directory *****/ else if ((NumFiles = scandir (Path,&FileList,NULL,alphasort)) >= 0) // No error { /***** Check file by file removing old files *****/ for (NumFile = 0; NumFile < NumFiles; NumFile++) { if (strcmp (FileList[NumFile]->d_name,".") && strcmp (FileList[NumFile]->d_name,"..")) // Skip directories "." and ".." { /***** Construct the full path of the file or folder *****/ snprintf (PathFileRel,sizeof (PathFileRel),"%s/%s", Path,FileList[NumFile]->d_name); snprintf (PathFileInExplTree,sizeof (PathFileInExplTree),"%s/%s", PathInTree,FileList[NumFile]->d_name); /***** Get file or folder status *****/ if (lstat (PathFileRel,&FileStatus)) // On success ==> 0 is returned Err_ShowErrorAndExit ("Can not get information about a file or folder."); else if (S_ISDIR (FileStatus.st_mode)) // It's a folder /* Scan subtree starting at this this directory recursively */ Brw_ScanDirRemovingOldFiles (Level + 1,PathFileRel, PathFileInExplTree, TimeRemoveFilesOlder,Removed); else if (S_ISREG (FileStatus.st_mode) && // It's a regular file FileStatus.st_mtime < TimeRemoveFilesOlder) // ..and it's old { /* Remove file/link from disk and database */ Brw_RemoveFileFromDiskAndDB (PathFileRel, PathFileInExplTree); /* Update number of files/links removed */ if (Str_FileIs (PathFileRel,"url")) (Removed->NumLinks)++; // It's a link (URL inside a .url file) else (Removed->NumFiles)++; // It's a file } } free (FileList[NumFile]); } free (FileList); if (Level > 1) // If not root folder { if (NumFiles > 2) { /***** Rescan folder in order to count the new number of files after deletion *****/ if ((NumFiles = scandir (Path,&FileList,NULL,alphasort)) >= 0) // No error { /* Free list of files */ for (NumFile = 0; NumFile < NumFiles; NumFile++) free (FileList[NumFile]); free (FileList); } else Err_ShowErrorAndExit ("Error while scanning directory."); } if (NumFiles <= 2 && // It's an empty folder FolderStatus.st_mtime < TimeRemoveFilesOlder) // ..and it was old before deletion { /* Remove folder from disk and database */ if (Brw_RemoveFolderFromDiskAndDB (Path,PathInTree)) Err_ShowErrorAndExit ("Can not remove folder."); /* Update number of files/links removed */ (Removed->NumFolds)++; } } } else Err_ShowErrorAndExit ("Error while scanning directory."); } /*****************************************************************************/ /******************* Remove file/link from disk and database *****************/ /*****************************************************************************/ static void Brw_RemoveFileFromDiskAndDB (const char Path[PATH_MAX + 1], const char FullPathInTree[PATH_MAX + 1]) { /***** Remove file from disk *****/ if (unlink (Path)) Err_ShowErrorAndExit ("Can not remove file / link."); /***** If a file is removed, it is necessary to remove it from the database *****/ Brw_RemoveOneFileOrFolderFromDB (FullPathInTree); } /*****************************************************************************/ /******************** Remove folder from disk and database *******************/ /*****************************************************************************/ // Return the returned value of rmdir static int Brw_RemoveFolderFromDiskAndDB (const char Path[PATH_MAX + 1], const char FullPathInTree[PATH_MAX + 1]) { int Result; /***** Remove folder from disk *****/ Result = rmdir (Path); // On success, zero is returned. // On error, -1 is returned, and errno is set appropriately. if (!Result) // Success { /***** If a folder is removed, it is necessary to remove it from the database *****/ Brw_RemoveOneFileOrFolderFromDB (FullPathInTree); /***** Remove affected expanded folders *****/ Brw_DB_RemoveAffectedExpandedFolders (FullPathInTree); } return Result; } /*****************************************************************************/ /*********** Get action to expand folder for current file browser ************/ /*****************************************************************************/ Act_Action_t Brw_GetActionExpand (void) { return Brw_ActExpandFolder[Gbl.FileBrowser.Type]; } /*****************************************************************************/ /********** Get action to contract folder for current file browser ***********/ /*****************************************************************************/ Act_Action_t Brw_GetActionContract (void) { return Brw_ActContractFolder[Gbl.FileBrowser.Type]; } /*****************************************************************************/ /********************* Show stats about exploration trees ********************/ /*****************************************************************************/ // TODO: add links to statistic void Brw_GetAndShowFileBrowsersStats (void) { extern const char *Hlp_ANALYTICS_Figures_folders_and_files; extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; extern const char *Txt_STAT_COURSE_FILE_ZONES[Fig_NUM_STAT_CRS_FILE_ZONES]; static const Brw_FileBrowser_t StatCrsFileZone[Fig_NUM_STAT_CRS_FILE_ZONES] = { Brw_ADMI_DOC_CRS, Brw_ADMI_DOC_GRP, Brw_ADMI_TCH_CRS, Brw_ADMI_TCH_GRP, Brw_ADMI_SHR_CRS, Brw_ADMI_SHR_GRP, Brw_ADMI_MRK_CRS, Brw_ADMI_MRK_GRP, Brw_ADMI_ASG_USR, Brw_ADMI_WRK_USR, Brw_UNKNOWN, Brw_ADMI_BRF_USR, }; struct BrwSiz_SizeOfFileZone SizeOfFileZone[Fig_NUM_STAT_CRS_FILE_ZONES]; unsigned NumStat; /***** Get sizes of all file zones *****/ for (NumStat = 0; NumStat < Fig_NUM_STAT_CRS_FILE_ZONES; NumStat++) BrwSiz_GetSizeOfFileZone (StatCrsFileZone[NumStat], &SizeOfFileZone[NumStat]); /***** Begin box *****/ Box_BoxBegin (NULL,Txt_FIGURE_TYPES[Fig_FOLDERS_AND_FILES], NULL,NULL, Hlp_ANALYTICS_Figures_folders_and_files,Box_NOT_CLOSABLE); /***** Write sizes of all file zones *****/ HTM_TABLE_BeginCenterPadding (2); Brw_WriteStatsFileZonesTableHead1 (); for (NumStat = 0; NumStat < Fig_NUM_STAT_CRS_FILE_ZONES; NumStat++) Brw_WriteRowStatsFileBrowsers1 (Txt_STAT_COURSE_FILE_ZONES[NumStat], StatCrsFileZone[NumStat], &SizeOfFileZone[NumStat]); HTM_TABLE_End (); /***** Write sizes of all file zones per course *****/ HTM_TABLE_BeginCenterPadding (2); Brw_WriteStatsFileZonesTableHead2 (); for (NumStat = 0; NumStat < Fig_NUM_STAT_CRS_FILE_ZONES; NumStat++) Brw_WriteRowStatsFileBrowsers2 (Txt_STAT_COURSE_FILE_ZONES[NumStat], StatCrsFileZone[NumStat], &SizeOfFileZone[NumStat]); HTM_TABLE_End (); /***** Write sizes of all file zones per user *****/ HTM_TABLE_BeginCenterPadding (2); Brw_WriteStatsFileZonesTableHead3 (); for (NumStat = 0; NumStat < Fig_NUM_STAT_CRS_FILE_ZONES; NumStat++) Brw_WriteRowStatsFileBrowsers3 (Txt_STAT_COURSE_FILE_ZONES[NumStat], StatCrsFileZone[NumStat], &SizeOfFileZone[NumStat]); HTM_TABLE_End (); /***** End box *****/ Box_BoxEnd (); } /*****************************************************************************/ /*************** Write table heading for stats of file zones *****************/ /*****************************************************************************/ static void Brw_WriteStatsFileZonesTableHead1 (void) { extern const char *Txt_File_zones; extern const char *Txt_Courses; extern const char *Txt_Groups; extern const char *Txt_Users; extern const char *Txt_Max_levels; extern const char *Txt_Folders; extern const char *Txt_Files; extern const char *Txt_Size; HTM_TR_Begin (NULL); HTM_TH (Txt_File_zones,HTM_HEAD_LEFT); HTM_TH (Txt_Courses ,HTM_HEAD_RIGHT); HTM_TH (Txt_Groups ,HTM_HEAD_RIGHT); HTM_TH (Txt_Users ,HTM_HEAD_RIGHT); HTM_TH (Txt_Max_levels,HTM_HEAD_RIGHT); HTM_TH (Txt_Folders ,HTM_HEAD_RIGHT); HTM_TH (Txt_Files ,HTM_HEAD_RIGHT); HTM_TH (Txt_Size ,HTM_HEAD_RIGHT); HTM_TR_End (); } static void Brw_WriteStatsFileZonesTableHead2 (void) { extern const char *Txt_File_zones; extern const char *Txt_Folders; extern const char *Txt_Files; extern const char *Txt_Size; extern const char *Txt_course; HTM_TR_Begin (NULL); HTM_TH (Txt_File_zones,HTM_HEAD_LEFT); HTM_TH_Begin (HTM_HEAD_RIGHT); HTM_TxtF ("%s/",Txt_Folders); HTM_BR (); HTM_Txt (Txt_course); HTM_TH_End (); HTM_TH_Begin (HTM_HEAD_RIGHT); HTM_TxtF ("%s/",Txt_Files); HTM_BR (); HTM_Txt (Txt_course); HTM_TH_End (); HTM_TH_Begin (HTM_HEAD_RIGHT); HTM_TxtF ("%s/",Txt_Size); HTM_BR (); HTM_Txt (Txt_course); HTM_TH_End (); HTM_TR_End (); } static void Brw_WriteStatsFileZonesTableHead3 (void) { extern const char *Txt_File_zones; extern const char *Txt_Folders; extern const char *Txt_Files; extern const char *Txt_Size; extern const char *Txt_user[Usr_NUM_SEXS]; HTM_TR_Begin (NULL); HTM_TH (Txt_File_zones,HTM_HEAD_LEFT); HTM_TH_Begin (HTM_HEAD_RIGHT); HTM_TxtF ("%s/",Txt_Folders); HTM_BR (); HTM_Txt (Txt_user[Usr_SEX_UNKNOWN]); HTM_TH_End (); HTM_TH_Begin (HTM_HEAD_RIGHT); HTM_TxtF ("%s/",Txt_Files); HTM_BR (); HTM_Txt (Txt_user[Usr_SEX_UNKNOWN]); HTM_TH_End (); HTM_TH_Begin (HTM_HEAD_RIGHT); HTM_TxtF ("%s/",Txt_Size); HTM_BR (); HTM_Txt (Txt_user[Usr_SEX_UNKNOWN]); HTM_TH_End (); HTM_TR_End (); } /*****************************************************************************/ /*************** Write a row of stats of exploration trees *******************/ /*****************************************************************************/ static void Brw_WriteRowStatsFileBrowsers1 (const char *NameOfFileZones, Brw_FileBrowser_t FileZone, struct BrwSiz_SizeOfFileZone *SizeOfFileZone) { char StrNumCrss[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; char StrNumGrps[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; char StrNumUsrs[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; char FileSizeStr[Fil_MAX_BYTES_FILE_SIZE_STRING + 1]; const char *Class = (FileZone == Brw_UNKNOWN) ? "LINE_TOP DAT_STRONG" : "DAT"; Fil_WriteFileSizeFull ((double) SizeOfFileZone->Size,FileSizeStr); if (SizeOfFileZone->NumCrss == -1) // Not applicable Str_Copy (StrNumCrss,"-",sizeof (StrNumCrss) - 1); else snprintf (StrNumCrss,sizeof (StrNumCrss),"%d", SizeOfFileZone->NumCrss); if (SizeOfFileZone->NumGrps == -1) // Not applicable Str_Copy (StrNumGrps,"-",sizeof (StrNumGrps) - 1); else snprintf (StrNumGrps,sizeof (StrNumGrps),"%d", SizeOfFileZone->NumGrps); if (SizeOfFileZone->NumUsrs == -1) // Not applicable Str_Copy (StrNumUsrs,"-",sizeof (StrNumUsrs) - 1); else snprintf (StrNumUsrs,sizeof (StrNumUsrs),"%d", SizeOfFileZone->NumUsrs); HTM_TR_Begin (NULL); HTM_TD_Begin ("class=\"LM %s_%s\"",Class,The_GetSuffix ()); HTM_Txt (NameOfFileZones); HTM_TD_End (); HTM_TD_Begin ("class=\"RM %s_%s\"",Class,The_GetSuffix ()); HTM_Txt (StrNumCrss); HTM_TD_End (); HTM_TD_Begin ("class=\"RM %s_%s\"",Class,The_GetSuffix ()); HTM_Txt (StrNumGrps); HTM_TD_End (); HTM_TD_Begin ("class=\"RM %s_%s\"",Class,The_GetSuffix ()); HTM_Txt (StrNumUsrs); HTM_TD_End (); HTM_TD_Begin ("class=\"RM %s_%s\"",Class,The_GetSuffix ()); HTM_Unsigned (SizeOfFileZone->MaxLevels); HTM_TD_End (); HTM_TD_Begin ("class=\"RM %s_%s\"",Class,The_GetSuffix ()); HTM_UnsignedLong (SizeOfFileZone->NumFolders); HTM_TD_End (); HTM_TD_Begin ("class=\"RM %s_%s\"",Class,The_GetSuffix ()); HTM_UnsignedLong (SizeOfFileZone->NumFiles); HTM_TD_End (); HTM_TD_Begin ("class=\"RM %s_%s\"",Class,The_GetSuffix ()); HTM_Txt (FileSizeStr); HTM_TD_End (); HTM_TR_End (); } static void Brw_WriteRowStatsFileBrowsers2 (const char *NameOfFileZones, Brw_FileBrowser_t FileZone, struct BrwSiz_SizeOfFileZone *SizeOfFileZone) { char StrNumFoldersPerCrs[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; char StrNumFilesPerCrs[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; char FileSizePerCrsStr[Fil_MAX_BYTES_FILE_SIZE_STRING + 1]; const char *Class = (FileZone == Brw_UNKNOWN) ? "LINE_TOP DAT_STRONG" : "DAT"; if (SizeOfFileZone->NumCrss == -1) // Not applicable { Str_Copy (StrNumFoldersPerCrs,"-",sizeof (StrNumFoldersPerCrs) - 1); Str_Copy (StrNumFilesPerCrs ,"-",sizeof (StrNumFilesPerCrs ) - 1); Str_Copy (FileSizePerCrsStr ,"-",sizeof (FileSizePerCrsStr ) - 1); } else { snprintf (StrNumFoldersPerCrs,sizeof (StrNumFoldersPerCrs),"%.1f", SizeOfFileZone->NumCrss ? (double) SizeOfFileZone->NumFolders / (double) SizeOfFileZone->NumCrss : 0.0); snprintf (StrNumFilesPerCrs,sizeof (StrNumFilesPerCrs),"%.1f", SizeOfFileZone->NumCrss ? (double) SizeOfFileZone->NumFiles / (double) SizeOfFileZone->NumCrss : 0.0); Fil_WriteFileSizeFull (SizeOfFileZone->NumCrss ? (double) SizeOfFileZone->Size / (double) SizeOfFileZone->NumCrss : 0.0, FileSizePerCrsStr); } HTM_TR_Begin (NULL); HTM_TD_Begin ("class=\"LM %s_%s\"",Class,The_GetSuffix ()); HTM_Txt (NameOfFileZones); HTM_TD_End (); HTM_TD_Begin ("class=\"RM %s_%s\"",Class,The_GetSuffix ()); HTM_Txt (StrNumFoldersPerCrs); HTM_TD_End (); HTM_TD_Begin ("class=\"RM %s_%s\"",Class,The_GetSuffix ()); HTM_Txt (StrNumFilesPerCrs); HTM_TD_End (); HTM_TD_Begin ("class=\"RM %s_%s\"",Class,The_GetSuffix ()); HTM_Txt (FileSizePerCrsStr); HTM_TD_End (); HTM_TR_End (); } static void Brw_WriteRowStatsFileBrowsers3 (const char *NameOfFileZones, Brw_FileBrowser_t FileZone, struct BrwSiz_SizeOfFileZone *SizeOfFileZone) { char StrNumFoldersPerUsr[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; char StrNumFilesPerUsr[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; char FileSizePerUsrStr[Fil_MAX_BYTES_FILE_SIZE_STRING + 1]; const char *Class = (FileZone == Brw_UNKNOWN) ? "LINE_TOP DAT_STRONG" : "DAT"; if (SizeOfFileZone->NumUsrs == -1) // Not applicable { Str_Copy (StrNumFoldersPerUsr,"-",sizeof (StrNumFoldersPerUsr) - 1); Str_Copy (StrNumFilesPerUsr ,"-",sizeof (StrNumFilesPerUsr ) - 1); Str_Copy (FileSizePerUsrStr ,"-",sizeof (FileSizePerUsrStr ) - 1); } else { snprintf (StrNumFoldersPerUsr,sizeof (StrNumFoldersPerUsr),"%.1f", SizeOfFileZone->NumUsrs ? (double) SizeOfFileZone->NumFolders / (double) SizeOfFileZone->NumUsrs : 0.0); snprintf (StrNumFilesPerUsr,sizeof (StrNumFilesPerUsr),"%.1f", SizeOfFileZone->NumUsrs ? (double) SizeOfFileZone->NumFiles / (double) SizeOfFileZone->NumUsrs : 0.0); Fil_WriteFileSizeFull (SizeOfFileZone->NumUsrs ? (double) SizeOfFileZone->Size / (double) SizeOfFileZone->NumUsrs : 0.0, FileSizePerUsrStr); } HTM_TR_Begin (NULL); HTM_TD_Begin ("class=\"LM %s_%s\"",Class,The_GetSuffix ()); HTM_Txt (NameOfFileZones); HTM_TD_End (); HTM_TD_Begin ("class=\"RM %s_%s\"",Class,The_GetSuffix ()); HTM_Txt (StrNumFoldersPerUsr); HTM_TD_End (); HTM_TD_Begin ("class=\"RM %s_%s\"",Class,The_GetSuffix ()); HTM_Txt (StrNumFilesPerUsr); HTM_TD_End (); HTM_TD_Begin ("class=\"RM %s_%s\"",Class,The_GetSuffix ()); HTM_Txt (FileSizePerUsrStr); HTM_TD_End (); HTM_TR_End (); } /*****************************************************************************/ /************ Show stats about Open Educational Resources (OERs) *************/ /*****************************************************************************/ void Brw_GetAndShowOERsStats (void) { extern const char *Hlp_ANALYTICS_Figures_open_educational_resources_oer; extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; extern const char *Txt_License; extern const char *Txt_Number_of_private_files; extern const char *Txt_Number_of_public_files; extern const char *Txt_LICENSES[Brw_NUM_LICENSES]; Brw_License_t License; unsigned long NumFiles[2]; /***** Begin box and table *****/ Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_OER], NULL,NULL, Hlp_ANALYTICS_Figures_open_educational_resources_oer,Box_NOT_CLOSABLE,2); /***** Write table heading *****/ HTM_TR_Begin (NULL); HTM_TH (Txt_License ,HTM_HEAD_LEFT); HTM_TH (Txt_Number_of_private_files,HTM_HEAD_RIGHT); HTM_TH (Txt_Number_of_public_files ,HTM_HEAD_RIGHT); HTM_TR_End (); for (License = (Brw_License_t) 0; License <= (Brw_License_t) (Brw_NUM_LICENSES - 1); License++) { Brw_GetNumberOfOERs (License,NumFiles); HTM_TR_Begin (NULL); HTM_TD_Begin ("class=\"LM DAT_%s\"",The_GetSuffix ()); HTM_Txt (Txt_LICENSES[License]); HTM_TD_End (); HTM_TD_Begin ("class=\"RM DAT_%s\"",The_GetSuffix ()); HTM_UnsignedLong (NumFiles[0]); HTM_TD_End (); HTM_TD_Begin ("class=\"RM DAT_%s\"",The_GetSuffix ()); HTM_UnsignedLong (NumFiles[1]); HTM_TD_End (); HTM_TR_End (); } /***** End table and box *****/ Box_BoxTableEnd (); } /*****************************************************************************/ /**************** Get the size of a file zone from database ******************/ /*****************************************************************************/ static void Brw_GetNumberOfOERs (Brw_License_t License, unsigned long NumFiles[2]) { MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned NumRows = 0; // Initialized to avoid warning unsigned NumRow; unsigned Public; /***** Get the size of a file browser *****/ /* Query database */ NumRows = Brw_DB_GetNumberOfPublicFiles (&mysql_res,License); /* Reset values to zero */ NumFiles[0] = NumFiles[1] = 0L; for (NumRow = 0; NumRow < NumRows; NumRow++) { /* Get row */ row = mysql_fetch_row (mysql_res); /* Get if public (row[0]) */ Public = (row[0][0] == 'Y') ? 1 : 0; /* Get number of files (row[1]) */ if (sscanf (row[1],"%lu",&NumFiles[Public]) != 1) Err_ShowErrorAndExit ("Error when getting number of files."); } /* Free structure that stores the query result */ DB_FreeMySQLResult (&mysql_res); }