[gnome-subtitles] Fix bug #638484, based on a patch from Michał Sawicz (Apply a Reaction Delay when timing subtitle s



commit 4e720e242d9dce95027ca241d1497db99032c9bc
Author: Pedro Castro <mail pedrocastro org>
Date:   Sun Jan 2 04:21:35 2011 +0000

    Fix bug #638484, based on a patch from MichaÅ? Sawicz (Apply a Reaction Delay when timing subtitle start/end )

 data/gnome-subtitles.schemas                   |   22 +++
 src/Glade/PreferencesDialog.glade              |  203 ++++++++++++++++--------
 src/GnomeSubtitles/Core/Config.cs              |   37 ++++-
 src/GnomeSubtitles/Core/EventHandlers.cs       |   19 +++
 src/GnomeSubtitles/Dialog/PreferencesDialog.cs |   33 ++++-
 src/GnomeSubtitles/Ui/VideoPreview/Video.cs    |    4 +
 6 files changed, 251 insertions(+), 67 deletions(-)
---
diff --git a/data/gnome-subtitles.schemas b/data/gnome-subtitles.schemas
index d7e3811..ee10ecf 100644
--- a/data/gnome-subtitles.schemas
+++ b/data/gnome-subtitles.schemas
@@ -36,6 +36,28 @@
 			</locale>
 		</schema>
 		<schema>
+			<key>/schemas/apps/gnome-subtitles/preferences/video/apply_reaction_delay</key>
+			<applyto>/apps/gnome-subtitles/preferences/video/apply_reaction_delay</applyto>
+			<owner>gnome-subtitles</owner>
+			<type>bool</type>
+			<default>TRUE</default>
+			<locale name="C">
+				<short>Apply reaction delay</short>
+				<long>Whether to apply a reaction delay when setting the start or end times of a subtitle with the video playing.</long>
+			</locale>
+		</schema>
+		<schema>
+			<key>/schemas/apps/gnome-subtitles/preferences/video/reaction_delay</key>
+			<applyto>/apps/gnome-subtitles/preferences/video/reaction_delay</applyto>
+			<owner>gnome-subtitles</owner>
+			<type>int</type>
+			<default>200</default>
+			<locale name="C">
+				<short>Reaction delay</short>
+				<long>Time, in milliseconds, to subtract from the start or end times when setting them with the video playing.</long>
+			</locale>
+		</schema>
+		<schema>
 			<key>/schemas/apps/gnome-subtitles/preferences/view/line_lengths</key>
 			<applyto>/apps/gnome-subtitles/preferences/view/line_lengths</applyto>
 			<owner>gnome-subtitles</owner>
diff --git a/src/Glade/PreferencesDialog.glade b/src/Glade/PreferencesDialog.glade
index 2a9ce44..1a91cb7 100644
--- a/src/Glade/PreferencesDialog.glade
+++ b/src/Glade/PreferencesDialog.glade
@@ -65,98 +65,72 @@
               </packing>
             </child>
             <child>
-              <widget class="GtkFrame" id="frame1">
+              <widget class="GtkFrame" id="frame5">
                 <property name="visible">True</property>
                 <property name="label_xalign">0</property>
                 <property name="shadow_type">none</property>
                 <child>
-                  <widget class="GtkAlignment" id="alignment1">
+                  <widget class="GtkAlignment" id="alignment5">
                     <property name="visible">True</property>
                     <property name="left_padding">12</property>
                     <child>
-                      <widget class="GtkVBox" id="vbox4">
+                      <widget class="GtkHBox" id="hbox2">
                         <property name="visible">True</property>
-                        <property name="spacing">5</property>
+                        <property name="spacing">3</property>
                         <child>
-                          <widget class="GtkTable" id="table2">
+                          <widget class="GtkCheckButton" id="reactionDelayCheckButton">
+                            <property name="label" translatable="yes">Subtract</property>
                             <property name="visible">True</property>
-                            <property name="n_rows">2</property>
-                            <property name="n_columns">2</property>
-                            <property name="column_spacing">5</property>
-                            <property name="row_spacing">5</property>
-                            <child>
-                              <widget class="GtkLabel" id="label6">
-                                <property name="visible">True</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">Character c_oding to use:</property>
-                                <property name="use_underline">True</property>
-                              </widget>
-                              <packing>
-                                <property name="x_options">GTK_FILL</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkComboBox" id="fileOpenEncodingComboBox">
-                                <property name="visible">True</property>
-                              </widget>
-                              <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkLabel" id="label7">
-                                <property name="visible">True</property>
-                                <property name="xalign">0</property>
-                                <property name="label" translatable="yes">If auto detection _fails, use:</property>
-                                <property name="use_underline">True</property>
-                              </widget>
-                              <packing>
-                                <property name="top_attach">1</property>
-                                <property name="bottom_attach">2</property>
-                                <property name="x_options">GTK_FILL</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkComboBox" id="fileOpenFallbackEncodingComboBox">
-                                <property name="visible">True</property>
-                              </widget>
-                              <packing>
-                                <property name="left_attach">1</property>
-                                <property name="right_attach">2</property>
-                                <property name="top_attach">1</property>
-                                <property name="bottom_attach">2</property>
-                              </packing>
-                            </child>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="use_underline">True</property>
+                            <property name="draw_indicator">True</property>
+                            <signal name="toggled" handler="OnReactionDelayToggled"/>
                           </widget>
                           <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkCheckButton" id="videoAutoChooseFileCheckButton">
-                            <property name="label" translatable="yes">Automatically choose the _video file to open</property>
+                          <widget class="GtkSpinButton" id="reactionDelaySpinButton">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
-                            <property name="receives_default">False</property>
-                            <property name="use_underline">True</property>
-                            <property name="draw_indicator">True</property>
-                            <signal name="toggled" handler="OnVideoAutoChooseFileToggled"/>
+                            <property name="max_length">4</property>
+                            <property name="invisible_char">&#x25CF;</property>
+                            <property name="width_chars">4</property>
+                            <property name="invisible_char_set">True</property>
+                            <property name="adjustment">2000 0 2000 50 100 0</property>
+                            <property name="numeric">True</property>
+                            <signal name="value_changed" handler="OnReactionDelaySpinButtonValueChanged"/>
                           </widget>
                           <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
                             <property name="position">1</property>
                           </packing>
                         </child>
+                        <child>
+                          <widget class="GtkLabel" id="label11">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">milliseconds when setting subtitle start/end on playback</property>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
                       </widget>
                     </child>
                   </widget>
                 </child>
                 <child>
-                  <widget class="GtkLabel" id="label3">
+                  <widget class="GtkLabel" id="label12">
                     <property name="visible">True</property>
-                    <property name="label" translatable="yes">&lt;b&gt;File Open&lt;/b&gt;</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Reaction Delay&lt;/b&gt;</property>
                     <property name="use_markup">True</property>
-                    <property name="use_underline">True</property>
                   </widget>
                   <packing>
                     <property name="type">label_item</property>
@@ -272,6 +246,109 @@
               </packing>
             </child>
             <child>
+              <widget class="GtkFrame" id="frame1">
+                <property name="visible">True</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">none</property>
+                <child>
+                  <widget class="GtkAlignment" id="alignment1">
+                    <property name="visible">True</property>
+                    <property name="left_padding">12</property>
+                    <child>
+                      <widget class="GtkVBox" id="vbox4">
+                        <property name="visible">True</property>
+                        <property name="spacing">5</property>
+                        <child>
+                          <widget class="GtkTable" id="table2">
+                            <property name="visible">True</property>
+                            <property name="n_rows">2</property>
+                            <property name="n_columns">2</property>
+                            <property name="column_spacing">5</property>
+                            <property name="row_spacing">5</property>
+                            <child>
+                              <widget class="GtkLabel" id="label6">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Character c_oding to use:</property>
+                                <property name="use_underline">True</property>
+                              </widget>
+                              <packing>
+                                <property name="x_options">GTK_FILL</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkComboBox" id="fileOpenEncodingComboBox">
+                                <property name="visible">True</property>
+                              </widget>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkLabel" id="label7">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">If auto detection _fails, use:</property>
+                                <property name="use_underline">True</property>
+                              </widget>
+                              <packing>
+                                <property name="top_attach">1</property>
+                                <property name="bottom_attach">2</property>
+                                <property name="x_options">GTK_FILL</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkComboBox" id="fileOpenFallbackEncodingComboBox">
+                                <property name="visible">True</property>
+                              </widget>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">1</property>
+                                <property name="bottom_attach">2</property>
+                              </packing>
+                            </child>
+                          </widget>
+                          <packing>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkCheckButton" id="videoAutoChooseFileCheckButton">
+                            <property name="label" translatable="yes">Automatically choose the _video file to open</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="use_underline">True</property>
+                            <property name="draw_indicator">True</property>
+                            <signal name="toggled" handler="OnVideoAutoChooseFileToggled"/>
+                          </widget>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </widget>
+                    </child>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label3">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">&lt;b&gt;File Open&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                    <property name="use_underline">True</property>
+                  </widget>
+                  <packing>
+                    <property name="type">label_item</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child>
               <widget class="GtkFrame" id="frame4">
                 <property name="visible">True</property>
                 <property name="label_xalign">0</property>
@@ -344,7 +421,7 @@
                 </child>
               </widget>
               <packing>
-                <property name="position">3</property>
+                <property name="position">4</property>
               </packing>
             </child>
           </widget>
diff --git a/src/GnomeSubtitles/Core/Config.cs b/src/GnomeSubtitles/Core/Config.cs
index bca87e6..e1a514e 100644
--- a/src/GnomeSubtitles/Core/Config.cs
+++ b/src/GnomeSubtitles/Core/Config.cs
@@ -52,6 +52,8 @@ public class Config {
 	private const string keyPrefsEncodingsShownInMenu = keyPrefsEncodings + "shown_in_menu";
 	private const string keyPrefsTranslationSaveAll = keyPrefsTranslation + "save_all";
 	private const string keyPrefsVideoAutoChooseFile = keyPrefsVideo + "auto_choose_file";
+	private const string keyPrefsVideoApplyReactionDelay = keyPrefsVideo + "apply_reaction_delay";
+	private const string keyPrefsVideoReactionDelay = keyPrefsVideo + "reaction_delay";
 	private const string keyPrefsViewLineLengths = keyPrefsView + "line_lengths";
 	private const string keyPrefsSpellCheckActiveTextLanguage = keyPrefsSpellCheck + "active_text_language";
 	private const string keyPrefsSpellCheckActiveTranslationLanguage = keyPrefsSpellCheck + "active_translation_language";
@@ -69,7 +71,12 @@ public class Config {
 	private const string keyPrefsDefaultsFileSaveNewline = keyPrefsDefaults + "file_save_newline";
 	private const string keyPrefsBackupAutoBackup = keyPrefsBackup + "auto_backup";
 	private const string keyPrefsBackupBackupTime = keyPrefsBackup + "backup_time";
-
+	
+	/* Cached values */
+	private bool isValuePrefsVideoApplyReactionDelayCached = false;
+	private bool valuePrefsVideoApplyReactionDelay = false;
+	private int valuePrefsVideoReactionDelay = -1;
+	
 
 	public Config () {
 		client = new Client();
@@ -105,6 +112,34 @@ public class Config {
 		set { Set(keyPrefsVideoAutoChooseFile, value); }
 	}
 	
+	public bool PrefsVideoApplyReactionDelay {
+		get {
+			if (!isValuePrefsVideoApplyReactionDelayCached) {
+				this.valuePrefsVideoApplyReactionDelay = GetBool(keyPrefsVideoApplyReactionDelay, false);
+				this.isValuePrefsVideoApplyReactionDelayCached = true;
+			}
+			return valuePrefsVideoApplyReactionDelay;
+		}
+		set {
+			Set(keyPrefsVideoApplyReactionDelay, value);
+			this.valuePrefsVideoApplyReactionDelay = value;
+			this.isValuePrefsVideoApplyReactionDelayCached = true;
+		}
+	}
+
+	public int PrefsVideoReactionDelay {
+		get {
+			if (this.valuePrefsVideoReactionDelay == -1) {
+				this.valuePrefsVideoReactionDelay = GetInt(keyPrefsVideoReactionDelay, 200, 0, true, 2000, true);
+			}
+			return this.valuePrefsVideoReactionDelay;
+		}
+		set {
+			Set(keyPrefsVideoReactionDelay, value);
+			this.valuePrefsVideoReactionDelay = value;
+		}
+	}
+	
 	public bool PrefsViewLineLengths {
 		get { return GetBool(keyPrefsViewLineLengths, true); }
 		set { Set(keyPrefsViewLineLengths, value); }
diff --git a/src/GnomeSubtitles/Core/EventHandlers.cs b/src/GnomeSubtitles/Core/EventHandlers.cs
index 107c08c..f51b264 100644
--- a/src/GnomeSubtitles/Core/EventHandlers.cs
+++ b/src/GnomeSubtitles/Core/EventHandlers.cs
@@ -24,6 +24,7 @@ using GnomeSubtitles.Ui;
 using Gtk;
 using Mono.Unix;
 using SubLib.Core.Domain;
+using SubLib.Core.Timing;
 using System;
 using System.Text;
 
@@ -269,10 +270,16 @@ public class EventHandlers {
 	public void OnVideoSetSubtitleStart (object o, EventArgs args) {
 		if (Base.TimingMode == TimingMode.Times) {
 			TimeSpan time = Base.Ui.Video.Position.CurrentTime;
+			if (Base.Ui.Video.IsStatePlaying && Base.Config.PrefsVideoApplyReactionDelay) {
+				time -= TimeSpan.FromMilliseconds(Base.Config.PrefsVideoReactionDelay);
+			}
 			Base.CommandManager.Execute(new VideoSetSubtitleStartCommand(time));
 		}
 		else {
 			int frames = Base.Ui.Video.Position.CurrentFrames;
+			if (Base.Ui.Video.IsStatePlaying && Base.Config.PrefsVideoApplyReactionDelay) {
+				frames -= (int)TimingUtil.TimeMillisecondsToFrames(Base.Config.PrefsVideoReactionDelay, Base.Ui.Video.FrameRate);
+			}
 			Base.CommandManager.Execute(new VideoSetSubtitleStartCommand(frames));
 		}			
 	}
@@ -280,10 +287,16 @@ public class EventHandlers {
 	public void OnVideoSetSubtitleEnd (object o, EventArgs args) {
 		if (Base.TimingMode == TimingMode.Times) {
 			TimeSpan time = Base.Ui.Video.Position.CurrentTime;
+			if (Base.Ui.Video.IsStatePlaying && Base.Config.PrefsVideoApplyReactionDelay) {
+				time -= TimeSpan.FromMilliseconds(Base.Config.PrefsVideoReactionDelay);
+			}
 			Base.CommandManager.Execute(new VideoSetSubtitleEndCommand(time));
 		}
 		else {
 			int frames = Base.Ui.Video.Position.CurrentFrames;
+			if (Base.Ui.Video.IsStatePlaying && Base.Config.PrefsVideoApplyReactionDelay) {
+				frames -= (int)TimingUtil.TimeMillisecondsToFrames(Base.Config.PrefsVideoReactionDelay, Base.Ui.Video.FrameRate);
+			}
 			Base.CommandManager.Execute(new VideoSetSubtitleEndCommand(frames));
 		}
 	}
@@ -291,11 +304,17 @@ public class EventHandlers {
 	public void OnVideoSetSubtitleStartEnd (object o, EventArgs args) {
 		if (Base.TimingMode == TimingMode.Times) {
 			TimeSpan time = Base.Ui.Video.Position.CurrentTime;
+			if (Base.Ui.Video.IsStatePlaying && Base.Config.PrefsVideoApplyReactionDelay) {
+				time -= TimeSpan.FromMilliseconds(Base.Config.PrefsVideoReactionDelay);
+			}
 			Base.CommandManager.Execute(new VideoSetSubtitleEndCommand(time));
 			Base.Ui.View.SelectNextSubtitle();
 		}
 		else {
 			int frames = Base.Ui.Video.Position.CurrentFrames;
+			if (Base.Ui.Video.IsStatePlaying && Base.Config.PrefsVideoApplyReactionDelay) {
+				frames -= (int)TimingUtil.TimeMillisecondsToFrames(Base.Config.PrefsVideoReactionDelay, Base.Ui.Video.FrameRate);
+			}
 			Base.CommandManager.Execute(new VideoSetSubtitleEndCommand(frames));
 			Base.Ui.View.SelectNextSubtitle();
 		}
diff --git a/src/GnomeSubtitles/Dialog/PreferencesDialog.cs b/src/GnomeSubtitles/Dialog/PreferencesDialog.cs
index 9543e89..3b3975d 100644
--- a/src/GnomeSubtitles/Dialog/PreferencesDialog.cs
+++ b/src/GnomeSubtitles/Dialog/PreferencesDialog.cs
@@ -43,12 +43,14 @@ public class PreferencesDialog : GladeDialog {
 	[WidgetAttribute] private CheckButton translationSaveAllCheckButton = null;
 	[WidgetAttribute] private CheckButton videoAutoChooseFileCheckButton = null;
 	[WidgetAttribute] private CheckButton autoBackupCheckButton = null;
+	[WidgetAttribute] private CheckButton reactionDelayCheckButton = null;
 	[WidgetAttribute] private ComboBox fileOpenEncodingComboBox = null;
 	[WidgetAttribute] private ComboBox fileOpenFallbackEncodingComboBox = null;
 	[WidgetAttribute] private ComboBox fileSaveEncodingComboBox = null;
 	[WidgetAttribute] private ComboBox fileSaveFormatComboBox = null;
 	[WidgetAttribute] private ComboBox fileSaveNewlineComboBox = null;
 	[WidgetAttribute] private SpinButton autoBackupTimeSpinButton = null;
+	[WidgetAttribute] private SpinButton reactionDelaySpinButton = null;
 
 
 	public PreferencesDialog () : base(gladeFilename, false) {
@@ -74,6 +76,9 @@ public class PreferencesDialog : GladeDialog {
 		
 		/* Auto Backup */
 		SetAutoBackup();
+		
+		/* Reaction Delay */
+		SetReactionDelay();
 	}
 
 	private void SetDefaultsFileOpenEncoding () {
@@ -161,7 +166,15 @@ public class PreferencesDialog : GladeDialog {
 		autoBackupCheckButton.Active = autoBackupEnabled;
 		
 		autoBackupTimeSpinButton.Sensitive = autoBackupEnabled;
-		autoBackupTimeSpinButton.Value = (int)Base.Config.PrefsBackupBackupTime / 60; //Minutes
+		autoBackupTimeSpinButton.Value = Base.Config.PrefsBackupBackupTime / 60; //Minutes
+	}
+	
+	private void SetReactionDelay () {
+		bool reactionDelayEnabled = Base.Config.PrefsVideoApplyReactionDelay;
+		reactionDelayCheckButton.Active = reactionDelayEnabled;
+
+		reactionDelaySpinButton.Sensitive = reactionDelayEnabled;
+		reactionDelaySpinButton.Value = Base.Config.PrefsVideoReactionDelay;
 	}
 
 	private void ResetDialogToDefaults () {
@@ -175,10 +188,13 @@ public class PreferencesDialog : GladeDialog {
 		fileSaveFormat.ActiveSelection = 0; //Keep Existing
 		fileSaveNewline.ChosenNewlineType = NewlineType.Windows;
 		
-		autoBackupCheckButton.Active = true;
+		autoBackupCheckButton.Active = true; //FIXME defaults plus time
+		
+		reactionDelayCheckButton.Active = true;
+		reactionDelaySpinButton.Value = 200;
 	}
 
-	
+
 	/* Event members */
 
 	#pragma warning disable 169		//Disables warning about handlers not being used
@@ -303,6 +319,17 @@ public class PreferencesDialog : GladeDialog {
 		Base.Config.PrefsBackupBackupTime = (o as SpinButton).ValueAsInt * 60; //seconds
 		Base.Backup.ReCheck();
 	}
+	
+	private void OnReactionDelayToggled (object o, EventArgs args) {
+		bool isActive = (o as CheckButton).Active;
+
+		Base.Config.PrefsVideoApplyReactionDelay = isActive;
+		reactionDelaySpinButton.Sensitive = isActive;
+	}
+
+	private void OnReactionDelaySpinButtonValueChanged (object o, EventArgs args) {
+		Base.Config.PrefsVideoReactionDelay = (o as SpinButton).ValueAsInt;
+	}
 
 	protected override bool ProcessResponse (ResponseType response) {
 		if (response == ResponseType.Cancel) {
diff --git a/src/GnomeSubtitles/Ui/VideoPreview/Video.cs b/src/GnomeSubtitles/Ui/VideoPreview/Video.cs
index 23bac39..3a9d8a1 100644
--- a/src/GnomeSubtitles/Ui/VideoPreview/Video.cs
+++ b/src/GnomeSubtitles/Ui/VideoPreview/Video.cs
@@ -78,6 +78,10 @@ public class Video {
 		get { return isLoaded; }
 	}
 	
+	public bool IsStatePlaying {
+		get { return player.State == MediaStatus.Playing; }
+	}
+	
 	public float FrameRate {
 		get { return player.FrameRate; }
 	}



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