diff --git a/qt/app.py b/qt/app.py index 3e066c04b..169b989fc 100644 --- a/qt/app.py +++ b/qt/app.py @@ -1088,6 +1088,8 @@ def updateProfile(self): else: self.places.set_sorting(sorting) + self.status_bar.set_disk_space_info(self.config.snapshotsPath()) + def comboProfileChanged(self, _index): if self.disableProfileChanged: return @@ -1193,6 +1195,8 @@ def _update_backup_status(self, force_wait_lock=False): if self.shutdown.activate_shutdown and get_shutdown_confirmation(): self.shutdown.shutdown() + self.status_bar.set_disk_space_info(self.config.snapshotsPath()) + message = self._set_take_snapshot_message( message=takeSnapshotMessage, force_update=force_update, diff --git a/qt/statusbar.py b/qt/statusbar.py index 3bc70e60b..30fd41a46 100644 --- a/qt/statusbar.py +++ b/qt/statusbar.py @@ -11,6 +11,7 @@ # . """A module offering a status bar widget """ +import os from PyQt6.QtWidgets import (QFrame, QHBoxLayout, QLabel, @@ -26,6 +27,7 @@ import qttools _PROGRESS_BAR_WIDTH_FX = 10 +_UNIT_MULTIPLIER = 1024 class StatusBar(QStatusBar): @@ -44,7 +46,6 @@ def __init__(self, main_window: QMainWindow): layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) container.setLayout(layout) - # Status text self._status = QLabel(container) self._status.setWordWrap(False) @@ -58,12 +59,23 @@ def __init__(self, main_window: QMainWindow): self._progress.setTextVisible(False) self._progress.setVisible(False) + # Disk space info label + self._disk_space = QLabel(container) + self._disk_space.setWordWrap(False) + self._disk_space.setSizePolicy( + QSizePolicy.Policy.Preferred, + QSizePolicy.Policy.Preferred, + ) + self._disk_space.setVisible(False) + # Layout if self._root: layout.addWidget(self._root) layout.addWidget(self._status, stretch=_PROGRESS_BAR_WIDTH_FX-1) + layout.addWidget(self._disk_space) layout.addStretch(0) layout.addWidget(self._progress, stretch=1) + self.addPermanentWidget(container, 1) container.resizeEvent = self._on_resize @@ -125,3 +137,34 @@ def progress_hide(self) -> None: def set_progress_value(self, val: int) -> None: """Set numeric value of progress bar.""" self._progress.setValue(val) + + def set_disk_space_info(self, path: str) -> None: + """Set the backup disk space information.""" + if not path: + self._disk_space.setVisible(False) + return + + try: + statvfs = os.statvfs(path) + + free = statvfs.f_frsize + if bitbase.IS_IN_ROOT_MODE: + free *= statvfs.f_bfree + else: + free *= statvfs.f_bavail + + for unit in ['B', 'KB', 'MB', 'GB', 'TB']: + if free < _UNIT_MULTIPLIER: + break + free /= _UNIT_MULTIPLIER + + formatted = f"{free:.1f} {unit}" + self._disk_space.setText(_('Free space: ') + formatted) + self._disk_space.setVisible(True) + + except OSError: + self._disk_space.setVisible(False) + + def hide_disk_space_info(self) -> None: + """Hide the disk space information.""" + self._disk_space.setVisible(False)