156 lines
4.9 KiB
GDScript
156 lines
4.9 KiB
GDScript
class_name TimeEntriesItemsTree extends Tree
|
|
|
|
enum COL{
|
|
TEXT,
|
|
TIME
|
|
}
|
|
|
|
const META_KEY = "time_entry"
|
|
|
|
var config: ConfigManager = preload("res://config_manager.tres")
|
|
|
|
var _timer := Timer.new()
|
|
|
|
|
|
func _ready() -> void:
|
|
hide_root = true
|
|
add_child(_timer)
|
|
# warning-ignore:return_value_discarded
|
|
connect("button_pressed", self, "_on_button_pressed")
|
|
# warning-ignore:return_value_discarded
|
|
_timer.connect("timeout", self, "_on_timer_timeout")
|
|
# warning-ignore:return_value_discarded
|
|
config.connect("time_sheet_loaded", self, "populate_entries")
|
|
# warning-ignore:return_value_discarded
|
|
connect("item_edited", self, "on_Tree_item_edited")
|
|
populate_entries()
|
|
|
|
|
|
func on_Tree_item_edited():
|
|
var tree_item := get_edited()
|
|
var time_entry := tree_item.get_meta(META_KEY) as TimeEntry
|
|
if time_entry == null:
|
|
return
|
|
|
|
var edited_start_time_str := tree_item.get_text(COL.TEXT)
|
|
var edited_start_time := TimeStamp.new().from_string(edited_start_time_str)
|
|
if edited_start_time.year == 1970:
|
|
_update_from_time_entry(time_entry, tree_item)
|
|
return
|
|
|
|
var edited_duration_str := tree_item.get_text(COL.TIME)
|
|
var edited_duration := TimeEntry.period_to_time(edited_duration_str)
|
|
if edited_duration == -1:
|
|
_update_from_time_entry(time_entry, tree_item)
|
|
return
|
|
|
|
var edited_end_time_unix := edited_start_time.unix + edited_duration
|
|
var edited_end_time := TimeStamp.new().from_unix_time(edited_end_time_unix)
|
|
|
|
if edited_start_time.equals(time_entry.start_time) \
|
|
and edited_end_time.equals(time_entry.end_time):
|
|
_update_from_time_entry(time_entry, tree_item)
|
|
return
|
|
|
|
time_entry.start_time = edited_start_time
|
|
time_entry.end_time = edited_end_time
|
|
config.timesheet.save()
|
|
|
|
|
|
|
|
func populate_entries() -> void:
|
|
clear()
|
|
var tree_items_root := create_item()
|
|
var item_entries_tree := config.timesheet.make_items_tree()
|
|
_populate_from_entry(tree_items_root, item_entries_tree)
|
|
_timer.start()
|
|
|
|
|
|
func _on_timer_timeout() -> void:
|
|
config.timesheet.update()
|
|
|
|
|
|
func _populate_from_entry(tree_item_root: TreeItem, time_entry_item_root: TimeEntryTreeItem):
|
|
var children := time_entry_item_root.children
|
|
for time_entry_name in children:
|
|
var time_entry_item: TimeEntryTreeItem = children[time_entry_name]
|
|
var item := find_or_create_item(tree_item_root, time_entry_name)
|
|
item.set_metadata(COL.TEXT, time_entry_name)
|
|
item.set_text(COL.TIME, time_entry_item.get_period())
|
|
# warning-ignore:return_value_discarded
|
|
time_entry_item.connect("end_time_updated", self, "_on_time_entry_changed_update_item", [time_entry_item, item])
|
|
_populate_from_entry(item, time_entry_item)
|
|
var has_at_least_one_running_entry := time_entry_item.find_active_time_entry() != null
|
|
var texture := preload("res://assets/stop_small.svg") \
|
|
if has_at_least_one_running_entry \
|
|
else preload("res://assets/play_small.svg")
|
|
item.add_button(COL.TIME, texture)
|
|
var entries = time_entry_item_root.time_entries
|
|
for entry_item in entries:
|
|
var time_entry_item := entry_item as TimeEntryTreeItem
|
|
var item := create_item(tree_item_root)
|
|
var time_entry := time_entry_item.time_entry
|
|
item.set_meta(META_KEY, time_entry)
|
|
item.set_metadata(COL.TEXT, time_entry.name)
|
|
item.set_editable(COL.TEXT, true)
|
|
item.set_editable(COL.TIME, true)
|
|
|
|
_update_from_time_entry(time_entry, item)
|
|
# warning-ignore:return_value_discarded
|
|
time_entry_item.connect("end_time_updated", self, "_on_time_entry_changed_update_item", [time_entry_item, item])
|
|
|
|
|
|
func _update_from_time_entry(time_entry: TimeEntry, item: TreeItem) -> void:
|
|
|
|
item.set_text(COL.TEXT, time_entry.start_time.to_string())
|
|
item.set_text(COL.TIME, time_entry.get_period())
|
|
if time_entry.is_closed == false:
|
|
if item.get_button_count(COL.TIME) < 1:
|
|
var texture := preload("res://assets/stop_small.svg")
|
|
item.add_button(COL.TIME, texture, 0)
|
|
else:
|
|
if item.get_button_count(COL.TIME) > 0:
|
|
item.erase_button(COL.TIME, 0)
|
|
|
|
|
|
func _on_time_entry_changed_update_item(time_entry_item: TimeEntryTreeItem, item: TreeItem) -> void:
|
|
item.set_text(COL.TIME, time_entry_item.get_period())
|
|
|
|
|
|
func _on_button_pressed(item: TreeItem, _column: int, _id: int) -> void:
|
|
var task_name: String = item.get_metadata(COL.TEXT)
|
|
if task_name == "":
|
|
return
|
|
config.timesheet.toggle_entry(task_name)
|
|
|
|
|
|
## Unecessary in Godot 4, can bre replaced with get_children()
|
|
static func _get_tree_item_children(item: TreeItem):
|
|
var children = []
|
|
var child = item.get_children()
|
|
if child == null:
|
|
return children
|
|
children.append(child)
|
|
child = child.get_next()
|
|
while child != null:
|
|
children.append(child)
|
|
child = child.get_next()
|
|
return children
|
|
|
|
|
|
## Finds an item in the tree by text
|
|
func find_item(root: TreeItem, item_name: String) -> TreeItem:
|
|
for child in _get_tree_item_children(root):
|
|
if child.get_text(COL.TEXT) == item_name:
|
|
return child
|
|
return null
|
|
|
|
|
|
func find_or_create_item(root: TreeItem, item_name: String) -> TreeItem:
|
|
var child := find_item(root, item_name)
|
|
if child != null:
|
|
return child
|
|
child = create_item(root)
|
|
child.set_text(COL.TEXT, item_name)
|
|
return child
|