[gnome-subtitles] Added gconf option to set time between subtitles. Finished merge and split features (fixes bug #6519



commit 76d655a914bfed8312c788aa5aa1cbc26b2cd9f4
Author: Pedro Castro <mail pedrocastro org>
Date:   Sun Jun 12 23:29:36 2011 +0100

    Added gconf option to set time between subtitles.
    Finished merge and split features (fixes bug #651958).

 data/gnome-subtitles.schemas                       |   11 +++
 gnome-subtitles.mdp                                |    1 +
 .../Core/Command/MergeSubtitlesCommand.cs          |   87 ++++++++++++++++++++
 .../Core/Command/SplitSubtitlesCommand.cs          |   18 +++-
 src/GnomeSubtitles/Core/Config.cs                  |   21 ++++-
 src/GnomeSubtitles/Core/EventHandlers.cs           |    3 +-
 src/GnomeSubtitles/Ui/Menus.cs                     |   22 +++--
 src/GnomeSubtitles/Ui/WidgetNames.cs               |    2 +
 src/SubLib/Core/Timing/SplitOperator.cs            |   39 ++++++++-
 9 files changed, 184 insertions(+), 20 deletions(-)
---
diff --git a/data/gnome-subtitles.schemas b/data/gnome-subtitles.schemas
index 21028b3..7f7c97e 100644
--- a/data/gnome-subtitles.schemas
+++ b/data/gnome-subtitles.schemas
@@ -288,5 +288,16 @@
 				<long>Frames to add or subtract when adjusting frames in spinbutton controls (e.g., start, end and duration).</long>
 			</locale>
 		</schema>
+		<schema>
+			<key>/schemas/apps/gnome-subtitles/preferences/timings/time_between_subs</key>
+			<applyto>/apps/gnome-subtitles/preferences/timings/time_between_subs</applyto>
+			<owner>gnome-subtitles</owner>
+			<type>int</type>
+			<default>100</default>
+			<locale name="C">
+				<short>Time between subtitles</short>
+				<long>Recommended time between subtitles, in milliseconds, used for example when splitting a subtitle in two.</long>
+			</locale>
+		</schema>
 	</schemalist>
 </gconfschemafile>
diff --git a/gnome-subtitles.mdp b/gnome-subtitles.mdp
index c31a3b0..2aa6bcf 100644
--- a/gnome-subtitles.mdp
+++ b/gnome-subtitles.mdp
@@ -257,6 +257,7 @@
     <File subtype="Code" buildaction="Compile" name="src/GnomeSubtitles/Core/Command/SplitSubtitlesCommand.cs" />
     <File subtype="Code" buildaction="Compile" name="src/SubLib/Core/Timing/SplitOperator.cs" />
     <File subtype="Code" buildaction="Compile" name="src/SubLib/Core/Timing/MergeOperator.cs" />
+    <File subtype="Code" buildaction="Compile" name="src/GnomeSubtitles/Core/Command/MergeSubtitlesCommand.cs" />
   </Contents>
   <References>
     <ProjectReference type="Gac" localcopy="True" refto="Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
diff --git a/src/GnomeSubtitles/Core/Command/MergeSubtitlesCommand.cs b/src/GnomeSubtitles/Core/Command/MergeSubtitlesCommand.cs
new file mode 100644
index 0000000..d906e6a
--- /dev/null
+++ b/src/GnomeSubtitles/Core/Command/MergeSubtitlesCommand.cs
@@ -0,0 +1,87 @@
+/*
+ * This file is part of Gnome Subtitles.
+ * Copyright (C) 2011 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Gnome Subtitles is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+using GnomeSubtitles.Ui.View;
+using Gtk;
+using Mono.Unix;
+using SubLib.Core.Domain;
+using SubLib.Core.Timing;
+using System.Collections;
+
+namespace GnomeSubtitles.Core.Command {
+
+public class MergeSubtitlesCommand : MultipleSelectionCommand {
+	private static string description = Catalog.GetString("Merging subtitles");
+	private Subtitle[] subtitlesBefore = null;
+	private Subtitle subtitleAfter = null;
+	
+	public MergeSubtitlesCommand () : base(description, false, SelectionIntended.Range, null) {
+	}
+
+	public override bool Execute () {
+		GnomeSubtitles.Ui.View.Subtitles subtitles = Base.Document.Subtitles;
+		int firstPathInt = Util.PathToInt(this.FirstPath);
+		int lastPathInt = Util.PathToInt(this.LastPath);
+		
+		/* Store selected subtitles */
+		int subtitleCount = lastPathInt - firstPathInt + 1;
+		this.subtitlesBefore = new Subtitle[subtitleCount];
+		this.subtitlesBefore[0] = subtitles[firstPathInt].Clone(subtitles.Properties); //only the first needs to be cloned, the rest won't be changed
+		for (int index = 1, currentPath = firstPathInt + 1 ; index < subtitleCount ; index++, currentPath++) {
+			this.subtitlesBefore[index] = subtitles[currentPath];
+		}
+		
+		/* Merge subtitles */
+		MergeOperator mergeOperator = new MergeOperator(Base.Document.Subtitles);
+		if (!mergeOperator.Merge(firstPathInt, lastPathInt))
+			return false;
+		else {
+			TreePath secondPath = Util.IntToPath(firstPathInt + 1);
+			subtitles.RemoveRange(secondPath, this.LastPath);
+			Base.Ui.View.RedrawPath(this.FirstPath);
+			Base.Ui.View.Selection.Select(this.FirstPath, true, true);
+			PostProcess();
+			return true;
+		}
+	}
+	
+	public override void Undo () {
+		if (this.subtitleAfter == null) {
+			this.subtitleAfter = Base.Document.Subtitles[this.FirstPath];
+		}		
+		Base.Document.Subtitles.Remove(this.FirstPath);
+		Base.Ui.View.Insert(this.subtitlesBefore, this.FirstPath, this.FirstPath);
+		PostProcess();
+	}
+
+	public override void Redo () {
+		Base.Document.Subtitles.RemoveRange(this.FirstPath, this.LastPath);
+		Base.Ui.View.Insert(this.subtitleAfter, this.FirstPath);
+		PostProcess();
+	}
+	
+	/* Protected members */
+	
+	protected void PostProcess () {
+		Base.Ui.Video.SeekToSelection(true);
+	}
+
+}
+
+}
diff --git a/src/GnomeSubtitles/Core/Command/SplitSubtitlesCommand.cs b/src/GnomeSubtitles/Core/Command/SplitSubtitlesCommand.cs
index a9d5de9..31c5489 100644
--- a/src/GnomeSubtitles/Core/Command/SplitSubtitlesCommand.cs
+++ b/src/GnomeSubtitles/Core/Command/SplitSubtitlesCommand.cs
@@ -41,7 +41,7 @@ public class SplitSubtitlesCommand : MultipleSelectionCommand {
 		ArrayList subtitlesBefore = new ArrayList();
 		ArrayList pathsAfter = new ArrayList();
 		
-		SplitOperator splitOperator = new SplitOperator(subtitles, 100); //FIXME 100
+		SplitOperator splitOperator = new SplitOperator(subtitles, Base.Config.PrefsTimingsTimeBetweenSubtitles);
 		
 		foreach (TreePath path in Paths) {
 			int subtitleIndex = Util.PathToInt(path) + subtitlesBefore.Count; //need to account for subtitles already added in this loop
@@ -66,7 +66,9 @@ public class SplitSubtitlesCommand : MultipleSelectionCommand {
 			this.subtitlesBefore = (Subtitle[])subtitlesBefore.ToArray(typeof(Subtitle));
 			this.Paths = (TreePath[])pathsBefore.ToArray(typeof(TreePath));
 			this.pathsAfter = (TreePath[])pathsAfter.ToArray(typeof(TreePath));
-			Base.Ui.View.Selection.Select(this.pathsAfter, null, true);
+			Base.Ui.View.RedrawPaths(this.pathsAfter);
+			Base.Ui.View.Selection.Select(this.pathsAfter, this.pathsAfter[0], true);
+			PostProcess();
 			return true;
 		}
 	}
@@ -76,12 +78,20 @@ public class SplitSubtitlesCommand : MultipleSelectionCommand {
 			this.subtitlesAfter = GetSubtitlesAfter(Base.Document.Subtitles, this.pathsAfter);
 		}
 		Base.Document.Subtitles.Remove(this.pathsAfter);
-		Base.Ui.View.Insert(this.subtitlesBefore, this.Paths, null);
+		Base.Ui.View.Insert(this.subtitlesBefore, this.Paths, this.FirstPath);
+		PostProcess();
 	}
 
 	public override void Redo () {
 		Base.Document.Subtitles.Remove(this.Paths);
-		Base.Ui.View.Insert(this.subtitlesAfter, this.pathsAfter, null);
+		Base.Ui.View.Insert(this.subtitlesAfter, this.pathsAfter, this.pathsAfter[0]);
+		PostProcess();
+	}
+	
+	/* Protected members */
+	
+	protected void PostProcess () {
+		Base.Ui.Video.SeekToSelection(true);
 	}
 	
 	
diff --git a/src/GnomeSubtitles/Core/Config.cs b/src/GnomeSubtitles/Core/Config.cs
index 7d627a1..e941fbe 100644
--- a/src/GnomeSubtitles/Core/Config.cs
+++ b/src/GnomeSubtitles/Core/Config.cs
@@ -56,7 +56,7 @@ public class Config {
 	private const string keyPrefsVideoApplyReactionDelay = keyPrefsVideo + "apply_reaction_delay";
 	private const string keyPrefsVideoReactionDelay = keyPrefsVideo + "reaction_delay";
 	private const string keyPrefsVideoSeekOnChange = keyPrefsVideo + "seek_on_change"; //FIXME add option to the Preferences Dialog
-	private const string keyPrefsVideoSeekOnChangeRewind = keyPrefsVideo + "seek_on_change_rewind";
+	private const string keyPrefsVideoSeekOnChangeRewind = keyPrefsVideo + "seek_on_change_rewind"; //FIXME add option to the Preferences Dialog
 	private const string keyPrefsViewLineLengths = keyPrefsView + "line_lengths";
 	private const string keyPrefsSpellCheckActiveTextLanguage = keyPrefsSpellCheck + "active_text_language";
 	private const string keyPrefsSpellCheckActiveTranslationLanguage = keyPrefsSpellCheck + "active_translation_language";
@@ -75,7 +75,8 @@ public class Config {
 	private const string keyPrefsBackupAutoBackup = keyPrefsBackup + "auto_backup";
 	private const string keyPrefsBackupBackupTime = keyPrefsBackup + "backup_time";
 	private const string keyPrefsTimingsTimeStep = keyPrefsTimings + "time_step"; //FIXME add option to the Preferences Dialog
-	private const string keyPrefsTimingsFramesStep = keyPrefsTimings + "frames_step";
+	private const string keyPrefsTimingsFramesStep = keyPrefsTimings + "frames_step"; //FIXME add option to the Preferences Dialog
+	private const string keyPrefsTimingsTimeBetweenSubtitles = keyPrefsTimings + "time_between_subs"; //FIXME add option to the Preferences Dialog
 	
 	/* Cached values */
 	private bool isValuePrefsVideoApplyReactionDelayCached = false;
@@ -86,6 +87,7 @@ public class Config {
 	private int valuePrefsVideoSeekOnChangeRewind = -1;
 	private int valuePrefsTimingsTimeStep = -1;
 	private int valuePrefsTimingsFramesStep = -1;
+	private int valuePrefsTimingsTimeBetweenSubtitles = -1;
 	
 
 	public Config () {
@@ -165,7 +167,7 @@ public class Config {
 		}
 	}
 
-	//FIXME apply this to other changes
+	//FIXME use this in other commands
 	public int PrefsVideoSeekOnChangeRewind {
 		get {
 			if (this.valuePrefsVideoSeekOnChangeRewind == -1) {
@@ -305,6 +307,19 @@ public class Config {
 			this.valuePrefsTimingsFramesStep = value;
 		}
 	}
+	
+	public int PrefsTimingsTimeBetweenSubtitles {
+		get {
+			if (this.valuePrefsTimingsTimeBetweenSubtitles == -1) {
+				this.valuePrefsTimingsTimeBetweenSubtitles = GetInt(keyPrefsTimingsTimeBetweenSubtitles, 100, 0, true, 5000, true);
+			}
+			return this.valuePrefsTimingsTimeBetweenSubtitles;
+		}
+		set {
+			Set(keyPrefsTimingsTimeBetweenSubtitles, value);
+			this.valuePrefsTimingsTimeBetweenSubtitles = value;
+		}
+	}
 
 	
 	/* Private members */
diff --git a/src/GnomeSubtitles/Core/EventHandlers.cs b/src/GnomeSubtitles/Core/EventHandlers.cs
index c637905..9ec7ad3 100644
--- a/src/GnomeSubtitles/Core/EventHandlers.cs
+++ b/src/GnomeSubtitles/Core/EventHandlers.cs
@@ -136,12 +136,11 @@ public class EventHandlers {
 	}
 	
 	public void OnEditSplit (object o, EventArgs args) {
-		Console.WriteLine ("OnEditSplit");
 		Base.CommandManager.Execute(new SplitSubtitlesCommand());
 	}
 	
 	public void OnEditMerge (object o, EventArgs args) {
-		Console.WriteLine ("OnEditMerge");
+		Base.CommandManager.Execute(new MergeSubtitlesCommand());
 	}
 	
 	public void OnEditInsertSubtitleBefore (object o, EventArgs args) {
diff --git a/src/GnomeSubtitles/Ui/Menus.cs b/src/GnomeSubtitles/Ui/Menus.cs
index d06e8ef..dd69a07 100644
--- a/src/GnomeSubtitles/Ui/Menus.cs
+++ b/src/GnomeSubtitles/Ui/Menus.cs
@@ -130,10 +130,13 @@ public class Menus {
 	/* Private members */
 	
 	/// <summary>Sets the sensitivity depending on 1 or more selected subtitles.</summary>
+	/// <param name="selectionCount">The number of selected subtitles.</param>
 	/// <param name="sensitivity">Whether the items are set sensitive.</param>
-	private void SetNonZeroSelectionDependentSensitivity (bool sensitivity) {
+	private void SetNonZeroSelectionDependentSensitivity (int selectionCount, bool sensitivity) {
 		SetStylesSensitivity(sensitivity);
 		SetSensitivity(WidgetNames.EditDeleteSubtitles, sensitivity);
+		SetSensitivity(WidgetNames.EditSplit, sensitivity);
+		SetSensitivity(WidgetNames.EditMerge, selectionCount >= 2);
 		SetSensitivity(WidgetNames.DeleteSubtitlesButton, sensitivity);
 	}
 	
@@ -173,8 +176,8 @@ public class Menus {
 	}
 
 	private void SetDocumentSensitivity (bool documentLoaded) {
-		/* Set Sensitivity that is equal to the document loaded status */
-
+		/* Set Sensitivity that corresponds to the document loaded status */
+	
 		/* File Menu */
 		SetSensitivity(WidgetNames.FileSave, documentLoaded);
 		SetSensitivity(WidgetNames.FileSaveAs, documentLoaded);
@@ -203,7 +206,7 @@ public class Menus {
 		SetSensitivity(WidgetNames.SaveButton, documentLoaded);
 		SetSensitivity(WidgetNames.InsertSubtitleButton, documentLoaded);
 		
-		/* Set sensitivity that only applies when the document is not loaded */
+		/* Set sensitivity that's only applicable when the document is not loaded */
 		
 		if (!documentLoaded) {
 			/* Edit menu */
@@ -213,6 +216,8 @@ public class Menus {
 			SetSensitivity(WidgetNames.EditCut, false);
 			SetSensitivity(WidgetNames.EditCopy, false);
 			SetSensitivity(WidgetNames.EditPaste, false);
+			SetSensitivity(WidgetNames.EditSplit, false);
+			SetSensitivity(WidgetNames.EditMerge, false);
 			/* Search menu */
 			SetSensitivity(WidgetNames.SearchFindNext, false);
 			SetSensitivity(WidgetNames.SearchFindPrevious, false);
@@ -568,20 +573,21 @@ public class Menus {
 		if (subtitle != null) {
 			/* One subtitle selected */
 			SetStylesActivity(subtitle.Style.Bold, subtitle.Style.Italic, subtitle.Style.Underline);
-			SetNonZeroSelectionDependentSensitivity(true);
+			SetNonZeroSelectionDependentSensitivity(1, true);
 			SetOneSelectionDependentSensitivity(true);
 		}
 		else {
 			SetOneSelectionDependentSensitivity(false);
+			int selectionCount = paths.Length;
 	
-			if (paths.Length == 0) {
+			if (selectionCount == 0) {
 				/* No selection */
-				SetNonZeroSelectionDependentSensitivity(false);
+				SetNonZeroSelectionDependentSensitivity(selectionCount, false);
 				SetStylesActivity(false, false, false);
 			}
 			else {
 				/* Multiple paths selected */
-				SetNonZeroSelectionDependentSensitivity(true);
+				SetNonZeroSelectionDependentSensitivity(selectionCount, true);
 				bool bold, italic, underline;
 				GetGlobalStyles(paths, out bold, out italic, out underline);
 				SetStylesActivity(bold, italic, underline);	
diff --git a/src/GnomeSubtitles/Ui/WidgetNames.cs b/src/GnomeSubtitles/Ui/WidgetNames.cs
index 069b04d..c69a042 100644
--- a/src/GnomeSubtitles/Ui/WidgetNames.cs
+++ b/src/GnomeSubtitles/Ui/WidgetNames.cs
@@ -51,6 +51,8 @@ public class WidgetNames {
 	public const string EditInsertSubtitleMenu = "editInsertSubtitleMenu";
 	public const string EditInsertSubtitleAtVideoPosition = "editInsertSubtitleAtVideoPosition";
 	public const string EditDeleteSubtitles = "editDeleteSubtitles";
+	public const string EditSplit = "editSplit";
+	public const string EditMerge = "editMerge";
 	
 	/* View Menu */
 	public const string ViewTimes = "viewTimes";
diff --git a/src/SubLib/Core/Timing/SplitOperator.cs b/src/SubLib/Core/Timing/SplitOperator.cs
index c7c0e1f..7aa243a 100644
--- a/src/SubLib/Core/Timing/SplitOperator.cs
+++ b/src/SubLib/Core/Timing/SplitOperator.cs
@@ -70,15 +70,48 @@ public class SplitOperator {
 			subtitle2.Times.Start = TimeSpan.FromMilliseconds(subtitle2Start);
 		}
 		
-		/* Change text */
-		//FIXME divide text in half
-	
+		/* 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);
+		}
+		
+		/* 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);
+			}
+		}
+		
 		return subtitle2;
 	}
 	
 	private bool isOperationValid (Subtitle subtitle) {
 		return subtitle.Times.End >= subtitle.Times.Start;
 	}
+	
+	private void SplitArray<T> (T[] array, ref T[] half1, ref T[] half2) {
+		int arrayLength = array.Length;
+		int half1Length = arrayLength / 2;
+		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);
+	}
 }
 
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]