Skip to content

Commit 1b9a0e0

Browse files
committed
Base done.
1 parent 8bc7258 commit 1b9a0e0

11 files changed

Lines changed: 339 additions & 77 deletions

SubtitleRenamer/Action.cs

Lines changed: 171 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
using System.Linq;
1010
using System.Text;
1111
using System.Text.RegularExpressions;
12+
using System.Threading.Tasks;
1213
using System.Windows.Forms;
1314

1415
namespace SubtitleRenamer
1516
{
1617
public partial class MainForm
1718
{
1819
private static string OpenPath = "";
20+
private static bool isFilesLoading = false;
1921
private static List<FileInfo> VideoFileList = new List<FileInfo> { };
2022
private static List<FileInfo> SubtitleFileList = new List<FileInfo> { };
2123

@@ -26,10 +28,48 @@ public partial class MainForm
2628
private static Dictionary<string, string> SubtitleEpisDict = new Dictionary<string, string> { };
2729

2830
private static Dictionary<string, string> SubtitleRenameDict = new Dictionary<string, string> { }; // 之前文件名 -> 修改后文件名
31+
private static Dictionary<string, string> SubtitleChangedStatus = new Dictionary<string, string> { }; // 已经修改了文件名的字幕(原始文件名)
2932

30-
private void ReloadFiles()
33+
private static string CurtStatus = "";
34+
private void SetCurtStatus(string status)
35+
{
36+
CurtStatus = status.Trim();
37+
RefreshFileListBox();
38+
}
39+
40+
private static FileSystemWatcher OpenPathWatcher = null;
41+
42+
// 实时检测 OpenPath 文件变化,并重载文件列表
43+
private void OpenPathWatcherRestart()
44+
{
45+
if (OpenPathWatcher == null)
46+
{
47+
OpenPathWatcher = new FileSystemWatcher();
48+
OpenPathWatcher.Created += OpenPathFileChanged;
49+
OpenPathWatcher.Deleted += OpenPathFileChanged;
50+
OpenPathWatcher.Renamed += OpenPathFileChanged;
51+
}
52+
53+
OpenPathWatcher.Path = OpenPath;
54+
OpenPathWatcher.EnableRaisingEvents = false;
55+
}
56+
57+
private void OpenPathFileChanged(object sender, FileSystemEventArgs e)
58+
{
59+
ReloadFiles();
60+
}
61+
62+
// 重新加载 OpenPath 中的文件
63+
protected void ReloadFiles() => Task.Factory.StartNew(() => _ReloadFiles());
64+
65+
private void _ReloadFiles()
3166
{
3267
if (OpenPath == null || OpenPath.Trim() == "") return;
68+
// 显示加载中...
69+
isFilesLoading = true;
70+
CurtStatus = "";
71+
RefreshFileListBox();
72+
OpenPathWatcherRestart();
3373

3474
var folder = new DirectoryInfo(OpenPath);
3575
var files = folder.GetFiles("*");
@@ -46,49 +86,86 @@ private void ReloadFiles()
4686

4787
// 清空历史数据
4888
SubtitleRenameDict.Clear();
89+
SubtitleChangedStatus.Clear();
4990
VideoEpisDict.Clear();
5091
SubtitleEpisDict.Clear();
5192

5293
// 刷新文件列表
94+
isFilesLoading = false;
5395
RefreshFileListBox();
96+
97+
// 处理文件
98+
MatchEpisode();
99+
100+
// 启动 OpenPath 实时监测,刷新列表
101+
OpenPathWatcher.EnableRaisingEvents = true;
54102
}
55103

56-
private void RefreshFileListBox()
104+
private void RefreshFileListBox() => BeginInvoke((MethodInvoker)delegate
105+
{
106+
_RefreshFileListBox();
107+
});
108+
109+
private void _RefreshFileListBox()
57110
{
58-
// 字幕 listBox
59111
SubtitleFileListBox.Items.Clear();
112+
VideoFileListBox.Items.Clear();
113+
114+
// Head
115+
SubtitleFileListBox.Items.Add($" ◈ 字幕文件 - {SubtitleFileList.Count} 个项目 {(!CurtStatus.Equals("") ? $"[{CurtStatus}]" : "")}");
116+
VideoFileListBox.Items.Add($" ◈ 视频文件 - {VideoFileList.Count} 个项目");
117+
118+
// Loading
119+
if (isFilesLoading)
120+
{
121+
SubtitleFileListBox.Items.Add(" 加载中...");
122+
VideoFileListBox.Items.Add(" 加载中...");
123+
return;
124+
}
125+
126+
// 字幕文件
60127
foreach (var file in SubtitleFileList)
61128
{
62-
var str = "";
129+
var str = " ";
63130
if (SubtitleEpisDict.ContainsKey(file.Name))
64131
str += $"[集数:{SubtitleEpisDict[file.Name]}] ";
65132
str += file.Name;
66133
SubtitleFileListBox.Items.Add(str);
67134
if (SubtitleRenameDict.ContainsKey(file.Name))
68135
{
69-
SubtitleFileListBox.Items.Add(String.Format("{0,12}", " => ") + SubtitleRenameDict[file.Name]);
136+
string renameStatus = SubtitleChangedStatus.ContainsKey(file.Name) ? SubtitleChangedStatus[file.Name] : "";
137+
SubtitleFileListBox.Items.Add(String.Format("{0,17}", renameStatus + " => ") + SubtitleRenameDict[file.Name]);
70138
}
71139
}
72140

73-
// 视频 listBox
74-
VideoFileListBox.Items.Clear();
141+
// 视频文件
75142
foreach (var file in VideoFileList)
76143
{
77-
var str = "";
144+
var str = " ";
78145
if (VideoEpisDict.ContainsKey(file.Name))
79146
str += $"[集数:{VideoEpisDict[file.Name]}] ";
80147
str += file.Name;
81148
VideoFileListBox.Items.Add(str);
82149
}
83150
}
84151

152+
protected void MatchEpisode() => Task.Factory.StartNew(() => _MatchEpisode());
153+
85154
// 匹配 视频 & 字幕 集数位置
86-
private void MatchEpisode()
155+
private void _MatchEpisode()
87156
{
88-
int beginPos = GetEpisodePosByTwoStr(VideoFileList[0].Name, VideoFileList[1].Name); // 视频文件名集数开始位置
89-
int subBeginPos = GetEpisodePosByTwoStr(SubtitleFileList[0].Name, SubtitleFileList[1].Name); // 字幕文件名集数开始位置
157+
if (VideoFileList.Count < 2 || SubtitleFileList.Count < 2) return;
158+
159+
SetCurtStatus("匹配集数中...");
90160

91-
if (beginPos <= -1 || subBeginPos <= -1)
161+
int beginPos;
162+
int subBeginPos;
163+
try
164+
{
165+
beginPos = GetEpisodePosByTwoStr(VideoFileList[0].Name, VideoFileList[1].Name); // 视频文件名集数开始位置
166+
subBeginPos = GetEpisodePosByTwoStr(SubtitleFileList[0].Name, SubtitleFileList[1].Name); // 字幕文件名集数开始位置
167+
}
168+
catch
92169
{
93170
MessageBox.Show("无法正确匹配集数位置,需进一步手动确认", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
94171
return;
@@ -121,6 +198,7 @@ private void MatchEpisode()
121198
}
122199

123200
// 刷新文件列表
201+
SetCurtStatus("集数已匹配");
124202
RefreshFileListBox();
125203
}
126204

@@ -143,25 +221,101 @@ private int GetEpisodePosByTwoStr(string strA, string strB)
143221
}
144222
}
145223

224+
if (beginPos == -1)
225+
{
226+
throw new Exception("beginPos == -1");
227+
}
228+
146229
return beginPos;
147230
}
148231

149232
/// 获取集数
150233
private string GetEpisByFileName(string fileName, int beginPos)
151234
{
152235
if (beginPos <= -1)
153-
{
154236
return null;
155-
}
156237

157238
var str = fileName.Substring(beginPos);
158-
return Regex.Matches(str, @"(\d+)")[0].Value; // 为了获得完整的数字,无论多少位
239+
var grp = Regex.Matches(str, @"(\d+)");
240+
return (grp.Count >= 1) ? grp[0].Value : null; // 为了获得完整的数字,无论多少位
159241
}
160242

243+
protected void StartRename() => Task.Factory.StartNew(() => _StartRename());
244+
161245
/// 执行改名操作
162-
private void StartRename()
246+
private void _StartRename()
163247
{
164-
MessageBox.Show("修改文件名代码还没写... 睡觉了...");
248+
OpenPathWatcher.EnableRaisingEvents = false; // 暂时关闭目录变化列表实时更新
249+
SubtitleChangedStatus.Clear();
250+
251+
foreach (var item in SubtitleRenameDict)
252+
{
253+
string before = item.Key;
254+
string after = item.Value;
255+
string beforeFullPath = Path.Combine(OpenPath, before);
256+
string afterFullPath = Path.Combine(OpenPath, after);
257+
258+
SubtitleChangedStatus[before] = "更名中";
259+
RefreshFileListBox();
260+
261+
// 无需更名
262+
if (before.Equals(after) || SubtitleChangedStatus[before] == "✔")
263+
{
264+
SubtitleChangedStatus[before] = "✔";
265+
continue;
266+
}
267+
268+
// 原文件是否存在
269+
if (!File.Exists(beforeFullPath))
270+
{
271+
SubtitleChangedStatus[before] = "✖";
272+
continue;
273+
}
274+
275+
// 文件备份功能
276+
if (MainSettings.Default.RawSubtitleBuckup)
277+
{
278+
string buckupPath = Path.Combine(OpenPath, "SubtitleFileBackup");
279+
try
280+
{
281+
if (!Directory.Exists(buckupPath))
282+
Directory.CreateDirectory(buckupPath);
283+
File.Copy(beforeFullPath, Path.Combine(buckupPath, before), true);
284+
}
285+
catch (Exception e)
286+
{
287+
BeginInvoke((MethodInvoker)delegate
288+
{
289+
MessageBox.Show("原始字幕备份失败\n\n" + e.Message, "字幕备份失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
290+
});
291+
SubtitleChangedStatus[before] = "✖";
292+
continue;
293+
}
294+
}
295+
296+
// 执行更名
297+
try
298+
{
299+
File.Move(beforeFullPath, afterFullPath);
300+
SubtitleChangedStatus[before] = "✔";
301+
}
302+
catch
303+
{
304+
// 更名失败
305+
SubtitleChangedStatus[before] = "✖";
306+
}
307+
308+
RefreshFileListBox();
309+
}
310+
311+
SetCurtStatus("更名完毕");
312+
RefreshFileListBox();
313+
OpenPathWatcher.EnableRaisingEvents = true;
314+
315+
if (MainSettings.Default.OpenFolderFinished)
316+
{
317+
Process.Start(OpenPath);
318+
}
165319
}
166320
}
167321
}

SubtitleRenamer/MainForm.Designer.cs

Lines changed: 11 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)