public async Task ConvertAsync() { if (IsLoading) { return; } try { IsLoading = true; // Attempt to get a default directory FileSystemPath?defaultDir = SelectedType.SelectedMode.GetDefaultDir(); // Make sure the directory exists if (defaultDir?.DirectoryExists != true) { defaultDir = null; } // Allow the user to select the files FileBrowserResult fileResult = await Services.BrowseUI.BrowseFileAsync(new FileBrowserViewModel() { Title = Resources.Utilities_Converter_FileSelectionHeader, DefaultDirectory = defaultDir?.FullPath, ExtensionFilter = SelectedType.SourceFileExtension.GetFileFilterItem.ToString(), MultiSelection = true }); if (fileResult.CanceledByUser) { return; } // Allow the user to select the destination directory DirectoryBrowserResult destinationResult = await Services.BrowseUI.BrowseDirectoryAsync(new DirectoryBrowserViewModel() { Title = Resources.Browse_DestinationHeader, }); if (destinationResult.CanceledByUser) { return; } // Allow the user to select the file extension to export as FileExtensionSelectionDialogResult extResult = await Services.UI.SelectFileExtensionAsync(new FileExtensionSelectionDialogViewModel(SelectedType.ConvertFormats, Resources.Utilities_Converter_ExportExtensionHeader)); if (extResult.CanceledByUser) { return; } try { await Task.Run(() => { using RCPContext context = new(fileResult.SelectedFiles.First().Parent); SelectedType.SelectedMode.InitContext(context); // Convert every file foreach (FileSystemPath file in fileResult.SelectedFiles) { // Get the destination file FileSystemPath destinationFile = destinationResult.SelectedDirectory + file.Name; // Set the file extension destinationFile = destinationFile.ChangeFileExtension(new FileExtension(extResult.SelectedFileFormat, multiple: true)).GetNonExistingFileName(); // Convert the file SelectedType.Convert(context, file.Name, destinationFile); } }); await Services.MessageUI.DisplaySuccessfulActionMessageAsync(Resources.Utilities_Converter_Success); } catch (Exception ex) { Logger.Error(ex, "Converting files"); await Services.MessageUI.DisplayExceptionMessageAsync(ex, Resources.Utilities_Converter_Error); } } finally { IsLoading = false; } }
/// <summary> /// Exports the directory /// </summary> /// <param name="forceNativeFormat">Indicates if the native format should be forced</param> /// <param name="selectedFilesOnly">Indicates if only selected files in the current directory should be exported</param> /// <returns>The task</returns> public async Task ExportAsync(bool forceNativeFormat, bool selectedFilesOnly = false) { // Run as a load operation using (await Archive.LoadOperation.RunAsync()) { // Lock the access to the archive using (await Archive.ArchiveLock.LockAsync()) { // Get the output path DirectoryBrowserResult result = await Services.BrowseUI.BrowseDirectoryAsync(new DirectoryBrowserViewModel() { Title = Resources.Archive_ExportHeader }); if (result.CanceledByUser) { return; } // Make sure there isn't an existing file at the output path if ((result.SelectedDirectory + ExportDirName).FileExists) { await Services.MessageUI.DisplayMessageAsync(String.Format(Resources.Archive_ExportDirFileConflict, ExportDirName), MessageType.Error); return; } // Run as a task await Task.Run(async() => { // Get the manager IArchiveDataManager manager = Archive.Manager; // Save the selected format for each collection Dictionary <IArchiveFileType, FileExtension?> selectedFormats = new(); try { ArchiveDirectoryViewModel[] allDirs; if (selectedFilesOnly) { allDirs = new ArchiveDirectoryViewModel[] { this } } ; else { allDirs = this.GetAllChildren(true).ToArray(); } int fileIndex = 0; int filesCount = allDirs.SelectMany(x => x.Files).Count(x => !selectedFilesOnly || x.IsSelected); // Handle each directory foreach (ArchiveDirectoryViewModel item in allDirs) { // Get the directory path FileSystemPath path = result.SelectedDirectory + ExportDirName + item.FullPath.Remove(0, FullPath.Length).Trim(manager.PathSeparatorCharacter); // Create the directory Directory.CreateDirectory(path); // Save each file foreach (ArchiveFileViewModel file in item.Files.Where(x => !selectedFilesOnly || x.IsSelected)) { // Get the file stream using ArchiveFileStream fileStream = file.GetDecodedFileStream(); // Initialize the file without loading the thumbnail file.InitializeFile(fileStream, ArchiveFileViewModel.ThumbnailLoadMode.None); fileStream.SeekToBeginning(); // Check if the format has not been selected if (!forceNativeFormat && !selectedFormats.ContainsKey(file.FileType) && file.FileType is not ArchiveFileType_Default) { // Get the available extensions string[] ext = new string[] { Resources.Archive_Export_Format_Original }.Concat(file.FileType.ExportFormats.Select(x => x.FileExtensions)).ToArray(); // Have user select the format FileExtensionSelectionDialogResult extResult = await Services.UI.SelectFileExtensionAsync(new FileExtensionSelectionDialogViewModel(ext, String.Format(Resources.Archive_FileExtensionSelectionInfoHeader, file.FileType.TypeDisplayName))); // Since this operation can't be canceled we get the first format if (extResult.CanceledByUser) { extResult.SelectedFileFormat = ext.First(); } // Add the selected format FileExtension?e = extResult.SelectedFileFormat == ext.First() ? null : new FileExtension(extResult.SelectedFileFormat, multiple: true); selectedFormats.Add(file.FileType, e); } // Get the selected format FileExtension?format = forceNativeFormat || file.FileType is ArchiveFileType_Default ? null : selectedFormats[file.FileType]; // Get the final file name to use when exporting FileSystemPath exportFileName = format == null ? new FileSystemPath(file.FileName) : new FileSystemPath(file.FileName).ChangeFileExtension(format, true); Archive.SetDisplayStatus($"{String.Format(Resources.Archive_ExportingFileStatus, file.FileName)}" + $"{Environment.NewLine}{++fileIndex}/{filesCount}"); try { // Export the file file.ExportFile(path + exportFileName, fileStream, format); } catch (Exception ex) { // If the export failed for a native format we throw if (format == null) { throw; } Logger.Error(ex, "Exporting archive file {0}", file.FileName); // If the export failed and we tried converting it we instead export it as the native format // Start by setting the file in the error state, thus changing the type file.InitializeAsError(); // Seek to the beginning of the stream in case some bytes were read fileStream.SeekToBeginning(); // Export the file as the native format file.ExportFile(path + file.FileName, fileStream, null); } } } } catch (Exception ex) { Logger.Error(ex, "Exporting archive directory {0}", DisplayName); await Services.MessageUI.DisplayExceptionMessageAsync(ex, String.Format(Resources.Archive_ExportError, DisplayName)); return; } finally { Archive.SetDisplayStatus(String.Empty); } await Services.MessageUI.DisplaySuccessfulActionMessageAsync(Resources.Archive_ExportFilesSuccess); }); } } }