aboutsummaryrefslogtreecommitdiff
path: root/logic
diff options
context:
space:
mode:
Diffstat (limited to 'logic')
-rw-r--r--logic/database.gd145
-rw-r--r--logic/database_entry.gd6
-rw-r--r--logic/popup.gd12
-rw-r--r--logic/stage.gd85
4 files changed, 167 insertions, 81 deletions
diff --git a/logic/database.gd b/logic/database.gd
index 262a18a..8acf1b6 100644
--- a/logic/database.gd
+++ b/logic/database.gd
@@ -8,7 +8,7 @@ var db: Array
var selected_idx: int
var staged_idx: int
-onready var stage := get_node("/root/main/stage") as Stage
+onready var stage := get_node("/root/main/stage") # as Stage @DAM Commented to avoid cyclic dependency.
onready var delete_button := get_node("actions/delete") as Button
onready var edit_button := get_node("actions/edit") as Button
onready var add_button := get_node("actions/add") as Button
@@ -18,7 +18,6 @@ onready var dialog := get_node("/root/main/dialog") as Dialog
func _init():
selected_idx = -1
staged_idx = -1
- load_database()
func _ready():
@@ -32,10 +31,7 @@ func _ready():
stage.connect("save", self, "save_stage")
stage.connect("discard", self, "discard_stage")
- for it in db:
- self.add_item(get_entry_view(it))
-
- clear_selection()
+ load_database()
func get_entry_view(database_entry: Dictionary) -> String:
@@ -62,7 +58,7 @@ func delete_action():
if selected_idx < 0:
return
- dialog.setup("The entry with process ID '%s' will be deleted from the database." % db[selected_idx].process_id, "Delete", "No")
+ dialog.setup("The entry #%d with process ID '%s' will be deleted from the database." % [selected_idx+1, db[selected_idx].process_id], "Delete", "No")
dialog.connect("accepted", self, "delete_action_confirmed")
popup.open_popup("Delete entry?", dialog)
@@ -95,8 +91,8 @@ func add_action():
func save_stage(entry: Dictionary):
if DatabaseEntry.is_valid_entry(entry) == false:
- printerr("INVALID ENTRY RECEIVED")
- return # @DAM Deal with this.
+ printerr("Invalid entry detected.")
+ return
var next_selected_idx: int
if staged_idx >= 0:
@@ -125,7 +121,89 @@ func discard_stage():
grab_focus()
+func save_database(file_path: String = DATABASE_FILE_PATH):
+ match file_path.get_extension():
+ "json":
+ export_json(file_path, db)
+
+ "csv":
+ export_csv(file_path, db)
+
+ _:
+ printerr("Invalid database file extension: '%s'." % file_path.get_file())
+ return
+
+
+static func export_json(file_path: String, data: Array):
+ var database_file := {
+ "version": DATABASE_FILE_VERSION,
+ "database": data,
+ }
+ var indentation_char := "" if file_path == DATABASE_FILE_PATH else "\t"
+ var file_content := JSON.print(database_file, indentation_char)
+
+ var file := File.new()
+ file.open(file_path, File.WRITE)
+ file.store_string(file_content)
+ file.close()
+
+
+static func export_csv(file_path: String, data: Array):
+ var file := File.new()
+ file.open(file_path, File.WRITE)
+ var header := PoolStringArray(DatabaseEntry.ENTRY_PROTOTYPE.keys())
+ file.store_csv_line(header)
+ for it in data:
+ file.store_csv_line(it.values())
+ file.close()
+
+
func load_database(file_path: String = DATABASE_FILE_PATH):
+ match file_path.get_extension():
+ "json":
+ clear_database()
+ db = import_json(file_path)
+ if file_path != DATABASE_FILE_PATH:
+ sanitize_database(db)
+
+ "csv":
+ clear_database()
+ db = import_csv(file_path)
+
+ _:
+ printerr("Invalid database file extension: '%s'." % file_path.get_file())
+ return
+
+ for it in db:
+ # The JSON specification does not define integer or float types, but only a number type.
+ # Therefore, converting a Variant to JSON text will convert all numerical values to float types.
+ # Thus, we cast all integer values once we load them.
+ it["date_year"] = int(it["date_year"])
+ it["date_month"] = int(it["date_month"])
+ it["date_day"] = int(it["date_day"])
+
+ self.add_item(get_entry_view(it))
+
+
+static func sanitize_database(database: Array):
+ var blueprint := DatabaseEntry.ENTRY_PROTOTYPE
+
+ for entry in database:
+ # Delete extra keys.
+ var keys_to_delete: Array
+ for key in entry:
+ if blueprint.has(key) == false:
+ keys_to_delete.append(key)
+ for key in keys_to_delete:
+ entry.erase(key)
+
+ # Fix wrong value types.
+ for key in blueprint:
+ if entry.has(key) == false || typeof(entry[key]) != typeof(blueprint[key]):
+ entry[key] = blueprint[key]
+
+
+static func import_json(file_path: String) -> Array:
var file := File.new()
file.open(file_path, File.READ_WRITE)
var file_content = file.get_as_text()
@@ -133,43 +211,21 @@ func load_database(file_path: String = DATABASE_FILE_PATH):
var parse_result = JSON.parse(file_content)
if parse_result.error != OK || typeof(parse_result.result) != TYPE_DICTIONARY:
- push_error("Failed to parse database file: '%s'.")
- return
+ printerr("Failed to parse database file: '%s'.")
+ return []
if parse_result.result["version"] != DATABASE_FILE_VERSION:
- push_error("Invalid database file version '%s', expected '%s'." % DATABASE_FILE_VERSION)
- return
+ printerr("Invalid database file version '%s', expected '%s'." % DATABASE_FILE_VERSION)
+ return []
if typeof(parse_result.result["database"]) != TYPE_ARRAY:
- push_error("Failed to load database file contents.")
- return
-
- db = parse_result.result["database"]
-
- # The JSON specification does not define integer or float types, but only a number type.
- # Therefore, converting a Variant to JSON text will convert all numerical values to float types.
- # Thus, we cast all integer values once we load them.
- for it in db:
- it.date_year = int(it.date_year)
- it.date_month = int(it.date_month)
- it.date_day = int(it.date_day)
-
-
-func save_database(file_path: String = DATABASE_FILE_PATH):
- var database_file := {
- "version": DATABASE_FILE_VERSION,
- "database": db,
- }
- var indentation_char := "" if file_path == DATABASE_FILE_PATH else "\t"
- var file_content := JSON.print(database_file, indentation_char)
+ printerr("Failed to load database file contents.")
+ return []
- var file := File.new()
- file.open(file_path, File.WRITE)
- file.store_string(file_content)
- file.close()
+ return parse_result.result["database"]
-static func import_database(file_path: String) -> Array:
+static func import_csv(file_path: String) -> Array:
var result: Array
var file := File.new()
file.open(file_path, File.READ_WRITE)
@@ -196,17 +252,6 @@ static func import_database(file_path: String) -> Array:
return result
-static func export_database(file_path: String, database: Array = db):
- var file := File.new()
- file.open(file_path, File.WRITE)
- var header := PoolStringArray(DatabaseEntry.ENTRY_PROTOTYPE.keys())
- file.store_csv_line(header)
- for it in database:
- # @DAM This approach depends on the order the dictionary fields are created.
- file.store_csv_line(it.values())
- file.close()
-
-
func clear_database():
clear_selection()
self.clear()
diff --git a/logic/database_entry.gd b/logic/database_entry.gd
index 496b752..8b0c51f 100644
--- a/logic/database_entry.gd
+++ b/logic/database_entry.gd
@@ -6,9 +6,9 @@ const DATE_FORMAT: String = "%04d-%02d-%02d"
const ENTRY_PROTOTYPE: Dictionary = {
"process_id": "",
"surgery_id": "",
- "date_year": 0,
- "date_month": 0,
- "date_day": 0,
+ "date_year": 1,
+ "date_month": 1,
+ "date_day": 1,
"place": "",
"anesthesia": "",
"first_assistant": "",
diff --git a/logic/popup.gd b/logic/popup.gd
index d7c98f9..95fc2c3 100644
--- a/logic/popup.gd
+++ b/logic/popup.gd
@@ -5,12 +5,12 @@ signal dismissed # ()
export var clear_signals_on_hide := true
-var control : Control
-var control_parent : Node
+var control : Control
+var control_parent : Node
-onready var title := get_node("title") as Label
-onready var background := get_node("background") as Panel
-onready var dismiss := get_node("dismiss") as Button
+onready var title := get_node("title") as Label
+onready var background := get_node("background") as Panel
+onready var dismiss_button := get_node("dismiss") as Button
func _init():
@@ -21,7 +21,7 @@ func _init():
func _ready():
- dismiss.connect("pressed", self, "dismiss")
+ dismiss_button.connect("pressed", self, "dismiss")
func _clear_signals():
diff --git a/logic/stage.gd b/logic/stage.gd
index e2248fa..764ee52 100644
--- a/logic/stage.gd
+++ b/logic/stage.gd
@@ -105,7 +105,7 @@ func show_options(field: String):
func save_action():
self.visible = false
var staged_entry := get_stage()
- gather_option_sets(staged_entry)
+ gather_option_sets(staged_entry, option_sets)
save_option_sets()
emit_signal("save", staged_entry)
@@ -164,7 +164,7 @@ func get_stage() -> Dictionary:
return entry
-func sanitize_option_sets(entry: Dictionary, blueprint: Dictionary = OPTION_SETS_TREE_STRUCTURE):
+static func sanitize_option_sets(entry: Dictionary, blueprint: Dictionary = OPTION_SETS_TREE_STRUCTURE):
# Delete extra keys.
var keys_to_delete: Array
for key in entry:
@@ -185,7 +185,7 @@ func sanitize_option_sets(entry: Dictionary, blueprint: Dictionary = OPTION_SETS
sanitize_option_sets(entry[key][sub_key], blueprint[key])
-func gather_option_sets(entry: Dictionary, target: Dictionary = option_sets, blueprint: Dictionary = OPTION_SETS_TREE_STRUCTURE):
+static func gather_option_sets(entry: Dictionary, target: Dictionary, blueprint: Dictionary = OPTION_SETS_TREE_STRUCTURE):
for key in blueprint:
if target.get(key) == null:
target[key] = {}
@@ -201,7 +201,55 @@ func gather_option_sets(entry: Dictionary, target: Dictionary = option_sets, blu
gather_option_sets(entry, target[key][value], blueprint[key])
+func save_option_sets(file_path: String = OPTION_SETS_FILE_PATH):
+ match file_path.get_extension():
+ "json":
+ export_json(file_path, option_sets)
+
+# "csv":
+# export_csv(file_path, option_sets)
+
+ _:
+ printerr("Invalid option sets file extension: '%s'." % file_path.get_file())
+ return
+
+
+static func export_json(file_path: String, data: Dictionary):
+ var option_sets_file := {
+ "version": OPTION_SETS_FILE_VERSION,
+ "option_sets": data,
+ }
+ var indentation_char := "" if file_path == OPTION_SETS_FILE_PATH else "\t"
+ var file_content := JSON.print(option_sets_file, indentation_char)
+
+ var file := File.new()
+ file.open(file_path, File.WRITE)
+ file.store_string(file_content)
+ file.close()
+
+
+#static func export_csv(file_path: String, data: Dictionary):
+# pass
+
+
func load_option_sets(file_path: String = OPTION_SETS_FILE_PATH):
+ match file_path.get_extension():
+ "json":
+ clear_option_sets()
+ option_sets = import_json(file_path)
+ if file_path != OPTION_SETS_FILE_PATH:
+ sanitize_option_sets(option_sets)
+
+ "csv":
+ clear_option_sets()
+ option_sets = import_csv(file_path)
+
+ _:
+ printerr("Invalid option sets file extension: '%s'." % file_path.get_file())
+ return
+
+
+static func import_json(file_path: String) -> Dictionary:
var file := File.new()
file.open(file_path, File.READ_WRITE)
var file_content = file.get_as_text()
@@ -209,32 +257,25 @@ func load_option_sets(file_path: String = OPTION_SETS_FILE_PATH):
var parse_result = JSON.parse(file_content)
if parse_result.error != OK || typeof(parse_result.result) != TYPE_DICTIONARY:
- push_error("Failed to parse option sets file: '%s'.")
- return
+ printerr("Failed to parse option sets file: '%s'.")
+ return {}
if parse_result.result["version"] != OPTION_SETS_FILE_VERSION:
- push_error("Invalid option sets file version '%s', expected '%s'." % OPTION_SETS_FILE_VERSION)
- return
+ printerr("Invalid option sets file version '%s', expected '%s'." % OPTION_SETS_FILE_VERSION)
+ return {}
if typeof(parse_result.result["option_sets"]) != TYPE_DICTIONARY:
- push_error("Failed to load option sets file contents.")
- return
+ printerr("Failed to load option sets file contents.")
+ return {}
- option_sets = parse_result.result["option_sets"]
+ return parse_result.result["option_sets"]
-func save_option_sets(file_path: String = OPTION_SETS_FILE_PATH):
- var option_sets_file := {
- "version": OPTION_SETS_FILE_VERSION,
- "option_sets": option_sets,
- }
- var indentation_char := "" if file_path == OPTION_SETS_FILE_PATH else "\t"
- var file_content := JSON.print(option_sets_file, indentation_char)
-
- var file := File.new()
- file.open(file_path, File.WRITE)
- file.store_string(file_content)
- file.close()
+static func import_csv(file_path: String) -> Dictionary:
+ var result := {}
+ for it in Database.import_csv(file_path):
+ gather_option_sets(it, result)
+ return result
func clear_option_sets():