Add options to set file created/modified timestamps (#638)

This commit is contained in:
MBucari 2023-06-25 14:07:39 -06:00
parent a5d98364fa
commit ac87d70613
14 changed files with 227 additions and 122 deletions

View File

@ -81,6 +81,9 @@ namespace FileLiberator
extension: "mp3", extension: "mp3",
Configuration.Instance.OverwriteExisting); Configuration.Instance.OverwriteExisting);
SetFileTime(libraryBook, realMp3Path);
SetDirectoryTime(libraryBook, Path.GetDirectoryName(realMp3Path));
OnFileCreated(libraryBook, realMp3Path); OnFileCreated(libraryBook, realMp3Path);
} }
} }

View File

@ -99,8 +99,12 @@ namespace FileLiberator
} }
finally finally
{ {
if (moveFilesTask.IsCompletedSuccessfully) if (moveFilesTask.IsCompletedSuccessfully)
await Task.Run(() => libraryBook.UpdateBookStatus(LiberatedStatus.Liberated, Configuration.LibationVersion)); {
await Task.Run(() => libraryBook.UpdateBookStatus(LiberatedStatus.Liberated, Configuration.LibationVersion));
SetDirectoryTime(libraryBook, finalStorageDir);
}
} }
return new StatusHandler(); return new StatusHandler();
@ -367,7 +371,8 @@ namespace FileLiberator
Configuration.Instance.ReplacementCharacters, Configuration.Instance.ReplacementCharacters,
overwrite: Configuration.Instance.OverwriteExisting); overwrite: Configuration.Instance.OverwriteExisting);
FilePathCache.Insert(libraryBook.Book.AudibleProductId, realDest); SetFileTime(libraryBook, realDest);
FilePathCache.Insert(libraryBook.Book.AudibleProductId, realDest);
// propagate corrected path. Must update cache with corrected path. Also want updated path for cue file (after this for-loop) // propagate corrected path. Must update cache with corrected path. Also want updated path for cue file (after this for-loop)
entries[i] = entry with { Path = realDest }; entries[i] = entry with { Path = realDest };
@ -375,7 +380,10 @@ namespace FileLiberator
var cue = entries.FirstOrDefault(f => f.FileType == FileType.Cue); var cue = entries.FirstOrDefault(f => f.FileType == FileType.Cue);
if (cue != default) if (cue != default)
{
Cue.UpdateFileName(cue.Path, getFirstAudioFile(entries).Path); Cue.UpdateFileName(cue.Path, getFirstAudioFile(entries).Path);
SetFileTime(libraryBook, cue.Path);
}
AudibleFileStorage.Audio.Refresh(); AudibleFileStorage.Audio.Refresh();
} }
@ -408,7 +416,10 @@ namespace FileLiberator
var picBytes = PictureStorage.GetPictureSynchronously(new(libraryBook.Book.PictureLarge ?? libraryBook.Book.PictureId, PictureSize.Native)); var picBytes = PictureStorage.GetPictureSynchronously(new(libraryBook.Book.PictureLarge ?? libraryBook.Book.PictureId, PictureSize.Native));
if (picBytes.Length > 0) if (picBytes.Length > 0)
{
File.WriteAllBytes(coverPath, picBytes); File.WriteAllBytes(coverPath, picBytes);
SetFileTime(libraryBook, coverPath);
}
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -30,6 +30,11 @@ namespace FileLiberator
var actualDownloadedFilePath = await downloadPdfAsync(libraryBook, proposedDownloadFilePath); var actualDownloadedFilePath = await downloadPdfAsync(libraryBook, proposedDownloadFilePath);
var result = verifyDownload(actualDownloadedFilePath); var result = verifyDownload(actualDownloadedFilePath);
if (result.IsSuccess)
{
SetFileTime(libraryBook, actualDownloadedFilePath);
SetDirectoryTime(libraryBook, Path.GetDirectoryName(actualDownloadedFilePath));
}
libraryBook.UpdatePdfStatus(result.IsSuccess ? LiberatedStatus.Liberated : LiberatedStatus.NotLiberated); libraryBook.UpdatePdfStatus(result.IsSuccess ? LiberatedStatus.Liberated : LiberatedStatus.NotLiberated);
return result; return result;

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using DataLayer; using DataLayer;
@ -98,5 +99,26 @@ namespace FileLiberator
Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(Completed), Book = libraryBook.LogFriendly() }); Serilog.Log.Logger.Debug("Event fired {@DebugInfo}", new { Name = nameof(Completed), Book = libraryBook.LogFriendly() });
Completed?.Invoke(this, libraryBook); Completed?.Invoke(this, libraryBook);
} }
}
protected static void SetFileTime(LibraryBook libraryBook, string file)
=> setFileSystemTime(libraryBook, new FileInfo(file));
protected static void SetDirectoryTime(LibraryBook libraryBook, string file)
=> setFileSystemTime(libraryBook, new DirectoryInfo(file));
private static void setFileSystemTime(LibraryBook libraryBook, FileSystemInfo fileInfo)
{
if (!fileInfo.Exists) return;
fileInfo.CreationTimeUtc = getTimeValue(Configuration.Instance.CreationTime) ?? fileInfo.CreationTimeUtc;
fileInfo.LastWriteTimeUtc = getTimeValue(Configuration.Instance.LastWriteTime) ?? fileInfo.LastWriteTimeUtc;
DateTime? getTimeValue(Configuration.DateTimeSource source) => source switch
{
Configuration.DateTimeSource.Added => libraryBook.DateAdded,
Configuration.DateTimeSource.Published => libraryBook.Book.DatePublished,
_ => null,
};
}
}
} }

View File

@ -32,6 +32,40 @@
<TextBlock Text="{CompiledBinding OverwriteExistingText}" /> <TextBlock Text="{CompiledBinding OverwriteExistingText}" />
</CheckBox> </CheckBox>
<Grid
RowDefinitions="Auto,Auto"
ColumnDefinitions="Auto,*">
<TextBlock
VerticalAlignment="Center"
Margin="0,0,10,0"
Text="{CompiledBinding CreationTimeText}" />
<controls:WheelComboBox
Height="25"
Grid.Column="1"
Margin="0,5"
HorizontalContentAlignment="Stretch"
SelectedItem="{CompiledBinding CreationTime, Mode=TwoWay}"
ItemsSource="{CompiledBinding DateTimeSources}" />
<TextBlock
VerticalAlignment="Center"
Grid.Row="1"
Margin="0,0,10,0"
Text="{CompiledBinding LastWriteTimeText}" />
<controls:WheelComboBox
Height="25"
Grid.Row="1"
Grid.Column="1"
Margin="0,5"
HorizontalContentAlignment="Stretch"
SelectedItem="{CompiledBinding LastWriteTime, Mode=TwoWay}"
ItemsSource="{CompiledBinding DateTimeSources}" />
</Grid>
</StackPanel> </StackPanel>
</controls:GroupBox> </controls:GroupBox>

View File

@ -1,9 +1,11 @@
using Avalonia.Collections; using AAXClean;
using Avalonia.Collections;
using Avalonia.Controls; using Avalonia.Controls;
using Dinah.Core; using Dinah.Core;
using LibationFileManager; using LibationFileManager;
using LibationUiBase; using LibationUiBase;
using ReactiveUI; using ReactiveUI;
using System;
using System.Linq; using System.Linq;
namespace LibationAvalonia.ViewModels.Settings namespace LibationAvalonia.ViewModels.Settings
@ -19,21 +21,11 @@ namespace LibationAvalonia.ViewModels.Settings
private int _lameBitrate; private int _lameBitrate;
private int _lameVBRQuality; private int _lameVBRQuality;
private string _chapterTitleTemplate; private string _chapterTitleTemplate;
public SampleRateSelection SelectedSampleRate { get; set; } public EnumDiaplay<SampleRate> SelectedSampleRate { get; set; }
public NAudio.Lame.EncoderQuality SelectedEncoderQuality { get; set; } public NAudio.Lame.EncoderQuality SelectedEncoderQuality { get; set; }
public AvaloniaList<SampleRateSelection> SampleRates { get; } public AvaloniaList<EnumDiaplay<SampleRate>> SampleRates { get; }
= new( = new(Enum.GetValues<SampleRate>().Select(v => new EnumDiaplay<SampleRate>(v, $"{(int)v} Hz")));
new[]
{
AAXClean.SampleRate.Hz_44100,
AAXClean.SampleRate.Hz_32000,
AAXClean.SampleRate.Hz_24000,
AAXClean.SampleRate.Hz_22050,
AAXClean.SampleRate.Hz_16000,
AAXClean.SampleRate.Hz_12000,
}
.Select(s => new SampleRateSelection(s)));
public AvaloniaList<NAudio.Lame.EncoderQuality> EncoderQualities { get; } public AvaloniaList<NAudio.Lame.EncoderQuality> EncoderQualities { get; }
= new( = new(
@ -71,7 +63,7 @@ namespace LibationAvalonia.ViewModels.Settings
LameBitrate = config.LameBitrate; LameBitrate = config.LameBitrate;
LameVBRQuality = config.LameVBRQuality; LameVBRQuality = config.LameVBRQuality;
SelectedSampleRate = SampleRates.FirstOrDefault(s => s.SampleRate == config.MaxSampleRate); SelectedSampleRate = SampleRates.SingleOrDefault(s => s.Value == config.MaxSampleRate);
SelectedEncoderQuality = config.LameEncoderQuality; SelectedEncoderQuality = config.LameEncoderQuality;
} }
@ -98,7 +90,7 @@ namespace LibationAvalonia.ViewModels.Settings
config.LameVBRQuality = LameVBRQuality; config.LameVBRQuality = LameVBRQuality;
config.LameEncoderQuality = SelectedEncoderQuality; config.LameEncoderQuality = SelectedEncoderQuality;
config.MaxSampleRate = SelectedSampleRate?.SampleRate ?? config.MaxSampleRate; config.MaxSampleRate = SelectedSampleRate?.Value ?? config.MaxSampleRate;
} }
public AvaloniaList<Configuration.ClipBookmarkFormat> ClipBookmarkFormats { get; } = new(Enum<Configuration.ClipBookmarkFormat>.GetValues()); public AvaloniaList<Configuration.ClipBookmarkFormat> ClipBookmarkFormats { get; } = new(Enum<Configuration.ClipBookmarkFormat>.GetValues());

View File

@ -1,9 +1,11 @@
using Dinah.Core; using Dinah.Core;
using FileManager; using FileManager;
using LibationFileManager; using LibationFileManager;
using LibationUiBase;
using ReactiveUI; using ReactiveUI;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace LibationAvalonia.ViewModels.Settings namespace LibationAvalonia.ViewModels.Settings
{ {
@ -22,6 +24,8 @@ namespace LibationAvalonia.ViewModels.Settings
BooksDirectory = config.Books.PathWithoutPrefix; BooksDirectory = config.Books.PathWithoutPrefix;
SavePodcastsToParentFolder = config.SavePodcastsToParentFolder; SavePodcastsToParentFolder = config.SavePodcastsToParentFolder;
OverwriteExisting = config.OverwriteExisting; OverwriteExisting = config.OverwriteExisting;
CreationTime = DateTimeSources.SingleOrDefault(v => v.Value == config.CreationTime) ?? DateTimeSources[0];
LastWriteTime = DateTimeSources.SingleOrDefault(v => v.Value == config.LastWriteTime) ?? DateTimeSources[0];
LoggingLevel = config.LogLevel; LoggingLevel = config.LogLevel;
ThemeVariant = initialThemeVariant ThemeVariant = initialThemeVariant
= Configuration.Instance.GetString(propertyName: nameof(ThemeVariant)) is nameof(Avalonia.Styling.ThemeVariant.Dark) = Configuration.Instance.GetString(propertyName: nameof(ThemeVariant)) is nameof(Avalonia.Styling.ThemeVariant.Dark)
@ -37,6 +41,8 @@ namespace LibationAvalonia.ViewModels.Settings
config.Books = lonNewBooks; config.Books = lonNewBooks;
config.SavePodcastsToParentFolder = SavePodcastsToParentFolder; config.SavePodcastsToParentFolder = SavePodcastsToParentFolder;
config.OverwriteExisting = OverwriteExisting; config.OverwriteExisting = OverwriteExisting;
config.CreationTime = CreationTime.Value;
config.LastWriteTime = LastWriteTime.Value;
config.LogLevel = LoggingLevel; config.LogLevel = LoggingLevel;
Configuration.Instance.SetString(ThemeVariant, nameof(ThemeVariant)); Configuration.Instance.SetString(ThemeVariant, nameof(ThemeVariant));
} }
@ -53,6 +59,12 @@ namespace LibationAvalonia.ViewModels.Settings
public string BooksText { get; } = Configuration.GetDescription(nameof(Configuration.Books)); public string BooksText { get; } = Configuration.GetDescription(nameof(Configuration.Books));
public string SavePodcastsToParentFolderText { get; } = Configuration.GetDescription(nameof(Configuration.SavePodcastsToParentFolder)); public string SavePodcastsToParentFolderText { get; } = Configuration.GetDescription(nameof(Configuration.SavePodcastsToParentFolder));
public string OverwriteExistingText { get; } = Configuration.GetDescription(nameof(Configuration.OverwriteExisting)); public string OverwriteExistingText { get; } = Configuration.GetDescription(nameof(Configuration.OverwriteExisting));
public string CreationTimeText { get; } = Configuration.GetDescription(nameof(Configuration.CreationTime));
public string LastWriteTimeText { get; } = Configuration.GetDescription(nameof(Configuration.LastWriteTime));
public EnumDiaplay<Configuration.DateTimeSource>[] DateTimeSources { get; }
= Enum.GetValues<Configuration.DateTimeSource>()
.Select(v => new EnumDiaplay<Configuration.DateTimeSource>(v))
.ToArray();
public Serilog.Events.LogEventLevel[] LoggingLevels { get; } = Enum.GetValues<Serilog.Events.LogEventLevel>(); public Serilog.Events.LogEventLevel[] LoggingLevels { get; } = Enum.GetValues<Serilog.Events.LogEventLevel>();
public string BetaOptInText { get; } = Configuration.GetDescription(nameof(Configuration.BetaOptIn)); public string BetaOptInText { get; } = Configuration.GetDescription(nameof(Configuration.BetaOptIn));
public string[] Themes { get; } = { nameof(Avalonia.Styling.ThemeVariant.Light), nameof(Avalonia.Styling.ThemeVariant.Dark) }; public string[] Themes { get; } = { nameof(Avalonia.Styling.ThemeVariant.Light), nameof(Avalonia.Styling.ThemeVariant.Dark) };
@ -60,6 +72,8 @@ namespace LibationAvalonia.ViewModels.Settings
public string BooksDirectory { get; set; } public string BooksDirectory { get; set; }
public bool SavePodcastsToParentFolder { get; set; } public bool SavePodcastsToParentFolder { get; set; }
public bool OverwriteExisting { get; set; } public bool OverwriteExisting { get; set; }
public EnumDiaplay<Configuration.DateTimeSource> CreationTime { get; set; }
public EnumDiaplay<Configuration.DateTimeSource> LastWriteTime { get; set; }
public Serilog.Events.LogEventLevel LoggingLevel { get; set; } public Serilog.Events.LogEventLevel LoggingLevel { get; set; }
public string ThemeVariant public string ThemeVariant

View File

@ -194,6 +194,23 @@ namespace LibationFileManager
Ignore = 3 Ignore = 3
} }
[JsonConverter(typeof(StringEnumConverter))]
public enum DateTimeSource
{
[Description("File creation date/time.")]
File,
[Description("Audiobook publication date")]
Published,
[Description("Date the book added to your Audible account")]
Added
}
[Description("Set file \"created\" timestamp to:")]
public DateTimeSource CreationTime { get => GetNonString(defaultValue: DateTimeSource.Published); set => SetNonString(value); }
[Description("Set file \"modified\" timestamp to:")]
public DateTimeSource LastWriteTime { get => GetNonString(defaultValue: DateTimeSource.Published); set => SetNonString(value); }
[Description("Indicates that this is the first time Libation has been run")] [Description("Indicates that this is the first time Libation has been run")]
public bool FirstLaunch { get => GetNonString(defaultValue: true); set => SetNonString(value); } public bool FirstLaunch { get => GetNonString(defaultValue: true); set => SetNonString(value); }

View File

@ -0,0 +1,17 @@
using Dinah.Core;
using System;
namespace LibationUiBase
{
public record EnumDiaplay<T> where T : Enum
{
public T Value { get; }
public string Description { get; }
public EnumDiaplay(T value, string description = null)
{
Value = value;
Description = description ?? value.GetDescription() ?? value.ToString();
}
public override string ToString() => Description;
}
}

View File

@ -1,12 +0,0 @@
namespace LibationUiBase
{
public class SampleRateSelection
{
public AAXClean.SampleRate SampleRate { get; }
public SampleRateSelection(AAXClean.SampleRate sampleRate)
{
SampleRate = sampleRate;
}
public override string ToString() => $"{(int)SampleRate} Hz";
}
}

View File

@ -28,15 +28,9 @@ namespace LibationWinForms.Dialogs
}); });
maxSampleRateCb.Items.AddRange( maxSampleRateCb.Items.AddRange(
new object[] Enum.GetValues<AAXClean.SampleRate>()
{ .Select(v => new EnumDiaplay<AAXClean.SampleRate>(v, $"{(int)v} Hz"))
new SampleRateSelection(AAXClean.SampleRate.Hz_44100), .ToArray());
new SampleRateSelection(AAXClean.SampleRate.Hz_32000),
new SampleRateSelection(AAXClean.SampleRate.Hz_24000),
new SampleRateSelection(AAXClean.SampleRate.Hz_22050),
new SampleRateSelection(AAXClean.SampleRate.Hz_16000),
new SampleRateSelection(AAXClean.SampleRate.Hz_12000)
});
encoderQualityCb.Items.AddRange( encoderQualityCb.Items.AddRange(
new object[] new object[]
@ -62,7 +56,13 @@ namespace LibationWinForms.Dialogs
lameTargetBitrateRb.Checked = config.LameTargetBitrate; lameTargetBitrateRb.Checked = config.LameTargetBitrate;
lameTargetQualityRb.Checked = !config.LameTargetBitrate; lameTargetQualityRb.Checked = !config.LameTargetBitrate;
maxSampleRateCb.SelectedItem = maxSampleRateCb.Items.Cast<SampleRateSelection>().Single(s => s.SampleRate == config.MaxSampleRate);
maxSampleRateCb.SelectedItem
= maxSampleRateCb.Items
.Cast<EnumDiaplay<AAXClean.SampleRate>>()
.SingleOrDefault(v => v.Value == config.MaxSampleRate)
?? maxSampleRateCb.Items[0];
encoderQualityCb.SelectedItem = config.LameEncoderQuality; encoderQualityCb.SelectedItem = config.LameEncoderQuality;
lameDownsampleMonoCbox.Checked = config.LameDownsampleMono; lameDownsampleMonoCbox.Checked = config.LameDownsampleMono;
lameBitrateTb.Value = config.LameBitrate; lameBitrateTb.Value = config.LameBitrate;
@ -95,9 +95,8 @@ namespace LibationWinForms.Dialogs
config.StripAudibleBrandAudio = stripAudibleBrandingCbox.Checked; config.StripAudibleBrandAudio = stripAudibleBrandingCbox.Checked;
config.DecryptToLossy = convertLossyRb.Checked; config.DecryptToLossy = convertLossyRb.Checked;
config.MoveMoovToBeginning = moveMoovAtomCbox.Checked; config.MoveMoovToBeginning = moveMoovAtomCbox.Checked;
config.LameTargetBitrate = lameTargetBitrateRb.Checked; config.LameTargetBitrate = lameTargetBitrateRb.Checked;
config.MaxSampleRate = ((SampleRateSelection)maxSampleRateCb.SelectedItem).SampleRate; config.MaxSampleRate = ((EnumDiaplay<AAXClean.SampleRate>)maxSampleRateCb.SelectedItem).Value;
config.LameEncoderQuality = (NAudio.Lame.EncoderQuality)encoderQualityCb.SelectedItem; config.LameEncoderQuality = (NAudio.Lame.EncoderQuality)encoderQualityCb.SelectedItem;
encoderQualityCb.SelectedItem = config.LameEncoderQuality; encoderQualityCb.SelectedItem = config.LameEncoderQuality;
config.LameDownsampleMono = lameDownsampleMonoCbox.Checked; config.LameDownsampleMono = lameDownsampleMonoCbox.Checked;

View File

@ -53,6 +53,11 @@
tab1ImportantSettings = new System.Windows.Forms.TabPage(); tab1ImportantSettings = new System.Windows.Forms.TabPage();
betaOptInCbox = new System.Windows.Forms.CheckBox(); betaOptInCbox = new System.Windows.Forms.CheckBox();
booksGb = new System.Windows.Forms.GroupBox(); booksGb = new System.Windows.Forms.GroupBox();
lastWriteTimeCb = new System.Windows.Forms.ComboBox();
creationTimeCb = new System.Windows.Forms.ComboBox();
lastWriteTimeLbl = new System.Windows.Forms.Label();
creationTimeLbl = new System.Windows.Forms.Label();
overwriteExistingCbox = new System.Windows.Forms.CheckBox();
saveEpisodesToSeriesFolderCbox = new System.Windows.Forms.CheckBox(); saveEpisodesToSeriesFolderCbox = new System.Windows.Forms.CheckBox();
tab2ImportLibrary = new System.Windows.Forms.TabPage(); tab2ImportLibrary = new System.Windows.Forms.TabPage();
autoDownloadEpisodesCb = new System.Windows.Forms.CheckBox(); autoDownloadEpisodesCb = new System.Windows.Forms.CheckBox();
@ -119,7 +124,6 @@
retainAaxFileCbox = new System.Windows.Forms.CheckBox(); retainAaxFileCbox = new System.Windows.Forms.CheckBox();
downloadCoverArtCbox = new System.Windows.Forms.CheckBox(); downloadCoverArtCbox = new System.Windows.Forms.CheckBox();
createCueSheetCbox = new System.Windows.Forms.CheckBox(); createCueSheetCbox = new System.Windows.Forms.CheckBox();
overwriteExistingCbox = new System.Windows.Forms.CheckBox();
badBookGb.SuspendLayout(); badBookGb.SuspendLayout();
tabControl.SuspendLayout(); tabControl.SuspendLayout();
tab1ImportantSettings.SuspendLayout(); tab1ImportantSettings.SuspendLayout();
@ -331,7 +335,7 @@
// //
// logsBtn // logsBtn
// //
logsBtn.Location = new System.Drawing.Point(256, 220); logsBtn.Location = new System.Drawing.Point(256, 261);
logsBtn.Name = "logsBtn"; logsBtn.Name = "logsBtn";
logsBtn.Size = new System.Drawing.Size(132, 23); logsBtn.Size = new System.Drawing.Size(132, 23);
logsBtn.TabIndex = 5; logsBtn.TabIndex = 5;
@ -351,7 +355,7 @@
// loggingLevelLbl // loggingLevelLbl
// //
loggingLevelLbl.AutoSize = true; loggingLevelLbl.AutoSize = true;
loggingLevelLbl.Location = new System.Drawing.Point(6, 223); loggingLevelLbl.Location = new System.Drawing.Point(6, 264);
loggingLevelLbl.Name = "loggingLevelLbl"; loggingLevelLbl.Name = "loggingLevelLbl";
loggingLevelLbl.Size = new System.Drawing.Size(78, 15); loggingLevelLbl.Size = new System.Drawing.Size(78, 15);
loggingLevelLbl.TabIndex = 3; loggingLevelLbl.TabIndex = 3;
@ -361,7 +365,7 @@
// //
loggingLevelCb.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; loggingLevelCb.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
loggingLevelCb.FormattingEnabled = true; loggingLevelCb.FormattingEnabled = true;
loggingLevelCb.Location = new System.Drawing.Point(90, 220); loggingLevelCb.Location = new System.Drawing.Point(90, 261);
loggingLevelCb.Name = "loggingLevelCb"; loggingLevelCb.Name = "loggingLevelCb";
loggingLevelCb.Size = new System.Drawing.Size(129, 23); loggingLevelCb.Size = new System.Drawing.Size(129, 23);
loggingLevelCb.TabIndex = 4; loggingLevelCb.TabIndex = 4;
@ -409,17 +413,69 @@
// booksGb // booksGb
// //
booksGb.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; booksGb.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
booksGb.Controls.Add(lastWriteTimeCb);
booksGb.Controls.Add(creationTimeCb);
booksGb.Controls.Add(lastWriteTimeLbl);
booksGb.Controls.Add(creationTimeLbl);
booksGb.Controls.Add(overwriteExistingCbox); booksGb.Controls.Add(overwriteExistingCbox);
booksGb.Controls.Add(saveEpisodesToSeriesFolderCbox); booksGb.Controls.Add(saveEpisodesToSeriesFolderCbox);
booksGb.Controls.Add(booksSelectControl); booksGb.Controls.Add(booksSelectControl);
booksGb.Controls.Add(booksLocationDescLbl); booksGb.Controls.Add(booksLocationDescLbl);
booksGb.Location = new System.Drawing.Point(6, 6); booksGb.Location = new System.Drawing.Point(6, 6);
booksGb.Name = "booksGb"; booksGb.Name = "booksGb";
booksGb.Size = new System.Drawing.Size(842, 182); booksGb.Size = new System.Drawing.Size(842, 249);
booksGb.TabIndex = 0; booksGb.TabIndex = 0;
booksGb.TabStop = false; booksGb.TabStop = false;
booksGb.Text = "Books location"; booksGb.Text = "Books location";
// //
// lastWriteTimeCb
//
lastWriteTimeCb.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
lastWriteTimeCb.FormattingEnabled = true;
lastWriteTimeCb.Location = new System.Drawing.Point(188, 214);
lastWriteTimeCb.Name = "lastWriteTimeCb";
lastWriteTimeCb.Size = new System.Drawing.Size(266, 23);
lastWriteTimeCb.TabIndex = 5;
//
// creationTimeCb
//
creationTimeCb.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
creationTimeCb.FormattingEnabled = true;
creationTimeCb.Location = new System.Drawing.Point(188, 185);
creationTimeCb.Name = "creationTimeCb";
creationTimeCb.Size = new System.Drawing.Size(266, 23);
creationTimeCb.TabIndex = 5;
//
// lastWriteTimeLbl
//
lastWriteTimeLbl.AutoSize = true;
lastWriteTimeLbl.Location = new System.Drawing.Point(7, 217);
lastWriteTimeLbl.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
lastWriteTimeLbl.Name = "lastWriteTimeLbl";
lastWriteTimeLbl.Size = new System.Drawing.Size(116, 15);
lastWriteTimeLbl.TabIndex = 4;
lastWriteTimeLbl.Text = "[last write time desc]";
//
// creationTimeLbl
//
creationTimeLbl.AutoSize = true;
creationTimeLbl.Location = new System.Drawing.Point(7, 188);
creationTimeLbl.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
creationTimeLbl.Name = "creationTimeLbl";
creationTimeLbl.Size = new System.Drawing.Size(112, 15);
creationTimeLbl.TabIndex = 4;
creationTimeLbl.Text = "[creation time desc]";
//
// overwriteExistingCbox
//
overwriteExistingCbox.AutoSize = true;
overwriteExistingCbox.Location = new System.Drawing.Point(7, 156);
overwriteExistingCbox.Name = "overwriteExistingCbox";
overwriteExistingCbox.Size = new System.Drawing.Size(129, 19);
overwriteExistingCbox.TabIndex = 3;
overwriteExistingCbox.Text = "[Overwrite Existing]";
overwriteExistingCbox.UseVisualStyleBackColor = true;
//
// saveEpisodesToSeriesFolderCbox // saveEpisodesToSeriesFolderCbox
// //
saveEpisodesToSeriesFolderCbox.AutoSize = true; saveEpisodesToSeriesFolderCbox.AutoSize = true;
@ -1145,16 +1201,6 @@
createCueSheetCbox.UseVisualStyleBackColor = true; createCueSheetCbox.UseVisualStyleBackColor = true;
createCueSheetCbox.CheckedChanged += allowLibationFixupCbox_CheckedChanged; createCueSheetCbox.CheckedChanged += allowLibationFixupCbox_CheckedChanged;
// //
// overwriteExistingCbox
//
overwriteExistingCbox.AutoSize = true;
overwriteExistingCbox.Location = new System.Drawing.Point(7, 156);
overwriteExistingCbox.Name = "overwriteExistingCbox";
overwriteExistingCbox.Size = new System.Drawing.Size(129, 19);
overwriteExistingCbox.TabIndex = 3;
overwriteExistingCbox.Text = "[Overwrite Existing]";
overwriteExistingCbox.UseVisualStyleBackColor = true;
//
// SettingsDialog // SettingsDialog
// //
AcceptButton = saveBtn; AcceptButton = saveBtn;
@ -1300,5 +1346,9 @@
private System.Windows.Forms.Label label21; private System.Windows.Forms.Label label21;
private System.Windows.Forms.Label label20; private System.Windows.Forms.Label label20;
private System.Windows.Forms.CheckBox overwriteExistingCbox; private System.Windows.Forms.CheckBox overwriteExistingCbox;
private System.Windows.Forms.Label creationTimeLbl;
private System.Windows.Forms.ComboBox lastWriteTimeCb;
private System.Windows.Forms.ComboBox creationTimeCb;
private System.Windows.Forms.Label lastWriteTimeLbl;
} }
} }

View File

@ -1,4 +1,5 @@
using LibationFileManager; using LibationFileManager;
using LibationUiBase;
using System; using System;
using System.Linq; using System.Linq;
@ -13,6 +14,15 @@ namespace LibationWinForms.Dialogs
this.importEpisodesCb.Text = desc(nameof(config.ImportEpisodes)); this.importEpisodesCb.Text = desc(nameof(config.ImportEpisodes));
this.downloadEpisodesCb.Text = desc(nameof(config.DownloadEpisodes)); this.downloadEpisodesCb.Text = desc(nameof(config.DownloadEpisodes));
this.autoDownloadEpisodesCb.Text = desc(nameof(config.AutoDownloadEpisodes)); this.autoDownloadEpisodesCb.Text = desc(nameof(config.AutoDownloadEpisodes));
creationTimeLbl.Text = desc(nameof(config.CreationTime));
lastWriteTimeLbl.Text = desc(nameof(config.LastWriteTime));
var dateTimeSources = Enum.GetValues<Configuration.DateTimeSource>().Select(v => new EnumDiaplay<Configuration.DateTimeSource>(v)).ToArray();
creationTimeCb.Items.AddRange(dateTimeSources);
lastWriteTimeCb.Items.AddRange(dateTimeSources);
creationTimeCb.SelectedItem = dateTimeSources.SingleOrDefault(v => v.Value == config.CreationTime) ?? dateTimeSources[0];
lastWriteTimeCb.SelectedItem = dateTimeSources.SingleOrDefault(v => v.Value == config.LastWriteTime) ?? dateTimeSources[0];
autoScanCb.Checked = config.AutoScan; autoScanCb.Checked = config.AutoScan;
showImportedStatsCb.Checked = config.ShowImportedStats; showImportedStatsCb.Checked = config.ShowImportedStats;
@ -22,6 +32,9 @@ namespace LibationWinForms.Dialogs
} }
private void Save_ImportLibrary(Configuration config) private void Save_ImportLibrary(Configuration config)
{ {
config.CreationTime = ((EnumDiaplay<Configuration.DateTimeSource>)creationTimeCb.SelectedItem).Value;
config.LastWriteTime = ((EnumDiaplay<Configuration.DateTimeSource>)lastWriteTimeCb.SelectedItem).Value;
config.AutoScan = autoScanCb.Checked; config.AutoScan = autoScanCb.Checked;
config.ShowImportedStats = showImportedStatsCb.Checked; config.ShowImportedStats = showImportedStatsCb.Checked;
config.ImportEpisodes = importEpisodesCb.Checked; config.ImportEpisodes = importEpisodesCb.Checked;

View File

@ -1,64 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <root>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true"> <xsd:element name="root" msdata:IsDataSet="true">