88using System . Drawing ;
99using System . IO ;
1010using System . Linq ;
11+ using System . Reflection ;
1112using System . Text ;
1213using System . Text . RegularExpressions ;
14+ using System . Threading ;
1315using System . Threading . Tasks ;
1416using System . Windows . Forms ;
1517using static SubRenamer . Global ;
@@ -21,9 +23,6 @@ public partial class MainForm
2123 private List < VsItem > VsList = new List < VsItem > { } ;
2224 public MatchMode CurtMatchMode = MatchMode . Auto ;
2325
24- public static readonly List < string > VideoExts = new List < string > { ".mkv" , ".mp4" , "flv" , ".avi" , ".mov" , ".rmvb" , ".wmv" , ".mpg" , ".avs" } ;
25- public static readonly List < string > SubExts = new List < string > { ".srt" , ".ass" , ".ssa" , ".sub" , ".idx" } ;
26-
2726 // 匹配模式
2827 public enum MatchMode
2928 {
@@ -210,21 +209,30 @@ private string GetMatchKeyByFileName(string fileName, AppFileType fileType, List
210209 else if ( CurtMatchMode == MatchMode . Regex )
211210 {
212211 if ( fileType == AppFileType . Video && M_Regx_V != null )
213- matchKey = M_Regx_V . Match ( fileName ) . Groups [ 1 ] . Value ;
212+ matchKey = GetMatchKeyByRegex ( fileName , M_Regx_V ) ;
214213 else if ( fileType == AppFileType . Sub && M_Regx_S != null )
215- matchKey = M_Regx_S . Match ( fileName ) . Groups [ 1 ] . Value ;
214+ matchKey = GetMatchKeyByRegex ( fileName , M_Regx_S ) ;
216215 }
217216
218217 if ( string . IsNullOrWhiteSpace ( matchKey ) ) matchKey = null ;
219218 return matchKey ;
220219 }
221220
221+ public static string GetMatchKeyByRegex ( string fileName , Regex regex )
222+ {
223+ if ( regex == null || string . IsNullOrWhiteSpace ( fileName ) ) return null ;
224+ if ( regex . Match ( fileName ) . Groups . Count < 2 ) return null ;
225+ return regex . Match ( fileName ) . Groups [ 1 ] . Value ;
226+ }
227+
222228 public static string GetMatchKeyByBeginEndStr ( string fileName , string start , string end )
223229 {
224- if ( string . IsNullOrWhiteSpace ( fileName )
225- || string . IsNullOrWhiteSpace ( start )
226- || string . IsNullOrWhiteSpace ( end ) )
230+ if ( string . IsNullOrWhiteSpace ( fileName ) )
227231 return null ;
232+ if ( string . IsNullOrWhiteSpace ( start ) && string . IsNullOrWhiteSpace ( end ) )
233+ return null ; // 前后字符都没有,直接返回 null
234+ if ( start == null ) start = "" ;
235+ if ( end == null ) end = "" ;
228236
229237 fileName = fileName . Trim ( ) ;
230238
@@ -249,6 +257,7 @@ private string GetEpisByFileName(string fileName, int beginPos, string endStr)
249257 {
250258 if ( string . IsNullOrWhiteSpace ( fileName ) ) return null ;
251259 if ( beginPos <= - 1 ) return null ;
260+ if ( beginPos >= fileName . Length ) return null ;
252261 var str = fileName . Substring ( beginPos ) ;
253262
254263 var result = "" ;
@@ -343,14 +352,23 @@ private string GetEndStrByList(List<FileInfo> list, int beginPos)
343352
344353 protected void StartRename ( )
345354 {
346- if ( GetSubRenameDict ( ) . Count ( ) <= 0 ) return ;
347- Task . Factory . StartNew ( ( ) => _StartRename ( ) ) ;
355+ var subRenameDict = GetSubRenameDict ( ) ;
356+ if ( subRenameDict . Count ( ) <= 0 ) return ;
357+ SwitchPreview ( true ) ;
358+ Task . Factory . StartNew ( ( ) => _StartRename ( subRenameDict ) ) ;
348359 }
349360
350361 /// 执行改名操作
351- private void _StartRename ( )
362+ private void _StartRename ( Dictionary < string , string > subRenameDict )
352363 {
353- var subRenameDict = GetSubRenameDict ( ) ;
364+ Program . Log ( $ "[=============== 开始执行改名操作 ===============]") ;
365+
366+ string btnRawText = "" ;
367+ Invoke ( ( MethodInvoker ) delegate {
368+ StartBtn . Enabled = false ;
369+ btnRawText = StartBtn . Text ;
370+ StartBtn . Text = "改名中..." ;
371+ } ) ;
354372 int renTotal = subRenameDict . Count ( ) ;
355373 int errTotal = 0 ;
356374 void SetCurrentProgress ( KeyValuePair < string , string > subRename , int index )
@@ -364,7 +382,7 @@ void SetCurrentProgress(KeyValuePair<string, string> subRename, int index)
364382 double percentage = ( index / ( double ) renTotal ) * 100 ;
365383 //td.Text = $"执行一键改名操作中,请稍后... ({index}/{renTotal})" + Environment.NewLine;
366384 //td.Text += $"\"{Path.GetFileName(subRename.Key)}\"{Environment.NewLine}=> \"{Path.GetFileName(subRename.Value)}\"";
367- // td.ProgressBar.Value = int.Parse(Math.Truncate(percentage).ToString());
385+ //td.ProgressBar.Value = int.Parse(Math.Truncate(percentage).ToString());
368386 }
369387
370388 int i = 0 ;
@@ -373,28 +391,36 @@ void SetCurrentProgress(KeyValuePair<string, string> subRename, int index)
373391 try
374392 {
375393 _RenameOnce ( subRename ) ;
376- // td.DetailsExpandedText += $"[成功] [\"{subRename.Key}\"=>\"{subRename.Value}\"]{Environment.NewLine}";
394+ Program . Log ( "[成功]" , $ "[\" { subRename . Key } \" =>\" { subRename . Value } \" ]") ;
395+ Invoke ( ( MethodInvoker ) delegate { RefreshFileListUi ( ) ; } ) ;
377396 }
378397 catch ( Exception e )
379398 {
380- // td.DetailsExpandedText += $"[失败] [\"{subRename.Key}\"=>\"{subRename.Value}\"] {e.Message}{Environment.NewLine}" ;
399+ Program . Log ( "[错误]" , $ " [\" { subRename . Key } \" =>\" { subRename . Value } \" ]{ Environment . NewLine } ==> { e . Message } " ) ;
381400 errTotal ++ ;
382401 }
383402 finally
384403 {
385404 i ++ ;
386- SetCurrentProgress ( subRename , i ) ;
405+ // SetCurrentProgress(subRename, i);
387406 }
388407 }
389408
390- RefreshFileListUi ( ) ;
409+ if ( errTotal > 0 )
410+ Process . Start ( LOG_FILENAME ) ;
411+
412+ Invoke ( ( MethodInvoker ) delegate {
413+ StartBtn . Text = btnRawText ;
414+ StartBtn . Enabled = true ;
415+ } ) ;
391416 }
392417
393418 private void _RenameOnce ( KeyValuePair < string , string > subRename )
394419 {
395420 var vsFile = VsList . Find ( o => o . Sub == subRename . Key ) ;
396421 if ( vsFile == null ) throw new Exception ( "找不到修改项" ) ;
397- if ( vsFile . Status != VsStatus . Ready ) throw new Exception ( "当然状态无法修改" ) ;
422+ if ( vsFile . Status == VsStatus . Done ) return ; // 无需再改名了
423+ if ( vsFile . Status != VsStatus . Ready && vsFile . Status != VsStatus . Fatal ) throw new Exception ( "当然状态无法修改" ) ;
398424 if ( vsFile . Video == null || vsFile . Sub == null ) throw new Exception ( "字幕/视频文件不完整" ) ;
399425
400426 var before = new FileInfo ( subRename . Key ) ;
@@ -404,7 +430,7 @@ private void _RenameOnce(KeyValuePair<string, string> subRename)
404430 if ( before . FullName . Equals ( after . FullName ) )
405431 {
406432 vsFile . Status = VsStatus . Done ;
407- throw new Exception ( "字幕文件名无需修改 ") ;
433+ throw new Exception ( $ "文件名名未修改,因为改名后的文件已存在,无需改名 ") ;
408434 }
409435
410436 // 若原文件不存在
@@ -414,10 +440,37 @@ private void _RenameOnce(KeyValuePair<string, string> subRename)
414440 throw new Exception ( $ "字幕源文件不存在") ;
415441 }
416442
443+ // 执行备份
444+ if ( AppSettings . RawSubtitleBuckup )
445+ {
446+ try
447+ {
448+ // 前字幕文件 和 后字幕文件 若是在同一个目录下
449+ if ( before . DirectoryName == after . DirectoryName && File . Exists ( before . FullName ) )
450+ BackupFile ( before . FullName ) ;
451+
452+ if ( File . Exists ( after . FullName ) )
453+ BackupFile ( after . FullName ) ;
454+ }
455+ catch ( Exception e )
456+ {
457+ throw new Exception ( $ "改名前备份发生错误 { e . GetType ( ) . FullName } { e . ToString ( ) } ") ;
458+ }
459+ }
460+
417461 // 执行更名
418462 try
419463 {
420- File . Move ( before . FullName , after . FullName ) ;
464+ if ( before . DirectoryName == after . DirectoryName )
465+ {
466+ if ( File . Exists ( after . FullName ) ) File . Delete ( after . FullName ) ; // 若后文件存在,则先删除 (上面有备份的)
467+ File . Move ( before . FullName , after . FullName ) ; // 前后字幕相同目录,执行改名
468+ }
469+ else
470+ {
471+ File . Copy ( before . FullName , after . FullName , true ) ; // 前后字幕不同文件,执行复制
472+ }
473+
421474 vsFile . Status = VsStatus . Done ;
422475 }
423476 catch ( Exception e )
@@ -428,6 +481,21 @@ private void _RenameOnce(KeyValuePair<string, string> subRename)
428481 }
429482 }
430483
484+ private void BackupFile ( string filename )
485+ {
486+ if ( ! File . Exists ( filename ) ) return ;
487+ var bkFolder = Path . Combine ( Path . GetDirectoryName ( filename ) , "SubBackup/" ) ;
488+ if ( ! Directory . Exists ( bkFolder ) ) Directory . CreateDirectory ( bkFolder ) ;
489+
490+ string bkDistFile = Path . Combine ( bkFolder , Path . GetFileName ( filename ) ) ;
491+ if ( File . Exists ( bkDistFile ) ) // 解决文件重名问题
492+ bkDistFile = Path . Combine (
493+ bkFolder , Path . GetFileNameWithoutExtension ( filename ) + $ ".{ Program . GetNowDatetime ( ) } { Path . GetExtension ( filename ) } "
494+ ) ;
495+
496+ File . Copy ( filename , bkDistFile , true ) ;
497+ }
498+
431499 // 获取修改的字幕文件名 (原始完整路径->修改后完整路径)
432500 private Dictionary < string , string > GetSubRenameDict ( )
433501 {
@@ -440,7 +508,7 @@ private Dictionary<string, string> GetSubRenameDict()
440508 if ( item . Video == null || item . Sub == null ) continue ;
441509 string videoName = Path . GetFileNameWithoutExtension ( item . VideoFileInfo . Name ) ; // 去掉后缀的视频文件名
442510 string subAfterFilename = videoName + item . SubFileInfo . Extension ; // 修改的字幕文件名
443- dict [ item . SubFileInfo . FullName ] = Path . Combine ( item . SubFileInfo . DirectoryName , subAfterFilename ) ;
511+ dict [ item . SubFileInfo . FullName ] = Path . Combine ( item . VideoFileInfo . DirectoryName , subAfterFilename ) ;
444512 }
445513
446514 return dict ;
0 commit comments