Merge pull request #90743 from timothyqiu/empty-selection-clipboard
Add TextEdit option to prevent copying without a selection
This commit is contained in:
commit
720c236fc0
|
@ -1200,6 +1200,9 @@
|
||||||
<member name="text_editor/behavior/files/trim_trailing_whitespace_on_save" type="bool" setter="" getter="">
|
<member name="text_editor/behavior/files/trim_trailing_whitespace_on_save" type="bool" setter="" getter="">
|
||||||
If [code]true[/code], trims trailing whitespace when saving a script. Trailing whitespace refers to tab and space characters placed at the end of lines. Since these serve no practical purpose, they can and should be removed to make version control diffs less noisy.
|
If [code]true[/code], trims trailing whitespace when saving a script. Trailing whitespace refers to tab and space characters placed at the end of lines. Since these serve no practical purpose, they can and should be removed to make version control diffs less noisy.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="text_editor/behavior/general/empty_selection_clipboard" type="bool" setter="" getter="">
|
||||||
|
If [code]true[/code], copying or cutting without a selection is performed on all lines with a caret. Otherwise, copy and cut require a selection.
|
||||||
|
</member>
|
||||||
<member name="text_editor/behavior/indent/auto_indent" type="bool" setter="" getter="">
|
<member name="text_editor/behavior/indent/auto_indent" type="bool" setter="" getter="">
|
||||||
If [code]true[/code], automatically indents code when pressing the [kbd]Enter[/kbd] key based on blocks above the new line.
|
If [code]true[/code], automatically indents code when pressing the [kbd]Enter[/kbd] key based on blocks above the new line.
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -1299,6 +1299,9 @@
|
||||||
<member name="editable" type="bool" setter="set_editable" getter="is_editable" default="true" keywords="readonly, disabled, enabled">
|
<member name="editable" type="bool" setter="set_editable" getter="is_editable" default="true" keywords="readonly, disabled, enabled">
|
||||||
If [code]false[/code], existing text cannot be modified and new text cannot be added.
|
If [code]false[/code], existing text cannot be modified and new text cannot be added.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="empty_selection_clipboard_enabled" type="bool" setter="set_empty_selection_clipboard_enabled" getter="is_empty_selection_clipboard_enabled" default="true">
|
||||||
|
If [code]true[/code], copying or cutting without a selection is performed on all lines with a caret. Otherwise, copy and cut require a selection.
|
||||||
|
</member>
|
||||||
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="2" />
|
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" overrides="Control" enum="Control.FocusMode" default="2" />
|
||||||
<member name="highlight_all_occurrences" type="bool" setter="set_highlight_all_occurrences" getter="is_highlight_all_occurrences_enabled" default="false">
|
<member name="highlight_all_occurrences" type="bool" setter="set_highlight_all_occurrences" getter="is_highlight_all_occurrences_enabled" default="false">
|
||||||
If [code]true[/code], all occurrences of the selected text will be highlighted.
|
If [code]true[/code], all occurrences of the selected text will be highlighted.
|
||||||
|
|
|
@ -1090,6 +1090,9 @@ void CodeTextEditor::update_editor_settings() {
|
||||||
text_editor->set_draw_spaces(EDITOR_GET("text_editor/appearance/whitespace/draw_spaces"));
|
text_editor->set_draw_spaces(EDITOR_GET("text_editor/appearance/whitespace/draw_spaces"));
|
||||||
text_editor->add_theme_constant_override("line_spacing", EDITOR_GET("text_editor/appearance/whitespace/line_spacing"));
|
text_editor->add_theme_constant_override("line_spacing", EDITOR_GET("text_editor/appearance/whitespace/line_spacing"));
|
||||||
|
|
||||||
|
// Behavior: General
|
||||||
|
text_editor->set_empty_selection_clipboard_enabled(EDITOR_GET("text_editor/behavior/general/empty_selection_clipboard"));
|
||||||
|
|
||||||
// Behavior: Navigation
|
// Behavior: Navigation
|
||||||
text_editor->set_scroll_past_end_of_file_enabled(EDITOR_GET("text_editor/behavior/navigation/scroll_past_end_of_file"));
|
text_editor->set_scroll_past_end_of_file_enabled(EDITOR_GET("text_editor/behavior/navigation/scroll_past_end_of_file"));
|
||||||
text_editor->set_smooth_scroll_enabled(EDITOR_GET("text_editor/behavior/navigation/smooth_scrolling"));
|
text_editor->set_smooth_scroll_enabled(EDITOR_GET("text_editor/behavior/navigation/smooth_scrolling"));
|
||||||
|
|
|
@ -668,6 +668,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
|
||||||
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "text_editor/appearance/whitespace/line_spacing", 4, "0,50,1")
|
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "text_editor/appearance/whitespace/line_spacing", 4, "0,50,1")
|
||||||
|
|
||||||
// Behavior
|
// Behavior
|
||||||
|
// Behavior: General
|
||||||
|
_initial_set("text_editor/behavior/general/empty_selection_clipboard", true);
|
||||||
|
|
||||||
// Behavior: Navigation
|
// Behavior: Navigation
|
||||||
_initial_set("text_editor/behavior/navigation/move_caret_on_right_click", true, true);
|
_initial_set("text_editor/behavior/navigation/move_caret_on_right_click", true, true);
|
||||||
_initial_set("text_editor/behavior/navigation/scroll_past_end_of_file", false, true);
|
_initial_set("text_editor/behavior/navigation/scroll_past_end_of_file", false, true);
|
||||||
|
|
|
@ -831,6 +831,9 @@ void CodeEdit::_cut_internal(int p_caret) {
|
||||||
delete_selection(p_caret);
|
delete_selection(p_caret);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!is_empty_selection_clipboard_enabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (p_caret == -1) {
|
if (p_caret == -1) {
|
||||||
delete_lines();
|
delete_lines();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3367,6 +3367,14 @@ bool TextEdit::is_middle_mouse_paste_enabled() const {
|
||||||
return middle_mouse_paste_enabled;
|
return middle_mouse_paste_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextEdit::set_empty_selection_clipboard_enabled(bool p_enabled) {
|
||||||
|
empty_selection_clipboard_enabled = p_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextEdit::is_empty_selection_clipboard_enabled() const {
|
||||||
|
return empty_selection_clipboard_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
// Text manipulation
|
// Text manipulation
|
||||||
void TextEdit::clear() {
|
void TextEdit::clear() {
|
||||||
setting_text = true;
|
setting_text = true;
|
||||||
|
@ -6569,6 +6577,9 @@ void TextEdit::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_middle_mouse_paste_enabled", "enabled"), &TextEdit::set_middle_mouse_paste_enabled);
|
ClassDB::bind_method(D_METHOD("set_middle_mouse_paste_enabled", "enabled"), &TextEdit::set_middle_mouse_paste_enabled);
|
||||||
ClassDB::bind_method(D_METHOD("is_middle_mouse_paste_enabled"), &TextEdit::is_middle_mouse_paste_enabled);
|
ClassDB::bind_method(D_METHOD("is_middle_mouse_paste_enabled"), &TextEdit::is_middle_mouse_paste_enabled);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_empty_selection_clipboard_enabled", "enabled"), &TextEdit::set_empty_selection_clipboard_enabled);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_empty_selection_clipboard_enabled"), &TextEdit::is_empty_selection_clipboard_enabled);
|
||||||
|
|
||||||
// Text manipulation
|
// Text manipulation
|
||||||
ClassDB::bind_method(D_METHOD("clear"), &TextEdit::clear);
|
ClassDB::bind_method(D_METHOD("clear"), &TextEdit::clear);
|
||||||
|
|
||||||
|
@ -6962,6 +6973,7 @@ void TextEdit::_bind_methods() {
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_and_drop_selection_enabled"), "set_drag_and_drop_selection_enabled", "is_drag_and_drop_selection_enabled");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_and_drop_selection_enabled"), "set_drag_and_drop_selection_enabled", "is_drag_and_drop_selection_enabled");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "virtual_keyboard_enabled"), "set_virtual_keyboard_enabled", "is_virtual_keyboard_enabled");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "virtual_keyboard_enabled"), "set_virtual_keyboard_enabled", "is_virtual_keyboard_enabled");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "middle_mouse_paste_enabled"), "set_middle_mouse_paste_enabled", "is_middle_mouse_paste_enabled");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "middle_mouse_paste_enabled"), "set_middle_mouse_paste_enabled", "is_middle_mouse_paste_enabled");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "empty_selection_clipboard_enabled"), "set_empty_selection_clipboard_enabled", "is_empty_selection_clipboard_enabled");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "wrap_mode", PROPERTY_HINT_ENUM, "None,Boundary"), "set_line_wrapping_mode", "get_line_wrapping_mode");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "wrap_mode", PROPERTY_HINT_ENUM, "None,Boundary"), "set_line_wrapping_mode", "get_line_wrapping_mode");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Arbitrary:1,Word:2,Word (Smart):3"), "set_autowrap_mode", "get_autowrap_mode");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Arbitrary:1,Word:2,Word (Smart):3"), "set_autowrap_mode", "get_autowrap_mode");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "indent_wrapped_lines"), "set_indent_wrapped_lines", "is_indent_wrapped_lines");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "indent_wrapped_lines"), "set_indent_wrapped_lines", "is_indent_wrapped_lines");
|
||||||
|
@ -7216,6 +7228,10 @@ void TextEdit::_cut_internal(int p_caret) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!empty_selection_clipboard_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Remove full lines.
|
// Remove full lines.
|
||||||
begin_complex_operation();
|
begin_complex_operation();
|
||||||
begin_multicaret_edit();
|
begin_multicaret_edit();
|
||||||
|
@ -7246,6 +7262,10 @@ void TextEdit::_copy_internal(int p_caret) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!empty_selection_clipboard_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy full lines.
|
// Copy full lines.
|
||||||
StringBuilder clipboard;
|
StringBuilder clipboard;
|
||||||
Vector<Point2i> line_ranges;
|
Vector<Point2i> line_ranges;
|
||||||
|
|
|
@ -319,6 +319,7 @@ private:
|
||||||
bool shortcut_keys_enabled = true;
|
bool shortcut_keys_enabled = true;
|
||||||
bool virtual_keyboard_enabled = true;
|
bool virtual_keyboard_enabled = true;
|
||||||
bool middle_mouse_paste_enabled = true;
|
bool middle_mouse_paste_enabled = true;
|
||||||
|
bool empty_selection_clipboard_enabled = true;
|
||||||
|
|
||||||
// Overridable actions.
|
// Overridable actions.
|
||||||
String cut_copy_line = "";
|
String cut_copy_line = "";
|
||||||
|
@ -770,6 +771,9 @@ public:
|
||||||
void set_middle_mouse_paste_enabled(bool p_enabled);
|
void set_middle_mouse_paste_enabled(bool p_enabled);
|
||||||
bool is_middle_mouse_paste_enabled() const;
|
bool is_middle_mouse_paste_enabled() const;
|
||||||
|
|
||||||
|
void set_empty_selection_clipboard_enabled(bool p_enabled);
|
||||||
|
bool is_empty_selection_clipboard_enabled() const;
|
||||||
|
|
||||||
// Text manipulation
|
// Text manipulation
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
|
|
@ -4779,6 +4779,31 @@ TEST_CASE("[SceneTree][CodeEdit] text manipulation") {
|
||||||
CHECK(code_edit->get_caret_column(3) == 0);
|
CHECK(code_edit->get_caret_column(3) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SUBCASE("[SceneTree][CodeEdit] cut when empty selection clipboard disabled") {
|
||||||
|
DisplayServerMock *DS = (DisplayServerMock *)(DisplayServer::get_singleton());
|
||||||
|
code_edit->set_empty_selection_clipboard_enabled(false);
|
||||||
|
DS->clipboard_set("");
|
||||||
|
|
||||||
|
code_edit->set_text("this is\nsome\n");
|
||||||
|
code_edit->set_caret_line(0);
|
||||||
|
code_edit->set_caret_column(6);
|
||||||
|
MessageQueue::get_singleton()->flush();
|
||||||
|
SIGNAL_DISCARD("text_set");
|
||||||
|
SIGNAL_DISCARD("text_changed");
|
||||||
|
SIGNAL_DISCARD("lines_edited_from");
|
||||||
|
SIGNAL_DISCARD("caret_changed");
|
||||||
|
|
||||||
|
code_edit->cut();
|
||||||
|
MessageQueue::get_singleton()->flush();
|
||||||
|
CHECK(DS->clipboard_get() == "");
|
||||||
|
CHECK(code_edit->get_text() == "this is\nsome\n");
|
||||||
|
CHECK(code_edit->get_caret_line() == 0);
|
||||||
|
CHECK(code_edit->get_caret_column() == 6);
|
||||||
|
SIGNAL_CHECK_FALSE("caret_changed");
|
||||||
|
SIGNAL_CHECK_FALSE("text_changed");
|
||||||
|
SIGNAL_CHECK_FALSE("lines_edited_from");
|
||||||
|
}
|
||||||
|
|
||||||
SUBCASE("[SceneTree][CodeEdit] new line") {
|
SUBCASE("[SceneTree][CodeEdit] new line") {
|
||||||
// Add a new line.
|
// Add a new line.
|
||||||
code_edit->set_text("test new line");
|
code_edit->set_text("test new line");
|
||||||
|
|
|
@ -3585,6 +3585,54 @@ TEST_CASE("[SceneTree][TextEdit] text entry") {
|
||||||
SIGNAL_CHECK_FALSE("lines_edited_from");
|
SIGNAL_CHECK_FALSE("lines_edited_from");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SUBCASE("[TextEdit] cut when empty selection clipboard disabled") {
|
||||||
|
text_edit->set_empty_selection_clipboard_enabled(false);
|
||||||
|
DS->clipboard_set("");
|
||||||
|
|
||||||
|
text_edit->set_text("this is\nsome\n");
|
||||||
|
text_edit->set_caret_line(0);
|
||||||
|
text_edit->set_caret_column(6);
|
||||||
|
MessageQueue::get_singleton()->flush();
|
||||||
|
SIGNAL_DISCARD("text_set");
|
||||||
|
SIGNAL_DISCARD("text_changed");
|
||||||
|
SIGNAL_DISCARD("lines_edited_from");
|
||||||
|
SIGNAL_DISCARD("caret_changed");
|
||||||
|
|
||||||
|
text_edit->cut();
|
||||||
|
MessageQueue::get_singleton()->flush();
|
||||||
|
CHECK(DS->clipboard_get() == "");
|
||||||
|
CHECK(text_edit->get_text() == "this is\nsome\n");
|
||||||
|
CHECK(text_edit->get_caret_line() == 0);
|
||||||
|
CHECK(text_edit->get_caret_column() == 6);
|
||||||
|
SIGNAL_CHECK_FALSE("caret_changed");
|
||||||
|
SIGNAL_CHECK_FALSE("text_changed");
|
||||||
|
SIGNAL_CHECK_FALSE("lines_edited_from");
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("[TextEdit] copy when empty selection clipboard disabled") {
|
||||||
|
text_edit->set_empty_selection_clipboard_enabled(false);
|
||||||
|
DS->clipboard_set("");
|
||||||
|
|
||||||
|
text_edit->set_text("this is\nsome\n");
|
||||||
|
text_edit->set_caret_line(0);
|
||||||
|
text_edit->set_caret_column(6);
|
||||||
|
MessageQueue::get_singleton()->flush();
|
||||||
|
SIGNAL_DISCARD("text_set");
|
||||||
|
SIGNAL_DISCARD("text_changed");
|
||||||
|
SIGNAL_DISCARD("lines_edited_from");
|
||||||
|
SIGNAL_DISCARD("caret_changed");
|
||||||
|
|
||||||
|
text_edit->copy();
|
||||||
|
MessageQueue::get_singleton()->flush();
|
||||||
|
CHECK(DS->clipboard_get() == "");
|
||||||
|
CHECK(text_edit->get_text() == "this is\nsome\n");
|
||||||
|
CHECK(text_edit->get_caret_line() == 0);
|
||||||
|
CHECK(text_edit->get_caret_column() == 6);
|
||||||
|
SIGNAL_CHECK_FALSE("caret_changed");
|
||||||
|
SIGNAL_CHECK_FALSE("text_changed");
|
||||||
|
SIGNAL_CHECK_FALSE("lines_edited_from");
|
||||||
|
}
|
||||||
|
|
||||||
SIGNAL_UNWATCH(text_edit, "text_set");
|
SIGNAL_UNWATCH(text_edit, "text_set");
|
||||||
SIGNAL_UNWATCH(text_edit, "text_changed");
|
SIGNAL_UNWATCH(text_edit, "text_changed");
|
||||||
SIGNAL_UNWATCH(text_edit, "lines_edited_from");
|
SIGNAL_UNWATCH(text_edit, "lines_edited_from");
|
||||||
|
|
Loading…
Reference in New Issue