Separate disk usage display for backup and restore modes

Add a new frame with two canvases for the restore view to show the disk usage  before and after the restore.
Show the new frame only in restore mode.
Show the old frames for disk usage only in backup mode. Update the drawing logic to draw the new canvases.
This commit is contained in:
2025-08-26 23:02:31 +02:00
parent 6e3d2ad496
commit 0534c846b3
7 changed files with 120 additions and 12 deletions

View File

@@ -245,8 +245,43 @@ class MainApplication(tk.Tk):
target_label_frame, text="0.00 GB / 0.00 GB")
self.target_size_label.pack(side=tk.RIGHT)
self.restore_size_frame = ttk.Frame(self.content_frame)
self.restore_size_frame.grid(row=4, column=0, sticky="ew", padx=10, pady=5, rowspan=2)
self.restore_size_frame.grid_columnconfigure(0, weight=1)
self.restore_size_frame.grid_remove()
self.restore_size_frame_before = ttk.LabelFrame(
self.restore_size_frame, text="Before Restoration", padding=10)
self.restore_size_frame_before.grid(row=0, column=0, sticky="ew", padx=10, pady=5)
self.restore_size_frame_before.grid_columnconfigure(0, weight=1)
self.restore_size_canvas_before = tk.Canvas(
self.restore_size_frame_before, height=20, relief="solid", borderwidth=1)
self.restore_size_canvas_before.grid(row=0, column=0, sticky="ew")
restore_label_frame_before = ttk.Frame(self.restore_size_frame_before)
restore_label_frame_before.grid(row=1, column=0, sticky="ew")
self.restore_size_label_before = ttk.Label(
restore_label_frame_before, text="0.00 GB / 0.00 GB")
self.restore_size_label_before.pack(side=tk.RIGHT)
self.restore_size_frame_after = ttk.LabelFrame(
self.restore_size_frame, text="After Restoration", padding=10)
self.restore_size_frame_after.grid(row=1, column=0, sticky="ew", padx=10, pady=5)
self.restore_size_frame_after.grid_columnconfigure(0, weight=1)
self.restore_size_canvas_after = tk.Canvas(
self.restore_size_frame_after, height=20, relief="solid", borderwidth=1)
self.restore_size_canvas_after.grid(row=0, column=0, sticky="ew")
restore_label_frame_after = ttk.Frame(self.restore_size_frame_after)
restore_label_frame_after.grid(row=1, column=0, sticky="ew")
self.restore_size_label_after = ttk.Label(
restore_label_frame_after, text="0.00 GB / 0.00 GB")
self.restore_size_label_after.pack(side=tk.RIGHT)
self._load_state_and_initialize()
self.update_backup_options_from_config() # Add this call
self.update_backup_options_from_config() # Add this call
self.protocol("WM_DELETE_WINDOW", self.on_closing)
def _load_state_and_initialize(self):
@@ -303,8 +338,10 @@ class MainApplication(tk.Tk):
if restore_src_path:
self.drawing.calculate_restore_folder_size()
# Trigger calculation for the left canvas (destination) based on last selection
restore_dest_folder = self.restore_left_canvas_data.get('folder', 'Computer')
self.after(100, self.actions.on_sidebar_button_click, restore_dest_folder)
restore_dest_folder = self.restore_left_canvas_data.get(
'folder', 'Computer')
self.after(100, self.actions.on_sidebar_button_click,
restore_dest_folder)
else:
# Default action if no specific state to restore
self.after(100, self.actions.on_sidebar_button_click, "Computer")
@@ -354,15 +391,16 @@ class MainApplication(tk.Tk):
self.incremental_cb = ttk.Checkbutton(checkbox_frame, text=Msg.STR["incremental"],
variable=self.inkrementell_var, command=lambda: enforce_backup_type_exclusivity(self.inkrementell_var, self.vollbackup_var, self.inkrementell_var.get()))
self.incremental_cb.pack(side=tk.LEFT, padx=5)
self.test_run_cb = ttk.Checkbutton(checkbox_frame, text=Msg.STR["test_run"],
variable=self.testlauf_var)
self.test_run_cb.pack(side=tk.LEFT, padx=5)
self.compressed_cb = ttk.Checkbutton(checkbox_frame, text=Msg.STR["compressed"],
variable=self.compressed_var)
self.compressed_cb.pack(side=tk.LEFT, padx=5)
self.encrypted_cb = ttk.Checkbutton(checkbox_frame, text=Msg.STR["encrypted"],
variable=self.encrypted_var)
self.encrypted_cb.pack(side=tk.LEFT, padx=5)
self.test_run_cb = ttk.Checkbutton(checkbox_frame, text=Msg.STR["test_run"],
variable=self.testlauf_var)
self.test_run_cb.pack(side=tk.LEFT, padx=5)
self.bypass_security_cb = ttk.Checkbutton(checkbox_frame, text=Msg.STR["bypass_security"],
variable=self.bypass_security_var)
self.bypass_security_cb.pack(side=tk.LEFT, padx=5)
@@ -428,8 +466,10 @@ class MainApplication(tk.Tk):
A 'force' setting overrides the user's selection and disables the control.
"""
# Full/Incremental Logic
force_full = self.config_manager.get_setting("force_full_backup", False)
force_incremental = self.config_manager.get_setting("force_incremental_backup", False)
force_full = self.config_manager.get_setting(
"force_full_backup", False)
force_incremental = self.config_manager.get_setting(
"force_incremental_backup", False)
if force_full:
self.vollbackup_var.set(True)
@@ -443,19 +483,19 @@ class MainApplication(tk.Tk):
self.incremental_cb.config(state="disabled")
# Compression Logic
force_compression = self.config_manager.get_setting("force_compression", False)
force_compression = self.config_manager.get_setting(
"force_compression", False)
if force_compression:
self.compressed_var.set(True)
self.compressed_cb.config(state="disabled")
# Encryption Logic
force_encryption = self.config_manager.get_setting("force_encryption", False)
force_encryption = self.config_manager.get_setting(
"force_encryption", False)
if force_encryption:
self.encrypted_var.set(True)
self.encrypted_cb.config(state="disabled")
if __name__ == "__main__":
import argparse

View File

@@ -197,6 +197,11 @@ class Drawing:
self.app.after(0, update_ui)
def update_target_projection(self):
if self.app.mode == "restore":
self.update_restore_projection_before()
self.update_restore_projection_after()
return
if self.app.destination_total_bytes == 0:
return
@@ -259,6 +264,63 @@ class Drawing:
self.app.target_size_label.config(
text=f"{projected_total_used / (1024**3):.2f} GB / {self.app.destination_total_bytes / (1024**3):.2f} GB")
def update_restore_projection_before(self):
if self.app.destination_total_bytes == 0:
return
canvas = self.app.restore_size_canvas_before
canvas.delete("all")
canvas_width = canvas.winfo_width()
if canvas_width <= 1:
self.app.after(50, self.update_restore_projection_before)
return
used_percentage = self.app.destination_used_bytes / \
self.app.destination_total_bytes
used_width = canvas_width * used_percentage
canvas.create_rectangle(
0, 0, used_width, canvas.winfo_height(), fill="#0078d7", outline="")
self.app.restore_size_label_before.config(
text=f"{self.app.destination_used_bytes / (1024**3):.2f} GB / {self.app.destination_total_bytes / (1024**3):.2f} GB")
def update_restore_projection_after(self):
if self.app.destination_total_bytes == 0:
return
canvas = self.app.restore_size_canvas_after
canvas.delete("all")
canvas_width = canvas.winfo_width()
if canvas_width <= 1:
self.app.after(50, self.update_restore_projection_after)
return
projected_total_used = self.app.destination_used_bytes + self.app.source_size_bytes
projected_total_percentage = projected_total_used / \
self.app.destination_total_bytes
if projected_total_percentage >= 0.95:
canvas.create_rectangle(0, 0, canvas_width, canvas.winfo_height(
), fill="#ff0000", outline="") # Red bar
elif projected_total_percentage >= 0.90:
canvas.create_rectangle(0, 0, canvas_width, canvas.winfo_height(
), fill="#ff8c00", outline="") # Orange bar
else:
used_percentage = self.app.destination_used_bytes / \
self.app.destination_total_bytes
used_width = canvas_width * used_percentage
canvas.create_rectangle(
0, 0, used_width, canvas.winfo_height(), fill="#0078d7", outline="")
projected_percentage = self.app.source_size_bytes / \
self.app.destination_total_bytes
projected_width = canvas_width * projected_percentage
canvas.create_rectangle(used_width, 0, used_width + projected_width,
canvas.winfo_height(), fill="#ff8c00", outline="")
self.app.restore_size_label_after.config(
text=f"{projected_total_used / (1024**3):.2f} GB / {self.app.destination_total_bytes / (1024**3):.2f} GB")
def update_nav_buttons(self, active_index):
for i, button in enumerate(self.app.nav_buttons):
if i == active_index:

View File

@@ -64,6 +64,9 @@ class Navigation:
# Update UI elements
if mode == "backup":
self.app.source_size_frame.grid()
self.app.target_size_frame.grid()
self.app.restore_size_frame.grid_remove()
self.app.mode_button_icon = self.app.image_manager.get_icon("forward_extralarge")
self.app.info_label.config(text=Msg.STR["backup_mode_info"])
self.app.full_backup_cb.config(state="normal")
@@ -74,6 +77,9 @@ class Navigation:
# Let the central config function handle the state of these checkboxes
self.app.update_backup_options_from_config()
else: # restore
self.app.source_size_frame.grid_remove()
self.app.target_size_frame.grid_remove()
self.app.restore_size_frame.grid()
self.app.mode_button_icon = self.app.image_manager.get_icon("back_extralarge")
self.app.info_label.config(text=Msg.STR["restore_mode_info"])
self.app.full_backup_cb.config(state='disabled')