[gnome-subtitles: 1/6] #2 Split improvements Split improvements: split all lines (previously were split into 2 halves) and
- From: Pedro Castro <pcastro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-subtitles: 1/6] #2 Split improvements Split improvements: split all lines (previously were split into 2 halves) and
- Date: Tue, 14 May 2019 07:44:20 +0000 (UTC)
commit 5000ab00dd7aacc4735962f3575e3b63595bd649
Author: Pedro Castro <pedro gnomesubtitles org>
Date: Sat May 4 19:35:27 2019 +0100
#2 Split improvements
Split improvements: split all lines (previously
were split into 2 halves) and only split subtitles
with multiple lines
src/Glade/MainWindow.ui | 4 +-
.../Core/Command/SplitSubtitlesCommand.cs | 45 +++---
src/SubLib/Core/Domain/SubtitleText.cs | 3 +-
src/SubLib/Core/Timing/SplitOperator.cs | 172 ++++++++++++---------
4 files changed, 127 insertions(+), 97 deletions(-)
---
diff --git a/src/Glade/MainWindow.ui b/src/Glade/MainWindow.ui
index 4d4f662..e4ca82e 100644
--- a/src/Glade/MainWindow.ui
+++ b/src/Glade/MainWindow.ui
@@ -351,7 +351,7 @@
<object class="GtkMenuItem" id="editSplit">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label" translatable="yes">_Split</property>
+ <property name="label" translatable="yes">_Split Lines</property>
<property name="use_underline">True</property>
<signal name="activate" handler="OnEditSplit" swapped="no"/>
<accelerator key="m" signal="activate" modifiers="GDK_SHIFT_MASK |
GDK_CONTROL_MASK"/>
@@ -361,7 +361,7 @@
<object class="GtkMenuItem" id="editMerge">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label" translatable="yes">_Merge</property>
+ <property name="label" translatable="yes">_Merge Lines</property>
<property name="use_underline">True</property>
<signal name="activate" handler="OnEditMerge" swapped="no"/>
<accelerator key="m" signal="activate" modifiers="GDK_CONTROL_MASK"/>
diff --git a/src/GnomeSubtitles/Core/Command/SplitSubtitlesCommand.cs
b/src/GnomeSubtitles/Core/Command/SplitSubtitlesCommand.cs
index 5bde4dd..0ac685f 100644
--- a/src/GnomeSubtitles/Core/Command/SplitSubtitlesCommand.cs
+++ b/src/GnomeSubtitles/Core/Command/SplitSubtitlesCommand.cs
@@ -1,6 +1,6 @@
/*
* This file is part of Gnome Subtitles.
- * Copyright (C) 2017 Pedro Castro
+ * Copyright (C) 2017-2019 Pedro Castro
*
* Gnome Subtitles is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,7 +36,7 @@ public class SplitSubtitlesCommand : MultipleSelectionCommand {
}
public override bool Execute () {
- GnomeSubtitles.Ui.View.Subtitles subtitles = Base.Document.Subtitles;
+ Ui.View.Subtitles subtitles = Base.Document.Subtitles;
ArrayList pathsBefore = new ArrayList();
ArrayList subtitlesBefore = new ArrayList();
ArrayList pathsAfter = new ArrayList();
@@ -44,33 +44,34 @@ public class SplitSubtitlesCommand : MultipleSelectionCommand {
SplitOperator splitOperator = new SplitOperator(subtitles,
Base.Config.TimingsTimeBetweenSubtitles);
foreach (TreePath path in Paths) {
- int subtitleIndex = Util.PathToInt(path) + subtitlesBefore.Count; //need to account
for subtitles already added in this loop
+ int subtitlesThatHaveBeenAdded = pathsAfter.Count - pathsBefore.Count; //number of
subtitles that have been added ever since, in this loop
+ int subtitleIndex = Util.PathToInt(path) + subtitlesThatHaveBeenAdded;
Subtitle subtitle = subtitles[subtitleIndex];
- Subtitle subtitleClone = subtitle.Clone(subtitles.Properties);
- Subtitle subtitle2 = splitOperator.Split(subtitle);
- if (subtitle2 != null) {
- pathsAfter.Add(Util.IntToPath(subtitleIndex));
- pathsAfter.Add(Util.IntToPath(subtitleIndex + 1));
-
+
+ Subtitle[] newSubtitles = splitOperator.Split(subtitle);
+ if (newSubtitles != null) {
pathsBefore.Add(path);
- subtitlesBefore.Add(subtitleClone);
-
- subtitles.Add(subtitle2, subtitleIndex + 1);
+ subtitlesBefore.Add(subtitle);
+
+ subtitles.Remove(subtitleIndex);
+ for (int i = 0 ; i < newSubtitles.Length ; i++) {
+ pathsAfter.Add(Util.IntToPath(subtitleIndex + i));
+ subtitles.Add(newSubtitles[i], subtitleIndex + i);
+ }
}
}
- /* If any subtitle was changed, the command was successful */
- if (subtitlesBefore.Count == 0)
+ if (subtitlesBefore.Count == 0) {
return false;
- else {
- this.subtitlesBefore = (Subtitle[])subtitlesBefore.ToArray(typeof(Subtitle));
- this.Paths = (TreePath[])pathsBefore.ToArray(typeof(TreePath));
- this.pathsAfter = (TreePath[])pathsAfter.ToArray(typeof(TreePath));
- Base.Ui.View.RedrawPaths(this.pathsAfter);
- Base.Ui.View.Selection.Select(this.pathsAfter, this.pathsAfter[0], true);
- PostProcess();
- return true;
}
+
+ this.subtitlesBefore = (Subtitle [])subtitlesBefore.ToArray(typeof(Subtitle));
+ this.Paths = (TreePath [])pathsBefore.ToArray(typeof(TreePath));
+ this.pathsAfter = (TreePath [])pathsAfter.ToArray(typeof(TreePath));
+ Base.Ui.View.RedrawPaths(this.pathsAfter);
+ Base.Ui.View.Selection.Select(this.pathsAfter, this.pathsAfter [0], true);
+ PostProcess();
+ return true;
}
public override void Undo () {
diff --git a/src/SubLib/Core/Domain/SubtitleText.cs b/src/SubLib/Core/Domain/SubtitleText.cs
index 6000f31..812ab96 100644
--- a/src/SubLib/Core/Domain/SubtitleText.cs
+++ b/src/SubLib/Core/Domain/SubtitleText.cs
@@ -1,6 +1,6 @@
/*
* This file is part of SubLib.
- * Copyright (C) 2005-2011 Pedro Castro
+ * Copyright (C) 2005-2019 Pedro Castro
*
* SubLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,7 +19,6 @@
using System;
using System.Collections;
-using System.Text;
using System.Text.RegularExpressions;
namespace SubLib.Core.Domain {
diff --git a/src/SubLib/Core/Timing/SplitOperator.cs b/src/SubLib/Core/Timing/SplitOperator.cs
index be31573..d588924 100644
--- a/src/SubLib/Core/Timing/SplitOperator.cs
+++ b/src/SubLib/Core/Timing/SplitOperator.cs
@@ -1,6 +1,6 @@
/*
* This file is part of SubLib.
- * Copyright (C) 2011 Pedro Castro
+ * Copyright (C) 2011-2019 Pedro Castro
*
* SubLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
using SubLib.Core.Domain;
using System;
+using System.Collections;
namespace SubLib.Core.Timing {
@@ -34,101 +35,130 @@ public class SplitOperator {
/* Public members */
- public Subtitle Split (Subtitle subtitle) {
- if (!isOperationValid(subtitle))
+ public Subtitle[] Split (Subtitle subtitle) {
+ if (!IsOperationValid(subtitle))
return null;
- Subtitle subtitle2 = Split(subtitle, this.subtitles.Properties, this.timeBetweenSubtitles);
- return subtitle2;
+ return Split(subtitle, this.subtitles.Properties, this.timeBetweenSubtitles);
}
/* Private members */
- /// <summary>Splits a subtitle in two halves. The subtitle passed as parameter is turned into the
first half and the second half is returned.</summary>
+ /// <summary>Splits a single subtitle into multiple subtitles - one for each subtitle line.</summary>
/// <param name="subtitle">The subtitle to split</param>
/// <param name="subtitleProperties">The subtitle properties</param>
/// <param name="timeBetweenSubtitles">Time between the 2 subtitles, in milliseconds</param>
- private Subtitle Split (Subtitle subtitle, SubtitleProperties subtitleProperties, int
timeBetweenSubtitles) {
- Subtitle subtitle2 = subtitle.Clone(subtitleProperties);
+ private Subtitle[] Split (Subtitle subtitle, SubtitleProperties subtitleProperties, int
timeBetweenSubtitles) {
- /* Change timings */
+ //Get text lines
+ ArrayList textLines = GetTextLines(subtitle);
+ if (textLines == null) {
+ return null;
+ }
+
+ //Get translation lines
+ ArrayList translationLines = GetAlignedTranslationLines(subtitle, textLines);
+
+ //Prepare times. There must be at least
int originalStart = (int)subtitle.Times.Start.TotalMilliseconds;
int originalEnd = (int)subtitle.Times.End.TotalMilliseconds;
+ int originalDuration = originalEnd - originalStart;
+
+ int newDuration = CalculateSubtitleDuration(originalDuration, timeBetweenSubtitles,
textLines.Count);
+ if (newDuration < timeBetweenSubtitles) {
+ timeBetweenSubtitles = 0; //If each subtitle would have a duration shorter than
timeBetweenSubtitles itself, we don't use it
+ newDuration = CalculateSubtitleDuration(originalDuration, timeBetweenSubtitles,
textLines.Count);
+ }
+
+ /* Create a new Subtitle for each line by cloning the original one and setting appropriate
text and times.
+ * Note: textLines can have a single line (which means the other original lines were empty).
In this case,
+ * the subtitle will still be changed as a form of "cleanup" where the empty lines are
removed.
+ */
+ ArrayList result = new ArrayList();
+ for (int i = 0; i < textLines.Count; i++) {
+ Subtitle newSubtitle = subtitle.Clone(subtitleProperties);
+
+ //Set text
+ newSubtitle.Text.Set(textLines[i] as String);
+
+ //Set translation
+ if (subtitle.HasTranslation) {
+ if (i < translationLines.Count) {
+ newSubtitle.Translation.Set(translationLines[i] as String);
+ } else {
+ newSubtitle.Translation.Clear();
+ }
+ }
+
+ int start = originalStart + i * (newDuration + timeBetweenSubtitles);
+ newSubtitle.Times.Start = TimeSpan.FromMilliseconds(start);
+ newSubtitle.Times.End = TimeSpan.FromMilliseconds(start + newDuration);
- if ((originalEnd - originalStart) <= timeBetweenSubtitles) {
- /* Not possible to have the predefined time between subtitle, subtitle 2 will start
at subtitle's end time */
- int originalMiddle = (originalStart + originalEnd) / 2;
- TimeSpan newSubtitleEnd = TimeSpan.FromMilliseconds(originalMiddle);
- subtitle.Times.End = newSubtitleEnd;
- subtitle2.Times.Start = newSubtitleEnd;
+ result.Add(newSubtitle);
}
- else {
- int newSubtitleEnd = (originalStart + originalEnd - timeBetweenSubtitles) / 2;
- int subtitle2Start = newSubtitleEnd + timeBetweenSubtitles;
- subtitle.Times.End = TimeSpan.FromMilliseconds(newSubtitleEnd);
- subtitle2.Times.Start = TimeSpan.FromMilliseconds(subtitle2Start);
+
+ return (Subtitle[])result.ToArray(typeof(Subtitle));
+ }
+
+ private ArrayList GetTextLines (Subtitle subtitle) {
+ //Check if we have multiple text lines in this subtitle. If we don't, just return.
+ string[] originalLines = subtitle.Text.GetLines();
+ if ((originalLines == null) || (originalLines.Length <= 1)) {
+ return null;
}
- /* Change subtitle text */
- string[] textLines = subtitle.Text.GetLines();
- if (textLines.Length == 1)
- subtitle2.Text.Clear();
- else if (textLines.Length > 1) {
- string[] textLinesHalf1 = null;
- string[] textLinesHalf2 = null;
- SplitArray(textLines, ref textLinesHalf1, ref textLinesHalf2);
- subtitle.Text.Set(textLinesHalf1);
- subtitle2.Text.Set(textLinesHalf2);
+ //Remove empty or whitespace text lines.
+ ArrayList textLines = GetNonEmptyLines(originalLines);
+ if (textLines.Count == 0) {
+ return null;
}
+
+ return textLines;
+ }
- /* Change translation text */
- if (subtitle.HasTranslation) {
- string[] translationLines = subtitle.Translation.GetLines();
- if (translationLines.Length == 1)
- subtitle2.Translation.Clear();
- else if (translationLines.Length > 1) {
- string[] translationLinesHalf1 = null;
- string[] translationLinesHalf2 = null;
- SplitArray(translationLines, ref translationLinesHalf1, ref
translationLinesHalf2);
- subtitle.Translation.Set(translationLinesHalf1);
- subtitle2.Translation.Set(translationLinesHalf2);
- }
+ private ArrayList GetAlignedTranslationLines (Subtitle subtitle, ArrayList textLines) {
+ if (!subtitle.HasTranslation) {
+ return null;
+ }
+
+ string[] originalLines = subtitle.Translation.GetLines();
+ if (originalLines == null) {
+ return null;
}
- return subtitle2;
+ //Remove empty or whitespace text lines.
+ ArrayList translationLines = GetNonEmptyLines(originalLines);
+ if (translationLines.Count > textLines.Count) {
+ int lastTextIndex = textLines.Count - 1;
+ String lastLine = String.Join("\n",
(string[])translationLines.ToArray(typeof(string)), lastTextIndex, translationLines.Count - textLines.Count +
1);
+ translationLines[lastTextIndex] = lastLine;
+ translationLines.RemoveRange(lastTextIndex + 1, translationLines.Count -
textLines.Count);
+ }
+
+ return translationLines;
+ }
+
+ private ArrayList GetNonEmptyLines (string[] lines) {
+ ArrayList result = new ArrayList();
+
+ foreach (string line in lines) {
+ if (!String.IsNullOrWhiteSpace(line)) {
+ result.Add(line);
+ }
+ }
+
+ return result;
+ }
+
+ private int CalculateSubtitleDuration (int originalDuration, int timeBetweenSubtitles, int lineCount)
{
+ return (originalDuration - (timeBetweenSubtitles * (lineCount - 1))) / lineCount;
}
- private bool isOperationValid (Subtitle subtitle) {
+ private bool IsOperationValid (Subtitle subtitle) {
return subtitle.Times.End >= subtitle.Times.Start;
}
- private void SplitArray<T> (T[] array, ref T[] half1, ref T[] half2) {
- if (array == null) {
- half1 = null;
- half2 = null;
- return;
- }
-
- int arrayLength = array.Length;
- if (arrayLength == 0) {
- half1 = new T[0];
- half2 = new T[0];
- }
- else if (arrayLength == 1) {
- half1 = new T[1];
- half1[0] = array[0];
- half2 = new T[0];
- }
- else {
- int half1Length = (int)Math.Round(arrayLength / 2d);
- int half2Length = arrayLength - half1Length;
- half1 = new T[half1Length];
- half2 = new T[half2Length];
- Array.Copy(array, 0, half1, 0, half1Length);
- Array.Copy(array, half1Length, half2, 0, half2Length);
- }
- }
}
-}
+}
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]