From 3b2d43bd40987c891cb0ff5d733228203a1eeed8 Mon Sep 17 00:00:00 2001 From: Krishna Pinnaka Date: Sun, 11 May 2025 20:54:23 -0700 Subject: [PATCH] Check and show the confirmation dialogue for available disk size before writing file --- .../gui/dpx/WriteFilesModalController.java | 13 ++ .../gui/mxf/WriteFilesModalControllerMXF.java | 24 +++ .../embarc/system/DiskSpaceChecker.java | 168 ++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 src/main/com/portalmedia/embarc/system/DiskSpaceChecker.java diff --git a/src/main/com/portalmedia/embarc/gui/dpx/WriteFilesModalController.java b/src/main/com/portalmedia/embarc/gui/dpx/WriteFilesModalController.java index efb7bfe..d1c5b23 100644 --- a/src/main/com/portalmedia/embarc/gui/dpx/WriteFilesModalController.java +++ b/src/main/com/portalmedia/embarc/gui/dpx/WriteFilesModalController.java @@ -3,10 +3,14 @@ import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.List; import java.util.Optional; import com.portalmedia.embarc.gui.Main; import com.portalmedia.embarc.gui.helper.CleanInputPathHelper; +import com.portalmedia.embarc.gui.helper.DPXFileListHelper; +import com.portalmedia.embarc.gui.model.DPXFileInformationViewModel; +import com.portalmedia.embarc.system.DiskSpaceChecker; import com.portalmedia.embarc.system.UserPreferencesService; import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon; @@ -185,6 +189,15 @@ public void changed(ObservableValue observable, Boolean oldVa final String tmpWriteFilesPath = saveAsCb.isSelected() ? writeFilesPath.getText() : ""; final String tmpReportPath = reportCb.isSelected() ? reportPath.getText() : ""; + // Check for available disk space when saving to a separate directory + if (saveAsCb.isSelected() && !tmpWriteFilesPath.isEmpty()) { + List fileList = DPXFileListHelper.getAllFilesToWrite(writeEditedCb.isSelected()); + if (!DiskSpaceChecker.checkDiskSpaceForDPX(tmpWriteFilesPath, fileList)) { + // User chose not to proceed due to insufficient disk space + return; + } + } + final WriteFilesDialog d = new WriteFilesDialog(tmpWriteFilesPath, tmpReportPath, writeEditedCb.isSelected()); diff --git a/src/main/com/portalmedia/embarc/gui/mxf/WriteFilesModalControllerMXF.java b/src/main/com/portalmedia/embarc/gui/mxf/WriteFilesModalControllerMXF.java index 4d76c7a..f94095e 100644 --- a/src/main/com/portalmedia/embarc/gui/mxf/WriteFilesModalControllerMXF.java +++ b/src/main/com/portalmedia/embarc/gui/mxf/WriteFilesModalControllerMXF.java @@ -2,11 +2,16 @@ import java.io.File; import java.io.FileNotFoundException; +import java.util.List; import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; import com.portalmedia.embarc.gui.Main; +import com.portalmedia.embarc.gui.helper.MXFFileList; +import com.portalmedia.embarc.parser.FileInformation; +import com.portalmedia.embarc.parser.mxf.MXFMetadata; +import com.portalmedia.embarc.system.DiskSpaceChecker; import com.portalmedia.embarc.gui.helper.CleanInputPathHelper; import com.portalmedia.embarc.system.UserPreferencesService; @@ -147,6 +152,25 @@ public void changed(ObservableValue observable, Boolean oldVa final String tmpWriteFilesPath = saveAsCb.isSelected() ? writeFilesPath.getText() : ""; + // Check for available disk space when saving to a separate directory + if (saveAsCb.isSelected() && !tmpWriteFilesPath.isEmpty()) { + List> fileList; + if (writeEditedCb.isSelected()) { + // Filter to only get edited files + fileList = MXFFileList.getList().stream() + .filter(file -> file.isEdited() && file.getFileShouldBeWritten()) + .collect(java.util.stream.Collectors.toList()); + } else { + // Get all files + fileList = MXFFileList.getList(); + } + + if (!DiskSpaceChecker.checkDiskSpaceForMXF(tmpWriteFilesPath, fileList)) { + // User chose not to proceed due to insufficient disk space + return; + } + } + WriteFilesDialogMXF d; try { d = new WriteFilesDialogMXF(tmpWriteFilesPath, writeEditedCb.isSelected()); diff --git a/src/main/com/portalmedia/embarc/system/DiskSpaceChecker.java b/src/main/com/portalmedia/embarc/system/DiskSpaceChecker.java new file mode 100644 index 0000000..6db0bbd --- /dev/null +++ b/src/main/com/portalmedia/embarc/system/DiskSpaceChecker.java @@ -0,0 +1,168 @@ +package com.portalmedia.embarc.system; + +import java.io.File; +import java.text.DecimalFormat; +import java.util.List; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.portalmedia.embarc.gui.Main; +import com.portalmedia.embarc.gui.model.DPXFileInformationViewModel; +import com.portalmedia.embarc.parser.FileInformation; +import com.portalmedia.embarc.parser.mxf.MXFMetadata; + +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.ButtonBar.ButtonData; +import javafx.scene.control.ButtonType; + +/** + * Utility class to check available disk space before writing files + * + * @author PortalMedia + * @version 1.0 + * @since 2025-05-11 + */ +public class DiskSpaceChecker { + private static final Logger LOGGER = Logger.getLogger(DiskSpaceChecker.class.getName()); + + /** + * Checks if there is enough disk space available in the target directory for DPX files + * + * @param targetDir The directory where files will be written + * @param fileList List of DPX files to be written + * @return true if user confirms to proceed or if there's enough space, false otherwise + */ + public static boolean checkDiskSpaceForDPX(String targetDir, List fileList) { + if (targetDir == null || targetDir.isEmpty() || fileList == null || fileList.isEmpty()) { + return true; + } + + File directory = new File(targetDir); + if (!directory.exists()) { + // Create directory if it doesn't exist + if (!directory.mkdirs()) { + LOGGER.log(Level.WARNING, "Failed to create directory: " + targetDir); + return true; // Continue anyway as this will be handled during file writing + } + } + + // Calculate total size of files to be written + long totalSize = 0; + for (DPXFileInformationViewModel file : fileList) { + try { + String filePath = file.getProp("path"); + if (filePath != null && !filePath.isEmpty()) { + File sourceFile = new File(filePath); + if (sourceFile.exists()) { + totalSize += sourceFile.length(); + } + } + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Error calculating file size", e); + } + } + + // Get available space in target directory + long availableSpace = directory.getFreeSpace(); + + // If available space is less than total size, show confirmation dialog + if (availableSpace < totalSize) { + LOGGER.log(Level.SEVERE, "Available space is less than total size"); + return showConfirmationDialog(totalSize, availableSpace); + } + + return true; + } + + /** + * Checks if there is enough disk space available in the target directory for MXF files + * + * @param targetDir The directory where files will be written + * @param fileList List of MXF files to be written + * @return true if user confirms to proceed or if there's enough space, false otherwise + */ + public static boolean checkDiskSpaceForMXF(String targetDir, List> fileList) { + if (targetDir == null || targetDir.isEmpty() || fileList == null || fileList.isEmpty()) { + return true; + } + + File directory = new File(targetDir); + if (!directory.exists()) { + // Create directory if it doesn't exist + if (!directory.mkdirs()) { + LOGGER.log(Level.WARNING, "Failed to create directory: " + targetDir); + return true; // Continue anyway as this will be handled during file writing + } + } + + // Calculate total size of files to be written + long totalSize = 0; + for (FileInformation file : fileList) { + try { + totalSize += file.getFileData().getFileSize(); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Error calculating file size", e); + } + } + + // Get available space in target directory + long availableSpace = directory.getFreeSpace(); + + // If available space is less than total size, show confirmation dialog + if (availableSpace < totalSize) { + return showConfirmationDialog(totalSize, availableSpace); + } + + return true; + } + + /** + * Shows a confirmation dialog to the user when there's not enough disk space + * + * @param requiredSpace The amount of space required for the files + * @param availableSpace The amount of space available on the disk + * @return true if user confirms to proceed, false otherwise + */ + private static boolean showConfirmationDialog(long requiredSpace, long availableSpace) { + Alert alert = new Alert(AlertType.WARNING); + alert.setTitle("Disk Space Warning"); + alert.setHeaderText("Insufficient Disk Space"); + + String formattedRequired = formatSize(requiredSpace); + String formattedAvailable = formatSize(availableSpace); + + alert.setContentText("embARC is about to write " + formattedRequired + " of data, but only " + + formattedAvailable + " is available on the target drive. Do you want to continue?"); + + ButtonType buttonTypeYes = new ButtonType("Yes", ButtonData.YES); + ButtonType buttonTypeNo = new ButtonType("No", ButtonData.NO); + + alert.getButtonTypes().setAll(buttonTypeYes, buttonTypeNo); + alert.initOwner(Main.getPrimaryStage()); + + Optional result = alert.showAndWait(); + return result.isPresent() && result.get() == buttonTypeYes; + } + + /** + * Formats a size in bytes to a human-readable string (KB, MB, GB, TB) + * + * @param size Size in bytes + * @return Formatted string + */ + private static String formatSize(long size) { + if (size <= 0) return "0 B"; + + final String[] units = new String[] { "B", "KB", "MB", "GB", "TB" }; + int digitGroups = (int) (Math.log10(size) / Math.log10(1024)); + + if (digitGroups >= units.length) { + digitGroups = units.length - 1; + } + + DecimalFormat df = new DecimalFormat("#,##0.##"); + return df.format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups]; + } +}