Пример #1
0
    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;
        }
    }
Пример #2
0
    /// <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);
                });
            }
        }
    }