<Compile Include="Services\Scan\EventArgs\ScanProgressEventArgs.cs" />\r
<Compile Include="Utilities\Converters.cs" />\r
<Compile Include="Utilities\EnumHelper.cs" />\r
+ <Compile Include="Utilities\Execute.cs" />\r
<Compile Include="Utilities\ExtensionMethods.cs" />\r
+ <Compile Include="Utilities\Interfaces\INotifyPropertyChangedEx.cs" />\r
<Compile Include="Utilities\PropertyChangedBase.cs" />\r
<Compile Include="Utilities\SystemInfo.cs" />\r
<Compile Include="Utilities\VersionHelper.cs" />\r
--- /dev/null
+// --------------------------------------------------------------------------------------------------------------------\r
+// <copyright company="HandBrake Project (http://handbrake.fr)" file="Execute.cs">\r
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.\r
+// </copyright>\r
+// <summary>\r
+// Enables easy marshalling of code to the UI thread.\r
+// Borrowed from Caliburn Micro.\r
+// </summary>\r
+// --------------------------------------------------------------------------------------------------------------------\r
+\r
+namespace HandBrake.ApplicationServices.Utilities\r
+{\r
+ using System;\r
+ using System.ComponentModel;\r
+ using System.Diagnostics;\r
+ using System.Threading.Tasks;\r
+ using System.Windows;\r
+ using System.Windows.Threading;\r
+\r
+ /// <summary>\r
+ /// Enables easy marshalling of code to the UI thread.\r
+ /// </summary>\r
+ public static class Execute\r
+ {\r
+ private static System.Action<System.Action> executor = (System.Action<System.Action>)(action => action());\r
+ private static Dispatcher dispatcher;\r
+ private static bool? inDesignMode;\r
+\r
+ /// <summary>\r
+ /// Indicates whether or not the framework is in design-time mode.\r
+ /// </summary>\r
+ public static bool InDesignMode\r
+ {\r
+ get\r
+ {\r
+ if (!Execute.inDesignMode.HasValue)\r
+ {\r
+ Execute.inDesignMode = new bool?((bool)DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof(FrameworkElement)).Metadata.DefaultValue);\r
+ if (!Execute.inDesignMode.GetValueOrDefault(false) && Process.GetCurrentProcess().ProcessName.StartsWith("devenv", StringComparison.Ordinal))\r
+ Execute.inDesignMode = new bool?(true);\r
+ }\r
+ return Execute.inDesignMode.GetValueOrDefault(false);\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Initializes the framework using the current dispatcher.\r
+ /// </summary>\r
+ public static void InitializeWithDispatcher()\r
+ {\r
+ Execute.dispatcher = Dispatcher.CurrentDispatcher;\r
+ Execute.executor = (System.Action<System.Action>)null;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Resets the executor to use a non-dispatcher-based action executor.\r
+ /// </summary>\r
+ public static void ResetWithoutDispatcher()\r
+ {\r
+ executor = (System.Action<System.Action>)(action => action());\r
+ dispatcher = (Dispatcher)null;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Sets a custom UI thread marshaller.\r
+ /// </summary>\r
+ /// <param name="marshaller">The marshaller.</param>\r
+ [Obsolete]\r
+ public static void SetUIThreadMarshaller(System.Action<System.Action> marshaller)\r
+ {\r
+ Execute.executor = marshaller;\r
+ Execute.dispatcher = (Dispatcher)null;\r
+ }\r
+\r
+ private static void ValidateDispatcher()\r
+ {\r
+ if (Execute.dispatcher == null)\r
+ throw new InvalidOperationException("Not initialized with dispatcher.");\r
+ }\r
+\r
+ /// <summary>\r
+ /// Executes the action on the UI thread asynchronously.\r
+ /// </summary>\r
+ /// <param name="action">The action to execute.</param>\r
+ public static void BeginOnUIThread(this System.Action action)\r
+ {\r
+ Execute.ValidateDispatcher();\r
+ Execute.dispatcher.BeginInvoke((Delegate)action);\r
+ }\r
+\r
+ /// <summary>\r
+ /// Executes the action on the UI thread asynchronously.\r
+ /// </summary>\r
+ /// <param name="action">The action to execute.</param>\r
+ public static Task OnUIThreadAsync(this System.Action action)\r
+ {\r
+ Execute.ValidateDispatcher();\r
+ TaskCompletionSource<object> taskSource = new TaskCompletionSource<object>();\r
+ System.Action action1 = (System.Action)(() =>\r
+ {\r
+ try\r
+ {\r
+ action();\r
+ taskSource.SetResult((object)null);\r
+ }\r
+ catch (Exception ex)\r
+ {\r
+ taskSource.SetException(ex);\r
+ }\r
+ });\r
+ Execute.dispatcher.BeginInvoke((Delegate)action1);\r
+ return (Task)taskSource.Task;\r
+ }\r
+\r
+ private static bool CheckAccess()\r
+ {\r
+ if (Execute.dispatcher != null)\r
+ return Execute.dispatcher.CheckAccess();\r
+ return true;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Executes the action on the UI thread.\r
+ /// </summary>\r
+ /// <param name="action">The action to execute.</param>\r
+ public static void OnUIThread(this System.Action action)\r
+ {\r
+ if (Execute.executor != null)\r
+ Execute.executor(action);\r
+ else if (Execute.CheckAccess())\r
+ action();\r
+ else\r
+ Execute.OnUIThreadAsync(action).Wait();\r
+ }\r
+ }\r
+}\r
--- /dev/null
+// --------------------------------------------------------------------------------------------------------------------\r
+// <copyright file="INotifyPropertyChangedEx.cs" company="HandBrake Project (http://handbrake.fr)">\r
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.\r
+// </copyright>\r
+// <summary>\r
+// Extends <see cref="T:System.ComponentModel.INotifyPropertyChanged" /> such that the change event can be raised by external parties.\r
+// </summary>\r
+// --------------------------------------------------------------------------------------------------------------------\r
+\r
+namespace HandBrake.ApplicationServices.Utilities.Interfaces\r
+{\r
+ using System.ComponentModel;\r
+\r
+ /// <summary>\r
+ /// Extends <see cref="T:System.ComponentModel.INotifyPropertyChanged"/> such that the change event can be raised by external parties.\r
+ /// </summary>\r
+ public interface INotifyPropertyChangedEx : INotifyPropertyChanged\r
+ {\r
+ /// <summary>\r
+ /// Enables/Disables property change notification.\r
+ /// </summary>\r
+ bool IsNotifying { get; set; }\r
+\r
+ /// <summary>\r
+ /// Notifies subscribers of the property change.\r
+ /// </summary>\r
+ /// <param name="propertyName">\r
+ /// Name of the property.\r
+ /// </param>\r
+ void NotifyOfPropertyChange(string propertyName);\r
+\r
+ /// <summary>\r
+ /// Raises a change notification indicating that all bindings should be refreshed.\r
+ /// </summary>\r
+ void Refresh();\r
+ }\r
+}\r
// --------------------------------------------------------------------------------------------------------------------\r
-// <copyright file="PropertyChangedBase.cs" company="HandBrake Project (http://handbrake.fr)">\r
+// <copyright company="HandBrake Project (http://handbrake.fr)" file="PropertyChangedBase.cs">\r
// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.\r
// </copyright>\r
// <summary>\r
// A base class that implements the infrastructure for property change notification and automatically performs UI thread marshalling.\r
-// This class is a modified version of the caliburn micro \r
+// Borrowed from Caliburn Micro\r
// </summary>\r
// --------------------------------------------------------------------------------------------------------------------\r
\r
using System.Linq.Expressions;\r
using System.Runtime.Serialization;\r
\r
+ using HandBrake.ApplicationServices.Utilities.Interfaces;\r
+\r
/// <summary>\r
- /// Property Changed Base implimentation.\r
+ /// A base class that implements the infrastructure for property change notification and automatically performs UI thread marshalling.\r
/// </summary>\r
- [DataContract]\r
- public class PropertyChangedBase : INotifyPropertyChanged\r
+ [Serializable]\r
+ public class PropertyChangedBase : INotifyPropertyChangedEx, INotifyPropertyChanged\r
{\r
+ [NonSerialized]\r
+ private bool isNotifying;\r
+\r
/// <summary>\r
- /// Creates an instance of <see cref = "PropertyChangedBase" />.\r
+ /// Enables/Disables property change notification.\r
/// </summary>\r
- public PropertyChangedBase()\r
+ [Browsable(false)]\r
+ public bool IsNotifying\r
{\r
- IsNotifying = true;\r
+ get\r
+ {\r
+ return this.isNotifying;\r
+ }\r
+ set\r
+ {\r
+ this.isNotifying = value;\r
+ }\r
}\r
\r
/// <summary>\r
/// Occurs when a property value changes.\r
/// </summary>\r
- public event PropertyChangedEventHandler PropertyChanged = delegate { };\r
+ public event PropertyChangedEventHandler PropertyChanged = (param0, param1) => { };\r
\r
/// <summary>\r
- /// Enables/Disables property change notification.\r
+ /// Creates an instance of <see cref="T:HandBrake.ApplicationServices.Utilities.PropertyChangedBase"/>.\r
/// </summary>\r
- public bool IsNotifying { get; set; }\r
+ public PropertyChangedBase()\r
+ {\r
+ this.IsNotifying = true;\r
+ }\r
\r
/// <summary>\r
/// Raises a change notification indicating that all bindings should be refreshed.\r
/// </summary>\r
- public virtual void Refresh()\r
+ public void Refresh()\r
{\r
- NotifyOfPropertyChange(string.Empty);\r
+ this.NotifyOfPropertyChange(string.Empty);\r
}\r
\r
/// <summary>\r
/// Notifies subscribers of the property change.\r
/// </summary>\r
- /// <param name = "propertyName">Name of the property.</param>\r
- public virtual void NotifyOfPropertyChange(string propertyName = null)\r
+ /// <param name="propertyName">Name of the property.</param>\r
+ public virtual void NotifyOfPropertyChange(string propertyName)\r
{\r
- if (IsNotifying)\r
- {\r
- OnPropertyChanged(new PropertyChangedEventArgs(propertyName));\r
- }\r
+ if (!this.IsNotifying)\r
+ return;\r
+ Execute.OnUIThread((System.Action)(() => this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName))));\r
}\r
\r
/// <summary>\r
/// Notifies subscribers of the property change.\r
/// </summary>\r
- /// <typeparam name = "TProperty">The type of the property.</typeparam>\r
- /// <param name = "property">The property expression.</param>\r
+ /// <typeparam name="TProperty">The type of the property.</typeparam><param name="property">The property expression.</param>\r
public void NotifyOfPropertyChange<TProperty>(Expression<Func<TProperty>> property)\r
{\r
- NotifyOfPropertyChange(property.GetMemberInfo().Name);\r
+ this.NotifyOfPropertyChange(ExtensionMethods.GetMemberInfo((Expression)property).Name);\r
}\r
\r
/// <summary>\r
- /// Raises the <see cref="PropertyChanged" /> event directly.\r
+ /// Raises the <see cref="E:PropertyChanged"/> event directly.\r
/// </summary>\r
- /// <param name="e">The <see cref="PropertyChangedEventArgs"/> instance containing the event data.</param>\r
+ /// <param name="e">The <see cref="T:System.ComponentModel.PropertyChangedEventArgs"/> instance containing the event data.</param>\r
[EditorBrowsable(EditorBrowsableState.Never)]\r
protected void OnPropertyChanged(PropertyChangedEventArgs e)\r
{\r
- var handler = PropertyChanged;\r
- if (handler != null)\r
- {\r
- handler(this, e);\r
- }\r
+ PropertyChangedEventHandler changedEventHandler = this.PropertyChanged;\r
+ if (changedEventHandler == null)\r
+ return;\r
+ changedEventHandler((object)this, e);\r
+ }\r
+\r
+ /// <summary>\r
+ /// Called when the object is deserialized.\r
+ /// </summary>\r
+ /// <param name="c">The streaming context.</param>\r
+ [OnDeserialized]\r
+ public void OnDeserialized(StreamingContext c)\r
+ {\r
+ this.IsNotifying = true;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Used to indicate whether or not the IsNotifying property is serialized to Xml.\r
+ /// </summary>\r
+ /// <returns>\r
+ /// Whether or not to serialize the IsNotifying property. The default is false.\r
+ /// </returns>\r
+ public virtual bool ShouldSerializeIsNotifying()\r
+ {\r
+ return false;\r
}\r
}\r
}\r
using HandBrakeWPF.Services.Interfaces;\r
using HandBrakeWPF.ViewModels.Interfaces;\r
\r
+ using Execute = Caliburn.Micro.Execute;\r
+\r
/// <summary>\r
/// The when done service.\r
/// </summary>\r
using HandBrake.ApplicationServices.Services.Encode.Interfaces;\r
using HandBrake.ApplicationServices.Utilities;\r
\r
+ using Execute = Caliburn.Micro.Execute;\r
using IQueueProcessor = HandBrakeWPF.Services.Interfaces.IQueueProcessor;\r
using QueueCompletedEventArgs = HandBrakeWPF.EventArgs.QueueCompletedEventArgs;\r
using QueueProgressEventArgs = HandBrakeWPF.EventArgs.QueueProgressEventArgs;\r
\r
using Ookii.Dialogs.Wpf;\r
\r
+ using Execute = Caliburn.Micro.Execute;\r
using IQueueProcessor = HandBrakeWPF.Services.Interfaces.IQueueProcessor;\r
\r
/// <summary>\r
\r
using Ookii.Dialogs.Wpf;\r
\r
+ using Execute = Caliburn.Micro.Execute;\r
+\r
/// <summary>\r
/// The Options View Model\r
/// </summary>\r