From d4309adfad7b128b33ddb9c3d012b4beeac41f36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Santilio?= Date: Mon, 12 Oct 2020 18:14:08 +0200 Subject: [PATCH] Add scripts for custom font feature --- scripts/CsvEditor.gd | 217 +++++++++++++ scripts/FileEditor.gd | 604 ++++++++++++++++++++++++++++++++++++ scripts/FileEditorButton.gd | 19 ++ scripts/FileScene.gd | 198 ++++++++++++ scripts/IconLoader.gd | 20 ++ scripts/IniVisualEditor.gd | 284 +++++++++++++++++ scripts/LastOpenedFiles.gd | 42 +++ scripts/Preview.gd | 160 ++++++++++ scripts/VanillaEditor.gd | 220 +++++++++++++ scripts/file-editor.gd | 33 ++ 10 files changed, 1797 insertions(+) create mode 100644 scripts/CsvEditor.gd create mode 100644 scripts/FileEditor.gd create mode 100644 scripts/FileEditorButton.gd create mode 100644 scripts/FileScene.gd create mode 100644 scripts/IconLoader.gd create mode 100644 scripts/IniVisualEditor.gd create mode 100644 scripts/LastOpenedFiles.gd create mode 100644 scripts/Preview.gd create mode 100644 scripts/VanillaEditor.gd create mode 100644 scripts/file-editor.gd diff --git a/scripts/CsvEditor.gd b/scripts/CsvEditor.gd new file mode 100644 index 0000000..6530df5 --- /dev/null +++ b/scripts/CsvEditor.gd @@ -0,0 +1,217 @@ +tool +extends Control + +var IconLoader = preload("res://addons/file-editor/scripts/IconLoader.gd").new() +var LastOpenedFiles = preload("res://addons/file-editor/scripts/LastOpenedFiles.gd").new() + +onready var Table = $Editor/TableContainer/ScrollContainer/Table +onready var AlignBTN = $Editor/Buttons/align_bt.get_popup() +onready var EditBTN = $Editor/Buttons/edit_bt.get_popup() +onready var OptionsBTN = $Editor/Buttons/options_btn.get_popup() +onready var FileInfo = $Editor/FileInfo +onready var ReadOnly = $Editor/FileInfo/Readonly + +onready var Horizontal = $Editor/Horizontal +onready var Vertical = $Editor/TableContainer/Vertical + +onready var ChangeDelimiterDialog = $ChangeDelimiterDialog + +var current_file_path : String = "" + +var rows : int +var columns : int +var csv_delimiter : String +var filepath : String + +signal update_file() + +func _ready(): + add_to_group("csv_editor") + connect_signals() + + load_icons() + +func connect_signals(): + AlignBTN.connect("id_pressed",self,"on_align_pressed") + EditBTN.connect("id_pressed",self,"on_edit_pressed") + OptionsBTN.connect("id_pressed",self,"on_options_pressed") + ReadOnly.connect("toggled",self,"_on_Readonly_toggled") + ChangeDelimiterDialog.connect("confirmed",self,"on_changedelimiter_confirmed") + + connect("visibility_changed",self,"_on_visibility_changed") + +func load_icons(): + $Editor/Buttons/align_bt.set_button_icon(IconLoader.load_icon_from_name("align")) + $Editor/Buttons/edit_bt.set_button_icon(IconLoader.load_icon_from_name("edit_")) + + AlignBTN.set_item_icon(0,IconLoader.load_icon_from_name("text-left")) + AlignBTN.set_item_icon(1,IconLoader.load_icon_from_name("text-center")) + AlignBTN.set_item_icon(2,IconLoader.load_icon_from_name("text-right")) + AlignBTN.set_item_icon(3,IconLoader.load_icon_from_name("text-fill")) + + EditBTN.set_item_icon(0,IconLoader.load_icon_from_name("row")) + EditBTN.set_item_icon(1,IconLoader.load_icon_from_name("column")) + EditBTN.set_item_icon(3,IconLoader.load_icon_from_name("save")) + + ReadOnly.set("custom_icons/checked",IconLoader.load_icon_from_name("read")) + ReadOnly.set("custom_icons/unchecked",IconLoader.load_icon_from_name("edit")) + +func open_csv_file(filepath : String, csv_delimiter : String) -> void: + self.filepath = filepath + var csv = File.new() + csv.open(filepath,File.READ) + var rows : Array = [] + var columns = -1 + while not csv.eof_reached(): + var csv_line = csv.get_csv_line(csv_delimiter) + if Array(csv_line) != [""]: + rows.append(csv_line) + if columns == -1: + columns = rows[0].size() + csv.close() + self.csv_delimiter = csv_delimiter + load_file_in_table(rows,columns) + ReadOnly.pressed = (true) + $Editor/FileInfo/delimiter.set_text(csv_delimiter) + ChangeDelimiterDialog.get_node("VBoxContainer/delim_read").set_text(csv_delimiter) + +func load_file_in_table(rows : Array, columns : int) -> void: + Table.set_columns(columns) + for row in rows: + add_row(row.size(),"",row) + update_dimensions(rows.size()-1,columns) + +func add_row(columns : int, cell_text : String = "", cell2text : PoolStringArray = []): + for i in range(0,columns): + if cell2text.size()<1: + var cell = LineEdit.new() + cell.set_h_size_flags(2) + cell.set_h_size_flags(3) + cell.set_text(cell_text) + Table.add_child(cell) + if ReadOnly.pressed: + cell.set_editable(false) + + else: +# if cell2text[i]!="": + var cell = LineEdit.new() + cell.set_h_size_flags(2) + cell.set_h_size_flags(3) + Table.add_child(cell) + if cell2text: + cell.set_text(cell2text[i]) + else: + cell.set_text(cell_text) + if ReadOnly.pressed: + cell.set_editable(false) + +func add_column(rows : int ,cell_text : String = ""): + for i in range(0,rows): + var cell = LineEdit.new() + cell.set_h_size_flags(2) + cell.set_h_size_flags(3) + Table.add_child(cell) + Table.move_child(cell,(columns)*(i+1)-1) + cell.set_text(cell_text) + if ReadOnly.pressed: + cell.set_editable(false) + +func on_align_pressed(index : int) -> void: + for cell in Table.get_children(): + cell.set_align(index) + +func on_edit_pressed(index :int) -> void: + match index: + 0: + update_dimensions(rows+1,columns) + add_row(columns) + 1: + update_dimensions(rows,columns+1) + add_column(rows) + 3: + save_table() + +func on_options_pressed(index : int) -> void: + match index: + 0: + ChangeDelimiterDialog.popup() + +func table_ruler(rows : int, columns : int): + for child in Vertical.get_children(): + child.queue_free() + for child in Horizontal.get_children(): + child.queue_free() + for i in range(0,rows): + var lb = Label.new() + lb.set_h_size_flags(2) + lb.set_h_size_flags(3) + lb.set_text(str(i+1)) + Vertical.add_child(lb) + var lb = Label.new() + lb.set_text(" ") + Horizontal.add_child(lb) + for j in range(0,columns): + var lb2 = Label.new() + lb2.set_h_size_flags(2) + lb2.set_h_size_flags(3) + lb2.set_align(1) + lb2.set_text(str(j+1)) + Horizontal.add_child(lb2) + +func update_dimensions(rows : int, columns : int): + self.rows = rows + self.columns = columns + table_ruler(rows,columns) + Table.set_columns(columns) + FileInfo.get_node("rows").set_text(str(rows)) + FileInfo.get_node("columns").set_text(str(columns)) + +func _on_Readonly_toggled(button_pressed): + if button_pressed: + ReadOnly.set_text("Read Only") + for cell in Table.get_children(): + cell.set_editable(false) + else: + ReadOnly.set_text("Can Edit") + for cell in Table.get_children(): + cell.set_editable(true) + +func save_table(): + var content : Array = [] + var column = 0 + var row_ : PoolStringArray = [] + for cell in Table.get_children(): + if column < columns: + row_.append(cell.get_text()) + column+=1 + else: + content.append(row_) + row_ = [] + row_.append(cell.get_text()) + column = 1 + content.append(row_) + + var file = File.new() + file.open(filepath, File.WRITE) + for line in content: + file.store_csv_line(line,csv_delimiter) + file.close() + + emit_signal("update_file") + +func on_changedelimiter_confirmed(): + change_delimiter(ChangeDelimiterDialog.get_node("VBoxContainer/delim_read").get_text()) + +func change_delimiter(delim : String): + csv_delimiter = delim + reload() + +func reload(): + for element in Table.get_children(): + element.queue_free() + open_csv_file(current_file_path,csv_delimiter) + FileInfo.show() + +func _on_visibility_changed(): + if visible: + reload() diff --git a/scripts/FileEditor.gd b/scripts/FileEditor.gd new file mode 100644 index 0000000..fede799 --- /dev/null +++ b/scripts/FileEditor.gd @@ -0,0 +1,604 @@ +tool +extends Control + +onready var FileList = $FileList + +onready var NewFileDialogue = $NewFileDialogue +onready var NewFileDialogue_name = $NewFileDialogue/VBoxContainer/new_filename + +onready var FileBTN = $FileEditorContainer/TobBar/file_btn.get_popup() +onready var PreviewBTN = $FileEditorContainer/TobBar/preview_btn.get_popup() +onready var EditorBTN = $FileEditorContainer/TobBar/editor_btn.get_popup() +onready var SettingsBTN : PopupMenu = $FileEditorContainer/TobBar/SettingsBtn.get_popup() + +onready var Version = $FileEditorContainer/TobBar/version + +onready var SelectFontDialog : FileDialog = $SelectFontDialog + +onready var FileContainer = $FileEditorContainer/SplitContainer/FileContainer +onready var OpenFileList = $FileEditorContainer/SplitContainer/FileContainer/OpenFileList +onready var OpenFileName = $FileEditorContainer/SplitContainer/EditorContainer/HBoxContainer/OpenFileName +onready var SplitEditorContainer = $FileEditorContainer/SplitContainer/EditorContainer +onready var WrapBTN = $FileEditorContainer/SplitContainer/EditorContainer/HBoxContainer/wrap_button +onready var MapBTN = $FileEditorContainer/SplitContainer/EditorContainer/HBoxContainer/map_button + +var IconLoader = preload("res://addons/file-editor/scripts/IconLoader.gd").new() +var LastOpenedFiles = preload("res://addons/file-editor/scripts/LastOpenedFiles.gd").new() + +var Preview = preload("res://addons/file-editor/scenes/Preview.tscn") +var IniEditor = preload("res://addons/file-editor/scenes/IniEditor.tscn") +var VanillaEditor = preload("res://addons/file-editor/scenes/VanillaEditor.tscn") +var CsvEditor = preload("res://addons/file-editor/scenes/CsvEditor.tscn") + +onready var EditorContainer = $FileEditorContainer/SplitContainer + +var DIRECTORY : String = "res://" +var EXCEPTIONS : String = "addons" +var EXTENSIONS : PoolStringArray = [ +"*.txt ; Plain Text File", +"*.rtf ; Rich Text Format File", +"*.log ; Log File", +"*.md ; MD File", +"*.doc ; WordPad Document", +"*.doc ; Microsoft Word Document", +"*.docm ; Word Open XML Macro-Enabled Document", +"*.docx ; Microsoft Word Open XML Document", +"*.bbs ; Bulletin Board System Text", +"*.dat ; Data File", +"*.xml ; XML File", +"*.sql ; SQL database file", +"*.json ; JavaScript Object Notation File", +"*.html ; HyperText Markup Language", +"*.csv ; Comma-separated values", +"*.cfg ; Configuration File", +"*.ini ; Initialization File (same as .cfg Configuration File)", +"*.csv ; Comma-separated values File", +"*.res ; Resource File", +] + +var directories = [] +var files = [] +var current_file_index = -1 +var current_file_path = "" +var save_as = false +var current_editor : Control +var current_ini_editor : Control +var current_csv_editor : Control +var current_font : DynamicFont + + +func _ready(): + + clean_editor() + update_version() + connect_signals() + create_shortcuts() + load_icons() + + var opened_files : Array = LastOpenedFiles.load_opened_files() + for opened_file in opened_files: + open_file(opened_file[1], opened_file[2]) + + FileList.set_filters(EXTENSIONS) + +func create_shortcuts(): + var hotkey + + hotkey = InputEventKey.new() + hotkey.scancode = KEY_S + hotkey.control = true + FileBTN.set_item_accelerator(4,hotkey.get_scancode_with_modifiers()) # save file + + hotkey = InputEventKey.new() + hotkey.scancode = KEY_N + hotkey.control = true + FileBTN.set_item_accelerator(0,hotkey.get_scancode_with_modifiers()) # new file + + hotkey = InputEventKey.new() + hotkey.scancode = KEY_O + hotkey.control = true + FileBTN.set_item_accelerator(1,hotkey.get_scancode_with_modifiers()) # open file + + hotkey = InputEventKey.new() + hotkey.scancode = KEY_D + hotkey.control = true + FileBTN.set_item_accelerator(6,hotkey.get_scancode_with_modifiers()) # delete file + + hotkey = InputEventKey.new() + hotkey.scancode = KEY_S + hotkey.control = true + hotkey.alt = true + FileBTN.set_item_accelerator(5,hotkey.get_scancode_with_modifiers()) #save file as + + hotkey = InputEventKey.new() + hotkey.scancode = KEY_C + hotkey.control = true + hotkey.alt = true + FileBTN.set_item_accelerator(2,hotkey.get_scancode_with_modifiers()) # close file + + hotkey = InputEventKey.new() + hotkey.scancode = KEY_F + hotkey.control = true + FileBTN.set_item_accelerator(8,hotkey.get_scancode_with_modifiers()) # search + + hotkey = InputEventKey.new() + hotkey.scancode = KEY_R + hotkey.control = true + FileBTN.set_item_accelerator(9,hotkey.get_scancode_with_modifiers()) # replace + + # vanilla editor ----------------------- + + hotkey = InputEventKey.new() + hotkey.scancode = KEY_1 + hotkey.control = true + EditorBTN.set_item_accelerator(0,hotkey.get_scancode_with_modifiers()) # vanilla editor + + hotkey = InputEventKey.new() + hotkey.scancode = KEY_2 + hotkey.control = true + EditorBTN.set_item_accelerator(1,hotkey.get_scancode_with_modifiers()) # csv editor + + hotkey = InputEventKey.new() + hotkey.scancode = KEY_3 + hotkey.control = true + EditorBTN.set_item_accelerator(2,hotkey.get_scancode_with_modifiers()) # inieditor editor + +func load_icons(): + $FileEditorContainer/TobBar/file_btn.icon = IconLoader.load_icon_from_name("file") + $FileEditorContainer/TobBar/preview_btn.icon = IconLoader.load_icon_from_name("read") + $FileEditorContainer/TobBar/editor_btn.icon = IconLoader.load_icon_from_name("edit_") + $FileEditorContainer/TobBar/SettingsBtn.icon = IconLoader.load_icon_from_name("settings") + +func connect_signals(): + FileList.connect("confirmed",self,"update_list") + FileBTN.connect("id_pressed",self,"_on_filebtn_pressed") + PreviewBTN.connect("id_pressed",self,"_on_previewbtn_pressed") + EditorBTN.connect("id_pressed",self,"_on_editorbtn_pressed") + SettingsBTN.connect("id_pressed",self,"_on_settingsbtn_pressed") + + OpenFileList.connect("item_selected",self,"_on_fileitem_pressed") + WrapBTN.connect("item_selected",self,"on_wrap_button") + MapBTN.connect("item_selected",self,"on_minimap_button") + + SelectFontDialog.connect("file_selected",self,"_on_font_selected") + +func update_version(): + var plugin_version = "" + var config = ConfigFile.new() + var err = config.load("res://addons/file-editor/plugin.cfg") + if err == OK: + plugin_version = config.get_value("plugin","version") + Version.set_text("v"+plugin_version) + print(plugin_version) + +func create_selected_file(): + update_list() + FileList.mode = FileDialog.MODE_SAVE_FILE + FileList.set_title("Create a new File") + if FileList.is_connected("file_selected",self,"delete_file"): + FileList.disconnect("file_selected",self,"delete_file") + if FileList.is_connected("file_selected",self,"open_file"): + FileList.disconnect("file_selected",self,"open_file") + if not FileList.is_connected("file_selected",self,"create_new_file"): + FileList.connect("file_selected",self,"create_new_file") + open_filelist() + +func open_selected_file(): + update_list() + FileList.mode = FileDialog.MODE_OPEN_FILE + FileList.set_title("Select a File you want to edit") + if FileList.is_connected("file_selected",self,"delete_file"): + FileList.disconnect("file_selected",self,"delete_file") + if FileList.is_connected("file_selected",self,"create_new_file"): + FileList.disconnect("file_selected",self,"create_new_file") + if not FileList.is_connected("file_selected",self,"open_file"): + FileList.connect("file_selected",self,"open_file") + open_filelist() + +func delete_selected_file(): + update_list() + FileList.mode = FileDialog.MODE_OPEN_FILES + FileList.set_title("Select one or more Files you want to delete") + if FileList.is_connected("file_selected",self,"open_file"): + FileList.disconnect("file_selected",self,"open_file") + if FileList.is_connected("file_selected",self,"create_new_file"): + FileList.disconnect("file_selected",self,"create_new_file") + if not FileList.is_connected("files_selected",self,"delete_file"): + FileList.connect("files_selected",self,"delete_file") + open_filelist() + +func save_current_file_as(): + update_list() + FileList.mode = FileDialog.MODE_SAVE_FILE + FileList.set_title("Save this File as...") + if FileList.is_connected("file_selected",self,"delete_file"): + FileList.disconnect("file_selected",self,"delete_file") + if FileList.is_connected("file_selected",self,"open_file"): + FileList.disconnect("file_selected",self,"open_file") + if not FileList.is_connected("file_selected",self,"create_new_file"): + FileList.connect("file_selected",self,"create_new_file") + open_filelist() + +func _on_filebtn_pressed(index : int): + match index: + 0: + create_selected_file() + 1: + open_selected_file() + 2: + if current_file_index!=-1 and current_file_path != "": + close_file(current_file_index) + + 3: + if current_file_index!=-1 and current_file_path != "": + save_as = false + if current_csv_editor and current_csv_editor.visible: + current_csv_editor.save_table() + save_file(current_file_path) + 4: + if current_file_index!=-1 and current_file_path != "": + save_as = true + save_file(current_file_path) + save_current_file_as() + 5: + delete_selected_file() + 6: + current_editor.open_searchbox() + 7: + current_editor.open_replacebox() + +func _on_previewbtn_pressed(id : int): + if id == 0: + bbcode_preview() + elif id == 1: + markdown_preview() + elif id == 2: + html_preview() + elif id == 3: + csv_preview() + elif id == 4: + xml_preview() + elif id == 5: + json_preview() + +func _on_editorbtn_pressed(index : int): + match index: + 0: + if not current_editor.visible: + current_editor.show() + if current_csv_editor: + current_csv_editor.hide() + if current_ini_editor: + current_ini_editor.hide() + 1: + if current_csv_editor and not current_csv_editor.visible: + if current_ini_editor: + current_ini_editor.hide() + current_editor.hide() + current_csv_editor = open_in_csveditor(current_file_path) + current_csv_editor.show() + 2: + if current_ini_editor and not current_ini_editor.visible: + current_editor.hide() + if current_csv_editor: + current_csv_editor.hide() + current_ini_editor = open_in_inieditor(current_file_path) + current_ini_editor.show() + +func _on_settingsbtn_pressed(index : int): + match index: + 0: + SelectFontDialog.popup() + +func _on_font_selected(font_path : String): + current_editor.set_font(font_path) + LastOpenedFiles.store_editor_fonts(current_file_path.get_file(), font_path) +# Enable this part of code to apply the new font to all Vanilla Editors opened +# for file in [0,OpenFileList.get_child_count()]: +# OpenFileList.get_item_metadata(file)[0].set_font(dynamic_font) +# current_font = dynamic_font + +func _on_fileitem_pressed(index : int): + current_file_index = index + var selected_item_metadata = OpenFileList.get_item_metadata(current_file_index) + var extension = selected_item_metadata[0].current_path.get_file().get_extension() + + current_file_path = selected_item_metadata[0].current_path + if current_editor.visible: + current_editor.hide() + current_editor = selected_item_metadata[0] + current_editor.show() + OpenFileName.set_text(current_editor.current_path) + current_csv_editor = selected_item_metadata[2] + current_ini_editor = selected_item_metadata[1] + if WrapBTN.get_selected_id() == 1: + current_editor.set_wrap_enabled(true) + else: + current_editor.set_wrap_enabled(false) + if MapBTN.get_selected_id() == 1: + current_editor.draw_minimap(true) + else: + current_editor.draw_minimap(false) + elif current_csv_editor and current_csv_editor.visible: + if extension == "csv": + current_csv_editor.hide() + current_csv_editor = selected_item_metadata[2] + current_csv_editor.show() + OpenFileName.set_text(current_csv_editor.current_file_path) + current_editor = selected_item_metadata[0] + current_ini_editor = selected_item_metadata[1] + else: + if current_csv_editor: + current_csv_editor.hide() + current_csv_editor = selected_item_metadata[2] + if current_ini_editor: + current_ini_editor.hide() + current_ini_editor = selected_item_metadata[1] + current_editor.hide() + current_editor = selected_item_metadata[0] + current_editor.show() + OpenFileName.set_text(current_editor.current_path) + elif current_ini_editor and current_ini_editor.visible: + if extension == "cfg" or extension == "ini": + current_ini_editor.hide() + current_ini_editor = selected_item_metadata[1] + current_ini_editor.show() + OpenFileName.set_text(current_ini_editor.current_file_path) + else: + if current_ini_editor: + current_ini_editor.hide() + current_ini_editor = selected_item_metadata[1] + if current_csv_editor: + current_csv_editor.hide() + current_csv_editor = selected_item_metadata[2] + current_editor.hide() + current_editor = selected_item_metadata[0] + current_editor.show() + OpenFileName.set_text(current_editor.current_path) + +func open_file(path : String, font : String = "null"): + if current_file_path != path: + current_file_path = path + + var vanilla_editor = open_in_vanillaeditor(path) + if font != "null": + vanilla_editor.set_font(font) + var ini_editor = open_in_inieditor(path) + var csv_editor = open_in_csveditor(path) + + generate_file_item(path,vanilla_editor,ini_editor,csv_editor) + + LastOpenedFiles.store_opened_files(OpenFileList) + current_editor.show() + +func generate_file_item(path : String , veditor : Control , inieditor : Control, csveditor : Control): + OpenFileName.set_text(path) + OpenFileList.add_item(path.get_file(),IconLoader.load_icon_from_name("file"),true) + current_file_index = OpenFileList.get_item_count()-1 + OpenFileList.set_item_metadata(current_file_index,[veditor,inieditor,csveditor]) + OpenFileList.select(OpenFileList.get_item_count()-1) + +func open_in_vanillaeditor(path : String) -> Control: + var editor = VanillaEditor.instance() + SplitEditorContainer.add_child(editor,true) + + if current_editor and current_editor!=editor: + editor.show() + current_editor.hide() + if current_csv_editor and current_csv_editor.visible: + current_csv_editor.hide() + if current_ini_editor and current_ini_editor.visible: + current_ini_editor.hide() + + current_editor = editor + + + editor.connect("text_changed",self,"_on_vanillaeditor_text_changed") + + var current_file : File = File.new() + current_file.open(path,File.READ) + var current_content = "" + current_content = current_file.get_as_text() + + var last_modified = OS.get_datetime_from_unix_time(current_file.get_modified_time(path)) + + current_file.close() + + editor.new_file_open(current_content,last_modified,current_file_path) + + update_list() + + if WrapBTN.get_selected_id() == 1: + current_editor.set_wrap_enabled(true) + + + return editor + +func open_in_inieditor(path : String) -> Control: + var extension = path.get_file().get_extension() + if extension == "ini" or extension == "cfg": + var inieditor = IniEditor.instance() + SplitEditorContainer.add_child(inieditor) + inieditor.hide() + inieditor.connect("update_file",self,"_on_update_file") + current_ini_editor = inieditor + inieditor.current_file_path = path + var current_file : ConfigFile = ConfigFile.new() + var err = current_file.load(path) + if err == OK: + var sections = current_file.get_sections() + var filemap = [] + for section in sections: + var keys = [] + var section_keys = current_file.get_section_keys(section) + for key in section_keys: + keys.append([key,current_file.get_value(section,key)]) + + filemap.append([section,keys]) + + inieditor.open_file(filemap) + return inieditor + else: + current_ini_editor = null + return null + +func open_in_csveditor(path : String) -> Control: + var extension = path.get_file().get_extension() + if extension == "csv": + var csveditor = CsvEditor.instance() + SplitEditorContainer.add_child(csveditor) + csveditor.hide() + csveditor.connect("update_file",self,"_on_update_file") + current_csv_editor = csveditor + csveditor.current_file_path = path + csveditor.open_csv_file(path,"|") + return csveditor + else: + current_csv_editor = null + return null + +func close_file(index): + LastOpenedFiles.remove_opened_file(index,OpenFileList) + OpenFileList.remove_item(index) + OpenFileName.clear() + current_editor.queue_free() + + if index>0: + OpenFileList.select(OpenFileList.get_item_count()-1) + _on_fileitem_pressed(OpenFileList.get_item_count()-1) + +func _on_update_file(): +# current_editor.clean_editor() + var current_file : File = File.new() + current_file.open(current_file_path,File.READ) + + var current_content = current_file.get_as_text() + var last_modified = OS.get_datetime_from_unix_time(current_file.get_modified_time(current_file_path)) + + current_file.close() + + current_editor.new_file_open(current_content,last_modified,current_file_path) + +func delete_file(files_selected : PoolStringArray): + var dir = Directory.new() + for file in files_selected: + dir.remove(file) + + update_list() + +func open_newfiledialogue(): + NewFileDialogue.popup() + NewFileDialogue.set_position(OS.get_screen_size()/2 - NewFileDialogue.get_size()/2) + +func open_filelist(): + update_list() + FileList.popup() + FileList.set_position(OS.get_screen_size()/2 - FileList.get_size()/2) + +func create_new_file(given_path : String): + var current_file = File.new() + current_file.open(given_path,File.WRITE) + if save_as : + current_file.store_line(current_editor.get_node("TextEditor").get_text()) + current_file.close() + + open_file(given_path) + +func save_file(current_path : String): + var current_file = File.new() + current_file.open(current_path,File.WRITE) + var current_content = "" + var lines = current_editor.get_node("TextEditor").get_line_count() + for line in range(0,lines): + current_content = current_editor.get_node("TextEditor").get_text() + current_file.store_line(current_editor.get_node("TextEditor").get_line(line)) + current_file.close() + + current_file_path = current_path + + var last_modified = OS.get_datetime_from_unix_time(current_file.get_modified_time(current_file_path)) + + current_editor.update_lastmodified(last_modified,"save") + OpenFileList.set_item_metadata(current_file_index,[current_editor,current_ini_editor,current_csv_editor]) + print(OpenFileList.get_item_metadata(current_file_index)) + + if OpenFileList.get_item_text(current_file_index).ends_with("(*)"): + OpenFileList.set_item_text(current_file_index,OpenFileList.get_item_text(current_file_index).rstrip("(*)")) + +# OpenFileList.set_item_metadata(current_file_index,[current_editor,open_in_inieditor(current_file_path),open_in_csveditor(current_file_path)]) + + update_list() + +func clean_editor() -> void : + for inieditor in get_tree().get_nodes_in_group("ini_editor"): + inieditor.queue_free() + for vanillaeditor in get_tree().get_nodes_in_group("vanilla_editor"): + vanillaeditor.queue_free() + OpenFileName.clear() + OpenFileList.clear() + + +func csv_preview(): + var preview = Preview.instance() + get_parent().get_parent().get_parent().add_child(preview) + preview.popup() + preview.window_title += " ("+current_file_path.get_file()+")" + var lines = current_editor.get_node("TextEditor").get_line_count() + var rows = [] + for i in range(0,lines-1): + rows.append(current_editor.get_node("TextEditor").get_line(i).rsplit(",",false)) + preview.print_csv(rows) + +func bbcode_preview(): + var preview = Preview.instance() + get_parent().get_parent().get_parent().add_child(preview) + preview.popup() + preview.window_title += " ("+current_file_path.get_file()+")" + preview.print_bb(current_editor.get_node("TextEditor").get_text()) + +func markdown_preview(): + var preview = Preview.instance() + get_parent().get_parent().get_parent().add_child(preview) + preview.popup() + preview.window_title += " ("+current_file_path.get_file()+")" + preview.print_markdown(current_editor.get_node("TextEditor").get_text()) + +func html_preview(): + var preview = Preview.instance() + get_parent().get_parent().get_parent().add_child(preview) + preview.popup() + preview.window_title += " ("+current_file_path.get_file()+")" + preview.print_html(current_editor.get_node("TextEditor").get_text()) + +func xml_preview(): + pass + +func json_preview(): + pass + + +func _on_vanillaeditor_text_changed(): + if not OpenFileList.get_item_text(current_file_index).ends_with("(*)"): + OpenFileList.set_item_text(current_file_index,OpenFileList.get_item_text(current_file_index)+"(*)") + + +func update_list(): + FileList.invalidate() + +func on_wrap_button(index:int): + match index: + 0: + current_editor.set_wrap_enabled(false) + 1: + current_editor.set_wrap_enabled(true) + +func on_minimap_button(index:int): + match index: + 0: + current_editor.draw_minimap(false) + 1: + current_editor.draw_minimap(true) + +func check_file_preview(file : String): + # check whether the opened file has a corresponding preview session for its extension + pass diff --git a/scripts/FileEditorButton.gd b/scripts/FileEditorButton.gd new file mode 100644 index 0000000..95b3ac3 --- /dev/null +++ b/scripts/FileEditorButton.gd @@ -0,0 +1,19 @@ +tool +extends ToolButton + +var fileditor_workspace +var fileditor + +func _ready(): + connect("pressed",self,"show_fileditor") + +func show_fileditor(): + fileditor_workspace.get_children()[0].hide() + fileditor_workspace.get_children()[1].hide() + fileditor_workspace.get_children()[2].hide() + fileditor_workspace.add_child(fileditor) + fileditor.show() + +func load_values(fi, fe): + fileditor_workspace = fi + fileditor = fe diff --git a/scripts/FileScene.gd b/scripts/FileScene.gd new file mode 100644 index 0000000..7fbdc1f --- /dev/null +++ b/scripts/FileScene.gd @@ -0,0 +1,198 @@ +tool +extends VBoxContainer + +var IconLoader = preload("res://addons/file-editor/scripts/IconLoader.gd").new() +var LastOpenedFiles = preload("res://addons/file-editor/scripts/LastOpenedFiles.gd").new() + +onready var ReadOnly = $FileInfo/Readonly + +onready var TextEditor = $TextEditor + +onready var LastModified = $FileInfo/lastmodified + +onready var FileList = get_parent().get_parent().get_parent().get_node("FileList") + +onready var ClosingFile = get_parent().get_parent().get_parent().get_node("ConfirmationDialog") + +onready var LastModifiedIcon = $FileInfo/lastmodified_icon + +onready var SearchBox = $SearchBox +onready var ReplaceBox = $ReplaceBox + +onready var c_counter = $FileInfo/c_counter + +var current_path = "" +var current_filename = "" +var Preview = load("res://addons/file-editor/scenes/Preview.tscn") + + +var search_flag = 0 + +signal text_changed() + +func _ready(): + ClosingFile.connect("confirmed",self,"queue_free") + + ReadOnly.connect("toggled",self,"_on_Readonly_toggled") + + ReadOnly.set("custom_icons/checked",IconLoader.load_icon_from_name("read")) + ReadOnly.set("custom_icons/unchecked",IconLoader.load_icon_from_name("edit")) + + add_to_group("vanilla_editor") + +func color_region(filextension : String): # -----------------------------> dal momento che voglio creare un editor per ogni file, renderĂ² questa funzione singola in base all'estensione del file + match(filextension): + "bbs": + TextEditor.add_color_region("[b]","[/b]",Color8(153,153,255,255),false) + TextEditor.add_color_region("[i]","[/i]",Color8(153,255,153,255),false) + TextEditor.add_color_region("[s]","[/s]",Color8(255,153,153,255),false) + TextEditor.add_color_region("[u]","[/u]",Color8(255,255,102,255),false) + TextEditor.add_color_region("[url","[/url]",Color8(153,204,255,255),false) + TextEditor.add_color_region("[code]","[/code]",Color8(192,192,192,255),false) + TextEditor.add_color_region("[img]","[/img]",Color8(255,204,153,255),false) + TextEditor.add_color_region("[center]","[/center]",Color8(175,238,238,255),false) + TextEditor.add_color_region("[right]","[/right]",Color8(135,206,235,255),false) + "html": + TextEditor.add_color_region("","",Color8(153,153,255,255),false) + TextEditor.add_color_region("","",Color8(153,255,153,255),false) + TextEditor.add_color_region("","",Color8(255,153,153,255),false) + TextEditor.add_color_region("","",Color8(255,255,102,255),false) + TextEditor.add_color_region("",Color8(153,204,255,255),false) + TextEditor.add_color_region("",Color8(255,204,153,255),true) + TextEditor.add_color_region("
","
",Color8(192,192,192,255),false) + TextEditor.add_color_region("
","
",Color8(175,238,238,255),false) + TextEditor.add_color_region("","",Color8(135,206,235,255),false) + "md": + TextEditor.add_color_region("**","**",Color8(153,153,255,255),false) + TextEditor.add_color_region("*","*",Color8(153,255,153,255),false) + TextEditor.add_color_region("+ ","",Color8(255,178,102,255),false) + TextEditor.add_color_region("- ","",Color8(255,178,102,255),false) + TextEditor.add_color_region("~~","~~",Color8(255,153,153,255),false) + TextEditor.add_color_region("__","__",Color8(255,255,102,255),false) + TextEditor.add_color_region("[",")",Color8(153,204,255,255),false) + TextEditor.add_color_region("`","`",Color8(192,192,192,255),false) + TextEditor.add_color_region('"*.','"',Color8(255,255,255,255),true) + TextEditor.add_color_region("# ","",Color8(105,105,105,255),true) + TextEditor.add_color_region("## ","",Color8(128,128,128,255),true) + TextEditor.add_color_region("### ","",Color8(169,169,169,255),true) + TextEditor.add_color_region("#### ","",Color8(192,192,192,255),true) + TextEditor.add_color_region("##### ","",Color8(211,211,211,255),true) + TextEditor.add_color_region("###### ","",Color8(255,255,255,255),true) + "cfg": + TextEditor.add_color_region("[","]",Color8(153,204,255,255),false) + TextEditor.add_color_region('"','"',Color8(255,255,102,255),false) + _: + pass + +func clean_editor(): + TextEditor.set_text("") + LastModifiedIcon.texture = IconLoader.load_icon_from_name("save") + LastModified.set_text("") + FileList.invalidate() + current_filename = "" + current_path = "" + +func new_file_open(file_content, last_modified , current_file_path): + current_path = current_file_path + current_filename = current_file_path.get_file() + color_region(current_filename.get_extension()) + TextEditor.set_text(file_content) + update_lastmodified(last_modified,"save") + FileList.invalidate() + count_characters() + +func update_lastmodified(last_modified : Dictionary, icon : String): + LastModified.set_text(str(last_modified.hour)+":"+str(last_modified.minute)+" "+str(last_modified.day)+"/"+str(last_modified.month)+"/"+str(last_modified.year)) + LastModifiedIcon.texture = IconLoader.load_icon_from_name(icon) + +func new_file_create(file_name): + TextEditor.set_text("") + + FileList.invalidate() + +func _on_Readonly_toggled(button_pressed): + if button_pressed: + ReadOnly.set_text("Read Only") + TextEditor.readonly = (true) + else: + ReadOnly.set_text("Can Edit") + TextEditor.readonly = (false) + +func _on_TextEditor_text_changed(): + LastModifiedIcon.texture = IconLoader.load_icon_from_name("saveas") + count_characters() + emit_signal("text_changed") + +func count_characters(): + var counted : int = 0 + for line in TextEditor.get_line_count(): + counted += TextEditor.get_line(line).length() + c_counter.set_text(str(counted)) + +func _on_LineEdit_text_changed(new_text): + var linecount = TextEditor.get_line_count() + if new_text != "": + var found + var find = false + for line in range(0,linecount): + for column in range(0,TextEditor.get_line(line).length()): + found = TextEditor.search( new_text, search_flag, line , column ) + if found.size(): + if found[1] == line: +# if not find: + TextEditor.select(line,found[0],found[1],found[0]+new_text.length()) +# find = true + else: + TextEditor.select(0,0,0,0) + else: + TextEditor.select(0,0,0,0) + +func _on_matchcase_toggled(button_pressed): + if button_pressed: + search_flag = 1 + else: + if $SearchBox/wholewords.is_pressed(): + search_flag = 2 + else: + search_flag = 0 + _on_LineEdit_text_changed($SearchBox/LineEdit.get_text()) + +func _on_wholewords_toggled(button_pressed): + if button_pressed: + search_flag = 2 + else: + if $SearchBox/matchcase.is_pressed(): + search_flag = 1 + else: + search_flag = 0 + _on_LineEdit_text_changed($SearchBox/LineEdit.get_text()) + +func _on_close_pressed(): + SearchBox.hide() + +func open_searchbox(): + if SearchBox.visible: + SearchBox.hide() + else: + SearchBox.show() + SearchBox.get_node("LineEdit").grab_focus() + +func _on_Button_pressed(): + var linecount = TextEditor.get_line_count()-1 + var old_text = $ReplaceBox/replace.get_text() + var new_text = $ReplaceBox/with.get_text() + var text = TextEditor.get_text() + TextEditor.set_text(text.replace(old_text,new_text)) + +func open_replacebox(): + if ReplaceBox.visible: + ReplaceBox.hide() + else: + ReplaceBox.show() + ReplaceBox.get_node("replace").grab_focus() + +func _on_close2_pressed(): + ReplaceBox.hide() + +func _on_LineEdit_focus_entered(): + _on_LineEdit_text_changed($SearchBox/LineEdit.get_text()) diff --git a/scripts/IconLoader.gd b/scripts/IconLoader.gd new file mode 100644 index 0000000..a832ca2 --- /dev/null +++ b/scripts/IconLoader.gd @@ -0,0 +1,20 @@ +tool +extends Node + +var imgBuffer + +func _ready(): + pass + +func load_icon_from_name(icon_name : String) -> ImageTexture: + var file = File.new() + var image = Image.new() + var texture = ImageTexture.new() + + file.open("res://addons/file-editor/icons.pngs/"+icon_name+".png.buttonicon", File.READ) + var buffer = file.get_buffer(file.get_len()) + file.close() + + image.load_png_from_buffer(buffer) + texture.create_from_image(image) + return texture diff --git a/scripts/IniVisualEditor.gd b/scripts/IniVisualEditor.gd new file mode 100644 index 0000000..3e0d642 --- /dev/null +++ b/scripts/IniVisualEditor.gd @@ -0,0 +1,284 @@ +tool +extends Control + +var IconLoader = preload("res://addons/file-editor/scripts/IconLoader.gd").new() +var LastOpenedFiles = preload("res://addons/file-editor/scripts/LastOpenedFiles.gd").new() + +onready var Keys = $VBoxContainer/HSplitContainer/VBoxContainer2/keys +onready var Sections = $VBoxContainer/HSplitContainer/VBoxContainer/sections2 + +onready var BtnAddSection = $VBoxContainer/HSplitContainer/VBoxContainer/HBoxContainer2/btn_add_section +onready var BtnRemoveSection = $VBoxContainer/HSplitContainer/VBoxContainer/HBoxContainer2/btn_remove_section + +onready var BtnAddKey = $VBoxContainer/HSplitContainer/VBoxContainer2/HBoxContainer3/btn_add_key +onready var BtnEditKey = $VBoxContainer/HSplitContainer/VBoxContainer2/HBoxContainer3/btn_edit_key +onready var BtnRemoveKey = $VBoxContainer/HSplitContainer/VBoxContainer2/HBoxContainer3/btn_remove_key + +onready var Section = $Section +onready var Key = $Key + +var selected_key +var selected_section : int = -1 +var root : TreeItem + +var current_file_path : String = "" + +signal update_file() + +func _ready(): + create_table_names() + connect_signals() + load_icons() + clean_editor() + + add_to_group("ini_editor") + +# var metadata = [["name","Godot Engine"],["version","1.0.0"],["color","Light Blue"]] +# load_section("Engine", metadata) + +func connect_signals(): + Sections.connect("item_selected",self,"_on_section_selected") + Sections.connect("nothing_selected",self,"_on_nosection_selected") + + BtnAddSection.connect("pressed",self,"_on_addsection_pressed") + BtnRemoveSection.connect("pressed",self,"_on_removesection_pressed") + + Keys.connect("item_selected",self,"_on_key_selected") + Keys.connect("nothing_selected",self,"_on_nokey_selected") + + BtnAddKey.connect("pressed",self,"_on_addkey_pressed") + BtnRemoveKey.connect("pressed",self,"_on_removekey_pressed") + BtnEditKey.connect("pressed",self,"_on_editkey_pressed") + + connect("visibility_changed",self,"_on_visibility_changed") + +func create_table_names(): + create_root() + Keys.hide_root = true + + Keys.set_column_titles_visible(true) + Keys.set_column_title(0,"Name") + Keys.set_column_title(1,"Value") + +func load_icons(): + $VBoxContainer/HSplitContainer/VBoxContainer/HBoxContainer/sections_icon.texture = IconLoader.load_icon_from_name("sections") + $VBoxContainer/HSplitContainer/VBoxContainer2/HBoxContainer2/keys_icon.texture = IconLoader.load_icon_from_name("keys") + BtnAddSection.icon = IconLoader.load_icon_from_name("add") + BtnAddSection.hint_tooltip = "Add a new Section" + BtnRemoveSection.icon = IconLoader.load_icon_from_name("delete") + BtnRemoveSection.hint_tooltip = "Remove selected Section" + + BtnAddKey.icon = IconLoader.load_icon_from_name("add") + BtnAddKey.hint_tooltip = "Add a new Key" + BtnRemoveKey.icon = IconLoader.load_icon_from_name("delete") + BtnRemoveKey.hint_tooltip = "Remove selected Key" + BtnEditKey.icon = IconLoader.load_icon_from_name("edit_") + BtnEditKey.hint_tooltip = "Edit selected Key" + +func _on_addsection_pressed(): + Section.get_node("Container/section/_name").show() + Section.window_title = "Add a new Section" + if not Section.is_connected("confirmed",self,"new_section"): + Section.connect("confirmed",self,"new_section") + if Section.is_connected("confirmed",self,"remove_section"): + Section.disconnect("confirmed",self,"remove_section") + Section.popup() + +func _on_removesection_pressed(): + Section.get_node("Container").hide() + Section.window_title = "Remove selected Section" + Section.dialog_text = "Are you sure you want to remove this Section?" + if not Section.is_connected("confirmed",self,"remove_section"): + Section.connect("confirmed",self,"remove_section") + if Section.is_connected("confirmed",self,"new_section"): + Section.disconnect("confirmed",self,"new_section") + Section.popup() + +func _on_addkey_pressed(): + Key.get_node("data").show() + Key.get_node("data/HBoxContainer/name").editable = true + Key.get_node("data/HBoxContainer/name").set_text("") + Key.window_title = "Add a new Key" + Key.dialog_text = "" + if not Key.is_connected("confirmed",self,"new_key"): + Key.connect("confirmed",self,"new_key") + if Key.is_connected("confirmed",self,"edit_key"): + Key.disconnect("confirmed",self,"edit_key") + if Key.is_connected("confirmed",self,"remove_key"): + Key.disconnect("confirmed",self,"remove_key") + Key.popup() + +func _on_removekey_pressed(): + Key.get_node("data").hide() + Key.window_title = "Delete selected Key" + Key.dialog_text = "Are you sure you want to remove the selected Key?" + if not Key.is_connected("confirmed",self,"remove_key"): + Key.connect("confirmed",self,"remove_key") + if Key.is_connected("confirmed",self,"edit_key"): + Key.disconnect("confirmed",self,"edit_key") + if Key.is_connected("confirmed",self,"new_key"): + Key.disconnect("confirmed",self,"new_key") + Key.popup() + +func _on_editkey_pressed(): + Key.get_node("data").show() + Key.get_node("data/HBoxContainer/name").editable = false + Key.get_node("data/HBoxContainer/name").set_text(str(selected_key.get_text(0))) + Key.get_node("data/HBoxContainer2/value").set_text(str(selected_key.get_text(1))) + Key.window_title = "Edit selected Key" + Key.dialog_text = "" + if not Key.is_connected("confirmed",self,"edit_key"): + Key.connect("confirmed",self,"edit_key") + if Key.is_connected("confirmed",self,"remove_key"): + Key.disconnect("confirmed",self,"remove_key") + if Key.is_connected("confirmed",self,"new_key"): + Key.disconnect("confirmed",self,"new_key") + Key.popup() + +func clean_editor(): + Keys.clear() + Sections.clear() + selected_section = -1 + BtnAddKey.disabled = true + if current_file_path == "": + BtnAddSection.disabled = true + else: + BtnAddSection.disabled = false + BtnEditKey.disabled = true + BtnRemoveKey.disabled = true + BtnRemoveSection.disabled = true + + create_root() + +func open_file(filemap : Array): + clean_editor() + for section in filemap: + load_sections(section[0],section[1]) + +func new_section(): + var file = ConfigFile.new() + file.load(current_file_path) + + var section_name = str(Section.get_node("Container/section/_name").get_text()) + var key_name = str(Section.get_node("Container/key/_name").get_text()) + var key_value = Section.get_node("Container/value/_value").get_text() + + if section_name and key_name and key_value: + file.set_value(section_name,key_name,key_value) + file.save(current_file_path) + + load_sections(section_name,[[key_name,key_value]]) + + emit_signal("update_file") + else: + print("Section <",section_name,"> with Key name: <",key_name,"> and Key value: <",key_value,"> not valid.") + +func remove_section(): + var file = ConfigFile.new() + file.load(current_file_path) + var current_section = Sections.get_item_text(selected_section) + file.erase_section(current_section) + Sections.remove_item(selected_section) + file.save(current_file_path) + + emit_signal("update_file") + +func new_key(): + var key_name = str(Key.get_node("data/HBoxContainer/name").get_text()) + var key_value = Key.get_node("data/HBoxContainer2/value").get_text() + if key_name and key_value: + + var file = ConfigFile.new() + file.load(current_file_path) + + var current_section = Sections.get_item_text(selected_section) + + file.set_value(current_section,key_name,key_value) + file.save(current_file_path) + + load_keys_selected_section([[key_name,key_value]]) + + file.save(current_file_path) + + emit_signal("update_file") + else: + print("Key name: <",key_name,"> with Key value: <",key_value,"> not valid.") + +func remove_key(): + var section = Sections.get_item_text(selected_section) + var sectionmetadata = Sections.get_item_metadata(selected_section) + + for meta in sectionmetadata: + if meta.has(selected_key.get_text(0)): + sectionmetadata.erase(meta) + + Sections.set_item_metadata(selected_section,sectionmetadata) + + if Sections.get_item_metadata(selected_section) == []: + Sections.remove_item(selected_section) + + var file = ConfigFile.new() + file.load(current_file_path) + file.set_value(section,selected_key.get_text(0),null) + file.save(current_file_path) + + Keys.clear() + create_root() + load_keys_selected_section(sectionmetadata) + + emit_signal("update_file") + +func edit_key(): + remove_key() + new_key() + +# load a section with custom fields @section_name = name of section ; @section_metadata = keys of this section with keys' properties +func load_sections(section_name : String, section_metadata : Array): + Sections.add_item(section_name,IconLoader.load_icon_from_name("section"),true) + Sections.set_item_metadata(Sections.get_item_count()-1,section_metadata) + +# load a key of a selected section to fill the "keys" list +func load_keys_selected_section(metadata : Array): + for key in metadata: + var key_item = Keys.create_item(root) + key_item.set_text(0,key[0]) + key_item.set_text(1,key[1]) + +func _on_section_selected(index : int): + Keys.clear() + create_root() + BtnRemoveSection.disabled = false + BtnAddSection.disabled = false + BtnAddKey.disabled = false + BtnRemoveKey.disabled = true + BtnEditKey.disabled = true + + selected_section = index + if Sections.get_item_metadata(index): + load_keys_selected_section(Sections.get_item_metadata(index)) + +func _on_key_selected(): + selected_key = Keys.get_selected() + BtnRemoveKey.disabled = false + BtnEditKey.disabled = false + +func _on_nosection_selected(): + BtnRemoveKey.disabled = true + BtnAddKey.disabled = true + BtnEditKey.disabled = true + BtnRemoveSection.disabled = true + Keys.clear() + selected_section = -1 + +func _on_nokey_selected(): + BtnRemoveKey.disabled = true + BtnEditKey.disabled = true + +func create_root(): + root = Keys.create_item() + root.set_text(0,"KEY_NAME") + root.set_text(1,"KEY_VALUE") + +func _on_visibility_changed(): + if visible: + pass diff --git a/scripts/LastOpenedFiles.gd b/scripts/LastOpenedFiles.gd new file mode 100644 index 0000000..e47f517 --- /dev/null +++ b/scripts/LastOpenedFiles.gd @@ -0,0 +1,42 @@ +tool +extends Node + +const lastopenedfile_path : String = "res://addons/file-editor/lastopenedfiles.lastcfg" + +func _ready(): + pass + +func store_opened_files(filecontainer : Control): + var file = ConfigFile.new() + file.load(lastopenedfile_path) + for child in range(0,filecontainer.get_item_count()): + var filepath = filecontainer.get_item_metadata(child)[0].current_path + file.set_value("Opened",filepath.get_file(),filepath) + + file.save(lastopenedfile_path) + +func remove_opened_file(index : int , filecontainer : Control): + var file = ConfigFile.new() + file.load(lastopenedfile_path) + var filepath = filecontainer.get_item_metadata(index)[0].current_path + file.set_value("Opened",filepath.get_file(),null) + file.save(lastopenedfile_path) + +func load_opened_files() -> Array: + var file = ConfigFile.new() + file.load(lastopenedfile_path) + var keys = [] + # Load opened files + if file.has_section("Opened"): + var openedfiles = file.get_section_keys("Opened") + for openedfile in openedfiles: + # Load each single file which was opened + # creating and returning an Array with this format [1:file name, 2:file path, 3:file font] + keys.append([openedfile, file.get_value("Opened",openedfile), file.get_value("Fonts",openedfile) if file.has_section_key("Fonts",openedfile) else "null"]) + return keys + +func store_editor_fonts(file_name : String, font_path : String): + var file = ConfigFile.new() + file.load(lastopenedfile_path) + file.set_value("Fonts",file_name,font_path) + file.save(lastopenedfile_path) diff --git a/scripts/Preview.gd b/scripts/Preview.gd new file mode 100644 index 0000000..93bbcd4 --- /dev/null +++ b/scripts/Preview.gd @@ -0,0 +1,160 @@ +tool +extends WindowDialog + +var IconLoader = preload("res://addons/file-editor/scripts/IconLoader.gd").new() +var LastOpenedFiles = preload("res://addons/file-editor/scripts/LastOpenedFiles.gd").new() + +onready var TextPreview = $Container/TextPreview +onready var TablePreview = $Container/TablePreview + +signal image_downloaded() +signal image_loaded() + +var imgBuffer : Image + +func _ready(): + TextPreview.hide() + TablePreview.hide() + +func print_preview(content : String): + TextPreview.append_bbcode(content) + TextPreview.show() + +func print_bb(content : String): + TextPreview.append_bbcode(content) + TextPreview.show() + +func print_markdown(content : String): + var result = "" + var bolded = [] + var italics = [] + var striked = [] + var coded = [] + var linknames = [] + var images = [] + var links = [] + var lists = [] + var underlined = [] + + var regex = RegEx.new() + regex.compile('\\*\\*(?.*)\\*\\*') + result = regex.search_all(content) + if result: + for res in result: + bolded.append(res.get_string("boldtext")) + + regex.compile('\\_\\_(?.*)\\_\\_') + result = regex.search_all(content) + if result: + for res in result: + underlined.append(res.get_string("underlinetext")) + + regex.compile("\\*(?.*)\\*") + result = regex.search_all(content) + if result: + for res in result: + italics.append(res.get_string("italictext")) + + regex.compile("~~(?.*)~~") + result = regex.search_all(content) + if result: + for res in result: + striked.append(res.get_string("strikedtext")) + + regex.compile("`(?.*)`") + result = regex.search_all(content) + if result: + for res in result: + coded.append(res.get_string("coded")) + + regex.compile("[+-*](?\\s.*)") + result = regex.search_all(content) + if result: + for res in result: + lists.append(res.get_string("element")) + + regex.compile("(?!\\[.*?\\))") + result = regex.search_all(content) + if result: + for res in result: + images.append(res.get_string("img")) + + regex.compile("\\[(?.*?)\\]|\\((?[h\\.]\\S*?)\\)") + result = regex.search_all(content) + if result: + for res in result: + if res.get_string("link")!="": + links.append(res.get_string("link")) + if res.get_string("linkname")!="": + linknames.append(res.get_string("linkname")) + + for bold in bolded: + content = content.replace("**"+bold+"**","[b]"+bold+"[/b]") + for italic in italics: + content = content.replace("*"+italic+"*","[i]"+italic+"[/i]") + for strik in striked: + content = content.replace("~~"+strik+"~~","[s]"+strik+"[/s]") + for underline in underlined: + content = content.replace("__"+underline+"__","[u]"+underline+"[/u]") + for code in coded: + content = content.replace("`"+code+"`","[code]"+code+"[/code]") + for image in images: + var substr = image.split("(") + var imglink = substr[1].rstrip(")") + content = content.replace(image,"[img]"+imglink+"[/img]") + for i in links.size(): + content = content.replace("["+linknames[i]+"]("+links[i]+")","[url="+links[i]+"]"+linknames[i]+"[/url]") + for element in lists: + if content.find("- "+element): + content = content.replace("-"+element,"[indent]-"+element+"[/indent]") + if content.find("+ "+element): + content = content.replace("+"+element,"[indent]-"+element+"[/indent]") + if content.find("* "+element): + content = content.replace("+"+element,"[indent]-"+element+"[/indent]") + + TextPreview.append_bbcode(content) + TextPreview.show() + +func print_html(content : String): + content = content.replace("","[i]") + content = content.replace("","[/i]") + content = content.replace("","[b]") + content = content.replace("","[/b]") + content = content.replace("","[u]") + content = content.replace("","[/u]") + content = content.replace("","[u]") + content = content.replace("","[/u]") + content = content.replace("","[s]") + content = content.replace("","[/s]") + content = content.replace('',"]") + content = content.replace("","[/url]") + content = content.replace('',"[/img]") + content = content.replace('"/>',"[/img]") + content = content.replace("
","[code]")
+	content = content.replace("
","[/code]") + content = content.replace("
","[center]") + content = content.replace("
","[/center]") + content = content.replace("","[right]") + content = content.replace("","[/right]") + + TextPreview.append_bbcode(content) + TextPreview.show() + +func print_csv(rows : Array): + TablePreview.columns = rows[0].size() + for item in rows: + for string in item: + var label = Label.new() + label.text = str(string) + label.set_h_size_flags(SIZE_EXPAND) + label.set_align(1) + label.set_valign(1) + TablePreview.add_child(label) + + + TablePreview.show() + +func _on_Preview_popup_hide(): + queue_free() diff --git a/scripts/VanillaEditor.gd b/scripts/VanillaEditor.gd new file mode 100644 index 0000000..4068a3e --- /dev/null +++ b/scripts/VanillaEditor.gd @@ -0,0 +1,220 @@ +tool +extends VBoxContainer + +var IconLoader = preload("res://addons/file-editor/scripts/IconLoader.gd").new() +var LastOpenedFiles = preload("res://addons/file-editor/scripts/LastOpenedFiles.gd").new() + +onready var ReadOnly = $FileInfo/Readonly + +onready var TextEditor = $TextEditor + +onready var LastModified = $FileInfo/lastmodified + +onready var FileList = get_parent().get_parent().get_parent().get_parent().get_node("FileList") + +onready var ClosingFile = get_parent().get_parent().get_parent().get_parent().get_node("ConfirmationDialog") + +onready var LastModifiedIcon = $FileInfo/lastmodified_icon + +onready var SearchBox = $SearchBox +onready var ReplaceBox = $ReplaceBox + +onready var c_counter = $FileInfo/c_counter + +var current_path = "" +var current_filename = "" +var Preview = load("res://addons/file-editor/scenes/Preview.tscn") + + +var search_flag = 0 + +signal text_changed() + +func _ready(): + ClosingFile.connect("confirmed",self,"queue_free") + + ReadOnly.connect("toggled",self,"_on_Readonly_toggled") + + ReadOnly.set("custom_icons/checked",IconLoader.load_icon_from_name("read")) + ReadOnly.set("custom_icons/unchecked",IconLoader.load_icon_from_name("edit")) + + add_to_group("vanilla_editor") + +func set_font(font_path : String) -> void: + var dynamic_font : DynamicFont = DynamicFont.new() + var dynamic_font_data : DynamicFontData = DynamicFontData.new() + dynamic_font_data.set_font_path(font_path) + dynamic_font.set_font_data(dynamic_font_data) + TextEditor.set("custom_fonts/font",dynamic_font) + +func set_wrap_enabled(enabled:bool): + TextEditor.set_wrap_enabled(enabled) + TextEditor.update() + +func draw_minimap(value:bool): + TextEditor.draw_minimap(value) + TextEditor.update() + +func color_region(filextension : String): # -----------------------------> dal momento che voglio creare un editor per ogni file, renderĂ² questa funzione singola in base all'estensione del file + match(filextension): + "bbs": + TextEditor.add_color_region("[b]","[/b]",Color8(153,153,255,255),false) + TextEditor.add_color_region("[i]","[/i]",Color8(153,255,153,255),false) + TextEditor.add_color_region("[s]","[/s]",Color8(255,153,153,255),false) + TextEditor.add_color_region("[u]","[/u]",Color8(255,255,102,255),false) + TextEditor.add_color_region("[url","[/url]",Color8(153,204,255,255),false) + TextEditor.add_color_region("[code]","[/code]",Color8(192,192,192,255),false) + TextEditor.add_color_region("[img]","[/img]",Color8(255,204,153,255),false) + TextEditor.add_color_region("[center]","[/center]",Color8(175,238,238,255),false) + TextEditor.add_color_region("[right]","[/right]",Color8(135,206,235,255),false) + "html": + TextEditor.add_color_region("","",Color8(153,153,255,255),false) + TextEditor.add_color_region("","",Color8(153,255,153,255),false) + TextEditor.add_color_region("","",Color8(255,153,153,255),false) + TextEditor.add_color_region("","",Color8(255,255,102,255),false) + TextEditor.add_color_region("",Color8(153,204,255,255),false) + TextEditor.add_color_region("",Color8(255,204,153,255),true) + TextEditor.add_color_region("
","
",Color8(192,192,192,255),false) + TextEditor.add_color_region("
","
",Color8(175,238,238,255),false) + TextEditor.add_color_region("","",Color8(135,206,235,255),false) + "md": + TextEditor.add_color_region("***","***",Color8(126,186,181,255),false) + TextEditor.add_color_region("**","**",Color8(153,153,255,255),false) + TextEditor.add_color_region("*","*",Color8(153,255,153,255),false) + TextEditor.add_color_region("+ ","",Color8(255,178,102,255),false) + TextEditor.add_color_region("- ","",Color8(255,178,102,255),false) + TextEditor.add_color_region("~~","~~",Color8(255,153,153,255),false) + TextEditor.add_color_region("__","__",Color8(255,255,102,255),false) + TextEditor.add_color_region("[",")",Color8(153,204,255,255),false) + TextEditor.add_color_region("`","`",Color8(192,192,192,255),false) + TextEditor.add_color_region('"*.','"',Color8(255,255,255,255),true) + TextEditor.add_color_region("# ","",Color8(105,105,105,255),true) + TextEditor.add_color_region("## ","",Color8(128,128,128,255),true) + TextEditor.add_color_region("### ","",Color8(169,169,169,255),true) + TextEditor.add_color_region("#### ","",Color8(192,192,192,255),true) + TextEditor.add_color_region("##### ","",Color8(211,211,211,255),true) + TextEditor.add_color_region("###### ","",Color8(255,255,255,255),true) + TextEditor.add_color_region("> ","",Color8(172,138,79,255),true) + "cfg": + TextEditor.add_color_region("[","]",Color8(153,204,255,255),false) + TextEditor.add_color_region('"','"',Color8(255,255,102,255),false) + TextEditor.add_color_region(';','',Color8(128,128,128,255),true) + "ini": + TextEditor.add_color_region("[","]",Color8(153,204,255,255),false) + TextEditor.add_color_region('"','"',Color8(255,255,102,255),false) + TextEditor.add_color_region(';','',Color8(128,128,128,255),true) + _: + pass + +func clean_editor(): + TextEditor.set_text("") + LastModifiedIcon.texture = IconLoader.load_icon_from_name("save") + LastModified.set_text("") + FileList.invalidate() + current_filename = "" + current_path = "" + +func new_file_open(file_content : String, last_modified : Dictionary, current_file_path : String): + current_path = current_file_path + current_filename = current_file_path.get_file() + color_region(current_filename.get_extension()) + TextEditor.set_text(file_content) + update_lastmodified(last_modified,"save") + FileList.invalidate() + count_characters() + +func update_lastmodified(last_modified : Dictionary, icon : String): + LastModified.set_text(str(last_modified.hour)+":"+str(last_modified.minute)+" "+str(last_modified.day)+"/"+str(last_modified.month)+"/"+str(last_modified.year)) + LastModifiedIcon.texture = IconLoader.load_icon_from_name(icon) + +func new_file_create(file_name): + TextEditor.set_text("") + + FileList.invalidate() + +func _on_Readonly_toggled(button_pressed): + if button_pressed: + ReadOnly.set_text("Read Only") + TextEditor.readonly = (true) + else: + ReadOnly.set_text("Can Edit") + TextEditor.readonly = (false) + +func _on_TextEditor_text_changed(): + LastModifiedIcon.texture = IconLoader.load_icon_from_name("saveas") + count_characters() + emit_signal("text_changed") + +func count_characters(): + var counted : int = 0 + for line in TextEditor.get_line_count(): + counted += TextEditor.get_line(line).length() + c_counter.set_text(str(counted)) + +func _on_LineEdit_text_changed(new_text): + var linecount = TextEditor.get_line_count() + if new_text != "": + var found + var find = false + for line in range(0,linecount): + for column in range(0,TextEditor.get_line(line).length()): + found = TextEditor.search( new_text, search_flag, line , column ) + if found.size(): + if found[1] == line: +# if not find: + TextEditor.select(line,found[0],found[1],found[0]+new_text.length()) +# find = true + else: + TextEditor.select(0,0,0,0) + else: + TextEditor.select(0,0,0,0) + +func _on_matchcase_toggled(button_pressed): + if button_pressed: + search_flag = 1 + else: + if $SearchBox/wholewords.is_pressed(): + search_flag = 2 + else: + search_flag = 0 + _on_LineEdit_text_changed($SearchBox/LineEdit.get_text()) + +func _on_wholewords_toggled(button_pressed): + if button_pressed: + search_flag = 2 + else: + if $SearchBox/matchcase.is_pressed(): + search_flag = 1 + else: + search_flag = 0 + _on_LineEdit_text_changed($SearchBox/LineEdit.get_text()) + +func _on_close_pressed(): + SearchBox.hide() + +func open_searchbox(): + if SearchBox.visible: + SearchBox.hide() + else: + SearchBox.show() + SearchBox.get_node("LineEdit").grab_focus() + +func _on_Button_pressed(): + var linecount = TextEditor.get_line_count()-1 + var old_text = $ReplaceBox/replace.get_text() + var new_text = $ReplaceBox/with.get_text() + var text = TextEditor.get_text() + TextEditor.set_text(text.replace(old_text,new_text)) + +func open_replacebox(): + if ReplaceBox.visible: + ReplaceBox.hide() + else: + ReplaceBox.show() + ReplaceBox.get_node("replace").grab_focus() + +func _on_close2_pressed(): + ReplaceBox.hide() + +func _on_LineEdit_focus_entered(): + _on_LineEdit_text_changed($SearchBox/LineEdit.get_text()) diff --git a/scripts/file-editor.gd b/scripts/file-editor.gd new file mode 100644 index 0000000..e347a83 --- /dev/null +++ b/scripts/file-editor.gd @@ -0,0 +1,33 @@ +tool +extends EditorPlugin + +#var doc = preload("../scenes/FileEditor.tscn") + +var IconLoader = preload("res://addons/file-editor/scripts/IconLoader.gd").new() + +var FileEditor + +func _enter_tree(): + add_autoload_singleton("IconLoader","res://addons/file-editor/scripts/IconLoader.gd") + add_autoload_singleton("LastOpenedFiles","res://addons/file-editor/scripts/LastOpenedFiles.gd") + FileEditor = preload("../scenes/FileEditor.tscn").instance() + get_editor_interface().get_editor_viewport().add_child(FileEditor) + FileEditor.hide() + +func _exit_tree(): +# FileEditor.clean_editor() + remove_autoload_singleton("IconLoader") + remove_autoload_singleton("LastOpenedFiles") + get_editor_interface().get_editor_viewport().remove_child(FileEditor) + +func has_main_screen(): + return true + +func get_plugin_name(): + return "File" + +func get_plugin_icon(): + return IconLoader.load_icon_from_name("file") + +func make_visible(visible): + FileEditor.visible = visible