mirror of
https://github.com/godotengine/godot.git
synced 2024-11-27 09:16:35 +08:00
Merge pull request #19225 from Paulb23/open_all_files_in_script_editor
Open all files in script editor
This commit is contained in:
commit
b92c432313
@ -784,6 +784,345 @@ void CodeTextEditor::update_editor_settings() {
|
||||
text_editor->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/open_scripts/v_scroll_speed"));
|
||||
}
|
||||
|
||||
void CodeTextEditor::trim_trailing_whitespace() {
|
||||
bool trimed_whitespace = false;
|
||||
for (int i = 0; i < text_editor->get_line_count(); i++) {
|
||||
String line = text_editor->get_line(i);
|
||||
if (line.ends_with(" ") || line.ends_with("\t")) {
|
||||
|
||||
if (!trimed_whitespace) {
|
||||
text_editor->begin_complex_operation();
|
||||
trimed_whitespace = true;
|
||||
}
|
||||
|
||||
int end = 0;
|
||||
for (int j = line.length() - 1; j > -1; j--) {
|
||||
if (line[j] != ' ' && line[j] != '\t') {
|
||||
end = j + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
text_editor->set_line(i, line.substr(0, end));
|
||||
}
|
||||
}
|
||||
|
||||
if (trimed_whitespace) {
|
||||
text_editor->end_complex_operation();
|
||||
text_editor->update();
|
||||
}
|
||||
}
|
||||
|
||||
void CodeTextEditor::convert_indent_to_spaces() {
|
||||
int indent_size = EditorSettings::get_singleton()->get("text_editor/indent/size");
|
||||
String indent = "";
|
||||
|
||||
for (int i = 0; i < indent_size; i++) {
|
||||
indent += " ";
|
||||
}
|
||||
|
||||
int cursor_line = text_editor->cursor_get_line();
|
||||
int cursor_column = text_editor->cursor_get_column();
|
||||
|
||||
bool changed_indentation = false;
|
||||
for (int i = 0; i < text_editor->get_line_count(); i++) {
|
||||
String line = text_editor->get_line(i);
|
||||
|
||||
if (line.length() <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
while (j < line.length() && (line[j] == ' ' || line[j] == '\t')) {
|
||||
if (line[j] == '\t') {
|
||||
if (!changed_indentation) {
|
||||
text_editor->begin_complex_operation();
|
||||
changed_indentation = true;
|
||||
}
|
||||
if (cursor_line == i && cursor_column > j) {
|
||||
cursor_column += indent_size - 1;
|
||||
}
|
||||
line = line.left(j) + indent + line.right(j + 1);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (changed_indentation) {
|
||||
text_editor->set_line(i, line);
|
||||
}
|
||||
}
|
||||
if (changed_indentation) {
|
||||
text_editor->cursor_set_column(cursor_column);
|
||||
text_editor->end_complex_operation();
|
||||
text_editor->update();
|
||||
}
|
||||
}
|
||||
|
||||
void CodeTextEditor::convert_indent_to_tabs() {
|
||||
int indent_size = EditorSettings::get_singleton()->get("text_editor/indent/size");
|
||||
indent_size -= 1;
|
||||
|
||||
int cursor_line = text_editor->cursor_get_line();
|
||||
int cursor_column = text_editor->cursor_get_column();
|
||||
|
||||
bool changed_indentation = false;
|
||||
for (int i = 0; i < text_editor->get_line_count(); i++) {
|
||||
String line = text_editor->get_line(i);
|
||||
|
||||
if (line.length() <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
int space_count = -1;
|
||||
while (j < line.length() && (line[j] == ' ' || line[j] == '\t')) {
|
||||
if (line[j] != '\t') {
|
||||
space_count++;
|
||||
|
||||
if (space_count == indent_size) {
|
||||
if (!changed_indentation) {
|
||||
text_editor->begin_complex_operation();
|
||||
changed_indentation = true;
|
||||
}
|
||||
if (cursor_line == i && cursor_column > j) {
|
||||
cursor_column -= indent_size;
|
||||
}
|
||||
line = line.left(j - indent_size) + "\t" + line.right(j + 1);
|
||||
j = 0;
|
||||
space_count = -1;
|
||||
}
|
||||
} else {
|
||||
space_count = -1;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (changed_indentation) {
|
||||
text_editor->set_line(i, line);
|
||||
}
|
||||
}
|
||||
if (changed_indentation) {
|
||||
text_editor->cursor_set_column(cursor_column);
|
||||
text_editor->end_complex_operation();
|
||||
text_editor->update();
|
||||
}
|
||||
}
|
||||
|
||||
void CodeTextEditor::convert_case(CaseStyle p_case) {
|
||||
if (!text_editor->is_selection_active()) {
|
||||
return;
|
||||
}
|
||||
|
||||
text_editor->begin_complex_operation();
|
||||
|
||||
int begin = text_editor->get_selection_from_line();
|
||||
int end = text_editor->get_selection_to_line();
|
||||
int begin_col = text_editor->get_selection_from_column();
|
||||
int end_col = text_editor->get_selection_to_column();
|
||||
|
||||
for (int i = begin; i <= end; i++) {
|
||||
int len = text_editor->get_line(i).length();
|
||||
if (i == end)
|
||||
len -= len - end_col;
|
||||
if (i == begin)
|
||||
len -= begin_col;
|
||||
String new_line = text_editor->get_line(i).substr(i == begin ? begin_col : 0, len);
|
||||
|
||||
switch (p_case) {
|
||||
case UPPER: {
|
||||
new_line = new_line.to_upper();
|
||||
} break;
|
||||
case LOWER: {
|
||||
new_line = new_line.to_lower();
|
||||
} break;
|
||||
case CAPITALIZE: {
|
||||
new_line = new_line.capitalize();
|
||||
} break;
|
||||
}
|
||||
|
||||
if (i == begin) {
|
||||
new_line = text_editor->get_line(i).left(begin_col) + new_line;
|
||||
}
|
||||
if (i == end) {
|
||||
new_line = new_line + text_editor->get_line(i).right(end_col);
|
||||
}
|
||||
text_editor->set_line(i, new_line);
|
||||
}
|
||||
text_editor->end_complex_operation();
|
||||
}
|
||||
|
||||
void CodeTextEditor::move_lines_up() {
|
||||
text_editor->begin_complex_operation();
|
||||
if (text_editor->is_selection_active()) {
|
||||
int from_line = text_editor->get_selection_from_line();
|
||||
int from_col = text_editor->get_selection_from_column();
|
||||
int to_line = text_editor->get_selection_to_line();
|
||||
int to_column = text_editor->get_selection_to_column();
|
||||
|
||||
for (int i = from_line; i <= to_line; i++) {
|
||||
int line_id = i;
|
||||
int next_id = i - 1;
|
||||
|
||||
if (line_id == 0 || next_id < 0)
|
||||
return;
|
||||
|
||||
text_editor->unfold_line(line_id);
|
||||
text_editor->unfold_line(next_id);
|
||||
|
||||
text_editor->swap_lines(line_id, next_id);
|
||||
text_editor->cursor_set_line(next_id);
|
||||
}
|
||||
int from_line_up = from_line > 0 ? from_line - 1 : from_line;
|
||||
int to_line_up = to_line > 0 ? to_line - 1 : to_line;
|
||||
text_editor->select(from_line_up, from_col, to_line_up, to_column);
|
||||
} else {
|
||||
int line_id = text_editor->cursor_get_line();
|
||||
int next_id = line_id - 1;
|
||||
|
||||
if (line_id == 0 || next_id < 0)
|
||||
return;
|
||||
|
||||
text_editor->unfold_line(line_id);
|
||||
text_editor->unfold_line(next_id);
|
||||
|
||||
text_editor->swap_lines(line_id, next_id);
|
||||
text_editor->cursor_set_line(next_id);
|
||||
}
|
||||
text_editor->end_complex_operation();
|
||||
text_editor->update();
|
||||
}
|
||||
|
||||
void CodeTextEditor::move_lines_down() {
|
||||
text_editor->begin_complex_operation();
|
||||
if (text_editor->is_selection_active()) {
|
||||
int from_line = text_editor->get_selection_from_line();
|
||||
int from_col = text_editor->get_selection_from_column();
|
||||
int to_line = text_editor->get_selection_to_line();
|
||||
int to_column = text_editor->get_selection_to_column();
|
||||
|
||||
for (int i = to_line; i >= from_line; i--) {
|
||||
int line_id = i;
|
||||
int next_id = i + 1;
|
||||
|
||||
if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count())
|
||||
return;
|
||||
|
||||
text_editor->unfold_line(line_id);
|
||||
text_editor->unfold_line(next_id);
|
||||
|
||||
text_editor->swap_lines(line_id, next_id);
|
||||
text_editor->cursor_set_line(next_id);
|
||||
}
|
||||
int from_line_down = from_line < text_editor->get_line_count() ? from_line + 1 : from_line;
|
||||
int to_line_down = to_line < text_editor->get_line_count() ? to_line + 1 : to_line;
|
||||
text_editor->select(from_line_down, from_col, to_line_down, to_column);
|
||||
} else {
|
||||
int line_id = text_editor->cursor_get_line();
|
||||
int next_id = line_id + 1;
|
||||
|
||||
if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count())
|
||||
return;
|
||||
|
||||
text_editor->unfold_line(line_id);
|
||||
text_editor->unfold_line(next_id);
|
||||
|
||||
text_editor->swap_lines(line_id, next_id);
|
||||
text_editor->cursor_set_line(next_id);
|
||||
}
|
||||
text_editor->end_complex_operation();
|
||||
text_editor->update();
|
||||
}
|
||||
|
||||
void CodeTextEditor::delete_lines() {
|
||||
text_editor->begin_complex_operation();
|
||||
if (text_editor->is_selection_active()) {
|
||||
int to_line = text_editor->get_selection_to_line();
|
||||
int from_line = text_editor->get_selection_from_line();
|
||||
int count = Math::abs(to_line - from_line) + 1;
|
||||
while (count) {
|
||||
text_editor->set_line(text_editor->cursor_get_line(), "");
|
||||
text_editor->backspace_at_cursor();
|
||||
count--;
|
||||
if (count)
|
||||
text_editor->unfold_line(from_line);
|
||||
}
|
||||
text_editor->cursor_set_line(from_line - 1);
|
||||
text_editor->deselect();
|
||||
} else {
|
||||
int line = text_editor->cursor_get_line();
|
||||
text_editor->set_line(text_editor->cursor_get_line(), "");
|
||||
text_editor->backspace_at_cursor();
|
||||
text_editor->unfold_line(line);
|
||||
text_editor->cursor_set_line(line);
|
||||
}
|
||||
text_editor->end_complex_operation();
|
||||
}
|
||||
|
||||
void CodeTextEditor::code_lines_down() {
|
||||
int from_line = text_editor->cursor_get_line();
|
||||
int to_line = text_editor->cursor_get_line();
|
||||
int column = text_editor->cursor_get_column();
|
||||
|
||||
if (text_editor->is_selection_active()) {
|
||||
from_line = text_editor->get_selection_from_line();
|
||||
to_line = text_editor->get_selection_to_line();
|
||||
column = text_editor->cursor_get_column();
|
||||
}
|
||||
int next_line = to_line + 1;
|
||||
|
||||
if (to_line >= text_editor->get_line_count() - 1) {
|
||||
text_editor->set_line(to_line, text_editor->get_line(to_line) + "\n");
|
||||
}
|
||||
|
||||
text_editor->begin_complex_operation();
|
||||
for (int i = from_line; i <= to_line; i++) {
|
||||
|
||||
text_editor->unfold_line(i);
|
||||
if (i >= text_editor->get_line_count() - 1) {
|
||||
text_editor->set_line(i, text_editor->get_line(i) + "\n");
|
||||
}
|
||||
String line_clone = text_editor->get_line(i);
|
||||
text_editor->insert_at(line_clone, next_line);
|
||||
next_line++;
|
||||
}
|
||||
|
||||
text_editor->cursor_set_column(column);
|
||||
if (text_editor->is_selection_active()) {
|
||||
text_editor->select(to_line + 1, text_editor->get_selection_from_column(), next_line - 1, text_editor->get_selection_to_column());
|
||||
}
|
||||
|
||||
text_editor->end_complex_operation();
|
||||
text_editor->update();
|
||||
}
|
||||
|
||||
void CodeTextEditor::goto_line(int p_line) {
|
||||
text_editor->deselect();
|
||||
text_editor->unfold_line(p_line);
|
||||
text_editor->call_deferred("cursor_set_line", p_line);
|
||||
}
|
||||
|
||||
void CodeTextEditor::goto_line_selection(int p_line, int p_begin, int p_end) {
|
||||
text_editor->unfold_line(p_line);
|
||||
text_editor->call_deferred("cursor_set_line", p_line);
|
||||
text_editor->call_deferred("cursor_set_column", p_begin);
|
||||
text_editor->select(p_line, p_begin, p_line, p_end);
|
||||
}
|
||||
|
||||
Variant CodeTextEditor::get_edit_state() {
|
||||
Dictionary state;
|
||||
|
||||
state["scroll_position"] = text_editor->get_v_scroll();
|
||||
state["column"] = text_editor->cursor_get_column();
|
||||
state["row"] = text_editor->cursor_get_line();
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void CodeTextEditor::set_edit_state(const Variant &p_state) {
|
||||
Dictionary state = p_state;
|
||||
text_editor->cursor_set_column(state["column"]);
|
||||
text_editor->cursor_set_line(state["row"]);
|
||||
text_editor->set_v_scroll(state["scroll_position"]);
|
||||
text_editor->grab_focus();
|
||||
}
|
||||
|
||||
void CodeTextEditor::set_error(const String &p_error) {
|
||||
|
||||
error->set_text(p_error);
|
||||
|
@ -186,6 +186,29 @@ protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void trim_trailing_whitespace();
|
||||
|
||||
void convert_indent_to_spaces();
|
||||
void convert_indent_to_tabs();
|
||||
|
||||
enum CaseStyle {
|
||||
UPPER,
|
||||
LOWER,
|
||||
CAPITALIZE,
|
||||
};
|
||||
void convert_case(CaseStyle p_case);
|
||||
|
||||
void move_lines_up();
|
||||
void move_lines_down();
|
||||
void delete_lines();
|
||||
void code_lines_down();
|
||||
|
||||
void goto_line(int p_line);
|
||||
void goto_line_selection(int p_line, int p_begin, int p_end);
|
||||
|
||||
Variant get_edit_state();
|
||||
void set_edit_state(const Variant &p_state);
|
||||
|
||||
void update_editor_settings();
|
||||
void set_error(const String &p_error);
|
||||
void update_line_and_column() { _line_col_changed(); }
|
||||
|
@ -112,6 +112,7 @@
|
||||
#include "editor/plugins/sprite_editor_plugin.h"
|
||||
#include "editor/plugins/sprite_frames_editor_plugin.h"
|
||||
#include "editor/plugins/style_box_editor_plugin.h"
|
||||
#include "editor/plugins/text_editor.h"
|
||||
#include "editor/plugins/texture_editor_plugin.h"
|
||||
#include "editor/plugins/texture_region_editor_plugin.h"
|
||||
#include "editor/plugins/theme_editor_plugin.h"
|
||||
@ -5468,6 +5469,7 @@ EditorNode::EditorNode() {
|
||||
EditorAudioBuses *audio_bus_editor = EditorAudioBuses::register_editor();
|
||||
|
||||
ScriptTextEditor::register_editor(); //register one for text scripts
|
||||
TextEditor::register_editor();
|
||||
|
||||
if (StreamPeerSSL::is_available()) {
|
||||
add_editor_plugin(memnew(AssetLibraryEditorPlugin(this)));
|
||||
|
@ -140,6 +140,7 @@ void InspectorDock::_load_resource(const String &p_type) {
|
||||
|
||||
void InspectorDock::_resource_file_selected(String p_file) {
|
||||
RES res = ResourceLoader::load(p_file);
|
||||
|
||||
if (res.is_null()) {
|
||||
warning_dialog->get_ok()->set_text("Ugh");
|
||||
warning_dialog->set_text(TTR("Failed to load resource."));
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "script_editor_plugin.h"
|
||||
|
||||
#include "core/io/resource_loader.h"
|
||||
#include "core/io/resource_saver.h"
|
||||
#include "core/os/file_access.h"
|
||||
#include "core/os/input.h"
|
||||
#include "core/os/keyboard.h"
|
||||
@ -283,7 +282,6 @@ void ScriptEditor::_breaked(bool p_breaked, bool p_can_debug) {
|
||||
|
||||
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
|
||||
if (!se) {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -402,7 +400,10 @@ void ScriptEditor::_go_to_tab(int p_idx) {
|
||||
if (is_visible_in_tree())
|
||||
Object::cast_to<ScriptEditorBase>(c)->ensure_focus();
|
||||
|
||||
notify_script_changed(Object::cast_to<ScriptEditorBase>(c)->get_edited_script());
|
||||
Ref<Script> script = Object::cast_to<ScriptEditorBase>(c)->get_edited_resource();
|
||||
if (script != NULL) {
|
||||
notify_script_changed(script);
|
||||
}
|
||||
}
|
||||
if (Object::cast_to<EditorHelp>(c)) {
|
||||
|
||||
@ -482,12 +483,23 @@ void ScriptEditor::_open_recent_script(int p_idx) {
|
||||
String path = rc[p_idx];
|
||||
// if its not on disk its a help file or deleted
|
||||
if (FileAccess::exists(path)) {
|
||||
Ref<Script> script = ResourceLoader::load(path);
|
||||
if (script.is_valid()) {
|
||||
edit(script, true);
|
||||
return;
|
||||
List<String> extensions;
|
||||
ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
|
||||
|
||||
if (extensions.find(path.get_extension())) {
|
||||
Ref<Script> script = ResourceLoader::load(path);
|
||||
if (script.is_valid()) {
|
||||
edit(script, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Error err;
|
||||
Ref<TextFile> text_file = _load_text_file(path, &err);
|
||||
if (text_file.is_valid()) {
|
||||
edit(text_file, true);
|
||||
return;
|
||||
}
|
||||
// if it's a path then its most likely a deleted file not help
|
||||
} else if (!path.is_resource_file()) {
|
||||
_help_class_open(path);
|
||||
@ -513,12 +525,17 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
|
||||
return;
|
||||
|
||||
Node *tselected = tab_container->get_child(selected);
|
||||
|
||||
ScriptEditorBase *current = Object::cast_to<ScriptEditorBase>(tab_container->get_child(selected));
|
||||
if (current) {
|
||||
if (p_save) {
|
||||
apply_scripts();
|
||||
}
|
||||
notify_script_close(current->get_edited_script());
|
||||
|
||||
Ref<Script> script = current->get_edited_resource();
|
||||
if (script != NULL) {
|
||||
notify_script_close(script);
|
||||
}
|
||||
}
|
||||
|
||||
// roll back to previous tab
|
||||
@ -589,7 +606,7 @@ void ScriptEditor::_close_docs_tab() {
|
||||
|
||||
void ScriptEditor::_copy_script_path() {
|
||||
ScriptEditorBase *se = _get_current_editor();
|
||||
Ref<Script> script = se->get_edited_script();
|
||||
RES script = se->get_edited_resource();
|
||||
OS::get_singleton()->set_clipboard(script->get_path());
|
||||
}
|
||||
|
||||
@ -655,7 +672,7 @@ void ScriptEditor::_resave_scripts(const String &p_str) {
|
||||
if (!se)
|
||||
continue;
|
||||
|
||||
Ref<Script> script = se->get_edited_script();
|
||||
RES script = se->get_edited_resource();
|
||||
|
||||
if (script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1)
|
||||
continue; //internal script, who cares
|
||||
@ -672,7 +689,14 @@ void ScriptEditor::_resave_scripts(const String &p_str) {
|
||||
}
|
||||
}
|
||||
|
||||
editor->save_resource(script);
|
||||
Ref<TextFile> text_file = script;
|
||||
if (text_file != NULL) {
|
||||
se->apply_code();
|
||||
_save_text_file(text_file, text_file->get_path());
|
||||
break;
|
||||
} else {
|
||||
editor->save_resource(script);
|
||||
}
|
||||
se->tag_saved_version();
|
||||
}
|
||||
|
||||
@ -689,25 +713,37 @@ void ScriptEditor::_reload_scripts() {
|
||||
continue;
|
||||
}
|
||||
|
||||
Ref<Script> script = se->get_edited_script();
|
||||
RES edited_res = se->get_edited_resource();
|
||||
|
||||
if (script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1) {
|
||||
if (edited_res->get_path() == "" || edited_res->get_path().find("local://") != -1 || edited_res->get_path().find("::") != -1) {
|
||||
|
||||
continue; //internal script, who cares
|
||||
}
|
||||
|
||||
uint64_t last_date = script->get_last_modified_time();
|
||||
uint64_t date = FileAccess::get_modified_time(script->get_path());
|
||||
uint64_t last_date = edited_res->get_last_modified_time();
|
||||
uint64_t date = FileAccess::get_modified_time(edited_res->get_path());
|
||||
|
||||
if (last_date == date) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), true);
|
||||
ERR_CONTINUE(!rel_script.is_valid());
|
||||
script->set_source_code(rel_script->get_source_code());
|
||||
script->set_last_modified_time(rel_script->get_last_modified_time());
|
||||
script->reload();
|
||||
Ref<Script> script = edited_res;
|
||||
if (script != NULL) {
|
||||
Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), true);
|
||||
ERR_CONTINUE(!rel_script.is_valid());
|
||||
script->set_source_code(rel_script->get_source_code());
|
||||
script->set_last_modified_time(rel_script->get_last_modified_time());
|
||||
script->reload();
|
||||
}
|
||||
|
||||
Ref<TextFile> text_file = edited_res;
|
||||
if (text_file != NULL) {
|
||||
Error err;
|
||||
Ref<TextFile> rel_text_file = _load_text_file(text_file->get_path(), &err);
|
||||
ERR_CONTINUE(!rel_text_file.is_valid());
|
||||
text_file->set_text(rel_text_file->get_text());
|
||||
text_file->set_last_modified_time(rel_text_file->get_last_modified_time());
|
||||
}
|
||||
se->reload_text();
|
||||
}
|
||||
|
||||
@ -725,7 +761,7 @@ void ScriptEditor::_res_saved_callback(const Ref<Resource> &p_res) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Ref<Script> script = se->get_edited_script();
|
||||
RES script = se->get_edited_resource();
|
||||
|
||||
if (script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1) {
|
||||
continue; //internal script, who cares
|
||||
@ -750,7 +786,7 @@ void ScriptEditor::_live_auto_reload_running_scripts() {
|
||||
debugger->reload_scripts();
|
||||
}
|
||||
|
||||
bool ScriptEditor::_test_script_times_on_disk(Ref<Script> p_for_script) {
|
||||
bool ScriptEditor::_test_script_times_on_disk(RES p_for_script) {
|
||||
|
||||
disk_changed_list->clear();
|
||||
TreeItem *r = disk_changed_list->create_item();
|
||||
@ -765,21 +801,20 @@ bool ScriptEditor::_test_script_times_on_disk(Ref<Script> p_for_script) {
|
||||
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
|
||||
if (se) {
|
||||
|
||||
Ref<Script> script = se->get_edited_script();
|
||||
|
||||
if (p_for_script.is_valid() && p_for_script != script)
|
||||
RES edited_res = se->get_edited_resource();
|
||||
if (edited_res.is_valid() && p_for_script != edited_res)
|
||||
continue;
|
||||
|
||||
if (script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1)
|
||||
if (edited_res->get_path() == "" || edited_res->get_path().find("local://") != -1 || edited_res->get_path().find("::") != -1)
|
||||
continue; //internal script, who cares
|
||||
|
||||
uint64_t last_date = script->get_last_modified_time();
|
||||
uint64_t date = FileAccess::get_modified_time(script->get_path());
|
||||
uint64_t last_date = edited_res->get_last_modified_time();
|
||||
uint64_t date = FileAccess::get_modified_time(edited_res->get_path());
|
||||
|
||||
if (last_date != date) {
|
||||
|
||||
TreeItem *ti = disk_changed_list->create_item(r);
|
||||
ti->set_text(0, script->get_path().get_file());
|
||||
ti->set_text(0, edited_res->get_path().get_file());
|
||||
|
||||
if (!use_autoreload || se->is_unsaved()) {
|
||||
need_ask = true;
|
||||
@ -804,6 +839,49 @@ bool ScriptEditor::_test_script_times_on_disk(Ref<Script> p_for_script) {
|
||||
void ScriptEditor::_file_dialog_action(String p_file) {
|
||||
|
||||
switch (file_dialog_option) {
|
||||
case FILE_OPEN: {
|
||||
|
||||
List<String> extensions;
|
||||
ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
|
||||
if (extensions.find(p_file.get_extension())) {
|
||||
Ref<Script> scr = ResourceLoader::load(p_file);
|
||||
if (!scr.is_valid()) {
|
||||
editor->show_warning(TTR("Error could not load file."), TTR("Error!"));
|
||||
file_dialog_option = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
edit(scr);
|
||||
file_dialog_option = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
Error error;
|
||||
Ref<TextFile> text_file = _load_text_file(p_file, &error);
|
||||
if (error != OK) {
|
||||
editor->show_warning(TTR("Error could not load file."), TTR("Error!"));
|
||||
}
|
||||
|
||||
if (text_file.is_valid()) {
|
||||
edit(text_file);
|
||||
file_dialog_option = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
case FILE_SAVE_AS: {
|
||||
ScriptEditorBase *current = _get_current_editor();
|
||||
|
||||
String path = ProjectSettings::get_singleton()->localize_path(p_file);
|
||||
Error err = _save_text_file(current->get_edited_resource(), path);
|
||||
|
||||
if (err != OK) {
|
||||
editor->show_accept(TTR("Error saving file!"), TTR("OK"));
|
||||
return;
|
||||
}
|
||||
|
||||
((Resource *)current->get_edited_resource().ptr())->set_path(path);
|
||||
_update_script_names();
|
||||
} break;
|
||||
case THEME_SAVE_AS: {
|
||||
if (!EditorSettings::get_singleton()->save_text_editor_theme_as(p_file)) {
|
||||
editor->show_warning(TTR("Error while saving theme"), TTR("Error saving"));
|
||||
@ -823,7 +901,8 @@ Ref<Script> ScriptEditor::_get_current_script() {
|
||||
ScriptEditorBase *current = _get_current_editor();
|
||||
|
||||
if (current) {
|
||||
return current->get_edited_script();
|
||||
Ref<Script> script = current->get_edited_resource();
|
||||
return script != NULL ? script : NULL;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
@ -848,8 +927,19 @@ void ScriptEditor::_menu_option(int p_option) {
|
||||
script_create_dialog->popup_centered(Size2(300, 300) * EDSCALE);
|
||||
} break;
|
||||
case FILE_OPEN: {
|
||||
file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE);
|
||||
file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
|
||||
file_dialog_option = FILE_OPEN;
|
||||
|
||||
editor->open_resource("Script");
|
||||
List<String> extensions;
|
||||
ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
|
||||
file_dialog->clear_filters();
|
||||
for (int i = 0; i < extensions.size(); i++) {
|
||||
file_dialog->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
|
||||
}
|
||||
|
||||
file_dialog->popup_centered_ratio();
|
||||
file_dialog->set_title(TTR("Open File"));
|
||||
return;
|
||||
} break;
|
||||
case FILE_SAVE_ALL: {
|
||||
@ -929,7 +1019,14 @@ void ScriptEditor::_menu_option(int p_option) {
|
||||
current->convert_indent_to_tabs();
|
||||
}
|
||||
}
|
||||
editor->save_resource(current->get_edited_script());
|
||||
|
||||
Ref<TextFile> text_file = current->get_edited_resource();
|
||||
if (text_file != NULL) {
|
||||
current->apply_code();
|
||||
_save_text_file(text_file, text_file->get_path());
|
||||
break;
|
||||
}
|
||||
editor->save_resource(current->get_edited_resource());
|
||||
|
||||
} break;
|
||||
case FILE_SAVE_AS: {
|
||||
@ -943,8 +1040,25 @@ void ScriptEditor::_menu_option(int p_option) {
|
||||
current->convert_indent_to_tabs();
|
||||
}
|
||||
}
|
||||
editor->push_item(Object::cast_to<Object>(current->get_edited_script().ptr()));
|
||||
editor->save_resource_as(current->get_edited_script());
|
||||
|
||||
Ref<TextFile> text_file = current->get_edited_resource();
|
||||
if (text_file != NULL) {
|
||||
file_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
|
||||
file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
|
||||
file_dialog_option = FILE_SAVE_AS;
|
||||
|
||||
List<String> extensions;
|
||||
ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
|
||||
file_dialog->clear_filters();
|
||||
file_dialog->set_current_dir(text_file->get_path().get_base_dir());
|
||||
file_dialog->set_current_file(text_file->get_path().get_file());
|
||||
file_dialog->popup_centered_ratio();
|
||||
file_dialog->set_title(TTR("Save File As..."));
|
||||
break;
|
||||
}
|
||||
|
||||
editor->push_item(Object::cast_to<Object>(current->get_edited_resource().ptr()));
|
||||
editor->save_resource_as(current->get_edited_resource());
|
||||
|
||||
} break;
|
||||
|
||||
@ -956,8 +1070,8 @@ void ScriptEditor::_menu_option(int p_option) {
|
||||
} break;
|
||||
case FILE_RUN: {
|
||||
|
||||
Ref<Script> scr = current->get_edited_script();
|
||||
if (scr.is_null()) {
|
||||
Ref<Script> scr = current->get_edited_resource();
|
||||
if (scr == NULL || scr.is_null()) {
|
||||
EditorNode::get_singleton()->show_warning("Can't obtain the script for running");
|
||||
break;
|
||||
}
|
||||
@ -1000,8 +1114,7 @@ void ScriptEditor::_menu_option(int p_option) {
|
||||
_copy_script_path();
|
||||
} break;
|
||||
case SHOW_IN_FILE_SYSTEM: {
|
||||
ScriptEditorBase *se = _get_current_editor();
|
||||
Ref<Script> script = se->get_edited_script();
|
||||
RES script = current->get_edited_resource();
|
||||
FileSystemDock *file_system_dock = EditorNode::get_singleton()->get_filesystem_dock();
|
||||
file_system_dock->navigate_to_path(script->get_path());
|
||||
// Ensure that the FileSystem dock is visible.
|
||||
@ -1259,8 +1372,8 @@ void ScriptEditor::close_builtin_scripts_from_scene(const String &p_scene) {
|
||||
|
||||
if (se) {
|
||||
|
||||
Ref<Script> script = se->get_edited_script();
|
||||
if (!script.is_valid())
|
||||
Ref<Script> script = se->get_edited_resource();
|
||||
if (script == NULL || !script.is_valid())
|
||||
continue;
|
||||
|
||||
if (script->get_path().find("::") != -1 && script->get_path().begins_with(p_scene)) { //is an internal script and belongs to scene being closed
|
||||
@ -1307,9 +1420,13 @@ void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
|
||||
if (!se)
|
||||
continue;
|
||||
|
||||
Ref<Script> script = se->get_edited_resource();
|
||||
if (script == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<int> bpoints;
|
||||
se->get_breakpoints(&bpoints);
|
||||
Ref<Script> script = se->get_edited_script();
|
||||
String base = script->get_path();
|
||||
ERR_CONTINUE(base.begins_with("local://") || base == "");
|
||||
|
||||
@ -1452,7 +1569,7 @@ void ScriptEditor::_update_members_overview() {
|
||||
members_overview->set_item_metadata(i, functions[i].get_slice(":", 1).to_int() - 1);
|
||||
}
|
||||
|
||||
String path = se->get_edited_script()->get_path();
|
||||
String path = se->get_edited_resource()->get_path();
|
||||
bool built_in = !path.is_resource_file();
|
||||
String name = built_in ? path.get_file() : se->get_name();
|
||||
filename->set_text(name);
|
||||
@ -1570,7 +1687,7 @@ void ScriptEditor::_update_script_names() {
|
||||
if (se) {
|
||||
|
||||
Ref<Texture> icon = se->get_icon();
|
||||
String path = se->get_edited_script()->get_path();
|
||||
String path = se->get_edited_resource()->get_path();
|
||||
bool built_in = !path.is_resource_file();
|
||||
String name = built_in ? path.get_file() : se->get_name();
|
||||
|
||||
@ -1579,7 +1696,7 @@ void ScriptEditor::_update_script_names() {
|
||||
sd.name = name;
|
||||
sd.tooltip = path;
|
||||
sd.index = i;
|
||||
sd.used = used.has(se->get_edited_script());
|
||||
sd.used = used.has(se->get_edited_resource());
|
||||
sd.category = 0;
|
||||
sd.ref = se;
|
||||
|
||||
@ -1681,11 +1798,65 @@ void ScriptEditor::_update_script_names() {
|
||||
_update_script_colors();
|
||||
}
|
||||
|
||||
bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool p_grab_focus) {
|
||||
Ref<TextFile> ScriptEditor::_load_text_file(const String &p_path, Error *r_error) {
|
||||
if (r_error) {
|
||||
*r_error = ERR_FILE_CANT_OPEN;
|
||||
}
|
||||
|
||||
if (p_script.is_null())
|
||||
String local_path = ProjectSettings::get_singleton()->localize_path(p_path);
|
||||
String path = ResourceLoader::path_remap(local_path);
|
||||
|
||||
TextFile *text_file = memnew(TextFile);
|
||||
Ref<TextFile> text_res(text_file);
|
||||
Error err = text_file->load_text(path);
|
||||
|
||||
if (err != OK) {
|
||||
ERR_FAIL_COND_V(err != OK, RES());
|
||||
}
|
||||
|
||||
text_file->set_file_path(local_path);
|
||||
text_file->set_path(local_path, true);
|
||||
|
||||
if (r_error) {
|
||||
*r_error = OK;
|
||||
}
|
||||
|
||||
return text_res;
|
||||
}
|
||||
|
||||
Error ScriptEditor::_save_text_file(Ref<TextFile> p_text_file, const String &p_path) {
|
||||
Ref<TextFile> sqscr = p_text_file;
|
||||
ERR_FAIL_COND_V(sqscr.is_null(), ERR_INVALID_PARAMETER);
|
||||
|
||||
String source = sqscr->get_text();
|
||||
|
||||
Error err;
|
||||
FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err);
|
||||
|
||||
if (err) {
|
||||
|
||||
ERR_FAIL_COND_V(err, err);
|
||||
}
|
||||
|
||||
file->store_string(source);
|
||||
if (file->get_error() != OK && file->get_error() != ERR_FILE_EOF) {
|
||||
memdelete(file);
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
file->close();
|
||||
memdelete(file);
|
||||
|
||||
_res_saved_callback(sqscr);
|
||||
return OK;
|
||||
}
|
||||
|
||||
bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_grab_focus) {
|
||||
|
||||
if (p_resource.is_null())
|
||||
return false;
|
||||
|
||||
Ref<Script> script = p_resource;
|
||||
|
||||
// refuse to open built-in if scene is not loaded
|
||||
|
||||
// see if already has it
|
||||
@ -1694,17 +1865,17 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
|
||||
|
||||
const bool should_open = open_dominant || !EditorNode::get_singleton()->is_changing_scene();
|
||||
|
||||
if (p_script->get_language()->overrides_external_editor()) {
|
||||
if (script != NULL && script->get_language()->overrides_external_editor()) {
|
||||
if (should_open) {
|
||||
Error err = p_script->get_language()->open_in_external_editor(p_script, p_line >= 0 ? p_line : 0, p_col);
|
||||
Error err = script->get_language()->open_in_external_editor(script, p_line >= 0 ? p_line : 0, p_col);
|
||||
if (err != OK)
|
||||
ERR_PRINT("Couldn't open script in the overridden external text editor");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((debugger->get_dump_stack_script() != p_script || debugger->get_debug_with_external_editor()) &&
|
||||
p_script->get_path().is_resource_file() &&
|
||||
if ((debugger->get_dump_stack_script() != p_resource || debugger->get_debug_with_external_editor()) &&
|
||||
p_resource->get_path().is_resource_file() &&
|
||||
bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) {
|
||||
|
||||
String path = EditorSettings::get_singleton()->get("text_editor/external/exec_path");
|
||||
@ -1714,7 +1885,7 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
|
||||
|
||||
if (flags.size()) {
|
||||
String project_path = ProjectSettings::get_singleton()->get_resource_path();
|
||||
String script_path = ProjectSettings::get_singleton()->globalize_path(p_script->get_path());
|
||||
String script_path = ProjectSettings::get_singleton()->globalize_path(p_resource->get_path());
|
||||
|
||||
flags = flags.replacen("{line}", itos(p_line > 0 ? p_line : 0));
|
||||
flags = flags.replacen("{col}", itos(p_col));
|
||||
@ -1762,7 +1933,7 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
|
||||
if (!se)
|
||||
continue;
|
||||
|
||||
if (se->get_edited_script() == p_script) {
|
||||
if (se->get_edited_resource() == p_resource) {
|
||||
|
||||
if (should_open) {
|
||||
if (tab_container->get_current_tab() != i) {
|
||||
@ -1784,7 +1955,7 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
|
||||
ScriptEditorBase *se;
|
||||
|
||||
for (int i = script_editor_func_count - 1; i >= 0; i--) {
|
||||
se = script_editor_funcs[i](p_script);
|
||||
se = script_editor_funcs[i](p_resource);
|
||||
if (se)
|
||||
break;
|
||||
}
|
||||
@ -1795,9 +1966,9 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
|
||||
SyntaxHighlighter *highlighter = syntax_highlighters_funcs[i]();
|
||||
se->add_syntax_highlighter(highlighter);
|
||||
|
||||
if (!highlighter_set) {
|
||||
if (script != NULL && !highlighter_set) {
|
||||
List<String> languages = highlighter->get_supported_languages();
|
||||
if (languages.find(p_script->get_language()->get_name())) {
|
||||
if (languages.find(script->get_language()->get_name())) {
|
||||
se->set_syntax_highlighter(highlighter);
|
||||
highlighter_set = true;
|
||||
}
|
||||
@ -1805,7 +1976,7 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
|
||||
}
|
||||
|
||||
tab_container->add_child(se);
|
||||
se->set_edited_script(p_script);
|
||||
se->set_edited_resource(p_resource);
|
||||
se->set_tooltip_request_func("_get_debug_tooltip", this);
|
||||
if (se->get_edit_menu()) {
|
||||
se->get_edit_menu()->hide();
|
||||
@ -1829,14 +2000,14 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
|
||||
|
||||
//test for modification, maybe the script was not edited but was loaded
|
||||
|
||||
_test_script_times_on_disk(p_script);
|
||||
_update_modified_scripts_for_external_editor(p_script);
|
||||
_test_script_times_on_disk(p_resource);
|
||||
_update_modified_scripts_for_external_editor(p_resource);
|
||||
|
||||
if (p_line >= 0)
|
||||
se->goto_line(p_line - 1);
|
||||
|
||||
notify_script_changed(p_script);
|
||||
_add_recent_script(p_script->get_path());
|
||||
notify_script_changed(p_resource);
|
||||
_add_recent_script(p_resource->get_path());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1863,12 +2034,19 @@ void ScriptEditor::save_all_scripts() {
|
||||
if (!se->is_unsaved())
|
||||
continue;
|
||||
|
||||
Ref<Script> script = se->get_edited_script();
|
||||
if (script.is_valid())
|
||||
RES edited_res = se->get_edited_resource();
|
||||
if (edited_res.is_valid()) {
|
||||
se->apply_code();
|
||||
}
|
||||
|
||||
if (script->get_path() != "" && script->get_path().find("local://") == -1 && script->get_path().find("::") == -1)
|
||||
editor->save_resource(script); //external script, save it
|
||||
if (edited_res->get_path() != "" && edited_res->get_path().find("local://") == -1 && edited_res->get_path().find("::") == -1) {
|
||||
Ref<TextFile> text_file = edited_res;
|
||||
if (text_file != NULL) {
|
||||
_save_text_file(text_file, text_file->get_path());
|
||||
continue;
|
||||
}
|
||||
editor->save_resource(edited_res); //external script, save it
|
||||
}
|
||||
}
|
||||
|
||||
_update_script_names();
|
||||
@ -1938,7 +2116,7 @@ void ScriptEditor::_add_callback(Object *p_obj, const String &p_function, const
|
||||
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
|
||||
if (!se)
|
||||
continue;
|
||||
if (se->get_edited_script() != script)
|
||||
if (se->get_edited_resource() != script)
|
||||
continue;
|
||||
|
||||
se->add_callback(p_function, p_args);
|
||||
@ -2228,9 +2406,12 @@ void ScriptEditor::_make_script_list_context_menu() {
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_other_tabs"), CLOSE_OTHER_TABS);
|
||||
context_menu->add_separator();
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/copy_path"), FILE_COPY_PATH);
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/reload_script_soft"), FILE_TOOL_RELOAD_SOFT);
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/show_in_file_system"), SHOW_IN_FILE_SYSTEM);
|
||||
Ref<Script> scr = se->get_edited_script();
|
||||
}
|
||||
|
||||
Ref<Script> scr = se->get_edited_resource();
|
||||
if (scr != NULL) {
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/reload_script_soft"), FILE_TOOL_RELOAD_SOFT);
|
||||
if (!scr.is_null() && scr->is_tool()) {
|
||||
context_menu->add_separator();
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/run_file"), FILE_RUN);
|
||||
@ -2266,14 +2447,28 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
|
||||
|
||||
restoring_layout = true;
|
||||
|
||||
List<String> extensions;
|
||||
ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
|
||||
|
||||
for (int i = 0; i < scripts.size(); i++) {
|
||||
|
||||
String path = scripts[i];
|
||||
if (!FileAccess::exists(path))
|
||||
continue;
|
||||
Ref<Script> scr = ResourceLoader::load(path);
|
||||
if (scr.is_valid()) {
|
||||
edit(scr);
|
||||
|
||||
if (extensions.find(path.get_extension())) {
|
||||
Ref<Script> scr = ResourceLoader::load(path);
|
||||
if (scr.is_valid()) {
|
||||
edit(scr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Error error;
|
||||
Ref<TextFile> text_file = _load_text_file(path, &error);
|
||||
if (error == OK && text_file.is_valid()) {
|
||||
edit(text_file);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2309,7 +2504,7 @@ void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) {
|
||||
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
|
||||
if (se) {
|
||||
|
||||
String path = se->get_edited_script()->get_path();
|
||||
String path = se->get_edited_resource()->get_path();
|
||||
if (!path.is_resource_file())
|
||||
continue;
|
||||
|
||||
@ -2434,7 +2629,10 @@ void ScriptEditor::_update_history_pos(int p_new_pos) {
|
||||
Object::cast_to<ScriptEditorBase>(n)->set_edit_state(history[history_pos].state);
|
||||
Object::cast_to<ScriptEditorBase>(n)->ensure_focus();
|
||||
|
||||
notify_script_changed(Object::cast_to<ScriptEditorBase>(n)->get_edited_script());
|
||||
Ref<Script> script = Object::cast_to<ScriptEditorBase>(n)->get_edited_resource();
|
||||
if (script != NULL) {
|
||||
notify_script_changed(script);
|
||||
}
|
||||
}
|
||||
|
||||
if (Object::cast_to<EditorHelp>(n)) {
|
||||
@ -2471,7 +2669,11 @@ Vector<Ref<Script> > ScriptEditor::get_open_scripts() const {
|
||||
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
|
||||
if (!se)
|
||||
continue;
|
||||
out_scripts.push_back(se->get_edited_script());
|
||||
|
||||
Ref<Script> script = se->get_edited_resource();
|
||||
if (script != NULL) {
|
||||
out_scripts.push_back(script);
|
||||
}
|
||||
}
|
||||
|
||||
return out_scripts;
|
||||
@ -2517,6 +2719,14 @@ void ScriptEditor::_open_script_request(const String &p_path) {
|
||||
Ref<Script> script = ResourceLoader::load(p_path);
|
||||
if (script.is_valid()) {
|
||||
script_editor->edit(script, false);
|
||||
return;
|
||||
}
|
||||
|
||||
Error err;
|
||||
Ref<TextFile> text_file = script_editor->_load_text_file(p_path, &err);
|
||||
if (text_file.is_valid()) {
|
||||
script_editor->edit(text_file, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2550,7 +2760,7 @@ void ScriptEditor::_on_find_in_files_requested(String text) {
|
||||
|
||||
void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_number, int begin, int end) {
|
||||
|
||||
Ref<Resource> res = ResourceLoader::load(fpath);
|
||||
RES res = ResourceLoader::load(fpath);
|
||||
edit(res);
|
||||
|
||||
ScriptEditorBase *seb = _get_current_editor();
|
||||
@ -2966,14 +3176,21 @@ ScriptEditor::~ScriptEditor() {
|
||||
|
||||
void ScriptEditorPlugin::edit(Object *p_object) {
|
||||
|
||||
if (!Object::cast_to<Script>(p_object))
|
||||
return;
|
||||
if (Object::cast_to<Script>(p_object)) {
|
||||
script_editor->edit(Object::cast_to<Script>(p_object));
|
||||
}
|
||||
|
||||
script_editor->edit(Object::cast_to<Script>(p_object));
|
||||
if (Object::cast_to<TextFile>(p_object)) {
|
||||
script_editor->edit(Object::cast_to<TextFile>(p_object));
|
||||
}
|
||||
}
|
||||
|
||||
bool ScriptEditorPlugin::handles(Object *p_object) const {
|
||||
|
||||
if (Object::cast_to<TextFile>(p_object)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Object::cast_to<Script>(p_object)) {
|
||||
|
||||
bool valid = _can_open_in_editor(Object::cast_to<Script>(p_object));
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "scene/gui/tool_button.h"
|
||||
#include "scene/gui/tree.h"
|
||||
#include "scene/main/timer.h"
|
||||
#include "scene/resources/text_file.h"
|
||||
#include "script_language.h"
|
||||
|
||||
class ScriptEditorQuickOpen : public ConfirmationDialog {
|
||||
@ -74,7 +75,7 @@ class ScriptEditorDebugger;
|
||||
|
||||
class ScriptEditorBase : public VBoxContainer {
|
||||
|
||||
GDCLASS(ScriptEditorBase, VBoxContainer);
|
||||
GDCLASS(ScriptEditorBase, VBoxContainer)
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
@ -84,9 +85,9 @@ public:
|
||||
virtual void set_syntax_highlighter(SyntaxHighlighter *p_highlighter) = 0;
|
||||
|
||||
virtual void apply_code() = 0;
|
||||
virtual Ref<Script> get_edited_script() const = 0;
|
||||
virtual RES get_edited_resource() const = 0;
|
||||
virtual Vector<String> get_functions() = 0;
|
||||
virtual void set_edited_script(const Ref<Script> &p_script) = 0;
|
||||
virtual void set_edited_resource(const RES &p_res) = 0;
|
||||
virtual void reload_text() = 0;
|
||||
virtual String get_name() = 0;
|
||||
virtual Ref<Texture> get_icon() = 0;
|
||||
@ -99,7 +100,7 @@ public:
|
||||
virtual void convert_indent_to_tabs() = 0;
|
||||
virtual void ensure_focus() = 0;
|
||||
virtual void tag_saved_version() = 0;
|
||||
virtual void reload(bool p_soft) = 0;
|
||||
virtual void reload(bool p_soft) {}
|
||||
virtual void get_breakpoints(List<int> *p_breakpoints) = 0;
|
||||
virtual void add_callback(const String &p_function, PoolStringArray p_args) = 0;
|
||||
virtual void update_settings() = 0;
|
||||
@ -116,7 +117,7 @@ public:
|
||||
};
|
||||
|
||||
typedef SyntaxHighlighter *(*CreateSyntaxHighlighterFunc)();
|
||||
typedef ScriptEditorBase *(*CreateScriptEditorFunc)(const Ref<Script> &p_script);
|
||||
typedef ScriptEditorBase *(*CreateScriptEditorFunc)(const RES &p_resource);
|
||||
|
||||
class EditorScriptCodeCompletionCache;
|
||||
class FindInFilesDialog;
|
||||
@ -268,7 +269,7 @@ class ScriptEditor : public PanelContainer {
|
||||
void _resave_scripts(const String &p_str);
|
||||
void _reload_scripts();
|
||||
|
||||
bool _test_script_times_on_disk(Ref<Script> p_for_script = Ref<Script>());
|
||||
bool _test_script_times_on_disk(RES p_for_script = Ref<Resource>());
|
||||
|
||||
void _add_recent_script(String p_path);
|
||||
void _update_recent_scripts();
|
||||
@ -378,6 +379,9 @@ class ScriptEditor : public PanelContainer {
|
||||
Ref<Script> _get_current_script();
|
||||
Array _get_open_scripts() const;
|
||||
|
||||
Ref<TextFile> _load_text_file(const String &p_path, Error *r_error);
|
||||
Error _save_text_file(Ref<TextFile> p_text_file, const String &p_path);
|
||||
|
||||
void _on_find_in_files_requested(String text);
|
||||
void _on_find_in_files_result_selected(String fpath, int line_number, int begin, int end);
|
||||
void _start_find_in_files(bool with_replace);
|
||||
@ -400,8 +404,8 @@ public:
|
||||
|
||||
void ensure_select_current();
|
||||
|
||||
_FORCE_INLINE_ bool edit(const Ref<Script> &p_script, bool p_grab_focus = true) { return edit(p_script, -1, 0, p_grab_focus); }
|
||||
bool edit(const Ref<Script> &p_script, int p_line, int p_col, bool p_grab_focus = true);
|
||||
_FORCE_INLINE_ bool edit(const RES &p_resource, bool p_grab_focus = true) { return edit(p_resource, -1, 0, p_grab_focus); }
|
||||
bool edit(const RES &p_resource, int p_line, int p_col, bool p_grab_focus = true);
|
||||
|
||||
void get_breakpoints(List<String> *p_breakpoints);
|
||||
|
||||
|
@ -66,11 +66,24 @@ void ScriptTextEditor::apply_code() {
|
||||
_update_member_keywords();
|
||||
}
|
||||
|
||||
Ref<Script> ScriptTextEditor::get_edited_script() const {
|
||||
|
||||
RES ScriptTextEditor::get_edited_resource() const {
|
||||
return script;
|
||||
}
|
||||
|
||||
void ScriptTextEditor::set_edited_resource(const RES &p_res) {
|
||||
ERR_FAIL_COND(!script.is_null());
|
||||
|
||||
script = p_res;
|
||||
_set_theme_for_script();
|
||||
|
||||
code_editor->get_text_edit()->set_text(script->get_source_code());
|
||||
code_editor->get_text_edit()->clear_undo_history();
|
||||
code_editor->get_text_edit()->tag_saved_version();
|
||||
|
||||
emit_signal("name_changed");
|
||||
code_editor->update_line_and_column();
|
||||
}
|
||||
|
||||
void ScriptTextEditor::_update_member_keywords() {
|
||||
member_keywords.clear();
|
||||
code_editor->get_text_edit()->clear_member_keywords();
|
||||
@ -190,6 +203,7 @@ void ScriptTextEditor::_set_theme_for_script() {
|
||||
|
||||
List<String> keywords;
|
||||
script->get_language()->get_reserved_words(&keywords);
|
||||
|
||||
for (List<String>::Element *E = keywords.front(); E; E = E->next()) {
|
||||
|
||||
text_edit->add_keyword_color(E->get(), colors_cache.keyword_color);
|
||||
@ -251,7 +265,6 @@ void ScriptTextEditor::_set_theme_for_script() {
|
||||
//colorize strings
|
||||
List<String> strings;
|
||||
script->get_language()->get_string_delimiters(&strings);
|
||||
|
||||
for (List<String>::Element *E = strings.front(); E; E = E->next()) {
|
||||
|
||||
String string = E->get();
|
||||
@ -326,197 +339,32 @@ bool ScriptTextEditor::is_unsaved() {
|
||||
|
||||
Variant ScriptTextEditor::get_edit_state() {
|
||||
|
||||
Dictionary state;
|
||||
|
||||
state["scroll_position"] = code_editor->get_text_edit()->get_v_scroll();
|
||||
state["column"] = code_editor->get_text_edit()->cursor_get_column();
|
||||
state["row"] = code_editor->get_text_edit()->cursor_get_line();
|
||||
|
||||
return state;
|
||||
return code_editor->get_edit_state();
|
||||
}
|
||||
|
||||
void ScriptTextEditor::_convert_case(CaseStyle p_case) {
|
||||
TextEdit *te = code_editor->get_text_edit();
|
||||
Ref<Script> scr = get_edited_script();
|
||||
if (scr.is_null()) {
|
||||
return;
|
||||
}
|
||||
void ScriptTextEditor::set_edit_state(const Variant &p_state) {
|
||||
|
||||
if (te->is_selection_active()) {
|
||||
te->begin_complex_operation();
|
||||
code_editor->set_edit_state(p_state);
|
||||
}
|
||||
|
||||
int begin = te->get_selection_from_line();
|
||||
int end = te->get_selection_to_line();
|
||||
int begin_col = te->get_selection_from_column();
|
||||
int end_col = te->get_selection_to_column();
|
||||
void ScriptTextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) {
|
||||
|
||||
for (int i = begin; i <= end; i++) {
|
||||
int len = te->get_line(i).length();
|
||||
if (i == end)
|
||||
len -= len - end_col;
|
||||
if (i == begin)
|
||||
len -= begin_col;
|
||||
String new_line = te->get_line(i).substr(i == begin ? begin_col : 0, len);
|
||||
|
||||
switch (p_case) {
|
||||
case UPPER: {
|
||||
new_line = new_line.to_upper();
|
||||
} break;
|
||||
case LOWER: {
|
||||
new_line = new_line.to_lower();
|
||||
} break;
|
||||
case CAPITALIZE: {
|
||||
new_line = new_line.capitalize();
|
||||
} break;
|
||||
}
|
||||
|
||||
if (i == begin) {
|
||||
new_line = te->get_line(i).left(begin_col) + new_line;
|
||||
}
|
||||
if (i == end) {
|
||||
new_line = new_line + te->get_line(i).right(end_col);
|
||||
}
|
||||
te->set_line(i, new_line);
|
||||
}
|
||||
te->end_complex_operation();
|
||||
}
|
||||
code_editor->convert_case(p_case);
|
||||
}
|
||||
|
||||
void ScriptTextEditor::trim_trailing_whitespace() {
|
||||
|
||||
TextEdit *tx = code_editor->get_text_edit();
|
||||
|
||||
bool trimed_whitespace = false;
|
||||
for (int i = 0; i < tx->get_line_count(); i++) {
|
||||
String line = tx->get_line(i);
|
||||
if (line.ends_with(" ") || line.ends_with("\t")) {
|
||||
|
||||
if (!trimed_whitespace) {
|
||||
tx->begin_complex_operation();
|
||||
trimed_whitespace = true;
|
||||
}
|
||||
|
||||
int end = 0;
|
||||
for (int j = line.length() - 1; j > -1; j--) {
|
||||
if (line[j] != ' ' && line[j] != '\t') {
|
||||
end = j + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tx->set_line(i, line.substr(0, end));
|
||||
}
|
||||
}
|
||||
if (trimed_whitespace) {
|
||||
tx->end_complex_operation();
|
||||
tx->update();
|
||||
}
|
||||
code_editor->trim_trailing_whitespace();
|
||||
}
|
||||
|
||||
void ScriptTextEditor::convert_indent_to_spaces() {
|
||||
TextEdit *tx = code_editor->get_text_edit();
|
||||
Ref<Script> scr = get_edited_script();
|
||||
|
||||
if (scr.is_null()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int indent_size = EditorSettings::get_singleton()->get("text_editor/indent/size");
|
||||
String indent = "";
|
||||
|
||||
for (int i = 0; i < indent_size; i++) {
|
||||
indent += " ";
|
||||
}
|
||||
|
||||
int cursor_line = tx->cursor_get_line();
|
||||
int cursor_column = tx->cursor_get_column();
|
||||
|
||||
bool changed_indentation = false;
|
||||
for (int i = 0; i < tx->get_line_count(); i++) {
|
||||
String line = tx->get_line(i);
|
||||
|
||||
if (line.length() <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
while (j < line.length() && (line[j] == ' ' || line[j] == '\t')) {
|
||||
if (line[j] == '\t') {
|
||||
if (!changed_indentation) {
|
||||
tx->begin_complex_operation();
|
||||
changed_indentation = true;
|
||||
}
|
||||
if (cursor_line == i && cursor_column > j) {
|
||||
cursor_column += indent_size - 1;
|
||||
}
|
||||
line = line.left(j) + indent + line.right(j + 1);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (changed_indentation) {
|
||||
tx->set_line(i, line);
|
||||
}
|
||||
}
|
||||
if (changed_indentation) {
|
||||
tx->cursor_set_column(cursor_column);
|
||||
tx->end_complex_operation();
|
||||
tx->update();
|
||||
}
|
||||
code_editor->convert_indent_to_spaces();
|
||||
}
|
||||
|
||||
void ScriptTextEditor::convert_indent_to_tabs() {
|
||||
TextEdit *tx = code_editor->get_text_edit();
|
||||
Ref<Script> scr = get_edited_script();
|
||||
|
||||
if (scr.is_null()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int indent_size = EditorSettings::get_singleton()->get("text_editor/indent/size");
|
||||
indent_size -= 1;
|
||||
|
||||
int cursor_line = tx->cursor_get_line();
|
||||
int cursor_column = tx->cursor_get_column();
|
||||
|
||||
bool changed_indentation = false;
|
||||
for (int i = 0; i < tx->get_line_count(); i++) {
|
||||
String line = tx->get_line(i);
|
||||
|
||||
if (line.length() <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
int space_count = -1;
|
||||
while (j < line.length() && (line[j] == ' ' || line[j] == '\t')) {
|
||||
if (line[j] != '\t') {
|
||||
space_count++;
|
||||
|
||||
if (space_count == indent_size) {
|
||||
if (!changed_indentation) {
|
||||
tx->begin_complex_operation();
|
||||
changed_indentation = true;
|
||||
}
|
||||
if (cursor_line == i && cursor_column > j) {
|
||||
cursor_column -= indent_size;
|
||||
}
|
||||
line = line.left(j - indent_size) + "\t" + line.right(j + 1);
|
||||
j = 0;
|
||||
space_count = -1;
|
||||
}
|
||||
} else {
|
||||
space_count = -1;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (changed_indentation) {
|
||||
tx->set_line(i, line);
|
||||
}
|
||||
}
|
||||
if (changed_indentation) {
|
||||
tx->cursor_set_column(cursor_column);
|
||||
tx->end_complex_operation();
|
||||
tx->update();
|
||||
}
|
||||
code_editor->convert_indent_to_tabs();
|
||||
}
|
||||
|
||||
void ScriptTextEditor::tag_saved_version() {
|
||||
@ -525,18 +373,13 @@ void ScriptTextEditor::tag_saved_version() {
|
||||
}
|
||||
|
||||
void ScriptTextEditor::goto_line(int p_line, bool p_with_error) {
|
||||
TextEdit *tx = code_editor->get_text_edit();
|
||||
tx->deselect();
|
||||
tx->unfold_line(p_line);
|
||||
tx->call_deferred("cursor_set_line", p_line);
|
||||
|
||||
code_editor->goto_line(p_line);
|
||||
}
|
||||
|
||||
void ScriptTextEditor::goto_line_selection(int p_line, int p_begin, int p_end) {
|
||||
TextEdit *tx = code_editor->get_text_edit();
|
||||
tx->unfold_line(p_line);
|
||||
tx->call_deferred("cursor_set_line", p_line);
|
||||
tx->call_deferred("cursor_set_column", p_begin);
|
||||
tx->select(p_line, p_begin, p_line, p_end);
|
||||
|
||||
code_editor->goto_line_selection(p_line, p_begin, p_end);
|
||||
}
|
||||
|
||||
void ScriptTextEditor::ensure_focus() {
|
||||
@ -544,15 +387,6 @@ void ScriptTextEditor::ensure_focus() {
|
||||
code_editor->get_text_edit()->grab_focus();
|
||||
}
|
||||
|
||||
void ScriptTextEditor::set_edit_state(const Variant &p_state) {
|
||||
|
||||
Dictionary state = p_state;
|
||||
code_editor->get_text_edit()->cursor_set_column(state["column"]);
|
||||
code_editor->get_text_edit()->cursor_set_line(state["row"]);
|
||||
code_editor->get_text_edit()->set_v_scroll(state["scroll_position"]);
|
||||
code_editor->get_text_edit()->grab_focus();
|
||||
}
|
||||
|
||||
String ScriptTextEditor::get_name() {
|
||||
String name;
|
||||
|
||||
@ -578,22 +412,6 @@ Ref<Texture> ScriptTextEditor::get_icon() {
|
||||
return Ref<Texture>();
|
||||
}
|
||||
|
||||
void ScriptTextEditor::set_edited_script(const Ref<Script> &p_script) {
|
||||
|
||||
ERR_FAIL_COND(!script.is_null());
|
||||
|
||||
script = p_script;
|
||||
_set_theme_for_script();
|
||||
|
||||
code_editor->get_text_edit()->set_text(script->get_source_code());
|
||||
code_editor->get_text_edit()->clear_undo_history();
|
||||
code_editor->get_text_edit()->tag_saved_version();
|
||||
|
||||
emit_signal("name_changed");
|
||||
code_editor->update_line_and_column();
|
||||
call_deferred("_validate_script");
|
||||
}
|
||||
|
||||
void ScriptTextEditor::_validate_script() {
|
||||
|
||||
String errortxt;
|
||||
@ -878,98 +696,15 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||
} break;
|
||||
case EDIT_MOVE_LINE_UP: {
|
||||
|
||||
Ref<Script> scr = script;
|
||||
if (scr.is_null())
|
||||
return;
|
||||
|
||||
tx->begin_complex_operation();
|
||||
if (tx->is_selection_active()) {
|
||||
int from_line = tx->get_selection_from_line();
|
||||
int from_col = tx->get_selection_from_column();
|
||||
int to_line = tx->get_selection_to_line();
|
||||
int to_column = tx->get_selection_to_column();
|
||||
|
||||
for (int i = from_line; i <= to_line; i++) {
|
||||
int line_id = i;
|
||||
int next_id = i - 1;
|
||||
|
||||
if (line_id == 0 || next_id < 0)
|
||||
return;
|
||||
|
||||
tx->unfold_line(line_id);
|
||||
tx->unfold_line(next_id);
|
||||
|
||||
tx->swap_lines(line_id, next_id);
|
||||
tx->cursor_set_line(next_id);
|
||||
}
|
||||
int from_line_up = from_line > 0 ? from_line - 1 : from_line;
|
||||
int to_line_up = to_line > 0 ? to_line - 1 : to_line;
|
||||
tx->select(from_line_up, from_col, to_line_up, to_column);
|
||||
} else {
|
||||
int line_id = tx->cursor_get_line();
|
||||
int next_id = line_id - 1;
|
||||
|
||||
if (line_id == 0 || next_id < 0)
|
||||
return;
|
||||
|
||||
tx->unfold_line(line_id);
|
||||
tx->unfold_line(next_id);
|
||||
|
||||
tx->swap_lines(line_id, next_id);
|
||||
tx->cursor_set_line(next_id);
|
||||
}
|
||||
tx->end_complex_operation();
|
||||
tx->update();
|
||||
code_editor->move_lines_up();
|
||||
} break;
|
||||
case EDIT_MOVE_LINE_DOWN: {
|
||||
|
||||
Ref<Script> scr = get_edited_script();
|
||||
if (scr.is_null())
|
||||
return;
|
||||
|
||||
tx->begin_complex_operation();
|
||||
if (tx->is_selection_active()) {
|
||||
int from_line = tx->get_selection_from_line();
|
||||
int from_col = tx->get_selection_from_column();
|
||||
int to_line = tx->get_selection_to_line();
|
||||
int to_column = tx->get_selection_to_column();
|
||||
|
||||
for (int i = to_line; i >= from_line; i--) {
|
||||
int line_id = i;
|
||||
int next_id = i + 1;
|
||||
|
||||
if (line_id == tx->get_line_count() - 1 || next_id > tx->get_line_count())
|
||||
return;
|
||||
|
||||
tx->unfold_line(line_id);
|
||||
tx->unfold_line(next_id);
|
||||
|
||||
tx->swap_lines(line_id, next_id);
|
||||
tx->cursor_set_line(next_id);
|
||||
}
|
||||
int from_line_down = from_line < tx->get_line_count() ? from_line + 1 : from_line;
|
||||
int to_line_down = to_line < tx->get_line_count() ? to_line + 1 : to_line;
|
||||
tx->select(from_line_down, from_col, to_line_down, to_column);
|
||||
} else {
|
||||
int line_id = tx->cursor_get_line();
|
||||
int next_id = line_id + 1;
|
||||
|
||||
if (line_id == tx->get_line_count() - 1 || next_id > tx->get_line_count())
|
||||
return;
|
||||
|
||||
tx->unfold_line(line_id);
|
||||
tx->unfold_line(next_id);
|
||||
|
||||
tx->swap_lines(line_id, next_id);
|
||||
tx->cursor_set_line(next_id);
|
||||
}
|
||||
tx->end_complex_operation();
|
||||
tx->update();
|
||||
|
||||
code_editor->move_lines_down();
|
||||
} break;
|
||||
case EDIT_INDENT_LEFT: {
|
||||
|
||||
Ref<Script> scr = get_edited_script();
|
||||
Ref<Script> scr = script;
|
||||
if (scr.is_null())
|
||||
return;
|
||||
|
||||
@ -977,7 +712,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||
} break;
|
||||
case EDIT_INDENT_RIGHT: {
|
||||
|
||||
Ref<Script> scr = get_edited_script();
|
||||
Ref<Script> scr = script;
|
||||
if (scr.is_null())
|
||||
return;
|
||||
|
||||
@ -985,72 +720,11 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||
} break;
|
||||
case EDIT_DELETE_LINE: {
|
||||
|
||||
Ref<Script> scr = get_edited_script();
|
||||
if (scr.is_null())
|
||||
return;
|
||||
tx->begin_complex_operation();
|
||||
if (tx->is_selection_active()) {
|
||||
int to_line = tx->get_selection_to_line();
|
||||
int from_line = tx->get_selection_from_line();
|
||||
int count = Math::abs(to_line - from_line) + 1;
|
||||
while (count) {
|
||||
tx->set_line(tx->cursor_get_line(), "");
|
||||
tx->backspace_at_cursor();
|
||||
count--;
|
||||
if (count)
|
||||
tx->unfold_line(from_line);
|
||||
}
|
||||
tx->cursor_set_line(from_line - 1);
|
||||
tx->deselect();
|
||||
} else {
|
||||
int line = tx->cursor_get_line();
|
||||
tx->set_line(tx->cursor_get_line(), "");
|
||||
tx->backspace_at_cursor();
|
||||
tx->unfold_line(line);
|
||||
tx->cursor_set_line(line);
|
||||
}
|
||||
tx->end_complex_operation();
|
||||
code_editor->delete_lines();
|
||||
} break;
|
||||
case EDIT_CLONE_DOWN: {
|
||||
|
||||
Ref<Script> scr = get_edited_script();
|
||||
if (scr.is_null())
|
||||
return;
|
||||
|
||||
int from_line = tx->cursor_get_line();
|
||||
int to_line = tx->cursor_get_line();
|
||||
int column = tx->cursor_get_column();
|
||||
|
||||
if (tx->is_selection_active()) {
|
||||
from_line = tx->get_selection_from_line();
|
||||
to_line = tx->get_selection_to_line();
|
||||
column = tx->cursor_get_column();
|
||||
}
|
||||
int next_line = to_line + 1;
|
||||
|
||||
if (to_line >= tx->get_line_count() - 1) {
|
||||
tx->set_line(to_line, tx->get_line(to_line) + "\n");
|
||||
}
|
||||
|
||||
tx->begin_complex_operation();
|
||||
for (int i = from_line; i <= to_line; i++) {
|
||||
|
||||
tx->unfold_line(i);
|
||||
if (i >= tx->get_line_count() - 1) {
|
||||
tx->set_line(i, tx->get_line(i) + "\n");
|
||||
}
|
||||
String line_clone = tx->get_line(i);
|
||||
tx->insert_at(line_clone, next_line);
|
||||
next_line++;
|
||||
}
|
||||
|
||||
tx->cursor_set_column(column);
|
||||
if (tx->is_selection_active()) {
|
||||
tx->select(to_line + 1, tx->get_selection_from_column(), next_line - 1, tx->get_selection_to_column());
|
||||
}
|
||||
|
||||
tx->end_complex_operation();
|
||||
tx->update();
|
||||
code_editor->code_lines_down();
|
||||
} break;
|
||||
case EDIT_TOGGLE_FOLD_LINE: {
|
||||
|
||||
@ -1069,7 +743,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||
} break;
|
||||
case EDIT_TOGGLE_COMMENT: {
|
||||
|
||||
Ref<Script> scr = get_edited_script();
|
||||
Ref<Script> scr = script;
|
||||
if (scr.is_null())
|
||||
return;
|
||||
|
||||
@ -1137,7 +811,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||
case EDIT_AUTO_INDENT: {
|
||||
|
||||
String text = tx->get_text();
|
||||
Ref<Script> scr = get_edited_script();
|
||||
Ref<Script> scr = script;
|
||||
if (scr.is_null())
|
||||
return;
|
||||
|
||||
@ -1180,15 +854,15 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||
} break;
|
||||
case EDIT_TO_UPPERCASE: {
|
||||
|
||||
_convert_case(UPPER);
|
||||
_convert_case(CodeTextEditor::UPPER);
|
||||
} break;
|
||||
case EDIT_TO_LOWERCASE: {
|
||||
|
||||
_convert_case(LOWER);
|
||||
_convert_case(CodeTextEditor::LOWER);
|
||||
} break;
|
||||
case EDIT_CAPITALIZE: {
|
||||
|
||||
_convert_case(CAPITALIZE);
|
||||
_convert_case(CodeTextEditor::CAPITALIZE);
|
||||
} break;
|
||||
case SEARCH_FIND: {
|
||||
|
||||
@ -1228,7 +902,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||
int line = tx->cursor_get_line();
|
||||
bool dobreak = !tx->is_line_set_as_breakpoint(line);
|
||||
tx->set_line_as_breakpoint(line, dobreak);
|
||||
ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(get_edited_script()->get_path(), line + 1, dobreak);
|
||||
ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(script->get_path(), line + 1, dobreak);
|
||||
} break;
|
||||
case DEBUG_REMOVE_ALL_BREAKPOINTS: {
|
||||
|
||||
@ -1239,7 +913,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||
int line = E->get();
|
||||
bool dobreak = !tx->is_line_set_as_breakpoint(line);
|
||||
tx->set_line_as_breakpoint(line, dobreak);
|
||||
ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(get_edited_script()->get_path(), line + 1, dobreak);
|
||||
ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(script->get_path(), line + 1, dobreak);
|
||||
}
|
||||
}
|
||||
case DEBUG_GOTO_NEXT_BREAKPOINT: {
|
||||
@ -1359,7 +1033,7 @@ void ScriptTextEditor::clear_edit_menu() {
|
||||
void ScriptTextEditor::reload(bool p_soft) {
|
||||
|
||||
TextEdit *te = code_editor->get_text_edit();
|
||||
Ref<Script> scr = get_edited_script();
|
||||
Ref<Script> scr = script;
|
||||
if (scr.is_null())
|
||||
return;
|
||||
scr->set_source_code(te->get_text());
|
||||
@ -1743,9 +1417,12 @@ ScriptTextEditor::ScriptTextEditor() {
|
||||
code_editor->get_text_edit()->set_drag_forwarding(this);
|
||||
}
|
||||
|
||||
static ScriptEditorBase *create_editor(const Ref<Script> &p_script) {
|
||||
static ScriptEditorBase *create_editor(const RES &p_resource) {
|
||||
|
||||
return memnew(ScriptTextEditor);
|
||||
if (Object::cast_to<Script>(*p_resource)) {
|
||||
return memnew(ScriptTextEditor);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ScriptTextEditor::register_editor() {
|
||||
|
@ -138,12 +138,7 @@ protected:
|
||||
void _goto_line(int p_line) { goto_line(p_line); }
|
||||
void _lookup_symbol(const String &p_symbol, int p_row, int p_column);
|
||||
|
||||
enum CaseStyle {
|
||||
UPPER,
|
||||
LOWER,
|
||||
CAPITALIZE,
|
||||
};
|
||||
void _convert_case(CaseStyle p_case);
|
||||
void _convert_case(CodeTextEditor::CaseStyle p_case);
|
||||
|
||||
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
|
||||
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
|
||||
@ -154,14 +149,13 @@ public:
|
||||
virtual void set_syntax_highlighter(SyntaxHighlighter *p_highlighter);
|
||||
|
||||
virtual void apply_code();
|
||||
virtual Ref<Script> get_edited_script() const;
|
||||
virtual RES get_edited_resource() const;
|
||||
virtual void set_edited_resource(const RES &p_res);
|
||||
virtual Vector<String> get_functions();
|
||||
virtual void set_edited_script(const Ref<Script> &p_script);
|
||||
virtual void reload_text();
|
||||
virtual String get_name();
|
||||
virtual Ref<Texture> get_icon();
|
||||
virtual bool is_unsaved();
|
||||
|
||||
virtual Variant get_edit_state();
|
||||
virtual void set_edit_state(const Variant &p_state);
|
||||
virtual void ensure_focus();
|
||||
|
@ -258,84 +258,10 @@ void ShaderEditor::_menu_option(int p_option) {
|
||||
shader_editor->get_text_edit()->select_all();
|
||||
} break;
|
||||
case EDIT_MOVE_LINE_UP: {
|
||||
|
||||
TextEdit *tx = shader_editor->get_text_edit();
|
||||
if (shader.is_null())
|
||||
return;
|
||||
|
||||
tx->begin_complex_operation();
|
||||
if (tx->is_selection_active()) {
|
||||
int from_line = tx->get_selection_from_line();
|
||||
int from_col = tx->get_selection_from_column();
|
||||
int to_line = tx->get_selection_to_line();
|
||||
int to_column = tx->get_selection_to_column();
|
||||
|
||||
for (int i = from_line; i <= to_line; i++) {
|
||||
int line_id = i;
|
||||
int next_id = i - 1;
|
||||
|
||||
if (line_id == 0 || next_id < 0)
|
||||
return;
|
||||
|
||||
tx->swap_lines(line_id, next_id);
|
||||
tx->cursor_set_line(next_id);
|
||||
}
|
||||
int from_line_up = from_line > 0 ? from_line - 1 : from_line;
|
||||
int to_line_up = to_line > 0 ? to_line - 1 : to_line;
|
||||
tx->select(from_line_up, from_col, to_line_up, to_column);
|
||||
} else {
|
||||
int line_id = tx->cursor_get_line();
|
||||
int next_id = line_id - 1;
|
||||
|
||||
if (line_id == 0 || next_id < 0)
|
||||
return;
|
||||
|
||||
tx->swap_lines(line_id, next_id);
|
||||
tx->cursor_set_line(next_id);
|
||||
}
|
||||
tx->end_complex_operation();
|
||||
tx->update();
|
||||
|
||||
shader_editor->move_lines_up();
|
||||
} break;
|
||||
case EDIT_MOVE_LINE_DOWN: {
|
||||
|
||||
TextEdit *tx = shader_editor->get_text_edit();
|
||||
if (shader.is_null())
|
||||
return;
|
||||
|
||||
tx->begin_complex_operation();
|
||||
if (tx->is_selection_active()) {
|
||||
int from_line = tx->get_selection_from_line();
|
||||
int from_col = tx->get_selection_from_column();
|
||||
int to_line = tx->get_selection_to_line();
|
||||
int to_column = tx->get_selection_to_column();
|
||||
|
||||
for (int i = to_line; i >= from_line; i--) {
|
||||
int line_id = i;
|
||||
int next_id = i + 1;
|
||||
|
||||
if (line_id == tx->get_line_count() - 1 || next_id > tx->get_line_count())
|
||||
return;
|
||||
|
||||
tx->swap_lines(line_id, next_id);
|
||||
tx->cursor_set_line(next_id);
|
||||
}
|
||||
int from_line_down = from_line < tx->get_line_count() ? from_line + 1 : from_line;
|
||||
int to_line_down = to_line < tx->get_line_count() ? to_line + 1 : to_line;
|
||||
tx->select(from_line_down, from_col, to_line_down, to_column);
|
||||
} else {
|
||||
int line_id = tx->cursor_get_line();
|
||||
int next_id = line_id + 1;
|
||||
|
||||
if (line_id == tx->get_line_count() - 1 || next_id > tx->get_line_count())
|
||||
return;
|
||||
|
||||
tx->swap_lines(line_id, next_id);
|
||||
tx->cursor_set_line(next_id);
|
||||
}
|
||||
tx->end_complex_operation();
|
||||
tx->update();
|
||||
|
||||
shader_editor->move_lines_down();
|
||||
} break;
|
||||
case EDIT_INDENT_LEFT: {
|
||||
|
||||
@ -356,55 +282,10 @@ void ShaderEditor::_menu_option(int p_option) {
|
||||
|
||||
} break;
|
||||
case EDIT_DELETE_LINE: {
|
||||
|
||||
TextEdit *tx = shader_editor->get_text_edit();
|
||||
if (shader.is_null())
|
||||
return;
|
||||
|
||||
tx->begin_complex_operation();
|
||||
int line = tx->cursor_get_line();
|
||||
tx->set_line(tx->cursor_get_line(), "");
|
||||
tx->backspace_at_cursor();
|
||||
tx->cursor_set_line(line);
|
||||
tx->end_complex_operation();
|
||||
|
||||
shader_editor->delete_lines();
|
||||
} break;
|
||||
case EDIT_CLONE_DOWN: {
|
||||
|
||||
TextEdit *tx = shader_editor->get_text_edit();
|
||||
if (shader.is_null())
|
||||
return;
|
||||
|
||||
int from_line = tx->cursor_get_line();
|
||||
int to_line = tx->cursor_get_line();
|
||||
int column = tx->cursor_get_column();
|
||||
|
||||
if (tx->is_selection_active()) {
|
||||
from_line = tx->get_selection_from_line();
|
||||
to_line = tx->get_selection_to_line();
|
||||
column = tx->cursor_get_column();
|
||||
}
|
||||
int next_line = to_line + 1;
|
||||
|
||||
tx->begin_complex_operation();
|
||||
for (int i = from_line; i <= to_line; i++) {
|
||||
|
||||
if (i >= tx->get_line_count() - 1) {
|
||||
tx->set_line(i, tx->get_line(i) + "\n");
|
||||
}
|
||||
String line_clone = tx->get_line(i);
|
||||
tx->insert_at(line_clone, next_line);
|
||||
next_line++;
|
||||
}
|
||||
|
||||
tx->cursor_set_column(column);
|
||||
if (tx->is_selection_active()) {
|
||||
tx->select(to_line + 1, tx->get_selection_from_column(), next_line - 1, tx->get_selection_to_column());
|
||||
}
|
||||
|
||||
tx->end_complex_operation();
|
||||
tx->update();
|
||||
|
||||
shader_editor->code_lines_down();
|
||||
} break;
|
||||
case EDIT_TOGGLE_COMMENT: {
|
||||
|
||||
|
607
editor/plugins/text_editor.cpp
Normal file
607
editor/plugins/text_editor.cpp
Normal file
@ -0,0 +1,607 @@
|
||||
/*************************************************************************/
|
||||
/* text_editor.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "text_editor.h"
|
||||
|
||||
void TextEditor::add_syntax_highlighter(SyntaxHighlighter *p_highlighter) {
|
||||
highlighters[p_highlighter->get_name()] = p_highlighter;
|
||||
highlighter_menu->add_radio_check_item(p_highlighter->get_name());
|
||||
}
|
||||
|
||||
void TextEditor::set_syntax_highlighter(SyntaxHighlighter *p_highlighter) {
|
||||
TextEdit *te = code_editor->get_text_edit();
|
||||
te->_set_syntax_highlighting(p_highlighter);
|
||||
if (p_highlighter != NULL) {
|
||||
highlighter_menu->set_item_checked(highlighter_menu->get_item_idx_from_text(p_highlighter->get_name()), true);
|
||||
} else {
|
||||
highlighter_menu->set_item_checked(highlighter_menu->get_item_idx_from_text("Standard"), true);
|
||||
}
|
||||
|
||||
// little work around. GDScript highlighter goes through text_edit for colours,
|
||||
// so to remove all colours we need to set and unset them here.
|
||||
if (p_highlighter == NULL) { // standard
|
||||
TextEdit *text_edit = code_editor->get_text_edit();
|
||||
text_edit->add_color_override("number_color", colors_cache.font_color);
|
||||
text_edit->add_color_override("function_color", colors_cache.font_color);
|
||||
text_edit->add_color_override("number_color", colors_cache.font_color);
|
||||
text_edit->add_color_override("member_variable_color", colors_cache.font_color);
|
||||
} else {
|
||||
_load_theme_settings();
|
||||
}
|
||||
}
|
||||
|
||||
void TextEditor::_change_syntax_highlighter(int p_idx) {
|
||||
Map<String, SyntaxHighlighter *>::Element *el = highlighters.front();
|
||||
while (el != NULL) {
|
||||
highlighter_menu->set_item_checked(highlighter_menu->get_item_idx_from_text(el->key()), false);
|
||||
el = el->next();
|
||||
}
|
||||
set_syntax_highlighter(highlighters[highlighter_menu->get_item_text(p_idx)]);
|
||||
}
|
||||
|
||||
void TextEditor::_load_theme_settings() {
|
||||
|
||||
TextEdit *text_edit = code_editor->get_text_edit();
|
||||
text_edit->clear_colors();
|
||||
|
||||
Color background_color = EDITOR_GET("text_editor/highlighting/background_color");
|
||||
Color completion_background_color = EDITOR_GET("text_editor/highlighting/completion_background_color");
|
||||
Color completion_selected_color = EDITOR_GET("text_editor/highlighting/completion_selected_color");
|
||||
Color completion_existing_color = EDITOR_GET("text_editor/highlighting/completion_existing_color");
|
||||
Color completion_scroll_color = EDITOR_GET("text_editor/highlighting/completion_scroll_color");
|
||||
Color completion_font_color = EDITOR_GET("text_editor/highlighting/completion_font_color");
|
||||
Color text_color = EDITOR_GET("text_editor/highlighting/text_color");
|
||||
Color line_number_color = EDITOR_GET("text_editor/highlighting/line_number_color");
|
||||
Color caret_color = EDITOR_GET("text_editor/highlighting/caret_color");
|
||||
Color caret_background_color = EDITOR_GET("text_editor/highlighting/caret_background_color");
|
||||
Color text_selected_color = EDITOR_GET("text_editor/highlighting/text_selected_color");
|
||||
Color selection_color = EDITOR_GET("text_editor/highlighting/selection_color");
|
||||
Color brace_mismatch_color = EDITOR_GET("text_editor/highlighting/brace_mismatch_color");
|
||||
Color current_line_color = EDITOR_GET("text_editor/highlighting/current_line_color");
|
||||
Color line_length_guideline_color = EDITOR_GET("text_editor/highlighting/line_length_guideline_color");
|
||||
Color word_highlighted_color = EDITOR_GET("text_editor/highlighting/word_highlighted_color");
|
||||
Color number_color = EDITOR_GET("text_editor/highlighting/number_color");
|
||||
Color function_color = EDITOR_GET("text_editor/highlighting/function_color");
|
||||
Color member_variable_color = EDITOR_GET("text_editor/highlighting/member_variable_color");
|
||||
Color mark_color = EDITOR_GET("text_editor/highlighting/mark_color");
|
||||
Color breakpoint_color = EDITOR_GET("text_editor/highlighting/breakpoint_color");
|
||||
Color code_folding_color = EDITOR_GET("text_editor/highlighting/code_folding_color");
|
||||
Color search_result_color = EDITOR_GET("text_editor/highlighting/search_result_color");
|
||||
Color search_result_border_color = EDITOR_GET("text_editor/highlighting/search_result_border_color");
|
||||
Color symbol_color = EDITOR_GET("text_editor/highlighting/symbol_color");
|
||||
Color keyword_color = EDITOR_GET("text_editor/highlighting/keyword_color");
|
||||
Color basetype_color = EDITOR_GET("text_editor/highlighting/base_type_color");
|
||||
Color type_color = EDITOR_GET("text_editor/highlighting/engine_type_color");
|
||||
Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color");
|
||||
Color string_color = EDITOR_GET("text_editor/highlighting/string_color");
|
||||
|
||||
text_edit->add_color_override("background_color", background_color);
|
||||
text_edit->add_color_override("completion_background_color", completion_background_color);
|
||||
text_edit->add_color_override("completion_selected_color", completion_selected_color);
|
||||
text_edit->add_color_override("completion_existing_color", completion_existing_color);
|
||||
text_edit->add_color_override("completion_scroll_color", completion_scroll_color);
|
||||
text_edit->add_color_override("completion_font_color", completion_font_color);
|
||||
text_edit->add_color_override("font_color", text_color);
|
||||
text_edit->add_color_override("line_number_color", line_number_color);
|
||||
text_edit->add_color_override("caret_color", caret_color);
|
||||
text_edit->add_color_override("caret_background_color", caret_background_color);
|
||||
text_edit->add_color_override("font_selected_color", text_selected_color);
|
||||
text_edit->add_color_override("selection_color", selection_color);
|
||||
text_edit->add_color_override("brace_mismatch_color", brace_mismatch_color);
|
||||
text_edit->add_color_override("current_line_color", current_line_color);
|
||||
text_edit->add_color_override("line_length_guideline_color", line_length_guideline_color);
|
||||
text_edit->add_color_override("word_highlighted_color", word_highlighted_color);
|
||||
text_edit->add_color_override("number_color", number_color);
|
||||
text_edit->add_color_override("function_color", function_color);
|
||||
text_edit->add_color_override("member_variable_color", member_variable_color);
|
||||
text_edit->add_color_override("breakpoint_color", breakpoint_color);
|
||||
text_edit->add_color_override("mark_color", mark_color);
|
||||
text_edit->add_color_override("code_folding_color", code_folding_color);
|
||||
text_edit->add_color_override("search_result_color", search_result_color);
|
||||
text_edit->add_color_override("search_result_border_color", search_result_border_color);
|
||||
text_edit->add_color_override("symbol_color", symbol_color);
|
||||
|
||||
text_edit->add_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 4));
|
||||
|
||||
colors_cache.font_color = text_color;
|
||||
colors_cache.symbol_color = symbol_color;
|
||||
colors_cache.keyword_color = keyword_color;
|
||||
colors_cache.basetype_color = basetype_color;
|
||||
colors_cache.type_color = type_color;
|
||||
colors_cache.comment_color = comment_color;
|
||||
colors_cache.string_color = string_color;
|
||||
}
|
||||
|
||||
String TextEditor::get_name() {
|
||||
String name;
|
||||
|
||||
if (text_file->get_path().find("local://") == -1 && text_file->get_path().find("::") == -1) {
|
||||
name = text_file->get_path().get_file();
|
||||
if (is_unsaved()) {
|
||||
name += "(*)";
|
||||
}
|
||||
} else if (text_file->get_name() != "") {
|
||||
name = text_file->get_name();
|
||||
} else {
|
||||
name = text_file->get_class() + "(" + itos(text_file->get_instance_id()) + ")";
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
Ref<Texture> TextEditor::get_icon() {
|
||||
|
||||
if (get_parent_control() && get_parent_control()->has_icon(text_file->get_class(), "EditorIcons")) {
|
||||
return get_parent_control()->get_icon(text_file->get_class(), "EditorIcons");
|
||||
}
|
||||
return Ref<Texture>();
|
||||
}
|
||||
|
||||
RES TextEditor::get_edited_resource() const {
|
||||
return text_file;
|
||||
}
|
||||
|
||||
void TextEditor::set_edited_resource(const RES &p_res) {
|
||||
ERR_FAIL_COND(!text_file.is_null());
|
||||
|
||||
text_file = p_res;
|
||||
|
||||
code_editor->get_text_edit()->set_text(text_file->get_text());
|
||||
code_editor->get_text_edit()->clear_undo_history();
|
||||
code_editor->get_text_edit()->tag_saved_version();
|
||||
|
||||
emit_signal("name_changed");
|
||||
code_editor->update_line_and_column();
|
||||
}
|
||||
|
||||
void TextEditor::add_callback(const String &p_function, PoolStringArray p_args) {
|
||||
}
|
||||
|
||||
void TextEditor::set_debugger_active(bool p_active) {
|
||||
}
|
||||
|
||||
void TextEditor::get_breakpoints(List<int> *p_breakpoints) {
|
||||
}
|
||||
|
||||
void TextEditor::reload_text() {
|
||||
|
||||
ERR_FAIL_COND(text_file.is_null());
|
||||
|
||||
TextEdit *te = code_editor->get_text_edit();
|
||||
int column = te->cursor_get_column();
|
||||
int row = te->cursor_get_line();
|
||||
int h = te->get_h_scroll();
|
||||
int v = te->get_v_scroll();
|
||||
|
||||
te->set_text(text_file->get_text());
|
||||
te->clear_undo_history();
|
||||
te->cursor_set_line(row);
|
||||
te->cursor_set_column(column);
|
||||
te->set_h_scroll(h);
|
||||
te->set_v_scroll(v);
|
||||
|
||||
te->tag_saved_version();
|
||||
|
||||
code_editor->update_line_and_column();
|
||||
}
|
||||
|
||||
void TextEditor::_validate_script() {
|
||||
emit_signal("name_changed");
|
||||
emit_signal("edited_script_changed");
|
||||
}
|
||||
|
||||
void TextEditor::apply_code() {
|
||||
text_file->set_text(code_editor->get_text_edit()->get_text());
|
||||
}
|
||||
|
||||
bool TextEditor::is_unsaved() {
|
||||
|
||||
return code_editor->get_text_edit()->get_version() != code_editor->get_text_edit()->get_saved_version();
|
||||
}
|
||||
|
||||
Variant TextEditor::get_edit_state() {
|
||||
|
||||
return code_editor->get_edit_state();
|
||||
}
|
||||
|
||||
void TextEditor::set_edit_state(const Variant &p_state) {
|
||||
|
||||
code_editor->set_edit_state(p_state);
|
||||
}
|
||||
|
||||
void TextEditor::trim_trailing_whitespace() {
|
||||
|
||||
code_editor->trim_trailing_whitespace();
|
||||
}
|
||||
|
||||
void TextEditor::convert_indent_to_spaces() {
|
||||
|
||||
code_editor->convert_indent_to_spaces();
|
||||
}
|
||||
|
||||
void TextEditor::convert_indent_to_tabs() {
|
||||
|
||||
code_editor->convert_indent_to_tabs();
|
||||
}
|
||||
|
||||
void TextEditor::tag_saved_version() {
|
||||
|
||||
code_editor->get_text_edit()->tag_saved_version();
|
||||
}
|
||||
|
||||
void TextEditor::goto_line(int p_line, bool p_with_error) {
|
||||
|
||||
code_editor->goto_line(p_line);
|
||||
}
|
||||
|
||||
void TextEditor::ensure_focus() {
|
||||
|
||||
code_editor->get_text_edit()->grab_focus();
|
||||
}
|
||||
|
||||
Vector<String> TextEditor::get_functions() {
|
||||
|
||||
return Vector<String>();
|
||||
}
|
||||
|
||||
bool TextEditor::show_members_overview() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void TextEditor::update_settings() {
|
||||
|
||||
code_editor->update_editor_settings();
|
||||
}
|
||||
|
||||
void TextEditor::set_tooltip_request_func(String p_method, Object *p_obj) {
|
||||
|
||||
code_editor->get_text_edit()->set_tooltip_request_func(p_obj, p_method, this);
|
||||
}
|
||||
|
||||
Control *TextEditor::get_edit_menu() {
|
||||
|
||||
return edit_hb;
|
||||
}
|
||||
|
||||
void TextEditor::clear_edit_menu() {
|
||||
memdelete(edit_hb);
|
||||
}
|
||||
|
||||
void TextEditor::_notification(int p_what) {
|
||||
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_READY:
|
||||
_load_theme_settings();
|
||||
set_syntax_highlighter(NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TextEditor::_edit_option(int p_op) {
|
||||
TextEdit *tx = code_editor->get_text_edit();
|
||||
|
||||
switch (p_op) {
|
||||
case EDIT_UNDO: {
|
||||
|
||||
tx->undo();
|
||||
tx->call_deferred("grab_focus");
|
||||
} break;
|
||||
case EDIT_REDO: {
|
||||
|
||||
tx->redo();
|
||||
tx->call_deferred("grab_focus");
|
||||
} break;
|
||||
case EDIT_CUT: {
|
||||
|
||||
tx->cut();
|
||||
tx->call_deferred("grab_focus");
|
||||
} break;
|
||||
case EDIT_COPY: {
|
||||
|
||||
tx->copy();
|
||||
tx->call_deferred("grab_focus");
|
||||
} break;
|
||||
case EDIT_PASTE: {
|
||||
|
||||
tx->paste();
|
||||
tx->call_deferred("grab_focus");
|
||||
} break;
|
||||
case EDIT_SELECT_ALL: {
|
||||
|
||||
tx->select_all();
|
||||
tx->call_deferred("grab_focus");
|
||||
} break;
|
||||
case EDIT_MOVE_LINE_UP: {
|
||||
|
||||
code_editor->move_lines_up();
|
||||
} break;
|
||||
case EDIT_MOVE_LINE_DOWN: {
|
||||
|
||||
code_editor->move_lines_down();
|
||||
} break;
|
||||
case EDIT_INDENT_LEFT: {
|
||||
|
||||
tx->indent_left();
|
||||
} break;
|
||||
case EDIT_INDENT_RIGHT: {
|
||||
|
||||
tx->indent_right();
|
||||
} break;
|
||||
case EDIT_DELETE_LINE: {
|
||||
|
||||
code_editor->delete_lines();
|
||||
} break;
|
||||
case EDIT_CLONE_DOWN: {
|
||||
|
||||
code_editor->code_lines_down();
|
||||
} break;
|
||||
case EDIT_TOGGLE_FOLD_LINE: {
|
||||
|
||||
tx->toggle_fold_line(tx->cursor_get_line());
|
||||
tx->update();
|
||||
} break;
|
||||
case EDIT_FOLD_ALL_LINES: {
|
||||
|
||||
tx->fold_all_lines();
|
||||
tx->update();
|
||||
} break;
|
||||
case EDIT_UNFOLD_ALL_LINES: {
|
||||
|
||||
tx->unhide_all_lines();
|
||||
tx->update();
|
||||
} break;
|
||||
case EDIT_TRIM_TRAILING_WHITESAPCE: {
|
||||
|
||||
trim_trailing_whitespace();
|
||||
} break;
|
||||
case EDIT_CONVERT_INDENT_TO_SPACES: {
|
||||
|
||||
convert_indent_to_spaces();
|
||||
} break;
|
||||
case EDIT_CONVERT_INDENT_TO_TABS: {
|
||||
|
||||
convert_indent_to_tabs();
|
||||
} break;
|
||||
case EDIT_TO_UPPERCASE: {
|
||||
|
||||
_convert_case(CodeTextEditor::UPPER);
|
||||
} break;
|
||||
case EDIT_TO_LOWERCASE: {
|
||||
|
||||
_convert_case(CodeTextEditor::LOWER);
|
||||
} break;
|
||||
case EDIT_CAPITALIZE: {
|
||||
|
||||
_convert_case(CodeTextEditor::CAPITALIZE);
|
||||
} break;
|
||||
case SEARCH_FIND: {
|
||||
|
||||
code_editor->get_find_replace_bar()->popup_search();
|
||||
} break;
|
||||
case SEARCH_FIND_NEXT: {
|
||||
|
||||
code_editor->get_find_replace_bar()->search_next();
|
||||
} break;
|
||||
case SEARCH_FIND_PREV: {
|
||||
|
||||
code_editor->get_find_replace_bar()->search_prev();
|
||||
} break;
|
||||
case SEARCH_REPLACE: {
|
||||
|
||||
code_editor->get_find_replace_bar()->popup_replace();
|
||||
} break;
|
||||
case SEARCH_GOTO_LINE: {
|
||||
|
||||
goto_line_dialog->popup_find_line(tx);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void TextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) {
|
||||
|
||||
code_editor->convert_case(p_case);
|
||||
}
|
||||
|
||||
void TextEditor::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method("_validate_script", &TextEditor::_validate_script);
|
||||
ClassDB::bind_method("_load_theme_settings", &TextEditor::_load_theme_settings);
|
||||
ClassDB::bind_method("_edit_option", &TextEditor::_edit_option);
|
||||
ClassDB::bind_method("_change_syntax_highlighter", &TextEditor::_change_syntax_highlighter);
|
||||
ClassDB::bind_method("_text_edit_gui_input", &TextEditor::_text_edit_gui_input);
|
||||
}
|
||||
|
||||
static ScriptEditorBase *create_editor(const RES &p_resource) {
|
||||
|
||||
if (Object::cast_to<TextFile>(*p_resource)) {
|
||||
return memnew(TextEditor);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void TextEditor::register_editor() {
|
||||
|
||||
ScriptEditor::register_create_script_editor_function(create_editor);
|
||||
}
|
||||
|
||||
void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
|
||||
|
||||
Ref<InputEventMouseButton> mb = ev;
|
||||
|
||||
if (mb.is_valid()) {
|
||||
if (mb->get_button_index() == BUTTON_RIGHT) {
|
||||
|
||||
int col, row;
|
||||
TextEdit *tx = code_editor->get_text_edit();
|
||||
tx->_get_mouse_pos(mb->get_global_position() - tx->get_global_position(), row, col);
|
||||
|
||||
tx->set_right_click_moves_caret(EditorSettings::get_singleton()->get("text_editor/cursor/right_click_moves_caret"));
|
||||
bool can_fold = tx->can_fold(row);
|
||||
bool is_folded = tx->is_folded(row);
|
||||
|
||||
if (tx->is_right_click_moving_caret()) {
|
||||
if (tx->is_selection_active()) {
|
||||
|
||||
int from_line = tx->get_selection_from_line();
|
||||
int to_line = tx->get_selection_to_line();
|
||||
int from_column = tx->get_selection_from_column();
|
||||
int to_column = tx->get_selection_to_column();
|
||||
|
||||
if (row < from_line || row > to_line || (row == from_line && col < from_column) || (row == to_line && col > to_column)) {
|
||||
// Right click is outside the seleted text
|
||||
tx->deselect();
|
||||
}
|
||||
}
|
||||
if (!tx->is_selection_active()) {
|
||||
tx->cursor_set_line(row, true, false);
|
||||
tx->cursor_set_column(col);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mb->is_pressed()) {
|
||||
_make_context_menu(tx->is_selection_active(), can_fold, is_folded);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextEditor::_make_context_menu(bool p_selection, bool p_can_fold, bool p_is_folded) {
|
||||
|
||||
context_menu->clear();
|
||||
if (p_selection) {
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
|
||||
}
|
||||
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE);
|
||||
context_menu->add_separator();
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL);
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
|
||||
context_menu->add_separator();
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT);
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT);
|
||||
|
||||
if (p_selection) {
|
||||
context_menu->add_separator();
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_uppercase"), EDIT_TO_UPPERCASE);
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_lowercase"), EDIT_TO_LOWERCASE);
|
||||
}
|
||||
if (p_can_fold || p_is_folded)
|
||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
|
||||
|
||||
context_menu->set_position(get_global_transform().xform(get_local_mouse_position()));
|
||||
context_menu->set_size(Vector2(1, 1));
|
||||
context_menu->popup();
|
||||
}
|
||||
|
||||
TextEditor::TextEditor() {
|
||||
code_editor = memnew(CodeTextEditor);
|
||||
add_child(code_editor);
|
||||
code_editor->add_constant_override("separation", 0);
|
||||
code_editor->connect("load_theme_settings", this, "_load_theme_settings");
|
||||
code_editor->connect("validate_script", this, "_validate_script");
|
||||
code_editor->set_anchors_and_margins_preset(Control::PRESET_WIDE);
|
||||
code_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
|
||||
update_settings();
|
||||
|
||||
code_editor->get_text_edit()->set_context_menu_enabled(false);
|
||||
code_editor->get_text_edit()->connect("gui_input", this, "_text_edit_gui_input");
|
||||
|
||||
context_menu = memnew(PopupMenu);
|
||||
add_child(context_menu);
|
||||
context_menu->connect("id_pressed", this, "_edit_option");
|
||||
|
||||
edit_hb = memnew(HBoxContainer);
|
||||
|
||||
search_menu = memnew(MenuButton);
|
||||
edit_hb->add_child(search_menu);
|
||||
search_menu->set_text(TTR("Search"));
|
||||
search_menu->get_popup()->connect("id_pressed", this, "_edit_option");
|
||||
|
||||
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find"), SEARCH_FIND);
|
||||
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT);
|
||||
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV);
|
||||
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE);
|
||||
search_menu->get_popup()->add_separator();
|
||||
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
|
||||
|
||||
goto_line_dialog = memnew(GotoLineDialog);
|
||||
add_child(goto_line_dialog);
|
||||
|
||||
edit_menu = memnew(MenuButton);
|
||||
edit_menu->set_text(TTR("Edit"));
|
||||
edit_menu->get_popup()->connect("id_pressed", this, "_edit_option");
|
||||
|
||||
edit_hb->add_child(edit_menu);
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
|
||||
edit_menu->get_popup()->add_separator();
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE);
|
||||
edit_menu->get_popup()->add_separator();
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL);
|
||||
edit_menu->get_popup()->add_separator();
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP);
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN);
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT);
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT);
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/delete_line"), EDIT_DELETE_LINE);
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/fold_all_lines"), EDIT_FOLD_ALL_LINES);
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_all_lines"), EDIT_UNFOLD_ALL_LINES);
|
||||
edit_menu->get_popup()->add_separator();
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN);
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE);
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES);
|
||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_tabs"), EDIT_CONVERT_INDENT_TO_TABS);
|
||||
|
||||
edit_menu->get_popup()->add_separator();
|
||||
PopupMenu *convert_case = memnew(PopupMenu);
|
||||
convert_case->set_name("convert_case");
|
||||
edit_menu->get_popup()->add_child(convert_case);
|
||||
edit_menu->get_popup()->add_submenu_item(TTR("Convert Case"), "convert_case");
|
||||
convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_uppercase", TTR("Uppercase")), EDIT_TO_UPPERCASE);
|
||||
convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_lowercase", TTR("Lowercase")), EDIT_TO_LOWERCASE);
|
||||
convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/capitalize", TTR("Capitalize")), EDIT_CAPITALIZE);
|
||||
convert_case->connect("id_pressed", this, "_edit_option");
|
||||
|
||||
highlighters["Standard"] = NULL;
|
||||
highlighter_menu = memnew(PopupMenu);
|
||||
highlighter_menu->set_name("highlighter_menu");
|
||||
edit_menu->get_popup()->add_child(highlighter_menu);
|
||||
edit_menu->get_popup()->add_submenu_item(TTR("Syntax Highlighter"), "highlighter_menu");
|
||||
highlighter_menu->add_radio_check_item(TTR("Standard"));
|
||||
highlighter_menu->connect("id_pressed", this, "_change_syntax_highlighter");
|
||||
|
||||
code_editor->get_text_edit()->set_drag_forwarding(this);
|
||||
}
|
146
editor/plugins/text_editor.h
Normal file
146
editor/plugins/text_editor.h
Normal file
@ -0,0 +1,146 @@
|
||||
/*************************************************************************/
|
||||
/* text_editor.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef TEXT_EDITOR_H
|
||||
#define TEXT_EDITOR_H
|
||||
|
||||
#include "script_editor_plugin.h"
|
||||
|
||||
class TextEditor : public ScriptEditorBase {
|
||||
|
||||
GDCLASS(TextEditor, ScriptEditorBase)
|
||||
|
||||
private:
|
||||
CodeTextEditor *code_editor;
|
||||
|
||||
Ref<TextFile> text_file;
|
||||
|
||||
HBoxContainer *edit_hb;
|
||||
MenuButton *edit_menu;
|
||||
PopupMenu *highlighter_menu;
|
||||
MenuButton *search_menu;
|
||||
PopupMenu *context_menu;
|
||||
|
||||
GotoLineDialog *goto_line_dialog;
|
||||
|
||||
struct ColorsCache {
|
||||
Color font_color;
|
||||
Color symbol_color;
|
||||
Color keyword_color;
|
||||
Color basetype_color;
|
||||
Color type_color;
|
||||
Color comment_color;
|
||||
Color string_color;
|
||||
} colors_cache;
|
||||
|
||||
enum {
|
||||
EDIT_UNDO,
|
||||
EDIT_REDO,
|
||||
EDIT_CUT,
|
||||
EDIT_COPY,
|
||||
EDIT_PASTE,
|
||||
EDIT_SELECT_ALL,
|
||||
EDIT_TRIM_TRAILING_WHITESAPCE,
|
||||
EDIT_CONVERT_INDENT_TO_SPACES,
|
||||
EDIT_CONVERT_INDENT_TO_TABS,
|
||||
EDIT_MOVE_LINE_UP,
|
||||
EDIT_MOVE_LINE_DOWN,
|
||||
EDIT_INDENT_RIGHT,
|
||||
EDIT_INDENT_LEFT,
|
||||
EDIT_DELETE_LINE,
|
||||
EDIT_CLONE_DOWN,
|
||||
EDIT_TO_UPPERCASE,
|
||||
EDIT_TO_LOWERCASE,
|
||||
EDIT_CAPITALIZE,
|
||||
EDIT_TOGGLE_FOLD_LINE,
|
||||
EDIT_FOLD_ALL_LINES,
|
||||
EDIT_UNFOLD_ALL_LINES,
|
||||
SEARCH_FIND,
|
||||
SEARCH_FIND_NEXT,
|
||||
SEARCH_FIND_PREV,
|
||||
SEARCH_REPLACE,
|
||||
SEARCH_GOTO_LINE,
|
||||
};
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
void _notification(int p_what);
|
||||
|
||||
void _edit_option(int p_op);
|
||||
void _make_context_menu(bool p_selection, bool p_can_fold, bool p_is_folded);
|
||||
void _text_edit_gui_input(const Ref<InputEvent> &ev);
|
||||
|
||||
Map<String, SyntaxHighlighter *> highlighters;
|
||||
void _change_syntax_highlighter(int p_idx);
|
||||
void _load_theme_settings();
|
||||
|
||||
void _convert_case(CodeTextEditor::CaseStyle p_case);
|
||||
|
||||
void _validate_script();
|
||||
|
||||
public:
|
||||
virtual void add_syntax_highlighter(SyntaxHighlighter *p_highlighter);
|
||||
virtual void set_syntax_highlighter(SyntaxHighlighter *p_highlighter);
|
||||
|
||||
virtual String get_name();
|
||||
virtual Ref<Texture> get_icon();
|
||||
virtual RES get_edited_resource() const;
|
||||
virtual void set_edited_resource(const RES &p_res);
|
||||
void set_edited_file(const Ref<TextFile> &p_file);
|
||||
virtual void reload_text();
|
||||
virtual void apply_code();
|
||||
virtual bool is_unsaved();
|
||||
virtual Variant get_edit_state();
|
||||
virtual void set_edit_state(const Variant &p_state);
|
||||
virtual Vector<String> get_functions();
|
||||
virtual void get_breakpoints(List<int> *p_breakpoints);
|
||||
virtual void goto_line(int p_line, bool p_with_error = false);
|
||||
virtual void trim_trailing_whitespace();
|
||||
virtual void convert_indent_to_spaces();
|
||||
virtual void convert_indent_to_tabs();
|
||||
virtual void ensure_focus();
|
||||
virtual void tag_saved_version();
|
||||
virtual void update_settings();
|
||||
virtual bool show_members_overview();
|
||||
virtual bool can_lose_focus_on_node_selection() { return true; }
|
||||
virtual void set_debugger_active(bool p_active);
|
||||
virtual void set_tooltip_request_func(String p_method, Object *p_obj);
|
||||
virtual void add_callback(const String &p_function, PoolStringArray p_args);
|
||||
|
||||
virtual Control *get_edit_menu();
|
||||
virtual void clear_edit_menu();
|
||||
|
||||
static void register_editor();
|
||||
|
||||
TextEditor();
|
||||
};
|
||||
|
||||
#endif // TEXT_EDITOR_H
|
@ -1962,22 +1962,16 @@ void VisualScriptEditor::_button_resource_previewed(const String &p_path, const
|
||||
void VisualScriptEditor::apply_code() {
|
||||
}
|
||||
|
||||
Ref<Script> VisualScriptEditor::get_edited_script() const {
|
||||
|
||||
RES VisualScriptEditor::get_edited_resource() const {
|
||||
return script;
|
||||
}
|
||||
|
||||
Vector<String> VisualScriptEditor::get_functions() {
|
||||
void VisualScriptEditor::set_edited_resource(const RES &p_res) {
|
||||
|
||||
return Vector<String>();
|
||||
}
|
||||
|
||||
void VisualScriptEditor::set_edited_script(const Ref<Script> &p_script) {
|
||||
|
||||
script = p_script;
|
||||
signal_editor->script = p_script;
|
||||
script = p_res;
|
||||
signal_editor->script = script;
|
||||
signal_editor->undo_redo = undo_redo;
|
||||
variable_editor->script = p_script;
|
||||
variable_editor->script = script;
|
||||
variable_editor->undo_redo = undo_redo;
|
||||
|
||||
script->connect("node_ports_changed", this, "_node_ports_changed");
|
||||
@ -1986,6 +1980,11 @@ void VisualScriptEditor::set_edited_script(const Ref<Script> &p_script) {
|
||||
_update_available_nodes();
|
||||
}
|
||||
|
||||
Vector<String> VisualScriptEditor::get_functions() {
|
||||
|
||||
return Vector<String>();
|
||||
}
|
||||
|
||||
void VisualScriptEditor::reload_text() {
|
||||
}
|
||||
|
||||
@ -3515,9 +3514,9 @@ VisualScriptEditor::~VisualScriptEditor() {
|
||||
memdelete(variable_editor);
|
||||
}
|
||||
|
||||
static ScriptEditorBase *create_editor(const Ref<Script> &p_script) {
|
||||
static ScriptEditorBase *create_editor(const RES &p_resource) {
|
||||
|
||||
if (Object::cast_to<VisualScript>(*p_script)) {
|
||||
if (Object::cast_to<VisualScript>(*p_resource)) {
|
||||
return memnew(VisualScriptEditor);
|
||||
}
|
||||
|
||||
|
@ -250,9 +250,9 @@ public:
|
||||
virtual void set_syntax_highlighter(SyntaxHighlighter *p_highlighter);
|
||||
|
||||
virtual void apply_code();
|
||||
virtual Ref<Script> get_edited_script() const;
|
||||
virtual RES get_edited_resource() const;
|
||||
virtual void set_edited_resource(const RES &p_res);
|
||||
virtual Vector<String> get_functions();
|
||||
virtual void set_edited_script(const Ref<Script> &p_script);
|
||||
virtual void reload_text();
|
||||
virtual String get_name();
|
||||
virtual Ref<Texture> get_icon();
|
||||
|
@ -156,6 +156,7 @@
|
||||
#include "scene/resources/sky_box.h"
|
||||
#include "scene/resources/sphere_shape.h"
|
||||
#include "scene/resources/surface_tool.h"
|
||||
#include "scene/resources/text_file.h"
|
||||
#include "scene/resources/texture.h"
|
||||
#include "scene/resources/tile_set.h"
|
||||
#include "scene/resources/video_stream.h"
|
||||
@ -617,6 +618,8 @@ void register_scene_types() {
|
||||
ClassDB::register_class<BitmapFont>();
|
||||
ClassDB::register_class<Curve>();
|
||||
|
||||
ClassDB::register_class<TextFile>();
|
||||
|
||||
ClassDB::register_class<DynamicFontData>();
|
||||
ClassDB::register_class<DynamicFont>();
|
||||
|
||||
|
77
scene/resources/text_file.cpp
Normal file
77
scene/resources/text_file.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
/*************************************************************************/
|
||||
/* text_file.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "text_file.h"
|
||||
|
||||
#include "os/file_access.h"
|
||||
|
||||
bool TextFile::has_text() const {
|
||||
return text != "";
|
||||
}
|
||||
|
||||
String TextFile::get_text() const {
|
||||
return text;
|
||||
}
|
||||
|
||||
void TextFile::set_text(const String &p_code) {
|
||||
text = p_code;
|
||||
}
|
||||
|
||||
void TextFile::reload_from_file() {
|
||||
load_text(path);
|
||||
}
|
||||
|
||||
Error TextFile::load_text(const String &p_path) {
|
||||
|
||||
PoolVector<uint8_t> sourcef;
|
||||
Error err;
|
||||
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
|
||||
if (err) {
|
||||
ERR_FAIL_COND_V(err, err);
|
||||
}
|
||||
|
||||
int len = f->get_len();
|
||||
sourcef.resize(len + 1);
|
||||
PoolVector<uint8_t>::Write w = sourcef.write();
|
||||
int r = f->get_buffer(w.ptr(), len);
|
||||
f->close();
|
||||
memdelete(f);
|
||||
ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN);
|
||||
w[len] = 0;
|
||||
|
||||
String s;
|
||||
if (s.parse_utf8((const char *)w.ptr())) {
|
||||
ERR_EXPLAIN("Script '" + p_path + "' contains invalid unicode (utf-8), so it was not loaded. Please ensure that scripts are saved in valid utf-8 unicode.");
|
||||
ERR_FAIL_V(ERR_INVALID_DATA);
|
||||
}
|
||||
text = s;
|
||||
path = p_path;
|
||||
return OK;
|
||||
}
|
55
scene/resources/text_file.h
Normal file
55
scene/resources/text_file.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*************************************************************************/
|
||||
/* text_file.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef TEXTFILE_H
|
||||
#define TEXTFILE_H
|
||||
|
||||
#include "io/resource_loader.h"
|
||||
#include "io/resource_saver.h"
|
||||
|
||||
class TextFile : public Resource {
|
||||
|
||||
GDCLASS(TextFile, Resource)
|
||||
|
||||
private:
|
||||
String text;
|
||||
String path;
|
||||
|
||||
public:
|
||||
virtual bool has_text() const;
|
||||
virtual String get_text() const;
|
||||
virtual void set_text(const String &p_code);
|
||||
virtual void reload_from_file();
|
||||
|
||||
void set_file_path(const String &p_path) { path = p_path; }
|
||||
Error load_text(const String &p_path);
|
||||
};
|
||||
|
||||
#endif // TEXTFILE_H
|
Loading…
Reference in New Issue
Block a user