diff --git a/code/modules/modular_computers/file_system/computer_file.dm b/code/modules/modular_computers/file_system/computer_file.dm
index 527ce2161bd..dbf457293dd 100644
--- a/code/modules/modular_computers/file_system/computer_file.dm
+++ b/code/modules/modular_computers/file_system/computer_file.dm
@@ -5,6 +5,7 @@ GLOBAL_VAR_INIT(file_uid, 0)
var/filename = "NewFile"
/// File full names are [filename].[filetype] so like NewFile.XXX in this case
var/filetype = "XXX"
+ /// Description of the file, shown in file browser.
var/filedesc = null
/// File size in GQ. Integers only!
var/size = 1
@@ -46,6 +47,8 @@ GLOBAL_VAR_INIT(file_uid, 0)
temp.filename = filename + "(Copy)"
else
temp.filename = filename
+ if(filedesc)
+ temp.filedesc = filedesc
temp.filetype = filetype
return temp
diff --git a/code/modules/modular_computers/file_system/programs/system/file_browser.dm b/code/modules/modular_computers/file_system/programs/system/file_browser.dm
index 0d993f0e4a4..5750a6c3bd9 100644
--- a/code/modules/modular_computers/file_system/programs/system/file_browser.dm
+++ b/code/modules/modular_computers/file_system/programs/system/file_browser.dm
@@ -1,4 +1,9 @@
#define MAX_TEXTFILE_LENGTH 128000 // 512GQ file
+#define FMS_FILEBROWSER 0
+#define FMS_SHOWFILE 1
+#define FMS_FORMS 2
+#define FMS_EDIT 3
+
/datum/computer_file/program/filemanager
filename = "filemanager"
filedesc = "NTOS File Manager"
@@ -11,6 +16,10 @@
available_on_ntnet = FALSE
undeletable = TRUE
tgui_id = "FileManager"
+ //Current screen of file manager.
+ var/screen = FMS_FILEBROWSER
+ //Department filter for forms browser.
+ var/sql_filter_dept = ""
var/open_file
var/open_file_is_usb = FALSE
var/error
@@ -21,61 +30,89 @@
var/obj/item/computer_hardware/hard_drive/HDD
var/obj/item/computer_hardware/hard_drive/portable/RHDD
data["error"] = error
+ data["screen"] = screen
+
+ if(!computer || !computer.hard_drive)
+ data["error"] = "I/O ERROR: Unable to access hard drive."
+ return data
+ if(screen == FMS_FILEBROWSER)
+ data["script_data"] = null
+ data["file_data"] = null
+ data["file_is_usb"] = FALSE
+ data["file_name"] = null
+ HDD = computer.hard_drive
+ RHDD = computer.portable_drive
+ var/list/files = list()
+ for(var/datum/computer_file/F in HDD.stored_files)
+ files.Add(list(list(
+ "name" = F.filename,
+ "type" = F.filetype,
+ "desc" = F.filedesc,
+ "size" = F.size,
+ "undeletable" = F.undeletable,
+ "password" = !!F.password
+ )))
+ data["files"] = files
+ if(RHDD)
+ data["usb_connected"] = TRUE
+ var/list/usb_files = list()
+ for(var/datum/computer_file/F in RHDD.stored_files)
+ usb_files.Add(list(list(
+ "name" = F.filename,
+ "type" = F.filetype,
+ "desc" = F.filedesc,
+ "size" = F.size,
+ "undeletable" = F.undeletable,
+ "password" = !!F.password
+ )))
+ data["usb_files"] = usb_files
+ else
+ data["usb_connected"] = FALSE
+ if(screen == FMS_FORMS)
+ if(!SSdbcore.Connect())
+ data["sql_error"] = 1
+ else
+ var/datum/db_query/query
+ if(sql_filter_dept)
+ query = SSdbcore.NewQuery(
+ "SELECT id, name, department FROM ss13_forms WHERE department LIKE :filter ORDER BY id",
+ list("filter" = "%[sql_filter_dept]%"))
+ else
+ query = SSdbcore.NewQuery("SELECT id, name, department FROM ss13_forms ORDER BY id")
+ if(!query.Execute())
+ data["sql_error"] = 1
+ else
+ var/list/forms = list()
+ while(query.NextRow())
+ forms += list(list("id" = query.item[1], "name" = query.item[2], "department" = query.item[3]))
+ if(!forms.len)
+ data["sql_error"] = 1
+ data["forms"] = forms
+ qdel(query)
if(open_file)
var/datum/computer_file/data/file
var/datum/computer_file/script/script
-
- if(!computer || !computer.hard_drive)
- data["error"] = "I/O ERROR: Unable to access hard drive."
- else
- HDD = open_file_is_usb ? computer.portable_drive : computer.hard_drive
- data["file_is_usb"] = open_file_is_usb
- if(!HDD)
+ HDD = open_file_is_usb ? computer.portable_drive : computer.hard_drive
+ data["file_is_usb"] = open_file_is_usb
+ if(!HDD)
+ data["error"] = "I/O ERROR: Unable to open file."
+ return data
+ file = HDD.find_file_by_name(open_file)
+ script = file
+ data["file_name"] = "[file.filename]"
+ data["file_type"] = "[file.filetype]"
+ data["file_desc"] = "[file.filedesc]"
+ if(!istype(file))
+ if(!istype(script))
data["error"] = "I/O ERROR: Unable to open file."
return data
- file = HDD.find_file_by_name(open_file)
- script = file
- if(!istype(file))
- if(!istype(script))
- data["error"] = "I/O ERROR: Unable to open file."
- else
- data["scriptdata"] = html_encode(script.code)
- data["filename"] = "[script.filename].[script.filetype]"
else
- data["filedata"] = pencode2html(file.stored_data)
- data["filename"] = "[file.filename].[file.filetype]"
- else
- if(!computer || !computer.hard_drive)
- data["error"] = "I/O ERROR: Unable to access hard drive."
+ data["script_data"] = html_encode(script.code)
+ return data
+ if(screen == FMS_EDIT)
+ data["file_data"] = file.stored_data
else
- data["scriptdata"] = null
- data["filedata"] = null
- data["file_is_usb"] = FALSE
- data["filename"] = null
- HDD = computer.hard_drive
- RHDD = computer.portable_drive
- var/list/files = list()
- for(var/datum/computer_file/F in HDD.stored_files)
- files.Add(list(list(
- "name" = F.filename,
- "type" = F.filetype,
- "size" = F.size,
- "undeletable" = F.undeletable,
- "encrypted" = !!F.password
- )))
- data["files"] = files
- if(RHDD)
- data["usbconnected"] = TRUE
- var/list/usbfiles = list()
- for(var/datum/computer_file/F in RHDD.stored_files)
- usbfiles.Add(list(list(
- "name" = F.filename,
- "type" = F.filetype,
- "size" = F.size,
- "undeletable" = F.undeletable,
- "encrypted" = !!F.password
- )))
- data["usbfiles"] = usbfiles
+ data["file_data"] = pencode2html(file.stored_data)
return data
/datum/computer_file/program/filemanager/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
@@ -83,68 +120,87 @@
return
switch(action)
- if("PRG_openfile")
+ if("set_screen")
+ . = TRUE
+ var/new_screen = text2num(params["screen"])
+ if(new_screen == FMS_EDIT)
+ if(!open_file)
+ return TRUE
+ var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
+ if(!HDD)
+ return TRUE
+ var/datum/computer_file/data/F = HDD.find_file_by_name(open_file)
+ if(!F || !istype(F))
+ return TRUE
+ if(F.do_not_edit && (alert("WARNING: This file is not compatible with editor. Editing it may result in permanently corrupted formatting or damaged data consistency. Edit anyway?", "Incompatible File", "No", "Yes") == "No"))
+ return TRUE
+ screen = new_screen
+
+ if("PRG_open_file")
. = TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
- var/datum/computer_file/F = HDD.find_file_by_name(params["PRG_openfile"])
+ var/datum/computer_file/F = HDD.find_file_by_name(params["PRG_open_file"])
if(!F)
return
if(F.can_access_file(usr))
- open_file = params["PRG_openfile"]
+ open_file = params["PRG_open_file"]
open_file_is_usb = FALSE
+ screen = FMS_SHOWFILE
- if("PRG_usbopenfile")
+ if("PRG_usb_open_file")
. = TRUE
var/obj/item/computer_hardware/hard_drive/RHDD = computer.portable_drive
if(!RHDD)
return
- var/datum/computer_file/F = RHDD.find_file_by_name(params["PRG_usbopenfile"])
+ var/datum/computer_file/F = RHDD.find_file_by_name(params["PRG_usb_open_file"])
if(!F)
return
if(F.can_access_file(usr))
- open_file = params["PRG_usbopenfile"]
+ open_file = params["PRG_usb_open_file"]
open_file_is_usb = TRUE
+ screen = FMS_SHOWFILE
- if("PRG_newtextfile")
+ if("PRG_new_text_file")
. = TRUE
- var/newname = sanitize_filename(tgui_input_text(usr, "Enter file name or leave blank to cancel:", "File rename"))
- if(!newname)
- return TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return TRUE
var/datum/computer_file/data/F = new/datum/computer_file/data()
- F.filename = newname
+ F.filename = "NewFile"
F.filetype = "TXT"
+ F.stored_data = ""
if(!HDD.store_file(F))
qdel(F)
error = "I/O ERROR: Unable to create file. The hard drive may be full, read-only, or contain a conflicting file."
+ open_file = F.filename
+ screen = FMS_EDIT
- if("PRG_deletefile")
+ if("PRG_delete_file")
. = TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return TRUE
- var/datum/computer_file/file = HDD.find_file_by_name(params["PRG_deletefile"])
+ var/datum/computer_file/file = HDD.find_file_by_name(params["PRG_delete_file"])
if(!file || file.undeletable)
return TRUE
HDD.remove_file(file)
- if("PRG_usbdeletefile")
+ if("PRG_usb_delete_file")
. = TRUE
var/obj/item/computer_hardware/hard_drive/RHDD = computer.portable_drive
if(!RHDD)
return TRUE
- var/datum/computer_file/file = RHDD.find_file_by_name(params["PRG_usbdeletefile"])
+ var/datum/computer_file/file = RHDD.find_file_by_name(params["PRG_usb_delete_file"])
if(!file || file.undeletable)
return TRUE
RHDD.remove_file(file)
- if("PRG_closefile")
+ if("PRG_close_file")
. = TRUE
open_file = null
open_file_is_usb = FALSE
error = null
+ screen = FMS_FILEBROWSER
if("PRG_clone")
. = TRUE
@@ -162,42 +218,29 @@
qdel(C)
error = "I/O ERROR: Unable to clone file. The hard drive may be full, read-only, or contain a conflicting file."
- if("PRG_rename")
- . = TRUE
- var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
- if(!HDD)
- return TRUE
- var/datum/computer_file/file = HDD.find_file_by_name(params["PRG_rename"])
- if(!file || !istype(file))
- return TRUE
- var/newname = sanitize_filename(tgui_input_text(usr, "Enter new file name or leave blank to cancel:", "File rename", file.filename))
- if(file && newname)
- file.filename = newname
-
if("PRG_edit")
. = TRUE
- if(!open_file)
- return TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return TRUE
var/datum/computer_file/data/F = HDD.find_file_by_name(open_file)
if(!F || !istype(F))
return TRUE
- if(F.do_not_edit && (alert("WARNING: This file is not compatible with editor. Editing it may result in permanently corrupted formatting or damaged data consistency. Edit anyway?", "Incompatible File", "No", "Yes") == "No"))
- return TRUE
- var/oldtext = html_decode(F.stored_data)
- oldtext = replacetext(oldtext, "\[editorbr\]", "\n")
-
- var/newtext = sanitize_filename(replacetext(tgui_input_text(usr, "Editing file [open_file]. You may use most tags used in paper formatting:", "Text Editor", oldtext), "\n", "\[editorbr\]"), MAX_TEXTFILE_LENGTH)
- if(!newtext)
+ if(params["PRG_rename"])
+ var/newname = sanitize_filename(params["PRG_rename"])
+ F.filename = newname
+ open_file = newname
return
- if(F)
+ if(params["PRG_desc"])
+ F.filedesc = params["PRG_desc"]
+ return
+
+ if(params["PRG_edit"])
var/datum/computer_file/data/backup = F.clone()
HDD.remove_file(F)
- F.stored_data = newtext
+ F.stored_data = params["PRG_edit"]
F.calculate_size()
// We can't store the updated file, it's probably too large. Print an error and restore backed up version.
// This is mostly intended to prevent people from losing texts they spent lot of time working on due to running out of space.
@@ -206,7 +249,7 @@
error = "I/O error: Unable to overwrite file. Hard drive is probably full. You may want to backup your changes before closing this window:
[html_decode(F.stored_data)]
"
HDD.store_file(backup)
- if("PRG_printfile")
+ if("PRG_print_file")
. = TRUE
if(!open_file)
return TRUE
@@ -221,29 +264,26 @@
if(!F)
return TRUE
if(istype(F))
- if(!computer.nano_printer.print_text(F.stored_data))
+ if(!computer.nano_printer.print_text(F.stored_data, F.filename))
error = "Hardware error: Printer was unable to print the file. It may be out of paper."
return FALSE
else if(istype(S))
- if(!computer.nano_printer.print_text(S.code))
+ if(!computer.nano_printer.print_text(S.code, S.filename))
error = "Hardware error: Printer was unable to print the file. It may be out of paper."
return FALSE
- if("PRG_copytousb")
+ if("PRG_copy_to_usb")
. = TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
var/obj/item/computer_hardware/hard_drive/portable/RHDD = computer.portable_drive
if(!HDD || !RHDD)
return FALSE
- var/datum/computer_file/F = HDD.find_file_by_name(params["PRG_copytousb"])
+ var/datum/computer_file/F = HDD.find_file_by_name(params["PRG_copy_to_usb"])
if(!F || !istype(F))
return FALSE
var/is_usr_tech_support = FALSE
- if(ishuman(usr))
- var/mob/living/carbon/human/H = usr
- var/obj/item/card/id/ID = H.GetIdCard()
- if(ACCESS_IT in ID.access)
- is_usr_tech_support = TRUE
+ if(can_run(usr,FALSE,ACCESS_IT))
+ is_usr_tech_support = TRUE
if(!is_usr_tech_support && computer.enrolled != DEVICE_PRIVATE && istype(F, /datum/computer_file/program))
to_chat(usr, SPAN_WARNING("Work devices can't export programs to portable drives! Contact Tech Support to get them to load it."))
return TRUE
@@ -258,21 +298,18 @@
return
RHDD.store_file(C)
- if("PRG_copyfromusb")
+ if("PRG_copy_from_usb")
. = TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
var/obj/item/computer_hardware/hard_drive/portable/RHDD = computer.portable_drive
if(!HDD || !RHDD)
return TRUE
- var/datum/computer_file/F = RHDD.find_file_by_name(params["PRG_copyfromusb"])
+ var/datum/computer_file/F = RHDD.find_file_by_name(params["PRG_copy_from_usb"])
if(!F || !istype(F))
return TRUE
var/is_usr_tech_support = FALSE
- if(ishuman(usr))
- var/mob/living/carbon/human/H = usr
- var/obj/item/card/id/ID = H.GetIdCard()
- if(ACCESS_IT in ID.access)
- is_usr_tech_support = TRUE
+ if(can_run(usr,FALSE,ACCESS_IT))
+ is_usr_tech_support = TRUE
if(!is_usr_tech_support && computer.enrolled != DEVICE_PRIVATE && istype(F, /datum/computer_file/program))
to_chat(usr, SPAN_WARNING("Work devices can't import programs from portable drives! Contact Tech Support to get them to load it."))
return TRUE
@@ -292,22 +329,72 @@
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
if (!HDD)
return
- var/datum/computer_file/F = HDD.find_file_by_name(params["PRG_encrypt"])
+ var/datum/computer_file/F = HDD.find_file_by_name(params["PRG_file_to_encrypt"])
if(!F || F.undeletable)
return
- if(F.password)
- return
- F.password = sanitize_filename(tgui_input_text(usr, "Enter an encryption key:", "Encrypt File"))
-
- if("PRG_decrypt")
- . = TRUE
- var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
- if (!HDD)
- return
- var/datum/computer_file/F = HDD.find_file_by_name(params["PRG_encrypt"])
- if(!F || F.undeletable)
- return
- if (F.can_access_file(usr))
+ if(F.password && F.password == params["PRG_encrypt"])
F.password = ""
+ return
+ F.password = params["PRG_encrypt"]
+
+ if("PRG_sort_forms")
+ sql_filter_dept = sanitize(params["department"])
+ return TRUE
+
+ if("PRG_reset_sql")
+ sql_filter_dept = ""
+ return TRUE
+
+ if("PRG_generate_form")
+ var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
+ var/printid = text2num(params["id"])
+ if(!printid)
+ return TRUE
+ if(!SSdbcore.Connect())
+ to_chat(usr, SPAN_WARNING("Connection to the database lost. Aborting."))
+ return TRUE
+ var/datum/db_query/query = SSdbcore.NewQuery(
+ "SELECT id, name, data FROM ss13_forms WHERE id = :id",
+ list("id" = printid))
+ if(!query.Execute())
+ to_chat(usr, SPAN_WARNING("Connection to the database lost. Aborting."))
+ qdel(query)
+ return TRUE
+ while(query.NextRow())
+ var/datum/computer_file/data/F = new/datum/computer_file/data()
+ F.filename = "SCCF-[query.item[1]]-[query.item[2]]"
+ F.filetype = "TXT"
+ F.stored_data = query.item[3]
+ if(!HDD.store_file(F))
+ qdel(F)
+ error = "I/O ERROR: Unable to create file. The hard drive may be full, read-only, or contain a conflicting file."
+ qdel(query)
+ screen = FMS_FILEBROWSER
+ return TRUE
+
+ if("PRG_whatis")
+ var/whatisid = text2num(params["id"])
+ if(!whatisid)
+ return TRUE
+ if(!SSdbcore.Connect())
+ to_chat(usr, SPAN_WARNING("Connection to the database lost. Aborting."))
+ return TRUE
+ var/datum/db_query/query = SSdbcore.NewQuery(
+ "SELECT id, name, department, info FROM ss13_forms WHERE id = :id",
+ list("id" = whatisid))
+ if(!query.Execute())
+ to_chat(usr, SPAN_WARNING("Connection to the database lost. Aborting."))
+ qdel(query)
+ return TRUE
+ var/dat = "