mirror of
https://github.com/cyanfish/naps2.git
synced 2024-11-10 14:28:12 +03:00
Add a DisposableList helper
This commit is contained in:
parent
c9d982a531
commit
5460ceea9f
@ -34,6 +34,9 @@ public record Memento(ImmutableList<ProcessedImage> Images) : IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Images.DisposeAll();
|
||||
foreach (var image in Images)
|
||||
{
|
||||
image.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
@ -45,6 +45,9 @@ public class AutoSaver
|
||||
var imageList = new List<ProcessedImage>();
|
||||
source.ForEach(img =>
|
||||
{
|
||||
// TODO: We should assume the returned sink may dispose what we give it, therefore we should make
|
||||
// a clone before sending it out, and then dispose the clone when we're done with it
|
||||
// TODO: We should add tests for this class
|
||||
sink.PutImage(img);
|
||||
imageList.Add(img);
|
||||
}).ContinueWith(async t =>
|
||||
|
@ -10,7 +10,7 @@ public interface IScannedImagePrinter
|
||||
/// <param name="images">The full list of images to print.</param>
|
||||
/// <param name="selectedImages">The list of selected images. If non-empty, the user will be presented an option to print selected.</param>
|
||||
/// <returns>True if the print completed, false if there was nothing to print or the user cancelled.</returns>
|
||||
Task<bool> PromptToPrint(List<ProcessedImage> images, List<ProcessedImage> selectedImages);
|
||||
Task<bool> PromptToPrint(IList<ProcessedImage> images, IList<ProcessedImage> selectedImages);
|
||||
|
||||
/// <summary>
|
||||
/// Prints the provided images with the specified printer settings.
|
||||
@ -19,5 +19,5 @@ public interface IScannedImagePrinter
|
||||
/// <param name="images">The full list of images to print.</param>
|
||||
/// <param name="selectedImages">The list of selected images, to be used if the printer settings specify to print selected.</param>
|
||||
/// <returns>True if the print completed, false if there was nothing to print.</returns>
|
||||
Task<bool> Print(PrinterSettings printerSettings, List<ProcessedImage> images, List<ProcessedImage> selectedImages);
|
||||
Task<bool> Print(PrinterSettings printerSettings, IList<ProcessedImage> images, IList<ProcessedImage> selectedImages);
|
||||
}
|
@ -32,7 +32,7 @@ public class SaveImagesOperation : OperationBase
|
||||
/// <param name="placeholders"></param>
|
||||
/// <param name="images">The collection of images to save.</param>
|
||||
/// <param name="batch"></param>
|
||||
public bool Start(string fileName, Placeholders placeholders, List<ProcessedImage> images, IConfigProvider<ImageSettings> imageSettings, bool batch = false)
|
||||
public bool Start(string fileName, Placeholders placeholders, IList<ProcessedImage> images, IConfigProvider<ImageSettings> imageSettings, bool batch = false)
|
||||
{
|
||||
Status = new OperationStatus
|
||||
{
|
||||
@ -123,11 +123,6 @@ public class SaveImagesOperation : OperationBase
|
||||
Log.ErrorException(MiscResources.ErrorSaving, ex);
|
||||
InvokeError(MiscResources.ErrorSaving, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
images.ForEach(s => s.Dispose());
|
||||
GC.Collect();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
Success.ContinueWith(task =>
|
||||
|
@ -8,7 +8,7 @@ namespace NAPS2.ImportExport.Images;
|
||||
|
||||
public class TiffHelper
|
||||
{
|
||||
public async Task<bool> SaveMultipage(List<ProcessedImage> images, string location, TiffCompression compression, ProgressHandler progressCallback, CancellationToken cancelToken)
|
||||
public async Task<bool> SaveMultipage(IList<ProcessedImage> images, string location, TiffCompression compression, ProgressHandler progressCallback, CancellationToken cancelToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -14,7 +14,7 @@ public class PrintDocumentPrinter : IScannedImagePrinter
|
||||
_imageContext = imageContext;
|
||||
}
|
||||
|
||||
public async Task<bool> PromptToPrint(List<ProcessedImage> images, List<ProcessedImage> selectedImages)
|
||||
public async Task<bool> PromptToPrint(IList<ProcessedImage> images, IList<ProcessedImage> selectedImages)
|
||||
{
|
||||
if (!images.Any())
|
||||
{
|
||||
@ -39,9 +39,9 @@ public class PrintDocumentPrinter : IScannedImagePrinter
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<bool> Print(PrinterSettings printerSettings, List<ProcessedImage> images, List<ProcessedImage> selectedImages)
|
||||
public async Task<bool> Print(PrinterSettings printerSettings, IList<ProcessedImage> images, IList<ProcessedImage> selectedImages)
|
||||
{
|
||||
List<ProcessedImage> imagesToPrint;
|
||||
IList<ProcessedImage> imagesToPrint;
|
||||
switch (printerSettings.PrintRange)
|
||||
{
|
||||
case PrintRange.AllPages:
|
||||
|
@ -1,4 +1,6 @@
|
||||
namespace NAPS2.Util;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace NAPS2.Util;
|
||||
|
||||
public static class CollectionExtensions
|
||||
{
|
||||
@ -221,11 +223,8 @@ public static class CollectionExtensions
|
||||
|
||||
public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> enumerable) => enumerable.Where(x => x != null)!;
|
||||
|
||||
public static void DisposeAll<T>(this IEnumerable<T?> enumerable) where T : IDisposable
|
||||
public static DisposableList<T> ToDisposableList<T>(this IEnumerable<T> enumerable) where T : IDisposable
|
||||
{
|
||||
foreach(var obj in enumerable)
|
||||
{
|
||||
obj?.Dispose();
|
||||
}
|
||||
return new DisposableList<T>(enumerable.ToImmutableList());
|
||||
}
|
||||
}
|
23
NAPS2.Sdk/Util/DisposableList.cs
Normal file
23
NAPS2.Sdk/Util/DisposableList.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace NAPS2.Util;
|
||||
|
||||
// TODO: Maybe instead of a generic DisposableList we should create an class for a list of ProcessedImage that has
|
||||
// explicit ownership semantics
|
||||
public class DisposableList<T> : IDisposable where T : IDisposable
|
||||
{
|
||||
public DisposableList(ImmutableList<T> innerList)
|
||||
{
|
||||
InnerList = innerList;
|
||||
}
|
||||
|
||||
public ImmutableList<T> InnerList { get; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach(var item in InnerList)
|
||||
{
|
||||
item.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
@ -884,59 +884,35 @@ namespace NAPS2.WinForms
|
||||
|
||||
private async void SavePDF(List<UiImage> images)
|
||||
{
|
||||
var imagesToSave = images.Select(x => x.GetClonedImage()).ToList();
|
||||
try
|
||||
using var imagesToSave = images.Select(x => x.GetClonedImage()).ToDisposableList();
|
||||
if (await _exportHelper.SavePDF(imagesToSave.InnerList, _notify))
|
||||
{
|
||||
if (await _exportHelper.SavePDF(imagesToSave, _notify))
|
||||
if (Config.Get(c => c.DeleteAfterSaving))
|
||||
{
|
||||
if (Config.Get(c => c.DeleteAfterSaving))
|
||||
SafeInvoke(() =>
|
||||
{
|
||||
SafeInvoke(() =>
|
||||
{
|
||||
_imageList.Mutate(new ImageListMutation.DeleteSelected(), ListSelection.From(images));
|
||||
});
|
||||
}
|
||||
_imageList.Mutate(new ImageListMutation.DeleteSelected(), ListSelection.From(images));
|
||||
});
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// TODO: We probably want a disposable list wrapper (around an immutable list) instead of DisposeAll
|
||||
imagesToSave.DisposeAll();
|
||||
}
|
||||
}
|
||||
|
||||
private async void SaveImages(List<UiImage> images)
|
||||
{
|
||||
var imagesToSave = images.Select(x => x.GetClonedImage()).ToList();
|
||||
try
|
||||
using var imagesToSave = images.Select(x => x.GetClonedImage()).ToDisposableList();
|
||||
if (await _exportHelper.SaveImages(imagesToSave.InnerList, _notify))
|
||||
{
|
||||
if (await _exportHelper.SaveImages(imagesToSave, _notify))
|
||||
if (Config.Get(c => c.DeleteAfterSaving))
|
||||
{
|
||||
if (Config.Get(c => c.DeleteAfterSaving))
|
||||
{
|
||||
_imageList.Mutate(new ImageListMutation.DeleteSelected(), ListSelection.From(images));
|
||||
}
|
||||
_imageList.Mutate(new ImageListMutation.DeleteSelected(), ListSelection.From(images));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// TODO: We probably want a disposable list wrapper (around an immutable list) instead of DisposeAll
|
||||
imagesToSave.DisposeAll();
|
||||
}
|
||||
}
|
||||
|
||||
private async void EmailPDF(List<UiImage> images)
|
||||
{
|
||||
var imagesToEmail = images.Select(x => x.GetClonedImage()).ToList();
|
||||
try
|
||||
{
|
||||
await _exportHelper.EmailPDF(imagesToEmail);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// TODO: We probably want a disposable list wrapper (around an immutable list) instead of DisposeAll
|
||||
imagesToEmail.DisposeAll();
|
||||
}
|
||||
using var imagesToEmail = images.Select(x => x.GetClonedImage()).ToDisposableList();
|
||||
await _exportHelper.EmailPDF(imagesToEmail.InnerList);
|
||||
}
|
||||
|
||||
private void Import()
|
||||
@ -1281,19 +1257,11 @@ namespace NAPS2.WinForms
|
||||
private async void tsPrint_Click(object sender, EventArgs e)
|
||||
{
|
||||
var state = _imageList.CurrentState;
|
||||
var allImages = _imageList.Images.Select(x => x.GetClonedImage()).ToList();
|
||||
var selectedImages = SelectedImages.Select(x => x.GetClonedImage()).ToList();
|
||||
try
|
||||
using var allImages = _imageList.Images.Select(x => x.GetClonedImage()).ToDisposableList();
|
||||
using var selectedImages = SelectedImages.Select(x => x.GetClonedImage()).ToDisposableList();
|
||||
if (await _scannedImagePrinter.PromptToPrint(allImages.InnerList, selectedImages.InnerList))
|
||||
{
|
||||
if (await _scannedImagePrinter.PromptToPrint(allImages, selectedImages))
|
||||
{
|
||||
_imageList.SavedState = state;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
allImages.DisposeAll();
|
||||
selectedImages.DisposeAll();
|
||||
_imageList.SavedState = state;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1489,16 +1457,8 @@ namespace NAPS2.WinForms
|
||||
|
||||
private async void ctxCopy_Click(object sender, EventArgs e)
|
||||
{
|
||||
var imagesToCopy = SelectedImages.Select(x => x.GetClonedImage()).ToList();
|
||||
try
|
||||
{
|
||||
await _imageClipboard.Write(imagesToCopy, true);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// TODO: We probably want a disposable list wrapper (around an immutable list) instead of DisposeAll
|
||||
imagesToCopy.DisposeAll();
|
||||
}
|
||||
using var imagesToCopy = SelectedImages.Select(x => x.GetClonedImage()).ToDisposableList();
|
||||
await _imageClipboard.Write(imagesToCopy.InnerList, true);
|
||||
}
|
||||
|
||||
private void ctxPaste_Click(object sender, EventArgs e)
|
||||
@ -1686,16 +1646,9 @@ namespace NAPS2.WinForms
|
||||
if (SelectedIndices.Any())
|
||||
{
|
||||
var ido = new DataObject();
|
||||
var selectedImages = SelectedImages.Select(x => x.GetClonedImage()).ToList();
|
||||
try
|
||||
{
|
||||
_imageTransfer.AddTo(ido.ToEto(), selectedImages);
|
||||
DoDragDrop(ido, DragDropEffects.Move | DragDropEffects.Copy);
|
||||
}
|
||||
finally
|
||||
{
|
||||
selectedImages.DisposeAll();
|
||||
}
|
||||
using var selectedImages = SelectedImages.Select(x => x.GetClonedImage()).ToDisposableList();
|
||||
_imageTransfer.AddTo(ido.ToEto(), selectedImages.InnerList);
|
||||
DoDragDrop(ido, DragDropEffects.Move | DragDropEffects.Copy);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ public class WinFormsExportHelper
|
||||
_uiImageList = uiImageList;
|
||||
}
|
||||
|
||||
public async Task<bool> SavePDF(List<ProcessedImage> images, ISaveNotify notify)
|
||||
public async Task<bool> SavePDF(IList<ProcessedImage> images, ISaveNotify notify)
|
||||
{
|
||||
if (images.Any())
|
||||
{
|
||||
@ -63,7 +63,7 @@ public class WinFormsExportHelper
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<bool> ExportPDF(string filename, List<ProcessedImage> images, bool email, EmailMessage emailMessage)
|
||||
public async Task<bool> ExportPDF(string filename, IList<ProcessedImage> images, bool email, EmailMessage emailMessage)
|
||||
{
|
||||
var op = _operationFactory.Create<SavePdfOperation>();
|
||||
|
||||
@ -74,7 +74,7 @@ public class WinFormsExportHelper
|
||||
return await op.Success;
|
||||
}
|
||||
|
||||
public async Task<bool> SaveImages(List<ProcessedImage> images, ISaveNotify notify)
|
||||
public async Task<bool> SaveImages(IList<ProcessedImage> images, ISaveNotify notify)
|
||||
{
|
||||
if (images.Any())
|
||||
{
|
||||
@ -108,7 +108,7 @@ public class WinFormsExportHelper
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<bool> EmailPDF(List<ProcessedImage> images)
|
||||
public async Task<bool> EmailPDF(IList<ProcessedImage> images)
|
||||
{
|
||||
if (!images.Any())
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user