From aed3ccd8f99f2d6a10bc5e3b163fadfcecf10304 Mon Sep 17 00:00:00 2001 From: "Martijn van Berkel (Flitskikker)" Date: Mon, 5 Feb 2024 13:34:05 +0100 Subject: [PATCH 1/7] When chaining, also check for shot changes in between when only the right in-cue is on a shot change --- src/libse/Forms/TimeCodesBeautifier.cs | 37 +++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/libse/Forms/TimeCodesBeautifier.cs b/src/libse/Forms/TimeCodesBeautifier.cs index 7f43a0bad..82d9519ff 100644 --- a/src/libse/Forms/TimeCodesBeautifier.cs +++ b/src/libse/Forms/TimeCodesBeautifier.cs @@ -525,11 +525,40 @@ namespace Nikse.SubtitleEdit.Core.Forms var fixedLeftOutCueFrame = GetFixedChainableSubtitlesLeftOutCueFrameInCueOnShot(bestLeftOutCueFrame, bestRightInCueFrame); if (fixedLeftOutCueFrame != null) { - newLeftOutCueFrame = fixedLeftOutCueFrame.Value; - newRightInCueFrame = bestRightInCueFrame; + // Check if there are any shot changes in between them + var firstShotChangeInBetween = GetFirstShotChangeFrameInBetween(bestLeftOutCueFrame, bestRightInCueFrame); + if (firstShotChangeInBetween != null) + { + // There are shot changes in between. Check behaviors + switch (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralShotChangeBehavior) + { + case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.DontChain: + // Don't do anything + return false; + case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.ExtendCrossingShotChange: + // Apply the chaining + newLeftOutCueFrame = fixedLeftOutCueFrame.Value; + newRightInCueFrame = bestRightInCueFrame; - // Make sure the newly connected subtitles get fixed - shouldFixConnectedSubtitles = true; + // Make sure the newly connected subtitles get fixed + shouldFixConnectedSubtitles = true; + break; + case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.ExtendUntilShotChange: + // Put the left out cue on the shot change, minus gap + newLeftOutCueFrame = firstShotChangeInBetween.Value - Configuration.Settings.BeautifyTimeCodes.Profile.OutCuesGap; + newRightInCueFrame = bestRightInCueFrame; + break; + } + } + else + { + // Apply the chaining + newLeftOutCueFrame = fixedLeftOutCueFrame.Value; + newRightInCueFrame = bestRightInCueFrame; + + // Make sure the newly connected subtitles get fixed + shouldFixConnectedSubtitles = true; + } } else { From 48b7c612b3d4ec6bca2971305eb2825f637ba8d8 Mon Sep 17 00:00:00 2001 From: "Martijn van Berkel (Flitskikker)" Date: Mon, 5 Feb 2024 20:36:02 +0100 Subject: [PATCH 2/7] Fix typo --- src/libse/Forms/TimeCodesBeautifier.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libse/Forms/TimeCodesBeautifier.cs b/src/libse/Forms/TimeCodesBeautifier.cs index 82d9519ff..cfb106fa3 100644 --- a/src/libse/Forms/TimeCodesBeautifier.cs +++ b/src/libse/Forms/TimeCodesBeautifier.cs @@ -760,7 +760,7 @@ namespace Nikse.SubtitleEdit.Core.Forms { var leftOutCueWithGreenZone = leftOutCueFrame + Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotRightGreenZone; var isInGreenZone = rightInCueFrame < leftOutCueWithGreenZone && rightInCueFrame > (leftOutCueFrame + Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotRightRedZone); - var isInRedZone = rightInCueFrame <= (leftOutCueFrame + Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralLeftRedZone) && rightInCueFrame >= leftOutCueFrame; + var isInRedZone = rightInCueFrame <= (leftOutCueFrame + Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotRightRedZone) && rightInCueFrame >= leftOutCueFrame; if (isInRedZone) { From 2270bf012b732d17fd4b352d39af3a4b58f88896 Mon Sep 17 00:00:00 2001 From: "Martijn van Berkel (Flitskikker)" Date: Mon, 5 Feb 2024 21:16:13 +0100 Subject: [PATCH 3/7] Ditto when only the left out-cue is on a shot change --- src/libse/Forms/TimeCodesBeautifier.cs | 37 +++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/libse/Forms/TimeCodesBeautifier.cs b/src/libse/Forms/TimeCodesBeautifier.cs index cfb106fa3..1c55cd6dc 100644 --- a/src/libse/Forms/TimeCodesBeautifier.cs +++ b/src/libse/Forms/TimeCodesBeautifier.cs @@ -573,11 +573,40 @@ namespace Nikse.SubtitleEdit.Core.Forms var fixedRightInCueFrame = GetFixedChainableSubtitlesRightInCueFrameOutCueOnShot(bestLeftOutCueFrame, bestRightInCueFrame); if (fixedRightInCueFrame != null) { - newLeftOutCueFrame = bestLeftOutCueFrame; - newRightInCueFrame = fixedRightInCueFrame.Value; + // Check if there are any shot changes in between them + var lastShotChangeInBetween = GetLastShotChangeFrameInBetween(bestLeftOutCueFrame, bestRightInCueFrame); + if (lastShotChangeInBetween != null) + { + // There are shot changes in between. Check behaviors + switch (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralShotChangeBehavior) + { + case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.DontChain: + // Don't do anything + return false; + case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.ExtendCrossingShotChange: + // Apply the chaining + newLeftOutCueFrame = bestLeftOutCueFrame; + newRightInCueFrame = fixedRightInCueFrame.Value; - // Make sure the newly connected subtitles get fixed - shouldFixConnectedSubtitles = true; + // Make sure the newly connected subtitles get fixed + shouldFixConnectedSubtitles = true; + break; + case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.ExtendUntilShotChange: + // Put the right in cue on the shot change, plus gap + newLeftOutCueFrame = bestLeftOutCueFrame; + newRightInCueFrame = lastShotChangeInBetween.Value + Configuration.Settings.BeautifyTimeCodes.Profile.OutCuesGap; + break; + } + } + else + { + // Apply the chaining + newLeftOutCueFrame = bestLeftOutCueFrame; + newRightInCueFrame = fixedRightInCueFrame.Value; + + // Make sure the newly connected subtitles get fixed + shouldFixConnectedSubtitles = true; + } } else { From 2502e5b3631886f7f9a8552564db2ee63e3cfbaf Mon Sep 17 00:00:00 2001 From: "Martijn van Berkel (Flitskikker)" Date: Mon, 5 Feb 2024 21:44:07 +0100 Subject: [PATCH 4/7] Fix another typo --- src/libse/Forms/TimeCodesBeautifier.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libse/Forms/TimeCodesBeautifier.cs b/src/libse/Forms/TimeCodesBeautifier.cs index 1c55cd6dc..ec2a1ea7c 100644 --- a/src/libse/Forms/TimeCodesBeautifier.cs +++ b/src/libse/Forms/TimeCodesBeautifier.cs @@ -568,7 +568,7 @@ namespace Nikse.SubtitleEdit.Core.Forms } else if (isLeftOutCueOnShotChange) { - // The left out cue in on a shot change + // The left out cue is on a shot change // Try to chain the subtitles var fixedRightInCueFrame = GetFixedChainableSubtitlesRightInCueFrameOutCueOnShot(bestLeftOutCueFrame, bestRightInCueFrame); if (fixedRightInCueFrame != null) From 7a641b0ef2d2c390326ff1656d05025992cbd81e Mon Sep 17 00:00:00 2001 From: "Martijn van Berkel (Flitskikker)" Date: Wed, 7 Feb 2024 21:48:38 +0100 Subject: [PATCH 5/7] Several Beautify timecodes improvements - Fix intermediate shot changes being ignored during chaining - By default, still enforce general chaining rules if unaffected by cue-specific rules - Prepare separate shot change behavior settings for cue-specific rules if ever needed - Show review dialog if some paragraphs were not fully chained --- src/libse/Common/Settings.cs | 64 ++++++-- src/libse/Forms/TimeCodesBeautifier.cs | 146 ++++++++++++++---- .../BeautifyTimeCodes/BeautifyTimeCodes.cs | 43 ++++++ .../BeautifyTimeCodesProfile.Designer.cs | 30 ++++ .../BeautifyTimeCodesProfile.cs | 18 ++- .../BeautifyTimeCodesProfileSimple.cs | 2 +- ...fyTimeCodesUnfixableParagraphs.Designer.cs | 119 ++++++++++++++ .../BeautifyTimeCodesUnfixableParagraphs.cs | 80 ++++++++++ .../BeautifyTimeCodesUnfixableParagraphs.resx | 126 +++++++++++++++ src/ui/Forms/Main.cs | 20 +++ src/ui/Logic/Language.cs | 9 ++ src/ui/Logic/LanguageStructure.cs | 7 + src/ui/SubtitleEdit.csproj | 9 ++ 13 files changed, 627 insertions(+), 46 deletions(-) create mode 100644 src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.Designer.cs create mode 100644 src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.cs create mode 100644 src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.resx diff --git a/src/libse/Common/Settings.cs b/src/libse/Common/Settings.cs index 9f4bf352d..9dc2c4009 100644 --- a/src/libse/Common/Settings.cs +++ b/src/libse/Common/Settings.cs @@ -2977,15 +2977,19 @@ $HorzAlign = Center public int ChainingGeneralMaxGap { get; set; } public int ChainingGeneralLeftGreenZone { get; set; } public int ChainingGeneralLeftRedZone { get; set; } - public ChainingGeneralShotChangeBehaviorEnum ChainingGeneralShotChangeBehavior { get; set; } + public ChainingShotChangeBehaviorEnum ChainingGeneralShotChangeBehavior { get; set; } public bool ChainingInCueOnShotUseZones { get; set; } public int ChainingInCueOnShotMaxGap { get; set; } public int ChainingInCueOnShotLeftGreenZone { get; set; } public int ChainingInCueOnShotLeftRedZone { get; set; } + public ChainingShotChangeBehaviorEnum ChainingInCueOnShotShotChangeBehavior { get; set; } + public bool ChainingInCueOnShotCheckGeneral { get; set; } public bool ChainingOutCueOnShotUseZones { get; set; } public int ChainingOutCueOnShotMaxGap { get; set; } public int ChainingOutCueOnShotRightRedZone { get; set; } public int ChainingOutCueOnShotRightGreenZone { get; set; } + public ChainingShotChangeBehaviorEnum ChainingOutCueOnShotShotChangeBehavior { get; set; } + public bool ChainingOutCueOnShotCheckGeneral { get; set; } public enum Preset : int { @@ -2994,7 +2998,7 @@ $HorzAlign = Center SDI = 2, } - public enum ChainingGeneralShotChangeBehaviorEnum : int + public enum ChainingShotChangeBehaviorEnum : int { DontChain = 0, ExtendCrossingShotChange = 1, @@ -3034,15 +3038,19 @@ $HorzAlign = Center ChainingGeneralMaxGap = 500; ChainingGeneralLeftGreenZone = 12; ChainingGeneralLeftRedZone = 11; - ChainingGeneralShotChangeBehavior = ChainingGeneralShotChangeBehaviorEnum.ExtendUntilShotChange; + ChainingGeneralShotChangeBehavior = ChainingShotChangeBehaviorEnum.ExtendUntilShotChange; ChainingInCueOnShotUseZones = false; ChainingInCueOnShotMaxGap = 500; ChainingInCueOnShotLeftGreenZone = 12; ChainingInCueOnShotLeftRedZone = 11; + ChainingInCueOnShotShotChangeBehavior = ChainingShotChangeBehaviorEnum.ExtendUntilShotChange; + ChainingInCueOnShotCheckGeneral = true; ChainingOutCueOnShotUseZones = false; ChainingOutCueOnShotMaxGap = 500; ChainingOutCueOnShotRightRedZone = 11; ChainingOutCueOnShotRightGreenZone = 12; + ChainingOutCueOnShotShotChangeBehavior = ChainingShotChangeBehaviorEnum.ExtendUntilShotChange; + ChainingOutCueOnShotCheckGeneral = true; break; case Preset.SDI: Gap = 4; @@ -3073,15 +3081,19 @@ $HorzAlign = Center ChainingGeneralMaxGap = 1000; ChainingGeneralLeftGreenZone = 25; ChainingGeneralLeftRedZone = 24; - ChainingGeneralShotChangeBehavior = ChainingGeneralShotChangeBehaviorEnum.ExtendCrossingShotChange; + ChainingGeneralShotChangeBehavior = ChainingShotChangeBehaviorEnum.ExtendCrossingShotChange; ChainingInCueOnShotUseZones = false; ChainingInCueOnShotMaxGap = 1000; ChainingInCueOnShotLeftGreenZone = 25; ChainingInCueOnShotLeftRedZone = 24; - ChainingOutCueOnShotUseZones = false; - ChainingOutCueOnShotMaxGap = 1000; - ChainingOutCueOnShotRightRedZone = 24; - ChainingOutCueOnShotRightGreenZone = 25; + ChainingInCueOnShotShotChangeBehavior = ChainingShotChangeBehaviorEnum.ExtendCrossingShotChange; + ChainingInCueOnShotCheckGeneral = true; + ChainingOutCueOnShotUseZones = true; + ChainingOutCueOnShotMaxGap = 500; + ChainingOutCueOnShotRightRedZone = 7; + ChainingOutCueOnShotRightGreenZone = 12; + ChainingOutCueOnShotShotChangeBehavior = ChainingShotChangeBehaviorEnum.ExtendCrossingShotChange; + ChainingOutCueOnShotCheckGeneral = true; break; default: Gap = 3; @@ -3112,15 +3124,19 @@ $HorzAlign = Center ChainingGeneralMaxGap = 1000; ChainingGeneralLeftGreenZone = 25; ChainingGeneralLeftRedZone = 24; - ChainingGeneralShotChangeBehavior = ChainingGeneralShotChangeBehaviorEnum.ExtendUntilShotChange; + ChainingGeneralShotChangeBehavior = ChainingShotChangeBehaviorEnum.ExtendUntilShotChange; ChainingInCueOnShotUseZones = false; ChainingInCueOnShotMaxGap = 1000; ChainingInCueOnShotLeftGreenZone = 25; ChainingInCueOnShotLeftRedZone = 24; + ChainingInCueOnShotShotChangeBehavior = ChainingShotChangeBehaviorEnum.ExtendUntilShotChange; + ChainingInCueOnShotCheckGeneral = true; ChainingOutCueOnShotUseZones = false; ChainingOutCueOnShotMaxGap = 500; ChainingOutCueOnShotRightRedZone = 11; ChainingOutCueOnShotRightGreenZone = 12; + ChainingOutCueOnShotShotChangeBehavior = ChainingShotChangeBehaviorEnum.ExtendUntilShotChange; + ChainingOutCueOnShotCheckGeneral = true; break; } } @@ -8930,7 +8946,7 @@ $HorzAlign = Center subNode = profileNode.SelectSingleNode("ChainingGeneralShotChangeBehavior"); if (subNode != null) { - settings.BeautifyTimeCodes.Profile.ChainingGeneralShotChangeBehavior = (BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum)Enum.Parse(typeof(BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum), subNode.InnerText); + settings.BeautifyTimeCodes.Profile.ChainingGeneralShotChangeBehavior = (BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum)Enum.Parse(typeof(BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum), subNode.InnerText); } subNode = profileNode.SelectSingleNode("ChainingInCueOnShotUseZones"); @@ -8957,6 +8973,18 @@ $HorzAlign = Center settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotLeftRedZone = Convert.ToInt32(subNode.InnerText, CultureInfo.InvariantCulture); } + subNode = profileNode.SelectSingleNode("ChainingInCueOnShotShotChangeBehavior"); + if (subNode != null) + { + settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotShotChangeBehavior = (BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum)Enum.Parse(typeof(BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum), subNode.InnerText); + } + + subNode = profileNode.SelectSingleNode("ChainingInCueOnShotCheckGeneral"); + if (subNode != null) + { + settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotCheckGeneral = Convert.ToBoolean(subNode.InnerText, CultureInfo.InvariantCulture); + } + subNode = profileNode.SelectSingleNode("ChainingOutCueOnShotUseZones"); if (subNode != null) { @@ -8980,6 +9008,18 @@ $HorzAlign = Center { settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotRightGreenZone = Convert.ToInt32(subNode.InnerText, CultureInfo.InvariantCulture); } + + subNode = profileNode.SelectSingleNode("ChainingOutCueOnShotShotChangeBehavior"); + if (subNode != null) + { + settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotShotChangeBehavior = (BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum)Enum.Parse(typeof(BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum), subNode.InnerText); + } + + subNode = profileNode.SelectSingleNode("ChainingOutCueOnShotCheckGeneral"); + if (subNode != null) + { + settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotCheckGeneral = Convert.ToBoolean(subNode.InnerText, CultureInfo.InvariantCulture); + } } } @@ -12389,10 +12429,14 @@ $HorzAlign = Center textWriter.WriteElementString("ChainingInCueOnShotMaxGap", settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotMaxGap.ToString(CultureInfo.InvariantCulture)); textWriter.WriteElementString("ChainingInCueOnShotLeftGreenZone", settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotLeftGreenZone.ToString(CultureInfo.InvariantCulture)); textWriter.WriteElementString("ChainingInCueOnShotLeftRedZone", settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotLeftRedZone.ToString(CultureInfo.InvariantCulture)); + textWriter.WriteElementString("ChainingInCueOnShotShotChangeBehavior", settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotShotChangeBehavior.ToString()); + textWriter.WriteElementString("ChainingInCueOnShotCheckGeneral", settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotCheckGeneral.ToString(CultureInfo.InvariantCulture)); textWriter.WriteElementString("ChainingOutCueOnShotUseZones", settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotUseZones.ToString(CultureInfo.InvariantCulture)); textWriter.WriteElementString("ChainingOutCueOnShotMaxGap", settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotMaxGap.ToString(CultureInfo.InvariantCulture)); textWriter.WriteElementString("ChainingOutCueOnShotRightRedZone", settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotRightRedZone.ToString(CultureInfo.InvariantCulture)); textWriter.WriteElementString("ChainingOutCueOnShotRightGreenZone", settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotRightGreenZone.ToString(CultureInfo.InvariantCulture)); + textWriter.WriteElementString("ChainingOutCueOnShotShotChangeBehavior", settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotShotChangeBehavior.ToString()); + textWriter.WriteElementString("ChainingOutCueOnShotCheckGeneral", settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotCheckGeneral.ToString(CultureInfo.InvariantCulture)); textWriter.WriteEndElement(); textWriter.WriteEndElement(); diff --git a/src/libse/Forms/TimeCodesBeautifier.cs b/src/libse/Forms/TimeCodesBeautifier.cs index ec2a1ea7c..6c6ff4cb5 100644 --- a/src/libse/Forms/TimeCodesBeautifier.cs +++ b/src/libse/Forms/TimeCodesBeautifier.cs @@ -518,6 +518,8 @@ namespace Nikse.SubtitleEdit.Core.Forms var isLeftOutCueOnShotChange = IsCueOnShotChange(bestLeftOutCueFrame, false); var isRightInCueOnShotChange = IsCueOnShotChange(bestRightInCueFrame, true); + var performGeneralChaining = false; + if (isRightInCueOnShotChange) { // The right in cue is on a shot change @@ -525,17 +527,16 @@ namespace Nikse.SubtitleEdit.Core.Forms var fixedLeftOutCueFrame = GetFixedChainableSubtitlesLeftOutCueFrameInCueOnShot(bestLeftOutCueFrame, bestRightInCueFrame); if (fixedLeftOutCueFrame != null) { - // Check if there are any shot changes in between them + // Check if there are any other shot changes *before* the shot change we want to chain towards var firstShotChangeInBetween = GetFirstShotChangeFrameInBetween(bestLeftOutCueFrame, bestRightInCueFrame); - if (firstShotChangeInBetween != null) - { - // There are shot changes in between. Check behaviors - switch (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralShotChangeBehavior) + if (firstShotChangeInBetween != null && !IsCueOnShotChange(bestRightInCueFrame, true, firstShotChangeInBetween.Value)) { + // There is another shot change in between. Check behaviors + switch (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotShotChangeBehavior) { - case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.DontChain: + case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum.DontChain: // Don't do anything return false; - case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.ExtendCrossingShotChange: + case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum.ExtendCrossingShotChange: // Apply the chaining newLeftOutCueFrame = fixedLeftOutCueFrame.Value; newRightInCueFrame = bestRightInCueFrame; @@ -543,7 +544,7 @@ namespace Nikse.SubtitleEdit.Core.Forms // Make sure the newly connected subtitles get fixed shouldFixConnectedSubtitles = true; break; - case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.ExtendUntilShotChange: + case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum.ExtendUntilShotChange: // Put the left out cue on the shot change, minus gap newLeftOutCueFrame = firstShotChangeInBetween.Value - Configuration.Settings.BeautifyTimeCodes.Profile.OutCuesGap; newRightInCueFrame = bestRightInCueFrame; @@ -552,7 +553,7 @@ namespace Nikse.SubtitleEdit.Core.Forms } else { - // Apply the chaining + // No shot changes in between, just apply the chaining newLeftOutCueFrame = fixedLeftOutCueFrame.Value; newRightInCueFrame = bestRightInCueFrame; @@ -563,7 +564,16 @@ namespace Nikse.SubtitleEdit.Core.Forms else { // Chaining wasn't needed - return false; + // If set, we will still check the general rules + if (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotCheckGeneral) + { + performGeneralChaining = true; + } + else + { + // Chaining wasn't needed + return false; + } } } else if (isLeftOutCueOnShotChange) @@ -573,17 +583,17 @@ namespace Nikse.SubtitleEdit.Core.Forms var fixedRightInCueFrame = GetFixedChainableSubtitlesRightInCueFrameOutCueOnShot(bestLeftOutCueFrame, bestRightInCueFrame); if (fixedRightInCueFrame != null) { - // Check if there are any shot changes in between them + // Check if there are any other shot changes *after* the shot change we want to chain towards var lastShotChangeInBetween = GetLastShotChangeFrameInBetween(bestLeftOutCueFrame, bestRightInCueFrame); - if (lastShotChangeInBetween != null) + if (lastShotChangeInBetween != null && !IsCueOnShotChange(bestLeftOutCueFrame, false, lastShotChangeInBetween.Value)) { - // There are shot changes in between. Check behaviors - switch (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralShotChangeBehavior) + // There is another shot change in between. Check behaviors + switch (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotShotChangeBehavior) { - case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.DontChain: + case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum.DontChain: // Don't do anything return false; - case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.ExtendCrossingShotChange: + case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum.ExtendCrossingShotChange: // Apply the chaining newLeftOutCueFrame = bestLeftOutCueFrame; newRightInCueFrame = fixedRightInCueFrame.Value; @@ -591,7 +601,7 @@ namespace Nikse.SubtitleEdit.Core.Forms // Make sure the newly connected subtitles get fixed shouldFixConnectedSubtitles = true; break; - case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.ExtendUntilShotChange: + case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum.ExtendUntilShotChange: // Put the right in cue on the shot change, plus gap newLeftOutCueFrame = bestLeftOutCueFrame; newRightInCueFrame = lastShotChangeInBetween.Value + Configuration.Settings.BeautifyTimeCodes.Profile.OutCuesGap; @@ -600,7 +610,7 @@ namespace Nikse.SubtitleEdit.Core.Forms } else { - // Apply the chaining + // No shot changes in between, just apply the chaining newLeftOutCueFrame = bestLeftOutCueFrame; newRightInCueFrame = fixedRightInCueFrame.Value; @@ -611,12 +621,27 @@ namespace Nikse.SubtitleEdit.Core.Forms else { // Chaining wasn't needed - return false; + // If set, we will still check the general rules + if (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotCheckGeneral) + { + performGeneralChaining = true; + } + else + { + // Chaining wasn't needed + return false; + } } } else { // The cues are not on shot changes + // So, perform general chaining + performGeneralChaining = true; + } + + if (performGeneralChaining) + { // Try to chain the subtitles already, maybe chaining is not needed var fixedLeftOutCueFrame = GetFixedChainableSubtitlesLeftOutCueFrameGeneral(bestLeftOutCueFrame, bestRightInCueFrame); if (fixedLeftOutCueFrame != null) @@ -628,18 +653,28 @@ namespace Nikse.SubtitleEdit.Core.Forms // There are shot changes in between. Check behaviors switch (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralShotChangeBehavior) { - case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.DontChain: + case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum.DontChain: // Don't do anything return false; - case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.ExtendCrossingShotChange: - // Apply the chaining - newLeftOutCueFrame = fixedLeftOutCueFrame.Value; - newRightInCueFrame = bestRightInCueFrame; + case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum.ExtendCrossingShotChange: + // Check if the right in cue was moved forward + if (bestRightInCueFrameInfo.result == FindBestCueResult.SnappedToRightGreenZone) + { + // Yes, then we'll want to use the original position instead: after chaining, the connected subtitles might partially end up in a red zone, + // leading to both being snapped to a shot change before (moving backward). Consequently, only the left out cue needs to be changed. + newLeftOutCueFrame = newRightInCueFrame - Configuration.Settings.BeautifyTimeCodes.Profile.Gap; + } + else + { + // Apply the chaining normally + newLeftOutCueFrame = fixedLeftOutCueFrame.Value; + newRightInCueFrame = bestRightInCueFrame; + } // Make sure the newly connected subtitles get fixed shouldFixConnectedSubtitles = true; break; - case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.ExtendUntilShotChange: + case BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum.ExtendUntilShotChange: // Put the left out cue on the shot change, minus gap newLeftOutCueFrame = firstShotChangeInBetween.Value - Configuration.Settings.BeautifyTimeCodes.Profile.OutCuesGap; newRightInCueFrame = bestRightInCueFrame; @@ -648,7 +683,7 @@ namespace Nikse.SubtitleEdit.Core.Forms } else { - // Apply the chaining + // No shot changes in between, just apply the chaining newLeftOutCueFrame = fixedLeftOutCueFrame.Value; newRightInCueFrame = bestRightInCueFrame; } @@ -1084,14 +1119,7 @@ namespace Nikse.SubtitleEdit.Core.Forms var closestShotChangeFrame = GetClosestShotChangeFrame(cueFrame); if (closestShotChangeFrame != null) { - if (isInCue) - { - return cueFrame >= closestShotChangeFrame.Value && cueFrame <= closestShotChangeFrame.Value + Configuration.Settings.BeautifyTimeCodes.Profile.InCuesGap; - } - else - { - return cueFrame <= closestShotChangeFrame.Value && cueFrame >= closestShotChangeFrame.Value - Configuration.Settings.BeautifyTimeCodes.Profile.OutCuesGap; - } + return IsCueOnShotChange(cueFrame, isInCue, closestShotChangeFrame.Value); } else { @@ -1099,6 +1127,18 @@ namespace Nikse.SubtitleEdit.Core.Forms } } + private bool IsCueOnShotChange(int cueFrame, bool isInCue, int shotChangeFrame) + { + if (isInCue) + { + return cueFrame >= shotChangeFrame && cueFrame <= shotChangeFrame + Configuration.Settings.BeautifyTimeCodes.Profile.InCuesGap; + } + else + { + return cueFrame <= shotChangeFrame && cueFrame >= shotChangeFrame - Configuration.Settings.BeautifyTimeCodes.Profile.OutCuesGap; + } + } + // Delegates @@ -1121,5 +1161,43 @@ namespace Nikse.SubtitleEdit.Core.Forms { return GetFrameDurationMs(frameRate) * Configuration.Settings.BeautifyTimeCodes.Profile.OutCuesGap; } + + public static int GetSmallestMaxGapFrames(double? frameRate = null) + { + var frameDurationMs = GetFrameDurationMs(frameRate); + int smallestMaxGapFrames = int.MaxValue; + + if (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralUseZones) + { + smallestMaxGapFrames = Math.Min(smallestMaxGapFrames, Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralLeftGreenZone); + } + else + { + var maxGap = Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralMaxGap / frameDurationMs; + smallestMaxGapFrames = Math.Min(smallestMaxGapFrames, Convert.ToInt32(Math.Round(maxGap))); + } + + if (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotUseZones) + { + smallestMaxGapFrames = Math.Min(smallestMaxGapFrames, Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotLeftGreenZone); + } + else + { + var maxGap = Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotMaxGap / frameDurationMs; + smallestMaxGapFrames = Math.Min(smallestMaxGapFrames, Convert.ToInt32(Math.Round(maxGap))); + } + + if (Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotUseZones) + { + smallestMaxGapFrames = Math.Min(smallestMaxGapFrames, Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotRightGreenZone); + } + else + { + var maxGap = Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotMaxGap / frameDurationMs; + smallestMaxGapFrames = Math.Min(smallestMaxGapFrames, Convert.ToInt32(Math.Round(maxGap))); + } + + return smallestMaxGapFrames; + } } } diff --git a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodes.cs b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodes.cs index 3489b51f2..e4ef5b351 100644 --- a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodes.cs +++ b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodes.cs @@ -1,11 +1,13 @@ using Nikse.SubtitleEdit.Core.Common; using Nikse.SubtitleEdit.Core.Forms; +using Nikse.SubtitleEdit.Core.SubtitleFormats; using Nikse.SubtitleEdit.Forms.ShotChanges; using Nikse.SubtitleEdit.Logic; using System; using System.Collections.Generic; using System.Drawing; using System.IO; +using System.Linq; using System.Windows.Forms; using MessageBox = Nikse.SubtitleEdit.Forms.SeMsgBox.MessageBox; @@ -25,6 +27,14 @@ namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes public List ShotChangesInSeconds = new List(); // For storing imported/generated shot changes that will be returned to the main form public Subtitle FixedSubtitle { get; private set; } + public List UnfixableParagraphs { get; private set; } + public struct UnfixableParagraphsPair + { + public Paragraph leftParagraph; + public Paragraph rightParagraph; + public int gapFrames; + } + private bool _abortTimeCodes; private TimeCodesGenerator _timeCodesGenerator; @@ -287,6 +297,9 @@ namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes }; timeCodesBeautifier.Beautify(); + // Check for any paragraphs that still have a gap smaller than the smallest max. gap + CheckUnfixableParagraphs(); + // Re-enable group boxes, otherwise child controls are also disabled, and we need their original state for the checks below groupBoxTimeCodes.Enabled = true; groupBoxShotChanges.Enabled = true; @@ -307,6 +320,36 @@ namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes DialogResult = DialogResult.OK; } + private void CheckUnfixableParagraphs() + { + var minGap = Configuration.Settings.BeautifyTimeCodes.Profile.Gap; + var minGapInCueClosest = Configuration.Settings.BeautifyTimeCodes.Profile.ConnectedSubtitlesInCueClosestLeftGap + Configuration.Settings.BeautifyTimeCodes.Profile.ConnectedSubtitlesInCueClosestRightGap; + var minGapOutCueClosest = Configuration.Settings.BeautifyTimeCodes.Profile.ConnectedSubtitlesOutCueClosestLeftGap + Configuration.Settings.BeautifyTimeCodes.Profile.ConnectedSubtitlesOutCueClosestRightGap; + var smallestMaxGapFrames = TimeCodesBeautifierUtils.GetSmallestMaxGapFrames(_frameRate); + + UnfixableParagraphs = new List(); + + for (var p = 0; p < FixedSubtitle.Paragraphs.Count - 2; p++) + { + var paragraph = FixedSubtitle.Paragraphs.ElementAtOrDefault(p); + var nextParagraph = FixedSubtitle.Paragraphs.ElementAtOrDefault(p + 1); + + if (paragraph != null && nextParagraph != null) + { + var gapFrames = SubtitleFormat.MillisecondsToFrames(nextParagraph.StartTime.TotalMilliseconds - paragraph.EndTime.TotalMilliseconds, _frameRate); + if (gapFrames < smallestMaxGapFrames && gapFrames != minGap && gapFrames != minGapInCueClosest && gapFrames != minGapOutCueClosest) + { + UnfixableParagraphs.Add(new UnfixableParagraphsPair() + { + leftParagraph = paragraph, + rightParagraph = nextParagraph, + gapFrames = gapFrames + }); + } + } + } + } + private void checkBoxAlignTimeCodes_CheckedChanged(object sender, EventArgs e) { RefreshControls(); diff --git a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesProfile.Designer.cs b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesProfile.Designer.cs index 657f04084..0c6b4fb98 100644 --- a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesProfile.Designer.cs +++ b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesProfile.Designer.cs @@ -104,6 +104,8 @@ namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes this.radioButtonChainingOutCueOnShotMaxGap = new System.Windows.Forms.RadioButton(); this.numericUpDownChainingOutCueOnShotMaxGap = new Nikse.SubtitleEdit.Controls.NikseUpDown(); this.buttonCreateSimple = new System.Windows.Forms.Button(); + this.checkBoxChainingInCueOnShotCheckGeneral = new System.Windows.Forms.CheckBox(); + this.checkBoxChainingOutCueOnShotCheckGeneral = new System.Windows.Forms.CheckBox(); this.menuStrip.SuspendLayout(); this.groupBoxGeneral.SuspendLayout(); this.groupBoxInCues.SuspendLayout(); @@ -1482,6 +1484,7 @@ namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes // // tabPageChainingInCueOnShot // + this.tabPageChainingInCueOnShot.Controls.Add(this.checkBoxChainingInCueOnShotCheckGeneral); this.tabPageChainingInCueOnShot.Controls.Add(this.labelChainingInCueOnShotMaxGapSuffix); this.tabPageChainingInCueOnShot.Controls.Add(this.radioButtonChainingInCueOnShotZones); this.tabPageChainingInCueOnShot.Controls.Add(this.radioButtonChainingInCueOnShotMaxGap); @@ -1646,6 +1649,7 @@ namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes // // tabPageChainingOutCueOnShot // + this.tabPageChainingOutCueOnShot.Controls.Add(this.checkBoxChainingOutCueOnShotCheckGeneral); this.tabPageChainingOutCueOnShot.Controls.Add(this.numericUpDownChainingOutCueOnShotRightGreenZone); this.tabPageChainingOutCueOnShot.Controls.Add(this.numericUpDownChainingOutCueOnShotRightRedZone); this.tabPageChainingOutCueOnShot.Controls.Add(this.labelChainingOutCueOnShotMaxGapSuffix); @@ -1816,6 +1820,30 @@ namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes this.buttonCreateSimple.UseVisualStyleBackColor = true; this.buttonCreateSimple.Click += new System.EventHandler(this.buttonCreateSimple_Click); // + // checkBoxChainingInCueOnShotCheckGeneral + // + this.checkBoxChainingInCueOnShotCheckGeneral.AutoSize = true; + this.checkBoxChainingInCueOnShotCheckGeneral.Checked = true; + this.checkBoxChainingInCueOnShotCheckGeneral.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxChainingInCueOnShotCheckGeneral.Location = new System.Drawing.Point(0, 78); + this.checkBoxChainingInCueOnShotCheckGeneral.Name = "checkBoxChainingInCueOnShotCheckGeneral"; + this.checkBoxChainingInCueOnShotCheckGeneral.Size = new System.Drawing.Size(251, 19); + this.checkBoxChainingInCueOnShotCheckGeneral.TabIndex = 16; + this.checkBoxChainingInCueOnShotCheckGeneral.Text = "Still enforce General rules when unaffected"; + this.checkBoxChainingInCueOnShotCheckGeneral.UseVisualStyleBackColor = true; + // + // checkBoxChainingOutCueOnShotCheckGeneral + // + this.checkBoxChainingOutCueOnShotCheckGeneral.AutoSize = true; + this.checkBoxChainingOutCueOnShotCheckGeneral.Checked = true; + this.checkBoxChainingOutCueOnShotCheckGeneral.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxChainingOutCueOnShotCheckGeneral.Location = new System.Drawing.Point(0, 78); + this.checkBoxChainingOutCueOnShotCheckGeneral.Name = "checkBoxChainingOutCueOnShotCheckGeneral"; + this.checkBoxChainingOutCueOnShotCheckGeneral.Size = new System.Drawing.Size(251, 19); + this.checkBoxChainingOutCueOnShotCheckGeneral.TabIndex = 26; + this.checkBoxChainingOutCueOnShotCheckGeneral.Text = "Still enforce General rules when unaffected"; + this.checkBoxChainingOutCueOnShotCheckGeneral.UseVisualStyleBackColor = true; + // // BeautifyTimeCodesProfile // this.AcceptButton = this.buttonOK; @@ -1950,5 +1978,7 @@ namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes private System.Windows.Forms.Label labelConnectedSubtitlesOutCueClosestGaps; private Controls.CuesPreviewView cuesPreviewViewConnectedSubtitlesOutCueClosest; private System.Windows.Forms.Button buttonCreateSimple; + private System.Windows.Forms.CheckBox checkBoxChainingInCueOnShotCheckGeneral; + private System.Windows.Forms.CheckBox checkBoxChainingOutCueOnShotCheckGeneral; } } \ No newline at end of file diff --git a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesProfile.cs b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesProfile.cs index b9ecc1383..3a0958ea4 100644 --- a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesProfile.cs +++ b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesProfile.cs @@ -64,10 +64,12 @@ namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes radioButtonChainingInCueOnShotMaxGap.Text = language.MaxGap; labelChainingInCueOnShotMaxGapSuffix.Text = language.Milliseconds; radioButtonChainingInCueOnShotZones.Text = language.Zones; + checkBoxChainingInCueOnShotCheckGeneral.Text = language.CheckGeneral; tabPageChainingOutCueOnShot.Text = language.OutCueOnShot; radioButtonChainingOutCueOnShotMaxGap.Text = language.MaxGap; labelChainingOutCueOnShotMaxGapSuffix.Text = language.Milliseconds; radioButtonChainingOutCueOnShotZones.Text = language.Zones; + checkBoxChainingOutCueOnShotCheckGeneral.Text = language.CheckGeneral; cuesPreviewViewInCues.PreviewText = language.SubtitlePreviewText; cuesPreviewViewOutCues.PreviewText = language.SubtitlePreviewText; @@ -155,12 +157,14 @@ namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes numericUpDownChainingInCueOnShotMaxGap.Value = settings.ChainingInCueOnShotMaxGap; numericUpDownChainingInCueOnShotLeftRedZone.Value = settings.ChainingInCueOnShotLeftRedZone; numericUpDownChainingInCueOnShotLeftGreenZone.Value = settings.ChainingInCueOnShotLeftGreenZone; + checkBoxChainingInCueOnShotCheckGeneral.Checked = settings.ChainingInCueOnShotCheckGeneral; radioButtonChainingOutCueOnShotZones.Checked = settings.ChainingOutCueOnShotUseZones; radioButtonChainingOutCueOnShotMaxGap.Checked = !settings.ChainingOutCueOnShotUseZones; numericUpDownChainingOutCueOnShotMaxGap.Value = settings.ChainingOutCueOnShotMaxGap; numericUpDownChainingOutCueOnShotRightRedZone.Value = settings.ChainingOutCueOnShotRightRedZone; numericUpDownChainingOutCueOnShotRightGreenZone.Value = settings.ChainingOutCueOnShotRightGreenZone; + checkBoxChainingOutCueOnShotCheckGeneral.Checked = settings.ChainingOutCueOnShotCheckGeneral; RefreshControls(); } @@ -233,6 +237,9 @@ namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes private void buttonOK_Click(object sender, EventArgs e) { + // Remember value for check later on + var previousGeneralShotChangeBehavior = Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralShotChangeBehavior; + // Save settings Configuration.Settings.BeautifyTimeCodes.Profile.Gap = Convert.ToInt32(numericUpDownGap.Value); @@ -262,17 +269,26 @@ namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralMaxGap = Convert.ToInt32(numericUpDownChainingGeneralMaxGap.Value); Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralLeftGreenZone = Convert.ToInt32(numericUpDownChainingGeneralLeftGreenZone.Value); Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralLeftRedZone = Convert.ToInt32(numericUpDownChainingGeneralLeftRedZone.Value); - Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralShotChangeBehavior = (BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum)comboBoxChainingGeneralShotChangeBehavior.SelectedIndex; + Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralShotChangeBehavior = (BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum)comboBoxChainingGeneralShotChangeBehavior.SelectedIndex; Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotUseZones = radioButtonChainingInCueOnShotZones.Checked; Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotMaxGap = Convert.ToInt32(numericUpDownChainingInCueOnShotMaxGap.Value); Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotLeftGreenZone = Convert.ToInt32(numericUpDownChainingInCueOnShotLeftGreenZone.Value); Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotLeftRedZone = Convert.ToInt32(numericUpDownChainingInCueOnShotLeftRedZone.Value); + Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotCheckGeneral = checkBoxChainingInCueOnShotCheckGeneral.Checked; Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotUseZones = radioButtonChainingOutCueOnShotZones.Checked; Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotMaxGap = Convert.ToInt32(numericUpDownChainingOutCueOnShotMaxGap.Value); Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotRightRedZone = Convert.ToInt32(numericUpDownChainingOutCueOnShotRightRedZone.Value); Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotRightGreenZone = Convert.ToInt32(numericUpDownChainingOutCueOnShotRightGreenZone.Value); + Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotCheckGeneral = checkBoxChainingOutCueOnShotCheckGeneral.Checked; + + // Update hidden shot change behavior settings if value for general bahavior has changed + if (previousGeneralShotChangeBehavior != Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralShotChangeBehavior) + { + Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotShotChangeBehavior = Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralShotChangeBehavior; + Configuration.Settings.BeautifyTimeCodes.Profile.ChainingOutCueOnShotShotChangeBehavior = Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralShotChangeBehavior; + } DialogResult = DialogResult.OK; } diff --git a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesProfileSimple.cs b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesProfileSimple.cs index e9284ffcd..95ec25c96 100644 --- a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesProfileSimple.cs +++ b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesProfileSimple.cs @@ -179,7 +179,7 @@ namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralMaxGap = Convert.ToInt32(numericUpDownChainingGap.Value); Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralLeftGreenZone = GetChainingZoneFrames(Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralMaxGap); Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralLeftRedZone = GetChainingZoneFrames(Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralMaxGap) - 1; - Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralShotChangeBehavior = BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingGeneralShotChangeBehaviorEnum.ExtendUntilShotChange; + Configuration.Settings.BeautifyTimeCodes.Profile.ChainingGeneralShotChangeBehavior = BeautifyTimeCodesSettings.BeautifyTimeCodesProfile.ChainingShotChangeBehaviorEnum.ExtendUntilShotChange; Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotUseZones = false; Configuration.Settings.BeautifyTimeCodes.Profile.ChainingInCueOnShotMaxGap = Convert.ToInt32(numericUpDownChainingGap.Value); diff --git a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.Designer.cs b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.Designer.cs new file mode 100644 index 000000000..a70a0e333 --- /dev/null +++ b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.Designer.cs @@ -0,0 +1,119 @@ +namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes +{ + partial class BeautifyTimeCodesUnfixableParagraphs + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BeautifyTimeCodesUnfixableParagraphs)); + this.buttonClose = new System.Windows.Forms.Button(); + this.labelInstructions = new System.Windows.Forms.Label(); + this.listView = new System.Windows.Forms.ListView(); + this.columnHeaderParagraphs = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderGap = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.SuspendLayout(); + // + // buttonClose + // + this.buttonClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonClose.DialogResult = System.Windows.Forms.DialogResult.OK; + this.buttonClose.Location = new System.Drawing.Point(404, 357); + this.buttonClose.Name = "buttonClose"; + this.buttonClose.Size = new System.Drawing.Size(75, 23); + this.buttonClose.TabIndex = 10; + this.buttonClose.Text = "Close"; + this.buttonClose.UseVisualStyleBackColor = true; + this.buttonClose.Click += new System.EventHandler(this.buttonClose_Click); + // + // labelInstructions + // + this.labelInstructions.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.labelInstructions.Location = new System.Drawing.Point(12, 9); + this.labelInstructions.Name = "labelInstructions"; + this.labelInstructions.Size = new System.Drawing.Size(467, 80); + this.labelInstructions.TabIndex = 1; + this.labelInstructions.Text = resources.GetString("labelInstructions.Text"); + // + // listView + // + this.listView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.listView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnHeaderParagraphs, + this.columnHeaderGap}); + this.listView.FullRowSelect = true; + this.listView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; + this.listView.HideSelection = false; + this.listView.Location = new System.Drawing.Point(13, 92); + this.listView.MultiSelect = false; + this.listView.Name = "listView"; + this.listView.Size = new System.Drawing.Size(465, 259); + this.listView.TabIndex = 2; + this.listView.UseCompatibleStateImageBehavior = false; + this.listView.View = System.Windows.Forms.View.Details; + this.listView.SelectedIndexChanged += new System.EventHandler(this.listView_SelectedIndexChanged); + // + // columnHeaderParagraphs + // + this.columnHeaderParagraphs.Width = 150; + // + // columnHeaderGap + // + this.columnHeaderGap.Width = 150; + // + // BeautifyTimeCodesUnfixableParagraphs + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(491, 392); + this.Controls.Add(this.listView); + this.Controls.Add(this.labelInstructions); + this.Controls.Add(this.buttonClose); + this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "BeautifyTimeCodesUnfixableParagraphs"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Check short gaps"; + this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.BeautifyTimeCodesUnfixableParagraphs_KeyDown); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button buttonClose; + private System.Windows.Forms.Label labelInstructions; + private System.Windows.Forms.ListView listView; + private System.Windows.Forms.ColumnHeader columnHeaderParagraphs; + private System.Windows.Forms.ColumnHeader columnHeaderGap; + } +} \ No newline at end of file diff --git a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.cs b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.cs new file mode 100644 index 000000000..68d9fa789 --- /dev/null +++ b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.cs @@ -0,0 +1,80 @@ +using Nikse.SubtitleEdit.Controls; +using Nikse.SubtitleEdit.Core.Common; +using Nikse.SubtitleEdit.Logic; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using static Nikse.SubtitleEdit.Forms.BeautifyTimeCodes.BeautifyTimeCodes; + +namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes +{ + public partial class BeautifyTimeCodesUnfixableParagraphs : Form + { + private readonly List _paragraphs; + private readonly Action _selectParagraphAction; + + public BeautifyTimeCodesUnfixableParagraphs(List paragraphs, Action selectParagraphAction) + { + _paragraphs = paragraphs; + _selectParagraphAction = selectParagraphAction; + + UiUtil.PreInitialize(this); + InitializeComponent(); + UiUtil.FixFonts(this); + + var language = LanguageSettings.Current.BeautifyTimeCodes; + Text = language.UnfixableParagraphsTitle; + labelInstructions.Text = language.UnfixableParagraphsInstructions; + columnHeaderParagraphs.Text = language.UnfixableParagraphsColumnParagraphs; + columnHeaderGap.Text = language.UnfixableParagraphsColumnGap; + + buttonClose.Text = LanguageSettings.Current.General.Close; + UiUtil.FixLargeFonts(this, buttonClose); + + PopulateListView(); + } + + private void PopulateListView() + { + listView.BeginUpdate(); + foreach (var pair in _paragraphs) + { + listView.Items.Add(new ListViewItem(new[] { + String.Format(LanguageSettings.Current.BeautifyTimeCodes.UnfixableParagraphsColumnParagraphsFormat, pair.leftParagraph.Number, pair.rightParagraph.Number), + pair.gapFrames.ToString() + })); + } + listView.EndUpdate(); + } + + private void BeautifyTimeCodesUnfixableParagraphs_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Escape) + { + this.Close(); + } + } + + private void buttonClose_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void listView_SelectedIndexChanged(object sender, EventArgs e) + { + if (listView.SelectedIndices.Count > 0) + { + var index = listView.SelectedIndices[0]; + var pair = _paragraphs[index]; + + _selectParagraphAction.Invoke(pair.rightParagraph); + } + } + } +} diff --git a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.resx b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.resx new file mode 100644 index 000000000..4d7e341ba --- /dev/null +++ b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Some subtitles were not fully chained in accordance with your profile, most likely due to too tightly clustered shot changes (possibly false positives). + +You might want to review these cases manually to ensure your cues are snapped to the correct (real) shot changes. + + + \ No newline at end of file diff --git a/src/ui/Forms/Main.cs b/src/ui/Forms/Main.cs index c579b04ad..b73caa138 100644 --- a/src/ui/Forms/Main.cs +++ b/src/ui/Forms/Main.cs @@ -119,6 +119,7 @@ namespace Nikse.SubtitleEdit.Forms private FindReplaceDialogHelper _findHelper; private FindDialog _findDialog; private ReplaceDialog _replaceDialog; + private Form _dialog; private bool _sourceViewChange; private int _changeSubtitleHash = -1; private int _changeOriginalSubtitleHash = -1; @@ -36032,6 +36033,8 @@ namespace Nikse.SubtitleEdit.Forms return; } + var unfixableParagraphs = new List(); + if (onlySelectedLines) { var selectedIndices = SubtitleListview1.GetSelectedIndices(); @@ -36078,6 +36081,8 @@ namespace Nikse.SubtitleEdit.Forms RestoreSubtitleListviewIndices(); ShowStatus(_language.BeautifiedTimeCodesSelectedLines); + + unfixableParagraphs = form.UnfixableParagraphs; } } } @@ -36110,9 +36115,24 @@ namespace Nikse.SubtitleEdit.Forms RestoreSubtitleListviewIndices(); ShowStatus(_language.BeautifiedTimeCodes); + + unfixableParagraphs = form.UnfixableParagraphs; } } } + + if (unfixableParagraphs.Count > 0) + { + BeginInvoke(new Action(() => { + _dialog?.Dispose(); + _dialog = new BeautifyTimeCodes.BeautifyTimeCodesUnfixableParagraphs(unfixableParagraphs, (paragraph) => + { + SubtitleListview1.SelectIndexAndEnsureVisible(paragraph); + GotoSubPositionAndPause(); + }); + _dialog.Show(this); + })); + } } private void ToolStripSplitButtonPlayRateClick(object sender, EventArgs e) diff --git a/src/ui/Logic/Language.cs b/src/ui/Logic/Language.cs index d04475542..ce347c591 100644 --- a/src/ui/Logic/Language.cs +++ b/src/ui/Logic/Language.cs @@ -146,6 +146,7 @@ namespace Nikse.SubtitleEdit.Logic Cancel = "C&ancel", Yes = "Yes", No = "No", + Close = "Close", Apply = "Apply", ApplyTo = "Apply to", None = "None", @@ -578,6 +579,13 @@ namespace Nikse.SubtitleEdit.Logic BatchAlignTimeCodes = "Align time codes to frame time codes", BatchUseExactTimeCodes = "Use exact time codes (if available)", BatchSnapToShotChanges = "Snap cues to shot changes (if available)", + UnfixableParagraphsTitle = "Review not fully chained subtitles", + UnfixableParagraphsInstructions = "Some subtitles were not fully chained in accordance with your profile, most likely due to too tightly clustered shot changes (possibly false positives)." + + Environment.NewLine + Environment.NewLine + + "You might want to review these cases manually to ensure your cues are snapped to the correct (real) shot changes.", + UnfixableParagraphsColumnParagraphs = "Lines", + UnfixableParagraphsColumnParagraphsFormat = "#{0} – #{1}", + UnfixableParagraphsColumnGap = "Gap (frames)" }; BeautifyTimeCodesProfile = new LanguageStructure.BeautifyTimeCodesProfile @@ -603,6 +611,7 @@ namespace Nikse.SubtitleEdit.Logic Chaining = "Chaining", InCueOnShot = "In cue on shot change", OutCueOnShot = "Out cue on shot change", + CheckGeneral = "Still enforce General rules when unaffected", MaxGap = "Max. gap:", ShotChangeBehavior = "If there is a shot change in between:", DontChain = "Don't chain", diff --git a/src/ui/Logic/LanguageStructure.cs b/src/ui/Logic/LanguageStructure.cs index 926acb2ba..81b220382 100644 --- a/src/ui/Logic/LanguageStructure.cs +++ b/src/ui/Logic/LanguageStructure.cs @@ -14,6 +14,7 @@ public string Cancel { get; set; } public string Yes { get; set; } public string No { get; set; } + public string Close { get; set; } public string Apply { get; set; } public string ApplyTo { get; set; } public string None { get; set; } @@ -422,6 +423,11 @@ public string BatchAlignTimeCodes { get; set; } public string BatchUseExactTimeCodes { get; set; } public string BatchSnapToShotChanges { get; set; } + public string UnfixableParagraphsTitle { get; set; } + public string UnfixableParagraphsInstructions { get; set; } + public string UnfixableParagraphsColumnParagraphs { get; set; } + public string UnfixableParagraphsColumnParagraphsFormat { get; set; } + public string UnfixableParagraphsColumnGap { get; set; } } public class BeautifyTimeCodesProfile @@ -447,6 +453,7 @@ public string Chaining { get; set; } public string InCueOnShot { get; set; } public string OutCueOnShot { get; set; } + public string CheckGeneral { get; set; } public string MaxGap { get; set; } public string ShotChangeBehavior { get; set; } public string DontChain { get; set; } diff --git a/src/ui/SubtitleEdit.csproj b/src/ui/SubtitleEdit.csproj index e37155f06..9206dd1d5 100644 --- a/src/ui/SubtitleEdit.csproj +++ b/src/ui/SubtitleEdit.csproj @@ -322,6 +322,12 @@ BeautifyTimeCodesProfileSimple.cs + + Form + + + BeautifyTimeCodesUnfixableParagraphs.cs + Form @@ -1732,6 +1738,9 @@ BeautifyTimeCodesProfileSimple.cs + + BeautifyTimeCodesUnfixableParagraphs.cs + BinEdit.cs From 384b75c0a51c574b53e506ee7c5d026023084ff9 Mon Sep 17 00:00:00 2001 From: "Martijn van Berkel (Flitskikker)" Date: Thu, 8 Feb 2024 16:10:48 +0100 Subject: [PATCH 6/7] Update dialog flags --- ...eautifyTimeCodesUnfixableParagraphs.Designer.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.Designer.cs b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.Designer.cs index a70a0e333..d28f220cd 100644 --- a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.Designer.cs +++ b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.Designer.cs @@ -40,7 +40,7 @@ // this.buttonClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.buttonClose.DialogResult = System.Windows.Forms.DialogResult.OK; - this.buttonClose.Location = new System.Drawing.Point(404, 357); + this.buttonClose.Location = new System.Drawing.Point(397, 356); this.buttonClose.Name = "buttonClose"; this.buttonClose.Size = new System.Drawing.Size(75, 23); this.buttonClose.TabIndex = 10; @@ -52,9 +52,10 @@ // this.labelInstructions.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this.labelInstructions.AutoEllipsis = true; this.labelInstructions.Location = new System.Drawing.Point(12, 9); this.labelInstructions.Name = "labelInstructions"; - this.labelInstructions.Size = new System.Drawing.Size(467, 80); + this.labelInstructions.Size = new System.Drawing.Size(460, 80); this.labelInstructions.TabIndex = 1; this.labelInstructions.Text = resources.GetString("labelInstructions.Text"); // @@ -72,7 +73,7 @@ this.listView.Location = new System.Drawing.Point(13, 92); this.listView.MultiSelect = false; this.listView.Name = "listView"; - this.listView.Size = new System.Drawing.Size(465, 259); + this.listView.Size = new System.Drawing.Size(458, 258); this.listView.TabIndex = 2; this.listView.UseCompatibleStateImageBehavior = false; this.listView.View = System.Windows.Forms.View.Details; @@ -90,19 +91,18 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(491, 392); + this.ClientSize = new System.Drawing.Size(484, 391); this.Controls.Add(this.listView); this.Controls.Add(this.labelInstructions); this.Controls.Add(this.buttonClose); this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.MaximizeBox = false; - this.MinimizeBox = false; + this.MinimumSize = new System.Drawing.Size(460, 250); this.Name = "BeautifyTimeCodesUnfixableParagraphs"; this.ShowIcon = false; - this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Check short gaps"; + this.Text = "Review not fully chained subtitles"; this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.BeautifyTimeCodesUnfixableParagraphs_KeyDown); this.ResumeLayout(false); From 535da8ebe09606677e5389db969d257028ef4e1b Mon Sep 17 00:00:00 2001 From: "Martijn van Berkel (Flitskikker)" Date: Wed, 14 Feb 2024 18:04:31 +0100 Subject: [PATCH 7/7] Add click handler, remove unused imports --- ...eautifyTimeCodesUnfixableParagraphs.Designer.cs | 1 + .../BeautifyTimeCodesUnfixableParagraphs.cs | 14 ++++++-------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.Designer.cs b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.Designer.cs index d28f220cd..3e408698e 100644 --- a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.Designer.cs +++ b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.Designer.cs @@ -78,6 +78,7 @@ this.listView.UseCompatibleStateImageBehavior = false; this.listView.View = System.Windows.Forms.View.Details; this.listView.SelectedIndexChanged += new System.EventHandler(this.listView_SelectedIndexChanged); + this.listView.Click += new System.EventHandler(this.listView_Click); // // columnHeaderParagraphs // diff --git a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.cs b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.cs index 68d9fa789..79d0d6d56 100644 --- a/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.cs +++ b/src/ui/Forms/BeautifyTimeCodes/BeautifyTimeCodesUnfixableParagraphs.cs @@ -1,14 +1,7 @@ -using Nikse.SubtitleEdit.Controls; -using Nikse.SubtitleEdit.Core.Common; +using Nikse.SubtitleEdit.Core.Common; using Nikse.SubtitleEdit.Logic; using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; using static Nikse.SubtitleEdit.Forms.BeautifyTimeCodes.BeautifyTimeCodes; @@ -76,5 +69,10 @@ namespace Nikse.SubtitleEdit.Forms.BeautifyTimeCodes _selectParagraphAction.Invoke(pair.rightParagraph); } } + + private void listView_Click(object sender, EventArgs e) + { + listView_SelectedIndexChanged(sender, e); + } } }