diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece ICSharpCode.SharpZipLib.dll Binary file ICSharpCode.SharpZipLib.dll has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece INIFileParser.dll Binary file INIFileParser.dll has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece Interop.SHDocVw.dll Binary file Interop.SHDocVw.dll has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/App.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/App.config Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,116 @@ + + + + +
+
+
+
+
+
+ + + + + + + + True + + + True + + + True + + + + + + 200000 + + + 30 + + + 5 + + + 10 + + + 5 + + + + + + False + + + + + + .exe;.com + + + -a + + + + + + 5 + + + False + + + + + + + + + False + + + + + + 80 + + + + + + + + + + + + True + + + + + + + + + + + + + + + True + + + 3000 + + + + + diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/App.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/App.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,253 @@ +using System; +using System.Diagnostics; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; + +using MyDownloader.App; +using MyDownloader.App.UI; +using MyDownloader.App.SingleInstancing; + +using MyDownloader.Core; +using MyDownloader.Core.Extensions; +using MyDownloader.Core.UI; + +using MyDownloader.Extension; +using MyDownloader.Extension.AntiVirus; +using MyDownloader.Extension.Protocols; +using MyDownloader.Extension.Notifications; +using MyDownloader.Extension.Video; +using MyDownloader.Extension.AutoDownloads; +using MyDownloader.Extension.SpeedLimit; +using MyDownloader.Extension.PersistedList; +using MyDownloader.Extension.WindowsIntegration; + +using Microsoft.Test.CommandLineParsing; +using System.IO; + +namespace MyDownloader.App +{ + [Serializable] + public class App : IApp + { + #region Singleton + + private static App instance = new App(); + + public static App Instance + { + get + { + return instance; + } + } + + private App() + { + AppManager.Instance.Initialize(this); + + extensions = new List(); + + extensions.Add(new CoreExtention()); + extensions.Add(new HttpFtpProtocolExtension()); + extensions.Add(new VideoDownloadExtension()); + extensions.Add(new SpeedLimitExtension()); + extensions.Add(new PersistedListExtension()); + extensions.Add(new AntiVirusExtension()); + extensions.Add(new NotificationsExtension()); + extensions.Add(new AutoDownloadsExtension()); + extensions.Add(new WindowsIntegrationExtension()); + } + + #endregion + + #region Fields + + private List extensions; + private SingleInstanceTracker tracker = null; + private bool disposed = false; + + #endregion + + #region Properties + + public Form MainForm + { + get + { + return (MainForm)tracker.Enforcer; + } + } + + public NotifyIcon NotifyIcon + { + get + { + return ((UI.MainForm)MainForm).notifyIcon; + } + } + + public List Extensions + { + get + { + return extensions; + } + } + + #endregion + + #region Methods + + public IExtension GetExtensionByType(Type type) + { + for (int i = 0; i < this.extensions.Count; i++) + { + if (this.extensions[i].GetType() == type) + { + return this.extensions[i]; + } + } + + return null; + } + + private ISingleInstanceEnforcer GetSingleInstanceEnforcer() + { + return new MainForm(); + } + + public void InitExtensions() + { + for (int i = 0; i < Extensions.Count; i++) + { + if (Extensions[i] is IInitializable) + { + ((IInitializable)Extensions[i]).Init(); + } + } + + } + public void Dispose() + { + if (!disposed) + { + disposed = true; + for (int i = 0; i < Extensions.Count; i++) + { + if (Extensions[i] is IDisposable) + { + try + { + ((IDisposable)Extensions[i]).Dispose(); + } + catch (Exception ex) + { + Debug.WriteLine(ex.ToString()); + } + } + } + } + } + + public void Start(string[] args) + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + try + { + // Attempt to create a tracker + tracker = new SingleInstanceTracker("SingleInstanceSample", new SingleInstanceEnforcerRetriever(GetSingleInstanceEnforcer)); + + // If this is the first instance of the application, run the main form + if (tracker.IsFirstInstance) + { + try + { + NewDownloadForm df = null; + MainForm form = (MainForm)tracker.Enforcer; + + if (args.Length > 0) + { + //form.downloadList1.AddDownloadURLs(ResourceLocation.FromURLArray(args), 1, null, 0); + + CommandLineArguments argstruct = new CommandLineArguments(); + + argstruct.ParseArguments(args); + + + if (argstruct.StartMinimized == true) + form.WindowState = FormWindowState.Minimized; + + //DownloadManager.Instance.Add(ResourceLocation.FromURL(argstruct.File), null, Path.Combine(argstruct.path, Path.GetFileName(argstruct.File)), argstruct.Segments, true); + + // form.downloadList1.AddDownloadURLs(ResourceLocation.FromURL(argstruct.File), argstruct.Segments, argstruct.path, 0); + if (argstruct.File != null) + { + df = new NewDownloadForm(argstruct.File, Path.GetFileName(argstruct.File), argstruct.path, argstruct.Segments, argstruct.username, argstruct.password); + + df.Show(); + df.Focus(); + df.BringToFront(); + + } + + } + + form.Load += delegate(object sender, EventArgs e) + { + InitExtensions(); + + if (form.WindowState == FormWindowState.Minimized) + { + form.HideForm(); + } + + /*if (args.Length > 0) + { + form.OnMessageReceived(new MessageEventArgs(args)); + }*/ + }; + + + + form.FormClosing += delegate(object sender, FormClosingEventArgs e) + { + Dispose(); + }; + + Application.Run(form); + + + } + finally + { + Dispose(); + } + } + else + { + // This is not the first instance of the application, so do nothing but send a message to the first instance + if (args.Length > 0) + { + tracker.SendMessageToFirstInstance(args); + } + } + } + catch (SingleInstancingException ex) + { + MessageBox.Show("Could not create a SingleInstanceTracker object:\n" + ex.Message + "\nApplication will now terminate.\n" + ex.InnerException.ToString()); + + return; + } + finally + { + if (tracker != null) + tracker.Dispose(); + } + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/CommandLineArguments.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/CommandLineArguments.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Test.CommandLineParsing; +using System.ComponentModel; +using System.IO; + +namespace MyDownloader.App +{ + class CommandLineArguments + { + public CommandLineArguments() + { + this.path = Path.Combine(System.Environment.GetEnvironmentVariable("USERPROFILE"), "Downloads"); + Segments = 1; + username = ""; + password = ""; + } + + [Description("Starts the application minimized to the tray.")] + public bool? StartMinimized { get; set; } + + // Backwards compatibility + public bool? @as { get { return this.StartMinimized; } set { this.StartMinimized = value; } } + + public string File { get; set; } + + public int Segments { get; set; } + + public string path { get; set; } + + public string username { get; set; } + + public string password { get; set; } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/CommandLineParsing/Command.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/CommandLineParsing/Command.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,77 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using System; + +namespace Microsoft.Test.CommandLineParsing +{ + /// + /// Provides a base class for the functionality that all commands must implement. + /// + /// + /// + /// The following example shows parsing of a command-line such as "Test.exe RUN /verbose /runId=10" + /// into a strongly-typed Command, that can then be excuted. + /// + /// using System; + /// using System.Linq; + /// using Microsoft.Test.CommandLineParsing; + /// + /// public class RunCommand : Command + /// { + /// public bool? Verbose { get; set; } + /// public int? RunId { get; set; } + /// + /// public override void Execute() + /// { + /// Console.WriteLine("RunCommand: Verbose={0} RunId={1}", Verbose, RunId); + /// } + /// } + /// + /// public class Program + /// { + /// public static void Main(string[] args) + /// { + /// if (String.Compare(args[0], "run", StringComparison.InvariantCultureIgnoreCase) == 0) + /// { + /// Command c = new RunCommand(); + /// c.ParseArguments(args.Skip(1)); // or CommandLineParser.ParseArguments(c, args.Skip(1)) + /// c.Execute(); + /// } + /// } + /// } + /// + /// + public abstract class Command + { + /// + /// The name of the command. The base implementation is to strip off the last + /// instance of "Command" from the end of the type name. So "DiscoverCommand" + /// would become "Discover". If the type name does not have the string "Command" in it, + /// then the name of the command is the same as the type name. This behavior can be + /// overridden, but most derived classes are going to be of the form [Command Name] + Command. + /// + public virtual string Name + { + get + { + string typeName = this.GetType().Name; + if (typeName.Contains("Command")) + { + return typeName.Remove(typeName.LastIndexOf("Command", StringComparison.Ordinal)); + } + else + { + return typeName; + } + } + } + + /// + /// Executes the command. + /// + public abstract void Execute(); + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/CommandLineParsing/CommandLineDictionary.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/CommandLineParsing/CommandLineDictionary.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,206 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Runtime.Serialization; + +namespace Microsoft.Test.CommandLineParsing +{ + /// + /// Represents a dictionary that is aware of command line input patterns. All lookups for keys ignore case. + /// + /// + /// + /// The example below demonstrates parsing a command line such as "Test.exe /verbose /runId=10" + /// + /// CommandLineDictionary d = CommandLineDictionary.FromArguments(args); + /// + /// bool verbose = d.ContainsKey("verbose"); + /// int runId = Int32.Parse(d["runId"]); + /// + /// + /// + /// + /// You can also explicitly provide key and value identifiers for the cases + /// that use other characters (rather than '/' and '=') as key/value identifiers. + /// The example below demonstrates parsing a command line such as "Test.exe -verbose -runId:10" + /// + /// CommandLineDictionary d = CommandLineDictionary.FromArguments(args, '-', ':'); + /// + /// bool verbose = d.ContainsKey("verbose"); + /// int runId = Int32.Parse(d["runId"]); + /// + /// + [Serializable] + public class CommandLineDictionary : Dictionary + { + #region Constructors + + /// + /// Create an empty CommandLineDictionary using the default key/value + /// separators of '/' and '='. + /// + public CommandLineDictionary() + : base(StringComparer.OrdinalIgnoreCase) + { + KeyCharacter = '/'; + ValueCharacter = '='; + } + + /// + /// Creates a dictionary using a serialization info and context. This + /// is used for Xml deserialization and isn't normally called from user code. + /// + /// Data needed to deserialize the dictionary. + /// Describes source and destination of the stream. + protected CommandLineDictionary(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + #endregion + + #region Public Members + + /// + /// Initializes a new instance of the CommandLineDictionary class, populating a + /// dictionary with key/value pairs from a command line that supports syntax + /// where options are provided in the form "/key=value". + /// + /// Key/value pairs. + /// + public static CommandLineDictionary FromArguments(IEnumerable arguments) + { + return FromArguments(arguments, '/', '='); + } + + /// + /// Creates a dictionary that is populated with key/value pairs from a command line + /// that supports syntax where options are provided in the form "/key=value". + /// This method supports the ability to specify delimiter characters for options in + /// the command line. + /// + /// Key/value pairs. + /// A character that precedes a key. + /// A character that separates a key from a value. + /// + public static CommandLineDictionary FromArguments(IEnumerable arguments, char keyCharacter, char valueCharacter) + { + CommandLineDictionary cld = new CommandLineDictionary(); + cld.KeyCharacter = keyCharacter; + cld.ValueCharacter = valueCharacter; + foreach (string argument in arguments) + { + cld.AddArgument(argument); + } + + return cld; + } + + #endregion + + #region Override Members + + /// + /// Converts dictionary contents to a command line string of key/value pairs. + /// + /// Command line string. + public override string ToString() + { + string commandline = String.Empty; + foreach (KeyValuePair pair in this) + { + if (!string.IsNullOrEmpty(pair.Value)) + { + commandline += String.Format(CultureInfo.InvariantCulture, "{0}{1}{2}{3} ", KeyCharacter, pair.Key, ValueCharacter, pair.Value); + } + else // There is no value, so we just serialize the key + { + commandline += String.Format(CultureInfo.InvariantCulture, "{0}{1} ", KeyCharacter, pair.Key); + } + } + return commandline.TrimEnd(); + } + + #endregion + + #region Protected Members + + /// + /// Populates a SerializationInfo with data needed to serialize the dictionary. + /// This is used by Xml serialization and isn't normally called from user code. + /// + /// SerializationInfo object to populate. + /// StreamingContext to populate data from. + [SuppressMessage("Microsoft.Security", "CA2123")] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + } + + #endregion + + #region Private Members + + /// + /// Character to treat as the key character in the value line. + /// If the arguments should be of the form /Foo=Bar, then the + /// key character is /. (Which is the default) + /// + private char KeyCharacter { get; set; } + + /// + /// Character to treat as the value character in the value line. + /// If the arguments should be of the form /Foo=Bar, then the + /// value character is =. (Which is the default) + /// + private char ValueCharacter { get; set; } + + /// + /// Adds the specified argument to the dictionary + /// + /// Key/Value pair argument. + private void AddArgument(string argument) + { + if (argument == null) + { + throw new ArgumentNullException("argument"); + } + + string key; + string value; + + if (argument.StartsWith(KeyCharacter.ToString(), StringComparison.OrdinalIgnoreCase)) + { + string[] splitArg = argument.Substring(1).Split(ValueCharacter); + + //Key is extracted from first element + key = splitArg[0]; + + //Reconstruct the value. We could also do this using substrings. + if (splitArg.Length > 1) + { + value = string.Join("=", splitArg, 1, splitArg.Length - 1); + } + else + { + value = string.Empty; + } + } + else + { + throw new ArgumentException("Unsupported value line argument format.", argument); + } + + Add(key, value); + } + + #endregion + } +} + diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/CommandLineParsing/CommandLineParser.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/CommandLineParsing/CommandLineParser.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,425 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace Microsoft.Test.CommandLineParsing +{ + /// + /// Provides utilities for parsing command-line values. + /// + /// + /// + /// The following example shows parsing of a command-line such as "Test.exe /verbose /runId=10" + /// into a strongly-typed structure. + /// + /// using System; + /// using System.Linq; + /// using Microsoft.Test.CommandLineParsing; + /// + /// public class CommandLineArguments + /// { + /// public bool? Verbose { get; set; } + /// public int? RunId { get; set; } + /// } + /// + /// public class Program + /// { + /// public static void Main(string[] args) + /// { + /// CommandLineArguments a = new CommandLineArguments(); + /// a.ParseArguments(args); // or CommandLineParser.ParseArguments(a, args); + /// + /// Console.WriteLine("Verbose: {0}, RunId: {1}", a.Verbose, a.RunId); + /// } + /// } + /// + /// + /// + /// + /// The following example shows parsing of a command-line such as "Test.exe RUN /verbose /runId=10" + /// into a strongly-typed Command, that can then be excuted. + /// + /// using System; + /// using System.Linq; + /// using Microsoft.Test.CommandLineParsing; + /// + /// public class RunCommand : Command + /// { + /// public bool? Verbose { get; set; } + /// public int? RunId { get; set; } + /// + /// public override void Execute() + /// { + /// Console.WriteLine("RunCommand: Verbose={0} RunId={1}", Verbose, RunId); + /// } + /// } + /// + /// public class Program + /// { + /// public static void Main(string[] args) + /// { + /// if (String.Compare(args[0], "run", StringComparison.InvariantCultureIgnoreCase) == 0) + /// { + /// Command c = new RunCommand(); + /// c.ParseArguments(args.Skip(1)); // or CommandLineParser.ParseArguments(c, args.Skip(1)) + /// c.Execute(); + /// } + /// } + /// } + /// + /// + public static class CommandLineParser + { + #region Constructors + + /// + /// Static constructor. + /// + static CommandLineParser() + { + // The parser will want to convert from value line string arguments into various + // data types on a value. Any type that doesn't have a default TypeConverter that + // can convert from string to it's type needs to have a custom TypeConverter written + // for it, and have it added here. + TypeDescriptor.AddAttributes(typeof(DirectoryInfo), new TypeConverterAttribute(typeof(DirectoryInfoConverter))); + TypeDescriptor.AddAttributes(typeof(FileInfo), new TypeConverterAttribute(typeof(FileInfoConverter))); + } + + #endregion + + #region Public Members + + /// + /// Sets properties on an object from a series of key/value string + /// arguments that are in the form "/PropertyName=Value", where the + /// value is converted from a string into the property type. + /// + /// The object to set properties on. + /// The key/value arguments describing the property names and values to set. + /// + /// Indicates whether the properties were successfully set. Reasons for failure reasons include + /// a property name that does not exist or a value that cannot be converted from a string. + /// + /// Thrown when one of the key/value strings cannot be parsed into a property. + public static void ParseArguments(this object valueToPopulate, IEnumerable args) + { + CommandLineDictionary commandLineDictionary = CommandLineDictionary.FromArguments(args); + + PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(valueToPopulate); + + // Ensure required properties are specified. + foreach (PropertyDescriptor property in properties) + { + // See whether any of the attributes on the property is a RequiredAttribute. + if (property.Attributes.Cast().Any(attribute => attribute is RequiredAttribute)) + { + // If so, and the command line dictionary doesn't contain a key matching + // the property's name, it means that a required property isn't specified. + if (!commandLineDictionary.ContainsKey(property.Name)) + { + throw new ArgumentException("A value for the " + property.Name + " property is required."); + } + } + } + + foreach (KeyValuePair keyValuePair in commandLineDictionary) + { + // Find a property whose name matches the kvp's key, ignoring case. + // We can't just use the indexer because that is case-sensitive. + PropertyDescriptor property = MatchProperty(keyValuePair.Key, properties,valueToPopulate.GetType()); + + // If the value is null/empty and the property is a bool, we + // treat it as a flag, which means its presence means true. + if (String.IsNullOrEmpty(keyValuePair.Value) && + (property.PropertyType == typeof(bool) || property.PropertyType == typeof(bool?))) + { + property.SetValue(valueToPopulate, true); + continue; + } + + object valueToSet; + + // We support a limited set of collection types. Setting a List + // is one of the most flexible types as it supports three different + // interfaces, but the catch is that we don't support the concrete + // Collection type. We can expand it to support Collection + // in the future, but the code will get a bit uglier. + switch (property.PropertyType.Name) + { + case "IEnumerable`1": + case "ICollection`1": + case "IList`1": + case "List`1": + MethodInfo methodInfo = typeof(CommandLineParser).GetMethod("FromCommaSeparatedList", BindingFlags.Static | BindingFlags.NonPublic); + Type[] genericArguments = property.PropertyType.GetGenericArguments(); + MethodInfo genericMethodInfo = methodInfo.MakeGenericMethod(genericArguments); + valueToSet = genericMethodInfo.Invoke(null, new object[] { keyValuePair.Value }); + break; + default: + TypeConverter typeConverter = TypeDescriptor.GetConverter(property.PropertyType); + if (typeConverter == null || !typeConverter.CanConvertFrom(typeof(string))) + { + throw new ArgumentException("Unable to convert from a string to a property of type " + property.PropertyType + "."); + } + valueToSet = typeConverter.ConvertFromInvariantString(keyValuePair.Value); + break; + } + + property.SetValue(valueToPopulate, valueToSet); + } + + return; + } + + /// + /// Match the property to the specified keyName + /// + /// If match cannot be found, throw an argument exception + /// + private static PropertyDescriptor MatchProperty(string keyName, PropertyDescriptorCollection properties, Type targetType) + { + foreach(PropertyDescriptor prop in properties) + { + if(prop.Name.Equals(keyName, StringComparison.OrdinalIgnoreCase)) + { + return prop; + } + } + throw new ArgumentException("A matching public property of name " + keyName + " on type " + targetType + " could not be found."); + } + + /// + /// Prints names and descriptions for properties on the specified component. + /// + /// The component to print usage for. + public static void PrintUsage(object component) + { + IEnumerable properties = TypeDescriptor.GetProperties(component).Cast(); + IEnumerable propertyNames = properties.Select(property => property.Name); + IEnumerable propertyDescriptions = properties.Select(property => property.Description); + IEnumerable lines = FormatNamesAndDescriptions(propertyNames, propertyDescriptions, Console.WindowWidth); + + Console.WriteLine("Possible arguments:"); + foreach (string line in lines) + { + Console.WriteLine(line); + } + } + + /// + /// Prints a general summary of each command. + /// + /// A collection of possible commands. + public static void PrintCommands(IEnumerable commands) + { + // Print out general descriptions for every command. + IEnumerable commandNames = commands.Select(command => command.Name); + IEnumerable commandDescriptions = commands.Select(command => command.GetAttribute().Description); + IEnumerable lines = FormatNamesAndDescriptions(commandNames, commandDescriptions, Console.WindowWidth); + + Console.WriteLine("Possible commands:"); + foreach (string line in lines) + { + Console.WriteLine(line); + } + } + + /// + /// Creates a string that represents key/value arguments for the properties of the + /// specified object. For example, an object with a name (string) of "example" and a + /// priority value (integer) of 1 translates to '/name=example /priority=1'. This + /// can be used to send data structures through the command line. + /// + /// Value to create key/value arguments from. + /// Space-delimited key/value arguments. + public static string ToString(object valueToConvert) + { + IEnumerable properties = TypeDescriptor.GetProperties(valueToConvert).Cast(); + IEnumerable propertiesOnParent = TypeDescriptor.GetProperties(valueToConvert.GetType().BaseType).Cast(); + properties = properties.Except(propertiesOnParent); + CommandLineDictionary commandLineDictionary = new CommandLineDictionary(); + + foreach (PropertyDescriptor property in properties) + { + commandLineDictionary[property.Name] = property.GetValue(valueToConvert).ToString(); + } + + return commandLineDictionary.ToString(); + } + + #endregion + + #region Private Members + + /// + /// Given collections of names and descriptions, returns a set of lines + /// where the description text is wrapped and left aligned. eg: + /// First Name this is a string that wraps around + /// and is left aligned. + /// Second Name this is another string. + /// + /// Collection of name strings. + /// Collection of description strings. + /// Maximum length of formatted lines + /// Formatted lines of text. + private static IEnumerable FormatNamesAndDescriptions(IEnumerable names, IEnumerable descriptions, int maxLineLength) + { + if (names.Count() != descriptions.Count()) + { + throw new ArgumentException("Collection sizes are not equal", "names"); + } + + int namesMaxLength = names.Max(commandName => commandName.Length); + + List lines = new List(); + + for (int i = 0; i < names.Count(); i++) + { + string line = names.ElementAt(i); + line = line.PadRight(namesMaxLength + 2); + + foreach (string wrappedLine in WordWrap(descriptions.ElementAt(i), maxLineLength - namesMaxLength - 3)) + { + line += wrappedLine; + lines.Add(line); + line = new string(' ', namesMaxLength + 2); + } + } + + return lines; + } + + /// + /// Convert a comma separated list to a List of T. There must be a + /// TypeConverter for the collection type that can convert from a string. + /// "1,2,3" => List(int) containing 1, 2, and 3. + /// Commas in the textual representation itself should be escaped with + /// a blackslash, as should backslash itself. + /// + /// Type of objects in the collection. + /// Comma separated list representation. + /// Collection of objects. + private static List FromCommaSeparatedList(this string commaSeparatedList) + { + List collection = new List(); + + TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(T)); + if (typeConverter.CanConvertFrom(typeof(string))) + { + StringBuilder builder = new StringBuilder(); + bool isEscaped = false; + + foreach (char character in commaSeparatedList) + { + // If we are in escaped mode, add the character and exit escape mode + if (isEscaped) + { + builder.Append(character); + isEscaped = false; + } + // If we see the backslash and are not in escaped mode, go into escaped mode + else if (character == '\\' && !isEscaped) + { + isEscaped = true; + } + // A comma outside of escaped mode is an item separator, convert + // built string to T and add to collection, then zero out the builder + else if (character == ',' && !isEscaped) + { + collection.Add((T)typeConverter.ConvertFromInvariantString(builder.ToString())); + builder.Length = 0; + } + // Otherwise simply add the character + else + { + builder.Append(character); + } + } + + // If builder.Length is non-zero, of course we want to add it. + // If, however, it is zero, it can mean one of two things: + // - There are no items at all, i.e. the commaSeparatedList string + // is null/empty, and we should return an empty collection. + // - The builder just got flushed by a comma, and there is one last + // item in the collection to add that should be typeconverted + // from an empty string. + // collection.Count is always 0 for the former and greater than 0 + // for the later, so we will also add if Count > 0. + if (builder.Length > 0 || collection.Count > 0) + { + collection.Add((T)typeConverter.ConvertFromInvariantString(builder.ToString())); + } + } + + return collection; + } + + /// + /// Gets an attribute on the specified object instance. + /// + /// Type of attribute to get. + /// Object instance to look for attribute on. + /// First instance of the specified attribute. + private static T GetAttribute(this object value) where T : Attribute + { + IEnumerable attributes = TypeDescriptor.GetAttributes(value).Cast(); + return (T)attributes.First(attribute => attribute is T); + } + + /// + /// Word wrap text for a specified maximum line length. + /// + /// Text to word wrap. + /// Maximum length of a line. + /// Collection of lines for the word wrapped text. + private static IEnumerable WordWrap(string text, int maxLineLength) + { + List lines = new List(); + string currentLine = String.Empty; + + foreach (string word in text.Split(' ')) + { + // Whenever adding the word would push us over the maximum + // width, add the current line to the lines collection and + // begin a new line. The new line starts with space padding + // it to be left aligned with the previous line of text from + // this column. + if (currentLine.Length + word.Length > maxLineLength) + { + lines.Add(currentLine); + currentLine = String.Empty; + } + + currentLine += word; + + // Add spaces between words except for when we are at exactly the + // maximum width. + if (currentLine.Length != maxLineLength) + { + currentLine += " "; + } + } + + // Add the remainder of the current line except for when it is + // empty, which is true in the case when we had just started a + // new line. + if (currentLine.Trim() != String.Empty) + { + lines.Add(currentLine); + } + + return lines; + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/CommandLineParsing/DirectoryInfoConverter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/CommandLineParsing/DirectoryInfoConverter.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,47 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using System; +using System.ComponentModel; +using System.IO; + +namespace Microsoft.Test.CommandLineParsing +{ + /// + /// Converter that can convert from a string to a DirectoryInfo. + /// + public class DirectoryInfoConverter : TypeConverter + { + /// + /// Converts from a string to a DirectoryInfo. + /// + /// Context. + /// Culture. + /// Value to convert. + /// DirectoryInfo, or null if value was null or non-string. + public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) + { + if (value is string && value != null) + { + return new DirectoryInfo((string)value); + } + else + { + return null; + } + } + + /// + /// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context. + /// + /// An ITypeDescriptorContext that provides a format context. + /// A Type that represents the type you want to convert from. + /// True if this converter can perform the conversion; otherwise, False. + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return (sourceType == typeof(string)); + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/CommandLineParsing/FileInfoConverter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/CommandLineParsing/FileInfoConverter.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,70 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using System; +using System.ComponentModel; +using System.IO; + +namespace Microsoft.Test.CommandLineParsing +{ + /// + /// Converter that can convert from a string to a FileInfo. + /// + public class FileInfoConverter : TypeConverter + { + /// + /// Converts from a string to a FileInfo. + /// + /// Context. + /// Culture. + /// Value to convert. + /// FileInfo, or null if value was null or non-string. + public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) + { + if (value is string && value != null) + { + return new FileInfo((string)value); + } + else + { + return null; + } + } + + /// + /// Returns whether this converter can convert an object of the given type to a FileInfo. + /// + /// An ITypeDescriptorContext that provides a format context. + /// A Type that represents the type you want to convert from. + /// True if this converter can perform the conversion; otherwise, False. + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return (sourceType == typeof(string)); + } + + /// + /// Converts from a FileInfo to a string. + /// + public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) + { + if (value is FileInfo && destinationType == typeof(string)) + { + return ((FileInfo)value).FullName; + } + else + { + return null; + } + } + + /// + /// Returns whether this converter can convert a FileInfo object to the specified type. + /// + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + return (destinationType == typeof(string)); + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/CommandLineParsing/NamespaceDoc.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/CommandLineParsing/NamespaceDoc.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,19 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +namespace Microsoft.Test.CommandLineParsing +{ + /// + /// Contains a full-featured API for command-line parsing. The API is exposed + /// in several decoupled layers – from a string-based command-line dictionary, + /// to a strongly-typed command-line parser. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1812")] + [System.Runtime.CompilerServices.CompilerGenerated()] + class NamespaceDoc + { + // Empty class used only for generation of namespace comments. + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/CommandLineParsing/RequiredAttribute.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/CommandLineParsing/RequiredAttribute.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,21 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using System; + +namespace Microsoft.Test.CommandLineParsing +{ + /// + /// Defines whether a property value is required to be specified. + /// + [AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)] + public sealed class RequiredAttribute : Attribute + { + /// + public RequiredAttribute() + { + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/Controls/Block.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/Controls/Block.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.App.Controls +{ + [Serializable()] + public class Block + { + private float _blockSize = 0; + private float _percentProgress = 0; + + public Block(float BlockSize, float PercentProgress) + { + this.BlockSize = BlockSize; + this.PercentProgress = PercentProgress; + } + + public float BlockSize + { + get { return _blockSize; } + set { _blockSize = value; } + } + + public float PercentProgress + { + get { return _percentProgress; } + set { _percentProgress = value; } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/Controls/BlockList.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/Controls/BlockList.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.App.Controls +{ + [Serializable()] + public class BlockList + { + private int _length = 0; + private List _blockList; + + public BlockList() + { + _blockList = new List(); + } + + public enum UpdateMode + { + All, + FilledSegments, + FullListSegment, + BlockList + } + + /// + /// Update mode of segments + /// + public UpdateMode Update = UpdateMode.All; + + /// + /// Change quantity of segments + /// + public int Length + { + get { return _length; } + set + { + if (_length != value && value > 0) + { + bool[] bools = FullListSegment; + bool[] bools2 = new bool[value]; + for (int i = 0; i < bools.Length; i++) + bools2[i] = bools[i]; + FullListSegment = bools2; + } + } + } + /// + /// Get or set filled segments + /// + public int[] FilledSegments + { + get + { + bool[] bools = FullListSegment; + List filled = new List(); ; + for (int i = 0; i < bools.Length; i++) + if (bools[i]) filled.Add(i); + return filled.ToArray(); + } + set + { + if (Update != UpdateMode.All && Update != UpdateMode.FilledSegments) + throw new InvalidOperationException(); + if (value != null) + if (value.Length > 0) + { + bool[] bools = FullListSegment; + for (int i = 0; i < value.Length; i++) + bools.SetValue(true, value[i]); + FullListSegment = bools; + } + } + } + /// + /// Get or sets the full list of segments + /// + public bool[] FullListSegment + { + get + { + int size_anterior = 0; + bool[] bools = new bool[_length]; + if (bools.Length > 0) + { + foreach (Block block in _blockList) + { + for (int i = 0; i < Convert.ToInt32(block.BlockSize * block.PercentProgress / 100); i++) + bools.SetValue(true, i + size_anterior); + size_anterior += Convert.ToInt32(block.BlockSize); + } + } + return bools; + } + set + { + if (Update != UpdateMode.All && Update != UpdateMode.FullListSegment) + throw new InvalidOperationException(); + + bool b_old = false; + int qtd = 0; + int filled = 0; + float percent = 0; + if (value != null) + { + if (value.Length > 0) + { + _blockList.Clear(); + foreach (bool b in value) + { + if (b == b_old) + qtd++; + else + { + if (b_old) + filled = qtd; + else if (filled + qtd > 0) + { + percent = (float)filled / (float)(filled + qtd) * (float)100; + _blockList.Add(new Block(filled + qtd, percent)); + } + qtd = 1; + b_old = b; + } + } + if (filled + qtd > 0) + { + percent = (float)filled / (float)(filled + qtd) * (float)100; + _blockList.Add(new Block(filled + qtd, percent)); + } + _length = value.Length; + } + } + else + { + _length = 0; + } + } + } + /// + /// Get or set the block list of segments + /// + public List List + { + get + { + return _blockList; + } + set + { + if (Update != UpdateMode.All && Update != UpdateMode.BlockList) + throw new InvalidOperationException(); + float size = 0; + _blockList = value; + if (_blockList != null) + foreach (Block block in _blockList) + size += block.BlockSize; + _length = Convert.ToInt32(size); + } + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/Controls/BlockedProgressBar.bmp Binary file MyDownloader.App/Controls/BlockedProgressBar.bmp has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/Controls/BlockedProgressBar.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/Controls/BlockedProgressBar.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.App.Controls +{ + [ToolboxBitmap(typeof(BlockedProgressBar), "BlockedProgressBar.bmp")] //without namespace + public partial class BlockedProgressBar : Control + { + BlockList _blockList; + + /// + /// MyProgressBar Constructor + /// + public BlockedProgressBar() + { + InitializeComponent(); + _blockList = new BlockList(); + _direction = DirectionMode.Horizontal; + SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer, true); + } + /// + /// Update mode of segments + /// + [Description("The mode of update of progress bar")] + [Category("MyProgressBar")] + [RefreshProperties(RefreshProperties.All)] + public BlockList.UpdateMode UpdateMode + { + get { return _blockList.Update; } + set { _blockList.Update = value; } + } + + /// + /// Change quantity of segments + /// + [Description("The length of segments of progress bar")] + [Category("MyProgressBar")] + [RefreshProperties(RefreshProperties.All)] + public int Length + { + get { return _blockList.Length; } + set { _blockList.Length = value; this.Refresh(); } + } + /// + /// Get or set filled segments + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public int[] FilledSegments + { + get { return _blockList.FilledSegments; } + set { _blockList.FilledSegments = value; this.Refresh(); } + } + /// + /// Get or sets the full list of segments + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public bool[] FullListSegment + { + get { return _blockList.FullListSegment; } + set { _blockList.FullListSegment = value; this.Refresh(); } + } + /// + /// Get or set the block list of segments + /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public List BlockList + { + get { return _blockList.List; } + set { _blockList.List = value; this.Refresh(); } + } + /// + /// DirectionMode of bar + /// + public enum DirectionMode : int + { + Horizontal = 0, + Vertical = 1 + } + private DirectionMode _direction = DirectionMode.Horizontal; + /// + /// Horizontal or Vertical + /// + [Description("The filling direction of progress bar")] + [Category("MyProgressBar")] + [RefreshProperties(RefreshProperties.All)] + public DirectionMode Direction + { + get { return _direction; } + set { _direction = value; this.Refresh(); } + } + /// + /// OnPaint event + /// + /// + protected override void OnPaint(PaintEventArgs pe) + { + Color Color1 = ControlPaint.Dark(this.ForeColor); + Color Color2 = ControlPaint.Light(this.ForeColor); + + if (_direction == DirectionMode.Horizontal) + { + int top = ClientRectangle.Top + ClientRectangle.Height / 2 - 1; + int height = ClientRectangle.Height - top; + DrawRectangleH(pe, top, height, Color2, Color1); + + top = ClientRectangle.Top; + height = ClientRectangle.Height / 2; + DrawRectangleH(pe, top, height, Color1, Color2); + } + else + { + int left = ClientRectangle.Left; + int width = ClientRectangle.Width / 2; + DrawRectangleV(pe, left, width, Color1, Color2); + + left = ClientRectangle.Left + ClientRectangle.Width / 2; + width = ClientRectangle.Width / 2; + DrawRectangleV(pe, left, width, Color2, Color1); + } + + pe.Graphics.DrawRectangle(new Pen(Color.Black), ClientRectangle); + base.OnPaint(pe); + } + private void DrawRectangleH(PaintEventArgs pe, int top, int height, Color fromColor, Color toColor) + { + Rectangle rect = new Rectangle(ClientRectangle.Left, top, ClientRectangle.Width, height); + LinearGradientBrush brush = new LinearGradientBrush(rect, fromColor, toColor, LinearGradientMode.Vertical); + if (_blockList.Length > 0) + { + Rectangle[] rects = GetRectanglesH(top, height); + if (rects.Length > 0) pe.Graphics.FillRectangles(brush, rects); //SystemBrushes.Control + } + } + private void DrawRectangleV(PaintEventArgs pe, int left, int width, Color fromColor, Color toColor) + { + Rectangle rect = new Rectangle(left, ClientRectangle.Top, width, ClientRectangle.Height); + LinearGradientBrush brush = new LinearGradientBrush(rect, fromColor, toColor, LinearGradientMode.Horizontal); + if (_blockList.Length > 0) + { + Rectangle[] rects = GetRectanglesV(left, width); + if (rects.Length > 0) pe.Graphics.FillRectangles(brush, rects); //SystemBrushes.Control + } + } + private Rectangle[] GetRectanglesH(int top, int height) + { + List rects = new List(); + float xf = 0, wf = 0, pf = 1; + int x = 0, y = top, w = 0, h = height; + + pf = (float)this.Width / (float)_blockList.Length; + //h = this.Height; + + foreach (Block block in _blockList.List) + { + if (block.PercentProgress > 0) + { + x = Convert.ToInt32(xf); + wf = (pf * (block.BlockSize * block.PercentProgress / 100)) + xf - x; + w = Convert.ToInt32(wf); + + rects.Add(new Rectangle(x, y, w, h)); + } + + xf += pf * block.BlockSize; + } + return rects.ToArray(); + } + + private Rectangle[] GetRectanglesV(int left, int width) + { + List rects = new List(); + float yf = 0, hf = 0, pf = 1; + int x = left, y = 0, w = width, h = 0; + + pf = (float)this.Height / (float)_blockList.Length; + //w = this.Width; + + foreach (Block block in _blockList.List) + { + if (block.PercentProgress > 0) + { + y = Convert.ToInt32(yf); + hf = (pf * (block.BlockSize * block.PercentProgress / 100)) + yf - y; + h = Convert.ToInt32(hf); + + rects.Add(new Rectangle(x, y, w, h)); + } + + yf += pf * block.BlockSize; + } + return rects.ToArray(); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/Controls/BlockedProgressBar.designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/Controls/BlockedProgressBar.designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,36 @@ +using System.Collections; +namespace MyDownloader.App.Controls +{ + partial class BlockedProgressBar + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/Controls/CheckableTreeView.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/Controls/CheckableTreeView.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.App.Controls +{ + public class CheckableTreeView: TreeView + { + private static bool IsSomeChildNodeChecked(TreeNode node) + { + for (int i = 0; i < node.Nodes.Count; i++) + { + if (node.Nodes[i].Checked) + { + return true; + } + } + + return false; + } + + private static void CheckAllChildren(TreeNode node, bool check) + { + for (int i = 0; i < node.Nodes.Count; i++) + { + if (node.Nodes[i].Checked != check) + { + node.Nodes[i].Checked = check; + } + + CheckAllChildren(node.Nodes[i], check); + } + } + + protected override void OnAfterCheck(TreeViewEventArgs e) + { + base.OnAfterCheck(e); + + if (!(e.Action == TreeViewAction.ByKeyboard || e.Action == TreeViewAction.ByMouse)) + { + return; + } + + try + { + this.BeginUpdate(); + + // the node if checked... + if (e.Node.Checked) + { + // check all child nodes... + CheckAllChildren(e.Node, true); + + // check all parents... + TreeNode parent = e.Node.Parent; + + while (parent != null) + { + if (!parent.Checked) parent.Checked = true; + parent = parent.Parent; + } + } + else + { + // check all child nodes... + CheckAllChildren(e.Node, false); + + // uncheck the parent node if all child nodes are unchecked... + TreeNode parent = e.Node.Parent; + while (parent != null) + { + if (!IsSomeChildNodeChecked(parent)) parent.Checked = false; + parent = parent.Parent; + } + } + } + finally + { + this.EndUpdate(); + } + } + + + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/DONE.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/DONE.txt Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,71 @@ +* limite da rate +* melhorar calculo de rate + +* popup notify icon +* (OK) janela de download de video + * (OK) forçar o protocol provider + * (OK) funcionar + +* autenticacao na URL ftp +* rever tratamento de erros, pois nem todas as excecoes estao sendo capturas + +* http://keepvid.com/ +* Support for GVideo +* Support for YouTube +* Support for Putfile +* Support for Metacafe +* Support for Break - esse site tb prove o formato WMV + +* Melhorar na parte inferior colocar uma tabControl: Segments | Log + +* jobs/scheduler: + * numero maximo de jobs + * se mandou startar, vai embora + * se download terminou e tem algum na fila, começa o primeiro + * se pause, nao começa outro (caso o numero de downloads estaja < max jobs) nao faz nada + +* Testar HTTPs Downloader +* download d arquivos q o servidor nao diz o tamanho +* Tela de download batch suportar autentication +* urls alternativas + * cada URL pode ser de um tipo diferente + * validar se o arquivo no mirror tem o mesmo tamanho +* Qnd retoma um download pausado nao ta fazendo retry +* melhorar integracao com parte do marco (chamar mtas imagems) + + +* melhorar o refresh de UI +* se o arquivo no servidor mudou? +* ter diretorio comum para salvar + * mudar tela de new donwload + * mudar jeito que processa parametros de entrada +* performance para salvar a lista de downloads (xml serializer) +* melhorar uso de CPU qnd a lista fica grande +* tela de batch download +* exibir erro Downloader.LastError na UI +* executar arquivo do concluir +* resetar o contador de try qnd recomeça o download / segmento +* se tenta retomar arquivo que nao suporta ranges +* se falhar ao obter o file info deixar como erro e tentar + tarde +* calcular tempo que download consuminiu no total (added date) +* about box + * mostrar plug'in + * link para site +* se um segmento falhar tentar + tarde (configurado) +* ordenacao da lista na UI +* subir balao no relogio do windows qnd download terminar +* sons para notificar eventos +* se fechou o programa qnd esta em needtoPrepare ou preparing da erro na volta +pois nesse caso ainda nao gerou os segmentos +* evitar que seja aberta 1 conexao pra pegar o info e depois seja despresada +* download de YouTUbe +* se um segmento terminar, quebrar o que esta rodando em 2 +* salvar estados dos downloads para reiniciar a aplicacao +* configuracao visual do proxy +* integracao com anti-virus +* formatar os bytes em casas decimais para exibir no grid +* download via FTP +* download via HTTP +* download segmentado +* pause e restart +* tornar o download http e ftp uma extensions \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/Download.ico Binary file MyDownloader.App/Download.ico has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/MyDownloader.App.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/MyDownloader.App.csproj Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,260 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {18AE3994-8F48-49B1-AC63-342F70ED1135} + WinExe + Properties + MyDownloader.App + MyDownloader.App + + + + + + + 3.5 + Download.ico + v3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + x86 + true + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + AnyCPU + + + + False + ..\ICSharpCode.SharpZipLib.dll + + + + + + + + + + + False + ..\TabStrip.dll + + + + + + + + + + + + + + + + Component + + + BlockedProgressBar.cs + + + Component + + + + + True + True + Resources.resx + + + True + True + Settings.settings + + + + + + + + Form + + + AboutForm.cs + + + Form + + + CreateBatchDownloadForm.cs + + + UserControl + + + DownloadList.cs + + + + + Form + + + ImportFromFileForm.cs + + + Form + + + ImportFromFilePreviewForm.cs + + + Form + + + MainForm.cs + + + Form + + + NewDownloadForm.cs + + + Form + + + OptionsForm.cs + + + + + + + + + + + {E763345E-6696-4C53-8764-47E4ABD67DEF} + MyDownloader.Core + + + {FEA18B6C-491F-401A-A06B-AE47888FF288} + MyDownloader.Extension + + + {69C99442-953E-4559-96D3-C82CC57A3C87} + MyDownloader.Spider + + + + + Designer + AboutForm.cs + + + Designer + MainForm.cs + + + Designer + OptionsForm.cs + + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + Designer + ResXFileCodeGenerator + Resources.Designer.cs + + + + Designer + CreateBatchDownloadForm.cs + + + Designer + DownloadList.cs + + + Designer + ImportFromFileForm.cs + + + Designer + ImportFromFilePreviewForm.cs + + + NewDownloadForm.cs + Designer + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/Program.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/Program.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using MyDownloader.Core; +using System.Diagnostics; +using System.Windows.Forms; +using MyDownloader.App.UI; +using MyDownloader.Extension.Protocols; +using MyDownloader.Extension.Video; +using MyDownloader.Extension.Video.Impl; + +namespace MyDownloader.App +{ + class Program + { + [STAThread] + static void Main(string[] args) + { + App.Instance.Start(args); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/Properties/AssemblyInfo.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,42 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MyDownloader.App")] +[assembly: AssemblyDescription( +@" +.Net Download Manager + +Nathan Adams - + +My Downloader + +Glacial ListView - Copyright Glacial Components Software 2004 - http://www.glacialcomponents.com/" +)] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct(@".Net Download Manager")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e962837f-7d13-4b2b-9f04-e9c2f871f155")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.3.0.0")] +[assembly: AssemblyFileVersion("1.3.0.0")] diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/Properties/Resources.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/Properties/Resources.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MyDownloader.App.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MyDownloader.App.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/Properties/Resources.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/Properties/Resources.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/Settings.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/Settings.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,62 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MyDownloader.App { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool ViewTransDetails { + get { + return ((bool)(this["ViewTransDetails"])); + } + set { + this["ViewTransDetails"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool ViewToolbar { + get { + return ((bool)(this["ViewToolbar"])); + } + set { + this["ViewToolbar"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool ViewGrid { + get { + return ((bool)(this["ViewGrid"])); + } + set { + this["ViewGrid"] = value; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/Settings.settings --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/Settings.settings Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,15 @@ + + + + + + True + + + True + + + True + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/SingleInstancing/ISingleInstanceEnforcer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/SingleInstancing/ISingleInstanceEnforcer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,21 @@ +using System; + +namespace MyDownloader.App.SingleInstancing +{ + /// + /// Provides methods which a single instance application can use to in order to be respond to any new instance of it. + /// + public interface ISingleInstanceEnforcer + { + /// + /// Handles messages received from a new instance of the application. + /// + /// The EventArgs object holding information about the event. + void OnMessageReceived(MessageEventArgs e); + /// + /// Handles a creation of a new instance of the application. + /// + /// The EventArgs object holding information about the event. + void OnNewInstanceCreated(EventArgs e); + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/SingleInstancing/MessageEventArgs.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/SingleInstancing/MessageEventArgs.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,49 @@ +using System; + +namespace MyDownloader.App.SingleInstancing +{ + /// + /// Provides data for the SingleInstancing.ISingleInstanceEnforcer.OnMessageReceived method. + /// + [Serializable()] + public class MessageEventArgs : EventArgs + { + #region Member Variables + + private object message; + + #endregion + + #region Construction / Destruction + + /// + /// Instantiates a new MessageEventArgs object. + /// + /// The message to pass to the first running instance of the application. + /// message is null. + public MessageEventArgs(object message) + { + if (message == null) + throw new ArgumentNullException("message", "message cannot be null."); + + this.message = message; + } + + #endregion + + #region Properties + + /// + /// Gets the message sent to the first instance of the application. + /// + public object Message + { + get + { + return message; + } + } + + #endregion + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/SingleInstancing/SingleInstanceException.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/SingleInstancing/SingleInstanceException.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,44 @@ +using System; +using System.Runtime.Serialization; + +namespace MyDownloader.App.SingleInstancing +{ + /// + /// Represents errors occured while trying to enforce single application instancing. + /// + [Serializable()] + public class SingleInstancingException : Exception + { + #region Construction / Destruction + + /// + /// Instantiates a new SingleInstancingException object. + /// + public SingleInstancingException() { } + + /// + /// Instantiates a new SingleInstancingException object. + /// + /// The message that describes the error. + public SingleInstancingException(string message) + : base(message) { } + + /// + /// Instantiates a new SingleInstancingException object. + /// + /// The message that describes the error. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public SingleInstancingException(string message, Exception inner) + : base(message, inner) { } + + /// + /// Instantiates a new SingleInstancingException object with serialized data. + /// + /// The System.Runtime.Serialization.SerializationInfo that holds the serialized object data about the exception being thrown. + /// The System.Runtime.Serialization.StreamingContext that contains contextual information about the source or destination. + protected SingleInstancingException(SerializationInfo info, StreamingContext context) + : base(info, context) { } + + #endregion + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/SingleInstancing/SingleInstanceProxy.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/SingleInstancing/SingleInstanceProxy.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,57 @@ +using System; + +namespace MyDownloader.App.SingleInstancing +{ + /// + /// Provides a proxy to communicate with the first instance of the application. + /// + internal class SingleInstanceProxy : MarshalByRefObject + { + #region Member Variables + + private ISingleInstanceEnforcer enforcer; + + #endregion + + #region Construction / Destruction + + /// + /// Instantiates a new SingleInstanceProxy object. + /// + /// The enforcer (first instance of the application) which will receive messages from the new instances of the application. + /// enforcer is null. + public SingleInstanceProxy(ISingleInstanceEnforcer enforcer) + { + if (enforcer == null) + throw new ArgumentNullException("enforcer", "enforcer cannot be null."); + + this.enforcer = enforcer; + } + + #endregion + + #region Properties + + /// + /// Gets or sets the enforcer (first instance of the application) which will receive messages from the new instances of the application. + /// + public ISingleInstanceEnforcer Enforcer + { + get + { + return enforcer; + } + } + + #endregion + + /// + /// Override and return NULL to prevent windows from doing + /// garbage collection on the proxy object. + /// + public override object InitializeLifetimeService() + { + return null; + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/SingleInstancing/SingleInstanceTracker.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/SingleInstancing/SingleInstanceTracker.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,219 @@ +using System; +using System.Threading; +using System.Runtime.Remoting; +using System.Runtime.Remoting.Channels; +using System.Runtime.Remoting.Channels.Ipc; + +namespace MyDownloader.App.SingleInstancing +{ + /// + /// Represents the method which would be used to retrieve an ISingleInstanceEnforcer object when instantiating a SingleInstanceTracker object. + /// If the method returns null, the SingleInstanceTracker's constructor will throw an exception. + /// + /// An ISingleInstanceEnforcer object which would receive messages. + public delegate ISingleInstanceEnforcer SingleInstanceEnforcerRetriever(); + + /// + /// Represents an object used to check for a previous instance of an application, and sending messages to it. + /// + public class SingleInstanceTracker : IDisposable + { + #region Member Variables + + private bool disposed; + private Mutex singleInstanceMutex; + private bool isFirstInstance; + private IChannel ipcChannel; + private SingleInstanceProxy proxy; + + #endregion + + #region Construction / Destruction + + /// + /// Instantiates a new SingleInstanceTracker object. + /// When using this constructor it is assumed that there is no need for sending messages to the first application instance. + /// To enable the tracker's ability to send messages to the first instance, use the SingleInstanceTracker(string name, SingleInstanceEnforcerRetriever enforcerRetriever) constructor overload instead. + /// + /// The unique name used to identify the application. + /// name is null or empty. + /// A general error occured while trying to instantiate the SingleInstanceInteractor. See InnerException for more details. + public SingleInstanceTracker(string name) + : this(name, null) { } + + /// + /// Instantiates a new SingleInstanceTracker object. + /// When using this constructor overload and enforcerRetriever is null, the SingleInstanceTracker object can only be used to determine whether the application is already running. + /// + /// The unique name used to identify the application. + /// The method which would be used to retrieve an ISingleInstanceEnforcer object when instantiating the new object. + /// name is null or empty. + /// A general error occured while trying to instantiate the SingleInstanceInteractor. See InnerException for more details. + public SingleInstanceTracker(string name, SingleInstanceEnforcerRetriever enforcerRetriever) + { + if (string.IsNullOrEmpty(name)) + throw new ArgumentNullException("name", "name cannot be null or empty."); + + try + { + singleInstanceMutex = new Mutex(true, name, out isFirstInstance); + + // Do not attempt to construct the IPC channel if there is no need for messages + if (enforcerRetriever != null) + { + string proxyObjectName = "SingleInstanceProxy"; + string proxyUri = "ipc://" + name + "/" + proxyObjectName; + + // If no previous instance was found, create a server channel which will provide the proxy to the first created instance + if (isFirstInstance) + { + // Create an IPC server channel to listen for SingleInstanceProxy object requests + ipcChannel = new IpcServerChannel(name); + // Register the channel and get it ready for use + ChannelServices.RegisterChannel(ipcChannel, false); + // Register the service which gets the SingleInstanceProxy object, so it can be accessible by IPC client channels + RemotingConfiguration.RegisterWellKnownServiceType(typeof(SingleInstanceProxy), proxyObjectName, WellKnownObjectMode.Singleton); + + // Attempt to retrieve the enforcer from the delegated method + ISingleInstanceEnforcer enforcer = enforcerRetriever(); + // Validate that an enforcer object was returned + if (enforcer == null) + throw new InvalidOperationException("The method delegated by the enforcerRetriever argument returned null. The method must return an ISingleInstanceEnforcer object."); + + // Create the first proxy object + proxy = new SingleInstanceProxy(enforcer); + // Publish the first proxy object so IPC clients requesting a proxy would receive a reference to it + RemotingServices.Marshal(proxy, proxyObjectName); + } + else + { + // Create an IPC client channel to request the existing SingleInstanceProxy object. + ipcChannel = new IpcClientChannel(); + // Register the channel and get it ready for use + ChannelServices.RegisterChannel(ipcChannel, false); + + // Retreive a reference to the proxy object which will be later used to send messages + proxy = (SingleInstanceProxy)Activator.GetObject(typeof(SingleInstanceProxy), proxyUri); + + // Notify the first instance of the application that a new instance was created + // proxy.Enforcer.OnNewInstanceCreated(new EventArgs()); + } + } + } + catch (Exception ex) + { + throw new SingleInstancingException("Failed to instantiate a new SingleInstanceTracker object. See InnerException for more details.", ex); + } + } + + /// + /// Releases all unmanaged resources used by the object. + /// + ~SingleInstanceTracker() + { + Dispose(false); + } + + #region IDisposable Members + + /// + /// Releases all unmanaged resources used by the object, and potentially releases managed resources. + /// + /// true to dispose of managed resources; otherwise false. + protected virtual void Dispose(bool disposing) + { + if (!disposed) + { + if (disposing) + { + if (singleInstanceMutex != null) + { + singleInstanceMutex.Close(); + singleInstanceMutex = null; + } + + if (ipcChannel != null) + { + ChannelServices.UnregisterChannel(ipcChannel); + ipcChannel = null; + } + } + + disposed = true; + } + } + + /// + /// Releases all resources used by the object. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + + #endregion + + #region Member Functions + + /// + /// Sends a message to the first instance of the application. + /// + /// The message to send to the first instance of the application. The message must be serializable. + /// The object was constructed with the SingleInstanceTracker(string name) constructor overload, or with the SingleInstanceTracker(string name, SingleInstanceEnforcerRetriever enforcerRetriever) cosntructor overload, with enforcerRetriever set to null. + /// The SingleInstanceInteractor has failed to send the message to the first application instance. The first instance might have terminated. + public void SendMessageToFirstInstance(object message) + { + if (disposed) + throw new ObjectDisposedException("The SingleInstanceTracker object has already been disposed."); + + if (ipcChannel == null) + throw new InvalidOperationException("The object was constructed with the SingleInstanceTracker(string name) constructor overload, or with the SingleInstanceTracker(string name, SingleInstanceEnforcerRetriever enforcerRetriever) constructor overload, with enforcerRetriever set to null, thus you cannot send messages to the first instance."); + + try + { + proxy.Enforcer.OnMessageReceived(new MessageEventArgs(message)); + } + catch (Exception ex) + { + throw new SingleInstancingException("Failed to send message to the first instance of the application. The first instance might have terminated.", ex); + } + } + + #endregion + + #region Properties + + /// + /// Gets a value indicating whether this instance of the application is the first instance. + /// + public bool IsFirstInstance + { + get + { + if (disposed) + throw new ObjectDisposedException("The SingleInstanceTracker object has already been disposed."); + + return isFirstInstance; + } + } + + /// + /// Gets the single instance enforcer (the first instance of the application) which would receive messages. + /// + public ISingleInstanceEnforcer Enforcer + { + get + { + if (disposed) + throw new ObjectDisposedException("The SingleInstanceTracker object has already been disposed."); + + return proxy.Enforcer; + } + } + + #endregion + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/TODO.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/TODO.txt Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,180 @@ +http://jogos.download.uol.com.br/videos/x360/mxvsatvuntamed(*).wmv +http://jogos.download.uol.com.br/videos/x360/mxvsatvuntamed10.wmv +http://jogos.download.uol.com.br/videos/x360/mxvsatvuntamed09.wmv +http://jogos.download.uol.com.br/videos/x360/mxvsatvuntamed08.wmv +http://jogos.download.uol.com.br/videos/x360/mxvsatvuntamed07.wmv +http://jogos.download.uol.com.br/videos/x360/mxvsatvuntamed06.wmv +http://jogos.download.uol.com.br/videos/x360/mxvsatvuntamed05.wmv + +* http://downloads.uol.com.br/windows/web/save2pc.jhtm +* http://baixaki.ig.com.br/ +* http://www.shareit.com/ +www.superdownlods.com ( e o blog) + +* ok - Conta no paypal +* Site +* Instalador para versao final +* Nome "unico" + +* Creditos: +BandObjectLib +TabStrip + +--------------------------- VERSION 2 +* (OK) (Video Download) Convert video to AVI,MPEG,MP3 using ffmpeg.exe + * (OK) Vai salver direto no formato, qual extensao usar na hr de salvar? + * (OK) Download windows deve forçar a extensao correta + * (OK) Salvar o formato do video no downlods.xml +* (OK) Colocar o nome do video na tela de download video, pegar o nome do arquivo pelo titutlo no site +* (OK) Ja traz URL no campo qnd abre uma janela de new download e ja tem no clipboard +* (OK) import from text file +* (OK) New column on download list "Resume": Yes or No +* (OK) Confirmar para deletar downloads +* (OK) Fix view toolbar, nao esta ajudastando o tamanho! +* (OK) Criar controle folder browser +* (OK) Nas edicoes de rate, qnd aplica as cotas, as vezes da erro +* (OK) move up / move down in download queue - http://www.codeproject.com/KB/cpp/listview.aspx?print=true +* (OK) Tabs na janela principal http://www.codeproject.com/cs/miscctrl/TabStrip.asp +* (OK) Renomear o scheduler para Auto-Downloads +* (OK) Opcao para ativar modo scheduler no star-up, Is it possible to start downloading, by starting the Downloader +* (OK) Fix de performance na download lista + * (OK) Qnd add pl spider adiciona varios lisks, fica lerdo +* (OK) Remover dependencia com GlacialList.dll +* (OK) batch windows (import file and bacths from url) + * (OK) Option to start the scheduler + * (OK) Set simutaneos downloads limit +* (OK) Pause, esta demorando mto + * (OK) deve abortar as threads? + * (OK) Pause all junto com o speed limit, da dead lock + * (OK) Speed limit deixa o pause all lento + * (OK) Lock da download list deve ser de 1 - writer e N readers +* (OK) Testar autenticacao http +* (OK) Authentication in http +* (OK) let the software start as a service, so it would start automaically in the background when windows login +* (OK) Rever o parser de html do gringo + * (OK) Acho que pode colocar na tela de "Import From File" + * (OK) Algo como "Import from HTML" e ai tb exibe um campo base URL +* (OK) Melhorar calculo de rate + * (OK) qnd baixando arquivo local e poe limite, demora mto pra cair + * (OK) em muitos downloads ao mesmo tempo, o rate fica mto auto +* (Speed Limit) + * (OK) Testar se com varios download a performance nao cai (cpu) + * Option to disable the speed limit while screen saver is running or computer is idle + * (OK) Improve + * (OK) Integrar com scheduler + * (OK) Especificar horarios que nao deve trabalhar + * (OK) Especificar horarios com limites + * (OK) Testar +* (OK) Todas as janelas + * (OK) Rever tab order + * (OK) Rever accep button e cancel button + +* HTML Spider + * (OK) Desabilitar os botoes de Download/Abort + * (OK) Colocar animacao tipo do google reader + * (OK) Ja ativar o modo auto-downloads qnd começar + * (OK) IFRAME, FRAMES + * (OK) Abort + * (OK) Permitir imagens fora de location? + * (OK) Filtros + * (OK) Ignore Nome + * (OK) Ignore Extension + * (OK) Download deaph + * (OK) Remove from list when completed + * (OK) Bug nas reg. expressions +

Castle Stronghold

+ + < + > + +

If you have any question, do not hesitate to contact us. We would be pleased to talk to you.

+ + * (OK) Melhorar gerenciamento de conexao + * (OK) Um download da erro e ai fica parado por mto tempo e os outros ficam esperando +* (OK) Clipboard monitor +* (OK) Integrate with IE + * (OK) Qnd for site de video, mostrar animacao - http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=469442&SiteID=1 + * (OK) Interceptar clicks de links and ALT apertado + * (OK) Chamar o processo + * (OK) Botao de "Lauch MD" + * (OK) Botao do video +* (OK) Validar entrada de dados nos forms +* Procurar TODO + +* OK - Allow user to explore ZIP file before download + * OK - Colocar controle de espera qnd esta listando conteudo do zip + +* Testes: + * ok - Esquema dos horarios do download scheduler + * ok - Se o rate fica controlado no horario configurado e depois volta + + * Testar mais sites no Web Spider + * URL superiror tem IFRAME http://www2.uol.com.br/chantili/ensaios/renata_soares2/g0_0.htm + http://www2.uol.com.br/chantili/ensaios/index.html?pamela_vogue + * ok - Tirar URL padrao dos controles de location + * ok - Tirar URL padrao no Web Spider + * Testar opcao de subir junto com o Windows + + * ok - importar URLs + * ok - Testar video (todos os sites) + * ok - Testar video conversao + + * ok- Testar + download de ZIP + * ok - Teste arquivo sem size + + * ok - Clipboard monitor + +--------------------------- VERSION 3 +* Grabber++ + +* how about support for categories, downloading, downloaded, trash, and custom folders/categories. +* new function: check update of the downloaded file, if newer version(last modified date) exists, download the new one, ask for replace the old one. +if add a new download file that already downloaded, allow to apply new download settings(new file path/name etc). + +1. add new download item, the download folder textbox will be better to be combobox remembering latest folders (could be configured at options, default is 10) ;-) +2. allow to autorun at win startup; +3. set referer of http download to avoid some anti-pirate link websites; +4. larger default buffer, how about 4M, you know, nowadays, wide bandwidth [laugh] +* double click download item to open file/directory +* support auto redirect, it seems that it does not support auto url redirection [doh] + +* Integrate with IE + * Para links simples funciona, mas para rapidshare/webmails nao +* Simplificar nome dos elementos XML no save +* DropZone + * Aceita drag de HTML (abrir janela pedindo URL base) + * Aceita drag de link +* Melhorar o algortimo de selecao do mirror + * tempo do ping + * Localizacao + * download rate do download anterior +* Download batch = FDM +* XY graph to display the transfer rate +* AutoShut down after download end + * Shutdownl + * Hibernate + * Restart + * Close MD +* Add Site login user name & password; coz I use RAPIDSHARE a lot and I have a user name and password for it, +but it is not supported by your program +* Integrate with FF +* Option to "Run when terminate" + * Fazer parecido com o FDM, abri uma janela com um timer para cancelar a execucao +* incluir um botao para excluir todos aqueles "tentando sem conseguir" no myFreeDownLoaderByGui +* Create download category and allow user to label the downloads +* Search for TODO in code +* Authentication in https +* FTP should have a separated proxy setting +* add / remove segments in download while downloading +* (Video Download) Media monitor to intercept traffic from IE / FF. +* Show a progress bar like emule in download list -> ***||**||||**||| +* MetaLink http://en.wikipedia.org/wiki/Metalink +* Download from MMS +* reteste em caso de falhas no segmento +* qnd o segmento termina nao esta vendo isso direito (o download do NFS tinha termando mais ainda continuava tentando baixar) +* Lock da segment list deve ser de 1 - writer e N readers +* Evento que usa o DownloaderEventArgs, pode ficar + simples, as vezes se adiciona uma lsita mto grande + e para cada item é criado esse objeto +* No Speed Limit, como chama toda hr o TotalSpeed faz mto lock na download list se juntar com o WebSpider ficara mto ruim +* Pause/Pause All - Fazer assincrono para tela nao travar +* Se Download == Pausing, deixar o sleep = 0 no SpeedLimit \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/About.rtf Binary file MyDownloader.App/UI/About.rtf has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/AboutForm.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/AboutForm.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,207 @@ +namespace MyDownloader.App.UI +{ + partial class AboutForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutForm)); + this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); + this.okButton = new System.Windows.Forms.Button(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.richTextBox1 = new System.Windows.Forms.RichTextBox(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.lvwPlugs = new System.Windows.Forms.ListView(); + this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.tabPage3 = new System.Windows.Forms.TabPage(); + this.richTextBox2 = new System.Windows.Forms.RichTextBox(); + this.tableLayoutPanel.SuspendLayout(); + this.tabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this.tabPage2.SuspendLayout(); + this.tabPage3.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel + // + this.tableLayoutPanel.ColumnCount = 1; + this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel.Controls.Add(this.okButton, 0, 1); + this.tableLayoutPanel.Controls.Add(this.tabControl1, 0, 0); + this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel.Location = new System.Drawing.Point(9, 9); + this.tableLayoutPanel.Name = "tableLayoutPanel"; + this.tableLayoutPanel.RowCount = 2; + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel.Size = new System.Drawing.Size(343, 349); + this.tableLayoutPanel.TabIndex = 0; + // + // okButton + // + this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.okButton.Location = new System.Drawing.Point(265, 323); + this.okButton.Name = "okButton"; + this.okButton.Size = new System.Drawing.Size(75, 23); + this.okButton.TabIndex = 1; + this.okButton.Text = "&OK"; + // + // tabControl1 + // + this.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Controls.Add(this.tabPage2); + this.tabControl1.Controls.Add(this.tabPage3); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabControl1.Location = new System.Drawing.Point(3, 3); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(337, 314); + this.tabControl1.TabIndex = 0; + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.richTextBox1); + this.tabPage1.Location = new System.Drawing.Point(4, 22); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(329, 288); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "About"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // richTextBox1 + // + this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.richTextBox1.Location = new System.Drawing.Point(3, 3); + this.richTextBox1.Name = "richTextBox1"; + this.richTextBox1.Size = new System.Drawing.Size(323, 282); + this.richTextBox1.TabIndex = 0; + this.richTextBox1.Text = ""; + this.richTextBox1.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.richTextBox1_LinkClicked); + this.richTextBox1.TextChanged += new System.EventHandler(this.richTextBox1_TextChanged); + // + // tabPage2 + // + this.tabPage2.Controls.Add(this.lvwPlugs); + this.tabPage2.Location = new System.Drawing.Point(4, 22); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3); + this.tabPage2.Size = new System.Drawing.Size(329, 288); + this.tabPage2.TabIndex = 1; + this.tabPage2.Text = "Plug\'ins"; + this.tabPage2.UseVisualStyleBackColor = true; + // + // lvwPlugs + // + this.lvwPlugs.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnHeader1, + this.columnHeader2}); + this.lvwPlugs.Dock = System.Windows.Forms.DockStyle.Fill; + this.lvwPlugs.FullRowSelect = true; + this.lvwPlugs.GridLines = true; + this.lvwPlugs.Location = new System.Drawing.Point(3, 3); + this.lvwPlugs.Name = "lvwPlugs"; + this.lvwPlugs.Size = new System.Drawing.Size(323, 282); + this.lvwPlugs.TabIndex = 0; + this.lvwPlugs.UseCompatibleStateImageBehavior = false; + this.lvwPlugs.View = System.Windows.Forms.View.Details; + // + // columnHeader1 + // + this.columnHeader1.Text = "Plug\'n"; + this.columnHeader1.Width = 213; + // + // columnHeader2 + // + this.columnHeader2.Text = "Version"; + this.columnHeader2.Width = 92; + // + // tabPage3 + // + this.tabPage3.Controls.Add(this.richTextBox2); + this.tabPage3.Location = new System.Drawing.Point(4, 22); + this.tabPage3.Name = "tabPage3"; + this.tabPage3.Padding = new System.Windows.Forms.Padding(3); + this.tabPage3.Size = new System.Drawing.Size(329, 288); + this.tabPage3.TabIndex = 2; + this.tabPage3.Text = "Licenses"; + this.tabPage3.UseVisualStyleBackColor = true; + // + // richTextBox2 + // + this.richTextBox2.Location = new System.Drawing.Point(3, 3); + this.richTextBox2.Name = "richTextBox2"; + this.richTextBox2.Size = new System.Drawing.Size(323, 282); + this.richTextBox2.TabIndex = 0; + this.richTextBox2.Text = resources.GetString("richTextBox2.Text"); + // + // AboutForm + // + this.AcceptButton = this.okButton; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.okButton; + this.ClientSize = new System.Drawing.Size(361, 367); + this.Controls.Add(this.tableLayoutPanel); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AboutForm"; + this.Padding = new System.Windows.Forms.Padding(9); + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "About"; + this.tableLayoutPanel.ResumeLayout(false); + this.tabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.tabPage2.ResumeLayout(false); + this.tabPage3.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel; + private System.Windows.Forms.Button okButton; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.RichTextBox richTextBox1; + private System.Windows.Forms.ListView lvwPlugs; + private System.Windows.Forms.ColumnHeader columnHeader1; + private System.Windows.Forms.ColumnHeader columnHeader2; + private System.Windows.Forms.TabPage tabPage3; + private System.Windows.Forms.RichTextBox richTextBox2; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/AboutForm.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/AboutForm.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using System.Reflection; +using MyDownloader.Core.UI; +using MyDownloader.Core.Extensions; +using System.Resources; +using System.IO; +using System.Globalization; +using System.Diagnostics; + +namespace MyDownloader.App.UI +{ + partial class AboutForm : Form + { + public AboutForm() + { + InitializeComponent(); + + // Initialize the AboutBox to display the product information from the assembly information. + // Change assembly information settings for your application through either: + // - Project->Properties->Application->Assembly Information + // - AssemblyInfo.cs + this.Text = String.Format("About {0}", AssemblyTitle); + + + for (int i = 0; i < AppManager.Instance.Application.Extensions.Count; i++) + { + IExtension ext = AppManager.Instance.Application.Extensions[i]; + + ListViewItem item = new ListViewItem(ext.Name); + item.SubItems.Add(AssemblyVersion(ext.GetType().Assembly)); + lvwPlugs.Items.Add(item); + } + + using (Stream s = this.GetType().Assembly.GetManifestResourceStream("MyDownloader.App.UI.About.rtf")) + { + richTextBox1.LoadFile(s, RichTextBoxStreamType.RichText); + } + } + + #region Assembly Attribute Accessors + + public string AssemblyTitle + { + get + { + // Get all Title attributes on this assembly + object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false); + // If there is at least one Title attribute + if (attributes.Length > 0) + { + // Select the first one + AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0]; + // If it is not an empty string, return it + if (titleAttribute.Title != "") + return titleAttribute.Title; + } + // If there was no Title attribute, or if the Title attribute was the empty string, return the .exe name + return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase); + } + } + + public string AssemblyVersion(Assembly a) + { + return a.GetName().Version.ToString(); + } + + //public string AssemblyDescription + //{ + // get + // { + // // Get all Description attributes on this assembly + // object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false); + // // If there aren't any Description attributes, return an empty string + // if (attributes.Length == 0) + // return ""; + // // If there is a Description attribute, return its value + // return ((AssemblyDescriptionAttribute)attributes[0]).Description; + // } + //} + + //public string AssemblyProduct + //{ + // get + // { + // // Get all Product attributes on this assembly + // object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false); + // // If there aren't any Product attributes, return an empty string + // if (attributes.Length == 0) + // return ""; + // // If there is a Product attribute, return its value + // return ((AssemblyProductAttribute)attributes[0]).Product; + // } + //} + + //public string AssemblyCopyright + //{ + // get + // { + // // Get all Copyright attributes on this assembly + // object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); + // // If there aren't any Copyright attributes, return an empty string + // if (attributes.Length == 0) + // return ""; + // // If there is a Copyright attribute, return its value + // return ((AssemblyCopyrightAttribute)attributes[0]).Copyright; + // } + //} + + //public string AssemblyCompany + //{ + // get + // { + // // Get all Company attributes on this assembly + // object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false); + // // If there aren't any Company attributes, return an empty string + // if (attributes.Length == 0) + // return ""; + // // If there is a Company attribute, return its value + // return ((AssemblyCompanyAttribute)attributes[0]).Company; + // } + //} + #endregion + + private void richTextBox1_LinkClicked(object sender, LinkClickedEventArgs e) + { + Process.Start(e.LinkText); + } + + private void richTextBox1_TextChanged(object sender, EventArgs e) + { + + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/AboutForm.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/AboutForm.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + .Net Download Manager is Licensed under the Apache Version 2.0. + +DNDM also uses the following projects from other developers: +* A command line parser licensed under the MS-PL. +* A ini parser licensed under MIT + + +Apache License 2.0 + +Copyright [2012] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +Microsoft Public License (Ms-PL) + +This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. + +1. Definitions + +The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. + +A "contribution" is the original software, or any additions or changes to the software. + +A "contributor" is any person that distributes its contribution under this license. + +"Licensed patents" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights + +(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. + +(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. + +3. Conditions and Limitations + +(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. + +(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. + +(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. + +(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. + +(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. + + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/CreateBatchDownloadForm.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/CreateBatchDownloadForm.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,321 @@ +using MyDownloader.Core.UI; +namespace MyDownloader.App.UI +{ + partial class CreateBatchDownloadForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.numSegments = new System.Windows.Forms.NumericUpDown(); + this.label2 = new System.Windows.Forms.Label(); + this.rdoNumbers = new System.Windows.Forms.RadioButton(); + this.rdoLetters = new System.Windows.Forms.RadioButton(); + this.label3 = new System.Windows.Forms.Label(); + this.txtTo = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.txtFrom = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.lvwListPreview = new System.Windows.Forms.ListBox(); + this.button2 = new System.Windows.Forms.Button(); + this.button1 = new System.Windows.Forms.Button(); + this.label7 = new System.Windows.Forms.Label(); + this.numWildcard = new System.Windows.Forms.NumericUpDown(); + this.label8 = new System.Windows.Forms.Label(); + this.numFrom = new System.Windows.Forms.NumericUpDown(); + this.numTo = new System.Windows.Forms.NumericUpDown(); + this.folderBrowser1 = new MyDownloader.Core.UI.DownloadFolder(); + this.location1 = new MyDownloader.App.UI.Location(); + this.scheduledDownloadEnabler1 = new MyDownloader.Extension.AutoDownloads.UI.ScheduledDownloadEnabler(); + ((System.ComponentModel.ISupportInitialize)(this.numSegments)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numWildcard)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numFrom)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numTo)).BeginInit(); + this.SuspendLayout(); + // + // numSegments + // + this.numSegments.Location = new System.Drawing.Point(401, 110); + this.numSegments.Name = "numSegments"; + this.numSegments.Size = new System.Drawing.Size(75, 20); + this.numSegments.TabIndex = 13; + this.numSegments.Value = new decimal(new int[] { + 1, + 0, + 0, + 0}); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(398, 94); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(54, 13); + this.label2.TabIndex = 12; + this.label2.Text = "Segments"; + // + // rdoNumbers + // + this.rdoNumbers.AutoSize = true; + this.rdoNumbers.Checked = true; + this.rdoNumbers.Location = new System.Drawing.Point(7, 95); + this.rdoNumbers.Name = "rdoNumbers"; + this.rdoNumbers.Size = new System.Drawing.Size(45, 17); + this.rdoNumbers.TabIndex = 1; + this.rdoNumbers.TabStop = true; + this.rdoNumbers.Text = "from"; + this.rdoNumbers.UseVisualStyleBackColor = true; + this.rdoNumbers.CheckedChanged += new System.EventHandler(this.rdoNumbers_CheckedChanged); + // + // rdoLetters + // + this.rdoLetters.AutoSize = true; + this.rdoLetters.Location = new System.Drawing.Point(7, 124); + this.rdoLetters.Name = "rdoLetters"; + this.rdoLetters.Size = new System.Drawing.Size(45, 17); + this.rdoLetters.TabIndex = 7; + this.rdoLetters.TabStop = true; + this.rdoLetters.Text = "from"; + this.rdoLetters.UseVisualStyleBackColor = true; + this.rdoLetters.CheckedChanged += new System.EventHandler(this.rdoNumbers_CheckedChanged); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(117, 99); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(16, 13); + this.label3.TabIndex = 3; + this.label3.Text = "to"; + // + // txtTo + // + this.txtTo.Location = new System.Drawing.Point(139, 123); + this.txtTo.MaxLength = 1; + this.txtTo.Name = "txtTo"; + this.txtTo.Size = new System.Drawing.Size(52, 20); + this.txtTo.TabIndex = 10; + this.txtTo.TextChanged += new System.EventHandler(this.numFrom_ValueChanged); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(117, 127); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(16, 13); + this.label4.TabIndex = 9; + this.label4.Text = "to"; + // + // txtFrom + // + this.txtFrom.Location = new System.Drawing.Point(59, 123); + this.txtFrom.MaxLength = 1; + this.txtFrom.Name = "txtFrom"; + this.txtFrom.Size = new System.Drawing.Size(52, 20); + this.txtFrom.TabIndex = 8; + this.txtFrom.TextChanged += new System.EventHandler(this.numFrom_ValueChanged); + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(4, 194); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(113, 13); + this.label6.TabIndex = 15; + this.label6.Text = "Download list preview:"; + // + // lvwListPreview + // + this.lvwListPreview.FormattingEnabled = true; + this.lvwListPreview.Location = new System.Drawing.Point(8, 208); + this.lvwListPreview.Name = "lvwListPreview"; + this.lvwListPreview.Size = new System.Drawing.Size(468, 95); + this.lvwListPreview.TabIndex = 16; + // + // button2 + // + this.button2.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.button2.Location = new System.Drawing.Point(400, 472); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(75, 23); + this.button2.TabIndex = 19; + this.button2.Text = "Cancel"; + this.button2.UseVisualStyleBackColor = true; + // + // button1 + // + this.button1.DialogResult = System.Windows.Forms.DialogResult.OK; + this.button1.Location = new System.Drawing.Point(319, 472); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 23); + this.button1.TabIndex = 18; + this.button1.Text = "OK"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(197, 98); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(97, 13); + this.label7.TabIndex = 5; + this.label7.Text = "Length of wildcard:"; + // + // numWildcard + // + this.numWildcard.Location = new System.Drawing.Point(300, 94); + this.numWildcard.Name = "numWildcard"; + this.numWildcard.Size = new System.Drawing.Size(75, 20); + this.numWildcard.TabIndex = 6; + this.numWildcard.Value = new decimal(new int[] { + 2, + 0, + 0, + 0}); + this.numWildcard.ValueChanged += new System.EventHandler(this.numFrom_ValueChanged); + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(197, 127); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(80, 13); + this.label8.TabIndex = 11; + this.label8.Text = "(case sensitive)"; + // + // numFrom + // + this.numFrom.Location = new System.Drawing.Point(59, 94); + this.numFrom.Name = "numFrom"; + this.numFrom.Size = new System.Drawing.Size(52, 20); + this.numFrom.TabIndex = 2; + this.numFrom.ValueChanged += new System.EventHandler(this.numFrom_ValueChanged); + // + // numTo + // + this.numTo.Location = new System.Drawing.Point(139, 94); + this.numTo.Maximum = new decimal(new int[] { + 100000, + 0, + 0, + 0}); + this.numTo.Name = "numTo"; + this.numTo.Size = new System.Drawing.Size(52, 20); + this.numTo.TabIndex = 4; + this.numTo.ValueChanged += new System.EventHandler(this.numFrom_ValueChanged); + // + // folderBrowser1 + // + this.folderBrowser1.LabelText = "Save to:"; + this.folderBrowser1.Location = new System.Drawing.Point(7, 149); + this.folderBrowser1.Name = "folderBrowser1"; + this.folderBrowser1.Size = new System.Drawing.Size(468, 42); + this.folderBrowser1.TabIndex = 14; + // + // location1 + // + this.location1.Location = new System.Drawing.Point(7, 0); + this.location1.Name = "location1"; + this.location1.Size = new System.Drawing.Size(468, 87); + this.location1.TabIndex = 0; + this.location1.UrlLabelTitle = "URL (e.g http://download.microsoft.com/file(*).zip)"; + // + // scheduledDownloadEnabler1 + // + this.scheduledDownloadEnabler1.Location = new System.Drawing.Point(8, 304); + this.scheduledDownloadEnabler1.Name = "scheduledDownloadEnabler1"; + this.scheduledDownloadEnabler1.Size = new System.Drawing.Size(468, 164); + this.scheduledDownloadEnabler1.TabIndex = 17; + // + // CreateBatchDownloadForm + // + this.AcceptButton = this.button1; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.button2; + this.ClientSize = new System.Drawing.Size(482, 499); + this.Controls.Add(this.scheduledDownloadEnabler1); + this.Controls.Add(this.folderBrowser1); + this.Controls.Add(this.location1); + this.Controls.Add(this.numTo); + this.Controls.Add(this.numFrom); + this.Controls.Add(this.label8); + this.Controls.Add(this.numWildcard); + this.Controls.Add(this.label7); + this.Controls.Add(this.button2); + this.Controls.Add(this.button1); + this.Controls.Add(this.lvwListPreview); + this.Controls.Add(this.label6); + this.Controls.Add(this.txtTo); + this.Controls.Add(this.label4); + this.Controls.Add(this.txtFrom); + this.Controls.Add(this.label3); + this.Controls.Add(this.rdoLetters); + this.Controls.Add(this.rdoNumbers); + this.Controls.Add(this.numSegments); + this.Controls.Add(this.label2); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "CreateBatchDownloadForm"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Create batch download"; + this.Load += new System.EventHandler(this.CreateBatchDownloadForm_Load); + ((System.ComponentModel.ISupportInitialize)(this.numSegments)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numWildcard)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numFrom)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numTo)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.NumericUpDown numSegments; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.RadioButton rdoNumbers; + private System.Windows.Forms.RadioButton rdoLetters; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox txtTo; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox txtFrom; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.ListBox lvwListPreview; + private System.Windows.Forms.Button button2; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.NumericUpDown numWildcard; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.NumericUpDown numFrom; + private System.Windows.Forms.NumericUpDown numTo; + private Location location1; + private DownloadFolder folderBrowser1; + private MyDownloader.Extension.AutoDownloads.UI.ScheduledDownloadEnabler scheduledDownloadEnabler1; + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/CreateBatchDownloadForm.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/CreateBatchDownloadForm.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,197 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.IO; +using System.Text.RegularExpressions; +using MyDownloader.Core; +using MyDownloader.Core.Common; +using MyDownloader.Core.UI; + +namespace MyDownloader.App.UI +{ + public partial class CreateBatchDownloadForm : Form + { + public CreateBatchDownloadForm() + { + InitializeComponent(); + + location1.UrlChanged += new EventHandler(numFrom_ValueChanged); + } + + private static ResourceLocation GetNumberURL(ResourceLocation locationBase, int i, int wildcard) + { + ResourceLocation r = locationBase.Clone(); + r.URL = locationBase.URL.Replace("(*)", i.ToString().PadLeft(wildcard, '0')); + return r; + } + + private ResourceLocation GetCharURL(ResourceLocation locationBase, string c) + { + ResourceLocation r = locationBase.Clone(); + r.URL = locationBase.URL.Replace("(*)", c); + return r; + } + + public string DownloadPath + { + get + { + return folderBrowser1.Folder; + } + } + + public int Segments + { + get + { + return (int)numSegments.Value; + } + } + + public ResourceLocation[] URLs + { + get + { + ResourceLocation[] result = new ResourceLocation[0]; + //TODO: multiple location handle here + ResourceLocation locationBase = location1.ResourceLocation[0]; + + if (rdoNumbers.Checked) + { + int from = (int)numFrom.Value; + int to = (int)numTo.Value; + int wildcard = (int)numWildcard.Value; + + if (from <= to) + { + result = new ResourceLocation[to - from + 1]; + + for (int i = from, j = 0; i <= to; i++, j++) + { + result[j] = GetNumberURL(locationBase, i, wildcard); + } + } + else + { + result = new ResourceLocation[2]; + result[0] = GetNumberURL(locationBase, from, wildcard); + result[1] = GetNumberURL(locationBase, to, wildcard); + } + } + else + { + string strFrom = txtFrom.Text; + string strTo = txtTo.Text; + + if (String.IsNullOrEmpty(strTo) && !String.IsNullOrEmpty(strFrom)) + { + result = new ResourceLocation[1]; + result[0] = GetCharURL(locationBase, strFrom); + } + else if (!String.IsNullOrEmpty(strTo) && String.IsNullOrEmpty(strFrom)) + { + result = new ResourceLocation[1]; + result[0] = GetCharURL(locationBase, strTo); + } + else if (!String.IsNullOrEmpty(strTo) && !String.IsNullOrEmpty(strFrom)) + { + char from = strFrom[0]; + char to = strTo[0]; + + if (from <= to) + { + result = new ResourceLocation[((int)(to - from)) + 1]; + + int j = 0; + for (char i = from; i <= to; i++) + { + result[j++] = GetCharURL(locationBase, i.ToString()); + } + } + else + { + result = new ResourceLocation[2]; + result[0] = GetCharURL(locationBase, strFrom); + result[1] = GetCharURL(locationBase, strTo); + } + + } + + } + + return result; + } + } + + private void PreviewURLs() + { + lvwListPreview.BeginUpdate(); + lvwListPreview.DataSource = URLs; + lvwListPreview.EndUpdate(); + } + + private void numFrom_ValueChanged(object sender, EventArgs e) + { + PreviewURLs(); + } + + private void rdoNumbers_CheckedChanged(object sender, EventArgs e) + { + UpdateUI(); + + PreviewURLs(); + } + + private void UpdateUI() + { + numFrom.Enabled = rdoNumbers.Checked; + numTo.Enabled = rdoNumbers.Checked; + numWildcard.Enabled = rdoNumbers.Checked; + txtFrom.Enabled = rdoLetters.Checked; + txtTo.Enabled = rdoLetters.Checked; + } + + private void CreateBatchDownloadForm_Load(object sender, EventArgs e) + { + UpdateUI(); + } + + public void ApplySettings() + { + scheduledDownloadEnabler1.ApplySettings(); + } + + private void button1_Click(object sender, EventArgs e) + { + try + { + //TODO: multiple location handle here + ResourceLocation rl = this.location1.ResourceLocation[0]; + + rl.BindProtocolProviderType(); + + if (rl.ProtocolProviderType == null) + { + MessageBox.Show("Invalid URL format, please check the location field.", + AppManager.Instance.Application.MainForm.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); + + DialogResult = DialogResult.None; + return; + } + } + catch + { + DialogResult = DialogResult.None; + + MessageBox.Show("Unknow error, please check your input data.", + AppManager.Instance.Application.MainForm.Text, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/CreateBatchDownloadForm.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/CreateBatchDownloadForm.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/DownloadList.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/DownloadList.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,477 @@ +namespace MyDownloader.App.UI +{ + partial class DownloadList + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.splitContainer2 = new System.Windows.Forms.SplitContainer(); + this.lvwDownloads = new System.Windows.Forms.ListView(); + this.columnFile = new System.Windows.Forms.ColumnHeader(); + this.columnSize = new System.Windows.Forms.ColumnHeader(); + this.columnCompleted = new System.Windows.Forms.ColumnHeader(); + this.columnProgress = new System.Windows.Forms.ColumnHeader(); + this.columnLeft = new System.Windows.Forms.ColumnHeader(); + this.columnRate = new System.Windows.Forms.ColumnHeader(); + this.columnAdded = new System.Windows.Forms.ColumnHeader(); + this.columnState = new System.Windows.Forms.ColumnHeader(); + this.columnResume = new System.Windows.Forms.ColumnHeader(); + this.columnURL = new System.Windows.Forms.ColumnHeader(); + this.popUpContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components); + this.newDownloadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.startToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.pauseToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); + this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); + this.openFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.copyURLToClipboardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.showInExplorerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.tabSegmentsLogs = new System.Windows.Forms.TabControl(); + this.tabSegments = new System.Windows.Forms.TabPage(); + this.blockedProgressBar1 = new MyDownloader.App.Controls.BlockedProgressBar(); + this.lvwSegments = new System.Windows.Forms.ListView(); + this.columnCurrentTry = new System.Windows.Forms.ColumnHeader(); + this.columnSegProgress = new System.Windows.Forms.ColumnHeader(); + this.columnSegCompleted = new System.Windows.Forms.ColumnHeader(); + this.columnSegSize = new System.Windows.Forms.ColumnHeader(); + this.columnStartPosition = new System.Windows.Forms.ColumnHeader(); + this.columnEndPosition = new System.Windows.Forms.ColumnHeader(); + this.columnSegRate = new System.Windows.Forms.ColumnHeader(); + this.columnSegLeft = new System.Windows.Forms.ColumnHeader(); + this.columnSegState = new System.Windows.Forms.ColumnHeader(); + this.columnCurrURL = new System.Windows.Forms.ColumnHeader(); + this.tabLog = new System.Windows.Forms.TabPage(); + this.richLog = new System.Windows.Forms.RichTextBox(); + this.logContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components); + this.clearLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.splitContainer2.Panel1.SuspendLayout(); + this.splitContainer2.Panel2.SuspendLayout(); + this.splitContainer2.SuspendLayout(); + this.popUpContextMenu.SuspendLayout(); + this.tabSegmentsLogs.SuspendLayout(); + this.tabSegments.SuspendLayout(); + this.tabLog.SuspendLayout(); + this.logContextMenu.SuspendLayout(); + this.SuspendLayout(); + // + // splitContainer2 + // + this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer2.Location = new System.Drawing.Point(0, 0); + this.splitContainer2.Name = "splitContainer2"; + this.splitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer2.Panel1 + // + this.splitContainer2.Panel1.Controls.Add(this.lvwDownloads); + // + // splitContainer2.Panel2 + // + this.splitContainer2.Panel2.Controls.Add(this.tabSegmentsLogs); + this.splitContainer2.Size = new System.Drawing.Size(722, 436); + this.splitContainer2.SplitterDistance = 211; + this.splitContainer2.TabIndex = 15; + // + // lvwDownloads + // + this.lvwDownloads.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnFile, + this.columnSize, + this.columnCompleted, + this.columnProgress, + this.columnLeft, + this.columnRate, + this.columnAdded, + this.columnState, + this.columnResume, + this.columnURL}); + this.lvwDownloads.ContextMenuStrip = this.popUpContextMenu; + this.lvwDownloads.Dock = System.Windows.Forms.DockStyle.Fill; + this.lvwDownloads.FullRowSelect = true; + this.lvwDownloads.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; + this.lvwDownloads.HideSelection = false; + this.lvwDownloads.Location = new System.Drawing.Point(0, 0); + this.lvwDownloads.Name = "lvwDownloads"; + this.lvwDownloads.ShowGroups = false; + this.lvwDownloads.ShowItemToolTips = true; + this.lvwDownloads.Size = new System.Drawing.Size(722, 211); + this.lvwDownloads.TabIndex = 0; + this.lvwDownloads.UseCompatibleStateImageBehavior = false; + this.lvwDownloads.View = System.Windows.Forms.View.Details; + this.lvwDownloads.DoubleClick += new System.EventHandler(this.lvwDownloads_DoubleClick); + this.lvwDownloads.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.lvwDownloads_ItemSelectionChanged); + // + // columnFile + // + this.columnFile.Text = "File"; + this.columnFile.Width = 98; + // + // columnSize + // + this.columnSize.Text = "Size"; + this.columnSize.Width = 80; + // + // columnCompleted + // + this.columnCompleted.Text = "Completed"; + this.columnCompleted.Width = 81; + // + // columnProgress + // + this.columnProgress.Text = "Progress"; + this.columnProgress.Width = 63; + // + // columnLeft + // + this.columnLeft.Text = "Left"; + this.columnLeft.Width = 70; + // + // columnRate + // + this.columnRate.Text = "Rate"; + this.columnRate.Width = 72; + // + // columnAdded + // + this.columnAdded.Text = "Added"; + this.columnAdded.Width = 77; + // + // columnState + // + this.columnState.Text = "State"; + this.columnState.Width = 97; + // + // columnResume + // + this.columnResume.Text = "Resume"; + // + // columnURL + // + this.columnURL.Text = "URL"; + this.columnURL.Width = 171; + // + // popUpContextMenu + // + this.popUpContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.newDownloadToolStripMenuItem, + this.toolStripSeparator5, + this.startToolStripMenuItem, + this.pauseToolStripMenuItem, + this.toolStripSeparator6, + this.removeToolStripMenuItem, + this.toolStripSeparator7, + this.openFileToolStripMenuItem, + this.copyURLToClipboardToolStripMenuItem, + this.showInExplorerToolStripMenuItem}); + this.popUpContextMenu.Name = "contextMenuStrip1"; + this.popUpContextMenu.Size = new System.Drawing.Size(196, 176); + this.popUpContextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.popUpContextMenu_Opening); + // + // newDownloadToolStripMenuItem + // + this.newDownloadToolStripMenuItem.Name = "newDownloadToolStripMenuItem"; + this.newDownloadToolStripMenuItem.Size = new System.Drawing.Size(195, 22); + this.newDownloadToolStripMenuItem.Text = "New Download..."; + this.newDownloadToolStripMenuItem.Click += new System.EventHandler(this.newDownloadToolStripMenuItem_Click); + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(192, 6); + // + // startToolStripMenuItem + // + this.startToolStripMenuItem.Name = "startToolStripMenuItem"; + this.startToolStripMenuItem.Size = new System.Drawing.Size(195, 22); + this.startToolStripMenuItem.Text = "Start"; + this.startToolStripMenuItem.Click += new System.EventHandler(this.startToolStripMenuItem_Click); + // + // pauseToolStripMenuItem + // + this.pauseToolStripMenuItem.Name = "pauseToolStripMenuItem"; + this.pauseToolStripMenuItem.Size = new System.Drawing.Size(195, 22); + this.pauseToolStripMenuItem.Text = "Pause"; + this.pauseToolStripMenuItem.Click += new System.EventHandler(this.pauseToolStripMenuItem_Click); + // + // toolStripSeparator6 + // + this.toolStripSeparator6.Name = "toolStripSeparator6"; + this.toolStripSeparator6.Size = new System.Drawing.Size(192, 6); + // + // removeToolStripMenuItem + // + this.removeToolStripMenuItem.Name = "removeToolStripMenuItem"; + this.removeToolStripMenuItem.Size = new System.Drawing.Size(195, 22); + this.removeToolStripMenuItem.Text = "Remove"; + this.removeToolStripMenuItem.Click += new System.EventHandler(this.removeToolStripMenuItem_Click); + // + // toolStripSeparator7 + // + this.toolStripSeparator7.Name = "toolStripSeparator7"; + this.toolStripSeparator7.Size = new System.Drawing.Size(192, 6); + // + // openFileToolStripMenuItem + // + this.openFileToolStripMenuItem.Name = "openFileToolStripMenuItem"; + this.openFileToolStripMenuItem.Size = new System.Drawing.Size(195, 22); + this.openFileToolStripMenuItem.Text = "Open File"; + this.openFileToolStripMenuItem.Click += new System.EventHandler(this.openFileToolStripMenuItem_Click); + // + // copyURLToClipboardToolStripMenuItem + // + this.copyURLToClipboardToolStripMenuItem.Name = "copyURLToClipboardToolStripMenuItem"; + this.copyURLToClipboardToolStripMenuItem.Size = new System.Drawing.Size(195, 22); + this.copyURLToClipboardToolStripMenuItem.Text = "Copy URL to Clipboard"; + this.copyURLToClipboardToolStripMenuItem.Click += new System.EventHandler(this.copyURLToClipboardToolStripMenuItem_Click); + // + // showInExplorerToolStripMenuItem + // + this.showInExplorerToolStripMenuItem.Name = "showInExplorerToolStripMenuItem"; + this.showInExplorerToolStripMenuItem.Size = new System.Drawing.Size(195, 22); + this.showInExplorerToolStripMenuItem.Text = "Show in Explorer"; + this.showInExplorerToolStripMenuItem.Click += new System.EventHandler(this.showInExplorerToolStripMenuItem_Click); + // + // tabSegmentsLogs + // + this.tabSegmentsLogs.Controls.Add(this.tabSegments); + this.tabSegmentsLogs.Controls.Add(this.tabLog); + this.tabSegmentsLogs.Dock = System.Windows.Forms.DockStyle.Fill; + this.tabSegmentsLogs.Location = new System.Drawing.Point(0, 0); + this.tabSegmentsLogs.Name = "tabSegmentsLogs"; + this.tabSegmentsLogs.SelectedIndex = 0; + this.tabSegmentsLogs.Size = new System.Drawing.Size(722, 221); + this.tabSegmentsLogs.TabIndex = 0; + // + // tabSegments + // + this.tabSegments.Controls.Add(this.blockedProgressBar1); + this.tabSegments.Controls.Add(this.lvwSegments); + this.tabSegments.Location = new System.Drawing.Point(4, 22); + this.tabSegments.Name = "tabSegments"; + this.tabSegments.Padding = new System.Windows.Forms.Padding(3); + this.tabSegments.Size = new System.Drawing.Size(714, 195); + this.tabSegments.TabIndex = 0; + this.tabSegments.Text = "Segments"; + this.tabSegments.UseVisualStyleBackColor = true; + // + // blockedProgressBar1 + // + this.blockedProgressBar1.BackColor = System.Drawing.SystemColors.Window; + this.blockedProgressBar1.Direction = MyDownloader.App.Controls.BlockedProgressBar.DirectionMode.Horizontal; + this.blockedProgressBar1.Dock = System.Windows.Forms.DockStyle.Top; + this.blockedProgressBar1.ForeColor = System.Drawing.SystemColors.GradientActiveCaption; + this.blockedProgressBar1.Length = 0; + this.blockedProgressBar1.Location = new System.Drawing.Point(3, 3); + this.blockedProgressBar1.Name = "blockedProgressBar1"; + this.blockedProgressBar1.Size = new System.Drawing.Size(708, 23); + this.blockedProgressBar1.TabIndex = 0; + this.blockedProgressBar1.Text = "blockedProgressBar1"; + this.blockedProgressBar1.UpdateMode = MyDownloader.App.Controls.BlockList.UpdateMode.All; + // + // lvwSegments + // + this.lvwSegments.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lvwSegments.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnCurrentTry, + this.columnSegProgress, + this.columnSegCompleted, + this.columnSegSize, + this.columnStartPosition, + this.columnEndPosition, + this.columnSegRate, + this.columnSegLeft, + this.columnSegState, + this.columnCurrURL}); + this.lvwSegments.FullRowSelect = true; + this.lvwSegments.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; + this.lvwSegments.HideSelection = false; + this.lvwSegments.Location = new System.Drawing.Point(3, 30); + this.lvwSegments.Name = "lvwSegments"; + this.lvwSegments.ShowGroups = false; + this.lvwSegments.ShowItemToolTips = true; + this.lvwSegments.Size = new System.Drawing.Size(708, 162); + this.lvwSegments.TabIndex = 1; + this.lvwSegments.UseCompatibleStateImageBehavior = false; + this.lvwSegments.View = System.Windows.Forms.View.Details; + // + // columnCurrentTry + // + this.columnCurrentTry.Text = "Current Try"; + this.columnCurrentTry.Width = 66; + // + // columnSegProgress + // + this.columnSegProgress.Text = "Progress"; + this.columnSegProgress.Width = 80; + // + // columnSegCompleted + // + this.columnSegCompleted.Text = "Completed"; + this.columnSegCompleted.Width = 81; + // + // columnSegSize + // + this.columnSegSize.Text = "Size"; + this.columnSegSize.Width = 77; + // + // columnStartPosition + // + this.columnStartPosition.Text = "Start Position"; + this.columnStartPosition.Width = 97; + // + // columnEndPosition + // + this.columnEndPosition.Text = "End Position"; + this.columnEndPosition.Width = 100; + // + // columnSegRate + // + this.columnSegRate.Text = "Rate"; + this.columnSegRate.Width = 55; + // + // columnSegLeft + // + this.columnSegLeft.Text = "Left"; + this.columnSegLeft.Width = 80; + // + // columnSegState + // + this.columnSegState.Text = "State"; + this.columnSegState.Width = 133; + // + // columnCurrURL + // + this.columnCurrURL.Text = "Current URL"; + this.columnCurrURL.Width = 100; + // + // tabLog + // + this.tabLog.Controls.Add(this.richLog); + this.tabLog.Location = new System.Drawing.Point(4, 22); + this.tabLog.Name = "tabLog"; + this.tabLog.Padding = new System.Windows.Forms.Padding(3); + this.tabLog.Size = new System.Drawing.Size(714, 195); + this.tabLog.TabIndex = 1; + this.tabLog.Text = "Log"; + this.tabLog.UseVisualStyleBackColor = true; + // + // richLog + // + this.richLog.BackColor = System.Drawing.SystemColors.Window; + this.richLog.ContextMenuStrip = this.logContextMenu; + this.richLog.Dock = System.Windows.Forms.DockStyle.Fill; + this.richLog.Location = new System.Drawing.Point(3, 3); + this.richLog.Name = "richLog"; + this.richLog.ReadOnly = true; + this.richLog.Size = new System.Drawing.Size(708, 189); + this.richLog.TabIndex = 0; + this.richLog.Text = ""; + this.richLog.WordWrap = false; + // + // logContextMenu + // + this.logContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.clearLogToolStripMenuItem}); + this.logContextMenu.Name = "logContextMenu"; + this.logContextMenu.Size = new System.Drawing.Size(125, 26); + // + // clearLogToolStripMenuItem + // + this.clearLogToolStripMenuItem.Name = "clearLogToolStripMenuItem"; + this.clearLogToolStripMenuItem.Size = new System.Drawing.Size(124, 22); + this.clearLogToolStripMenuItem.Text = "Clear Log"; + this.clearLogToolStripMenuItem.Click += new System.EventHandler(this.clearLogToolStripMenuItem_Click); + // + // DownloadList + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.splitContainer2); + this.Name = "DownloadList"; + this.Size = new System.Drawing.Size(722, 436); + this.Load += new System.EventHandler(this.DownloadList_Load); + this.splitContainer2.Panel1.ResumeLayout(false); + this.splitContainer2.Panel2.ResumeLayout(false); + this.splitContainer2.ResumeLayout(false); + this.popUpContextMenu.ResumeLayout(false); + this.tabSegmentsLogs.ResumeLayout(false); + this.tabSegments.ResumeLayout(false); + this.tabLog.ResumeLayout(false); + this.logContextMenu.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.SplitContainer splitContainer2; + private System.Windows.Forms.ListView lvwDownloads; + private System.Windows.Forms.ColumnHeader columnFile; + private System.Windows.Forms.ColumnHeader columnSize; + private System.Windows.Forms.ColumnHeader columnCompleted; + private System.Windows.Forms.ColumnHeader columnProgress; + private System.Windows.Forms.ColumnHeader columnLeft; + private System.Windows.Forms.ColumnHeader columnRate; + private System.Windows.Forms.ColumnHeader columnAdded; + private System.Windows.Forms.ColumnHeader columnState; + private System.Windows.Forms.ColumnHeader columnURL; + private System.Windows.Forms.TabControl tabSegmentsLogs; + private System.Windows.Forms.TabPage tabSegments; + private System.Windows.Forms.ListView lvwSegments; + private System.Windows.Forms.ColumnHeader columnCurrentTry; + private System.Windows.Forms.ColumnHeader columnSegProgress; + private System.Windows.Forms.ColumnHeader columnSegCompleted; + private System.Windows.Forms.ColumnHeader columnSegSize; + private System.Windows.Forms.ColumnHeader columnStartPosition; + private System.Windows.Forms.ColumnHeader columnEndPosition; + private System.Windows.Forms.ColumnHeader columnSegRate; + private System.Windows.Forms.ColumnHeader columnSegLeft; + private System.Windows.Forms.ColumnHeader columnSegState; + private System.Windows.Forms.ColumnHeader columnCurrURL; + private System.Windows.Forms.TabPage tabLog; + private System.Windows.Forms.RichTextBox richLog; + private System.Windows.Forms.ContextMenuStrip logContextMenu; + private System.Windows.Forms.ToolStripMenuItem clearLogToolStripMenuItem; + private System.Windows.Forms.ContextMenuStrip popUpContextMenu; + private System.Windows.Forms.ToolStripMenuItem newDownloadToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripMenuItem startToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem pauseToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator6; + private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator7; + private System.Windows.Forms.ToolStripMenuItem openFileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem copyURLToClipboardToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem showInExplorerToolStripMenuItem; + private System.Windows.Forms.ColumnHeader columnResume; + private MyDownloader.App.Controls.BlockedProgressBar blockedProgressBar1; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/DownloadList.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/DownloadList.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,1019 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using MyDownloader.Core; +using System.Collections; +using System.Diagnostics; +using System.IO; +using MyDownloader.Core.Common; +using MyDownloader.Extension.Video; +using System.Web; +using MyDownloader.Extension.AutoDownloads; +using MyDownloader.App.Controls; +using MyDownloader.Core.UI; +using MyDownloader.Extension.WindowsIntegration.ClipboardMonitor; + +namespace MyDownloader.App.UI +{ + public partial class DownloadList : UserControl, IClipboardDataHandler + { + delegate void ActionDownloader(Downloader d, ListViewItem item); + + Hashtable mapItemToDownload = new Hashtable(); + Hashtable mapDownloadToItem = new Hashtable(); + + ListViewItem lastSelection = null; + AutoDownloadsExtension scheduler; + ClipboardMonitor clipMonitor; + + public DownloadList() + { + InitializeComponent(); + lvwDownloads.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(lvwDownloads, true, null); + lvwSegments.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(lvwSegments, true, null); + + DownloadManager.Instance.DownloadAdded += new EventHandler(Instance_DownloadAdded); + DownloadManager.Instance.DownloadRemoved += new EventHandler(Instance_DownloadRemoved); + DownloadManager.Instance.DownloadEnded += new EventHandler(Instance_DownloadEnded); + + for (int i = 0; i < DownloadManager.Instance.Downloads.Count; i++) + { + AddDownload(DownloadManager.Instance.Downloads[i]); + } + + lvwDownloads.SmallImageList = FileTypeImageList.GetSharedInstance(); + } + + private void DownloadList_Load(object sender, EventArgs e) + { + DownloadManager.Instance.BeginAddBatchDownloads += new EventHandler(Instance_BeginAddBatchDownloads); + DownloadManager.Instance.EndAddBatchDownloads += new EventHandler(Instance_EndAddBatchDownloads); + DownloadManager.Instance.DownloadRemoved+=new EventHandler(Instance_DownloadRemoved); + + scheduler = (AutoDownloadsExtension)App.Instance.GetExtensionByType(typeof(AutoDownloadsExtension)); + clipMonitor = new ClipboardMonitor(this, this.Handle); + + this.Disposed += delegate(object snd, EventArgs ea) + { + clipMonitor.Dispose(); + }; + } + + void Instance_EndAddBatchDownloads(object sender, EventArgs e) + { + this.BeginInvoke((MethodInvoker)lvwDownloads.EndUpdate); + } + + void Instance_BeginAddBatchDownloads(object sender, EventArgs e) + { + this.BeginInvoke((MethodInvoker)lvwDownloads.BeginUpdate); + } + + public void ImportFromTextFile() + { + using (ImportFromFileForm importFile = new ImportFromFileForm()) + { + if (importFile.ShowDialog() == DialogResult.OK) + { + AddDownloadURLs( + importFile.URLs, + 1, + importFile.DownloadPath, + 0); + + importFile.ApplySettings(); + } + } + } + + public void NewBatchDownload() + { + using (CreateBatchDownloadForm batchDownload = new CreateBatchDownloadForm()) + { + if (batchDownload.ShowDialog() == DialogResult.OK) + { + AddDownloadURLs( + batchDownload.URLs, + batchDownload.Segments, + batchDownload.DownloadPath, + 0); + + batchDownload.ApplySettings(); + } + } + } + + string lastClipboardURL; + + #region IClipboardDataHandler Members + + protected override void WndProc(ref Message m) + { + if (clipMonitor == null || !clipMonitor.FilterMessage(ref m)) + { + base.WndProc(ref m); + } + } + + public void HandleClipboardData(IDataObject data) + { + NewDownloadFromClipboardData(); + } + + #endregion + + public void NewDownloadFromData(string url) + { + VideoDownloadExtension ext = (VideoDownloadExtension)App.Instance.GetExtensionByType(typeof(VideoDownloadExtension)); + + if (ext.GetHandlerByURL(url) != null) + { + ((VideoDownloadUIExtension)ext.UIExtension).ShowNewVideoDialog(url, false); + } + else + { + NewFileDownload(url, false); + } + } + + public void NewDownloadFromClipboardData() + { + string url = ClipboardHelper.GetURLOnClipboard(); + + if (string.IsNullOrEmpty(url) || lastClipboardURL == url) + { + return; + } + + lastClipboardURL = url; + + VideoDownloadExtension ext = (VideoDownloadExtension)App.Instance.GetExtensionByType(typeof(VideoDownloadExtension)); + + if (ext.GetHandlerByURL(url) != null) + { + ((VideoDownloadUIExtension)ext.UIExtension).ShowNewVideoDialog(null, false); + } + else + { + NewFileDownload(null, false); + } + } + + public void NewVideoDownload() + { + VideoDownloadExtension ext = (VideoDownloadExtension)App.Instance.GetExtensionByType(typeof(VideoDownloadExtension)); + ((VideoDownloadUIExtension)ext.UIExtension).ShowNewVideoDialog(null, true); + } + + public void NewFileDownload(string url, bool modal) + { + if (modal) + { + using (NewDownloadForm newDownload = new NewDownloadForm()) + { + if (!String.IsNullOrEmpty(url)) + { + ResourceLocation[] rl = new ResourceLocation[1]; + rl[0]= ResourceLocation.FromURL(url); + newDownload.DownloadLocation =rl; + } + + newDownload.ShowDialog(); + } + } + else + { + NewDownloadForm newDownload = new NewDownloadForm(); + + if (!String.IsNullOrEmpty(url)) + { + ResourceLocation[] rl = new ResourceLocation[1]; + rl[0] = ResourceLocation.FromURL(url); + newDownload.DownloadLocation = rl; + } + + newDownload.ShowInTaskbar = true; + newDownload.MinimizeBox = true; + newDownload.Show(); + newDownload.Focus(); + newDownload.TopMost = true; + } + } + + public void StartScheduler(bool enabled) + { + scheduler.Active = enabled; + } + + public bool SchedulerStarted() + { + return scheduler.Active; + } + + public void StartSelections() + { + DownloadsAction( + delegate(Downloader d, ListViewItem item) + { + d.ScheduleState=DownloaderScheduleState.Waiting; + DownloadManager.Instance.StartNextDownload(); + //d.Start(); + } + ); + } + + public void Pause() + { + DownloadsAction( + delegate(Downloader d, ListViewItem item) + { + d.Pause(); + } + ); + } + + public void PauseAll() + { + DownloadManager.Instance.PauseAll(); + UpdateList(); + } + + public void RemoveSelections() + { + if (MessageBox.Show("Are you sure that you want to remove selected downloads?", + this.ParentForm.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { + try + { + lvwDownloads.ItemSelectionChanged -= new ListViewItemSelectionChangedEventHandler(lvwDownloads_ItemSelectionChanged); + DownloadManager.Instance.DownloadRemoved -= new EventHandler(Instance_DownloadRemoved); + + DownloadsAction( + delegate(Downloader d, ListViewItem item) + { + lvwDownloads.Items.RemoveAt(item.Index); + DownloadManager.Instance.RemoveDownload(d); + System.IO.FileInfo fi = new FileInfo(d.LocalFile); + if (fi.Exists) + try + { + fi.Delete(); + } + catch + { + MessageBox.Show("Unable to delete: " + fi.FullName); + } + } + ); + } + finally + { + lvwDownloads.ItemSelectionChanged += new ListViewItemSelectionChangedEventHandler(lvwDownloads_ItemSelectionChanged); + lvwDownloads_ItemSelectionChanged(null, null); + + DownloadManager.Instance.DownloadRemoved += new EventHandler(Instance_DownloadRemoved); + } + } + } + + public void SelectAll() + { + using (DownloadManager.Instance.LockDownloadList(false)) + { + lvwDownloads.BeginUpdate(); + try + { + lvwDownloads.ItemSelectionChanged -= new ListViewItemSelectionChangedEventHandler(lvwDownloads_ItemSelectionChanged); + + for (int i = 0; i < lvwDownloads.Items.Count; i++) + { + lvwDownloads.Items[i].Selected = true; + } + } + finally + { + lvwDownloads.ItemSelectionChanged += new ListViewItemSelectionChangedEventHandler(lvwDownloads_ItemSelectionChanged); + lvwDownloads_ItemSelectionChanged(null, null); + + lvwDownloads.EndUpdate(); + } + } + } + + public void RemoveCompleted() + { + lvwDownloads.BeginUpdate(); + try + { + DownloadManager.Instance.ClearEnded(); + UpdateList(); + } + finally + { + lvwDownloads.EndUpdate(); + } + } + + public void AddDownloadURLs( + ResourceLocation arg, + int segments, + string path, + int nrOfSubfolders) + { + if (arg == null) return; + + if (path == null) + { + path = PathHelper.GetWithBackslash(Core.Settings.Default.DownloadFolder); + } + else + { + path = PathHelper.GetWithBackslash(path); + } + + try + { + DownloadManager.Instance.OnBeginAddBatchDownloads(); + + //foreach (ResourceLocation rl in args) + //{ + Uri uri = new Uri(arg.URL); + + string fileName = uri.Segments[uri.Segments.Length - 1]; + fileName = HttpUtility.UrlDecode(fileName).Replace("/", "\\"); + + DownloadManager.Instance.Add( + arg, + null, + path + fileName, + segments, + false); + //} + } + finally + { + DownloadManager.Instance.OnEndAddBatchDownloads(); + } + } + + public void AddDownloadURLs( + ResourceLocation[] args, + int segments, + string path, + int nrOfSubfolders) + { + if (args == null) return; + + if (path == null) + { + path = PathHelper.GetWithBackslash(Core.Settings.Default.DownloadFolder); + } + else + { + path = PathHelper.GetWithBackslash(path); + } + + try + { + DownloadManager.Instance.OnBeginAddBatchDownloads(); + + foreach (ResourceLocation rl in args) + { + Uri uri = new Uri(rl.URL); + + string fileName = uri.Segments[uri.Segments.Length - 1]; + fileName = HttpUtility.UrlDecode(fileName).Replace("/", "\\"); + + DownloadManager.Instance.Add( + rl, + null, + path + fileName, + segments, + false); + } + } + finally + { + DownloadManager.Instance.OnEndAddBatchDownloads(); + } + } + + private void lvwDownloads_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) + { + UpdateSegments(); + + UpdateUI(); + } + + public void LoadSettingsView() + { + lvwDownloads.GridLines = Settings.Default.ViewGrid; + lvwSegments.GridLines = Settings.Default.ViewGrid; + splitContainer2.Panel2Collapsed = !Settings.Default.ViewTransDetails; + } + + public void UpdateUI() + { + bool isSelected = lvwDownloads.SelectedItems.Count > 0; + + removeToolStripMenuItem.Enabled = isSelected; + startToolStripMenuItem.Enabled = isSelected; + pauseToolStripMenuItem.Enabled = isSelected; + + isSelected = lvwDownloads.SelectedItems.Count == 1; + copyURLToClipboardToolStripMenuItem.Enabled = isSelected; + + showInExplorerToolStripMenuItem.Enabled = isSelected; + openFileToolStripMenuItem.Enabled = isSelected && SelectedDownloaders[0].State == DownloaderState.Ended; + + OnSelectionChange(); + } + + public event EventHandler SelectionChange; + + protected virtual void OnSelectionChange() + { + if (SelectionChange != null) + { + SelectionChange(this, EventArgs.Empty); + } + } + + private void copyURLToClipboardToolStripMenuItem_Click(object sender, EventArgs e) + { + Clipboard.SetText(SelectedDownloaders[0].ResourceLocation.URL); + } + + private void showInExplorerToolStripMenuItem_Click(object sender, EventArgs e) + { + Process.Start("explorer.exe", String.Format("/select,{0}", SelectedDownloaders[0].LocalFile)); + } + + private void openFileToolStripMenuItem_Click(object sender, EventArgs e) + { + try + { + Process.Start(SelectedDownloaders[0].LocalFile); + } + catch (Exception) + { + } + } + + public int SelectedCount + { + get + { + return lvwDownloads.SelectedItems.Count; + } + } + + public Downloader[] SelectedDownloaders + { + get + { + if (lvwDownloads.SelectedItems.Count > 0) + { + Downloader[] downloaders = new Downloader[lvwDownloads.SelectedItems.Count]; + for (int i = 0; i < downloaders.Length; i++) + { + downloaders[i] = mapItemToDownload[lvwDownloads.SelectedItems[i]] as Downloader; + } + return downloaders; + } + + return null; + } + } + + void Instance_DownloadRemoved(object sender, DownloaderEventArgs e) + { + this.BeginInvoke((MethodInvoker)delegate() + { + ListViewItem item = mapDownloadToItem[e.Downloader] as ListViewItem; + + if (item != null) + { + if (item.Selected) + { + lastSelection = null; + + lvwSegments.Items.Clear(); + //lvwDownloads.SelectedItems.Clear(); + } + + mapDownloadToItem[e.Downloader] = null; + mapItemToDownload[item] = null; + + item.Remove(); + } + + } + ); + } + + void Instance_DownloadAdded(object sender, DownloaderEventArgs e) + { + if (IsHandleCreated) + { + this.BeginInvoke((MethodInvoker)delegate() { AddDownload(e.Downloader); }); + } + else + { + AddDownload(e.Downloader); + } + } + + private void AddDownload(Downloader d) + { + d.RestartingSegment += new EventHandler(download_RestartingSegment); + d.SegmentStoped += new EventHandler(download_SegmentEnded); + d.SegmentFailed += new EventHandler(download_SegmentFailed); + d.SegmentStarted += new EventHandler(download_SegmentStarted); + d.InfoReceived += new EventHandler(download_InfoReceived); + d.SegmentStarting += new EventHandler(Downloader_SegmentStarting); + + string ext = Path.GetExtension(d.LocalFile); + + ListViewItem item = new ListViewItem(); + + item.ImageIndex = FileTypeImageList.GetImageIndexByExtention(ext); + item.Text = Path.GetFileName(d.LocalFile); + + // size + item.SubItems.Add(ByteFormatter.ToString(d.FileSize)); + // completed + item.SubItems.Add(ByteFormatter.ToString(d.Transfered)); + // progress + item.SubItems.Add(String.Format("{0:0.##}%", d.Progress)); + // left + item.SubItems.Add(TimeSpanFormatter.ToString(d.Left)); + // rate + item.SubItems.Add("0"); + // added + item.SubItems.Add(d.CreatedDateTime.ToShortDateString() + " " + d.CreatedDateTime.ToShortTimeString()); + // state + item.SubItems.Add(d.State.ToString()); + // resume + item.SubItems.Add(GetResumeStr(d)); + // url + item.SubItems.Add(d.ResourceLocation.URL); + + mapDownloadToItem[d] = item; + mapItemToDownload[item] = d; + + lvwDownloads.Items.Add(item); + } + + private static string GetResumeStr(Downloader d) + { + return (d.RemoteFileInfo != null && d.RemoteFileInfo.AcceptRanges ? "Yes" : "No"); + } + + public void UpdateList() + { + lvwDownloads.BeginUpdate(); + + for (int i = 0; i < lvwDownloads.Items.Count; i++) + { + ListViewItem item = lvwDownloads.Items[i]; + if (item == null) return; + Downloader d = mapItemToDownload[item] as Downloader; + if (d == null) return; + + DownloaderState state; + + if (item.Tag == null) state = DownloaderState.Working; + else state = (DownloaderState)item.Tag; + + if (state != d.State || + state == DownloaderState.Working || + state == DownloaderState.WaitingForReconnect) + { + item.SubItems[0].Text = d.FileName; + item.SubItems[1].Text = ByteFormatter.ToString(d.FileSize); + item.SubItems[2].Text = ByteFormatter.ToString(d.Transfered); + item.SubItems[3].Text = String.Format("{0:0.##}%", d.Progress); + item.SubItems[4].Text = TimeSpanFormatter.ToString(d.Left); + item.SubItems[5].Text = String.Format("{0:0.##}", d.Rate / 1024.0); + + if (d.LastError != null) + { + item.SubItems[7].Text = d.ScheduleState.ToString() + ", " + d.LastError.Message; + } + else + { + if (String.IsNullOrEmpty(d.StatusMessage)) + { + item.SubItems[7].Text = d.ScheduleState.ToString(); + } + else + { + item.SubItems[7].Text = d.ScheduleState.ToString() + ", " + d.StatusMessage; + } + } + + item.SubItems[8].Text = GetResumeStr(d); + item.SubItems[9].Text = d.ResourceLocation.URL; + item.Tag = d.State; + } + } + + UpdateSegments(); + lvwDownloads.EndUpdate(); + } + + private void UpdateSegments() + { + try + { + lvwSegments.BeginUpdate(); + + if (lvwDownloads.SelectedItems.Count == 1) + { + ListViewItem newSelection = lvwDownloads.SelectedItems[0]; + Downloader d = mapItemToDownload[newSelection] as Downloader; + + if (lastSelection == newSelection) + { + if (d.Segments.Count == lvwSegments.Items.Count) + { + UpdateSegmentsWithoutInsert(d); + } + else + { + UpdateSegmentsInserting(d, newSelection); + } + } + else + { + UpdateSegmentsInserting(d, newSelection); + } + } + else + { + lastSelection = null; + + blockedProgressBar1.BlockList.Clear(); + blockedProgressBar1.Refresh(); + + lvwSegments.Items.Clear(); + } + } + finally + { + lvwSegments.EndUpdate(); + } + } + + private void DownloadsAction(ActionDownloader action) + { + if (lvwDownloads.SelectedItems.Count > 0) + { + try + { + lvwDownloads.BeginUpdate(); + + lvwDownloads.ItemSelectionChanged -= new ListViewItemSelectionChangedEventHandler(lvwDownloads_ItemSelectionChanged); + + for (int i = lvwDownloads.SelectedItems.Count - 1; i >= 0; i--) + { + ListViewItem item = lvwDownloads.SelectedItems[i]; + action((Downloader)mapItemToDownload[item], item); + } + + lvwDownloads.ItemSelectionChanged += new ListViewItemSelectionChangedEventHandler(lvwDownloads_ItemSelectionChanged); + lvwDownloads_ItemSelectionChanged(null, null); + } + finally + { + lvwDownloads.EndUpdate(); + UpdateSegments(); + } + } + } + + private void UpdateSegmentsWithoutInsert(Downloader d) + { + for (int i = 0; i < d.Segments.Count; i++) + { + lvwSegments.Items[i].SubItems[0].Text = d.Segments[i].CurrentTry.ToString(); + lvwSegments.Items[i].SubItems[1].Text = String.Format("{0:0.##}%", d.Segments[i].Progress); + lvwSegments.Items[i].SubItems[2].Text = ByteFormatter.ToString(d.Segments[i].Transfered); + lvwSegments.Items[i].SubItems[3].Text = ByteFormatter.ToString(d.Segments[i].TotalToTransfer); + lvwSegments.Items[i].SubItems[4].Text = ByteFormatter.ToString(d.Segments[i].InitialStartPosition); + lvwSegments.Items[i].SubItems[5].Text = ByteFormatter.ToString(d.Segments[i].EndPosition); + lvwSegments.Items[i].SubItems[6].Text = String.Format("{0:0.##}", d.Segments[i].Rate / 1024.0); + lvwSegments.Items[i].SubItems[7].Text = TimeSpanFormatter.ToString(d.Segments[i].Left); + if (d.Segments[i].LastError != null) + { + lvwSegments.Items[i].SubItems[8].Text = d.Segments[i].State.ToString() + ", " + d.Segments[i].LastError.Message; + } + else + { + lvwSegments.Items[i].SubItems[8].Text = d.Segments[i].State.ToString(); + } + lvwSegments.Items[i].SubItems[9].Text = d.Segments[i].CurrentURL; + + this.blockedProgressBar1.BlockList[i].BlockSize = d.Segments[i].TotalToTransfer; + this.blockedProgressBar1.BlockList[i].PercentProgress = (float)d.Segments[i].Progress; + } + + this.blockedProgressBar1.Refresh(); + } + + private void UpdateSegmentsInserting(Downloader d, ListViewItem newSelection) + { + lastSelection = newSelection; + + lvwSegments.Items.Clear(); + + List blocks = new List(); + + for (int i = 0; i < d.Segments.Count; i++) + { + ListViewItem item = new ListViewItem(); + + item.Text = d.Segments[i].CurrentTry.ToString(); + item.SubItems.Add(String.Format("{0:0.##}%", d.Segments[i].Progress)); + item.SubItems.Add(ByteFormatter.ToString(d.Segments[i].Transfered)); + item.SubItems.Add(ByteFormatter.ToString(d.Segments[i].TotalToTransfer)); + item.SubItems.Add(ByteFormatter.ToString(d.Segments[i].InitialStartPosition)); + item.SubItems.Add(ByteFormatter.ToString(d.Segments[i].EndPosition)); + item.SubItems.Add(String.Format("{0:0.##}", d.Segments[i].Rate / 1024.0)); + item.SubItems.Add(TimeSpanFormatter.ToString(d.Segments[i].Left)); + item.SubItems.Add(d.Segments[i].State.ToString()); + item.SubItems.Add(d.Segments[i].CurrentURL); + + lvwSegments.Items.Add(item); + + blocks.Add(new Block(d.Segments[i].TotalToTransfer, (float)d.Segments[i].Progress)); + } + + this.blockedProgressBar1.BlockList = blocks; + } + + void download_InfoReceived(object sender, EventArgs e) + { + Downloader d = (Downloader)sender; + + Log( + d, + String.Format( + "Connected to: {2}. File size = {0}, Resume = {1}", + ByteFormatter.ToString(d.FileSize), + d.RemoteFileInfo.AcceptRanges, + d.ResourceLocation.URL), + LogMode.Information); + } + + void Downloader_SegmentStarting(object sender, SegmentEventArgs e) + { + Log( + e.Downloader, + String.Format( + "Starting segment for {3}, start position = {0}, end position {1}, segment size = {2}", + ByteFormatter.ToString(e.Segment.InitialStartPosition), + ByteFormatter.ToString(e.Segment.EndPosition), + ByteFormatter.ToString(e.Segment.TotalToTransfer), + e.Downloader.ResourceLocation.URL), + LogMode.Information); + } + + void download_SegmentStarted(object sender, SegmentEventArgs e) + { + Log( + e.Downloader, + String.Format( + "Started segment for {3}, start position = {0}, end position {1}, segment size = {2}", + ByteFormatter.ToString(e.Segment.InitialStartPosition), + ByteFormatter.ToString(e.Segment.EndPosition), + ByteFormatter.ToString(e.Segment.TotalToTransfer), + e.Downloader.ResourceLocation.URL), + LogMode.Information); + } + + void download_SegmentFailed(object sender, SegmentEventArgs e) + { + Log( + e.Downloader, + String.Format( + "Download segment ({0}) failed for {2}, reason = {1}", + e.Segment.Index, + e.Segment.LastError.Message, + e.Downloader.ResourceLocation.URL), + LogMode.Error); + } + + void download_SegmentEnded(object sender, SegmentEventArgs e) + { + Log( + e.Downloader, + String.Format( + "Download segment ({0}) ended for {1}", + e.Segment.Index, + e.Downloader.ResourceLocation.URL), + LogMode.Information); + } + + void download_RestartingSegment(object sender, SegmentEventArgs e) + { + Log( + e.Downloader, + String.Format( + "Download segment ({0}) is restarting for {1}", + e.Segment.Index, + e.Downloader.ResourceLocation.URL), + LogMode.Information); + } + + void Instance_DownloadEnded(object sender, DownloaderEventArgs e) + { + Log( + e.Downloader, + String.Format( + "Download ended {0}", + e.Downloader.ResourceLocation.URL), + LogMode.Information); + } + + enum LogMode + { + Error, + Information + } + + void Log(Downloader downloader, string msg, LogMode m) + { + try + { + this.BeginInvoke( + (MethodInvoker) + delegate() + { + int len = richLog.Text.Length; + if (len > 0) + { + richLog.SelectionStart = len; + } + + if (m == LogMode.Error) + { + richLog.SelectionColor = Color.Red; + } + else + { + richLog.SelectionColor = Color.Blue; + } + + richLog.AppendText(DateTime.Now + " - " + msg + Environment.NewLine); + } + ); + } + catch { } + } + + private void clearLogToolStripMenuItem_Click(object sender, EventArgs e) + { + richLog.Clear(); + } + + private void newDownloadToolStripMenuItem_Click(object sender, EventArgs e) + { + NewFileDownload(null, true); + } + + private void startToolStripMenuItem_Click(object sender, EventArgs e) + { + StartSelections(); + } + + private void pauseToolStripMenuItem_Click(object sender, EventArgs e) + { + Pause(); + } + + private void removeToolStripMenuItem_Click(object sender, EventArgs e) + { + RemoveSelections(); + } + + private void SwapElements(int idx) + { + ListViewItem it1 = lvwDownloads.Items[idx]; + ListViewItem it2 = lvwDownloads.Items[idx - 1]; + + lvwDownloads.Items.RemoveAt(idx); + lvwDownloads.Items.RemoveAt(idx - 1); + + lvwDownloads.Items.Insert(idx - 1, it1); + lvwDownloads.Items.Insert(idx, it2); + + DownloadManager.Instance.SwapDownloads(idx, true); + } + + public void MoveSelectionsDown() + { + int selCount = lvwDownloads.SelectedItems.Count; + if (selCount > 0) + { + try + { + lvwDownloads.BeginUpdate(); + + ListViewItem lvi = null; + + using (DownloadManager.Instance.LockDownloadList(true)) + { + for (int i = selCount - 1; i >= 0; i--) + { + lvi = lvwDownloads.SelectedItems[i]; + + if (lvi.Index < lvwDownloads.Items.Count - 1 + && !lvwDownloads.Items[lvi.Index + 1].Selected) + { + SwapElements(lvi.Index + 1); + } + } + } + + lvwDownloads.SelectedItems[selCount - 1].EnsureVisible(); + } + finally + { + lvwDownloads.EndUpdate(); + } + } + } + + public void MoveSelectionsUp() + { + int selCount = lvwDownloads.SelectedItems.Count; + + if (selCount > 0) + { + try + { + lvwDownloads.BeginUpdate(); + + ListViewItem lvi = null; + + using (DownloadManager.Instance.LockDownloadList(true)) + { + for (int i = 0; i < selCount; i++) + { + lvi = lvwDownloads.SelectedItems[i]; + + if (lvi.Index > 0 + && !lvwDownloads.Items[lvi.Index - 1].Selected) + { + SwapElements(lvi.Index); + } + } + } + + lvwDownloads.SelectedItems[0].EnsureVisible(); + } + finally + { + lvwDownloads.EndUpdate(); + } + } + } + + public bool ClipboardMonitorEnabled + { + set + { + if (clipMonitor != null) + { + clipMonitor.Enabled = value; + } + } + get + { + if (clipMonitor != null) + { + return clipMonitor.Enabled; + } + return false; + } + } + + private void popUpContextMenu_Opening(object sender, CancelEventArgs e) + { + UpdateUI(); + } + + private void lvwDownloads_DoubleClick(object sender, EventArgs e) + { + UpdateUI(); + + openFileToolStripMenuItem_Click(sender, e); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/DownloadList.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/DownloadList.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 528, 54 + + + 396, 54 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/FileTypeImageList.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/FileTypeImageList.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.Drawing; + +namespace MyDownloader.App.UI +{ + public class FileTypeImageList + { + private const string OpenFolderKey = "OpenFolderKey"; + private const string CloseFolderKey = "OpenFolderKey"; + + private static ImageList instance; + + public static ImageList GetSharedInstance() + { + if (instance == null) + { + instance = new ImageList(); + instance.TransparentColor = Color.Black; + instance.TransparentColor = Color.Transparent; + instance.ColorDepth = ColorDepth.Depth32Bit; + instance.ImageSize = new Size(16, 16); + } + + return instance; + } + + public static int GetImageIndexByExtention(string ext) + { + GetSharedInstance(); + + ext = ext.ToLower(); + + if (!instance.Images.ContainsKey(ext)) + { + //Icon iconForFile = IconExtractor.Extract(ext); + Icon iconForFile = IconReader.GetFileIconByExt(ext, IconReader.EnumIconSize.Small, false); + + instance.Images.Add(ext, iconForFile); + } + + return instance.Images.IndexOfKey(ext); + } + + public static int GetImageIndexFromFolder(bool open) + { + string key; + + GetSharedInstance(); + + if (open) + { + key = OpenFolderKey; + } + else + { + key = CloseFolderKey; + } + + if (!instance.Images.ContainsKey(key)) + { + Icon iconForFile = IconReader.GetFolderIcon( + IconReader.EnumIconSize.Small, + (open ? IconReader.EnumFolderType.Open : IconReader.EnumFolderType.Closed)); + + instance.Images.Add(key, iconForFile); + } + + return instance.Images.IndexOfKey(key); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/IconReader.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/IconReader.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,272 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace MyDownloader.App.UI +{ + + public class IconReader + { + /// + /// used to get/return information about a file + /// in SHGetFileInfo call + /// + [System.FlagsAttribute()] + private enum EnumFileInfoFlags : uint + { + /// get large icon + LARGEICON = 0x000000000, + /// get small icon + SMALLICON = 0x000000001, + /// get open icon + OPENICON = 0x000000002, + /// get shell size icon + SHELLICONSIZE = 0x000000004, + /// pszPath is a pidl + PIDL = 0x000000008, + /// use passed dwFileAttribute + USEFILEATTRIBUTES = 0x000000010, + /// apply the appropriate overlays + ADDOVERLAYS = 0x000000020, + /// get the index of the overlay + OVERLAYINDEX = 0x000000040, + /// get icon + ICON = 0x000000100, + /// get display name + DISPLAYNAME = 0x000000200, + /// get type name + TYPENAME = 0x000000400, + /// get attributes + ATTRIBUTES = 0x000000800, + /// get icon location + ICONLOCATION = 0x000001000, + /// return exe type + EXETYPE = 0x000002000, + /// get system icon index + SYSICONINDEX = 0x000004000, + /// put a link overlay on icon + LINKOVERLAY = 0x000008000, + /// show icon in selected state + SELECTED = 0x000010000, + /// get only specified attributes + ATTR_SPECIFIED = 0x000020000 + } + + /// + /// maxumum length of path + /// + private const int conMAX_PATH = 260; + + /// + /// looking for folder + /// + private const uint conFILE_ATTRIBUTE_DIRECTORY = 0x00000010; + + /// + /// looking for file + /// + private const uint conFILE_ATTRIBUTE_NORMAL = 0x00000080; + + /// + /// size of the icon + /// + public enum EnumIconSize + { + /// 32x32 + Large = 0, + /// 16x16 + Small = 1 + } + + /// + /// state of the folder + /// + public enum EnumFolderType + { + /// open folder + Open = 0, + /// closed folder + Closed = 1 + } + + /// + /// hold file/icon information + /// see platformSDK SHFILEINFO + /// + /// + /// be sure to call DestroyIcon [hIcon] when done + /// + [System.Runtime.InteropServices.StructLayout( + System.Runtime.InteropServices.LayoutKind.Sequential)] + private struct ShellFileInfo + { + + public const int conNameSize = 80; + public System.IntPtr hIcon; // note to call DestroyIcon + public int iIndex; + public uint dwAttributes; + + [System.Runtime.InteropServices.MarshalAs( + System.Runtime.InteropServices.UnmanagedType.ByValTStr, + SizeConst = conMAX_PATH)] + public string szDisplayName; + + [System.Runtime.InteropServices.MarshalAs( + System.Runtime.InteropServices.UnmanagedType.ByValTStr, + SizeConst = conNameSize)] + public string szTypeName; + }; + + /// + /// used to free a windows icon handle + /// + /// "hIcon">icon handle. + [System.Runtime.InteropServices.DllImport("User32.dll")] + private static extern int DestroyIcon(System.IntPtr hIcon); + + /// + /// gets file information + /// see platformSDK + /// + [System.Runtime.InteropServices.DllImport("Shell32.dll")] + private static extern System.IntPtr SHGetFileInfo( + string pszPath, + uint dwFileAttributes, + ref ShellFileInfo psfi, + uint cbFileInfo, + uint uFlags + ); + + public static System.Drawing.Icon GetFileIcon(string filePath, + EnumIconSize size, bool addLinkOverlay) + { + EnumFileInfoFlags flags = + EnumFileInfoFlags.ICON | EnumFileInfoFlags.USEFILEATTRIBUTES; + + // add link overlay if requested + if (addLinkOverlay) + { + flags |= EnumFileInfoFlags.LINKOVERLAY; + } + + // set size + if (size == EnumIconSize.Small) + { + flags |= EnumFileInfoFlags.SMALLICON; + } + else + { + flags |= EnumFileInfoFlags.LARGEICON; + } + + ShellFileInfo shellFileInfo = new ShellFileInfo(); + + SHGetFileInfo( + filePath, + conFILE_ATTRIBUTE_NORMAL, + ref shellFileInfo, + (uint)System.Runtime.InteropServices.Marshal.SizeOf(shellFileInfo), + (uint)flags); + + // deep copy + System.Drawing.Icon icon = + (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shellFileInfo.hIcon).Clone(); + + // release handle + DestroyIcon(shellFileInfo.hIcon); + + return icon; + } + /// + /// lookup and return an icon from windows shell + /// + /// "name">path to the file + /// "size">large or small + /// "linkOverlay">true to include the overlay link iconlet + /// requested icon + public static System.Drawing.Icon GetFileIconByExt( + string fileExt, + EnumIconSize size, + bool addLinkOverlay) + { + string tempFile = Path.GetTempPath() + Guid.NewGuid().ToString("N") + fileExt; + + try + { + File.WriteAllBytes(tempFile, new byte[1] { 0 }); + + return GetFileIcon(tempFile, size, addLinkOverlay); + } + finally + { + try + { + File.Delete(tempFile); + } + catch (Exception) + { + } + } + } + + /// + /// lookup and return an icon from windows shell + /// + /// "size">large or small + /// "folderType">open or closed + /// requested icon + public static System.Drawing.Icon GetFolderIcon( + EnumIconSize size, + EnumFolderType folderType) + { + return GetFolderIcon(null, size, folderType); + } + + /// + /// lookup and return an icon from windows shell + /// + /// "folderPath">path to folder + /// "size">large or small + /// "folderType">open or closed + /// requested icon + public static System.Drawing.Icon GetFolderIcon( + string folderPath, + EnumIconSize size, + EnumFolderType folderType) + { + + EnumFileInfoFlags flags = + EnumFileInfoFlags.ICON | EnumFileInfoFlags.USEFILEATTRIBUTES; + + if (folderType == EnumFolderType.Open) + { + flags |= EnumFileInfoFlags.OPENICON; + } + + if (EnumIconSize.Small == size) + { + flags |= EnumFileInfoFlags.SMALLICON; + } + else + { + flags |= EnumFileInfoFlags.LARGEICON; + } + + ShellFileInfo shellFileInfo = new ShellFileInfo(); + SHGetFileInfo( + folderPath, + conFILE_ATTRIBUTE_DIRECTORY, + ref shellFileInfo, + (uint)System.Runtime.InteropServices.Marshal.SizeOf(shellFileInfo), + (uint)flags); + + // deep copy + System.Drawing.Icon icon = + (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shellFileInfo.hIcon).Clone(); + // release handle + DestroyIcon(shellFileInfo.hIcon); + return icon; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/ImportFromFileForm.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/ImportFromFileForm.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,218 @@ +namespace MyDownloader.App.UI +{ + partial class ImportFromFileForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnSelFile = new System.Windows.Forms.Button(); + this.txtFileName = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.btnCancel = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.rdoTextFile = new System.Windows.Forms.RadioButton(); + this.rdoHTML = new System.Windows.Forms.RadioButton(); + this.btnPreview = new System.Windows.Forms.Button(); + this.location1 = new MyDownloader.App.UI.Location(); + this.downloadFolder1 = new MyDownloader.Core.UI.DownloadFolder(); + this.scheduledDownloadEnabler1 = new MyDownloader.Extension.AutoDownloads.UI.ScheduledDownloadEnabler(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // btnSelFile + // + this.btnSelFile.Location = new System.Drawing.Point(429, 65); + this.btnSelFile.Name = "btnSelFile"; + this.btnSelFile.Size = new System.Drawing.Size(26, 23); + this.btnSelFile.TabIndex = 4; + this.btnSelFile.Text = "..."; + this.btnSelFile.UseVisualStyleBackColor = true; + this.btnSelFile.Click += new System.EventHandler(this.btnSelFile_Click); + // + // txtFileName + // + this.txtFileName.Location = new System.Drawing.Point(5, 68); + this.txtFileName.Name = "txtFileName"; + this.txtFileName.Size = new System.Drawing.Size(422, 20); + this.txtFileName.TabIndex = 3; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(5, 51); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(69, 13); + this.label1.TabIndex = 2; + this.label1.Text = "File to import:"; + // + // btnCancel + // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(383, 408); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 9; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // btnOK + // + this.btnOK.AllowDrop = true; + this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; + this.btnOK.Location = new System.Drawing.Point(302, 408); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 8; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // openFileDialog1 + // + this.openFileDialog1.FileName = "openFileDialog1"; + this.openFileDialog1.Filter = "HTML Files (*.html;*.htm)|*.html;*.htm|Text Files (*.txt)|*.txt|All File (*.*)|*." + + "*"; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.rdoTextFile); + this.groupBox1.Controls.Add(this.rdoHTML); + this.groupBox1.Location = new System.Drawing.Point(8, 3); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(449, 45); + this.groupBox1.TabIndex = 0; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Import from"; + // + // rdoTextFile + // + this.rdoTextFile.AutoSize = true; + this.rdoTextFile.Checked = true; + this.rdoTextFile.Location = new System.Drawing.Point(6, 19); + this.rdoTextFile.Name = "rdoTextFile"; + this.rdoTextFile.Size = new System.Drawing.Size(65, 17); + this.rdoTextFile.TabIndex = 0; + this.rdoTextFile.TabStop = true; + this.rdoTextFile.Text = "Text File"; + this.rdoTextFile.UseVisualStyleBackColor = true; + this.rdoTextFile.CheckedChanged += new System.EventHandler(this.rdoDownloadMode_Changed); + // + // rdoHTML + // + this.rdoHTML.AutoSize = true; + this.rdoHTML.Location = new System.Drawing.Point(172, 19); + this.rdoHTML.Name = "rdoHTML"; + this.rdoHTML.Size = new System.Drawing.Size(74, 17); + this.rdoHTML.TabIndex = 1; + this.rdoHTML.Text = "HTML File"; + this.rdoHTML.UseVisualStyleBackColor = true; + this.rdoHTML.CheckedChanged += new System.EventHandler(this.rdoDownloadMode_Changed); + // + // btnPreview + // + this.btnPreview.Location = new System.Drawing.Point(8, 408); + this.btnPreview.Name = "btnPreview"; + this.btnPreview.Size = new System.Drawing.Size(110, 23); + this.btnPreview.TabIndex = 7; + this.btnPreview.Text = "Preview URLs"; + this.btnPreview.UseVisualStyleBackColor = true; + this.btnPreview.Click += new System.EventHandler(this.btnPreview_Click); + // + // location1 + // + this.location1.Enabled = false; + this.location1.Location = new System.Drawing.Point(5, 142); + this.location1.Name = "location1"; + this.location1.Size = new System.Drawing.Size(449, 89); + this.location1.TabIndex = 1; + this.location1.UrlLabelTitle = "Base URL:"; + // + // downloadFolder1 + // + this.downloadFolder1.LabelText = "Save to:"; + this.downloadFolder1.Location = new System.Drawing.Point(5, 94); + this.downloadFolder1.Name = "downloadFolder1"; + this.downloadFolder1.Size = new System.Drawing.Size(450, 42); + this.downloadFolder1.TabIndex = 5; + // + // scheduledDownloadEnabler1 + // + this.scheduledDownloadEnabler1.Location = new System.Drawing.Point(5, 237); + this.scheduledDownloadEnabler1.Name = "scheduledDownloadEnabler1"; + this.scheduledDownloadEnabler1.Size = new System.Drawing.Size(450, 164); + this.scheduledDownloadEnabler1.TabIndex = 6; + // + // ImportFromFileForm + // + this.AcceptButton = this.btnOK; + this.AllowDrop = true; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(463, 437); + this.Controls.Add(this.location1); + this.Controls.Add(this.btnPreview); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.scheduledDownloadEnabler1); + this.Controls.Add(this.downloadFolder1); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.btnSelFile); + this.Controls.Add(this.txtFileName); + this.Controls.Add(this.label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "ImportFromFileForm"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Import from file"; + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnSelFile; + private System.Windows.Forms.TextBox txtFileName; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private MyDownloader.Core.UI.DownloadFolder downloadFolder1; + private MyDownloader.Extension.AutoDownloads.UI.ScheduledDownloadEnabler scheduledDownloadEnabler1; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Button btnPreview; + private System.Windows.Forms.RadioButton rdoTextFile; + private System.Windows.Forms.RadioButton rdoHTML; + private Location location1; + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/ImportFromFileForm.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/ImportFromFileForm.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,309 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using MyDownloader.Core; +using System.IO; +using System.Text.RegularExpressions; +using MyDownloader.Spider.Parsers.Html; +using MyDownloader.Core.UI; + +namespace MyDownloader.App.UI +{ + public partial class ImportFromFileForm : Form + { + public ImportFromFileForm() + { + InitializeComponent(); + } + + public string DownloadPath + { + get + { + return downloadFolder1.Folder; + } + } + + public ResourceLocation[] URLs + { + get + { + List urls = new List(); + + if (rdoTextFile.Checked) + { + FillListFromTextFile(urls); + } + else + { + FillListFromHtmlFile(urls); + } + + return urls.ToArray(); + } + } + + private void FillListFromHtmlFile(List urls) + { + using (Stream htmlStream = File.OpenRead(txtFileName.Text)) + { + using (HtmlParser parser = new HtmlParser(htmlStream)) + { + //TODO:fix for multiple file download??? + IEnumerator enumUri = parser.GetHrefs(this.location1.ResourceLocation[0].URL).GetEnumerator(); + + while (enumUri.MoveNext()) + { + ResourceLocation newRl = location1.ResourceLocation[0]; + newRl.URL = enumUri.Current.OriginalString; + urls.Add(newRl); + } + } + } + } + + private void FillListFromTextFile(List urls) + { + string[] lines = File.ReadAllLines(txtFileName.Text); + + for (int i = 0; i < lines.Length; i++) + { + string url = lines[i].Trim(); + + if (!String.IsNullOrEmpty(url) && ResourceLocation.IsURL(url)) + { + urls.Add(ResourceLocation.FromURL(url)); + } + } + } + + private void btnSelFile_Click(object sender, EventArgs e) + { + if (openFileDialog1.ShowDialog() == DialogResult.OK) + { + txtFileName.Text = openFileDialog1.FileName; + } + } + + public void ApplySettings() + { + scheduledDownloadEnabler1.ApplySettings(); + } + + /*private void CreateBatchDownloadForm_DragEnter(object sender, DragEventArgs e) + { + if (!string.IsNullOrEmpty(downloadFolder1.Folder)) + { + if ((e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy) + { + object data = ((IDataObject)e.Data).GetData("HTML Format", true); + if (data != null) + { + e.Effect = DragDropEffects.Copy; + } + } + } + } + + private string GetBaseFolder(string url) + { + Uri uri = new Uri(url); + return string.Format("{0}://{1}{2}", uri.Scheme, uri.Host, string.Join("", uri.Segments, 0, uri.Segments.Length - 1)); + } + + private void CreateBatchDownloadForm_DragDrop(object sender, DragEventArgs e) + { + //numFrom.Value = 0; + //numTo.Value = 0; + //location1.Clear(); + string html = GetDroppedHtmlSnippet(e); + string url = GetDroppedHtmlUrl(e); + string baseuri = GetBaseFolder(url); + List links = RetrieveLinks(html, url); + + dragdropURLs = ResourceLocation.FromURLArray(links.ToArray()); + //PreviewURLs(); + } + + private string GetDroppedHtmlSnippet(DragEventArgs e) + { + string text = ((DataObject)e.Data).GetData(DataFormats.Html) as string; + if (string.IsNullOrEmpty(text)) + { + text = ((DataObject)e.Data).GetData(DataFormats.Text) as string; + } + else + { + byte[] buffer = Encoding.Default.GetBytes(text); + text = Encoding.UTF8.GetString(buffer); + } + if (!string.IsNullOrEmpty(text)) + { + int startPos = text.IndexOf(""); + int endPos = text.IndexOf(""); + if (startPos != -1) + { + startPos += 20; + } + if (startPos != -1 && endPos != -1) + { + text = text.Substring(startPos, endPos - startPos); + } + if (string.IsNullOrEmpty(text)) + { + text = ((DataObject)e.Data).GetData(DataFormats.Rtf) as string; + if (string.IsNullOrEmpty(text)) + { + text = ((DataObject)e.Data).GetData(DataFormats.Text) as string; + } + } + } + text = text.Replace("Â", " "); //   + return text; + } + + private string GetDroppedHtmlUrl(DragEventArgs e) + { + string text = ((DataObject)e.Data).GetData(DataFormats.Html) as string; + if (!string.IsNullOrEmpty(text)) + { + int startPos = text.IndexOf("SourceURL:"); + int endPos = text.IndexOf("\r\n", startPos); + if (startPos != -1) + { + startPos += 10; + } + if (startPos != -1 && endPos != -1) + { + text = text.Substring(startPos, endPos - startPos); + } + if (string.IsNullOrEmpty(text)) + { + text = ((DataObject)e.Data).GetData(DataFormats.Rtf) as string; + if (string.IsNullOrEmpty(text)) + { + text = ((DataObject)e.Data).GetData(DataFormats.Text) as string; + } + } + } + return text; + } + + private List RetrieveLinks(string html, string baseUrl) + { + List tbl = new List(); + + if (html == null || html.Length == 0) + return tbl; + + for (Match m = RegExFindHref.Match(html); m.Success; m = m.NextMatch()) + { + + string href = m.Groups[1].ToString(); // filter non-real relation urls: + if (href.StartsWith("mailto:") || href.StartsWith("javascript:") || + href.EndsWith(".gif") || href.EndsWith(".jpg") || href.EndsWith(".png")) + { + continue; + } + href = ConvertToAbsoluteUrl(href, baseUrl); + if (href == null || href.Length == 0) + continue; + + string linkText = m.Groups[2].ToString(); + + if (!tbl.Contains(href)) + tbl.Add(href); + } + + return tbl; + } + + private string ConvertToAbsoluteUrl(string url, string baseUrl) + { + // we try to prevent the exception caused in the case the url is relative + // (no scheme info) just for speed + if (url.IndexOf(Uri.SchemeDelimiter) < 0 && baseUrl != null) + { + try + { + Uri baseUri = new Uri(baseUrl); + return (new Uri(baseUri, url).ToString()); + } + catch + { + return null; + } + } + + try + { + Uri uri = new Uri(url); + return uri.ToString(); + } + catch (Exception) + { + + if (baseUrl != null) + { + try + { + Uri baseUri = new Uri(baseUrl); + return (new Uri(baseUri, url).ToString()); + } + catch (Exception) + { + return null; + } + } + else + { + return null; + } + } + }*/ + + private void rdoDownloadMode_Changed(object sender, EventArgs e) + { + location1.Enabled = rdoHTML.Checked; + } + + private bool IsValid() + { + if (!File.Exists(txtFileName.Text)) + { + MessageBox.Show("Invalid file name.", + AppManager.Instance.Application.MainForm.Text, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + + return false; + } + + return true; + } + + private void btnPreview_Click(object sender, EventArgs e) + { + if (IsValid()) + { + using (ImportFromFilePreviewForm preview = new ImportFromFilePreviewForm(this.URLs)) + { + preview.ShowDialog(); + } + } + } + + private void btnOK_Click(object sender, EventArgs e) + { + if (! IsValid()) + { + DialogResult = DialogResult.None; + return; + } + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/ImportFromFileForm.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/ImportFromFileForm.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 15, 25 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/ImportFromFilePreviewForm.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/ImportFromFilePreviewForm.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,81 @@ +namespace MyDownloader.App.UI +{ + partial class ImportFromFilePreviewForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.button1 = new System.Windows.Forms.Button(); + this.lslUrls = new System.Windows.Forms.ListBox(); + this.SuspendLayout(); + // + // button1 + // + this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.button1.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.button1.Location = new System.Drawing.Point(473, 270); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 23); + this.button1.TabIndex = 1; + this.button1.Text = "Close"; + this.button1.UseVisualStyleBackColor = true; + // + // lslUrls + // + this.lslUrls.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lslUrls.FormattingEnabled = true; + this.lslUrls.Location = new System.Drawing.Point(8, 12); + this.lslUrls.Name = "lslUrls"; + this.lslUrls.Size = new System.Drawing.Size(540, 251); + this.lslUrls.TabIndex = 0; + // + // ImportFromFilePreviewForm + // + this.AcceptButton = this.button1; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.button1; + this.ClientSize = new System.Drawing.Size(555, 298); + this.Controls.Add(this.lslUrls); + this.Controls.Add(this.button1); + this.MinimizeBox = false; + this.Name = "ImportFromFilePreviewForm"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Import From File - Preview"; + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button button1; + private System.Windows.Forms.ListBox lslUrls; + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/ImportFromFilePreviewForm.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/ImportFromFilePreviewForm.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using MyDownloader.Core; + +namespace MyDownloader.App.UI +{ + public partial class ImportFromFilePreviewForm : Form + { + public ImportFromFilePreviewForm(ResourceLocation[] locations) + { + InitializeComponent(); + + lslUrls.DataSource = locations; + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/ImportFromFilePreviewForm.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/ImportFromFilePreviewForm.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/MainForm.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/MainForm.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,779 @@ +using MyDownloader.Spider.UI; +namespace MyDownloader.App.UI +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); + this.tmrRefresh = new System.Windows.Forms.Timer(this.components); + this.toolStripMain = new System.Windows.Forms.ToolStrip(); + this.tsbMenu = new System.Windows.Forms.ToolStripButton(); + this.toolNewDownload = new System.Windows.Forms.ToolStripButton(); + this.toolStripButton1 = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStart = new System.Windows.Forms.ToolStripButton(); + this.toolStripScheduler = new System.Windows.Forms.ToolStripButton(); + this.toolPause = new System.Windows.Forms.ToolStripButton(); + this.toolPauseAll = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.toolRemove = new System.Windows.Forms.ToolStripButton(); + this.toolRemoveCompleted = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.toolMoveSelectionsUp = new System.Windows.Forms.ToolStripButton(); + this.toolMoveSelectionsDown = new System.Windows.Forms.ToolStripButton(); + this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components); + this.notifyIconContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components); + this.showHideToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.clipboardMonitoringToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator14 = new System.Windows.Forms.ToolStripSeparator(); + this.newDownloadToolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); + this.newBatchDownloadToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator11 = new System.Windows.Forms.ToolStripSeparator(); + this.pauseAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator12 = new System.Windows.Forms.ToolStripSeparator(); + this.optionsToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator13 = new System.Windows.Forms.ToolStripSeparator(); + this.exitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.menuBarStrip = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.newDownloadToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.newVideoDownloadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.newBatchDownloadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator(); + this.importFromTextFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.removeCompletedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); + this.selectAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.copyURLToClipboardToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator9 = new System.Windows.Forms.ToolStripSeparator(); + this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripMenuItem(); + this.segmentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolbarToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.gridToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator10 = new System.Windows.Forms.ToolStripSeparator(); + this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.faTabStrip1 = new FarsiLibrary.Win.FATabStrip(); + this.faTabStripItem1 = new FarsiLibrary.Win.FATabStripItem(); + this.downloadList1 = new MyDownloader.App.UI.DownloadList(); + this.faTabStripItem2 = new FarsiLibrary.Win.FATabStripItem(); + this.webSpider1 = new MyDownloader.Spider.UI.WebSpider(); + this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.cntxMenuDownLimit = new System.Windows.Forms.ContextMenuStrip(this.components); + this.setCustomToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.enableSpeedLimitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripLblRate = new System.Windows.Forms.ToolStripStatusLabel(); + this.toolStripLblRateTxt = new System.Windows.Forms.ToolStripStatusLabel(); + this.toolStripMain.SuspendLayout(); + this.notifyIconContextMenu.SuspendLayout(); + this.menuBarStrip.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.faTabStrip1)).BeginInit(); + this.faTabStrip1.SuspendLayout(); + this.faTabStripItem1.SuspendLayout(); + this.faTabStripItem2.SuspendLayout(); + this.statusStrip1.SuspendLayout(); + this.cntxMenuDownLimit.SuspendLayout(); + this.SuspendLayout(); + // + // tmrRefresh + // + this.tmrRefresh.Enabled = true; + this.tmrRefresh.Interval = 1500; + this.tmrRefresh.Tick += new System.EventHandler(this.tmrRefresh_Tick); + // + // toolStripMain + // + this.toolStripMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.tsbMenu, + this.toolNewDownload, + this.toolStripButton1, + this.toolStripSeparator1, + this.toolStart, + this.toolStripScheduler, + this.toolPause, + this.toolPauseAll, + this.toolStripSeparator2, + this.toolRemove, + this.toolRemoveCompleted, + this.toolStripSeparator3, + this.toolMoveSelectionsUp, + this.toolMoveSelectionsDown}); + this.toolStripMain.Location = new System.Drawing.Point(0, 0); + this.toolStripMain.Name = "toolStripMain"; + this.toolStripMain.Size = new System.Drawing.Size(541, 25); + this.toolStripMain.TabIndex = 1; + // + // tsbMenu + // + this.tsbMenu.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.tsbMenu.Image = ((System.Drawing.Image)(resources.GetObject("tsbMenu.Image"))); + this.tsbMenu.ImageTransparentColor = System.Drawing.Color.Magenta; + this.tsbMenu.Name = "tsbMenu"; + this.tsbMenu.Size = new System.Drawing.Size(23, 22); + this.tsbMenu.Text = "Toggle menu bar"; + this.tsbMenu.Click += new System.EventHandler(this.tsbMenu_Click); + // + // toolNewDownload + // + this.toolNewDownload.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolNewDownload.Image = ((System.Drawing.Image)(resources.GetObject("toolNewDownload.Image"))); + this.toolNewDownload.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolNewDownload.Name = "toolNewDownload"; + this.toolNewDownload.Size = new System.Drawing.Size(23, 22); + this.toolNewDownload.Text = "New Download"; + this.toolNewDownload.Click += new System.EventHandler(this.toolNewDownload_Click); + // + // toolStripButton1 + // + this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image"))); + this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton1.Name = "toolStripButton1"; + this.toolStripButton1.Size = new System.Drawing.Size(127, 22); + this.toolStripButton1.Text = "New Video Download"; + this.toolStripButton1.ToolTipText = "New Video Download (from YouTube, GoogleVideo, Break...)"; + this.toolStripButton1.Click += new System.EventHandler(this.newVideoDownloadToolStripMenuItem_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // toolStart + // + this.toolStart.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStart.Image = ((System.Drawing.Image)(resources.GetObject("toolStart.Image"))); + this.toolStart.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStart.Name = "toolStart"; + this.toolStart.Size = new System.Drawing.Size(23, 22); + this.toolStart.Text = "Start"; + this.toolStart.Click += new System.EventHandler(this.toolStart_Click); + // + // toolStripScheduler + // + this.toolStripScheduler.CheckOnClick = true; + this.toolStripScheduler.Image = ((System.Drawing.Image)(resources.GetObject("toolStripScheduler.Image"))); + this.toolStripScheduler.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripScheduler.Name = "toolStripScheduler"; + this.toolStripScheduler.Size = new System.Drawing.Size(106, 22); + this.toolStripScheduler.Text = "Auto-Downloads"; + this.toolStripScheduler.ToolTipText = "Toggle Auto-Downloads On/Off"; + this.toolStripScheduler.Click += new System.EventHandler(this.toolStripScheduler_Click); + // + // toolPause + // + this.toolPause.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolPause.Image = ((System.Drawing.Image)(resources.GetObject("toolPause.Image"))); + this.toolPause.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolPause.Name = "toolPause"; + this.toolPause.Size = new System.Drawing.Size(23, 22); + this.toolPause.Text = "Pause"; + this.toolPause.Click += new System.EventHandler(this.toolPause_Click); + // + // toolPauseAll + // + this.toolPauseAll.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolPauseAll.Image = ((System.Drawing.Image)(resources.GetObject("toolPauseAll.Image"))); + this.toolPauseAll.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolPauseAll.Name = "toolPauseAll"; + this.toolPauseAll.Size = new System.Drawing.Size(23, 22); + this.toolPauseAll.Text = "Pause All"; + this.toolPauseAll.Click += new System.EventHandler(this.toolPauseAll_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); + // + // toolRemove + // + this.toolRemove.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolRemove.Image = ((System.Drawing.Image)(resources.GetObject("toolRemove.Image"))); + this.toolRemove.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolRemove.Name = "toolRemove"; + this.toolRemove.Size = new System.Drawing.Size(23, 22); + this.toolRemove.Text = "Remove"; + this.toolRemove.Click += new System.EventHandler(this.toolRemove_Click); + // + // toolRemoveCompleted + // + this.toolRemoveCompleted.Image = ((System.Drawing.Image)(resources.GetObject("toolRemoveCompleted.Image"))); + this.toolRemoveCompleted.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolRemoveCompleted.Name = "toolRemoveCompleted"; + this.toolRemoveCompleted.Size = new System.Drawing.Size(120, 22); + this.toolRemoveCompleted.Text = "Remove Completed"; + this.toolRemoveCompleted.Click += new System.EventHandler(this.toolRemoveCompleted_Click); + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(6, 25); + // + // toolMoveSelectionsUp + // + this.toolMoveSelectionsUp.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolMoveSelectionsUp.Image = ((System.Drawing.Image)(resources.GetObject("toolMoveSelectionsUp.Image"))); + this.toolMoveSelectionsUp.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolMoveSelectionsUp.Name = "toolMoveSelectionsUp"; + this.toolMoveSelectionsUp.Size = new System.Drawing.Size(23, 20); + this.toolMoveSelectionsUp.Text = "Move Selections Up"; + this.toolMoveSelectionsUp.Click += new System.EventHandler(this.toolStripButton2_Click); + // + // toolMoveSelectionsDown + // + this.toolMoveSelectionsDown.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolMoveSelectionsDown.Image = ((System.Drawing.Image)(resources.GetObject("toolMoveSelectionsDown.Image"))); + this.toolMoveSelectionsDown.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolMoveSelectionsDown.Name = "toolMoveSelectionsDown"; + this.toolMoveSelectionsDown.Size = new System.Drawing.Size(23, 20); + this.toolMoveSelectionsDown.Text = "Move Selections Down"; + this.toolMoveSelectionsDown.Click += new System.EventHandler(this.toolStripButton3_Click); + // + // notifyIcon + // + this.notifyIcon.ContextMenuStrip = this.notifyIconContextMenu; + this.notifyIcon.Text = "notifyIcon1"; + this.notifyIcon.Visible = true; + this.notifyIcon.MouseClick += new System.Windows.Forms.MouseEventHandler(this.showHideToolStripMenuItem_Click); + // + // notifyIconContextMenu + // + this.notifyIconContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.showHideToolStripMenuItem, + this.toolStripSeparator4, + this.clipboardMonitoringToolStripMenuItem, + this.toolStripSeparator14, + this.newDownloadToolStripMenuItem2, + this.newBatchDownloadToolStripMenuItem1, + this.toolStripSeparator11, + this.pauseAllToolStripMenuItem, + this.toolStripSeparator12, + this.optionsToolStripMenuItem1, + this.toolStripSeparator13, + this.exitToolStripMenuItem1}); + this.notifyIconContextMenu.Name = "notifyIconContextMenu"; + this.notifyIconContextMenu.Size = new System.Drawing.Size(188, 188); + this.notifyIconContextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.notifyIconContextMenu_Opening); + // + // showHideToolStripMenuItem + // + this.showHideToolStripMenuItem.Name = "showHideToolStripMenuItem"; + this.showHideToolStripMenuItem.Size = new System.Drawing.Size(187, 22); + this.showHideToolStripMenuItem.Text = "Show/Hide"; + this.showHideToolStripMenuItem.Click += new System.EventHandler(this.showHideToolStripMenuItem_Click); + // + // toolStripSeparator4 + // + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(184, 6); + // + // clipboardMonitoringToolStripMenuItem + // + this.clipboardMonitoringToolStripMenuItem.CheckOnClick = true; + this.clipboardMonitoringToolStripMenuItem.Name = "clipboardMonitoringToolStripMenuItem"; + this.clipboardMonitoringToolStripMenuItem.Size = new System.Drawing.Size(187, 22); + this.clipboardMonitoringToolStripMenuItem.Text = "Clipboard monitoring"; + this.clipboardMonitoringToolStripMenuItem.Click += new System.EventHandler(this.clipboardMonitoringToolStripMenuItem_Click); + // + // toolStripSeparator14 + // + this.toolStripSeparator14.Name = "toolStripSeparator14"; + this.toolStripSeparator14.Size = new System.Drawing.Size(184, 6); + // + // newDownloadToolStripMenuItem2 + // + this.newDownloadToolStripMenuItem2.Name = "newDownloadToolStripMenuItem2"; + this.newDownloadToolStripMenuItem2.Size = new System.Drawing.Size(187, 22); + this.newDownloadToolStripMenuItem2.Text = "New Download..."; + this.newDownloadToolStripMenuItem2.Click += new System.EventHandler(this.toolNewDownload_Click); + // + // newBatchDownloadToolStripMenuItem1 + // + this.newBatchDownloadToolStripMenuItem1.Name = "newBatchDownloadToolStripMenuItem1"; + this.newBatchDownloadToolStripMenuItem1.Size = new System.Drawing.Size(187, 22); + this.newBatchDownloadToolStripMenuItem1.Text = "New Batch Download..."; + this.newBatchDownloadToolStripMenuItem1.Click += new System.EventHandler(this.newBatchDownloadToolStripMenuItem_Click); + // + // toolStripSeparator11 + // + this.toolStripSeparator11.Name = "toolStripSeparator11"; + this.toolStripSeparator11.Size = new System.Drawing.Size(184, 6); + // + // pauseAllToolStripMenuItem + // + this.pauseAllToolStripMenuItem.Name = "pauseAllToolStripMenuItem"; + this.pauseAllToolStripMenuItem.Size = new System.Drawing.Size(187, 22); + this.pauseAllToolStripMenuItem.Text = "Pause All"; + this.pauseAllToolStripMenuItem.Click += new System.EventHandler(this.toolPauseAll_Click); + // + // toolStripSeparator12 + // + this.toolStripSeparator12.Name = "toolStripSeparator12"; + this.toolStripSeparator12.Size = new System.Drawing.Size(184, 6); + // + // optionsToolStripMenuItem1 + // + this.optionsToolStripMenuItem1.Name = "optionsToolStripMenuItem1"; + this.optionsToolStripMenuItem1.Size = new System.Drawing.Size(187, 22); + this.optionsToolStripMenuItem1.Text = "Options..."; + this.optionsToolStripMenuItem1.Click += new System.EventHandler(this.toolOptions_Click); + // + // toolStripSeparator13 + // + this.toolStripSeparator13.Name = "toolStripSeparator13"; + this.toolStripSeparator13.Size = new System.Drawing.Size(184, 6); + // + // exitToolStripMenuItem1 + // + this.exitToolStripMenuItem1.Name = "exitToolStripMenuItem1"; + this.exitToolStripMenuItem1.Size = new System.Drawing.Size(187, 22); + this.exitToolStripMenuItem1.Text = "Exit"; + this.exitToolStripMenuItem1.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // menuBarStrip + // + this.menuBarStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem, + this.editToolStripMenuItem, + this.toolStripMenuItem4, + this.helpToolStripMenuItem}); + this.menuBarStrip.Location = new System.Drawing.Point(0, 0); + this.menuBarStrip.Name = "menuBarStrip"; + this.menuBarStrip.Size = new System.Drawing.Size(541, 24); + this.menuBarStrip.TabIndex = 0; + this.menuBarStrip.Text = "menuStrip1"; + this.menuBarStrip.Visible = false; + this.menuBarStrip.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.menuBarStrip_ItemClicked); + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.newDownloadToolStripMenuItem1, + this.newVideoDownloadToolStripMenuItem, + this.newBatchDownloadToolStripMenuItem, + this.toolStripSeparator8, + this.importFromTextFileToolStripMenuItem, + this.toolStripSeparator5, + this.exitToolStripMenuItem}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20); + this.fileToolStripMenuItem.Text = "File"; + // + // newDownloadToolStripMenuItem1 + // + this.newDownloadToolStripMenuItem1.Name = "newDownloadToolStripMenuItem1"; + this.newDownloadToolStripMenuItem1.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N))); + this.newDownloadToolStripMenuItem1.Size = new System.Drawing.Size(255, 22); + this.newDownloadToolStripMenuItem1.Text = "New Download..."; + this.newDownloadToolStripMenuItem1.Click += new System.EventHandler(this.toolNewDownload_Click); + // + // newVideoDownloadToolStripMenuItem + // + this.newVideoDownloadToolStripMenuItem.Name = "newVideoDownloadToolStripMenuItem"; + this.newVideoDownloadToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) + | System.Windows.Forms.Keys.N))); + this.newVideoDownloadToolStripMenuItem.Size = new System.Drawing.Size(255, 22); + this.newVideoDownloadToolStripMenuItem.Text = "New Video Download..."; + this.newVideoDownloadToolStripMenuItem.Click += new System.EventHandler(this.newVideoDownloadToolStripMenuItem_Click); + // + // newBatchDownloadToolStripMenuItem + // + this.newBatchDownloadToolStripMenuItem.Name = "newBatchDownloadToolStripMenuItem"; + this.newBatchDownloadToolStripMenuItem.Size = new System.Drawing.Size(255, 22); + this.newBatchDownloadToolStripMenuItem.Text = "New Batch Download..."; + this.newBatchDownloadToolStripMenuItem.Click += new System.EventHandler(this.newBatchDownloadToolStripMenuItem_Click); + // + // toolStripSeparator8 + // + this.toolStripSeparator8.Name = "toolStripSeparator8"; + this.toolStripSeparator8.Size = new System.Drawing.Size(252, 6); + // + // importFromTextFileToolStripMenuItem + // + this.importFromTextFileToolStripMenuItem.Name = "importFromTextFileToolStripMenuItem"; + this.importFromTextFileToolStripMenuItem.Size = new System.Drawing.Size(255, 22); + this.importFromTextFileToolStripMenuItem.Text = "Import from file..."; + this.importFromTextFileToolStripMenuItem.Click += new System.EventHandler(this.importFromTextFileToolStripMenuItem_Click); + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(252, 6); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(255, 22); + this.exitToolStripMenuItem.Text = "Exit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // editToolStripMenuItem + // + this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.removeToolStripMenuItem, + this.removeCompletedToolStripMenuItem, + this.toolStripSeparator6, + this.selectAllToolStripMenuItem, + this.copyURLToClipboardToolStripMenuItem1, + this.toolStripSeparator9, + this.optionsToolStripMenuItem}); + this.editToolStripMenuItem.Name = "editToolStripMenuItem"; + this.editToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + this.editToolStripMenuItem.Text = "Edit"; + // + // removeToolStripMenuItem + // + this.removeToolStripMenuItem.Name = "removeToolStripMenuItem"; + this.removeToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Delete; + this.removeToolStripMenuItem.Size = new System.Drawing.Size(219, 22); + this.removeToolStripMenuItem.Text = "Remove"; + this.removeToolStripMenuItem.Click += new System.EventHandler(this.toolRemove_Click); + // + // removeCompletedToolStripMenuItem + // + this.removeCompletedToolStripMenuItem.Name = "removeCompletedToolStripMenuItem"; + this.removeCompletedToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Shift | System.Windows.Forms.Keys.Delete))); + this.removeCompletedToolStripMenuItem.Size = new System.Drawing.Size(219, 22); + this.removeCompletedToolStripMenuItem.Text = "Remove Completed"; + this.removeCompletedToolStripMenuItem.Click += new System.EventHandler(this.toolRemoveCompleted_Click); + // + // toolStripSeparator6 + // + this.toolStripSeparator6.Name = "toolStripSeparator6"; + this.toolStripSeparator6.Size = new System.Drawing.Size(216, 6); + // + // selectAllToolStripMenuItem + // + this.selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem"; + this.selectAllToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A))); + this.selectAllToolStripMenuItem.Size = new System.Drawing.Size(219, 22); + this.selectAllToolStripMenuItem.Text = "Select All"; + this.selectAllToolStripMenuItem.Click += new System.EventHandler(this.selectAllToolStripMenuItem_Click); + // + // copyURLToClipboardToolStripMenuItem1 + // + this.copyURLToClipboardToolStripMenuItem1.Name = "copyURLToClipboardToolStripMenuItem1"; + this.copyURLToClipboardToolStripMenuItem1.Size = new System.Drawing.Size(219, 22); + this.copyURLToClipboardToolStripMenuItem1.Text = "Copy URL to Clipboard"; + // + // toolStripSeparator9 + // + this.toolStripSeparator9.Name = "toolStripSeparator9"; + this.toolStripSeparator9.Size = new System.Drawing.Size(216, 6); + // + // optionsToolStripMenuItem + // + this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem"; + this.optionsToolStripMenuItem.Size = new System.Drawing.Size(219, 22); + this.optionsToolStripMenuItem.Text = "Options..."; + this.optionsToolStripMenuItem.Click += new System.EventHandler(this.toolOptions_Click); + // + // toolStripMenuItem4 + // + this.toolStripMenuItem4.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.segmentsToolStripMenuItem, + this.toolbarToolStripMenuItem, + this.gridToolStripMenuItem}); + this.toolStripMenuItem4.Name = "toolStripMenuItem4"; + this.toolStripMenuItem4.Size = new System.Drawing.Size(41, 20); + this.toolStripMenuItem4.Text = "View"; + // + // segmentsToolStripMenuItem + // + this.segmentsToolStripMenuItem.Name = "segmentsToolStripMenuItem"; + this.segmentsToolStripMenuItem.Size = new System.Drawing.Size(121, 22); + this.segmentsToolStripMenuItem.Text = "Segments"; + this.segmentsToolStripMenuItem.Click += new System.EventHandler(this.viewMenuClickClick); + // + // toolbarToolStripMenuItem + // + this.toolbarToolStripMenuItem.Name = "toolbarToolStripMenuItem"; + this.toolbarToolStripMenuItem.Size = new System.Drawing.Size(121, 22); + this.toolbarToolStripMenuItem.Text = "Toolbar"; + this.toolbarToolStripMenuItem.Click += new System.EventHandler(this.viewMenuClickClick); + // + // gridToolStripMenuItem + // + this.gridToolStripMenuItem.Name = "gridToolStripMenuItem"; + this.gridToolStripMenuItem.Size = new System.Drawing.Size(121, 22); + this.gridToolStripMenuItem.Text = "Grid"; + this.gridToolStripMenuItem.Click += new System.EventHandler(this.viewMenuClickClick); + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripMenuItem2, + this.toolStripMenuItem1, + this.toolStripSeparator10, + this.aboutToolStripMenuItem}); + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(40, 20); + this.helpToolStripMenuItem.Text = "Help"; + // + // toolStripMenuItem2 + // + this.toolStripMenuItem2.Name = "toolStripMenuItem2"; + this.toolStripMenuItem2.Size = new System.Drawing.Size(205, 22); + this.toolStripMenuItem2.Text = "My Downloader Home Page"; + // + // toolStripMenuItem1 + // + this.toolStripMenuItem1.Name = "toolStripMenuItem1"; + this.toolStripMenuItem1.Size = new System.Drawing.Size(205, 22); + this.toolStripMenuItem1.Text = "Make a Donation"; + // + // toolStripSeparator10 + // + this.toolStripSeparator10.Name = "toolStripSeparator10"; + this.toolStripSeparator10.Size = new System.Drawing.Size(202, 6); + // + // aboutToolStripMenuItem + // + this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; + this.aboutToolStripMenuItem.Size = new System.Drawing.Size(205, 22); + this.aboutToolStripMenuItem.Text = "About..."; + this.aboutToolStripMenuItem.Click += new System.EventHandler(this.toolAbout_Click); + // + // faTabStrip1 + // + this.faTabStrip1.AlwaysShowClose = false; + this.faTabStrip1.AlwaysShowMenuGlyph = false; + this.faTabStrip1.Dock = System.Windows.Forms.DockStyle.Fill; + this.faTabStrip1.Font = new System.Drawing.Font("Tahoma", 8.25F); + this.faTabStrip1.Items.AddRange(new FarsiLibrary.Win.FATabStripItem[] { + this.faTabStripItem1, + this.faTabStripItem2}); + this.faTabStrip1.Location = new System.Drawing.Point(0, 25); + this.faTabStrip1.Name = "faTabStrip1"; + this.faTabStrip1.SelectedItem = this.faTabStripItem1; + this.faTabStrip1.Size = new System.Drawing.Size(541, 353); + this.faTabStrip1.TabIndex = 2; + this.faTabStrip1.Text = "Downloads"; + // + // faTabStripItem1 + // + this.faTabStripItem1.CanClose = false; + this.faTabStripItem1.Controls.Add(this.downloadList1); + this.faTabStripItem1.IsDrawn = true; + this.faTabStripItem1.Name = "faTabStripItem1"; + this.faTabStripItem1.Selected = true; + this.faTabStripItem1.Size = new System.Drawing.Size(539, 332); + this.faTabStripItem1.TabIndex = 0; + this.faTabStripItem1.Title = "Downloads"; + // + // downloadList1 + // + this.downloadList1.ClipboardMonitorEnabled = false; + this.downloadList1.Dock = System.Windows.Forms.DockStyle.Fill; + this.downloadList1.Location = new System.Drawing.Point(0, 0); + this.downloadList1.Name = "downloadList1"; + this.downloadList1.Size = new System.Drawing.Size(539, 332); + this.downloadList1.TabIndex = 0; + // + // faTabStripItem2 + // + this.faTabStripItem2.CanClose = false; + this.faTabStripItem2.Controls.Add(this.webSpider1); + this.faTabStripItem2.IsDrawn = true; + this.faTabStripItem2.Name = "faTabStripItem2"; + this.faTabStripItem2.Size = new System.Drawing.Size(655, 320); + this.faTabStripItem2.TabIndex = 1; + this.faTabStripItem2.Title = "Web Spider"; + // + // webSpider1 + // + this.webSpider1.Dock = System.Windows.Forms.DockStyle.Fill; + this.webSpider1.Location = new System.Drawing.Point(0, 0); + this.webSpider1.Name = "webSpider1"; + this.webSpider1.Size = new System.Drawing.Size(655, 320); + this.webSpider1.TabIndex = 0; + // + // statusStrip1 + // + this.statusStrip1.ContextMenuStrip = this.cntxMenuDownLimit; + this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripLblRate, + this.toolStripLblRateTxt}); + this.statusStrip1.Location = new System.Drawing.Point(0, 378); + this.statusStrip1.Name = "statusStrip1"; + this.statusStrip1.Size = new System.Drawing.Size(541, 22); + this.statusStrip1.TabIndex = 3; + this.statusStrip1.Text = "statusStrip1"; + // + // cntxMenuDownLimit + // + this.cntxMenuDownLimit.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.setCustomToolStripMenuItem, + this.enableSpeedLimitToolStripMenuItem}); + this.cntxMenuDownLimit.Name = "cntxMenuDownLimit"; + this.cntxMenuDownLimit.Size = new System.Drawing.Size(164, 48); + this.cntxMenuDownLimit.Opening += new System.ComponentModel.CancelEventHandler(this.cntxMenuDownLimit_Opening); + // + // setCustomToolStripMenuItem + // + this.setCustomToolStripMenuItem.Name = "setCustomToolStripMenuItem"; + this.setCustomToolStripMenuItem.Size = new System.Drawing.Size(163, 22); + this.setCustomToolStripMenuItem.Text = "Set Custom..."; + this.setCustomToolStripMenuItem.Click += new System.EventHandler(this.setCustomToolStripMenuItem_Click); + // + // enableSpeedLimitToolStripMenuItem + // + this.enableSpeedLimitToolStripMenuItem.CheckOnClick = true; + this.enableSpeedLimitToolStripMenuItem.Name = "enableSpeedLimitToolStripMenuItem"; + this.enableSpeedLimitToolStripMenuItem.Size = new System.Drawing.Size(163, 22); + this.enableSpeedLimitToolStripMenuItem.Text = "Enable Speed Limit"; + this.enableSpeedLimitToolStripMenuItem.Click += new System.EventHandler(this.enableSpeedLimitToolStripMenuItem_Click); + // + // toolStripLblRate + // + this.toolStripLblRate.Name = "toolStripLblRate"; + this.toolStripLblRate.Size = new System.Drawing.Size(34, 17); + this.toolStripLblRate.Text = "Rate:"; + // + // toolStripLblRateTxt + // + this.toolStripLblRateTxt.Name = "toolStripLblRateTxt"; + this.toolStripLblRateTxt.Size = new System.Drawing.Size(38, 17); + this.toolStripLblRateTxt.Text = "0 kbps"; + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(541, 400); + this.Controls.Add(this.faTabStrip1); + this.Controls.Add(this.toolStripMain); + this.Controls.Add(this.menuBarStrip); + this.Controls.Add(this.statusStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MainMenuStrip = this.menuBarStrip; + this.Name = "MainForm"; + this.Text = ".Net Download Manager"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); + this.Load += new System.EventHandler(this.MainForm_Load); + this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyDown); + this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.MainForm_KeyPress); + this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyUp); + this.toolStripMain.ResumeLayout(false); + this.toolStripMain.PerformLayout(); + this.notifyIconContextMenu.ResumeLayout(false); + this.menuBarStrip.ResumeLayout(false); + this.menuBarStrip.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.faTabStrip1)).EndInit(); + this.faTabStrip1.ResumeLayout(false); + this.faTabStripItem1.ResumeLayout(false); + this.faTabStripItem2.ResumeLayout(false); + this.statusStrip1.ResumeLayout(false); + this.statusStrip1.PerformLayout(); + this.cntxMenuDownLimit.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Timer tmrRefresh; + private System.Windows.Forms.ToolStrip toolStripMain; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripButton toolStart; + private System.Windows.Forms.ToolStripButton toolPause; + private System.Windows.Forms.ToolStripButton toolPauseAll; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripButton toolRemove; + private System.Windows.Forms.ToolStripButton toolRemoveCompleted; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; + private System.Windows.Forms.ToolStripButton toolNewDownload; + internal System.Windows.Forms.NotifyIcon notifyIcon; + private System.Windows.Forms.MenuStrip menuBarStrip; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem newDownloadToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem newBatchDownloadToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator8; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem copyURLToClipboardToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem removeCompletedToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator9; + private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem2; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator10; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem4; + private System.Windows.Forms.ToolStripMenuItem segmentsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem toolbarToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem gridToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1; + private System.Windows.Forms.ContextMenuStrip notifyIconContextMenu; + private System.Windows.Forms.ToolStripMenuItem newDownloadToolStripMenuItem2; + private System.Windows.Forms.ToolStripMenuItem newBatchDownloadToolStripMenuItem1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator11; + private System.Windows.Forms.ToolStripMenuItem pauseAllToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator12; + private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator13; + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator14; + private System.Windows.Forms.ToolStripMenuItem showHideToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem newVideoDownloadToolStripMenuItem; + private System.Windows.Forms.ToolStripButton toolStripButton1; + private System.Windows.Forms.ToolStripButton toolStripScheduler; + private FarsiLibrary.Win.FATabStrip faTabStrip1; + private FarsiLibrary.Win.FATabStripItem faTabStripItem1; + protected internal DownloadList downloadList1; + private System.Windows.Forms.ToolStripMenuItem importFromTextFileToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator6; + private System.Windows.Forms.StatusStrip statusStrip1; + private System.Windows.Forms.ToolStripStatusLabel toolStripLblRate; + private System.Windows.Forms.ToolStripStatusLabel toolStripLblRateTxt; + private System.Windows.Forms.ToolStripButton toolMoveSelectionsUp; + private System.Windows.Forms.ToolStripButton toolMoveSelectionsDown; + private System.Windows.Forms.ContextMenuStrip cntxMenuDownLimit; + private System.Windows.Forms.ToolStripMenuItem setCustomToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem enableSpeedLimitToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem selectAllToolStripMenuItem; + private FarsiLibrary.Win.FATabStripItem faTabStripItem2; + private WebSpider webSpider1; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + private System.Windows.Forms.ToolStripMenuItem clipboardMonitoringToolStripMenuItem; + private System.Windows.Forms.ToolStripButton tsbMenu; + + + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/MainForm.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/MainForm.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,334 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Collections; +using System.IO; +using System.Web; +using System.Diagnostics; + +using MyDownloader.Core; +using MyDownloader.Core.Common; +using MyDownloader.App.SingleInstancing; +using MyDownloader.Extension.AutoDownloads; +using MyDownloader.Core.Extensions; +using MyDownloader.Extension.SpeedLimit; +using MyDownloader.Extension.Video; +using MyDownloader.Extension.WindowsIntegration.ClipboardMonitor; + +namespace MyDownloader.App.UI +{ + public partial class MainForm : Form, ISingleInstanceEnforcer + { + SpeedLimitExtension speedLimit; + + public MainForm() + { + InitializeComponent(); + + downloadList1.SelectionChange += new EventHandler(downloadList1_SelectionChange); + downloadList1.UpdateUI(); + + speedLimit = (SpeedLimitExtension)App.Instance.GetExtensionByType(typeof(SpeedLimitExtension)); + this.KeyUp+=new KeyEventHandler(MainForm_KeyUp); + this.KeyPreview = true; + } + + void downloadList1_SelectionChange(object sender, EventArgs e) + { + int cnt = downloadList1.SelectedCount; + + bool isSelected = cnt > 0; + bool isSelectedOnlyOne = cnt == 1; + + removeToolStripMenuItem.Enabled = isSelected; + removeCompletedToolStripMenuItem.Enabled = isSelected; + + toolStart.Enabled = isSelected; + toolPause.Enabled = isSelected; + toolRemove.Enabled = isSelected; + + copyURLToClipboardToolStripMenuItem1.Enabled = isSelectedOnlyOne; + + toolMoveSelectionsDown.Enabled = isSelected; + toolMoveSelectionsUp.Enabled = isSelected; + } + + private void tmrRefresh_Tick(object sender, EventArgs e) + { + string strRate; + + if (speedLimit.CurrentEnabled) + { + strRate = String.Format("[{0:0.##} kpbs] {1:0.##} kbps", + speedLimit.CurrentMaxRate / 1024.0, + DownloadManager.Instance.TotalDownloadRate / 1024.0); + } + else + { + strRate = String.Format("{0:0.##} kbps", DownloadManager.Instance.TotalDownloadRate / 1024.0); + } + + toolStripScheduler.Checked = downloadList1.SchedulerStarted(); + + toolStripLblRateTxt.Text = strRate; + + notifyIcon.Text = String.Concat(this.Text, "\n", toolStripLblRate.Text, " ", strRate); + + downloadList1.UpdateList(); + } + + private void MainForm_Load(object sender, EventArgs e) + { + LoadViewSettings(); + + notifyIcon.Icon = this.Icon; + notifyIcon.Text = this.Text; + notifyIcon.Visible = true; + } + + private void toolNewDownload_Click(object sender, EventArgs e) + { + downloadList1.NewFileDownload(null, true); + } + + private void toolStart_Click(object sender, EventArgs e) + { + downloadList1.StartSelections(); + } + + private void toolPause_Click(object sender, EventArgs e) + { + downloadList1.Pause(); + } + + private void toolPauseAll_Click(object sender, EventArgs e) + { + downloadList1.PauseAll(); + } + + private void toolRemove_Click(object sender, EventArgs e) + { + downloadList1.RemoveSelections(); + } + + private void toolRemoveCompleted_Click(object sender, EventArgs e) + { + downloadList1.RemoveCompleted(); + } + + private void toolOptions_Click(object sender, EventArgs e) + { + using (OptionsForm options = new OptionsForm()) + { + options.ShowDialog(); + } + } + + private void toolAbout_Click(object sender, EventArgs e) + { + using (AboutForm about = new AboutForm()) + { + about.ShowDialog(); + } + } + + #region ISingleInstanceEnforcer Members + + public void OnMessageReceived(MessageEventArgs e) + { + string[] args = (string[])e.Message; + + if (args.Length == 2 && args[0] == "/sw") + { + this.BeginInvoke((MethodInvoker) delegate { downloadList1.NewDownloadFromData(args[1]); }); + } + else + { + downloadList1.AddDownloadURLs(ResourceLocation.FromURLArray(args), 1, null, 0); + } + } + + public void OnNewInstanceCreated(EventArgs e) + { + this.Focus(); + } + + #endregion + + private void LoadViewSettings() + { + downloadList1.LoadSettingsView(); + + toolStripMain.Visible = Settings.Default.ViewToolbar; + + if (toolStripMain.Visible) + { + faTabStrip1.Top = menuBarStrip.Height + toolStripMain.Top + 1; + } + else + { + faTabStrip1.Top = menuBarStrip.Height + 4; + } + + faTabStrip1.Height = this.ClientSize.Height - statusStrip1.Height - faTabStrip1.Top; + + gridToolStripMenuItem.Checked = Settings.Default.ViewGrid; + segmentsToolStripMenuItem.Checked = Settings.Default.ViewTransDetails; + toolbarToolStripMenuItem.Checked = Settings.Default.ViewToolbar; + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + Close(); + } + + private void newBatchDownloadToolStripMenuItem_Click(object sender, EventArgs e) + { + downloadList1.NewBatchDownload(); + } + + private void viewMenuClickClick(object sender, EventArgs e) + { + ToolStripMenuItem menu = ((ToolStripMenuItem)sender); + menu.Checked = !menu.Checked; + + Settings.Default.ViewGrid = gridToolStripMenuItem.Checked; + Settings.Default.ViewToolbar = toolbarToolStripMenuItem.Checked; + Settings.Default.ViewTransDetails = segmentsToolStripMenuItem.Checked; + + LoadViewSettings(); + } + + private void MainForm_FormClosing(object sender, FormClosingEventArgs e) + { + Settings.Default.Save(); + } + + private void showHideToolStripMenuItem_Click(object sender, EventArgs e) + { + ShowHideForm(); + } + + public void ShowHideForm() + { + if (this.Visible) + { + HideForm(); + } + else + { + ShowForm(); + LoadViewSettings(); + } + } + + public void ShowForm() + { + this.ShowInTaskbar = true; + this.Visible = true; + this.WindowState = FormWindowState.Normal; + } + + public void HideForm() + { + this.ShowInTaskbar = false; + this.Visible = false; + } + + private void showHideToolStripMenuItem_Click(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + ShowHideForm(); + } + } + + private void newVideoDownloadToolStripMenuItem_Click(object sender, EventArgs e) + { + downloadList1.NewVideoDownload(); + } + + private void toolStripScheduler_Click(object sender, EventArgs e) + { + downloadList1.StartScheduler(toolStripScheduler.Checked); + } + + private void importFromTextFileToolStripMenuItem_Click(object sender, EventArgs e) + { + downloadList1.ImportFromTextFile(); + } + + private void toolStripButton2_Click(object sender, EventArgs e) + { + downloadList1.MoveSelectionsUp(); + } + + private void toolStripButton3_Click(object sender, EventArgs e) + { + downloadList1.MoveSelectionsDown(); + } + + private void setCustomToolStripMenuItem_Click(object sender, EventArgs e) + { + ((SpeedLimitUIExtension)speedLimit.UIExtension).ShowSpeedLimitDialog(); + } + + private void enableSpeedLimitToolStripMenuItem_Click(object sender, EventArgs e) + { + speedLimit.Parameters.Enabled = enableSpeedLimitToolStripMenuItem.Checked; + } + + private void cntxMenuDownLimit_Opening(object sender, CancelEventArgs e) + { + enableSpeedLimitToolStripMenuItem.Checked = speedLimit.Parameters.Enabled; + } + + private void selectAllToolStripMenuItem_Click(object sender, EventArgs e) + { + downloadList1.SelectAll(); + } + + private void clipboardMonitoringToolStripMenuItem_Click(object sender, EventArgs e) + { + downloadList1.ClipboardMonitorEnabled = (clipboardMonitoringToolStripMenuItem.Checked); + } + + private void notifyIconContextMenu_Opening(object sender, CancelEventArgs e) + { + clipboardMonitoringToolStripMenuItem.Checked = downloadList1.ClipboardMonitorEnabled; + } + + private void menuBarStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e) + { + + } + + private void MainForm_KeyPress(object sender, KeyPressEventArgs e) + { + + } + + private void MainForm_KeyUp(object sender, KeyEventArgs e) + { + + + } + + private void tsbMenu_Click(object sender, EventArgs e) + { + menuBarStrip.Visible = !menuBarStrip.Visible; + } + + private void MainForm_KeyDown(object sender, KeyEventArgs e) + { + if (e.Alt) + { + menuBarStrip.Visible = !menuBarStrip.Visible; + } + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/MainForm.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/MainForm.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,955 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 124, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIISURBVDhPpZP7S1NxGMbPPxKaXVUkMEq8IpKUCoY/hGgI + ymqkDYYXcCjDZOANURSjCNGFQUTsl4GXVMxKk62YU4fXQpaIlygHQxBRH8/zwvyaIAYe+HLgnPN8nue9 + HA3nvDTq63oW/jm13XOwvPTB3DYFY5MH+bXfcN8ygfTSMSSXfESicQDxBqdYHwH29g9w2tnZ3UcguIvN + rR3417exuBJE5N1n/wfwLgXEOc38Bc6xNRHb+/y4nm49G0Bnit2zf9H6bkliE/jKuYxrd6oVgDWfjB+K + TWeKMyrGEVfowITvD9re/9ABVQrAhh0HHK+ZselMMaN/mvwtDb+aVqkA7HYIwIj3ysfluPTorJnP6Ezx + oHsD1s5ZXEktUwCOioB5f1CEPR9+wTG6iuiserTo8dkwng7HT/R+XUPF8xlcTjErAOdMcW6NW8STiwG8 + 7vej8oUPN/PsEv3t8Ao0TZP3T1u8uJRkUgAuSYHtO97oLxmXd5t9Ho8aPTK+GzntqNfrLm2fFoihwYOI + xGIF4KjoGBLzY1OrF9k6OOFxnwDC4wxIMX1G0pMhgVyMNyoA13PAtS7OrJk1PrC69LUdQWxuF6IybHrX + LRI7JrtZdoDAo1XmbjMyD+tjSXxGcXRmnYg5ttD9QuxDhN0uUgDOmbvNTpPOJaGAo2K36cyaGZvOFIfd + KlSA8/zRh9ABIDUG+1JpAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHNSURBVDhPrdJLTxNRGMZxPosLl14WkvgRdOvGjSvdundD + IgmJpOIFKw1Y1FoVoxNqNEqNkBbEUokx1AhiuViHdppebKbj9Dpl+nfmYCeplykLT/LmzFm8v7znOdPX + 9z+WHDuPmhzGKIyzGTpIM3cNdfsmO+8vsS+/kgnw7dVR0EZIvzlt7ddJzRxC3fLuDzCKE6D7oBVHV6at + fVGcd9Yv43swI2rs/kvm4x//DialA8jRU1RyTzEpUyu+EGdltp/OuhF4Tv/Jc0SXEn8iYgLNC42oQOxJ + xLl81wGuToZ4HVsVSCS20o1UlSCp8BHM/ADZpTNWo9fK4LAVZsABPOOPRXOnusJNL1/Ye4WsByVynNSX + CWryKPnEoAOY7Ta3p98yKS0KxPV1nK5fH1Yv9WaLklYjNJ/k2Imz/wZGbkm/99MwdlH1OpnCD6S5NXdg + eOxRF2C0dtEqTbLfdTbSJabCK+7A0GjQAVqmiV5tkitV2MqoJDbz3Hv2zh24eOWOAEyzTbVuUFCrpLJl + Pm0Xia8q+J8suAMDHj9tK7V6Yy80Oafx+WuR5TWFyAcZ38O53oAdmp22HZh954A1tl9awDc1izcY7n0F + +5l6Vec/+AnmUPTg0ZAUnAAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABYAAAASCAYAAABfJS4tAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAMbSURBVDhP1VRLKK1RGN1TUwMDIsnreL8fx1sij5BnOByl + GJlTKBMDBl4pZKIMJMpIkpRn8gpxBqfDySuP8joHdSLr3vXpv7lncu/kDu6u1f/v/e+9vvWt79u/Uv/L + 2NzcxF9p/fj4wPv7O+x2Oz4/P/Hy8oLl5WV0dXWhpaUF4+Pj2N/fx9raGrq7u+Hj44OzszMo/BxPT08w + mUx4e3sTEofDgeHhYZSXlyM5ORn9/f0wm824ubnBwMAAgoODhcBoNGJ7exsbGxvo6+uDr68vPD09cX5+ + DpWXl4eAgACJ/vz8jKurKywuLsqat7c3GhsbcXp6itvbW4yNjSE+Pl6CVVRUiLLDw0NcXl5ibm4OKysr + 2NraEh6VmJiIzs5OChfS6+trpKWloa2tTVJjdA5a8Pj4+HXoD8Nms0E1NDTg+PgYr6+vQnB0dIShoSFM + T09jZGRE0r+/v4fVahVVXB8dHRX19H13dxd3d3eYnZ1FR0cHenp6ZK5qa2tRVlaGk5MTPDw8CKg2MDBQ + vKyvr4fFYpEALFJJSQn8/PwQFhYGg8GAnZ0dHBwcYHJyEkVFRXBxcRFLVHNzM8LDwyV9Fuji4kKKV1dX + h5iYGPj7+wv53t4elpaWpFiVlZXIz8+Hh4cH2tvbJYuFhQVMTU1Bp9NhfX0dqqmpCaWlpbIxISEB2dnZ + 8PLykuIUFBQgKSkJUVFRSE1NlW+svF6vR0REhJDExsaKenZDbm4u3N3dMT8/D1VTU4PMzEwBiUjAIERc + XJwcysnJAYvM98LCQoSEhAghs2S20dHRco7WcS6KW1tbZUN6erqA7wQ3pqSkSGsRzIatRjAgbSIhwYy4 + xqerqytWV1eh6BdJMjIyBBq5MzEVk1wLQCKqZgCCc35jTdhZqqqqCsXFxb8p1pTSSxISJNGgqaVCIjIy + UmwgKT3m9VbV1dXi2XcrnImpRFP2PX2NlMQ8w3lQUNAX8cTEBHitv6vgRladxQoNDRXwgDPYFRrc3NxE + cVZWllxzuZxs7sHBQQF/MgR/PPyxEL29vb/etTXnJ2/rzMzMV0f8y/EDxS7Ufs2gVXAAAAAASUVORK5C + YII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAC3SURBVDhPY2CgBTj/6Mx/isxNmJHw//zD0+QbAjLAocLg + /7kHp8gzJGFGwP8NNxaADTn74CTphgRMCPhfcKAAbsiZ+ydIMySgwwFsAAgnLAgAu+TMvePEG+LQADRg + QwJEc4PBf4MChf8KGQL/L90gMmANgJqQNQskMBCvGRT/BhUKcJtBmi9cJzEMFIBOBjkbpPn8VRL8Dkt9 + IP+CNJ+9fJT4gENOugIJAv9PXzxEnmaK8sCAaAYAI/1yOuyCUFkAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADfSURBVDhPzZO7DcMgEIYZgREYgRE8AiNQpnTp0mXKlC4z + gkeIIkV52I7zUBRXiZNFLoCVw5bN1UaiQN/9HwcCxmYx6m8JoUYohhmdaag/xaSEYgNBlEg4t6eRxApC + rCdQkDdrV1i1x4FEZ2GGArVSEG9ilJTvA0oo5gXLyAns1GvlOilfeydRBENBlBpBrrtwKkHGAsSCw60p + zDrMUCBNqB/mmrmwLaCYFyQCd7bhy9PfgSQYCoRp2bZtw/WjO/t/UMwXmfPacHXfjd6BvYsQQwHXHIrr + dvIlUmwW/5D9AAiU5HOciitHAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACUSURBVDhPY2AYfmDChv//Qbh8zoP/IN+h8wn6GKThwoP/ + /w0iNsANQOYTNKBhw4f/D178/68QsABsADqfsAErPoBdoOABNQCNT9iABUADbvz/L+AwAeICND5RBhy4 + ADTAAmEAMp+gAQUzHvzfcAJogEED2AXofKIMWHDgw38GJAOQ+QQNKJtzH6IZagA6n6ABI1ABADKdl1Hq + gthwAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACzSURBVDhPY2AYVGDChv//Qbh8zoP/IIeh8wk6FqThwoP/ + /w0iNsANQOYTNKBhw4f/D178/68QsABsADqfsAErPoBdoOABMYBkLzUsABpw4/9/AYcJWL2A7kUMF4EM + OHABaIAFxACSvVQw48H/DSeABhg0QAxA8xI6H8MFIAMWHPjwnwFmAJqX0L2IYUDZnPsQzUgGoHgJzYsE + YwXdS+h8ogxA9hK6FwkagO4ldD5BA+iiAADgBf5+NvTs7wAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFjSURBVDhPrZJNKMNhHMd3Vd5K7eKCWu2ATLIJyWRIQ2Qa + kbdJO3BYJLTLDg6kXMgBF8mBpKScaNlpjMlLmqxJyWUH1v/4fOwlatnsT57Lc3i+38/v+/s9P4Xivw7W + NnA7+ROP3Q3ESDNiwADHBz9CePbD9mq8hv1NGDchBg2I4UZYX0wIiSQUA/XgGEtcJArpKEOYK8HWHScS + MxaESQtL9p/bZGsF0aSOgpi1gO8a5idj0PAta0b476GnJtZSWymiUwcTvfLMnxU4Ow1H1iGMRdCq+Z05 + AsFcBeU5SJps3jWZ0F4mH4KpAqpzCQ4Z4fYi+kOvhWHIzlpqCH16QrV5+OqKCLpOvgzM2fCqMpCuzpND + mB4CfT6XhUqCh3txQkJvvDQUE+hvSbIDp0dIWiXegjQCo12JF+npEacqC8nr/v7OsoOAOh2foQQCD0lj + SnYr3HgSAO68sDAFHlfqQcnaJpmiD4li7HlpWRgfAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACjSURBVDhP7ZHBCYNAEEUHRFCsSsRCRETEMjyIiAcLsAgR + ewkJnnNOBS+MZjUJiRevLjxmZufzWf6KnOd4AhcR9rhaFsrkOCvvetEFfQ/j+JthAIPqtH9pH56HqBtd + B3EMSQJpCnm+obOi+yhaapbNJvfVoG0hDCEI/uP7YFDdh0HTQF2DVtPrrJTlQlFsVNV8t75gcl2+udn2 + brgmyOPfeDrIE2+j8lfhrSv8AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACWSURBVDhPY2AY/sCx/P5/sn3pU33l/6JD///7Nz0h3RC7 + rL3/e9a++z9z5w/SDTGKWv4/p//q/9r5jyCG7CLBEFWfmf9BOLrhBNiQmvmP//esgxhiV3j9P9FhAjIk + pv4kxCXzHv03Sd5PWjiADPAp2At3iUHMFtINsE/dDDYE5BKdsJWkGwALDxCt7j+fNAPITjxDTyMA5vB1 + magAfuoAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACeSURBVDhPY2AYBVhDQN1//n9Vn5komKSg0glb+T+m/uR/ + n4K9/+1TN4MNIskAg5gt/3P6r/6PbjgBNoRkA0yS9/+vnfcIbAjIJUQb4Fh+/79d4fX/M3f9+N+z7t3/ + mvmP4S6BhQlBr/g3Pfm/6NB/iCFr3/2vnQ9xiVHUcuLDAW7IToghdll7idcMcyLMEJ/qK6RrhhkCChOC + fh76CgCQHnWZxAuPXQAAAABJRU5ErkJggg== + + + + 238, 20 + + + 335, 21 + + + 502, 21 + + + 621, 21 + + + 731, 21 + + + 72 + + + + AAABAAQAAAAAAAEAIABmZAAARgAAABAQAAABACAAaAQAAKxkAAAgIAAAAQAgAKgQAAAUaQAAMDAAAAEA + IACoJQAAvHkAAIlQTkcNChoKAAAADUlIRFIAAAEAAAABAAgGAAAAXHKoZgAAZC1JREFUeJzsvQmYJNdV + Jnoi960qa9+X3le1utWtltSyVsvCRuB9kz14PGNsA48xw8PGw2LAhnnzeDAMM9gMDMPwwTDY2BjjBWFs + g7xLxrIleZFktdyt7lZ37XvuS0S8c+69J+JmVFZ1dVdWV1VnHOl2ZGVGRkZGxn/Of5Z7rmHbNvjiiy/N + KYHNPgFffPFl88RXAL740sTiKwBffGli8RWAL740sfgKwBdfmlh8BeCLL00svgLwxZcmFl8B+OJLE4uv + AHzxpYnFVwC++NLE4isAX3xpYvEVgC++NLH4CsAXX5pYfAXgiy9NLL4C8MWXJhZfAfjiSxOLrwB88aWJ + xVcAvvjSxOIrAF98aWLxFYAvvjSx+ArAF1+aWHwF4IsvTSy+AvDFlyYWXwH44ksTi68AfPGlicVXAL74 + 0sTiKwBffGli8RWAL740sfgKwBdfmlh8BeCLL00svgLwxZcmFl8B+OJLE4uvAHzxpYnFVwC++NLE4isA + X3xpYvEVgC++NLH4CsAXX5pYfAXgiy9NLL4C8MWXJhZfAfjiSxOLrwB88aWJxVcAvvjSxOIrAF98aWLx + FYAvvjSx+ArAF1+aWEKbfQLXSkbu/rnNPoWGSSAUhcVz34CFs1/b7FOpkd6b3gjRtkGwzcpmn4oug7Zt + 34Db/ZZll3H7zVKl+uSLTx203veT90FHWxpy+TxUymWIx+MQCAahUqlAJBKBID7O5XIQi8XANE0IGAAL + 2TL86d/9C3zzOz+E+cUclBBCVnsvgLHcll76m1+45l/2SqVpFIAvTSctCPw7bRveYlv2i8CAlmAYwWpZ + Z6sF6/+tmtbHN/sEt4L4LoAv15MkEPCnLAt+v1o1Hwsaxt8nE9EHR3f2Dh+9aW/bnbcfbHvzq04df8eD + d31sqK/t/6tUzTbDMEJgGJt93psmPgPwZTsLGbDdaOlvNU37dsTxnaGgcTgQDhldXe3Q1p6CHUPdsGuw + A47s6IPhnjREwkGk81Ujlyu+NxgKPZjP5z9nmeY38TifRkUwZTSZMvAZgC/bSZDWA4LdehuODyGdfwyt + +JMI2r/s7Ej9THdf+w0HD40aL7n3KLz07iPw9lfdBv/2gZvhwXuPwbG9A9DZmoDWZBx6uzphdKgP2lpS + I0Yg8A58/4cQ/P+Ix/uTUqn0Rvx7dLO/6LUSnwH4slWF6Hw/gL0LbLjNsq1TpmXvC4eCg8lkNGYbAWhN + J2C4vwMSiRj0d7XAwR290JaMwWB3K3S1JiEaCUMwYABZdQroIdgpBgDZbFZskTmIAF8oFIoiC7ipUq0e + QwXw1nKp9B18z2/ie/5+sy/CRouvAHzZChLD0Y3jBsuyjyM4jyJm94RCwT2GEWgBBG5PRwu0I6UPI6hH + +tthD1L7VCwMAwj8gc4WSMQiEA2HcAQR7PK2poh+AN9brVahUCyKLRH8qAS9UAr0XKlcBhO3pmka4XA4 + gu85WS6X/wf+/Ye4+x+jMpiTroG9eVdog8RXAL5ca4ni2INA348W+AA+3o/YOoLbA6YN8Ra04Gm07AYC + tLUlDntHu6EdrXkSwb57sBP62lsgHg1CKh6FZDQCwVAQCJgEaAI7GnUBahstfLFUEo8R1ALsqVRK7EMp + PXo+n8sBBQDpvZQCpC2lAOm1gGEMoGL4Ndz/1fjc4zi+EY9FH8bdz2/u5Wus+ArAl40Sii/1I9CHcbsL + QXojgvO4aVn70Ja2J+LRlmg8bFi4WyoVh51DndCKPno0EoTdA50w0tcO8UgI2hJRaEvFIIFgN5DOE4AJ + 0AF0AWz6z5ajVCoL8BLQSQuEcB+R1yfaj4An211EFkDgJ2tOz8cTCbE/vZ9Av7i4KF/DEcP3JpLJWLVS + udm2rZuRWfwbAOvbqDH+CzKT7+C5jOEH5bY7J/AVgC81kk6nqQgmiQ87EBgtp06d6u3s6tqBnvQAoqMN + wdEFEtwBpNiXMktL3/7Hz3/hW5ls0Sibxq5A1TwOpoVgt/eg/z0YjoT6jGBApNo6kML3d6chiDQ+iRb8 + wI5u6OtohUg4AJ1o7Xvw9VQ8AiEEJ41IRFpuAhkBk0g4+e5Iz8WWLL9lWkIhkPWm4h0CNgkpAwK8UBC4 + ryGOF3H3weNR8U+hUBDHos9JKIVAn4XAx3MwIJVOwcxCHp74wYXIZ7745KmzL0x9LJMtLS3mimOoKf7B + sOzfxvOb2bQfbJ3iK4AmFEWXDbR60eHhkbYjR47sI8Dic/tuPHp0Z0tLywiCYCfu2oP7Ggw+4QcbhgNG + ssj4Lxw7fkt5bK4E43OFyNQi+tOBMITRzzbCEehF/3zXUAe0JGLCPx9BBdDTkRTWPYL0PYojFo0ooNsQ + DMhgHQGXLDeBnRQA++9B5bsLFoD7MVhpX9pWycLTd1RKgfYNEgvA4xHgiQFU1DFZIdCx6PPo64RD9G5S + IhF49sI0fOGRp+HL33wGfnB2HKqoc+xw1KiEYmkj3JIOBQMHUXn8WMy2fwFP47Ob9XuuR4Lvf//7N/sc + ron8/p9vy9+nrhhoUEsLF6E4f2HN79m3b3/rzp27bhwcHLz7ta993YP3veQlP3vHHXf+h1tvu+19Bw4e + /Mndu3e/Gscd4VDoMO4+hMBKobU3aiiu7f7FjwgusVg42N8RD+4ZbIGDo21ww2gajuzuhpv398GxvX1w + Yt8Q3LRnAG7c3QcDXWloRWWQbklAKkGUP6IObQtLXEIQV9B3J6DS3wEF9mg0qvn5tlAMZeXjE7jp3MJ4 + LIrq0/6kGMR+uE9RHY+EjiHofTyG4A8JlhEQMYQgTMxm4bvPTcCnHv4O/MFf/hP86d98Gb7y7dMwncH3 + x1JgJtEt6eyCF53YD6+8+wi85Jb9EE8mu56fWHwTujqkU7+kX653v+HUlf+411gM297uXszapFnmAhBA + +vr6w3j/j5w4cWL/6I4dt9mWfdvQ0NAe9Hl7cJck0WMBZlX0QveAbuV5gPKHV/pbDGWF2XcOBAMIKENo + BnpLGFkAAbO1pQUGBgZEIC6EoC4pGh9QQGXLzv45nR8B27Hq2rkSiAXIQSkipTzKlYr7fQBk8I+OS+eI + 5p1SgmTl6fhzi3mYmsvCxckFeOqHY/D40+fh/KUZmJxdglypCiFiMJE4VPBaI8hhz3AP3HV0BH7s1r1w + CF2XdDIqPqOA+37iq8/A+/7sYSiWqz+Fn/Un/Fv4cwF82TAxgpGav5OpVOyuO++6DUH2sv0HDtyOFvMG + BEK7pLaGAFFVASTAwA0EloG+Btj0Gm7l/qQgDOdvRxnw68seGyJQJ1wGhGkmm4PTz/0QLXlExBn6enuF + zy38egY6Re/xMVlrBjopi6iy/GzVReoOrToBv0r+O8UMcB86toGfSUAni05b07QhWyhBvliBsalFePrM + BDxzdgzOXpiCsxenYRYVAaUZIRQBG8FuJzoh2Z3Ac0zBUE8bnDo0BLcfHkYW0w+drTEwLWQVVROPWRbX + kj7jJ+6/ES5MLcF//ugjv5aIBR/Cpy9d05thHeIzgG0rBow/9hdQLSyi3xqAN7/pzQ/u3rvnv4eD4Xa6 + SYWfjJY3JCLmykJTXpwtrBIRYANYZsm9gCdgSVCz1QcB8GUKQH+fpgScxyAVDlnnRDIBSXIDkN7zMYIa + zSe/3lLWXcQA6HVxXPm5BPKI2F+yA6HkTAuy+TI8f2kWAT4Dz9N4YRpOn5uA2YUcVPD1EnoDFoI9EIlC + GN0BGi2pOOwZ7EQXphuO7u6BG3b2wO5+pPxRWUxUqlSFMgG9UtiW14+u/8xiAV7xqx+BF6aWfiYSDv4x + vXzxY//3NboXrl58BbA9JWgEQl256R/25yaeHj5w6Oibe9PBl4UCdjIUMMLRcEDUvAeJjgeCAmARvNkj + uI3GooKGk/WNxxNOKkyxdukZgKsQXMCvYPHrgVx77FUWzmNDfiBZ7o72dqEQCOQc7DOUG0AKIYTfJRQM + CfrOrgq9nC1UYHImg1Q+A+MzS/DD85No3cfhwtgsLGULsJBF/x/BHqTIf4QAH0MrHxGVg6MI7tHedjgw + 0gk37emDgyNd0N4Sh1ak9iG8bqRIqoKJ1IQ+lgm/RHUK7/njL8D/+ocnvoyP76HnfAWwhWSbKoAk/jzt + eJt14uOD+PgAWsMD+JvtRoB1R2OxHgRIvFIpQhDK0JkMQGsC4WGbELCr0J4IQTKCgMG/rWqFJsFAVfne + HP2OJ5LQ0dkBPT090NbWAamWlFAYliWDZrUsoP5jmVarA/J67MBhGQGHZVD0P+wU48g4gEgFBuV7cki3 + FxHQS7mSoPHPojU/fW4SLk3OwzSCfxJHBq1+AI9BmQdA626FCPQR6EAq39neAv2dLXBotAstezfsGegQ + 1YN9HSnxGYRiE68JMSdL1RVcidDexBS+/J3z8IYPfHwxHA6ewEtw5uJHf77xd0SDxc8CbL6IQDoOCtAd + xRvwpXgjPoggfSf+/fMIgF9CQPyCbRivSyRj9wz0td8wMNA50NHd0bZrZ0/4zpO74UXH98CN+4fh2EH0 + VQ/vhuOHduHfO2DvrhEYHR6CHSMjMIJjaGgQ+vrRl+3qEpafbvRsJgPTU1Nw/tw5HM/DzPQ0lEtlaG1t + hbZ0m4iYy6CbDOZFUGkI5RHBbdjd1n8clu8Ly6AdjUiI0nM48Dnh46tBFX0iqIa+Oo1nz03B1588C5/5 + 0vfgb7/wOHz4oW/Cn33i6/AJfPzId87B0+dn4MJcEWbKATBjLZBEBdba2wd9+B1P3LgLHrjjMPzEj9wE + b3vgOPzUy0/ATz5wE9x/fBcc2dkLg12tot6AAE+W3rQtmUkAGbisGxPRB9QGRoVrQkoLlcnnHjsbm88U + HsHnFt79+lOZzbut1ia+Ari2gqiDXXiz3WRZ9ksQgA8iCn8a/36faVq/irfg2+PxyCvb2lIvamlNHkq1 + pQZ27+pP3HoTgvrITji0bxBedGw33H/bAbjv5B4RoDq6i+gr+q17BmD/aD8M9XXBQG8XDA8M4LYX+nq7 + oRMtfHtHO3R0dCCo09CGlLuruwt6EDC9uE9Xdzda/hbBDGZnZoQy+OFzz0EmsySi990ILnIdQiKusBzw + DG7+O6QAL3LxAuhhAXCRxgtK18QNQNJlkcU65Gs/iqD/1f/6KQH6f3r0Gfj6d8/DM5fmYSJrQjkch0BL + Oxit+H3wvA8d2Al3nNgPD7zoMDx431EB9He9+iS88e7DcP+JnXBsdy+M9KSRniPYidIj4E01bAfwCtBX + 8p8H/OzOJNAN+OfHz8KZsfnv4He5+J43nJrczJttLeIrgMYLRbq68AbbiffYUby3fxwfvxVvwHdXqtYv + 483+s7FY+O2xeOQVoWjk9lQ6eXDPzt6uGw4NR3bt6g/s2zsA99yyD176okNw78174LYbRuDkgUG4Bcet + B4Zg71An9CJ17Um3QE9HmwheJRCcUUXpQyrtJWrcBRApOh6DZDIprHo7gp9GZ0cndLS1iYg8gV9YfFIQ + bdLqU6rw4gsvwDNPPw2ZpQwMI4Nob29zinDCobAD8nCNNQ+KfSj2wDPxxH82VfFJoNPEm0q5Igbl6UtF + 9NULebFtT0Xh6YsLcA5tZyGcgtaeXti5ZxQOH9wBdx3fB69/8Y3w06+4GX72VSfhLfcfhTfcfRDuPjqK + lr1H0HoqMCK3wVa03lJgV3j1jHrZj9UtPwk5LVJv2eIxxSboM2gy0le++wI8eWbyB6jkLr33wdvPfOAD + HwAeWxFrvgK4OqHfP4UD/XM4hD/+i3G8BkH+M5Zp/xzeKz+PFu89eBO8DVHwo63p5MnR4e6dO0Z72nsH + u+P79vQH7rvtINx723647egOuP1GvLmP7YR7cNx+aAQODnfBUHcr7Ohrh8FuBGxLEhLxqArmhUW1nG1T + kIpSZ3JiS1WlzkRKTBXOhBUF16P+4FTxBQTQW1papELo7IQuHKQA6DnyxykARwU35BqcfvZZGBwYRDdi + SAAhKNJsQSc95+bpLVGeSyCvVqqi6q5cLomy3GKhAPl8HvK0zeXkwL+p7x6V5NIIBwFZSxfs2z0Eb/nR + m+EdL8eB9P0nX3YT/PipvagMB2BnP7KZ1riwuGTH2W8Xw/2al6fydZVCnaEAz48DirWIuAco5QIy8Pn4 + Dyfgmz8YO4uKZDz/zOe/o980WxFrfh3A5SWOYzdNaqFyWRw7AoaxE2+gXXi77TBtO02Wrw1vSJrJRrPY + AgiOod42GKW56ghcijORdRrsQjoaR6uJf8cFXQ4K601Aops4oFJbtiVIsSxbRSCJfLeqZAuoNBgF18Kh + iAs8EcSSvqylcuokQTUlloZIoVHEH8DJt1vCSspcOgfiWpEVkLvQ29sDU5OTMHbpIkyMjcPH/voj8Na3 + vQ127twpAM3v5SGOh0Pf8mfon8X1+U7ATQGXvkkGn9+Hiu/+20aho7MLFZV2vqL+/+plTb1+9ACgKkYy + 1PUFdb7it1DfgbWESLFCGFqTpHCNOO6XXNfJXiPxFYArPfijHcZB3WAG8PclsO/DG2AH/p2OxyIJHAGK + NNv4g7elEzAy0C6mqtqo+dOJKOwd7haWKYIIjyO4U+h70qSXWJRz8SDSWaQwZNDJVmkmCQKi3VTgwhbb + ATuBEyk++60MKKqm4/1IuPEFBemIATCwGHhUKWfje5zjG7JgJkw58UDCLbShiTTdnTA2kYZixYCLUxnI + mrOQnZ2DL3z+c/CvfuItghmQdReluB6Q26wUFEgcy6xbaR1ohuGAk54toCuwlMlDLFESc/c5z7/edl3L + 3q3OQT8fWwM8D1GYRN+HCpUEs6nIxzTJiK4juUJUOYgjIllCwLLXebLXSPw0IMCtaN3fiTfsSyORUB+O + YNU2IJGQE1na0klh0SPo39F89MGetGg+EcabsiMVg7aWmAgyhYSlFVPkICZmnEk/lMttuVy1qkDCYOPS + V7bULFzxxjXsTHFJ2N/mnDioY5nKv+bj8iw4nhAju+LIklg+X0qxLWWLkMkVYX6pABcn5uH5SzPw3PkJ + mJpZhNnZWZiemoSF+RnYNxCF2w4Pwate/WpkB32Qy2Yd0DvnyI/V3zWyhnuNzpeUFwUe+/sHaEqurFO4 + SnGCffr51CghCk7YzrnzEFOIaVQrklGVyrhFhUfzCmhacUk2EREpS5pX0NIK8fY2+MtHzsJv/tWjD1XA + +Ozsp977h/XOZStJMyuATvzqv4M+61sT8Uiwq7sN2jpaYc9IF4z00lz0IFrzhCgOocBUmIJfQZmbJotO + 0W4hhlsfb2m02vFJ1fVlCg5ablyvduPHTHN54gv72Kwc2NLysRl8IdXyKiAAHhSWPRSSn1UuV6FQqiAD + qIpc+oXxeRyz8AKCfWJqASZmMzA2vQAzCzkJXCMIVSS0JrkmdEy7CiErCyl7Ce7YEYWXveReuOHIEeG7 + 87k0SrhKkNyQwaEhEY+ga7FGAl8jQhnRbyH+sB0aTzUOtmk5z4mhrDxZeLMqLbxFsweJ5RDgkZVUiwWx + rRTyqABKQjFQhWQolYRYRyek+nrhY9+bhN/62GP/gKr3s+VP/8qHFvXz2YJYa9YgYC/+GJ/BW+rlg0Nd + gb0HRuHkkVH48dsPwt3HdsHxvQNwYLgLhnvaoAuVQDqVgNYUla3GRZ+5QCDoWFyy0mXlczMYA6o2nWvZ + A2qSi5jWivuWFXVmP5gkpEp3uUCH6S6XwZJ7wIolwP56TFa1xYl6RsKieIYAT7Xv58Zm4YlnXoBHnjgL + n3/kGfjY574Nf/53j8BffuYb8NCXvwtf+tYZePSpi/DMxQW4tFiGLEQg2NIGgdYOiLSjEtwxBDce3gn3 + nDwIL8Prcv+J3XB8T7coPaac9649exwmo7sq6x2CrdDA75dMpUQGg+IAV0L/hXIU1hvBjNeNQCysNo5K + oQDVPI08VFGBVXJZqGRwIJspLy3JsbgEpYUFKM3PQ2luHorzc1Ccm4MSukClhXnxWhlfK2cy+L4MWKLv + gCUqDp+eysHXfnDpDF6VH/acfvgxvVHAVsRaMzKAMH7nT6KlfGD3ngE4dGAEbj84BLceHIEUgonAaahm + FDJQZgm/nCwdz1YjcRpNatacxFSTbjio5zAAkZaTsQBQZa7Oe+hGVdaJS2C51j2kAMFRbU6tEW2fW8wh + bc+LSjii7ucuzcKZC1Mwh89lidJnkNoXy8KiB0mpROQcfSsQEn93t6fE6EynYKSnFfYOtMOO/jbYjdsO + ZD6pRFT03SOaPDszDd/7/lPwxX9+GPK5PLzpX71ZKIBKpfGrABFTorLlnp5eaO/oEEpxrQrAseIE/FJJ + Ar5UBKskrTm9RtYdVKDS1gb9DqD8e1NZf7LydCxRQUlKm/1/+t60PylBPNd4Vxe07hiFT10swO899NQX + rED4oYf+/tf/oEvUZUrZsQWx1oxBwHfg/fzAzl19cDNVjJ3cDYd2D4uUFS0R1dKSEmksajElovD4Q1Nk + nAbdgvRcWVljtsh0I4FSCDwJRw/M8b4cmWcflKfPiny9Sq2Ri0GuBikQqojLIGXP47nML+bRN5+D82Mz + SN/nYGp2CWYXsgj+rPDdDSquCYWRtocEwK0gui2U4utH9tIi22EPdrfAvsEO2IUAH+1Ji1LY7nQCFUBc + uid1hL5fhQCCSoTKhlvb20VcgLIARM851tAwUS6VaOZpVlXbL6vu0lvLzlUF6oiyV9C6kzUv4SDrLmg8 + KgRSAAR2UNRfxAHYZVNuAKjsha1YGrsIhmA8eCrUh5BiPJTeEe3G0FBUUEGQW1BGt8C2jIBlGc/jrtNa + 5GNH465Sw6TZFEAKLfpPdeKNPzraB/ceHYXDe0YcX5aKYkp4ozBoicLTxBlSAhVtuipbfp0B1CgEZRk5 + GBdUs9eIVYSVkiD/nNhFpWqKQVNMJ9A3n5hZFNZ8bHpR1LnT44uT87CQLYiiFgpQFiyKM4cQ9Kg4Yi0Q + H+iBMFmheBSG0JIPd6dFrpys+kBXSoCd6gqSwpovt6TEPiqmufxqsdggOu3GYtRIIyGuFSmAjs5Ox+1p + qCgFILMIlIpDvF3OeNJ1x2toUoERKvICUvf81JSk7qgEqtT6q0rgVLN71DRpl1m4AVU+nmRohnT58Pvr + U6fFaypAKNie6kVIxoAUAP5M8GgyCQ/jvcUhzJc2/kqtW5pNAdyE1P/Gnv5OOLanD27cO+J0laECGFIE + FIGm9BZRb6KhJdVOmkCiesg7+W0CAYkMUoFkAQT0sKyI0xtJk/3KIR2/hMCenUfLPZsRDSkoGEfU/dLU + PNL2EjWVQNpegUIFb6RgWKSYgjSTLYlkMhgWSmQfgrm/gyoBEdy9bQj2NgHyXQj6lkQE4tGQqEpjoXMg + ZVOuXjlYGR4B1VMvFouKm5++O8UqTJUTb6hw0FMpUz2YupLYitKTpS+hD5+fnobc5AQU0G8nP5+i9qBn + Xcg9I8UclLEHlcKRFp6Lm+i43P9AnZfzmgB7RFp91FDEvgyeFGXbopMS/QKPN/bKNFyaSQEM4U10igDU + 39sOtx4YhmgkBAsLOUFlyWIT+IWVx52JxpNCEB1miQngPhQLoMHWncpruc00/U35fwpekRWfQZBP46A5 + 6DQfXUTc8Xny3cmazyClJzyKGWx489A0VTtI01WDkOyNw2g6KYKPnUjRyXqTX04AH0ar3pWmzEQcWhNR + J0dOYjmz2QDdlDrR+avITDuVdQH53aLIAuhzqIKPFIKprlejhbMfepXfiueoaDz56kT9ixzAU4E6q1xy + gqfkchFzCqjgLPcWMFQWxWmGosqp5XfXKh0BHMVOzED0BKD4kJrnADbPEQDj4Bb0+b3SNAoAb4BO07T3 + tbclBJioxLaQLzg0nqfI0qoxVAVH4OfIND1PZatBZf0pHkBReFpsgqa1UlNL+vEff+YCfOZL34Vvf/95 + tOrTaM0tYVXQI5RpNSOoAnAJSPV1iZbXdCzqiEvBt519bUjh0zCCgO9pS0Jvuxw0eUYXkQokkFevMAVX + Z1fD+efyQulF6itAPi9dH1KSrAwbLTo1F7xltTn5luwOXEErXy4o/x9HtVSRQCXrHJSB0ACnSw1ZFWlo + bch4Uo/B8RB90g+fDVctEgPA/wSLIJYSCKoqS0OVJ4P9dMOvSuOlaRQACjrAdjKEDODAaI8IttFklIi6 + iWm7hL4iWXWit8IHxR+WWAFZOwIq3fS0FRQYmQC9J45+9YXxBfj9v/gn+MLXvwe5fAkCaCXNaCsYaKWp + EUVLPCKWqhoSPnkrDHa1wI6+NAx0yC2tWUddZSKhoAN2WTRkQwlBjg76VVnvtbzFdv5Zw/HQEkaiMiJP + yi+k0nUNdwHA9bXp5AzvSXq+mIAcBQrNqrD2RMspmi+6/EYk6EH0HNRqK9TW+Szd4oOmgGxwmIhzFssq + Gt2JA6oA8Eou66ZKMykA+rWDVP/Rin4yz+ByVopREWD6m3PuBHZKC1L3HGIGFAPgQpwYTcxB0D7+9EX4 + xf/8N3D2/ATEUimAzg4IJlNwfO8g3Hd8B5zcPyAAH0efPIWfSyOsKttMBXIOpJUI6JX6lNq4irvJrYGr + d8C1H0cCQnYXogIoYk0UOxEzDlXf/o0QWTthLz9+nQJDKuyhIKClUneim5CoK4iK+RmGsv4BeWC3K5H6 + Ww8AOpdGMQIbai8XKwMRnaTPtS01KcjgiyVCij24/b/wz6uvY9x4aSYFIIR+rGCgNkVHoKcbmigtB7Vo + H4oH0M1OQUH6Uen1ArIBESuolGF6wYT3/O7fwLkXJiFOQcRYO9x50274mZcfF40k08mYiPBzvb9oKFk2 + oQTVOme2OiJXA9lVvdNx7ld9s7Or9HkRUOGQsPolLQBqrYEBeAuGSPSJRF43wpkb4FTvrh4DsLiaj34/ + VeUn4itk7WnLPj5o7MID/PrfXH1/WUss1ZH6LHAmNMm9OcQqPp00Nn5eH2ztJbibTgFISldr/Xl5KFG4 + o35UstL0GrsGlCUg8BMbIFegu6sTfv2P/hrOnB+HVFs7FOKd8NOvuAXe++ApaEHfntpFL2SLdX3s+rfb + VdhRww1IXdWbr+Bjyc+WllMuvlkS0W9LguwyqUBOmRKD4jbg/DyxoJLKxNT5VGdG3op6TAUA5RRkU7AA + ca7iA/D3xFFZXILsxITIBggFRGwgJBUZP3YGV25yIFApF4srC0UhUUUwjYoqLqLgI1H/+R/EITpbhGNL + c93PJkfDS3gKXYODzrl+cGhobRd7DfKuixcbcpzmUwDAt77tlOfqE24szb+TdfRlEfDjugCR/25Pw3dO + j6PP/11UCHHIRVrgVXcegl99yx3iRqX+dIaOL7sW9LZ7Ems81xVkZVysQeq/83KfR1mHsOoTQNctTErz + Mp9E4Kdy5enpaXj66adFGzK6QNSE5PDhwyLoyqv31jtLzfuue1LiP8MW7M4WQykBfExpwDP/+Fko4GdT + qW6IFhihdC4FcqlnAip0+pse02tBeoz7BZVi4AYmVAlIhURVNSoUbCwVRX1Bhc5djTi+9tJy9YbD4TOv + 6Esk/gi/UfYyl2dTpSkVgJTaW11vakHC68VRKSndEGKVWbwhqA89BQof/saXYHExB7HOLujp6YSfe+0t + wu8rVqpOd1220CT67Xsl8by68YAreP+VykowE1ZYdhIRJc1FBdhIJLLCO6SQxSXL/4Nnn4VPfvKTMIxW + 8NZbbxXX95FHHoFv/Mu/wGtf8xrYsXOn4w54P5dX/ql/wjwpSvUYMPkYNhSzWXj205+S5boc2ddmBJIY + 2jx/ZhNO9R8/ryYV6fsZ4BYUObMLQV6iSCgQ3AWZO0rh8O+jgvhpVDarVFltrjSxAqgVt6ON7c7U06a2 + 8uIaVAhTQj/+yWfOQygSgrwRgTfduhf2DnRCsVwBZqurgfRyr19O1mL1G60knKo4FQtZouKaurRdOwc1 + s48s/x/8t/8G+/fvh9cg2Ekh0Gv9/f3woQ99CD74wQ/Cb/zGb4hGpcvSiqJE1+UBdU5MWHt3Cq8lc3A4 + Jh//tqDtie5uiO/ZI+i6CFyq9RKCosgqIlcPovJtzS0wVIqQgC8Kgehveo32R/ZALkC4Il0BU80XsNQ8 + AfoOC0jR0YC8vRoIfKSSzz+8cpxhc8VXACuIowDIctDNpQJG0UhUVOuduziNN0xE9Na/9dAg0Cp6lsW+ + rTQMhsoJs+h/1Q951ZcVX13lbZeLnF+psNtC2QBSAMJv15bsWkmIRX3m05+Gp596Ct75znfCwsKCaP1F + QvGUe++9F9797nfD5z//eXjd61+/fHLRKsafX5fWX5X1q9+NKDsVBPUeOyYyNksISCsiW4WLfUgZEHhz + OVkefIXCwUPaEojIFQqgYjORddBsQQuVyCJ+VvvAwNsnn3jCVwBbRez6iaX6+6p6cbbYIjgYDkGuZEEm + WxDFHx3pJOzqb4NC2ZQKwHBTdgbTZiU1t8AKNKDebbLi2V7DRDOzXSNoCNpPLsDlGADRfwI7Uf/+gQER + M3juuedqgoCkBCgGQPu88lWvqplZ6RbVXIYBKDdBVEKqRqBhdNPi7e0QIR8dAbnjvvsgjJ8DqoxXdPKB + 9bMxw7vFY+dR2Zz/6EdhFrfRzs5bbvu1XzMyZ85sybKAplMAsMq9VE9014BElntS4w5TpIGT6BJQ1R41 + 53T6xwHUbNWRPAfWz2MlZrD8LZsl0u81BAOgakBiANTcczUGQGCcnJyEp9D633///QL8bP1ZqNaCJmE9 + 8cQTYpYhlWUv/+xVsgxODEAFAIX/bkK0tRViFMPBz9//jneIKbtV1ULN0EYjhY/XcfQoxDs7Ye4XfxGq + Cwsdu++/P/FcuZzbiIKp9UrzKYB1ikv9JIIDaBFp+i5NtgGH+quScHDpK7kINT+/rR1vjbKZt4/e2Sis + 5ucvLS6uqADoeVIS42NjIo1KqdPTp08vo/jMJsg1mBgfFxOwiLLz5+ltxlY4MbeeQAUATarjwGMUz56F + /jvuEFH+cj6/4rW+WkXg/T3oLIlVVPC6xPv7YfDUKXjmq1+NzTz9dNeNb35zzlptxuUmia8A1ilM952V + ZYAtv4f7NwK9m0gBJHGSDEDOnwjAHFrs1RQAAXt2bk5Y+TNnzog0qjfVR889//zzIgA4g8fr7esTCsD9 + 3LVUKinHjtO4FBOoVkQ5cGp4WJQGs5/PrExnAFd7Wfln1X9ah/3h92w/cgSCX/96aPLxx3sSnZ3n7QYq + gO6DBxtyHF8BrFcMcBaf8DqUempopTTgMr2w2t24AVPv1ypcGyFnBcqy2smpKTe9VkeoVmBhfl5QfAI5 + WXtvmo8UxYULF2B0dBTmUVl4GYLY21pFe7Lvb8oWbZQFEGXBOAj0FOkXaUBNQTssjisBV/kOq32uOIxi + KN5YAqUXyQ2hZVfnz5xJLuL3b6QLsP+Vr2zIcZpSATSSShtaAErNXVE3mLuYhK1C6E5NwOVyhFtYRBdc + tVYgUXZTZQLqlepy3wBaiuws0nEaEa29ObsJ5B6kqdKS4gOe44jo/moTIZT1l0VA8rcwuREoCXf90Y7r + 1HxoJeFXI/JnVfMHtPbnhvruItgoJxkZxgZNmlqvNJ8C2IAfgYtV6D41ePKIreIATgxgecxvayaGVhZb + 3dAEfkHZp6eFhaeKPtNDb52W58gUUsmkAD4F+ZzmKUrIJaC6gCQej0twSejaUPrfZMW68kmpOgA3CyBb + fVnCHxdtvLiQB8AFvpr9d9W/ATcMsW2HTYi2Yfw6Kx5YXmS2laT5FEBDRZWgcl95cCmmC35DBQeXe7Nb + zx6sLvQNaEYgFdEkUil44fkzIshHabx6CoBiBaQcyAWgLSkAbwyAgoridbWPXANAKo9q1QLquHc5gm6r + WgAnEGjLNmI1Vt95oFF/9fd6xOAT4GNprsZ2EF8BrEsM4aTKFBQ4NQA8AUi6ALbjFji3hrF9bhCvcNNT + UgBEtZ988kk4fMMNdfel75hGUFPFX1dXl9NRiZUFTxCi12gf6r8o+/QFIJcvQgVkk9RV64AEva9dh8FW + fxsMSI0BgHJXaoC7HuFSYN6q1YK4fHir/87NqQBWis5dhRjgRp4d0IsX1OKTOt031Ifb21MB0D1ODIBW + Bo5G45BMpuDxb30L7rvvJdDT27MsgEeUnlwFWoJ8eHhYBAUzmYzDAohJkIKg13p6esQcC+qQfOHCC2AG + IqIl+NragdnOeoS06IfFi5Vo4Ld1F4Abd2gWez0XRZ9DwAuR2JoLsJWlORVAA4Xpp3AFFQuQG08wS3cJ + YPvRfxLOAlAhEK3Zl2xNw9TYRfi7T/wt/Nu3v112V1LFNiRiFmA8LoDc19cngnxUE1CuyglTEVIASP0H + BgagD5UEgfeRRx6FWKoddu3ZS5PqV00AiHNSeTiL3QCb3W/b2aFemq5h0gglsonSdApgrWXAaz+a7TTj + ZIsvt7VU32k+sy2hL4V7JkQR1LF4ArdJdAVa4dvfeky8/sY3vUnQebL05BbRRCCi9d3d3WKtv0UEv+z3 + L4NlpDBof8oSXLp0CZ7+wWkYGtkJx0/ukj0awF6WNqx3TqAsv6kW96AqTb2QiK0zMzPH+l+2Icjargmv + K+B1AWzfBbjORQWaTBUD0DpCCaAbGvqdCkF+71a/M1YQWqaLrD+V7BK9jyRSqPxM+NZj3xTLiN/z4vvg + +IkTwrKTAiCwDyHFX1xcFP4/TanmdRhIGWRQKdBEoVRLG+w/fASGd+xAV6BFuA+ytGJ1hemskeikY7kc + 2GUANVN2VXquYVZb9/89n7MdmEGTKoDG/TA2xwC0NCBZf6cmQNUDu4pBvW/r3xvLhKPnNCOytbVNRO6p + HJjao8VbgjA1PQt//eEPw5cefhj27N0rintEX0XRoNNwGqvQqsK0ChOVTydSLdDXPwC79+2HXbt3I1vo + EYFBulJrWXRElgqbMvqvFma1PBbZncMP0lprNQDrlWXgV5+zlrUMtoI0nwJo9G9CDNCUroAEueFYf1YC + TAU4UwCwPQmATHUaog6gFf3/rq4eyCwuCcovvlsCrbZZhem5eRj7yleRxj8iZk9ywU82lxfWv4JgjaOV + p7UWuhDww8Oj6PPvQ6YwikqlXczJXzN2HAPPtQB6UxBwMwBcHKRmA4rnGhEItN2GIbYWbAReMGWLK4Hm + UwANlhoGwNQfZN2foTMAx/Q3JPmwqUKLayRbUtDTKwN7VIVHZbxiijCt4RegRhvxmvRcMBqCFnwuhQCn + i0FWvr29A/oGBhH4I4IFtKXbhNsgMbNGC6pov5MFMGubjNqadfa+T37KOsXDAJzP2QbgJ2kyBSCh19Aw + oCWX3aphAFoMQD5envvfjgyAhUpzwugGtHd0Or0Sad1AqgosFPIiHShz/ZLycCfgEKUPaS2FZBLa2tqR + QXRDV08PtKEiSCSSAvwcL1kzfba5HZiMxYj1AUUnZpcB2MotEL8PuwBO15Z1/hLsZngYgNNGbItLkykA + gCvtB7AWWdawwqH6nPKz3dJgbZftKuL70IpI8QR0dndDCF2CJNL5uZkZEeyTSqAso+CGXFJMLKKC+xPt + p9hBGq19S2urAD69JoJ+ihpdiYq2VQMQ03KnBcvOvW6jV70QyFbU32iUEvDUG+ifw5+1laX5FICQBsIP + LY1p2Q7NNwydCagyVqNGH2xr6y+EA5yUEoxRR5+QyAgQpacFVMgtIAVAlpi6CAvLT/P8cR+51HpC/E2x + BFH/rwH/igNnNvv9smU3BSTNUlEuDqJe16Pzhk7ZYf2/RW0Fonb+24D+kzSXAmg48mh9OEk9WQEEFOUX + isAAZdUMJwuwYadyrcUtppcMQLkBrWjZqTuSSct0qVRcSCzLJZcRC6nl0d0uvUzK7Kub7sxBP1oXoFIV + qwBX8gWoFgvL6LkQck20OgD5Fa7y11BKZSUXYNVGJltEmksBQAMjAHzPEOszucyUab6aCefcY/YyBXD9 + iaH6BCDIw+wSuWmPgFqVxymFsvi3WOfvIWi/KZdwp9WB0f0oZ5dEv35+3aHo9GnEzPQMgGr6elVC79ep + v+73bwPwkxjbIVfZCBm+6123IFV/T09P6+t/+9+/Am7cM6wqxq7sOH29PbCUr8CL3vgbMJs3YXj3Tvi9 + d/0YMMiJ8jo5f6PW8rvVgNe/eC/rhn1n8vnLJdH4M3/xAmRPPwvZ556F4f17oPzQ38PoK18JkfZ2ZwKS + aPet1gmUTzQuCEgtwUF9DrUez/3wh/DYn/95tfWee34kGA5/sZFuwes+8YmGHKfpGICQRoYAbDlnHdS0 + VZkNkJmAAFcDsiIA2NYzAdcjG2VmRO6/qoqA0AWwaMGSfA5dgJLcwVJrBmqlwOD11dcZBHTovl7+6/Ql + 2NoGtjkVQAPFrVfnoJJbCOTUmmuVgNt1JuBWE1qqnFb4DYo1wINAaypT119aYiyfQzegUhar8tqeIKCY + z6C5ABsVBPQrAbeqNLwSkBcEsYX/H7BcBgAGFwBpU4OblAFcrQRFDYFUq1zvT8BayuYhkyvC/GIWsguL + MDU2AbPnz8L88+dgcWwa7t1bhGN0AM9kIIP9dp4WDLAhacDtEgNoKgXAWfmGaQFVsGIqBiBcgIBkAAFD + BpwCHAS83lKBDRVDgBwMUA1B5BJkpXIFFjN5yOaLsIDb6bkMTM0v4eMcWvqymFZcKpWhhHTfLmTBWpiG + KiqEarkkWoOTLMsC0A/hzQQ0oBS4bhZgC7YB90pTKQAhGzAXwDTlYpGCAdhqbUFxM9sqK2C4CkDJ9Z0R + uIyoakmy7jQohlJAEBdLFZhbysL49AJMzS3BIlr5bK6Elr4g1l1k5eANsMZCQTBpUPcgMvDcdVWz/jUK + gC11A3r12aspAN8FuJ5F8QnFANjvt9XNGXBSgu4sQEOjAM2kAAiqwaAsBxbr9qFlLCDYp9Gaz+CYns/g + NguzCxlh2Xl6Lwm7ANHICreqzWsCWLIzMNQu/VYToAPFyizVJlzvC+CtDfB8htzYNasEe+m/XwrchCJ/ + f/lDB1So31CzgLgwyLb1GABPF93Ms9444VQoBeg43lGuVNGiL8LcQhYmcDs+tQAzCHZ6vkSRe9MSCoIC + eiKoV68N6ErXi7Ss7tXJSJ/7BLMAkLUIgWhUpAEFS6PagWIRKtSfoFAQj221wq+t3IQApw1pVeBYDELx + OISodyEdg+YukLLSVzSuMxnItldtBL82UQqLCqmMy6zJeCXSdArAdv5p1NEsJwgo737DBbpj+m2nWajh + BJ4adQ6bK/ydiJ4TiInOLyFlpzE1uwiXJueEpSc/nug8WemgmhxElydE26AX8FfyA1ku4G1RlVX7flLE + tJQZgrSaz0NpfFzUDJSmp8USXpVMRgDfAb1KGertvqlYKMDLg1M1YzIJ4bY2iLa3Q6y3lxYAhWBLC3Dv + f1IsNWwAFcDPfOITxh+9+tVXd+dR5gKPTeXTdI6mdwXldUjTKYBGBwEI/FVahUat/Uf+Z1DR/4CKBdQW + A3E93PYV9t9pWnClYqJ/XoaFpRy8MDELkwh6Ajz9XalajvsjZwMS0JeDfV1syFZdgJ3GH1DjexPYcy+8 + AAunT4tVeyu0RiApLASUADQVBKmiIPHbhELL4wLqeGTpaVlxYgyFiQnxmcwQwuk0xFEZJEdGIN7XBway + BSo6UkFGY886viKVTbdS6/WyDHw2UppQATRenOYTxHotl/7TmgEBPQ1ogLsW/TbSACLfHgyIOAdZ+GK5 + CjNI5SfnlmBiZkEMSslV1Vx89tsj4eC1PVGHfoOYhVhFoJ7/2MeElSebKRQRUflEAoK4BTERaQW/XxdW + 2nWUN1lkKjsuzc/D4jPPCEWX6O+HziNHpLsB0hD8Mm7Lyw68BqHrqRRWtVS6miOsKr4CWK/Y4LoAtvR/ + JfDZ9Mud3EDg1ke+9OENx4Uh+j6/mIPZ+QxcnJoT1D5fKENBdQAOBWhyD22J9mi31LWIc1iyGpDbAYs+ + ALbMvtCioGUEv8M76Ds1qBWYI3RMVCQUEyDqTwwhh0yjiIPKgUG0NwN4Avc8fCVXRGUrbJrTEI839pw1 + aT4F0OCbkoh/VWUBZDzKkDebymvXpAFV9G+rqQDp5nJKzhKLcpAPPz49D+NT8zCHdJ7y8SW0/LpyiITq + WfhrFd20VR0Gtd4iv70qegNSDMDmuEADKv2uVAxtUGWirRRA+AouDF1bKm2uLi2J32QjpfkUQINvUFu0 + o9IUgG3UbL05a+eG3EQtUAt4W0TjFzJLIv8+OSNz8FRs4/Q6pAAfrQfgofTXPs9tO1FcGfezRA9CWgrc + qpRxlMDEx6L2fwu0XLmqn5hSpZUKFKenRXwhuIHWn6QJFUDjRawMrBf5swmg9ng2uIpAm3ey2oK3DRcV + tOOGpVUE9vTCkqD0kzOLMD4zD0vZglAEpvLhhR8f2kyuouqmVZ7fSd/YMtrPC4BaBP5iHul+HsxSAWxU + AqQUtgD+r1gMBf4sug9CQVOacYOliRSA4N/qcaNKgWVBiFwiW36EjAYgzAIuCwDD8Qg2PAbg6CBDltfS + jUSR+sWlLMyjVR+bnBOReqqlzxVKsmEnFemQlafh0Hr72oPIdn+fmpV9FNgZ+MLqE9U30dqT5UcFYOYW + wcxnUBEUkLlUtlyhxeXOhsBPUf7Fs2fF39FkcuNPCppKAWyESMSLSkAGOihTb7HJB4f7y4eNvTFdl8Jw + ou+VahWKxSrMLWYQ8POi2o5KbLP5kvMe2i9c14ffBHEKZiylQVUwT+TSTQX2qkP3BfDJ8lfRxy6XhPW3 + EPxmfkk8tkWqbOtU4dH1Tqz2OoG/VILZZ58VdQiRVOpanVrzKQBexrtBR3NWo3EZgIKkY/LBowAa9NEK + 8CJghJ9fLldEKS357zM4pnHkiiVn5WLaN+QpuNkSteoqjy8tPRfiaIA3K4Lm2wR25evXPCbKXy6CTUqg + mHNcgC3wzWpkJTJPGQQC//T3vid6GkYSq6mKxkvTKYDGi8yNswJwnwXpBgC4HYG5HBiuRhFISs9BxVKp + AjNI6ecWkdZPzwvQUx09zaBjnz+gSlm3rPC6AabpWHVbgZ2BToE9YekV2OVjVyHILTGBMgC+DvQcKpBr + GmOpI96ft97p6OCnAqXQBgf86klzKoBGWj4RA9AYgC0nnMhYlZsJ4P6ATmLqsrUnhlNBR++jFFy+UEQ6 + nxHpOcrLZ3J5ManG8feNOrR+K1j5esIVfGStyY9HK26VC2pblMBHei8sulIEcosKjpSFqdpvmRLwQLSf + tjZP9Kn9OCcCtJbCn6sR7bhsC/Qr7/1EAf5iEaa//31RWWhskqJuTgXQQLHUghRuA1At3B+Qt4CzUrDY + rFwJaKh6erp/qbNusVQWZbVE5+eQ3hPoKVLPbcfq+fFbgtavRYR/X5VApyBeISsHRfTLeaEEbIcFlJVl + VzEAke/Ha2BVVTdhBXoCP6jAK7hgZNnonIacBm44SremYlDfT4F/Sln+zWRpzacANgAfNJvNVmk/mRBk + 8HPi33ZdAG06MFt3eV42WviSrLhbWILJWVlPT4CnjrdGQPr8wWUTZ7anWMr6k5Un4Fey81DNLuJj8uML + CvSK5gtrX3WCgs7EHxUwZKg7bhiVJcLyIqBrmdRkBsDbrHqewF5VtL+6yeAnuWIFsB1KWevJ0J3vUo82 + qBAooA7Ns38oBWhzYxBQnYJEmkBMeaX3ZKjbDdJ6su6cmiM/vqIW1DBUxV2Nld8uFt4jdk2Kz1JlsyUB + +Ep2ASqLc6gA5tEnzonnyeIbSkkYFi+0ablzKZQYCvXMvgwFftNengWwVH3Dmur/r0Cc9C67bep5VYIs + FokQ05EV+IXlR9pP9f2bLZt/BpshDcYQBQHJ4It7D1z6H6D/DDc1V0E/fgn9dgrYzS9lIZMtCAUgCokc + n38LpefWIbYzRdd9bDt+vyly9Sb6/FUEfKWQQSpMvfyXkBrnACoEflP07zdsVWTFbn1NHEUpVW9TD3wu + WpGz5mxt8Ou2Z3LPukU/noj/aC6AZQXy8/Pd9LCUycDcs8+KSUpbAfwkW+Mstqs4hUCWiPgHDQl4kR6k + efGFAiyqOnpqXrmYRapLPrxaMUdYeVo6K2h4Drv9rHxN4Y4DeMsFvdMxxxTLeFE03yzlEfTo5pQKqBzz + YvKOCPKh9Q/ge8QAl0o7HF/fao9tpQRa8Jmh7JJ4jvs1OwqAautVT4aGcQCeZMTHV7ND6fhmtWpkzp9/ + d7yr65uTTzwhqnw2K+BXT3wF0AAJIIDp5qZJM9l8Qfju80jrc2jdxRJZqCAI5DTE5I6g0UgGummiW3Yn + qs898mwN8KqYx7LkEt5E603K7yPwq+UiVEkZoFIcbGuFgz07IRKQIKbIPqXJqAGGGOWyXHZMFAFxw03D + QTKdTQQ/c2dbG8RQ2dJMPOIBwikQTQyCWmlG438AoQTU5B1WMAH6vsXizUYo9BVUbp/Dz53H61L3w/H9 + hhUMIvkxUfdZwoNAtyGIbKGMF+9SIBDI4YX9e3z+XKPOOfj+97//it7wgQ98oFGffU2ldfTWQbw5b4/H + QofvP3UA+rrarsrSplJJKFUs+LOPfwlKVbL8ISjkS/Dd0y/A6efH4MyFCTFdtliU3W/oVwyrdlcBLQO4 + nfFvO/X4pqTzqiqPtiZNyKkgUGlL4C4rkJeKYiueq8iteFwtiffcP9wH73rgfrjlwAE4smsXjHZ1wUh3 + N4zgdqi9HQbSaRhsbYX+VAr6EwkYoJFMwmCqdvS3pcUCpJ14jMq5c1BaXJTXmuoiqI2XagJiNCgW4Lyb + laAl1ot3ng9ScBfPNRyLtUbS6ZtC8fjtOE6FvSOROBVJJk9FWlpui7a03Bptbb0Fx0kcN+O4FZ9/Cb7+ + QKy19TXlfP6pfa973dl1nbgSnwGsQ+gGojz8d5+7iCA3IBamGXMBYemNoDufXvdDt7u4lN5UK/JWJKVX + 1XuWet5Wa/bpDKAeMyBXyQ4E4eWnboFENOrQ8wjVwiNIRdcdtPwOaAFEXGClhTdoDn7/yZMQzedhemxM + Pqnm7BuqFdlGiDg30d4sCDYqGV6dOITn2Iuj2NsLCFzBYuofwF2jwFAtyGgyUAhZTJBagVE8RHYYGkl0 + df0m7vmFRpy3rwDWK/jjMr0XFt62axHf4PlHmy4qf28SbWdLL5RARS7P5YBdAt7SJ/HYqt4fXJdB+s1B + 6Orugo6hQSghdS+i1S5S6y6x/HgMIkjpyR0QZc2qdx8vEOIttgkT7Z+agov//M/CbaASXG7YQe2+OAbQ + UB+MjyXcu6D4HJkdQneFnl5ago5CAeI33AABVGze24IfM/B50GrKQV5ZGVlNQCmE6WeeGWzUqfsKwJc1 + C1t/AnwVwV+hIB5RearkYxagTdW1tYCg/N+uTWPaKqIfDIu2XeceegguPfoo5GZmoEDzG2imIjUeAZAz + FcH13Tm/7oAHZOutIPncqDxoXwK/6ATM/f/Y+m9QJSAzAO5EbCmXoIqKqPD978PCc8/hSYVFYLKqnT8n + LJ3vo5rGENOh7xFS3z+BLlG0vx9KocbN024yBWAoy9Ogwzlz1GH1Adp2Owvd1CKCjwqAAnhFit4XBBsQ + Fp99YNDSgCyrXXQjAGc/8xkoffc7wC0vOZ9O79LX1+E7n4m8Hs3nTxSAAZl3p95/ZDkD3A+Btw1kAbLs + Q1MA4mRkapdahPGyZCKgiYO/k/cWqTd/sar2paNGEwnInD4NC04TyvVLkwUB4fZ4LHj4/lMHoa97/UHA + YsWEKt68IRX8DaqtM7RMlZ6xErLdooBisQ6ZvyerXxHBvYIM+pELwGk+sFQ3HnttSk+BcP/CNLQsLdRY + pNBlBlt5HvrzRJ2pAWhAC/oFGKCNVACc99eO5cw5IFEKh++1gGcEta1gOOAqN35s8Ot4fSukTPr7T5/4 + d//uf67/5H0FcMXH8SoAEwKiGaZY1MKQE3Jqh+wRwO3AVOnKtsM/KP+d+ueT3y8j+qoFFzfjvFrBi1PF + K3JgflKu6Avuza+DI6Rt9eeDhnvtCfjUppsCaDr4DU/kv9EMALTzZobB2Qc9+MjPM/DrKQPDc+yA+o4U + B8kGAmbXyZO/d/jNb/5GI879+igsX6u4OZvNPIttKcKmaxkAp7CHg3rrlKfiafjh0E5J4ZXfH/aMGiWA + gAojqEMUGKNW3zgoAEhBsrD621ECpBQUEBsNfpYat0I95s8mF4Qi+XRuIdyG1ZbOnb5DmL4LuApNVwpO + bANHHh8nDx78SqK7+3836rybiwEA3B6LBhQD6FgfA/hbZABlZAC2IVyAoKzvkRbfOwA0BrBN6wBUcI8s + vllVDIB8f9N0CoHWIxQwm0ym4UBmBuKVsgB4QAXDGAwC/CqoJ/x6tTwX5/cF4MnSqyh6PdA7BUAbkAUw + PFvH79NShAHPtiY96XHt+QzpWhD1N3t6FnpPnnwn7vvsvle/uiGn3nQKIB5hF6B93S5AARVAVbkAAeUG + BPRhaCvZOjEArRpoGwkvwEmVjSL9R2lASv15l+Jah+TxMNmePtg9eRGieEyhBMDjC5M1VYE9LuoJqHSZ + wRF/jXYvC/yRbFAWQG48ykb7bEPVIwRYIXgVFICKo7hxhJBaUDWbSFT67rjjvYmWlr+ldOv+17ymIafd + ZFmABovkxc2RBdCtPD92siCN+3LfrxjQdug43PfUtyCuCn9MLd8vYKIBSa/Dr0fta0p+N7r+2jCca+Gc + ixYgNPh7ELNRRU7cP8DLogxF++m5bChk99x2239NdXX9z0auC0jiK4B1yfVS37cW0TSaw2Zsz+uNEAMe + CSagY98RuPn09yBOVh5k41Xx6aacJegs/KFZWfHuawn4uqfvUUD1XuN0qXbOIosi1jOQ+4m24LjfIo62 + W275aMfo6G8i+BuLfvAVwPrlctb/umEAsqbZcL6XUfudGod/ge1/bumD3t452DV5CUJUwWcYkgkQSKgn + IFFjspLkCrDl5Cq/rST6+aiYBrMAsDiuUhWlw+L7KWVG1D9LlYz79z/dvW/fL+Hr2Y3oBdGECqCxF3Et + +Pfqgu0o7neQ5l9vu7UR36toWvD5XUfhTYvz0FEuinJYUQJMn0flwGphT5vr7wFqm4VsNUWgxJ05absN + UWnVYeppaLh9IMnYVzo7s8PHjr0Hv9d58f024Ds1nwJo2N3q0rnmYAC1Pr+hfS9jjTU/a/4ckECZQEx8 + 8dhd8MC/fA6oUz6lzIgDC7pcLosOPwYBSMUERBR9C821rxH287lEmM5bWX4atnJlxHRxfG0pErF6b7nl + tyKx2GdJOWxUJ67mUwBCGonG7Y7stYpj/508puF5rXEiiTJlHZ4Kp2Do6O1w05NfF7MF6Yatss+MSsDU + 5gZQRkCU3QYCNcG3TRVNoTnDksuoC/CTIlNMhovH5vC1tpMnP9La1/dBUy0JvlFNYppTATQa/03BAID7 + m7pxAM/rjf08FRW3bHi0ew/0DFyCHRMXIBKJOD60aC6imADRZltlDWxVh7/lRDEA4DgGDXpOnT/5/Zli + EUL79j3dtWfP+1BBFDb6lJpOATTaVjVLDIDEjf2pOABszPdSy4ES9sXMggI++Mqx+6Dtix+FzmoJIuGw + cAUqHDknIIlzk66AiLArZSBks5SB1rPAbYkmy6mF30/nrqYAh3CUEPylzs7M8E03/QIqinO2tfHLmzVL + IVCgZfjEEN4JL4pFAofuv/0g9PessxLw41+GYqkKVctukkpAeTPTTcu9AEy1KAf3OGycqFJa6qQUDEMw + FIZSKAbFgREYOvM9iKk58jXRdK0nn14PsBFlv2sS7d6yVdpSdk9Sfj8H/fC7UJaDrutcMGj13nnnryfa + 2v63eH0V2f/a1zbkNK9HBqBjjOdYhCvZ6dZgoiPW2K98Pdj1tYrH3hve5xqcXdH6DLI7cDrZA33H74Eb + v/1FaEkmhdWkT6XGG6BSg+wGuBWXtcU411KcfghKcVrK+osVjbiYiQbuO4OuTPrUqb9p6ev7Q9E16Bqd + 7/WgAHSDynMpeP4IAh5owbVEaWl8JBZOpOWfvqxH3KYcG3mTLu8uTPLYyI3QOXEedk5eEL3/OHXGQTVy + A4g4BxQbcOIB11IJeComuU+gWLWY6D+dkypjJr9/PpMhv/+Z7n37fhm/Q/7anKSU7agA+FfUZ1HS96gB + PA5aYJ2ay7biSFfzczdY6cFO8c5GGiu97/R1HgSUgUDD870M9/VGCVfLEH4sTrNKMJXw8x65+WXQ+rm/ + gF4EUzgs192tKstqK2rNBTVOPOAag1+P+Is4BbczU6lKAn8YlUA+l4NiRwf5/T+PZ/i8tUHR/pVkO8QA + vBPCaKYoAZ0AjhYdCNS08MIADvTzYQeOXTj24Nirxu5gNLUnnOweTbWmW2gyUKNiABWTegI2QUMQZYlp + 8o+cEagmA9GSXZ7efOsWNWlK9sijKbXU2CPszPDLB8JQ6B+CgdNPQpym/apKQc6z633/auIBABvLAnTw + 03kw+JXvTzULoCYu0VRgquufxr167rrrfej3/x/zMn6/LtfzZCDdh+cp0kzpo+BaeKoNIQufVlt+nFav + pdR+NCK2Ve3EXyK2ASHrpmIA7vdwG5s0/Ktp18zWrL94LPg9wHPJXug5fg8ce/xL0Nbe7ry1qpqGOkFB + 8EzP3WBXwF5BCQjwq9mKFMCk+QyT+Tykb7vtb9N9fX/E+f5rLZutAHR7yIBnHz4KLuDJ2hOQdaC3qsEK + gPeh/SPqvW6fBdtO2BvSAGW7I3ut4hYCLE8AbkwhkAQ++f+mCgbq/hbAt4aPQNfkeYhMvgDJ1lb1VkM0 + 4RSuAMUAeLYgwMbGAzS/n5mIIXooqslLdA5s/fGzZxYXIYh+f9fevb+C4M9v1mpQ19oF0KPzDHSm9Axs + ovQ94FL6nTh2g6Ly2nYHjlEc1CK5D0cXjjaQlj+pjsmxgUAo1hqOtPQlU63t0YalAYvoAlTt5mgJBoaq + XZeRbLEIiOgFqPzaBt+/cv68dAEoFRgKRsRWTv2VgKY2YjM9IzB47ilIoJKI0LoC8s3uvIA6LKDhqcF6 + fr+y/gZRfwCnZwH5/dlMBhbb2hYG77jjbYFA4FtXcx82Kg14LRSA14dnq05AZcD3ggT8CCz34feov3eo + 1/vV/vQ+Bryg+QA1nZVqcCYUQGt/QigAigH0rl8B0KIgFbHsVzPEAEDGABBo5PvzEIuArKcf4Coim3pQ + f/wIGCEEf5CafQRrAno5WpmpdxAGTj8hSoVpdqBD9dWUW3vZj9D4eIDgJTrweeB5iJZgSgFUikWYrFat + XvL70+m/4nqAKx1bOQag3+I6pSeAxsGl9EzhWREwnWffXqf0UfV+p+mr53PW/Es2OFzVVOIyGJfFbKge + 0+rnnTgAaGxb/ZY/SPRA99E74cR3vwadXV1y+jAJWV+abktZADVHwNaZQSNcAc/58TDUa4ZqUhpQ5zCF + 1j99662fbO3t/R/XMt+/kjRKASwrvAHXj+eIvR6ka9Me0/MctIur/WPgdnquZ9Gv/qr5QcCrF+f7bAz8 + be2BiALYbjBNLrKhXBCmVlqG8NGBG6FrZgwiMxehta3NsfAisq467/BEIfE5jZg05PH7RYxBKYCASvdx + vp/cw4nZWTAo379//3vtajW3vqvVGGmEAmDAc9COc/BsyRn4BPp2cK09U/cYuAE7HfAk24AwXw/IXqtc + Tqtd2bWwlz2ofY3XALRsOXvOVCW1Ac4IAGPQhgJuv3j4Xmj90v+BaKEAsURCBgDpZSpf1ubhG2oeA6xn + 0pA32q/O1+AtWXzVn5AqFhfm5yHX0bEwfNNN/x7fdIaCg1tB1qMA2KcnEBOg29ToABfwOs3nLVt59tn1 + DsjXCPANBG1TMQDN8utM4HLfkWuFbPfPlXa1tX9sg4NqcljCstpypSDDTREyCxhHO/LVW34cXva1j0M/ + tQmnbkHitA2RhrNseQwdvFc1aahOnb9o4wUK/KrMl0t9S7kcTJum1XfLLb+FiukL1U1K+dWTq1UAhnov + AZoi8BSJpyAeRe8pOKfn4r1pObby18SN3Cjhk14L/pel0LepeMoAnOf07YpvrPOnXedJnRVYKu9PoEX8 + OEE18YKhuQiaK/BEuAe6D70Ibv/Bo9Dd2yviAaQATPb5QQGfA2pX6QKw38+uhgh4GVqPQkX9KR05vrhI + +f5PtPT2/nF1C/j9ulyNAmDQEqgJ7BShPwAySk8VeUT5vbRet/IAmwr6RocBtzusr0SWqzJDd9jX8G73 + D3v5c/pLhE2LqLSk/gL8JllsNcC1/M4AW+iGh7tvgJ455AML45Du6BA3oLDKCEZiD6YGQHmMK3AF9O+p + KQGOdgP3+leMYGxmBoy9e59Rff2uaZ3/WmQ9DIDATWAnBkDpuVGQ9J/A713laOuoPD8IuC6pW8XgpTde + a+75y+v7L3s76RQZBBDW3zBVBx1Ct6kKgoyAig8YINcsAPU3QAbHZ3bfBe3f/GuIIv2OpVLy3MklUO21 + SBFYHA/QSplXTQ+y0mKfn3v44TbI/j9ZfdXaa352FrJtbYsjN930c/jSGYcxbCFZbxCQrgSvDMGKsF4Q + z5frTuRPW3NL296HGuj5DqkHenu5AnAWGGWrb8n59EHDcjSE9AYshwFYSgHQ2y7YEfiHIz8Kb3z872CA + WolFIjKISKdBbIKVAJ/HGl0BvXZE3PBqBSNh/dWcBAr6FbJZmKxU7N577/1/oonEPzW6n3+j5GoVAF0F + dGZgEccYuJafrkM7uCyAZAsqgUaaY1Wc3hSievXUMBwb+L/le0OtUrD1rV1XAdja3wbYKv1HLgCV1CpF + ADI4wOEAS1lwjsexIngUPdS+3bfBjzz/TegdGJANN7WTsVVKUCxDzgHCleICHuBzpaeguvRaMOgsAUbF + PZfm5sjv/3hrT89/F/n+LSpXowD4SlAocx7H8+rvIg7qYUbuAJXlUiqQ3IStpwAahf+10P9t7gJ4LTNw + fw5g628439MbBhD71Vh9W3usbW3PFtxAnWFTvh7fWUWABmgtZur+I5Wu5VEA5BmYtu0oBjrGJ5IH7MGO + cYjNTRvtXV3O1GBTpeEEYAn8CviuUtKUgPbFRDCLKD6XenMnYvL75dWAi1NTlO9/ivL9CP7cWuIjmyXr + YQB0BamYYRKoLFuCP6fGDpDluhwQ9K56vGnS2J/CBt3+rVUXbGXx+udS5E/nAA74+9iOtZXReKPmzbb2 + pZcB3Pnb3dcFv2IAiuqLGECAJtaQylEKgBp/0GdbLtj5/OixWcoUzez4Qj43Pv3RYC7bXyiciGazkQRN + GtJdAdyazAy44Ai0E9GYgLD8yr93/H6KIZACMORqPnMI/kxra2bk+PFfwP3PbWXwk6wnBkDfjIBPgCdl + QIwgr/7OqseUHtRdgi3Albf2D7JZ4qXrNc8r5Nq2q+o4/ebs56H1y19zGYB3n1rwa+W+mgUm+h8wpUKQ + ltoSYKenLFEnYNlmcSFv5ScWrcwLU3Z+agasygK+e/5ZgLmvDQycT42NvXEwFjMoHiBEWX1DgZeyA6ZQ + KnIZMu80YgF61cE3yIEHVXZMU3wLmQyMl8tU5/+fItHo57eq36/LeoOAzAQI7PRty+pxBlwlMAwyXSjW + doDNzv37+BdSz9Lbnh1sF/4OxXd9bVlNV0PBl1l7jQnUfZ0fe95va+4FDcsQtINqAcRRDQF/dAsqJoI+ + Z2ZemLVzY9N2ER1v21zCnWhQfGpWjZm/Ghv73LHu7kB0cvINfUNDso04fhBH73nF3oCKBbASIDHY32fa + D5I92Gq6Mb2X+vtfmJkhv/+j6d7eD1a3sN+vSyNKgfl3pG+8oLbsDmTUGAWZLqRqQKoP0CfzbG+xNWSs + xvs3WfHUp/a1z7un6v6hA1OuaKOotrC6IKv0bOl/czrOOW4dy+4Cn/c1tPdwpwF3UXCbbhWblgWT04Dt + SrFqFsaWrPz4nJ0fn7ZLiwRwMjYM+jmQsakF9Tfdf2SIyh8OBH7vp+PxA9GZmRs7+/pkdaCaOmwxkEGl + trSW3LKrs3w9wE0+6DxVFSG9/sLEBBh79ny/e9++X7Gq1dyWXJegjjS6RS65BPRjsEtQUH9n1WPdJeAC + oWso3h9ltaLU60NWB77HQqt/dJ3lUHubo+tqAKghfXGXuntYg0b79c/heAE/dtcaCMhhyHllthFEJl+u + WMWpHJQWFq3C1DQ6+ARwAjYBfF4bBHpSBGR8KChdVh9BBqflicnJ2KeHhv7olWNjvxNbWmppSaehopYW + C6iTE9V7KrrPJ1xTsqpnC5RSmJmchKXW1iz6/e/G189tVnOPq5FGTwdezSVgTUwuAWUJtoZLcJ3JZS09 + eECqHiwHqHxka68JJYB03JRGUAXgZPCPg28rvR80Wi+tvOH+LebsB6XlN0RqDv35DIJ+rgjF2ZxdzRXA + MsmI0D00p8aC9phpP91fZIRINxHTpHusZhr6QxcvxloHBj77wNjY62OxmBGkeIBdO5PPUEqAr5UT2lTN + PRn81NE3j37/WLFo99xxB+X7P7+VU371ZKNagtEPwHUCrAT4B6QfaifUugRcKrz9ZDXqfw1cgGWHtZc/ + 7/XF+XENJa8DeH0/nu5qmrZoa18ln9ySUXiT3QAtMOhYdVBgr1EAhgC6JQAvgW+bZcsszZbt/GTZLmeq + YJap26ieXaJ7Z0Ftc+r5Krhl6dxDgoTu65g24tqIfmRsrNDZ3n46Oja2f2B0VPj2lvqOrNkCKrLPMQqn + wSf9qWr+Ceznp6chfcstfy38/i00yWetspE9AelaicVcQf5Q7BLoAULdJeCZgddAGoNGx5eFa5sGtJ1/ + WIwaSq/72TUKwXb3q1UA3r+9wOe/bQF2MUgRWLIylyLxTiyA3qSAY2uzB5nWC2XAoK8WqmbuYhmKc1W0 + 8rR6Bu3M1aVkOOieKaot3UvcXCalHtN906pe4yvi7SnJzWR4iMlof5HLjfeHw/3xmZnWrt5e2c0H1BdX + QOf+gbwikrgWWvkv+f2wa9fT3fv3C7//6n/RzZNr0RSUfsyi2tIPRUqAGQFdNOr7Ry4BaXD6gbZMzcBW + krX58nbt844igBqg0yPrsoC3Xcttc4mtBH6VwG/bDvgl/TeczIBUNArsDq0XtNq2CvNI7WeqdnEWrXzJ + kI0+HSOhD1IA7EbSvUNuOQeQeQo631NcmsAxOVYCIW1wibowMplyOfCRdPpcz9LSDYmWlkCc+gdwcM+y + nEIkvq5OjENR/4WZGVrKqzxy9Ogvi3X8PDUD20WuVVdgr0vATIBp3ShIl4CmERNN27jYQCNN8QbK6oBX + j1fw5eVrXipfm6OvAbz+nFIUbnEP+/kuAxDTcykWoHx/01Zddw2pBATgKXinqL1VmKvY+Qmk9uj9WVU+ + K1ONKrgWn/+uas/T0Cfc8QIwDHqnnF8JK4F6W9C28P3Fxfzn2ttfeM34+OjIjh2icafJSsB7zRSroTqA + YqEA5+fmoPOuu/40lko9tB3y/SvJtWwLTtePswS0JVZADICitxTIobgANfxkNhBV59dgRbC56F/tiyyn + 9p4/2YrX/K0e2t5tvdy6subggp3EcoBe+7dAl8YAJBUmhmzIYCAC38SfyFLZFLksF4G+VDXz4xUozJh1 + qL0O8grUAp0fe4FN24C2rXOl6oqxwmNHPr20NLEnkUjHJiba+oaHRTqQMxxe141XGjo/Pg6RQ4e+0bFj + x2+Z5fLWaO1zlXKt1wXg68kuAfl2zAJIEdA8AnIJSBFQRyEK6lxXdQPMU73PrcXS6/vWt/RroPb8nLLs + JNzV21I7OMU9zn6aklB+v2VTEI/AH0HQmGCVkNrnp8p2ac6EaoGQooPeC3ivlV8Jc165LKCvVMro03zE + ts/1lUqHo3Nz4bbOTuB2XfpJEfgjOC4h+HPt7bO7jh59D16QiUacw2bKZi0Mwi4BUz+KCZASmAI5t4Bc + AlIE1GGIFAG7BdsyPmDXbG0xp96bKr5iwPPz3gKbFai9pdgDA9yh9qC9rjEBt8ZfDmeSjSUNulU1TTM/ + W7aWLpagOF21zSLtGALXerNf7wU9++xs6S8H+g2X89ls8ePd3WfeMjOzLxgOB5LptJgsRCdZseWswSiO + iYkJGLPt8sitt/5SKBT6+pUs5bVVZTNXBmI/kOIBdFOwEpgBqQhoUM0AtRqjTkMU9OFswVW5BYaxsXea + l67rf5BvbKi6I7sOBViN2tdSeVYja/PlaxSA2qdGAWgKQZ9QU/ua8P1tq5KvWrmJnJU5l4fibNmu5Hku + tE7XubqKf1+d2jca9Eyo1n2cr01Pz7X39Jz78bGxXSP4Q8VQCVA2wKLqQBzjk5NwKZulOv/f/k+PPfbn + //HFL17nR24NMa60amkDSxw5wEMRXrL6FBQk8BMbIEVAbgH1HdDLidecNoymB+OpoeNdXb1Drb/7ntfB + iaP7RW35lX7/vt4eWMpX4I4HPwAzCznIZgsQCwcgHDIgHJRDrBQktiBWDBKrA6mtqCFRx1oJ8DVbBeJl + Fl4Dd41/r/a1tL9dK78CrV/2mq1SezTBZq6IVj5nFybzdmGmQGV5UOvPeyPw+u9iAaxK768WuN731TvO + as/VOwexfV1///Bdk5O7+9rajBZ0B3J4LZ5Hy79kWdX2Eyf++KPnz//Hf7lwgWJW1U+9+c2bxlpe8Vd/ + 1ZDjbPbagLqwW8A1AxQgFBM5cEyDVAIcH6DaAV4NaFPjAww+5+9lD7S/mQGA57HnOG4arpYBOJZef66O + pYc6FtydKuv5G9wptYL2V0umlZssWLmxnJ0bK9iVTAnfoNN3Ts/pvrsOfr0d3GqWfrXnV7qCKykQ27NP + vfesBH7+Wyipj4+PzxWGh2dPZTJHYs8/n8iixq729i5Uhob+8neffPJPxjMZp9TvlR/+sLGZSqARspUY + gC58M5Glp4wAZQYI+KQEdoBkBtRvgNKGpAh4XsGKJ+cwgB5kAL/YOAaQydRhAEFDLBNGTIAtvxxGTarY + C3h+blmEXntuLdR+VcB7aT5Z+dJS2cqNF63MxSwU58q2WdALuBj0DHz26Rn8bO31HLxOy73gvNzfKz22 + oZZJgPYc1HndO3i/lY6hpxWrJ/r720+m07ujkUj5fKXytU8+88yX8HkK+pFRElWI1wMD2KoKQHyUGlzW + SWCnWIDuFgxCbSfiFeMDG6MAsrCUKdYqAEX/XQUA7iKhPL1cHcsxPQ6wJbiBwQ0aG9Csvh6trwnmWZpV + t/VafQ/lNysWUvuCtfQCUvuJol1cQCtfZYvOoNetfUl7zhvEA8/X0R97gVfvsb6PqT3nBa8372/XeW61 + 1y73mP/WsxbMRKl8necfZMENYEPkyNu1r137A5e+8yew1WUrKwDnI8Gt96ZsAMcHyB0YUYP+5p4DetrQ + OdlaBfBaVAAH1q8A5qUCiEYCEFGWP6zAT75/KFDr+wcM7QZxAM0Vd/ZyCw+gWXoZSOTedct8eQDVEku+ + ia08R+/NSrFq5Sezdn4iZ2cvZe3yEs+U4xueAV+C2hJcHqwMvLl6gJUtbj3wev8Gz3OrgbVeTGEl5aC/ + BlD/8wDqH5/jG6z8uN0dzzCsqv19BXANhavBSBEQ0CkgSMAnJsD1A/R33fgAK4Du3qHW33lPgxQAMoDF + JVQAxADwk1wFwEMqAlk77laK6q2odWrv5OU91l4P9LkTb2pfMz203zJNovZFqzCdt7MXl+zCVAaqBbqB + GcQM6CK4YM+rx3lYrgD0VF49On2l1tnLCLwAhTrvW+1vfl89peT9W99ff817jvWyGPpn+ApgE2Sl+ACz + AVIE5BYQUyBFINyCaPtwMjV4vLOnZ6D19/7DG+DYkb1QrZrL8vGXE68CmF8sKAWgGIACfkBTAoKKGOD0 + kSdZ5suDS/V1l0D66cupPSuAGmpfLZtWcb5gZS9l7Px4xi7N5ymqBy64icryRCwePNuuoA22ejzJpl7B + jhd4KwGtHiDrAb0eWFd7zftcvffBKq97ZbXP956nI74C2DzR68IpNUigp5jAKCyvH4jGOkbbkv03dnV0 + Dba++60vgVf96CmoIgOQLGDt8zi8CmAOFUAk6CoAov20JYsfdOi/4ab/aui/qwSWF+K4gLfZlwfXr2cl + US1ny3aOqP1kzsqNL0Elw8Bl2kqA5045FMDiZho8GYv381J8rnJZLbC2FrCtBYgrPfa+xysr7Xu551ba + xxueuex7fQWwuaLHB8jaE/2n7ADHB9z6ASPQEghF4/0H7h7evXNv20vuvhledtcRBHSnA8i1SD0F4IJf + Wf0guP3jdAagHcdJ2YEnQKcUgVOea3movWVSbj5v5ZnaT2bJ9IPrr3JjVrL23DSD06mz4LIALsDilJ7j + 18Lq4F7Ngq709xXyrDW/52qO21DxFcDWEE5BERug+QOkCDhtSIyAmIGID8QS6fZ4z/7uYPfRvhv39hs/ + 9YYXwa1H90EwFJRLT11G6ikAAntQKYCQQ//d6P8y8APU+PUulWeQ245bQI/NSoG64xTs7FjGzuEo44fa + FgfteFIVDW+LLO6PR88T8MnycyMNBvyVgHqtQu9rRIXelhdfAWwtqRcfIFdAVwQ0vyAd69zVl9xx52hX + e3v4X7/8BLzyJSegJZVQ389YMThYTwFwfp8ZAFf+BTXw1+T/GfiWpgB0mm9atoXU3spNILUfy1j5qTxU + 8/WoPdN77oc3q7bcG4/bsOnRa70cF6B+7UTTAHi94iuArSfsFlB8gNKGK8YHQvH2rvTuu3aHWwbS95zY + BW95+S1wcM8QhCNhxx/3ykoKgET3+wN69B+3tnZv1Pj5iv5bZtUyCzN58uWFlS9M59HKc3qOqT03wtS7 + 3/JgK8/0Xo/4Cz8+dOCt4hsJdBvyswNqgY2aFbHU99b38zIY/i7O39r7nH2NWkVqaB9i80Ftft49BM/Z + 8H6mVyMZYLgnrI6pfw/5EYZ73QHqqjuZlfF8KfcrqNfc46xcbrb9FMBWKgVulLB149QVAYFAwRaSZhuK + jEG1ML8499RnFlNDx3f+U7U0/L3nxoIP3HkIXn7PjbBjuFcs9iD6w69RR8qAnVpowrYV+Jfzf67GM8vZ + kk0FOdmLWciNZe1qrqzKbvX8M5/7PLi+PBelMOg5mMcFO06NfvDgW23wANsXX1iuRwWgCwOBqTNZUAKR + M+3Ytq3BzAvfWizOnp2sDp3Y+b9ml7oe/uZzgZffdRjuvmUf7BzpRfDQUlABZZ1WZ0BO6S2wtbAdK4S8 + 3rTLmZKdG8/auUsZBH8JTNFJUu+BpwfxmN7TXAgGPkfxc+AW6DjUPnTwrapr9cpujC++sFzvCoCEUMB9 + CQkonA8nMJEioPru0Up+bmHh9BdmIi19/Wcyx0b/cGKh45Nf/J5x65FRuO82VARDPdDV2YqsIOBQVG3t + iBU+mPJ0JWqUkbPz4zmgKrzSQgHcqDu3R+MeiXrkXu91zxSf8/UMepfa+4D35SqkGRSAkME732Vd+uoH + 2SemLUfNiRFMqzFSzkwslp/9R1IEvaWZfX0XLo23fe4bp6M7+tJwdP8QHD0wAidvOgjxWATSqSgsLBU8 + FB8NMIG8OJ23idYj6GWL65rSUgY9W3kGPfv2TO+5aIeLcxxLH1T+vE/tfVmPNI0CINlx97vs3kTVnsyH + Sue+/EG2wOxjE8UWbADHMCqCJRyzgXAsXUgPt89fHEk/8f3ORCyRihzavzNYKZflIhEk1ULFLi8UKHiH + vvySXVosgm3yxBrd0utLWHnTdby4BSkmPXLvNNLwLb0vjZamUgC6DN31LvPiVz7IkXICJ4GvJj6AY9Cq + FHsLM88t4YgagWAon+iIPXqmNRKOp6OWEQ7A4nTeLEwtQSXL1J4tvb4Wgp6j11e24VSdTu1rgnihg//G + 1len8cWXRsr1mAa8GtHrBzhtyIVE3JuQ1y0gESEAcAOMHMTTK/J08LNvrxfkePPzemGOL9tUths78xVA + rfD8Ap52TIVEVEHIcwq8CoCtvXcqLWcduOEpR/bZl1+pKMeXbS6+Atj+wmXF3H+AgN+iHrPLxKDVp4rq + jTS8ra/1STbejjS+XEfiK4DrR7j/APcg4EVKSPSJMroV9y5q4R2+XOey3RRA0wYB1yD0S+rpOxKvAvDu + v9JrvviyJcVXAJcXtt4rZdz9iTP/f3t3bAMADMMw7P+v80IzNiKPEODJfGs9AYA7no81gHsEAMIEAMIE + AMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIE + AMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIEAMIE + AMIEAMIEAMIEAMIGZefFHr8PQOIAAAAASUVORK5CYIIoAAAAEAAAACAAAAABACAAAAAAAEAEAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJyIfAD4wIwAnFAgACgIAAAoFAwADAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAA4NDEACwkHAFNLRgCXh3wBXjkhAUQkDwE3GgoAHw0DAAQAAAAAAAAA + AAAIAAgISQANDXAAAAAAAAAAAAAAAAAAAgICAAEBAQE6NDECUEM2CjEdDwsrGhEEVDUiAkwsGQEkEwkB + FAoFAQ0JLgEWFZMBFxejAA0NhwAXF6wAAAAAACUiIAELCQcKT0hDN4V2a4RTMhyMPyEOXTYbCzAiEAYZ + CQQCEwYEBBAFBBYOCgpXCg8PjgILC5oADw+bAAAAAAIFBQUdAgEBaE1IRLutoJfvbEgy9F07JulXNB7S + QiUUtR0OBqMOBwSQCQYkghMTg3kVFZ0dCwuRARMTowAAAAALAQEBWgEBAadMR0TRsqae9nJQOvpoRzT6 + Z0Yy+ls8Kvg3Ihf2NSAd7CMYZt4XFqTlEhKlfQwMmg4UFKIBAAAAAgoKCBEJBgUrfnZwgbmtpPB5Vj77 + b044/G9OOPxiRTL7Pisi+y8iTPoZFpb6FhWn+BAQpdoKCpxUDg6XBgAAAABwamYBWEs/BLiso1rBtazs + jW9X+4JjTPx8XET8cVM8/FM9M/wtJF/7FhWR+xYWp/kQEKLTFRWccR4enQ0AAAAAnJONAXlpXAO8sKhY + ysC57Luol/q5qJj7sJuK/KGLd/yOdmL8cV1Z+0A6hvs1NbH3LS2tkyMjnRQrK6MCAAAAAMK4sQCVhHUC + vrOqV87Gv+rRxbn62dDG+9nPxvvOxbz8qqKa/LSqpvuSjr36iYjP9nl5yYxUVLIKcnLBAQAAAADCuK8A + qpaJAr+zqlTRycPo2tDG+OXf2Prn4tv62NTQ+7Gwr/vFwsT6qafR+pGQzvN/fcF/Y2GtB4OBxAEAAAAA + vK+jALWrnQGzpJYvx721nsi8scPNwbfYzMO76sG8t/PFw8P21dHQ+crG1vi0sdDro5q1Y4p7jwOpobwA + AAAAAMO5sQCikH8Am4d3A6ydkBGzpJcesKKWMp+alVqem5l7s62pjcS6sq3LwLjHzMG7ncSzrC26p6MB + zL63AAAAAAC8r6QAtaueALmsnwDPyMMBw7iuAci+tQGtqKADlZKPBp+UiQquoJIUuKqgIbuurRKbg4MC + ua+0AIqFtgAAAAAAAAAAAAAAAACUgG4AqpqMALSkmACxo5cAopyXAaKfnAG5tbMBy8O9Ac/EvQHRxsAB + ybq0ALehlwDNv7cAAAAAAAAAAAAAAAAAAAAAAAAAAAATExIAYF9fAH59dgCAfnwAl4p9AKucjQC6q58A + v7KrAKOFdgDOxcAAAAAAAP/////x////wAf//4AD//8AAf//AAD//wAA//+AAP//gAD//8AA///AAP// + wAH//+AB///wA////gf///////8oAAAAIAAAAEAAAAABACAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIREAAODg4A + CgYEAAQBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjHhsA + GBMPAEQ3LwBpU0QBQB8JASAMAAAKAwAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQAA + CwoIAAkHBgBMQz0BaWViAj02MAUjEggFLhgJAz4fCwEwFgYBIg8DABsLAgAMBAAAAQAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAICFAAICDoAAAAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAABAQEAEg8NAiMdGQs/NS40UUA0YjIYB14cDAFADQYCHw4IBQsvGxADTSoUAUAfCwEuFgUB + DAQAAQEAAAEAAAABAAAAAQAAAQEAAAcBDg5cARoakwATE3sAGxuXAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAQoJBwcKCAcjS0I7bZuTjcSfjYDpWzEV6UwmDtU+HgqvLxYGfiEPBEocDAQk + EgkDFAwGAw0HAwELBQIACgMBAAkBAAAIAAAABwEBCwYICDgGEhJyAxUVkgAXF58AGRmjAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAZAgICUwUEAp1uZF7b0M7N97mqn/tqQCT7Yz0l+mA6I/dbNBzw + UiwU30UiDsExGAihGw0DhwcCAHsBAABzAAAAbAEAAGcBAAFiAAAHXQsLSl8WFoI1ERF/BRcXnAANDYoA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAANQAAAIYBAQG9BQMC0HBmYOnU0tH7uquh/GtDKfxmRC/8 + ZkQx+2VDL/tlQSv6Yz0l+lw1HvdJKBTwJxMH6RcLA+EMBQHTBgMBvAMBA6gEBCa3FxeN3x0dq7QZGaQq + FhahAxQUnQAPD6UAAAAAAAAAAAAAAAAAAAAACAAAAEwAAAClAAAAyAEBAc4FAwLScWdh6tTS0vu7rKL9 + bUUr/WhGMv1oRzT9aEc0/WhHNP1nRjP8ZkUx/Fk6KPs4Ixb7MR0Q+jAaDfY7Hw/kNBsfvhgTf8wbG671 + Gxux7xgYrJIUFKAXDw+YAhYWjAAJCZQAAAAAAAAAAAAAAAAKAAAATgAAAIkAAACrAQEBvwUDAstyaGLo + 1dPT+7ytov1wRyz9bEkz/WtKNv1sSjb9a0s3/WxKN/1qSTb9XD8u/DsoHfw2JBn8OCUa/FE0Kvw+KFz7 + GRaf+hgXqfwXF6r6FBSq5RERpWwPD5kLDQ2gAQ0NkwABAZcAAAAAAAAAAAAAAAAGAAAAEQAAACUDAwJD + CgcEa4Z8c8bW1dT6vK2i/XJKLf1uTDX9bk04/W5NOP1uTTj9bk45/W1NOP1dQS/9PCof/TgnHf08KiH9 + QS5O/RsWlfwWFaf8GBiq/RcXqvwUFKn5Dg6k0w0NnUcZGZQFERGXAC4upAAAAAAAAAAAAAAAAAAAAAAB + AgEAAT46NwNIMyMPsKKYl9nX1ve+r6T8dk0w/XNQOP5yUTr9c1E6/nNRO/1zUjv+clE6/V9EMf0/LSD9 + OSgf/TQlNf0bFX/9EhKk/RcXqf0YGKr9Fxeq/BYWqfwQEKb1BweesgwMlioMDJQCAQGXAAAAAAAAAAAA + AAAAAAAAAAAAAAAAZmBaAW1NNgq1p5yT2dfW976vpPx6UjP9d1Q6/XdVPf12Vj39d1Y9/XdWPf12VTz9 + Zko0/UczJf09LCX9KyJh/RIRlP0REZ/9FBSn/RgYqv0YGKr8ExOo/A8PovYODpzqGRmegB8fmQkSEpsA + AAAAAAAAAAAAAAAAAAAAAAwHAwCvpJsBeFU7CreonZPa2Nf3w7Wq/JZ2W/2SdV79iGpS/YFiSf1+XkP9 + fVxC/XtbQP13Vz39a084/V1ENP0+MlH9Hx1f/RYVc/0REaH9GBiq/RgYqvwNDaXvERGdmiYmnXI8PKlI + Pj6mBS4upAAAAAAAAAAAAAAAAAAAAAAAAAAAALKmnQF4VTsJt6idk9rZ1/fIurD8s5uG/byqmv24ppb9 + sJ2L/aWOev2af2j9j3JZ/YZnTP2AYET9e1xB/WpPP/1QPDz9LSNX/RMSnP0ZGar9GRmq/A0NpeEMDJ9I + Hh6WCTg4owRISKkAAQGXAAAAAAAAAAAAAAAAAAAAAAAAAAAAsqaeAXtXPQm4qZ6S2tnY9sm8s/y/qpf9 + y72v/cq9sP3LvbH9y72w/ci5rP3CsaL9uKWU/auVgv2dhG39knde/YZqVP1aS2f9REOu/UVFuf1ISLv7 + Rka64Dk5sEMtLZQDODiuATc3pAAuLqQAAAAAAAAAAAAAAAAAAAAAAAAAAACzp54BeVY8CbipnpLb2dj2 + y7+2/Mm3p/3XzcL918zD/djNw/3XzcP92M3D/djNw/3Tyb/9xLqw/b+1qv3JvrL9xLas/Y+Hp/2BgMn9 + jo7U/Y2N1Pt+fs7gXV2+QlhYnAJfX8ABW1uxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALOnngF7WD0J + uKqektva2PbMwLf80sK0/eHZ0f3h2dH94trS/eLa0v3i2tL94drR/cvFvv2koJz9gn97/bGspv3b0879 + rajI/ZKR0v2dndr9nZ3Z+4yM0uBnZ8FBZ2enAWpqxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + s6eeAH1ZPgi5qp+R29rY9s3CuPzZzL/96uXf/erl4P3r5uD96+bg/ezm4f3r5uD9y8fD/b++vf1tbGz9 + n56c/eTg3f24tdT9lpbT/aCg2f2fn9j6jo7R3mdnwD9/f8gBaWnCAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAC6raMAgV1BCLmqnY/b2dj00Ma/+tDAsfzp4tz87efi/O/q5f3w7Oj98u7q/fDt6f3Qz839 + 1tXU/bu7uv3MzMv96+no/b672f2BgMT9iYnK/IeHyfpxbrfIUk2fKnJxtwFcXLsAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAALipmwCFbVMFrZqJddLMx+nW0s/3yr60+sq9sfvOwLP70sW5+9jMwvve1Mr8 + 4dnR/MXCwPzOzc79z8/P/djX2P3v7u792djo/ain1P2iodP8mpjO+ZGHra99YWAWjIWwAXBwxQAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtKieAJeQawCReF4frZyLZbiqnYi+saanw7mvwsa8tNnJv7fn + xr228r+2r/mupJz6ramm+sTExfvEw8X7yMTC+97Uzfzn4d384t7k/N3a5vrSz+L2wre9pp16WxLEvMcA + XFy7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC5qZwAgmdOAJeFbgGNeGMGl4BrCqGJdRCeiHMa + nIRxLZ+KeEeVjYZ9kI+PrZSTksekoqHUsa2q2MC6tubMxsH0zMK6+cu/tfvLvbL6z8G19tbJvt3Qvq5v + pX9ZBt3PwwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACalW4AlntiAL2wpAHQysUB + 19XTAbKwsAGwq6gBoZiRAouHhAeDgn8Wh4WEJ4uIhzOShXw4pJGBTrGik3C6q5+Ww7euws/Iw9HPx8KY + taCQTqmKchSibmIAl5CzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABrWTQA + c1Y7AIxwWACehnEAoYp2AJ+IdQCijXwAl5CIAYuKigGSkpABpKKhAYmFggKJem4DjnZgB5uCbQ2agGoe + p5F/KsjBvA/AvLcEz8K2AaeCVwDe0MQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAABAQEAFhYWAEpKSQB+fn4Ag4OBAIaFhQCLiIgAk4Z9AKuajAHDubAB + 083KAdza2gHY1dQByL2zAbGXgQGriWwApm5lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEAQkFAAGRhYAAzJx0A + Wz8pAHtdQACUemMAmoFrAKmVhADJxMAAsK6sAJyamgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAP//////////////////////n////gP///wAAH/wAAA/wAAAH8AAAA+AAAAH + gAAAA8AAAAPgAAAB+AAAAfgAAAH4AAAD+AAAA/gAAAP4AAAH/AAAB/wAAAf8AAAH/gAAD/4AAA//AAAf + //wAH///4D//////////////////////KAAAADAAAABgAAAAAQAgAAAAAACAJQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAQAAAAAAAAABAAAACQQCAAUCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAsFAgASDQoACAYFADopHgGejoMBoo1/AVsoBgFPIgQBKhICAQsEAAEBAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwEAAAYGBQAIBQMAXVBIATMyMQYLCwoiDwoGNwkEAS4FAgEf + CwYDDSgVCANPJgsBPBsFARYJAQEDAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEPCwgEEA0LHCwgGGZgU0q9 + dl9P3UQeBNUtFAK8GQsBkQoEAV0EAgEwCQUCER4QBwVOJg4BSiIIASAOAgEFAgABAAAAAQAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBBgAODjwADg4sAAwMXAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQAAAgcGBREIBgRL + RjoyqaSZkevV0tD7tqOV/GEuC/xgMBH7WC0R9kokDOk2GQfNIxADnhEHAWgGAwE4BwQCFg4HAwsVCwQH + FQoCBQkEAAQCAAAEAAAAAwAAAAMAAAACAAAAAgAAAAIAAAABAAACAQwMVAEfH6EBHR2jACwsowAdHasA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAK + AAAAOAEBAYgLBwTFkoR88t3c3Pze3t79t6SW/mMzFP1kPCL+ZT4n/WQ8I/xjOB38XTIW+VEpD+9AHgnW + KxMFsBQJAo8FAgBzAQAAYQAAAFsAAABXAAAAUgAAAE0AAABJAAAARAAAAD8AAAA7AAABNwEBCzQNDTwr + ERFECBsbngAqKrwAGRmoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB + AAAABQAAACcAAABzAAAAtwEBAc8MBwTVl4qB9t7d3f3e3t79t6SX/mM1GP1mQSn+Z0Ux/mdFMf1mQy7+ + ZkAr/WU+JfxkOiD8YDQZ+1UsEfZDIQvqKRMF2Q4GAdEDAQDNAAAAwwAAAL4AAAC7AAAAuAAAALYAAAC1 + AAADswoKRcEcHJjUHByUViIipAMcHKQAHR24ABcXoQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAEAAAANAAAATgAAAKcAAADMAAAA0QEBAdMLBwTXl4qB9t7d3f3f39/9uKWX/mQ2Gf1nQiv+ + aEc0/mhHNf1oRzX+aEc0/mdGMv1nRDD+ZkIs/mU/KP1kOyL9VS8Y/DUbC/ooFAb3HA0D7w8HAeMFAgDR + AQAAtAEAAJ0AAAKjBAQowRoaovIlJbz6Hx+y1R4epC8eHrACHBylABYWsQAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAQAAABsAAABwAAAAvQAAANAAAADRAAAA0wEBAdMMBwTXmIuC9t/e3v7f39/+ + uKWY/mU3Gv5oQyz+aUg1/mlJNv5pSTb+akk2/mpJNv5pSTb+aUg1/mhHNP5oRTH+WDkn/TgkF/40HxL+ + NB4P/TMbDPwyGQn1ORwJ2SwVB6gUChyAFRSYzB8fuPwiIrb8Hx+4+hsbra4fH6AVGBirARwcoQAQEKcA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAHcAAADCAAAAzwAAANEAAADSAAAA0gEBAdMMBwTX + mIuC9t/e3v3f39/+uaWY/2c4Gv5qRCz/a0k1/2tKN/5rSjf/bEo3/2xLN/5sSzj/a0o3/mtKN/5rSjf+ + Wj4u/TooHf42JBr+NiMY/TYiFv4+Jhf+Xjcf/WA1HvwzH2P0GBix+xoZrf4aGq3+GRmu/BgYsfYYGKaB + Hh6gCBUVpgESEqYADg6dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAC0AAABcAAAAhwAAAKoAAADA + AAAAzAEBAdEMBwTWmIyD9t/e3v3f39/9uaaY/2k6G/1sRi3/bUs2/21MOP1tTDj/bkw4/21NOf1uTTn/ + bUw4/21MOP9tTDj/Wj8u/TspHv44Jx3+OCcc/TgmHP5DLiH+ZEMx/U00Vv4YFaX9Fhas/RkZrP4aGqz+ + GRms/RUVrPwSEqrqFhahVBcXogMUFKEABASiABAQmgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD + AAAACwAAAB0AAAA5AAAAXwICAoYPCQSunI+G8d/e3v3f39/+uaaY/ms8G/5uSC7+b003/m9OOf5vTjn+ + cE45/m9OOv5wTzr+b045/m9OOf5vTjn+WkAv/jsqH/45KB7+OSge/jkoHv5HMib+WT9K/R0Xl/4REan+ + GRmr/RoarP4aGqz+Ghqs/RgYq/0QEKn7Dg6k0xcXnS4MDKECExOcAAEBnQAPD5cAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAQAAAxcXFws5IxQur6GW19/f3v3f39/+uqaY/20/Hf5wSzD/ + cVA5/3FRO/5xUTv/clE7/3JRO/5yUjz/cVE7/3FRO/9xUTv/W0Ev/jwrH/86KR7/Oike/jopH/9GMjH/ + Jh2D/g0Mp/8XF6r/GRms/hkZrP8aGqz+GRms/RkZrP4XF6v9Cwul+gsLn64ZGZsVCgqeAQ8PmQAFBZsA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWNjYwJuRCcYtaab0N/f3v3f39/9 + uqeZ/29AHv1zTTH/dFI6/3RTPP10Uzz/dVM8/3VTPf11VD3/dFM8/3RTPP9zUzz/W0Iv/T4sIP88Kx// + Oyof/ToqI/8mHGT/CQmi/RQUqf8ZGav/GRmr/RoarP8aGqz/GRms/RkZq/4ZGav+ExOp/AcHofUMDJuB + JSWeCAYGnABJSa8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgEAAMLCwgFyRykX + taab0N/f3/3f39/+uqeZ/nJDIP52UDP+d1U8/ndWPv53Vj3+d1Y9/ndXPv54Vz7+d1Y9/ndWPf52Vj3+ + XkQx/kAuIf49LCD+PCsg/iwgR/4GBJH+BQWd/gwMo/4SEqj+GBir/hoarP4aGqz+Ghqs/RgYq/4TE6n+ + DAyk/AQEn/oCApjqEBCaUgYGmQEICJkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAN/e3gF0SCkXtqeb0N/f3/3f39/+u6iZ/3hLJ/56VTb/elg9/3pZP/56WT//elk//3paQP57WkD/ + elk//3lZP/95WT//blE5/lc/LP9MNyj/RDEk/kI6bv8xMZv/ICCV/h0dl/8QEKL/FBSp/hoarP8aGqz/ + GRms/RMTqv4KCqT8Gxuf8R8fnO4vL6XtQECvgy4uogE+PrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAN/f3wF0SCoXtqec0ODg3/3g39/9vqud/518YP2jiHP/mH5o/41wWf2EZEv/ + f15D/31cQf19XUH/fVxC/31cQf99XEH/fFtA/XlZPv90VTz/Z0w3/T8xPP8hHkf/ERBE/RMRSf8UFJH/ + Dg6o/Roaq/8aGqz/Ghqs/Q4OqP0ICKPKICCWQycnmDpOTq05amq8GUpKqwBycsEAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN/e3gF0SCoXt6ec0ODg3/3g4N/+v62f/6yPdv69qZn/ + vayd/7uqm/61opL/qpWC/52Dbv6Qc1r/hmdL/4FhRP+AYEP/gF9D/n9fQv9/X0L/fl5C/m1RPv9TPjj/ + PCw0/iQcNf8VFIn/Dg2n/hoarP8aGqz/Ghqs/Q0NqP0HB6OyISGfCQEBnAICApYBERGeAAwMlQAKCp4A + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN/f3gF0SSoXt6ec0N/f3/3g39/+ + wK6g/7SZgv7GtaX/xrep/8a3qv7Gt6r/x7ir/8e4qv7EtKX/vKqa/6+Zhv+ghnD/knVb/olpTf+EY0b/ + g2JE/oJhRP+AYET/e1xE/ldCQf8fHYz/ERCo/hoarP8aGqz/Gxus/RISqv0SEqayJiaeCBsboQFPT60A + amq8AEpKqgBycsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN/f3wF0SSoW + uKicz9/f3/zg4OD9wa+h/ruijf3PwLL+z8K1/s/Ctv3Pwrb+0MK2/s/Ct/3Qw7f+0MK2/tDDt/7PwrX+ + y72w/cGxov60oI7+po54/Zl+ZP6PcVX+iWlN/WZPR/5QTZ7+Xl7E/VdXwf5UVMH+XFzE/GdnyPxRUb2x + NDSlB2xsywEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAN/f3gF0SSoXuKic0ODg3/3g4OD+wbCi/8Krl/7Xyr//18zB/9fMwv7XzML/2MzC/9fMwv7YzcP/ + 2MzC/9fNwv/XzML/18vB/tbMwf/Vy8D/1cq//tPIvP/OwbT/xreo/pWIk/9qaLb/jY3V/pOT1/+Tk9f/ + k5PX/YyM1f1hYcOxPj6pB4OD1AEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAODf3gF0SSoXuKmc0N/f3/3g4N/+wrCj/8izof7e1Mr/3tXL/97VzP7f1cz/ + 39bN/9/Wzf7f1s3/39bN/9/Wzf/e1cz/2NDH/rKro/+blY//qqOc/tDHv//d1Mv/3dTM/rmywv9+fMb/ + lpbZ/pub2v+bm9r/m5va/ZWV2f1oaMSxQECpB42N1wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAODf3wF0SSoWuKmdz9/f3/zh4OD9w7Gj/s67qv3l3dX+ + 5d7W/uXe1v3m3tb+5t/X/ube1/3m39f+5d7X/uXe1v7l3tb+wbu1/ZORj/6cm5r+UlFP/ZCNif7e19D+ + 5N3V/cW/zf6Ihsz+np7b/aOj3f6jo93+o6Pd/J6e2/xtbcawQUGqBpWV2QEAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN/f3wF0SioWuKmdz+Dg4P3h4eD+ + w7Kk/9PCsv7r5d7/6+Xf/+vm4P7s5uD/7Ofg/+zm4P7s5+H/6+bg/+vm4P/r5eD/t7Ow/tHR0P+goJ// + IiIi/nV1dP/k4d3/6uTf/s3I1/+Ojc//o6Pd/qen3v+np97+p6fe/aKi3fxycsewQ0OqBpyc2wAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN/e3gF1SisW + uamcz9/f3/3h4OD9w7Kk/tbFtf7w6+b/8Ovn//Ds5/7x7Of/8ezo//Ht6P7y7en/8e3o//Ht6P/w7Of/ + vLq4/uDg3/+vr67/d3d3/paWlf/q6Ob/8Ozo/tTQ3/+Hhsn/lZXR/piY1P+ZmdX+mJjV/ZKS0vxeXbul + Tk6uBXx8ygAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAN/f3gB1SisWuamdzuDf3/zh4eH9zMC3/rugif3s5Nz+8+7p/vXx7v328u/+9vLv/vbz7/328+/+ + 9fLv/vXy7/7y7+z+vr28/ePj4v7e3t3+zc3N/djY1/7t7Ov+9fLw/dvY5/6CgcP+amm5/X18xf6Hhsr+ + ennD/GNgr/VEPIxgWVmyATU0nQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAANXQywB3TS8RsJyLxOHg3/vi4uL84N7d/cKzp/y6o5D9vaeT/sOtmv3Nuqj+ + 2Mm7/uTZz/3v6OH+9fHt/vj28/708/H/vLu7/tjY2P/a2dn/2tra/tra2v/p6Of/+Pb1/ufm7/+jotH/ + kpHL/pmY0P+bmtL+mZjR/ZaOtu2IZVQ7j47NAXNxvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJyBaQCNa1MDjWxRZ7mpm97Mxb7y087J+tnX1Pzd3Nv9 + 3NrZ/dfSz/zPx8D9x7qv/cCvoPy8qJb+vaeU/sKsmf6+rZ7+qKWj/cTExv7Dw8T/w8PF/sTExv/n5+f/ + /Pv7/vn4+v/h4O//y8vl/sLB4v6zstv+np7T/KGZuuySbVI5lpXPATk5pQAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJd5YwCAWjsAf1g8Bn9YOyaMa1BF + lnhgZJ+GcYerlYOotaSVxr+yp9/Jv7fw0cvG+dXS0PzT0tH9ycfH/bGtq/2Ri4f9ubi3/M/Pz/3Ly8z9 + x8bI/cG/vv7Juaz+3M7B/enh2P707+z++ff2/fj3+f708/f97Ovz+93U0OanfVIx6ejxACsmiwAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKfiwCGYUgA + mHxjAdnW0gHh4eIB2tfWAbutowKJZk4GelEzEH1WNiKHY0Y8kHJYW4h6b56IhoTdioqK8pCPj/qioqH9 + sbCv/Li3tv3Av779z87O/NrY2P3PyML9xrit/L6snP27pJL+v6iU/cu2pf3cz8L87+nj+9vKusOjdkcU + 8evmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAHRIKACGYUIAcEIiAHlPMACJZ0sBm4BoAbOikQHNxb4B29rYAeDg4AHe3t4B1dXVAYeHhwiFhIQi + h4aFQ4iHhmWKiYiGjoyLlZCIgo6ahnWrsqKUzMK2rOfNxr/22NTR+97d3f3f3t792tfV/M/HwPu6p5jm + q4xxrLCNakGdckkCtZRzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqOhkAaDkYAGc8GgBpOxoAbUAfAHdMKwCEX0EA + lXdeAZ+OfwGalpMBiYmKAX9/fwGJiIgCkI6OA5qNhAKCXkMHe1M0FIJcPi2NbFFRm39of6qUgrS+r6Pj + 083I3N3c3JTa2to6ycG7CtPDtgGwjWkA+vj2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACDg4QAhIODAHNzcgCAf38AhoWFAYyLigGRkI8BlpWVAZqWlAGtpqAB09HPAd/f3wHc29sB + uaqfAn9YPAp9Vjcuk3RcKsK3rgWYc1QBvaCEAbqZdwCWZTMAxKmNAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwcHABMS0sAYV9dAFs+KQBrPhwA + cEQiAHxTNACObVIBq5WCAc/IwAHg398B4eHhAeDg4AHa2toAycK+ALammwDU09MAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAGo6GQBvQiEAc0orAGw+HQB4Ty8Aj29VAMW+uACKZ0sA29nZAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////////////////// + ////////////////////////////////////////////////////////////8B/////////gA/////// + /4AAH//////+AAAAA/////wAAAAB////8AAAAAD////gAAAAAH///8AAAAAAP///wAAAAAAf///AAAAA + AB////AAAAAAD///8AAAAAAH////AAAAAAf///+AAAAAA////4AAAAAD////gAAAAAf///+AAAAAD/// + /4AAAAAf////gAAAAB////+AAAAAH////4AAAAAf////gAAAAB////+AAAAAP////4AAAAA/////wAAA + AD/////AAAAAP////8AAAAA/////4AAAAH/////gAAAAf/////gAAAB///////AAAP///////gAB//// + /////gf///////////////////////////////////////////////////////////////////////// + /////w== + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/NewDownloadForm.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/NewDownloadForm.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,395 @@ +using MyDownloader.Core.UI; +namespace MyDownloader.App.UI +{ + partial class NewDownloadForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.tableLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.chkChooseZIP = new System.Windows.Forms.CheckBox(); + this.pnlFileName = new System.Windows.Forms.Panel(); + this.label4 = new System.Windows.Forms.Label(); + this.txtFilename = new System.Windows.Forms.TextBox(); + this.checkableTreeView1 = new MyDownloader.App.Controls.CheckableTreeView(); + this.folderBrowser1 = new MyDownloader.Core.UI.DownloadFolder(); + this.chkStartNow = new System.Windows.Forms.CheckBox(); + this.pnlSegments = new System.Windows.Forms.Panel(); + this.numSegments = new System.Windows.Forms.NumericUpDown(); + this.label2 = new System.Windows.Forms.Label(); + this.locationMain = new MyDownloader.App.UI.Location(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.locationAlternate = new MyDownloader.App.UI.Location(); + this.btnRemove = new System.Windows.Forms.Button(); + this.btnAdd = new System.Windows.Forms.Button(); + this.lvwLocations = new System.Windows.Forms.ListView(); + this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.waitControl1 = new MyDownloader.Core.UI.WaitControl(); + this.backgroundWorkerRetriveZIPInformation = new System.ComponentModel.BackgroundWorker(); + this.tabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this.tableLayoutPanel1.SuspendLayout(); + this.pnlFileName.SuspendLayout(); + this.pnlSegments.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numSegments)).BeginInit(); + this.tabPage2.SuspendLayout(); + this.SuspendLayout(); + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; + this.btnOK.Location = new System.Drawing.Point(328, 589); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 1; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(409, 589); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 2; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // tabControl1 + // + this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Controls.Add(this.tabPage2); + this.tabControl1.Location = new System.Drawing.Point(8, 8); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(474, 573); + this.tabControl1.TabIndex = 0; + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.tableLayoutPanel1); + this.tabPage1.Controls.Add(this.locationMain); + this.tabPage1.Location = new System.Drawing.Point(4, 22); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(466, 547); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "General"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.Controls.Add(this.chkChooseZIP); + this.tableLayoutPanel1.Controls.Add(this.pnlFileName); + this.tableLayoutPanel1.Controls.Add(this.checkableTreeView1); + this.tableLayoutPanel1.Controls.Add(this.folderBrowser1); + this.tableLayoutPanel1.Controls.Add(this.chkStartNow); + this.tableLayoutPanel1.Controls.Add(this.pnlSegments); + this.tableLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; + this.tableLayoutPanel1.Location = new System.Drawing.Point(8, 153); + this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.Size = new System.Drawing.Size(455, 391); + this.tableLayoutPanel1.TabIndex = 1; + // + // chkChooseZIP + // + this.chkChooseZIP.Location = new System.Drawing.Point(3, 3); + this.chkChooseZIP.Name = "chkChooseZIP"; + this.chkChooseZIP.Size = new System.Drawing.Size(400, 20); + this.chkChooseZIP.TabIndex = 0; + this.chkChooseZIP.Text = "Choose files inside ZIP"; + this.chkChooseZIP.UseVisualStyleBackColor = true; + this.chkChooseZIP.CheckedChanged += new System.EventHandler(this.chkChooseZIP_CheckedChanged); + // + // pnlFileName + // + this.pnlFileName.Controls.Add(this.label4); + this.pnlFileName.Controls.Add(this.txtFilename); + this.pnlFileName.Location = new System.Drawing.Point(3, 29); + this.pnlFileName.Name = "pnlFileName"; + this.pnlFileName.Size = new System.Drawing.Size(448, 40); + this.pnlFileName.TabIndex = 1; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(0, 1); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(55, 13); + this.label4.TabIndex = 1; + this.label4.Text = "File name:"; + // + // txtFilename + // + this.txtFilename.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtFilename.Location = new System.Drawing.Point(0, 17); + this.txtFilename.Name = "txtFilename"; + this.txtFilename.Size = new System.Drawing.Size(448, 20); + this.txtFilename.TabIndex = 2; + this.txtFilename.TextChanged += new System.EventHandler(this.txtFilename_TextChanged); + // + // checkableTreeView1 + // + this.checkableTreeView1.CheckBoxes = true; + this.checkableTreeView1.Location = new System.Drawing.Point(3, 75); + this.checkableTreeView1.Name = "checkableTreeView1"; + this.checkableTreeView1.Size = new System.Drawing.Size(449, 196); + this.checkableTreeView1.TabIndex = 2; + // + // folderBrowser1 + // + this.folderBrowser1.LabelText = "Save to:"; + this.folderBrowser1.Location = new System.Drawing.Point(3, 277); + this.folderBrowser1.Name = "folderBrowser1"; + this.folderBrowser1.Size = new System.Drawing.Size(447, 42); + this.folderBrowser1.TabIndex = 3; + // + // chkStartNow + // + this.chkStartNow.Location = new System.Drawing.Point(3, 325); + this.chkStartNow.Name = "chkStartNow"; + this.chkStartNow.Size = new System.Drawing.Size(449, 17); + this.chkStartNow.TabIndex = 4; + this.chkStartNow.Text = "Start Now"; + this.chkStartNow.UseVisualStyleBackColor = true; + // + // pnlSegments + // + this.pnlSegments.Controls.Add(this.numSegments); + this.pnlSegments.Controls.Add(this.label2); + this.pnlSegments.Location = new System.Drawing.Point(3, 348); + this.pnlSegments.Name = "pnlSegments"; + this.pnlSegments.Size = new System.Drawing.Size(448, 37); + this.pnlSegments.TabIndex = 9; + // + // numSegments + // + this.numSegments.Location = new System.Drawing.Point(0, 16); + this.numSegments.Name = "numSegments"; + this.numSegments.Size = new System.Drawing.Size(75, 20); + this.numSegments.TabIndex = 1; + this.numSegments.Value = new decimal(new int[] { + 1, + 0, + 0, + 0}); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(-3, 0); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(54, 13); + this.label2.TabIndex = 0; + this.label2.Text = "Segments"; + // + // locationMain + // + this.locationMain.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.locationMain.Location = new System.Drawing.Point(8, 3); + this.locationMain.Name = "locationMain"; + this.locationMain.Size = new System.Drawing.Size(453, 147); + this.locationMain.TabIndex = 0; + this.locationMain.UrlLabelTitle = "URL"; + // + // tabPage2 + // + this.tabPage2.Controls.Add(this.locationAlternate); + this.tabPage2.Controls.Add(this.btnRemove); + this.tabPage2.Controls.Add(this.btnAdd); + this.tabPage2.Controls.Add(this.lvwLocations); + this.tabPage2.Location = new System.Drawing.Point(4, 22); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3); + this.tabPage2.Size = new System.Drawing.Size(466, 547); + this.tabPage2.TabIndex = 1; + this.tabPage2.Text = "Alternate URL"; + this.tabPage2.UseVisualStyleBackColor = true; + // + // locationAlternate + // + this.locationAlternate.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.locationAlternate.Location = new System.Drawing.Point(8, 3); + this.locationAlternate.Name = "locationAlternate"; + this.locationAlternate.Size = new System.Drawing.Size(447, 98); + this.locationAlternate.TabIndex = 0; + this.locationAlternate.UrlLabelTitle = "URL"; + // + // btnRemove + // + this.btnRemove.Location = new System.Drawing.Point(154, 107); + this.btnRemove.Name = "btnRemove"; + this.btnRemove.Size = new System.Drawing.Size(75, 23); + this.btnRemove.TabIndex = 2; + this.btnRemove.Text = "Remove"; + this.btnRemove.UseVisualStyleBackColor = true; + this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click); + // + // btnAdd + // + this.btnAdd.Location = new System.Drawing.Point(6, 107); + this.btnAdd.Name = "btnAdd"; + this.btnAdd.Size = new System.Drawing.Size(142, 23); + this.btnAdd.TabIndex = 1; + this.btnAdd.Text = "Add / Update Selection"; + this.btnAdd.UseVisualStyleBackColor = true; + this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click); + // + // lvwLocations + // + this.lvwLocations.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lvwLocations.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnHeader1, + this.columnHeader4, + this.columnHeader2, + this.columnHeader3}); + this.lvwLocations.FullRowSelect = true; + this.lvwLocations.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; + this.lvwLocations.HideSelection = false; + this.lvwLocations.Location = new System.Drawing.Point(6, 130); + this.lvwLocations.MultiSelect = false; + this.lvwLocations.Name = "lvwLocations"; + this.lvwLocations.Size = new System.Drawing.Size(447, 388); + this.lvwLocations.TabIndex = 3; + this.lvwLocations.UseCompatibleStateImageBehavior = false; + this.lvwLocations.View = System.Windows.Forms.View.Details; + this.lvwLocations.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.lvwLocations_ItemSelectionChanged); + // + // columnHeader1 + // + this.columnHeader1.Text = "URL"; + this.columnHeader1.Width = 248; + // + // columnHeader4 + // + this.columnHeader4.Text = "Authenticate?"; + this.columnHeader4.Width = 86; + // + // columnHeader2 + // + this.columnHeader2.Text = "Login"; + this.columnHeader2.Width = 73; + // + // columnHeader3 + // + this.columnHeader3.Text = "Password"; + this.columnHeader3.Width = 83; + // + // waitControl1 + // + this.waitControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.waitControl1.Location = new System.Drawing.Point(8, 592); + this.waitControl1.Name = "waitControl1"; + this.waitControl1.Size = new System.Drawing.Size(232, 16); + this.waitControl1.TabIndex = 3; + this.waitControl1.Text = "Loading zip contents..."; + this.waitControl1.Visible = false; + // + // NewDownloadForm + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(489, 618); + this.Controls.Add(this.waitControl1); + this.Controls.Add(this.tabControl1); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOK); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "NewDownloadForm"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "New Download"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.NewDownloadForm_FormClosing); + this.Load += new System.EventHandler(this.NewDownloadForm_Load); + this.tabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.tableLayoutPanel1.ResumeLayout(false); + this.pnlFileName.ResumeLayout(false); + this.pnlFileName.PerformLayout(); + this.pnlSegments.ResumeLayout(false); + this.pnlSegments.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numSegments)).EndInit(); + this.tabPage2.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.Button btnRemove; + private System.Windows.Forms.Button btnAdd; + private Location locationMain; + private Location locationAlternate; + private System.Windows.Forms.ListView lvwLocations; + private System.Windows.Forms.ColumnHeader columnHeader1; + private System.Windows.Forms.ColumnHeader columnHeader4; + private System.Windows.Forms.ColumnHeader columnHeader2; + private System.Windows.Forms.ColumnHeader columnHeader3; + private DownloadFolder folderBrowser1; + private System.Windows.Forms.CheckBox chkChooseZIP; + private System.Windows.Forms.FlowLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.Panel pnlFileName; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox txtFilename; + private MyDownloader.App.Controls.CheckableTreeView checkableTreeView1; + private System.Windows.Forms.Panel pnlSegments; + private System.Windows.Forms.NumericUpDown numSegments; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.CheckBox chkStartNow; + private WaitControl waitControl1; + private System.ComponentModel.BackgroundWorker backgroundWorkerRetriveZIPInformation; + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/NewDownloadForm.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/NewDownloadForm.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,534 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using MyDownloader.Core.Common; +using MyDownloader.Core; +using MyDownloader.Core.UI; +using MyDownloader.Extension.Protocols; +using ICSharpCode.SharpZipLib.Zip; +using MyDownloader.Extension.Zip; +using System.IO; +using System.Threading; + +namespace MyDownloader.App.UI +{ + public partial class NewDownloadForm : Form + { + Thread zipReaderThread; + + public NewDownloadForm(string file, string filename, string location, int segments, string username, string password) + { + InitializeComponent(); + txtFilename.Text = filename; + numSegments.Value = segments; + //folderBrowser1. + ResourceLocation[] rl = new ResourceLocation[1]; + rl[0] = ResourceLocation.FromURL(file); + DownloadLocation = rl; + folderBrowser1.Folder = location; + chkStartNow.Checked = true; + if (username != "" || password != "") + { + locationMain.Username = username; + locationMain.Password = password; + } + //AddLocation(ResourceLocation.FromURL(file)); + } + + public NewDownloadForm() + { + InitializeComponent(); + + locationMain.UrlChanged += new EventHandler(locationMain_UrlChanged); + + + ShowZIPMode(false); + + numSegments.Maximum = Core.Settings.Default.MaxSegments; + numSegments.Value = Core.Settings.Default.MaxSegments; + chkStartNow.Checked = true; + } + + void locationMain_UrlChanged(object sender, EventArgs e) + { + if (Core.Settings.Default.AutomaticFileName) + { + try + { + Uri u = new Uri(locationMain.ResourceLocation[0].URL); + txtFilename.Text = u.Segments[u.Segments.Length - 1]; + } + catch + { + txtFilename.Text = string.Empty; + } + } + } + + public ResourceLocation[] DownloadLocation + { + get + { + return locationMain.ResourceLocation; + } + set + { + locationMain.ResourceLocation = value; + } + } + + public ResourceLocation[] Mirrors + { + get + { + MyDownloader.Core.ResourceLocation[] mirrors = new MyDownloader.Core.ResourceLocation[lvwLocations.Items.Count]; + + for (int i = 0; i < lvwLocations.Items.Count; i++) + { + ListViewItem item = lvwLocations.Items[i]; + mirrors[i] = MyDownloader.Core.ResourceLocation.FromURL( + item.SubItems[0].Text, + BoolFormatter.FromString(item.SubItems[1].Text), + item.SubItems[2].Text, + item.SubItems[3].Text); + } + + return mirrors; + } + } + + public string LocalFile + { + get + { + return PathHelper.GetWithBackslash(folderBrowser1.Folder) + txtFilename.Text; + } + } + + public int Segments + { + get + { + return (int)numSegments.Value; + } + } + + public bool StartNow + { + get + { + return chkStartNow.Checked; + } + } + + private void lvwLocations_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) + { + bool hasSelected = lvwLocations.SelectedItems.Count > 0; + btnRemove.Enabled = hasSelected; + if (hasSelected) + { + ListViewItem item = lvwLocations.SelectedItems[0]; + ResourceLocation[]rl=new ResourceLocation[1]; + rl[0]=MyDownloader.Core.ResourceLocation.FromURL( + item.SubItems[0].Text, BoolFormatter.FromString(item.SubItems[1].Text), item.SubItems[2].Text, item.SubItems[3].Text); + locationAlternate.ResourceLocation = rl; + } + else + { + locationAlternate.ResourceLocation = null; + } + } + + private void btnRemove_Click(object sender, EventArgs e) + { + for (int i = lvwLocations.Items.Count - 1; i >= 0; i--) + { + if (lvwLocations.Items[i].Selected) + { + lvwLocations.Items.RemoveAt(i); + } + } + } + + private void btnAdd_Click(object sender, EventArgs e) + { + foreach (ResourceLocation rl in locationAlternate.ResourceLocation) + AddLocation(rl); + } + + private void AddLocation(ResourceLocation rl) + { + if (lvwLocations.SelectedItems.Count > 0) + { + ListViewItem item = lvwLocations.SelectedItems[0]; + item.SubItems[0].Text = rl.URL; + item.SubItems[1].Text = BoolFormatter.ToString(rl.Authenticate); + item.SubItems[2].Text = rl.Login; + item.SubItems[3].Text = rl.Password; + } + else + { + ListViewItem item = new ListViewItem(); + item.Text = rl.URL; + item.SubItems.Add(BoolFormatter.ToString(rl.Authenticate)); + item.SubItems.Add(rl.Login); + item.SubItems.Add(rl.Password); + lvwLocations.Items.Add(item); + } + } + + private void btnOK_Click(object sender, EventArgs e) + { + foreach (ResourceLocation rl in this.DownloadLocation) + StartDownload(rl); + } + + private void StartDownload(ResourceLocation rl) + { + try + { + rl.BindProtocolProviderType(); + + if (rl.ProtocolProviderType == null) + { + MessageBox.Show("Invalid URL format, please check the location field.", + AppManager.Instance.Application.MainForm.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); + + DialogResult = DialogResult.None; + return; + } + + ResourceLocation[] mirrors = this.Mirrors; + + if (mirrors != null && mirrors.Length > 0) + { + foreach (ResourceLocation mirrorRl in mirrors) + { + mirrorRl.BindProtocolProviderType(); + + if (mirrorRl.ProtocolProviderType == null) + { + MessageBox.Show("Invalid mirror URL format, please check the mirror URLs.", + AppManager.Instance.Application.MainForm.Text, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + + DialogResult = DialogResult.None; + return; + } + } + } + + if (chkChooseZIP.Checked) + { + AddDownloadsFromZip(checkableTreeView1.Nodes, mirrors); + } + else + { + Downloader download = DownloadManager.Instance.Add( + rl, + mirrors, + this.LocalFile, + this.Segments, + this.StartNow); + } + + Close(); + } + catch (Exception) + { + DialogResult = DialogResult.None; + + MessageBox.Show("Unknow error, please check your input data.", + AppManager.Instance.Application.MainForm.Text, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + } + + + private void AddDownloadsFromZip(TreeNodeCollection nodes, ResourceLocation[] mirrors) + { + for (int i = 0; i < nodes.Count; i++) + { + if (nodes[i].Checked) + { + if (nodes[i].Nodes.Count > 0) + { + AddDownloadsFromZip(nodes[i].Nodes, mirrors); + } + else + { + //TODO:fix for multiple file download + ResourceLocation newLocation = this.DownloadLocation[0]; + newLocation.ProtocolProviderType = typeof(ZipProtocolProvider).AssemblyQualifiedName; + + string entryName = ((ZipEntry)nodes[i].Tag).Name; + + Downloader download = DownloadManager.Instance.Add( + newLocation, + mirrors, + this.folderBrowser1.Folder + entryName, + 1, + false); + + ZipProtocolProvider.SetZipEntryNameProperty(download, entryName); + + if (this.StartNow) + { + download.Start(); + } + } + } + } + } + + + private void btnCancel_Click(object sender, EventArgs e) + { + Close(); + } + + private void chkChooseZIP_CheckedChanged(object sender, EventArgs e) + { + ReleaseZIPThread(); + + ShowZIPMode(chkChooseZIP.Checked); + + if (chkChooseZIP.Checked) + { + LoadZIP(); + } + } + + private TreeNode GetNodeFromPath(String path, out string displayName) + { + string[] subPaths = path.Split('/'); + + if (subPaths.Length == 0) + { + displayName = null; + return null; + } + + TreeNode result = null; + + TreeNodeCollection nodes = checkableTreeView1.Nodes; + + displayName = subPaths[subPaths.Length - 1]; + + for (int j = 0; j < subPaths.Length - 1; j++) + { + TreeNode parentNode = null; + + for (int i = 0; i < nodes.Count; i++) + { + if (String.Equals(nodes[i].Text, subPaths[j], StringComparison.OrdinalIgnoreCase)) + { + parentNode = nodes[i]; + break; + } + } + + if (parentNode == null) + { + // add the path + result = new TreeNode(subPaths[j]); + result.ImageIndex = FileTypeImageList.GetImageIndexFromFolder(false); + result.SelectedImageIndex = FileTypeImageList.GetImageIndexFromFolder(true); + nodes.Add(result); + } + else + { + result = parentNode; + } + + nodes = result.Nodes; + } + + return result; + } + + private void ReleaseZIPThread() + { + if (zipReaderThread != null) + { + if (zipReaderThread.IsAlive) + { + zipReaderThread.Abort(); + zipReaderThread = null; + } + } + + waitControl1.Visible = false; + } + + private void LoadZIP() + { + checkableTreeView1.Nodes.Clear(); + + ResourceLocation rl = this.DownloadLocation[0]; + + rl.BindProtocolProviderType(); + + if (rl.ProtocolProviderType == null) + { + chkChooseZIP.Checked = false; + + MessageBox.Show("Invalid URL format, please check the location field.", + AppManager.Instance.Application.MainForm.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); + + return; + } + + ReleaseZIPThread(); + + zipReaderThread = new Thread( + delegate(object state) + { + ZipRemoteFile zipFile = new ZipRemoteFile((ResourceLocation)state); + + try + { + if (zipFile.Load()) + { + this.BeginInvoke((MethodInvoker)delegate() { DisplayZIPOnTree(zipFile); waitControl1.Visible = false; }); + } + else + { + this.BeginInvoke((MethodInvoker)delegate() + { + waitControl1.Visible = false; + + MessageBox.Show("Unable to load ZIP contents.", + AppManager.Instance.Application.MainForm.Text, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + }); + } + } + catch (Exception ex) + { + this.BeginInvoke((MethodInvoker)delegate() + { + waitControl1.Visible = false; + + MessageBox.Show("Unable to load ZIP contents: " + ex.Message, + AppManager.Instance.Application.MainForm.Text, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + }); + } + } + ); + + waitControl1.Visible = true; + zipReaderThread.Start(rl); + } + + private void DisplayZIPOnTree(ZipRemoteFile zipFile) + { + checkableTreeView1.ImageList = FileTypeImageList.GetSharedInstance(); + checkableTreeView1.Nodes.Clear(); + + foreach (ZipEntry entry in zipFile) + { + // skip folders... + if (entry.Name.EndsWith("/")) + { + continue; + } + + string displayName; + TreeNode parentNd = GetNodeFromPath(entry.Name, out displayName); + + TreeNode newNd = new TreeNode(displayName); + newNd.Tag = entry; + newNd.ImageIndex = FileTypeImageList.GetImageIndexByExtention(Path.GetExtension(entry.Name)); + newNd.SelectedImageIndex = newNd.ImageIndex; + + if (parentNd == null) + { + checkableTreeView1.Nodes.Add(newNd); + } + else + { + parentNd.Nodes.Add(newNd); + } + } + } + + private void ShowZIPMode(bool show) + { + if (show) + { + this.tableLayoutPanel1.Controls.Clear(); + //this.tableLayoutPanel1.Controls.Add(this.chkChooseZIP, 0, 0); + //this.tableLayoutPanel1.Controls.Add(this.checkableTreeView1, 0, 1); + //this.tableLayoutPanel1.Controls.Add(this.folderBrowser1, 0, 2); + //this.tableLayoutPanel1.Controls.Add(this.chkStartNow, 0, 3); + //this.tableLayoutPanel1.Controls.Add(this.pnlSegments, 0, 4); + + this.tableLayoutPanel1.Controls.Add(this.chkChooseZIP); + this.tableLayoutPanel1.Controls.Add(this.checkableTreeView1); + this.tableLayoutPanel1.Controls.Add(this.folderBrowser1); + this.tableLayoutPanel1.Controls.Add(this.chkStartNow); + this.tableLayoutPanel1.Controls.Add(this.pnlSegments); + + //this.tableLayoutPanel1.RowCount = 5; + this.tableLayoutPanel1.AutoSize = true; + this.Height = 600; + + /* this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());*/ + } + else + { + this.tableLayoutPanel1.Controls.Clear(); + //this.tableLayoutPanel1.Controls.Add(this.chkChooseZIP, 0, 0); + //this.tableLayoutPanel1.Controls.Add(this.pnlFileName, 0, 1); + //this.tableLayoutPanel1.Controls.Add(this.folderBrowser1, 0, 2); + //this.tableLayoutPanel1.Controls.Add(this.chkStartNow, 0, 3); + //this.tableLayoutPanel1.Controls.Add(this.pnlSegments, 0, 4); + + this.tableLayoutPanel1.Controls.Add(this.chkChooseZIP); + this.tableLayoutPanel1.Controls.Add(this.pnlFileName); + this.tableLayoutPanel1.Controls.Add(this.folderBrowser1); + this.tableLayoutPanel1.Controls.Add(this.chkStartNow); + this.tableLayoutPanel1.Controls.Add(this.pnlSegments); + + //this.tableLayoutPanel1.RowCount = 5; + this.tableLayoutPanel1.AutoSize = true; + this.Height = 444; + + /* this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());*/ + } + } + + private void NewDownloadForm_FormClosing(object sender, FormClosingEventArgs e) + { + this.ReleaseZIPThread(); + } + + private void NewDownloadForm_Load(object sender, EventArgs e) + { + + } + + private void txtFilename_TextChanged(object sender, EventArgs e) + { + + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/NewDownloadForm.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/NewDownloadForm.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 59 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/OptionsForm.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/OptionsForm.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,110 @@ +namespace MyDownloader.App.UI +{ + partial class OptionsForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.treeOptions = new System.Windows.Forms.TreeView(); + this.pnlExtension = new System.Windows.Forms.Panel(); + this.btnCancel = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // treeOptions + // + this.treeOptions.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.treeOptions.Location = new System.Drawing.Point(13, 13); + this.treeOptions.Name = "treeOptions"; + this.treeOptions.Size = new System.Drawing.Size(150, 417); + this.treeOptions.TabIndex = 0; + this.treeOptions.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeOptions_AfterSelect); + // + // pnlExtension + // + this.pnlExtension.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pnlExtension.Location = new System.Drawing.Point(175, 16); + this.pnlExtension.Name = "pnlExtension"; + this.pnlExtension.Size = new System.Drawing.Size(453, 414); + this.pnlExtension.TabIndex = 1; + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(553, 436); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 3; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.Location = new System.Drawing.Point(472, 436); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 2; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // OptionsForm + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(640, 469); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.pnlExtension); + this.Controls.Add(this.treeOptions); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "OptionsForm"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Options"; + this.Load += new System.EventHandler(this.OptionsForm_Load); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TreeView treeOptions; + private System.Windows.Forms.Panel pnlExtension; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnOK; + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/OptionsForm.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/OptionsForm.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using MyDownloader.Core.Extensions; + +namespace MyDownloader.App.UI +{ + public partial class OptionsForm : Form + { + delegate void ProcessItemDelegate(IExtension extension, Control[] options); + + public OptionsForm() + { + InitializeComponent(); + } + + private void OptionsForm_Load(object sender, EventArgs e) + { + try + { + treeOptions.BeginUpdate(); + + for (int i = 0; i < App.Instance.Extensions.Count; i++) + { + IExtension extension = App.Instance.Extensions[i]; + IUIExtension uiExtension = extension.UIExtension; + + if (uiExtension == null) + { + continue; + } + + Control[] options = uiExtension.CreateSettingsView(); + + if (options == null || options.Length == 0) + { + continue; + } + + TreeNode node = new TreeNode(extension.Name); + node.Tag = extension; + + for (int j = 0; j < options.Length; j++) + { + TreeNode optioNd = new TreeNode(options[j].Text); + optioNd.Tag = options[j]; + node.Nodes.Add(optioNd); + } + + node.Expand(); + + treeOptions.Nodes.Add(node); + } + } + finally + { + treeOptions.EndUpdate(); + } + } + + private void ProcessSettings(ProcessItemDelegate process) + { + for (int i = 0; i < treeOptions.Nodes.Count; i++) + { + TreeNode node = treeOptions.Nodes[i]; + IExtension extension = (IExtension)node.Tag; + Control[] options = new Control[node.Nodes.Count]; + for (int j = 0; j < node.Nodes.Count; j++) + { + options[j] = (Control)node.Nodes[j].Tag; + } + + process(extension, options); + } + + treeOptions.Nodes.Clear(); + } + + private void treeOptions_AfterSelect(object sender, TreeViewEventArgs e) + { + pnlExtension.Controls.Clear(); + + if (e.Node.Parent != null) + { + ShowOptionFromNode(e.Node); + } + else + { + ShowOptionFromNode(e.Node.Nodes[0]); + } + } + + private void ShowOptionFromNode(TreeNode node) + { + Control ctrl = (Control)node.Tag; + ctrl.Visible = true; + ctrl.Dock = DockStyle.Fill; + pnlExtension.Controls.Add(ctrl); + } + + private void btnOK_Click(object sender, EventArgs e) + { + ProcessSettings( + delegate(IExtension extension, Control[] options) + { + extension.UIExtension.PersistSettings(options); + + for (int i = 0; i < options.Length; i++) + { + options[i].Dispose(); + } + } + ); + + DialogResult = DialogResult.OK; + } + + private void btnCancel_Click(object sender, EventArgs e) + { + ProcessSettings( + delegate(IExtension extension, Control[] options) + { + for (int i = 0; i < options.Length; i++) + { + options[i].Dispose(); + } + } + ); + + DialogResult = DialogResult.Cancel; + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/UI/OptionsForm.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/UI/OptionsForm.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/bin/Release/License.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/bin/Release/License.txt Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,64 @@ +.Net Download Manager is Licensed under the Apache Version 2.0. + +DNDM also uses the following projects from other developers: +* A command line parser licensed under the MS-PL. +* A ini parser licensed under MIT + + +Apache License 2.0 + +Copyright [2012] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +Microsoft Public License (Ms-PL) + +This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. + +1. Definitions + +The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. + +A "contribution" is the original software, or any additions or changes to the software. + +A "contributor" is any person that distributes its contribution under this license. + +"Licensed patents" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights + +(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. + +(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. + +3. Conditions and Limitations + +(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. + +(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. + +(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. + +(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. + +(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. + + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.App/bin/Release/readme.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.App/bin/Release/readme.txt Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,25 @@ +.Net Download Manager (DNDM) is a fork of MyDownloader + +Original Google code link = http://code.google.com/p/mydownloader/ +Original Codeproject link = http://www.codeproject.com/Articles/21053/MyDownloader-A-Multi-thread-C-Segmented-Download-M + +I contacted the author for special permission to fork under the Apache license instead of GPL. + +Some of the features I have included in this forked release: ++ Fixed support for FTP +(The application would crash if you didn't give it a file name when downloading from FTP) ++ Fixed up the parameter support so you can add downloads via the command line +(This was needed for the following Chrome extension - https://chrome.google.com/webstore/detail/downloaders/lfjamigppmepikjlacjdpgjaiojdjhoj - I'm sure an extension exists for Firefox as well where you can use a custom download manager. See the wiki for more information on intergration.) ++ Upgraded to VS2010/.Net 3.5 ++ Create an installer ++ Fixed cookie support +(Microsoft randomizes the cookie file names now) ++ Added cookie support for Chrome and Firefox (this can be changed in settings) + +I highly recommend you check out his original project as it is freaking awesome. You will see "MyDownloader" tags all over this application - the reason is very simple - Guilherme Labigalini deserves most of the credit as all I did was merely added/updated some code and created the installer. + +I do want to note a couple of things: ++ This fork's source will always be available ++ The installer that I create will NEVER contain toolbars/greyware/malware (unlike other download managers) ++ Please do not contact Guilherme with questions about DNDM - those should be directed to me adamsna[at]datanethost.net . Questions about MyDownloader should be directed to him, but I should be able to answer some. ++ Please do contact me with bugs/issues - while I can't make any promises at least they can be recorded. \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/CalculatedSegment.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/CalculatedSegment.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Core +{ + [Serializable] + public struct CalculatedSegment + { + private long startPosition; + private long endPosition; + + public long StartPosition + { + get { return startPosition; } + set { startPosition = value; } + } + + public long EndPosition + { + get { return endPosition; } + set { endPosition = value; } + } + + public CalculatedSegment(long startPos, long endPos) + { + this.endPosition = endPos; + this.startPosition = startPos; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Common/ArrayExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Common/ArrayExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Core.Common +{ + public static class ArrayExtension + { + public static int indexOf(this byte[] haystack, byte[] needle) + { + //int ret = -1; + // pos = index of needle 1 + // if pos is not -1 + // check next char + //Object[] tmphay = (object[])haystack; + //Object[] tmpneedle = (object[])needle; + + int pos = -1; + bool found = false; + pos = Array.IndexOf(haystack, needle[0]); + if (needle.Length == 1) + return pos; + while (pos != -1 && !found) + { + if (pos != -1) + { + for (int i = 1; i < needle.Length; i++) + { + if (haystack[pos + i] != needle[i]) + { + found = false; + break; + } + found = true; + } + } + if (found) + break; + pos = Array.IndexOf(haystack, needle[0], pos + 1); + } + return pos; + } + + public static byte[] sub(this byte[] arr, int start, int end) + { + byte[] ret = new byte[end - start]; + for (int i = start; i < end; i++) + { + ret[i - start] = arr[i]; + } + return ret; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Common/BoolFormatter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Common/BoolFormatter.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Core.Common +{ + public static class BoolFormatter + { + private const string Yes = "Yes"; + private const string No = "No"; + + public static bool FromString(string s) + { + if (s == Yes) return true; + return false; + } + + public static string ToString(bool v) + { + if (v) return Yes; + return No; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Common/ByteFormatter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Common/ByteFormatter.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Core.Common +{ + public static class ByteFormatter + { + private const long KB = 1024; + private const long MB = KB * 1024; + private const long GB = MB * 1024; + + private const string BFormatPattern = "{0} b"; + private const string KBFormatPattern = "{0:0} KB"; + private const string MBFormatPattern = "{0:0,###} MB"; + private const string GBFormatPattern = "{0:0,###.###} GB"; + + public static string ToString(long size) + { + if (size < KB) + { + return String.Format(BFormatPattern, size); + } + else if (size >= KB && size < MB) + { + return String.Format(KBFormatPattern, size / 1024.0f); + } + else if (size >= MB && size < GB) + { + return String.Format(MBFormatPattern, size / 1024.0f); + } + else // size >= GB + { + return String.Format(GBFormatPattern, size / 1024.0f); + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Common/CookieManager.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Common/CookieManager.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,245 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Net; +using System.Runtime.InteropServices; +using System.IO; +using System.Data; +using IniParser; +using IniParser.Model; + +namespace MyDownloader.Core.Common +{ + public class CookieManager + { + // Cookies are now randomized in IE - http://blogs.msdn.com/b/ieinternals/archive/2011/08/12/internet-explorer-9.0.2-update-changes-file-protocol-and-cookie-naming.aspx + + public class CookieStruct + { + //1 The Variable Name + //2 The Value for the Variable + //3 The Website of the Cookie’s Owner + //4 Optional Flags + //5 The Most Significant Integer for Expired Time, in FILETIME Format + //6 The Least Significant Integer for Expired Time, in FILETIME Format + //7 The Most Significant Integer for Creation Time, in FILETIME Format + //8 The Least Significant Integer for Creation Time, in FILETIME Format + //9 The Cookie Record Delimiter (a * character) + public string VarName; + public string VarValue; + public string Domain; + public int Flags; + public DateTime ExpirationDate; + public DateTime CreationDate; + } + public static CookieCollection GetCookieCollection(string url) + { + CookieCollection ret = new CookieCollection(); + Uri location = new Uri(url); + + if (Settings.Default.CookieSource == "Internet Explorer") + { + BinaryReader br = new BinaryReader(File.Open(Environment.GetFolderPath(Environment.SpecialFolder.Cookies) + "/Low/index.dat", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); + byte[] indexfile = br.ReadBytes((int)br.BaseStream.Length); + br.Close(); + int loc = 0; + int locfile = 0; + int endlocfile = 0; + byte[] domainfind = Encoding.Default.GetBytes(location.Host.Replace("www.", "")); + loc = indexfile.indexOf(domainfind); + byte[] bfile; + if (loc != -1) + { + locfile = Array.IndexOf(indexfile, (byte)0xDE, loc); + endlocfile = Array.IndexOf(indexfile, (byte)0x2E, locfile); + bfile = indexfile.sub(locfile + 1, endlocfile); + CookieStruct[] cs = ReadCookie(Environment.GetFolderPath(Environment.SpecialFolder.Cookies) + "/Low/" + Encoding.Default.GetString(bfile) + ".txt"); + foreach (CookieStruct c in cs) + { + Cookie nc = new Cookie(c.VarName.Trim(), c.VarValue.Trim()); + nc.Expires = c.ExpirationDate; + nc.Domain = c.Domain; + ret.Add(nc); + } + } + } + else if (Settings.Default.CookieSource == "Chrome") + { + string chromepath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\Google\Chrome\User Data\Default"; + //string cookie = chromepath + @"\Cookies"; + if (!File.Exists(chromepath + @"\Cookies")) + { + throw new Exception("Could not find Chrome cookie file!"); + } + if (File.Exists(chromepath + @"\Cookies.dndm")) + { + File.Delete(chromepath + @"\Cookies.dndm"); + } + + // We have to copy the cookies SQLite file because Chrome locks it + File.Copy(chromepath + @"\Cookies", chromepath + @"\Cookies.dndm", true); + + SQLiteDatabase db = new SQLiteDatabase(chromepath + @"\Cookies.dndm"); + + DataTable cookietable = db.GetDataTable(String.Format("SELECT * FROM cookies where host_key = \"{0}\" or host_key = \"{1}\" or host_key = \"{2}\" or host_key = \"{3}\"", location.Host, location.Host, location.Host.Replace("www.", ""), "." + location.Host)); + if (cookietable.Rows.Count > 0) + { + foreach(DataRow dr in cookietable.Rows) + { + Cookie nc = new Cookie(dr["name"].ToString().Trim(), dr["value"].ToString().Trim()); + nc.Expires = DateTimeExtension.FromUnixTime((Double.Parse(dr["expires_utc"].ToString()) / 1000000) - 11644473600); + nc.Domain = dr["host_key"].ToString(); + ret.Add(nc); + } + } + + File.Delete(chromepath + @"\Cookies.dndm"); + + } + else if (Settings.Default.CookieSource == "Firefox") + { + //Get default folder + string firefoxpath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\..\Roaming\Mozilla\Firefox"; + firefoxpath = Path.GetFullPath(firefoxpath); + string profilesini = firefoxpath + @"\profiles.ini"; + FileIniDataParser iniparser = new FileIniDataParser(); + IniData inifile = iniparser.ReadFile(profilesini); + string profilefolder = inifile["Profile0"]["Path"]; + string userfolder = firefoxpath + @"\" + profilefolder; + + string ffbookmarks = userfolder + @"\cookies.sqlite"; + string tmpffbook = userfolder + @"\cookies.dndm"; + File.Copy(ffbookmarks, tmpffbook, true); + + SQLiteDatabase db = new SQLiteDatabase(Path.GetFullPath(tmpffbook)); + DataTable cookietable = db.GetDataTable(String.Format("SELECT * FROM moz_cookies where host = \"{0}\" or host = \"{1}\" or host = \"{2}\" or host = \"{3}\"", location.Host, location.Host, location.Host.Replace("www.", ""), "." + location.Host)); + if (cookietable.Rows.Count > 0) + { + foreach (DataRow dr in cookietable.Rows) + { + Cookie nc = new Cookie(dr["name"].ToString(), dr["value"].ToString()); + nc.Expires = DateTimeExtension.FromUnixTime(Double.Parse(dr["expiry"].ToString())); + nc.Domain = dr["host"].ToString(); + ret.Add(nc); + } + } + File.Delete(tmpffbook); + } + + // Old way of finding cookies - no longer works due to IE randomization of cookie file names + /*FileInfo[] fis = SearchCookies(Domain); + foreach (FileInfo fi in fis) + { + CookieStruct[] cs = ReadCookie(fi.FullName); + foreach(CookieStruct c in cs) + if (baseUrl.EndsWith(c.Domain) && c.ExpirationDate > DateTime.Now) + { + Cookie nc = new Cookie(c.VarName, c.VarValue); + nc.Expires = c.ExpirationDate; + nc.Domain = c.Domain; + ret.Add(nc); + } + }*/ + + + return ret; + } + + private static FileInfo[] SearchCookies(string Domain) + { + string path = Environment.GetFolderPath(Environment.SpecialFolder.Cookies); + DirectoryInfo di = new DirectoryInfo(path); + FileInfo[] fis = di.GetFiles(string.Format("*@{0}[*.txt", Domain)); + di = new DirectoryInfo(path + "//Low"); + if (di.Exists) + { + FileInfo[] fisLow = di.GetFiles(string.Format("*@{0}[*.txt", Domain)); + FileInfo[] ret = new FileInfo[fis.Length + fisLow.Length]; + fis.CopyTo(ret, 0); + fisLow.CopyTo(ret, fis.Length); + return ret; + } + else + return fis; + } + + private static CookieStruct[] ReadCookie(string fn) + { + StreamReader sr = new StreamReader(fn); + string cookie = sr.ReadToEnd(); + sr.Close(); + string[] data=cookie.Split('\n'); + int cookieNum = data.Length / 9; + CookieStruct[] ret = new CookieStruct[cookieNum]; + for (int i = 0; i < cookieNum; i++) + { + int bline = i * 9; + ret[i] = new CookieStruct(); + ret[i].VarName = data[bline]; + ret[i].VarValue = data[bline+1]; + ret[i].Domain = data[bline + 2]; + ret[i].Flags = Convert.ToInt32(data[bline + 3]); + long l = Convert.ToInt64(data[bline + 4]); + l += Convert.ToInt64(data[bline + 5]) << 32; + ret[i].ExpirationDate = DateTime.FromFileTime(l); + l = Convert.ToInt64(data[bline + 6]); + l += Convert.ToInt64(data[bline + 7]) << 32; + ret[i].CreationDate = DateTime.FromFileTime(l); + } + return ret; + } + + //[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)] + //static extern bool InternetGetCookie(string lpszUrlName, string lpszCookieName, [Out] StringBuilder lpszCookieData, [MarshalAs(UnmanagedType.U4)] ref int lpdwSize); + //[DllImport("wininet.dll", EntryPoint = "InternetSetCookie", ExactSpelling = false, CharSet = CharSet.Unicode, SetLastError = true)] + //static extern bool InternetSetCookie(string url, string cookieName, string cookieData); + + //const int ERROR_NO_MORE_ITEMS = 259; + //const int ERROR_INSUFFICIENT_BUFFER = 122; + //const int ERROR_INVALID_PARAMETER = 87; + //const int INTERNET_COOKIE_HTTPONLY = 0x00002000; + + + //public static void SetCookie(string siteUrl, string cookieName, string cookieData) + //{ + // if (!InternetSetCookie(siteUrl, cookieName, cookieData)) + // { + // throw new Exception("Exception setting cookie: Win32 Error code=" + Marshal.GetLastWin32Error()); + // } + //} + + + + /*public static CookieContainer GetUriCookieContainer(string uri) + { + CookieContainer cookies = null; + + // Determine the size of the cookie + int datasize = 256; + StringBuilder cookieData = new StringBuilder(datasize); + + if (!InternetGetCookieEx(uri, null, cookieData, ref datasize, INTERNET_COOKIE_HTTPONLY, null)) + { + int er = Marshal.GetLastWin32Error(); + if (er == ERROR_NO_MORE_ITEMS) + return new CookieContainer(); + else + if (er == ERROR_INSUFFICIENT_BUFFER) + { + cookieData = new StringBuilder(datasize); + if (!InternetGetCookie(uri, null, cookieData, ref datasize)) + return new CookieContainer(); + } + else + if (er == ERROR_INVALID_PARAMETER) + throw new Exception("InternetGetCookie: Invalid Parameter submitted."); + else + throw new Exception(String.Format("InternetGetCookie: Error. (Error Code: {0})", er)); + + } + cookies = new CookieContainer(); + cookies.SetCookies(new Uri(uri), cookieData.ToString().Replace(';', ',')); + return cookies; + }*/ + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Common/DateTimeExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Common/DateTimeExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace MyDownloader.Core.Common +{ + public static class DateTimeExtension + { + public static int ToUnixTime(this DateTime time) + { + TimeSpan span = (time - new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime()); + return (int)span.TotalSeconds; + } + + public static DateTime FromUnixTime(double timestamp) + { + DateTime converted = new DateTime(1970, 1, 1, 0, 0, 0, 0); + DateTime newDateTime = converted.AddSeconds(timestamp); + return newDateTime.ToUniversalTime(); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Common/PathHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Common/PathHelper.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace MyDownloader.Core.Common +{ + public static class PathHelper + { + public static string GetWithBackslash(string path) + { + if (!path.EndsWith(Path.DirectorySeparatorChar.ToString())) + { + path += Path.DirectorySeparatorChar.ToString(); + } + + return path; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Common/SQLiteDatabase.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Common/SQLiteDatabase.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,232 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SQLite; +using System.Windows.Forms; + + +// Copied library from http://www.dreamincode.net/forums/topic/157830-using-sqlite-with-c%23/ +namespace MyDownloader.Core.Common +{ + class SQLiteDatabase + { + String dbConnection; + + /// + /// Default Constructor for SQLiteDatabase Class. + /// + public SQLiteDatabase() + { + dbConnection = "Data Source=recipes.s3db"; + } + + /// + /// Single Param Constructor for specifying the DB file. + /// + /// The File containing the DB + public SQLiteDatabase(String inputFile) + { + dbConnection = String.Format("Data Source={0}", inputFile); + } + + /// + /// Single Param Constructor for specifying advanced connection options. + /// + /// A dictionary containing all desired options and their values + public SQLiteDatabase(Dictionary connectionOpts) + { + String str = ""; + foreach (KeyValuePair row in connectionOpts) + { + str += String.Format("{0}={1}; ", row.Key, row.Value); + } + str = str.Trim().Substring(0, str.Length - 1); + dbConnection = str; + } + + /// + /// Allows the programmer to run a query against the Database. + /// + /// The SQL to run + /// A DataTable containing the result set. + public DataTable GetDataTable(string sql) + { + DataTable dt = new DataTable(); + try + { + SQLiteConnection cnn = new SQLiteConnection(dbConnection); + cnn.Open(); + SQLiteCommand mycommand = new SQLiteCommand(cnn); + mycommand.CommandText = sql; + SQLiteDataReader reader = mycommand.ExecuteReader(); + dt.Load(reader); + reader.Close(); + mycommand.Dispose(); + cnn.Close(); + } + catch (Exception e) + { + throw new Exception(e.Message); + } + return dt; + } + + /// + /// Allows the programmer to interact with the database for purposes other than a query. + /// + /// The SQL to be run. + /// An Integer containing the number of rows updated. + public int ExecuteNonQuery(string sql) + { + SQLiteConnection cnn = new SQLiteConnection(dbConnection); + cnn.Open(); + SQLiteCommand mycommand = new SQLiteCommand(cnn); + mycommand.CommandText = sql; + int rowsUpdated = mycommand.ExecuteNonQuery(); + cnn.Close(); + return rowsUpdated; + } + + /// + /// Allows the programmer to retrieve single items from the DB. + /// + /// The query to run. + /// A string. + public string ExecuteScalar(string sql) + { + SQLiteConnection cnn = new SQLiteConnection(dbConnection); + cnn.Open(); + SQLiteCommand mycommand = new SQLiteCommand(cnn); + mycommand.CommandText = sql; + object value = mycommand.ExecuteScalar(); + cnn.Close(); + if (value != null) + { + return value.ToString(); + } + return ""; + } + + /// + /// Allows the programmer to easily update rows in the DB. + /// + /// The table to update. + /// A dictionary containing Column names and their new values. + /// The where clause for the update statement. + /// A boolean true or false to signify success or failure. + public bool Update(String tableName, Dictionary data, String where) + { + String vals = ""; + Boolean returnCode = true; + if (data.Count >= 1) + { + foreach (KeyValuePair val in data) + { + vals += String.Format(" {0} = '{1}',", val.Key.ToString(), val.Value.ToString()); + } + vals = vals.Substring(0, vals.Length - 1); + } + try + { + this.ExecuteNonQuery(String.Format("update {0} set {1} where {2};", tableName, vals, where)); + } + catch + { + returnCode = false; + } + return returnCode; + } + + /// + /// Allows the programmer to easily delete rows from the DB. + /// + /// The table from which to delete. + /// The where clause for the delete. + /// A boolean true or false to signify success or failure. + public bool Delete(String tableName, String where) + { + Boolean returnCode = true; + try + { + this.ExecuteNonQuery(String.Format("delete from {0} where {1};", tableName, where)); + } + catch (Exception fail) + { + MessageBox.Show(fail.Message); + returnCode = false; + } + return returnCode; + } + + /// + /// Allows the programmer to easily insert into the DB + /// + /// The table into which we insert the data. + /// A dictionary containing the column names and data for the insert. + /// A boolean true or false to signify success or failure. + public bool Insert(String tableName, Dictionary data) + { + String columns = ""; + String values = ""; + Boolean returnCode = true; + foreach (KeyValuePair val in data) + { + columns += String.Format(" {0},", val.Key.ToString()); + values += String.Format(" '{0}',", val.Value); + } + columns = columns.Substring(0, columns.Length - 1); + values = values.Substring(0, values.Length - 1); + try + { + this.ExecuteNonQuery(String.Format("insert into {0}({1}) values({2});", tableName, columns, values)); + } + catch (Exception fail) + { + MessageBox.Show(fail.Message); + returnCode = false; + } + return returnCode; + } + + /// + /// Allows the programmer to easily delete all data from the DB. + /// + /// A boolean true or false to signify success or failure. + public bool ClearDB() + { + DataTable tables; + try + { + tables = this.GetDataTable("select NAME from SQLITE_MASTER where type='table' order by NAME;"); + foreach (DataRow table in tables.Rows) + { + this.ClearTable(table["NAME"].ToString()); + } + return true; + } + catch + { + return false; + } + } + + /// + /// Allows the user to easily clear all data from a specific table. + /// + /// The name of the table to clear. + /// A boolean true or false to signify success or failure. + public bool ClearTable(String table) + { + try + { + + this.ExecuteNonQuery(String.Format("delete from {0};", table)); + return true; + } + catch + { + return false; + } + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Common/TimeSpanFormatter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Common/TimeSpanFormatter.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Core.Common +{ + public static class TimeSpanFormatter + { + public static string ToString(TimeSpan ts) + { + if (ts == TimeSpan.MaxValue) + { + return "?"; + } + + string str = ts.ToString(); + int index = str.LastIndexOf('.'); + if (index > 0) + { + return str.Remove(index); + } + else + { + return str; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Concurrency/ObjectLocker.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Concurrency/ObjectLocker.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace MyDownloader.Core.Concurrency +{ + public class ObjectLocker : IDisposable + { + #region Fields + + private object obj; + + #endregion + + #region Constructor + + public ObjectLocker(object obj) + { + this.obj = obj; + Monitor.Enter(this.obj); + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + Monitor.Exit(this.obj); + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Concurrency/ReaderWriterObjectLocker.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Concurrency/ReaderWriterObjectLocker.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace MyDownloader.Core.Concurrency +{ + public class ReaderWriterObjectLocker + { + #region BaseReleaser + class BaseReleaser + { + protected ReaderWriterObjectLocker locker; + + public BaseReleaser(ReaderWriterObjectLocker locker) + { + this.locker = locker; + } + } + #endregion + + #region ReaderReleaser + class ReaderReleaser : BaseReleaser, IDisposable + { + public ReaderReleaser(ReaderWriterObjectLocker locker) + : base(locker) + { + } + + #region IDisposable Members + + public void Dispose() + { + locker.locker.ReleaseReaderLock(); + } + + #endregion + } + #endregion + + #region WriterReleaser + class WriterReleaser : BaseReleaser, IDisposable + { + public WriterReleaser(ReaderWriterObjectLocker locker) + : base(locker) + { + } + + #region IDisposable Members + + public void Dispose() + { + locker.locker.ReleaseWriterLock(); + } + + #endregion + } + #endregion + + #region Fields + private ReaderWriterLock locker; + private IDisposable writerReleaser; + private IDisposable readerReleaser; + #endregion + + #region Constructor + public ReaderWriterObjectLocker() + { + // TODO: update to ReaderWriterLockSlim on .net 3.5 + locker = new ReaderWriterLock(); + + writerReleaser = new WriterReleaser(this); + readerReleaser = new ReaderReleaser(this); + } + #endregion + + #region Methods + public IDisposable LockForRead() + { + locker.AcquireReaderLock(-1); + + return readerReleaser; + } + + public IDisposable LockForWrite() + { + locker.AcquireWriterLock(-1); + + return writerReleaser; + } + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/DownloadManager.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/DownloadManager.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,299 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections.ObjectModel; +using System.Collections; +using System.Threading; +using MyDownloader.Core.Concurrency; + +namespace MyDownloader.Core +{ + public class DownloadManager + { + #region Singleton + + private static DownloadManager instance = new DownloadManager(); + + public static DownloadManager Instance + { + get + { + return instance; + } + } + + #endregion + + #region Fields + + private List downloads = new List(); + private int addBatchCount; + private ReaderWriterObjectLocker downloadListSync = new ReaderWriterObjectLocker(); + private int maxSimultaneusDownloads = 10; + + #endregion + + #region Properties + + public event EventHandler BeginAddBatchDownloads; + + public event EventHandler EndAddBatchDownloads; + + public event EventHandler DownloadEnded; + + public event EventHandler DownloadAdded; + + public event EventHandler DownloadRemoved; + + public ReadOnlyCollection Downloads + { + get + { + return downloads.AsReadOnly(); + } + } + + public double TotalDownloadRate + { + get + { + double total = 0; + + using (LockDownloadList(false)) + { + for (int i = 0; i < this.Downloads.Count; i++) + { + if (this.Downloads[i].State == DownloaderState.Working) + { + total += this.Downloads[i].Rate; + } + } + } + + return total; + } + } + + public int AddBatchCount + { + get + { + return addBatchCount; + } + } + + #endregion + + #region Methods + + void downloader_StateChanged(object sender, EventArgs e) + { + Downloader downloader = (Downloader)sender; + + if (downloader.State == DownloaderState.Ended || + downloader.State == DownloaderState.EndedWithError) + { + OnDownloadEnded((Downloader)sender); + } + } + + public IDisposable LockDownloadList(bool lockForWrite) + { + if (lockForWrite) + { + return downloadListSync.LockForWrite(); + } + else + { + return downloadListSync.LockForRead(); + } + } + + public void RemoveDownload(int index) + { + RemoveDownload(downloads[index]); + } + + public void RemoveDownload(Downloader downloader) + { + if (downloader.State != DownloaderState.NeedToPrepare || + downloader.State != DownloaderState.Ended || + downloader.State != DownloaderState.Paused) + { + downloader.Pause(); + } + + using (LockDownloadList(true)) + { + downloads.Remove(downloader); + } + + OnDownloadRemoved(downloader); + } + + public void ClearEnded() + { + using (LockDownloadList(true)) + { + for (int i = downloads.Count - 1; i >= 0; i--) + { + if (downloads[i].State == DownloaderState.Ended) + { + Downloader d = downloads[i]; + downloads.RemoveAt(i); + OnDownloadRemoved(d); + } + } + } + } + + public void PauseAll() + { + using (LockDownloadList(false)) + { + for (int i = 0; i < this.Downloads.Count; i++) + { + this.Downloads[i].Pause(); + } + } + } + + public Downloader Add(ResourceLocation rl, ResourceLocation[] mirrors, string localFile, int segments, bool autoStart) + { + Downloader d = new Downloader(rl, mirrors, localFile, segments); + Add(d, autoStart); + + return d; + } + + public Downloader Add(ResourceLocation rl, ResourceLocation[] mirrors, string localFile, List segments, RemoteFileInfo remoteInfo, int requestedSegmentCount, bool autoStart, DateTime createdDateTime) + { + Downloader d = new Downloader(rl, mirrors, localFile, segments, remoteInfo, requestedSegmentCount, createdDateTime); + Add(d, autoStart); + + return d; + } + + public void Add(Downloader downloader, bool autoStart) + { + downloader.StateChanged += new EventHandler(downloader_StateChanged); + + using (LockDownloadList(true)) + { + downloads.Add(downloader); + } + + OnDownloadAdded(downloader, autoStart); + + if (autoStart) + downloader.ScheduleState = DownloaderScheduleState.Waiting; + else + downloader.ScheduleState = DownloaderScheduleState.Paused; + //if (autoStart) + //{ + // downloader.Start(); + //} + StartNextDownload(); + } + + public void StartNextDownload() + { + int cnt = 0; + foreach (Downloader d in downloads) + if (d.ScheduleState == DownloaderScheduleState.Working) + cnt++; + if(cnt>=maxSimultaneusDownloads) + return; + foreach (Downloader d in downloads) + { + if (d.ScheduleState == DownloaderScheduleState.Waiting) + { + d.Start(); + Thread.Sleep(500); + return; + } + } + } + + public virtual void OnBeginAddBatchDownloads() + { + addBatchCount++; + + if (BeginAddBatchDownloads != null) + { + BeginAddBatchDownloads(this, EventArgs.Empty); + } + } + + public virtual void OnEndAddBatchDownloads() + { + addBatchCount--; + + if (EndAddBatchDownloads != null) + { + EndAddBatchDownloads(this, EventArgs.Empty); + } + } + + protected virtual void OnDownloadEnded(Downloader d) + { + StartNextDownload(); + if (DownloadEnded != null) + { + DownloadEnded(this, new DownloaderEventArgs(d)); + } + } + + protected virtual void OnDownloadAdded(Downloader d, bool willStart) + { + if (DownloadAdded != null) + { + DownloadAdded(this, new DownloaderEventArgs(d, willStart)); + } + } + + protected virtual void OnDownloadRemoved(Downloader d) + { + if (DownloadRemoved != null) + { + DownloadRemoved(this, new DownloaderEventArgs(d)); + } + } + + public void SwapDownloads(int idx, bool isThreadSafe) + { + if (isThreadSafe) + { + InternalSwap(idx); + } + else + { + using (LockDownloadList(true)) + { + InternalSwap(idx); + } + } + } + + private void InternalSwap(int idx) + { + if (this.downloads.Count <= idx) + { + //return; + } + + Downloader it1 = this.downloads[idx]; + Downloader it2 = this.downloads[idx - 1]; + + this.downloads.RemoveAt(idx); + this.downloads.RemoveAt(idx - 1); + + this.downloads.Insert(idx - 1, it1); + this.downloads.Insert(idx, it2); + } + + #endregion + + + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Downloader.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Downloader.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,1036 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Threading; +using System.Diagnostics; +using System.Collections; +using System.Net; +using MyDownloader.Core.Concurrency; +using MyDownloader.Core.Common; + +namespace MyDownloader.Core +{ + public class Downloader + { + private string localFile; + private int requestedSegmentCount; + private ResourceLocation resourceLocation; + private List mirrors; + private List segments; + private Thread mainThread; + private List threads; + private RemoteFileInfo remoteFileInfo; + private DownloaderState state; + public DownloaderScheduleState ScheduleState; + private DateTime createdDateTime; + private Exception lastError; + private Dictionary extentedProperties = new Dictionary(); + + private IProtocolProvider defaultDownloadProvider; + private ISegmentCalculator segmentCalculator; + private IMirrorSelector mirrorSelector; + + //private CookieContainer cookieContainer; + + private string statusMessage; + + private Downloader( + ResourceLocation rl, + ResourceLocation[] mirrors, + string localFile) + { + //this.cookieContainer = new CookieContainer(); + this.threads = new List(); + this.resourceLocation = rl; + if (mirrors == null) + { + this.mirrors = new List(); + } + else + { + this.mirrors = new List(mirrors); + } + this.localFile = localFile; + + extentedProperties = new Dictionary(); + + defaultDownloadProvider = rl.BindProtocolProviderInstance(this); + + segmentCalculator = new MinSizeSegmentCalculator(); + this.MirrorSelector = new SequentialMirrorSelector(); + } + + public Downloader( + ResourceLocation rl, + ResourceLocation[] mirrors, + string localFile, + int segmentCount): + this(rl, mirrors, localFile) + { + SetState(DownloaderState.NeedToPrepare); + + this.createdDateTime = DateTime.Now; + this.requestedSegmentCount = segmentCount; + this.segments = new List(); + } + + public Downloader( + ResourceLocation rl, + ResourceLocation[] mirrors, + string localFile, + List segments, + RemoteFileInfo remoteInfo, + int requestedSegmentCount, + DateTime createdDateTime): + this(rl, mirrors, localFile) + { + if (segments.Count > 0) + { + SetState(DownloaderState.Prepared); + } + else + { + SetState(DownloaderState.NeedToPrepare); + } + + this.createdDateTime = createdDateTime; + this.remoteFileInfo = remoteInfo; + this.requestedSegmentCount = requestedSegmentCount; + this.segments = segments; + } + + #region Properties + + public event EventHandler Ending; + + public event EventHandler InfoReceived; + + public event EventHandler StateChanged; + + public event EventHandler RestartingSegment; + + public event EventHandler SegmentStoped; + + public event EventHandler SegmentStarting; + + public event EventHandler SegmentStarted; + + public event EventHandler SegmentFailed; + + public Dictionary ExtendedProperties + { + get { return extentedProperties; } + } + + public ResourceLocation ResourceLocation + { + get + { + return this.resourceLocation; + } + } + + public List Mirrors + { + get + { + return this.mirrors; + } + } + + public string FileName + { + get { return localFile.Substring(localFile.LastIndexOf("\\")+1); } + } + + public long FileSize + { + get + { + if (remoteFileInfo == null) + { + return 0; + } + return remoteFileInfo.FileSize; + } + } + + public DateTime CreatedDateTime + { + get + { + return createdDateTime; + } + } + + public int RequestedSegments + { + get + { + return requestedSegmentCount; + } + } + + public string LocalFile + { + get + { + return this.localFile; + } + } + + public double Progress + { + get + { + int count = segments.Count; + + if (count > 0) + { + double progress = 0; + + for (int i = 0; i < count; i++) + { + progress += segments[i].Progress; + } + + return progress / count; + } + else + { + return 0; + } + } + } + + public double Rate + { + get + { + double rate = 0; + + for (int i = 0; i < segments.Count; i++) + { + rate += segments[i].Rate; + } + + return rate; + } + } + + public long Transfered + { + get + { + long transfered = 0; + + for (int i = 0; i < segments.Count; i++) + { + transfered += segments[i].Transfered; + } + + return transfered; + } + } + + //public CookieContainer CookieContainer + //{ + // get + // { + // return cookieContainer; + // } + // set + // { + // cookieContainer = value; + // } + //} + + public TimeSpan Left + { + get + { + if (this.Rate == 0) + { + return TimeSpan.MaxValue; + } + + double missingTransfer = 0; + + for (int i = 0; i < segments.Count; i++) + { + missingTransfer += segments[i].MissingTransfer; + } + + return TimeSpan.FromSeconds(missingTransfer / this.Rate); + } + } + + public List Segments + { + get + { + return segments; + } + } + + public Exception LastError + { + get { return lastError; } + set { lastError = value; } + } + + public DownloaderState State + { + get { return state; } + } + + public bool IsWorking() + { + DownloaderState state = this.State; + return (state == DownloaderState.Preparing || + state == DownloaderState.WaitingForReconnect || + state == DownloaderState.Working); + } + + public RemoteFileInfo RemoteFileInfo + { + get { return remoteFileInfo; } + } + + public string StatusMessage + { + get { return statusMessage; } + set { statusMessage = value; } + } + + public ISegmentCalculator SegmentCalculator + { + get { return segmentCalculator; } + set + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + + segmentCalculator = value; + } + } + + public IMirrorSelector MirrorSelector + { + get { return mirrorSelector; } + set + { + if (value == null) + { + throw new ArgumentNullException("value"); + } + + mirrorSelector = value; + mirrorSelector.Init(this); + } + } + + #endregion + + private void SetState(DownloaderState value) + { + state = value; + if (state == DownloaderState.EndedWithError) + ScheduleState = DownloaderScheduleState.Error; + OnStateChanged(); + } + + private void StartToPrepare() + { + mainThread = new Thread(new ParameterizedThreadStart(StartDownloadThreadProc)); + mainThread.Start(requestedSegmentCount); + } + + private void StartPrepared() + { + mainThread = new Thread(new ThreadStart(RestartDownload)); + mainThread.Start(); + } + + protected virtual void OnRestartingSegment(Segment segment) + { + if (RestartingSegment != null) + { + RestartingSegment(this, new SegmentEventArgs(this, segment)); + } + } + + protected virtual void OnSegmentStoped(Segment segment) + { + if (SegmentStoped != null) + { + SegmentStoped(this, new SegmentEventArgs(this, segment)); + } + } + + protected virtual void OnSegmentFailed(Segment segment) + { + if (SegmentFailed != null) + { + SegmentFailed(this, new SegmentEventArgs(this, segment)); + } + } + + protected virtual void OnSegmentStarting(Segment segment) + { + if (SegmentStarting != null) + { + SegmentStarting(this, new SegmentEventArgs(this, segment)); + } + } + + protected virtual void OnSegmentStarted(Segment segment) + { + if (SegmentStarted != null) + { + SegmentStarted(this, new SegmentEventArgs(this, segment)); + } + } + + protected virtual void OnStateChanged() + { + if (StateChanged != null) + { + StateChanged(this, EventArgs.Empty); + } + } + + protected virtual void OnEnding() + { + ScheduleState = DownloaderScheduleState.Ended; + if (Ending != null) + { + Ending(this, EventArgs.Empty); + } + } + + protected virtual void OnInfoReceived() + { + if (InfoReceived != null) + { + InfoReceived(this, EventArgs.Empty); + } + } + + public IDisposable LockSegments() + { + return new ObjectLocker(this.segments); + } + + public void WaitForConclusion() + { + if (! IsWorking()) + { + if (mainThread != null && mainThread.IsAlive) + { + mainThread.Join(TimeSpan.FromSeconds(1)); + } + } + + while (IsWorking()) + { + Thread.Sleep(100); + } + + Debug.WriteLine(this.State.ToString()); + } + + public void Pause() + { + ScheduleState = DownloaderScheduleState.Paused; + if (state == DownloaderState.Preparing || state == DownloaderState.WaitingForReconnect) + { + Segments.Clear(); + + mainThread.Abort(); + mainThread = null; + SetState(DownloaderState.NeedToPrepare); + return; + } + + if (state == DownloaderState.Working) + { + SetState(DownloaderState.Pausing); + + while (!AllWorkersStopped(5)) + ; + + lock (threads) + { + threads.Clear(); + } + + mainThread.Abort(); + mainThread = null; + + if (RemoteFileInfo != null && !RemoteFileInfo.AcceptRanges) + { + // reset the segment + Segments[0].StartPosition = 0; + } + + SetState(DownloaderState.Paused); + } + } + + public void Start() + { + ScheduleState = DownloaderScheduleState.Working; + if (state == DownloaderState.NeedToPrepare) + { + SetState(DownloaderState.Preparing); + + StartToPrepare(); + } + else if ( + state != DownloaderState.Preparing && + state != DownloaderState.Pausing && + state != DownloaderState.Working && + state != DownloaderState.WaitingForReconnect) + { + SetState(DownloaderState.Preparing); + + StartPrepared(); + } + } + + private void AllocLocalFile() + { + if(this.LocalFile.EndsWith("/")) + this.localFile = this.localFile.Substring(0, this.localFile.Length - 1) + this.remoteFileInfo.FileName; + else + if(this.LocalFile.EndsWith("\\")) + this.localFile += this.remoteFileInfo.FileName; + FileInfo fileInfo = new FileInfo(this.LocalFile); + if (!Directory.Exists(fileInfo.DirectoryName)) + { + Directory.CreateDirectory(fileInfo.DirectoryName); + } + + if (fileInfo.Exists) + { + // auto rename the file... + int count = 1; + + string fileExitWithoutExt = Path.GetFileNameWithoutExtension(this.LocalFile); + string ext = Path.GetExtension(this.LocalFile); + + string newFileName; + + do + { + newFileName = PathHelper.GetWithBackslash(fileInfo.DirectoryName) + + fileExitWithoutExt + String.Format("({0})", count++) + ext; + } + while (File.Exists(newFileName)); + + this.localFile = newFileName; + } + + using (FileStream fs = new FileStream(this.LocalFile, FileMode.Create, FileAccess.Write)) + { + fs.SetLength(Math.Max(this.FileSize, 0)); + } + } + + private void StartDownloadThreadProc(object objSegmentCount) + { + SetState(DownloaderState.Preparing); + + int segmentCount = Math.Min((int)objSegmentCount, Settings.Default.MaxSegments); + Stream inputStream = null; + int currentTry = 0; + + do + { + lastError = null; + + if (state == DownloaderState.Pausing) + { + SetState(DownloaderState.NeedToPrepare); + return; + } + + SetState(DownloaderState.Preparing); + + currentTry++; + try + { + remoteFileInfo = defaultDownloadProvider.GetFileInfo(this.ResourceLocation, out inputStream); + break; + } + catch (ThreadAbortException) + { + SetState(DownloaderState.NeedToPrepare); + return; + } + catch (Exception ex) + { + lastError = ex; + if (currentTry < Settings.Default.MaxRetries) + { + SetState(DownloaderState.WaitingForReconnect); + Thread.Sleep(TimeSpan.FromSeconds(Settings.Default.RetryDelay)); + } + else + { + SetState(DownloaderState.NeedToPrepare); + return; + } + } + } + while (true); + + try + { + lastError = null; + StartSegments(segmentCount, inputStream); + } + catch (ThreadAbortException) + { + throw; + } + catch (Exception ex) + { + lastError = ex; + SetState(DownloaderState.EndedWithError); + } + } + + private void StartSegments(int segmentCount, Stream inputStream) + { + // notifies + OnInfoReceived(); + + // allocs the file on disk + AllocLocalFile(); + + if (this.segments.Count==0) + { + long segmentSize; + CalculatedSegment[] calculatedSegments; + + if (!remoteFileInfo.AcceptRanges) + { + calculatedSegments = new CalculatedSegment[] { new CalculatedSegment(0, remoteFileInfo.FileSize) }; + } + else + { + calculatedSegments = this.SegmentCalculator.GetSegments(segmentCount, remoteFileInfo); + } + + lock (threads) threads.Clear(); + lock (segments) segments.Clear(); + + for (int i = 0; i < calculatedSegments.Length; i++) + { + Segment segment = new Segment(); + if (i == 0) + { + segment.InputStream = inputStream; + } + + segment.Index = i; + segment.InitialStartPosition = calculatedSegments[i].StartPosition; + segment.StartPosition = calculatedSegments[i].StartPosition; + segment.EndPosition = calculatedSegments[i].EndPosition; + + segments.Add(segment); + } + } + + RunSegments(); + } + + private void RestartDownload() + { + int currentTry = 0; + Stream stream; + RemoteFileInfo newInfo; + + try + { + do + { + lastError = null; + + SetState(DownloaderState.Preparing); + + currentTry++; + try + { + newInfo = defaultDownloadProvider.GetFileInfo(this.ResourceLocation, out stream); + + break; + } + catch (Exception ex) + { + lastError = ex; + if (currentTry < Settings.Default.MaxRetries) + { + SetState(DownloaderState.WaitingForReconnect); + Thread.Sleep(TimeSpan.FromSeconds(Settings.Default.RetryDelay)); + } + else + { + return; + } + } + } + while (true); + } + finally + { + SetState(DownloaderState.Prepared); + } + + try + { + // check if the file changed on the server + if (!newInfo.AcceptRanges || + newInfo.LastModified > RemoteFileInfo.LastModified || + newInfo.FileSize != RemoteFileInfo.FileSize) + { + this.remoteFileInfo = newInfo; + StartSegments(this.RequestedSegments, stream); + } + else + { + if (stream != null) + { + stream.Dispose(); + } + + RunSegments(); + } + } + catch (ThreadAbortException) + { + throw; + } + catch (Exception ex) + { + lastError = ex; + SetState(DownloaderState.EndedWithError); + } + } + + private void RunSegments() + { + SetState(DownloaderState.Working); + + // TODO comparar o remote file Info se esta igual, se o download saiu de paused/prepared + // e nao veio da thread que le o fileinfo + + using (FileStream fs = new FileStream(this.LocalFile, FileMode.Open, FileAccess.Write)) + { + for (int i = 0; i < this.Segments.Count; i++) + { + Segments[i].OutputStream = fs; + StartSegment(Segments[i]); + } + + do + { + while (!AllWorkersStopped(1000)) + ; + } + while (RestartFailedSegments()); + } + + for (int i = 0; i < this.Segments.Count; i++) + { + if (Segments[i].State == SegmentState.Error) + { + SetState(DownloaderState.EndedWithError); + return; + } + } + + if (this.State != DownloaderState.Pausing) + { + OnEnding(); + } + + SetState(DownloaderState.Ended); + } + + private bool RestartFailedSegments() + { + bool hasErrors = false; + double delay = 0; + + for (int i = 0; i < this.Segments.Count; i++) + { + if (Segments[i].State == SegmentState.Error && + Segments[i].LastErrorDateTime != DateTime.MinValue && + (Settings.Default.MaxRetries == 0 || + Segments[i].CurrentTry < Settings.Default.MaxRetries)) + { + hasErrors = true; + TimeSpan ts = DateTime.Now - Segments[i].LastErrorDateTime; + + if (ts.TotalSeconds >= Settings.Default.RetryDelay) + { + Segments[i].CurrentTry++; + StartSegment(Segments[i]); + OnRestartingSegment(Segments[i]); + } + else + { + delay = Math.Max(delay, Settings.Default.RetryDelay * 1000 - ts.TotalMilliseconds); + } + } + } + + Thread.Sleep((int)delay); + + return hasErrors; + } + + private void StartSegment(Segment newSegment) + { + Thread segmentThread = new Thread(new ParameterizedThreadStart(SegmentThreadProc)); + segmentThread.Start(newSegment); + + lock (threads) + { + threads.Add(segmentThread); + } + } + + private bool AllWorkersStopped(int timeOut) + { + bool allFinished = true; + + Thread[] workers; + + lock (threads) + { + workers = threads.ToArray(); + } + + foreach (Thread t in workers) + { + bool finished = t.Join(timeOut); + allFinished = allFinished & finished; + + if (finished) + { + lock (threads) + { + threads.Remove(t); + } + } + } + + return allFinished; + } + + private void SegmentThreadProc(object objSegment) + { + Segment segment = (Segment)objSegment; + + segment.LastError = null; + + try + { + if (segment.EndPosition > 0 && segment.StartPosition >= segment.EndPosition) + { + segment.State = SegmentState.Finished; + + // raise the event + OnSegmentStoped(segment); + + return; + } + + int buffSize = 8192; + byte[] buffer = new byte[buffSize]; + + segment.State = SegmentState.Connecting; + + // raise the event + OnSegmentStarting(segment); + + if (segment.InputStream == null) + { + // get the next URL (It can the the main url or some mirror) + ResourceLocation location = this.MirrorSelector.GetNextResourceLocation(); + // get the protocol provider for that mirror + IProtocolProvider provider = location.BindProtocolProviderInstance(this); + + while (location != this.ResourceLocation) + { + Stream tempStream; + + // get the remote file info on mirror + RemoteFileInfo tempRemoteInfo = provider.GetFileInfo(location, out tempStream); + if (tempStream != null) tempStream.Dispose(); + + // check if the file on mirror is the same + if (tempRemoteInfo.FileSize == remoteFileInfo.FileSize && + tempRemoteInfo.AcceptRanges == remoteFileInfo.AcceptRanges) + { + // if yes, stop looking for the mirror + break; + } + + lock (mirrors) + { + // the file on the mirror is not the same, so remove from the mirror list + mirrors.Remove(location); + } + + // the file on the mirror is different + // so get other mirror to use in the segment + location = this.MirrorSelector.GetNextResourceLocation(); + provider = location.BindProtocolProviderInstance(this); + } + + // get the input stream from start position + segment.InputStream = provider.CreateStream(location, segment.StartPosition, segment.EndPosition); + + // change the segment URL to the mirror URL + segment.CurrentURL = location.URL; + } + else + { + // change the segment URL to the main URL + segment.CurrentURL = this.resourceLocation.URL; + } + + using (segment.InputStream) + { + // raise the event + OnSegmentStarted(segment); + + // change the segment state + segment.State = SegmentState.Downloading; + segment.CurrentTry = 0; + + long readSize; + + do + { + // reads the buffer from input stream + readSize = segment.InputStream.Read(buffer, 0, buffSize); + + // check if the segment has reached the end + if (segment.EndPosition > 0 && + segment.StartPosition + readSize > segment.EndPosition) + { + // adjust the 'readSize' to write only necessary bytes + readSize = (segment.EndPosition - segment.StartPosition); + if (readSize <= 0) + { + segment.StartPosition = segment.EndPosition; + break; + } + } + + // locks the stream to avoid that other threads changes + // the position of stream while this thread is writing into the stream + lock (segment.OutputStream) + { + segment.OutputStream.Position = segment.StartPosition; + segment.OutputStream.Write(buffer, 0, (int)readSize); + } + + // increse the start position of the segment and also calculates the rate + segment.IncreaseStartPosition(readSize); + + // check if the stream has reached its end + if (segment.EndPosition > 0 && segment.StartPosition >= segment.EndPosition) + { + segment.StartPosition = segment.EndPosition; + break; + } + + // check if the user have requested to pause the download + if (state == DownloaderState.Pausing) + { + segment.State = SegmentState.Paused; + break; + } + + //Thread.Sleep(1500); + } + while (readSize > 0); + + if (segment.State == SegmentState.Downloading) + { + segment.State = SegmentState.Finished; + + // try to create other segment, + // spliting the missing bytes from one existing segment + AddNewSegmentIfNeeded(); + } + } + + // raise the event + OnSegmentStoped(segment); + } + catch (Exception ex) + { + // store the error information + segment.State = SegmentState.Error; + segment.LastError = ex; + + Debug.WriteLine(ex.ToString()); + + // raise the event + OnSegmentFailed(segment); + } + finally + { + // clean up the segment + segment.InputStream = null; + } + } + + private void AddNewSegmentIfNeeded() + { + lock (segments) + { + for (int i = 0; i < this.segments.Count; i++) + { + Segment oldSegment = this.segments[i]; + if (oldSegment.State == SegmentState.Downloading && + oldSegment.Left.TotalSeconds > Settings.Default.MinSegmentLeftToStartNewSegment && + oldSegment.MissingTransfer / 2 >= Settings.Default.MinSegmentSize) + { + // get the half of missing size of oldSegment + long newSize = oldSegment.MissingTransfer / 2; + + // create a new segment allocation the half old segment + Segment newSegment = new Segment(); + newSegment.Index = this.segments.Count; + newSegment.StartPosition = oldSegment.StartPosition + newSize; + newSegment.InitialStartPosition = newSegment.StartPosition; + newSegment.EndPosition = oldSegment.EndPosition; + newSegment.OutputStream = oldSegment.OutputStream; + + // removes bytes from old segments + oldSegment.EndPosition = oldSegment.EndPosition - newSize; + + // add the new segment to the list + segments.Add(newSegment); + + StartSegment(newSegment); + + break; + } + } + } + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/DownloaderState.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/DownloaderState.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Core +{ + public enum DownloaderState: byte + { + NeedToPrepare = 0, + Preparing, + WaitingForReconnect, + Prepared, + Working, + Pausing, + Paused, + Ended, + EndedWithError + } + + public enum DownloaderScheduleState : byte + { + Paused = 0, + Waiting, + Working, + Error, + Ended + } + +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/EventArgs.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/EventArgs.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Core +{ + #region ResolvingProtocolProviderEventArgs + public class ResolvingProtocolProviderEventArgs : EventArgs + { + #region Fields + + private IProtocolProvider provider; + private string url; + + #endregion + + #region Constructor + + public ResolvingProtocolProviderEventArgs(IProtocolProvider provider, + string url) + { + this.url = url; + this.provider = provider; + } + + #endregion + + #region Properties + + public string URL + { + get { return url; } + } + + public IProtocolProvider ProtocolProvider + { + get { return provider; } + set { provider = value; } + } + + #endregion + } + #endregion + + #region DownloaderEventArgs + public class DownloaderEventArgs : EventArgs + { + #region Fields + + private Downloader downloader; + private bool willStart; + + #endregion + + #region Constructor + + public DownloaderEventArgs(Downloader download) + { + this.downloader = download; + } + + public DownloaderEventArgs(Downloader download, bool willStart): this(download) + { + this.willStart = willStart; + } + + #endregion + + #region Properties + + public Downloader Downloader + { + get { return downloader; } + } + + public bool WillStart + { + get { return willStart; } + } + + #endregion + } + #endregion + + #region SegmentEventArgs + public class SegmentEventArgs : DownloaderEventArgs + { + #region Fields + + private Segment segment; + + #endregion + + #region Constructor + + public SegmentEventArgs(Downloader d, Segment segment) + : base(d) + { + this.segment = segment; + } + + #endregion + + #region Properties + + public Segment Segment + { + get { return segment; } + set { segment = value; } + } + + #endregion + } + #endregion +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Extensions/IExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Extensions/IExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core; + +namespace MyDownloader.Core.Extensions +{ + public interface IExtension + { + string Name { get; } + + IUIExtension UIExtension { get; } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Extensions/IExtensionParameters.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Extensions/IExtensionParameters.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.ComponentModel; + +namespace MyDownloader.Core.Extensions +{ + public interface IExtensionParameters + { + event PropertyChangedEventHandler ParameterChanged; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Extensions/IInitializable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Extensions/IInitializable.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Core.Extensions +{ + public interface IInitializable + { + void Init(); + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Extensions/IUIExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Extensions/IUIExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.Core.Extensions +{ + public interface IUIExtension + { + Control[] CreateSettingsView(); + + void PersistSettings(Control[] settingsView); + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/IMirrorSelector.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/IMirrorSelector.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Core +{ + public interface IMirrorSelector + { + void Init(Downloader downloader); + + ResourceLocation GetNextResourceLocation(); + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/IProtocolProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/IProtocolProvider.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace MyDownloader.Core +{ + public interface IProtocolProvider + { + // TODO: remove this method? Acoplamento ficara só de um lado + void Initialize(Downloader downloader); + + Stream CreateStream(ResourceLocation rl, long initialPosition, long endPosition); + + RemoteFileInfo GetFileInfo(ResourceLocation rl, out Stream stream); + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/ISegmentCalculator.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/ISegmentCalculator.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Core +{ + public interface ISegmentCalculator + { + CalculatedSegment[] GetSegments(int segmentCount, RemoteFileInfo fileSize); + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Instrumentation/MyStopwatch.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Instrumentation/MyStopwatch.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; + +namespace MyDownloader.Core.Instrumentation +{ + /// + /// MyStopwatch is a debbuging tool to count the amout of time used by an operation. + /// + public class MyStopwatch : IDisposable + { + #region Fields + + private Stopwatch internalStopwatch; + private string name; + + #endregion + + #region Constructor + + /// + /// Initializes the MyStopwatch + /// + /// The name of MyStopwatch + public MyStopwatch(string name) + { +#if DEBUG + this.name = name; + internalStopwatch = new Stopwatch(); + internalStopwatch.Start(); +#endif + } + + #endregion + + #region Methods + + /// + /// Disposes the MyStopwatch and writes into debug the amount of time used on the operation. + /// + public void Dispose() + { +#if DEBUG + internalStopwatch.Stop(); + Debug.WriteLine(name + ": " + internalStopwatch.Elapsed); +#endif + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/MinSizeSegmentCalculator.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/MinSizeSegmentCalculator.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Core +{ + public class MinSizeSegmentCalculator: ISegmentCalculator + { + #region ISegmentCalculator Members + + public CalculatedSegment[] GetSegments(int segmentCount, RemoteFileInfo remoteFileInfo) + { + long minSize = Settings.Default.MinSegmentSize; + long segmentSize = remoteFileInfo.FileSize / (long)segmentCount; + + while (segmentCount > 1 && segmentSize < minSize) + { + segmentCount--; + segmentSize = remoteFileInfo.FileSize / (long)segmentCount; + } + + long startPosition = 0; + + List segments = new List(); + + for (int i = 0; i < segmentCount; i++) + { + if (segmentCount - 1 == i) + { + // lvx bug? + //segments.Add(new CalculatedSegment(startPosition, remoteFileInfo.FileSize - 1)); + segments.Add(new CalculatedSegment(startPosition, remoteFileInfo.FileSize)); + } + else + { + segments.Add(new CalculatedSegment(startPosition, startPosition + (int)segmentSize)); + } + + startPosition = segments[segments.Count - 1].EndPosition; + } + return segments.ToArray(); + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/MyDownloader.Core.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/MyDownloader.Core.csproj Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,206 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {E763345E-6696-4C53-8764-47E4ABD67DEF} + Library + Properties + MyDownloader.Core + MyDownloader.Core + + + + + + + 3.5 + false + v3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + x86 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + AnyCPU + + + + ..\INIFileParser.dll + + + + + False + ..\System.Data.SQLite.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Settings.settings + + + + + UserControl + + + Connection.cs + + + + + UserControl + + + DownloadFolder.cs + + + + UserControl + + + Location.cs + + + UserControl + + + WaitControl.cs + + + + + + PublicSettingsSingleFileGenerator + Settings.Designer.cs + + + + + Designer + Connection.cs + + + Designer + DownloadFolder.cs + + + Location.cs + Designer + + + Designer + WaitControl.cs + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + PreserveNewest + + + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Properties/AssemblyInfo.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MyDownloader.Core")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Programmmers")] +[assembly: AssemblyProduct("MyDownloader.Core")] +[assembly: AssemblyCopyright("Copyright © Programmmers 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("99822afd-3d8c-41e4-9481-578a49c9c0ae")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/ProtocolProviderFactory.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/ProtocolProviderFactory.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections; + +namespace MyDownloader.Core +{ + public static class ProtocolProviderFactory + { + private static Hashtable protocolHandlers = new Hashtable(); + + public static event EventHandler ResolvingProtocolProvider; + + public static void RegisterProtocolHandler(string prefix, Type protocolProvider) + { + protocolHandlers[prefix] = protocolProvider; + } + + public static IProtocolProvider CreateProvider(string uri, Downloader downloader) + { + IProtocolProvider provider = InternalGetProvider(uri); + + if (downloader != null) + { + provider.Initialize(downloader); + } + + return provider; + } + + public static IProtocolProvider GetProvider(string uri) + { + return InternalGetProvider(uri); + } + + public static Type GetProviderType(string uri) + { + int index = uri.IndexOf("://"); + + if (index > 0) + { + string prefix = uri.Substring(0, index); + Type type = protocolHandlers[prefix] as Type; + return type; + } + else + { + return null; + } + } + + public static IProtocolProvider CreateProvider(Type providerType, Downloader downloader) + { + IProtocolProvider provider = CreateFromType(providerType); + + if (ResolvingProtocolProvider != null) + { + ResolvingProtocolProviderEventArgs e = new ResolvingProtocolProviderEventArgs(provider, null); + ResolvingProtocolProvider(null, e); + provider = e.ProtocolProvider; + } + + if (downloader != null) + { + provider.Initialize(downloader); + } + + return provider; + } + + private static IProtocolProvider InternalGetProvider(string uri) + { + Type type = GetProviderType(uri); + + IProtocolProvider provider = CreateFromType(type); + + if (ResolvingProtocolProvider != null) + { + ResolvingProtocolProviderEventArgs e = new ResolvingProtocolProviderEventArgs(provider, uri); + ResolvingProtocolProvider(null, e); + provider = e.ProtocolProvider; + } + + return provider; + } + + private static IProtocolProvider CreateFromType(Type type) + { + IProtocolProvider provider = (IProtocolProvider)Activator.CreateInstance(type); + return provider; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/RemoteFileInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/RemoteFileInfo.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Core +{ + [Serializable] + public class RemoteFileInfo + { + private bool acceptRanges; + private long fileSize; + private string fileName; + private DateTime lastModified = DateTime.MinValue; + + private string mimeType; + + public string MimeType + { + get { return mimeType; } + set { mimeType = value; } + } + + public string FileName + { + get { return fileName; } + set { fileName = value; } + } + + public bool AcceptRanges + { + get { return acceptRanges; } + set { acceptRanges = value; } + } + + public long FileSize + { + get { return fileSize; } + set { fileSize = value; } + } + + public DateTime LastModified + { + get { return lastModified; } + set { lastModified = value; } + } + + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/ResourceLocation.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/ResourceLocation.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; + +namespace MyDownloader.Core +{ + [Serializable] + public class ResourceLocation + { + #region Fields + + private string url; + private bool authenticate; + private string login; + private string password; + private Type protocolProviderType; + private IProtocolProvider provider; + + #endregion + + #region Constructor + public ResourceLocation() + { + } + + public static ResourceLocation FromURL(string url) + { + ResourceLocation rl = new ResourceLocation(); + rl.URL = url; + return rl; + } + + public static ResourceLocation[] FromURLArray(string[] urls) + { + List result = new List(); + + for (int i = 0; i < urls.Length; i++) + { + if (IsURL(urls[i])) + { + result.Add(ResourceLocation.FromURL(urls[i])); + } + } + + return result.ToArray(); + } + + public static ResourceLocation FromURL( + string url, + bool authenticate, + string login, + string password) + { + ResourceLocation rl = new ResourceLocation(); + rl.URL = url; + rl.Authenticate = authenticate; + rl.Login = login; + rl.Password = password; + return rl; + } + #endregion + + #region Properties + + public string URL + { + get { return url; } + set + { + url = value; + BindProtocolProviderType(); + } + } + + public bool Authenticate + { + get { return authenticate; } + set { authenticate = value; } + } + + public string Login + { + get { return login; } + set { login = value; } + } + + public string Password + { + get { return password; } + set { password = value; } + } + + public string ProtocolProviderType + { + get + { + if (protocolProviderType == null) + { + return null; + } + return protocolProviderType.AssemblyQualifiedName; + } + set + { + if (value == null) + { + BindProtocolProviderType(); + } + else + { + protocolProviderType = Type.GetType(value); + } + } + } + + #endregion + + #region Methods + + public IProtocolProvider GetProtocolProvider(Downloader downloader) + { + return BindProtocolProviderInstance(downloader); + } + + public void BindProtocolProviderType() + { + provider = null; + + if (! String.IsNullOrEmpty(this.URL)) + { + protocolProviderType = ProtocolProviderFactory.GetProviderType(this.URL); + } + } + + public IProtocolProvider BindProtocolProviderInstance(Downloader downloader) + { + if (protocolProviderType == null) + { + BindProtocolProviderType(); + } + + if (provider == null) + { + provider = ProtocolProviderFactory.CreateProvider(protocolProviderType, downloader); + } + + return provider; + } + + public ResourceLocation Clone() + { + return (ResourceLocation)this.MemberwiseClone(); + } + + public override string ToString() + { + return this.URL; + } + + public static bool IsURL(string url) + { + Match m = Regex.Match(url, @"(?\w+):\/\/(?[\w.]+\/?)\S*"); + if (m.ToString() != string.Empty) + { + return true; + } + return false; + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Segment.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Segment.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,273 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace MyDownloader.Core +{ + public class Segment + { + private long startPosition; + private int index; + private string currentURL; + private long initialStartPosition; + private long endPosition; + private Stream outputStream; + private Stream inputStream; + private Exception lastError; + private SegmentState state; + private bool started = false; + private DateTime lastReception = DateTime.MinValue; + private DateTime lastErrorDateTime = DateTime.MinValue; + private double rate; + private long start; + private TimeSpan left = TimeSpan.Zero; + private int currentTry; + + public int CurrentTry + { + get { return currentTry; } + set { currentTry = value; } + } + + public SegmentState State + { + get + { + return state; + } + set + { + state = value; + + switch (state) + { + case SegmentState.Downloading: + BeginWork(); + break; + + case SegmentState.Connecting: + case SegmentState.Paused: + case SegmentState.Finished: + case SegmentState.Error: + rate = 0.0; + left = TimeSpan.Zero; + break; + } + } + } + + public DateTime LastErrorDateTime + { + get + { + return lastErrorDateTime; + } + } + + public Exception LastError + { + get + { + return lastError; + } + set + { + if (value != null) + { + lastErrorDateTime = DateTime.Now; + } + else + { + lastErrorDateTime = DateTime.MinValue; + } + lastError = value; + } + } + + public int Index + { + get + { + return index; + } + set + { + index = value; + } + } + + public long InitialStartPosition + { + get + { + return initialStartPosition; + } + set + { + initialStartPosition = value; + } + } + + public long StartPosition + { + get + { + return startPosition; + } + set + { + startPosition = value; + } + } + + public long Transfered + { + get + { + return this.StartPosition - this.InitialStartPosition; + } + } + + public long TotalToTransfer + { + get + { + return (this.EndPosition <= 0? 0: this.EndPosition - this.InitialStartPosition); + } + } + + public long MissingTransfer + { + get + { + return (this.EndPosition <= 0? 0: this.EndPosition - this.StartPosition); + } + } + + + public double Progress + { + get + { + return (this.EndPosition <= 0? 0: ((double)Transfered / (double)TotalToTransfer * 100.0f)); + } + } + + public long EndPosition + { + get + { + return endPosition; + } + set + { + endPosition = value; + } + } + + public Stream OutputStream + { + get + { + return outputStream; + } + set + { + outputStream = value; + } + } + + public Stream InputStream + { + get + { + return inputStream; + } + set + { + inputStream = value; + } + } + + public string CurrentURL + { + get + { + return currentURL; + } + set + { + currentURL = value; + } + } + + public double Rate + { + get + { + if (this.State == SegmentState.Downloading) + { + IncreaseStartPosition(0); + return rate; + } + else + { + return 0; + } + } + } + + public TimeSpan Left + { + get + { + return left; + } + } + + public void BeginWork() + { + start = startPosition; + lastReception = DateTime.Now; + started = true; + } + + public void IncreaseStartPosition(long size) + { + lock (this) + { + DateTime now = DateTime.Now; + + startPosition += size; + + if (started) + { + TimeSpan ts = (now - lastReception); + if (ts.TotalSeconds == 0) + { + return; + } + + // bytes per seconds + rate = ((double)(startPosition - start)) / ts.TotalSeconds; + + if (rate > 0.0) + { + left = TimeSpan.FromSeconds(MissingTransfer / rate); + } + else + { + left = TimeSpan.MaxValue; + } + } + else + { + start = startPosition; + lastReception = now; + started = true; + } + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/SegmentState.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/SegmentState.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Core +{ + public enum SegmentState + { + Idle, + Connecting, + Downloading, + Paused, + Finished, + Error, + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/SequentialMirrorSelector.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/SequentialMirrorSelector.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Core +{ + public class SequentialMirrorSelector: IMirrorSelector + { + private Downloader downloader; + private int queryMirrorCount; + + #region IMirrorSelector Members + + public void Init(Downloader downloader) + { + queryMirrorCount = 0; + this.downloader = downloader; + } + + public ResourceLocation GetNextResourceLocation() + { + if (downloader.Mirrors == null || downloader.Mirrors.Count == 0) + { + return this.downloader.ResourceLocation; + } + + lock (downloader.Mirrors) + { + if (queryMirrorCount >= downloader.Mirrors.Count) + { + queryMirrorCount = 0; + + return this.downloader.ResourceLocation; + } + + return downloader.Mirrors[queryMirrorCount++]; + } + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Settings.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Settings.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,122 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MyDownloader.Core { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("200000")] + public long MinSegmentSize { + get { + return ((long)(this["MinSegmentSize"])); + } + set { + this["MinSegmentSize"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("30")] + public int MinSegmentLeftToStartNewSegment { + get { + return ((int)(this["MinSegmentLeftToStartNewSegment"])); + } + set { + this["MinSegmentLeftToStartNewSegment"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("5")] + public int RetryDelay { + get { + return ((int)(this["RetryDelay"])); + } + set { + this["RetryDelay"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("10")] + public int MaxRetries { + get { + return ((int)(this["MaxRetries"])); + } + set { + this["MaxRetries"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("5")] + public int MaxSegments { + get { + return ((int)(this["MaxSegments"])); + } + set { + this["MaxSegments"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string DownloadFolder { + get { + return ((string)(this["DownloadFolder"])); + } + set { + this["DownloadFolder"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool AutomaticFileName { + get { + return ((bool)(this["AutomaticFileName"])); + } + set { + this["AutomaticFileName"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("Internet Explorer")] + public string CookieSource { + get { + return ((string)(this["CookieSource"])); + } + set { + this["CookieSource"] = value; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/Settings.settings --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/Settings.settings Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,30 @@ + + + + + + 200000 + + + 30 + + + 5 + + + 10 + + + 5 + + + + + + True + + + Internet Explorer + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/AppManager.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/AppManager.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.App; + +namespace MyDownloader.Core.UI +{ + public class AppManager + { + private AppManager() + { + } + + private static AppManager instance = new AppManager(); + + public static AppManager Instance + { + get { return instance; } + } + + private IApp application; + + public IApp Application + { + get { return application; } + } + + public void Initialize(IApp app) + { + this.application = app; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/ApplicationSettings.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/ApplicationSettings.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,73 @@ +namespace MyDownloader.Core.UI +{ + partial class ApplicationSettings + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.checkBox1 = new System.Windows.Forms.CheckBox(); + this.checkBox2 = new System.Windows.Forms.CheckBox(); + this.SuspendLayout(); + // + // checkBox1 + // + this.checkBox1.AutoSize = true; + this.checkBox1.Location = new System.Drawing.Point(4, 4); + this.checkBox1.Name = "checkBox1"; + this.checkBox1.Size = new System.Drawing.Size(114, 17); + this.checkBox1.TabIndex = 0; + this.checkBox1.Text = "Start with windows"; + this.checkBox1.UseVisualStyleBackColor = true; + // + // checkBox2 + // + this.checkBox2.AutoSize = true; + this.checkBox2.Location = new System.Drawing.Point(4, 27); + this.checkBox2.Name = "checkBox2"; + this.checkBox2.Size = new System.Drawing.Size(146, 17); + this.checkBox2.TabIndex = 1; + this.checkBox2.Text = "Start downloads at starup"; + this.checkBox2.UseVisualStyleBackColor = true; + // + // Application + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.checkBox2); + this.Controls.Add(this.checkBox1); + this.Name = "Application"; + this.Size = new System.Drawing.Size(214, 150); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.CheckBox checkBox1; + private System.Windows.Forms.CheckBox checkBox2; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/ApplicationSettings.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/ApplicationSettings.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.Core.UI +{ + public partial class ApplicationSettings : UserControl + { + public ApplicationSettings() + { + Text = "Application"; + InitializeComponent(); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/ApplicationSettings.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/ApplicationSettings.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/ClipboardHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/ClipboardHelper.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.Core.UI +{ + public static class ClipboardHelper + { + public static string GetURLOnClipboard() + { + string url = string.Empty; + + if (Clipboard.ContainsText()) + { + string tempUrl = Clipboard.GetText(); + + if (ResourceLocation.IsURL(tempUrl)) + { + url = tempUrl; + } + else + { + tempUrl = null; + } + } + + return url; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/Connection.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/Connection.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,208 @@ +namespace MyDownloader.Core.UI +{ + partial class Connection + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.numRetryDelay = new System.Windows.Forms.NumericUpDown(); + this.label6 = new System.Windows.Forms.Label(); + this.numMinSegSize = new System.Windows.Forms.NumericUpDown(); + this.numMaxRetries = new System.Windows.Forms.NumericUpDown(); + this.label3 = new System.Windows.Forms.Label(); + this.lblMinSize = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.numMaxSegments = new System.Windows.Forms.NumericUpDown(); + this.chkAutoFileName = new System.Windows.Forms.CheckBox(); + this.cmbCookieSource = new System.Windows.Forms.ComboBox(); + this.label2 = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.numRetryDelay)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numMinSegSize)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numMaxRetries)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numMaxSegments)).BeginInit(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(-3, 95); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(65, 13); + this.label1.TabIndex = 5; + this.label1.Text = "Retry Delay:"; + // + // numRetryDelay + // + this.numRetryDelay.Location = new System.Drawing.Point(0, 112); + this.numRetryDelay.Name = "numRetryDelay"; + this.numRetryDelay.Size = new System.Drawing.Size(96, 20); + this.numRetryDelay.TabIndex = 6; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(-3, 0); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(95, 13); + this.label6.TabIndex = 0; + this.label6.Text = "Min Segment Size:"; + // + // numMinSegSize + // + this.numMinSegSize.Location = new System.Drawing.Point(0, 17); + this.numMinSegSize.Maximum = new decimal(new int[] { + 2147483647, + 0, + 0, + 0}); + this.numMinSegSize.Name = "numMinSegSize"; + this.numMinSegSize.Size = new System.Drawing.Size(116, 20); + this.numMinSegSize.TabIndex = 1; + this.numMinSegSize.ValueChanged += new System.EventHandler(this.numMinSegSize_ValueChanged); + // + // numMaxRetries + // + this.numMaxRetries.Location = new System.Drawing.Point(0, 160); + this.numMaxRetries.Name = "numMaxRetries"; + this.numMaxRetries.Size = new System.Drawing.Size(96, 20); + this.numMaxRetries.TabIndex = 8; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(-3, 143); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(129, 13); + this.label3.TabIndex = 7; + this.label3.Text = "Max Retries (0 for infinite):"; + // + // lblMinSize + // + this.lblMinSize.AutoSize = true; + this.lblMinSize.Location = new System.Drawing.Point(122, 19); + this.lblMinSize.Name = "lblMinSize"; + this.lblMinSize.Size = new System.Drawing.Size(54, 13); + this.lblMinSize.TabIndex = 2; + this.lblMinSize.Text = "lblMinSize"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(-3, 48); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(80, 13); + this.label5.TabIndex = 3; + this.label5.Text = "Max Segments:"; + // + // numMaxSegments + // + this.numMaxSegments.Location = new System.Drawing.Point(0, 65); + this.numMaxSegments.Maximum = new decimal(new int[] { + 2147483647, + 0, + 0, + 0}); + this.numMaxSegments.Name = "numMaxSegments"; + this.numMaxSegments.Size = new System.Drawing.Size(116, 20); + this.numMaxSegments.TabIndex = 4; + // + // chkAutoFileName + // + this.chkAutoFileName.AutoSize = true; + this.chkAutoFileName.Location = new System.Drawing.Point(3, 198); + this.chkAutoFileName.Name = "chkAutoFileName"; + this.chkAutoFileName.Size = new System.Drawing.Size(172, 17); + this.chkAutoFileName.TabIndex = 9; + this.chkAutoFileName.Text = "Automatic File Name Detection"; + this.chkAutoFileName.UseVisualStyleBackColor = true; + // + // cmbCookieSource + // + this.cmbCookieSource.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cmbCookieSource.FormattingEnabled = true; + this.cmbCookieSource.Items.AddRange(new object[] { + "Internet Explorer", + "Chrome", + "Firefox"}); + this.cmbCookieSource.Location = new System.Drawing.Point(3, 231); + this.cmbCookieSource.Name = "cmbCookieSource"; + this.cmbCookieSource.Size = new System.Drawing.Size(121, 21); + this.cmbCookieSource.TabIndex = 10; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(130, 234); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(93, 13); + this.label2.TabIndex = 11; + this.label2.Text = "Source of cookies"; + // + // Connection + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.label2); + this.Controls.Add(this.cmbCookieSource); + this.Controls.Add(this.chkAutoFileName); + this.Controls.Add(this.label5); + this.Controls.Add(this.numMaxSegments); + this.Controls.Add(this.numMaxRetries); + this.Controls.Add(this.label3); + this.Controls.Add(this.label1); + this.Controls.Add(this.lblMinSize); + this.Controls.Add(this.numRetryDelay); + this.Controls.Add(this.label6); + this.Controls.Add(this.numMinSegSize); + this.Name = "Connection"; + this.Size = new System.Drawing.Size(363, 282); + this.Load += new System.EventHandler(this.Connection_Load); + ((System.ComponentModel.ISupportInitialize)(this.numRetryDelay)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numMinSegSize)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numMaxRetries)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numMaxSegments)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.NumericUpDown numRetryDelay; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.NumericUpDown numMinSegSize; + private System.Windows.Forms.NumericUpDown numMaxRetries; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label lblMinSize; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.NumericUpDown numMaxSegments; + private System.Windows.Forms.CheckBox chkAutoFileName; + private System.Windows.Forms.ComboBox cmbCookieSource; + private System.Windows.Forms.Label label2; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/Connection.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/Connection.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using MyDownloader.Core.Common; + +namespace MyDownloader.Core.UI +{ + public partial class Connection : UserControl + { + public Connection() + { + Text = "Connection"; + InitializeComponent(); + + numRetryDelay.Value = Settings.Default.RetryDelay; + numMaxRetries.Value = Settings.Default.MaxRetries; + numMinSegSize.Value = Settings.Default.MinSegmentSize; + numMaxSegments.Value = Settings.Default.MaxSegments; + chkAutoFileName.Checked = Settings.Default.AutomaticFileName; + cmbCookieSource.SelectedItem = Settings.Default.CookieSource; + + UpdateControls(); + } + + public int RetryDelay + { + get + { + return (int)numRetryDelay.Value; + } + } + + public int MaxRetries + { + get + { + return (int)numMaxRetries.Value; + } + } + + public int MinSegmentSize + { + get + { + return (int)numMinSegSize.Value; + } + } + + public int MaxSegments + { + get + { + return (int)numMaxSegments.Value; + } + } + + public bool AutomaticFileName + { + get + { + return (bool)chkAutoFileName.Checked; + } + } + + public string CookieSource + { + get + { + return (string)cmbCookieSource.SelectedItem; + } + } + + private void numMinSegSize_ValueChanged(object sender, EventArgs e) + { + UpdateControls(); + } + + private void UpdateControls() + { + lblMinSize.Text = ByteFormatter.ToString((int)numMinSegSize.Value); + } + + private void Connection_Load(object sender, EventArgs e) + { + + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/Connection.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/Connection.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/CoreExtention.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/CoreExtention.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; + +namespace MyDownloader.Core.UI +{ + public class CoreExtention : IExtension + { + #region IExtension Members + + public string Name + { + get { return "Core"; } + } + + public IUIExtension UIExtension + { + get { return new CoreUIExtention(); } + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/CoreUIExtention.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/CoreUIExtention.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; +using System.Windows.Forms; + +namespace MyDownloader.Core.UI +{ + public class CoreUIExtention: IUIExtension + { + #region IUIExtension Members + + public Control[] CreateSettingsView() + { + return new Control[] { new Connection(), new DownloadFolder() }; + } + + public void PersistSettings(System.Windows.Forms.Control[] settingsView) + { + Connection connection = (Connection)settingsView[0]; + DownloadFolder downloadFolder = (DownloadFolder)settingsView[1]; + + Settings.Default.MaxRetries = connection.MaxRetries; + Settings.Default.MinSegmentSize = connection.MinSegmentSize; + Settings.Default.RetryDelay = connection.RetryDelay; + Settings.Default.MaxSegments = connection.MaxSegments; + Settings.Default.AutomaticFileName = connection.AutomaticFileName; + Settings.Default.CookieSource = connection.CookieSource; + + Settings.Default.DownloadFolder = downloadFolder.Folder; + + Settings.Default.Save(); + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/DownloadFolder.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/DownloadFolder.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,87 @@ +namespace MyDownloader.Core.UI +{ + partial class DownloadFolder + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnSelAV = new System.Windows.Forms.Button(); + this.txtSaveTo = new System.Windows.Forms.TextBox(); + this.lblText = new System.Windows.Forms.Label(); + this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); + this.SuspendLayout(); + // + // btnSelAV + // + this.btnSelAV.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnSelAV.Location = new System.Drawing.Point(321, 19); + this.btnSelAV.Name = "btnSelAV"; + this.btnSelAV.Size = new System.Drawing.Size(26, 23); + this.btnSelAV.TabIndex = 2; + this.btnSelAV.Text = "..."; + this.btnSelAV.UseVisualStyleBackColor = true; + this.btnSelAV.Click += new System.EventHandler(this.btnSelAV_Click); + // + // txtSaveTo + // + this.txtSaveTo.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtSaveTo.Location = new System.Drawing.Point(0, 19); + this.txtSaveTo.Name = "txtSaveTo"; + this.txtSaveTo.Size = new System.Drawing.Size(319, 20); + this.txtSaveTo.TabIndex = 1; + // + // lblText + // + this.lblText.AutoSize = true; + this.lblText.Location = new System.Drawing.Point(0, 2); + this.lblText.Name = "lblText"; + this.lblText.Size = new System.Drawing.Size(122, 13); + this.lblText.TabIndex = 0; + this.lblText.Text = "Default download folder:"; + // + // DownloadFolder + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.btnSelAV); + this.Controls.Add(this.txtSaveTo); + this.Controls.Add(this.lblText); + this.Name = "DownloadFolder"; + this.Size = new System.Drawing.Size(347, 50); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnSelAV; + private System.Windows.Forms.TextBox txtSaveTo; + private System.Windows.Forms.Label lblText; + private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/DownloadFolder.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/DownloadFolder.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using MyDownloader.Core.Common; + +namespace MyDownloader.Core.UI +{ + public partial class DownloadFolder : UserControl + { + public DownloadFolder() + { + InitializeComponent(); + + Text = "Directory"; + if (Settings.Default.DownloadFolder == "") + Settings.Default.DownloadFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + txtSaveTo.Text = Settings.Default.DownloadFolder; + + } + + public string LabelText + { + get + { + return lblText.Text; + } + set + { + lblText.Text = value; + } + } + + public string Folder + { + get { return PathHelper.GetWithBackslash(txtSaveTo.Text); } + set { txtSaveTo.Text = value; } + } + + private void btnSelAV_Click(object sender, EventArgs e) + { + if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) + { + txtSaveTo.Text = folderBrowserDialog1.SelectedPath; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/DownloadFolder.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/DownloadFolder.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/IApp.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/IApp.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using MyDownloader.Core.Extensions; +using System.Windows.Forms; +namespace MyDownloader.App +{ + public interface IApp: IDisposable + { + Form MainForm { get; } + + NotifyIcon NotifyIcon { get; } + + List Extensions { get; } + + IExtension GetExtensionByType(Type type); + + void Start(string[] args); + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/Location.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/Location.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,133 @@ +namespace MyDownloader.App.UI +{ + partial class Location + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.lblURL = new System.Windows.Forms.Label(); + this.txtURL = new System.Windows.Forms.TextBox(); + this.txtPass = new System.Windows.Forms.TextBox(); + this.lblPass = new System.Windows.Forms.Label(); + this.txtLogin = new System.Windows.Forms.TextBox(); + this.lblLogin = new System.Windows.Forms.Label(); + this.chkLogin = new System.Windows.Forms.CheckBox(); + this.SuspendLayout(); + // + // lblURL + // + this.lblURL.AutoSize = true; + this.lblURL.Location = new System.Drawing.Point(0, 3); + this.lblURL.Name = "lblURL"; + this.lblURL.Size = new System.Drawing.Size(29, 13); + this.lblURL.TabIndex = 0; + this.lblURL.Text = "URL"; + // + // txtURL + // + this.txtURL.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtURL.Location = new System.Drawing.Point(0, 19); + this.txtURL.Multiline = true; + this.txtURL.Name = "txtURL"; + this.txtURL.Size = new System.Drawing.Size(450, 77); + this.txtURL.TabIndex = 1; + this.txtURL.Text = "http://localhost/servicemodelsamples/Desktop.zip"; + this.txtURL.TextChanged += new System.EventHandler(this.txtURL_TextChanged); + // + // txtPass + // + this.txtPass.Location = new System.Drawing.Point(291, 119); + this.txtPass.Name = "txtPass"; + this.txtPass.Size = new System.Drawing.Size(157, 20); + this.txtPass.TabIndex = 6; + // + // lblPass + // + this.lblPass.AutoSize = true; + this.lblPass.Location = new System.Drawing.Point(288, 102); + this.lblPass.Name = "lblPass"; + this.lblPass.Size = new System.Drawing.Size(56, 13); + this.lblPass.TabIndex = 5; + this.lblPass.Text = "Password:"; + // + // txtLogin + // + this.txtLogin.Location = new System.Drawing.Point(124, 119); + this.txtLogin.Name = "txtLogin"; + this.txtLogin.Size = new System.Drawing.Size(161, 20); + this.txtLogin.TabIndex = 4; + // + // lblLogin + // + this.lblLogin.AutoSize = true; + this.lblLogin.Location = new System.Drawing.Point(121, 102); + this.lblLogin.Name = "lblLogin"; + this.lblLogin.Size = new System.Drawing.Size(36, 13); + this.lblLogin.TabIndex = 3; + this.lblLogin.Text = "Login:"; + // + // chkLogin + // + this.chkLogin.AutoSize = true; + this.chkLogin.Location = new System.Drawing.Point(3, 102); + this.chkLogin.Name = "chkLogin"; + this.chkLogin.Size = new System.Drawing.Size(96, 17); + this.chkLogin.TabIndex = 2; + this.chkLogin.Text = "Login to server"; + this.chkLogin.UseVisualStyleBackColor = true; + this.chkLogin.CheckedChanged += new System.EventHandler(this.chkLogin_CheckedChanged); + // + // Location + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.lblURL); + this.Controls.Add(this.txtURL); + this.Controls.Add(this.txtPass); + this.Controls.Add(this.lblPass); + this.Controls.Add(this.txtLogin); + this.Controls.Add(this.lblLogin); + this.Controls.Add(this.chkLogin); + this.Name = "Location"; + this.Size = new System.Drawing.Size(451, 145); + this.Load += new System.EventHandler(this.Location_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label lblURL; + private System.Windows.Forms.TextBox txtURL; + private System.Windows.Forms.TextBox txtPass; + private System.Windows.Forms.Label lblPass; + private System.Windows.Forms.TextBox txtLogin; + private System.Windows.Forms.Label lblLogin; + private System.Windows.Forms.CheckBox chkLogin; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/Location.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/Location.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using MyDownloader.Core; +using MyDownloader.Core.UI; + +namespace MyDownloader.App.UI +{ + public partial class Location : UserControl + { + private bool hasSet = false; + + public Location() + { + InitializeComponent(); + + Clear(); + } + + public event EventHandler UrlChanged; + + public string UrlLabelTitle + { + get + { + return lblURL.Text; + } + set + { + lblURL.Text = value; + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ResourceLocation[] ResourceLocation + { + get + { + string[] Urls = txtURL.Text.Replace("\r","").Split('\n'); + ResourceLocation[] ret=new ResourceLocation[Urls.Length]; + int cnt = 0; + foreach(string u in Urls) + { + if (u.Trim() != "") + { + ResourceLocation rl = new ResourceLocation(); + rl.Authenticate = chkLogin.Checked; + rl.Login = txtLogin.Text; + rl.Password = txtPass.Text; + rl.URL = u; + ret[cnt] = rl; + cnt++; + } + } + return ret; + } + set + { + hasSet = true; + + if (value != null) + { + chkLogin.Checked = value[0].Authenticate; + txtLogin.Text = value[0].Login; + txtPass.Text = value[0].Password; + txtURL.Text = value[0].URL; + } + else + { + chkLogin.Checked = false; + txtLogin.Text = String.Empty; + txtPass.Text = String.Empty; + txtURL.Text = String.Empty; + } + } + } + + public void Clear() + { + txtURL.Text = string.Empty; + chkLogin.Checked = false; + txtPass.Text = string.Empty; + txtLogin.Text = string.Empty; + UpdateUI(); + } + + private void chkLogin_CheckedChanged(object sender, EventArgs e) + { + UpdateUI(); + } + + private void UpdateUI() + { + lblLogin.Enabled = chkLogin.Checked; + lblPass.Enabled = chkLogin.Checked; + txtLogin.Enabled = chkLogin.Checked; + txtPass.Enabled = chkLogin.Checked; + } + + private void txtURL_TextChanged(object sender, EventArgs e) + { + if (UrlChanged != null) + { + UrlChanged(this, EventArgs.Empty); + } + } + + private void Location_Load(object sender, EventArgs e) + { + if (! hasSet) + { + txtURL.Text = ClipboardHelper.GetURLOnClipboard(); + } + } + + public string Username + { + get { return this.txtLogin.Text; } + set { chkLogin.Checked = true; this.txtLogin.Text = value; } + } + + public string Password + { + get { return this.txtPass.Text; } + set { chkLogin.Checked = true; this.txtPass.Text = value; } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/Location.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/Location.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/WaitControl.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/WaitControl.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,76 @@ +namespace MyDownloader.Core.UI +{ + partial class WaitControl + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WaitControl)); + this.label3 = new System.Windows.Forms.Label(); + this.pictureBox2 = new System.Windows.Forms.PictureBox(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit(); + this.SuspendLayout(); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label3.Location = new System.Drawing.Point(16, 2); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(188, 13); + this.label3.TabIndex = 0; + this.label3.Text = "Downloading site, please wait..."; + // + // pictureBox2 + // + this.pictureBox2.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox2.Image"))); + this.pictureBox2.Location = new System.Drawing.Point(0, 0); + this.pictureBox2.Name = "pictureBox2"; + this.pictureBox2.Size = new System.Drawing.Size(16, 16); + this.pictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; + this.pictureBox2.TabIndex = 39; + this.pictureBox2.TabStop = false; + // + // WaitControl + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.label3); + this.Controls.Add(this.pictureBox2); + this.Name = "WaitControl"; + this.Size = new System.Drawing.Size(210, 18); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label3; + private System.Windows.Forms.PictureBox pictureBox2; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/WaitControl.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/WaitControl.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.Core.UI +{ + public partial class WaitControl : UserControl + { + public WaitControl() + { + InitializeComponent(); + } + + [EditorBrowsable(EditorBrowsableState.Always)] + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public override string Text + { + get + { + return label3.Text; + } + set + { + label3.Text = value; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/UI/WaitControl.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/UI/WaitControl.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + R0lGODlhEAAQAKIFAEJCQgQEBKCgY3R0Y7+/Y/nRY9TQY////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJ + AAAFACwAAAAAEAAQAAADOVi6BEArFjJMASEAqZr2GlcMWSA0gFUIkYFVIgfFkcDSi5DdogGRJppPIRjg + jsgkMcbrqZCEmVKUAAAh+QQJAAAFACwAAAAAEAAQAAADO1i6BmMryhHCKAKISAYplCVUwaYAAUAYw4VW + l0KoUpZ+i1nTUu+vPgYOGCwYcMWkchnU1ZIGCJOAZPoSACH5BAkAAAUALAAAAAAQABAAAAM5WLolwpCJ + EB4ZJqpBBQEBkC2PIgwF12mMwYlsS8TRB8zEqIFhkcc8AE1h0w2PsVJEqTEYaYQZMpYAACH5BAkAAAUA + LAAAAAAQABAAAAM7WLrcroS8ZwwclgknQBgTY3RSqJmNAWAFkT1D8LWvE8+oMYBot/WyQEnxY3hkPEel + IJABio0IcTBEMRIAIfkECQAABQAsAAAAABAAEAAAAzVYutyuhLxnzFRi5su7b8JGWFoQZOM1mFsnDB4x + kBwBBABdiAAgm6fHDWe4ASbDoyH1sOUcCQAh+QQJAAAFACwAAAAAEAAQAAADO1i63K6EvGfMVGLmy7u/ + hHUZUhFy5OcIwNaUWBC0LyAWgDwbwGCwgcFCIGsNZD7CAFYQLAvHoMcwEDoSACH5BAkAAAUALAAAAAAQ + ABAAAAM5WLrcroS8Z8xUYubLOyMAIHVAEACXIZVnKoGA5RXEIHPgeU+DGWSCTUFYMJRsAhOxIbD0fjPB + 4JEAACH5BAUAAAUALAAAAAAQABAAAAM5WLrcK0AoQpwSIUtjbAFZADjSQmRA5T3pqhjD0LlfNqxGNdi4 + GtMNFZAAmNF2rUbJNFBxgBMh1JIAADs= + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/app.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Core/app.config Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,36 @@ + + + + +
+ + + + + + 200000 + + + 30 + + + 5 + + + 10 + + + 5 + + + + + + True + + + Internet Explorer + + + + diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Core/sqlite3.dll Binary file MyDownloader.Core/sqlite3.dll has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AntiVirus/AntiVirusExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AntiVirus/AntiVirusExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; +using System.IO; +using System.Diagnostics; +using MyDownloader.Core; + +namespace MyDownloader.Extension.AntiVirus +{ + public class AntiVirusExtension: IExtension + { + private IAntiVirusParameters parameters; + + #region Constructor + + public AntiVirusExtension(): + this(new AntiVirusParametersSettingsProxy()) + { + } + + public AntiVirusExtension(IAntiVirusParameters parameters) + { + if (parameters == null) + { + throw new ArgumentNullException("parameters"); + } + + this.parameters = parameters; + + DownloadManager.Instance.DownloadEnded += new EventHandler(manager_DownloadEnded); + } + + #endregion + + #region IExtension Members + + public string Name + { + get { return "Anti-virus integration"; } + } + + public IUIExtension UIExtension + { + get + { + return new AntiVirusUIExtension(); + } + } + + #endregion + + #region Methods + + void manager_DownloadEnded(object sender, MyDownloader.Core.DownloaderEventArgs e) + { + if (parameters.CheckFileWithAV) + { + string fileExtension = Path.GetExtension(e.Downloader.LocalFile).ToUpper(); + string[] extensionsToCheck = parameters.FileTypes.ToUpper().Split(';'); + int index = Array.IndexOf(extensionsToCheck, fileExtension); + if (index >= 0) + { + Process.Start(parameters.AVFileName, + String.Format( + "{0} {1}", + parameters.AVParameter, + e.Downloader.LocalFile)); + } + } + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AntiVirus/AntiVirusParametersSettingsProxy.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AntiVirus/AntiVirusParametersSettingsProxy.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Extension.AntiVirus +{ + internal class AntiVirusParametersSettingsProxy : IAntiVirusParameters + { + #region IAntiVirusParameters Members + + public bool CheckFileWithAV + { + get + { + return Settings.Default.CheckFileWithAV; + } + set + { + Settings.Default.CheckFileWithAV = value; + } + } + + public string AVFileName + { + get + { + return Settings.Default.AVFileName; + } + set + { + Settings.Default.AVFileName = value; + } + } + + public string FileTypes + { + get + { + return Settings.Default.FileTypes; + } + set + { + Settings.Default.FileTypes = value; + } + } + + public string AVParameter + { + get + { + return Settings.Default.AVParameter; + } + set + { + Settings.Default.AVParameter = value; + } + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AntiVirus/AntiVirusUIExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AntiVirus/AntiVirusUIExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; +using System.Windows.Forms; +using MyDownloader.Extension.AntiVirus.UI; + +namespace MyDownloader.Extension.AntiVirus +{ + public class AntiVirusUIExtension: IUIExtension + { + #region IUIExtension Members + + public Control[] CreateSettingsView() + { + return new Control[] { new AVOptions() }; + } + + public void PersistSettings(Control[] settingsView) + { + AVOptions options = (AVOptions)settingsView[0]; + Settings.Default.AVParameter = options.AVParameter; + Settings.Default.CheckFileWithAV = options.CheckFileWithAV; + Settings.Default.FileTypes = options.FileTypes; + Settings.Default.AVFileName = options.AVFileName; + Settings.Default.Save(); + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AntiVirus/IAntiVirusParameters.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AntiVirus/IAntiVirusParameters.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Extension.AntiVirus +{ + public interface IAntiVirusParameters + { + bool CheckFileWithAV { get; set; } + + string AVFileName { get; set; } + + string FileTypes { get; set; } + + string AVParameter { get; set; } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AntiVirus/Settings.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AntiVirus/Settings.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,74 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MyDownloader.Extension.AntiVirus { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool CheckFileWithAV { + get { + return ((bool)(this["CheckFileWithAV"])); + } + set { + this["CheckFileWithAV"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string AVFileName { + get { + return ((string)(this["AVFileName"])); + } + set { + this["AVFileName"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string FileTypes { + get { + return ((string)(this["FileTypes"])); + } + set { + this["FileTypes"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string AVParameter { + get { + return ((string)(this["AVParameter"])); + } + set { + this["AVParameter"] = value; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AntiVirus/Settings.settings --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AntiVirus/Settings.settings Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,18 @@ + + + + + + True + + + + + + + + + + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AntiVirus/UI/AVOptions.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AntiVirus/UI/AVOptions.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,141 @@ +namespace MyDownloader.Extension.AntiVirus.UI +{ + partial class AVOptions + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.chkAllowAV = new System.Windows.Forms.CheckBox(); + this.txtAVFileName = new System.Windows.Forms.TextBox(); + this.btnSelAV = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.txtFileTypes = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.txtParameter = new System.Windows.Forms.TextBox(); + this.openFileDlg = new System.Windows.Forms.OpenFileDialog(); + this.SuspendLayout(); + // + // chkAllowAV + // + this.chkAllowAV.AutoSize = true; + this.chkAllowAV.Location = new System.Drawing.Point(3, 3); + this.chkAllowAV.Name = "chkAllowAV"; + this.chkAllowAV.Size = new System.Drawing.Size(233, 17); + this.chkAllowAV.TabIndex = 0; + this.chkAllowAV.Text = "Scan files with AV after finishing downloads:"; + this.chkAllowAV.UseVisualStyleBackColor = true; + this.chkAllowAV.CheckedChanged += new System.EventHandler(this.chkAllowAV_CheckedChanged); + // + // txtAVFileName + // + this.txtAVFileName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtAVFileName.Location = new System.Drawing.Point(4, 21); + this.txtAVFileName.Name = "txtAVFileName"; + this.txtAVFileName.Size = new System.Drawing.Size(284, 20); + this.txtAVFileName.TabIndex = 1; + // + // btnSelAV + // + this.btnSelAV.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnSelAV.Location = new System.Drawing.Point(291, 20); + this.btnSelAV.Name = "btnSelAV"; + this.btnSelAV.Size = new System.Drawing.Size(26, 23); + this.btnSelAV.TabIndex = 2; + this.btnSelAV.Text = "..."; + this.btnSelAV.UseVisualStyleBackColor = true; + this.btnSelAV.Click += new System.EventHandler(this.btnSelAV_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(0, 51); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(93, 13); + this.label1.TabIndex = 3; + this.label1.Text = "Scaning file types:"; + // + // txtFileTypes + // + this.txtFileTypes.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtFileTypes.Location = new System.Drawing.Point(3, 67); + this.txtFileTypes.Name = "txtFileTypes"; + this.txtFileTypes.Size = new System.Drawing.Size(314, 20); + this.txtFileTypes.TabIndex = 4; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(0, 95); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(58, 13); + this.label2.TabIndex = 5; + this.label2.Text = "Parameter:"; + // + // txtParameter + // + this.txtParameter.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtParameter.Location = new System.Drawing.Point(3, 112); + this.txtParameter.Name = "txtParameter"; + this.txtParameter.Size = new System.Drawing.Size(314, 20); + this.txtParameter.TabIndex = 6; + // + // openFileDlg + // + this.openFileDlg.Filter = "Executable|*.exe"; + // + // AVOptions + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.txtParameter); + this.Controls.Add(this.label2); + this.Controls.Add(this.txtFileTypes); + this.Controls.Add(this.label1); + this.Controls.Add(this.btnSelAV); + this.Controls.Add(this.txtAVFileName); + this.Controls.Add(this.chkAllowAV); + this.Name = "AVOptions"; + this.Size = new System.Drawing.Size(320, 236); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.CheckBox chkAllowAV; + private System.Windows.Forms.TextBox txtAVFileName; + private System.Windows.Forms.Button btnSelAV; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox txtFileTypes; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox txtParameter; + private System.Windows.Forms.OpenFileDialog openFileDlg; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AntiVirus/UI/AVOptions.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AntiVirus/UI/AVOptions.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.Extension.AntiVirus.UI +{ + public partial class AVOptions : UserControl + { + public AVOptions() + { + InitializeComponent(); + + this.Text = "Options"; + + CheckFileWithAV = Settings.Default.CheckFileWithAV; + AVFileName = Settings.Default.AVFileName; + FileTypes = Settings.Default.FileTypes; + AVParameter = Settings.Default.AVParameter; + + UpdateControls(); + } + + public bool CheckFileWithAV + { + get + { + return chkAllowAV.Checked; + } + set + { + chkAllowAV.Checked = value; + } + } + + public string AVFileName + { + get + { + return txtAVFileName.Text; + } + set + { + txtAVFileName.Text = value; + } + } + + public string FileTypes + { + get + { + return txtFileTypes.Text; + } + set + { + txtFileTypes.Text = value; + } + } + + public string AVParameter + { + get + { + return txtParameter.Text; + } + set + { + txtParameter.Text = value; + } + } + + private void chkAllowAV_CheckedChanged(object sender, EventArgs e) + { + UpdateControls(); + } + + private void UpdateControls() + { + btnSelAV.Enabled = chkAllowAV.Checked; + txtAVFileName.Enabled = chkAllowAV.Checked; + txtFileTypes.Enabled = chkAllowAV.Checked; + txtParameter.Enabled = chkAllowAV.Checked; + } + + private void btnSelAV_Click(object sender, EventArgs e) + { + if (openFileDlg.ShowDialog() == DialogResult.OK) + { + txtAVFileName.Text = openFileDlg.FileName; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AntiVirus/UI/AVOptions.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AntiVirus/UI/AVOptions.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/AutoDownloadsExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/AutoDownloadsExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,247 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; +using MyDownloader.Core; +using System.Threading; +using MyDownloader.Extension.SpeedLimit; +using MyDownloader.Core.UI; +using System.Diagnostics; +using System.ComponentModel; + +namespace MyDownloader.Extension.AutoDownloads +{ + public class AutoDownloadsExtension: IExtension, IDisposable + { + DayHourMatrix matrix; + private bool active; + private bool needToRestore; + private System.Threading.Timer timer; + private IAutoDownloadsParameters parameters; + + #region IExtension Members + + public string Name + { + get { return "Auto-Downloads"; } + } + + public IUIExtension UIExtension + { + get { return new AutoDownloadsUIExtension(); } + } + + #endregion + + #region Properties + + public bool Active + { + get { return active; } + set + { + active = value; + if (active) + { + StartJobsIfNeeded(); + } + else + { + RestoreIfNecessary(); + } + } + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + RestoreIfNecessary(); + + if (timer != null) + { + timer.Dispose(); + timer = null; + } + } + + #endregion + + #region Methods + + private void PersistList(object state) + { + StartJobsIfNeeded(); + } + + private void LoadTimes() + { + matrix = new DayHourMatrix(parameters.TimesToWork); + } + + void Default_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + if (e.PropertyName == "TimesToWork") + { + LoadTimes(); + } + } + + void Instance_DownloadRemoved(object sender, DownloaderEventArgs e) + { + StartJobsIfNeeded(); + } + + void Instance_DownloadEnded(object sender, DownloaderEventArgs e) + { + StartJobsIfNeeded(); + } + + void Instance_EndAddBatchDownloads(object sender, EventArgs e) + { + StartJobsIfNeeded(); + } + + void Instance_DownloadAdded(object sender, DownloaderEventArgs e) + { + if (!e.WillStart) + { + StartJobsIfNeeded(); + + e.Downloader.StateChanged += delegate(object s, EventArgs ea) + { + if (((Downloader)s).State == DownloaderState.WaitingForReconnect) + { + StartJobsIfNeeded(); + } + }; + } + } + + private int GetActiveJobsCount() + { + int count = 0; + + for (int i = 0; i < DownloadManager.Instance.Downloads.Count; i++) + { + if (DownloadManager.Instance.Downloads[i].IsWorking() && + DownloadManager.Instance.Downloads[i].State != DownloaderState.WaitingForReconnect) + { + count++; + } + } + + return count; + } + + private void StartJobsIfNeeded() + { + if (!Active || DownloadManager.Instance.AddBatchCount > 0) + { + Debug.WriteLine("Leaving StartJobsIfNeeded"); + return; + } + + DateTime now = DateTime.Now; + + EnableMode em = matrix[now.DayOfWeek, now.Hour]; + + if (parameters.WorkOnlyOnSpecifiedTimes && em == EnableMode.Disabled) + { + RestoreIfNecessary(); + return; + } + + if (em == EnableMode.ActiveWithLimit) + { + SpeedLimitExtension limit = (SpeedLimitExtension)AppManager.Instance.Application.GetExtensionByType(typeof(SpeedLimitExtension)); + + if (limit.Parameters.MaxRate != parameters.MaxRateOnTime) + { + //limit.Parameters.Enabled = true; + //limit.Parameters.MaxRate = parameters.MaxRateOnTime; + limit.SetMaxRateTemp(parameters.MaxRateOnTime); + needToRestore = true; + } + } + else + { + RestoreIfNecessary(); + } + + int maxJobs = parameters.MaxJobs; + + using (DownloadManager.Instance.LockDownloadList(false)) + { + int count = GetActiveJobsCount(); + + if (count < maxJobs) + { + for (int i = 0; + (count < maxJobs) && i < DownloadManager.Instance.Downloads.Count; + i++) + { + Downloader d = DownloadManager.Instance.Downloads[i]; + if (d.State != DownloaderState.Ended && ! d.IsWorking()) + { + DownloadManager.Instance.Downloads[i].Start(); + count ++; + } + } + } + } + } + + private void RestoreIfNecessary() + { + if (needToRestore) + { + SpeedLimitExtension limit = (SpeedLimitExtension)AppManager.Instance.Application.GetExtensionByType(typeof(SpeedLimitExtension)); + + limit.RestoreMaxRateFromParameters(); + needToRestore = false; + } + } + + #endregion + + #region Constructor + + public AutoDownloadsExtension(): + this(new AutoDownloadsParametersSettingsProxy()) + { + } + + public AutoDownloadsExtension(IAutoDownloadsParameters parameters) + { + if (parameters == null) + { + throw new ArgumentNullException("parameters"); + } + + this.parameters = parameters; + + parameters.ParameterChanged += new PropertyChangedEventHandler(Default_PropertyChanged); + + DownloadManager.Instance.EndAddBatchDownloads += new EventHandler(Instance_EndAddBatchDownloads); + DownloadManager.Instance.DownloadAdded += new EventHandler(Instance_DownloadAdded); + DownloadManager.Instance.DownloadEnded += new EventHandler(Instance_DownloadEnded); + //DownloadManager.Instance.DownloadRemoved += new EventHandler(Instance_DownloadRemoved); + + LoadTimes(); + + TimerCallback refreshCallBack = new TimerCallback(PersistList); + TimeSpan refreshInterval = TimeSpan.FromMinutes(1); + timer = new Timer(refreshCallBack, null, new TimeSpan(-1), refreshInterval); + + if (parameters.AutoStart) + { + this.Active = true; + } + } + + #endregion + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/AutoDownloadsParametersSettingsProxy.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/AutoDownloadsParametersSettingsProxy.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Extension.AutoDownloads +{ + internal class AutoDownloadsParametersSettingsProxy : IAutoDownloadsParameters + { + #region IAutoDownloadsParameters Members + + public int MaxJobs + { + get + { + return Settings.Default.MaxJobs; + } + set + { + Settings.Default.MaxJobs = value; + OnParameterChanged("MaxJobs"); + } + } + + public bool WorkOnlyOnSpecifiedTimes + { + get + { + return Settings.Default.WorkOnlyOnSpecifiedTimes; + } + set + { + Settings.Default.WorkOnlyOnSpecifiedTimes = value; + OnParameterChanged("WorkOnlyOnSpecifiedTimes"); + } + } + + public string TimesToWork + { + get + { + return Settings.Default.TimesToWork; + } + set + { + Settings.Default.TimesToWork = value; + OnParameterChanged("TimesToWork"); + } + } + + public double MaxRateOnTime + { + get + { + return Settings.Default.MaxRateOnTime; + } + set + { + Settings.Default.MaxRateOnTime = value; + OnParameterChanged("MaxRateOnTime"); + } + } + + public bool AutoStart + { + get + { + return Settings.Default.AutoStart; + } + set + { + Settings.Default.AutoStart = value; + OnParameterChanged("AutoStart"); + } + } + + #endregion + + #region IExtensionParameters Members + + public event System.ComponentModel.PropertyChangedEventHandler ParameterChanged; + + #endregion + + #region Methods + + protected void OnParameterChanged(string propertyname) + { + if (ParameterChanged != null) + { + ParameterChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyname)); + } + } + + void Default_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + OnParameterChanged(e.PropertyName); + } + + #endregion + + public AutoDownloadsParametersSettingsProxy() + { + Settings.Default.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(Default_PropertyChanged); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/AutoDownloadsUIExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/AutoDownloadsUIExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; +using System.Windows.Forms; +using MyDownloader.Extension.AutoDownloads.UI; + +namespace MyDownloader.Extension.AutoDownloads +{ + public class AutoDownloadsUIExtension: IUIExtension + { + #region IUIExtension Members + + public Control[] CreateSettingsView() + { + return new Control[] { new Jobs() }; + } + + public void PersistSettings(Control[] settingsView) + { + Jobs jobs = (Jobs)settingsView[0]; + + Settings.Default.MaxJobs = jobs.MaxJobs; + Settings.Default.WorkOnlyOnSpecifiedTimes = jobs.WorkOnlyOnSpecifiedTimes; + Settings.Default.TimesToWork = jobs.TimesToWork; + Settings.Default.MaxRateOnTime = jobs.MaxRate; + Settings.Default.AutoStart = jobs.AutoStart; + Settings.Default.Save(); + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/DayHourMatrix.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/DayHourMatrix.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Extension.AutoDownloads +{ + [Serializable] + public enum EnableMode: int + { + Active = 1, + ActiveWithLimit, + Disabled + } + + public class DayHourMatrix + { + public const int DAYS = 7; + public const int HOURS = 24; + + private EnableMode[,] enabledAt = new EnableMode[DAYS, HOURS]; + + public DayHourMatrix() + { + } + + public DayHourMatrix(string data) + { + if (data == null || (data = data.Trim()).Length == 0) + { + return; + } + + string[] days = data.Split('|'); + + for (int i = 0; i < days.Length; i++) + { + string[] values = days[i].Split(','); + if (values.Length == 3) + { + int day = int.Parse(values[0]); + int hour = int.Parse(values[1]); + EnableMode em = (EnableMode)int.Parse(values[2]); + + this[(DayOfWeek)day, hour] = em; + } + } + } + + public EnableMode this[DayOfWeek day, int hour] + { + get + { + return enabledAt[(int)day, hour]; + } + set + { + enabledAt[(int)day, hour] = value; + } + } + + public override string ToString() + { + string selected = String.Empty; + + for (int i = 0; i < DayHourMatrix.DAYS; i++) + { + for (int j = 0; j < DayHourMatrix.HOURS; j++) + { + if (this[(DayOfWeek)i, j] != EnableMode.Disabled) + { + if (selected.Length > 0) + { + selected += "|"; + } + + // day,hour,mode|day,hour,mode.... + selected += i + "," + j + "," + (int)this[(DayOfWeek)i, j]; + } + } + } + + return selected; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/IAutoDownloadsParameters.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/IAutoDownloadsParameters.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; + +namespace MyDownloader.Extension.AutoDownloads +{ + public interface IAutoDownloadsParameters : IExtensionParameters + { + int MaxJobs { get; set; } + + bool WorkOnlyOnSpecifiedTimes { get; set; } + + string TimesToWork { get; set; } + + double MaxRateOnTime { get; set; } + + bool AutoStart { get; set; } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/Settings.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/Settings.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,86 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MyDownloader.Extension.AutoDownloads { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("5")] + public int MaxJobs { + get { + return ((int)(this["MaxJobs"])); + } + set { + this["MaxJobs"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool WorkOnlyOnSpecifiedTimes { + get { + return ((bool)(this["WorkOnlyOnSpecifiedTimes"])); + } + set { + this["WorkOnlyOnSpecifiedTimes"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string TimesToWork { + get { + return ((string)(this["TimesToWork"])); + } + set { + this["TimesToWork"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("1")] + public double MaxRateOnTime { + get { + return ((double)(this["MaxRateOnTime"])); + } + set { + this["MaxRateOnTime"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool AutoStart { + get { + return ((bool)(this["AutoStart"])); + } + set { + this["AutoStart"] = value; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/Settings.settings --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/Settings.settings Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,21 @@ + + + + + + 5 + + + False + + + + + + 1 + + + False + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/UI/Jobs.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/UI/Jobs.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,253 @@ +namespace MyDownloader.Extension.AutoDownloads.UI +{ + partial class Jobs + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Jobs)); + MyDownloader.Extension.AutoDownloads.DayHourMatrix dayHourMatrix1 = new MyDownloader.Extension.AutoDownloads.DayHourMatrix(); + this.numMaxJobs = new System.Windows.Forms.NumericUpDown(); + this.label2 = new System.Windows.Forms.Label(); + this.chkUseTime = new System.Windows.Forms.CheckBox(); + this.label1 = new System.Windows.Forms.Label(); + this.panel1 = new System.Windows.Forms.Panel(); + this.panel2 = new System.Windows.Forms.Panel(); + this.label3 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.pnlTime = new System.Windows.Forms.Panel(); + this.label5 = new System.Windows.Forms.Label(); + this.panel3 = new System.Windows.Forms.Panel(); + this.numMaxRate = new System.Windows.Forms.NumericUpDown(); + this.lblMaxRate = new System.Windows.Forms.Label(); + this.chkAutoStart = new System.Windows.Forms.CheckBox(); + this.timeGrid1 = new MyDownloader.Extension.AutoDownloads.UI.TimeGrid(); + ((System.ComponentModel.ISupportInitialize)(this.numMaxJobs)).BeginInit(); + this.pnlTime.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numMaxRate)).BeginInit(); + this.SuspendLayout(); + // + // numMaxJobs + // + this.numMaxJobs.Location = new System.Drawing.Point(0, 41); + this.numMaxJobs.Name = "numMaxJobs"; + this.numMaxJobs.Size = new System.Drawing.Size(96, 20); + this.numMaxJobs.TabIndex = 2; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(-3, 25); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(55, 13); + this.label2.TabIndex = 1; + this.label2.Text = "Max Jobs:"; + // + // chkUseTime + // + this.chkUseTime.AutoSize = true; + this.chkUseTime.Location = new System.Drawing.Point(0, 77); + this.chkUseTime.Name = "chkUseTime"; + this.chkUseTime.Size = new System.Drawing.Size(89, 17); + this.chkUseTime.TabIndex = 3; + this.chkUseTime.Text = "Work only at:"; + this.chkUseTime.UseVisualStyleBackColor = true; + this.chkUseTime.CheckedChanged += new System.EventHandler(this.chkUseTime_CheckedChanged); + // + // label1 + // + this.label1.Dock = System.Windows.Forms.DockStyle.Bottom; + this.label1.Location = new System.Drawing.Point(0, 152); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(400, 75); + this.label1.TabIndex = 20; + this.label1.Text = resources.GetString("label1.Text"); + // + // panel1 + // + this.panel1.BackColor = System.Drawing.Color.Green; + this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.panel1.Location = new System.Drawing.Point(8, 8); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(16, 16); + this.panel1.TabIndex = 21; + // + // panel2 + // + this.panel2.BackColor = System.Drawing.Color.Gray; + this.panel2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.panel2.Location = new System.Drawing.Point(230, 8); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(16, 16); + this.panel2.TabIndex = 22; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(24, 8); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(55, 13); + this.label3.TabIndex = 23; + this.label3.Text = "Full speed"; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(248, 8); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(44, 13); + this.label4.TabIndex = 24; + this.label4.Text = "Turn off"; + // + // pnlTime + // + this.pnlTime.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pnlTime.Controls.Add(this.label5); + this.pnlTime.Controls.Add(this.panel3); + this.pnlTime.Controls.Add(this.panel1); + this.pnlTime.Controls.Add(this.label4); + this.pnlTime.Controls.Add(this.timeGrid1); + this.pnlTime.Controls.Add(this.label3); + this.pnlTime.Controls.Add(this.label1); + this.pnlTime.Controls.Add(this.panel2); + this.pnlTime.Location = new System.Drawing.Point(0, 101); + this.pnlTime.Name = "pnlTime"; + this.pnlTime.Size = new System.Drawing.Size(400, 227); + this.pnlTime.TabIndex = 4; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(136, 8); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(40, 13); + this.label5.TabIndex = 26; + this.label5.Text = "Limited"; + // + // panel3 + // + this.panel3.BackColor = System.Drawing.Color.PaleGreen; + this.panel3.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.panel3.Location = new System.Drawing.Point(117, 8); + this.panel3.Name = "panel3"; + this.panel3.Size = new System.Drawing.Size(16, 16); + this.panel3.TabIndex = 25; + // + // numMaxRate + // + this.numMaxRate.Location = new System.Drawing.Point(3, 344); + this.numMaxRate.Maximum = new decimal(new int[] { + 1000, + 0, + 0, + 0}); + this.numMaxRate.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.numMaxRate.Name = "numMaxRate"; + this.numMaxRate.Size = new System.Drawing.Size(96, 20); + this.numMaxRate.TabIndex = 6; + this.numMaxRate.Value = new decimal(new int[] { + 1, + 0, + 0, + 0}); + // + // lblMaxRate + // + this.lblMaxRate.AutoSize = true; + this.lblMaxRate.Location = new System.Drawing.Point(0, 328); + this.lblMaxRate.Name = "lblMaxRate"; + this.lblMaxRate.Size = new System.Drawing.Size(152, 13); + this.lblMaxRate.TabIndex = 5; + this.lblMaxRate.Text = "Limited Download Rate (kbps):"; + // + // chkAutoStart + // + this.chkAutoStart.AutoSize = true; + this.chkAutoStart.Location = new System.Drawing.Point(0, 0); + this.chkAutoStart.Name = "chkAutoStart"; + this.chkAutoStart.Size = new System.Drawing.Size(196, 17); + this.chkAutoStart.TabIndex = 0; + this.chkAutoStart.Text = "Auto-start auto-downloads at startup"; + this.chkAutoStart.UseVisualStyleBackColor = true; + // + // timeGrid1 + // + this.timeGrid1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.timeGrid1.Location = new System.Drawing.Point(0, 32); + this.timeGrid1.Name = "timeGrid1"; + this.timeGrid1.SelectedTimes = dayHourMatrix1; + this.timeGrid1.Size = new System.Drawing.Size(395, 120); + this.timeGrid1.StartPosition = new System.Drawing.Point(32, 16); + this.timeGrid1.TabIndex = 0; + // + // Jobs + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.chkAutoStart); + this.Controls.Add(this.numMaxRate); + this.Controls.Add(this.lblMaxRate); + this.Controls.Add(this.pnlTime); + this.Controls.Add(this.chkUseTime); + this.Controls.Add(this.numMaxJobs); + this.Controls.Add(this.label2); + this.Name = "Jobs"; + this.Size = new System.Drawing.Size(400, 403); + ((System.ComponentModel.ISupportInitialize)(this.numMaxJobs)).EndInit(); + this.pnlTime.ResumeLayout(false); + this.pnlTime.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numMaxRate)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.NumericUpDown numMaxJobs; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.CheckBox chkUseTime; + private TimeGrid timeGrid1; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Panel panel2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Panel pnlTime; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Panel panel3; + private System.Windows.Forms.NumericUpDown numMaxRate; + private System.Windows.Forms.Label lblMaxRate; + private System.Windows.Forms.CheckBox chkAutoStart; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/UI/Jobs.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/UI/Jobs.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.Extension.AutoDownloads.UI +{ + public partial class Jobs : UserControl + { + public Jobs() + { + InitializeComponent(); + + Text = "Auto-Downloads"; + + numMaxJobs.Value = Settings.Default.MaxJobs; + chkUseTime.Checked = Settings.Default.WorkOnlyOnSpecifiedTimes; + timeGrid1.SelectedTimes = new DayHourMatrix(Settings.Default.TimesToWork); + numMaxRate.Value = (decimal)(Math.Max(Settings.Default.MaxRateOnTime, 1024) / 1024.0); + chkAutoStart.Checked = Settings.Default.AutoStart; + + UpdateUI(); + } + + private void chkUseTime_CheckedChanged(object sender, EventArgs e) + { + UpdateUI(); + } + + private void UpdateUI() + { + pnlTime.Enabled = chkUseTime.Checked; + } + + public int MaxJobs + { + get { return (int)numMaxJobs.Value; } + } + + public double MaxRate + { + get { return ((double)numMaxRate.Value) * 1024; } + } + + public bool WorkOnlyOnSpecifiedTimes + { + get { return chkUseTime.Checked; } + } + + public bool AutoStart + { + get { return chkAutoStart.Checked; } + } + + public string TimesToWork + { + get { return timeGrid1.SelectedTimes.ToString(); } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/UI/Jobs.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/UI/Jobs.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + * Left button: hold left button and move to selected the time +* Left button + SHIFT: hold left button and move to selected the time with limited speed +* Right button: hold left button and move to unselected the time + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/UI/ScheduledDownloadEnabler.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/UI/ScheduledDownloadEnabler.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,130 @@ +namespace MyDownloader.Extension.AutoDownloads.UI +{ + partial class ScheduledDownloadEnabler + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ScheduledDownloadEnabler)); + this.chkDisableWorkOnlyAt = new System.Windows.Forms.CheckBox(); + this.numMaxJobs = new System.Windows.Forms.NumericUpDown(); + this.chkOverrideMaxActive = new System.Windows.Forms.CheckBox(); + this.chkStartScheduler = new System.Windows.Forms.CheckBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.label2 = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.numMaxJobs)).BeginInit(); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // chkDisableWorkOnlyAt + // + this.chkDisableWorkOnlyAt.AutoSize = true; + this.chkDisableWorkOnlyAt.Location = new System.Drawing.Point(0, 72); + this.chkDisableWorkOnlyAt.Name = "chkDisableWorkOnlyAt"; + this.chkDisableWorkOnlyAt.Size = new System.Drawing.Size(299, 17); + this.chkDisableWorkOnlyAt.TabIndex = 3; + this.chkDisableWorkOnlyAt.Text = "Disable \"Work only at\" configuration and work at any time"; + this.chkDisableWorkOnlyAt.UseVisualStyleBackColor = true; + // + // numMaxJobs + // + this.numMaxJobs.Location = new System.Drawing.Point(0, 46); + this.numMaxJobs.Name = "numMaxJobs"; + this.numMaxJobs.Size = new System.Drawing.Size(96, 20); + this.numMaxJobs.TabIndex = 2; + // + // chkOverrideMaxActive + // + this.chkOverrideMaxActive.AutoSize = true; + this.chkOverrideMaxActive.Location = new System.Drawing.Point(0, 23); + this.chkOverrideMaxActive.Name = "chkOverrideMaxActive"; + this.chkOverrideMaxActive.Size = new System.Drawing.Size(189, 17); + this.chkOverrideMaxActive.TabIndex = 1; + this.chkOverrideMaxActive.Text = "Override max active downloads to:"; + this.chkOverrideMaxActive.UseVisualStyleBackColor = true; + this.chkOverrideMaxActive.CheckedChanged += new System.EventHandler(this.chkOverrideMaxActive_CheckedChanged); + // + // chkStartScheduler + // + this.chkStartScheduler.AutoSize = true; + this.chkStartScheduler.Location = new System.Drawing.Point(0, 0); + this.chkStartScheduler.Name = "chkStartScheduler"; + this.chkStartScheduler.Size = new System.Drawing.Size(126, 17); + this.chkStartScheduler.TabIndex = 0; + this.chkStartScheduler.Text = "Start auto-downloads"; + this.chkStartScheduler.UseVisualStyleBackColor = true; + this.chkStartScheduler.CheckedChanged += new System.EventHandler(this.chkStartScheduler_CheckedChanged); + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.BackColor = System.Drawing.SystemColors.Info; + this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.panel1.Controls.Add(this.label2); + this.panel1.Location = new System.Drawing.Point(0, 95); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(393, 66); + this.panel1.TabIndex = 34; + // + // label2 + // + this.label2.Dock = System.Windows.Forms.DockStyle.Fill; + this.label2.Location = new System.Drawing.Point(0, 0); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(391, 64); + this.label2.TabIndex = 0; + this.label2.Text = resources.GetString("label2.Text"); + // + // ScheduledDownloadEnabler + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.chkDisableWorkOnlyAt); + this.Controls.Add(this.numMaxJobs); + this.Controls.Add(this.chkOverrideMaxActive); + this.Controls.Add(this.chkStartScheduler); + this.Controls.Add(this.panel1); + this.Name = "ScheduledDownloadEnabler"; + this.Size = new System.Drawing.Size(393, 163); + this.Load += new System.EventHandler(this.ScheduledDownloadEnabler_Load); + ((System.ComponentModel.ISupportInitialize)(this.numMaxJobs)).EndInit(); + this.panel1.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.CheckBox chkDisableWorkOnlyAt; + private System.Windows.Forms.NumericUpDown numMaxJobs; + private System.Windows.Forms.CheckBox chkOverrideMaxActive; + private System.Windows.Forms.CheckBox chkStartScheduler; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Label label2; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/UI/ScheduledDownloadEnabler.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/UI/ScheduledDownloadEnabler.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using MyDownloader.Core.UI; + +namespace MyDownloader.Extension.AutoDownloads.UI +{ + public partial class ScheduledDownloadEnabler : UserControl + { + public ScheduledDownloadEnabler() + { + InitializeComponent(); + } + + private void ScheduledDownloadEnabler_Load(object sender, EventArgs e) + { + numMaxJobs.Value = Settings.Default.MaxJobs; + + UpdateUI(); + } + + private void chkStartScheduler_CheckedChanged(object sender, EventArgs e) + { + UpdateUI(); + } + + private void chkOverrideMaxActive_CheckedChanged(object sender, EventArgs e) + { + UpdateUI(); + } + + private void UpdateUI() + { + chkDisableWorkOnlyAt.Enabled = chkStartScheduler.Checked && Settings.Default.WorkOnlyOnSpecifiedTimes; + chkOverrideMaxActive.Enabled = chkStartScheduler.Checked; + numMaxJobs.Enabled = chkStartScheduler.Checked && chkOverrideMaxActive.Checked; + panel1.Enabled = chkStartScheduler.Checked; + } + + public void ApplySettings() + { + if (chkStartScheduler.Checked) + { + bool needToSave = false; + + if (chkOverrideMaxActive.Checked) + { + Settings.Default.MaxJobs = (int)numMaxJobs.Value; + needToSave = true; + } + if (chkDisableWorkOnlyAt.Checked) + { + Settings.Default.WorkOnlyOnSpecifiedTimes = false; + needToSave = true; + } + + if (needToSave) + { + Settings.Default.Save(); + } + + AutoDownloadsExtension scheduler = (AutoDownloadsExtension)AppManager.Instance. + Application.GetExtensionByType(typeof(AutoDownloadsExtension)); + scheduler.Active = true; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/UI/ScheduledDownloadEnabler.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/UI/ScheduledDownloadEnabler.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Starting the "Auto-Downloads" may not necessarily start downloads, downloads only will be started if the number of active is lower than max active downloads and if downloads are allowed at this time (as configured tough options dialog). + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/UI/TimeGrid.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/UI/TimeGrid.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,49 @@ +namespace MyDownloader.Extension.AutoDownloads.UI +{ + partial class TimeGrid + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // TimeGrid + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.DoubleBuffered = true; + this.Name = "TimeGrid"; + this.Size = new System.Drawing.Size(532, 258); + this.Layout += new System.Windows.Forms.LayoutEventHandler(this.TimeGrid_Layout); + this.Load += new System.EventHandler(this.TimeGrid_Load); + this.ResumeLayout(false); + + } + + #endregion + + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/UI/TimeGrid.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/UI/TimeGrid.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,218 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using System.Diagnostics; + +namespace MyDownloader.Extension.AutoDownloads.UI +{ + public partial class TimeGrid : UserControl + { + object Selected = new object(); + object Unselected = new object(); + object SelectedWithLimit = new object(); + + Color UnselectedColor = Color.DarkGray; + Color SelectedColor = Color.Green; + Color SelectedWithLimitColor = Color.PaleGreen; + + private Point startPosition; + + // days x hours + PictureBox[,] timePanels = new PictureBox[DayHourMatrix.DAYS, DayHourMatrix.HOURS]; + Label[] timeLbs = new Label[DayHourMatrix.HOURS]; + Label[] dayLbl = new Label[DayHourMatrix.DAYS]; + PictureBox lastPanel; + DayHourMatrix matrix = new DayHourMatrix(); + + public TimeGrid() + { + InitializeComponent(); + + this.SuspendLayout(); + + for (int i = 0; i < DayHourMatrix.DAYS; i++) + { + for (int j = 0; j < DayHourMatrix.HOURS; j++) + { + timePanels[i, j] = new PictureBox(); + InitPanel(timePanels[i, j]); + } + } + + for (int i = 0; i < DayHourMatrix.DAYS; i++) + { + dayLbl[i] = new Label(); + dayLbl[i].AutoSize = false; + dayLbl[i].TextAlign = ContentAlignment.MiddleLeft; + dayLbl[i].Text = ((DayOfWeek)i).ToString().Substring(0, 3); + dayLbl[i].Visible = true; + this.Controls.Add(dayLbl[i]); + } + + for (int i = 0; i < DayHourMatrix.HOURS; i++) + { + timeLbs[i] = new Label(); + timeLbs[i].AutoSize = true; + //timeLbs[i].TextAlign = ContentAlignment.MiddleCenter; + timeLbs[i].Text = i.ToString("0#"); + timeLbs[i].Visible = true; + this.Controls.Add(timeLbs[i]); + } + + this.ResumeLayout(true); + } + + public Point StartPosition + { + get + { + return startPosition; + } + set + { + startPosition = value; + this.layoutPanels(); + } + } + + public DayHourMatrix SelectedTimes + { + get + { + return matrix; + } + set + { + matrix = value; + + // unselect all + for (int i = 0; i < DayHourMatrix.DAYS; i++) + { + for (int j = 0; j < DayHourMatrix.HOURS; j++) + { + object v = Unselected; + + if (matrix != null) + { + EnableMode em = matrix[(DayOfWeek)i, j]; + if (em == EnableMode.Active) + { + v = Selected; + } + if (em == EnableMode.ActiveWithLimit) + { + v = SelectedWithLimit; + } + } + + SetPanel(timePanels[i, j], v); + } + } + } + } + + private void InitPanel(PictureBox p) + { + p.BackColor = UnselectedColor; + p.BorderStyle = BorderStyle.FixedSingle; + p.Visible = true; + p.MouseMove += new MouseEventHandler(panel_MouseMove); + p.Tag = Unselected; + this.Controls.Add(p); + } + + void panel_MouseMove(object sender, MouseEventArgs e) + { + Point pt = PointToClient(Cursor.Position); + + pt.Offset(-this.StartPosition.X, -this.StartPosition.Y); + + int hour = Math.Max(0, Math.Min(pt.X / timePanels[0, 0].Width, DayHourMatrix.HOURS - 1)); + int day = Math.Max(0, Math.Min(pt.Y / timePanels[0, 0].Height, DayHourMatrix.DAYS - 1)); + + PictureBox p = timePanels[day, hour]; + + if (p == lastPanel) return; + + if (e.Button == MouseButtons.Left) + { + if ((Control.ModifierKeys == Keys.Shift)) + { + SetPanel(p, SelectedWithLimit); + matrix[(DayOfWeek)day, hour] = EnableMode.ActiveWithLimit; + } + else + { + SetPanel(p, Selected); + matrix[(DayOfWeek)day, hour] = EnableMode.Active; + } + } + else if (e.Button == MouseButtons.Right) + { + SetPanel(p, Unselected); + matrix[(DayOfWeek)day, hour] = EnableMode.Disabled; + } + } + + private void SetPanel(PictureBox p, object action) + { + if (action == null) action = p.Tag; + + if (action == Selected) + { + p.Tag = Selected; + p.BackColor = SelectedColor; + } + else if (action == Unselected) + { + p.Tag = Unselected; + p.BackColor = UnselectedColor; + } + else + { + p.Tag = SelectedWithLimit; + p.BackColor = SelectedWithLimitColor; + } + + lastPanel = p; + } + + private void layoutPanels() + { + int width = (this.Width - StartPosition.X) / DayHourMatrix.HOURS; + int height = (this.Height - StartPosition.Y) / DayHourMatrix.DAYS; + + for (int i = 0; i < DayHourMatrix.DAYS; i++) + { + dayLbl[i].Location = new Point(0, i * height + StartPosition.Y); + dayLbl[i].Size = new Size(StartPosition.X, height); + + for (int j = 0; j < DayHourMatrix.HOURS; j++) + { + timePanels[i, j].Location = new Point(j * width + StartPosition.X, i * height + StartPosition.Y); + timePanels[i, j].Size = new Size(width, height); + } + } + + for (int j = 0; j < DayHourMatrix.HOURS; j++) + { + timeLbs[j].Location = new Point(j * width + StartPosition.X, 0); + timeLbs[j].Size = new Size(width, StartPosition.Y); + } + } + + private void TimeGrid_Layout(object sender, LayoutEventArgs e) + { + layoutPanels(); + } + + private void TimeGrid_Load(object sender, EventArgs e) + { + layoutPanels(); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/AutoDownloads/UI/TimeGrid.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/AutoDownloads/UI/TimeGrid.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/MyDownloader.Extension.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/MyDownloader.Extension.csproj Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,366 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {FEA18B6C-491F-401A-A06B-AE47888FF288} + Library + Properties + MyDownloader.Extension + MyDownloader.Extension + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + x86 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + AnyCPU + + + + False + ..\ICSharpCode.SharpZipLib.dll + + + False + bin\Release\MyDownloader.Core.dll + + + + + + + + + + + + + UserControl + + + AVOptions.cs + + + + + Settings.settings + True + True + + + + + + + UserControl + + + SoundChooser.cs + + + Code + + + Code + + + Code + + + + Code + + + Code + + + + + + + + + UserControl + + + Proxy.cs + + + Settings.settings + True + True + + + + + + + + + + + + Settings.settings + True + True + + + + UserControl + + + SoundsOptions.cs + + + UserControl + + + XPBalloonOptions.cs + + + + + + UserControl + + + Jobs.cs + + + UserControl + + + ScheduledDownloadEnabler.cs + + + + + True + True + Settings.settings + + + UserControl + + + TimeGrid.cs + + + + UserControl + + + LimitCfg.cs + + + + + Form + + + SetSpeedLimitDialog.cs + + + True + True + Settings.settings + + + + + + + + + + + UserControl + + + VideoFormatCtrl.cs + + + Form + + + NewVideoDownload.cs + + + Form + + + SupportedVideoSitesForm.cs + + + + + + + True + True + Settings.settings + + + + + UserControl + + + WindowsIntegrationUI.cs + + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + AVOptions.cs + Designer + + + Designer + SoundChooser.cs + + + SoundsOptions.cs + Designer + + + XPBalloonOptions.cs + Designer + + + Designer + Jobs.cs + + + ScheduledDownloadEnabler.cs + Designer + + + Designer + TimeGrid.cs + + + Proxy.cs + Designer + + + Designer + LimitCfg.cs + + + Designer + SetSpeedLimitDialog.cs + + + + + + + + Designer + VideoFormatCtrl.cs + + + NewVideoDownload.cs + Designer + + + SupportedVideoSitesForm.cs + Designer + + + WindowsIntegrationUI.cs + Designer + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/Helpers/BalloonHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/Helpers/BalloonHelper.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core; +using MyDownloader.Core.UI; +using System.Windows.Forms; + +namespace MyDownloader.Extension.Notifications.Helpers +{ + class BalloonHelper + { + private static INotificationsExtensionParameters parameters; + + static void Instance_DownloadEnded(object sender, DownloaderEventArgs e) + { + if (parameters.ShowBallon && + AppManager.Instance.Application.NotifyIcon.Visible) + { + AppManager.Instance.Application.NotifyIcon.ShowBalloonTip( + parameters.BallonTimeout, + AppManager.Instance.Application.MainForm.Text, + String.Format("Download finished: {0}", e.Downloader.LocalFile), + ToolTipIcon.Info); + } + } + + public static void Start(INotificationsExtensionParameters parameters) + { + BalloonHelper.parameters = parameters; + + DownloadManager.Instance.DownloadEnded += new EventHandler(Instance_DownloadEnded); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/Helpers/SoundHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/Helpers/SoundHelper.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core; + +namespace MyDownloader.Extension.Notifications.Helpers +{ + class SoundHelper + { + private static INotificationsExtensionParameters parameters; + + public static void PlayWav(string fileName) + { + if (!String.IsNullOrEmpty(fileName)) + { + new System.Media.SoundPlayer(fileName).Play(); + } + } + + static void Instance_DownloadRemoved(object sender, DownloaderEventArgs e) + { + PlayWav(parameters.DownloadRemovedSoundPath); + } + + static void Instance_DownloadEnded(object sender, DownloaderEventArgs e) + { + PlayWav(parameters.DownloadEndedSoundPath); + } + + static void Instance_DownloadAdded(object sender, DownloaderEventArgs e) + { + PlayWav(parameters.DownloadAddedSoundPath); + } + + public static void Start(INotificationsExtensionParameters parameters) + { + SoundHelper.parameters = parameters; + + DownloadManager.Instance.DownloadAdded += new EventHandler(Instance_DownloadAdded); + DownloadManager.Instance.DownloadEnded += new EventHandler(Instance_DownloadEnded); + DownloadManager.Instance.DownloadRemoved += new EventHandler(Instance_DownloadRemoved); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/INotificationsExtensionParameters.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/INotificationsExtensionParameters.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Extension.Notifications +{ + public interface INotificationsExtensionParameters + { + string DownloadAddedSoundPath { get; set; } + + string DownloadRemovedSoundPath { get; set; } + + string DownloadEndedSoundPath { get; set; } + + bool ShowBallon { get; set; } + + int BallonTimeout { get; set; } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/NotificationsExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/NotificationsExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; +using MyDownloader.Core; +using MyDownloader.Extension.Notifications.Helpers; + +namespace MyDownloader.Extension.Notifications +{ + public class NotificationsExtension: IExtension + { + #region IExtension Members + + public string Name + { + get { return "Notifications"; } + } + + public IUIExtension UIExtension + { + get { return new NotificationsUIExtension(); } + } + + #endregion + + #region Constructor + + public NotificationsExtension(INotificationsExtensionParameters parameters) + { + if (parameters == null) + { + throw new ArgumentNullException("parameters"); + } + + SoundHelper.Start(parameters); + BalloonHelper.Start(parameters); + } + + public NotificationsExtension(): + this(new NotificationsExtensionParametersSettingsProxy()) + { + + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/NotificationsExtensionParametersSettingsProxy.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/NotificationsExtensionParametersSettingsProxy.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Extension.Notifications +{ + internal class NotificationsExtensionParametersSettingsProxy: INotificationsExtensionParameters + { + #region INotificationsExtensionParameters Members + + public string DownloadAddedSoundPath + { + get + { + return Settings.Default.DownloadAddedSound; + } + set + { + Settings.Default.DownloadAddedSound = value; + } + } + + public string DownloadRemovedSoundPath + { + get + { + return Settings.Default.DownloadRemovedSound; + } + set + { + Settings.Default.DownloadRemovedSound = value; + } + } + + public string DownloadEndedSoundPath + { + get + { + return Settings.Default.DownloadEndedSound; + } + set + { + Settings.Default.DownloadEndedSound = value; + } + } + + public bool ShowBallon + { + get + { + return Settings.Default.ShowBallon; + } + set + { + Settings.Default.ShowBallon = value; + } + } + + public int BallonTimeout + { + get + { + return Settings.Default.BallonTimeout; + } + set + { + Settings.Default.BallonTimeout = value; + } + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/NotificationsUIExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/NotificationsUIExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; +using System.Windows.Forms; +using MyDownloader.Extension.Notifications.UI; + +namespace MyDownloader.Extension.Notifications +{ + public class NotificationsUIExtension : IUIExtension + { + #region IUIExtension Members + + public Control[] CreateSettingsView() + { + return new Control[] { new SoundsOptions(), new XPBalloonOptions() }; + } + + public void PersistSettings(Control[] settingsView) + { + SoundsOptions sounds = (SoundsOptions)settingsView[0]; + XPBalloonOptions ballon = (XPBalloonOptions)settingsView[1]; + + Settings.Default.DownloadAddedSound = sounds.DownloadAdded; + Settings.Default.DownloadRemovedSound = sounds.DownloadRemoved; + Settings.Default.DownloadEndedSound = sounds.DownloadEnded; + + Settings.Default.ShowBallon = ballon.ShowBallon; + Settings.Default.BallonTimeout = ballon.BallonTimeout; + + Settings.Default.Save(); + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/Settings.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/Settings.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,86 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MyDownloader.Extension.Notifications { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string DownloadAddedSound { + get { + return ((string)(this["DownloadAddedSound"])); + } + set { + this["DownloadAddedSound"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string DownloadRemovedSound { + get { + return ((string)(this["DownloadRemovedSound"])); + } + set { + this["DownloadRemovedSound"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string DownloadEndedSound { + get { + return ((string)(this["DownloadEndedSound"])); + } + set { + this["DownloadEndedSound"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool ShowBallon { + get { + return ((bool)(this["ShowBallon"])); + } + set { + this["ShowBallon"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("3000")] + public int BallonTimeout { + get { + return ((int)(this["BallonTimeout"])); + } + set { + this["BallonTimeout"] = value; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/Settings.settings --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/Settings.settings Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + True + + + 3000 + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/UI/SoundChooser.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/UI/SoundChooser.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,105 @@ +namespace MyDownloader.Extension.Notifications.UI +{ + partial class SoundChooser + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.lblText = new System.Windows.Forms.Label(); + this.btnPreview = new System.Windows.Forms.Button(); + this.txtSound = new System.Windows.Forms.TextBox(); + this.btnSelect = new System.Windows.Forms.Button(); + this.openFDlg = new System.Windows.Forms.OpenFileDialog(); + this.SuspendLayout(); + // + // lblText + // + this.lblText.AutoSize = true; + this.lblText.Location = new System.Drawing.Point(-3, 0); + this.lblText.Name = "lblText"; + this.lblText.Size = new System.Drawing.Size(35, 13); + this.lblText.TabIndex = 0; + this.lblText.Text = "label1"; + // + // btnPreview + // + this.btnPreview.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnPreview.Location = new System.Drawing.Point(264, 14); + this.btnPreview.Name = "btnPreview"; + this.btnPreview.Size = new System.Drawing.Size(75, 23); + this.btnPreview.TabIndex = 3; + this.btnPreview.Text = "Preview"; + this.btnPreview.UseVisualStyleBackColor = true; + this.btnPreview.Click += new System.EventHandler(this.btnPreview_Click); + // + // txtSound + // + this.txtSound.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtSound.Location = new System.Drawing.Point(0, 16); + this.txtSound.Name = "txtSound"; + this.txtSound.Size = new System.Drawing.Size(230, 20); + this.txtSound.TabIndex = 1; + // + // btnSelect + // + this.btnSelect.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnSelect.Location = new System.Drawing.Point(234, 14); + this.btnSelect.Name = "btnSelect"; + this.btnSelect.Size = new System.Drawing.Size(27, 23); + this.btnSelect.TabIndex = 2; + this.btnSelect.Text = "..."; + this.btnSelect.UseVisualStyleBackColor = true; + this.btnSelect.Click += new System.EventHandler(this.btnSelect_Click); + // + // openFDlg + // + this.openFDlg.Filter = "Wav Files (*.wav)|*.wav"; + // + // SoundChooser + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.btnSelect); + this.Controls.Add(this.txtSound); + this.Controls.Add(this.btnPreview); + this.Controls.Add(this.lblText); + this.Name = "SoundChooser"; + this.Size = new System.Drawing.Size(341, 41); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label lblText; + private System.Windows.Forms.Button btnPreview; + private System.Windows.Forms.TextBox txtSound; + private System.Windows.Forms.Button btnSelect; + private System.Windows.Forms.OpenFileDialog openFDlg; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/UI/SoundChooser.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/UI/SoundChooser.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using MyDownloader.Extension.Notifications.Helpers; + +namespace MyDownloader.Extension.Notifications.UI +{ + public partial class SoundChooser : UserControl + { + public SoundChooser() + { + InitializeComponent(); + } + + [EditorBrowsable(EditorBrowsableState.Always)] + [Browsable(true)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public override string Text + { + get + { + return lblText.Text; + } + set + { + lblText.Text = value; + } + } + + public string FileName + { + get + { + return txtSound.Text; + } + set + { + txtSound.Text = value; + } + } + + private void btnSelect_Click(object sender, EventArgs e) + { + if (openFDlg.ShowDialog() == DialogResult.OK) + { + txtSound.Text = openFDlg.FileName; + } + } + + private void btnPreview_Click(object sender, EventArgs e) + { + SoundHelper.PlayWav(txtSound.Text); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/UI/SoundChooser.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/UI/SoundChooser.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/UI/SoundsOptions.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/UI/SoundsOptions.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,95 @@ +namespace MyDownloader.Extension.Notifications.UI +{ + partial class SoundsOptions + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.openFDlg = new System.Windows.Forms.OpenFileDialog(); + this.soundChooserEnded = new MyDownloader.Extension.Notifications.UI.SoundChooser(); + this.soundChooserRemoved = new MyDownloader.Extension.Notifications.UI.SoundChooser(); + this.soundChooserAdded = new MyDownloader.Extension.Notifications.UI.SoundChooser(); + this.SuspendLayout(); + // + // openFDlg + // + this.openFDlg.Filter = "Wav Files (*.wav)|*.wav"; + // + // soundChooserEnded + // + this.soundChooserEnded.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.soundChooserEnded.FileName = ""; + this.soundChooserEnded.Location = new System.Drawing.Point(3, 94); + this.soundChooserEnded.Name = "soundChooserEnded"; + this.soundChooserEnded.Size = new System.Drawing.Size(365, 41); + this.soundChooserEnded.TabIndex = 2; + this.soundChooserEnded.Text = "Download Ended"; + // + // soundChooserRemoved + // + this.soundChooserRemoved.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.soundChooserRemoved.FileName = ""; + this.soundChooserRemoved.Location = new System.Drawing.Point(3, 47); + this.soundChooserRemoved.Name = "soundChooserRemoved"; + this.soundChooserRemoved.Size = new System.Drawing.Size(365, 41); + this.soundChooserRemoved.TabIndex = 1; + this.soundChooserRemoved.Text = "Download Removed"; + // + // soundChooserAdded + // + this.soundChooserAdded.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.soundChooserAdded.FileName = ""; + this.soundChooserAdded.Location = new System.Drawing.Point(3, 0); + this.soundChooserAdded.Name = "soundChooserAdded"; + this.soundChooserAdded.Size = new System.Drawing.Size(365, 41); + this.soundChooserAdded.TabIndex = 0; + this.soundChooserAdded.Text = "Download Added"; + // + // SoundsOptions + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.soundChooserEnded); + this.Controls.Add(this.soundChooserRemoved); + this.Controls.Add(this.soundChooserAdded); + this.Name = "SoundsOptions"; + this.Size = new System.Drawing.Size(369, 226); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.OpenFileDialog openFDlg; + private SoundChooser soundChooserAdded; + private SoundChooser soundChooserRemoved; + private SoundChooser soundChooserEnded; + + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/UI/SoundsOptions.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/UI/SoundsOptions.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.Extension.Notifications.UI +{ + public partial class SoundsOptions : UserControl + { + public SoundsOptions() + { + this.Text = "Sounds"; + + InitializeComponent(); + + soundChooserAdded.FileName = Settings.Default.DownloadAddedSound; + soundChooserRemoved.FileName = Settings.Default.DownloadRemovedSound; + soundChooserEnded.FileName = Settings.Default.DownloadEndedSound; + } + + public string DownloadAdded + { + get + { + return soundChooserAdded.FileName; + } + } + + public string DownloadRemoved + { + get + { + return soundChooserRemoved.FileName; + } + } + + public string DownloadEnded + { + get + { + return soundChooserEnded.FileName; + } + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/UI/SoundsOptions.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/UI/SoundsOptions.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/UI/XPBalloonOptions.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/UI/XPBalloonOptions.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,88 @@ +namespace MyDownloader.Extension.Notifications.UI +{ + partial class XPBalloonOptions + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.chkBallon = new System.Windows.Forms.CheckBox(); + this.label1 = new System.Windows.Forms.Label(); + this.numDuration = new System.Windows.Forms.NumericUpDown(); + ((System.ComponentModel.ISupportInitialize)(this.numDuration)).BeginInit(); + this.SuspendLayout(); + // + // chkBallon + // + this.chkBallon.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.chkBallon.AutoEllipsis = true; + this.chkBallon.CheckAlign = System.Drawing.ContentAlignment.TopLeft; + this.chkBallon.Location = new System.Drawing.Point(0, 3); + this.chkBallon.Name = "chkBallon"; + this.chkBallon.Size = new System.Drawing.Size(294, 19); + this.chkBallon.TabIndex = 0; + this.chkBallon.Text = "Show XP ballon when download finishes"; + this.chkBallon.TextAlign = System.Drawing.ContentAlignment.TopLeft; + this.chkBallon.UseVisualStyleBackColor = true; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(-3, 30); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(50, 13); + this.label1.TabIndex = 1; + this.label1.Text = "Duration:"; + // + // numDuration + // + this.numDuration.Location = new System.Drawing.Point(0, 46); + this.numDuration.Name = "numDuration"; + this.numDuration.Size = new System.Drawing.Size(120, 20); + this.numDuration.TabIndex = 2; + // + // XPBalloonOptions + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.numDuration); + this.Controls.Add(this.label1); + this.Controls.Add(this.chkBallon); + this.Name = "XPBalloonOptions"; + this.Size = new System.Drawing.Size(294, 150); + ((System.ComponentModel.ISupportInitialize)(this.numDuration)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.CheckBox chkBallon; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.NumericUpDown numDuration; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/UI/XPBalloonOptions.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/UI/XPBalloonOptions.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.Extension.Notifications.UI +{ + public partial class XPBalloonOptions : UserControl + { + public XPBalloonOptions() + { + this.Text = "Balloon"; + + InitializeComponent(); + + chkBallon.Checked = Settings.Default.ShowBallon; + numDuration.Value = Settings.Default.BallonTimeout / 1000; + } + + public bool ShowBallon + { + get { return chkBallon.Checked; } + } + + public int BallonTimeout + { + get { return (int)numDuration.Value * 1000; } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Notifications/UI/XPBalloonOptions.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Notifications/UI/XPBalloonOptions.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/PersistedList/PersistedListExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/PersistedList/PersistedListExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,249 @@ +using System; +using System.Threading; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; +using MyDownloader.Core; +using System.IO; +using System.Runtime.InteropServices; +using System.Xml.Serialization; +using MyDownloader.Core.Instrumentation; +using System.Diagnostics; + +namespace MyDownloader.Extension.PersistedList +{ + public class PersistedListExtension: IExtension, IDisposable + { + [Serializable] + public class DownloadItem + { + public ResourceLocation rl; + + public ResourceLocation[] mirrors; + + [XmlAttribute("lf")] + public string LocalFile; + + public RemoteFileInfo remoteInfo; + + [XmlAttribute("segCnt")] + public int requestedSegments; + + [XmlAttribute("dt")] + public DateTime createdDateTime; + + public SegmentItem[] Segments; + + public SerializableDictionary extendedProperties; + } + + [Serializable] + public class SegmentItem + { + [XmlAttribute("i")] + public int Index; + + [XmlAttribute("isp")] + public long InitialStartPositon; + + [XmlAttribute("sp")] + public long StartPositon; + + [XmlAttribute("ep")] + public long EndPosition; + } + + private const int SaveListIntervalInSeconds = 120; + + private XmlSerializer serializer; + private System.Threading.Timer timer; + + private object SaveFromDispose = new object(); + private object SaveFromTimer = new object(); + private object SaveFromListChange = new object(); + + #region IExtension Members + + public string Name + { + get { return "Persisted Download List"; } + } + + public IUIExtension UIExtension + { + get { return null; } + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + if (timer != null) + { + timer.Dispose(); + timer = null; + } + + DownloadManager.Instance.PauseAll(); + + PersistList(SaveFromDispose); + } + + #endregion + + #region Methods + + private void PersistList(object state) + { + List downloadsToSave = new List(); + + using (DownloadManager.Instance.LockDownloadList(false)) + { + IList downloads = DownloadManager.Instance.Downloads; + + for (int i = 0; i < downloads.Count; i++) + { + if (downloads[i].State == DownloaderState.Ended) + { + continue; + } + + Downloader downloader = downloads[i]; + + DownloadItem di = new DownloadItem(); + di.LocalFile = downloader.LocalFile; + di.rl = downloader.ResourceLocation; + di.mirrors = downloader.Mirrors.ToArray(); + di.remoteInfo = downloader.RemoteFileInfo; + di.requestedSegments = downloader.RequestedSegments; + di.createdDateTime = downloader.CreatedDateTime; + di.extendedProperties = new SerializableDictionary(downloader.ExtendedProperties); + + using (downloader.LockSegments()) + { + di.Segments = new SegmentItem[downloader.Segments.Count]; + + for (int j = 0; j < downloader.Segments.Count; j++) + { + SegmentItem si = new SegmentItem(); + Segment seg = downloader.Segments[j]; + + si.Index = seg.Index; + si.InitialStartPositon = seg.InitialStartPosition; + si.StartPositon = seg.StartPosition; + si.EndPosition = seg.EndPosition; + + di.Segments[j] = si; + } + } + + downloadsToSave.Add(di); + } + } + + SaveObjects(downloadsToSave); + } + + private string GetDatabaseFile() + { + string file = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + "\\" + "downloads.xml"; + return file; + } + + private void LoadSavedList() + { + if (File.Exists(GetDatabaseFile())) + { + try + { + using (FileStream fs = new FileStream(GetDatabaseFile(), FileMode.Open)) + { + DownloadItem[] downloads = (DownloadItem[])serializer.Deserialize(fs); + + LoadPersistedObjects(downloads); + } + } + catch (Exception ex) + { + Debug.WriteLine(ex.ToString()); + } + } + } + + private void SaveObjects(List downloadsToSave) + { + using (new MyStopwatch("Saving download list")) + { + try + { + using (FileStream fs = new FileStream(GetDatabaseFile(), FileMode.Create)) + { + serializer.Serialize(fs, downloadsToSave.ToArray()); + } + } + catch (Exception ex) + { + Debug.WriteLine(ex.ToString()); + } + } + } + + private static void LoadPersistedObjects(DownloadItem[] downloads) + { + for (int i = 0; i < downloads.Length; i++) + { + List segments = new List(); + + for (int j = 0; j < downloads[i].Segments.Length; j++) + { + Segment seg = new Segment(); + seg.Index = downloads[i].Segments[j].Index; + seg.InitialStartPosition = downloads[i].Segments[j].InitialStartPositon; + seg.StartPosition = downloads[i].Segments[j].StartPositon; + seg.EndPosition = downloads[i].Segments[j].EndPosition; + + segments.Add(seg); + } + + Downloader d = DownloadManager.Instance.Add( + downloads[i].rl, + downloads[i].mirrors, + downloads[i].LocalFile, + segments, + downloads[i].remoteInfo, + downloads[i].requestedSegments, + false, + downloads[i].createdDateTime); + + if (downloads[i].extendedProperties != null) + { + SerializableDictionary.Enumerator e = downloads[i].extendedProperties.GetEnumerator(); + + while (e.MoveNext()) + { + d.ExtendedProperties.Add(e.Current.Key, e.Current.Value); + } + } + } + } + + #endregion + + #region Constructor + + public PersistedListExtension() + { + serializer = new XmlSerializer(typeof(DownloadItem[])); + + LoadSavedList(); + + TimerCallback refreshCallBack = new TimerCallback(PersistList); + TimeSpan refreshInterval = TimeSpan.FromSeconds(SaveListIntervalInSeconds); + timer = new Timer(refreshCallBack, null, new TimeSpan(-1), refreshInterval); + } + + #endregion + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/PersistedList/SerializableDictionary.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/PersistedList/SerializableDictionary.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml.Serialization; + +namespace MyDownloader.Extension.PersistedList +{ + [XmlRoot("dictionary")] + public class SerializableDictionary + : Dictionary, IXmlSerializable + { + #region Constructor + public SerializableDictionary() + { + } + + public SerializableDictionary(IDictionary dictionary) + : base(dictionary) + { + } + #endregion + + #region IXmlSerializable Members + + public System.Xml.Schema.XmlSchema GetSchema() + { + return null; + } + + public void ReadXml(System.Xml.XmlReader reader) + { + XmlSerializer keySerializer = new XmlSerializer(typeof(TKey)); + XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue)); + + bool wasEmpty = reader.IsEmptyElement; + + reader.Read(); + + if (wasEmpty) + return; + + while (reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + reader.ReadStartElement("item"); + reader.ReadStartElement("key"); + TKey key = (TKey)keySerializer.Deserialize(reader); + reader.ReadEndElement(); + + reader.ReadStartElement("value"); + TValue value = (TValue)valueSerializer.Deserialize(reader); + reader.ReadEndElement(); + + this.Add(key, value); + + reader.ReadEndElement(); + reader.MoveToContent(); + } + + reader.ReadEndElement(); + } + + public void WriteXml(System.Xml.XmlWriter writer) + { + XmlSerializer keySerializer = new XmlSerializer(typeof(TKey)); + XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue)); + + foreach (TKey key in this.Keys) + { + writer.WriteStartElement("item"); + + writer.WriteStartElement("key"); + keySerializer.Serialize(writer, key); + writer.WriteEndElement(); + + writer.WriteStartElement("value"); + TValue value = this[key]; + valueSerializer.Serialize(writer, value); + writer.WriteEndElement(); + + writer.WriteEndElement(); + } + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Properties/AssemblyInfo.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MyDownloader.Extension")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Programmmers")] +[assembly: AssemblyProduct("MyDownloader.Extension")] +[assembly: AssemblyCopyright("Copyright © Programmmers 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("1d6ed868-3dc7-4db0-a934-7d01165843ae")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Protocols/BaseProtocolProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Protocols/BaseProtocolProvider.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core; +using System.Net; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; + +namespace MyDownloader.Extension.Protocols +{ + public class BaseProtocolProvider + { + static BaseProtocolProvider() + { + ServicePointManager.DefaultConnectionLimit = int.MaxValue; + } + + protected WebRequest GetRequest(ResourceLocation location) + { + WebRequest request = WebRequest.Create(location.URL); + request.Timeout = 30000; + SetProxy(request); + return request; + } + + protected void SetProxy(WebRequest request) + { + if (HttpFtpProtocolExtension.parameters.UseProxy) + { + WebProxy proxy = new WebProxy(HttpFtpProtocolExtension.parameters.ProxyAddress, HttpFtpProtocolExtension.parameters.ProxyPort); + proxy.BypassProxyOnLocal = HttpFtpProtocolExtension.parameters.ProxyByPassOnLocal; + request.Proxy = proxy; + + if (!String.IsNullOrEmpty(HttpFtpProtocolExtension.parameters.ProxyUserName)) + { + request.Proxy.Credentials = new NetworkCredential( + HttpFtpProtocolExtension.parameters.ProxyUserName, + HttpFtpProtocolExtension.parameters.ProxyPassword, + HttpFtpProtocolExtension.parameters.ProxyDomain); + } + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Protocols/FtpProtocolProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Protocols/FtpProtocolProvider.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Net; +using System.IO; +using MyDownloader.Core; + +namespace MyDownloader.Extension.Protocols +{ + public class FtpProtocolProvider: BaseProtocolProvider, IProtocolProvider + { + private void FillCredentials(FtpWebRequest request, ResourceLocation rl) + { + if (rl.Authenticate) + { + string login = rl.Login; + string domain = string.Empty; + + int slashIndex = login.IndexOf('\\'); + + if (slashIndex >= 0) + { + domain = login.Substring(0, slashIndex); + login = login.Substring(slashIndex + 1); + } + + NetworkCredential myCred = new NetworkCredential(login, rl.Password); + myCred.Domain = domain; + + request.Credentials = myCred; + } + } + + #region IProtocolProvider Members + + public void Initialize(Downloader downloader) + { + } + + public Stream CreateStream(ResourceLocation rl, long initialPosition, long endPosition) + { + FtpWebRequest request = (FtpWebRequest)GetRequest(rl); + + FillCredentials(request, rl); + + request.Method = WebRequestMethods.Ftp.DownloadFile; + request.ContentOffset = initialPosition; + + WebResponse response = request.GetResponse(); + + return response.GetResponseStream(); + } + + public RemoteFileInfo GetFileInfo(ResourceLocation rl, out Stream stream) + { + FtpWebRequest request; + + RemoteFileInfo result = new RemoteFileInfo(); + result.AcceptRanges = true; + + stream = null; + + request = (FtpWebRequest)GetRequest(rl); + request.Method = WebRequestMethods.Ftp.GetFileSize; + FillCredentials(request, rl); + + using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) + { + result.FileSize = response.ContentLength; + } + + request = (FtpWebRequest)GetRequest(rl); + request.Method = WebRequestMethods.Ftp.GetDateTimestamp; + FillCredentials(request, rl); + + using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) + { + result.LastModified = response.LastModified; + } + + return result; + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Protocols/HttpFtpProtocolExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Protocols/HttpFtpProtocolExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; +using MyDownloader.Core; +using System.IO; + +namespace MyDownloader.Extension.Protocols +{ + public class HttpFtpProtocolExtension: IExtension + { + internal static IHttpFtpProtocolParameters parameters; + + #region IExtension Members + + public string Name + { + get { return "HTTP/FTP"; } + } + + public IUIExtension UIExtension + { + get { return new HttpFtpProtocolUIExtension(); } + } + + public HttpFtpProtocolExtension(): + this(new HttpFtpProtocolParametersSettingsProxy()) + { + } + + public HttpFtpProtocolExtension(IHttpFtpProtocolParameters parameters) + { + if (parameters == null) + { + throw new ArgumentNullException("parameters"); + } + + if (HttpFtpProtocolExtension.parameters != null) + { + throw new InvalidOperationException("The type HttpFtpProtocolExtension is already initialized."); + } + + HttpFtpProtocolExtension.parameters = parameters; + + ProtocolProviderFactory.RegisterProtocolHandler("http", typeof(HttpProtocolProvider)); + ProtocolProviderFactory.RegisterProtocolHandler("https", typeof(HttpProtocolProvider)); + ProtocolProviderFactory.RegisterProtocolHandler("ftp", typeof(FtpProtocolProvider)); + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Protocols/HttpFtpProtocolParametersSettingsProxy.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Protocols/HttpFtpProtocolParametersSettingsProxy.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Extension.Protocols +{ + class HttpFtpProtocolParametersSettingsProxy : IHttpFtpProtocolParameters + { + #region IHttpFtpProtocolParameters Members + + public string ProxyAddress + { + get + { + return Settings.Default.ProxyAddress; + } + set + { + Settings.Default.ProxyAddress = value; + } + } + + public string ProxyUserName + { + get + { + return Settings.Default.ProxyUserName; + } + set + { + Settings.Default.ProxyUserName = value; + } + } + + public string ProxyPassword + { + get + { + return Settings.Default.ProxyPassword; + } + set + { + Settings.Default.ProxyPassword = value; + } + } + + public string ProxyDomain + { + get + { + return Settings.Default.ProxyDomain; + } + set + { + Settings.Default.ProxyDomain = value; + } + } + + public bool UseProxy + { + get + { + return Settings.Default.UseProxy; + } + set + { + Settings.Default.UseProxy = value; + } + } + + public bool ProxyByPassOnLocal + { + get + { + return Settings.Default.ProxyByPassOnLocal; + } + set + { + Settings.Default.ProxyByPassOnLocal = value; + } + } + + public int ProxyPort + { + get + { + return Settings.Default.ProxyPort; + } + set + { + Settings.Default.ProxyPort = value; + } + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Protocols/HttpFtpProtocolUIExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Protocols/HttpFtpProtocolUIExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; +using System.Windows.Forms; +using MyDownloader.Extension.Protocols.UI; + +namespace MyDownloader.Extension.Protocols +{ + public class HttpFtpProtocolUIExtension : IUIExtension + { + #region IUIExtension Members + + public System.Windows.Forms.Control[] CreateSettingsView() + { + return new Control[] { new Proxy() }; + } + + public void PersistSettings(System.Windows.Forms.Control[] settingsView) + { + Proxy proxy = (Proxy)settingsView[0]; + + Settings.Default.UseProxy = proxy.UseProxy; + Settings.Default.ProxyAddress = proxy.ProxyAddress; + Settings.Default.ProxyPort = proxy.ProxyPort; + Settings.Default.ProxyByPassOnLocal = proxy.ProxyByPassOnLocal; + Settings.Default.ProxyUserName = proxy.ProxyUserName; + Settings.Default.ProxyPassword = proxy.ProxyPassword; + Settings.Default.ProxyDomain = proxy.ProxyDomain; + Settings.Default.Save(); + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Protocols/HttpProtocolProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Protocols/HttpProtocolProvider.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Net; +using MyDownloader.Core; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; +using System.Runtime.InteropServices; +using MyDownloader.Core.Common; + +namespace MyDownloader.Extension.Protocols +{ + public class HttpProtocolProvider : BaseProtocolProvider, IProtocolProvider + { + private Downloader downloader; + + static HttpProtocolProvider() + { + ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(certificateCallBack); + } + + static bool certificateCallBack( + object sender, + X509Certificate certificate, + X509Chain chain, + SslPolicyErrors sslPolicyErrors) + { + return true; + } + + private void FillCredentials(HttpWebRequest request, ResourceLocation rl) + { + if (rl.Authenticate) + { + string login = rl.Login; + string domain = string.Empty; + + int slashIndex = login.IndexOf('\\'); + + if (slashIndex >= 0) + { + domain = login.Substring(0, slashIndex ); + login = login.Substring(slashIndex + 1); + } + + NetworkCredential myCred = new NetworkCredential(login, rl.Password); + myCred.Domain = domain; + + request.Credentials = myCred; + } + } + + #region IProtocolProvider Members + + public virtual void Initialize(Downloader d) + { + downloader = d; + } + + private static CookieContainer GetUriCookieContainer(string uri) + { + CookieContainer cookies=new CookieContainer(); + foreach (Cookie c in CookieManager.GetCookieCollection(uri)) + cookies.SetCookies(new Uri(uri), c.ToString()); + return cookies; + + } + + private HttpWebRequest GetRequest(ResourceLocation rl) + { + HttpWebRequest request = (HttpWebRequest)base.GetRequest(rl); + request.CookieContainer = GetUriCookieContainer(rl.URL); + return request; + + } + public virtual Stream CreateStream(ResourceLocation rl, long initialPosition, long endPosition) + { + HttpWebRequest request = this.GetRequest(rl); + + FillCredentials(request, rl); + + if (initialPosition != 0) + { + if (endPosition == 0) + { + request.AddRange((int)initialPosition); + } + else + { + request.AddRange((int)initialPosition, (int)endPosition); + } + } + + WebResponse response = request.GetResponse(); + + return response.GetResponseStream(); + } + + public virtual RemoteFileInfo GetFileInfo(ResourceLocation rl, out Stream stream) + { + restart: + HttpWebRequest request = this.GetRequest(rl); + + FillCredentials(request, rl); + + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + + if (response.ResponseUri.AbsoluteUri != rl.URL) + { + rl.URL = response.ResponseUri.AbsoluteUri; + goto restart; + } + RemoteFileInfo result = new RemoteFileInfo(); + string filename=response.ResponseUri.LocalPath; + result.FileName = filename.Substring(filename.LastIndexOf("/") + 1); + if ((result.FileName == "") && response.ContentType == "text/html") + result.FileName = "temp.html"; + result.MimeType = response.ContentType; + result.LastModified = response.LastModified; + result.FileSize = response.ContentLength; + result.AcceptRanges = String.Compare(response.Headers["Accept-Ranges"], "bytes", true) == 0; + + stream = response.GetResponseStream(); + + return result; + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Protocols/IHttpFtpProtocolParameters.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Protocols/IHttpFtpProtocolParameters.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Extension.Protocols +{ + public interface IHttpFtpProtocolParameters + { + string ProxyAddress { get; set; } + + string ProxyUserName { get; set; } + + string ProxyPassword { get; set; } + + string ProxyDomain { get; set; } + + bool UseProxy { get; set; } + + bool ProxyByPassOnLocal { get; set; } + + int ProxyPort { get; set; } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Protocols/Settings.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Protocols/Settings.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,110 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MyDownloader.Extension.Protocols { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string ProxyAddress { + get { + return ((string)(this["ProxyAddress"])); + } + set { + this["ProxyAddress"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string ProxyUserName { + get { + return ((string)(this["ProxyUserName"])); + } + set { + this["ProxyUserName"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string ProxyPassword { + get { + return ((string)(this["ProxyPassword"])); + } + set { + this["ProxyPassword"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string ProxyDomain { + get { + return ((string)(this["ProxyDomain"])); + } + set { + this["ProxyDomain"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool UseProxy { + get { + return ((bool)(this["UseProxy"])); + } + set { + this["UseProxy"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool ProxyByPassOnLocal { + get { + return ((bool)(this["ProxyByPassOnLocal"])); + } + set { + this["ProxyByPassOnLocal"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("80")] + public int ProxyPort { + get { + return ((int)(this["ProxyPort"])); + } + set { + this["ProxyPort"] = value; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Protocols/Settings.settings --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Protocols/Settings.settings Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + False + + + True + + + 80 + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Protocols/UI/Proxy.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Protocols/UI/Proxy.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,209 @@ +namespace MyDownloader.Extension.Protocols.UI +{ + partial class Proxy + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.chkUseProxy = new System.Windows.Forms.CheckBox(); + this.txtProxtAddress = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.numProxyPort = new System.Windows.Forms.NumericUpDown(); + this.label3 = new System.Windows.Forms.Label(); + this.txtUsername = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.txtPassword = new System.Windows.Forms.TextBox(); + this.label5 = new System.Windows.Forms.Label(); + this.txtDomain = new System.Windows.Forms.TextBox(); + this.chkBypass = new System.Windows.Forms.CheckBox(); + ((System.ComponentModel.ISupportInitialize)(this.numProxyPort)).BeginInit(); + this.SuspendLayout(); + // + // chkUseProxy + // + this.chkUseProxy.AutoSize = true; + this.chkUseProxy.Location = new System.Drawing.Point(0, 3); + this.chkUseProxy.Name = "chkUseProxy"; + this.chkUseProxy.Size = new System.Drawing.Size(73, 17); + this.chkUseProxy.TabIndex = 0; + this.chkUseProxy.Text = "Use proxy"; + this.chkUseProxy.UseVisualStyleBackColor = true; + this.chkUseProxy.CheckedChanged += new System.EventHandler(this.chkUseProxy_CheckedChanged); + // + // txtProxtAddress + // + this.txtProxtAddress.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtProxtAddress.Location = new System.Drawing.Point(1, 43); + this.txtProxtAddress.Name = "txtProxtAddress"; + this.txtProxtAddress.Size = new System.Drawing.Size(306, 20); + this.txtProxtAddress.TabIndex = 2; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(0, 27); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(77, 13); + this.label1.TabIndex = 1; + this.label1.Text = "Proxy Address:"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(0, 73); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(58, 13); + this.label2.TabIndex = 3; + this.label2.Text = "Proxy Port:"; + // + // numProxyPort + // + this.numProxyPort.Location = new System.Drawing.Point(3, 90); + this.numProxyPort.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.numProxyPort.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.numProxyPort.Name = "numProxyPort"; + this.numProxyPort.Size = new System.Drawing.Size(88, 20); + this.numProxyPort.TabIndex = 4; + this.numProxyPort.Value = new decimal(new int[] { + 1, + 0, + 0, + 0}); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(1, 169); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(63, 13); + this.label3.TabIndex = 6; + this.label3.Text = "User Name:"; + // + // txtUsername + // + this.txtUsername.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtUsername.Location = new System.Drawing.Point(2, 185); + this.txtUsername.Name = "txtUsername"; + this.txtUsername.Size = new System.Drawing.Size(306, 20); + this.txtUsername.TabIndex = 7; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(0, 211); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(56, 13); + this.label4.TabIndex = 8; + this.label4.Text = "Password:"; + // + // txtPassword + // + this.txtPassword.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtPassword.Location = new System.Drawing.Point(2, 227); + this.txtPassword.Name = "txtPassword"; + this.txtPassword.Size = new System.Drawing.Size(306, 20); + this.txtPassword.TabIndex = 9; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(0, 258); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(46, 13); + this.label5.TabIndex = 10; + this.label5.Text = "Domain:"; + // + // txtDomain + // + this.txtDomain.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtDomain.Location = new System.Drawing.Point(1, 274); + this.txtDomain.Name = "txtDomain"; + this.txtDomain.Size = new System.Drawing.Size(306, 20); + this.txtDomain.TabIndex = 11; + // + // chkBypass + // + this.chkBypass.AutoSize = true; + this.chkBypass.Location = new System.Drawing.Point(1, 131); + this.chkBypass.Name = "chkBypass"; + this.chkBypass.Size = new System.Drawing.Size(100, 17); + this.chkBypass.TabIndex = 5; + this.chkBypass.Text = "Bypass on local"; + this.chkBypass.UseVisualStyleBackColor = true; + // + // Proxy + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.txtDomain); + this.Controls.Add(this.txtPassword); + this.Controls.Add(this.txtUsername); + this.Controls.Add(this.txtProxtAddress); + this.Controls.Add(this.chkBypass); + this.Controls.Add(this.label5); + this.Controls.Add(this.label4); + this.Controls.Add(this.label3); + this.Controls.Add(this.numProxyPort); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.chkUseProxy); + this.Name = "Proxy"; + this.Size = new System.Drawing.Size(308, 308); + ((System.ComponentModel.ISupportInitialize)(this.numProxyPort)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.CheckBox chkUseProxy; + private System.Windows.Forms.TextBox txtProxtAddress; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.NumericUpDown numProxyPort; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox txtUsername; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox txtPassword; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.TextBox txtDomain; + private System.Windows.Forms.CheckBox chkBypass; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Protocols/UI/Proxy.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Protocols/UI/Proxy.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.Extension.Protocols.UI +{ + public partial class Proxy : UserControl + { + public Proxy() + { + this.Text = "Proxy"; + InitializeComponent(); + + UseProxy = Settings.Default.UseProxy; + ProxyAddress = Settings.Default.ProxyAddress; + ProxyPort = Settings.Default.ProxyPort; + ProxyByPassOnLocal = Settings.Default.ProxyByPassOnLocal; + ProxyUserName = Settings.Default.ProxyUserName; + ProxyPassword = Settings.Default.ProxyPassword; + ProxyDomain = Settings.Default.ProxyDomain; + + UpdateControls(); + } + + public bool UseProxy + { + get + { + return chkUseProxy.Checked; + } + set + { + chkUseProxy.Checked = value; + } + } + + public string ProxyAddress + { + get + { + return txtProxtAddress.Text; + } + set + { + txtProxtAddress.Text = value; + } + } + + public int ProxyPort + { + get + { + return (int)numProxyPort.Value; + } + set + { + numProxyPort.Value = value; + } + } + + public bool ProxyByPassOnLocal + { + get + { + return chkBypass.Checked; + } + set + { + chkBypass.Checked = value; + } + } + + public string ProxyUserName + { + get + { + return txtUsername.Text; + } + set + { + txtUsername.Text = value; + } + } + + public string ProxyPassword + { + get + { + return txtPassword.Text; + } + set + { + txtPassword.Text = value; + } + } + + public string ProxyDomain + { + get + { + return txtDomain.Text; + } + set + { + txtDomain.Text = value; + } + } + + private void chkUseProxy_CheckedChanged(object sender, EventArgs e) + { + UpdateControls(); + } + + private void UpdateControls() + { + for (int i = 0; i < this.Controls.Count; i++) + { + if (this.Controls[i] != chkUseProxy) + { + this.Controls[i].Enabled = chkUseProxy.Checked; + } + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Protocols/UI/Proxy.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Protocols/UI/Proxy.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/SpeedLimit/ISpeedLimitParameters.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/SpeedLimit/ISpeedLimitParameters.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; + +namespace MyDownloader.Extension.SpeedLimit +{ + public interface ISpeedLimitParameters: IExtensionParameters + { + bool Enabled { get; set; } + + double MaxRate { get; set; } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/SpeedLimit/LimitedRateStreamProxy.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/SpeedLimit/LimitedRateStreamProxy.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Threading; + +namespace MyDownloader.Extension.SpeedLimit +{ + public class LimitedRateStreamProxy: Stream + { + private Stream proxy; + private SpeedLimitExtension speedLimit; + + #region Stream + + public override bool CanRead + { + get { return proxy.CanRead; } + } + + public override bool CanSeek + { + get { return proxy.CanSeek; } + } + + public override bool CanWrite + { + get { return proxy.CanWrite; } + } + + public override void Flush() + { + proxy.Flush(); + } + + public override long Length + { + get { return proxy.Length; } + } + + public override long Position + { + get + { + return proxy.Position; + } + set + { + proxy.Position = value; + } + } + + public override int Read(byte[] buffer, int offset, int count) + { + speedLimit.WaitFor(); + + return proxy.Read(buffer, offset, count); + } + + public override long Seek(long offset, SeekOrigin origin) + { + return proxy.Seek(offset, origin); + } + + public override void SetLength(long value) + { + proxy.SetLength(value); + } + + public override void Write(byte[] buffer, int offset, int count) + { + proxy.Write(buffer, offset, count); + } + + #endregion + + public LimitedRateStreamProxy(Stream proxy, SpeedLimitExtension speedLimit) + { + this.speedLimit = speedLimit; + this.proxy = proxy; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/SpeedLimit/ProtocolProviderProxy.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/SpeedLimit/ProtocolProviderProxy.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core; + +namespace MyDownloader.Extension.SpeedLimit +{ + public class ProtocolProviderProxy: IProtocolProvider + { + private IProtocolProvider proxy; + private SpeedLimitExtension speedLimit; + + #region IProtocolProvider Members + + public void Initialize(Downloader downloader) + { + proxy.Initialize(downloader); + } + + public System.IO.Stream CreateStream(ResourceLocation rl, long initialPosition, long endPosition) + { + return new LimitedRateStreamProxy(proxy.CreateStream(rl, initialPosition, endPosition), speedLimit); + } + + public RemoteFileInfo GetFileInfo(ResourceLocation rl, out System.IO.Stream stream) + { + RemoteFileInfo result = proxy.GetFileInfo(rl, out stream); + + if (stream != null) + { + stream = new LimitedRateStreamProxy(stream, speedLimit); + } + + return result; + } + + #endregion + + public ProtocolProviderProxy(IProtocolProvider proxy, SpeedLimitExtension speedLimit) + { + this.proxy = proxy; + this.speedLimit = speedLimit; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/SpeedLimit/Settings.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/SpeedLimit/Settings.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MyDownloader.Extension.SpeedLimit { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool EnabledLimit { + get { + return ((bool)(this["EnabledLimit"])); + } + set { + this["EnabledLimit"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("1024")] + public double MaxRate { + get { + return ((double)(this["MaxRate"])); + } + set { + this["MaxRate"] = value; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/SpeedLimit/Settings.settings --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/SpeedLimit/Settings.settings Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,12 @@ + + + + + + False + + + 1024 + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/SpeedLimit/SpeedLimitExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/SpeedLimit/SpeedLimitExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; +using MyDownloader.Core; +using System.Threading; +using System.Diagnostics; +using Microsoft.Win32; +using System.ComponentModel; + +namespace MyDownloader.Extension.SpeedLimit +{ + public class SpeedLimitExtension: IExtension, IDisposable + { + private const int BalancerUp = 50; + private const int BalancerDown = -75; + + private double currentWait; + private bool enabled; + private double maxLimit; + private ISpeedLimitParameters parameters; + + #region IExtension Members + + public string Name + { + get { return "Speed Limit"; } + } + + public IUIExtension UIExtension + { + get { return new SpeedLimitUIExtension(); } + } + + #endregion + + #region Properties + + public ISpeedLimitParameters Parameters + { + get { return parameters; } + } + + public bool CurrentEnabled + { + get { return enabled; } + } + + public double CurrentMaxRate + { + get { return maxLimit; } + } + + #endregion + + #region Methods + + public void SetMaxRateTemp(double max) + { + this.enabled = true; + this.maxLimit = max; + } + + public void RestoreMaxRateFromParameters() + { + ReadSettings(); + } + + private void Default_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + ReadSettings(); + } + + private void ReadSettings() + { + currentWait = 0; + maxLimit = Parameters.MaxRate; + enabled = Parameters.Enabled; + } + + private void ProtocolProviderFactory_ResolvingProtocolProvider(object sender, ResolvingProtocolProviderEventArgs e) + { + e.ProtocolProvider = new ProtocolProviderProxy(e.ProtocolProvider, this); + } + + internal void WaitFor() + { + if (enabled) + { + double totalRate = DownloadManager.Instance.TotalDownloadRate; + + if (totalRate > maxLimit) + { + currentWait += BalancerUp; + } + else + { + currentWait = Math.Max(currentWait + BalancerDown, 0); + } + + Thread.Sleep(TimeSpan.FromMilliseconds(currentWait)); + + Debug.WriteLine("TotalDownloadRate = " + totalRate); + Debug.WriteLine("maxLimit = " + maxLimit); + Debug.WriteLine("currentWait = " + currentWait); + } + } + + #endregion + + #region Constructor + + public SpeedLimitExtension() + : + this(new SpeedLimitParametersSettingProxy()) + { + } + + public SpeedLimitExtension(ISpeedLimitParameters parameters) + { + if (parameters == null) + { + throw new ArgumentNullException("parameters"); + } + + this.parameters = parameters; + + ReadSettings(); + + ProtocolProviderFactory.ResolvingProtocolProvider += new EventHandler(ProtocolProviderFactory_ResolvingProtocolProvider); + this.parameters.ParameterChanged += new PropertyChangedEventHandler(Default_PropertyChanged); + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + if (this.parameters is IDisposable) + { + (this.parameters as IDisposable).Dispose(); + } + } + + #endregion + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/SpeedLimit/SpeedLimitParametersSettingProxy.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/SpeedLimit/SpeedLimitParametersSettingProxy.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Extension.SpeedLimit +{ + internal class SpeedLimitParametersSettingProxy : ISpeedLimitParameters, IDisposable + { + #region ISpeedLimitParameters Members + + public bool Enabled + { + get + { + return Settings.Default.EnabledLimit; + } + set + { + Settings.Default.EnabledLimit = value; + OnParameterChanged("Enabled"); + } + } + + public double MaxRate + { + get + { + return Settings.Default.MaxRate; + } + set + { + Settings.Default.MaxRate = value; + OnParameterChanged("MaxRate"); + } + } + + #endregion + + #region IExtensionParameters Members + + public event System.ComponentModel.PropertyChangedEventHandler ParameterChanged; + + #endregion + + #region Methods + + protected void OnParameterChanged(string propertyname) + { + if (ParameterChanged != null) + { + ParameterChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyname)); + } + } + + void Default_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + OnParameterChanged(e.PropertyName); + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + Settings.Default.Save(); + } + + #endregion + + public SpeedLimitParametersSettingProxy() + { + Settings.Default.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(Default_PropertyChanged); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/SpeedLimit/SpeedLimitUIExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/SpeedLimit/SpeedLimitUIExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; +using System.Windows.Forms; +using MyDownloader.Extension.SpeedLimit.UI; + +namespace MyDownloader.Extension.SpeedLimit +{ + public class SpeedLimitUIExtension: IUIExtension + { + #region IUIExtension Members + + public Control[] CreateSettingsView() + { + return new Control[] { new LimitCfg() }; + } + + public void PersistSettings(Control[] settingsView) + { + LimitCfg lmt = (LimitCfg)settingsView[0]; + + Settings.Default.MaxRate = lmt.MaxRate; + Settings.Default.EnabledLimit = lmt.EnableLimit; + + Settings.Default.Save(); + } + + #endregion + + public void ShowSpeedLimitDialog() + { + using (SetSpeedLimitDialog sld = new SetSpeedLimitDialog()) + { + if (sld.ShowDialog() == DialogResult.OK) + { + PersistSettings(new Control[] { sld.limitCfg1 }); + } + } + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/SpeedLimit/UI/LimitCfg.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/SpeedLimit/UI/LimitCfg.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,100 @@ +namespace MyDownloader.Extension.SpeedLimit.UI +{ + partial class LimitCfg + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.chkEnableLimit = new System.Windows.Forms.CheckBox(); + this.numMaxRate = new System.Windows.Forms.NumericUpDown(); + this.lblMaxRate = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.numMaxRate)).BeginInit(); + this.SuspendLayout(); + // + // chkEnableLimit + // + this.chkEnableLimit.AutoSize = true; + this.chkEnableLimit.Location = new System.Drawing.Point(0, 0); + this.chkEnableLimit.Name = "chkEnableLimit"; + this.chkEnableLimit.Size = new System.Drawing.Size(111, 17); + this.chkEnableLimit.TabIndex = 0; + this.chkEnableLimit.Text = "Enable speed limit"; + this.chkEnableLimit.UseVisualStyleBackColor = true; + this.chkEnableLimit.CheckedChanged += new System.EventHandler(this.chkEnableLimit_CheckedChanged); + // + // numMaxRate + // + this.numMaxRate.Location = new System.Drawing.Point(0, 48); + this.numMaxRate.Maximum = new decimal(new int[] { + 1000, + 0, + 0, + 0}); + this.numMaxRate.Minimum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.numMaxRate.Name = "numMaxRate"; + this.numMaxRate.Size = new System.Drawing.Size(96, 20); + this.numMaxRate.TabIndex = 2; + this.numMaxRate.Value = new decimal(new int[] { + 1, + 0, + 0, + 0}); + // + // lblMaxRate + // + this.lblMaxRate.AutoSize = true; + this.lblMaxRate.Location = new System.Drawing.Point(-3, 32); + this.lblMaxRate.Name = "lblMaxRate"; + this.lblMaxRate.Size = new System.Drawing.Size(88, 13); + this.lblMaxRate.TabIndex = 1; + this.lblMaxRate.Text = "Max Rate (kbps):"; + // + // LimitCfg + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.numMaxRate); + this.Controls.Add(this.lblMaxRate); + this.Controls.Add(this.chkEnableLimit); + this.Name = "LimitCfg"; + this.Size = new System.Drawing.Size(192, 71); + ((System.ComponentModel.ISupportInitialize)(this.numMaxRate)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.CheckBox chkEnableLimit; + private System.Windows.Forms.NumericUpDown numMaxRate; + private System.Windows.Forms.Label lblMaxRate; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/SpeedLimit/UI/LimitCfg.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/SpeedLimit/UI/LimitCfg.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.Extension.SpeedLimit.UI +{ + public partial class LimitCfg : UserControl + { + public LimitCfg() + { + InitializeComponent(); + + Text = "Speed Limit"; + + chkEnableLimit.Checked = Settings.Default.EnabledLimit; + numMaxRate.Value = (decimal)(Math.Max(Settings.Default.MaxRate, 1024) / 1024.0); + + UpdateUI(); + } + + private void chkEnableLimit_CheckedChanged(object sender, EventArgs e) + { + UpdateUI(); + } + + public double MaxRate + { + get { return ((double)numMaxRate.Value) * 1024; } + } + + public bool EnableLimit + { + get { return chkEnableLimit.Checked; } + } + + private void UpdateUI() + { + lblMaxRate.Enabled = chkEnableLimit.Checked; + numMaxRate.Enabled = chkEnableLimit.Checked; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/SpeedLimit/UI/LimitCfg.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/SpeedLimit/UI/LimitCfg.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/SpeedLimit/UI/SetSpeedLimitDialog.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/SpeedLimit/UI/SetSpeedLimitDialog.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,92 @@ +namespace MyDownloader.Extension.SpeedLimit.UI +{ + partial class SetSpeedLimitDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnCancel = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.limitCfg1 = new MyDownloader.Extension.SpeedLimit.UI.LimitCfg(); + this.SuspendLayout(); + // + // btnCancel + // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(105, 88); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 2; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // btnOK + // + this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; + this.btnOK.Location = new System.Drawing.Point(24, 88); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 1; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + // + // limitCfg1 + // + this.limitCfg1.Location = new System.Drawing.Point(8, 8); + this.limitCfg1.Name = "limitCfg1"; + this.limitCfg1.Size = new System.Drawing.Size(168, 71); + this.limitCfg1.TabIndex = 0; + // + // SetSpeedLimitDialog + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(186, 117); + this.Controls.Add(this.limitCfg1); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOK); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "SetSpeedLimitDialog"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Set download limit"; + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnOK; + internal LimitCfg limitCfg1; + + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/SpeedLimit/UI/SetSpeedLimitDialog.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/SpeedLimit/UI/SetSpeedLimitDialog.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.Extension.SpeedLimit.UI +{ + public partial class SetSpeedLimitDialog : Form + { + public SetSpeedLimitDialog() + { + InitializeComponent(); + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/SpeedLimit/UI/SetSpeedLimitDialog.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/SpeedLimit/UI/SetSpeedLimitDialog.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/Impl/BaseVideoDownloader.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/Impl/BaseVideoDownloader.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Extension.Protocols; +using MyDownloader.Core; +using System.IO; +using System.Net; + +namespace MyDownloader.Extension.Video.Impl +{ + public abstract class BaseVideoDownloader : HttpProtocolProvider + { + private ResourceLocation mappedUrl; + + void downloader_Ending(object sender, EventArgs e) + { + Downloader d = (Downloader)sender; + + VideoConverter.ConvertIfNecessary(d); + } + + protected abstract ResourceLocation ResolveVideoURL(string url, string pageData, out string videoTitle); + + public override void Initialize(Downloader downloader) + { + base.Initialize(downloader); + + downloader.Ending += new EventHandler(downloader_Ending); + } + + public override Stream CreateStream(ResourceLocation rl, long initialPosition, long endPosition) + { + return base.CreateStream(mappedUrl ?? rl, initialPosition, endPosition); + } + + public override RemoteFileInfo GetFileInfo(ResourceLocation rl, out Stream stream) + { + stream = null; + + mappedUrl = null; + + String title; + String pageData = GetPageData(rl); + + mappedUrl = ResolveVideoURL(rl.URL, pageData, out title); + + WebRequest request = this.GetRequest(mappedUrl); + + using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) + { + RemoteFileInfo result = new RemoteFileInfo(); + result.FileSize = response.ContentLength; + result.AcceptRanges = String.Compare(response.Headers["Accept-Ranges"], "bytes", true) == 0; + + if (response.ResponseUri != null) + { + mappedUrl.URL = response.ResponseUri.OriginalString; + } + else + { + stream = response.GetResponseStream(); + } + + return result; + } + } + + private String GetPageData(ResourceLocation rl) + { + String pageData; + + using (StreamReader sr = new StreamReader(this.CreateStream(rl, 0, 0))) + { + pageData = sr.ReadToEnd(); + } + + return pageData; + } + + public string GetTitle(ResourceLocation rl) + { + String pageData = GetPageData(rl); + + string title; + + mappedUrl = ResolveVideoURL(rl.URL, pageData, out title); + + return title; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/Impl/BreakVideoDownloader.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/Impl/BreakVideoDownloader.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core; +using System.Diagnostics; + +namespace MyDownloader.Extension.Video.Impl +{ + public class BreakVideoDownloader: BaseVideoDownloader + { + public const string SiteName = "Break"; + + //http://my.break.com/content/view.aspx?ContentID=393301 + //http://www.break.com/canon/canon-battle-of-viral-video-super-stars.html + //http://www.break.com/index/tomorrow-is-spank-it-saturday.html + public const string UrlPattern = @"(?:[Bb][Rr][Ee][Aa][Kk]\.[Cc][Oo][Mm]/)(\w[\w|-]*)"; + + protected override ResourceLocation ResolveVideoURL(string url, string pageData, + out string videoTitle) + { + string sGlobalFileName = TextUtil.JustAfter(pageData, "sGlobalFileName='", "';"); + string sGlobalContentFilePath = TextUtil.JustAfter(pageData, "sGlobalContentFilePath='", "';"); + + string flvUrl = TextUtil.JustAfter(pageData, "so.addVariable('videoPath', '", "');") + .Replace("'+sGlobalContentFilePath+'", sGlobalContentFilePath) + .Replace("'+sGlobalFileName+'", sGlobalFileName); + + string wmvUrl = TextUtil.JustAfter(pageData, "") + .Replace("'+sGlobalContentFilePath+'", sGlobalContentFilePath) + .Replace("'+sGlobalFileName+'", sGlobalFileName); + Debug.WriteLine(wmvUrl); + + videoTitle = TextUtil.JustAfter(pageData, ""); + + return ResourceLocation.FromURL(flvUrl); + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/Impl/GoogleVideoDownloader.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/Impl/GoogleVideoDownloader.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Extension.Protocols; +using MyDownloader.Core; +using System.IO; +using System.Net; +using System.Web; + +namespace MyDownloader.Extension.Video.Impl +{ + public class GoogleVideoDownloader : BaseVideoDownloader + { + public const string SiteName = "Google Video"; + + //http://video.google.com/videoplay?docid=6527966434248029824 + //http://video.google.com/videoplay?docid=-3840236067834151894 + public const string UrlPattern = @"(?:[Vv][Ii][Dd][Ee][Oo]\.[Gg][Oo][Oo][Gg][Ll][Ee]\.[Cc][Oo][Mm]/videoplay\?docid=)-?(\w[\w|-]*)"; + + protected override ResourceLocation ResolveVideoURL(string url, string pageData, + out string videoTitle) + { + videoTitle = TextUtil.JustAfter(pageData, "", ""); + + url = TextUtil.JustAfter(pageData, "src=\"/googleplayer.swf?&videoUrl=", "&thumbnailUrl="); + + return ResourceLocation.FromURL(HttpUtility.UrlDecode(url)); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/Impl/Logos/BreakVideoDownloader.png Binary file MyDownloader.Extension/Video/Impl/Logos/BreakVideoDownloader.png has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/Impl/Logos/GoogleVideoDownloader.png Binary file MyDownloader.Extension/Video/Impl/Logos/GoogleVideoDownloader.png has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/Impl/Logos/MetaCafeVideoDownloader.png Binary file MyDownloader.Extension/Video/Impl/Logos/MetaCafeVideoDownloader.png has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/Impl/Logos/PutfileVideoDownloader.PNG Binary file MyDownloader.Extension/Video/Impl/Logos/PutfileVideoDownloader.PNG has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/Impl/Logos/YouTubeDownloader.png Binary file MyDownloader.Extension/Video/Impl/Logos/YouTubeDownloader.png has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/Impl/MetaCafeVideoDownloader.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/Impl/MetaCafeVideoDownloader.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Web; +using MyDownloader.Core; + +namespace MyDownloader.Extension.Video.Impl +{ + public class MetaCafeVideoDownloader: BaseVideoDownloader + { + public const string SiteName = "Meta Cafe"; + + //http://www.metacafe.com/watch/851582/village_idiots/ + public const string UrlPattern = @"(?:[Mm][Ee][Ta][Aa][Cc][Aa][Ff][Ee]\.[Cc][Oo][Mm]/watch/)(\w[\w|-]*)/(\w[\w|-]*)"; + + protected override ResourceLocation ResolveVideoURL(string url, + string pageData, out string videoTitle) + { + url = TextUtil.JustAfter(pageData, "mediaURL=", "&"); + + videoTitle = TextUtil.JustAfter(pageData, "", ""); + + return ResourceLocation.FromURL(HttpUtility.UrlDecode(url)); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/Impl/PutfileVideoDownloader.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/Impl/PutfileVideoDownloader.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core; + +namespace MyDownloader.Extension.Video.Impl +{ + public class PutfileVideoDownloader: BaseVideoDownloader + { + public const string SiteName = "PutFile"; + + //http://media.putfile.com/kilo-the-amazing-pitt + public const string UrlPattern = @"(?:[Mm][Ee][Dd][Ii][Aa]\.[Pp][Uu][Tt][Ff][Ii][Ll][Ee]\.[Cc][Oo][Mm]/)(\w[\w|-]*)"; + + protected override ResourceLocation ResolveVideoURL(string url, string pageData, + out string videoTitle) + { + url = TextUtil.JustAfter(pageData, "so1.addVariable(\"flv\", \"", "\");"); + + videoTitle = TextUtil.JustAfter(pageData, ""); + + return ResourceLocation.FromURL(url); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/Impl/YouTubeDownloader.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/Impl/YouTubeDownloader.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core; +using System.IO; +using MyDownloader.Extension.Protocols; +using System.Net; + +namespace MyDownloader.Extension.Video.Impl +{ + public class YouTubeDownloader: BaseVideoDownloader + { + public const string SiteName = "You Tube"; + + //http://www.youtube.com/watch?v=5zOevLN3Tic + public const string UrlPattern = @"(?:[Yy][Oo][Uu][Tt][Uu][Bb][Ee]\.[Cc][Oo][Mm]/watch\?v=)(\w[\w|-]*)"; + + protected override ResourceLocation ResolveVideoURL(string url, string pageData, + out string videoTitle) + { + videoTitle = TextUtil.JustAfter(pageData, ""); + + return ResourceLocation.FromURL(String.Format("{0}/get_video?video_id={1}&t={2}", TextUtil.GetDomain(url), + TextUtil.JustAfter(url, "v=", "&"), TextUtil.JustAfter(pageData, "&t=", "&hl="))); + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/TextUtil.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/TextUtil.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Extension.Video +{ + internal static class TextUtil + { + internal static string JustBefore(string Str, string Seq) + { + string Orgi = Str; + try + { + Str = Str.ToLower(); + Seq = Seq.ToLower(); + + return Orgi.Substring(0, Str.Length - (Str.Length - Str.IndexOf(Seq))); + } + catch (Exception) + { + return ""; + } + } + + internal static string GetDomain(String URL) + { + return URL.Substring(0, URL.LastIndexOf("/")); + } + + internal static string GetFilename(String URL) + { + string Filename = URL.Substring(URL.LastIndexOf("/") + 2, URL.Length - URL.LastIndexOf("/") - 2); + + if (Filename.IndexOf("&") != -1) + Filename = JustBefore(Filename, "&"); + + return Filename; + } + + internal static string JustAfter(string Str, string Seq, string SeqEnd) + { + string Orgi = Str; + try + { + Str = Str.ToLower(); + Seq = Seq.ToLower(); + + int i = Str.IndexOf(Seq); + + if (i < 0) + return null; + + i = i + Seq.Length; + + int j = Str.IndexOf(SeqEnd, i); + int end; + + if (j > 0) end = j - i; + else end = Str.Length - i; + + return Orgi.Substring(i, end); + } + catch (Exception) + { + return ""; + } + } + + internal static string JustAfter(string Str, string Seq) + { + string Orgi = Str; + try + { + Str = Str.ToLower(); + Seq = Seq.ToLower(); + + int i = Str.IndexOf(Seq); + + if (i < 0) + return null; + + i = i + Seq.Length; + + return Orgi.Substring(i, Str.Length - i); + } + catch (Exception) + { + return ""; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/UI/NewVideoDownload.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/UI/NewVideoDownload.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,244 @@ +namespace MyDownloader.Extension.Video.UI +{ + partial class NewVideoDownload + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.btnCancel = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.txtFilename = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label9 = new System.Windows.Forms.Label(); + this.chkStartNow = new System.Windows.Forms.CheckBox(); + this.txtURL = new System.Windows.Forms.TextBox(); + this.numSegments = new System.Windows.Forms.NumericUpDown(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.lblSites = new System.Windows.Forms.LinkLabel(); + this.videoFormatCtrl1 = new MyDownloader.Extension.Video.UI.VideoFormatCtrl(); + this.downloadFolder1 = new MyDownloader.Core.UI.DownloadFolder(); + this.waitControl1 = new MyDownloader.Core.UI.WaitControl(); + ((System.ComponentModel.ISupportInitialize)(this.numSegments)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(392, 246); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 12; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; + this.btnOK.Enabled = false; + this.btnOK.Location = new System.Drawing.Point(312, 246); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(75, 23); + this.btnOK.TabIndex = 11; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // txtFilename + // + this.txtFilename.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtFilename.Location = new System.Drawing.Point(8, 171); + this.txtFilename.Name = "txtFilename"; + this.txtFilename.Size = new System.Drawing.Size(456, 20); + this.txtFilename.TabIndex = 8; + this.txtFilename.Leave += new System.EventHandler(this.txtFilename_Leave); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(8, 155); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(55, 13); + this.label4.TabIndex = 7; + this.label4.Text = "File name:"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(5, 56); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(54, 13); + this.label2.TabIndex = 3; + this.label2.Text = "Segments"; + // + // label9 + // + this.label9.AutoSize = true; + this.label9.Location = new System.Drawing.Point(8, 8); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(311, 13); + this.label9.TabIndex = 0; + this.label9.Text = "URL (e.g: http://www.youtube.com/watch?v=AdPWWDkKS8s)"; + // + // chkStartNow + // + this.chkStartNow.AutoSize = true; + this.chkStartNow.Location = new System.Drawing.Point(116, 74); + this.chkStartNow.Name = "chkStartNow"; + this.chkStartNow.Size = new System.Drawing.Size(73, 17); + this.chkStartNow.TabIndex = 5; + this.chkStartNow.Text = "Start Now"; + this.chkStartNow.UseVisualStyleBackColor = true; + // + // txtURL + // + this.txtURL.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtURL.Location = new System.Drawing.Point(8, 24); + this.txtURL.Name = "txtURL"; + this.txtURL.Size = new System.Drawing.Size(456, 20); + this.txtURL.TabIndex = 1; + this.txtURL.TextChanged += new System.EventHandler(this.txtURL_TextChanged); + // + // numSegments + // + this.numSegments.Location = new System.Drawing.Point(8, 72); + this.numSegments.Name = "numSegments"; + this.numSegments.Size = new System.Drawing.Size(75, 20); + this.numSegments.TabIndex = 4; + this.numSegments.Value = new decimal(new int[] { + 2, + 0, + 0, + 0}); + // + // pictureBox1 + // + this.pictureBox1.InitialImage = null; + this.pictureBox1.Location = new System.Drawing.Point(192, 46); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(272, 72); + this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; + this.pictureBox1.TabIndex = 36; + this.pictureBox1.TabStop = false; + // + // lblSites + // + this.lblSites.AutoSize = true; + this.lblSites.Location = new System.Drawing.Point(384, 8); + this.lblSites.Name = "lblSites"; + this.lblSites.Size = new System.Drawing.Size(80, 13); + this.lblSites.TabIndex = 2; + this.lblSites.TabStop = true; + this.lblSites.Text = "Supported sites"; + this.lblSites.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lblSites_LinkClicked); + // + // videoFormatCtrl1 + // + this.videoFormatCtrl1.Location = new System.Drawing.Point(8, 112); + this.videoFormatCtrl1.Name = "videoFormatCtrl1"; + this.videoFormatCtrl1.Size = new System.Drawing.Size(208, 40); + this.videoFormatCtrl1.TabIndex = 6; + this.videoFormatCtrl1.VideoFormat = MyDownloader.Extension.Video.VideoFormat.None; + // + // downloadFolder1 + // + this.downloadFolder1.LabelText = "Save to:"; + this.downloadFolder1.Location = new System.Drawing.Point(8, 197); + this.downloadFolder1.Name = "downloadFolder1"; + this.downloadFolder1.Size = new System.Drawing.Size(456, 43); + this.downloadFolder1.TabIndex = 9; + // + // waitControl1 + // + this.waitControl1.Location = new System.Drawing.Point(8, 248); + this.waitControl1.Name = "waitControl1"; + this.waitControl1.Size = new System.Drawing.Size(288, 16); + this.waitControl1.TabIndex = 37; + this.waitControl1.Text = "Getting video title..."; + this.waitControl1.Visible = false; + // + // NewVideoDownload + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(471, 273); + this.Controls.Add(this.waitControl1); + this.Controls.Add(this.pictureBox1); + this.Controls.Add(this.videoFormatCtrl1); + this.Controls.Add(this.lblSites); + this.Controls.Add(this.txtFilename); + this.Controls.Add(this.label4); + this.Controls.Add(this.label2); + this.Controls.Add(this.label9); + this.Controls.Add(this.chkStartNow); + this.Controls.Add(this.txtURL); + this.Controls.Add(this.numSegments); + this.Controls.Add(this.btnOK); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.downloadFolder1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "NewVideoDownload"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "New Video Download"; + this.Load += new System.EventHandler(this.NewVideoDownload_Load); + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.NewVideoDownload_FormClosing); + ((System.ComponentModel.ISupportInitialize)(this.numSegments)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.TextBox txtFilename; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.CheckBox chkStartNow; + private System.Windows.Forms.TextBox txtURL; + private System.Windows.Forms.NumericUpDown numSegments; + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.LinkLabel lblSites; + private VideoFormatCtrl videoFormatCtrl1; + private MyDownloader.Core.UI.DownloadFolder downloadFolder1; + private MyDownloader.Core.UI.WaitControl waitControl1; + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/UI/NewVideoDownload.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/UI/NewVideoDownload.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,231 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using MyDownloader.Core; +using MyDownloader.Extension.Video; +using System.Diagnostics; +using System.IO; +using MyDownloader.Core.Common; +using MyDownloader.Core.UI; +using MyDownloader.Extension.Video.Impl; +using System.Threading; + +namespace MyDownloader.Extension.Video.UI +{ + public partial class NewVideoDownload : Form + { + bool hasSet = false; + VideoDownloadHandler handler; + VideoDownloadExtension extension; + Thread videoTitleReaderThread; + + public NewVideoDownload() + { + InitializeComponent(); + + extension = (VideoDownloadExtension)AppManager.Instance.Application.GetExtensionByType(typeof(VideoDownloadExtension)); + + videoFormatCtrl1.Change += new EventHandler(videoFormatCtrl1_Change); + } + + void videoFormatCtrl1_Change(object sender, EventArgs e) + { + UpdateFileExt(); + } + + private void UpdateFileExt() + { + string file = txtFilename.Text; + + if (!string.IsNullOrEmpty(file)) + { + if (videoFormatCtrl1.VideoFormat != VideoFormat.None) + { + file = Path.ChangeExtension(file, "." + videoFormatCtrl1.VideoFormat.ToString().ToLower()); + } + else + { + file = Path.ChangeExtension(file, ".flv"); + } + + txtFilename.Text = file; + } + } + + private void txtURL_TextChanged(object sender, EventArgs e) + { + ReleaseVideoThread(); + + handler = extension.GetHandlerByURL(txtURL.Text); + if (handler == null) + { + btnOK.Enabled = false; + pictureBox1.Image = null; + return; + } + + btnOK.Enabled = true; + + Type typeHandler = handler.Type; + DisplayLogo(typeHandler); + + videoTitleReaderThread = new Thread( + delegate(object state) + { + object[] parms = (object[])state; + + Type type = (Type)parms[0]; + string url = (string)parms[1]; + + BaseVideoDownloader videoDownloader = (BaseVideoDownloader)Activator.CreateInstance(type); + + string titile = videoDownloader.GetTitle(ResourceLocation.FromURL(url)); + + this.BeginInvoke((MethodInvoker)delegate() { txtFilename.Text = titile; UpdateFileExt(); waitControl1.Visible = false; }); + } + ); + + waitControl1.Visible = true; + videoTitleReaderThread.Start(new object[] { typeHandler, txtURL.Text }); + } + + private void ReleaseVideoThread() + { + if (videoTitleReaderThread != null) + { + if (videoTitleReaderThread.IsAlive) + { + videoTitleReaderThread.Abort(); + videoTitleReaderThread = null; + } + } + + waitControl1.Visible = false; + } + + private void DisplayLogo(Type typeHandler) + { + string logoName = typeHandler.Namespace + ".Logos." + typeHandler.Name + ".png"; + + using (Stream s = handler.Type.Assembly.GetManifestResourceStream(logoName)) + { + pictureBox1.Image = Image.FromStream(s); + } + + //Debug.WriteLine(logoName); + } + + private void lblSites_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + using (SupportedVideoSitesForm sites = new SupportedVideoSitesForm()) + { + sites.ShowDialog(); + } + } + + public ResourceLocation DownloadLocation + { + get + { + ResourceLocation rl = ResourceLocation.FromURL(txtURL.Text); + rl.ProtocolProviderType = handler.Type.AssemblyQualifiedName; + + return rl; + } + set + { + hasSet = true; + if (value == null) + { + txtURL.Clear(); + } + else + { + txtURL.Text = value.URL; + } + } + } + + public string LocalFile + { + get + { + return PathHelper.GetWithBackslash(downloadFolder1.Folder) + txtFilename.Text; + } + } + + public int Segments + { + get + { + return (int)numSegments.Value; + } + } + + public bool StartNow + { + get + { + return chkStartNow.Checked; + } + } + + public VideoFormat VideoFormat + { + get { return videoFormatCtrl1.VideoFormat; } + } + + private void txtFilename_Leave(object sender, EventArgs e) + { + UpdateFileExt(); + } + + private void btnOK_Click(object sender, EventArgs e) + { + UpdateFileExt(); + + AddDownloadToList(); + + Close(); + } + + private void AddDownloadToList() + { + Downloader download = DownloadManager.Instance.Add( + this.DownloadLocation, + null, + this.LocalFile, + this.Segments, + false); + + VideoConverter.SetConvertOption(download, this.VideoFormat); + + if (this.StartNow) + { + download.Start(); + } + } + + private void NewVideoDownload_FormClosing(object sender, FormClosingEventArgs e) + { + ReleaseVideoThread(); + } + + private void NewVideoDownload_Load(object sender, EventArgs e) + { + if (!hasSet) + { + txtURL.Text = ClipboardHelper.GetURLOnClipboard(); + } + } + + private void btnCancel_Click(object sender, EventArgs e) + { + Close(); + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/UI/NewVideoDownload.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/UI/NewVideoDownload.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 64 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/UI/SupportedVideoSitesForm.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/UI/SupportedVideoSitesForm.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,109 @@ +namespace MyDownloader.Extension.Video.UI +{ + partial class SupportedVideoSitesForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.lstSites = new System.Windows.Forms.ListBox(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.button1 = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(9, 9); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(33, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Sites:"; + // + // lstSites + // + this.lstSites.FormattingEnabled = true; + this.lstSites.Location = new System.Drawing.Point(12, 25); + this.lstSites.Name = "lstSites"; + this.lstSites.Size = new System.Drawing.Size(272, 160); + this.lstSites.TabIndex = 1; + this.lstSites.SelectedIndexChanged += new System.EventHandler(this.lstSites_SelectedIndexChanged); + // + // pictureBox1 + // + this.pictureBox1.InitialImage = null; + this.pictureBox1.Location = new System.Drawing.Point(12, 191); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(272, 72); + this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; + this.pictureBox1.TabIndex = 37; + this.pictureBox1.TabStop = false; + // + // button1 + // + this.button1.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.button1.Location = new System.Drawing.Point(208, 269); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 23); + this.button1.TabIndex = 2; + this.button1.Text = "Close"; + this.button1.UseVisualStyleBackColor = true; + // + // SupportedVideoSitesForm + // + this.AcceptButton = this.button1; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.button1; + this.ClientSize = new System.Drawing.Size(296, 299); + this.Controls.Add(this.button1); + this.Controls.Add(this.pictureBox1); + this.Controls.Add(this.lstSites); + this.Controls.Add(this.label1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "SupportedVideoSitesForm"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Supported Video Sites"; + this.Load += new System.EventHandler(this.SupportedVideoSitesForm_Load); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.ListBox lstSites; + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.Button button1; + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/UI/SupportedVideoSitesForm.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/UI/SupportedVideoSitesForm.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using MyDownloader.Extension.Video; +using System.IO; +using MyDownloader.Core.UI; + +namespace MyDownloader.Extension.Video.UI +{ + public partial class SupportedVideoSitesForm : Form + { + VideoDownloadExtension extension; + + public SupportedVideoSitesForm() + { + InitializeComponent(); + } + + private void SupportedVideoSitesForm_Load(object sender, EventArgs e) + { + extension = (VideoDownloadExtension)AppManager.Instance.Application.GetExtensionByType(typeof(VideoDownloadExtension)); + + for (int i = 0; i < extension.Handlers.Count; i++) + { + this.lstSites.Items.Add(extension.Handlers[i]); + } + + if (this.lstSites.Items.Count > 0) + { + this.lstSites.SelectedIndex = 0; + } + } + + private void lstSites_SelectedIndexChanged(object sender, EventArgs e) + { + VideoDownloadHandler handler = (VideoDownloadHandler)lstSites.Items[lstSites.SelectedIndex]; + Type t = handler.Type; + string logoName = t.Namespace + ".Logos." + t.Name + ".png"; + + using (Stream s = t.Assembly.GetManifestResourceStream(logoName)) + { + pictureBox1.Image = Image.FromStream(s); + } + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/UI/SupportedVideoSitesForm.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/UI/SupportedVideoSitesForm.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/UI/VideoFormatCtrl.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/UI/VideoFormatCtrl.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,79 @@ +namespace MyDownloader.Extension.Video.UI +{ + partial class VideoFormatCtrl + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.chkConvert = new System.Windows.Forms.CheckBox(); + this.cboTypes = new System.Windows.Forms.ComboBox(); + this.SuspendLayout(); + // + // chkConvert + // + this.chkConvert.AutoSize = true; + this.chkConvert.Dock = System.Windows.Forms.DockStyle.Top; + this.chkConvert.Location = new System.Drawing.Point(0, 0); + this.chkConvert.Name = "chkConvert"; + this.chkConvert.Size = new System.Drawing.Size(202, 17); + this.chkConvert.TabIndex = 0; + this.chkConvert.Text = "Convert when done:"; + this.chkConvert.UseVisualStyleBackColor = true; + this.chkConvert.CheckedChanged += new System.EventHandler(this.chkConvert_CheckedChanged); + // + // cboTypes + // + this.cboTypes.Dock = System.Windows.Forms.DockStyle.Top; + this.cboTypes.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboTypes.Items.AddRange(new object[] { + "AVI", + "MPEG", + "MP3 (Audio Only)"}); + this.cboTypes.Location = new System.Drawing.Point(0, 17); + this.cboTypes.Name = "cboTypes"; + this.cboTypes.Size = new System.Drawing.Size(202, 21); + this.cboTypes.TabIndex = 1; + this.cboTypes.SelectedIndexChanged += new System.EventHandler(this.cboTypes_SelectedIndexChanged); + // + // VideoFormatCtrl + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.cboTypes); + this.Controls.Add(this.chkConvert); + this.Name = "VideoFormatCtrl"; + this.Size = new System.Drawing.Size(202, 52); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.CheckBox chkConvert; + private System.Windows.Forms.ComboBox cboTypes; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/UI/VideoFormatCtrl.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/UI/VideoFormatCtrl.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.Extension.Video.UI +{ + public partial class VideoFormatCtrl : UserControl + { + public VideoFormatCtrl() + { + InitializeComponent(); + + UpdateUI(); + cboTypes.SelectedIndex = 0; + } + + + public event EventHandler Change; + + public VideoFormat VideoFormat + { + get + { + if (chkConvert.Checked) + { + if (cboTypes.SelectedIndex == 0) return VideoFormat.AVI; + if (cboTypes.SelectedIndex == 1) return VideoFormat.MPEG; + return VideoFormat.MP3; + } + return VideoFormat.None; + } + set + { + chkConvert.Checked = value != VideoFormat.None; + switch (value) + { + case VideoFormat.AVI: + cboTypes.SelectedIndex = 0; + break; + case VideoFormat.MPEG: + cboTypes.SelectedIndex = 1; + break; + case VideoFormat.MP3: + cboTypes.SelectedIndex = 2; + break; + } + } + } + + protected virtual void OnChange() + { + if (Change != null) + { + Change(this, EventArgs.Empty); + } + } + + private void chkConvert_CheckedChanged(object sender, EventArgs e) + { + UpdateUI(); + + OnChange(); + } + + private void UpdateUI() + { + cboTypes.Enabled = chkConvert.Checked; + } + + private void cboTypes_SelectedIndexChanged(object sender, EventArgs e) + { + OnChange(); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/UI/VideoFormatCtrl.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/UI/VideoFormatCtrl.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/VideoConverter.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/VideoConverter.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core; +using System.Threading; +using System.Windows.Forms; +using System.Diagnostics; +using System.IO; +using System.Reflection; + +namespace MyDownloader.Extension.Video +{ + [Serializable] + public enum VideoFormat: int + { + None, + AVI, + MPEG, + MP3 + } + + public static class VideoConverter + { + private const string VideoConverterFormatProperty = "VideoConverterFormatProperty"; + + private const string ffmpeg = "ffmpeg.exe"; + + private const string ToAVICmdLine = "-y -i \"{0}\" -vcodec msmpeg4v2 -acodec mp3 -sameq -ab 128 \"{1}\""; + private const string ToMPEGCmdLine = "-y -i \"{0}\" -vcodec mpeg1video -acodec mp3 -sameq -ab 64 \"{1}\""; + private const string ToMP3CmdLine = "-y -i \"{0}\" -f mp3 -vn -acodec copy \"{1}\""; + + public static void Convert(string fileName, VideoFormat fmt) + { + if (fmt == VideoFormat.None) throw new ArgumentException("Invalid argmument.", "fmt"); + + string cmd = String.Empty; + + if (fmt == VideoFormat.AVI) cmd = ToAVICmdLine; + if (fmt == VideoFormat.MPEG) cmd = ToMPEGCmdLine; + if (fmt == VideoFormat.MP3) cmd = ToMP3CmdLine; + + string directory = Path.GetDirectoryName(fileName); + + // the original file name ends with 'AVI', 'MPEG', 'MP3'....new we rename the file to .FLV + + string flvPath = Path.Combine(directory, String.Concat(Guid.NewGuid().ToString("N"), ".flv")); + + try + { + File.Move(fileName, flvPath); + + string sourceFile = Path.GetFileName(flvPath); + string targetFile = Path.GetFileName(fileName); + + cmd = String.Format(cmd, sourceFile, targetFile); + + string toolPath = Path.GetDirectoryName(Application.ExecutablePath); + //toolPath = @"C:\Documents and Settings\guilherme.labigalini\Desktop\MyDownloader\MyDownloader\MyDownloader.App\bin\Debug\"; + ProcessStartInfo psi = new ProcessStartInfo(toolPath + "\\" + ffmpeg, cmd); + psi.UseShellExecute = false; + psi.CreateNoWindow = true; + psi.WorkingDirectory = directory; + + using (Process p = Process.Start(psi)) + { + p.WaitForExit(); + } + } + finally + { + File.Delete(flvPath); + } + } + + public static void ConvertIfNecessary(Downloader d) + { + VideoFormat fmt = GetConvertOption(d); + + if (fmt == VideoFormat.None) + { + return; + } + + try + { + d.StatusMessage = "converting video"; + + Convert(d.LocalFile, fmt); + } + catch (ThreadAbortException) + { + throw; + } + catch (Exception ex) + { + d.LastError = new Exception("error converting video: " + ex.Message, ex); + } + finally + { + d.StatusMessage = null; + } + } + + public static VideoFormat GetConvertOption(Downloader d) + { + if (! d.ExtendedProperties.ContainsKey(VideoConverterFormatProperty)) + { + return VideoFormat.None; + } + + object objFmt = d.ExtendedProperties[VideoConverterFormatProperty]; + + if (objFmt == null) + { + return VideoFormat.None; + } + + return (VideoFormat)objFmt; + } + + public static void SetConvertOption(Downloader d, VideoFormat format) + { + if (format == VideoFormat.None) + { + if (d.ExtendedProperties.ContainsKey(VideoConverterFormatProperty)) + { + d.ExtendedProperties.Remove(VideoConverterFormatProperty); + } + } + + d.ExtendedProperties[VideoConverterFormatProperty] = format; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/VideoDownloadExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/VideoDownloadExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; +using MyDownloader.Core; +using MyDownloader.Extension.Video.Impl; +using System.Windows.Forms; + +namespace MyDownloader.Extension.Video +{ + public class VideoDownloadExtension: IExtension + { + List handlers; + + #region IExtension Members + + public string Name + { + get { return "Video Downloader"; } + } + + public IUIExtension UIExtension + { + get { return new VideoDownloadUIExtension(); } + } + + #endregion + + #region Methods + + public VideoDownloadHandler GetHandlerByURL(string url) + { + for (int i = 0; i < handlers.Count; i++) + { + if (handlers[i].Matchs(url)) + { + return handlers[i]; + } + } + + return null; + } + + #endregion + + public List Handlers + { + get + { + return handlers; + } + } + + public VideoDownloadExtension() + { + handlers = new List(); + handlers.Add(new VideoDownloadHandler(YouTubeDownloader.SiteName, YouTubeDownloader.UrlPattern, typeof(YouTubeDownloader))); + handlers.Add(new VideoDownloadHandler(GoogleVideoDownloader.SiteName, GoogleVideoDownloader.UrlPattern, typeof(GoogleVideoDownloader))); + handlers.Add(new VideoDownloadHandler(PutfileVideoDownloader.SiteName, PutfileVideoDownloader.UrlPattern, typeof(PutfileVideoDownloader))); + handlers.Add(new VideoDownloadHandler(MetaCafeVideoDownloader.SiteName, MetaCafeVideoDownloader.UrlPattern, typeof(MetaCafeVideoDownloader))); + handlers.Add(new VideoDownloadHandler(BreakVideoDownloader.SiteName, BreakVideoDownloader.UrlPattern, typeof(BreakVideoDownloader))); + + //ProtocolProviderFactory.ResolvingProtocolProvider += new EventHandler(resolvingProtocolProviderEvent); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/VideoDownloadHandler.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/VideoDownloadHandler.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; +using MyDownloader.Core; + +namespace MyDownloader.Extension.Video +{ + public class VideoDownloadHandler + { + #region Fields + + private string urlRegExpr; + private string name; + private Type type; + private Regex reg; + + #endregion + + #region Constructor + + public VideoDownloadHandler(string name, string regExp, Type type) + { + this.Name = name; + this.UrlRegExpr = regExp; + this.Type = type; + + RegexOptions options = ((RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline) + | RegexOptions.IgnoreCase); + reg = new Regex(this.UrlRegExpr, options); + } + + #endregion + + #region Properties + + public string Name + { + get { return name; } + set { name = value; } + } + + public string UrlRegExpr + { + get { return urlRegExpr; } + set { urlRegExpr = value; } + } + + public Type Type + { + get { return type; } + set { type = value; } + } + + #endregion + + #region Methods + + public bool Matchs(string url) + { + return reg.IsMatch(url); + } + + public override string ToString() + { + return this.Name; + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Video/VideoDownloadUIExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Video/VideoDownloadUIExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; +using MyDownloader.Core; + +namespace MyDownloader.Extension.Video +{ + public class VideoDownloadUIExtension: IUIExtension + { + #region IUIExtension Members + + public System.Windows.Forms.Control[] CreateSettingsView() + { + return null; + } + + public void PersistSettings(System.Windows.Forms.Control[] settingsView) + { + } + + #endregion + + + public void ShowNewVideoDialog(string url, bool modal) + { + if (modal) + { + using (UI.NewVideoDownload videoDownload = new UI.NewVideoDownload()) + { + if (!String.IsNullOrEmpty(url)) + { + videoDownload.DownloadLocation = ResourceLocation.FromURL(url); + } + videoDownload.ShowDialog(); + } + } + else + { + UI.NewVideoDownload videoDownload = new UI.NewVideoDownload(); + + if (!String.IsNullOrEmpty(url)) + { + videoDownload.DownloadLocation = ResourceLocation.FromURL(url); + } + + videoDownload.ShowInTaskbar = true; + videoDownload.MinimizeBox = true; + videoDownload.Show(); + videoDownload.Focus(); + videoDownload.TopMost = true; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/WindowsIntegration/ClipboardMonitor/ClipboardMonitor.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/WindowsIntegration/ClipboardMonitor/ClipboardMonitor.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,166 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Diagnostics; +using MyDownloader.Core; +using MyDownloader.Core.UI; +using System.Security.Permissions; +using System.ComponentModel; + +//http://radsoftware.com.au/articles/clipboardmonitor.aspx +namespace MyDownloader.Extension.WindowsIntegration.ClipboardMonitor +{ + [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] + public class ClipboardMonitor : IDisposable + { + [DllImport("user32.dll", CharSet = CharSet.Auto)] + private static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer); + + [DllImport("User32.dll", CharSet = CharSet.Auto)] + private static extern bool ChangeClipboardChain( + IntPtr hWndRemove, // handle to window to remove + IntPtr hWndNewNext // handle to next window + ); + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + private static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam); + + private const int WM_DRAWCLIPBOARD = 0x0308; + private const int WM_CHANGECBCHAIN = 0x030D; + + private IntPtr handle; + private IntPtr clipboardViewerNext; + private IClipboardDataHandler dataHandler; + private bool enabled; + + #region Methods + + public bool FilterMessage(ref Message m) + { + if (!enabled) + { + return false; + } + + switch (m.Msg) + { + // + // The WM_DRAWCLIPBOARD message is sent to the first window + // in the clipboard viewer chain when the content of the + // clipboard changes. This enables a clipboard viewer + // window to display the new content of the clipboard. + // + case WM_DRAWCLIPBOARD: + + Debug.WriteLine("WindowProc DRAWCLIPBOARD: " + m.Msg, "WndProc"); + + if (dataHandler != null) + { + try + { + IDataObject iData = Clipboard.GetDataObject(); + + dataHandler.HandleClipboardData(iData); + } + catch + { + } + } + + // + // Each window that receives the WM_DRAWCLIPBOARD message + // must call the SendMessage function to pass the message + // on to the next window in the clipboard viewer chain. + // + SendMessage(clipboardViewerNext, m.Msg, m.WParam, m.LParam); + return true; + + + // + // The WM_CHANGECBCHAIN message is sent to the first window + // in the clipboard viewer chain when a window is being + // removed from the chain. + // + case WM_CHANGECBCHAIN: + Debug.WriteLine("WM_CHANGECBCHAIN: lParam: " + m.LParam, "WndProc"); + + // When a clipboard viewer window receives the WM_CHANGECBCHAIN message, + // it should call the SendMessage function to pass the message to the + // next window in the chain, unless the next window is the window + // being removed. In this case, the clipboard viewer should save + // the handle specified by the lParam parameter as the next window in the chain. + + // + // wParam is the Handle to the window being removed from + // the clipboard viewer chain + // lParam is the Handle to the next window in the chain + // following the window being removed. + if (m.WParam == clipboardViewerNext) + { + // + // If wParam is the next clipboard viewer then it + // is being removed so update pointer to the next + // window in the clipboard chain + // + clipboardViewerNext = m.LParam; + } + else + { + SendMessage(clipboardViewerNext, m.Msg, m.WParam, m.LParam); + } + return true; + + default: + return false; + } + } + #endregion + + #region IDisposable Members + + public void Dispose() + { + ChangeClipboardChain(handle, clipboardViewerNext); + handle = IntPtr.Zero; + clipboardViewerNext = IntPtr.Zero; + dataHandler = null; + } + + #endregion + + #region Properties + + public bool Enabled + { + get + { + return enabled; + } + set + { + Settings.Default.MonitorClipboard = value; + Settings.Default.Save(); + } + } + + #endregion + + public ClipboardMonitor(IClipboardDataHandler handler, IntPtr winHandle) + { + enabled = Settings.Default.MonitorClipboard; + + Settings.Default.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e) + { + enabled = Settings.Default.MonitorClipboard; + }; + + handle = winHandle; + clipboardViewerNext = SetClipboardViewer(handle); + + this.dataHandler = handler; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/WindowsIntegration/ClipboardMonitor/IClipboardDataHandler.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/WindowsIntegration/ClipboardMonitor/IClipboardDataHandler.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.Extension.WindowsIntegration.ClipboardMonitor +{ + public interface IClipboardDataHandler + { + void HandleClipboardData(IDataObject data); + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/WindowsIntegration/Settings.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/WindowsIntegration/Settings.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,38 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MyDownloader.Extension.WindowsIntegration { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool MonitorClipboard { + get { + return ((bool)(this["MonitorClipboard"])); + } + set { + this["MonitorClipboard"] = value; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/WindowsIntegration/Settings.settings --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/WindowsIntegration/Settings.settings Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,9 @@ + + + + + + False + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/WindowsIntegration/WindowsIntegrationExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/WindowsIntegration/WindowsIntegrationExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; + +namespace MyDownloader.Extension.WindowsIntegration +{ + public class WindowsIntegrationExtension: IExtension + { + #region IExtension Members + + public string Name + { + get { return ("Windows Integration"); } + } + + public IUIExtension UIExtension + { + get { return new WindowsIntegrationUIExtension(); } + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/WindowsIntegration/WindowsIntegrationUI.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/WindowsIntegration/WindowsIntegrationUI.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,73 @@ +namespace MyDownloader.Extension.WindowsIntegration +{ + partial class WindowsIntegrationUI + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.chkStartWithWindows = new System.Windows.Forms.CheckBox(); + this.chkMonitorWindowsClipboard = new System.Windows.Forms.CheckBox(); + this.SuspendLayout(); + // + // chkStartWithWindows + // + this.chkStartWithWindows.AutoSize = true; + this.chkStartWithWindows.Location = new System.Drawing.Point(0, 0); + this.chkStartWithWindows.Name = "chkStartWithWindows"; + this.chkStartWithWindows.Size = new System.Drawing.Size(191, 17); + this.chkStartWithWindows.TabIndex = 0; + this.chkStartWithWindows.Text = "Start MyDownloader with Windows"; + this.chkStartWithWindows.UseVisualStyleBackColor = true; + // + // chkMonitorWindowsClipboard + // + this.chkMonitorWindowsClipboard.AutoSize = true; + this.chkMonitorWindowsClipboard.Location = new System.Drawing.Point(0, 16); + this.chkMonitorWindowsClipboard.Name = "chkMonitorWindowsClipboard"; + this.chkMonitorWindowsClipboard.Size = new System.Drawing.Size(155, 17); + this.chkMonitorWindowsClipboard.TabIndex = 1; + this.chkMonitorWindowsClipboard.Text = "Monitor Windows Clipboard"; + this.chkMonitorWindowsClipboard.UseVisualStyleBackColor = true; + // + // WindowsIntegrationUI + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.chkMonitorWindowsClipboard); + this.Controls.Add(this.chkStartWithWindows); + this.Name = "WindowsIntegrationUI"; + this.Size = new System.Drawing.Size(429, 111); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.CheckBox chkStartWithWindows; + private System.Windows.Forms.CheckBox chkMonitorWindowsClipboard; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/WindowsIntegration/WindowsIntegrationUI.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/WindowsIntegration/WindowsIntegrationUI.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +namespace MyDownloader.Extension.WindowsIntegration +{ + public partial class WindowsIntegrationUI : UserControl + { + public WindowsIntegrationUI() + { + InitializeComponent(); + + this.Text = "Windows Integration"; + + chkStartWithWindows.Checked = WindowsStartupUtility.IsRegistered(); + chkMonitorWindowsClipboard.Checked = Settings.Default.MonitorClipboard; + } + + public bool MonitorClipboard + { + get + { + return chkMonitorWindowsClipboard.Checked; + } + } + + public bool StartWithWindows + { + get + { + return chkStartWithWindows.Checked; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/WindowsIntegration/WindowsIntegrationUI.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/WindowsIntegration/WindowsIntegrationUI.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/WindowsIntegration/WindowsIntegrationUIExtension.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/WindowsIntegration/WindowsIntegrationUIExtension.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core.Extensions; + +namespace MyDownloader.Extension.WindowsIntegration +{ + public class WindowsIntegrationUIExtension : IUIExtension + { + #region IUIExtension Members + + public System.Windows.Forms.Control[] CreateSettingsView() + { + return new System.Windows.Forms.Control[] { new WindowsIntegrationUI() }; + } + + public void PersistSettings(System.Windows.Forms.Control[] settingsView) + { + WindowsIntegrationUI windowsIntegration = (WindowsIntegrationUI)settingsView[0]; + + Settings.Default.MonitorClipboard = windowsIntegration.MonitorClipboard; + Settings.Default.Save(); + + WindowsStartupUtility.Register(windowsIntegration.StartWithWindows); + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/WindowsIntegration/WindowsStartupUtility.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/WindowsIntegration/WindowsStartupUtility.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Win32; +using System.Windows.Forms; +using System.IO; +using System.Security.Permissions; +using System.Security.AccessControl; + +namespace MyDownloader.Extension.WindowsIntegration +{ + [RegistryPermission(SecurityAction.LinkDemand, + Read = "Software\\Microsoft\\Windows\\CurrentVersion\\Run", + Write = "Software\\Microsoft\\Windows\\CurrentVersion\\Run")] + internal class WindowsStartupUtility + { + private static string GetKeyName() + { + return Path.GetFileNameWithoutExtension(Application.ExecutablePath); + } + + private static string GetKeyValue() + { + return String.Format("\"{0}\" /as", Application.ExecutablePath); + } + + private static RegistryKey GetRegistryKey() + { + // Create a security context for a new key that we will use to store our data. + // The security context will restrict access to only our user. + string user = Environment.UserDomainName + "\\" + Environment.UserName; + RegistrySecurity security = new RegistrySecurity(); + RegistryAccessRule rule = new RegistryAccessRule(user, + RegistryRights.FullControl, + InheritanceFlags.ContainerInherit, + PropagationFlags.None, + AccessControlType.Allow); + security.AddAccessRule(rule); + + RegistryKey key = Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", + RegistryKeyPermissionCheck.ReadWriteSubTree, security); + + return key; + } + + public static bool IsRegistered() + { + using (RegistryKey key = GetRegistryKey()) + { + string value = key.GetValue(GetKeyName(), null) as string; + + return value != null && value.Equals(GetKeyValue(), StringComparison.OrdinalIgnoreCase); + } + } + + public static void Register(bool register) + { + using (RegistryKey key = GetRegistryKey()) + { + if (register) + { + key.SetValue(GetKeyName(), GetKeyValue(), RegistryValueKind.String); + } + else + { + key.DeleteValue(GetKeyName(), false); + } + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Zip/NoCloseSubStream.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Zip/NoCloseSubStream.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace MyDownloader.Extension.Zip +{ + /// + /// Stream without + /// + internal class NoCloseSubStream : Stream + { + Stream baseStream; + + public NoCloseSubStream(Stream b) + { + baseStream = b; + } + + /// + /// I needed to implement the abstract member. + /// + public override bool CanRead + { + get + { + return baseStream.CanRead; + } + } + + /// + /// I needed to implement the abstract member. + /// + public override bool CanSeek + { + get + { + return baseStream.CanSeek; + } + } + + /// + /// I needed to implement the abstract member. + /// + public override bool CanWrite + { + get + { + return baseStream.CanWrite; + } + } + + /// + /// I needed to implement the abstract member. + /// + public override long Length + { + get + { + return baseStream.Length; + } + } + + /// + /// I needed to implement the abstract member. + /// + public override long Position + { + get + { + return baseStream.Position; + } + set + { + baseStream.Position = value; + } + } + + /// + /// I needed to implement the abstract member. + /// + public override long Seek(long offset, SeekOrigin origin) + { + return baseStream.Seek(offset, origin); + } + + /// + /// I needed to implement the abstract member. + /// + public override void SetLength(long val) + { + baseStream.SetLength(val); + } + + /// + /// I needed to implement the abstract member. + /// + public override int ReadByte() + { + return baseStream.ReadByte(); + } + + /// + /// I needed to implement the abstract member. + /// + public override int Read(byte[] b, int off, int len) + { + return baseStream.Read(b, off, len); + } + + public override void Write(byte[] buf, int off, int len) + { + baseStream.Write(buf, off, len); + } + + public override void WriteByte(byte bv) + { + baseStream.WriteByte(bv); + } + + public override void Close() + { + baseStream = null; + } + + public override void Flush() + { + baseStream.Flush(); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Zip/PartialInputStream.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Zip/PartialInputStream.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Net; +using ICSharpCode.SharpZipLib.Zip.Compression.Streams; + +namespace MyDownloader.Extension.Zip +{ + internal class PartialInputStream : InflaterInputStream + { + Stream baseStream; + long filepos; + long end; + + public PartialInputStream(Stream baseStream, long len) + : base(baseStream) + { + this.baseStream = baseStream; + filepos = 0; + end = len; + } + + public override int Available + { + get + { + long amount = end - filepos; + if (amount > Int32.MaxValue) + { + return Int32.MaxValue; + } + + return (int)amount; + } + } + + public override int ReadByte() + { + if (filepos == end) + { + return -1; + } + + lock (baseStream) + { + filepos++; + return baseStream.ReadByte(); + } + } + + public override int Read(byte[] b, int off, int len) + { + if (len > end - filepos) + { + len = (int)(end - filepos); + if (len == 0) + { + return 0; + } + } + lock (baseStream) + { + int count = StreamHelper.ReadAll(b, off, len, baseStream); + if (count > 0) + { + filepos += len; + } + return count; + } + } + + public long SkipBytes(long amount) + { + if (amount < 0) + { + throw new ArgumentOutOfRangeException(); + } + if (amount > end - filepos) + { + amount = end - filepos; + } + filepos += amount; + for (int i = 0; i < amount; i++) + baseStream.ReadByte(); + return amount; + } + + public override void Close() + { + baseStream.Close(); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Zip/StreamHelper.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Zip/StreamHelper.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace MyDownloader.Extension.Zip +{ + internal static class StreamHelper + { + internal static int ReadAll(byte[] bb, int p, int sst, Stream s) + { + int ss = 0; + while (ss < sst) + { + int r = s.Read(bb, p, sst - ss); + if (r <= 0) + return ss; + ss += r; + p += r; + } + return ss; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Zip/ZipOutputStream.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Zip/ZipOutputStream.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,554 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Collections; +using System.IO; + +using ICSharpCode.SharpZipLib.Zip.Compression.Streams; +using ICSharpCode.SharpZipLib.Zip; +using ICSharpCode.SharpZipLib.Checksums; +using ICSharpCode.SharpZipLib.Zip.Compression; +using ICSharpCode.SharpZipLib.BZip2; + +namespace MyDownloader.Extension.Zip +{ + /// + /// This is a FilterOutputStream that writes the files into a zip + /// archive one after another. It has a special method to start a new + /// zip entry. The zip entries contains information about the file name + /// size, compressed size, CRC, etc. + /// + /// It includes support for STORED and DEFLATED and BZIP2 entries. + /// This class is not thread safe. + /// + /// author of the original java version : Jochen Hoenicke + /// + /// This sample shows how to create a zip file + /// + /// using System; + /// using System.IO; + /// + /// using NZlib.Zip; + /// + /// class MainClass + /// { + /// public static void Main(string[] args) + /// { + /// string[] filenames = Directory.GetFiles(args[0]); + /// + /// ZipOutputStream s = new ZipOutputStream(File.Create(args[1])); + /// + /// s.SetLevel(5); // 0 - store only to 9 - means best compression + /// + /// foreach (string file in filenames) { + /// FileStream fs = File.OpenRead(file); + /// + /// byte[] buffer = new byte[fs.Length]; + /// fs.Read(buffer, 0, buffer.Length); + /// + /// ZipEntry entry = new ZipEntry(file); + /// + /// s.PutNextEntry(entry); + /// + /// s.Write(buffer, 0, buffer.Length); + /// + /// } + /// + /// s.Finish(); + /// s.Close(); + /// } + /// } + /// + /// + internal class ZipOutputStream : DeflaterOutputStream + { + private ArrayList entries = new ArrayList(); + private Crc32 crc = new Crc32(); + private ZipEntry curEntry = null; + + private long startPosition = 0; + private Stream additionalStream = null; + + private CompressionMethod curMethod; + private int size; + private int offset = 0; + + private byte[] zipComment = new byte[0]; + private int defaultMethod = DEFLATED; + + /// + /// Our Zip version is hard coded to 1.0 resp. 2.0 + /// + private const int ZIP_STORED_VERSION = 10; + private const int ZIP_DEFLATED_VERSION = 20; + + /// + /// Compression method. This method doesn't compress at all. + /// + public const int STORED = 0; + + /// + /// Compression method. This method uses the Deflater. + /// + public const int DEFLATED = 8; + + public const int BZIP2 = 12; + + /// + /// Creates a new Zip output stream, writing a zip archive. + /// + /// + /// the output stream to which the zip archive is written. + /// + public ZipOutputStream(Stream baseOutputStream) + : base(baseOutputStream, new Deflater(Deflater.DEFAULT_COMPRESSION, true)) + { + } + + /// + /// Set the zip file comment. + /// + /// + /// the comment. + /// + /// + /// if UTF8 encoding of comment is longer than 0xffff bytes. + /// + public void SetComment(string comment) + { + byte[] commentBytes = ZipConstants.ConvertToArray(comment); + if (commentBytes.Length > 0xffff) + { + throw new ArgumentException("Comment too long."); + } + zipComment = commentBytes; + } + + /// + /// Sets default compression method. If the Zip entry specifies + /// another method its method takes precedence. + /// + /// + /// the method. + /// + /// + /// if method is not supported. + /// + public void SetMethod(int method) + { + if (method != STORED && method != DEFLATED && method != BZIP2) + { + throw new ArgumentException("Method not supported."); + } + defaultMethod = method; + } + + /// + /// Sets default compression level. The new level will be activated + /// immediately. + /// + /// + /// if level is not supported. + /// + /// + public void SetLevel(int level) + { + deflater_.SetLevel(level); + } + + /// + /// Write an unsigned short in little endian byte order. + /// + private void WriteLeShort(int value) + { + baseOutputStream_.WriteByte((byte)value); + baseOutputStream_.WriteByte((byte)(value >> 8)); + } + + /// + /// Write an int in little endian byte order. + /// + private void WriteLeInt(int value) + { + WriteLeShort(value); + WriteLeShort(value >> 16); + } + + /// + /// Write an int in little endian byte order. + /// + private void WriteLeLong(long value) + { + WriteLeInt((int)value); + WriteLeInt((int)(value >> 32)); + } + + + bool shouldWriteBack = false; + long seekPos = -1; + /// + /// Starts a new Zip entry. It automatically closes the previous + /// entry if present. If the compression method is stored, the entry + /// must have a valid size and crc, otherwise all elements (except + /// name) are optional, but must be correct if present. If the time + /// is not set in the entry, the current time is used. + /// + /// + /// the entry. + /// + /// + /// if an I/O error occured. + /// + /// + /// if stream was finished + /// + public void PutNextEntry(ZipEntry entry) + { + if (entries == null) + { + throw new InvalidOperationException("ZipOutputStream was finished"); + } + + if (curEntry != null) + { + CloseEntry(); + } + + CompressionMethod method = entry.CompressionMethod; + int flags = 0; + + switch (method) + { + case CompressionMethod.Stored: + if (entry.CompressedSize >= 0) + { + if (entry.Size < 0) + { + entry.Size = entry.CompressedSize; + } + else if (entry.Size != entry.CompressedSize) + { + throw new ZipException("Method STORED, but compressed size != size"); + } + } + else + { + entry.CompressedSize = entry.Size; + } + + if (entry.Size < 0) + { + throw new ZipException("Method STORED, but size not set"); + } + else if (entry.Crc < 0) + { + throw new ZipException("Method STORED, but crc not set"); + } + break; + case (CompressionMethod)12: + startPosition = baseOutputStream_.Position; + additionalStream = new BZip2OutputStream(new NoCloseSubStream(baseOutputStream_)); + if (entry.CompressedSize < 0 || entry.Size < 0 || entry.Crc < 0) + { + flags |= 8; + } + break; + case CompressionMethod.Deflated: + if (entry.CompressedSize < 0 || entry.Size < 0 || entry.Crc < 0) + { + flags |= 8; + } + break; + } + + + // if (entry.DosTime < 0) { + // entry.Time = System.Environment.TickCount; + // } + + entry.Flags = flags; + entry.Offset = offset; + entry.CompressionMethod = (CompressionMethod)method; + + curMethod = method; + // Write the local file header + WriteLeInt(ZipConstants.LocalHeaderSignature); + + // write ZIP version + WriteLeShort(method == CompressionMethod.Stored ? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION); + if ((flags & 8) == 0) + { + WriteLeShort(flags); + WriteLeShort((byte)method); + WriteLeInt((int)entry.DosTime); + WriteLeInt((int)entry.Crc); + WriteLeInt((int)entry.CompressedSize); + WriteLeInt((int)entry.Size); + } + else + { + if (baseOutputStream_.CanSeek) + { + shouldWriteBack = true; + WriteLeShort((short)(flags & ~8)); + } + else + { + shouldWriteBack = false; + WriteLeShort(flags); + } + WriteLeShort((byte)method); + WriteLeInt((int)entry.DosTime); + seekPos = baseOutputStream_.Position; + WriteLeInt(0); + WriteLeInt(0); + WriteLeInt(0); + } + byte[] name = ZipConstants.ConvertToArray(entry.Name); + + if (name.Length > 0xFFFF) + { + throw new ZipException("Name too long."); + } + byte[] extra = entry.ExtraData; + if (extra == null) + { + extra = new byte[0]; + } + if (extra.Length > 0xFFFF) + { + throw new ZipException("Extra data too long."); + } + + WriteLeShort(name.Length); + WriteLeShort(extra.Length); + baseOutputStream_.Write(name, 0, name.Length); + baseOutputStream_.Write(extra, 0, extra.Length); + + offset += ZipConstants.LocalHeaderBaseSize + name.Length + extra.Length; + + /* Activate the entry. */ + curEntry = entry; + crc.Reset(); + if (method == CompressionMethod.Deflated) + { + deflater_.Reset(); + } + size = 0; + } + + /// + /// Closes the current entry. + /// + /// + /// if an I/O error occured. + /// + /// + /// if no entry is active. + /// + public void CloseEntry() + { + if (curEntry == null) + { + throw new InvalidOperationException("No open entry"); + } + + /* First finish the deflater, if appropriate */ + int csize = 0; + if (curMethod == CompressionMethod.Deflated) + { + base.Finish(); + csize = (int)deflater_.TotalOut; + } + else if (curMethod == (CompressionMethod)12) + { + // close the sub stream, no problem because the substream has a fake + // close + additionalStream.Close(); + additionalStream = null; + csize = (int)(baseOutputStream_.Position - startPosition); + } + else + csize = size; + + if (curEntry.Size < 0) + { + curEntry.Size = size; + } + else if (curEntry.Size != size) + { + throw new ZipException("size was " + size + ", but I expected " + curEntry.Size); + } + + if (curEntry.CompressedSize < 0) + { + curEntry.CompressedSize = csize; + } + else if (curEntry.CompressedSize != csize) + { + throw new ZipException("compressed size was " + csize + ", but I expected " + curEntry.CompressedSize); + } + + if (curEntry.Crc < 0) + { + curEntry.Crc = crc.Value; + } + else if (curEntry.Crc != crc.Value) + { + throw new ZipException("crc was " + crc.Value + + ", but I expected " + + curEntry.Crc); + } + + offset += csize; + + /* Now write the data descriptor entry if needed. */ + if (curMethod != CompressionMethod.Stored && (curEntry.Flags & 8) != 0) + { + if (shouldWriteBack) + { + curEntry.Flags &= ~8; + long curPos = baseOutputStream_.Position; + baseOutputStream_.Seek(seekPos, SeekOrigin.Begin); + WriteLeInt((int)curEntry.Crc); + WriteLeInt((int)curEntry.CompressedSize); + WriteLeInt((int)curEntry.Size); + baseOutputStream_.Seek(curPos, SeekOrigin.Begin); + shouldWriteBack = false; + } + else + { + WriteLeInt(ZipConstants.DataDescriptorSignature); + WriteLeInt((int)curEntry.Crc); + WriteLeInt((int)curEntry.CompressedSize); + WriteLeInt((int)curEntry.Size); + offset += ZipConstants.DataDescriptorSize; + } + } + + entries.Add(curEntry); + curEntry = null; + } + + /// + /// Writes the given buffer to the current entry. + /// + /// + /// if an I/O error occured. + /// + /// + /// if no entry is active. + /// + public override void Write(byte[] b, int off, int len) + { + if (curEntry == null) + { + throw new InvalidOperationException("No open entry."); + } + + switch (curMethod) + { + case (CompressionMethod)12: + additionalStream.Write(b, off, len); + break; + case CompressionMethod.Deflated: + base.Write(b, off, len); + break; + case CompressionMethod.Stored: + baseOutputStream_.Write(b, off, len); + break; + } + + crc.Update(b, off, len); + size += len; + } + + /// + /// Finishes the stream. This will write the central directory at the + /// end of the zip file and flush the stream. + /// + /// + /// if an I/O error occured. + /// + public override void Finish() + { + if (entries == null) + { + return; + } + + if (curEntry != null) + { + CloseEntry(); + } + + int numEntries = 0; + int sizeEntries = 0; + + foreach (ZipEntry entry in entries) + { + // TODO : check the appnote file for compilance with the central directory standard + CompressionMethod method = entry.CompressionMethod; + WriteLeInt(ZipConstants.CentralHeaderSignature); + WriteLeShort(method == CompressionMethod.Stored ? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION); + WriteLeShort(method == CompressionMethod.Stored ? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION); + if (entry.IsCrypted) + { + entry.Flags |= 1; + } + WriteLeShort(entry.Flags); + WriteLeShort((short)method); + WriteLeInt((int)entry.DosTime); + WriteLeInt((int)entry.Crc); + WriteLeInt((int)entry.CompressedSize); + WriteLeInt((int)entry.Size); + + byte[] name = ZipConstants.ConvertToArray(entry.Name); + + if (name.Length > 0xffff) + { + throw new ZipException("Name too long."); + } + + byte[] extra = entry.ExtraData; + if (extra == null) + { + extra = new byte[0]; + } + + string strComment = entry.Comment; + byte[] comment = strComment != null ? ZipConstants.ConvertToArray(strComment) : new byte[0]; + if (comment.Length > 0xffff) + { + throw new ZipException("Comment too long."); + } + + WriteLeShort(name.Length); + WriteLeShort(extra.Length); + WriteLeShort(comment.Length); + WriteLeShort(0); // disk number + WriteLeShort(0); // internal file attr + WriteLeInt(0); // external file attr + WriteLeInt((int)entry.Offset); + + baseOutputStream_.Write(name, 0, name.Length); + baseOutputStream_.Write(extra, 0, extra.Length); + baseOutputStream_.Write(comment, 0, comment.Length); + ++numEntries; + sizeEntries += ZipConstants.CentralHeaderBaseSize + name.Length + extra.Length + comment.Length; + } + + WriteLeInt(ZipConstants.EndOfCentralDirectorySignature); + WriteLeShort(0); // disk number + WriteLeShort(0); // disk with start of central dir + WriteLeShort(numEntries); + WriteLeShort(numEntries); + WriteLeInt(sizeEntries); + WriteLeInt(offset); + WriteLeShort(zipComment.Length); + baseOutputStream_.Write(zipComment, 0, zipComment.Length); + baseOutputStream_.Flush(); + entries = null; + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Zip/ZipProtocolProvider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Zip/ZipProtocolProvider.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core; +using System.IO; +using ICSharpCode.SharpZipLib.Zip; + +namespace MyDownloader.Extension.Zip +{ + public class ZipProtocolProvider: IProtocolProvider + { + private const string ZipEntryNameProperty = "ZipEntryNameProperty"; + + #region Helper Methods + + public static void SetZipEntryNameProperty(Downloader downloader, string entryName) + { + downloader.ExtendedProperties[ZipEntryNameProperty] = entryName; + } + + public static string GetZipEntryNameProperty(Downloader downloader) + { + return downloader.ExtendedProperties[ZipEntryNameProperty] as string; + } + + #endregion + + private Downloader downloader; + private ZipRemoteFile remoteZipFile; + private ZipEntry entry; + + #region IProtocolProvider Members + + public void Initialize(Downloader downloader) + { + this.downloader = downloader; + } + + public Stream CreateStream(ResourceLocation rl, long initialPosition, long endPosition) + { + /* + * a chamada desse metodo nao sera apos o GetFileInfo se o download for resumeable + * sendo assim, preciso ter algum repositorio comum para guardas os "remoteZipFile" + * assim evita-se de ficar carregando as entries a cada segmento/arquivo. + * + * outro, pronto, apos o uso do segmento, deve-se liberar o remoteZipFile se não houver + * nenhum outro download vinculado a este "remoteZipFile" + */ + return remoteZipFile.GetInputStream(entry); + } + + public RemoteFileInfo GetFileInfo(ResourceLocation rl, out System.IO.Stream stream) + { + stream = null; + + remoteZipFile = new ZipRemoteFile(rl); + remoteZipFile.Load(); + + string entryName = GetZipEntryNameProperty(this.downloader); + + entry = remoteZipFile[entryName]; + + RemoteFileInfo result = new RemoteFileInfo(); + result.AcceptRanges = false; // TODO make resumeable + result.FileSize = entry.Size; + result.LastModified = entry.DateTime; + result.MimeType = "application/zip"; + + return result; + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/Zip/ZipRemoteFile.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/Zip/ZipRemoteFile.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,472 @@ +// RemoteZipFile.cs +// Copyright (C) 2003 Emanuele Ruffaldi +// +// ZipEntry parsing code taken from ZipFile.cs in SharpLibZip +// Copyright (C) 2001 Mike Krueger +// +// The original SharpLibZip code was translated from java, it was part of the GNU Classpath +// Copyright (C) 2001 Free Software Foundation, Inc. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// Linking this library statically or dynamically with other modules is +// making a combined work based on this library. Thus, the terms and +// conditions of the GNU General Public License cover the whole +// combination. +// +// As a special exception, the copyright holders of this library give you +// permission to link this library with independent modules to produce an +// executable, regardless of the license terms of these independent +// modules, and to copy and distribute the resulting executable under +// terms of your choice, provided that you also meet, for each linked +// independent module, the terms and conditions of the license of that +// module. An independent module is a module which is not derived from +// or based on this library. If you modify this library, you may extend +// this exception to your version of the library, but you are not +// obligated to do so. If you do not wish to do so, delete this +// exception statement from your version. + +using System; +using ICSharpCode.SharpZipLib; +using ICSharpCode.SharpZipLib.Zip; +using ICSharpCode.SharpZipLib.Zip.Compression.Streams; +using ICSharpCode.SharpZipLib.Zip.Compression; +using ICSharpCode.SharpZipLib.BZip2; +using System.Collections; +using System.IO; +using System.Text; + +using ICSharpCode.SharpZipLib.Checksums; +using MyDownloader.Core; + +namespace MyDownloader.Extension.Zip +{ + public class ZipRemoteFile : IEnumerable + { + private ZipEntry[] entries; + private ResourceLocation url; + private int MaxFileOffset; + private IProtocolProvider protocolProvider; + + public ZipRemoteFile(ResourceLocation url) : + this(url, ProtocolProviderFactory.GetProvider(url.URL)) + { + } + + public ZipRemoteFile(ResourceLocation url, IProtocolProvider protocolProvider) + { + if (protocolProvider == null) + { + throw new ArgumentNullException("protocolProvider"); + } + + this.url = url; + this.protocolProvider = protocolProvider; + } + + /* + end of central dir signature 4 bytes (0x06054b50) + number of this disk 2 bytes + number of the disk with the start of the central directory 2 bytes + total number of entries in the central directory on this disk 2 bytes + total number of entries in the central directory 2 bytes + size of the central directory 4 bytes + offset of start of central directory + with respect to the starting disk number 4 bytes + .ZIP file comment length 2 bytes + .ZIP file comment (variable size) + */ + + /// + /// TODO: case when the whole file is smaller than 64K + /// TODO: handle non HTTP case + /// + /// + /// + public bool Load() + { + int CentralOffset, CentralSize; + int TotalEntries; + if(!FindCentralDirectory(out CentralOffset, out CentralSize, out TotalEntries)) + return false; + + MaxFileOffset = CentralOffset; + + // now retrieve the Central Directory + entries = new ZipEntry[TotalEntries]; + + //HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); + //req.AddRange(CentralOffset, CentralOffset+CentralSize); + //HttpWebResponse res = (HttpWebResponse)req.GetResponse(); + + using (Stream s = protocolProvider.CreateStream(this.url, + CentralOffset, CentralOffset + CentralSize)) + { + // code taken from SharpZipLib with modification for not seekable stream + // and adjustement for Central Directory entry + for (int i = 0; i < TotalEntries; i++) + { + if (ReadLeInt(s) != ZipConstants.CentralHeaderSignature) + { + throw new ZipException("Wrong Central Directory signature"); + } + + // skip 6 bytes: version made (W), version ext (W), flags (W) + ReadLeInt(s); + ReadLeShort(s); + int method = ReadLeShort(s); + int dostime = ReadLeInt(s); + int crc = ReadLeInt(s); + int csize = ReadLeInt(s); + int size = ReadLeInt(s); + int nameLen = ReadLeShort(s); + int extraLen = ReadLeShort(s); + int commentLen = ReadLeShort(s); + // skip 8 bytes: disk number start, internal file attribs, external file attribs (DW) + ReadLeInt(s); + ReadLeInt(s); + int offset = ReadLeInt(s); + + byte[] buffer = new byte[Math.Max(nameLen, commentLen)]; + + StreamHelper.ReadAll(buffer, 0, nameLen, s); + string name = ZipConstants.ConvertToString(buffer); + + ZipEntry entry = new ZipEntry(name); + entry.CompressionMethod = (CompressionMethod)method; + entry.Crc = crc & 0xffffffffL; + entry.Size = size & 0xffffffffL; + entry.CompressedSize = csize & 0xffffffffL; + entry.DosTime = (uint)dostime; + if (extraLen > 0) + { + byte[] extra = new byte[extraLen]; + StreamHelper.ReadAll(extra, 0, extraLen, s); + entry.ExtraData = extra; + } + if (commentLen > 0) + { + StreamHelper.ReadAll(buffer, 0, commentLen, s); + entry.Comment = ZipConstants.ConvertToString(buffer); + } + entry.ZipFileIndex = i; + entry.Offset = offset; + entries[i] = entry; + OnProgress((i*100)/TotalEntries); + } + } + + OnProgress(100); + + return true; + } + + /// + /// OnProgress during Central Header loading + /// + /// + public virtual void OnProgress(int pct) + { + + } + + /// + /// Checks if there is a local header at the current position in the stream and skips it + /// + /// + /// + void SkipLocalHeader(Stream baseStream, ZipEntry entry) + { + lock(baseStream) + { + if (ReadLeInt(baseStream) != ZipConstants.LocalHeaderSignature) + { + throw new ZipException("Wrong Local header signature"); + } + + Skip(baseStream, 10+12); + int namelen = ReadLeShort(baseStream); + int extralen = ReadLeShort(baseStream); + Skip(baseStream, namelen+extralen); + } + } + + /// + /// Finds the Central Header in the Zip file. We can minimize the number of requests and + /// the bytes taken + /// + /// Actually we do: 256, 1024, 65536 + /// + /// + /// + bool FindCentralDirectory(out int Offset, out int Size, out int Entries) + { + int currentLength = 256; + Entries = 0; + Size = 0; + Offset = -1; + + while(true) + { + //HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); + //req.AddRange(-(currentLength+22)); + //HttpWebResponse res = (HttpWebResponse)req.GetResponse(); + // bb = new byte[res.ContentLength]; + // endSize = StreamHelper.ReadAll(bb, 0, (int)res.ContentLength, res.getResponseStream()); + + int endSize; + byte[] bb; + + using (BinaryReader headerStream = new BinaryReader(protocolProvider.CreateStream( + this.url, -(currentLength + 22), 0))) + { + using (MemoryStream data = new MemoryStream()) + { + int count = 256; + byte[] buffer = new byte[count]; + + do + { + int readCount = headerStream.Read(buffer, 0, count); + if (readCount == 0) + { + break; + } + data.Write(buffer, 0, readCount); + } + while (count > 0); + + bb = data.ToArray(); + endSize = (int)data.Length; + } + } + + // scan for the central block. The position of the central block + // is end-comment-22 + //< + // 50 4B 05 06 + int pos = endSize-22; + //int state = 0; + while(pos >= 0) + { + if(bb[pos] == 0x50) + { + if(bb[pos+1] == 0x4b && bb[pos+2] == 0x05 && bb[pos+3] == 0x06) + break; // found!! + pos -= 4; + } + else + pos --; + } + + if(pos < 0) + { + if(currentLength == 65536) + break; + + if(currentLength == 1024) + currentLength = 65536; + else if(currentLength == 256) + currentLength = 1024; + else + break; + } + else + { + // found it!! so at offset pos+3*4 there is Size, and pos+4*4 + // BinaryReader is so elegant but now it's too much + Size = MakeInt(bb, pos+12); + Offset = MakeInt(bb, pos+16); + Entries = MakeShort(bb, pos+10); + return true; + } + } + return false; + } + + /// + /// Get a Stream for reading the specified entry + /// + /// + /// + public Stream GetInputStream(ZipEntry entry) + { + if(entry.Size == 0) + return null; + + if (entries == null) + { + throw new InvalidOperationException("ZipFile has closed"); + } + + int index = (int)entry.ZipFileIndex; + if (index < 0 || index >= entries.Length || entries[index].Name != entry.Name) + { + throw new IndexOutOfRangeException(); + } + + // WARNING + // should parse the Local Header to get the data address + // Maximum Size of the Local Header is ... 16+64K*2 + // + // So the HTTP request should ask for the big local header, but actually the + // additional data is not downloaded. + // Optionally use an additional Request to be really precise + //HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baseUrl); + + int limit = (int)(entry.Offset+entry.CompressedSize+16+65536*2); + if(limit >= MaxFileOffset) + limit = MaxFileOffset-1; + //req.AddRange((int)entry.Offset, limit); + //HttpWebResponse res = (HttpWebResponse)req.GetResponse(); + //Stream baseStream = res.GetResponseStream(); + + Stream baseStream = protocolProvider.CreateStream(this.url, (int)entry.Offset, limit); + + // skips all the header + SkipLocalHeader(baseStream, entries[index]); + CompressionMethod method = entries[index].CompressionMethod; + + Stream istr = new PartialInputStream(baseStream, entries[index].CompressedSize); + switch (method) + { + case CompressionMethod.Stored: + return istr; + case CompressionMethod.Deflated: + return new InflaterInputStream(istr, new Inflater(true)); + case (CompressionMethod)12: + return new BZip2InputStream(istr); + default: + throw new ZipException("Unknown compression method " + method); + } + } + + #region Helper methods + + /// + /// Read an unsigned short in little endian byte order. + /// + /// + /// if a i/o error occured. + /// + /// + /// if the file ends prematurely + /// + private static int ReadLeShort(Stream s) + { + return s.ReadByte() | s.ReadByte() << 8; + } + + /// + /// Read an int in little endian byte order. + /// + /// + /// if a i/o error occured. + /// + /// + /// if the file ends prematurely + /// + private static int ReadLeInt(Stream s) + { + return ReadLeShort(s) | ReadLeShort(s) << 16; + } + + private static void Skip(Stream s, int n) + { + for(int i = 0; i < n; i++) + s.ReadByte(); + } + + private static int MakeInt(byte [] bb, int pos) + { + return bb[pos+0]|(bb[pos+1]<<8)|(bb[pos+2]<<16)|(bb[pos+3]<<24); + } + + private static int MakeShort(byte[] bb, int pos) + { + return bb[pos+0]|(bb[pos+1]<<8); + } + + #endregion + + public int Size + { + get { return entries == null ? 0 : entries.Length; } + } + + public ZipEntry this[string entryName] + { + get + { + for (int i = 0; i < entries.Length; i++) + { + if (entries[i].Name == entryName) + { + return entries[i]; + } + } + + throw new ArgumentException("entryName"); + } + } + + public ZipEntry this[int index] + { + get { return entries[index]; } + } + + /// + /// Returns an IEnumerator of all Zip entries in this Zip file. + /// + public IEnumerator GetEnumerator() + { + if (entries == null) + { + throw new InvalidOperationException("ZipFile has closed"); + } + + return new ZipEntryEnumeration(entries); + } + + class ZipEntryEnumeration : IEnumerator + { + ZipEntry[] array; + int ptr = -1; + + public ZipEntryEnumeration(ZipEntry[] arr) + { + array = arr; + } + + public object Current + { + get + { + return array[ptr]; + } + } + + public void Reset() + { + ptr = -1; + } + + public bool MoveNext() + { + return (++ptr < array.Length); + } + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Extension/app.config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Extension/app.config Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,118 @@ + + + + +
+
+
+
+
+
+
+
+ + + + + + False + + + + + 5 + + + False + + + + + + 1 + + + False + + + + + + + + + + + + + + True + + + 3000 + + + + + + True + + + + + + + + + + + + + + + False + + + 1024 + + + + + 5 + + + False + + + + + + 1 + + + + + + + + + + + + + + + + + + False + + + True + + + 80 + + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/BandObjectLib/Attributes.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/BandObjectLib/Attributes.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,42 @@ +// Copyright Pavel Zolnikov, 2002 +// +// http://www.codeproject.com/KB/shell/dotnetbandobjects.aspx + +using System; +using System.Runtime.InteropServices; +using System.Reflection; + +namespace BandObjectLib +{ + /// + /// Represents different styles of a band object. + /// + [Flags] + [Serializable] + public enum BandObjectStyle : uint + { + Vertical = 1, + Horizontal = 2, + ExplorerToolbar = 4, + TaskbarToolBar = 8, + ExplorerBar = 16 + } + + /// + /// Specifies Style of the band object, its Name(displayed in explorer menu) and HelpText(displayed in status bar when menu command selected). + /// + [AttributeUsage(AttributeTargets.Class)] + public class BandObjectAttribute : System.Attribute + { + public BandObjectAttribute() { } + + public BandObjectAttribute(string name, BandObjectStyle style) + { + Name = name; + Style = style; + } + public BandObjectStyle Style; + public string Name; + public string HelpText; + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/BandObjectLib/BandObject.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/BandObjectLib/BandObject.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,383 @@ +// Copyright Pavel Zolnikov, 2002 +// +// BandObject - implements generic Band Object functionality. +// http://www.codeproject.com/KB/shell/dotnetbandobjects.aspx + +using System; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using SHDocVw; +using System.Reflection; +using System.Diagnostics; +using System.Drawing; +using System.ComponentModel; +using Microsoft.Win32; + +namespace BandObjectLib +{ + /// + /// Implements generic Band Object functionality. + /// + /// + /// [Guid("YOURGUID-GOES-HERE-YOUR-GUIDGOESHERE")] + /// [BandObject("Hello World Bar", BandObjectStyle.Horizontal | BandObjectStyle.ExplorerToolbar , HelpText = "Shows bar that says hello.")] + /// public class HelloWorldBar : BandObject + /// { /*...*/ } + /// + public class BandObject : UserControl, IObjectWithSite, IDeskBand, IDockingWindow, IOleWindow, IInputObject + { + /// + /// Reference to the host explorer. + /// + protected WebBrowserClass Explorer; + protected IInputObjectSite BandObjectSite; + /// + /// This event is fired after reference to hosting explorer is retreived and stored in Explorer property. + /// + public event EventHandler ExplorerAttached; + + public BandObject() + { + InitializeComponent(); + } + + private void InitializeComponent() + { + // + // ExplorerBar + // + this.Name = "BandObject"; + } + + + /// + /// Title of band object. Displayed at the left or on top of the band object. + /// + [Browsable(true)] + [DefaultValue("")] + public String Title + { + get + { + return _title; + } + set + { + _title = value; + } + }String _title; + + + /// + /// Minimum size of the band object. Default value of -1 sets no minimum constraint. + /// + [Browsable(true)] + [DefaultValue(typeof(Size), "-1,-1")] + public Size MinSize + { + get + { + return _minSize; + } + set + { + _minSize = value; + } + }Size _minSize = new Size(-1, -1); + + /// + /// Maximum size of the band object. Default value of -1 sets no maximum constraint. + /// + [Browsable(true)] + [DefaultValue(typeof(Size), "-1,-1")] + public Size MaxSize + { + get + { + return _maxSize; + } + set + { + _maxSize = value; + } + }Size _maxSize = new Size(-1, -1); + + /// + /// Says that band object's size must be multiple of this size. Defauilt value of -1 does not set this constraint. + /// + [Browsable(true)] + [DefaultValue(typeof(Size), "-1,-1")] + public Size IntegralSize + { + get + { + return _integralSize; + } + set + { + _integralSize = value; + } + }Size _integralSize = new Size(-1, -1); + + + public virtual void GetBandInfo( + UInt32 dwBandID, + UInt32 dwViewMode, + ref DESKBANDINFO dbi) + { + dbi.wszTitle = this.Title; + + dbi.ptActual.X = this.Size.Width; + dbi.ptActual.Y = this.Size.Height; + + dbi.ptMaxSize.X = this.MaxSize.Width; + dbi.ptMaxSize.Y = this.MaxSize.Height; + + dbi.ptMinSize.X = this.MinSize.Width; + dbi.ptMinSize.Y = this.MinSize.Height; + + dbi.ptIntegral.X = this.IntegralSize.Width; + dbi.ptIntegral.Y = this.IntegralSize.Height; + + dbi.dwModeFlags = DBIM.TITLE | DBIM.ACTUAL | DBIM.MAXSIZE | DBIM.MINSIZE | DBIM.INTEGRAL; + } + + /// + /// Called by explorer when band object needs to be showed or hidden. + /// + /// + public virtual void ShowDW(bool fShow) + { + if (fShow) + Show(); + else + Hide(); + } + + /// + /// Called by explorer when window is about to close. + /// + public virtual void CloseDW(UInt32 dwReserved) + { + Dispose(true); + } + + /// + /// Not used. + /// + public virtual void ResizeBorderDW(IntPtr prcBorder, Object punkToolbarSite, bool fReserved) { } + + public virtual void GetWindow(out System.IntPtr phwnd) + { + phwnd = Handle; + } + + public virtual void ContextSensitiveHelp(bool fEnterMode) { } + + public virtual void SetSite(Object pUnkSite) + { + if (BandObjectSite != null) + Marshal.ReleaseComObject(BandObjectSite); + + if (Explorer != null) + { + Marshal.ReleaseComObject(Explorer); + Explorer = null; + } + + BandObjectSite = (IInputObjectSite)pUnkSite; + if (BandObjectSite != null) + { + //pUnkSite is a pointer to object that implements IOleWindowSite or something similar + //we need to get access to the top level object - explorer itself + //to allows this explorer objects also implement IServiceProvider interface + //(don't mix it with System.IServiceProvider!) + //we get this interface and ask it to find WebBrowserApp + _IServiceProvider sp = BandObjectSite as _IServiceProvider; + Guid guid = ExplorerGUIDs.IID_IWebBrowserApp; + Guid riid = ExplorerGUIDs.IID_IUnknown; + + try + { + object w; + sp.QueryService( + ref guid, + ref riid, + out w); + + //once we have interface to the COM object we can create RCW from it + Explorer = (WebBrowserClass)Marshal.CreateWrapperOfType( + w as IWebBrowser, + typeof(WebBrowserClass) + ); + + OnExplorerAttached(EventArgs.Empty); + } + catch (COMException) + { + //we anticipate this exception in case our object instantiated + //as a Desk Band. There is no web browser service available. + } + } + + } + + public virtual void GetSite(ref Guid riid, out Object ppvSite) + { + ppvSite = BandObjectSite; + } + + /// + /// Called explorer when focus has to be chenged. + /// + public virtual void UIActivateIO(Int32 fActivate, ref MSG Msg) + { + if (fActivate != 0) + { + Control ctrl = GetNextControl(this, true);//first + if (ModifierKeys == Keys.Shift) + ctrl = GetNextControl(ctrl, false);//last + + if (ctrl != null) ctrl.Select(); + this.Focus(); + } + } + + public virtual Int32 HasFocusIO() + { + return this.ContainsFocus ? 0 : 1; //S_OK : S_FALSE; + } + + /// + /// Called by explorer to process keyboard events. Undersatands Tab and F6. + /// + /// + /// S_OK if message was processed, S_FALSE otherwise. + public virtual Int32 TranslateAcceleratorIO(ref MSG msg) + { + if (msg.message == 0x100)//WM_KEYDOWN + if (msg.wParam == (uint)Keys.Tab || msg.wParam == (uint)Keys.F6)//keys used by explorer to navigate from control to control + if (SelectNextControl( + ActiveControl, + ModifierKeys == Keys.Shift ? false : true, + true, + true, + false) + ) + return 0;//S_OK + + return 1;//S_FALSE + } + + /// + /// Override this method to handle ExplorerAttached event. + /// + /// + protected virtual void OnExplorerAttached(EventArgs ea) + { + if (ExplorerAttached != null) + ExplorerAttached(this, ea); + } + + /// + /// Notifies explorer of focus change. + /// + protected override void OnGotFocus(System.EventArgs e) + { + base.OnGotFocus(e); + BandObjectSite.OnFocusChangeIS(this as IInputObject, 1); + } + /// + /// Notifies explorer of focus change. + /// + protected override void OnLostFocus(System.EventArgs e) + { + base.OnLostFocus(e); + if (ActiveControl == null) + BandObjectSite.OnFocusChangeIS(this as IInputObject, 0); + } + + + /// + /// Called when derived class is registered as a COM server. + /// + [ComRegisterFunctionAttribute] + public static void Register(Type t) + { + string guid = t.GUID.ToString("B"); + + RegistryKey rkClass = Registry.ClassesRoot.CreateSubKey(@"CLSID\" + guid); + RegistryKey rkCat = rkClass.CreateSubKey("Implemented Categories"); + + BandObjectAttribute[] boa = (BandObjectAttribute[])t.GetCustomAttributes( + typeof(BandObjectAttribute), + false); + + string name = t.Name; + string help = t.Name; + BandObjectStyle style = 0; + if (boa.Length == 1) + { + if (boa[0].Name != null) + name = boa[0].Name; + + if (boa[0].HelpText != null) + help = boa[0].HelpText; + + style = boa[0].Style; + } + + rkClass.SetValue(null, name); + rkClass.SetValue("MenuText", name); + rkClass.SetValue("HelpText", help); + + + if (0 != (style & BandObjectStyle.Vertical)) + rkCat.CreateSubKey("{00021493-0000-0000-C000-000000000046}"); + else + if (rkCat.OpenSubKey("{00021493-0000-0000-C000-000000000046}") != null) rkCat.DeleteSubKey("{00021493-0000-0000-C000-000000000046}"); + + if (0 != (style & BandObjectStyle.Horizontal)) + rkCat.CreateSubKey("{00021494-0000-0000-C000-000000000046}"); + else + if (rkCat.OpenSubKey("{00021494-0000-0000-C000-000000000046}") != null) rkCat.DeleteSubKey("{00021494-0000-0000-C000-000000000046}"); + + + if (0 != (style & BandObjectStyle.TaskbarToolBar)) + rkCat.CreateSubKey("{00021492-0000-0000-C000-000000000046}"); + else + if (rkCat.OpenSubKey("{00021492-0000-0000-C000-000000000046}") != null) rkCat.DeleteSubKey("{00021492-0000-0000-C000-000000000046}"); + + + if (0 != (style & BandObjectStyle.ExplorerToolbar)) + Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Toolbar").SetValue(guid, name); + + if (0 != (style & BandObjectStyle.ExplorerBar)) + Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Explorer Bars").CreateSubKey(guid); + else + if (Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Explorer Bars").OpenSubKey(guid) != null) Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Explorer Bars").DeleteSubKey(guid); + + + } + + /// + /// Called when derived class is unregistered as a COM server. + /// + [ComUnregisterFunctionAttribute] + public static void Unregister(Type t) + { + string guid = t.GUID.ToString("B"); + BandObjectAttribute[] boa = (BandObjectAttribute[])t.GetCustomAttributes( + typeof(BandObjectAttribute), + false); + + BandObjectStyle style = 0; + if (boa.Length == 1) style = boa[0].Style; + + if (0 != (style & BandObjectStyle.ExplorerToolbar)) + Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Toolbar").DeleteValue(guid, false); + + Registry.ClassesRoot.CreateSubKey(@"CLSID").DeleteSubKeyTree(guid); + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/BandObjectLib/ComInterop.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/BandObjectLib/ComInterop.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,188 @@ +// This file is a part of the Command Prompt Explorer Bar project. +// +// Copyright Pavel Zolnikov, 2002 +// +// declarations of some COM interfaces and structues +// http://www.codeproject.com/KB/shell/dotnetbandobjects.aspx + +using System; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace BandObjectLib +{ + + abstract class ExplorerGUIDs + { + public static readonly Guid IID_IWebBrowserApp = new Guid("{0002DF05-0000-0000-C000-000000000046}"); + public static readonly Guid IID_IUnknown = new Guid("{00000000-0000-0000-C000-000000000046}"); + } + + + + [Flags] + public enum DBIM : uint + { + MINSIZE = 0x0001, + MAXSIZE = 0x0002, + INTEGRAL = 0x0004, + ACTUAL = 0x0008, + TITLE = 0x0010, + MODEFLAGS = 0x0020, + BKCOLOR = 0x0040 + } + + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DESKBANDINFO + { + public UInt32 dwMask; + public Point ptMinSize; + public Point ptMaxSize; + public Point ptIntegral; + public Point ptActual; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)] + public String wszTitle; + public DBIM dwModeFlags; + public Int32 crBkgnd; + }; + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")] + public interface IObjectWithSite + { + void SetSite([In, MarshalAs(UnmanagedType.IUnknown)] Object pUnkSite); + void GetSite(ref Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out Object ppvSite); + } + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("00000114-0000-0000-C000-000000000046")] + public interface IOleWindow + { + void GetWindow(out System.IntPtr phwnd); + void ContextSensitiveHelp([In] bool fEnterMode); + } + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("012dd920-7b26-11d0-8ca9-00a0c92dbfe8")] + public interface IDockingWindow + { + void GetWindow(out System.IntPtr phwnd); + void ContextSensitiveHelp([In] bool fEnterMode); + + void ShowDW([In] bool fShow); + void CloseDW([In] UInt32 dwReserved); + void ResizeBorderDW( + IntPtr prcBorder, + [In, MarshalAs(UnmanagedType.IUnknown)] Object punkToolbarSite, + bool fReserved); + } + + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("EB0FE172-1A3A-11D0-89B3-00A0C90A90AC")] + public interface IDeskBand + { + void GetWindow(out System.IntPtr phwnd); + void ContextSensitiveHelp([In] bool fEnterMode); + + void ShowDW([In] bool fShow); + void CloseDW([In] UInt32 dwReserved); + + void ResizeBorderDW( + IntPtr prcBorder, + [In, MarshalAs(UnmanagedType.IUnknown)] Object punkToolbarSite, + bool fReserved); + + void GetBandInfo( + UInt32 dwBandID, + UInt32 dwViewMode, + ref DESKBANDINFO pdbi); + } + + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("0000010c-0000-0000-C000-000000000046")] + public interface IPersist + { + void GetClassID(out Guid pClassID); + } + + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("00000109-0000-0000-C000-000000000046")] + public interface IPersistStream + { + void GetClassID(out Guid pClassID); + + void IsDirty(); + + void Load([In, MarshalAs(UnmanagedType.Interface)] Object pStm); + + void Save([In, MarshalAs(UnmanagedType.Interface)] Object pStm, + [In] bool fClearDirty); + + void GetSizeMax([Out] out UInt64 pcbSize); + } + + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("6d5140c1-7436-11ce-8034-00aa006009fa")] + public interface _IServiceProvider + { + void QueryService( + ref Guid guid, + ref Guid riid, + [MarshalAs(UnmanagedType.Interface)] out Object Obj); + } + + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("68284faa-6a48-11d0-8c78-00c04fd918b4")] + public interface IInputObject + { + void UIActivateIO(Int32 fActivate, ref MSG msg); + + [PreserveSig] + //[return:MarshalAs(UnmanagedType.Error)] + Int32 HasFocusIO(); + + [PreserveSig] + Int32 TranslateAcceleratorIO(ref MSG msg); + } + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("f1db8392-7331-11d0-8c99-00a0c92dbfe8")] + public interface IInputObjectSite + { + [PreserveSig] + Int32 OnFocusChangeIS([MarshalAs(UnmanagedType.IUnknown)] Object punkObj, Int32 fSetFocus); + } + + public struct POINT + { + public Int32 x; + public Int32 y; + } + + public struct MSG + { + public IntPtr hwnd; + public UInt32 message; + public UInt32 wParam; + public Int32 lParam; + public UInt32 time; + public POINT pt; + } + +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/IEMD.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/IEMD.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,207 @@ +using System; +using System.ComponentModel; +using System.Windows.Forms; +using System.Collections; +using System.Diagnostics; +using System.Drawing; +using System.IO; + +using BandObjectLib; +using System.Runtime.InteropServices; +using SHDocVw; +using System.Text.RegularExpressions; +using System.Collections.Generic; +using System.Threading; + +namespace MyDownloader.IEPlugin +{ + [Guid("3F93D37D-54B8-4d5d-92CB-6F5644E7A65F")] + [BandObject("MyDownloader", BandObjectStyle.Horizontal | BandObjectStyle.ExplorerToolbar | BandObjectStyle.TaskbarToolBar)] + public class IEMD : BandObject + { + private System.Windows.Forms.Button btnDownload; + private IContainer components; + private const int IE_TRUE = 1; + private const int IE_FALSE = 0; + private ToolTip toolTips; + VideoSitesRepository videoSites; + + DateTime lastDownload = DateTime.Now; + private Button btnOpenDownloader; + string lastUrl = ""; + + public IEMD() + { + InitializeComponent(); + + btnDownload.Enabled = false; + + videoSites = new VideoSitesRepository(); + } + + #region Component Designer generated code + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(IEMD)); + this.btnDownload = new System.Windows.Forms.Button(); + this.toolTips = new System.Windows.Forms.ToolTip(this.components); + this.btnOpenDownloader = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // btnDownload + // + this.btnDownload.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnDownload.ForeColor = System.Drawing.SystemColors.ControlDark; + this.btnDownload.Image = ((System.Drawing.Image)(resources.GetObject("btnDownload.Image"))); + this.btnDownload.Location = new System.Drawing.Point(0, 0); + this.btnDownload.Name = "btnDownload"; + this.btnDownload.Size = new System.Drawing.Size(24, 21); + this.btnDownload.TabIndex = 1; + this.toolTips.SetToolTip(this.btnDownload, "Download video using MyDownloader"); + this.btnDownload.Click += new System.EventHandler(this.btnDownload_Click); + // + // btnOpenDownloader + // + this.btnOpenDownloader.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnOpenDownloader.ForeColor = System.Drawing.SystemColors.ControlDark; + this.btnOpenDownloader.Image = ((System.Drawing.Image)(resources.GetObject("btnOpenDownloader.Image"))); + this.btnOpenDownloader.Location = new System.Drawing.Point(26, 0); + this.btnOpenDownloader.Name = "btnOpenDownloader"; + this.btnOpenDownloader.Size = new System.Drawing.Size(24, 21); + this.btnOpenDownloader.TabIndex = 2; + this.toolTips.SetToolTip(this.btnOpenDownloader, "Lauch MyDownloader"); + this.btnOpenDownloader.Click += new System.EventHandler(this.btnOpenDownloader_Click); + // + // IEMD + // + this.Controls.Add(this.btnOpenDownloader); + this.Controls.Add(this.btnDownload); + this.MinSize = new System.Drawing.Size(52, 21); + this.Name = "IEMD"; + this.Size = new System.Drawing.Size(52, 21); + this.Title = ""; + this.ResumeLayout(false); + + } + #endregion + + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (components != null) + components.Dispose(); + } + base.Dispose(disposing); + } + + public SHDocVw.WebBrowser GetIEDocument() + { + return (SHDocVw.WebBrowser) this.Explorer; + } + + protected override void OnExplorerAttached(EventArgs ea) + { + SHDocVw.WebBrowser IEDocument = this.GetIEDocument(); + IEDocument.BeforeNavigate2 +=new DWebBrowserEvents2_BeforeNavigate2EventHandler(BeforeNavigate); + IEDocument.NavigateComplete2 +=new DWebBrowserEvents2_NavigateComplete2EventHandler(AfterNavigate); + IEDocument.FileDownload += new DWebBrowserEvents2_FileDownloadEventHandler(IEDocument_FileDownload); + + base.OnExplorerAttached (ea); + } + + void IEDocument_FileDownload(bool ActiveDocument, ref bool Cancel) + { + if (!ActiveDocument) + { + if ((Control.ModifierKeys & Keys.Alt) == Keys.Alt) + { + Cancel = true; + + if ((DateTime.Now - lastDownload).TotalSeconds >= 1.9) + { + ThreadPool.QueueUserWorkItem( + delegate(object state) + { + DownloadURL(lastUrl); + }); + + lastDownload = DateTime.Now; + } + } + } + } + + private void DownloadURL(string url) + { + try + { + Process p; + if (url != null) + { + p = Process.Start(Settings.MyDownloaderPath, String.Format("/sw {0}", url)); + } + else + { + p = Process.Start(Settings.MyDownloaderPath); + } + p.WaitForInputIdle(5000); + } + catch (Exception ex) + { + MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void MakeVisible() + { + if(GetIEDocument().ToolBar == IE_FALSE) + //if(Configuration.AlwaysShow) + { + this.Visible = true; + GetIEDocument().ToolBar = IE_TRUE; + } + } + + public void AfterNavigate(object iDisp, ref object URL) + { + SHDocVw.WebBrowser IEDocument = GetIEDocument(); + MakeVisible(); + + mshtml.HTMLDocument HTML = (mshtml.HTMLDocument) IEDocument.Document; + // save cookies + //StreamWriter sw=new StreamWriter(Settings.MyDownloaderPath + "_cookie"); + //sw.Write(HTML.cookie); + //sw.Close(); + //HTML.cookie + //HTML.attachEvent(iDisp) + + btnDownload.Enabled = videoSites.IsVideoSite(IEDocument.LocationURL); + } + + public void BeforeNavigate(object iDisp, ref object URL, ref object Flags, ref object TargetFrameName, ref object PostData, ref object Headers, ref bool Cancel) + { + lastUrl = URL.ToString(); + } + + private void btnDownload_Click(object sender, System.EventArgs e) + { + try + { + SHDocVw.WebBrowser IEDocument = GetIEDocument(); + + DownloadURL(IEDocument.LocationURL); + } + catch (Exception ex) + { + MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void btnOpenDownloader_Click(object sender, EventArgs e) + { + DownloadURL(null); + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/IEMD.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/IEMD.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + R0lGODlhCQAMAPMAAJieqydPokFuxlaI7Gua91+F0Yev/pe5/P///wAAAAAAAAAAAAAAAAAAAAAAAAAA + ACH5BAEAAAgALAAAAAAJAAwAAAQvECFCS5GSnGMCRgU3eFhIjJ+JlsZJSoUxrJU8BgEgUIMg5AhAoPcD + YITFTxAoiQAAOw== + + + + 4, 31 + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAFVJREFUOE9jYKAU + NDQ0/KcEM4A0HzhwgGQM0gd0/H+4AQwM+4ECxGOiDfgPBCCb0GkMA8gJBxQvgK0gAWC4gAS9YKWjBlA7 + DMhJA/BYACcGyjBl+RkAj+eF6Chu5VQAAAAASUVORK5CYII= + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/IEManager.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/IEManager.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; + +using BandObjectLib; +using System.Runtime.InteropServices; +using SHDocVw; +using System.Text.RegularExpressions; +using System.Collections.Generic; +using System.Threading; + +namespace MyDownloader.IEPlugin +{ + //http://msdn.microsoft.com/en-us/library/aa753588.aspx + //http://msdn.microsoft.com/en-us/library/aa753590.aspx + [Guid("3F93D37D-54B8-4d5d-92CB-6F5644E7A65A")] + [BandObject("MyDownloader_List", BandObjectStyle.Vertical | BandObjectStyle.ExplorerBar )] + public class IEManager : BandObject + { + public IEManager() + { + //InitializeComponent(); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/IEManager.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/IEManager.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/MyDownloader.IEPlugin.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/MyDownloader.IEPlugin.csproj Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,171 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {91BB212C-D158-4B83-A3BC-1A41BBDC8463} + Library + Properties + MyDownloader.IEPlugin + MyDownloader.IEPlugin + true + MyDownloader.IEPlugin.snk + + + + + 3.5 + false + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + x86 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + + False + ..\Interop.SHDocVw.dll + + + + + + + + + + + UserControl + + + + + UserControl + + + UserControl + + + + True + True + Resources.resx + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + PreserveNewest + + + + + IEManager.cs + + + Designer + IEMD.cs + + + Designer + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + + + {3050F1C5-98B5-11CF-BB82-00AA00BDCE0B} + 4 + 0 + 0 + primary + False + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/MyDownloader.IEPlugin.snk Binary file MyDownloader.IEPlugin/MyDownloader.IEPlugin.snk has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/READ-ME.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/READ-ME.txt Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,5 @@ +To install MyDownloader toolbar: + +1) Edit 'register.reg' setting the correct MyDownloader filename +2) Run register.reg. +3) Run register.bat inside Visual Studio command prompt. \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/Settings.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/Settings.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Win32; + +namespace MyDownloader.IEPlugin +{ + internal static class Settings + { + private const string ROOTREG = "SOFTWARE\\MyDownloader"; + + public static string MyDownloaderPath + { + get + { + return GetValue("MyDownloaderPath"); + } + } + + private static string GetValue(string Key) + { + using (RegistryKey RKey = Registry.LocalMachine.CreateSubKey(ROOTREG)) + { + return RKey.GetValue(Key, "").ToString(); + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/VideoSitesRepository.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/VideoSitesRepository.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Text.RegularExpressions; + +namespace MyDownloader.IEPlugin +{ + internal class VideoSitesRepository + { + private List videoSites = new List(); + + #region Constructor + public VideoSitesRepository() + { + LoadVideoSites(); + } + #endregion + + #region Methods + + public bool IsVideoSite(string url) + { + for (int i = 0; i < videoSites.Count; i++) + { + if (videoSites[i].IsMatch(url)) + { + return true; + } + } + + return false; + } + + private void LoadVideoSites() + { + try + { + using (StreamReader urlsStream = new StreamReader(this.GetType().Assembly.GetManifestResourceStream("MyDownloader.IEPlugin.VideoSitesURLPatterns.txt"))) + { + string line = urlsStream.ReadLine(); + while (line != null || line.Length == 0) + { + RegexOptions options = ((RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline) + | RegexOptions.IgnoreCase); + Regex reg = new Regex(line, options); + videoSites.Add(reg); + + line = urlsStream.ReadLine(); + } + } + } + catch (Exception) + { + } + } + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/VideoSitesURLPatterns.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/VideoSitesURLPatterns.txt Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,5 @@ +(?:[Bb][Rr][Ee][Aa][Kk]\.[Cc][Oo][Mm]/)(\w[\w|-]*) +(?:[Vv][Ii][Dd][Ee][Oo]\.[Gg][Oo][Oo][Gg][Ll][Ee]\.[Cc][Oo][Mm]/videoplay\?docid=)-?(\w[\w|-]*) +(?:[Mm][Ee][Ta][Aa][Cc][Aa][Ff][Ee]\.[Cc][Oo][Mm]/watch/)(\w[\w|-]*)/(\w[\w|-]*) +(?:[Mm][Ee][Dd][Ii][Aa]\.[Pp][Uu][Tt][Ff][Ii][Ll][Ee]\.[Cc][Oo][Mm]/)(\w[\w|-]*) +(?:[Yy][Oo][Uu][Tt][Uu][Bb][Ee]\.[Cc][Oo][Mm]/watch\?v=)(\w[\w|-]*) \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/bin/Release/register.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/bin/Release/register.bat Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,3 @@ +gacutil /if Interop.SHDocVw.dll +gacutil /if MyDownloader.IEPlugin.dll +regasm MyDownloader.IEPlugin.dll \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/bin/Release/register.reg Binary file MyDownloader.IEPlugin/bin/Release/register.reg has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/bin/Release/unregister.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/bin/Release/unregister.bat Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,3 @@ +regasm /unregister MyDownloader.IEPlugin.dll +gacutil /u Interop.SHDocVw.dll +gacutil /u MyDownloader.IEPlugin.dll diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/bin/Release/unregister.reg Binary file MyDownloader.IEPlugin/bin/Release/unregister.reg has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/register.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/register.bat Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,3 @@ +gacutil /if Interop.SHDocVw.dll +gacutil /if MyDownloader.IEPlugin.dll +regasm MyDownloader.IEPlugin.dll \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/register.reg Binary file MyDownloader.IEPlugin/register.reg has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/unregister.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.IEPlugin/unregister.bat Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,3 @@ +regasm /unregister MyDownloader.IEPlugin.dll +gacutil /u Interop.SHDocVw.dll +gacutil /u MyDownloader.IEPlugin.dll diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.IEPlugin/unregister.reg Binary file MyDownloader.IEPlugin/unregister.reg has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/IAsyncRetriver.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/IAsyncRetriver.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Spider +{ + public interface IAsyncRetriver + { + ISpiderResource Resource { get; } + + bool IsCompleted { get; } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/INamingRule.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/INamingRule.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Spider +{ + public interface INamingRule + { + bool Accept(Uri location, SpiderContext context, ISpiderResource parentSpider); + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/ISpiderResource.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/ISpiderResource.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core; +using System.Text.RegularExpressions; +using System.Net.Mime; +using System.IO; +using System.Threading; + +namespace MyDownloader.Spider +{ + public interface ISpiderResource + { + string Location { get; } + + int Depth { get; } + + ISpiderResource ParentResource { get; } + + List NextResources { get; } + + IAsyncRetriver BeginReceive(); + + void EndReceive(); + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/ISpiderResourceFactory.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/ISpiderResourceFactory.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Spider +{ + public interface ISpiderResourceFactory + { + ISpiderResource CreateSpider(SpiderContext cntx, ISpiderResource parent, string location); + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/MyDownloader.Spider.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/MyDownloader.Spider.csproj Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,142 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {69C99442-953E-4559-96D3-C82CC57A3C87} + Library + Properties + MyDownloader.Spider + MyDownloader.Spider + + + + + 3.5 + v2.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + x86 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + + False + bin\Release\MyDownloader.Core.dll + + + + + + + + + False + ..\TabStrip.dll + + + + + + + + + + + + + + + Form + + + StartAutoDownloadsForm.cs + + + UserControl + + + WebSpider.cs + + + + + + + + + + + {FEA18B6C-491F-401A-A06B-AE47888FF288} + MyDownloader.Extension + + + + + Designer + StartAutoDownloadsForm.cs + + + WebSpider.cs + Designer + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/Parsers/Html/HtmlParser.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/Parsers/Html/HtmlParser.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Text.RegularExpressions; +using System.Web; + +namespace MyDownloader.Spider.Parsers.Html +{ + public class HtmlParser: IDisposable + { + private static string RegExprHREF = @"(?<=a\s+([^>]+\s+)?href\=[\x27\x22])(?<1>[^\x27\x22]*)(?=[\x27\x22])"; + + //private static string RegExprIMG = @"]+\s+)?src\s*=\s*(?:""(?<1>[/\a-z0-9_][^""\/]*)""|'(?<1>[/\a-z0-9_][^'']*)''|(?<1>[/\a-z0-9_]\S*))(\s?[^>]*/)?>"; + private static string RegExprIMG = @"(?<=img\s+([^>]+\s+)?src\=[\x27\x22])(?<1>[^\x27\x22]*)(?=[\x27\x22])"; + + private static string RegExprIFrame = @"(?<=iframe\s+src\=[\x27\x22])(?<1>[^\x27\x22]*)(?=[\x27\x22])"; + + private static string RegExprFrame = @"(?<=frame\s+src\=[\x27\x22])(?<1>[^\x27\x22]*)(?=[\x27\x22])"; + + private static Regex RegExFindHref = new Regex(RegExprHREF, RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled); + private static Regex RegExFindImg = new Regex(RegExprIMG, RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled); + private static Regex RegExFindIFrame = new Regex(RegExprIFrame, RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled); + private static Regex RegExFindFrame = new Regex(RegExprFrame, RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled); + + private static Regex[] regs = { RegExFindHref, RegExFindImg, RegExFindIFrame, RegExFindFrame }; + + private string htmlData; + + public HtmlParser(Stream htmlStream) + { + using (StreamReader sw = new StreamReader(htmlStream)) + { + htmlData = sw.ReadToEnd(); + } + } + + public IEnumerable GetResources(UrlType urlType, string baseUri) + { + return GetEnumerator(regs[(int)urlType], baseUri, this.htmlData); + } + + public IEnumerable GetHrefs(string baseUri) + { + return GetEnumerator(RegExFindHref, baseUri, this.htmlData); + } + + public IEnumerable GetImages(string baseUri) + { + return GetEnumerator(RegExFindImg, baseUri, this.htmlData); + } + + public IEnumerable GetFrames(string baseUri) + { + return GetEnumerator(RegExFindFrame, baseUri, this.htmlData); + } + + public IEnumerable GetIFrames(string baseUri) + { + return GetEnumerator(RegExFindIFrame, baseUri, this.htmlData); + } + + private static IEnumerable GetEnumerator(Regex regExpr, string baseUrl, string html) + { + for (Match m = regExpr.Match(html); m.Success; m = m.NextMatch()) + { + string href = m.Groups[1].ToString(); + + // filter non-real relation urls: + if (String.IsNullOrEmpty(href) || + href.StartsWith("#") || + href.StartsWith("mailto:") || + href.StartsWith("javascript:")) + { + continue; + } + + href = System.Web.HttpUtility.HtmlDecode(href); + + Uri uri = null; + try + { + uri = ConvertToAbsoluteUrl(href, baseUrl); + } + catch (Exception) + { + } + + if (uri != null) + { + yield return uri; + } + } + } + + private static Uri ConvertToAbsoluteUrl(string url, string baseUrl) + { + // we try to prevent the exception caused in the case the url is relative + // (no scheme info) just for speed + if (url.IndexOf(Uri.SchemeDelimiter) < 0 && baseUrl != null) + { + try + { + Uri baseUri = new Uri(baseUrl); + return new Uri(baseUri, url); + } + catch + { + return null; + } + } + + try + { + Uri uri = new Uri(url); + return uri; + } + catch (Exception) + { + if (baseUrl != null) + { + try + { + Uri baseUri = new Uri(baseUrl); + return new Uri(baseUri, url); + } + catch (Exception) + { + return null; + } + } + else + { + return null; + } + } + } + + #region IDisposable Members + + public void Dispose() + { + this.htmlData = null; + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/Parsers/Html/UrlType.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/Parsers/Html/UrlType.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Spider.Parsers.Html +{ + public enum UrlType : int + { + Href = 0, + Img = 1, + IFrame = 2, + Frame = 3, + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/Properties/AssemblyInfo.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MyDownloader.Spider")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Programmmers")] +[assembly: AssemblyProduct("MyDownloader.Spider")] +[assembly: AssemblyCopyright("Copyright © Programmmers 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("71b21d39-e11d-477c-bcc9-228a0407187f")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/Spider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/Spider.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Spider.Web; +using MyDownloader.Spider.Parsers.Html; + +namespace MyDownloader.Spider +{ + public class Spider + { + private SpiderContext context; + private ISpiderResourceFactory factory; + + public Spider(SpiderContext context, + ISpiderResourceFactory factory) + { + this.context = context; + this.factory = factory; + } + + #region Events + + public event EventHandler Aborted; + + public event CompletedEventHandler Completed + { + add + { + context.Completed += value; + } + remove + { + context.Completed -= value; + } + } + + protected virtual void OnAborted() + { + if (Aborted != null) + { + Aborted(this, EventArgs.Empty); + } + } + + #endregion + + #region Properties + + public SpiderContext Context + { + get + { + return context; + } + } + + #endregion + + #region Methods + + public virtual IAsyncRetriver BeginLookup() + { + ISpiderResource resourceSpider = factory.CreateSpider(this.context, null, this.context.BaseLocation); + + context.AddURIToVisit(new Uri(this.context.BaseLocation), resourceSpider); + + return resourceSpider.BeginReceive(); + } + + public virtual void Abort() + { + context.Abort(); + + OnAborted(); + } + + #endregion + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/SpiderContext.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/SpiderContext.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,172 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Spider.Parsers.Html; + +namespace MyDownloader.Spider +{ + public delegate void ResourceCompletedEventHandler(SpiderContext context, ISpiderResource resource); + + public delegate void CompletedEventHandler(SpiderContext context); + + public class SpiderContext + { + private bool aborted; + private string baseDirectory; + private string baseLocation; + + private List namingRules = new List(); + private List visitedLocations = new List(); + private List completedResources = new List(); + + public SpiderContext() + { + } + + public SpiderContext(string baseDirectory, string baseLocation) + { + this.baseDirectory = baseDirectory; + this.baseLocation = baseLocation; + } + + #region Properties + + public string BaseLocation + { + get + { + return baseLocation; + } + set + { + baseLocation = value; + } + } + + public string BaseDirectory + { + get + { + return baseDirectory; + } + set + { + baseDirectory = value; + } + } + + public List NamingRules + { + get + { + return namingRules; + } + } + + public List VisitedLocations + { + get + { + return visitedLocations; + } + } + + public List CompletedResources + { + get + { + return completedResources; + } + } + + #endregion + + #region Events + + public event ResourceCompletedEventHandler ResourceCompleted; + + public event CompletedEventHandler Completed; + + protected internal virtual void OnResourceCompleted(ISpiderResource spider) + { + if (ResourceCompleted != null) + { + ResourceCompleted(this, spider); + } + } + + protected internal virtual void OnCompleted() + { + if (Completed != null) + { + Completed(this); + } + } + + #endregion + + private bool ShouldAdd(Uri location, ISpiderResource parentSpider) + { + #region Aborted + if (aborted) + { + return false; + } + #endregion + + #region Naming rules + for (int j = 0; j < namingRules.Count; j++) + { + if (!namingRules[j].Accept(location, this, parentSpider)) return false; + } + #endregion + + return true; + } + + public void Abort() + { + aborted = true; + } + + public void NotifyCompletion(ISpiderResource spider) + { + lock (completedResources) + { + if (!completedResources.Contains(spider)) + { + completedResources.Add(spider); + } + } + + OnResourceCompleted(spider); + + if (completedResources.Count == VisitedLocations.Count) + { + OnCompleted(); + } + } + + public bool AddURIToVisit(Uri uri, ISpiderResource parentSpider) + { + if (ShouldAdd(uri, parentSpider)) + { + lock (visitedLocations) + { + if (visitedLocations.Contains(uri)) + { + return false; + } + + visitedLocations.Add(uri); + + return true; + } + } + else + { + return false; + } + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/UI/StartAutoDownloadsForm.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/UI/StartAutoDownloadsForm.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,103 @@ +namespace MyDownloader.Spider.UI +{ + partial class StartAutoDownloadsForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.scheduledDownloadEnabler1 = new MyDownloader.Extension.AutoDownloads.UI.ScheduledDownloadEnabler(); + this.label1 = new System.Windows.Forms.Label(); + this.btnNo = new System.Windows.Forms.Button(); + this.btnYes = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // scheduledDownloadEnabler1 + // + this.scheduledDownloadEnabler1.Location = new System.Drawing.Point(8, 56); + this.scheduledDownloadEnabler1.Name = "scheduledDownloadEnabler1"; + this.scheduledDownloadEnabler1.Size = new System.Drawing.Size(346, 163); + this.scheduledDownloadEnabler1.TabIndex = 1; + // + // label1 + // + this.label1.Location = new System.Drawing.Point(8, 8); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(344, 48); + this.label1.TabIndex = 0; + this.label1.Text = "The auto-downloads mode is not enabled. To Web Spider work correcly the auto-down" + + "loads mode must to be enabled. Do you want to enable it now?"; + // + // btnNo + // + this.btnNo.DialogResult = System.Windows.Forms.DialogResult.No; + this.btnNo.Location = new System.Drawing.Point(280, 224); + this.btnNo.Name = "btnNo"; + this.btnNo.Size = new System.Drawing.Size(75, 23); + this.btnNo.TabIndex = 3; + this.btnNo.Text = "No"; + this.btnNo.UseVisualStyleBackColor = true; + // + // btnYes + // + this.btnYes.DialogResult = System.Windows.Forms.DialogResult.Yes; + this.btnYes.Location = new System.Drawing.Point(200, 224); + this.btnYes.Name = "btnYes"; + this.btnYes.Size = new System.Drawing.Size(75, 23); + this.btnYes.TabIndex = 2; + this.btnYes.Text = "Yes"; + this.btnYes.UseVisualStyleBackColor = true; + // + // StartAutoDownloadsForm + // + this.AcceptButton = this.btnYes; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnNo; + this.ClientSize = new System.Drawing.Size(360, 252); + this.Controls.Add(this.btnYes); + this.Controls.Add(this.btnNo); + this.Controls.Add(this.label1); + this.Controls.Add(this.scheduledDownloadEnabler1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "StartAutoDownloadsForm"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Start Auto-downloads?"; + this.ResumeLayout(false); + + } + + #endregion + + private MyDownloader.Extension.AutoDownloads.UI.ScheduledDownloadEnabler scheduledDownloadEnabler1; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button btnNo; + private System.Windows.Forms.Button btnYes; + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/UI/StartAutoDownloadsForm.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/UI/StartAutoDownloadsForm.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using MyDownloader.Extension.AutoDownloads; +using MyDownloader.Extension.AutoDownloads.UI; + +namespace MyDownloader.Spider.UI +{ + public partial class StartAutoDownloadsForm : Form + { + public StartAutoDownloadsForm() + { + InitializeComponent(); + } + + public ScheduledDownloadEnabler ScheduledDownloadEnabler + { + get + { + return scheduledDownloadEnabler1; + } + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/UI/StartAutoDownloadsForm.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/UI/StartAutoDownloadsForm.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/UI/WebSpider.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/UI/WebSpider.Designer.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,394 @@ +using MyDownloader.Core.UI; +using MyDownloader.App.UI; + +namespace MyDownloader.Spider.UI +{ + partial class WebSpider + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.btnDownloadSite = new System.Windows.Forms.Button(); + this.btnAbort = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.label5 = new System.Windows.Forms.Label(); + this.lblTotalFiles = new System.Windows.Forms.Label(); + this.lblDownloadedFiles = new System.Windows.Forms.Label(); + this.progDownload = new System.Windows.Forms.ProgressBar(); + this.tabParams = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.chkResourcesFromExternal = new System.Windows.Forms.CheckBox(); + this.chkImagesFromExternal = new System.Windows.Forms.CheckBox(); + this.location1 = new MyDownloader.App.UI.Location(); + this.numDownloadDepth = new System.Windows.Forms.NumericUpDown(); + this.label6 = new System.Windows.Forms.Label(); + this.chkRemoveCompleted = new System.Windows.Forms.CheckBox(); + this.folderBrowser1 = new MyDownloader.Core.UI.DownloadFolder(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.txtExcludeExt = new System.Windows.Forms.TextBox(); + this.chkExcludeExtensions = new System.Windows.Forms.CheckBox(); + this.txtExcludeNames = new System.Windows.Forms.TextBox(); + this.chkExcludeNames = new System.Windows.Forms.CheckBox(); + this.tmrRefresh = new System.Windows.Forms.Timer(this.components); + this.waitControl1 = new MyDownloader.Core.UI.WaitControl(); + this.tableLayoutPanel1.SuspendLayout(); + this.tabParams.SuspendLayout(); + this.tabPage1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numDownloadDepth)).BeginInit(); + this.tabPage2.SuspendLayout(); + this.SuspendLayout(); + // + // btnDownloadSite + // + this.btnDownloadSite.Location = new System.Drawing.Point(0, 222); + this.btnDownloadSite.Name = "btnDownloadSite"; + this.btnDownloadSite.Size = new System.Drawing.Size(115, 23); + this.btnDownloadSite.TabIndex = 1; + this.btnDownloadSite.Text = "Download Site"; + this.btnDownloadSite.UseVisualStyleBackColor = true; + this.btnDownloadSite.Click += new System.EventHandler(this.btnDownloadSite_Click); + // + // btnAbort + // + this.btnAbort.Location = new System.Drawing.Point(121, 222); + this.btnAbort.Name = "btnAbort"; + this.btnAbort.Size = new System.Drawing.Size(75, 23); + this.btnAbort.TabIndex = 2; + this.btnAbort.Text = "Abort"; + this.btnAbort.UseVisualStyleBackColor = true; + this.btnAbort.Click += new System.EventHandler(this.btnAbort_Click); + // + // label1 + // + this.label1.AutoEllipsis = true; + this.label1.Dock = System.Windows.Forms.DockStyle.Fill; + this.label1.Location = new System.Drawing.Point(3, 0); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(133, 18); + this.label1.TabIndex = 0; + this.label1.Text = "Downloaded files:"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // label2 + // + this.label2.AutoEllipsis = true; + this.label2.Dock = System.Windows.Forms.DockStyle.Fill; + this.label2.Location = new System.Drawing.Point(3, 18); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(133, 18); + this.label2.TabIndex = 2; + this.label2.Text = "Total files:"; + this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 30F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 70F)); + this.tableLayoutPanel1.Controls.Add(this.label5, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.lblTotalFiles, 1, 1); + this.tableLayoutPanel1.Controls.Add(this.lblDownloadedFiles, 1, 0); + this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.label2, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.progDownload, 1, 2); + this.tableLayoutPanel1.Location = new System.Drawing.Point(2, 248); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 3; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(466, 56); + this.tableLayoutPanel1.TabIndex = 4; + // + // label5 + // + this.label5.AutoEllipsis = true; + this.label5.Dock = System.Windows.Forms.DockStyle.Fill; + this.label5.Location = new System.Drawing.Point(3, 36); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(133, 20); + this.label5.TabIndex = 4; + this.label5.Text = "Progress:"; + this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // lblTotalFiles + // + this.lblTotalFiles.Dock = System.Windows.Forms.DockStyle.Fill; + this.lblTotalFiles.Location = new System.Drawing.Point(142, 18); + this.lblTotalFiles.Name = "lblTotalFiles"; + this.lblTotalFiles.Size = new System.Drawing.Size(321, 18); + this.lblTotalFiles.TabIndex = 3; + this.lblTotalFiles.Text = "0"; + this.lblTotalFiles.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // lblDownloadedFiles + // + this.lblDownloadedFiles.Dock = System.Windows.Forms.DockStyle.Fill; + this.lblDownloadedFiles.Location = new System.Drawing.Point(142, 0); + this.lblDownloadedFiles.Name = "lblDownloadedFiles"; + this.lblDownloadedFiles.Size = new System.Drawing.Size(321, 18); + this.lblDownloadedFiles.TabIndex = 1; + this.lblDownloadedFiles.Text = "0"; + this.lblDownloadedFiles.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // progDownload + // + this.progDownload.Dock = System.Windows.Forms.DockStyle.Fill; + this.progDownload.Location = new System.Drawing.Point(142, 39); + this.progDownload.Name = "progDownload"; + this.progDownload.Size = new System.Drawing.Size(321, 14); + this.progDownload.TabIndex = 5; + this.progDownload.Value = 50; + // + // tabParams + // + this.tabParams.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tabParams.Controls.Add(this.tabPage1); + this.tabParams.Controls.Add(this.tabPage2); + this.tabParams.Location = new System.Drawing.Point(0, 1); + this.tabParams.Name = "tabParams"; + this.tabParams.SelectedIndex = 0; + this.tabParams.Size = new System.Drawing.Size(467, 215); + this.tabParams.TabIndex = 0; + // + // tabPage1 + // + this.tabPage1.AutoScroll = true; + this.tabPage1.Controls.Add(this.chkResourcesFromExternal); + this.tabPage1.Controls.Add(this.chkImagesFromExternal); + this.tabPage1.Controls.Add(this.location1); + this.tabPage1.Controls.Add(this.numDownloadDepth); + this.tabPage1.Controls.Add(this.label6); + this.tabPage1.Controls.Add(this.chkRemoveCompleted); + this.tabPage1.Controls.Add(this.folderBrowser1); + this.tabPage1.Location = new System.Drawing.Point(4, 22); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(459, 189); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "Parameters"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // chkResourcesFromExternal + // + this.chkResourcesFromExternal.AutoSize = true; + this.chkResourcesFromExternal.Location = new System.Drawing.Point(0, 168); + this.chkResourcesFromExternal.Name = "chkResourcesFromExternal"; + this.chkResourcesFromExternal.Size = new System.Drawing.Size(210, 17); + this.chkResourcesFromExternal.TabIndex = 4; + this.chkResourcesFromExternal.Text = "Download resources from external sites"; + this.chkResourcesFromExternal.UseVisualStyleBackColor = true; + // + // chkImagesFromExternal + // + this.chkImagesFromExternal.AutoSize = true; + this.chkImagesFromExternal.Location = new System.Drawing.Point(0, 152); + this.chkImagesFromExternal.Name = "chkImagesFromExternal"; + this.chkImagesFromExternal.Size = new System.Drawing.Size(197, 17); + this.chkImagesFromExternal.TabIndex = 3; + this.chkImagesFromExternal.Text = "Download images from external sites"; + this.chkImagesFromExternal.UseVisualStyleBackColor = true; + // + // location1 + // + this.location1.Dock = System.Windows.Forms.DockStyle.Top; + this.location1.Location = new System.Drawing.Point(3, 45); + this.location1.Name = "location1"; + this.location1.Size = new System.Drawing.Size(453, 91); + this.location1.TabIndex = 1; + this.location1.UrlLabelTitle = "URL"; + // + // numDownloadDepth + // + this.numDownloadDepth.Location = new System.Drawing.Point(288, 152); + this.numDownloadDepth.Name = "numDownloadDepth"; + this.numDownloadDepth.Size = new System.Drawing.Size(120, 20); + this.numDownloadDepth.TabIndex = 6; + this.numDownloadDepth.Value = new decimal(new int[] { + 4, + 0, + 0, + 0}); + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(288, 136); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(151, 13); + this.label6.TabIndex = 5; + this.label6.Text = "Download depth (0 for infinite):"; + // + // chkRemoveCompleted + // + this.chkRemoveCompleted.AutoSize = true; + this.chkRemoveCompleted.Location = new System.Drawing.Point(0, 136); + this.chkRemoveCompleted.Name = "chkRemoveCompleted"; + this.chkRemoveCompleted.Size = new System.Drawing.Size(210, 17); + this.chkRemoveCompleted.TabIndex = 2; + this.chkRemoveCompleted.Text = "Remove completed downloads from list"; + this.chkRemoveCompleted.UseVisualStyleBackColor = true; + // + // folderBrowser1 + // + this.folderBrowser1.Dock = System.Windows.Forms.DockStyle.Top; + this.folderBrowser1.LabelText = "Save to:"; + this.folderBrowser1.Location = new System.Drawing.Point(3, 3); + this.folderBrowser1.Name = "folderBrowser1"; + this.folderBrowser1.Size = new System.Drawing.Size(453, 42); + this.folderBrowser1.TabIndex = 0; + // + // tabPage2 + // + this.tabPage2.AutoScroll = true; + this.tabPage2.AutoScrollMargin = new System.Drawing.Size(0, 8); + this.tabPage2.Controls.Add(this.txtExcludeExt); + this.tabPage2.Controls.Add(this.chkExcludeExtensions); + this.tabPage2.Controls.Add(this.txtExcludeNames); + this.tabPage2.Controls.Add(this.chkExcludeNames); + this.tabPage2.Location = new System.Drawing.Point(4, 22); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3); + this.tabPage2.Size = new System.Drawing.Size(459, 189); + this.tabPage2.TabIndex = 1; + this.tabPage2.Text = "Advanced"; + this.tabPage2.UseVisualStyleBackColor = true; + // + // txtExcludeExt + // + this.txtExcludeExt.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtExcludeExt.Enabled = false; + this.txtExcludeExt.Location = new System.Drawing.Point(8, 64); + this.txtExcludeExt.Name = "txtExcludeExt"; + this.txtExcludeExt.Size = new System.Drawing.Size(422, 20); + this.txtExcludeExt.TabIndex = 3; + // + // chkExcludeExtensions + // + this.chkExcludeExtensions.AutoSize = true; + this.chkExcludeExtensions.Location = new System.Drawing.Point(8, 48); + this.chkExcludeExtensions.Name = "chkExcludeExtensions"; + this.chkExcludeExtensions.Size = new System.Drawing.Size(262, 17); + this.chkExcludeExtensions.TabIndex = 2; + this.chkExcludeExtensions.Text = "Exclude files with extension (separated by comma)"; + this.chkExcludeExtensions.UseVisualStyleBackColor = true; + this.chkExcludeExtensions.CheckedChanged += new System.EventHandler(this.check_CheckedChanged); + // + // txtExcludeNames + // + this.txtExcludeNames.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtExcludeNames.Enabled = false; + this.txtExcludeNames.Location = new System.Drawing.Point(8, 24); + this.txtExcludeNames.Name = "txtExcludeNames"; + this.txtExcludeNames.Size = new System.Drawing.Size(422, 20); + this.txtExcludeNames.TabIndex = 1; + // + // chkExcludeNames + // + this.chkExcludeNames.AutoSize = true; + this.chkExcludeNames.Location = new System.Drawing.Point(8, 8); + this.chkExcludeNames.Name = "chkExcludeNames"; + this.chkExcludeNames.Size = new System.Drawing.Size(285, 17); + this.chkExcludeNames.TabIndex = 0; + this.chkExcludeNames.Text = "Exclude files that name contains (separated by comma)"; + this.chkExcludeNames.UseVisualStyleBackColor = true; + this.chkExcludeNames.CheckedChanged += new System.EventHandler(this.check_CheckedChanged); + // + // tmrRefresh + // + this.tmrRefresh.Interval = 1500; + this.tmrRefresh.Tick += new System.EventHandler(this.tmrRefresh_Tick); + // + // waitControl1 + // + this.waitControl1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.waitControl1.Location = new System.Drawing.Point(200, 224); + this.waitControl1.Name = "waitControl1"; + this.waitControl1.Size = new System.Drawing.Size(257, 16); + this.waitControl1.TabIndex = 5; + this.waitControl1.Text = "Downloading site, please wait..."; + this.waitControl1.Visible = false; + // + // WebSpider + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.waitControl1); + this.Controls.Add(this.tabParams); + this.Controls.Add(this.tableLayoutPanel1); + this.Controls.Add(this.btnAbort); + this.Controls.Add(this.btnDownloadSite); + this.Name = "WebSpider"; + this.Size = new System.Drawing.Size(470, 348); + this.tableLayoutPanel1.ResumeLayout(false); + this.tabParams.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.tabPage1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numDownloadDepth)).EndInit(); + this.tabPage2.ResumeLayout(false); + this.tabPage2.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button btnDownloadSite; + private System.Windows.Forms.Button btnAbort; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.Label lblTotalFiles; + private System.Windows.Forms.Label label5; + private DownloadFolder folderBrowser1; + private System.Windows.Forms.TabControl tabParams; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.CheckBox chkRemoveCompleted; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.NumericUpDown numDownloadDepth; + private System.Windows.Forms.TextBox txtExcludeNames; + private System.Windows.Forms.CheckBox chkExcludeNames; + private System.Windows.Forms.TextBox txtExcludeExt; + private System.Windows.Forms.CheckBox chkExcludeExtensions; + private System.Windows.Forms.Label lblDownloadedFiles; + private System.Windows.Forms.ProgressBar progDownload; + private Location location1; + private System.Windows.Forms.Timer tmrRefresh; + private System.Windows.Forms.CheckBox chkResourcesFromExternal; + private System.Windows.Forms.CheckBox chkImagesFromExternal; + private WaitControl waitControl1; + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/UI/WebSpider.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/UI/WebSpider.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Text; +using System.Windows.Forms; +using MyDownloader.Spider.Web.Rules; +using MyDownloader.Core; +using MyDownloader.Extension.AutoDownloads; +using MyDownloader.Core.UI; +using MyDownloader.Spider.Web; + +namespace MyDownloader.Spider.UI +{ + public partial class WebSpider : UserControl + { + public WebSpider() + { + InitializeComponent(); + + EnterDownloadMode(false); + + UpdateInputBasesOnCheckBoxes(); + } + + Spider siteSpider; + + private void btnDownloadSite_Click(object sender, EventArgs e) + { + ResourceLocation rl = this.location1.ResourceLocation[0]; + + rl.BindProtocolProviderType(); + + if (rl.ProtocolProviderType == null) + { + MessageBox.Show("Invalid URL format, please check the location field.", + AppManager.Instance.Application.MainForm.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + AutoDownloadsExtension scheduler; + + scheduler = (AutoDownloadsExtension)AppManager.Instance.Application.GetExtensionByType(typeof(AutoDownloadsExtension)); + + if (! scheduler.Active) + { + using (StartAutoDownloadsForm startAd = new StartAutoDownloadsForm()) + { + if (startAd.ShowDialog() == DialogResult.Yes) + { + startAd.ScheduledDownloadEnabler.ApplySettings(); + } + } + + if (!scheduler.Active) + { + return; + } + } + + SpiderContext spiderCntx = new SpiderContext( + folderBrowser1.Folder, + rl.URL); + + spiderCntx.NamingRules.Add( + new BaseLocationNamingRule(chkImagesFromExternal.Checked, chkResourcesFromExternal.Checked)); + + if (chkExcludeExtensions.Checked) + { + spiderCntx.NamingRules.Add(new ExcludeExtensionNamingRule(txtExcludeExt.Text.Split(','))); + } + if (chkExcludeNames.Checked) + { + spiderCntx.NamingRules.Add(new ExcludeNameNamingRule(txtExcludeNames.Text.Split(','))); + } + if (numDownloadDepth.Value > 0) + { + spiderCntx.NamingRules.Add(new MaxDepthNamingRule((int)numDownloadDepth.Value)); + } + if (chkRemoveCompleted.Checked) + { + spiderCntx.ResourceCompleted += delegate(SpiderContext cntx, ISpiderResource resource) + { + DownloadManager.Instance.ClearEnded(); + }; + } + + siteSpider = new Spider(spiderCntx, new WebSpiderResourceFactory()); + siteSpider.Completed += new CompletedEventHandler(siteSpider_Completed); + siteSpider.Aborted += new EventHandler(siteSpider_Aborted); + siteSpider.BeginLookup(); + + EnterDownloadMode(true); + } + + private void EnterDownloadMode(bool downloading) + { + RefreshStatus(); + + progDownload.Value = 0; + tabParams.Enabled = !downloading; + btnAbort.Enabled = downloading; + btnDownloadSite.Enabled = !downloading; + waitControl1.Visible = downloading; + tmrRefresh.Enabled = downloading; + } + + void siteSpider_Aborted(object sender, EventArgs e) + { + this.BeginInvoke((MethodInvoker)delegate() { EnterDownloadMode(false); }); + } + + void siteSpider_Completed(SpiderContext cntx) + { + this.BeginInvoke((MethodInvoker)delegate() { EnterDownloadMode(false); }); + } + + private void btnAbort_Click(object sender, EventArgs e) + { + siteSpider.Abort(); + } + + private void tmrRefresh_Tick(object sender, EventArgs e) + { + RefreshStatus(); + } + + private void RefreshStatus() + { + float totalVisited; + float totalDownloaded; + + if (siteSpider != null) + { + totalVisited = siteSpider.Context.VisitedLocations.Count; + totalDownloaded = siteSpider.Context.CompletedResources.Count; + } + else + { + totalVisited = totalDownloaded = 0; + } + + lblTotalFiles.Text = totalVisited.ToString(); + lblDownloadedFiles.Text = totalDownloaded.ToString(); + + try + { + if (totalVisited != 0) + { + progDownload.Value = (int)((totalDownloaded / totalVisited) * 100); + } + else + { + progDownload.Value = 0; + } + } + catch (Exception) + { + } + } + + private void check_CheckedChanged(object sender, EventArgs e) + { + UpdateInputBasesOnCheckBoxes(); + } + + private void UpdateInputBasesOnCheckBoxes() + { + txtExcludeExt.Enabled = chkExcludeExtensions.Checked; + txtExcludeNames.Enabled = chkExcludeNames.Checked; + } + } +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/UI/WebSpider.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/UI/WebSpider.resx Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 58 + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/Web/DownloaderAsyncRetrive.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/Web/DownloaderAsyncRetrive.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Core; + +namespace MyDownloader.Spider.Web +{ + class DownloaderAsyncRetrive : IAsyncRetriver + { + Downloader downloader; + ISpiderResource resource; + + internal DownloaderAsyncRetrive(ISpiderResource resource, Downloader d) + { + this.downloader = d; + this.resource = resource; + } + + #region IAsyncRetrive Members + + public ISpiderResource Resource + { + get { return resource; } + } + + public bool IsCompleted + { + get { return !downloader.IsWorking() ; } + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/Web/Rules/BaseLocationNamingRule.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/Web/Rules/BaseLocationNamingRule.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyDownloader.Spider.Parsers.Html; + +namespace MyDownloader.Spider.Web.Rules +{ + public class BaseLocationNamingRule: INamingRule + { + private bool downloadImagesFromExternalSite; + private bool downloadResourceFromExternalSite; + + public BaseLocationNamingRule( + bool downloadImagesFromExternalSite, + bool downloadResourceFromExternalSite) + { + this.downloadImagesFromExternalSite = downloadImagesFromExternalSite; + this.downloadResourceFromExternalSite = downloadResourceFromExternalSite; + } + + #region INamingRule Members + + public bool Accept(Uri location, SpiderContext context, ISpiderResource parentSpider) + { + UrlType urlType = ((WebSpiderResource)parentSpider).addingUrlType; + + if ( + !(urlType == UrlType.Img && this.downloadImagesFromExternalSite) + && + !(urlType != UrlType.Img && this.downloadResourceFromExternalSite) + ) + { + string tempbase = context.BaseLocation; + int i; + + if ((i = tempbase.LastIndexOf("/")) >= 0) + { + tempbase = tempbase.Substring(0, i + 1); + } + + if (!location.OriginalString.StartsWith(tempbase)) + { + return false; + } + } + + return true; + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/Web/Rules/ExcludeExtensionNamingRule.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/Web/Rules/ExcludeExtensionNamingRule.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace MyDownloader.Spider.Web.Rules +{ + public class ExcludeExtensionNamingRule: INamingRule + { + string[] extensionsToExclude; + + public ExcludeExtensionNamingRule(string[] extensionsToExclude) + { + for (int i = 0; i < extensionsToExclude.Length; i++) + { + extensionsToExclude[i] = extensionsToExclude[i].ToLower(); + } + + this.extensionsToExclude = extensionsToExclude; + } + + #region INamingRule Members + + public bool Accept(Uri location, SpiderContext context, ISpiderResource parentSpider) + { + string ext = Path.GetExtension(location.Segments[location.Segments.Length-1]).ToLower(); + + int index = Array.IndexOf(this.extensionsToExclude, ext); + + return index < 0; + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/Web/Rules/ExcludeNameNamingRule.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/Web/Rules/ExcludeNameNamingRule.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Spider.Web.Rules +{ + class ExcludeNameNamingRule: INamingRule + { + string[] namesToExclude; + + public ExcludeNameNamingRule(string[] namesToExclude) + { + for (int i = 0; i < namesToExclude.Length; i++) + { + namesToExclude[i] = namesToExclude[i].ToLower(); + } + + this.namesToExclude = namesToExclude; + } + + #region INamingRule Members + + public bool Accept(Uri uri, SpiderContext context, ISpiderResource parentSpider) + { + string fileName = uri.Segments[uri.Segments.Length - 1]; + + for (int i = 0; i < namesToExclude.Length; i++) + { + if (fileName.IndexOf(namesToExclude[i]) >= 0) + { + return false; + } + } + + return true; + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/Web/Rules/MaxDepthNamingRule.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/Web/Rules/MaxDepthNamingRule.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Spider.Web.Rules +{ + public class MaxDepthNamingRule: INamingRule + { + private int maxDepth; + + public MaxDepthNamingRule(int maxDepth) + { + this.maxDepth = maxDepth; + } + + #region INamingRule Members + + public bool Accept(Uri location, SpiderContext context, ISpiderResource parentSpider) + { + if (this.maxDepth > 0 && parentSpider.Depth >= this.maxDepth) + { + return false; + } + else + { + return true; + } + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/Web/WebSpiderResource.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/Web/WebSpiderResource.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,185 @@ +using System; +using System.Collections.Generic; +using MyDownloader.Core; +using System.IO; +using MyDownloader.Spider.Parsers.Html; + +namespace MyDownloader.Spider.Web +{ + public class WebSpiderResource : ISpiderResource + { + private string location; + internal UrlType addingUrlType; + private int depth; + private ISpiderResource parent; + private SpiderContext context; + private Downloader download; + private List nextResources = new List(); + + public WebSpiderResource(SpiderContext context, ISpiderResource parent, string location) + { + this.context = context; + this.location = location; + this.parent = parent; + + UpdateDepth(); + + string localFile = GetLocalFile(); + + download = DownloadManager.Instance.Add( + ResourceLocation.FromURL(this.Location), + null, + localFile, + 1, + false); + + download.StateChanged += new EventHandler(download_StateChanged); + } + + private void UpdateDepth() + { + if (this.parent == null) + { + this.depth = 0; + } + else + { + ISpiderResource tmpParent = this.parent; + while (tmpParent != null) + { + this.depth++; + tmpParent = tmpParent.ParentResource; + } + } + } + + void download_StateChanged(object sender, EventArgs e) + { + switch (download.State) + { + case DownloaderState.Ended: + LoadData(); + goto case DownloaderState.EndedWithError; + case DownloaderState.EndedWithError: + context.NotifyCompletion(this); + break; + } + } + + private void LoadData() + { + nextResources.Clear(); + + if (download.RemoteFileInfo.MimeType.IndexOf("text/html", StringComparison.OrdinalIgnoreCase) < 0) + { + return; + } + + try + { + DownloadManager.Instance.OnBeginAddBatchDownloads(); + + using (Stream htmlStream = File.OpenRead(download.LocalFile)) + { + using (HtmlParser parser = new HtmlParser(htmlStream)) + { + AddUrls(parser.GetHrefs(context.BaseLocation), UrlType.Href); + AddUrls(parser.GetImages(context.BaseLocation), UrlType.Img); + AddUrls(parser.GetFrames(context.BaseLocation), UrlType.Frame); + AddUrls(parser.GetIFrames(context.BaseLocation), UrlType.IFrame); + } + } + } + finally + { + DownloadManager.Instance.OnEndAddBatchDownloads(); + } + } + + private void AddUrls(IEnumerable uris, UrlType type) + { + this.addingUrlType = type; + + IEnumerator enumUri = uris.GetEnumerator(); + + while (enumUri.MoveNext()) + { + AddUrl(enumUri.Current); + } + } + + private void AddUrl(Uri uri) + { + if (this.context.AddURIToVisit(uri, this)) + { + System.Diagnostics.Debug.WriteLine(uri.OriginalString); + + nextResources.Add( + new WebSpiderResource(this.context, this, uri.OriginalString)); + } + } + + private string GetLocalFile() + { + Uri uri = new Uri(this.Location); + + string dirSep = Path.DirectorySeparatorChar.ToString(); + + string fileName = String.Concat(uri.Host, string.Join("", uri.Segments)); + + string dir = + this.context.BaseDirectory + + dirSep + + fileName.Replace("/", dirSep); + + if (dir.EndsWith(dirSep)) + { + dir += "default.html"; + } + + return dir; + } + + #region ISpiderResource Members + + public IAsyncRetriver BeginReceive() + { + download.Start(); + + return new DownloaderAsyncRetrive(this, download); + } + + public void EndReceive() + { + download.WaitForConclusion(); + } + + public string Location + { + get { return location; } + } + + public int Depth + { + get { return this.depth; } + } + + public ISpiderResource ParentResource + { + get + { + return this.parent; + } + } + + public List NextResources + { + get + { + return this.nextResources; + } + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Spider/Web/WebSpiderResourceFactory.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Spider/Web/WebSpiderResourceFactory.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyDownloader.Spider.Web +{ + public class WebSpiderResourceFactory: ISpiderResourceFactory + { + #region ISpiderResourceFactory Members + + public ISpiderResource CreateSpider(SpiderContext cntx, ISpiderResource parent, string location) + { + return new WebSpiderResource(cntx, parent, location); + } + + #endregion + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Tests/Extension/Video/VideoConverterTest.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Tests/Extension/Video/VideoConverterTest.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Text; +using NUnit.Framework; +using MyDownloader.Extension.Video; + +namespace MyDownloader.Tests.Extension.Video +{ + [TestFixture] + public class VideoConverterTest + { + [Test] + public void ToMp3() + { + VideoConverter.Convert(@"C:\Temp\video.mp3", VideoFormat.MP3); + } + + [Test] + public void ToAVI() + { + VideoConverter.Convert(@"C:\Temp\video.avi", VideoFormat.AVI); + } + + [Test] + public void ToMPEG() + { + VideoConverter.Convert(@"C:\Temp\video.mpeg", VideoFormat.MPEG); + } + } +} diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Tests/MyDownloader.Tests.csproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Tests/MyDownloader.Tests.csproj Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,63 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {3232779E-E9F4-4D70-9969-F435D98B1A8B} + Library + Properties + MyDownloader.Tests + MyDownloader.Tests + + + + + 2.0 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + {E763345E-6696-4C53-8764-47E4ABD67DEF} + MyDownloader.Core + + + {FEA18B6C-491F-401A-A06B-AE47888FF288} + MyDownloader.Extension + + + + + \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.Tests/Properties/AssemblyInfo.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.Tests/Properties/AssemblyInfo.cs Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MyDownloader.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MyDownloader.Tests")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("658581b3-e94e-48f5-88d1-0fec8502245d")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece MyDownloader.sln --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MyDownloader.sln Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,44 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyDownloader.App", "MyDownloader.App\MyDownloader.App.csproj", "{18AE3994-8F48-49B1-AC63-342F70ED1135}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyDownloader.Core", "MyDownloader.Core\MyDownloader.Core.csproj", "{E763345E-6696-4C53-8764-47E4ABD67DEF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyDownloader.Extension", "MyDownloader.Extension\MyDownloader.Extension.csproj", "{FEA18B6C-491F-401A-A06B-AE47888FF288}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyDownloader.Spider", "MyDownloader.Spider\MyDownloader.Spider.csproj", "{69C99442-953E-4559-96D3-C82CC57A3C87}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyDownloader.IEPlugin", "MyDownloader.IEPlugin\MyDownloader.IEPlugin.csproj", "{91BB212C-D158-4B83-A3BC-1A41BBDC8463}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {18AE3994-8F48-49B1-AC63-342F70ED1135}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {18AE3994-8F48-49B1-AC63-342F70ED1135}.Debug|Any CPU.Build.0 = Debug|Any CPU + {18AE3994-8F48-49B1-AC63-342F70ED1135}.Release|Any CPU.ActiveCfg = Release|Any CPU + {18AE3994-8F48-49B1-AC63-342F70ED1135}.Release|Any CPU.Build.0 = Release|Any CPU + {E763345E-6696-4C53-8764-47E4ABD67DEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E763345E-6696-4C53-8764-47E4ABD67DEF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E763345E-6696-4C53-8764-47E4ABD67DEF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E763345E-6696-4C53-8764-47E4ABD67DEF}.Release|Any CPU.Build.0 = Release|Any CPU + {FEA18B6C-491F-401A-A06B-AE47888FF288}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FEA18B6C-491F-401A-A06B-AE47888FF288}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FEA18B6C-491F-401A-A06B-AE47888FF288}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FEA18B6C-491F-401A-A06B-AE47888FF288}.Release|Any CPU.Build.0 = Release|Any CPU + {69C99442-953E-4559-96D3-C82CC57A3C87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {69C99442-953E-4559-96D3-C82CC57A3C87}.Debug|Any CPU.Build.0 = Debug|Any CPU + {69C99442-953E-4559-96D3-C82CC57A3C87}.Release|Any CPU.ActiveCfg = Release|Any CPU + {69C99442-953E-4559-96D3-C82CC57A3C87}.Release|Any CPU.Build.0 = Release|Any CPU + {91BB212C-D158-4B83-A3BC-1A41BBDC8463}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {91BB212C-D158-4B83-A3BC-1A41BBDC8463}.Debug|Any CPU.Build.0 = Debug|Any CPU + {91BB212C-D158-4B83-A3BC-1A41BBDC8463}.Release|Any CPU.ActiveCfg = Release|Any CPU + {91BB212C-D158-4B83-A3BC-1A41BBDC8463}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece System.Data.SQLite.dll Binary file System.Data.SQLite.dll has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece TabStrip.dll Binary file TabStrip.dll has changed diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece installer.iss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/installer.iss Mon Feb 11 23:31:50 2013 -0600 @@ -0,0 +1,28 @@ +[Setup] +AppName=.Net Download Manager +AppVersion=1.3 +LicenseFile=MyDownloader.App\bin\Release\License.txt +AppPublisher=Nathan Adams +AppPublisherURL=http://code.google.com/u/112375326098483542471/ +DefaultDirName={pf}\.Net Download Manager +AppReadmeFile=MyDownloader.App\bin\Release\readme.txt +InfoBeforeFile=MyDownloader.App\bin\Release\readme.txt +DefaultGroupName=.Net Download Manager + +[Files] +Source: "MyDownloader.App\bin\Release\ICSharpCode.SharpZipLib.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "MyDownloader.App\bin\Release\MyDownloader.App.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "MyDownloader.App\bin\Release\MyDownloader.Core.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "MyDownloader.App\bin\Release\MyDownloader.Extension.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "MyDownloader.App\bin\Release\MyDownloader.Spider.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "MyDownloader.App\bin\Release\TabStrip.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "MyDownloader.App\bin\Release\sqlite3.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "MyDownloader.App\bin\Release\INIFileParser.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "MyDownloader.App\bin\Release\System.Data.SQLite.dll"; DestDir: "{app}"; Flags: ignoreversion + +[ThirdParty] +UseRelativePaths=True + +[Icons] +Name: "{userstartmenu}\.Net Download Manager\Uninstall DNDM"; Filename: "{uninstallexe}" +Name: "{userstartmenu}\.Net Download Manager\.Net Download Manager"; Filename: "{app}\MyDownloader.App.exe" diff -r 0000000000000000000000000000000000000000 -r 1dae03ea324288bcb7086f5a8568e2a13074eece sqlite3.dll Binary file sqlite3.dll has changed