Browse Source

Add TODO manager plugin

Arnaud Vergnet 10 months ago
parent
commit
efb4696b06

+ 16
- 0
addons/Todo_Manager/ColourPicker.gd View File

@@ -0,0 +1,16 @@
1
+tool
2
+extends HBoxContainer
3
+
4
+var colour : Color
5
+var title : String setget set_title
6
+var index : int
7
+
8
+onready var colour_picker := $TODOColourPickerButton
9
+
10
+func _ready() -> void:
11
+	$TODOColourPickerButton.color = colour
12
+	$Label.text = title
13
+
14
+func set_title(value: String) -> void:
15
+	title = value
16
+	$Label.text = value 

+ 45
- 0
addons/Todo_Manager/Current.gd View File

@@ -0,0 +1,45 @@
1
+tool
2
+extends Panel
3
+
4
+signal tree_built # used for debugging
5
+
6
+const Todo := preload("res://addons/Todo_Manager/todo_class.gd")
7
+const TodoItem := preload("res://addons/Todo_Manager/todoItem_class.gd")
8
+
9
+var sort_alphabetical := true
10
+
11
+onready var tree := $Tree as Tree
12
+
13
+func build_tree(todo_item : TodoItem, patterns : Array) -> void:
14
+	tree.clear()
15
+	var root := tree.create_item()
16
+	root.set_text(0, "Scripts")
17
+	var script := tree.create_item(root)
18
+	script.set_text(0, todo_item.get_short_path() + " -------")
19
+	script.set_metadata(0, todo_item)
20
+	for todo in todo_item.todos:
21
+		var item := tree.create_item(script)
22
+		var content_header : String = todo.content
23
+		if "\n" in todo.content:
24
+			content_header = content_header.split("\n")[0] + "..."
25
+		item.set_text(0, "(%0) - %1".format([todo.line_number, content_header], "%_"))
26
+		item.set_tooltip(0, todo.content)
27
+		item.set_metadata(0, todo)
28
+		for pattern in patterns:
29
+			if pattern[0] == todo.pattern:
30
+				item.set_custom_color(0, pattern[1])
31
+	emit_signal("tree_built")
32
+
33
+
34
+func sort_alphabetical(a, b) -> bool:
35
+	if a.script_path > b.script_path:
36
+		return true
37
+	else:
38
+		return false
39
+
40
+func sort_backwards(a, b) -> bool:
41
+	if a.script_path < b.script_path:
42
+		return true
43
+	else:
44
+		return false
45
+

+ 250
- 0
addons/Todo_Manager/Dock.gd View File

@@ -0,0 +1,250 @@
1
+tool
2
+extends Control
3
+
4
+#signal tree_built # used for debugging
5
+
6
+const Project := preload("res://addons/Todo_Manager/Project.gd")
7
+const Current := preload("res://addons/Todo_Manager/Current.gd")
8
+
9
+const Todo := preload("res://addons/Todo_Manager/todo_class.gd")
10
+const TodoItem := preload("res://addons/Todo_Manager/todoItem_class.gd")
11
+const ColourPicker := preload("res://addons/Todo_Manager/UI/ColourPicker.tscn")
12
+const Pattern := preload("res://addons/Todo_Manager/UI/Pattern.tscn")
13
+const DEFAULT_PATTERNS := [["\\bTODO\\b", Color("96f1ad")], ["\\bHACK\\b", Color("d5bc70")], ["\\bFIXME\\b", Color("d57070")]]
14
+const DEFAULT_SCRIPT_COLOUR := Color("ccced3")
15
+const DEFAULT_SCRIPT_NAME := false
16
+const DEFAULT_SORT := true
17
+
18
+var plugin : EditorPlugin
19
+
20
+var todo_items : Array
21
+
22
+var script_colour := Color("ccced3")
23
+var ignore_paths := []
24
+var full_path := false
25
+var sort_alphabetical := true
26
+var auto_refresh := true
27
+
28
+var patterns := [["\\bTODO\\b", Color("96f1ad")], ["\\bHACK\\b", Color("d5bc70")], ["\\bFIXME\\b", Color("d57070")]]
29
+
30
+onready var tabs := $VBoxContainer/TabContainer as TabContainer
31
+onready var project := $VBoxContainer/TabContainer/Project as Project
32
+onready var current := $VBoxContainer/TabContainer/Current as Current
33
+onready var project_tree := $VBoxContainer/TabContainer/Project/Tree as Tree
34
+onready var current_tree := $VBoxContainer/TabContainer/Current/Tree as Tree
35
+onready var settings_panel := $VBoxContainer/TabContainer/Settings as Panel
36
+onready var colours_container := $VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer3/Colours as VBoxContainer
37
+onready var pattern_container := $VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer4/Patterns as VBoxContainer
38
+onready var ignore_textbox := $VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/IgnorePaths/TextEdit as LineEdit
39
+
40
+func _ready() -> void:
41
+	load_config()
42
+	populate_settings()
43
+
44
+
45
+func build_tree() -> void:
46
+	if tabs:
47
+		match tabs.current_tab:
48
+			0:
49
+				project.build_tree(todo_items, ignore_paths, patterns, sort_alphabetical, full_path)
50
+				create_config_file()
51
+			1:
52
+				current.build_tree(get_active_script(), patterns)
53
+				create_config_file()
54
+			2:
55
+				pass
56
+			_:
57
+				pass
58
+
59
+
60
+func get_active_script() -> TodoItem:
61
+	var current_script : Script = plugin.get_editor_interface().get_script_editor().get_current_script()
62
+	if current_script:
63
+		var script_path = current_script.resource_path
64
+		for todo_item in todo_items:
65
+			if todo_item.script_path == script_path:
66
+				return todo_item
67
+		
68
+		# nothing found
69
+		var todo_item := TodoItem.new()
70
+		todo_item.script_path = script_path
71
+		return todo_item
72
+	else:
73
+		# not a script
74
+		var todo_item := TodoItem.new()
75
+		todo_item.script_path = "res://Documentation"
76
+		return todo_item
77
+
78
+
79
+func go_to_script(script_path: String, line_number : int = 0) -> void:
80
+	var script := load(script_path)
81
+	plugin.get_editor_interface().edit_resource(script)
82
+	plugin.get_editor_interface().get_script_editor().goto_line(line_number - 1)
83
+
84
+
85
+func sort_alphabetical(a, b) -> bool:
86
+	if a.script_path > b.script_path:
87
+		return true
88
+	else:
89
+		return false
90
+
91
+func sort_backwards(a, b) -> bool:
92
+	if a.script_path < b.script_path:
93
+		return true
94
+	else:
95
+		return false
96
+
97
+
98
+func populate_settings() -> void:
99
+	for i in patterns.size():
100
+		## Create Colour Pickers
101
+		var colour_picker := ColourPicker.instance()
102
+		colour_picker.colour = patterns[i][1]
103
+		colour_picker.title = patterns[i][0]
104
+		colour_picker.index = i
105
+		colours_container.add_child(colour_picker)
106
+		colour_picker.colour_picker.connect("color_changed", self, "change_colour", [i])
107
+		
108
+		## Create Patterns
109
+		var pattern_edit := Pattern.instance()
110
+		pattern_edit.text = patterns[i][0]
111
+		pattern_edit.index = i
112
+		pattern_container.add_child(pattern_edit)
113
+		pattern_edit.line_edit.connect("text_changed", self, "change_pattern", [i, colour_picker])
114
+		pattern_edit.remove_button.connect("pressed", self, "remove_pattern", [i, pattern_edit, colour_picker])
115
+	$VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer4/Patterns/AddPatternButton.raise()
116
+	
117
+	# path filtering
118
+	var ignore_paths_field := ignore_textbox
119
+	if !ignore_paths_field.is_connected("text_changed", self, "_on_ignore_paths_changed"):
120
+		ignore_paths_field.connect("text_changed", self, "_on_ignore_paths_changed")
121
+	var ignore_paths_text := ""
122
+	for path in ignore_paths:
123
+		ignore_paths_text += path + ", "
124
+	ignore_paths_text.rstrip(' ').rstrip(',')
125
+	ignore_paths_field.text = ignore_paths_text
126
+
127
+
128
+func rebuild_settings() -> void:
129
+	for node in colours_container.get_children():
130
+		node.queue_free()
131
+	for node in pattern_container.get_children():
132
+		if node is Button:
133
+			continue
134
+		node.queue_free()
135
+	populate_settings()
136
+
137
+
138
+#### CONFIG FILE ####
139
+func create_config_file() -> void:
140
+	var config = ConfigFile.new()
141
+	config.set_value("scripts", "full_path", full_path)
142
+	config.set_value("scripts", "sort_alphabetical", sort_alphabetical)
143
+	config.set_value("scripts", "script_colour", script_colour)
144
+	config.set_value("scripts", "ignore_paths", ignore_paths)
145
+	
146
+	config.set_value("patterns", "patterns", patterns)
147
+	
148
+	config.set_value("config", "auto_refresh", auto_refresh)
149
+	
150
+	var err = config.save("res://addons/Todo_Manager/todo.cfg")
151
+
152
+
153
+func load_config() -> void:
154
+	var config := ConfigFile.new()
155
+	if config.load("res://addons/Todo_Manager/todo.cfg") == OK:
156
+		full_path = config.get_value("scripts", "full_path", DEFAULT_SCRIPT_NAME)
157
+		sort_alphabetical = config.get_value("scripts", "sort_alphabetical", DEFAULT_SORT)
158
+		script_colour = config.get_value("scripts", "script_colour", DEFAULT_SCRIPT_COLOUR)
159
+		ignore_paths = config.get_value("scripts", "ignore_paths", [])
160
+		patterns = config.get_value("patterns", "patterns", DEFAULT_PATTERNS)
161
+		auto_refresh = config.get_value("config", "auto_refresh", true)
162
+	else:
163
+		create_config_file()
164
+
165
+
166
+#### Events ####
167
+func _on_SettingsButton_toggled(button_pressed: bool) -> void:
168
+	settings_panel.visible = button_pressed
169
+	if button_pressed == false:
170
+		create_config_file()
171
+#		plugin.find_tokens_from_path(plugin.script_cache)
172
+		if auto_refresh:
173
+			plugin.rescan_files()
174
+
175
+func _on_Tree_item_activated() -> void:
176
+	var item : TreeItem
177
+	match tabs.current_tab:
178
+		0:
179
+			item = project_tree.get_selected()
180
+		1: 
181
+			item = current_tree.get_selected()
182
+	if item.get_metadata(0) is Todo:
183
+		var todo : Todo = item.get_metadata(0)
184
+		call_deferred("go_to_script", todo.script_path, todo.line_number)
185
+	else:
186
+		var todo_item = item.get_metadata(0)
187
+		call_deferred("go_to_script", todo_item.script_path)
188
+
189
+func _on_FullPathCheckBox_toggled(button_pressed: bool) -> void:
190
+	full_path = button_pressed
191
+
192
+func _on_ScriptColourPickerButton_color_changed(color: Color) -> void:
193
+	script_colour = color
194
+
195
+func _on_TODOColourPickerButton_color_changed(color: Color) -> void:
196
+	patterns[0][1] = color
197
+
198
+func _on_RescanButton_pressed() -> void:
199
+	plugin.rescan_files()
200
+
201
+func change_colour(colour: Color, index: int) -> void:
202
+	patterns[index][1] = colour
203
+
204
+func change_pattern(value: String, index: int, this_colour: Node) -> void:
205
+	patterns[index][0] = value
206
+	this_colour.title = value
207
+
208
+func remove_pattern(index: int, this: Node, this_colour: Node) -> void:
209
+	patterns.remove(index)
210
+	this.queue_free()
211
+	this_colour.queue_free()
212
+
213
+func _on_DefaultButton_pressed() -> void:
214
+	patterns = DEFAULT_PATTERNS.duplicate(true)
215
+	sort_alphabetical = DEFAULT_SORT
216
+	script_colour = DEFAULT_SCRIPT_COLOUR
217
+	full_path = DEFAULT_SCRIPT_NAME
218
+	rebuild_settings()
219
+
220
+func _on_AlphSortCheckBox_toggled(button_pressed: bool) -> void:
221
+	sort_alphabetical = button_pressed
222
+
223
+func _on_AddPatternButton_pressed() -> void:
224
+	patterns.append(["\\bplaceholder\\b", Color.white])
225
+	rebuild_settings()
226
+
227
+func _on_RefreshCheckButton_toggled(button_pressed: bool) -> void:
228
+	auto_refresh = button_pressed
229
+
230
+func _on_Timer_timeout() -> void:
231
+	plugin.refresh_lock = false
232
+
233
+func _on_ignore_paths_changed(new_text: String) -> void:
234
+	var text = ignore_textbox.text
235
+	var split: Array = text.split(',')
236
+	ignore_paths.clear()
237
+	for elem in split:
238
+		if elem == " " || elem == "": 
239
+			continue
240
+		ignore_paths.push_front(elem.lstrip(' ').rstrip(' '))
241
+	# validate so no empty string slips through (all paths ignored)
242
+	var i := 0
243
+	for path in ignore_paths:
244
+		if (path == "" || path == " "):
245
+			ignore_paths.remove(i)
246
+		i += 1
247
+
248
+func _on_TabContainer_tab_changed(tab: int) -> void:
249
+	build_tree()
250
+

+ 19
- 0
addons/Todo_Manager/Pattern.gd View File

@@ -0,0 +1,19 @@
1
+tool
2
+extends HBoxContainer
3
+
4
+var text : String setget set_text
5
+var disabled : bool
6
+var index : int
7
+
8
+onready var line_edit := $LineEdit as LineEdit
9
+onready var remove_button := $RemoveButton as Button
10
+
11
+func _ready() -> void:
12
+	line_edit.text = text
13
+	remove_button.disabled = disabled
14
+
15
+
16
+func set_text(value: String) -> void:
17
+	text = value
18
+	if line_edit:
19
+		line_edit.text = value

+ 59
- 0
addons/Todo_Manager/Project.gd View File

@@ -0,0 +1,59 @@
1
+tool
2
+extends Panel
3
+
4
+signal tree_built # used for debugging
5
+
6
+const Todo := preload("res://addons/Todo_Manager/todo_class.gd")
7
+
8
+var sort_alphabetical := true
9
+
10
+onready var tree := $Tree as Tree
11
+
12
+func build_tree(todo_items : Array, ignore_paths : Array, patterns : Array, sort_alphabetical : bool, full_path : bool) -> void:
13
+	tree.clear()
14
+	if sort_alphabetical:
15
+		todo_items.sort_custom(self, "sort_alphabetical")
16
+	else:
17
+		todo_items.sort_custom(self, "sort_backwards")
18
+	var root := tree.create_item()
19
+	root.set_text(0, "Scripts")
20
+	for todo_item in todo_items:
21
+		var ignore := false
22
+		for ignore_path in ignore_paths:
23
+			var script_path : String = todo_item.script_path
24
+			if script_path.begins_with(ignore_path) or script_path.begins_with("res://" + ignore_path) or script_path.begins_with("res:///" + ignore_path):
25
+				ignore = true
26
+				break
27
+		if ignore: 
28
+			continue
29
+		var script := tree.create_item(root)
30
+		if full_path:
31
+			script.set_text(0, todo_item.script_path + " -------")
32
+		else:
33
+			script.set_text(0, todo_item.get_short_path() + " -------")
34
+		script.set_metadata(0, todo_item)
35
+		for todo in todo_item.todos:
36
+			var item := tree.create_item(script)
37
+			var content_header : String = todo.content
38
+			if "\n" in todo.content:
39
+				content_header = content_header.split("\n")[0] + "..."
40
+			item.set_text(0, "(%0) - %1".format([todo.line_number, content_header], "%_"))
41
+			item.set_tooltip(0, todo.content)
42
+			item.set_metadata(0, todo)
43
+			for pattern in patterns:
44
+				if pattern[0] == todo.pattern:
45
+					item.set_custom_color(0, pattern[1])
46
+	emit_signal("tree_built")
47
+
48
+
49
+func sort_alphabetical(a, b) -> bool:
50
+	if a.script_path > b.script_path:
51
+		return true
52
+	else:
53
+		return false
54
+
55
+func sort_backwards(a, b) -> bool:
56
+	if a.script_path < b.script_path:
57
+		return true
58
+	else:
59
+		return false

+ 24
- 0
addons/Todo_Manager/UI/ColourPicker.tscn View File

@@ -0,0 +1,24 @@
1
+[gd_scene load_steps=2 format=2]
2
+
3
+[ext_resource path="res://addons/Todo_Manager/ColourPicker.gd" type="Script" id=1]
4
+
5
+[node name="TODOColour" type="HBoxContainer"]
6
+margin_right = 156.0
7
+margin_bottom = 20.0
8
+script = ExtResource( 1 )
9
+__meta__ = {
10
+"_edit_use_anchors_": false
11
+}
12
+
13
+[node name="Label" type="Label" parent="."]
14
+margin_top = 3.0
15
+margin_right = 52.0
16
+margin_bottom = 17.0
17
+text = "#TODO:"
18
+
19
+[node name="TODOColourPickerButton" type="ColorPickerButton" parent="."]
20
+margin_left = 56.0
21
+margin_right = 156.0
22
+margin_bottom = 20.0
23
+rect_min_size = Vector2( 100, 0 )
24
+color = Color( 1, 1, 1, 1 )

+ 425
- 0
addons/Todo_Manager/UI/Dock.tscn View File

@@ -0,0 +1,425 @@
1
+[gd_scene load_steps=6 format=2]
2
+
3
+[ext_resource path="res://addons/Todo_Manager/Dock.gd" type="Script" id=1]
4
+[ext_resource path="res://addons/Todo_Manager/Project.gd" type="Script" id=2]
5
+[ext_resource path="res://addons/Todo_Manager/Current.gd" type="Script" id=3]
6
+
7
+[sub_resource type="ButtonGroup" id=1]
8
+
9
+[sub_resource type="ButtonGroup" id=2]
10
+
11
+[node name="Dock" type="Control"]
12
+anchor_right = 1.0
13
+anchor_bottom = 1.0
14
+rect_min_size = Vector2( 0, 200 )
15
+script = ExtResource( 1 )
16
+__meta__ = {
17
+"_edit_use_anchors_": false
18
+}
19
+
20
+[node name="VBoxContainer" type="VBoxContainer" parent="."]
21
+anchor_right = 1.0
22
+anchor_bottom = 1.0
23
+__meta__ = {
24
+"_edit_use_anchors_": false
25
+}
26
+
27
+[node name="Header" type="HBoxContainer" parent="VBoxContainer"]
28
+visible = false
29
+margin_right = 1024.0
30
+margin_bottom = 20.0
31
+__meta__ = {
32
+"_edit_use_anchors_": false
33
+}
34
+
35
+[node name="HeaderLeft" type="HBoxContainer" parent="VBoxContainer/Header"]
36
+margin_right = 510.0
37
+margin_bottom = 20.0
38
+size_flags_horizontal = 3
39
+
40
+[node name="Title" type="Label" parent="VBoxContainer/Header/HeaderLeft"]
41
+margin_top = 3.0
42
+margin_right = 71.0
43
+margin_bottom = 17.0
44
+text = "Todo Dock:"
45
+align = 1
46
+valign = 1
47
+
48
+[node name="HeaderRight" type="HBoxContainer" parent="VBoxContainer/Header"]
49
+margin_left = 514.0
50
+margin_right = 1024.0
51
+margin_bottom = 20.0
52
+size_flags_horizontal = 3
53
+alignment = 2
54
+
55
+[node name="SettingsButton" type="Button" parent="VBoxContainer/Header/HeaderRight"]
56
+visible = false
57
+margin_left = 447.0
58
+margin_right = 510.0
59
+margin_bottom = 20.0
60
+toggle_mode = true
61
+text = "Settings"
62
+__meta__ = {
63
+"_edit_use_anchors_": false
64
+}
65
+
66
+[node name="TabContainer" type="TabContainer" parent="VBoxContainer"]
67
+margin_right = 1024.0
68
+margin_bottom = 600.0
69
+size_flags_vertical = 3
70
+tab_align = 0
71
+
72
+[node name="Project" type="Panel" parent="VBoxContainer/TabContainer"]
73
+anchor_right = 1.0
74
+anchor_bottom = 1.0
75
+margin_left = 4.0
76
+margin_top = 32.0
77
+margin_right = -4.0
78
+margin_bottom = -4.0
79
+size_flags_horizontal = 3
80
+size_flags_vertical = 3
81
+script = ExtResource( 2 )
82
+__meta__ = {
83
+"_edit_use_anchors_": false
84
+}
85
+
86
+[node name="Tree" type="Tree" parent="VBoxContainer/TabContainer/Project"]
87
+anchor_right = 1.0
88
+anchor_bottom = 1.0
89
+hide_root = true
90
+__meta__ = {
91
+"_edit_use_anchors_": false
92
+}
93
+
94
+[node name="Current" type="Panel" parent="VBoxContainer/TabContainer"]
95
+visible = false
96
+anchor_right = 1.0
97
+anchor_bottom = 1.0
98
+margin_left = 4.0
99
+margin_top = 32.0
100
+margin_right = -4.0
101
+margin_bottom = -4.0
102
+size_flags_horizontal = 3
103
+size_flags_vertical = 3
104
+script = ExtResource( 3 )
105
+
106
+[node name="Tree" type="Tree" parent="VBoxContainer/TabContainer/Current"]
107
+anchor_right = 1.0
108
+anchor_bottom = 1.0
109
+custom_constants/draw_relationship_lines = 0
110
+hide_folding = true
111
+hide_root = true
112
+__meta__ = {
113
+"_edit_use_anchors_": false
114
+}
115
+
116
+[node name="Settings" type="Panel" parent="VBoxContainer/TabContainer"]
117
+visible = false
118
+anchor_right = 1.0
119
+anchor_bottom = 1.0
120
+margin_left = 4.0
121
+margin_top = 32.0
122
+margin_right = -4.0
123
+margin_bottom = -4.0
124
+__meta__ = {
125
+"_edit_use_anchors_": false
126
+}
127
+
128
+[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer/TabContainer/Settings"]
129
+anchor_right = 1.0
130
+anchor_bottom = 1.0
131
+__meta__ = {
132
+"_edit_use_anchors_": false
133
+}
134
+
135
+[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer"]
136
+margin_right = 1016.0
137
+margin_bottom = 564.0
138
+size_flags_horizontal = 3
139
+size_flags_vertical = 3
140
+custom_constants/margin_right = 5
141
+custom_constants/margin_top = 5
142
+custom_constants/margin_left = 5
143
+custom_constants/margin_bottom = 5
144
+
145
+[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer"]
146
+margin_left = 5.0
147
+margin_top = 5.0
148
+margin_right = 1011.0
149
+margin_bottom = 559.0
150
+size_flags_horizontal = 3
151
+size_flags_vertical = 3
152
+custom_constants/separation = 14
153
+
154
+[node name="Scripts" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"]
155
+margin_right = 1006.0
156
+margin_bottom = 14.0
157
+
158
+[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/Scripts"]
159
+margin_right = 47.0
160
+margin_bottom = 14.0
161
+text = "Scripts:"
162
+
163
+[node name="HSeparator" type="HSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/Scripts"]
164
+margin_left = 51.0
165
+margin_right = 1006.0
166
+margin_bottom = 14.0
167
+size_flags_horizontal = 3
168
+
169
+[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"]
170
+margin_top = 28.0
171
+margin_right = 1006.0
172
+margin_bottom = 132.0
173
+size_flags_horizontal = 5
174
+
175
+[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer"]
176
+margin_right = 1006.0
177
+margin_bottom = 104.0
178
+
179
+[node name="VSeparator" type="VSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2"]
180
+margin_right = 50.0
181
+margin_bottom = 104.0
182
+rect_min_size = Vector2( 50, 0 )
183
+
184
+[node name="Scripts" type="VBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2"]
185
+margin_left = 54.0
186
+margin_right = 545.0
187
+margin_bottom = 104.0
188
+
189
+[node name="ScriptName" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts"]
190
+margin_right = 491.0
191
+margin_bottom = 24.0
192
+
193
+[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptName"]
194
+margin_top = 5.0
195
+margin_right = 82.0
196
+margin_bottom = 19.0
197
+text = "Script Name:"
198
+
199
+[node name="FullPathCheckBox" type="CheckBox" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptName"]
200
+margin_left = 86.0
201
+margin_right = 169.0
202
+margin_bottom = 24.0
203
+group = SubResource( 1 )
204
+text = "Full path"
205
+
206
+[node name="ShortNameCheckBox" type="CheckBox" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptName"]
207
+margin_left = 173.0
208
+margin_right = 274.0
209
+margin_bottom = 24.0
210
+pressed = true
211
+group = SubResource( 1 )
212
+text = "Short name"
213
+
214
+[node name="ScriptSort" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts"]
215
+margin_top = 28.0
216
+margin_right = 491.0
217
+margin_bottom = 52.0
218
+
219
+[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptSort"]
220
+margin_top = 5.0
221
+margin_right = 70.0
222
+margin_bottom = 19.0
223
+text = "Sort Order:"
224
+
225
+[node name="AlphSortCheckBox" type="CheckBox" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptSort"]
226
+margin_left = 74.0
227
+margin_right = 181.0
228
+margin_bottom = 24.0
229
+pressed = true
230
+group = SubResource( 2 )
231
+text = "Alphabetical"
232
+
233
+[node name="RAlphSortCheckBox" type="CheckBox" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptSort"]
234
+margin_left = 185.0
235
+margin_right = 347.0
236
+margin_bottom = 24.0
237
+group = SubResource( 2 )
238
+text = "Reverse Alphabetical"
239
+
240
+[node name="Label2" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptSort"]
241
+margin_left = 351.0
242
+margin_top = 5.0
243
+margin_right = 475.0
244
+margin_bottom = 19.0
245
+custom_colors/font_color = Color( 0.392157, 0.392157, 0.392157, 1 )
246
+text = "(Sorted by full path)"
247
+
248
+[node name="ScriptColour" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts"]
249
+margin_top = 56.0
250
+margin_right = 491.0
251
+margin_bottom = 76.0
252
+
253
+[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptColour"]
254
+margin_top = 3.0
255
+margin_right = 85.0
256
+margin_bottom = 17.0
257
+text = "Script Colour:"
258
+
259
+[node name="ScriptColourPickerButton" type="ColorPickerButton" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptColour"]
260
+margin_left = 89.0
261
+margin_right = 189.0
262
+margin_bottom = 20.0
263
+rect_min_size = Vector2( 100, 0 )
264
+color = Color( 0.8, 0.807843, 0.827451, 1 )
265
+
266
+[node name="IgnorePaths" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts"]
267
+margin_top = 80.0
268
+margin_right = 491.0
269
+margin_bottom = 104.0
270
+
271
+[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/IgnorePaths"]
272
+margin_top = 5.0
273
+margin_right = 84.0
274
+margin_bottom = 19.0
275
+text = "Ignore Paths:"
276
+
277
+[node name="TextEdit" type="LineEdit" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/IgnorePaths"]
278
+margin_left = 88.0
279
+margin_right = 338.0
280
+margin_bottom = 24.0
281
+rect_min_size = Vector2( 250, 0 )
282
+
283
+[node name="Label3" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/IgnorePaths"]
284
+margin_left = 342.0
285
+margin_top = 5.0
286
+margin_right = 491.0
287
+margin_bottom = 19.0
288
+custom_colors/font_color = Color( 0.392157, 0.392157, 0.392157, 1 )
289
+text = "(Separated by commas)"
290
+
291
+[node name="TODOColours" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"]
292
+margin_top = 146.0
293
+margin_right = 1006.0
294
+margin_bottom = 160.0
295
+
296
+[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/TODOColours"]
297
+margin_right = 95.0
298
+margin_bottom = 14.0
299
+text = "TODO Colours:"
300
+
301
+[node name="HSeparator" type="HSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/TODOColours"]
302
+margin_left = 99.0
303
+margin_right = 1006.0
304
+margin_bottom = 14.0
305
+size_flags_horizontal = 3
306
+
307
+[node name="HBoxContainer3" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"]
308
+margin_top = 174.0
309
+margin_right = 1006.0
310
+margin_bottom = 242.0
311
+
312
+[node name="VSeparator" type="VSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer3"]
313
+margin_right = 50.0
314
+margin_bottom = 68.0
315
+rect_min_size = Vector2( 50, 0 )
316
+
317
+[node name="Colours" type="VBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer3"]
318
+margin_left = 54.0
319
+margin_right = 223.0
320
+margin_bottom = 68.0
321
+
322
+[node name="Patterns" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"]
323
+margin_top = 256.0
324
+margin_right = 1006.0
325
+margin_bottom = 270.0
326
+
327
+[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/Patterns"]
328
+margin_right = 57.0
329
+margin_bottom = 14.0
330
+text = "Patterns:"
331
+
332
+[node name="HSeparator" type="HSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/Patterns"]
333
+margin_left = 61.0
334
+margin_right = 1006.0
335
+margin_bottom = 14.0
336
+size_flags_horizontal = 3
337
+
338
+[node name="HBoxContainer4" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"]
339
+margin_top = 284.0
340
+margin_right = 1006.0
341
+margin_bottom = 388.0
342
+
343
+[node name="VSeparator" type="VSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer4"]
344
+margin_right = 50.0
345
+margin_bottom = 104.0
346
+rect_min_size = Vector2( 50, 0 )
347
+
348
+[node name="Patterns" type="VBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer4"]
349
+margin_left = 54.0
350
+margin_right = 282.0
351
+margin_bottom = 104.0
352
+
353
+[node name="AddPatternButton" type="Button" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer4/Patterns"]
354
+margin_top = 84.0
355
+margin_right = 37.0
356
+margin_bottom = 104.0
357
+size_flags_horizontal = 0
358
+text = "Add"
359
+
360
+[node name="Config" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"]
361
+margin_top = 402.0
362
+margin_right = 1006.0
363
+margin_bottom = 416.0
364
+
365
+[node name="Label" type="Label" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/Config"]
366
+margin_right = 43.0
367
+margin_bottom = 14.0
368
+text = "Config:"
369
+
370
+[node name="HSeparator" type="HSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/Config"]
371
+margin_left = 47.0
372
+margin_right = 1006.0
373
+margin_bottom = 14.0
374
+size_flags_horizontal = 3
375
+
376
+[node name="HBoxContainer5" type="HBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer"]
377
+margin_top = 430.0
378
+margin_right = 1006.0
379
+margin_bottom = 494.0
380
+
381
+[node name="VSeparator" type="VSeparator" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5"]
382
+margin_right = 50.0
383
+margin_bottom = 64.0
384
+rect_min_size = Vector2( 50, 0 )
385
+
386
+[node name="Patterns" type="VBoxContainer" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5"]
387
+margin_left = 54.0
388
+margin_right = 216.0
389
+margin_bottom = 64.0
390
+
391
+[node name="RefreshCheckButton" type="CheckButton" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5/Patterns"]
392
+margin_right = 162.0
393
+margin_bottom = 40.0
394
+pressed = true
395
+text = "Auto Refresh"
396
+
397
+[node name="DefaultButton" type="Button" parent="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5/Patterns"]
398
+margin_top = 44.0
399
+margin_right = 113.0
400
+margin_bottom = 64.0
401
+size_flags_horizontal = 0
402
+text = "Reset to default"
403
+
404
+[node name="Timer" type="Timer" parent="."]
405
+one_shot = true
406
+
407
+[node name="RescanButton" type="Button" parent="."]
408
+anchor_left = 1.0
409
+anchor_right = 1.0
410
+margin_left = -97.0
411
+margin_right = -6.0
412
+margin_bottom = 20.0
413
+text = "Rescan Files"
414
+[connection signal="toggled" from="VBoxContainer/Header/HeaderRight/SettingsButton" to="." method="_on_SettingsButton_toggled"]
415
+[connection signal="tab_changed" from="VBoxContainer/TabContainer" to="." method="_on_TabContainer_tab_changed"]
416
+[connection signal="item_activated" from="VBoxContainer/TabContainer/Project/Tree" to="." method="_on_Tree_item_activated"]
417
+[connection signal="item_activated" from="VBoxContainer/TabContainer/Current/Tree" to="." method="_on_Tree_item_activated"]
418
+[connection signal="toggled" from="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptName/FullPathCheckBox" to="." method="_on_FullPathCheckBox_toggled"]
419
+[connection signal="toggled" from="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptSort/AlphSortCheckBox" to="." method="_on_AlphSortCheckBox_toggled"]
420
+[connection signal="color_changed" from="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/VBoxContainer/HBoxContainer2/Scripts/ScriptColour/ScriptColourPickerButton" to="." method="_on_ScriptColourPickerButton_color_changed"]
421
+[connection signal="pressed" from="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer4/Patterns/AddPatternButton" to="." method="_on_AddPatternButton_pressed"]
422
+[connection signal="toggled" from="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5/Patterns/RefreshCheckButton" to="." method="_on_RefreshCheckButton_toggled"]
423
+[connection signal="pressed" from="VBoxContainer/TabContainer/Settings/ScrollContainer/MarginContainer/VBoxContainer/HBoxContainer5/Patterns/DefaultButton" to="." method="_on_DefaultButton_pressed"]
424
+[connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]
425
+[connection signal="pressed" from="RescanButton" to="." method="_on_RescanButton_pressed"]

+ 25
- 0
addons/Todo_Manager/UI/Pattern.tscn View File

@@ -0,0 +1,25 @@
1
+[gd_scene load_steps=2 format=2]
2
+
3
+[ext_resource path="res://addons/Todo_Manager/Pattern.gd" type="Script" id=1]
4
+
5
+[node name="Pattern" type="HBoxContainer"]
6
+margin_right = 228.0
7
+margin_bottom = 24.0
8
+script = ExtResource( 1 )
9
+__meta__ = {
10
+"_edit_use_anchors_": false
11
+}
12
+
13
+[node name="LineEdit" type="LineEdit" parent="."]
14
+margin_right = 200.0
15
+margin_bottom = 24.0
16
+rect_min_size = Vector2( 200, 0 )
17
+size_flags_horizontal = 0
18
+text = "\\bTODO\\b.*"
19
+
20
+[node name="RemoveButton" type="Button" parent="."]
21
+margin_left = 204.0
22
+margin_right = 228.0
23
+margin_bottom = 24.0
24
+rect_min_size = Vector2( 24, 24 )
25
+text = "-"

+ 7
- 0
addons/Todo_Manager/plugin.cfg View File

@@ -0,0 +1,7 @@
1
+[plugin]
2
+
3
+name="Todo Manager"
4
+description="Dock for housing TODO messages."
5
+author="Peter de Vroom"
6
+version="1.1"
7
+script="plugin.gd"

+ 257
- 0
addons/Todo_Manager/plugin.gd View File

@@ -0,0 +1,257 @@
1
+tool
2
+extends EditorPlugin
3
+
4
+const DockScene := preload("res://addons/Todo_Manager/UI/Dock.tscn")
5
+const Dock := preload("res://addons/Todo_Manager/Dock.gd")
6
+const Todo := preload("res://addons/Todo_Manager/todo_class.gd")
7
+const TodoItem := preload("res://addons/Todo_Manager/todoItem_class.gd")
8
+
9
+var _dockUI : Dock
10
+#var update_thread : Thread = Thread.new()
11
+
12
+var script_cache : Array
13
+var remove_queue : Array
14
+var combined_pattern : String
15
+
16
+var refresh_lock := false # makes sure _on_filesystem_changed only triggers once
17
+
18
+func _enter_tree() -> void:
19
+	_dockUI = DockScene.instance() as Control
20
+	add_control_to_bottom_panel(_dockUI, "TODO")
21
+	connect("resource_saved", self, "check_saved_file")
22
+	get_editor_interface().get_resource_filesystem().connect("filesystem_changed", self, "_on_filesystem_changed")
23
+	get_editor_interface().get_file_system_dock().connect("file_removed", self, "queue_remove")
24
+	get_editor_interface().get_script_editor().connect("editor_script_changed", self, "_on_active_script_changed")
25
+	_dockUI.plugin = self
26
+	combined_pattern = combine_patterns(_dockUI.patterns)
27
+	find_tokens_from_path(find_scripts())
28
+	_dockUI.build_tree()
29
+
30
+
31
+func _exit_tree() -> void:
32
+	_dockUI.create_config_file()
33
+	remove_control_from_bottom_panel(_dockUI)
34
+	_dockUI.queue_free()
35
+
36
+
37
+func queue_remove(file: String):
38
+	for i in _dockUI.todo_items.size() - 1:
39
+		if _dockUI.todo_items[i].script_path == file:
40
+			_dockUI.todo_items.remove(i)
41
+
42
+
43
+func find_tokens_from_path(scripts: Array) -> void:
44
+	for script_path in scripts:
45
+		var file := File.new()
46
+		file.open(script_path, File.READ)
47
+		var contents := file.get_as_text()
48
+		file.close()
49
+		find_tokens(contents, script_path)
50
+
51
+func find_tokens_from_script(script: Resource) -> void:
52
+	find_tokens(script.source_code, script.resource_path)
53
+
54
+
55
+func find_tokens(text: String, script_path: String) -> void:
56
+	var regex = RegEx.new()
57
+#	if regex.compile("#\\s*\\bTODO\\b.*|#\\s*\\bHACK\\b.*") == OK:
58
+	if regex.compile(combined_pattern) == OK:
59
+		var result : Array = regex.search_all(text)
60
+		if result.empty():
61
+			for i in _dockUI.todo_items.size():
62
+				if _dockUI.todo_items[i].script_path == script_path:
63
+					_dockUI.todo_items.remove(i)
64
+			return # No tokens found
65
+		var match_found : bool
66
+		var i := 0
67
+		for todo_item in _dockUI.todo_items:
68
+			if todo_item.script_path == script_path:
69
+				match_found = true
70
+				var updated_todo_item := update_todo_item(todo_item, result, text, script_path)
71
+				_dockUI.todo_items.remove(i)
72
+				_dockUI.todo_items.insert(i, updated_todo_item)
73
+				break
74
+			i += 1
75
+		if !match_found:
76
+			_dockUI.todo_items.append(create_todo_item(result, text, script_path))
77
+
78
+
79
+func create_todo_item(regex_results: Array, text: String, script_path: String) -> TodoItem:
80
+	var todo_item = TodoItem.new()
81
+	todo_item.script_path = script_path
82
+	var last_line_number := 0
83
+	var lines := text.split("\n")
84
+	for r in regex_results:
85
+		var new_todo : Todo = create_todo(r.get_string(), script_path)
86
+		new_todo.line_number = get_line_number(r.get_string(), text, last_line_number)
87
+		# GD Multiline comment
88
+		var trailing_line := new_todo.line_number
89
+		var should_break = false
90
+		while trailing_line < lines.size() and lines[trailing_line].dedent().begins_with("#"):
91
+			for other_r in regex_results:
92
+				if lines[trailing_line] in other_r.get_string():
93
+					should_break = true
94
+					break
95
+			if should_break:
96
+				break
97
+			
98
+			new_todo.content += "\n" + lines[trailing_line]
99
+			trailing_line += 1
100
+		
101
+		last_line_number = new_todo.line_number
102
+		todo_item.todos.append(new_todo)
103
+	return todo_item
104
+
105
+
106
+func update_todo_item(todo_item: TodoItem, regex_results: Array, text: String, script_path: String) -> TodoItem:
107
+	todo_item.todos.clear()
108
+	var lines := text.split("\n")
109
+	for r in regex_results:
110
+		var new_todo : Todo = create_todo(r.get_string(), script_path)
111
+		new_todo.line_number = get_line_number(r.get_string(), text)
112
+		# GD Multiline comment
113
+		var trailing_line := new_todo.line_number
114
+		var should_break = false
115
+		while trailing_line < lines.size() and lines[trailing_line].dedent().begins_with("#"):
116
+			for other_r in regex_results:
117
+				if lines[trailing_line] in other_r.get_string():
118
+					should_break = true
119
+					break
120
+			if should_break:
121
+				break
122
+			
123
+			new_todo.content += "\n" + lines[trailing_line]
124
+			trailing_line += 1
125
+		todo_item.todos.append(new_todo)
126
+	return todo_item
127
+
128
+
129
+func get_line_number(what: String, from: String, start := 0) -> int:
130
+	what = what.split('\n')[0] # Match first line of multiline C# comments
131
+	var temp_array := from.split('\n')
132
+	var lines := Array(temp_array)
133
+	var line_number# = lines.find(what) + 1
134
+	for i in range(start, lines.size()):
135
+		if what in lines[i]:
136
+			line_number = i + 1 # +1 to account of 0-based array vs 1-based line numbers
137
+			break
138
+		else:
139
+			line_number = 0 # This is an error
140
+	return line_number
141
+
142
+
143
+func check_saved_file(script: Resource) -> void:
144
+#	print(script)
145
+	pass
146
+#	if _dockUI.auto_refresh:
147
+#		if script is Script:
148
+#			find_tokens_from_script(script)
149
+#		_dockUI.build_tree()
150
+
151
+
152
+func _on_filesystem_changed() -> void:
153
+	if !refresh_lock:
154
+		if _dockUI.auto_refresh:
155
+			refresh_lock = true
156
+			_dockUI.get_node("Timer").start()
157
+			rescan_files()
158
+
159
+func find_scripts() -> Array:
160
+	var scripts : Array
161
+	var directory_queue : Array
162
+	var dir : Directory = Directory.new()
163
+	### FIRST PHASE ###
164
+	if dir.open("res://") == OK:
165
+		get_dir_contents(dir, scripts, directory_queue)
166
+	else:
167
+		printerr("TODO_Manager: There was an error during find_scripts() ### First Phase ###")
168
+	
169
+	### SECOND PHASE ###
170
+	while not directory_queue.empty():
171
+		if dir.change_dir(directory_queue[0]) == OK:
172
+			get_dir_contents(dir, scripts, directory_queue)
173
+		else:
174
+			printerr("TODO_Manager: There was an error at: " + directory_queue[0])
175
+		directory_queue.pop_front()
176
+	
177
+	cache_scripts(scripts)
178
+	return scripts
179
+
180
+
181
+func cache_scripts(scripts: Array) -> void:
182
+	for script in scripts:
183
+		if not script_cache.has(script):
184
+			script_cache.append(script)
185
+
186
+
187
+func get_dir_contents(dir: Directory, scripts: Array, directory_queue: Array) -> void:
188
+	dir.list_dir_begin(true, true)
189
+	var file_name : String = dir.get_next()
190
+	
191
+	while file_name != "":
192
+		if dir.current_is_dir():
193
+			if file_name == ".import" or filename == ".mono": # Skip .import folder which should never have scripts
194
+				pass
195
+			else:
196
+				directory_queue.append(dir.get_current_dir() + "/" + file_name)
197
+		else:
198
+			if file_name.ends_with(".gd") or file_name.ends_with(".cs"):
199
+				if dir.get_current_dir() == "res://":
200
+					scripts.append(dir.get_current_dir() + file_name)
201
+				else:
202
+					scripts.append(dir.get_current_dir() + "/" + file_name)
203
+		file_name = dir.get_next()
204
+
205
+
206
+func rescan_files() -> void:
207
+	_dockUI.todo_items.clear()
208
+	script_cache.clear()
209
+	combined_pattern = combine_patterns(_dockUI.patterns)
210
+	find_tokens_from_path(find_scripts())
211
+	_dockUI.build_tree()
212
+
213
+
214
+func combine_patterns(patterns: Array) -> String:
215
+	if patterns.size() == 1:
216
+		return patterns[0][0]
217
+	else:
218
+#		var pattern_string : String
219
+		var pattern_string := "((\\/\\*)|(#|\\/\\/))\\s*("
220
+		for i in range(patterns.size()):
221
+			if i == 0:
222
+				pattern_string += patterns[i][0]
223
+			else:
224
+				pattern_string += "|" + patterns[i][0]
225
+		pattern_string += ")(?(2)[\\s\\S]*?\\*\\/|.*)"
226
+#			if i == 0:
227
+##				pattern_string = "#\\s*" + patterns[i][0] + ".*"		
228
+#				pattern_string = "((\\/\\*)|(#|\\/\\/))\\s*" + patterns[i][0] + ".*" 		# (?(2)[\\s\\S]*?\\*\\/|.*)
229
+#			else:
230
+##				pattern_string += "|" + "#\\s*" + patterns[i][0]  + ".*"
231
+#				pattern_string += "|" + "((\\/\\*)|(#|\\/\\/))\\s*" + patterns[i][0]  + ".*"
232
+		return pattern_string
233
+
234
+
235
+func create_todo(todo_string: String, script_path: String) -> Todo:
236
+	var todo := Todo.new()
237
+	var regex = RegEx.new()
238
+	for pattern in _dockUI.patterns:
239
+		if regex.compile(pattern[0]) == OK:
240
+			var result : RegExMatch = regex.search(todo_string)
241
+			if result:
242
+				todo.pattern = pattern[0]
243
+				todo.title = result.strings[0]
244
+			else:
245
+				continue
246
+		else:
247
+			printerr("Error compiling " + pattern[0])
248
+	
249
+	todo.content = todo_string
250
+	todo.script_path = script_path
251
+	return todo
252
+
253
+
254
+func _on_active_script_changed(script) -> void:
255
+	if _dockUI:
256
+		if _dockUI.tabs.current_tab == 1:
257
+			_dockUI.build_tree()

+ 14
- 0
addons/Todo_Manager/todo.cfg View File

@@ -0,0 +1,14 @@
1
+[scripts]
2
+
3
+full_path=false
4
+sort_alphabetical=true
5
+script_colour=Color( 0.8, 0.807843, 0.827451, 1 )
6
+ignore_paths=[  ]
7
+
8
+[patterns]
9
+
10
+patterns=[ [ "\\bTODO\\b", Color( 0.588235, 0.945098, 0.678431, 1 ) ], [ "\\bHACK\\b", Color( 0.835294, 0.737255, 0.439216, 1 ) ], [ "\\bFIXME\\b", Color( 0.835294, 0.439216, 0.439216, 1 ) ] ]
11
+
12
+[config]
13
+
14
+auto_refresh=true

+ 14
- 0
addons/Todo_Manager/todoItem_class.gd View File

@@ -0,0 +1,14 @@
1
+tool
2
+extends Reference
3
+
4
+var script_path : String
5
+var todos : Array
6
+
7
+func get_short_path() -> String:
8
+	var temp_array := script_path.rsplit('/', false, 1)
9
+	var short_path : String
10
+	if !temp_array[1]:
11
+		short_path = "(!)" + temp_array[0]
12
+	else:
13
+		short_path = temp_array[1]
14
+	return short_path

+ 8
- 0
addons/Todo_Manager/todo_class.gd View File

@@ -0,0 +1,8 @@
1
+tool
2
+extends Reference
3
+
4
+var pattern : String
5
+var title : String
6
+var content : String
7
+var script_path : String
8
+var line_number : int

+ 4
- 0
project.godot View File

@@ -23,6 +23,10 @@ _global_script_class_icons={
23 23
 config/name="Pir-serious-game-ethics"
24 24
 config/icon="res://icon.png"
25 25
 
26
+[editor_plugins]
27
+
28
+enabled=PoolStringArray( "EXP-System-Dialog", "Todo_Manager" )
29
+
26 30
 [gdnative]
27 31
 
28 32
 singletons=[ "res://git_api.gdnlib" ]

Loading…
Cancel
Save