extends ItemList class_name Database const DATABASE_FILE_PATH: String = "user://database.csv" const DATE_SEPARATOR: String = "-" const DATE_FORMAT: String = "%04d-%02d-%02d" const ENTRY_PROTOTYPE: Dictionary = { "process_id": "", "surgery_id": "", "place": "", "date": "", "date_year": 0, "date_month": 0, "date_day": 0, "anesthetic": "", "first_assistant": "", "type": "", "sub_type": "", "sub_sub_type": "", "pathology": "", "intervention": "", "is_urgency": false, "notes": "", } var db: Array var staged_idx: int onready var delete_button: Button = get_node("actions/delete") onready var edit_button: Button = get_node("actions/edit") onready var add_button: Button = get_node("actions/add") onready var stage: Stage = get_node("/root/main/stage") func _init(): staged_idx = -1 load_database() store_database() # @DAM Only for testing. # @DAM WIP #func _notification(what: int): # if what == MainLoop.NOTIFICATION_WM_GO_BACK_REQUEST: # clear_selection() func _ready(): self.connect("nothing_selected", self, "clear_selection") delete_button.connect("pressed", self, "delete_action") edit_button.connect("pressed", self, "edit_action") add_button.connect("pressed", self, "add_action") stage.connect("save", self, "save") stage.connect("discard", self, "discard") for it in db: self.add_item(get_entry_view(it)) func get_entry_view(database_entry: Dictionary) -> String: return "%6s | %6s | %s" % [database_entry.process_id, database_entry.surgery_id, get_entry_date(database_entry)] func clear_selection(): unselect_all() func delete_action(): var selected_entries_idx := self.get_selected_items() if selected_entries_idx.size() == 0: return assert(selected_entries_idx.size() == 1, "Multiple selected items not supported.") var selected_idx = selected_entries_idx[0] db.remove(selected_idx) self.remove_item(selected_idx) store_database() func edit_action(): var selected_entries_idx := self.get_selected_items() if selected_entries_idx.size() == 0: return assert(selected_entries_idx.size() == 1, "Multiple selected items not supported.") staged_idx = selected_entries_idx[0] self.visible = false stage.visible = true stage.set_stage(db[staged_idx]) func add_action(): self.visible = false stage.visible = true var staged := instance_entry() stage.set_stage(staged) func save(database_entry: Dictionary): database_entry = instance_entry(database_entry) # @DAM Maybe we could not be creating endless dictionaries? if staged_idx >= 0: db[staged_idx] = database_entry set_item_text(staged_idx, get_entry_view(database_entry)) else: db.append(database_entry) add_item(get_entry_view(database_entry)) store_database() staged_idx = -1 self.visible = true func discard(): staged_idx = -1 self.visible = true func load_database(file_path: String = DATABASE_FILE_PATH): var file := File.new() file.open(file_path, File.READ_WRITE) var headers: PoolStringArray var is_first_line := true # while database_file.eof_reached() == false: while file.get_position() < file.get_len(): var csv_entry := file.get_csv_line() if is_first_line: is_first_line = false headers = csv_entry continue var entry = ENTRY_PROTOTYPE.duplicate(true) for idx in headers.size(): var field_name := headers[idx] var field_value := csv_entry[idx] match field_name: "date_year", "date_month", "date_day": entry[field_name] = int(field_value) "is_urgency": entry[field_name] = true if field_value.strip_edges().to_lower() == "true" else false _: entry[field_name] = field_value db.append(entry) return db = [ instance_entry({ "process_id": "000001", "surgery_id": "100000", "place": "central", "date": "2020-01-31", }), instance_entry({ "process_id": "000002", "surgery_id": "200000", "place": "central", "date": "2020-02-31", }), instance_entry({ "process_id": "000003", "surgery_id": "300000", "place": "central", "date": "2020-03-31", }), instance_entry({ "process_id": "000004", "surgery_id": "400000", "place": "central", "date": "2020-04-31", }), instance_entry({ "process_id": "000012", "surgery_id": "210000", "place": "central", "date": "2020-12-31", }), ] func store_database(file_path: String = DATABASE_FILE_PATH): var file := File.new() file.open(file_path, File.WRITE) var header := PoolStringArray(ENTRY_PROTOTYPE.keys()) file.store_csv_line(header) var entry := PoolStringArray() for it in db: file.store_csv_line(it.values()) file.close() static func instance_entry(params: Dictionary = {}) -> Dictionary: var new_entry := ENTRY_PROTOTYPE.duplicate(true) new_entry.process_id = params.get("process_id", "") new_entry.surgery_id = params.get("surgery_id", "") new_entry.place = params.get("place", "") var today = OS.get_date() new_entry.date_year = params.get("date_year", today.year) new_entry.date_month = params.get("date_month", today.month) new_entry.date_day = params.get("date_day", today.day) new_entry.date = params.get("date", get_entry_date(new_entry)) new_entry.anesthetic = params.get("anesthetic", "") new_entry.first_assistant = params.get("first_assistant", "") new_entry.type = params.get("type", "") new_entry.sub_type = params.get("sub_type", "") new_entry.sub_sub_type = params.get("sub_sub_type", "") new_entry.pathology = params.get("pathology", "") new_entry.intervention = params.get("intervention", "") new_entry.is_urgency = params.get("is_urgency", false) new_entry.notes = params.get("notes", "") return new_entry static func get_entry_date(entry: Dictionary) -> String: return DATE_FORMAT % [entry.date_year, entry.date_month, entry.date_day] static func set_entry_date(entry: Dictionary, date: String): date = date.strip_edges().replace(" ", DATE_SEPARATOR).replace("/", DATE_SEPARATOR).replace("\\", DATE_SEPARATOR) var year_month_idx := date.find(DATE_SEPARATOR) var month_day_idx := date.find(DATE_SEPARATOR, year_month_idx + 1) entry.date = date entry.date_year = int(date.substr(0, year_month_idx)) entry.date_month = int(date.substr(year_month_idx + 1, month_day_idx - year_month_idx - 1)) entry.date_day = int(date.substr(month_day_idx + 1))