|
|
|
@ -1,11 +1,16 @@
|
|
|
|
|
extends Control
|
|
|
|
|
|
|
|
|
|
const SERVER_STATUS_TEXT: Dictionary = {
|
|
|
|
|
"RUNNING": "Server is running!",
|
|
|
|
|
"NOT_RUNNING": "Server is not running."
|
|
|
|
|
true: "Server is running!",
|
|
|
|
|
false: "Server is not running.",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ACCEPTED_FILE_FORMATS := ["md"] # server should ignore these file types when adding endpoints
|
|
|
|
|
const START_BUTTON_SERVER_TEXT: Dictionary = {
|
|
|
|
|
true: "Stop server",
|
|
|
|
|
false: "Start server",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ACCEPTED_FILE_FORMATS := ["md"]
|
|
|
|
|
|
|
|
|
|
export(bool) var enable_file_autosave := true # if true, will save the active file's contents every save_file_timeout seconds.
|
|
|
|
|
export(float) var save_file_timeout := 4.0 # the time to save document content after the edited signal of TextEdit
|
|
|
|
@ -19,6 +24,7 @@ onready var server_path_label := $"%ServerPathLabel"
|
|
|
|
|
onready var port_spin_box := $"%PortSpinBox"
|
|
|
|
|
onready var start_server_button := $"%StartServerButton"
|
|
|
|
|
onready var server_status_label := $"%ServerStatusLabel"
|
|
|
|
|
onready var open_browser_button := $"%OpenBrowserButton"
|
|
|
|
|
|
|
|
|
|
onready var document_title_lineedit := $"%DocTitleLineEdit"
|
|
|
|
|
onready var document_date_lineedit := $"%DocDateLineEdit"
|
|
|
|
@ -32,12 +38,12 @@ onready var content_preview_richtextlabel := $"%ContentPreviewRichTextLabel"
|
|
|
|
|
onready var server_folder_dialog := $"%ServerFolderDialog"
|
|
|
|
|
|
|
|
|
|
signal server_folder_changed(new_path) # new_path: String
|
|
|
|
|
signal server_port_changed(new_port) # new_port: int
|
|
|
|
|
signal start_server_button_pressed(port, path) # port: int, path: String
|
|
|
|
|
signal stop_server_button_pressed() # emit from %StartServerButton, when the server is not running.
|
|
|
|
|
signal open_browser_button_pressed(port) # port: int
|
|
|
|
|
|
|
|
|
|
signal files_selection_changed(new_files) # new_files: Array<String>
|
|
|
|
|
#signal server_port_changed(new_port) # new_port: int
|
|
|
|
|
#signal open_browser_button_pressed(port) # port: int
|
|
|
|
|
#signal files_selection_changed(new_files) # new_files: Array<String>
|
|
|
|
|
|
|
|
|
|
var server_dir: String setget set_server_dir
|
|
|
|
|
var is_server_running: bool = false setget set_server_running
|
|
|
|
@ -68,9 +74,10 @@ func set_server_dir(dir: String) -> void:
|
|
|
|
|
|
|
|
|
|
var directory := Directory.new()
|
|
|
|
|
if directory.open(dir) == OK:
|
|
|
|
|
directory.list_dir_begin()
|
|
|
|
|
if directory.list_dir_begin() != OK:
|
|
|
|
|
push_error("Directory error") # TODO: show a user-facing error
|
|
|
|
|
|
|
|
|
|
var file_name: String = directory.get_next()
|
|
|
|
|
var idx: int = 0
|
|
|
|
|
while file_name != "":
|
|
|
|
|
if !directory.current_is_dir() && (file_name.get_extension() in ACCEPTED_FILE_FORMATS):
|
|
|
|
|
var fd = FileDef(file_name, false)
|
|
|
|
@ -84,16 +91,18 @@ func set_server_dir(dir: String) -> void:
|
|
|
|
|
fd.title = file_metadata["title"]
|
|
|
|
|
fd.date = file_metadata["date"]
|
|
|
|
|
|
|
|
|
|
idx += 1
|
|
|
|
|
|
|
|
|
|
file_name = directory.get_next()
|
|
|
|
|
|
|
|
|
|
directory.list_dir_end()
|
|
|
|
|
|
|
|
|
|
_reconstruct_tree_from_working_files()
|
|
|
|
|
emit_signal("server_folder_changed", server_dir)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _reconstruct_tree_from_working_files() -> void:
|
|
|
|
|
current_file = null
|
|
|
|
|
current_tree_selection = null
|
|
|
|
|
|
|
|
|
|
file_tree.clear()
|
|
|
|
|
var root: TreeItem = file_tree.create_item()
|
|
|
|
|
root.set_text(0, "Server files")
|
|
|
|
@ -128,6 +137,11 @@ func _on_FileTree_item_selected() -> void:
|
|
|
|
|
func _on_FileTree_item_rmb_selected(position: Vector2) -> void:
|
|
|
|
|
current_tree_selection = file_tree.get_selected()
|
|
|
|
|
file_tree_context_menu.rect_position = position + file_tree.rect_global_position
|
|
|
|
|
file_tree_context_menu.popup()
|
|
|
|
|
|
|
|
|
|
if is_server_running:
|
|
|
|
|
return # the file tree can't be edited while the server is running, so disable moving items as well
|
|
|
|
|
|
|
|
|
|
if (current_tree_selection.get_metadata(0)["id"] as int) == 0:
|
|
|
|
|
file_tree_context_menu.set_item_disabled(ContextMenuOptions.MOVE_UP, true)
|
|
|
|
|
else:
|
|
|
|
@ -139,29 +153,23 @@ func _on_FileTree_item_rmb_selected(position: Vector2) -> void:
|
|
|
|
|
file_tree_context_menu.set_item_disabled(ContextMenuOptions.MOVE_DOWN, false)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
file_tree_context_menu.popup()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _on_OpenServerFolderButton_pressed() -> void:
|
|
|
|
|
server_folder_dialog.popup()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func set_server_running(running: bool) -> void:
|
|
|
|
|
is_server_running = running
|
|
|
|
|
if is_server_running:
|
|
|
|
|
server_status_label.text = SERVER_STATUS_TEXT.RUNNING
|
|
|
|
|
start_server_button.text = "Stop server"
|
|
|
|
|
port_spin_box.editable = false
|
|
|
|
|
document_date_lineedit.editable = false
|
|
|
|
|
document_title_lineedit.editable = false
|
|
|
|
|
document_input_textedit.readonly = true
|
|
|
|
|
else:
|
|
|
|
|
server_status_label.text = SERVER_STATUS_TEXT.NOT_RUNNING
|
|
|
|
|
start_server_button.text = "Start server"
|
|
|
|
|
port_spin_box.editable = !false
|
|
|
|
|
document_date_lineedit.editable = !false
|
|
|
|
|
document_title_lineedit.editable = !false
|
|
|
|
|
document_input_textedit.readonly = !true
|
|
|
|
|
|
|
|
|
|
port_spin_box.editable = !running
|
|
|
|
|
document_date_lineedit.editable = !running
|
|
|
|
|
document_title_lineedit.editable = !running
|
|
|
|
|
document_input_textedit.readonly = running
|
|
|
|
|
open_browser_button.disabled = !running
|
|
|
|
|
_set_file_tree_disabled(running)
|
|
|
|
|
_set_context_menu_disabled(running)
|
|
|
|
|
|
|
|
|
|
server_status_label.text = SERVER_STATUS_TEXT[running]
|
|
|
|
|
start_server_button.text = START_BUTTON_SERVER_TEXT[running]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _generate_filestxt():
|
|
|
|
@ -170,7 +178,7 @@ func _generate_filestxt():
|
|
|
|
|
for file in working_files:
|
|
|
|
|
file = file as FileDef
|
|
|
|
|
if file.include_in_filestxt:
|
|
|
|
|
files += "%s %s %s\n" % [file.file_path, file.date, file.title]
|
|
|
|
|
files += ("%s %s %s" % [file.file_path, file.date, file.title]).strip_edges(false, true) + "\n"
|
|
|
|
|
|
|
|
|
|
var f := File.new()
|
|
|
|
|
if f.open(server_dir.plus_file("files.txt"), File.WRITE) == OK:
|
|
|
|
@ -235,6 +243,25 @@ func _get_file_content(path: String) -> String:
|
|
|
|
|
return content
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _set_file_tree_disabled(disabled: bool) -> void:
|
|
|
|
|
var root = file_tree.get_root()
|
|
|
|
|
var tree_item = root.get_children() as TreeItem
|
|
|
|
|
while tree_item != null:
|
|
|
|
|
tree_item.set_editable(0, !disabled)
|
|
|
|
|
tree_item = tree_item.get_next()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _set_context_menu_disabled(disabled: bool) -> void:
|
|
|
|
|
for i in file_tree_context_menu.get_item_count():
|
|
|
|
|
file_tree_context_menu.set_item_disabled(i, disabled)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _commit_all_files() -> void:
|
|
|
|
|
for file in working_files:
|
|
|
|
|
file = file as FileDef
|
|
|
|
|
file.commit(server_dir)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _on_FileTreeContextMenu_id_pressed(id: int) -> void:
|
|
|
|
|
var idx = current_tree_selection.get_metadata(0)["id"] as int
|
|
|
|
|
var fd = working_files[idx] as FileDef
|
|
|
|
@ -259,6 +286,17 @@ func _on_DocDateLineEdit_text_changed(new_text: String) -> void:
|
|
|
|
|
current_file.date = new_text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _on_OpenBrowserButton_pressed() -> void:
|
|
|
|
|
if OS.shell_open("http://localhost:%s" % port_spin_box.value) != OK:
|
|
|
|
|
push_error("Error opening browser!") # TODO: show a user-facing error
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _on_RefreshFilesButton_pressed() -> void:
|
|
|
|
|
_commit_all_files()
|
|
|
|
|
_generate_filestxt()
|
|
|
|
|
self.server_dir = server_dir
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _on_DocInputTextEdit_text_changed() -> void:
|
|
|
|
|
if current_file:
|
|
|
|
|
var new_text: String = document_input_textedit.text
|
|
|
|
@ -270,6 +308,7 @@ func _on_DocInputTextEdit_text_changed() -> void:
|
|
|
|
|
t.one_shot = true
|
|
|
|
|
current_file.timer = t
|
|
|
|
|
add_child(t)
|
|
|
|
|
# warning-ignore:return_value_discarded
|
|
|
|
|
t.connect("timeout", self, "_on_EditedTimeout_timeout", [t, current_file])
|
|
|
|
|
else:
|
|
|
|
|
current_file.timer.stop()
|
|
|
|
@ -280,9 +319,7 @@ func _on_EditedTimeout_timeout(timer: Timer, file: FileDef) -> void:
|
|
|
|
|
file.timer = null
|
|
|
|
|
timer.queue_free()
|
|
|
|
|
|
|
|
|
|
var f := File.new()
|
|
|
|
|
if f.open(server_dir.plus_file(file.file_path), File.WRITE) == OK:
|
|
|
|
|
f.store_string(file.content)
|
|
|
|
|
file.commit(server_dir)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func FileDef(
|
|
|
|
@ -308,3 +345,15 @@ class FileDef:
|
|
|
|
|
var content: String
|
|
|
|
|
|
|
|
|
|
var timer: Timer
|
|
|
|
|
|
|
|
|
|
func commit(server_dir: String) -> void:
|
|
|
|
|
var f := File.new()
|
|
|
|
|
var open := f.open(server_dir.plus_file(file_path), File.WRITE)
|
|
|
|
|
if open == OK:
|
|
|
|
|
f.store_string(content)
|
|
|
|
|
|
|
|
|
|
if timer && !timer.is_stopped(): # if there's an autosave pending, stop it since we're setting it here.
|
|
|
|
|
timer.stop()
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
push_error("Error committing file %s, code %s" % [file_path, open]) # TODO: show a user-facing error
|
|
|
|
|