[gnome-subtitles/improved-file-open] Initial patch from bug #607230 with minimal review



commit 15045f3cd8fd9d9c397618dd90f2f6840561fa65
Author: Pedro Castro <pedro gnomesubtitles org>
Date:   Sat Mar 10 10:17:11 2012 +0000

    Initial patch from bug #607230 with minimal review

 gnome-subtitles.mdp                                |    3 +
 m4/gtk-doc.m4                                      |    6 +
 src/Glade/FileOpenDialog.glade                     |  113 +++++-
 src/Glade/PreferencesDialog.glade                  |   13 +
 src/GnomeSubtitles/Core/Base.cs                    |    1 -
 src/GnomeSubtitles/Core/Config.cs                  |    7 +
 src/GnomeSubtitles/Core/FileTools.cs               |  218 +++++++++++
 src/GnomeSubtitles/Core/SpellLanguage.cs           |    6 +
 src/GnomeSubtitles/Dialog/FileOpenDialog.cs        |  379 ++++++++++----------
 .../Dialog/FileTranslationOpenDialog.cs            |   43 ++-
 src/GnomeSubtitles/Dialog/PreferencesDialog.cs     |    7 +
 src/GnomeSubtitles/Ui/Component/FileCombo.cs       |   85 +++++
 .../Ui/Component/FilexEncodingCombo.cs             |   62 ++++
 src/GnomeSubtitles/Ui/MainUi.cs                    |  106 +++---
 14 files changed, 781 insertions(+), 268 deletions(-)
---
diff --git a/gnome-subtitles.mdp b/gnome-subtitles.mdp
index 710d0a8..01dc0b4 100644
--- a/gnome-subtitles.mdp
+++ b/gnome-subtitles.mdp
@@ -261,6 +261,9 @@
     <File subtype="Code" buildaction="Compile" name="src/GnomeSubtitles/Core/Command/MergeSubtitlesCommand.cs" />
     <File subtype="Code" buildaction="Compile" name="src/SubLib/Exceptions/FileTooLargeException.cs" />
     <File subtype="Code" buildaction="Compile" name="src/GnomeSubtitles/Ui/Edit/SubtitleEditTextViewMargin.cs" />
+    <File subtype="Code" buildaction="Compile" name="src/GnomeSubtitles/Core/FileTools.cs" />
+    <File subtype="Code" buildaction="Compile" name="src/GnomeSubtitles/Ui/Component/FileCombo.cs" />
+    <File subtype="Code" buildaction="Compile" name="src/GnomeSubtitles/Ui/Component/FilexEncodingCombo.cs" />
   </Contents>
   <References>
     <ProjectReference type="Gac" localcopy="True" refto="Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
diff --git a/m4/gtk-doc.m4 b/m4/gtk-doc.m4
index 2cfa1e7..0ada151 100644
--- a/m4/gtk-doc.m4
+++ b/m4/gtk-doc.m4
@@ -6,6 +6,7 @@ dnl Usage:
 dnl   GTK_DOC_CHECK([minimum-gtk-doc-version])
 AC_DEFUN([GTK_DOC_CHECK],
 [
+  AC_REQUIRE([PKG_PROG_PKG_CONFIG])
   AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first
   AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first
 
@@ -33,6 +34,11 @@ AC_DEFUN([GTK_DOC_CHECK],
                         AC_MSG_ERROR([gtk-doc not installed and --enable-gtk-doc requested]))],
       [PKG_CHECK_EXISTS([gtk-doc >= $1],,
                         AC_MSG_ERROR([You need to have gtk-doc >= $1 installed to build $PACKAGE_NAME]))])
+    dnl don't check for glib if we build glib
+    if test "x$PACKAGE_NAME" != "xglib"; then
+      dnl don't fail if someone does not have glib
+      PKG_CHECK_MODULES(GTKDOC_DEPS, glib-2.0 >= 2.10.0 gobject-2.0  >= 2.10.0,,)
+    fi
   fi
 
   AC_MSG_CHECKING([whether to build gtk-doc documentation])
diff --git a/src/Glade/FileOpenDialog.glade b/src/Glade/FileOpenDialog.glade
index fdbb23a..34c22f7 100644
--- a/src/Glade/FileOpenDialog.glade
+++ b/src/Glade/FileOpenDialog.glade
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <glade-interface>
   <!-- interface-requires gtk+ 2.16 -->
   <!-- interface-naming-policy toplevel-contextual -->
@@ -11,60 +11,135 @@
     <property name="type_hint">dialog</property>
     <property name="skip_taskbar_hint">True</property>
     <property name="skip_pager_hint">True</property>
-    <property name="has_separator">False</property>
+    <property name="select_multiple">True</property>
     <child internal-child="vbox">
       <widget class="GtkVBox" id="dialogVBox">
         <property name="visible">True</property>
-        <property name="orientation">vertical</property>
         <property name="spacing">24</property>
         <child>
-          <widget class="GtkTable" id="table">
+          <widget class="GtkTable" id="table3">
             <property name="visible">True</property>
-            <property name="n_rows">2</property>
-            <property name="n_columns">2</property>
-            <property name="column_spacing">10</property>
-            <property name="row_spacing">10</property>
+            <property name="n_rows">3</property>
+            <property name="n_columns">4</property>
+            <property name="column_spacing">5</property>
+            <property name="row_spacing">2</property>
             <child>
-              <widget class="GtkComboBox" id="videoComboBox">
-                <property name="items" translatable="yes"></property>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="subtitleFileLabel">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Subtitle File:</property>
+              </widget>
+              <packing>
+                <property name="x_options">GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkComboBox" id="subtitleFileComboBox">
+                <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>
             <child>
-              <widget class="GtkLabel" id="videoLabel">
+              <widget class="GtkComboBox" id="subtitleEncodingComboBox">
+                <property name="visible">True</property>
+              </widget>
+              <packing>
+                <property name="left_attach">3</property>
+                <property name="right_attach">4</property>
+                <property name="x_options"></property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="subtitleEncodingLabel">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Character Encoding:</property>
+              </widget>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="right_attach">3</property>
+                <property name="x_options">GTK_FILL</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="translationFileLabel">
+                <property name="visible">True</property>
                 <property name="xalign">0</property>
-                <property name="label" translatable="yes">Video To Open:</property>
+                <property name="label" translatable="yes">Translation File:</property>
               </widget>
               <packing>
                 <property name="top_attach">1</property>
                 <property name="bottom_attach">2</property>
                 <property name="x_options">GTK_FILL</property>
-                <property name="y_options"></property>
               </packing>
             </child>
             <child>
-              <widget class="GtkLabel" id="encodingLabel">
+              <widget class="GtkLabel" id="videoFileLabel">
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
-                <property name="label" translatable="yes">Character Coding:</property>
+                <property name="label" translatable="yes">Video File:</property>
               </widget>
               <packing>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
                 <property name="x_options">GTK_FILL</property>
-                <property name="y_options"></property>
               </packing>
             </child>
             <child>
-              <widget class="GtkComboBox" id="fileEncodingComboBox">
+              <widget class="GtkLabel" id="translationEncodingLabel">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Character Encoding:</property>
+              </widget>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="right_attach">3</property>
+                <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="translationFileComboBox">
                 <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>
+            <child>
+              <widget class="GtkComboBox" id="videoFileComboBox">
+                <property name="visible">True</property>
+              </widget>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="right_attach">2</property>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkComboBox" id="translationEncodingComboBox">
+                <property name="visible">True</property>
+              </widget>
+              <packing>
+                <property name="left_attach">3</property>
+                <property name="right_attach">4</property>
+                <property name="top_attach">1</property>
+                <property name="bottom_attach">2</property>
+                <property name="x_options"></property>
               </packing>
             </child>
           </widget>
diff --git a/src/Glade/PreferencesDialog.glade b/src/Glade/PreferencesDialog.glade
index 6978fba..07c1c06 100644
--- a/src/Glade/PreferencesDialog.glade
+++ b/src/Glade/PreferencesDialog.glade
@@ -154,6 +154,19 @@
                                 <property name="position">1</property>
                               </packing>
                             </child>
+                            <child>
+                              <widget class="GtkCheckButton" id="translationAutoChooseFileCheckButton">
+                                <property name="label" translatable="yes">Automatically choose the translation _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>
+                              </widget>
+                              <packing>
+                                <property name="position">2</property>
+                              </packing>
+                            </child>
                           </widget>
                         </child>
                       </widget>
diff --git a/src/GnomeSubtitles/Core/Base.cs b/src/GnomeSubtitles/Core/Base.cs
index 0683d8e..a34b71b 100644
--- a/src/GnomeSubtitles/Core/Base.cs
+++ b/src/GnomeSubtitles/Core/Base.cs
@@ -25,7 +25,6 @@ using Gtk;
 using Mono.Unix;
 using SubLib.Core.Domain;
 using System;
-using System.IO;
 using System.Text;
 
 namespace GnomeSubtitles.Core {
diff --git a/src/GnomeSubtitles/Core/Config.cs b/src/GnomeSubtitles/Core/Config.cs
index 54ff8bf..fa2d54d 100644
--- a/src/GnomeSubtitles/Core/Config.cs
+++ b/src/GnomeSubtitles/Core/Config.cs
@@ -32,6 +32,7 @@ public enum ConfigFileSaveEncoding { KeepExisting = -1, CurrentLocale = 0, Fixed
 public enum ConfigFileSaveFormatOption { KeepExisting = 0, RememberLastUsed = 1, Specific = 3 }; //Values match ordering where the options are used
 public enum ConfigFileSaveFormat { KeepExisting = -1, Fixed = 0 }; //KeepExisting=-1 because it doesn't appear
 public enum ConfigFileSaveNewlineOption { RememberLastUsed = 0, Specific = 2 }; //Values match ordering where the options are used
+public enum ValidFileTypes { Subtitle = 3, Video = 2, None = 0};
 
 public class Config {
 	private Client client = null;
@@ -53,6 +54,7 @@ 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 keyPrefsTranslationAutoChooseFile = keyPrefsTranslation + "auto_choose_file";
 	private const string keyPrefsVideoApplyReactionDelay = keyPrefsVideo + "apply_reaction_delay";
 	private const string keyPrefsVideoReactionDelay = keyPrefsVideo + "reaction_delay";
 	private const string keyPrefsVideoSeekOnChange = keyPrefsVideo + "seek_on_change";
@@ -125,6 +127,11 @@ public class Config {
 		get { return GetBool(keyPrefsVideoAutoChooseFile, true); }
 		set { Set(keyPrefsVideoAutoChooseFile, value); }
 	}
+		
+	public bool PrefsTranslationAutoChooseFile {
+		get { return GetBool(keyPrefsTranslationAutoChooseFile, true); }
+		set { Set(keyPrefsTranslationAutoChooseFile, value); }
+	}
 	
 	public bool PrefsVideoApplyReactionDelay {
 		get {
diff --git a/src/GnomeSubtitles/Core/FileTools.cs b/src/GnomeSubtitles/Core/FileTools.cs
new file mode 100644
index 0000000..70689ea
--- /dev/null
+++ b/src/GnomeSubtitles/Core/FileTools.cs
@@ -0,0 +1,218 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+using GnomeSubtitles.Core;
+using SubLib.Core.Domain;
+
+
+namespace GnomeSubtitles.Core
+{
+	/// <summary>
+	/// !ThreadSafe in any way
+	/// </summary>
+	public class FileTools
+	{
+		
+		private static Regex languageIdRegex = new Regex(@"[a-z][a-z]_[a-z][a-z]");
+		private static Regex subtitleFileExtentionsRegex  = new Regex(BuildExtentionsPattern());
+		private static Regex videoFilesRegex = new Regex(@"^.*\.((3g2)|(3gp)|(asf)|(avi)|(bdm)|(cpi)|(divx)|(flv)|(m4v)|(mkv)|(mod)|(mov)|(mp3)|(mp4)|(mpeg)|(mpg)|(mts)|(ogg)|(ogm)|(rm)|(rmvb)|(spx)|(vob)|(wav)|(wma)|(wmv)|(xvid))$");
+			
+		/*Public Funtions */
+		
+		/// <summary>
+		/// Returns an collection of strings containing any files matching the type specified, Returns null if path is incorrect or empty list if no files of type found  
+		/// </summary>
+		/// <param name="path">
+		/// A <see cref="System.String"/>
+		/// </param>
+		/// <param name="type">
+		/// A <see cref="ValidFileTypes"/>
+		/// </param>
+		/// <returns>
+		/// A <see cref="IEnumerable<System.String>"/>
+		/// </returns>
+		public static IEnumerable<string> GetFilesOfType (string path, ValidFileTypes type) {
+			if ((path == null) || (path == String.Empty) || (!Directory.Exists(path)) )
+				return null;
+
+			string[] allFiles = Directory.GetFiles(path, "*.*");
+			return GetFilesOfType(allFiles, type);
+		}
+		
+		/// <summary>
+		/// Returns a collection of strings containing all string paths or filenames from supplied collection that match specified type
+		/// </summary>
+		/// <param name="filepaths">
+		/// A <see cref="System.String[]"/>
+		/// </param>
+		/// <param name="type">
+		/// A <see cref="ValidFileTypes"/>
+		/// </param>
+		/// <returns>
+		/// A <see cref="IEnumerable<System.String>"/>
+		/// </returns>
+		public static IEnumerable<string> GetFilesOfType (IEnumerable<string> filepaths, ValidFileTypes type) {
+			List<string> returnfiles = new List<string>();
+			foreach (string filepath in filepaths) {
+				if (GetFileType(filepath) == type) {
+					returnfiles.Add(filepath);
+				}
+			}
+			returnfiles.Sort();
+			return returnfiles;
+		}
+		
+		/// <summary>
+		/// Finds closest match available in given files parent folder that is of the specified type, Returns null if no match is found
+		/// </summary>
+		/// <param name="path">
+		/// A <see cref="System.String"/>
+		/// </param>
+		/// <param name="type">
+		/// A <see cref="ValidFileTypes"/>
+		/// </param>
+		/// <returns>
+		/// A <see cref="System.String"/>
+		/// </returns>
+		public static string FromFolderFindMatchOfType (string filepath, ValidFileTypes type) {			
+			return FindMatchingFile(filepath, GetFilesOfType(filepath, type));
+		}
+		
+		/// <summary>
+		/// Finds nearest match to supplied filename in given collection of files, Returns null if no match is found
+		/// </summary>
+		/// <param name="filetomatch">
+		/// A <see cref="System.String"/>
+		/// </param>
+		/// <param name="filestosearch">
+		/// A <see cref="IEnumerable<System.String>"/>
+		/// </param>
+		/// <returns>
+		/// A <see cref="System.String"/>
+		/// </returns>
+		public static string FindMatchingFile (string filetomatch, IEnumerable<string> filestosearch) {
+			string filenametomatch = GetCleanFilenamePattern(filetomatch);
+			string currentcultureid = FilenameContainsLanguageId(filetomatch) ? GetFilenameLanguageId(filetomatch) : CultureInfo.CurrentUICulture.Name; 
+			
+			List<string> matchingfiles = new List<string>();
+			List<string> matchingfileswithid = new List<string>();
+			List<string> matchingforeignfileswithid = new List<string>();
+			
+			foreach(string file in filestosearch) {
+				string filename = Path.GetFileName(file);
+				if (Regex.IsMatch(filename, filenametomatch) && file != filetomatch) 
+					matchingfiles.Add(file);
+			}
+			if (matchingfiles.Count > 0) {
+				foreach(string matchingfile in matchingfiles) {
+					if (FilenameContainsLanguageId(matchingfile)) 
+						matchingfileswithid.Add(matchingfile);
+				}
+				if (matchingfileswithid.Count > 0) {
+					foreach (string matchingfilewithid in matchingfileswithid) {
+						if (GetFilenameLanguageId(matchingfilewithid) != currentcultureid)
+							matchingforeignfileswithid.Add(matchingfilewithid);
+					}
+					if (matchingforeignfileswithid.Count > 0){
+						return matchingforeignfileswithid[0];
+					} else {
+						return matchingfileswithid[0];
+					}
+				} else {
+					return matchingfiles[0];
+				}
+			} return null;
+		}
+		
+		/// <summary>
+		/// Simply bolts on "file://" to given string and returns as uri
+		/// </summary>
+		/// <param name="filepath">
+		/// A <see cref="System.String"/>
+		/// </param>
+		/// <returns>
+		/// A <see cref="Uri"/>
+		/// </returns>
+		public static Uri GetUriFromFilePath (string filepath) {
+			return new Uri ("file://" + filepath);
+		}
+		
+		/*Private Functions */
+		
+		private static string BuildExtentionsPattern () {
+			SubtitleTypeInfo[] types = Subtitles.AvailableTypesSorted;
+			StringBuilder pattern = new StringBuilder(@"^.*\.(");
+			foreach(SubtitleTypeInfo type in types) {
+				foreach (string extention in type.Extensions)
+					pattern.Append("(").Append(extention).Append(")|");
+			}
+			pattern.Remove(pattern.Length -1, 1);	//remove last "|"
+			pattern.Append(")$");
+			return pattern.ToString();
+		}
+		
+		private static bool FileIsSubtitle (string file) {
+			return (subtitleFileExtentionsRegex.IsMatch(Path.GetExtension(file))); 
+		}
+		
+		private static bool FileIsVideo (string file) {
+			return videoFilesRegex.IsMatch(file);		
+		}
+				
+		private static bool FilenameContainsLanguageId (string file) {
+			return (languageIdRegex.IsMatch(file));
+			
+		}		
+		
+		/// <summary>
+		/// Returns a filetype based on a simple file extention regex test
+		/// </summary>
+		/// <param name="file">
+		/// A <see cref="System.String"/>
+		/// </param>
+		/// <returns>
+		/// A <see cref="ValidFileTypes"/>
+		/// </returns>
+		private static ValidFileTypes GetFileType (string file) {
+			if (FileTools.FileIsSubtitle(file)) {
+				return ValidFileTypes.Subtitle;	
+			} else if (FileTools.FileIsVideo(file)) { 
+				return ValidFileTypes.Video;
+			} else {
+				return ValidFileTypes.None;
+			}
+		}
+	
+		private static string GetFilenameLanguageId (string candidate) {
+			if (FilenameContainsLanguageId(candidate)){
+				foreach (SpellLanguage lang in Base.SpellLanguages.Languages) {
+					if(lang.StringMatchesId(candidate))
+						return lang.ID;
+				}
+			}
+			return String.Empty;
+		}
+	
+		/// <summary>
+		/// Attempts to remove any tags added by Gnome-Subtitles and escape any regex wildcards from a string filepath or filename  
+		/// </summary>
+		/// <param name="filename">
+		/// A <see cref="System.String"/>
+		/// </param>
+		/// <returns>
+		/// A <see cref="System.String"/>
+		/// </returns>
+		private static string GetCleanFilenamePattern (string filename) {
+			filename = Path.GetFileNameWithoutExtension(filename);
+			if (GetFilenameLanguageId(filename) != String.Empty)
+				filename.Replace(GetFilenameLanguageId(filename), "");
+			filename = Regex.Escape(filename);
+			filename.Trim();
+			return filename;
+		}
+	}
+}
+
diff --git a/src/GnomeSubtitles/Core/SpellLanguage.cs b/src/GnomeSubtitles/Core/SpellLanguage.cs
index 8f1e142..8bae314 100644
--- a/src/GnomeSubtitles/Core/SpellLanguage.cs
+++ b/src/GnomeSubtitles/Core/SpellLanguage.cs
@@ -49,6 +49,12 @@ public class SpellLanguage : IComparable {
 		get { return name; }
 	}
 	
+	public bool StringMatchesId (string candidate) {
+		if (regex.IsMatch(candidate))
+			return true;
+		return false;
+	}
+	
 	/* Public methods */
 	
 	public override bool Equals (object o) {
diff --git a/src/GnomeSubtitles/Dialog/FileOpenDialog.cs b/src/GnomeSubtitles/Dialog/FileOpenDialog.cs
index b7be207..eb4be50 100644
--- a/src/GnomeSubtitles/Dialog/FileOpenDialog.cs
+++ b/src/GnomeSubtitles/Dialog/FileOpenDialog.cs
@@ -16,77 +16,73 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
-
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Glade;
 using GnomeSubtitles.Core;
 using GnomeSubtitles.Ui.Component;
-using GnomeSubtitles.Ui.VideoPreview;
-using Glade;
 using Gtk;
 using Mono.Unix;
 using SubLib.Core.Domain;
-using System;
-using System.Collections;
-using System.IO;
-using System.Text;
-using System.Text.RegularExpressions;
 
 namespace GnomeSubtitles.Dialog {
 
 public class FileOpenDialog : GladeDialog {
 	protected FileChooserDialog dialog = null;
-
-	private string chosenFilename = String.Empty;
-	private EncodingDescription chosenEncoding = EncodingDescription.Empty;
-	private ArrayList videoFiles = null; //The full paths of the video files in the current dir
-	private ArrayList videoFilenames = null; //The filenames of videoFiles, without extensions
-	private Uri chosenVideoUri = null;
-	private bool autoChooseVideoFile = true;
-
+		
+	
+	/* Preferences */
+	protected bool autoChooseVideoFile = true;
+	protected bool autoChooseTranslationFile = true;
+	
+	protected List<string> subtitleFiles = new List<string>();
+	protected List<string> videoFiles = new List<string>();
+		
+	protected List<FilexEncodingCombo> ActiveSelectionCombos = new List<FilexEncodingCombo>();
+		
 	/* Constant strings */
 	private const string gladeFilename = "FileOpenDialog.glade";
 
 	/* Components */
-	private EncodingComboBox encodingComboBox = null;
+	protected FilexEncodingCombo selectedSubtitle = null;
+	protected FilexEncodingCombo selectedTranslation = null;
+	protected FileCombo selectedVideo = null;
 
 	/* Widgets */
-	[WidgetAttribute] private ComboBox fileEncodingComboBox = null;
-	[WidgetAttribute] private ComboBox videoComboBox = null;
-	[WidgetAttribute] private Label videoLabel = null;
+	
+	[WidgetAttribute] protected Label subtitleFileLabel = null;
+	[WidgetAttribute] protected ComboBox subtitleFileComboBox = null;
+	[WidgetAttribute] protected ComboBox subtitleEncodingComboBox = null;
+	[WidgetAttribute] protected Label translationFileLabel = null;
+	[WidgetAttribute] protected ComboBox translationFileComboBox = null;
+	[WidgetAttribute] protected ComboBox translationEncodingComboBox = null;
+	[WidgetAttribute] protected Label videoFileLabel = null;
+	[WidgetAttribute] protected ComboBox videoFileComboBox = null;
+
 	
 	
-	public FileOpenDialog () : this(true, Catalog.GetString("Open File")) {
+	public FileOpenDialog () : this(true, true ,Catalog.GetString("Open Files")) {
 	}
 	
-	protected FileOpenDialog (bool toEnableVideo, string title) : base(gladeFilename) {
+	protected FileOpenDialog (bool toEnableVideo, bool toEnableTranslation, string title) : base(gladeFilename) {
 		dialog = GetDialog() as FileChooserDialog;
 		dialog.Title = title;
-
-		InitEncodingComboBox();
-
-		if (toEnableVideo)
+		dialog.CurrentFolderChanged += OnCurrentFolderChangedGetTextFiles;
+		dialog.SelectionChanged += OnSelectionGetTextFiles;
+		
+		InitSelectedSubtitleCombo (); // this is overriden in TranslationFileOpen
+		
+		if (toEnableTranslation) {
+			InitSelectedTranslationCombo ();
+		}
+		if (toEnableVideo) // This must be enabled last to allow autoselection to funtion
 			EnableVideo();
 	
 		string startFolder = GetStartFolder();
 		dialog.SetCurrentFolder(startFolder);
-
-		SetFilters();
-	}
-
-	private void InitEncodingComboBox () {
-		int fixedEncoding = -1;
-		ConfigFileOpenEncoding encodingConfig = Base.Config.PrefsDefaultsFileOpenEncoding;
-		if (encodingConfig == ConfigFileOpenEncoding.Fixed) {
-			string encodingName = Base.Config.PrefsDefaultsFileOpenEncodingFixed;
-			EncodingDescription encodingDescription = EncodingDescription.Empty;
-			Encodings.Find(encodingName, ref encodingDescription);
-			fixedEncoding = encodingDescription.CodePage;
-		}
-
-		this.encodingComboBox = new EncodingComboBox(fileEncodingComboBox, true, null, fixedEncoding);
-
-		/* Only need to handle the case of currentLocale, as Fixed is handled before and AutoDetect is the default behaviour */
-		if (encodingConfig == ConfigFileOpenEncoding.CurrentLocale)
-			encodingComboBox.ActiveSelection = (int)encodingConfig;
+		
+		SetFilters();		
 	}
 
 	/* Overriden members */
@@ -96,23 +92,26 @@ public class FileOpenDialog : GladeDialog {
 	}
 
 	/* Public properties */
-
-	public EncodingDescription Encoding {
-		get { return chosenEncoding; }
+		
+	public string SelectedSubtitle {
+		get { return selectedSubtitle != null ? selectedSubtitle.ActiveSelection : null;}		
 	}
-
-	public string Filename {
-		get { return chosenFilename; }
+		
+	public EncodingDescription SelectedSubtitleEncoding {
+		get { return selectedSubtitle != null ?  selectedSubtitle.SelectedEncoding : EncodingDescription.Empty;}		
 	}
 	
-	public bool HasVideoFilename {
-		get { return chosenVideoUri != null; }
+	public string SelectedTranslation {
+		get { return selectedTranslation != null ? selectedTranslation.ActiveSelection : null;}		
 	}
-	
-	public Uri VideoUri {
-		get { return chosenVideoUri; }
+		
+	public EncodingDescription SelectedTranslationEncoding {
+		get { return selectedTranslation != null ? selectedTranslation.SelectedEncoding : EncodingDescription.Empty;}		
+	}
+		
+	public Uri SelectedVideo {
+		get { return selectedVideo.ActiveSelection != null ? FileTools.GetUriFromFilePath(selectedVideo.ActiveSelection) : null;}		
 	}
-
 
 	/* Protected members */
 	
@@ -123,123 +122,50 @@ public class FileOpenDialog : GladeDialog {
 			return Environment.GetFolderPath(Environment.SpecialFolder.Personal);
 	}
 
-
-	/* Private members */
+	protected virtual void InitSelectedSubtitleCombo () {
+		selectedSubtitle = new FilexEncodingCombo(subtitleFileLabel,subtitleFileComboBox, subtitleEncodingComboBox);
+		ActiveSelectionCombos.Add(selectedSubtitle);
+	}
 	
-	private void FillVideoComboBoxBasedOnCurrentFolder () {
-		videoFiles = null;
-		videoFilenames = null;
-		(videoComboBox.Model as ListStore).Clear();
-
-		string folder = String.Empty;
-		try {
-			folder = dialog.CurrentFolder;
-		}
-		catch (Exception e) {
-			System.Console.Error.WriteLine("Caught exception when trying to get the current folder:");
-			System.Console.Error.WriteLine(e);
-			SetVideoSelectionSensitivity(false);
-			return;
-		}
-			
-		if ((folder == null) || (folder == String.Empty)) {
-			System.Console.Error.WriteLine("Error when trying to get the current folder.");
-			SetVideoSelectionSensitivity(false);
-			return;
-		}
-
-		videoFiles = VideoFiles.GetVideoFilesAtPath(folder);
-
-		if ((videoFiles.Count == 0) || (videoFiles == null)) {
-			SetVideoSelectionSensitivity(false);
-			return;
-		}
-		else
-			SetVideoSelectionSensitivity(true);
-				
-		videoFiles.Sort();
-		videoFilenames = new ArrayList();
-		foreach (string file in videoFiles) {
-			string filename = Path.GetFileName(file);
-			videoComboBox.AppendText(filename);
-			
-			videoFilenames.Add(FilenameWithoutExtension(filename));
-		}
-		
-		videoComboBox.PrependText("-");
-		videoComboBox.PrependText(Catalog.GetString("None"));
-		videoComboBox.Active = 0;
+	protected virtual void InitSelectedTranslationCombo () {
+		autoChooseTranslationFile = true; //Base.Config.PrefsTranslationAutoChooseFile;
+		selectedTranslation = new FilexEncodingCombo(translationFileLabel, translationFileComboBox, translationEncodingComboBox);	
+		ActiveSelectionCombos.Add(selectedTranslation);
 	}
 	
-	private void SetActiveVideoFile () {
-		if ((videoFiles == null) || (videoFiles.Count == 0))
-			return;
-		
-		string filePath = String.Empty;
-		try {
-			filePath = dialog.Filename;
-		}
-		catch (Exception e) {
-			System.Console.Error.WriteLine("Caught exception when trying to get the current filename:");
-			System.Console.Error.WriteLine(e);
-			SetActiveComboBoxItem(0);
-			return;
-		}
+	protected void AutoChooseVideoFile () {	
+		if (ActiveSelectionCombos.Count > 0)
+		 if (ActiveSelectionCombos[0].ActiveSelection != null)
+			AutoChooseVideoFile(ActiveSelectionCombos[0].ActiveSelection);
+				
+	}	
 		
-		if ((filePath == null) || (filePath == String.Empty) || (!File.Exists(filePath))) {
-			SetActiveComboBoxItem(0);
-			return;
-		}
+	protected void AutoChooseVideoFile (string filetomatch) {
+		string matchingvideo = FileTools.FindMatchingFile(filetomatch, videoFiles);
+		if (videoFiles.Contains(matchingvideo))
+			selectedVideo.Active = videoFiles.IndexOf(matchingvideo);
+	}	
 		
-		string filename = Path.GetFileNameWithoutExtension(filePath);
-		if ((filename == String.Empty) || (filename == null)) {
-			SetActiveComboBoxItem(0);
-			return;
+	protected void AutoChooseTranslationFile (string filetomatch) {
+		string matchingtranslation = FileTools.FindMatchingFile(filetomatch, subtitleFiles);
+		if(subtitleFiles.Contains(matchingtranslation)){
+			selectedTranslation.Active = subtitleFiles.IndexOf(matchingtranslation);
 		}
+	} 	
 		
-		int activeVideoFile = 0;
+	/* Private members */
 		
-		for (int count = 0 ; count < videoFilenames.Count ; count++) {
-			string videoFilename = videoFilenames[count] as string;
-			if (filename.Equals(videoFilename)) {
-				activeVideoFile = count + 2; //Add 2 because of prepended text
-				break;
-			}
-		}
-		SetActiveComboBoxItem(activeVideoFile);		
-	}
-	
-	private void SetActiveComboBoxItem (int item) {
-		videoComboBox.Active = item;
-	}
-	
-	private void SetVideoSelectionSensitivity (bool sensitivity) {
-		videoComboBox.Sensitive = sensitivity;
-		videoLabel.Sensitive = sensitivity;
-	}
-	
-	private string FilenameWithoutExtension (string filename) {
-		int index = filename.LastIndexOf('.');
-		if (index != -1)
-			return filename.Substring(0, index);
-		else
-			return filename;
-	}
-	
 	private void EnableVideo () {
-		videoLabel.Visible = true;
-		videoComboBox.Visible = true;
-		
 		autoChooseVideoFile = Base.Config.PrefsVideoAutoChooseFile;
-		videoComboBox.RowSeparatorFunc = ComboBoxUtil.SeparatorFunc;
-		
-		dialog.CurrentFolderChanged += OnCurrentFolderChanged;
-		dialog.SelectionChanged += OnSelectionChanged;
+		videoFileComboBox.RowSeparatorFunc = ComboBoxUtil.SeparatorFunc;
+		selectedVideo = new FileCombo(videoFileLabel,videoFileComboBox);
+		dialog.CurrentFolderChanged += OnCurrentFolderChangedGetVideoFiles;
+		dialog.SelectionChanged += OnSelectionGetVideoFiles;
 	}
 	
 	private void SetFilters () {
 		SubtitleTypeInfo[] types = Subtitles.AvailableTypesSorted;
-		FileFilter[] filters = new FileFilter[types.Length + 2];
+		FileFilter[] filters = new FileFilter[types.Length + 3];
 		int filterPosition = 0;
 		
 		/* First filter corresponds to all files */
@@ -249,7 +175,14 @@ public class FileOpenDialog : GladeDialog {
 		filters[filterPosition] = allFilesFilter;
 		filterPosition++;
 		
-		/* Second filter corresponds to all subtitle files */
+		/* Second filter corresponds to all video files*/
+		FileFilter videoFilesFilter = new FileFilter();
+		videoFilesFilter.Name = Catalog.GetString("Video Files");
+		videoFilesFilter.AddMimeType("video/*");
+		filters[filterPosition] = videoFilesFilter;
+		filterPosition++;
+		
+		/* Third filter corresponds to all subtitle files */
 		FileFilter subtitleFilesFilter = new FileFilter();
 		subtitleFilesFilter.Name = Catalog.GetString("All Subtitle Files");
 		subtitleFilesFilter.AddPattern("*.txt");
@@ -272,44 +205,116 @@ public class FileOpenDialog : GladeDialog {
 		foreach (FileFilter filter in filters)
 			dialog.AddFilter(filter);
 		
-		dialog.Filter = subtitleFilesFilter;
+		dialog.Filter = allFilesFilter;
+	}	
+		
+	private void DisplayVideoFiles (List<string> selectedfiles) {
+		if (selectedfiles.Count == 1) {
+			selectedVideo.Active = videoFiles.IndexOf(selectedfiles[0]);
+			return;
+		} 
+		if ((autoChooseVideoFile)) {
+			AutoChooseVideoFile();
+			return;
+		}
+		selectedVideo.Active = -1;
 	}
-	
-	
+		
+	private void DisplayTextFiles (List<string> selectedfiles) {
+		ConnectFileSelectionGroupChanged(false);
+			
+		if (selectedfiles.Count == 1) {
+			ResetTextSelectionComboGroups();	
+			ActiveSelectionCombos[0].Active = subtitleFiles.IndexOf(selectedfiles[0]);
+			if (autoChooseTranslationFile) 
+				AutoChooseTranslationFile(selectedfiles[0]);		
+		}
+		else if (selectedfiles.Count == 2) {
+			selectedfiles.Sort(delegate(string f1, string f2) {return f1.Length.CompareTo(f2.Length);});
+			List<string> reversedlist = new List<string>(selectedfiles);
+			reversedlist.Reverse();
+				
+			ActiveSelectionCombos[0].FillComboBox(selectedfiles);
+			ActiveSelectionCombos[1].FillComboBox(reversedlist);
+			ActiveSelectionCombos[0].Active = 0;
+			ActiveSelectionCombos[1].Active = 0;
+				
+			ConnectFileSelectionGroupChanged(true);
+		} else {
+			ResetTextSelectionComboGroups();
+		}
+	}
+		
+	private void ResetTextSelectionComboGroups () {
+		foreach(FilexEncodingCombo combogroup in ActiveSelectionCombos) {
+			combogroup.FillComboBox(subtitleFiles);		
+		}		
+	}	
+
 	#pragma warning disable 169		//Disables warning about handlers not being used
 
 	protected override bool ProcessResponse (ResponseType response) {
 		if (response == ResponseType.Ok) {
-			chosenFilename = dialog.Filename;
-			chosenEncoding = encodingComboBox.ChosenEncoding;
-
-			if (Base.Config.PrefsDefaultsFileOpenEncodingOption == ConfigFileOpenEncodingOption.RememberLastUsed) {
-				int activeAction = encodingComboBox.ActiveSelection;
-				ConfigFileOpenEncoding activeOption = (ConfigFileOpenEncoding)Enum.ToObject(typeof(ConfigFileOpenEncoding), activeAction);
-				if (((int)activeOption) >= ((int)ConfigFileOpenEncoding.Fixed))
-					Base.Config.PrefsDefaultsFileOpenEncodingFixed = chosenEncoding.Name;
-				else
-					Base.Config.PrefsDefaultsFileOpenEncoding = activeOption;
-			}
-
-			if (videoComboBox.Active > 0) {
-				int videoFileIndex = videoComboBox.Active - 2;
-				chosenVideoUri = new Uri("file://" + videoFiles[videoFileIndex] as string);
-			}			
 			SetReturnValue(true);
 		}
 		return false;
 	}
 	
-	private void OnCurrentFolderChanged (object o, EventArgs args) {
-		FillVideoComboBoxBasedOnCurrentFolder();
+	private void OnCurrentFolderChangedGetTextFiles (object o, EventArgs args) {
+		subtitleFiles.Clear();
+		if (Directory.Exists(dialog.CurrentFolder)){
+			subtitleFiles = new List<string>(FileTools.GetFilesOfType(dialog.CurrentFolder, ValidFileTypes.Subtitle));
+			ResetTextSelectionComboGroups();
+		}
+	}
+		
+	private void OnCurrentFolderChangedGetVideoFiles (object o, EventArgs args) {
+		videoFiles.Clear();
+		if (Directory.Exists(dialog.CurrentFolder)) {
+			videoFiles = new List<string>(FileTools.GetFilesOfType(dialog.CurrentFolder, ValidFileTypes.Video));
+			selectedVideo.FillComboBox(videoFiles);
+		}
 	}
 	
-	private void OnSelectionChanged (object o, EventArgs args) {
-		if (autoChooseVideoFile)
-			SetActiveVideoFile();
+	private void OnSelectionGetTextFiles (object o, EventArgs args) {
+		List<string> selectedfiles = new List<string>(FileTools.GetFilesOfType(dialog.Filenames, ValidFileTypes.Subtitle));
+		if (selectedfiles.Count > ActiveSelectionCombos.Count)
+			selectedfiles.Clear();
+			
+		DisplayTextFiles(selectedfiles);
+	}
+		
+	private void OnSelectionGetVideoFiles (object o, EventArgs args) {
+		List<string> selectedfiles = new List<string>(FileTools.GetFilesOfType(dialog.Filenames, ValidFileTypes.Video));
+		if (selectedfiles.Count > 1)
+			selectedfiles.Clear();
+			
+		DisplayVideoFiles(selectedfiles);
+	}
+		
+	private void ConnectFileSelectionGroupChanged (bool toconnect) {
+		if (selectedSubtitle == null || selectedTranslation == null) 
+			return;
+			
+		if (toconnect) {
+			selectedSubtitle.FileSelectionChanged += OnSelectedSubtitleChanged;
+			selectedTranslation.FileSelectionChanged += OnSelectedTranslationChanged;
+		} else {
+			selectedSubtitle.FileSelectionChanged -= OnSelectedSubtitleChanged;
+			selectedTranslation.FileSelectionChanged -= OnSelectedTranslationChanged;		
+		}
 	}
 	
+	private void OnSelectedSubtitleChanged (object o, EventArgs args) {
+		if (selectedSubtitle.Active > -1 && selectedTranslation.Active > -1) {
+			selectedTranslation.Active = selectedSubtitle.Active;
+		}	
+	}
+	
+	private void OnSelectedTranslationChanged (object o, EventArgs args) {
+		if (selectedTranslation.Active > -1 && selectedSubtitle.Active > -1) {
+			selectedSubtitle.Active = selectedTranslation.Active;	
+		}
+	}
 }
-
-}
+}
\ No newline at end of file
diff --git a/src/GnomeSubtitles/Dialog/FileTranslationOpenDialog.cs b/src/GnomeSubtitles/Dialog/FileTranslationOpenDialog.cs
index f12c726..e13e589 100644
--- a/src/GnomeSubtitles/Dialog/FileTranslationOpenDialog.cs
+++ b/src/GnomeSubtitles/Dialog/FileTranslationOpenDialog.cs
@@ -17,25 +17,40 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+using System;
 using GnomeSubtitles.Core;
-using Mono.Unix;
+using GnomeSubtitles.Ui.Component;
 
-namespace GnomeSubtitles.Dialog {
-
-public class FileTranslationOpenDialog : FileOpenDialog {
-	
-	public FileTranslationOpenDialog () : base(false, Catalog.GetString("Open Translation File")) {
-	}
-	
-	/* Public members */
-	
-	protected override string GetStartFolder () {
+namespace GnomeSubtitles.Dialog
+{
+	public class TranslationFileOpenDialog : FileOpenDialog
+	{
+		public TranslationFileOpenDialog () : base(!Base.IsVideoLoaded, false, "Open Translation")
+		{
+			autoChooseTranslationFile = false;
+			
+			if (Base.IsDocumentLoaded)	{
+				AutoChooseTranslationFile(Base.Document.TextFile.Filename);
+				
+				if (!Base.IsVideoLoaded)
+					AutoChooseVideoFile(Base.Document.TextFile.Filename);
+			}
+		}
+		
+		/* Protected members */
+		
+		protected override string GetStartFolder () {
 		if (Base.IsDocumentLoaded && Base.Document.IsTranslationLoaded && Base.Document.HasTranslationFileProperties && Base.Document.TranslationFile.IsPathRooted)
 			return Base.Document.TranslationFile.Directory;
 		else
 			return base.GetStartFolder();
-	}
-
-}
+		}
 
+		/* Private members */
+		
+		protected override void InitSelectedSubtitleCombo () {
+			selectedTranslation = new FilexEncodingCombo(translationFileLabel ,translationFileComboBox, translationEncodingComboBox);
+			ActiveSelectionCombos.Add(selectedTranslation);
+		}
+	}
 }
diff --git a/src/GnomeSubtitles/Dialog/PreferencesDialog.cs b/src/GnomeSubtitles/Dialog/PreferencesDialog.cs
index 7be8fb2..707a319 100644
--- a/src/GnomeSubtitles/Dialog/PreferencesDialog.cs
+++ b/src/GnomeSubtitles/Dialog/PreferencesDialog.cs
@@ -42,6 +42,7 @@ public class PreferencesDialog : GladeDialog {
 	/* Widgets */
 	[WidgetAttribute] private CheckButton translationSaveAllCheckButton = null;
 	[WidgetAttribute] private CheckButton videoAutoChooseFileCheckButton = null;
+	[WidgetAttribute] private CheckButton translationAutoChooseFileCheckButton = null;
 	[WidgetAttribute] private CheckButton autoBackupCheckButton = null;
 	[WidgetAttribute] private CheckButton reactionDelayCheckButton = null;
 	[WidgetAttribute] private CheckButton videoSeekCheckButton = null;
@@ -80,6 +81,7 @@ public class PreferencesDialog : GladeDialog {
 
 		/* Video Auto choose file */
 		videoAutoChooseFileCheckButton.Active = Base.Config.PrefsVideoAutoChooseFile;
+		//translationSaveAllCheckButton.Active = Base.Config.PrefsTranslationAutoChooseFile;
 		
 		/* Auto Backup */
 		SetAutoBackup();
@@ -200,6 +202,7 @@ public class PreferencesDialog : GladeDialog {
 		fileOpenEncoding.ActiveSelection = 0; //Auto detect
 		fileOpenFallbackEncoding.ActiveSelection = 0; //Current Locale
 		videoAutoChooseFileCheckButton.Active = true;
+		translationAutoChooseFileCheckButton.Active = true;
 
 		fileSaveEncoding.ActiveSelection = 0; //Keep Existing
 		fileSaveFormat.ActiveSelection = 0; //Keep Existing
@@ -324,6 +327,10 @@ public class PreferencesDialog : GladeDialog {
 	private void OnVideoAutoChooseFileToggled (object o, EventArgs args) {
 		Base.Config.PrefsVideoAutoChooseFile = videoAutoChooseFileCheckButton.Active;
 	}
+		
+	private void OnTranslationAutoChooseFileToggled (object o, EventArgs args) {
+		Base.Config.PrefsTranslationAutoChooseFile = translationAutoChooseFileCheckButton.Active;		
+	}
 
 	private void OnTranslationSaveAllToggled (object o, EventArgs args) {
 		Base.Config.PrefsTranslationSaveAll = translationSaveAllCheckButton.Active;
diff --git a/src/GnomeSubtitles/Ui/Component/FileCombo.cs b/src/GnomeSubtitles/Ui/Component/FileCombo.cs
new file mode 100644
index 0000000..49305d2
--- /dev/null
+++ b/src/GnomeSubtitles/Ui/Component/FileCombo.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using GnomeSubtitles.Ui.Component;
+using Gtk;
+using Mono.Unix;
+
+namespace GnomeSubtitles.Ui.Component
+{
+	
+	public class FileCombo
+	{	
+		protected List<string> fileList;
+		protected ComboBox filesCombo = null;
+		protected Label label;
+		
+		public int Active {
+			get{return filesCombo.Active > 1 ? filesCombo.Active - 2 : -1;}
+			set{SetActiveItem(value);}
+		}
+		
+		public string ActiveSelection {
+			get{return filesCombo.Active > 1 ? fileList[filesCombo.Active -2] : null;}
+		}
+		
+		/* Events */
+	
+		public event EventHandler FileSelectionChanged;
+		
+		public FileCombo (Label newlabel, ComboBox newfilesCombo) {
+			filesCombo = newfilesCombo;
+			label = newlabel;
+			ComboBoxUtil.InitComboBox(filesCombo);
+			
+			label.Visible = true;
+			filesCombo.Visible = true;
+			
+		}
+
+		public void FillComboBox (IEnumerable<string> newlist) {
+			ConnectComboBoxChangedSignal(false);
+			
+			fileList = new List<string>(newlist);
+			(filesCombo.Model as ListStore).Clear();
+				
+			foreach (string file in fileList) {
+				filesCombo.AppendText(Path.GetFileName(file));
+			}
+			filesCombo.PrependText("-");
+			filesCombo.PrependText(Catalog.GetString("None"));
+			filesCombo.Active = 0;
+			
+			ConnectComboBoxChangedSignal(true);
+		}	
+		
+		private void SetActiveItem (int newactive) {
+			ConnectComboBoxChangedSignal(false);
+			
+			if (newactive == -1)
+				filesCombo.Active = 0;
+			else
+				filesCombo.Active = newactive + 2;
+			
+			ConnectComboBoxChangedSignal(true);
+		}
+		
+	
+		private void ConnectComboBoxChangedSignal (bool toconnect) {
+			if (toconnect) {
+				filesCombo.Changed += OnComboBoxChanged;
+			} else {
+				filesCombo.Changed -= OnComboBoxChanged;
+			}
+			
+		}
+		
+		/*Event Handlers */
+		
+		private void OnComboBoxChanged (object sender, EventArgs args) {
+			ComboBox o = filesCombo;
+			if (FileSelectionChanged != null)
+				FileSelectionChanged(o, args);
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/GnomeSubtitles/Ui/Component/FilexEncodingCombo.cs b/src/GnomeSubtitles/Ui/Component/FilexEncodingCombo.cs
new file mode 100644
index 0000000..dd2987f
--- /dev/null
+++ b/src/GnomeSubtitles/Ui/Component/FilexEncodingCombo.cs
@@ -0,0 +1,62 @@
+using System;
+using GnomeSubtitles.Core;
+using GnomeSubtitles.Ui.Component;
+using Gtk;
+
+namespace GnomeSubtitles.Ui.Component
+{
+	public class FilexEncodingCombo : FileCombo
+	{
+	protected EncodingComboBox encombo = null;
+		
+	protected ComboBox fileEncodingCombo = null;
+	
+	public EncodingDescription SelectedEncoding  {
+		get{GetSelectedEncoding(); return encombo.ChosenEncoding;}		
+	}
+	
+	public int EncomboActive {
+		get{return fileEncodingCombo.Active;}
+		set{fileEncodingCombo.Active = Active;}
+	}
+	
+	public FilexEncodingCombo (Label newlabel, ComboBox newfilesCombo, ComboBox newfileEncodingCombo ) : base(newlabel, newfilesCombo) {
+		fileEncodingCombo = newfileEncodingCombo;
+		InitEncodingComboBox();	
+		filesCombo.Changed += OnComboChanged;
+			
+		fileEncodingCombo.Visible = true;
+	}
+	
+	private void InitEncodingComboBox () { 
+		int fixedEncoding = -1;
+		ConfigFileOpenEncoding encodingConfig = Base.Config.PrefsDefaultsFileOpenEncoding;
+		if (encodingConfig == ConfigFileOpenEncoding.Fixed) {
+			string encodingName = Base.Config.PrefsDefaultsFileOpenEncodingFixed;
+			EncodingDescription encodingDescription = EncodingDescription.Empty;
+			Encodings.Find(encodingName, ref encodingDescription);
+			fixedEncoding = encodingDescription.CodePage;
+		}
+		this.encombo = new EncodingComboBox(fileEncodingCombo, true, null, fixedEncoding);
+		/* Only need to handle the case of currentLocale, as Fixed is handled before and AutoDetect is the default behaviour */
+		if (encodingConfig == ConfigFileOpenEncoding.CurrentLocale) {
+			encombo.ActiveSelection = (int)encodingConfig;
+		}
+	}	
+	
+	private void GetSelectedEncoding () {
+		if (Base.Config.PrefsDefaultsFileOpenEncodingOption == ConfigFileOpenEncodingOption.RememberLastUsed) {
+			int activeAction = encombo.ActiveSelection;
+			ConfigFileOpenEncoding activeOption = (ConfigFileOpenEncoding)Enum.ToObject(typeof(ConfigFileOpenEncoding), activeAction);
+			if (((int)activeOption) >= ((int)ConfigFileOpenEncoding.Fixed))
+				Base.Config.PrefsDefaultsFileOpenEncodingFixed = encombo.ChosenEncoding.Name;
+			else
+				Base.Config.PrefsDefaultsFileOpenEncoding = activeOption;
+		}		
+	}	
+			
+	private void OnComboChanged (object sender, EventArgs e) {
+		encombo.ActiveSelection = 0;		
+	}
+	}
+}
\ No newline at end of file
diff --git a/src/GnomeSubtitles/Ui/MainUi.cs b/src/GnomeSubtitles/Ui/MainUi.cs
index 19adc4e..4ca1cce 100644
--- a/src/GnomeSubtitles/Ui/MainUi.cs
+++ b/src/GnomeSubtitles/Ui/MainUi.cs
@@ -17,20 +17,17 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+using System;
+using System.Text;
 using GnomeSubtitles.Core;
-using GnomeSubtitles.Core.Command;
 using GnomeSubtitles.Dialog;
 using GnomeSubtitles.Dialog.Unmanaged;
 using GnomeSubtitles.Ui.Edit;
 using GnomeSubtitles.Ui.VideoPreview;
 using GnomeSubtitles.Ui.View;
 using Gtk;
-using Mono.Unix;
-using SubLib.Exceptions;
 using SubLib.Core.Domain;
-using System;
-using System.IO;
-using System.Text;
+using SubLib.Exceptions;
 
 namespace GnomeSubtitles.Ui {
 
@@ -101,9 +98,11 @@ public class MainUi {
     	string[] args = Base.ExecutionContext.Args;
     	if (args.Length > 0) {
     		string subtitleFile = args[0];
-    		Uri videoUri = Base.Config.PrefsVideoAutoChooseFile ? VideoFiles.FindMatchingVideo(subtitleFile) : null;
 			int codePage = GetFileOpenCodePageFromConfig();
-			Open(subtitleFile, codePage, videoUri);
+			Open(subtitleFile, codePage);
+			string videoFile = Base.Config.PrefsVideoAutoChooseFile ? FileTools.FromFolderFindMatchOfType(subtitleFile, ValidFileTypes.Video) : null;
+			if (videoFile != null)
+				Base.OpenVideo(FileTools.GetUriFromFilePath(videoFile));
 		}
     }
     
@@ -141,13 +140,40 @@ public class MainUi {
 		FileOpenDialog dialog = Base.Dialogs.Get(typeof(FileOpenDialog)) as FileOpenDialog;
     	dialog.Show();
     	bool gotOpenResponse = dialog.WaitForResponse();
-    	if (gotOpenResponse && ToOpenAfterWarning()) {
-    		string filename = dialog.Filename;
-    		int codePage = (dialog.Encoding.Equals(EncodingDescription.Empty) ? -1 : dialog.Encoding.CodePage);
-    		Uri videoUri = dialog.VideoUri;
-    		Open(filename, codePage, videoUri);
+    	if (gotOpenResponse) {
+    		if (dialog.SelectedSubtitle != null && ToOpenAfterWarning())
+				Open(dialog.SelectedSubtitle, dialog.SelectedSubtitleEncoding.CodePage);
+    		if (dialog.SelectedTranslation != null && ToOpenTranslationAfterWarning())
+				OpenTranslation(dialog.SelectedTranslation, dialog.SelectedTranslationEncoding.CodePage);
+			if (dialog.SelectedVideo != null)
+				Base.OpenVideo(dialog.SelectedVideo);
     	}
     }
+		
+	/// <summary>Shows the open translation dialog and possibly opens a file.</summary>
+    /// <remarks>If there's a translation currently open with unsaved changes, a warning dialog
+    /// is shown before opening the new file.</remarks>
+    public void TranslationOpen () {
+    	TranslationFileOpenDialog dialog = Base.Dialogs.Get(typeof(TranslationFileOpenDialog)) as TranslationFileOpenDialog;
+    	dialog.Show();
+    	bool toOpen = dialog.WaitForResponse();
+    	if (toOpen) {
+			if (ToOpenTranslationAfterWarning())
+    			OpenTranslation(dialog.SelectedTranslation, dialog.SelectedTranslationEncoding.CodePage);
+   			if (dialog.SelectedVideo != null)
+				Base.OpenVideo(dialog.SelectedVideo);	
+		}
+    }
+		
+	/// <summary>Opens the Open video dalog and possibly opens a file</summary> ///	
+	public void VideoOpen () {
+    	VideoOpenDialog dialog = Base.Dialogs.Get(typeof(VideoOpenDialog)) as VideoOpenDialog;
+    	dialog.Show();
+		bool toOpen = dialog.WaitForResponse();
+		if (toOpen) {
+			Base.OpenVideo(dialog.Uri);
+		}
+    }
 
 	/// <summary>Opens a subtitle.</summary>
 	/// <param name="filename">The path of the subtitles file to open.</param>
@@ -155,7 +181,7 @@ public class MainUi {
     /// is shown before opening the new file.</remarks>
     public void Open (string filename) {
 		if (ToOpenAfterWarning()) {
-			Open(filename, -1, null);
+			Open(filename, -1);
 		}
     }
         
@@ -204,20 +230,6 @@ public class MainUi {
 		Base.NewTranslation();
     }
     
-    /// <summary>Shows the open translation dialog and possibly opens a file.</summary>
-    /// <remarks>If there's a translation currently open with unsaved changes, a warning dialog
-    /// is shown before opening the new file.</remarks>
-    public void TranslationOpen () {
-    	FileOpenDialog dialog = Base.Dialogs.Get(typeof(FileTranslationOpenDialog)) as FileOpenDialog;
-    	dialog.Show();
-    	bool toOpen = dialog.WaitForResponse();
-    	if (toOpen && ToOpenTranslationAfterWarning()) {
-    		string filename = dialog.Filename;
-    		int codePage = (dialog.Encoding.Equals(EncodingDescription.Empty) ? -1 : dialog.Encoding.CodePage);
-    		OpenTranslation(filename, codePage);
-    	}
-    }
-    
     /// <summary>Executes a Save operation regarding the translation.</summary>
     /// <remarks>If the translation hasn't been saved before, a TranslationSaveAs is executed.</remarks>
     /// <returns>Whether the translation file was saved or not.</returns>
@@ -260,10 +272,10 @@ public class MainUi {
 	/// <param name="codePage">The code page of the filename. To use autodetection, set it to -1.</param>
 	/// <param name="videoUri">The URI of the video to open. If null, no video will be opened.</param>
 	/// <remarks>An error dialog is presented if an exception is caught during open.</remarks>
-    private void Open (string path, int codePage, Uri videoUri) {
+     private void Open (string path, int codePage) {
     	try {
     		Encoding encoding = CodePageToEncoding(codePage);
-    		Base.Open(path, encoding, videoUri);
+    		Base.Open(path, encoding, null);
 		}
 		catch (Exception exception) {
 			SubtitleFileOpenErrorDialog errorDialog = new SubtitleFileOpenErrorDialog(path, exception);
@@ -273,23 +285,6 @@ public class MainUi {
 				Open();
 		}
     }
-    
-    /// <summary>Creates an <see cref="Encoding" /> from a code page.</summary>
-    /// <param name="codePage">The code page.</param>
-    /// <returns>The respective <see cref="Encoding" />, or null if codePage == -1.</returns>
-    /// <exception cref="EncodingNotSupportedException">Thrown if a detected encoding is not supported by the platform.</exception>
-    //TODO move to util
-    private Encoding CodePageToEncoding (int codePage) {
-    	if (codePage == -1)
-    		return null;
-
-    	try {
-    		return Encoding.GetEncoding(codePage);
-    	}
-    	catch (NotSupportedException) {
-    		throw new EncodingNotSupportedException();
-    	}
-    }
 
     /// <summary>Opens a translation file, given its filename and code page.</summary>
 	/// <param name="path">The path of the translation file to open.</param>
@@ -308,6 +303,23 @@ public class MainUi {
 				Open();
 		}
     }
+	    
+    /// <summary>Creates an <see cref="Encoding" /> from a code page.</summary>
+    /// <param name="codePage">The code page.</param>
+    /// <returns>The respective <see cref="Encoding" />, or null if codePage == -1.</returns>
+    /// <exception cref="EncodingNotSupportedException">Thrown if a detected encoding is not supported by the platform.</exception>
+    //TODO move to util
+    private Encoding CodePageToEncoding (int codePage) {
+    	if (codePage == -1)
+    		return null;
+
+    	try {
+    		return Encoding.GetEncoding(codePage);
+    	}
+    	catch (NotSupportedException) {
+    		throw new EncodingNotSupportedException();
+    	}
+    }
 
     private void Save (FileProperties fileProperties) {
 		try {



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