Skip to content

Commit 0bb963e

Browse files
committed
feat: 保存画像ファイル名フォーマット指定 (#1477)
- ExportImageCommand の FileNameMode パラメーター廃止 - 代わりに FileNameFormat0,1,2 で指定する
1 parent 510c91f commit 0bb963e

55 files changed

Lines changed: 1240 additions & 179 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

NeeView/Archiver/LoosePath.cs

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System;
33
using System.Collections.Generic;
44
using System.Diagnostics.CodeAnalysis;
5+
using System.Globalization;
56
using System.Linq;
67
using System.Text.RegularExpressions;
78

@@ -111,6 +112,20 @@ public static string GetFileNameWithoutExtension(string? s)
111112
}
112113
}
113114

115+
public static string WithoutExtension(string? s)
116+
{
117+
if (string.IsNullOrEmpty(s)) return "";
118+
var ext = GetExtension(s);
119+
if (string.IsNullOrEmpty(ext))
120+
{
121+
return s;
122+
}
123+
else
124+
{
125+
return s[..^ext.Length];
126+
}
127+
}
128+
114129

115130
//
116131
public static string GetPathRoot(string? s)
@@ -235,7 +250,7 @@ public static string ValidFileName(string? s)
235250
{
236251
if (string.IsNullOrEmpty(s)) return "";
237252

238-
string valid = s;
253+
string valid = s.Trim();
239254
char[] invalids = System.IO.Path.GetInvalidFileNameChars();
240255

241256
foreach (char c in invalids)
@@ -385,7 +400,7 @@ public static bool TryReplaceStartsWith(string path, string src, string dst, [No
385400
}
386401
}
387402

388-
public static string CreateUniquePath(string name, bool withExtension, Func<string, bool> existsFunc)
403+
public static string CreateUniquePath(string name, bool withExtension, Func<string, bool> existsFunc, UniqueNamePolicy policy = UniqueNamePolicy.NumberSuffix)
389404
{
390405
if (!existsFunc(name))
391406
{
@@ -401,15 +416,26 @@ public static string CreateUniquePath(string name, bool withExtension, Func<stri
401416
baseName = name[..^ext.Length].TrimEnd();
402417
}
403418

419+
var format = policy == UniqueNamePolicy.UnderscoreNumberSuffix ? "{0}_{1}{2}" : "{0} ({1}){2}";
420+
404421
for (int i = 2; ; i++)
405422
{
406-
// TODO: 競合回避の番号の付け方を指定可能にする。 e.g.: "name (2).ext", "name_2.ext" など
407-
var newName = $"{baseName} ({i}){ext}";
423+
var newName = string.Format(CultureInfo.InvariantCulture, format, baseName, i, ext);
408424
if (!existsFunc(newName))
409425
{
410426
return newName;
411427
}
412428
}
413429
}
414430
}
431+
432+
public enum UniqueNamePolicy
433+
{
434+
// name (2).ext
435+
NumberSuffix,
436+
437+
// name_2.ext
438+
UnderscoreNumberSuffix,
439+
}
440+
415441
}

NeeView/Bitmap/BitmapImageFormat.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,16 @@ public enum BitmapImageFormat
1212
Png,
1313
}
1414

15+
public static class BitmapImageFormatExtensions
16+
{
17+
public static string GetExtension(this BitmapImageFormat format)
18+
{
19+
return format switch
20+
{
21+
BitmapImageFormat.Jpeg => ".jpg",
22+
BitmapImageFormat.Png => ".png",
23+
_ => throw new System.ArgumentOutOfRangeException(nameof(format), format, null)
24+
};
25+
}
26+
}
1527
}

NeeView/Book/PagePart.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ public static PagePart Reverse(this PagePart pagePart)
2929
_ => pagePart,
3030
};
3131
}
32+
33+
public static string ToSuffix(this PagePart pagePart)
34+
{
35+
return pagePart switch
36+
{
37+
PagePart.Left => "L",
38+
PagePart.Right => "R",
39+
_ => "",
40+
};
41+
}
3242
}
3343

3444

NeeView/Command/CommandParameters/ExportImageAsCommandParameter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace NeeView
1212
[Equatable(Explicit = true)]
1313
public partial class ExportImageAsCommandParameter : CommandParameter
1414
{
15-
[Obsolete("no used"), Alternative(null, 46, ErrorLevel = ScriptErrorLevel.Warning)]
15+
[Obsolete("no used"), Alternative(null, 46, ScriptErrorLevel.Warning)]
1616
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWriting)]
1717
[PropertyPath(FileDialogType = FileDialogType.Directory)]
1818
[DefaultEquality]
@@ -22,7 +22,7 @@ public string ExportFolder
2222
set => ExportFolderLegacy = value;
2323
}
2424

25-
[Obsolete("no used"), Alternative(null, 46, ErrorLevel = ScriptErrorLevel.Warning)]
25+
[Obsolete("no used"), Alternative(null, 46, ScriptErrorLevel.Warning)]
2626
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWriting)]
2727
[PropertyRange(5, 100, TickFrequency = 5)]
2828
[DefaultEquality]

NeeView/Command/CommandParameters/ExportImageCommandParameter.cs

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using Generator.Equals;
22
using NeeView.Windows.Controls;
33
using NeeView.Windows.Property;
4+
using System;
5+
using System.Text.Json.Serialization;
46

57
namespace NeeView
68
{
@@ -12,7 +14,9 @@ public partial class ExportImageCommandParameter : CommandParameter, IExportImag
1214
[DefaultEquality] private bool _isOriginalSize = true;
1315
[DefaultEquality] private bool _isDotKeep;
1416
[DefaultEquality] private string? _exportFolder;
15-
[DefaultEquality] private ExportImageFileNameMode _fileNameMode;
17+
[DefaultEquality] private string _fileNameFormat0 = ExportImageParameter.DefaultFileNameFormat0;
18+
[DefaultEquality] private string _fileNameFormat1 = ExportImageParameter.DefaultFileNameFormat1;
19+
[DefaultEquality] private string _fileNameFormat2 = ExportImageParameter.DefaultFileNameFormat2;
1620
[DefaultEquality] private BitmapImageFormat _fileFormat;
1721
[DefaultEquality] private int _qualityLevel = 80;
1822
[DefaultEquality] private bool _isShowToast = true;
@@ -54,11 +58,25 @@ public string ExportFolder
5458
set => SetProperty(ref _exportFolder, value);
5559
}
5660

57-
[PropertyMember(Name = "ExportImageParameter.FileNameMode")]
58-
public ExportImageFileNameMode FileNameMode
61+
[PropertyMember]
62+
public string FileNameFormat0
63+
{
64+
get { return _fileNameFormat0; }
65+
set { SetProperty(ref _fileNameFormat0, value); }
66+
}
67+
68+
[PropertyMember]
69+
public string FileNameFormat1
5970
{
60-
get => _fileNameMode;
61-
set => SetProperty(ref _fileNameMode, value);
71+
get { return _fileNameFormat1; }
72+
set { SetProperty(ref _fileNameFormat1, value); }
73+
}
74+
75+
[PropertyMember]
76+
public string FileNameFormat2
77+
{
78+
get { return _fileNameFormat2; }
79+
set { SetProperty(ref _fileNameFormat2, value); }
6280
}
6381

6482
[PropertyMember(Name = "ExportImageParameter.FileFormat")]
@@ -88,15 +106,43 @@ public ExportImageOverwriteMode OverwriteMode
88106
get { return _overwriteMode; }
89107
set { SetProperty(ref _overwriteMode, value); }
90108
}
109+
110+
111+
#region Obsolete
112+
113+
[Obsolete, Alternative("FileNameFormat0,1,2", 46, ScriptErrorLevel.Warning)] // ver.46
114+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWriting)]
115+
[PropertyMember(Name = "ExportImageParameter.FileNameMode")]
116+
public ExportImageFileNameMode FileNameMode
117+
{
118+
get => default;
119+
set
120+
{
121+
if (value == ExportImageFileNameMode.BookPageNumber)
122+
{
123+
FileNameFormat0 = "{Book}_{Page:000}";
124+
FileNameFormat1 = "{Book}_{Page:000}";
125+
FileNameFormat2 = "{Book}_{Page1:000}-{Page2:000}";
126+
}
127+
else
128+
{
129+
FileNameFormat0 = ExportImageParameter.DefaultFileNameFormat0;
130+
FileNameFormat1 = ExportImageParameter.DefaultFileNameFormat1;
131+
FileNameFormat2 = ExportImageParameter.DefaultFileNameFormat1;
132+
}
133+
}
134+
}
135+
136+
#endregion
91137
}
92138

93139

94140
public enum ExportImageOverwriteMode
95141
{
96142
Confirm,
97-
143+
98144
AddNumber,
99145

100-
Invalid,
146+
Disallow,
101147
}
102148
}

NeeView/Config/Config.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public string? Pagemark
143143
set { }
144144
}
145145

146-
[Obsolete("no used"), Alternative(null, 46, ErrorLevel = ScriptErrorLevel.Error)] // ver.46
146+
[Obsolete("no used"), Alternative(null, 46, ScriptErrorLevel.Error)] // ver.46
147147
[JsonIgnore]
148148
public string? Control
149149
{

NeeView/Controls/XHtmlTextBlock.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ private static void Hyperlink_RequestNavigate(object sender, System.Windows.Navi
135135
}
136136
else
137137
{
138-
ExternalProcess.Start(e.Uri.LocalPath);
138+
var path = e.Uri.Scheme == "file" ? e.Uri.LocalPath : e.Uri.AbsoluteUri;
139+
ExternalProcess.Start(path);
139140
}
140141
e.Handled = true;
141142
}

NeeView/ExportImage/ExportBook.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ private async Task<bool> ExportViewPageAsync(IExportImageWriter writer, ExportIm
169169
using var service = new ExportImageService(source, parameter);
170170
service.ThrowIfCannotExport();
171171

172-
var pageSource = new ExportPageSource(service.Source.BookAddress, service.Source.Pages);
172+
var pageSource = new ExportPageSource(service.Source.BookAddress, service.Source.Direction, service.Source.Elements);
173173
using (var stream = await writer.OpenEntryAsync(pageSource, service, parameter, overwritePolicy, token))
174174
{
175175
var page = pages.First();

NeeView/ExportImage/ExportBookDialog.xaml.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,35 @@ public ExportBookDialog(ExportBookParameter parameter, string bookName) : this()
2424
{
2525
_vm = new ExportBookDialogViewModel(parameter, bookName);
2626
this.DataContext = _vm;
27-
28-
this.Loaded += ExportBookDialog_Loaded;
29-
this.KeyDown += ExportBookDialog_KeyDown;
3027
}
3128

3229
public string FileName => _vm?.FileName ?? "";
3330

34-
private void ExportBookDialog_Loaded(object sender, RoutedEventArgs e)
31+
32+
protected override void OnClosed(EventArgs e)
33+
{
34+
_vm?.Dispose();
35+
36+
base.OnClosed(e);
37+
}
38+
39+
protected override void OnContentRendered(EventArgs e)
3540
{
41+
base.OnContentRendered(e);
42+
3643
this.SaveButton.Focus();
3744
}
3845

39-
private void ExportBookDialog_KeyDown(object sender, KeyEventArgs e)
46+
protected override void OnKeyDown(KeyEventArgs e)
4047
{
4148
if (e.Key == Key.Escape && Keyboard.Modifiers == ModifierKeys.None)
4249
{
4350
this.Close();
4451
e.Handled = true;
52+
return;
4553
}
54+
55+
base.OnKeyDown(e);
4656
}
4757

4858
private async void SaveButton_Click(object sender, RoutedEventArgs e)

0 commit comments

Comments
 (0)