tasks list working
This commit is contained in:
@ -1,16 +1,16 @@
|
||||
class_name ConfigManager extends Resource
|
||||
|
||||
|
||||
signal entry_started
|
||||
signal entry_stopped
|
||||
signal file_changed
|
||||
signal time_sheet_reloaded
|
||||
|
||||
const CONFIG_PATH := "user://settings.cfg"
|
||||
var _config := ConfigFile.new()
|
||||
var _watcher: FileWatcher
|
||||
|
||||
var timesheet: TimeSheet setget ,get_timesheet
|
||||
|
||||
var _config := ConfigFile.new()
|
||||
var _watcher: FileWatcher
|
||||
|
||||
func get_timesheet() -> TimeSheet:
|
||||
if timesheet == null:
|
||||
timesheet = _load_timesheet(get_current_file())
|
||||
@ -20,29 +20,26 @@ func get_timesheet() -> TimeSheet:
|
||||
func _load_timesheet(path: String) -> TimeSheet:
|
||||
timesheet = TimeSheet.restore(path)
|
||||
if timesheet == null:
|
||||
_watcher = null
|
||||
return null
|
||||
_watcher = FileWatcher.new()
|
||||
_watcher.file_name = path
|
||||
# warning-ignore:return_value_discarded
|
||||
_watcher.connect("file_changed", self, "reload_timesheet")
|
||||
_watcher.start()
|
||||
# warning-ignore:return_value_discarded
|
||||
_watcher.connect("file_changed", self, "_on_file_changed")
|
||||
#timesheet.connect("entry_started", self, "_on_entry_started")
|
||||
# warning-ignore:return_value_discarded
|
||||
timesheet.connect("entry_started", self, "_on_entry_started")
|
||||
# warning-ignore:return_value_discarded
|
||||
timesheet.connect("entry_stopped", self, "_on_entry_stopped")
|
||||
#timesheet.connect("entry_stopped", self, "_on_entry_stopped")
|
||||
return timesheet
|
||||
|
||||
|
||||
func _on_entry_started() -> void:
|
||||
emit_signal("entry_started")
|
||||
|
||||
func _on_entry_stopped() -> void:
|
||||
emit_signal("entry_stopped")
|
||||
|
||||
|
||||
func _on_file_changed() -> void:
|
||||
emit_signal("file_changed")
|
||||
func reload_timesheet() -> void:
|
||||
var new_timesheet = _load_timesheet(get_current_file())
|
||||
if new_timesheet == null:
|
||||
printerr("failed to load new timesheet")
|
||||
return
|
||||
timesheet = new_timesheet
|
||||
emit_signal("time_sheet_reloaded")
|
||||
|
||||
|
||||
var current_file: String = "" setget set_current_file, get_current_file
|
||||
|
@ -2,11 +2,14 @@
|
||||
## Has a beginning and an end
|
||||
class_name TimeEntry
|
||||
|
||||
|
||||
signal end_time_updated
|
||||
signal closed
|
||||
|
||||
var name := ""
|
||||
var closed := false
|
||||
var is_closed := false
|
||||
var start_time := TimeStamp.new()
|
||||
var end_time := TimeStamp.new()
|
||||
var previous_total := 0
|
||||
|
||||
|
||||
func start_recording() -> TimeEntry:
|
||||
@ -17,6 +20,13 @@ func start_recording() -> TimeEntry:
|
||||
|
||||
func update() -> void:
|
||||
end_time = end_time.from_current_time()
|
||||
emit_signal("end_time_updated")
|
||||
|
||||
|
||||
func close() -> void:
|
||||
update()
|
||||
is_closed = true
|
||||
emit_signal("closed")
|
||||
|
||||
|
||||
func get_elapsed_seconds() -> int:
|
||||
@ -24,21 +34,11 @@ func get_elapsed_seconds() -> int:
|
||||
return elapsed
|
||||
|
||||
|
||||
func get_total_elapsed_seconds() -> int:
|
||||
var elapsed := get_elapsed_seconds() + previous_total
|
||||
return elapsed
|
||||
|
||||
|
||||
func get_period() -> String:
|
||||
var time_in_secs := get_elapsed_seconds()
|
||||
return time_to_period(time_in_secs)
|
||||
|
||||
|
||||
func get_total_period() -> String:
|
||||
var time_in_secs := get_total_elapsed_seconds()
|
||||
return time_to_period(time_in_secs)
|
||||
|
||||
|
||||
static func time_to_period(time_in_secs: int) -> String:
|
||||
# warning-ignore:integer_division
|
||||
var seconds := time_in_secs%60
|
||||
@ -48,14 +48,16 @@ static func time_to_period(time_in_secs: int) -> String:
|
||||
var hours := (time_in_secs/60)/60
|
||||
return "%02d:%02d:%02d" % [hours, minutes, seconds]
|
||||
|
||||
|
||||
func to_csv_line() -> PoolStringArray:
|
||||
return PoolStringArray([
|
||||
name,
|
||||
start_time,
|
||||
end_time,
|
||||
str(get_elapsed_seconds()) if closed else tr(Consts.ONGOING)
|
||||
str(get_elapsed_seconds()) if is_closed else tr(Consts.ONGOING)
|
||||
])
|
||||
|
||||
|
||||
static func is_csv_line_valid(line: PoolStringArray) -> bool:
|
||||
return line.size() > 3
|
||||
|
||||
@ -68,9 +70,9 @@ func from_csv_line(line: PoolStringArray) -> TimeEntry:
|
||||
start_time.from_string(start_time_string)
|
||||
|
||||
var elapsed_seconds = int(line[3]) if line[3].is_valid_integer() else 0
|
||||
closed = elapsed_seconds > 0
|
||||
is_closed = elapsed_seconds > 0
|
||||
|
||||
if closed == true:
|
||||
if is_closed == true:
|
||||
var end_time_string = line[2]
|
||||
# warning-ignore:return_value_discarded
|
||||
end_time.from_string(end_time_string)
|
||||
@ -79,5 +81,12 @@ func from_csv_line(line: PoolStringArray) -> TimeEntry:
|
||||
end_time.from_current_time()
|
||||
return self
|
||||
|
||||
|
||||
func to_dict() -> Dictionary:
|
||||
return {
|
||||
start_time = start_time,
|
||||
closed = is_closed,
|
||||
}
|
||||
|
||||
func _to_string() -> String:
|
||||
return "%s\t%s\t%s"%[name, Consts.ONGOING if closed == false else "", start_time]
|
||||
return "%s\t%s\t%s"%[name, tr(Consts.ONGOING) if is_closed == false else end_time.to_string(), start_time]
|
||||
|
70
scripts/time_entry_tree_item.gd
Normal file
70
scripts/time_entry_tree_item.gd
Normal file
@ -0,0 +1,70 @@
|
||||
class_name TimeEntryTreeItem
|
||||
|
||||
signal end_time_updated
|
||||
|
||||
var time_entry: TimeEntry
|
||||
var children := {}
|
||||
var time_entries := []
|
||||
|
||||
func get_child(parts: Array, or_create := false):
|
||||
var TimeEntryTreeItem = load("res://scripts/time_entry_tree_item.gd")
|
||||
if parts.size() == 0:
|
||||
return self
|
||||
var part: String = parts.pop_front()
|
||||
if not children.has(part):
|
||||
if or_create == false:
|
||||
return null
|
||||
var time_entry_tree_item = TimeEntryTreeItem.new()
|
||||
# warning-ignore:return_value_discarded
|
||||
time_entry_tree_item.connect("end_time_updated", self, "_on_end_time_updated")
|
||||
children[part] = time_entry_tree_item
|
||||
return children[part].get_child(parts, or_create)
|
||||
|
||||
|
||||
func append(new_time_entry: TimeEntry) -> void:
|
||||
var TimeEntryTreeItem = load("res://scripts/time_entry_tree_item.gd")
|
||||
var time_entry_tree_item = TimeEntryTreeItem.new()
|
||||
time_entry_tree_item.time_entry = new_time_entry
|
||||
# warning-ignore:return_value_discarded
|
||||
new_time_entry.connect("end_time_updated", time_entry_tree_item, "_on_end_time_updated")
|
||||
# warning-ignore:return_value_discarded
|
||||
time_entry_tree_item.connect("end_time_updated", self, "_on_end_time_updated")
|
||||
time_entries.append(time_entry_tree_item)
|
||||
|
||||
|
||||
func _on_end_time_updated() -> void:
|
||||
emit_signal("end_time_updated")
|
||||
|
||||
|
||||
func get_elapsed_seconds() -> int:
|
||||
var seconds := time_entry.get_elapsed_seconds() if time_entry != null else 0
|
||||
for child_name in children:
|
||||
var child = children[child_name]
|
||||
seconds += child.get_elapsed_seconds()
|
||||
for entry in time_entries:
|
||||
seconds += entry.get_elapsed_seconds()
|
||||
return seconds
|
||||
|
||||
|
||||
func get_period() -> String:
|
||||
var time_in_secs := get_elapsed_seconds()
|
||||
return TimeEntry.time_to_period(time_in_secs)
|
||||
|
||||
|
||||
func to_dict() -> Dictionary:
|
||||
var json := {}
|
||||
var times := []
|
||||
if time_entries.size() > 0:
|
||||
for entry in time_entries:
|
||||
times.append(entry.to_dict())
|
||||
json["__time"] = times
|
||||
if children.size() > 0:
|
||||
for name in children:
|
||||
json[name] = children[name].to_dict()
|
||||
return json
|
||||
|
||||
|
||||
func _to_string() -> String:
|
||||
var json := to_dict()
|
||||
var json_string := JSON.print(json, "\t")
|
||||
return json_string
|
@ -1,13 +1,9 @@
|
||||
class_name TimeSheet
|
||||
|
||||
signal entry_started
|
||||
signal entry_stopped
|
||||
|
||||
var source_path := ""
|
||||
var entries := []
|
||||
var entries_names := {}
|
||||
var current_entry: TimeEntry
|
||||
|
||||
var tree := TimeEntryTreeItem.new()
|
||||
|
||||
## Loads the data file
|
||||
func load_file() -> bool:
|
||||
@ -19,6 +15,7 @@ func load_file() -> bool:
|
||||
printerr("Failed to open file %s"%[ProjectSettings.globalize_path(source_path)])
|
||||
return false
|
||||
return true
|
||||
|
||||
while not file.eof_reached():
|
||||
var line := file.get_csv_line()
|
||||
if line.size() == 0 or "".join(line).length() == 0:
|
||||
@ -28,22 +25,32 @@ func load_file() -> bool:
|
||||
continue
|
||||
var entry := TimeEntry.new().from_csv_line(line)
|
||||
entries.append(entry)
|
||||
if entry.closed == false:
|
||||
current_entry = entry
|
||||
if not entries_names.has(entry.name):
|
||||
entries_names[entry.name] = 0
|
||||
entries_names[entry.name] += entry.get_elapsed_seconds()
|
||||
# warning-ignore:return_value_discarded
|
||||
entry.connect("closed", self, "save")
|
||||
file.close()
|
||||
|
||||
entries.sort_custom(self, "_sort_entries")
|
||||
|
||||
|
||||
|
||||
for entry_index in entries.size():
|
||||
var entry: TimeEntry = entries[entry_index]
|
||||
var parts: PoolStringArray = entry.name.split("/")
|
||||
var repo: TimeEntryTreeItem = tree.get_child(parts, true)
|
||||
repo.append(entry)
|
||||
|
||||
return true
|
||||
|
||||
|
||||
func _sort_entries(a: TimeEntry, b: TimeEntry) -> bool:
|
||||
return a.name < b.name
|
||||
|
||||
|
||||
## Adds a new time entry to the tree and to the data file
|
||||
func start_entry(entry_name: String) -> void:
|
||||
current_entry = TimeEntry.new().start_recording()
|
||||
var current_entry := TimeEntry.new().start_recording()
|
||||
current_entry.name = entry_name
|
||||
current_entry.closed = false
|
||||
if entry_name in entries_names:
|
||||
current_entry.previous_total = entries_names[entry_name]
|
||||
var file := File.new()
|
||||
var success := file.open(source_path, File.READ_WRITE)
|
||||
if success != OK:
|
||||
@ -55,22 +62,10 @@ func start_entry(entry_name: String) -> void:
|
||||
|
||||
|
||||
func update() -> void:
|
||||
current_entry.update()
|
||||
entries_names[current_entry.name] = current_entry.get_total_elapsed_seconds()
|
||||
|
||||
|
||||
func close_entry() -> void:
|
||||
current_entry.closed = true
|
||||
save()
|
||||
emit_signal("entry_stopped")
|
||||
|
||||
|
||||
func get_period() -> String:
|
||||
return current_entry.get_period()
|
||||
|
||||
|
||||
func get_total_elapsed_seconds() -> int:
|
||||
return current_entry.get_total_elapsed_seconds()
|
||||
for entry in entries:
|
||||
var time_entry := entry as TimeEntry
|
||||
if time_entry.is_closed == false:
|
||||
time_entry.update()
|
||||
|
||||
|
||||
func save() -> void:
|
||||
@ -90,5 +85,3 @@ static func restore(file_path: String) -> TimeSheet:
|
||||
if success:
|
||||
return timesheet
|
||||
return null
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user