1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-18 09:09:47 +00:00

Save backups for all opened projects

current_save_paths and backup_save_paths in OpenSave.gd are arrays now, have paths for every project
This commit is contained in:
OverloadedOrama 2020-06-06 02:16:53 +03:00
parent 2c409ab025
commit 709a401373
8 changed files with 81 additions and 66 deletions

View file

@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). All the dates are in YYYY-MM-DD format.
<br><br>
## [v0.8] - Unreleased
### Added
- Project tabs! You can now have multiple projects open at the same time, and access each one with tabs.
<br><br>
## [v0.7.1] - Unreleased
This update has been brought to you by the contributions of:
Igor Santarek (jegor377), rob-a-bolton, Kinwailo

View file

@ -723,6 +723,8 @@ func _exit_tree() -> void:
config_cache.set_value("window", "size", OS.window_size)
config_cache.save("user://cache.ini")
# Thanks to qarmin from GitHub for pointing this out
var i := 0
for project in projects:
project.undo_redo.free()
OpenSave.remove_backup(i)
i += 1

View file

@ -1,8 +1,8 @@
extends Node
var current_save_path := ""
var current_save_paths := [] # Array of strings
# Stores a filename of a backup file in user:// until user saves manually
var backup_save_path = ""
var backup_save_paths := [] # Array of strings
onready var autosave_timer : Timer
@ -184,11 +184,11 @@ func open_pxo_file(path : String, untitled_backup : bool = false) -> void:
if not untitled_backup:
# Untitled backup should not change window title and save path
current_save_path = path
current_save_paths[Global.current_project_index] = path
Global.window_title = path.get_file() + " - Pixelorama " + Global.current_version
func save_pxo_file(path : String, autosave : bool) -> void:
func save_pxo_file(path : String, autosave : bool, project : Project = Global.current_project) -> void:
var file := File.new()
var err := file.open_compressed(path, File.WRITE, File.COMPRESSION_ZSTD)
if err == OK:
@ -196,7 +196,7 @@ func save_pxo_file(path : String, autosave : bool) -> void:
file.store_line(Global.current_version)
# Store Global layers
for layer in Global.current_project.layers:
for layer in project.layers:
file.store_line(".")
file.store_line(layer.name)
file.store_8(layer.visible)
@ -204,16 +204,16 @@ func save_pxo_file(path : String, autosave : bool) -> void:
file.store_8(layer.new_cels_linked)
var linked_cels := []
for frame in layer.linked_cels:
linked_cels.append(Global.current_project.frames.find(frame))
linked_cels.append(project.frames.find(frame))
file.store_var(linked_cels) # Linked cels as cel numbers
file.store_line("END_GLOBAL_LAYERS")
# Store frames
for frame in Global.current_project.frames:
for frame in project.frames:
file.store_line("--")
file.store_16(Global.current_project.size.x)
file.store_16(Global.current_project.size.y)
file.store_16(project.size.x)
file.store_16(project.size.y)
for cel in frame.cels: # Store canvas layers
file.store_line("-")
file.store_buffer(cel.image.get_data())
@ -246,8 +246,8 @@ func save_pxo_file(path : String, autosave : bool) -> void:
file.store_8(right_brush_size)
# Save custom brushes
for i in range(Global.current_project.brushes.size()):
var brush = Global.current_project.brushes[i]
for i in range(project.brushes.size()):
var brush = project.brushes[i]
file.store_line("/")
file.store_16(brush.get_size().x)
file.store_16(brush.get_size().y)
@ -255,7 +255,7 @@ func save_pxo_file(path : String, autosave : bool) -> void:
file.store_line("END_BRUSHES")
# Store animation tags
for tag in Global.current_project.animation_tags:
for tag in project.animation_tags:
file.store_line(".T/")
file.store_line(tag.name)
file.store_var(tag.color)
@ -265,19 +265,17 @@ func save_pxo_file(path : String, autosave : bool) -> void:
file.close()
if Global.current_project.has_changed and not autosave:
Global.current_project.has_changed = false
if project.has_changed and not autosave:
project.has_changed = false
if autosave:
Global.notification_label("File autosaved")
else:
# First remove backup then set current save path
remove_backup()
current_save_path = path
remove_backup(Global.current_project_index)
current_save_paths[Global.current_project_index] = path
Global.notification_label("File saved")
if backup_save_path == "":
Global.current_project.name = path.get_file()
project.name = path.get_file()
Global.window_title = path.get_file() + " - Pixelorama " + Global.current_version
else:
@ -292,39 +290,40 @@ func update_autosave() -> void:
func _on_Autosave_timeout() -> void:
if backup_save_path == "":
# Create a new backup file if it doesn't exist yet
backup_save_path = "user://backup-" + String(OS.get_unix_time())
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-" + String(OS.get_unix_time()) + "-%s" % i
store_backup_path()
save_pxo_file(backup_save_path, true)
store_backup_path(i)
save_pxo_file(backup_save_paths[i], true, Global.projects[i])
# 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 saved, "untitled" backup is stored -> {backup_save_path, backup_save_path}
func store_backup_path() -> void:
if current_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_path):
Global.config_cache.erase_section_key("backups", backup_save_path)
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_path, backup_save_path)
Global.config_cache.set_value("backups", current_save_paths[i], backup_save_paths[i])
else:
Global.config_cache.set_value("backups", backup_save_path, backup_save_path)
Global.config_cache.set_value("backups", backup_save_paths[i], backup_save_paths[i])
Global.config_cache.save("user://cache.ini")
func remove_backup() -> void:
func remove_backup(i : int) -> void:
# Remove backup file
if backup_save_path != "":
if current_save_path != "":
remove_backup_by_path(current_save_path, backup_save_path)
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_path, backup_save_path)
backup_save_path = ""
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:
@ -333,15 +332,15 @@ func remove_backup_by_path(project_path : String, backup_path : String) -> void:
Global.config_cache.save("user://cache.ini")
func reload_backup_file(project_path : String, backup_path : String) -> void:
# If project path is the same as backup save path -> the backup was untitled
open_pxo_file(backup_path, project_path == backup_path)
backup_save_path = backup_path
func reload_backup_file(project_paths : Array, backup_paths : Array) -> void:
for i in range(project_paths.size()):
# If project path is the same as backup save path -> the backup was untitled
open_pxo_file(backup_paths[i], project_paths[i] == backup_paths[i])
backup_save_paths[i] = backup_paths[i]
if project_path != backup_path:
current_save_path = project_path
Global.window_title = project_path.get_file() + " - Pixelorama(*) " + Global.current_version
Global.current_project.has_changed = true
if project_paths[i] != backup_paths[i]:
current_save_paths[i] = project_paths[i]
Global.window_title = project_paths[i].get_file() + " - Pixelorama(*) " + Global.current_version
Global.current_project.has_changed = true
Global.notification_label("Backup reloaded")

View file

@ -3,7 +3,7 @@ class_name Project extends Reference
var name := "" setget name_changed
var size : Vector2
var size := Vector2(64, 64)
var undo_redo : UndoRedo
var undos := 0 # The number of times we added undo properties
var has_changed := false setget has_changed_changed
@ -27,15 +27,16 @@ var cameras_zoom := [Vector2(0.15, 0.15), Vector2(0.15, 0.15), Vector2(0.15, 0.1
var cameras_offset := [Vector2.ZERO, Vector2.ZERO, Vector2.ZERO] # Array of Vector2
func _init(_frames := [], _name := tr("untitled"), _size := Vector2(64, 64)) -> void:
func _init(_frames := [], _name := tr("untitled")) -> void:
frames = _frames
name = _name
size = _size
x_max = size.x
y_max = size.y
undo_redo = UndoRedo.new()
Global.tabs.add_tab(name)
OpenSave.current_save_paths.append("")
OpenSave.backup_save_paths.append("")
func change_project() -> void:
@ -128,6 +129,8 @@ func change_project() -> void:
Global.zoom_level_label.text = str(round(100 / Global.camera.zoom.x)) + " %"
Global.canvas.update()
Global.transparent_checker._ready()
Global.horizontal_ruler.update()
Global.vertical_ruler.update()
Global.window_title = "%s - Pixelorama %s" % [name, Global.current_version]
if has_changed:
Global.window_title = Global.window_title + "(*)"

View file

@ -201,14 +201,16 @@ func handle_backup() -> void:
if Global.config_cache.has_section("backups"):
var project_paths = Global.config_cache.get_section_keys("backups")
if project_paths.size() > 0:
# Get backup path
var backup_path = Global.config_cache.get_value("backups", project_paths[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()
# For it's only possible to reload the first found backup
$BackupConfirmation.dialog_text = tr($BackupConfirmation.dialog_text) % project_paths[0]
$BackupConfirmation.connect("confirmed", self, "_on_BackupConfirmation_confirmed", [project_paths[0], backup_path])
$BackupConfirmation.get_cancel().connect("pressed", self, "_on_BackupConfirmation_delete", [project_paths[0], backup_path])
$BackupConfirmation.dialog_text = tr($BackupConfirmation.dialog_text) % project_paths
$BackupConfirmation.connect("confirmed", self, "_on_BackupConfirmation_confirmed", [project_paths, backup_paths])
$BackupConfirmation.get_cancel().connect("pressed", self, "_on_BackupConfirmation_delete", [project_paths, backup_paths])
$BackupConfirmation.popup_centered()
Global.can_draw = false
modulate = Color(0.5, 0.5, 0.5)
@ -595,29 +597,29 @@ func _on_QuitAndSaveDialog_custom_action(action : String) -> void:
$SaveSprite.popup_centered()
$QuitDialog.hide()
Global.dialog_open(true)
OpenSave.remove_backup()
func _on_QuitDialog_confirmed() -> void:
# Darken the UI to denote that the application is currently exiting
# (it won't respond to user input in this state).
modulate = Color(0.5, 0.5, 0.5)
OpenSave.remove_backup()
get_tree().quit()
func _on_BackupConfirmation_confirmed(project_path : String, backup_path : String) -> void:
OpenSave.reload_backup_file(project_path, backup_path)
func _on_BackupConfirmation_confirmed(project_paths : Array, backup_paths : Array) -> void:
OpenSave.reload_backup_file(project_paths, backup_paths)
# Global.tabs.delete_tab(0)
OpenSave.autosave_timer.start()
$ExportDialog.file_name = OpenSave.current_save_path.get_file().trim_suffix(".pxo")
$ExportDialog.directory_path = OpenSave.current_save_path.get_base_dir()
$ExportDialog.file_name = OpenSave.current_save_paths[0].get_file().trim_suffix(".pxo")
$ExportDialog.directory_path = OpenSave.current_save_paths[0].get_base_dir()
$ExportDialog.was_exported = false
file_menu.set_item_text(3, tr("Save") + " %s" % OpenSave.current_save_path.get_file())
file_menu.set_item_text(3, tr("Save") + " %s" % OpenSave.current_save_paths[0].get_file())
file_menu.set_item_text(6, tr("Export"))
func _on_BackupConfirmation_delete(project_path : String, backup_path : String) -> void:
OpenSave.remove_backup_by_path(project_path, backup_path)
func _on_BackupConfirmation_delete(project_paths : Array, backup_paths : Array) -> void:
for i in range(project_paths.size()):
OpenSave.remove_backup_by_path(project_paths[i], backup_paths[i])
OpenSave.autosave_timer.start()
# Reopen last project
if Global.open_last_project:

View file

@ -112,6 +112,6 @@ func _on_PreferencesDialog_popup_hide() -> void:
list.clear()
func _on_List_item_selected(index):
func _on_List_item_selected(index) -> void:
for child in right_side.get_children():
child.visible = child.name == ["General", "Languages", "Themes", "Canvas", "Image", "Shortcuts"][index]

View file

@ -185,9 +185,9 @@ margin_right = 506.0
margin_bottom = 24.0
mouse_default_cursor_shape = 2
size_flags_horizontal = 3
min_value = 0.5
min_value = 0.1
max_value = 30.0
step = 0.5
step = 0.25
value = 1.0
align = 2
suffix = "minute(s)"

View file

@ -27,6 +27,9 @@ func _on_Tabs_reposition_active_tab_request(idx_to : int) -> void:
func delete_tab(tab : int) -> void:
remove_tab(tab)
Global.projects[tab].undo_redo.free()
OpenSave.remove_backup(tab)
OpenSave.current_save_paths.remove(tab)
OpenSave.backup_save_paths.remove(tab)
Global.projects.remove(tab)
if tab > 0:
Global.current_project_index -= 1