mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-18 17:19:50 +00:00
Greatly simplify backup code, got rid of OpenSave's current_save_paths
and backup_save_paths
The previous backup code was unnecessarily complicated, hard to read/understand and prone to errors. The new system simply stores the save and backup paths in the `Project` class, and stores the backup files inside `user://backups`, instead of having their file paths be in `cache.ini`.
This commit is contained in:
parent
42bce917dc
commit
dd8145d369
|
@ -4,9 +4,6 @@ extends Node
|
|||
signal project_saved
|
||||
signal reference_image_imported
|
||||
|
||||
var current_save_paths: PackedStringArray = []
|
||||
## Stores a filename of a backup file in user:// until user saves manually
|
||||
var backup_save_paths: PackedStringArray = []
|
||||
var preview_dialog_tscn := preload("res://src/UI/Dialogs/ImportPreviewDialog.tscn")
|
||||
var preview_dialogs := [] ## Array of preview dialogs
|
||||
var last_dialog_option := 0
|
||||
|
@ -253,9 +250,11 @@ func open_pxo_file(path: String, is_backup := false, replace_empty := true) -> v
|
|||
Global.tabs.current_tab = Global.tabs.get_tab_count() - 1
|
||||
Global.canvas.camera_zoom()
|
||||
|
||||
if not is_backup:
|
||||
if is_backup:
|
||||
new_project.backup_path = path
|
||||
else:
|
||||
# Loading a backup should not change window title and save path
|
||||
current_save_paths[Global.current_project_index] = path
|
||||
new_project.save_path = path
|
||||
Global.main_window.title = path.get_file() + " - Pixelorama " + Global.current_version
|
||||
Global.save_sprites_dialog.current_path = path
|
||||
# Set last opened project path and save
|
||||
|
@ -366,8 +365,8 @@ func save_pxo_file(
|
|||
zip_packer.write_file(to_save.to_utf8_buffer())
|
||||
zip_packer.close_file()
|
||||
|
||||
if !autosave:
|
||||
current_save_paths[Global.current_project_index] = path
|
||||
if not autosave:
|
||||
project.save_path = path
|
||||
|
||||
var frame_index := 1
|
||||
for frame in project.frames:
|
||||
|
@ -417,7 +416,7 @@ func save_pxo_file(
|
|||
# First remove backup then set current save path
|
||||
if project.has_changed:
|
||||
project.has_changed = false
|
||||
remove_backup(Global.current_project_index)
|
||||
Global.current_project.remove_backup_file()
|
||||
Global.notification_label("File saved")
|
||||
Global.main_window.title = path.get_file() + " - Pixelorama " + Global.current_version
|
||||
|
||||
|
@ -809,83 +808,22 @@ func update_autosave() -> void:
|
|||
|
||||
|
||||
func _on_Autosave_timeout() -> void:
|
||||
for i in range(backup_save_paths.size()):
|
||||
if backup_save_paths[i] == "":
|
||||
# Create a new backup file if it doesn't exist yet
|
||||
backup_save_paths[i] = (
|
||||
"user://backup-" + str(Time.get_unix_time_from_system()) + "-%s" % i
|
||||
for i in Global.projects.size():
|
||||
var project := Global.projects[i]
|
||||
if project.backup_path.is_empty():
|
||||
project.backup_path = (
|
||||
"user://backups/backup-" + str(Time.get_unix_time_from_system()) + "-%s" % i
|
||||
)
|
||||
|
||||
store_backup_path(i)
|
||||
save_pxo_file(backup_save_paths[i], true, false, Global.projects[i])
|
||||
save_pxo_file(project.backup_path, true, false, project)
|
||||
|
||||
|
||||
## Backup paths are stored in two ways:
|
||||
## 1) User already manually saved and defined a save path -> {current_save_path, backup_save_path}
|
||||
## 2) User didn't manually save, "untitled" backup is stored -> {backup_save_path, backup_save_path}
|
||||
func store_backup_path(i: int) -> void:
|
||||
if current_save_paths[i] != "":
|
||||
# Remove "untitled" backup if it existed on this project instance
|
||||
if Global.config_cache.has_section_key("backups", backup_save_paths[i]):
|
||||
Global.config_cache.erase_section_key("backups", backup_save_paths[i])
|
||||
|
||||
Global.config_cache.set_value("backups", current_save_paths[i], backup_save_paths[i])
|
||||
else:
|
||||
Global.config_cache.set_value("backups", backup_save_paths[i], backup_save_paths[i])
|
||||
|
||||
Global.config_cache.save("user://cache.ini")
|
||||
|
||||
|
||||
func remove_backup(i: int) -> void:
|
||||
# Remove backup file
|
||||
if backup_save_paths[i] != "":
|
||||
if current_save_paths[i] != "":
|
||||
remove_backup_by_path(current_save_paths[i], backup_save_paths[i])
|
||||
else:
|
||||
# If manual save was not yet done - remove "untitled" backup
|
||||
remove_backup_by_path(backup_save_paths[i], backup_save_paths[i])
|
||||
backup_save_paths[i] = ""
|
||||
|
||||
|
||||
func remove_backup_by_path(project_path: String, backup_path: String) -> void:
|
||||
DirAccess.open("user://").remove(backup_path)
|
||||
if Global.config_cache.has_section_key("backups", project_path):
|
||||
Global.config_cache.erase_section_key("backups", project_path)
|
||||
elif Global.config_cache.has_section_key("backups", backup_path):
|
||||
Global.config_cache.erase_section_key("backups", backup_path)
|
||||
Global.config_cache.save("user://cache.ini")
|
||||
|
||||
|
||||
func reload_backup_file(project_paths: Array, backup_paths: Array) -> void:
|
||||
assert(project_paths.size() == backup_paths.size())
|
||||
# Clear non-existent backups
|
||||
var existing_backups_count := 0
|
||||
for i in range(backup_paths.size()):
|
||||
var dir := DirAccess.open("user://")
|
||||
if dir.file_exists(backup_paths[i]):
|
||||
project_paths[existing_backups_count] = project_paths[i]
|
||||
backup_paths[existing_backups_count] = backup_paths[i]
|
||||
existing_backups_count += 1
|
||||
else:
|
||||
if Global.config_cache.has_section_key("backups", backup_paths[i]):
|
||||
Global.config_cache.erase_section_key("backups", backup_paths[i])
|
||||
Global.config_cache.save("user://cache.ini")
|
||||
project_paths.resize(existing_backups_count)
|
||||
backup_paths.resize(existing_backups_count)
|
||||
|
||||
# Load the backup files
|
||||
for i in range(project_paths.size()):
|
||||
open_pxo_file(backup_paths[i], true, i == 0)
|
||||
backup_save_paths[i] = backup_paths[i]
|
||||
|
||||
# If project path is the same as backup save path -> the backup was untitled
|
||||
if project_paths[i] != backup_paths[i]: # If the user has saved
|
||||
current_save_paths[i] = project_paths[i]
|
||||
Global.main_window.title = (
|
||||
project_paths[i].get_file() + " - Pixelorama(*) " + Global.current_version
|
||||
)
|
||||
Global.current_project.has_changed = true
|
||||
|
||||
## Load the backup files
|
||||
func reload_backup_file() -> void:
|
||||
var dir := DirAccess.open("user://backups")
|
||||
var i := 0
|
||||
for file in dir.get_files():
|
||||
open_pxo_file("user://backups".path_join(file), true, i == 0)
|
||||
i += 1
|
||||
Global.notification_label("Backup reloaded")
|
||||
|
||||
|
||||
|
|
|
@ -73,11 +73,13 @@ var cameras_zoom: PackedVector2Array = [
|
|||
var cameras_offset: PackedVector2Array = [Vector2.ZERO, Vector2.ZERO, Vector2.ZERO]
|
||||
|
||||
# Export directory path and export file name
|
||||
var save_path := ""
|
||||
var export_directory_path := ""
|
||||
var file_name := "untitled"
|
||||
var file_format := Export.FileFormat.PNG
|
||||
var was_exported := false
|
||||
var export_overwrite := false
|
||||
var backup_path := ""
|
||||
|
||||
var animation_tag_node := preload("res://src/UI/Timeline/AnimationTagUI.tscn")
|
||||
|
||||
|
@ -88,20 +90,15 @@ func _init(_frames: Array[Frame] = [], _name := tr("untitled"), _size := Vector2
|
|||
size = _size
|
||||
tiles = Tiles.new(size)
|
||||
selection_map.copy_from(Image.create(size.x, size.y, false, Image.FORMAT_LA8))
|
||||
|
||||
Global.tabs.add_tab(name)
|
||||
OpenSave.current_save_paths.append("")
|
||||
OpenSave.backup_save_paths.append("")
|
||||
|
||||
x_symmetry_point = size.x - 1
|
||||
y_symmetry_point = size.y - 1
|
||||
|
||||
x_symmetry_axis.type = x_symmetry_axis.Types.HORIZONTAL
|
||||
x_symmetry_axis.project = self
|
||||
x_symmetry_axis.add_point(Vector2(-19999, y_symmetry_point / 2 + 0.5))
|
||||
x_symmetry_axis.add_point(Vector2(19999, y_symmetry_point / 2 + 0.5))
|
||||
Global.canvas.add_child(x_symmetry_axis)
|
||||
|
||||
y_symmetry_axis.type = y_symmetry_axis.Types.VERTICAL
|
||||
y_symmetry_axis.project = self
|
||||
y_symmetry_axis.add_point(Vector2(x_symmetry_point / 2 + 0.5, -19999))
|
||||
|
@ -118,6 +115,7 @@ func _init(_frames: Array[Frame] = [], _name := tr("untitled"), _size := Vector2
|
|||
|
||||
|
||||
func remove() -> void:
|
||||
remove_backup_file()
|
||||
undo_redo.free()
|
||||
for ri in reference_images:
|
||||
ri.queue_free()
|
||||
|
@ -138,6 +136,12 @@ func remove() -> void:
|
|||
Global.projects.erase(self)
|
||||
|
||||
|
||||
func remove_backup_file() -> void:
|
||||
if not backup_path.is_empty():
|
||||
if FileAccess.file_exists(backup_path):
|
||||
DirAccess.remove_absolute(backup_path)
|
||||
|
||||
|
||||
func commit_undo() -> void:
|
||||
if not can_undo:
|
||||
return
|
||||
|
|
52
src/Main.gd
52
src/Main.gd
|
@ -24,6 +24,8 @@ var splash_dialog: AcceptDialog:
|
|||
|
||||
|
||||
func _init() -> void:
|
||||
if not DirAccess.dir_exists_absolute("user://backups"):
|
||||
DirAccess.make_dir_recursive_absolute("user://backups")
|
||||
Global.shrink = _get_auto_display_scale()
|
||||
_handle_layout_files()
|
||||
|
||||
|
@ -171,27 +173,14 @@ func _show_splash_screen() -> void:
|
|||
func _handle_backup() -> void:
|
||||
# If backup file exists, Pixelorama was not closed properly (probably crashed) - reopen backup
|
||||
backup_confirmation.add_button("Discard All", false, "discard")
|
||||
if Global.config_cache.has_section("backups"):
|
||||
var project_paths = Global.config_cache.get_section_keys("backups")
|
||||
if project_paths.size() > 0:
|
||||
# Get backup paths
|
||||
var backup_paths := []
|
||||
for p_path in project_paths:
|
||||
backup_paths.append(Global.config_cache.get_value("backups", p_path))
|
||||
# Temporatily stop autosave until user confirms backup
|
||||
OpenSave.autosave_timer.stop()
|
||||
backup_confirmation.confirmed.connect(
|
||||
_on_BackupConfirmation_confirmed.bind(project_paths, backup_paths)
|
||||
)
|
||||
backup_confirmation.custom_action.connect(
|
||||
_on_BackupConfirmation_custom_action.bind(project_paths, backup_paths)
|
||||
)
|
||||
await get_tree().process_frame
|
||||
backup_confirmation.popup_centered()
|
||||
modulate = Color(0.5, 0.5, 0.5)
|
||||
else:
|
||||
if Global.open_last_project:
|
||||
load_last_project()
|
||||
var backup_dir := DirAccess.open("user://backups")
|
||||
if backup_dir.get_files().size() > 0:
|
||||
# Temporatily stop autosave until user confirms backup
|
||||
OpenSave.autosave_timer.stop()
|
||||
backup_confirmation.confirmed.connect(_on_BackupConfirmation_confirmed)
|
||||
backup_confirmation.custom_action.connect(_on_BackupConfirmation_custom_action)
|
||||
backup_confirmation.popup_centered()
|
||||
modulate = Color(0.5, 0.5, 0.5)
|
||||
else:
|
||||
if Global.open_last_project:
|
||||
load_last_project()
|
||||
|
@ -367,18 +356,15 @@ func _quit() -> void:
|
|||
get_tree().quit()
|
||||
|
||||
|
||||
func _on_BackupConfirmation_confirmed(project_paths: Array, backup_paths: Array) -> void:
|
||||
OpenSave.reload_backup_file(project_paths, backup_paths)
|
||||
func _on_BackupConfirmation_confirmed() -> void:
|
||||
OpenSave.reload_backup_file()
|
||||
|
||||
|
||||
func _on_BackupConfirmation_custom_action(
|
||||
action: String, project_paths: Array, backup_paths: Array
|
||||
) -> void:
|
||||
func _on_BackupConfirmation_custom_action(action: String) -> void:
|
||||
backup_confirmation.hide()
|
||||
if action != "discard":
|
||||
return
|
||||
for i in range(project_paths.size()):
|
||||
OpenSave.remove_backup_by_path(project_paths[i], backup_paths[i])
|
||||
_clear_backup_files()
|
||||
# Reopen last project
|
||||
if Global.open_last_project:
|
||||
load_last_project()
|
||||
|
@ -392,6 +378,11 @@ func _on_backup_confirmation_visibility_changed() -> void:
|
|||
Global.dialog_open(false)
|
||||
|
||||
|
||||
func _clear_backup_files() -> void:
|
||||
for file in DirAccess.get_files_at("user://backups"):
|
||||
DirAccess.remove_absolute("user://backups".path_join(file))
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
Global.config_cache.set_value("window", "layout", Global.layouts.find(main_ui.layout))
|
||||
Global.config_cache.set_value("window", "screen", get_window().current_screen)
|
||||
|
@ -415,8 +406,7 @@ func _exit_tree() -> void:
|
|||
Global.config_cache.set_value("view_menu", "show_mouse_guides", Global.show_mouse_guides)
|
||||
Global.config_cache.save("user://cache.ini")
|
||||
|
||||
var i := 0
|
||||
for project in Global.projects:
|
||||
project.remove()
|
||||
OpenSave.remove_backup(i)
|
||||
i += 1
|
||||
# For some reason, the above is not enough to remove all backup files
|
||||
_clear_backup_files()
|
||||
|
|
|
@ -77,7 +77,6 @@ popup_window = true
|
|||
dialog_text = "This is an error message!"
|
||||
|
||||
[node name="BackupConfirmation" type="ConfirmationDialog" parent="Dialogs"]
|
||||
exclusive = false
|
||||
popup_window = true
|
||||
dialog_text = "Autosaved project(s) from a crashed session were found.
|
||||
Do you want to recover the data?"
|
||||
|
|
|
@ -47,21 +47,10 @@ func _on_active_tab_rearranged(idx_to: int) -> void:
|
|||
Global.projects.erase(temp)
|
||||
Global.projects.insert(idx_to, temp)
|
||||
|
||||
# Change save paths
|
||||
var temp_save_path := OpenSave.current_save_paths[Global.current_project_index]
|
||||
OpenSave.current_save_paths.remove_at(Global.current_project_index)
|
||||
OpenSave.current_save_paths.insert(idx_to, temp_save_path)
|
||||
var temp_backup_path := OpenSave.backup_save_paths[Global.current_project_index]
|
||||
OpenSave.backup_save_paths.remove_at(Global.current_project_index)
|
||||
OpenSave.backup_save_paths.insert(idx_to, temp_backup_path)
|
||||
|
||||
|
||||
func delete_tab(tab: int) -> void:
|
||||
remove_tab(tab)
|
||||
Global.projects[tab].remove()
|
||||
OpenSave.remove_backup(tab)
|
||||
OpenSave.current_save_paths.remove_at(tab)
|
||||
OpenSave.backup_save_paths.remove_at(tab)
|
||||
if Global.current_project_index == tab:
|
||||
if tab > 0:
|
||||
Global.current_project_index -= 1
|
||||
|
|
|
@ -461,7 +461,7 @@ func _on_open_last_project_file_menu_option_pressed() -> void:
|
|||
|
||||
|
||||
func _save_project_file() -> void:
|
||||
var path: String = OpenSave.current_save_paths[Global.current_project_index]
|
||||
var path: String = Global.current_project.save_path
|
||||
if path == "":
|
||||
Global.control.show_save_dialog()
|
||||
else:
|
||||
|
|
Loading…
Reference in a new issue