summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
authorsr55 <[email protected]>2013-02-02 15:12:19 +0000
committersr55 <[email protected]>2013-02-02 15:12:19 +0000
commita7dfaa518ce3aaf73a64ecc3c61a88c9427aef81 (patch)
tree8efccea1be99fb4aca2fe1ad028c395095500675 /win
parentbc3b56381c6ac214b7736a00972c9d0902902453 (diff)
Merging trunk to cl branch.
git-svn-id: svn://svn.handbrake.fr/HandBrake/branches/opencl@5234 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'win')
-rw-r--r--win/CS/HandBrake.ApplicationServices/EventArgs/SettingChangedEventArgs.cs27
-rw-r--r--win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj1
-rw-r--r--win/CS/HandBrake.ApplicationServices/Model/EncodeTask.cs34
-rw-r--r--win/CS/HandBrake.ApplicationServices/Model/Encoding/ChapterMarker.cs14
-rw-r--r--win/CS/HandBrake.ApplicationServices/Model/QueueTask.cs69
-rw-r--r--win/CS/HandBrake.ApplicationServices/Parsing/Parser.cs33
-rw-r--r--win/CS/HandBrake.ApplicationServices/Parsing/Title.cs3
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs134
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/Encode.cs187
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs4
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/Interfaces/IUserSettingService.cs18
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs20
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs13
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/UserSettingService.cs23
-rw-r--r--win/CS/HandBrake.ApplicationServices/Utilities/InteropModelCreator.cs39
-rw-r--r--win/CS/HandBrake.ApplicationServices/Utilities/Win32.cs2
-rw-r--r--win/CS/HandBrake.Interop/HandBrakeInterop/SourceData/Title.cs17
-rw-r--r--win/CS/HandBrakeWPF/Controls/TimeSpanBox.xaml175
-rw-r--r--win/CS/HandBrakeWPF/Controls/TimeSpanBox.xaml.cs721
-rw-r--r--win/CS/HandBrakeWPF/Converters/InverseBooleanConverter.cs81
-rw-r--r--win/CS/HandBrakeWPF/HandBrakeWPF.csproj18
-rw-r--r--win/CS/HandBrakeWPF/Model/SelectionTitle.cs88
-rw-r--r--win/CS/HandBrakeWPF/Properties/Resources.Designer.cs15
-rw-r--r--win/CS/HandBrakeWPF/Properties/Resources.resx9
-rw-r--r--win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs2
-rw-r--r--win/CS/HandBrakeWPF/UserSettingConstants.cs5
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/AdvancedViewModel.cs40
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/ChaptersViewModel.cs2
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/Interfaces/IQueueSelectionViewModel.cs40
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs144
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/PreviewViewModel.cs4
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/QueueSelectionViewModel.cs198
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs55
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs68
-rw-r--r--win/CS/HandBrakeWPF/Views/AddPresetView.xaml.cs4
-rw-r--r--win/CS/HandBrakeWPF/Views/AdvancedView.xaml10
-rw-r--r--win/CS/HandBrakeWPF/Views/AudioView.xaml2
-rw-r--r--win/CS/HandBrakeWPF/Views/ChaptersView.xaml3
-rw-r--r--win/CS/HandBrakeWPF/Views/MainView.xaml31
-rw-r--r--win/CS/HandBrakeWPF/Views/QueueSelectionView.xaml140
-rw-r--r--win/CS/HandBrakeWPF/Views/QueueSelectionView.xaml.cs27
-rw-r--r--win/CS/HandBrakeWPF/Views/QueueView.xaml21
-rw-r--r--win/CS/HandBrakeWPF/Views/SubtitlesView.xaml13
-rw-r--r--win/CS/HandBrakeWPF/Views/TitleSpecificView.xaml10
-rw-r--r--win/CS/HandBrakeWPF/Views/VideoView.xaml87
-rw-r--r--win/CS/HandBrakeWPF/defaultsettings.xml8
-rw-r--r--win/CS/libraries/WPFDragDrop/GongSolutions.Wpf.DragDrop.XML78
-rw-r--r--win/CS/libraries/WPFDragDrop/GongSolutions.Wpf.DragDrop.dllbin31232 -> 34304 bytes
-rw-r--r--win/CS/libraries/WPFDragDrop/GongSolutions.Wpf.DragDrop.pdbbin69120 -> 81408 bytes
-rw-r--r--win/CS/libraries/WPFDragDrop/SourceModifications.zipbin21697 -> 28597 bytes
50 files changed, 2351 insertions, 386 deletions
diff --git a/win/CS/HandBrake.ApplicationServices/EventArgs/SettingChangedEventArgs.cs b/win/CS/HandBrake.ApplicationServices/EventArgs/SettingChangedEventArgs.cs
new file mode 100644
index 000000000..2687508b2
--- /dev/null
+++ b/win/CS/HandBrake.ApplicationServices/EventArgs/SettingChangedEventArgs.cs
@@ -0,0 +1,27 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="SettingChangedEventArgs.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// The setting changed event args.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrake.ApplicationServices.EventArgs
+{
+ /// <summary>
+ /// The setting changed event args.
+ /// </summary>
+ public class SettingChangedEventArgs
+ {
+ /// <summary>
+ /// Gets or sets the key.
+ /// </summary>
+ public string Key { get; set; }
+
+ /// <summary>
+ /// Gets or sets the value.
+ /// </summary>
+ public object Value { get; set; }
+ }
+}
diff --git a/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj b/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj
index 56df4d218..1448380b0 100644
--- a/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj
+++ b/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj
@@ -84,6 +84,7 @@
<ItemGroup>
<Compile Include="Collections\SerializableDictionary.cs" />
<Compile Include="Converters\EnumToDescConverter.cs" />
+ <Compile Include="EventArgs\SettingChangedEventArgs.cs" />
<Compile Include="Exceptions\GeneralApplicationException.cs" />
<Compile Include="EventArgs\EncodeCompletedEventArgs.cs" />
<Compile Include="EventArgs\EncodeProgressEventArgs.cs" />
diff --git a/win/CS/HandBrake.ApplicationServices/Model/EncodeTask.cs b/win/CS/HandBrake.ApplicationServices/Model/EncodeTask.cs
index f9053a8bb..36d416c9d 100644
--- a/win/CS/HandBrake.ApplicationServices/Model/EncodeTask.cs
+++ b/win/CS/HandBrake.ApplicationServices/Model/EncodeTask.cs
@@ -12,6 +12,8 @@ namespace HandBrake.ApplicationServices.Model
using System.Collections.ObjectModel;
using System.Linq;
+ using Caliburn.Micro;
+
using HandBrake.ApplicationServices.Model.Encoding;
using HandBrake.Interop.Model;
using HandBrake.Interop.Model.Encoding;
@@ -22,8 +24,17 @@ namespace HandBrake.ApplicationServices.Model
/// <summary>
/// An Encode Task
/// </summary>
- public class EncodeTask
+ public class EncodeTask : PropertyChangedBase
{
+ #region Private Fields
+
+ /// <summary>
+ /// The advanced panel enabled.
+ /// </summary>
+ private bool showAdvancedTab;
+
+ #endregion
+
/// <summary>
/// Initializes a new instance of the <see cref="EncodeTask"/> class.
/// </summary>
@@ -436,7 +447,7 @@ namespace HandBrake.ApplicationServices.Model
public bool FastDecode { get; set; }
/// <summary>
- /// Extra Advanced Arguments for the Video Tab.
+ /// Gets or sets Extra Advanced Arguments for the Video Tab.
/// </summary>
public string ExtraAdvancedArguments { get; set; }
@@ -493,6 +504,25 @@ namespace HandBrake.ApplicationServices.Model
/// Gets or sets PreviewEncodeStartAt.
/// </summary>
public string PreviewEncodeStartAt { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether advanced panel enabled.
+ /// </summary>
+ public bool ShowAdvancedTab
+ {
+ get
+ {
+ return this.showAdvancedTab;
+ }
+ set
+ {
+ if (!object.Equals(value, this.showAdvancedTab))
+ {
+ this.showAdvancedTab = value;
+ this.NotifyOfPropertyChange(() => this.ShowAdvancedTab);
+ }
+ }
+ }
#endregion
}
}
diff --git a/win/CS/HandBrake.ApplicationServices/Model/Encoding/ChapterMarker.cs b/win/CS/HandBrake.ApplicationServices/Model/Encoding/ChapterMarker.cs
index db3794151..1a20379f4 100644
--- a/win/CS/HandBrake.ApplicationServices/Model/Encoding/ChapterMarker.cs
+++ b/win/CS/HandBrake.ApplicationServices/Model/Encoding/ChapterMarker.cs
@@ -9,6 +9,8 @@
namespace HandBrake.ApplicationServices.Model.Encoding
{
+ using System;
+
using Caliburn.Micro;
/// <summary>
@@ -37,10 +39,14 @@ namespace HandBrake.ApplicationServices.Model.Encoding
/// <param name="name">
/// The name.
/// </param>
- public ChapterMarker(int number, string name)
+ /// <param name="duration">
+ /// The duration.
+ /// </param>
+ public ChapterMarker(int number, string name, TimeSpan duration)
{
this.ChapterName = name;
this.ChapterNumber = number;
+ this.Duration = duration;
}
/// <summary>
@@ -54,6 +60,7 @@ namespace HandBrake.ApplicationServices.Model.Encoding
{
this.ChapterName = chapter.ChapterName;
this.ChapterNumber = chapter.ChapterNumber;
+ this.Duration = chapter.Duration;
}
/// <summary>
@@ -62,6 +69,11 @@ namespace HandBrake.ApplicationServices.Model.Encoding
public int ChapterNumber { get; set; }
/// <summary>
+ /// Gets or sets the duration.
+ /// </summary>
+ public TimeSpan Duration { get; set; }
+
+ /// <summary>
/// Gets or sets ChapterName.
/// </summary>
public string ChapterName
diff --git a/win/CS/HandBrake.ApplicationServices/Model/QueueTask.cs b/win/CS/HandBrake.ApplicationServices/Model/QueueTask.cs
index 15f158381..84e9eee9f 100644
--- a/win/CS/HandBrake.ApplicationServices/Model/QueueTask.cs
+++ b/win/CS/HandBrake.ApplicationServices/Model/QueueTask.cs
@@ -30,6 +30,14 @@ namespace HandBrake.ApplicationServices.Model
#region Properties
/// <summary>
+ /// Initializes a new instance of the <see cref="QueueTask"/> class.
+ /// </summary>
+ public QueueTask()
+ {
+ this.Status = QueueItemStatus.Waiting;
+ }
+
+ /// <summary>
/// Gets or sets ScannedSource.
/// </summary>
public Source ScannedSource { get; set; }
@@ -62,5 +70,66 @@ namespace HandBrake.ApplicationServices.Model
public EncodeTask Task { get; set; }
#endregion
+
+ /// <summary>
+ /// The equals.
+ /// </summary>
+ /// <param name="other">
+ /// The other.
+ /// </param>
+ /// <returns>
+ /// The <see cref="bool"/>.
+ /// </returns>
+ protected bool Equals(QueueTask other)
+ {
+ return Equals(this.ScannedSource, other.ScannedSource) && this.CustomQuery.Equals(other.CustomQuery) && Equals(this.Task, other.Task) && this.status == other.status;
+ }
+
+ /// <summary>
+ /// The equals.
+ /// </summary>
+ /// <param name="obj">
+ /// The obj.
+ /// </param>
+ /// <returns>
+ /// The <see cref="bool"/>.
+ /// </returns>
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj))
+ {
+ return false;
+ }
+
+ if (ReferenceEquals(this, obj))
+ {
+ return true;
+ }
+
+ if (obj.GetType() != this.GetType())
+ {
+ return false;
+ }
+
+ return Equals((QueueTask)obj);
+ }
+
+ /// <summary>
+ /// The get hash code.
+ /// </summary>
+ /// <returns>
+ /// The <see cref="int"/>.
+ /// </returns>
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ int hashCode = (this.ScannedSource != null ? this.ScannedSource.GetHashCode() : 0);
+ hashCode = (hashCode * 397) ^ this.CustomQuery.GetHashCode();
+ hashCode = (hashCode * 397) ^ (this.Task != null ? this.Task.GetHashCode() : 0);
+ hashCode = (hashCode * 397) ^ (int)this.status;
+ return hashCode;
+ }
+ }
}
} \ No newline at end of file
diff --git a/win/CS/HandBrake.ApplicationServices/Parsing/Parser.cs b/win/CS/HandBrake.ApplicationServices/Parsing/Parser.cs
index 7f79e8aec..f17a6a51b 100644
--- a/win/CS/HandBrake.ApplicationServices/Parsing/Parser.cs
+++ b/win/CS/HandBrake.ApplicationServices/Parsing/Parser.cs
@@ -78,10 +78,6 @@ namespace HandBrake.ApplicationServices.Parsing
/// </summary>
public event ScanProgressEventHandler OnScanProgress;
- /// <summary>
- /// Raised upon the catching of a "Scanning title # of #..." in the stream
- /// </summary>
- public event EncodeProgressEventHandler OnEncodeProgress;
/// <summary>
/// Gets the buffer of data that came from the CLI standard input/error
@@ -133,34 +129,5 @@ namespace HandBrake.ApplicationServices.Parsing
return tmp;
}
-
- /// <summary>
- /// Pase the CLI status output (from standard output)
- /// </summary>
- public void ReadEncodeStatus()
- {
- string tmp = base.ReadLine();
-
- Match m = Regex.Match(tmp, @"^Encoding: task ([0-9]*) of ([0-9]*), ([0-9]*\.[0-9]*) %( \(([0-9]*\.[0-9]*) fps, avg ([0-9]*\.[0-9]*) fps, ETA ([0-9]{2})h([0-9]{2})m([0-9]{2})s\))?");
- if (m.Success && OnEncodeProgress != null)
- {
- int currentTask = int.Parse(m.Groups[1].Value);
- int totalTasks = int.Parse(m.Groups[2].Value);
- float percent = float.Parse(m.Groups[3].Value, CultureInfo.InvariantCulture);
- float currentFps = m.Groups[5].Value == string.Empty ? 0.0F : float.Parse(m.Groups[5].Value, CultureInfo.InvariantCulture);
- float avgFps = m.Groups[6].Value == string.Empty ? 0.0F : float.Parse(m.Groups[6].Value, CultureInfo.InvariantCulture);
- string remaining = string.Empty;
- if (m.Groups[7].Value != string.Empty)
- {
- remaining = m.Groups[7].Value + ":" + m.Groups[8].Value + ":" + m.Groups[9].Value;
- }
- if (string.IsNullOrEmpty(remaining))
- {
- remaining = "Calculating ...";
- }
-
- OnEncodeProgress(this, currentTask, totalTasks, percent, currentFps, avgFps, remaining);
- }
- }
}
} \ No newline at end of file
diff --git a/win/CS/HandBrake.ApplicationServices/Parsing/Title.cs b/win/CS/HandBrake.ApplicationServices/Parsing/Title.cs
index 00488eac8..324e97c16 100644
--- a/win/CS/HandBrake.ApplicationServices/Parsing/Title.cs
+++ b/win/CS/HandBrake.ApplicationServices/Parsing/Title.cs
@@ -16,9 +16,6 @@ namespace HandBrake.ApplicationServices.Parsing
using System.Linq;
using System.Text.RegularExpressions;
- using Caliburn.Micro;
-
- using HandBrake.ApplicationServices.Services.Interfaces;
using HandBrake.Interop.Model;
using Size = System.Drawing.Size;
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs b/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs
index 8ef67b28d..866edb794 100644
--- a/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs
+++ b/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs
@@ -10,8 +10,12 @@
namespace HandBrake.ApplicationServices.Services.Base
{
using System;
+ using System.Globalization;
using System.IO;
using System.Text;
+ using System.Text.RegularExpressions;
+
+ using Caliburn.Micro;
using HandBrake.ApplicationServices.EventArgs;
using HandBrake.ApplicationServices.Exceptions;
@@ -148,11 +152,15 @@ namespace HandBrake.ApplicationServices.Services.Base
/// </param>
public void InvokeEncodeStatusChanged(EncodeProgressEventArgs e)
{
- EncodeProgessStatus handler = this.EncodeStatusChanged;
- if (handler != null)
- {
- handler(this, e);
- }
+ Execute.OnUIThread(
+ () =>
+ {
+ EncodeProgessStatus handler = this.EncodeStatusChanged;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ });
}
/// <summary>
@@ -163,11 +171,15 @@ namespace HandBrake.ApplicationServices.Services.Base
/// </param>
public void InvokeEncodeCompleted(EncodeCompletedEventArgs e)
{
- EncodeCompletedStatus handler = this.EncodeCompleted;
- if (handler != null)
- {
- handler(this, e);
- }
+ Execute.OnUIThread(
+ () =>
+ {
+ EncodeCompletedStatus handler = this.EncodeCompleted;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ });
}
/// <summary>
@@ -178,11 +190,14 @@ namespace HandBrake.ApplicationServices.Services.Base
/// </param>
public void InvokeEncodeStarted(EventArgs e)
{
- EventHandler handler = this.EncodeStarted;
- if (handler != null)
- {
- handler(this, e);
- }
+ Execute.OnUIThread(() =>
+ {
+ EventHandler handler = this.EncodeStarted;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ });
}
#endregion
@@ -192,10 +207,7 @@ namespace HandBrake.ApplicationServices.Services.Base
/// <summary>
/// A Stop Method to be implemeneted.
/// </summary>
- /// <param name="exc">
- /// The Exception that occured that required a STOP action.
- /// </param>
- public virtual void Stop(Exception exc)
+ public virtual void Stop()
{
// Do Nothing
}
@@ -249,6 +261,73 @@ namespace HandBrake.ApplicationServices.Services.Base
}
}
+
+ /// <summary>
+ /// Pase the CLI status output (from standard output)
+ /// </summary>
+ /// <param name="encodeStatus">
+ /// The encode Status.
+ /// </param>
+ /// <param name="startTime">
+ /// The start Time.
+ /// </param>
+ /// <returns>
+ /// The <see cref="EncodeProgressEventArgs"/>.
+ /// </returns>
+ public EncodeProgressEventArgs ReadEncodeStatus(string encodeStatus, DateTime startTime)
+ {
+ try
+ {
+ Match m = Regex.Match(
+ encodeStatus,
+ @"^Encoding: task ([0-9]*) of ([0-9]*), ([0-9]*\.[0-9]*) %( \(([0-9]*\.[0-9]*) fps, avg ([0-9]*\.[0-9]*) fps, ETA ([0-9]{2})h([0-9]{2})m([0-9]{2})s\))?");
+
+ if (m.Success)
+ {
+ int currentTask = int.Parse(m.Groups[1].Value);
+ int totalTasks = int.Parse(m.Groups[2].Value);
+ float percent = float.Parse(m.Groups[3].Value, CultureInfo.InvariantCulture);
+ float currentFps = m.Groups[5].Value == string.Empty
+ ? 0.0F
+ : float.Parse(m.Groups[5].Value, CultureInfo.InvariantCulture);
+ float avgFps = m.Groups[6].Value == string.Empty
+ ? 0.0F
+ : float.Parse(m.Groups[6].Value, CultureInfo.InvariantCulture);
+ string remaining = string.Empty;
+ if (m.Groups[7].Value != string.Empty)
+ {
+ remaining = m.Groups[7].Value + ":" + m.Groups[8].Value + ":" + m.Groups[9].Value;
+ }
+ if (string.IsNullOrEmpty(remaining))
+ {
+ remaining = "Calculating ...";
+ }
+
+ EncodeProgressEventArgs eventArgs = new EncodeProgressEventArgs
+ {
+ AverageFrameRate = avgFps,
+ CurrentFrameRate = currentFps,
+ EstimatedTimeLeft =
+ Converters.EncodeToTimespan(
+ remaining),
+ PercentComplete = percent,
+ Task = currentTask,
+ TaskCount = totalTasks,
+ ElapsedTime =
+ DateTime.Now - startTime,
+ };
+
+ return eventArgs;
+ }
+
+ return null;
+ }
+ catch (Exception exc)
+ {
+ return null;
+ }
+ }
+
/// <summary>
/// Setup the logging.
/// </summary>
@@ -286,8 +365,8 @@ namespace HandBrake.ApplicationServices.Services.Base
this.fileWriter = new StreamWriter(logFile) { AutoFlush = true };
this.fileWriter.WriteLine(header);
- this.fileWriter.WriteLine(String.Format("CLI Query: {0}", query));
- this.fileWriter.WriteLine(String.Format("User Query: {0}", encodeQueueTask.CustomQuery));
+ this.fileWriter.WriteLine(string.Format("CLI Query: {0}", query));
+ this.fileWriter.WriteLine(string.Format("User Query: {0}", encodeQueueTask.CustomQuery));
this.fileWriter.WriteLine();
}
catch (Exception)
@@ -324,22 +403,9 @@ namespace HandBrake.ApplicationServices.Services.Base
if (this.fileWriter != null && this.fileWriter.BaseStream.CanWrite)
{
this.fileWriter.WriteLine(message);
-
- // If the logging grows past 100MB, kill the encode and stop.
- if (this.fileWriter.BaseStream.Length > 100000000)
- {
- this.Stop(
- new GeneralApplicationException(
- "The encode has been stopped. The log file has grown to over 100MB which indicates a serious problem has occured with the encode.",
- "Please check the encode log for an indication of what the problem is.", null));
- }
}
}
}
- catch (GeneralApplicationException)
- {
- throw;
- }
catch (Exception exc)
{
// Do Nothing.
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Encode.cs b/win/CS/HandBrake.ApplicationServices/Services/Encode.cs
index c136c18ee..577067050 100644
--- a/win/CS/HandBrake.ApplicationServices/Services/Encode.cs
+++ b/win/CS/HandBrake.ApplicationServices/Services/Encode.cs
@@ -11,18 +11,18 @@ namespace HandBrake.ApplicationServices.Services
{
using System;
using System.Diagnostics;
+ using System.Globalization;
using System.IO;
- using System.Threading;
using System.Windows.Forms;
+ using Caliburn.Micro;
+
using HandBrake.ApplicationServices.EventArgs;
using HandBrake.ApplicationServices.Model;
using HandBrake.ApplicationServices.Services.Base;
using HandBrake.ApplicationServices.Services.Interfaces;
using HandBrake.ApplicationServices.Utilities;
- using Parser = HandBrake.ApplicationServices.Parsing.Parser;
-
/// <summary>
/// Class which handles the CLI
/// </summary>
@@ -36,11 +36,6 @@ namespace HandBrake.ApplicationServices.Services
private readonly IUserSettingService userSettingService;
/// <summary>
- /// Gets The Process Handle
- /// </summary>
- private IntPtr processHandle;
-
- /// <summary>
/// Gets the Process ID
/// </summary>
private int processId;
@@ -55,6 +50,11 @@ namespace HandBrake.ApplicationServices.Services
/// </summary>
private QueueTask currentTask;
+ /// <summary>
+ /// The init shutdown.
+ /// </summary>
+ private bool initShutdown;
+
#endregion
/// <summary>
@@ -66,8 +66,7 @@ namespace HandBrake.ApplicationServices.Services
public Encode(IUserSettingService userSettingService)
: base(userSettingService)
{
- this.userSettingService = userSettingService;
- this.EncodeStarted += this.EncodeEncodeStarted;
+ this.userSettingService = userSettingService;
}
#region Properties
@@ -83,6 +82,7 @@ namespace HandBrake.ApplicationServices.Services
/// <summary>
/// Execute a HandBrakeCLI process.
+ /// This should only be called from the UI thread.
/// </summary>
/// <param name="encodeQueueTask">
/// The encodeQueueTask.
@@ -94,8 +94,6 @@ namespace HandBrake.ApplicationServices.Services
{
try
{
- this.currentTask = encodeQueueTask;
-
if (this.IsEncoding)
{
throw new Exception("HandBrake is already encodeing.");
@@ -103,6 +101,8 @@ namespace HandBrake.ApplicationServices.Services
this.IsEncoding = true;
+ this.currentTask = encodeQueueTask;
+
if (enableLogging)
{
try
@@ -160,8 +160,10 @@ namespace HandBrake.ApplicationServices.Services
this.HbProcess.BeginErrorReadLine();
}
+ this.HbProcess.OutputDataReceived += HbProcess_OutputDataReceived;
+ this.HbProcess.BeginOutputReadLine();
+
this.processId = this.HbProcess.Id;
- this.processHandle = this.HbProcess.Handle;
// Set the process Priority
if (this.processId != -1)
@@ -207,21 +209,9 @@ namespace HandBrake.ApplicationServices.Services
}
/// <summary>
- /// Stop the Encode
- /// </summary>
- public void Stop()
- {
- this.Stop(null);
- }
-
- /// <summary>
/// Kill the CLI process
/// </summary>
- /// <param name="exc">
- /// The Exception that has occured.
- /// This will get bubbled up through the EncodeCompletedEventArgs
- /// </param>
- public override void Stop(Exception exc)
+ public override void Stop()
{
try
{
@@ -234,11 +224,6 @@ namespace HandBrake.ApplicationServices.Services
{
// No need to report anything to the user. If it fails, it's probably already stopped.
}
-
- this.InvokeEncodeCompleted(
- exc == null
- ? new EncodeCompletedEventArgs(true, null, string.Empty)
- : new EncodeCompletedEventArgs(false, exc, "An Unknown Error has occured when trying to Stop this encode."));
}
/// <summary>
@@ -264,25 +249,12 @@ namespace HandBrake.ApplicationServices.Services
/// </param>
private void HbProcessExited(object sender, EventArgs e)
{
- this.IsEncoding = false;
- if (this.WindowsSeven.IsWindowsSeven)
- {
- this.WindowsSeven.SetTaskBarProgressToNoProgress();
- }
-
- if (this.userSettingService.GetUserSetting<bool>(ASUserSettingConstants.PreventSleep))
- {
- Win32.AllowSleep();
- }
+ HbProcess.WaitForExit();
try
{
- // This is just a quick hack to ensure that we are done processing the logging data.
- // Logging data comes in after the exit event has processed sometimes. We should really impliment ISyncronizingInvoke
- // and set the SyncObject on the process. I think this may resolve this properly.
- // For now, just wait 2.5 seconds to let any trailing log messages come in and be processed.
- Thread.Sleep(2500);
this.HbProcess.CancelErrorRead();
+ this.HbProcess.CancelOutputRead();
this.ShutdownFileWriter();
}
catch (Exception exc)
@@ -290,8 +262,22 @@ namespace HandBrake.ApplicationServices.Services
// This exception doesn't warrent user interaction, but it should be logged (TODO)
}
- this.currentTask.Status = QueueItemStatus.Completed;
- this.InvokeEncodeCompleted(new EncodeCompletedEventArgs(true, null, string.Empty));
+ Execute.OnUIThread(() =>
+ {
+ if (this.WindowsSeven.IsWindowsSeven)
+ {
+ this.WindowsSeven.SetTaskBarProgressToNoProgress();
+ }
+
+ if (this.userSettingService.GetUserSetting<bool>(ASUserSettingConstants.PreventSleep))
+ {
+ Win32.AllowSleep();
+ }
+
+ this.currentTask.Status = QueueItemStatus.Completed;
+ this.IsEncoding = false;
+ this.InvokeEncodeCompleted(new EncodeCompletedEventArgs(true, null, string.Empty));
+ });
}
/// <summary>
@@ -303,88 +289,69 @@ namespace HandBrake.ApplicationServices.Services
/// <param name="e">
/// DataReceived EventArgs
/// </param>
+ /// <remarks>
+ /// Worker Thread.
+ /// </remarks>
private void HbProcErrorDataReceived(object sender, DataReceivedEventArgs e)
{
if (!String.IsNullOrEmpty(e.Data))
{
+ if (initShutdown && this.LogBuffer.Length < 25000000)
+ {
+ initShutdown = false; // Reset this flag.
+ }
+
+ if (this.LogBuffer.Length > 25000000 && !initShutdown) // Approx 23.8MB and make sure it's only printed once
+ {
+ this.ProcessLogMessage("ERROR: Initiating automatic shutdown of encode process. The size of the log file inidcates that there is an error! ");
+ initShutdown = true;
+ this.Stop();
+ }
+
this.ProcessLogMessage(e.Data);
}
}
/// <summary>
- /// Encode Started
+ /// The hb process output data received.
/// </summary>
/// <param name="sender">
/// The sender.
/// </param>
/// <param name="e">
- /// The EventArgs.
+ /// The e.
/// </param>
- private void EncodeEncodeStarted(object sender, EventArgs e)
+ private void HbProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
- Thread monitor = new Thread(this.EncodeMonitor);
- monitor.Start();
- }
-
- /// <summary>
- /// Monitor the QueueTask
- /// </summary>
- private void EncodeMonitor()
- {
- try
+ if (!String.IsNullOrEmpty(e.Data) && this.IsEncoding)
{
- Parser encode = new Parser(this.HbProcess.StandardOutput.BaseStream);
- encode.OnEncodeProgress += this.EncodeOnEncodeProgress;
- while (!encode.EndOfStream)
+ EncodeProgressEventArgs eventArgs = this.ReadEncodeStatus(e.Data, this.startTime);
+ if (eventArgs != null)
{
- encode.ReadEncodeStatus();
+ Execute.OnUIThread(
+ () =>
+ {
+ if (!this.IsEncoding)
+ {
+ // We can get events out of order since the CLI progress is monitored on a background thread.
+ // So make sure we don't send a status update after an encode complete event.
+ return;
+ }
+
+ this.InvokeEncodeStatusChanged(eventArgs);
+
+ if (this.WindowsSeven.IsWindowsSeven)
+ {
+ int percent;
+ int.TryParse(
+ Math.Round(eventArgs.PercentComplete).ToString(CultureInfo.InvariantCulture),
+ out percent);
+
+ this.WindowsSeven.SetTaskBarProgress(percent);
+ }
+ });
}
}
- catch (Exception)
- {
- this.EncodeOnEncodeProgress(null, 0, 0, 0, 0, 0, "Unknown, status not available..");
- }
- }
-
- /// <summary>
- /// Displays the Encode status in the GUI
- /// </summary>
- /// <param name="sender">The sender</param>
- /// <param name="currentTask">The current task</param>
- /// <param name="taskCount">Number of tasks</param>
- /// <param name="percentComplete">Percent complete</param>
- /// <param name="currentFps">Current encode speed in fps</param>
- /// <param name="avg">Avg encode speed</param>
- /// <param name="timeRemaining">Time Left</param>
- private void EncodeOnEncodeProgress(object sender, int currentTask, int taskCount, float percentComplete, float currentFps, float avg, string timeRemaining)
- {
- if (!this.IsEncoding)
- {
- // We can get events out of order since the CLI progress is monitored on a background thread.
- // So make sure we don't send a status update after an encode complete event.
- return;
- }
-
- EncodeProgressEventArgs eventArgs = new EncodeProgressEventArgs
- {
- AverageFrameRate = avg,
- CurrentFrameRate = currentFps,
- EstimatedTimeLeft = Converters.EncodeToTimespan(timeRemaining),
- PercentComplete = percentComplete,
- Task = currentTask,
- TaskCount = taskCount,
- ElapsedTime = DateTime.Now - this.startTime,
- };
-
- this.InvokeEncodeStatusChanged(eventArgs);
-
- if (this.WindowsSeven.IsWindowsSeven)
- {
- int percent;
- int.TryParse(Math.Round(percentComplete).ToString(), out percent);
-
- this.WindowsSeven.SetTaskBarProgress(percent);
- }
}
#endregion
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs
index 0a952e516..b4c8872c0 100644
--- a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs
+++ b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs
@@ -10,7 +10,7 @@
namespace HandBrake.ApplicationServices.Services.Interfaces
{
using System;
- using System.Collections.ObjectModel;
+ using System.ComponentModel;
using HandBrake.ApplicationServices.Model;
@@ -70,7 +70,7 @@ namespace HandBrake.ApplicationServices.Services.Interfaces
/// <summary>
/// Gets The current queue.
/// </summary>
- ObservableCollection<QueueTask> Queue { get; }
+ BindingList<QueueTask> Queue { get; }
#endregion
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IUserSettingService.cs b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IUserSettingService.cs
index d7bba9550..bf6cb9c91 100644
--- a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IUserSettingService.cs
+++ b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IUserSettingService.cs
@@ -9,12 +9,30 @@
namespace HandBrake.ApplicationServices.Services.Interfaces
{
+ using HandBrake.ApplicationServices.EventArgs;
+
+ /// <summary>
+ /// The setting event handler.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ public delegate void SettingEventHandler(object sender, SettingChangedEventArgs e);
+
/// <summary>
/// The User Setting Service Interace.
/// </summary>
public interface IUserSettingService
{
/// <summary>
+ /// The setting changed.
+ /// </summary>
+ event SettingEventHandler SettingChanged;
+
+ /// <summary>
/// Set the specified user setting.
/// </summary>
/// <param name="name">
diff --git a/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs b/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs
index 64d604a34..320b96f1b 100644
--- a/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs
+++ b/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs
@@ -12,7 +12,6 @@ namespace HandBrake.ApplicationServices.Services
using System;
using System.Diagnostics;
- using HandBrake.ApplicationServices.Exceptions;
using HandBrake.ApplicationServices.Model;
using HandBrake.ApplicationServices.Services.Base;
using HandBrake.ApplicationServices.Services.Interfaces;
@@ -169,19 +168,7 @@ namespace HandBrake.ApplicationServices.Services
/// <summary>
/// Kill the CLI process
/// </summary>
- public void Stop()
- {
- this.Stop(null);
- }
-
- /// <summary>
- /// Kill the CLI process
- /// </summary>
- /// <param name="exc">
- /// The Exception that has occured.
- /// This will get bubbled up through the EncodeCompletedEventArgs
- /// </param>
- public override void Stop(Exception exc)
+ public override void Stop()
{
try
{
@@ -192,11 +179,6 @@ namespace HandBrake.ApplicationServices.Services
{
// Do Nothing.
}
-
- this.InvokeEncodeCompleted(
- exc == null
- ? new EncodeCompletedEventArgs(true, null, string.Empty)
- : new EncodeCompletedEventArgs(false, exc, "An Error has occured."));
}
/// <summary>
diff --git a/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs b/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs
index 7aefd285f..172fe7291 100644
--- a/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs
+++ b/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs
@@ -11,7 +11,7 @@ namespace HandBrake.ApplicationServices.Services
{
using System;
using System.Collections.Generic;
- using System.Collections.ObjectModel;
+ using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -41,7 +41,7 @@ namespace HandBrake.ApplicationServices.Services
/// <summary>
/// The Queue of Job objects
/// </summary>
- private readonly ObservableCollection<QueueTask> queue = new ObservableCollection<QueueTask>();
+ private readonly BindingList<QueueTask> queue = new BindingList<QueueTask>();
/// <summary>
/// The User Setting Service
@@ -152,7 +152,7 @@ namespace HandBrake.ApplicationServices.Services
/// <summary>
/// Gets The current queue.
/// </summary>
- public ObservableCollection<QueueTask> Queue
+ public BindingList<QueueTask> Queue
{
get
{
@@ -595,13 +595,6 @@ namespace HandBrake.ApplicationServices.Services
/// </summary>
private void ProcessNextJob()
{
- if (this.EncodeService.IsEncoding || !this.IsProcessing)
- {
- // We don't want to try start a second encode, so just return out. The event will trigger the next encode automatically.
- // Also, we don't want to start a new encode if we are paused.
- return;
- }
-
QueueTask job = this.GetNextJobForProcessing();
if (job != null)
{
diff --git a/win/CS/HandBrake.ApplicationServices/Services/UserSettingService.cs b/win/CS/HandBrake.ApplicationServices/Services/UserSettingService.cs
index ab77ce800..db7389637 100644
--- a/win/CS/HandBrake.ApplicationServices/Services/UserSettingService.cs
+++ b/win/CS/HandBrake.ApplicationServices/Services/UserSettingService.cs
@@ -16,6 +16,7 @@ namespace HandBrake.ApplicationServices.Services
using System.Xml.Serialization;
using HandBrake.ApplicationServices.Collections;
+ using HandBrake.ApplicationServices.EventArgs;
using HandBrake.ApplicationServices.Exceptions;
using HandBrake.ApplicationServices.Services.Interfaces;
@@ -48,6 +49,11 @@ namespace HandBrake.ApplicationServices.Services
}
/// <summary>
+ /// The setting changed.
+ /// </summary>
+ public event SettingEventHandler SettingChanged;
+
+ /// <summary>
/// Set the specified user setting.
/// </summary>
/// <param name="name">
@@ -60,6 +66,8 @@ namespace HandBrake.ApplicationServices.Services
{
this.userSettings[name] = value;
this.Save();
+
+ this.OnSettingChanged(new SettingChangedEventArgs {Key = name, Value = value});
}
/// <summary>
@@ -99,6 +107,21 @@ namespace HandBrake.ApplicationServices.Services
}
/// <summary>
+ /// The on setting changed.
+ /// </summary>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ protected virtual void OnSettingChanged(SettingChangedEventArgs e)
+ {
+ SettingEventHandler handler = this.SettingChanged;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ }
+
+ /// <summary>
/// Save the User Settings
/// </summary>
private void Save()
diff --git a/win/CS/HandBrake.ApplicationServices/Utilities/InteropModelCreator.cs b/win/CS/HandBrake.ApplicationServices/Utilities/InteropModelCreator.cs
index 618dd43cc..63a98abe4 100644
--- a/win/CS/HandBrake.ApplicationServices/Utilities/InteropModelCreator.cs
+++ b/win/CS/HandBrake.ApplicationServices/Utilities/InteropModelCreator.cs
@@ -23,10 +23,6 @@ namespace HandBrake.ApplicationServices.Utilities
/// </summary>
public class InteropModelCreator
{
- /*
- * TODO: This conversion class needs to be finished off before libencode will work.
- */
-
/// <summary>
/// Get an EncodeJob model for a LibHB Encode.
/// </summary>
@@ -182,12 +178,37 @@ namespace HandBrake.ApplicationServices.Utilities
// job.SourceType = work.Type;
job.Title = work.Title;
- // TODO Setup subtitles
+ // Subtitles
job.Subtitles = new Subtitles { SourceSubtitles = new List<SourceSubtitle>(), SrtSubtitles = new List<SrtSubtitle>() };
- //foreach (SubtitleTrack track in work.SubtitleTracks)
- //{
- // // TODO
- //}
+ foreach (SubtitleTrack track in work.SubtitleTracks)
+ {
+ if (track.IsSrtSubtitle)
+ {
+ job.Subtitles.SrtSubtitles.Add(
+ new SrtSubtitle
+ {
+ CharacterCode = track.SrtCharCode,
+ Default = track.Default,
+ FileName = track.SrtFileName,
+ LanguageCode = track.SrtLang,
+ Offset = track.SrtOffset
+ });
+ }
+ else
+ {
+ if (track.SourceTrack != null)
+ {
+ job.Subtitles.SourceSubtitles.Add(
+ new SourceSubtitle
+ {
+ BurnedIn = track.Burned,
+ Default = track.Default,
+ Forced = track.Forced,
+ TrackNumber = track.SourceTrack.TrackNumber
+ });
+ }
+ }
+ }
return job;
}
diff --git a/win/CS/HandBrake.ApplicationServices/Utilities/Win32.cs b/win/CS/HandBrake.ApplicationServices/Utilities/Win32.cs
index acc8948a1..81d4846ec 100644
--- a/win/CS/HandBrake.ApplicationServices/Utilities/Win32.cs
+++ b/win/CS/HandBrake.ApplicationServices/Utilities/Win32.cs
@@ -168,7 +168,7 @@ namespace HandBrake.ApplicationServices.Utilities
/// </summary>
public static void AllowSleep()
{
- SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS);
+ executor(() => SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS));
}
/// <summary>
diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/SourceData/Title.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/SourceData/Title.cs
index 344759c1d..fbe8e8532 100644
--- a/win/CS/HandBrake.Interop/HandBrakeInterop/SourceData/Title.cs
+++ b/win/CS/HandBrake.Interop/HandBrakeInterop/SourceData/Title.cs
@@ -19,9 +19,20 @@ namespace HandBrake.Interop.SourceData
/// </summary>
public class Title
{
- private readonly List<AudioTrack> audioTracks;
- private readonly List<Chapter> chapters;
- private readonly List<Subtitle> subtitles;
+ /// <summary>
+ /// The audio tracks.
+ /// </summary>
+ private readonly List<AudioTrack> audioTracks;
+
+ /// <summary>
+ /// The chapters.
+ /// </summary>
+ private readonly List<Chapter> chapters;
+
+ /// <summary>
+ /// The subtitles.
+ /// </summary>
+ private readonly List<Subtitle> subtitles;
/// <summary>
/// Initializes a new instance of the Title class.
diff --git a/win/CS/HandBrakeWPF/Controls/TimeSpanBox.xaml b/win/CS/HandBrakeWPF/Controls/TimeSpanBox.xaml
new file mode 100644
index 000000000..3fdc8d22f
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Controls/TimeSpanBox.xaml
@@ -0,0 +1,175 @@
+<UserControl x:Class="HandBrakeWPF.Controls.TimeSpanBox"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ Loaded="UserControl_Loaded">
+ <UserControl.Resources>
+ <Style x:Key="Arrow" TargetType="Polygon">
+ <Setter Property="Fill" Value="#333" />
+ </Style>
+ <!-- UpButton and DownButton are identical except for the border radius in the control template.
+ We can't pass that through so we need to duplicate the template. After a change is made from one button
+ template it should be copied to the other. -->
+ <Style x:Key="UpButton" TargetType="Button">
+ <Setter Property="Margin" Value="0"/>
+ <Setter Property="Background" >
+ <Setter.Value>
+ <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" >
+ <GradientStop Color="#EEE" Offset="0.4"/>
+ <GradientStop Color="#BBB" Offset="1"/>
+ </LinearGradientBrush>
+ </Setter.Value>
+ </Setter>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="Button">
+ <Border
+ Name="border"
+ BorderThickness="1"
+ BorderBrush="#888"
+ CornerRadius="0,2,0,0"
+ Background="{TemplateBinding Background}">
+ <ContentPresenter
+ Name="content"
+ HorizontalAlignment="Center" VerticalAlignment="Center" />
+ </Border>
+ <ControlTemplate.Triggers>
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter TargetName="border" Property="BorderBrush" Value="#FF4788c8" />
+ <Setter Property="Foreground" Value="#FF4788c8" />
+ </Trigger>
+ <Trigger Property="IsPressed" Value="True">
+ <Setter Property="Background" >
+ <Setter.Value>
+ <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" >
+ <GradientStop Color="#CCC" Offset="0.4"/>
+ <GradientStop Color="#999" Offset="1"/>
+ </LinearGradientBrush>
+ </Setter.Value>
+ </Setter>
+ <Setter TargetName="content" Property="RenderTransform" >
+ <Setter.Value>
+ <TranslateTransform Y="1.0" />
+ </Setter.Value>
+ </Setter>
+ </Trigger>
+ <Trigger Property="IsDefaulted" Value="True">
+ <Setter TargetName="border" Property="BorderBrush" Value="#FF282828" />
+ </Trigger>
+ <Trigger Property="IsFocused" Value="True">
+ <Setter TargetName="border" Property="BorderBrush" Value="#FF282828" />
+ </Trigger>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter TargetName="border" Property="Opacity" Value="0.7" />
+ <Setter Property="Foreground" Value="Gray" />
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+ <Style x:Key="DownButton" TargetType="Button">
+ <Setter Property="Margin" Value="0"/>
+ <Setter Property="Background" >
+ <Setter.Value>
+ <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" >
+ <GradientStop Color="#EEE" Offset="0.4"/>
+ <GradientStop Color="#BBB" Offset="1"/>
+ </LinearGradientBrush>
+ </Setter.Value>
+ </Setter>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="Button">
+ <Border
+ Name="border"
+ BorderThickness="1"
+ BorderBrush="#888"
+ CornerRadius="0,0,2,0"
+ Background="{TemplateBinding Background}">
+ <ContentPresenter
+ Name="content"
+ HorizontalAlignment="Center" VerticalAlignment="Center" />
+ </Border>
+ <ControlTemplate.Triggers>
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter TargetName="border" Property="BorderBrush" Value="#FF4788c8" />
+ <Setter Property="Foreground" Value="#FF4788c8" />
+ </Trigger>
+ <Trigger Property="IsPressed" Value="True">
+ <Setter Property="Background" >
+ <Setter.Value>
+ <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" >
+ <GradientStop Color="#CCC" Offset="0.4"/>
+ <GradientStop Color="#999" Offset="1"/>
+ </LinearGradientBrush>
+ </Setter.Value>
+ </Setter>
+ <Setter TargetName="content" Property="RenderTransform" >
+ <Setter.Value>
+ <TranslateTransform Y="1.0" />
+ </Setter.Value>
+ </Setter>
+ </Trigger>
+ <Trigger Property="IsDefaulted" Value="True">
+ <Setter TargetName="border" Property="BorderBrush" Value="#FF282828" />
+ </Trigger>
+ <Trigger Property="IsFocused" Value="True">
+ <Setter TargetName="border" Property="BorderBrush" Value="#FF282828" />
+ </Trigger>
+ <Trigger Property="IsEnabled" Value="False">
+ <Setter TargetName="border" Property="Opacity" Value="0.7" />
+ <Setter Property="Foreground" Value="Gray" />
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+ </UserControl.Resources>
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+ <TextBox
+ Name="numberBox"
+ Grid.Column="0"
+ GotFocus="NumberBoxGotFocus"
+ LostFocus="NumberBoxLostFocus"
+ PreviewTextInput="NumberBoxPreviewTextInput"
+ PreviewKeyDown="NumberBoxPreviewKeyDown"
+ PreviewMouseDown="NumberBoxPreviewMouseDown"
+ PreviewMouseUp="NumberBoxPreviewMouseUp"
+ TextChanged="NumberBoxTextChanged"
+ VerticalContentAlignment="Center"/>
+ <Grid
+ Name="incrementButtonsGrid"
+ Grid.Column="1"
+ Width="16">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="*" />
+ <RowDefinition Height="*" />
+ </Grid.RowDefinitions>
+ <Button
+ Style="{StaticResource UpButton}"
+ Grid.Row="0"
+ FontSize="4"
+ PreviewMouseLeftButtonDown="UpButtonMouseLeftButtonDown"
+ PreviewMouseLeftButtonUp="UpButtonMouseLeftButtonUp">
+ <Polygon
+ Style="{StaticResource Arrow}"
+ Points="4,0 0,4 8,4" />
+ </Button>
+ <Button
+ Style="{StaticResource DownButton}"
+ Grid.Row="1"
+ FontSize="4"
+ PreviewMouseLeftButtonDown="DownButtonMouseLeftButtonDown"
+ PreviewMouseLeftButtonUp="DownButtonMouseLeftButtonUp">
+ <Polygon
+ Style="{StaticResource Arrow}"
+ Points="0,0 8,0 4,4" />
+ </Button>
+ </Grid>
+ </Grid>
+</UserControl>
diff --git a/win/CS/HandBrakeWPF/Controls/TimeSpanBox.xaml.cs b/win/CS/HandBrakeWPF/Controls/TimeSpanBox.xaml.cs
new file mode 100644
index 000000000..5f983a699
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Controls/TimeSpanBox.xaml.cs
@@ -0,0 +1,721 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="TimeSpanBox.xaml.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Interaction logic for TimeSpanBox.xaml
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Controls
+{
+ using System;
+ using System.Globalization;
+ using System.Linq;
+ using System.Windows;
+ using System.Windows.Controls;
+ using System.Windows.Input;
+ using System.Windows.Media;
+
+ /// <summary>
+ /// Interaction logic for TimeSpanBox.xaml
+ /// </summary>
+ public partial class TimeSpanBox
+ {
+ #region Constants and Fields
+
+ /// <summary>
+ /// The maximum property name.
+ /// </summary>
+ public const string MaximumPropertyName = "Maximum";
+
+ /// <summary>
+ /// The minimum property name.
+ /// </summary>
+ public const string MinimumPropertyName = "Minimum";
+
+ /// <summary>
+ /// The modulus property name.
+ /// </summary>
+ public const string ModulusPropertyName = "Modulus";
+
+ /// <summary>
+ /// The allow empty property.
+ /// </summary>
+ public static readonly DependencyProperty AllowEmptyProperty = DependencyProperty.Register(
+ "AllowEmpty", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(true, OnAllowEmptyChanged));
+
+ /// <summary>
+ /// The maximum property.
+ /// </summary>
+ public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register(
+ MaximumPropertyName, typeof(int), typeof(TimeSpanBox), new UIPropertyMetadata(int.MaxValue));
+
+ /// <summary>
+ /// The minimum property.
+ /// </summary>
+ public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register(
+ MinimumPropertyName, typeof(int), typeof(TimeSpanBox), new UIPropertyMetadata(int.MinValue));
+
+ /// <summary>
+ /// The modulus property.
+ /// </summary>
+ public static readonly DependencyProperty ModulusProperty = DependencyProperty.Register(
+ ModulusPropertyName, typeof(int), typeof(TimeSpanBox), new UIPropertyMetadata(0));
+
+ /// <summary>
+ /// The number property.
+ /// </summary>
+ public static readonly DependencyProperty NumberProperty = DependencyProperty.Register(
+ "Number", typeof(int), typeof(TimeSpanBox), new PropertyMetadata(OnNumberChanged));
+
+ /// <summary>
+ /// The show time span property.
+ /// </summary>
+ public static readonly DependencyProperty ShowTimeSpanProperty = DependencyProperty.Register(
+ "ShowTimeSpan", typeof(bool), typeof(TimeSpanBox), new PropertyMetadata(OnShowTimeSpanChanged));
+
+ /// <summary>
+ /// The select all threshold.
+ /// </summary>
+ private static readonly TimeSpan SelectAllThreshold = TimeSpan.FromMilliseconds(500);
+
+ /// <summary>
+ /// The has focus.
+ /// </summary>
+ private bool hasFocus;
+
+ /// <summary>
+ /// The last focus mouse down.
+ /// </summary>
+ private DateTime lastFocusMouseDown;
+
+ /// <summary>
+ /// The none caption.
+ /// </summary>
+ private string noneCaption;
+
+ /// <summary>
+ /// The refire control.
+ /// </summary>
+ private RefireControl refireControl;
+
+ /// <summary>
+ /// The suppress refresh.
+ /// </summary>
+ private bool suppressRefresh;
+
+ #endregion
+
+ #region Constructors and Destructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TimeSpanBox"/> class.
+ /// </summary>
+ public TimeSpanBox()
+ {
+ this.noneCaption = "(none)";
+ this.UpdateBindingOnTextChange = true;
+ this.ShowIncrementButtons = true;
+ this.SelectAllOnClick = true;
+
+ this.InitializeComponent();
+
+ this.RefreshNumberBox();
+ }
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets or sets a value indicating whether show time span.
+ /// </summary>
+ public bool ShowTimeSpan
+ {
+ get
+ {
+ return (bool)this.GetValue(ShowTimeSpanProperty);
+ }
+
+ set
+ {
+ this.SetValue(ShowTimeSpanProperty, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether allow empty.
+ /// </summary>
+ public bool AllowEmpty
+ {
+ get
+ {
+ return (bool)this.GetValue(AllowEmptyProperty);
+ }
+
+ set
+ {
+ this.SetValue(AllowEmptyProperty, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the maximum.
+ /// </summary>
+ public int Maximum
+ {
+ get
+ {
+ return (int)this.GetValue(MaximumProperty);
+ }
+ set
+ {
+ this.SetValue(MaximumProperty, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the minimum.
+ /// </summary>
+ public int Minimum
+ {
+ get
+ {
+ return (int)this.GetValue(MinimumProperty);
+ }
+ set
+ {
+ this.SetValue(MinimumProperty, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the modulus.
+ /// </summary>
+ public int Modulus
+ {
+ get
+ {
+ return (int)this.GetValue(ModulusProperty);
+ }
+ set
+ {
+ this.SetValue(ModulusProperty, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the none caption.
+ /// </summary>
+ public string NoneCaption
+ {
+ get
+ {
+ return this.noneCaption;
+ }
+
+ set
+ {
+ this.noneCaption = value;
+ this.RefreshNumberBox();
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the number.
+ /// </summary>
+ public int Number
+ {
+ get
+ {
+ return (int)this.GetValue(NumberProperty);
+ }
+
+ set
+ {
+ this.SetValue(NumberProperty, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether select all on click.
+ /// </summary>
+ public bool SelectAllOnClick { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether show increment buttons.
+ /// </summary>
+ public bool ShowIncrementButtons { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether update binding on text change.
+ /// </summary>
+ public bool UpdateBindingOnTextChange { get; set; }
+
+ /// <summary>
+ /// Gets the increment.
+ /// </summary>
+ private int Increment
+ {
+ get
+ {
+ return this.Modulus > 0 ? this.Modulus : 1;
+ }
+ }
+
+ #endregion
+
+ #region Methods
+
+ /// <summary>
+ /// The on allow empty changed.
+ /// </summary>
+ /// <param name="dependencyObject">
+ /// The dependency object.
+ /// </param>
+ /// <param name="eventArgs">
+ /// The event args.
+ /// </param>
+ private static void OnAllowEmptyChanged(
+ DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs)
+ {
+ var numBox = dependencyObject as TimeSpanBox;
+ if (numBox != null)
+ {
+ numBox.RefreshNumberBox();
+ }
+ }
+
+ /// <summary>
+ /// The on number changed.
+ /// </summary>
+ /// <param name="dependencyObject">
+ /// The dependency object.
+ /// </param>
+ /// <param name="eventArgs">
+ /// The event args.
+ /// </param>
+ private static void OnNumberChanged(
+ DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs)
+ {
+ if (eventArgs.NewValue != eventArgs.OldValue)
+ {
+ var numBox = dependencyObject as TimeSpanBox;
+
+ if (!numBox.suppressRefresh)
+ {
+ numBox.RefreshNumberBox();
+ }
+ }
+ }
+
+ /// <summary>
+ /// The on show timespan number changed.
+ /// </summary>
+ /// <param name="dependencyObject">
+ /// The dependency object.
+ /// </param>
+ /// <param name="eventArgs">
+ /// The event args.
+ /// </param>
+ private static void OnShowTimeSpanChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs)
+ {
+ if (eventArgs.NewValue != eventArgs.OldValue)
+ {
+ var numBox = dependencyObject as TimeSpanBox;
+
+ if (!numBox.suppressRefresh)
+ {
+ numBox.RefreshNumberBox();
+ }
+ }
+ }
+
+ /// <summary>
+ /// The decrement number.
+ /// </summary>
+ private void DecrementNumber()
+ {
+ int newNumber;
+ if (this.AllowEmpty && this.Number == 0)
+ {
+ newNumber = Math.Min(this.Maximum, -this.Increment);
+ }
+ else
+ {
+ newNumber = this.Number - this.Increment;
+ }
+
+ if (newNumber < this.Minimum)
+ {
+ newNumber = this.Minimum;
+ }
+
+ if (newNumber != this.Number)
+ {
+ this.Number = newNumber;
+ }
+ }
+
+ /// <summary>
+ /// The down button mouse left button down.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void DownButtonMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+ {
+ this.refireControl = new RefireControl(this.DecrementNumber);
+ this.refireControl.Begin();
+ }
+
+ /// <summary>
+ /// The down button mouse left button up.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void DownButtonMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+ {
+ this.refireControl.Stop();
+ }
+
+ /// <summary>
+ /// The get nearest value.
+ /// </summary>
+ /// <param name="number">
+ /// The number.
+ /// </param>
+ /// <param name="modulus">
+ /// The modulus.
+ /// </param>
+ /// <returns>
+ /// The <see cref="double"/>.
+ /// </returns>
+ private int GetNearestValue(int number, int modulus)
+ {
+ int remainder = number % modulus;
+
+ if (remainder == 0)
+ {
+ return number;
+ }
+
+ return remainder >= (modulus / 2) ? number + (modulus - remainder) : number - remainder;
+ }
+
+ /// <summary>
+ /// The increment number.
+ /// </summary>
+ private void IncrementNumber()
+ {
+ int newNumber;
+ if (this.AllowEmpty && this.Number == 0)
+ {
+ newNumber = Math.Max(this.Minimum, this.Increment);
+ }
+ else
+ {
+ newNumber = this.Number + this.Increment;
+ }
+
+ if (newNumber > this.Maximum)
+ {
+ newNumber = this.Maximum;
+ }
+
+ if (newNumber != this.Number)
+ {
+ this.Number = newNumber;
+ }
+ }
+
+ /// <summary>
+ /// The number box got focus.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void NumberBoxGotFocus(object sender, RoutedEventArgs e)
+ {
+ this.hasFocus = true;
+
+ if (this.AllowEmpty)
+ {
+ if (this.Number == 0)
+ {
+ this.numberBox.Text = string.Empty;
+ }
+
+ this.numberBox.Foreground = new SolidColorBrush(Colors.Black);
+ }
+ }
+
+ /// <summary>
+ /// The number box lost focus.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void NumberBoxLostFocus(object sender, RoutedEventArgs e)
+ {
+ this.hasFocus = false;
+
+ if (this.AllowEmpty && this.numberBox.Text == string.Empty)
+ {
+ this.Number = 0;
+ this.RefreshNumberBox();
+ return;
+ }
+
+ this.UpdateNumberBindingFromBox();
+ this.RefreshNumberBox();
+ }
+
+ /// <summary>
+ /// The number box preview key down.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void NumberBoxPreviewKeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Space)
+ {
+ e.Handled = true;
+ }
+ }
+
+ /// <summary>
+ /// The number box preview mouse down.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void NumberBoxPreviewMouseDown(object sender, MouseButtonEventArgs e)
+ {
+ if (!this.hasFocus)
+ {
+ this.lastFocusMouseDown = DateTime.Now;
+ }
+ }
+
+ /// <summary>
+ /// The number box preview mouse up.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void NumberBoxPreviewMouseUp(object sender, MouseButtonEventArgs e)
+ {
+ // If this mouse up is soon enough after an initial click on the box, select all.
+ if (this.SelectAllOnClick && DateTime.Now - this.lastFocusMouseDown < SelectAllThreshold)
+ {
+ this.Dispatcher.BeginInvoke(new Action(() => this.numberBox.SelectAll()));
+ }
+ }
+
+ /// <summary>
+ /// The number box preview text input.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void NumberBoxPreviewTextInput(object sender, TextCompositionEventArgs e)
+ {
+ if (e.Text.Any(c => !char.IsNumber(c) && c != '.' && c != ':' && (this.Minimum >= 0 || c != '-')))
+ {
+ e.Handled = true;
+ }
+ }
+
+ /// <summary>
+ /// The number box text changed.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void NumberBoxTextChanged(object sender, TextChangedEventArgs e)
+ {
+ if (this.UpdateBindingOnTextChange)
+ {
+ if (this.AllowEmpty && this.numberBox.Text == string.Empty)
+ {
+ this.Number = 0;
+ return;
+ }
+
+ this.UpdateNumberBindingFromBox();
+ }
+
+ this.RefreshNumberBoxColor();
+ }
+
+ /// <summary>
+ /// The number is valid.
+ /// </summary>
+ /// <param name="number">
+ /// The number.
+ /// </param>
+ /// <returns>
+ /// The <see cref="bool"/>.
+ /// </returns>
+ private bool NumberIsValid(double number)
+ {
+ return number >= this.Minimum && number <= this.Maximum;
+ }
+
+ /// <summary>
+ /// The refresh number box.
+ /// </summary>
+ private void RefreshNumberBox()
+ {
+ if (this.AllowEmpty && this.Number == 0)
+ {
+ this.numberBox.Text = this.hasFocus ? string.Empty : this.NoneCaption;
+
+ // this.numberBox.Foreground = new SolidColorBrush(Colors.Gray);
+ }
+ else
+ {
+ if (this.ShowTimeSpan)
+ {
+ this.numberBox.Text = TimeSpan.FromSeconds(this.Number).ToString();
+ }
+ else
+ {
+ this.numberBox.Text = this.Number.ToString(CultureInfo.InvariantCulture);
+ }
+
+ // this.numberBox.Foreground = new SolidColorBrush(Colors.Black);
+ }
+
+ this.RefreshNumberBoxColor();
+ }
+
+ /// <summary>
+ /// The refresh number box color.
+ /// </summary>
+ private void RefreshNumberBoxColor()
+ {
+ this.numberBox.Foreground = this.numberBox.Text == this.NoneCaption ? new SolidColorBrush(Colors.Gray) : new SolidColorBrush(Colors.Black);
+ }
+
+ /// <summary>
+ /// The up button mouse left button down.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void UpButtonMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+ {
+ this.refireControl = new RefireControl(this.IncrementNumber);
+ this.refireControl.Begin();
+ }
+
+ /// <summary>
+ /// The up button mouse left button up.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void UpButtonMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+ {
+ this.refireControl.Stop();
+ }
+
+ /// <summary>
+ /// The update number binding from box.
+ /// </summary>
+ private void UpdateNumberBindingFromBox()
+ {
+ int newNumber;
+ TimeSpan newTimespanNumber;
+ if (int.TryParse(this.numberBox.Text, out newNumber))
+ {
+ if (this.NumberIsValid(newNumber))
+ {
+ if (this.Modulus != 0)
+ {
+ newNumber = this.GetNearestValue(newNumber, this.Modulus);
+ }
+
+ if (newNumber != this.Number)
+ {
+ // While updating the binding we don't need to react to the change.
+ this.suppressRefresh = true;
+ this.Number = newNumber;
+ this.suppressRefresh = false;
+ }
+ }
+ }
+ else if (TimeSpan.TryParse(this.numberBox.Text, out newTimespanNumber))
+ {
+ if (newTimespanNumber != TimeSpan.Zero)
+ {
+ int seconds = (int)Math.Round(newTimespanNumber.TotalSeconds, 0);
+ if (seconds != this.Number)
+ {
+ // While updating the binding we don't need to react to the change.
+ this.suppressRefresh = true;
+ this.Number = seconds;
+ this.suppressRefresh = false;
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// The user control_ loaded.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void UserControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ if (!this.ShowIncrementButtons)
+ {
+ this.incrementButtonsGrid.Visibility = Visibility.Collapsed;
+ }
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Converters/InverseBooleanConverter.cs b/win/CS/HandBrakeWPF/Converters/InverseBooleanConverter.cs
new file mode 100644
index 000000000..f44e18a3e
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Converters/InverseBooleanConverter.cs
@@ -0,0 +1,81 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="InverseBooleanConverter.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// The inverse boolean converter.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Converters
+{
+ using System;
+ using System.Globalization;
+ using System.Windows.Data;
+
+ /// <summary>
+ /// The inverse boolean converter.
+ /// </summary>
+ [ValueConversion(typeof(bool), typeof(bool))]
+ public class InverseBooleanConverter : IValueConverter
+ {
+ #region Implemented Interfaces
+
+ #region IValueConverter
+
+ /// <summary>
+ /// The convert.
+ /// </summary>
+ /// <param name="value">
+ /// The value.
+ /// </param>
+ /// <param name="targetType">
+ /// The target type.
+ /// </param>
+ /// <param name="parameter">
+ /// The parameter.
+ /// </param>
+ /// <param name="culture">
+ /// The culture.
+ /// </param>
+ /// <returns>
+ /// The <see cref="object"/>.
+ /// </returns>
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (targetType != typeof(bool))
+ {
+ throw new InvalidOperationException("The target must be a boolean");
+ }
+
+ return !(bool)value;
+ }
+
+ /// <summary>
+ /// The convert back.
+ /// </summary>
+ /// <param name="value">
+ /// The value.
+ /// </param>
+ /// <param name="targetType">
+ /// The target type.
+ /// </param>
+ /// <param name="parameter">
+ /// The parameter.
+ /// </param>
+ /// <param name="culture">
+ /// The culture.
+ /// </param>
+ /// <returns>
+ /// The <see cref="object"/>.
+ /// </returns>
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotSupportedException();
+ }
+
+ #endregion
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
index e11f8e8f9..c2214eee4 100644
--- a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
+++ b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
@@ -129,6 +129,9 @@
<Compile Include="Commands\ProcessShortcutCommand.cs" />
<Compile Include="Commands\SourceMenuCommand.cs" />
<Compile Include="Commands\AdvancedEncoderOptionsCommand.cs" />
+ <Compile Include="Controls\TimeSpanBox.xaml.cs">
+ <DependentUpon>TimeSpanBox.xaml</DependentUpon>
+ </Compile>
<Compile Include="Controls\Loading.xaml.cs">
<DependentUpon>Loading.xaml</DependentUpon>
</Compile>
@@ -143,6 +146,7 @@
<Compile Include="Converters\Audio\AudioEncoderConverter.cs" />
<Compile Include="Converters\Audio\AudioQueueDisplayConverter.cs" />
<Compile Include="Converters\BooleanToHiddenVisibilityConverter.cs" />
+ <Compile Include="Converters\InverseBooleanConverter.cs" />
<Compile Include="Converters\Options\OptionsTabConverter.cs" />
<Compile Include="Converters\Options\OptionsTabNameConverter.cs" />
<Compile Include="Converters\Subtitles\SubtitlesQueueDisplayConverter.cs" />
@@ -150,6 +154,7 @@
<Compile Include="Helpers\GrayscaleImage.cs" />
<Compile Include="Helpers\GrowlCommunicator.cs" />
<Compile Include="Model\OptionsTab.cs" />
+ <Compile Include="Model\SelectionTitle.cs" />
<Compile Include="Services\DriveDetectService.cs" />
<Compile Include="Services\EncodeServiceWrapper.cs" />
<Compile Include="Services\Interfaces\IDriveDetectService.cs" />
@@ -162,6 +167,11 @@
<Compile Include="Services\NotificationService.cs" />
<Compile Include="Services\ScanServiceWrapper.cs" />
<Compile Include="Services\UpdateService.cs" />
+ <Compile Include="ViewModels\Interfaces\IQueueSelectionViewModel.cs" />
+ <Compile Include="ViewModels\QueueSelectionViewModel.cs" />
+ <Compile Include="Views\QueueSelectionView.xaml.cs">
+ <DependentUpon>QueueSelectionView.xaml</DependentUpon>
+ </Compile>
<Compile Include="Views\ShellView.xaml.cs">
<DependentUpon>ShellView.xaml</DependentUpon>
</Compile>
@@ -304,6 +314,10 @@
<AppDesigner Include="Properties\" />
</ItemGroup>
<ItemGroup>
+ <Page Include="Controls\TimeSpanBox.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
<Page Include="Controls\Loading.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -316,6 +330,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
+ <Page Include="Views\QueueSelectionView.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
<Page Include="Views\ShellView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
diff --git a/win/CS/HandBrakeWPF/Model/SelectionTitle.cs b/win/CS/HandBrakeWPF/Model/SelectionTitle.cs
new file mode 100644
index 000000000..63ad47793
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Model/SelectionTitle.cs
@@ -0,0 +1,88 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="SelectionTitle.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// TODO: Update summary.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Model
+{
+ using Caliburn.Micro;
+
+ using HandBrake.ApplicationServices.Parsing;
+
+ /// <summary>
+ /// A model for the multiple selection window for adding to the queue.
+ /// </summary>
+ public class SelectionTitle : PropertyChangedBase
+ {
+ /// <summary>
+ /// The source name.
+ /// </summary>
+ private readonly string sourceName;
+
+ /// <summary>
+ /// The is selected.
+ /// </summary>
+ private bool isSelected;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SelectionTitle"/> class.
+ /// </summary>
+ /// <param name="title">
+ /// The title.
+ /// </param>
+ /// <param name="sourceName">
+ /// The source Name.
+ /// </param>
+ public SelectionTitle(Title title, string sourceName)
+ {
+ this.sourceName = sourceName;
+ this.Title = title;
+ }
+
+ /// <summary>
+ /// Gets the source name.
+ /// </summary>
+ public string SourceName
+ {
+ get
+ {
+ return !string.IsNullOrEmpty(Title.SourceName) ? Title.SourceName : sourceName;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the end point.
+ /// </summary>
+ public int EndPoint { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether is selected.
+ /// </summary>
+ public bool IsSelected
+ {
+ get
+ {
+ return this.isSelected;
+ }
+ set
+ {
+ this.isSelected = value;
+ this.NotifyOfPropertyChange(() => this.IsSelected);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the start point.
+ /// </summary>
+ public int StartPoint { get; set; }
+
+ /// <summary>
+ /// Gets or sets the title.
+ /// </summary>
+ public Title Title { get; set; }
+ }
+} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs b/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs
index 5adc38011..e2ccbcbda 100644
--- a/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs
+++ b/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs
@@ -216,7 +216,7 @@ namespace HandBrakeWPF.Properties {
/// <summary>
/// Looks up a localized string similar to This is the distance x264 searches from its best guess at the motion of a block in order to try to find its actual motion.
- ///Doesn&apos;t apply to Diamond or Hexagon search options.
+ ///
///The default is fine for most content, but extremely high motion video, especially at HD resolutions, may benefit from higher ranges, albeit at a high speed cost..
/// </summary>
public static string Advanced_MotionEstimationRangeToolTip {
@@ -237,6 +237,19 @@ namespace HandBrakeWPF.Properties {
}
/// <summary>
+ /// Looks up a localized string similar to The x264 Preset / Tune / Profile and Level options are currently in use on the Video Tab.
+ ///
+ ///To enable this tab, check the &quot;Use Advanced Tab instead&quot; option on the Video Tab.
+ ///
+ ///If you do not use this tab, it can be hidden from: Tools Menu &gt; Options &gt; Advanced..
+ /// </summary>
+ public static string Advanced_NotInUse {
+ get {
+ return ResourceManager.GetString("Advanced_NotInUse", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to Psychovisual Rate Distortion means x264 tries to retain detail, for better quality to the human eye,
///as opposed to trying to maximize quality the way a computer understands it, through signal-to-noise ratios that have trouble telling apart fine detail and noise..
/// </summary>
diff --git a/win/CS/HandBrakeWPF/Properties/Resources.resx b/win/CS/HandBrakeWPF/Properties/Resources.resx
index 6148d29c6..b39ace5a5 100644
--- a/win/CS/HandBrakeWPF/Properties/Resources.resx
+++ b/win/CS/HandBrakeWPF/Properties/Resources.resx
@@ -178,7 +178,7 @@ Transformed Exhaustive: Like exhaustive, but makes even more accurate decisions.
</data>
<data name="Advanced_MotionEstimationRangeToolTip" xml:space="preserve">
<value>This is the distance x264 searches from its best guess at the motion of a block in order to try to find its actual motion.
-Doesn't apply to Diamond or Hexagon search options.
+
The default is fine for most content, but extremely high motion video, especially at HD resolutions, may benefit from higher ranges, albeit at a high speed cost.</value>
</data>
<data name="Advanced_NoDctDecimateToolTip" xml:space="preserve">
@@ -321,4 +321,11 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</value>
</data>
+ <data name="Advanced_NotInUse" xml:space="preserve">
+ <value>The x264 Preset / Tune / Profile and Level options are currently in use on the Video Tab.
+
+To enable this tab, check the "Use Advanced Tab instead" option on the Video Tab.
+
+If you do not use this tab, it can be hidden from: Tools Menu &gt; Options &gt; Advanced.</value>
+ </data>
</root> \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs b/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs
index 5b06c97ba..97930ba4d 100644
--- a/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs
+++ b/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs
@@ -78,6 +78,8 @@ namespace HandBrakeWPF.Startup
this.windsorContainer.Register(Component.For<IOptionsViewModel>().ImplementedBy<OptionsViewModel>().LifeStyle.Is(LifestyleType.Singleton));
this.windsorContainer.Register(Component.For<IUpdateVersionService>().ImplementedBy<UpdateVersionService>().LifeStyle.Is(LifestyleType.Singleton));
this.windsorContainer.Register(Component.For<ITitleSpecificViewModel>().ImplementedBy<TitleSpecificViewModel>().LifeStyle.Is(LifestyleType.Singleton));
+ this.windsorContainer.Register(Component.For<IQueueSelectionViewModel>().ImplementedBy<QueueSelectionViewModel>().LifeStyle.Is(LifestyleType.Singleton));
+
// Tab Components
this.windsorContainer.Register(Component.For<IAudioViewModel>().ImplementedBy<AudioViewModel>().LifeStyle.Is(LifestyleType.Singleton));
diff --git a/win/CS/HandBrakeWPF/UserSettingConstants.cs b/win/CS/HandBrakeWPF/UserSettingConstants.cs
index 01fcea409..f0414ef6b 100644
--- a/win/CS/HandBrakeWPF/UserSettingConstants.cs
+++ b/win/CS/HandBrakeWPF/UserSettingConstants.cs
@@ -216,6 +216,11 @@ namespace HandBrakeWPF
/// </summary>
public const string ShowAdvancedTab = "ShowAdvancedTab";
+ /// <summary>
+ /// The last preview duration
+ /// </summary>
+ public const string LastPreviewDuration = "LastPreviewDuration";
+
#endregion
}
} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/ViewModels/AdvancedViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/AdvancedViewModel.cs
index 741f31876..1c0f9de67 100644
--- a/win/CS/HandBrakeWPF/ViewModels/AdvancedViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/AdvancedViewModel.cs
@@ -172,6 +172,9 @@ namespace HandBrakeWPF.ViewModels
/// <summary>
/// Initializes a new instance of the <see cref="AdvancedViewModel"/> class.
/// </summary>
+ /// <param name="advancedEncoderOptionsCommand">
+ /// The advanced Encoder Options Command.
+ /// </param>
public AdvancedViewModel(IAdvancedEncoderOptionsCommand advancedEncoderOptionsCommand)
{
this.advancedEncoderOptionsCommand = advancedEncoderOptionsCommand;
@@ -179,11 +182,34 @@ namespace HandBrakeWPF.ViewModels
this.UpdateUIFromAdvancedOptions();
}
+ /// <summary>
+ /// The task object property changed.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The PropertyChangedEventArgs.
+ /// </param>
+ private void Task_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == UserSettingConstants.ShowAdvancedTab)
+ {
+ ShowX264AdvancedOptions = this.Task.ShowAdvancedTab;
+ this.NotifyOfPropertyChange(() => ShowX264AdvancedOptions);
+ }
+ }
+
#endregion
#region Properties
/// <summary>
+ /// Gets or sets a value indicating whether show x 264 advanced options.
+ /// </summary>
+ public bool ShowX264AdvancedOptions { get; set; }
+
+ /// <summary>
/// Gets or sets a value indicating whether DisplayX264Options.
/// </summary>
public bool? DisplayX264Options
@@ -195,7 +221,19 @@ namespace HandBrakeWPF.ViewModels
set
{
this.displayX264Options = value;
+
+ if (this.displayX264Options == false)
+ {
+ this.ShowX264AdvancedOptions = false;
+ }
+
+ if (this.displayX264Options == true && this.Task.ShowAdvancedTab)
+ {
+ this.ShowX264AdvancedOptions = true;
+ }
+
this.NotifyOfPropertyChange(() => this.DisplayX264Options);
+ this.NotifyOfPropertyChange(() => this.ShowX264AdvancedOptions);
}
}
@@ -959,7 +997,9 @@ namespace HandBrakeWPF.ViewModels
/// </param>
public void SetPreset(Preset preset, EncodeTask task)
{
+ this.Task.PropertyChanged -= this.Task_PropertyChanged;
this.Task = task;
+ this.Task.PropertyChanged += this.Task_PropertyChanged;
this.AdvancedOptionsString = preset.Task.AdvancedEncoderOptions;
}
diff --git a/win/CS/HandBrakeWPF/ViewModels/ChaptersViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/ChaptersViewModel.cs
index 69a8a5d05..4276b97a4 100644
--- a/win/CS/HandBrakeWPF/ViewModels/ChaptersViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/ChaptersViewModel.cs
@@ -274,7 +274,7 @@ namespace HandBrakeWPF.ViewModels
foreach (Chapter chapter in this.SourceChapterList)
{
string chapterName = string.IsNullOrEmpty(chapter.ChapterName) ? string.Format("Chapter {0}", counter) : chapter.ChapterName;
- var marker = new ChapterMarker(chapter.ChapterNumber, chapterName);
+ var marker = new ChapterMarker(chapter.ChapterNumber, chapterName, chapter.Duration);
this.Task.ChapterNames.Add(marker);
counter += 1;
diff --git a/win/CS/HandBrakeWPF/ViewModels/Interfaces/IQueueSelectionViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IQueueSelectionViewModel.cs
new file mode 100644
index 000000000..36a64846a
--- /dev/null
+++ b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IQueueSelectionViewModel.cs
@@ -0,0 +1,40 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="IQueueSelectionViewModel.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// The Queue Selection View Model Interface
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.ViewModels.Interfaces
+{
+ using System.Collections.Generic;
+ using System.ComponentModel;
+
+ using HandBrake.ApplicationServices.Parsing;
+
+ using HandBrakeWPF.Model;
+
+ /// <summary>
+ /// The Add Preset View Model
+ /// </summary>
+ public interface IQueueSelectionViewModel
+ {
+ /// <summary>
+ /// Gets the selected titles.
+ /// </summary>
+ BindingList<SelectionTitle> TitleList { get; }
+
+ /// <summary>
+ /// The setup.
+ /// </summary>
+ /// <param name="scannedSource">
+ /// The scanned source.
+ /// </param>
+ /// <param name="sourceName">
+ /// The source Name.
+ /// </param>
+ void Setup(Source scannedSource, string sourceName);
+ }
+}
diff --git a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
index ad09f3043..fe52f88ce 100644
--- a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
@@ -221,6 +221,7 @@ namespace HandBrakeWPF.ViewModels
// Setup Properties
this.WindowTitle = "HandBrake";
this.CurrentTask = new EncodeTask();
+ this.CurrentTask.PropertyChanged += this.CurrentTask_PropertyChanged;
this.ScannedSource = new Source();
// Setup Events
@@ -231,6 +232,7 @@ namespace HandBrakeWPF.ViewModels
this.queueProcessor.QueueCompleted += this.QueueCompleted;
this.queueProcessor.QueueChanged += this.QueueChanged;
this.queueProcessor.EncodeService.EncodeStatusChanged += this.EncodeStatusChanged;
+ this.userSettingService.SettingChanged += this.UserSettingServiceSettingChanged;
this.Presets = this.presetService.Presets;
this.CancelScanCommand = new CancelScanCommand(this.scanService);
@@ -448,6 +450,12 @@ namespace HandBrakeWPF.ViewModels
{
get
{
+ // Sanity Check
+ if (ScannedSource == null || ScannedSource.ScanPath == null)
+ {
+ return string.Empty;
+ }
+
// The title that is selected has a source name. This means it's part of a batch scan.
if (selectedTitle != null && !string.IsNullOrEmpty(selectedTitle.SourceName))
{
@@ -597,7 +605,7 @@ namespace HandBrakeWPF.ViewModels
set
{
this.isMkv = value;
- this.NotifyOfPropertyChange("IsMkv");
+ this.NotifyOfPropertyChange(() => this.IsMkv);
}
}
@@ -737,6 +745,7 @@ namespace HandBrakeWPF.ViewModels
{
return this.CurrentTask.StartPoint;
}
+
set
{
this.CurrentTask.Angle = value;
@@ -745,6 +754,11 @@ namespace HandBrakeWPF.ViewModels
}
/// <summary>
+ /// Gets or sets a value indicating whether is timespan range.
+ /// </summary>
+ public bool IsTimespanRange { get; set; }
+
+ /// <summary>
/// Gets or sets SelectedStartPoint.
/// </summary>
public int SelectedStartPoint
@@ -759,7 +773,7 @@ namespace HandBrakeWPF.ViewModels
this.NotifyOfPropertyChange(() => this.SelectedStartPoint);
this.Duration = this.DurationCalculation();
- if (this.UserSettingService.GetUserSetting<bool>(UserSettingConstants.AutoNaming))
+ if (this.UserSettingService.GetUserSetting<bool>(UserSettingConstants.AutoNaming) && this.ScannedSource.ScanPath != null)
{
this.Destination = AutoNameHelper.AutoName(this.CurrentTask, this.SourceName);
}
@@ -781,7 +795,7 @@ namespace HandBrakeWPF.ViewModels
this.NotifyOfPropertyChange(() => this.SelectedEndPoint);
this.Duration = this.DurationCalculation();
- if (this.UserSettingService.GetUserSetting<bool>(UserSettingConstants.AutoNaming))
+ if (this.UserSettingService.GetUserSetting<bool>(UserSettingConstants.AutoNaming) && this.ScannedSource.ScanPath != null)
{
this.Destination = AutoNameHelper.AutoName(this.CurrentTask, this.SourceName);
}
@@ -805,21 +819,41 @@ namespace HandBrakeWPF.ViewModels
if (value == PointToPointMode.Chapters && this.SelectedTitle != null)
{
+ if (this.selectedTitle == null)
+ {
+ return;
+ }
+
+
this.SelectedStartPoint = 1;
this.SelectedEndPoint = selectedTitle.Chapters.Last().ChapterNumber;
}
else if (value == PointToPointMode.Seconds)
{
+ if (this.selectedTitle == null)
+ {
+ return;
+ }
+
+
this.SelectedStartPoint = 0;
int timeInSeconds;
if (int.TryParse(selectedTitle.Duration.TotalSeconds.ToString(CultureInfo.InvariantCulture), out timeInSeconds))
{
this.SelectedEndPoint = timeInSeconds;
- }
+ }
+
+ this.IsTimespanRange = true;
+ this.NotifyOfPropertyChange(() => this.IsTimespanRange);
}
else
{
+ if (this.selectedTitle == null)
+ {
+ return;
+ }
+
// Note this does not account for VFR. It's only a guesstimate.
double estimatedTotalFrames = selectedTitle.Fps * selectedTitle.Duration.TotalSeconds;
@@ -829,6 +863,9 @@ namespace HandBrakeWPF.ViewModels
{
this.SelectedEndPoint = totalFrames;
}
+
+ this.IsTimespanRange = false;
+ this.NotifyOfPropertyChange(() => this.IsTimespanRange);
}
}
}
@@ -927,6 +964,7 @@ namespace HandBrakeWPF.ViewModels
this.queueProcessor.QueueChanged -= this.QueueChanged;
this.queueProcessor.JobProcessingStarted -= this.QueueProcessorJobProcessingStarted;
this.queueProcessor.EncodeService.EncodeStatusChanged -= this.EncodeStatusChanged;
+ this.userSettingService.SettingChanged -= this.UserSettingServiceSettingChanged;
}
#endregion
@@ -1073,6 +1111,38 @@ namespace HandBrakeWPF.ViewModels
}
/// <summary>
+ /// The add selection to queue.
+ /// </summary>
+ public void AddSelectionToQueue()
+ {
+ if (this.ScannedSource == null || this.ScannedSource.Titles == null || this.ScannedSource.Titles.Count == 0)
+ {
+ this.errorService.ShowMessageBox("You must first scan a source and setup your job before adding to the queue.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+
+ if (!AutoNameHelper.IsAutonamingEnabled())
+ {
+ this.errorService.ShowMessageBox("You must turn on automatic file naming in preferences before you can add to the queue.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+
+ Window window = Application.Current.Windows.Cast<Window>().FirstOrDefault(x => x.GetType() == typeof(QueueSelectionViewModel));
+ IQueueSelectionViewModel viewModel = IoC.Get<IQueueSelectionViewModel>();
+
+ viewModel.Setup(this.ScannedSource, this.SourceName);
+
+ if (window != null)
+ {
+ window.Activate();
+ }
+ else
+ {
+ this.WindowManager.ShowWindow(viewModel);
+ }
+ }
+
+ /// <summary>
/// Folder Scan
/// </summary>
public void FolderScan()
@@ -1521,15 +1591,20 @@ namespace HandBrakeWPF.ViewModels
this.NotifyOfPropertyChange(() => this.ScannedSource.Titles);
// Select the Users Title
- this.CurrentTask = new EncodeTask(queueEditTask);
- this.NotifyOfPropertyChange(() => this.CurrentTask);
this.SelectedTitle = this.ScannedSource.Titles.FirstOrDefault(t => t.TitleNumber == this.CurrentTask.Title);
-
- // Update the Main UI control Area (TODO)
this.CurrentTask = new EncodeTask(queueEditTask);
this.NotifyOfPropertyChange(() => this.CurrentTask);
- // Update the Tab Controls (TODO)
+ // Update the Main Window
+ this.NotifyOfPropertyChange(() => this.Destination);
+ this.NotifyOfPropertyChange(() => this.SelectedStartPoint);
+ this.NotifyOfPropertyChange(() => this.SelectedEndPoint);
+ this.NotifyOfPropertyChange(() => this.SelectedAngle);
+ this.NotifyOfPropertyChange(() => this.SelectedPointToPoint);
+ this.NotifyOfPropertyChange(() => this.SelectedOutputFormat);
+ this.NotifyOfPropertyChange(() => IsMkv);
+
+ // Update the Tab Controls
this.PictureSettingsViewModel.UpdateTask(this.CurrentTask);
this.VideoViewModel.UpdateTask(this.CurrentTask);
this.FiltersViewModel.UpdateTask(this.CurrentTask);
@@ -1538,8 +1613,23 @@ namespace HandBrakeWPF.ViewModels
this.ChaptersViewModel.UpdateTask(this.CurrentTask);
this.AdvancedViewModel.UpdateTask(this.CurrentTask);
+ // Tell the Preivew Window
+ IPreviewViewModel viewModel = IoC.Get<IPreviewViewModel>();
+ viewModel.Task = this.CurrentTask;
+
// Cleanup
this.ShowStatusWindow = false;
+
+ if (this.SelectedTitle != null && !string.IsNullOrEmpty(this.SelectedTitle.SourceName))
+ {
+ this.SourceLabel = this.SelectedTitle.SourceName;
+ }
+ else
+ {
+ this.SourceLabel = this.SourceName;
+ }
+
+ this.StatusLabel = "Scan Completed";
});
}
@@ -1648,6 +1738,7 @@ namespace HandBrakeWPF.ViewModels
this.ProgramStatusLabel = "A New Update is Available. Goto Tools Menu > Options to Install";
}
}
+
#endregion
#region Event Handlers
@@ -1921,6 +2012,41 @@ namespace HandBrakeWPF.ViewModels
Caliburn.Micro.Execute.OnUIThread(() => this.SourceMenu = this.GenerateSourceMenu());
}
+ /// <summary>
+ /// Allows the main window to respond to setting changes.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void UserSettingServiceSettingChanged(object sender, HandBrake.ApplicationServices.EventArgs.SettingChangedEventArgs e)
+ {
+ if (e.Key == UserSettingConstants.ShowAdvancedTab)
+ {
+ this.NotifyOfPropertyChange(() => this.ShowAdvancedTab);
+ }
+ }
+
+ /// <summary>
+ /// Handle the property changed event of the encode task.
+ /// Allows the main window to respond to changes.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void CurrentTask_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == UserSettingConstants.ShowAdvancedTab)
+ {
+ this.NotifyOfPropertyChange(() => this.ShowAdvancedTab);
+ }
+ }
+
#endregion
}
} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/ViewModels/PreviewViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/PreviewViewModel.cs
index d917c20c8..7ebb88619 100644
--- a/win/CS/HandBrakeWPF/ViewModels/PreviewViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/PreviewViewModel.cs
@@ -95,6 +95,7 @@ namespace HandBrakeWPF.ViewModels
this.Duration = 30;
UseSystemDefaultPlayer = userSettingService.GetUserSetting<bool>(UserSettingConstants.DefaultPlayer);
+ this.Duration = userSettingService.GetUserSetting<int>(UserSettingConstants.LastPreviewDuration);
}
#endregion
@@ -113,7 +114,7 @@ namespace HandBrakeWPF.ViewModels
{
get
{
- return new List<int> { 10, 30, 45, 60, 75, 90, 105, 120 };
+ return new List<int> { 5, 10, 30, 45, 60, 75, 90, 105, 120 };
}
}
@@ -381,6 +382,7 @@ namespace HandBrakeWPF.ViewModels
this.encodeService.EncodeStatusChanged += this.encodeService_EncodeStatusChanged;
this.encodeService.Start((QueueTask)state, false);
+ this.userSettingService.SetUserSetting(UserSettingConstants.LastPreviewDuration, this.Duration);
}
#endregion
diff --git a/win/CS/HandBrakeWPF/ViewModels/QueueSelectionViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/QueueSelectionViewModel.cs
new file mode 100644
index 000000000..c5b6072cc
--- /dev/null
+++ b/win/CS/HandBrakeWPF/ViewModels/QueueSelectionViewModel.cs
@@ -0,0 +1,198 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="QueueSelectionViewModel.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// The Queue Selection View Model
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.ViewModels
+{
+ using System;
+ using System.Collections.Generic;
+ using System.ComponentModel;
+ using System.Linq;
+
+ using HandBrake.ApplicationServices.Parsing;
+
+ using HandBrakeWPF.Model;
+ using HandBrakeWPF.Services.Interfaces;
+ using HandBrakeWPF.ViewModels.Interfaces;
+
+ /// <summary>
+ /// The Queue Selection View Model
+ /// </summary>
+ public class QueueSelectionViewModel : ViewModelBase, IQueueSelectionViewModel
+ {
+ /// <summary>
+ /// The error service.
+ /// </summary>
+ private readonly IErrorService errorService;
+
+ /// <summary>
+ /// The ordered by duration.
+ /// </summary>
+ private bool orderedByDuration;
+
+ /// <summary>
+ /// The ordered by title.
+ /// </summary>
+ private bool orderedByTitle;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="QueueSelectionViewModel"/> class.
+ /// </summary>
+ /// <param name="errorService">
+ /// The Error Service
+ /// </param>
+ public QueueSelectionViewModel(IErrorService errorService)
+ {
+ this.errorService = errorService;
+ this.Title = "Add to Queue";
+ this.TitleList = new BindingList<SelectionTitle>();
+ this.OrderedByTitle = true;
+ }
+
+ /// <summary>
+ /// Gets or sets the source.
+ /// </summary>
+ public string Source { get; set; }
+
+ /// <summary>
+ /// Gets or sets the selected titles.
+ /// </summary>
+ public BindingList<SelectionTitle> TitleList { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether ordered by title.
+ /// </summary>
+ public bool OrderedByTitle
+ {
+ get
+ {
+ return this.orderedByTitle;
+ }
+
+ set
+ {
+ this.orderedByTitle = value;
+ this.NotifyOfPropertyChange(() => OrderedByTitle);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether ordered by duration.
+ /// </summary>
+ public bool OrderedByDuration
+ {
+ get
+ {
+ return this.orderedByDuration;
+ }
+
+ set
+ {
+ this.orderedByDuration = value;
+ this.NotifyOfPropertyChange(() => OrderedByDuration);
+ }
+ }
+
+ /// <summary>
+ /// The order by title.
+ /// </summary>
+ public void OrderByTitle()
+ {
+ TitleList = new BindingList<SelectionTitle>(TitleList.OrderBy(o => o.Title.TitleNumber).ToList());
+ this.NotifyOfPropertyChange(() => TitleList);
+ this.OrderedByTitle = true;
+ this.OrderedByDuration = false;
+ }
+
+ /// <summary>
+ /// The order by duration.
+ /// </summary>
+ public void OrderByDuration()
+ {
+ TitleList = new BindingList<SelectionTitle>(TitleList.OrderByDescending(o => o.Title.Duration).ToList());
+ this.NotifyOfPropertyChange(() => TitleList);
+ this.OrderedByTitle = false;
+ this.OrderedByDuration = true;
+ }
+
+ /// <summary>
+ /// The select all.
+ /// </summary>
+ public void SelectAll()
+ {
+ foreach (var item in TitleList)
+ {
+ item.IsSelected = true;
+ }
+ }
+
+ /// <summary>
+ /// The select all.
+ /// </summary>
+ public void UnSelectAll()
+ {
+ foreach (var item in TitleList)
+ {
+ item.IsSelected = false;
+ }
+ }
+
+ /// <summary>
+ /// Add a Preset
+ /// </summary>
+ public void Add()
+ {
+ this.Close();
+ }
+
+ /// <summary>
+ /// Cancel adding a preset
+ /// </summary>
+ public void Cancel()
+ {
+ this.TitleList.Clear();
+ this.Close();
+ }
+
+ /// <summary>
+ /// Close this window.
+ /// </summary>
+ public void Close()
+ {
+ this.TryClose();
+ }
+
+ /// <summary>
+ /// The setup.
+ /// </summary>
+ /// <param name="scannedSource">
+ /// The scanned source.
+ /// </param>
+ /// <param name="srcName">
+ /// The src Name.
+ /// </param>
+ public void Setup(Source scannedSource, string srcName)
+ {
+ this.TitleList.Clear();
+
+ if (scannedSource != null)
+ {
+
+ IEnumerable<Title> titles = orderedByTitle
+ ? scannedSource.Titles
+ : scannedSource.Titles.OrderByDescending(o => o.Duration).ToList();
+
+ foreach (Title item in titles)
+ {
+ SelectionTitle title = new SelectionTitle(item, srcName);
+ TitleList.Add(title);
+ }
+ }
+ }
+ }
+}
diff --git a/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs
index a3998be21..4f344db08 100644
--- a/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs
@@ -11,6 +11,7 @@ namespace HandBrakeWPF.ViewModels
{
using System;
using System.Collections.ObjectModel;
+ using System.ComponentModel;
using System.Windows;
using Caliburn.Micro;
@@ -30,6 +31,13 @@ namespace HandBrakeWPF.ViewModels
/// </summary>
public class QueueViewModel : ViewModelBase, IQueueViewModel
{
+ /*
+
+ * TODO FIX THE DRAP/DROP ADORNER!
+ */
+
+
+
#region Constants and Fields
/// <summary>
@@ -152,17 +160,6 @@ namespace HandBrakeWPF.ViewModels
}
/// <summary>
- /// Gets QueueJobs.
- /// </summary>
- public ObservableCollection<QueueTask> QueueJobs
- {
- get
- {
- return this.queueProcessor.Queue;
- }
- }
-
- /// <summary>
/// Gets or sets WhenDoneAction.
/// </summary>
public string WhenDoneAction
@@ -178,6 +175,17 @@ namespace HandBrakeWPF.ViewModels
}
}
+ /// <summary>
+ /// Gets the queue tasks.
+ /// </summary>
+ public BindingList<QueueTask> QueueTasks
+ {
+ get
+ {
+ return this.queueProcessor.Queue;
+ }
+ }
+
#endregion
#region Public Methods
@@ -270,8 +278,6 @@ namespace HandBrakeWPF.ViewModels
{
this.queueProcessor.Remove(task);
}
-
- this.JobsPending = string.Format("{0} jobs pending", this.queueProcessor.Count);
}
/// <summary>
@@ -408,16 +414,19 @@ namespace HandBrakeWPF.ViewModels
private void EncodeService_EncodeStatusChanged(
object sender, EncodeProgressEventArgs e)
{
- this.JobStatus =
- string.Format(
- "Encoding: Pass {0} of {1}, {2:00.00}%, FPS: {3:000.0}, Avg FPS: {4:000.0}, Time Remaining: {5}, Elapsed: {6:hh\\:mm\\:ss}",
- e.Task,
- e.TaskCount,
- e.PercentComplete,
- e.CurrentFrameRate,
- e.AverageFrameRate,
- e.EstimatedTimeLeft,
- e.ElapsedTime);
+ if (this.IsEncoding)
+ {
+ this.JobStatus =
+ string.Format(
+ "Encoding: Pass {0} of {1}, {2:00.00}%, FPS: {3:000.0}, Avg FPS: {4:000.0}, Time Remaining: {5}, Elapsed: {6:hh\\:mm\\:ss}",
+ e.Task,
+ e.TaskCount,
+ e.PercentComplete,
+ e.CurrentFrameRate,
+ e.AverageFrameRate,
+ e.EstimatedTimeLeft,
+ e.ElapsedTime);
+ }
}
/// <summary>
diff --git a/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs
index 6164e3603..a59105084 100644
--- a/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs
@@ -27,6 +27,7 @@ namespace HandBrakeWPF.ViewModels
using HandBrake.Interop.Model.Encoding.x264;
using HandBrakeWPF.Commands.Interfaces;
+ using HandBrakeWPF.Model;
using HandBrakeWPF.ViewModels.Interfaces;
/// <summary>
@@ -95,6 +96,11 @@ namespace HandBrakeWPF.ViewModels
/// </summary>
private bool canClear;
+ /// <summary>
+ /// The use advanced tab.
+ /// </summary>
+ private bool useAdvancedTab;
+
#endregion
#region Constructors and Destructors
@@ -122,6 +128,8 @@ namespace HandBrakeWPF.ViewModels
H264Profiles = EnumHelper<x264Profile>.GetEnumList();
X264Tunes = EnumHelper<x264Tune>.GetEnumList().Where(t => t != x264Tune.Fastdecode);
this.H264Levels = Levels;
+
+ this.userSettingService.SettingChanged += this.UserSettingServiceSettingChanged;
}
#endregion
@@ -134,6 +142,44 @@ namespace HandBrakeWPF.ViewModels
public EncodeTask Task { get; set; }
/// <summary>
+ /// Gets a value indicating whether show advanced tab.
+ /// </summary>
+ public bool ShowAdvancedTab
+ {
+ get
+ {
+ bool showAdvTabSetting =
+ this.userSettingService.GetUserSetting<bool>(UserSettingConstants.ShowAdvancedTab);
+ if (!showAdvTabSetting)
+ {
+ this.UseAdvancedTab = false;
+ }
+
+ return showAdvTabSetting;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether use video tab.
+ /// </summary>
+ public bool UseAdvancedTab
+ {
+ get
+ {
+ return this.useAdvancedTab;
+ }
+ set
+ {
+ if (!object.Equals(value, this.useAdvancedTab))
+ {
+ this.useAdvancedTab = value;
+ this.Task.ShowAdvancedTab = value;
+ this.NotifyOfPropertyChange(() => this.UseAdvancedTab);
+ }
+ }
+ }
+
+ /// <summary>
/// Gets Framerates.
/// </summary>
public IEnumerable<string> Framerates
@@ -335,6 +381,9 @@ namespace HandBrakeWPF.ViewModels
}
}
+ /// <summary>
+ /// Gets the rfqp.
+ /// </summary>
public string Rfqp
{
get
@@ -729,6 +778,8 @@ namespace HandBrakeWPF.ViewModels
this.H264Level = preset.Task.VideoEncoder == VideoEncoder.X264 ? preset.Task.H264Level : "Auto";
this.FastDecode = preset.Task.VideoEncoder == VideoEncoder.X264 && preset.Task.FastDecode;
this.ExtraArguments = preset.Task.ExtraAdvancedArguments;
+
+ this.UseAdvancedTab = !string.IsNullOrEmpty(preset.Task.AdvancedEncoderOptions) && this.ShowAdvancedTab;
}
}
@@ -866,5 +917,22 @@ namespace HandBrakeWPF.ViewModels
// TODO figure out what is wrong with this??
return HandBrakeUtils.CreateX264OptionsString(preset, tunes, this.ExtraArguments, profile, this.H264Level, width, height);
}
+
+ /// <summary>
+ /// The user setting service_ setting changed.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void UserSettingServiceSettingChanged(object sender, HandBrake.ApplicationServices.EventArgs.SettingChangedEventArgs e)
+ {
+ if (e.Key == UserSettingConstants.ShowAdvancedTab)
+ {
+ this.NotifyOfPropertyChange(() => this.ShowAdvancedTab);
+ }
+ }
}
} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Views/AddPresetView.xaml.cs b/win/CS/HandBrakeWPF/Views/AddPresetView.xaml.cs
index 91968fdc0..d3485d2c0 100644
--- a/win/CS/HandBrakeWPF/Views/AddPresetView.xaml.cs
+++ b/win/CS/HandBrakeWPF/Views/AddPresetView.xaml.cs
@@ -3,7 +3,7 @@
// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
// </copyright>
// <summary>
-// Interaction logic for VideoView.xaml
+// Interaction logic for AddPresetView.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------
@@ -12,7 +12,7 @@ namespace HandBrakeWPF.Views
using System.Windows;
/// <summary>
- /// Interaction logic for VideoView.xaml
+ /// Interaction logic for AddPresetView.xaml
/// </summary>
public partial class AddPresetView : Window
{
diff --git a/win/CS/HandBrakeWPF/Views/AdvancedView.xaml b/win/CS/HandBrakeWPF/Views/AdvancedView.xaml
index 785102cd2..b0b7698d2 100644
--- a/win/CS/HandBrakeWPF/Views/AdvancedView.xaml
+++ b/win/CS/HandBrakeWPF/Views/AdvancedView.xaml
@@ -42,7 +42,7 @@
VerticalAlignment="Center"
FontWeight="Bold"
Text="x264 Encoder Options:"
- Visibility="{Binding DisplayX264Options, Converter={StaticResource BooleanVisibilityConverter}, ConverterParameter=false}"
+ Visibility="{Binding ShowX264AdvancedOptions, Converter={StaticResource BooleanVisibilityConverter}, ConverterParameter=false}"
/>
<TextBox Grid.Row="3"
@@ -54,7 +54,7 @@
Text="{Binding AdvancedOptionsString,
UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap"
- Visibility="{Binding DisplayX264Options, Converter={StaticResource BooleanVisibilityConverter}, ConverterParameter=false}"
+ Visibility="{Binding ShowX264AdvancedOptions, Converter={StaticResource BooleanVisibilityConverter}, ConverterParameter=false}"
/>
<StackPanel Orientation="Vertical">
@@ -80,7 +80,11 @@
</Grid>
<!-- X264 -->
- <Grid Visibility="{Binding DisplayX264Options, Converter={StaticResource BooleanVisibilityConverter}, ConverterParameter=false}">
+ <TextBlock Text="{x:Static Properties:Resources.Advanced_NotInUse}"
+ TextWrapping="Wrap" Width="480" Margin="0, 100, 0, 0" FontSize="12"
+ Visibility="{Binding ShowX264AdvancedOptions, Converter={StaticResource BooleanVisibilityConverter}, ConverterParameter=true}" />
+
+ <Grid Visibility="{Binding ShowX264AdvancedOptions, Converter={StaticResource BooleanVisibilityConverter}, ConverterParameter=false}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
diff --git a/win/CS/HandBrakeWPF/Views/AudioView.xaml b/win/CS/HandBrakeWPF/Views/AudioView.xaml
index af5b81514..c63346642 100644
--- a/win/CS/HandBrakeWPF/Views/AudioView.xaml
+++ b/win/CS/HandBrakeWPF/Views/AudioView.xaml
@@ -9,6 +9,7 @@
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:NumericUpDown="clr-namespace:EagleBoost.Wpf.Presentation.Controls.NumericUpDown;assembly=EagleBoost.Wpf.Presentation"
+ xmlns:controls="clr-namespace:HandBrakeWPF.Controls"
d:DesignHeight="170"
d:DesignWidth="616"
mc:Ignorable="d">
@@ -265,6 +266,7 @@
Visibility="{Binding IsPassthru,
Converter={StaticResource boolToVisConverter},
ConverterParameter=true}" />
+
<NumericUpDown:NumericUpDown Name="drcNumericCtl"
Grid.Row="1"
Grid.Column="3"
diff --git a/win/CS/HandBrakeWPF/Views/ChaptersView.xaml b/win/CS/HandBrakeWPF/Views/ChaptersView.xaml
index c6cefb35e..a5fa6a6da 100644
--- a/win/CS/HandBrakeWPF/Views/ChaptersView.xaml
+++ b/win/CS/HandBrakeWPF/Views/ChaptersView.xaml
@@ -38,7 +38,8 @@
</ContextMenu>
</DataGrid.ContextMenu>
<DataGrid.Columns>
- <DataGridTextColumn Header="Chapter Number" Width="150" Binding="{Binding ChapterNumber}" IsReadOnly="True" />
+ <DataGridTextColumn Header="Chapter Number" Width="120" Binding="{Binding ChapterNumber}" IsReadOnly="True" />
+ <DataGridTextColumn Header="Duration" Width="100" Binding="{Binding Duration}" IsReadOnly="True" />
<DataGridTextColumn Header="Chapter Name" Width="*" Binding="{Binding ChapterName}" IsReadOnly="False" />
</DataGrid.Columns>
</DataGrid>
diff --git a/win/CS/HandBrakeWPF/Views/MainView.xaml b/win/CS/HandBrakeWPF/Views/MainView.xaml
index 0f85a2b73..1a020b603 100644
--- a/win/CS/HandBrakeWPF/Views/MainView.xaml
+++ b/win/CS/HandBrakeWPF/Views/MainView.xaml
@@ -269,6 +269,7 @@
</StackPanel>
</MenuItem.Header>
<MenuItem Header="Add All" Micro:Message.Attach="[Event Click] = [Action AddAllToQueue]" />
+ <!--<MenuItem Header="Add Selection" Micro:Message.Attach="[Event Click] = [Action AddSelectionToQueue]" />-->
</MenuItem>
</Menu>
@@ -370,14 +371,13 @@
Converter={StaticResource boolToVisConverter},
ConverterParameter=true}"
/>
- <TextBox Name="StartPointText"
- MinWidth="60"
- Margin="8,0,0,0"
- Text="{Binding SelectedStartPoint, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
- Visibility="{Binding ShowTextEntryForPointToPointMode,
- Converter={StaticResource boolToVisConverter},
- ConverterParameter=false}"
- />
+ <Controls:TimeSpanBox Number="{Binding SelectedStartPoint, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
+ Minimum="0" AllowEmpty="False" ShowTimeSpan="{Binding IsTimespanRange}"
+ MinWidth="80" Margin="8,0,0,0" Visibility="{Binding ShowTextEntryForPointToPointMode,
+ Converter={StaticResource boolToVisConverter},
+ ConverterParameter=false}"
+ />
+
<Label Margin="8,0,0,0" Content="through" />
<ComboBox Name="EndPoint"
MinWidth="60"
@@ -388,14 +388,13 @@
Converter={StaticResource boolToVisConverter},
ConverterParameter=true}"
/>
- <TextBox Name="EndPointText"
- MinWidth="60"
- Margin="8,0,0,0"
- Text="{Binding SelectedEndPoint, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
- Visibility="{Binding ShowTextEntryForPointToPointMode,
- Converter={StaticResource boolToVisConverter},
- ConverterParameter=false}"
- />
+ <Controls:TimeSpanBox Number="{Binding SelectedEndPoint, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
+ Minimum="0" AllowEmpty="False" ShowTimeSpan="{Binding IsTimespanRange}"
+ MinWidth="80" Margin="8,0,0,0" Visibility="{Binding ShowTextEntryForPointToPointMode,
+ Converter={StaticResource boolToVisConverter},
+ ConverterParameter=false}"
+ />
+
<Label Margin="8,0,0,0" Content="Duration" />
<Label Margin="8,0,0,0" Content="{Binding Duration}" />
</StackPanel>
diff --git a/win/CS/HandBrakeWPF/Views/QueueSelectionView.xaml b/win/CS/HandBrakeWPF/Views/QueueSelectionView.xaml
new file mode 100644
index 000000000..b46b07ff5
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Views/QueueSelectionView.xaml
@@ -0,0 +1,140 @@
+<Window x:Class="HandBrakeWPF.Views.QueueSelectionView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ Title="{Binding Title}"
+ Width="450"
+ MaxHeight="450"
+ SizeToContent="Height"
+ WindowStartupLocation="CenterScreen"
+ TextOptions.TextFormattingMode="Display"
+ mc:Ignorable="d">
+
+ <Window.Resources>
+
+ <Style x:Key="LongToolTipHolder" TargetType="FrameworkElement">
+ <Setter Property="ToolTipService.ShowDuration" Value="20000" />
+ <Setter Property="Margin" Value="0,2,0,2" />
+ </Style>
+ </Window.Resources>
+
+ <Grid HorizontalAlignment="Stretch"
+ VerticalAlignment="Stretch"
+ Background="#FFF1F0EF">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+
+ <!-- Header -->
+ <StackPanel Grid.Row="0"
+ Height="30"
+ Margin="0,0,0,10"
+ Background="White"
+ Orientation="Horizontal">
+ <Image Width="24"
+ Height="24"
+ Margin="10,0,5,0"
+ VerticalAlignment="Center"
+ Source="Images/AddToQueue_small.png" />
+ <StackPanel VerticalAlignment="Center" Orientation="Vertical">
+ <TextBlock FontWeight="Bold" Text="Queue Multiple Items" />
+ </StackPanel>
+ </StackPanel>
+
+ <!-- Text -->
+ <StackPanel Orientation="Vertical" Grid.Row="1" Margin="10,10,10,0">
+ <TextBlock Text="Select multiple titles to add: " />
+ </StackPanel>
+
+ <!-- Selection -->
+ <ListBox Grid.Row="2"
+ Margin="10,10,10,10"
+ VerticalAlignment="Stretch"
+ Background="LightGray"
+ ItemsSource="{Binding TitleList}"
+ SelectionMode="Single">
+ <ListBox.ItemContainerStyle>
+ <Style TargetType="ListBoxItem">
+ <Setter Property="HorizontalContentAlignment" Value="Stretch" />
+ <Setter Property="Background" Value="WhiteSmoke" />
+ <Setter Property="Margin" Value="0,0,0,1" />
+ </Style>
+ </ListBox.ItemContainerStyle>
+
+ <ListBox.ContextMenu>
+ <ContextMenu>
+ <MenuItem Header="Select All" cal:Message.Attach="[Event Click] = [Action SelectAll]" />
+ <MenuItem Header="Select All" cal:Message.Attach="[Event Click] = [Action UnSelectAll]" />
+ <Separator />
+ <MenuItem Header="Order by Title" IsChecked="{Binding OrderedByTitle}" cal:Message.Attach="[Event Click] = [Action OrderByTitle]" />
+ <MenuItem Header="Order by Duration" IsChecked="{Binding OrderedByDuration}" cal:Message.Attach="[Event Click] = [Action OrderByDuration]" />
+ </ContextMenu>
+ </ListBox.ContextMenu>
+
+ <ListBox.ItemTemplate>
+ <DataTemplate>
+ <Grid HorizontalAlignment="Stretch" MinHeight="28">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+
+ <CheckBox IsChecked="{Binding IsSelected}" Grid.RowSpan="2" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" />
+
+ <StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal" Margin="10,0,0,0" >
+ <TextBlock Text="Title:" Margin="0,0,5,0" FontWeight="Bold" />
+ <TextBlock Text="{Binding Title}" Margin="5,0,5,0" />
+ </StackPanel>
+
+ <StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal" Margin="10,0,0,0" >
+ <TextBlock Text="Source:" Margin="0,0,5,0" FontWeight="Bold" />
+ <TextBlock Text="{Binding SourceName}" Margin="5,0,5,0" />
+ </StackPanel>
+ </Grid>
+
+ </DataTemplate>
+ </ListBox.ItemTemplate>
+ </ListBox>
+
+ <!-- Checlist -->
+ <StackPanel Orientation="Vertical" Grid.Row="3" Margin="10,10,10,0">
+ <TextBlock Text="Checklist " />
+ </StackPanel>
+
+ <!-- Controls -->
+ <Grid Grid.Row="4"
+ Margin="0,20,0,0"
+ Background="LightGray">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+
+ <Button Grid.Column="1"
+ Margin="0,5,10,5"
+ cal:Message.Attach="[Event Click] = [Action Cancel]"
+ Content="Cancel"
+ IsCancel="True"
+ Padding="8,2" />
+ <Button Grid.Column="2"
+ Margin="0,5,10,5"
+ cal:Message.Attach="[Event Click] = [Action Add]"
+ Content="Add"
+ IsDefault="True"
+ Padding="8,2" />
+ </Grid>
+
+ </Grid>
+</Window>
diff --git a/win/CS/HandBrakeWPF/Views/QueueSelectionView.xaml.cs b/win/CS/HandBrakeWPF/Views/QueueSelectionView.xaml.cs
new file mode 100644
index 000000000..553c7201f
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Views/QueueSelectionView.xaml.cs
@@ -0,0 +1,27 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="QueueSelectionView.xaml.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Interaction logic for QueueSelectionView.xaml
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Views
+{
+ using System.Windows;
+
+ /// <summary>
+ /// Interaction logic for QueueSelectionView.xaml
+ /// </summary>
+ public partial class QueueSelectionView : Window
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="QueueSelectionView"/> class.
+ /// </summary>
+ public QueueSelectionView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/win/CS/HandBrakeWPF/Views/QueueView.xaml b/win/CS/HandBrakeWPF/Views/QueueView.xaml
index 5384948b3..394eb35e4 100644
--- a/win/CS/HandBrakeWPF/Views/QueueView.xaml
+++ b/win/CS/HandBrakeWPF/Views/QueueView.xaml
@@ -137,15 +137,14 @@
<TextBlock Text="{Binding JobsPending}" />
<TextBlock Text="{Binding JobStatus}" />
</StackPanel>
-
+
<ListBox Grid.Row="2"
Margin="10,0,10,10"
Background="LightGray"
dd:DragDrop.DropHandler="{Binding}"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
- ItemsSource="{Binding QueueJobs}"
- SelectedItem="{Binding SelectedJob}"
+ ItemsSource="{Binding QueueTasks, Mode=OneWay}"
SelectionMode="Extended">
<ListBox.ContextMenu>
@@ -263,16 +262,16 @@
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
- <Image Width="20" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2"
- Height="20" VerticalAlignment="Center" Margin="0,0,5,0"
+ <Image Width="20" Grid.Row="0" Grid.Column="0"
+ Height="20" VerticalAlignment="Center" Margin="0,5,0,0"
Source="Images/Refresh.ico"
ToolTip="Reset job status to Waiting."
Visibility="{Binding Status,
@@ -288,7 +287,7 @@
<Image Width="20" Grid.Row="0" Grid.Column="1"
Height="20"
- Margin="0,5,0,0"
+ Margin="10,5,0,0"
Source="Images/Options24.png"
ToolTip="Edit this Job">
<i:Interaction.Triggers>
@@ -300,9 +299,9 @@
</i:Interaction.Triggers>
</Image>
- <Image Width="20" Grid.Row="1" Grid.Column="1"
+ <Image Width="20" Grid.Row="0" Grid.Column="2"
Height="20"
- Margin="0,5,0,0"
+ Margin="10,5,0,0"
Source="Images/delete.png"
ToolTip="Remove this Job">
<i:Interaction.Triggers>
@@ -317,11 +316,7 @@
</Grid>
-
-
</Grid>
-
-
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
diff --git a/win/CS/HandBrakeWPF/Views/SubtitlesView.xaml b/win/CS/HandBrakeWPF/Views/SubtitlesView.xaml
index 362734851..a99989189 100644
--- a/win/CS/HandBrakeWPF/Views/SubtitlesView.xaml
+++ b/win/CS/HandBrakeWPF/Views/SubtitlesView.xaml
@@ -8,6 +8,7 @@
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:NumericUpDown="clr-namespace:EagleBoost.Wpf.Presentation.Controls.NumericUpDown;assembly=EagleBoost.Wpf.Presentation"
+ xmlns:controls="clr-namespace:HandBrakeWPF.Controls"
d:DesignHeight="153"
d:DesignWidth="319"
mc:Ignorable="d">
@@ -229,15 +230,11 @@
VerticalAlignment="Center"
FontWeight="Bold"
Text="Offset (ms)" />
- <NumericUpDown:NumericUpDown Grid.Row="1"
- Grid.Column="5"
- Width="65"
- Margin="5,0,5,0"
- HorizontalAlignment="Left"
- IsEnabled="{Binding IsSrtSubtitle}"
- Minimum="-10800"
- Value="{Binding SrtOffset, Mode=TwoWay}" />
+ <controls:NumberBox Grid.Row="1" Grid.Column="5" Width="65" Height="24" Margin="5,0,5,0"
+ Minimum="-900000" Maximum="900000" IsEnabled="{Binding IsSrtSubtitle}"
+ Number="{Binding SrtOffset, Mode=TwoWay}" />
+
</Grid>
<!-- Delete -->
diff --git a/win/CS/HandBrakeWPF/Views/TitleSpecificView.xaml b/win/CS/HandBrakeWPF/Views/TitleSpecificView.xaml
index 573236170..00add413e 100644
--- a/win/CS/HandBrakeWPF/Views/TitleSpecificView.xaml
+++ b/win/CS/HandBrakeWPF/Views/TitleSpecificView.xaml
@@ -5,6 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:NumericUpDown="clr-namespace:EagleBoost.Wpf.Presentation.Controls.NumericUpDown;assembly=EagleBoost.Wpf.Presentation"
+ xmlns:controls="clr-namespace:HandBrakeWPF.Controls"
Title="Scan Title"
Width="250"
Background="#FFF1F0EF"
@@ -39,12 +40,9 @@
Margin="10,10,0,10"
Orientation="Horizontal">
<TextBlock Text="Choose a title to scan:" />
- <NumericUpDown:NumericUpDown Width="60"
- Margin="10,0,0,0"
- Maximum="1000"
- Minimum="0"
- Value="{Binding SelectedTitle,
- Mode=TwoWay}" />
+
+ <controls:NumberBox Width="60" Height="24" Margin="10,0,0,0"
+ Minimum="0" Maximum="1000" Number="{Binding SelectedTitle, Mode=TwoWay}" />
</StackPanel>
<StackPanel Grid.Row="2"
diff --git a/win/CS/HandBrakeWPF/Views/VideoView.xaml b/win/CS/HandBrakeWPF/Views/VideoView.xaml
index c9b125abe..4cc1b6b9e 100644
--- a/win/CS/HandBrakeWPF/Views/VideoView.xaml
+++ b/win/CS/HandBrakeWPF/Views/VideoView.xaml
@@ -11,8 +11,9 @@
<Converters:BooleanConverter x:Key="boolConverter" />
<Converters:BooleanToVisibilityConverter x:Key="boolToVisConverter" />
<Converters:EnumComboConverter x:Key="enumComboConverter" />
+ <Converters:InverseBooleanConverter x:Key="inverseConverter" />
<Video:VideoEncoderConverter x:Key="videoEncoderConverter" />
-
+
<Style x:Key="LongToolTipHolder" TargetType="FrameworkElement">
<Setter Property="ToolTipService.ShowDuration" Value="20000" />
</Style>
@@ -109,63 +110,79 @@
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
-
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
-
- <TextBlock Text="Optimise Video:" Margin="0,0,0,8" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontWeight="Bold" VerticalAlignment="Center" />
-
- <!-- Row 1 -->
- <TextBlock Text="x264 Preset:" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" />
- <StackPanel Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" Orientation="Horizontal">
- <Slider Minimum="0" Maximum="9" Width="150" Value="{Binding X264PresetValue, Mode=Default, UpdateSourceTrigger=PropertyChanged}"
+
+ <TextBlock Text="Optimise Video:" Margin="0,0,0,8" Grid.Row="0" Grid.ColumnSpan="2" FontWeight="Bold" VerticalAlignment="Center" />
+
+ <CheckBox Content="Use Advanced Tab instead" Grid.Row="1" IsChecked="{Binding UseAdvancedTab}"
+ Visibility="{Binding ShowAdvancedTab, Converter={StaticResource boolToVisConverter}, ConverterParameter=false}" />
+
+ <Grid Grid.Row="2" Margin="0,5,0,0" IsEnabled="{Binding UseAdvancedTab, Converter={StaticResource inverseConverter}}"
+ Visibility="{Binding DisplayX264Options, Converter={StaticResource boolToVisConverter}}">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ </Grid.RowDefinitions>
+
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+
+
+
+ <!-- Row 1 -->
+ <TextBlock Text="x264 Preset:" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" />
+ <StackPanel Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" Orientation="Horizontal">
+ <Slider Minimum="0" Maximum="9" Width="150" Value="{Binding X264PresetValue, Mode=Default, UpdateSourceTrigger=PropertyChanged}"
IsSnapToTickEnabled="True" TickFrequency="1" TickPlacement="BottomRight" ToolTip="{x:Static Properties:Resources.Video_x264Preset}"
Style="{StaticResource LongToolTipHolder}" />
- <TextBlock Text="{Binding X264Preset, Converter={StaticResource enumComboConverter}}" Margin="5,0,0,0" />
- </StackPanel>
+ <TextBlock Text="{Binding X264Preset, Converter={StaticResource enumComboConverter}}" Margin="5,0,0,0" />
+ </StackPanel>
- <TextBlock Text="x264 Tune:" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" Margin="0,10,0,0" />
- <ComboBox Width="100" Grid.Row="2" Grid.Column="1" Margin="5,10,5,0" Height="22"
+ <TextBlock Text="x264 Tune:" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" Margin="0,10,0,0" />
+ <ComboBox Width="100" Grid.Row="2" Grid.Column="1" Margin="5,10,5,0" Height="22"
ItemsSource="{Binding X264Tunes, Converter={StaticResource enumComboConverter}}"
SelectedItem="{Binding X264Tune, Converter={StaticResource enumComboConverter}}"
ToolTip="{x:Static Properties:Resources.Video_x264Tune}"
Style="{StaticResource LongToolTipHolder}" />
- <CheckBox IsChecked="{Binding FastDecode}" Content="Fast Decode" Grid.Row="2" Grid.Column="2" Margin="10,10,10,0" VerticalAlignment="Center"
+ <CheckBox IsChecked="{Binding FastDecode}" Content="Fast Decode" Grid.Row="2" Grid.Column="2" Margin="10,10,10,0" VerticalAlignment="Center"
ToolTip="{x:Static Properties:Resources.Video_x264FastDecode}"/>
-
- <!-- Row 2-->
- <TextBlock Text="H.264 Profile:" Grid.Row="3" Grid.Column="0" Margin="0,10,0,0" VerticalAlignment="Center" />
- <ComboBox Width="100" Grid.Row="3" Grid.Column="1" Margin="5,10,5,0" Height="22" VerticalAlignment="Center"
+
+ <!-- Row 2-->
+ <TextBlock Text="H.264 Profile:" Grid.Row="3" Grid.Column="0" Margin="0,10,0,0" VerticalAlignment="Center" />
+ <ComboBox Width="100" Grid.Row="3" Grid.Column="1" Margin="5,10,5,0" Height="22" VerticalAlignment="Center"
ItemsSource="{Binding H264Profiles, Converter={StaticResource enumComboConverter}}"
SelectedItem="{Binding H264Profile, Converter={StaticResource enumComboConverter}}"
Style="{StaticResource LongToolTipHolder}"
ToolTip="{x:Static Properties:Resources.Video_x264Profile}" />
- <TextBlock Text="H.264 Level:" Grid.Row="3" Grid.Column="2" Margin="10,10,0,0" VerticalAlignment="Center" />
- <ComboBox Width="100" Grid.Row="3" Grid.Column="3" Margin="5,10,5,0" Height="22" VerticalAlignment="Center"
+ <TextBlock Text="H.264 Level:" Grid.Row="3" Grid.Column="2" Margin="10,10,0,0" VerticalAlignment="Center" />
+ <ComboBox Width="100" Grid.Row="3" Grid.Column="3" Margin="5,10,5,0" Height="22" VerticalAlignment="Center"
ItemsSource="{Binding H264Levels}"
SelectedItem="{Binding H264Level}"
Style="{StaticResource LongToolTipHolder}"
ToolTip="{x:Static Properties:Resources.Video_x264Level}"/>
-
- <!-- Row 3 -->
- <TextBlock Text="Extra Options:" Grid.Row="4" Grid.Column="0" Margin="0,10,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" />
- <TextBox Text="{Binding ExtraArguments, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
+
+ <!-- Row 3 -->
+ <TextBlock Text="Extra Options:" Grid.Row="4" Grid.Column="0" Margin="0,10,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" />
+ <TextBox Text="{Binding ExtraArguments, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Height="30" MaxLines="2" Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="3" Margin="5,10,0,0" VerticalAlignment="Center"
ToolTip="{Binding FullOptionsTooltip}"/>
-
-
+
+
+ </Grid>
</Grid>
+
+
</Grid>
</Grid>
diff --git a/win/CS/HandBrakeWPF/defaultsettings.xml b/win/CS/HandBrakeWPF/defaultsettings.xml
index 73d5742fc..c1a645647 100644
--- a/win/CS/HandBrakeWPF/defaultsettings.xml
+++ b/win/CS/HandBrakeWPF/defaultsettings.xml
@@ -481,4 +481,12 @@
<anyType xmlns:q1="http://www.w3.org/2001/XMLSchema" d4p1:type="q1:boolean" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance">true</anyType>
</value>
</item>
+ <item>
+ <key>
+ <string>LastPreviewDuration</string>
+ </key>
+ <value>
+ <anyType xmlns:q1="http://www.w3.org/2001/XMLSchema" d4p1:type="q1:int" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance">30</anyType>
+ </value>
+ </item>
</dictionary> \ No newline at end of file
diff --git a/win/CS/libraries/WPFDragDrop/GongSolutions.Wpf.DragDrop.XML b/win/CS/libraries/WPFDragDrop/GongSolutions.Wpf.DragDrop.XML
index 24df8ef25..37d4ff9b9 100644
--- a/win/CS/libraries/WPFDragDrop/GongSolutions.Wpf.DragDrop.XML
+++ b/win/CS/libraries/WPFDragDrop/GongSolutions.Wpf.DragDrop.XML
@@ -4,6 +4,35 @@
<name>GongSolutions.Wpf.DragDrop</name>
</assembly>
<members>
+ <member name="T:GongSolutions.Wpf.DragDrop.IDropTarget">
+ <summary>
+ Interface implemented by Drop Handlers.
+ </summary>
+ </member>
+ <member name="M:GongSolutions.Wpf.DragDrop.IDropTarget.DragOver(GongSolutions.Wpf.DragDrop.IDropInfo)">
+ <summary>
+ Updates the current drag state.
+ </summary>
+
+ <param name="dropInfo">
+ Information about the drag.
+ </param>
+
+ <remarks>
+ To allow a drop at the current drag position, the <see cref="P:GongSolutions.Wpf.DragDrop.DropInfo.Effects"/> property on
+ <paramref name="dropInfo"/> should be set to a value other than <see cref="F:System.Windows.DragDropEffects.None"/>
+ and <see cref="P:GongSolutions.Wpf.DragDrop.DropInfo.Data"/> should be set to a non-null value.
+ </remarks>
+ </member>
+ <member name="M:GongSolutions.Wpf.DragDrop.IDropTarget.Drop(GongSolutions.Wpf.DragDrop.IDropInfo)">
+ <summary>
+ Performs a drop.
+ </summary>
+
+ <param name="dropInfo">
+ Information about the drop.
+ </param>
+ </member>
<member name="P:GongSolutions.Wpf.DragDrop.IDropInfo.Data">
<summary>
Gets the drag data.
@@ -222,29 +251,28 @@
Gets th orientation of the current drop target.
</summary>
</member>
- <member name="T:GongSolutions.Wpf.DragDrop.IDropTarget">
+ <member name="T:GongSolutions.Wpf.DragDrop.IDragSource">
<summary>
- Interface implemented by Drop Handlers.
+ Interface implemented by Drag Handlers.
</summary>
</member>
- <member name="M:GongSolutions.Wpf.DragDrop.IDropTarget.DragOver(GongSolutions.Wpf.DragDrop.IDropInfo)">
+ <member name="M:GongSolutions.Wpf.DragDrop.IDragSource.StartDrag(GongSolutions.Wpf.DragDrop.IDragInfo)">
<summary>
- Updates the current drag state.
+ Queries whether a drag can be started.
</summary>
- <param name="dropInfo">
- Information about the drag.
+ <param name="dragInfo">
+ Information about the drag.
</param>
<remarks>
- To allow a drop at the current drag position, the <see cref="P:GongSolutions.Wpf.DragDrop.DropInfo.Effects"/> property on
- <paramref name="dropInfo"/> should be set to a value other than <see cref="F:System.Windows.DragDropEffects.None"/>
- and <see cref="P:GongSolutions.Wpf.DragDrop.DropInfo.Data"/> should be set to a non-null value.
+ To allow a drag to be started, the <see cref="P:GongSolutions.Wpf.DragDrop.DragInfo.Effects"/> property on <paramref name="dragInfo"/>
+ should be set to a value other than <see cref="!:DragDropEffects.None"/>.
</remarks>
</member>
- <member name="M:GongSolutions.Wpf.DragDrop.IDropTarget.Drop(GongSolutions.Wpf.DragDrop.IDropInfo)">
+ <member name="M:GongSolutions.Wpf.DragDrop.IDragSource.Dropped(GongSolutions.Wpf.DragDrop.IDropInfo)">
<summary>
- Performs a drop.
+ Notifies the drag handler that a drop has occurred.
</summary>
<param name="dropInfo">
@@ -419,33 +447,5 @@
will hold a ListBoxItem.
</remarks>
</member>
- <member name="T:GongSolutions.Wpf.DragDrop.IDragSource">
- <summary>
- Interface implemented by Drag Handlers.
- </summary>
- </member>
- <member name="M:GongSolutions.Wpf.DragDrop.IDragSource.StartDrag(GongSolutions.Wpf.DragDrop.IDragInfo)">
- <summary>
- Queries whether a drag can be started.
- </summary>
-
- <param name="dragInfo">
- Information about the drag.
- </param>
-
- <remarks>
- To allow a drag to be started, the <see cref="P:GongSolutions.Wpf.DragDrop.DragInfo.Effects"/> property on <paramref name="dragInfo"/>
- should be set to a value other than <see cref="!:DragDropEffects.None"/>.
- </remarks>
- </member>
- <member name="M:GongSolutions.Wpf.DragDrop.IDragSource.Dropped(GongSolutions.Wpf.DragDrop.IDropInfo)">
- <summary>
- Notifies the drag handler that a drop has occurred.
- </summary>
-
- <param name="dropInfo">
- Information about the drop.
- </param>
- </member>
</members>
</doc>
diff --git a/win/CS/libraries/WPFDragDrop/GongSolutions.Wpf.DragDrop.dll b/win/CS/libraries/WPFDragDrop/GongSolutions.Wpf.DragDrop.dll
index 47a513ca6..5617d91b9 100644
--- a/win/CS/libraries/WPFDragDrop/GongSolutions.Wpf.DragDrop.dll
+++ b/win/CS/libraries/WPFDragDrop/GongSolutions.Wpf.DragDrop.dll
Binary files differ
diff --git a/win/CS/libraries/WPFDragDrop/GongSolutions.Wpf.DragDrop.pdb b/win/CS/libraries/WPFDragDrop/GongSolutions.Wpf.DragDrop.pdb
index 90b441736..ce74a4036 100644
--- a/win/CS/libraries/WPFDragDrop/GongSolutions.Wpf.DragDrop.pdb
+++ b/win/CS/libraries/WPFDragDrop/GongSolutions.Wpf.DragDrop.pdb
Binary files differ
diff --git a/win/CS/libraries/WPFDragDrop/SourceModifications.zip b/win/CS/libraries/WPFDragDrop/SourceModifications.zip
index a08196a6e..9d050d455 100644
--- a/win/CS/libraries/WPFDragDrop/SourceModifications.zip
+++ b/win/CS/libraries/WPFDragDrop/SourceModifications.zip
Binary files differ