[gnome-subtitles] Improved support for FAB Subtitler files



commit 1a5a36bfd71cc2da6b422081d19ff965682aa17b
Author: Pedro Castro <mail pedrocastro org>
Date:   Sun Nov 21 02:42:56 2010 +0000

    Improved support for FAB Subtitler files

 src/Glade/MainWindow.glade                         |   23 +++----
 src/GnomeSubtitles/Core/Document.cs                |    1 +
 src/GnomeSubtitles/Core/EventHandlers.cs           |    8 ---
 src/GnomeSubtitles/Ui/Menus.cs                     |   65 ++++++++++++++------
 src/SubLib/Core/Domain/SubtitleProperties.cs       |    2 +-
 src/SubLib/Core/SubtitleFactory.cs                 |   22 ++++---
 src/SubLib/Core/SubtitleSaver.cs                   |    3 +-
 src/SubLib/IO/Input/ParsingProperties.cs           |   10 ++--
 src/SubLib/IO/Input/SubtitleInput.cs               |    6 +-
 src/SubLib/IO/Input/SubtitleParser.cs              |    9 ++-
 src/SubLib/IO/Output/SubtitleOutput.cs             |    8 +++
 .../SubtitleFormatAdobeEncoreDVD.cs                |    2 +-
 .../SubtitleFormats/SubtitleFormatFABSubtitler.cs  |   23 +------
 13 files changed, 97 insertions(+), 85 deletions(-)
---
diff --git a/src/Glade/MainWindow.glade b/src/Glade/MainWindow.glade
index b62086c..639e5c5 100644
--- a/src/Glade/MainWindow.glade
+++ b/src/Glade/MainWindow.glade
@@ -248,8 +248,8 @@
                         <property name="use_underline">True</property>
                         <property name="use_stock">True</property>
                         <signal name="activate" handler="OnEditRedo"/>
-                        <accelerator key="Y" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                         <accelerator key="Z" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
+                        <accelerator key="Y" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                       </widget>
                     </child>
                     <child>
@@ -532,8 +532,8 @@
                         <property name="label" translatable="yes">Find Ne_xt</property>
                         <property name="use_underline">True</property>
                         <signal name="activate" handler="OnSearchFindNext"/>
-                        <accelerator key="F3" signal="activate"/>
                         <accelerator key="g" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+                        <accelerator key="F3" signal="activate"/>
                       </widget>
                     </child>
                     <child>
@@ -543,8 +543,8 @@
                         <property name="label" translatable="yes">Find Pre_vious</property>
                         <property name="use_underline">True</property>
                         <signal name="activate" handler="OnSearchFindPrevious"/>
-                        <accelerator key="F3" signal="activate" modifiers="GDK_SHIFT_MASK"/>
                         <accelerator key="g" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
+                        <accelerator key="F3" signal="activate" modifiers="GDK_SHIFT_MASK"/>
                       </widget>
                     </child>
                     <child>
@@ -651,7 +651,6 @@
                                 <property name="label">23.976</property>
                                 <property name="use_underline">True</property>
                                 <property name="draw_as_radio">True</property>
-                                <signal name="toggled" handler="OnTimingsVideoFrameRate"/>
                               </widget>
                             </child>
                             <child>
@@ -662,7 +661,6 @@
                                 <property name="use_underline">True</property>
                                 <property name="draw_as_radio">True</property>
                                 <property name="group">timingsVideoFrameRate23</property>
-                                <signal name="toggled" handler="OnTimingsVideoFrameRate"/>
                               </widget>
                             </child>
                             <child>
@@ -674,7 +672,6 @@
                                 <property name="active">True</property>
                                 <property name="draw_as_radio">True</property>
                                 <property name="group">timingsVideoFrameRate23</property>
-                                <signal name="toggled" handler="OnTimingsVideoFrameRate"/>
                               </widget>
                             </child>
                             <child>
@@ -685,7 +682,6 @@
                                 <property name="use_underline">True</property>
                                 <property name="draw_as_radio">True</property>
                                 <property name="group">timingsVideoFrameRate23</property>
-                                <signal name="toggled" handler="OnTimingsVideoFrameRate"/>
                               </widget>
                             </child>
                             <child>
@@ -696,7 +692,6 @@
                                 <property name="use_underline">True</property>
                                 <property name="draw_as_radio">True</property>
                                 <property name="group">timingsVideoFrameRate23</property>
-                                <signal name="toggled" handler="OnTimingsVideoFrameRate"/>
                               </widget>
                             </child>
                           </widget>
@@ -793,8 +788,8 @@
                         <property name="use_underline">True</property>
                         <property name="use_stock">False</property>
                         <signal name="activate" handler="OnVideoPlayPause"/>
-                        <accelerator key="F5" signal="activate"/>
                         <accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+                        <accelerator key="F5" signal="activate"/>
                         <child internal-child="image">
                           <widget class="GtkImage" id="videoPlayPauseImage">
                             <property name="visible">True</property>
@@ -821,8 +816,8 @@
                         <property name="use_underline">True</property>
                         <property name="use_stock">False</property>
                         <signal name="activate" handler="OnVideoRewind"/>
-                        <accelerator key="F6" signal="activate"/>
                         <accelerator key="k" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+                        <accelerator key="F6" signal="activate"/>
                         <child internal-child="image">
                           <widget class="GtkImage" id="videoRewindImage">
                             <property name="visible">True</property>
@@ -840,8 +835,8 @@
                         <property name="use_underline">True</property>
                         <property name="use_stock">False</property>
                         <signal name="activate" handler="OnVideoForward"/>
-                        <accelerator key="F7" signal="activate"/>
                         <accelerator key="l" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+                        <accelerator key="F7" signal="activate"/>
                         <child internal-child="image">
                           <widget class="GtkImage" id="videoForwardImage">
                             <property name="visible">True</property>
@@ -881,8 +876,8 @@
                         <property name="label" translatable="yes">Seek _to Selection</property>
                         <property name="use_underline">True</property>
                         <signal name="activate" handler="OnVideoSeekToSelection"/>
-                        <accelerator key="F4" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
                         <accelerator key="r" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
+                        <accelerator key="F4" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
                       </widget>
                     </child>
                     <child>
@@ -892,8 +887,8 @@
                         <property name="label" translatable="yes">Select Nearest Subtitle</property>
                         <property name="use_underline">True</property>
                         <signal name="activate" handler="OnVideoSelectNearestSubtitle"/>
-                        <accelerator key="r" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                         <accelerator key="F4" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+                        <accelerator key="r" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                       </widget>
                     </child>
                     <child>
@@ -902,8 +897,8 @@
                         <property name="label" translatable="yes">Auto Select Subtitle</property>
                         <property name="use_underline">True</property>
                         <signal name="toggled" handler="OnVideoAutoSelectSubtitles"/>
-                        <accelerator key="j" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                         <accelerator key="F3" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+                        <accelerator key="j" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                       </widget>
                     </child>
                     <child>
diff --git a/src/GnomeSubtitles/Core/Document.cs b/src/GnomeSubtitles/Core/Document.cs
index 47fcd55..4a49e03 100644
--- a/src/GnomeSubtitles/Core/Document.cs
+++ b/src/GnomeSubtitles/Core/Document.cs
@@ -169,6 +169,7 @@ public class Document {
 		factory.Verbose = true;
 		factory.Encoding = encoding;
 		factory.FallbackEncoding = GetFallbackEncoding();
+		factory.InputFrameRate = Base.Ui.Menus.TimingsInputFrameRateActive;
 
 		SubLib.Core.Domain.Subtitles openedSubtitles = null;
 		try {
diff --git a/src/GnomeSubtitles/Core/EventHandlers.cs b/src/GnomeSubtitles/Core/EventHandlers.cs
index 3da485f..30d5483 100644
--- a/src/GnomeSubtitles/Core/EventHandlers.cs
+++ b/src/GnomeSubtitles/Core/EventHandlers.cs
@@ -205,14 +205,6 @@ public class EventHandlers {
 
 	/*	Timings Menu */
 	
-	public void OnTimingsVideoFrameRate (object o, EventArgs args) {
-		RadioMenuItem menuItem = o as RadioMenuItem;
-		if (menuItem.Active) {
-			float frameRate = Menus.FrameRateFromMenuItem((menuItem.Child as Label).Text);
-			Base.CommandManager.Execute(new ChangeVideoFrameRateCommand(frameRate));
-		}
-	}
-	
 	public void OnTimingsAdjust (object o, EventArgs args) {
 		Base.Dialogs.Get(typeof(TimingsAdjustDialog)).Show();
 	}
diff --git a/src/GnomeSubtitles/Ui/Menus.cs b/src/GnomeSubtitles/Ui/Menus.cs
index e71d9e3..b865fa9 100644
--- a/src/GnomeSubtitles/Ui/Menus.cs
+++ b/src/GnomeSubtitles/Ui/Menus.cs
@@ -32,8 +32,6 @@ public class Menus {
 	/* Constant strings */
 	private string videoTagText = Catalog.GetString("Video");
 
-	/* Public methods */
-
 	public Menus () {
 		SetToolbarHomogeneity(); //TODO needed until homogeneity definition in glade starts working
 		SetDocumentSensitivity(false);
@@ -42,6 +40,24 @@ public class Menus {
 		Base.InitFinished += OnBaseInitFinished;
 	}
 	
+	
+	/* Public properties */
+	
+	public float TimingsInputFrameRateActive {
+		get {
+			Menu menu = Base.GetWidget(WidgetNames.TimingsInputFrameRateMenu) as Menu;
+			foreach (RadioMenuItem menuItem in menu.Children) {
+				if (menuItem.Active) {
+					return FrameRateFromMenuItem((menuItem.Child as Label).Text);
+				}
+			}
+			return -1;
+		}
+	}
+	
+	
+	/* Public methods */
+	
 	public void SetCutCopySensitivity (bool sensitivity) {
 		SetSensitivity(WidgetNames.EditCut, sensitivity);
 		SetSensitivity(WidgetNames.EditCopy, sensitivity);
@@ -62,9 +78,11 @@ public class Menus {
 			SetCheckMenuItemActivity(InputFrameRateMenuItem(inputFrameRate), true);
 	}
 	
+	/* Note: this method makes the assumption that the OnTimingsVideoFrameRateToggled event handler is connected to the
+	   menu item, as it is disconnected and then connected again after changing the active menu item. */
 	public void UpdateActiveVideoFrameRateMenuItem () {
 		float videoFrameRate = Base.Document.Subtitles.Properties.CurrentFrameRate;
-		SetCheckMenuItemActivity(VideoFrameRateMenuItem(videoFrameRate), true, Base.Handlers.OnTimingsVideoFrameRate);
+		SetCheckMenuItemActivity(VideoFrameRateMenuItem(videoFrameRate), true, OnTimingsVideoFrameRateToggled);
 	}
 	
 	public void EnableFindNextPrevious () {
@@ -102,14 +120,6 @@ public class Menus {
 	}
 
 	
-	/* Static members */
-	
-	static public float FrameRateFromMenuItem (string menuItem) {
-		string frameRateText = menuItem.Split(' ')[0];
-		NumberFormatInfo invariant = NumberFormatInfo.InvariantInfo;
-		return (float)Convert.ToDouble(frameRateText, invariant);
-	}
-
 	/* Private members */
 	
 	/// <summary>Sets the sensitivity depending on 1 or more selected subtitles.</summary>
@@ -226,9 +236,10 @@ public class Menus {
 			if (Base.TimingMode == TimingMode.Frames) {
 				UpdateActiveInputFrameRateMenuItem(false);
 				SetMenuSensitivity(WidgetNames.TimingsInputFrameRateMenu, true);
-				SetInputFrameRateMenuHandlers(true);
+				SetFrameRateMenuHandlers(Base.GetWidget(WidgetNames.TimingsInputFrameRateMenu) as Menu, true, OnTimingsInputFrameRateToggled);
 				
 				SetMenuSensitivity(WidgetNames.TimingsVideoFrameRateMenu, true);
+				SetFrameRateMenuHandlers(Base.GetWidget(WidgetNames.TimingsVideoFrameRateMenu) as Menu, true, OnTimingsVideoFrameRateToggled);
 				UpdateActiveVideoFrameRateMenuItem();
 			}
 			else {
@@ -236,12 +247,14 @@ public class Menus {
 				SetMenuSensitivity(WidgetNames.TimingsInputFrameRateMenu, false);
 
 				SetMenuSensitivity(WidgetNames.TimingsVideoFrameRateMenu, true);
+				SetFrameRateMenuHandlers(Base.GetWidget(WidgetNames.TimingsVideoFrameRateMenu) as Menu, true, OnTimingsVideoFrameRateToggled);
 				UpdateActiveVideoFrameRateMenuItem();
 			}
 		}
 		else {
-			SetInputFrameRateMenuHandlers(false);
+			SetFrameRateMenuHandlers(Base.GetWidget(WidgetNames.TimingsInputFrameRateMenu) as Menu, false, OnTimingsInputFrameRateToggled);
 			SetMenuSensitivity(WidgetNames.TimingsInputFrameRateMenu, true);
+			SetFrameRateMenuHandlers(Base.GetWidget(WidgetNames.TimingsVideoFrameRateMenu) as Menu, false, OnTimingsVideoFrameRateToggled);
 		}
 	}
 	
@@ -463,6 +476,13 @@ public class Menus {
     private void ClearTooltip (Widget widget) {
     	SetTooltip(widget, null);
     }
+    
+   	private float FrameRateFromMenuItem (string menuItem) {
+		string frameRateText = menuItem.Split(' ')[0];
+		NumberFormatInfo invariant = NumberFormatInfo.InvariantInfo;
+		return (float)Convert.ToDouble(frameRateText, invariant);
+	}
+	
 
 	/* Event members */
 	
@@ -581,18 +601,25 @@ public class Menus {
 	private void OnTimingsInputFrameRateToggled (object o, EventArgs args) {
 		RadioMenuItem menuItem = o as RadioMenuItem;
 		if (menuItem.Active) {
-			float frameRate = Menus.FrameRateFromMenuItem((menuItem.Child as Label).Text);
+			float frameRate = FrameRateFromMenuItem((menuItem.Child as Label).Text);
 			Base.CommandManager.Execute(new ChangeInputFrameRateCommand(frameRate));
 		}
 	}
+	
+	private void OnTimingsVideoFrameRateToggled (object o, EventArgs args) {
+		RadioMenuItem menuItem = o as RadioMenuItem;
+		if (menuItem.Active) {
+			float frameRate = FrameRateFromMenuItem((menuItem.Child as Label).Text);
+			Base.CommandManager.Execute(new ChangeVideoFrameRateCommand(frameRate));
+		}
+	}
 
-	private void SetInputFrameRateMenuHandlers (bool activate) {
-		Menu menu = Base.GetWidget(WidgetNames.TimingsInputFrameRateMenu) as Menu;
+	private void SetFrameRateMenuHandlers (Menu menu, bool enable, EventHandler handler) {
 		foreach (RadioMenuItem menuItem in menu.Children) {
-			if (activate)
-				menuItem.Toggled += OnTimingsInputFrameRateToggled;
+			if (enable)
+				menuItem.Toggled += handler;
 			else 
-				menuItem.Toggled -= OnTimingsInputFrameRateToggled;
+				menuItem.Toggled -= handler;
 		}
 	}
 
diff --git a/src/SubLib/Core/Domain/SubtitleProperties.cs b/src/SubLib/Core/Domain/SubtitleProperties.cs
index 7b91fe0..d63cf07 100644
--- a/src/SubLib/Core/Domain/SubtitleProperties.cs
+++ b/src/SubLib/Core/Domain/SubtitleProperties.cs
@@ -48,7 +48,7 @@ public class SubtitleProperties : ICloneable {
 	/// class, with defaults for all properties.</summary>
 	internal SubtitleProperties (ParsingProperties properties) {
 		headers = properties.Headers;
-		originalFrameRate = properties.OriginalFrameRate;
+		originalFrameRate = properties.InputFrameRate;
 	}
 	
 	
diff --git a/src/SubLib/Core/SubtitleFactory.cs b/src/SubLib/Core/SubtitleFactory.cs
index 3f74c33..0700db0 100644
--- a/src/SubLib/Core/SubtitleFactory.cs
+++ b/src/SubLib/Core/SubtitleFactory.cs
@@ -37,6 +37,7 @@ public class SubtitleFactory {
 	
 	private Encoding encoding = null; //The encoding to be used to open a file 
 	private Encoding fallbackEncoding = Encoding.GetEncoding(1252); //The encoding to fall back to when no encoding is detected
+	private float inputFrameRate = 25; //The frame rate to be used to open a frame-based file
 	
 	private SubtitleType subtitleType = SubtitleType.Unknown;
 	
@@ -89,6 +90,12 @@ public class SubtitleFactory {
 		set { subtitleType = value; }
 	}
 	
+	/// <summary>The frame rate of the subtitle being opened, for frame-based files.</summary>
+	public float InputFrameRate {
+		get { return inputFrameRate; }
+		set { inputFrameRate = value; }
+	}
+	
 	/// <summary>Creates new empty <see cref="Subtitles" />.</summary>
 	/// <returns>The newly created subtitles.</returns>
 	public Subtitles New () {
@@ -119,7 +126,7 @@ public class SubtitleFactory {
 		if (IsTextEmpty(text))
 			return EmptySubtitles(path);
 		else
-			return ParsedSubtitles(path, fileEncoding, format, text);
+			return ParsedSubtitles(path, fileEncoding, format, inputFrameRate, text);
 	}
 	
 	/// <summary>Creates <see cref="Subtitles" /> by opening the plain text file at the specified path.</summary>
@@ -148,10 +155,10 @@ public class SubtitleFactory {
 		
 	/* Private members */
 		
-	private Subtitles ParsedSubtitles (string path, Encoding fileEncoding, SubtitleFormat format, string text) {
+	private Subtitles ParsedSubtitles (string path, Encoding fileEncoding, SubtitleFormat format, float inputFrameRate, string text) {
 		SubtitleCollection collection = null;
 		SubtitleParser subtitleParser = new SubtitleParser(includeIncompleteSubtitles);
-		ParsingProperties parsingProperties = subtitleParser.Parse(text, format, out collection, out incompleteSubtitles);
+		ParsingProperties parsingProperties = subtitleParser.Parse(text, format, inputFrameRate, out collection, out incompleteSubtitles);
 		
 		SubtitleProperties subtitleProperties = new SubtitleProperties(parsingProperties);
 		collection.SetPropertiesForAll(subtitleProperties);
@@ -159,14 +166,13 @@ public class SubtitleFactory {
 		Subtitles subtitles = new Subtitles(collection, subtitleProperties);
 		CompleteTimingsAfterParsing(subtitles, parsingProperties);
 		
-		fileProperties = new FileProperties(path, fileEncoding, format.Type , parsingProperties.TimingMode);
+		fileProperties = new FileProperties(path, fileEncoding, format.Type, parsingProperties.TimingMode);
 
-		VerboseConsole.WriteLine("[*] opened " + path + " with encoding " + fileEncoding + " and format " + format.Name);
+		VerboseConsole.WriteLine("[*] Opened \"" + path + "\" with encoding \"" + fileEncoding + "\", format \"" + format.Name + "\", timing mode \"" + parsingProperties.TimingMode + "\" and frame rate \"" + subtitleProperties.CurrentFrameRate + "\" (input frame rate was \"" + inputFrameRate + "\")");
 		return subtitles;
 	}
 	
-	private Subtitles ParsedSubtitlesPlain (string path, Encoding fileEncoding, string text, bool withCharacterNames,
-		                                        TimingMode timingMode, string lineSeparator) {
+	private Subtitles ParsedSubtitlesPlain (string path, Encoding fileEncoding, string text, bool withCharacterNames, TimingMode timingMode, string lineSeparator) {
 		SubtitleCollection collection = null;
 		PlainTextParser plainParser = new PlainTextParser(withCharacterNames, lineSeparator);
 		ParsingProperties parsingProperties = plainParser.Parse(text, timingMode, fileEncoding, out collection);
@@ -179,7 +185,7 @@ public class SubtitleFactory {
 		
 		fileProperties = new FileProperties(path, fileEncoding, parsingProperties.TimingMode);
 		
-		VerboseConsole.WriteLine("[*] opened " + path + " with encoding " + fileEncoding);
+		VerboseConsole.WriteLine("[*] Opened " + path + " with encoding " + fileEncoding);
 		return subtitles;
 	}
 		
diff --git a/src/SubLib/Core/SubtitleSaver.cs b/src/SubLib/Core/SubtitleSaver.cs
index c9a6531..24b3371 100644
--- a/src/SubLib/Core/SubtitleSaver.cs
+++ b/src/SubLib/Core/SubtitleSaver.cs
@@ -52,10 +52,9 @@ public class SubtitleSaver {
 
 		string text = output.Build(subtitles.Collection, subtitles.Properties, properties);
 		FileInputOutput.WriteFile(properties.Path, text, properties.Encoding);
-
 		
 		fileProperties = GetUpdatedFileProperties(properties); 
-		VerboseConsole.WriteLine("[*] Saved " + textType + " " + properties.Path + " with encoding " + properties.Encoding + " and format " + format.Name);
+		VerboseConsole.WriteLine("[*] Saved " + textType + " \"" + properties.Path + "\" with encoding \"" + properties.Encoding + "\", format \"" + format.Name + "\" and frame rate \"" + subtitles.Properties.CurrentFrameRate + "\"");
 	}
 	
 	/* Private methods */
diff --git a/src/SubLib/IO/Input/ParsingProperties.cs b/src/SubLib/IO/Input/ParsingProperties.cs
index 1f14c1c..e2a0e55 100644
--- a/src/SubLib/IO/Input/ParsingProperties.cs
+++ b/src/SubLib/IO/Input/ParsingProperties.cs
@@ -1,6 +1,6 @@
 /*
  * This file is part of SubLib.
- * Copyright (C) 2007-2008 Pedro Castro
+ * Copyright (C) 2007-2010 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
@@ -24,7 +24,7 @@ namespace SubLib.IO.Input {
 internal class ParsingProperties {
 	private Headers headers = new Headers();
 	private TimingMode timingMode = TimingMode.Times;
-	private float originalFrameRate = 25;
+	private float inputFrameRate = 25;
 	
 	public Headers Headers {
 		get { return headers; }
@@ -35,9 +35,9 @@ internal class ParsingProperties {
 		set { timingMode = value; }
 	}
 	
-	public float OriginalFrameRate {
-		get { return originalFrameRate; }
-		set { originalFrameRate = value; }
+	public float InputFrameRate {
+		get { return inputFrameRate; }
+		set { inputFrameRate = value; }
 	}
 
 }
diff --git a/src/SubLib/IO/Input/SubtitleInput.cs b/src/SubLib/IO/Input/SubtitleInput.cs
index f60f863..f654144 100644
--- a/src/SubLib/IO/Input/SubtitleInput.cs
+++ b/src/SubLib/IO/Input/SubtitleInput.cs
@@ -91,7 +91,7 @@ internal class SubtitleInput {
 		
 		/* Check if no codepage was detected */
 		if (codePages.Length == 0) {
-			VerboseConsole.WriteLine("No encoding was automatically detected. Using the fall-back encoding: " + fallbackEncoding.WebName);
+			VerboseConsole.WriteLine("No encoding was automatically detected. Using the fall-back encoding \"" + fallbackEncoding.WebName + "\"");
 			string text;
 			if (isSubtitleFile)
 				text = TestEncoding(fileStream, fallbackEncoding, out usedFormat);
@@ -183,7 +183,7 @@ internal class SubtitleInput {
 	}
 		
 	private string TestEncoding (FileStream fileStream, Encoding encoding) {
-		VerboseConsole.WriteLine("Trying the encoding " + encoding.WebName);
+		VerboseConsole.WriteLine("Trying the encoding \"" + encoding.WebName + "\"");
 		/* Get the text */
 		string text = FileInputOutput.ReadFile(fileStream, encoding, true);
 		
@@ -195,7 +195,7 @@ internal class SubtitleInput {
 		if (subtitleType == SubtitleType.Unknown)
 			VerboseConsole.WriteLine("Trying to autodetect the subtitle format.");
 		else
-			VerboseConsole.WriteLine("Trying the subtitle format " + subtitleType);
+			VerboseConsole.WriteLine("Trying the subtitle format \"" + subtitleType + "\"");
 
 		SubtitleFormat subtitleFormat = null;
 		if (subtitleType == SubtitleType.Unknown)
diff --git a/src/SubLib/IO/Input/SubtitleParser.cs b/src/SubLib/IO/Input/SubtitleParser.cs
index 79c5e25..ef8adfe 100644
--- a/src/SubLib/IO/Input/SubtitleParser.cs
+++ b/src/SubLib/IO/Input/SubtitleParser.cs
@@ -50,12 +50,13 @@ internal class SubtitleParser {
 	/// <summary>Parses the specified text, using the specified format.</summary>
 	/// <remarks>The created <see cref="SubtitleCollection" /> will have its <see cref="SubtitleProperties" /> property set to null.
 	/// It is mandatory to use <see cref="SubtitleCollection.SetPropertiesForAll" /> after.</remarks>
-	internal ParsingProperties Parse (string text, SubtitleFormat format, 
+	internal ParsingProperties Parse (string text, SubtitleFormat format, float inputFrameRate,
 			out SubtitleCollection collection, out IncompleteSubtitleCollection incompleteSubtitles){
 		
 		collection = new SubtitleCollection();
 		incompleteSubtitles = new IncompleteSubtitleCollection();
 		ParsingProperties properties = new ParsingProperties();
+		properties.InputFrameRate = inputFrameRate;
 
 		Regex subtitleRegex = null;
 		int bodyIndex = 0;
@@ -260,7 +261,7 @@ internal class SubtitleParser {
 		//Used to detect if a subtitles' timing mode is Frames in the case of a format that supports both
 		else if (ParseGroup(match, "TimingModeFrames", ref floatResult)) {
 			properties.TimingMode = TimingMode.Frames;
-			properties.OriginalFrameRate = floatResult;
+			properties.InputFrameRate = floatResult;
 		}
 		else {
 			return false;
@@ -379,7 +380,7 @@ internal class SubtitleParser {
 			isTimeDefined = true;
 		}
 		if (ParseGroup(match, "StartMillisecondsAsFrames", ref result)) {
-			startTime += TimingUtil.FramesToTime(result, properties.OriginalFrameRate);
+			startTime += TimingUtil.FramesToTime(result, properties.InputFrameRate);
 			isTimeDefined = true;
 		}
 		
@@ -425,7 +426,7 @@ internal class SubtitleParser {
 			isTimeDefined = true;
 		}
 		if (ParseGroup(match, "EndMillisecondsAsFrames", ref result)) {
-			endTime += TimingUtil.FramesToTime(result, properties.OriginalFrameRate);
+			endTime += TimingUtil.FramesToTime(result, properties.InputFrameRate);
 			isTimeDefined = true;
 		}
 		if (ParseGroup(match, "EndElapsedTime", ref floatResult)) {
diff --git a/src/SubLib/IO/Output/SubtitleOutput.cs b/src/SubLib/IO/Output/SubtitleOutput.cs
index 843b83e..28b1678 100644
--- a/src/SubLib/IO/Output/SubtitleOutput.cs
+++ b/src/SubLib/IO/Output/SubtitleOutput.cs
@@ -32,6 +32,7 @@ internal class SubtitleOutput {
 	private SubtitleFormat format = null;
 	private SubtitleTextType textType = SubtitleTextType.Text;
 	
+	private SubtitleProperties subtitleProperties = null;
 	private Subtitle subtitle = null;
 	private Subtitle previousSubtitle = null;
 	private int subtitleNumber = 1;
@@ -42,6 +43,7 @@ internal class SubtitleOutput {
 	}
 
 	internal string Build (SubtitleCollection collection, SubtitleProperties subtitleProperties, FileProperties fileProperties) {
+		this.subtitleProperties = subtitleProperties;
 		StringBuilder output = new StringBuilder();
 		if (format.HasHeaders)
 			output.Append(format.HeadersToString(subtitleProperties, fileProperties));
@@ -115,12 +117,18 @@ internal class SubtitleOutput {
 			case "StartMilliseconds":
 				int startMilliseconds = subtitle.Times.Start.Milliseconds;
 				return FormatedField(startMilliseconds, 3, match);
+			case "StartMillisecondsAsFrames":
+				int startMillisecondsAsFrames = (int)TimingUtil.TimeMillisecondsToFrames(subtitle.Times.Start.Milliseconds, this.subtitleProperties.CurrentFrameRate);
+				return FormatedField(startMillisecondsAsFrames, 2, match);
 			case "StartMillisecondsAsFramesPAL":
 				int startMillisecondsAsFramesPAL = (int)TimingUtil.TimeMillisecondsToFrames(subtitle.Times.Start.Milliseconds, 25);
 				return FormatedField(startMillisecondsAsFramesPAL, 2, match);
 			case "StartMillisecondsAsFramesNTSC":
 				int startMillisecondsAsFramesNTSC = (int)TimingUtil.TimeMillisecondsToFrames(subtitle.Times.Start.Milliseconds, 29.97F);
 				return FormatedField(startMillisecondsAsFramesNTSC, 2, match);
+			case "EndMillisecondsAsFrames":
+				int endMillisecondsAsFrames = (int)TimingUtil.TimeMillisecondsToFrames(subtitle.Times.End.Milliseconds, this.subtitleProperties.CurrentFrameRate);
+				return FormatedField(endMillisecondsAsFrames, 2, match);
 			case "EndMillisecondsAsFramesPAL":
 				int endMillisecondsAsFramesPAL = (int)TimingUtil.TimeMillisecondsToFrames(subtitle.Times.End.Milliseconds, 25);
 				return FormatedField(endMillisecondsAsFramesPAL, 2, match);
diff --git a/src/SubLib/IO/SubtitleFormats/SubtitleFormatAdobeEncoreDVD.cs b/src/SubLib/IO/SubtitleFormats/SubtitleFormatAdobeEncoreDVD.cs
index ffd8856..4f94d7a 100644
--- a/src/SubLib/IO/SubtitleFormats/SubtitleFormatAdobeEncoreDVD.cs
+++ b/src/SubLib/IO/SubtitleFormats/SubtitleFormatAdobeEncoreDVD.cs
@@ -51,7 +51,7 @@ internal class SubtitleFormatAdobeEncoreDVD : SubtitleFormat {
 	internal override void GlobalInputGetProperties (string text, ParsingProperties properties) {
 		bool isFrameRatePAL = inputRegexPAL.Match(text).Success;
 		float frameRate = (isFrameRatePAL ? 25 : 29.97F);
-		properties.OriginalFrameRate = frameRate;
+		properties.InputFrameRate = frameRate;
 	}
 
 	/* Private members */
diff --git a/src/SubLib/IO/SubtitleFormats/SubtitleFormatFABSubtitler.cs b/src/SubLib/IO/SubtitleFormats/SubtitleFormatFABSubtitler.cs
index 938b4c9..f6648f1 100644
--- a/src/SubLib/IO/SubtitleFormats/SubtitleFormatFABSubtitler.cs
+++ b/src/SubLib/IO/SubtitleFormats/SubtitleFormatFABSubtitler.cs
@@ -24,6 +24,8 @@ using System.Text.RegularExpressions;
 
 namespace SubLib.IO.SubtitleFormats {
 
+/* Note: it's not clear whether FAB Subtitler supports framerates besides PAL and NTSC. Because of that, all framerates
+   are supported here. The user should use the subtitle input and output framerate options accordingly. */
 internal class SubtitleFormatFABSubtitler : SubtitleFormat {
 	
 	internal SubtitleFormatFABSubtitler () {
@@ -37,26 +39,7 @@ internal class SubtitleFormatFABSubtitler : SubtitleFormat {
 		
 		subtitleIn = @"(?<StartHours>\d+)\s*:\s*(?<StartMinutes>\d+)\s*:\s*(?<StartSeconds>\d+)\s*:\s*(?<StartMillisecondsAsFrames>\d+)\s+(?<EndHours>\d+)\s*:\s*(?<EndMinutes>\d+)\s*:\s*(?<EndSeconds>\d+)\s*:\s*(?<EndMillisecondsAsFrames>\d+).*(\n(?<Text>(.*(?!\n\d+(\s*:\s*\d+){2})\n?)*.))?";
 		
-		subtitleOut = null;
-	}
-	
-	internal override void GlobalInputGetProperties (string text, ParsingProperties properties) {
-		properties.OriginalFrameRate = 25; //Framerate has to be PAL or NTSC, defaulting to PAL
-	}
-	
-	internal override string GetDynamicSubtitleOut (SubtitleProperties properties) {
-		bool isFrameRatePAL = IsFrameRatePAL(properties.CurrentFrameRate);
-		string suf = GetFrameRateSuffix(isFrameRatePAL);
-		return "<<StartHours>>:<<StartMinutes>>:<<StartSeconds>>:<<StartMillisecondsAsFrames" + suf + ">>  <<EndHours>>:<<EndMinutes>>:<<EndSeconds>>:<<EndMillisecondsAsFrames" + suf + ">>\n<<Text>>\n";
-	}
-	
-	/// <summary>Returns whether the frame rate is closer to PAL (25) or to NTSC (29.97).</summary>
-	private bool IsFrameRatePAL (float frameRate) {
-		return (Math.Abs(frameRate - 25) <= Math.Abs(frameRate - 29.97));
-	}
-	
-	private string GetFrameRateSuffix (bool isFrameRatePAL) {
-		return (isFrameRatePAL ? "PAL" : "NTSC");
+		subtitleOut = "<<StartHours>>:<<StartMinutes>>:<<StartSeconds>>:<<StartMillisecondsAsFrames>>  <<EndHours>>:<<EndMinutes>>:<<EndSeconds>>:<<EndMillisecondsAsFrames>>\n<<Text>>\n";;
 	}
 
 }



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