summaryrefslogtreecommitdiffstats
path: root/win/CS/HandBrakeWPF
diff options
context:
space:
mode:
authorsr55 <[email protected]>2013-09-06 17:20:29 +0000
committersr55 <[email protected]>2013-09-06 17:20:29 +0000
commite4fae451eef3425f4d94b6cfe61956a676b46218 (patch)
treed398b6e0b75da662ba144fef946067d62898792f /win/CS/HandBrakeWPF
parent10f5aec2de68e0f60a13c7696832e1a02dff187b (diff)
OpenCL: Merging WinGui Changes from Trunk to OpenCL
git-svn-id: svn://svn.handbrake.fr/HandBrake/branches/opencl@5771 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'win/CS/HandBrakeWPF')
-rw-r--r--win/CS/HandBrakeWPF/App.xaml.cs46
-rw-r--r--win/CS/HandBrakeWPF/AppArguments.cs22
-rw-r--r--win/CS/HandBrakeWPF/AttachedProperties/DriveMenu.cs33
-rw-r--r--win/CS/HandBrakeWPF/Commands/CancelScanCommand.cs16
-rw-r--r--win/CS/HandBrakeWPF/Commands/SourceMenuCommand.cs4
-rw-r--r--win/CS/HandBrakeWPF/Constants.cs20
-rw-r--r--win/CS/HandBrakeWPF/Controls/SplitButton/SplitMenuButton.cs295
-rw-r--r--win/CS/HandBrakeWPF/Converters/Audio/AudioBitrateConverter.cs21
-rw-r--r--win/CS/HandBrakeWPF/Converters/Audio/AudioEncoderConverter.cs9
-rw-r--r--win/CS/HandBrakeWPF/Converters/Audio/AudioQueueDisplayConverter.cs17
-rw-r--r--win/CS/HandBrakeWPF/Converters/EnumComboConverter.cs8
-rw-r--r--win/CS/HandBrakeWPF/Converters/InverseBooleanConverter.cs18
-rw-r--r--win/CS/HandBrakeWPF/Converters/Subtitles/SubtitlesQueueDisplayConverter.cs18
-rw-r--r--win/CS/HandBrakeWPF/Converters/Video/EncoderOptionsTooltipConverter.cs67
-rw-r--r--win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs7
-rw-r--r--win/CS/HandBrakeWPF/HandBrakeWPF.csproj34
-rw-r--r--win/CS/HandBrakeWPF/Helpers/AutoNameHelper.cs17
-rw-r--r--win/CS/HandBrakeWPF/Helpers/PictureSize.cs213
-rw-r--r--win/CS/HandBrakeWPF/Helpers/QueueRecoveryHelper.cs4
-rw-r--r--win/CS/HandBrakeWPF/Model/ShellWindow.cs3
-rw-r--r--win/CS/HandBrakeWPF/Model/SourceMenuItem.cs22
-rw-r--r--win/CS/HandBrakeWPF/Properties/Resources.Designer.cs2
-rw-r--r--win/CS/HandBrakeWPF/Properties/Resources.resx4
-rw-r--r--win/CS/HandBrakeWPF/Services/PrePostActionService.cs81
-rw-r--r--win/CS/HandBrakeWPF/Services/ScanServiceWrapper.cs56
-rw-r--r--win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs4
-rw-r--r--win/CS/HandBrakeWPF/Themes/Generic.xaml52
-rw-r--r--win/CS/HandBrakeWPF/UserSettingConstants.cs5
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/AddPresetViewModel.cs26
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/AudioViewModel.cs2
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/CountdownAlertViewModel.cs152
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/EncoderOptionsViewModel.cs1
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/FiltersViewModel.cs53
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/InstantViewModel.cs1014
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/Interfaces/ICountdownAlertViewModel.cs30
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/Interfaces/IInstantViewModel.cs18
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs118
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs29
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/PictureSettingsViewModel.cs310
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs16
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/ShellViewModel.cs53
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/SubtitlesViewModel.cs2
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs226
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/X264ViewModel.cs1
-rw-r--r--win/CS/HandBrakeWPF/Views/AddPresetView.xaml8
-rw-r--r--win/CS/HandBrakeWPF/Views/AudioView.xaml218
-rw-r--r--win/CS/HandBrakeWPF/Views/CountdownAlertView.xaml39
-rw-r--r--win/CS/HandBrakeWPF/Views/CountdownAlertView.xaml.cs27
-rw-r--r--win/CS/HandBrakeWPF/Views/FiltersView.xaml52
-rw-r--r--win/CS/HandBrakeWPF/Views/Images/Advanced.pngbin0 -> 1133 bytes
-rw-r--r--win/CS/HandBrakeWPF/Views/InstantView.xaml202
-rw-r--r--win/CS/HandBrakeWPF/Views/InstantView.xaml.cs27
-rw-r--r--win/CS/HandBrakeWPF/Views/MainView.xaml43
-rw-r--r--win/CS/HandBrakeWPF/Views/OptionsView.xaml21
-rw-r--r--win/CS/HandBrakeWPF/Views/PictureSettingsView.xaml5
-rw-r--r--win/CS/HandBrakeWPF/Views/QueueView.xaml70
-rw-r--r--win/CS/HandBrakeWPF/Views/QueueView.xaml.cs2
-rw-r--r--win/CS/HandBrakeWPF/Views/ShellView.xaml9
-rw-r--r--win/CS/HandBrakeWPF/Views/ShellView.xaml.cs8
-rw-r--r--win/CS/HandBrakeWPF/Views/SubtitlesView.xaml201
-rw-r--r--win/CS/HandBrakeWPF/Views/VideoView.xaml80
-rw-r--r--win/CS/HandBrakeWPF/Views/VideoView.xaml.cs86
62 files changed, 3485 insertions, 762 deletions
diff --git a/win/CS/HandBrakeWPF/App.xaml.cs b/win/CS/HandBrakeWPF/App.xaml.cs
index b674aa7b6..8ad696d7f 100644
--- a/win/CS/HandBrakeWPF/App.xaml.cs
+++ b/win/CS/HandBrakeWPF/App.xaml.cs
@@ -44,14 +44,20 @@ namespace HandBrakeWPF
/// </param>
protected override void OnStartup(StartupEventArgs e)
{
+ if (e.Args.Any(f => f.Equals("--instant")))
+ {
+ AppArguments.IsInstantHandBrake = true;
+ MessageBox.Show("Instant HandBrake is just a prototype for toying with ideas. It may or may not work, or even be included in future builds.", "Warning", MessageBoxButton.OK, MessageBoxImage.Warning);
+ }
+
base.OnStartup(e);
// If we have a file dropped on the icon, try scanning it.
- string[] fileNames = e.Args;
- if (fileNames.Any() && (File.Exists(fileNames[0]) || Directory.Exists(fileNames[0])))
+ string[] args = e.Args;
+ if (args.Any() && (File.Exists(args[0]) || Directory.Exists(args[0])))
{
IMainViewModel mvm = IoC.Get<IMainViewModel>();
- mvm.StartScan(fileNames[0], 0);
+ mvm.StartScan(args[0], 0);
}
}
@@ -102,6 +108,20 @@ namespace HandBrakeWPF
{
this.ShowError(e.Exception.InnerException);
}
+ else if (e.Exception.InnerException != null && e.Exception.InnerException.GetType() == typeof(Castle.MicroKernel.ComponentActivator.ComponentActivatorException))
+ {
+ // Handle Component Activation Exceptions. Can happen when one of the services throws an execption when being constructed.
+ Exception innerException = e.Exception.InnerException.InnerException;
+ if (innerException != null && innerException.InnerException != null &&
+ innerException.InnerException.GetType() == typeof(GeneralApplicationException))
+ {
+ this.ShowError(innerException.InnerException);
+ }
+ else
+ {
+ this.ShowError(innerException);
+ }
+ }
else
{
this.ShowError(e.Exception);
@@ -124,10 +144,10 @@ namespace HandBrakeWPF
if (windowManager != null)
{
ErrorViewModel errorView = new ErrorViewModel();
-
+ GeneralApplicationException applicationException = null;
if (exception.GetType() == typeof(GeneralApplicationException))
{
- GeneralApplicationException applicationException = exception as GeneralApplicationException;
+ applicationException = exception as GeneralApplicationException;
if (applicationException != null)
{
string details = string.Format(
@@ -136,9 +156,7 @@ namespace HandBrakeWPF
Environment.NewLine,
applicationException.Solution,
Environment.NewLine,
- applicationException.ActualException != null
- ? applicationException.ActualException.ToString()
- : "No additional exception information available.");
+ applicationException.ActualException != null ? applicationException.ActualException.ToString() : "No additional exception information available.");
errorView.ErrorMessage = applicationException.Error;
errorView.Solution = applicationException.Solution;
@@ -150,7 +168,17 @@ namespace HandBrakeWPF
errorView.Details = exception.ToString();
}
- windowManager.ShowDialog(errorView);
+ try
+ {
+ windowManager.ShowDialog(errorView);
+ }
+ catch (Exception)
+ {
+ if (applicationException != null)
+ {
+ MessageBox.Show(applicationException.Error + Environment.NewLine + Environment.NewLine + applicationException.Solution, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
}
}
catch (Exception)
diff --git a/win/CS/HandBrakeWPF/AppArguments.cs b/win/CS/HandBrakeWPF/AppArguments.cs
new file mode 100644
index 000000000..970ba9957
--- /dev/null
+++ b/win/CS/HandBrakeWPF/AppArguments.cs
@@ -0,0 +1,22 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="AppArguments.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>
+// Defines the AppArguments type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF
+{
+ /// <summary>
+ /// The app arguments.
+ /// </summary>
+ public class AppArguments
+ {
+ /// <summary>
+ /// Gets or sets a value indicating whether is instant hand brake.
+ /// </summary>
+ public static bool IsInstantHandBrake { get; set; }
+ }
+}
diff --git a/win/CS/HandBrakeWPF/AttachedProperties/DriveMenu.cs b/win/CS/HandBrakeWPF/AttachedProperties/DriveMenu.cs
index 1149b579e..ffe8fe634 100644
--- a/win/CS/HandBrakeWPF/AttachedProperties/DriveMenu.cs
+++ b/win/CS/HandBrakeWPF/AttachedProperties/DriveMenu.cs
@@ -14,8 +14,8 @@ namespace HandBrakeWPF.AttachedProperties
using System.Linq;
using System.Windows;
using System.Windows.Controls;
- using System.Windows.Media.Imaging;
+ using HandBrake.ApplicationServices.Exceptions;
using HandBrake.ApplicationServices.Utilities;
using HandBrakeWPF.Commands;
@@ -32,7 +32,7 @@ namespace HandBrakeWPF.AttachedProperties
/// </summary>
public static readonly DependencyProperty ShowAvailableDrivesProperty = DependencyProperty.RegisterAttached(
"ShowAvailableDrives",
- typeof(Boolean),
+ typeof(bool),
typeof(DriveMenu),
new PropertyMetadata(false, OnShowAvailableDrivesChanged));
@@ -76,11 +76,11 @@ namespace HandBrakeWPF.AttachedProperties
/// </param>
private static void OnShowAvailableDrivesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
- Menu menu = d as Menu;
+ MenuItem menu = d as MenuItem;
if (menu != null)
{
- menu.PreviewMouseDown -= MenuMouseDown;
- menu.PreviewMouseDown += MenuMouseDown;
+ menu.SubmenuOpened -= MenuMouseDown;
+ menu.SubmenuOpened += MenuMouseDown;
}
}
@@ -93,9 +93,15 @@ namespace HandBrakeWPF.AttachedProperties
/// <param name="e">
/// The e.
/// </param>
- private static void MenuMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ private static void MenuMouseDown(object sender, RoutedEventArgs e)
{
- Menu menu = sender as Menu;
+ MenuItem menu = sender as MenuItem;
+ MenuItem childMenuItem = e.OriginalSource as MenuItem;
+ if (childMenuItem != null && "Title Specific Scan".Equals(childMenuItem.Header))
+ {
+ return; // Skip, it's just a child menu.
+ }
+
if (menu != null)
{
MainViewModel mvm = menu.DataContext as MainViewModel;
@@ -111,16 +117,25 @@ namespace HandBrakeWPF.AttachedProperties
let driveInformation = item
select new SourceMenuItem
{
- Image = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/HandBrake;component/Views/Images/disc_small.png")), Width = 16, Height = 16 },
Text = string.Format("{0} ({1})", item.RootDirectory, item.VolumeLabel),
Command = new SourceMenuCommand(() => mvm.ProcessDrive(driveInformation)),
Tag = item,
IsDrive = true
})
{
- mvm.SourceMenu.Add(menuItem);
+ mvm.SourceMenu.Add(menuItem);
}
}
+ else
+ {
+ throw new GeneralApplicationException(
+ "DEBUG - Datacontext wasn't set!", "Please report this on the forum.", null);
+ }
+ }
+ else
+ {
+ throw new GeneralApplicationException(
+ "DEBUG - Source Menu wasn't set!", "Please report this on the forum.", null);
}
}
}
diff --git a/win/CS/HandBrakeWPF/Commands/CancelScanCommand.cs b/win/CS/HandBrakeWPF/Commands/CancelScanCommand.cs
index 617778b08..e9ec9966a 100644
--- a/win/CS/HandBrakeWPF/Commands/CancelScanCommand.cs
+++ b/win/CS/HandBrakeWPF/Commands/CancelScanCommand.cs
@@ -49,7 +49,7 @@ namespace HandBrakeWPF.Commands
/// </param>
private void ScanServiceWrapperScanCompleted(object sender, HandBrake.ApplicationServices.EventArgs.ScanCompletedEventArgs e)
{
- Caliburn.Micro.Execute.OnUIThread(() => this.CanExecuteChanged(sender, EventArgs.Empty));
+ Caliburn.Micro.Execute.OnUIThread(this.OnCanExecuteChanged);
}
/// <summary>
@@ -64,7 +64,7 @@ namespace HandBrakeWPF.Commands
/// </param>
private void ScanServiceWrapperScanStared(object sender, EventArgs e)
{
- Caliburn.Micro.Execute.OnUIThread(() => this.CanExecuteChanged(sender, EventArgs.Empty));
+ Caliburn.Micro.Execute.OnUIThread(this.OnCanExecuteChanged);
}
#region Implementation of ICommand
@@ -100,6 +100,18 @@ namespace HandBrakeWPF.Commands
/// </summary>
public event EventHandler CanExecuteChanged;
+ /// <summary>
+ /// The on can execute changed.
+ /// </summary>
+ protected virtual void OnCanExecuteChanged()
+ {
+ EventHandler handler = this.CanExecuteChanged;
+ if (handler != null)
+ {
+ handler(this, EventArgs.Empty);
+ }
+ }
+
#endregion
}
}
diff --git a/win/CS/HandBrakeWPF/Commands/SourceMenuCommand.cs b/win/CS/HandBrakeWPF/Commands/SourceMenuCommand.cs
index 661ef7fe3..8edc537fc 100644
--- a/win/CS/HandBrakeWPF/Commands/SourceMenuCommand.cs
+++ b/win/CS/HandBrakeWPF/Commands/SourceMenuCommand.cs
@@ -52,8 +52,6 @@ namespace HandBrakeWPF.Commands
#region Implemented Interfaces
- #region ICommand
-
/// <summary>
/// The can execute.
/// </summary>
@@ -80,7 +78,5 @@ namespace HandBrakeWPF.Commands
}
#endregion
-
- #endregion
}
} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Constants.cs b/win/CS/HandBrakeWPF/Constants.cs
index 1d279427a..36732611d 100644
--- a/win/CS/HandBrakeWPF/Constants.cs
+++ b/win/CS/HandBrakeWPF/Constants.cs
@@ -38,5 +38,25 @@ namespace HandBrakeWPF
/// The title.
/// </summary>
public const string Title = "{title}";
+
+ /// <summary>
+ /// The quality.
+ /// </summary>
+ public const string Quality = "{quality}";
+
+ /// <summary>
+ /// The quality.
+ /// </summary>
+ public const string Date = "{date}";
+
+ /// <summary>
+ /// The quality.
+ /// </summary>
+ public const string Time = "{time}";
+
+ /// <summary>
+ /// The bitrate.
+ /// </summary>
+ public const string Bitrate = "{bitrate}";
}
}
diff --git a/win/CS/HandBrakeWPF/Controls/SplitButton/SplitMenuButton.cs b/win/CS/HandBrakeWPF/Controls/SplitButton/SplitMenuButton.cs
new file mode 100644
index 000000000..46e662620
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Controls/SplitButton/SplitMenuButton.cs
@@ -0,0 +1,295 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="SplitMenuButton.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>
+// A Split Menu Button Control
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Controls.SplitButton
+{
+ using System;
+ using System.Collections.ObjectModel;
+ using System.Windows;
+ using System.Windows.Controls;
+ using System.Windows.Input;
+
+ /// <summary>
+ /// A Split Menu Button Control
+ /// </summary>
+ [TemplatePart(Name = SplitElementName, Type = typeof(UIElement))]
+ public class SplitMenuButton : Button
+ {
+ #region Fields and Constants
+
+ /// <summary>
+ /// The split element name.
+ /// </summary>
+ private const string SplitElementName = "SplitElement";
+
+ /// <summary>
+ /// The item source for the context menu
+ /// </summary>
+ private readonly ObservableCollection<object> itemSource = new ObservableCollection<object>();
+
+ /// <summary>
+ /// The is mouse over split element.
+ /// </summary>
+ private bool IsMouseOverSplitElement;
+
+ /// <summary>
+ /// The context menu.
+ /// </summary>
+ private ContextMenu contextMenu;
+
+ /// <summary>
+ /// The context menu initial offset.
+ /// </summary>
+ private Point contextMenuInitialOffset;
+
+ /// <summary>
+ /// The logical child.
+ /// </summary>
+ private DependencyObject logicalChild;
+
+ /// <summary>
+ /// The split element.
+ /// </summary>
+ private UIElement splitElement;
+
+ #endregion
+
+ #region Constructors and Destructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SplitMenuButton" /> class.
+ /// </summary>
+ public SplitMenuButton()
+ {
+ this.DefaultStyleKey = typeof(SplitMenuButton);
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets the ItemSource for the Context Menu
+ /// </summary>
+ public Collection<object> ItemSource
+ {
+ get
+ {
+ return this.itemSource;
+ }
+ }
+
+ #endregion
+
+ #region Public Methods and Operators
+
+ /// <summary>
+ /// Called when the template is changed.
+ /// </summary>
+ public override void OnApplyTemplate()
+ {
+ // Unhook existing handlers
+ if (this.splitElement != null)
+ {
+ this.splitElement.MouseEnter -= this.SplitElement_MouseEnter;
+ this.splitElement.MouseLeave -= this.SplitElement_MouseLeave;
+ this.splitElement = null;
+ }
+ if (this.contextMenu != null)
+ {
+ this.contextMenu.Opened -= this.ContextMenu_Opened;
+ this.contextMenu.Closed -= this.ContextMenu_Closed;
+ this.contextMenu = null;
+ }
+
+ if (this.logicalChild != null)
+ {
+ this.RemoveLogicalChild(this.logicalChild);
+ this.logicalChild = null;
+ }
+
+ // Apply new template
+ base.OnApplyTemplate();
+
+ // Hook new event handlers
+ this.splitElement = this.GetTemplateChild(SplitElementName) as UIElement;
+ if (this.splitElement != null)
+ {
+ this.splitElement.MouseEnter += this.SplitElement_MouseEnter;
+ this.splitElement.MouseLeave += this.SplitElement_MouseLeave;
+
+ this.contextMenu = ContextMenuService.GetContextMenu(this.splitElement);
+ if (this.contextMenu != null)
+ {
+ // Add the ContextMenu as a logical child (for DataContext and RoutedCommands)
+ this.contextMenu.IsOpen = true;
+ DependencyObject current = this.contextMenu;
+ do
+ {
+ this.logicalChild = current;
+ current = LogicalTreeHelper.GetParent(current);
+ }
+ while (null != current);
+
+ this.contextMenu.IsOpen = false;
+ this.AddLogicalChild(this.logicalChild);
+
+ this.contextMenu.Opened += this.ContextMenu_Opened;
+ this.contextMenu.Closed += this.ContextMenu_Closed;
+ }
+ }
+ }
+
+ #endregion
+
+ #region Methods
+
+ /// <summary>
+ /// Called when the Button is clicked.
+ /// </summary>
+ protected override void OnClick()
+ {
+ if (this.IsMouseOverSplitElement)
+ {
+ this.OpenButtonMenu();
+ }
+ else
+ {
+ base.OnClick();
+ }
+ }
+
+ /// <summary>
+ /// Called when a key is pressed.
+ /// </summary>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ if (null == e)
+ {
+ throw new ArgumentNullException("e");
+ }
+
+ if (Key.Down == e.Key || Key.Up == e.Key)
+ {
+ this.Dispatcher.BeginInvoke((Action)this.OpenButtonMenu);
+ }
+ else
+ {
+ base.OnKeyDown(e);
+ }
+ }
+
+ /// <summary>
+ /// The open button menu.
+ /// </summary>
+ protected void OpenButtonMenu()
+ {
+ if ((0 < this.ItemSource.Count) && (null != this.contextMenu))
+ {
+ this.contextMenu.HorizontalOffset = 0;
+ this.contextMenu.VerticalOffset = 0;
+ this.contextMenu.IsOpen = true;
+ }
+ }
+
+ /// <summary>
+ /// The context menu closed.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The RoutedEventArgs.
+ /// </param>
+ private void ContextMenu_Closed(object sender, RoutedEventArgs e)
+ {
+ this.LayoutUpdated -= this.SplitButton_LayoutUpdated;
+ this.Focus();
+ }
+
+ /// <summary>
+ /// The context menu opened.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The RoutedEventArgs.
+ /// </param>
+ private void ContextMenu_Opened(object sender, RoutedEventArgs e)
+ {
+ this.contextMenuInitialOffset = this.TranslatePoint(new Point(0, this.ActualHeight), this.contextMenu);
+ this.UpdateContextMenuOffsets();
+ this.LayoutUpdated += this.SplitButton_LayoutUpdated;
+ }
+
+ /// <summary>
+ /// The split button layout updated.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The EventArgs.
+ /// </param>
+ private void SplitButton_LayoutUpdated(object sender, EventArgs e)
+ {
+ this.UpdateContextMenuOffsets();
+ }
+
+ /// <summary>
+ /// The split element_ mouse enter.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The MouseEventArgs.
+ /// </param>
+ private void SplitElement_MouseEnter(object sender, MouseEventArgs e)
+ {
+ this.IsMouseOverSplitElement = true;
+ }
+
+ /// <summary>
+ /// The split element mouse leave.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The MouseEventArgs
+ /// </param>
+ private void SplitElement_MouseLeave(object sender, MouseEventArgs e)
+ {
+ this.IsMouseOverSplitElement = false;
+ }
+
+ /// <summary>
+ /// The update context menu offsets.
+ /// </summary>
+ private void UpdateContextMenuOffsets()
+ {
+ var currentOffset = new Point();
+ Point desiredOffset = this.contextMenuInitialOffset;
+
+ this.contextMenu.HorizontalOffset = desiredOffset.X - currentOffset.X;
+ this.contextMenu.VerticalOffset = desiredOffset.Y - currentOffset.Y;
+ if (FlowDirection.RightToLeft == this.FlowDirection)
+ {
+ this.contextMenu.HorizontalOffset *= -1;
+ }
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Converters/Audio/AudioBitrateConverter.cs b/win/CS/HandBrakeWPF/Converters/Audio/AudioBitrateConverter.cs
index f4e805957..bd7aeffca 100644
--- a/win/CS/HandBrakeWPF/Converters/Audio/AudioBitrateConverter.cs
+++ b/win/CS/HandBrakeWPF/Converters/Audio/AudioBitrateConverter.cs
@@ -70,14 +70,10 @@ namespace HandBrakeWPF.Converters.Audio
int samplerate = this.GetBestSampleRate(track);
int srShift = this.GetSamplerateShift(samplerate);
int lfeCount = this.GetLowFreqChannelCount(track.MixDown);
- int channels = this.GetChannelCount(track.MixDown) - lfeCount;
+ int channels = this.GetDiscreteChannelCount(track.MixDown) - lfeCount;
switch (track.Encoder)
{
- case AudioEncoder.Faac:
- low = (channels + lfeCount) * 32;
- max = (channels + lfeCount) * (192 >> srShift);
- break;
case AudioEncoder.ffaac:
low = ((channels + lfeCount) * 32);
max = ((channels + lfeCount) * ((192 + (64 * ((samplerate << srShift) >= 44100 ? 1 : 0))) >> srShift));
@@ -101,8 +97,17 @@ namespace HandBrakeWPF.Converters.Audio
case AudioEncoder.Mp3Passthru:
case AudioEncoder.Passthrough:
case AudioEncoder.ffflac:
+ case AudioEncoder.ffflac24:
max = 1536; // Since we don't care, just set it to the max.
break;
+ case AudioEncoder.fdkaac:
+ low = channels * samplerate * 2 / 3000;
+ max = channels * samplerate * 6 / 1000;
+ break;
+ case AudioEncoder.fdkheaac:
+ low = (channels * (12 + (4 * (samplerate >= 44100 ? 1 : 0))));
+ max = (channels - (channels > 2 ? 1 : 0)) * (48 + (16 * (samplerate >= 22050 ? 1 : 0)));
+ break;
default:
max = 768;
break;
@@ -132,7 +137,7 @@ namespace HandBrakeWPF.Converters.Audio
/// <returns>
/// The System.Int32.
/// </returns>
- private int GetChannelCount(Mixdown mixdown)
+ private int GetDiscreteChannelCount(Mixdown mixdown)
{
switch (mixdown)
{
@@ -228,6 +233,10 @@ namespace HandBrakeWPF.Converters.Audio
{
// AC-3 < 32 kHz suffers from poor hardware compatibility
bestSamplerate = 32000;
+ }
+ else if ((samplerate < 16000) && (track.Encoder == AudioEncoder.fdkheaac))
+ {
+ bestSamplerate = 16000;
}
else
{
diff --git a/win/CS/HandBrakeWPF/Converters/Audio/AudioEncoderConverter.cs b/win/CS/HandBrakeWPF/Converters/Audio/AudioEncoderConverter.cs
index 1db7a7c0a..0b1c2258d 100644
--- a/win/CS/HandBrakeWPF/Converters/Audio/AudioEncoderConverter.cs
+++ b/win/CS/HandBrakeWPF/Converters/Audio/AudioEncoderConverter.cs
@@ -51,6 +51,8 @@ namespace HandBrakeWPF.Converters.Audio
List<AudioEncoder> encoders = EnumHelper<AudioEncoder>.GetEnumList().ToList();
EncodeTask task = values[1] as EncodeTask;
+ encoders.Remove(AudioEncoder.faac);
+
if (task != null && task.OutputFormat != OutputFormat.Mkv)
{
encoders.Remove(AudioEncoder.Vorbis);
@@ -71,7 +73,12 @@ namespace HandBrakeWPF.Converters.Audio
return EnumHelper<AudioEncoder>.GetEnumDisplayValuesSubset(encoders);
}
- return EnumHelper<AudioEncoder>.GetDisplay((AudioEncoder)values[0]);
+ if (values.Any())
+ {
+ return EnumHelper<AudioEncoder>.GetDisplay((AudioEncoder)values[0]);
+ }
+
+ return EnumHelper<AudioEncoder>.GetDisplay(AudioEncoder.ffaac);
}
/// <summary>
diff --git a/win/CS/HandBrakeWPF/Converters/Audio/AudioQueueDisplayConverter.cs b/win/CS/HandBrakeWPF/Converters/Audio/AudioQueueDisplayConverter.cs
index d081be1a6..c729fac82 100644
--- a/win/CS/HandBrakeWPF/Converters/Audio/AudioQueueDisplayConverter.cs
+++ b/win/CS/HandBrakeWPF/Converters/Audio/AudioQueueDisplayConverter.cs
@@ -13,6 +13,7 @@ namespace HandBrakeWPF.Converters.Audio
using System.Collections.ObjectModel;
using System.Globalization;
using System.Text;
+ using System.Threading.Tasks;
using System.Windows.Data;
using HandBrake.ApplicationServices.Model.Encoding;
@@ -39,18 +40,16 @@ namespace HandBrakeWPF.Converters.Audio
{
foreach (AudioTrack track in tracks)
{
- if (string.IsNullOrEmpty(audioTracks.ToString()))
- {
- audioTracks.Append(EnumHelper<AudioEncoder>.GetDisplay(track.Encoder));
- }
- else
- {
- audioTracks.Append(", " + EnumHelper<AudioEncoder>.GetDisplay(track.Encoder));
- }
+ string trackName = string.Format(
+ "{0} {1}",
+ track.ScannedTrack.TrackNumber,
+ track.ScannedTrack.Language);
+
+ audioTracks.Append(string.Format("{0} - {1} To {2}{3}", trackName, track.TrackName, EnumHelper<AudioEncoder>.GetDisplay(track.Encoder), Environment.NewLine));
}
}
- return audioTracks.ToString();
+ return audioTracks.ToString().Trim();
}
/// <summary>
diff --git a/win/CS/HandBrakeWPF/Converters/EnumComboConverter.cs b/win/CS/HandBrakeWPF/Converters/EnumComboConverter.cs
index 6f89bb52f..d65b7f9f1 100644
--- a/win/CS/HandBrakeWPF/Converters/EnumComboConverter.cs
+++ b/win/CS/HandBrakeWPF/Converters/EnumComboConverter.cs
@@ -65,6 +65,10 @@ namespace HandBrakeWPF.Converters
{
return EnumHelper<Mixdown>.GetEnumDisplayValues(typeof(Mixdown));
}
+ if (targetType == typeof(QsvPreset) || value.GetType() == typeof(QsvPreset))
+ {
+ return EnumHelper<QsvPreset>.GetDisplay((QsvPreset)value);
+ }
if (value is IEnumerable<PresetPictureSettingsMode>)
{
@@ -182,6 +186,10 @@ namespace HandBrakeWPF.Converters
{
return EnumHelper<Mixdown>.GetValue(value.ToString());
}
+ if (targetType == typeof(QsvPreset) || value.GetType() == typeof(QsvPreset))
+ {
+ return EnumHelper<QsvPreset>.GetValue(value.ToString());
+ }
if (targetType == typeof(PresetPictureSettingsMode) || value.GetType() == typeof(PresetPictureSettingsMode))
{
diff --git a/win/CS/HandBrakeWPF/Converters/InverseBooleanConverter.cs b/win/CS/HandBrakeWPF/Converters/InverseBooleanConverter.cs
index f44e18a3e..b935953eb 100644
--- a/win/CS/HandBrakeWPF/Converters/InverseBooleanConverter.cs
+++ b/win/CS/HandBrakeWPF/Converters/InverseBooleanConverter.cs
@@ -16,13 +16,9 @@ namespace HandBrakeWPF.Converters
/// <summary>
/// The inverse boolean converter.
/// </summary>
- [ValueConversion(typeof(bool), typeof(bool))]
+ [ValueConversion(typeof(bool?), typeof(bool))]
public class InverseBooleanConverter : IValueConverter
{
- #region Implemented Interfaces
-
- #region IValueConverter
-
/// <summary>
/// The convert.
/// </summary>
@@ -43,12 +39,14 @@ namespace HandBrakeWPF.Converters
/// </returns>
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
- if (targetType != typeof(bool))
+ if (targetType != typeof(bool?) && targetType != typeof(bool))
{
throw new InvalidOperationException("The target must be a boolean");
}
- return !(bool)value;
+ bool result;
+ bool.TryParse(value.ToString(), out result);
+ return !result;
}
/// <summary>
@@ -71,11 +69,7 @@ namespace HandBrakeWPF.Converters
/// </returns>
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
- throw new NotSupportedException();
+ return null;
}
-
- #endregion
-
- #endregion
}
} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Converters/Subtitles/SubtitlesQueueDisplayConverter.cs b/win/CS/HandBrakeWPF/Converters/Subtitles/SubtitlesQueueDisplayConverter.cs
index e30967ae3..3e5f5d113 100644
--- a/win/CS/HandBrakeWPF/Converters/Subtitles/SubtitlesQueueDisplayConverter.cs
+++ b/win/CS/HandBrakeWPF/Converters/Subtitles/SubtitlesQueueDisplayConverter.cs
@@ -32,24 +32,20 @@ namespace HandBrakeWPF.Converters.Subtitles
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
ObservableCollection<SubtitleTrack> tracks = value as ObservableCollection<SubtitleTrack>;
- StringBuilder audioTracks = new StringBuilder();
+ StringBuilder sutitleTracks = new StringBuilder();
if (tracks != null)
{
foreach (SubtitleTrack track in tracks)
{
- string text = track.SourceTrack != null ? track.SourceTrack.ToString() : (track.SrtFileName + ".srt");
- if (string.IsNullOrEmpty(audioTracks.ToString()))
- {
- audioTracks.Append(text);
- }
- else
- {
- audioTracks.Append(", " + text);
- }
+ string text = track.SourceTrack != null
+ ? track.SourceTrack.ToString()
+ : (track.SrtFileName + ".srt");
+
+ sutitleTracks.AppendLine(text);
}
}
- return string.IsNullOrEmpty(audioTracks.ToString()) ? "None" : audioTracks.ToString();
+ return string.IsNullOrEmpty(sutitleTracks.ToString()) ? "None" : sutitleTracks.ToString().Trim();
}
/// <summary>
diff --git a/win/CS/HandBrakeWPF/Converters/Video/EncoderOptionsTooltipConverter.cs b/win/CS/HandBrakeWPF/Converters/Video/EncoderOptionsTooltipConverter.cs
new file mode 100644
index 000000000..dc78ad1ca
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Converters/Video/EncoderOptionsTooltipConverter.cs
@@ -0,0 +1,67 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="EncoderOptionsTooltipConverter.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 x 264 queue tooltip converter.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Converters.Video
+{
+ using System;
+ using System.Globalization;
+ using System.Windows.Data;
+
+ using HandBrake.ApplicationServices.Model;
+ using HandBrake.ApplicationServices.Utilities;
+ using HandBrake.Interop.Model.Encoding;
+ using HandBrake.Interop.Model.Encoding.x264;
+
+ /// <summary>
+ /// The x 264 queue tooltip converter.
+ /// </summary>
+ public class EncoderOptionsTooltipConverter : IValueConverter
+ {
+ /// <summary>
+ /// Converts a value.
+ /// </summary>
+ /// <returns>
+ /// A converted value. If the method returns null, the valid null value is used.
+ /// </returns>
+ /// <param name="value">The value produced by the binding source.</param><param name="targetType">The type of the binding target property.</param><param name="parameter">The converter parameter to use.</param><param name="culture">The culture to use in the converter.</param>
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ EncodeTask task = value as EncodeTask;
+ if (task != null && task.VideoEncoder == VideoEncoder.X264)
+ {
+ if (task.ShowAdvancedTab)
+ {
+ return task.AdvancedEncoderOptions;
+ }
+
+ return string.Format("Preset: {0}{5}Tune: {1}{5}Profile: {2}{5}Level: {3}{5}Extra Arguments: {4}{5}",
+ EnumHelper<x264Preset>.GetDisplay(task.X264Preset),
+ EnumHelper<x264Tune>.GetDisplay(task.X264Tune),
+ task.H264Profile,
+ task.H264Level,
+ string.IsNullOrEmpty(task.ExtraAdvancedArguments) ? "None" : task.ExtraAdvancedArguments,
+ Environment.NewLine);
+ }
+
+ return task != null ? task.AdvancedEncoderOptions.Trim() : string.Empty;
+ }
+
+ /// <summary>
+ /// Converts a value.
+ /// </summary>
+ /// <returns>
+ /// A converted value. If the method returns null, the valid null value is used.
+ /// </returns>
+ /// <param name="value">The value that is produced by the binding target.</param><param name="targetType">The type to convert to.</param><param name="parameter">The converter parameter to use.</param><param name="culture">The culture to use in the converter.</param>
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs b/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs
index 6ec2dc964..e7f76f813 100644
--- a/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs
+++ b/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs
@@ -50,11 +50,16 @@ namespace HandBrakeWPF.Converters.Video
List<VideoEncoder> encoders = EnumHelper<VideoEncoder>.GetEnumList().ToList();
EncodeTask task = values[1] as EncodeTask;
- if (task != null && task.OutputFormat != OutputFormat.Mkv)
+ if (task != null && task.OutputFormat != OutputFormat.Mkv && task.OutputFormat != OutputFormat.av_mkv)
{
encoders.Remove(VideoEncoder.Theora);
}
+ if (!SystemInfo.IsQsvAvailable)
+ {
+ encoders.Remove(VideoEncoder.QuickSync);
+ }
+
return EnumHelper<VideoEncoder>.GetEnumDisplayValuesSubset(encoders);
}
diff --git a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
index 83535814b..b0094ce23 100644
--- a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
+++ b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
@@ -100,6 +100,7 @@
<HintPath>..\libraries\OokiiDialogs\Ookii.Dialogs.Wpf.dll</HintPath>
</Reference>
<Reference Include="PresentationFramework" />
+ <Reference Include="PresentationFramework.Aero" />
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Drawing" />
@@ -123,6 +124,7 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
+ <Compile Include="AppArguments.cs" />
<Compile Include="AttachedProperties\DriveMenu.cs" />
<Compile Include="AttachedProperties\MenuItemExtensions.cs" />
<Compile Include="Commands\CancelScanCommand.cs" />
@@ -132,6 +134,12 @@
<Compile Include="Commands\SourceMenuCommand.cs" />
<Compile Include="Commands\AdvancedEncoderOptionsCommand.cs" />
<Compile Include="Constants.cs" />
+ <Compile Include="Controls\SplitButton\SplitMenuButton.cs" />
+ <Compile Include="ViewModels\CountdownAlertViewModel.cs" />
+ <Compile Include="ViewModels\Interfaces\ICountdownAlertViewModel.cs" />
+ <Compile Include="Views\CountdownAlertView.xaml.cs">
+ <DependentUpon>CountdownAlertView.xaml</DependentUpon>
+ </Compile>
<Compile Include="Controls\DropButton\DropButton.cs" />
<Compile Include="Controls\TimeSpanBox.xaml.cs">
<DependentUpon>TimeSpanBox.xaml</DependentUpon>
@@ -155,9 +163,11 @@
<Compile Include="Converters\Options\OptionsTabNameConverter.cs" />
<Compile Include="Converters\Subtitles\SubtitlesQueueDisplayConverter.cs" />
<Compile Include="Converters\Video\VideoEncoderConverter.cs" />
+ <Compile Include="Converters\Video\EncoderOptionsTooltipConverter.cs" />
<Compile Include="Helpers\GrayscaleImage.cs" />
<Compile Include="Helpers\GrowlCommunicator.cs" />
<Compile Include="Helpers\AppStyleHelper.cs" />
+ <Compile Include="Helpers\PictureSize.cs" />
<Compile Include="Model\OptionsTab.cs" />
<Compile Include="Model\SelectionTitle.cs" />
<Compile Include="Services\EncodeServiceWrapper.cs" />
@@ -174,7 +184,9 @@
<Compile Include="Services\PrePostActionService.cs" />
<Compile Include="ViewModels\AdvancedViewModel.cs" />
<Compile Include="ViewModels\EncoderOptionsViewModel.cs" />
+ <Compile Include="ViewModels\InstantViewModel.cs" />
<Compile Include="ViewModels\Interfaces\IEncoderOptionsViewModel.cs" />
+ <Compile Include="ViewModels\Interfaces\IInstantViewModel.cs" />
<Compile Include="ViewModels\Interfaces\IX264ViewModel.cs" />
<Compile Include="ViewModels\Interfaces\IQueueSelectionViewModel.cs" />
<Compile Include="ViewModels\QueueSelectionViewModel.cs" />
@@ -184,6 +196,9 @@
<Compile Include="Views\EncoderOptionsView.xaml.cs">
<DependentUpon>EncoderOptionsView.xaml</DependentUpon>
</Compile>
+ <Compile Include="Views\InstantView.xaml.cs">
+ <DependentUpon>InstantView.xaml</DependentUpon>
+ </Compile>
<Compile Include="Views\QueueSelectionView.xaml.cs">
<DependentUpon>QueueSelectionView.xaml</DependentUpon>
</Compile>
@@ -329,6 +344,14 @@
<AppDesigner Include="Properties\" />
</ItemGroup>
<ItemGroup>
+ <Page Include="Themes\Generic.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="Views\CountdownAlertView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Controls\TimeSpanBox.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -353,6 +376,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
+ <Page Include="Views\InstantView.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
<Page Include="Views\QueueSelectionView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -431,10 +458,10 @@
</Page>
</ItemGroup>
<ItemGroup>
- <Content Include="defaultsettings.xml">
+ <EmbeddedResource Include="defaultsettings.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<SubType>Designer</SubType>
- </Content>
+ </EmbeddedResource>
<Resource Include="Views\Images\add40.png" />
<Resource Include="Views\Images\add.png" />
<Resource Include="Views\Images\remove.png" />
@@ -490,6 +517,9 @@
<Name>HandBrake.Server</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <Resource Include="Views\Images\Advanced.png" />
+ </ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(ProgramFiles)\MSBuild\StyleCop\v4.*\StyleCop.targets" />
diff --git a/win/CS/HandBrakeWPF/Helpers/AutoNameHelper.cs b/win/CS/HandBrakeWPF/Helpers/AutoNameHelper.cs
index 407748027..cfe1714a0 100644
--- a/win/CS/HandBrakeWPF/Helpers/AutoNameHelper.cs
+++ b/win/CS/HandBrakeWPF/Helpers/AutoNameHelper.cs
@@ -19,6 +19,7 @@ namespace HandBrakeWPF.Helpers
using HandBrake.ApplicationServices.Model;
using HandBrake.ApplicationServices.Model.Encoding;
using HandBrake.ApplicationServices.Services.Interfaces;
+ using HandBrake.Interop.Model.Encoding;
/// <summary>
/// The Destination AutoName Helper
@@ -88,7 +89,17 @@ namespace HandBrakeWPF.Helpers
destinationFilename = destinationFilename.Replace("{source}", sourceName)
.Replace(Constants.Title, dvdTitle)
.Replace(Constants.Chapters, combinedChapterTag)
- .Replace("{date}", DateTime.Now.Date.ToShortDateString().Replace('/', '-'));
+ .Replace(Constants.Date, DateTime.Now.Date.ToShortDateString().Replace('/', '-'))
+ .Replace(Constants.Time, DateTime.Now.ToString("HH:mm"));
+
+ if (task.VideoEncodeRateType == VideoEncodeRateType.ConstantQuality)
+ {
+ destinationFilename = destinationFilename.Replace(Constants.Quality, task.Quality.ToString());
+ }
+ else
+ {
+ destinationFilename = destinationFilename.Replace(Constants.Bitrate, task.VideoBitrate.ToString());
+ }
}
else
destinationFilename = sourceName + "_T" + dvdTitle + "_C" + combinedChapterTag;
@@ -96,7 +107,7 @@ namespace HandBrakeWPF.Helpers
/*
* File Extension
*/
- if (task.OutputFormat == OutputFormat.Mp4 || task.OutputFormat == OutputFormat.M4V)
+ if (task.OutputFormat == OutputFormat.Mp4 || task.OutputFormat == OutputFormat.M4V || task.OutputFormat == OutputFormat.av_mp4)
{
switch (userSettingService.GetUserSetting<int>(UserSettingConstants.UseM4v))
{
@@ -111,7 +122,7 @@ namespace HandBrakeWPF.Helpers
break;
}
}
- else if (task.OutputFormat == OutputFormat.Mkv)
+ else if (task.OutputFormat == OutputFormat.Mkv || task.OutputFormat == OutputFormat.av_mkv)
destinationFilename += ".mkv";
/*
diff --git a/win/CS/HandBrakeWPF/Helpers/PictureSize.cs b/win/CS/HandBrakeWPF/Helpers/PictureSize.cs
new file mode 100644
index 000000000..8adfa909e
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Helpers/PictureSize.cs
@@ -0,0 +1,213 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="PictureSize.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>
+// Defines the PictureSize type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Helpers
+{
+ using System;
+ using System.Runtime.InteropServices;
+
+ using HandBrake.Interop.HbLib;
+ using HandBrake.Interop.Model;
+ using HandBrake.Interop.Model.Encoding;
+
+ /// <summary>
+ /// The picture size Helpers
+ /// </summary>
+ public class PictureSize
+ {
+ /// <summary>
+ /// The picture settings job.
+ /// </summary>
+ public class PictureSettingsJob
+ {
+ /// <summary>
+ /// Gets or sets the crop.
+ /// </summary>
+ public Cropping Crop { get; set; }
+
+ /// <summary>
+ /// Gets or sets the modulus.
+ /// </summary>
+ public int? Modulus { get; set; }
+
+ /// <summary>
+ /// Gets or sets the par w.
+ /// </summary>
+ public int ParW { get; set; }
+
+ /// <summary>
+ /// Gets or sets the par h.
+ /// </summary>
+ public int ParH { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether itu par.
+ /// </summary>
+ public bool ItuPar { get; set; }
+
+ /// <summary>
+ /// Gets or sets the width.
+ /// </summary>
+ public int Width { get; set; }
+
+ /// <summary>
+ /// Gets or sets the height.
+ /// </summary>
+ public int Height { get; set; }
+
+ /// <summary>
+ /// Gets or sets the anamorphic mode.
+ /// </summary>
+ public Anamorphic AnamorphicMode { get; set; }
+
+ /// <summary>
+ /// Gets or sets the max width.
+ /// </summary>
+ public int MaxWidth { get; set; }
+
+ /// <summary>
+ /// Gets or sets the max height.
+ /// </summary>
+ public int MaxHeight { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether keep display aspect.
+ /// </summary>
+ public bool KeepDisplayAspect { get; set; }
+
+ /// <summary>
+ /// Gets or sets the dar width.
+ /// </summary>
+ public int DarWidth { get; set; }
+
+ /// <summary>
+ /// Gets or sets the dar height.
+ /// </summary>
+ public int DarHeight { get; set; }
+ }
+
+ /// <summary>
+ /// The picture settings title.
+ /// </summary>
+ public class PictureSettingsTitle
+ {
+ /// <summary>
+ /// Gets or sets the width.
+ /// </summary>
+ public int Width { get; set; }
+
+ /// <summary>
+ /// Gets or sets the height.
+ /// </summary>
+ public int Height { get; set; }
+
+ /// <summary>
+ /// Gets or sets the par w.
+ /// </summary>
+ public int ParW { get; set; }
+
+ /// <summary>
+ /// Gets or sets the par h.
+ /// </summary>
+ public int ParH { get; set; }
+
+ /// <summary>
+ /// Gets or sets the aspect.
+ /// </summary>
+ public double Aspect { get; set; }
+ }
+
+ /// <summary>
+ /// The anamorphic result.
+ /// </summary>
+ public class AnamorphicResult
+ {
+ /// <summary>
+ /// Gets or sets the output width.
+ /// </summary>
+ public int OutputWidth { get; set; }
+
+ /// <summary>
+ /// Gets or sets the output height.
+ /// </summary>
+ public int OutputHeight { get; set; }
+
+ /// <summary>
+ /// Gets or sets the output par width.
+ /// </summary>
+ public double OutputParWidth { get; set; }
+
+ /// <summary>
+ /// Gets or sets the output par height.
+ /// </summary>
+ public double OutputParHeight { get; set; }
+ }
+
+ /// <summary>
+ /// The hb_set_anamorphic_size_native.
+ /// </summary>
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ /// <param name="title">
+ /// The title.
+ /// </param>
+ /// <returns>
+ /// The <see cref="AnamorphicResult"/> object.
+ /// </returns>
+ public static AnamorphicResult hb_set_anamorphic_size(PictureSettingsJob job, PictureSettingsTitle title)
+ {
+ int outputHeight = 0;
+ int outputParHeight = 0;
+ int outputParWidth = 0;
+ int outputWidth = 0;
+
+ hb_job_s nativeJob = new hb_job_s
+ {
+ modulus = job.Modulus.HasValue ? job.Modulus.Value : 16,
+ anamorphic =
+ new hb_anamorphic_substruct
+ {
+ par_width = job.ParW,
+ par_height = job.ParH,
+ itu_par = 0,
+ mode = (int)job.AnamorphicMode,
+ dar_width = 0,
+ dar_height = 0,
+ keep_display_aspect = job.KeepDisplayAspect ? 1 : 0
+ },
+ maxWidth = title.Width,
+ maxHeight = title.Height,
+ keep_ratio = job.KeepDisplayAspect ? 1 : 0,
+ width = job.Width,
+ height = job.Height,
+ crop = new[] { job.Crop.Top, job.Crop.Bottom, job.Crop.Left, job.Crop.Right }
+ };
+
+ hb_title_s title_s = new hb_title_s
+ {
+ crop = new[] { job.Crop.Top, job.Crop.Bottom, job.Crop.Left, job.Crop.Right },
+ width = title.Width,
+ height = title.Height,
+ pixel_aspect_width = title.ParW,
+ pixel_aspect_height = title.ParH,
+ aspect = 0
+ };
+
+ IntPtr pointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(hb_title_s)));
+ Marshal.StructureToPtr(title_s, pointer, false);
+ nativeJob.title = pointer;
+
+ HBFunctions.hb_set_anamorphic_size(
+ ref nativeJob, ref outputWidth, ref outputHeight, ref outputParWidth, ref outputParHeight);
+
+ return new AnamorphicResult { OutputWidth = outputWidth, OutputHeight = outputHeight, OutputParWidth = outputParWidth, OutputParHeight = outputParHeight };
+ }
+ }
+}
diff --git a/win/CS/HandBrakeWPF/Helpers/QueueRecoveryHelper.cs b/win/CS/HandBrakeWPF/Helpers/QueueRecoveryHelper.cs
index 25e77bfa2..53ab407e2 100644
--- a/win/CS/HandBrakeWPF/Helpers/QueueRecoveryHelper.cs
+++ b/win/CS/HandBrakeWPF/Helpers/QueueRecoveryHelper.cs
@@ -87,7 +87,7 @@ namespace HandBrakeWPF.Helpers
return queueFiles;
}
- catch (Exception exc)
+ catch (Exception)
{
return new List<string>(); // Keep quiet about the error.
}
@@ -132,7 +132,7 @@ namespace HandBrakeWPF.Helpers
// Once we load it in, remove it as we no longer need it.
File.Delete(Path.Combine(appDataPath, file));
}
- catch (Exception exc)
+ catch (Exception)
{
// Keep quite, nothing much we can do if there are problems.
// We will continue processing files.
diff --git a/win/CS/HandBrakeWPF/Model/ShellWindow.cs b/win/CS/HandBrakeWPF/Model/ShellWindow.cs
index 05ca1995e..bbb71625e 100644
--- a/win/CS/HandBrakeWPF/Model/ShellWindow.cs
+++ b/win/CS/HandBrakeWPF/Model/ShellWindow.cs
@@ -15,6 +15,7 @@ namespace HandBrakeWPF.Model
public enum ShellWindow
{
MainWindow,
- OptionsWindow
+ OptionsWindow,
+ InstantMainWindow
}
}
diff --git a/win/CS/HandBrakeWPF/Model/SourceMenuItem.cs b/win/CS/HandBrakeWPF/Model/SourceMenuItem.cs
index 4be52964e..00cb2e28f 100644
--- a/win/CS/HandBrakeWPF/Model/SourceMenuItem.cs
+++ b/win/CS/HandBrakeWPF/Model/SourceMenuItem.cs
@@ -10,7 +10,6 @@
namespace HandBrakeWPF.Model
{
using System.Collections.ObjectModel;
- using System.Windows.Controls;
using System.Windows.Input;
/// <summary>
@@ -37,11 +36,6 @@ namespace HandBrakeWPF.Model
public ICommand Command { get; set; }
/// <summary>
- /// Gets or sets the image.
- /// </summary>
- public Image Image { get; set; }
-
- /// <summary>
/// Gets or sets the children.
/// </summary>
public ObservableCollection<SourceMenuItem> Children { get; set; }
@@ -52,6 +46,22 @@ namespace HandBrakeWPF.Model
public bool IsDrive { get; set; }
/// <summary>
+ /// Gets or sets a value indicating whether is open folder.
+ /// </summary>
+ public bool IsOpenFolder { get; set; }
+
+ /// <summary>
+ /// Gets a value indicating whether is open file.
+ /// </summary>
+ public bool IsOpenFile
+ {
+ get
+ {
+ return !this.IsOpenFolder && (this.Children == null || this.Children.Count == 0);
+ }
+ }
+
+ /// <summary>
/// Gets or sets the tag.
/// </summary>
public object Tag { get; set; }
diff --git a/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs b/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs
index 05ecfba15..7dd8fdcf3 100644
--- a/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs
+++ b/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
-// Runtime Version:4.0.30319.18047
+// Runtime Version:4.0.30319.18052
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
diff --git a/win/CS/HandBrakeWPF/Properties/Resources.resx b/win/CS/HandBrakeWPF/Properties/Resources.resx
index 2b08ae332..2fd4015ed 100644
--- a/win/CS/HandBrakeWPF/Properties/Resources.resx
+++ b/win/CS/HandBrakeWPF/Properties/Resources.resx
@@ -298,9 +298,7 @@ None: There is no maximum resolution for encodes using this preset. When the pr
Custom: You can optionally set a Maximum width and Height. When doing this an encode will be less than or equal to these values. Keep Aspect Ratio will be automatically turned on.
-Source Maximum: Similar to custom, but the resolution of your current source is used as the Max width and Height values instead. Keep Aspect Ratio will be automatically turned on.
-
-No Limit: Always use the full source resolution for all sources keeping aspect ratio. This is the default behaviour.</value>
+Source Maximum: Similar to custom, but the resolution of your current source is used as the Max width and Height values instead. Keep Aspect Ratio will be automatically turned on.</value>
</data>
<data name="Advanced_EncoderOptions" xml:space="preserve">
<value>The options passed to the x264 encoder.
diff --git a/win/CS/HandBrakeWPF/Services/PrePostActionService.cs b/win/CS/HandBrakeWPF/Services/PrePostActionService.cs
index ce4eee423..7cfceace3 100644
--- a/win/CS/HandBrakeWPF/Services/PrePostActionService.cs
+++ b/win/CS/HandBrakeWPF/Services/PrePostActionService.cs
@@ -1,5 +1,5 @@
// --------------------------------------------------------------------------------------------------------------------
-// <copyright file="WhenDoneService.cs" company="HandBrake Project (http://handbrake.fr)">
+// <copyright file="PrePostActionService.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>
@@ -14,10 +14,12 @@ namespace HandBrakeWPF.Services
using Caliburn.Micro;
+ using HandBrake.ApplicationServices.EventArgs;
using HandBrake.ApplicationServices.Services.Interfaces;
using HandBrake.ApplicationServices.Utilities;
using HandBrakeWPF.Services.Interfaces;
+ using HandBrakeWPF.ViewModels.Interfaces;
using Application = System.Windows.Application;
@@ -37,6 +39,11 @@ namespace HandBrakeWPF.Services
private readonly IUserSettingService userSettingService;
/// <summary>
+ /// The window manager.
+ /// </summary>
+ private readonly IWindowManager windowManager;
+
+ /// <summary>
/// Initializes a new instance of the <see cref="PrePostActionService"/> class.
/// </summary>
/// <param name="queueProcessor">
@@ -45,10 +52,14 @@ namespace HandBrakeWPF.Services
/// <param name="userSettingService">
/// The user Setting Service.
/// </param>
- public PrePostActionService(IQueueProcessor queueProcessor, IUserSettingService userSettingService)
+ /// <param name="windowManager">
+ /// The window Manager.
+ /// </param>
+ public PrePostActionService(IQueueProcessor queueProcessor, IUserSettingService userSettingService, IWindowManager windowManager)
{
this.queueProcessor = queueProcessor;
this.userSettingService = userSettingService;
+ this.windowManager = windowManager;
this.queueProcessor.QueueCompleted += QueueProcessorQueueCompleted;
this.queueProcessor.EncodeService.EncodeCompleted += EncodeService_EncodeCompleted;
@@ -108,29 +119,53 @@ namespace HandBrakeWPF.Services
/// <param name="e">
/// The e.
/// </param>
- private void QueueProcessorQueueCompleted(object sender, System.EventArgs e)
+ private void QueueProcessorQueueCompleted(object sender, QueueCompletedEventArgs e)
{
- // Do something whent he encode ends.
- switch (this.userSettingService.GetUserSetting<string>(UserSettingConstants.WhenCompleteAction))
+ if (e.WasManuallyStopped)
+ {
+ return;
+ }
+
+
+ if (this.userSettingService.GetUserSetting<string>(UserSettingConstants.WhenCompleteAction) == "Do nothing")
{
- case "Shutdown":
- Process.Start("Shutdown", "-s -t 60");
- break;
- case "Log off":
- Win32.ExitWindowsEx(0, 0);
- break;
- case "Suspend":
- System.Windows.Forms.Application.SetSuspendState(PowerState.Suspend, true, true);
- break;
- case "Hibernate":
- System.Windows.Forms.Application.SetSuspendState(PowerState.Hibernate, true, true);
- break;
- case "Lock System":
- Win32.LockWorkStation();
- break;
- case "Quit HandBrake":
- Execute.OnUIThread(() => Application.Current.Shutdown());
- break;
+ return;
+ }
+
+ // Give the user the ability to cancel the shutdown. Default 60 second timer.
+ ICountdownAlertViewModel titleSpecificView = IoC.Get<ICountdownAlertViewModel>();
+ Caliburn.Micro.Execute.OnUIThread(
+ () =>
+ {
+ titleSpecificView.SetAction(this.userSettingService.GetUserSetting<string>(UserSettingConstants.WhenCompleteAction));
+ this.windowManager.ShowDialog(titleSpecificView);
+ });
+
+
+ if (!titleSpecificView.IsCancelled)
+ {
+ // Do something whent he encode ends.
+ switch (this.userSettingService.GetUserSetting<string>(UserSettingConstants.WhenCompleteAction))
+ {
+ case "Shutdown":
+ Process.Start("Shutdown", "-s -t 60");
+ break;
+ case "Log off":
+ Win32.ExitWindowsEx(0, 0);
+ break;
+ case "Suspend":
+ System.Windows.Forms.Application.SetSuspendState(PowerState.Suspend, true, true);
+ break;
+ case "Hibernate":
+ System.Windows.Forms.Application.SetSuspendState(PowerState.Hibernate, true, true);
+ break;
+ case "Lock System":
+ Win32.LockWorkStation();
+ break;
+ case "Quit HandBrake":
+ Execute.OnUIThread(() => Application.Current.Shutdown());
+ break;
+ }
}
}
diff --git a/win/CS/HandBrakeWPF/Services/ScanServiceWrapper.cs b/win/CS/HandBrakeWPF/Services/ScanServiceWrapper.cs
index f66aff538..8180ac070 100644
--- a/win/CS/HandBrakeWPF/Services/ScanServiceWrapper.cs
+++ b/win/CS/HandBrakeWPF/Services/ScanServiceWrapper.cs
@@ -13,12 +13,9 @@ namespace HandBrakeWPF.Services
{
using System;
- using HandBrake.ApplicationServices.Exceptions;
- using HandBrake.ApplicationServices.Isolation;
using HandBrake.ApplicationServices.Parsing;
using HandBrake.ApplicationServices.Services;
using HandBrake.ApplicationServices.Services.Interfaces;
- using HandBrake.Interop;
using HandBrake.Interop.Interfaces;
/// <summary>
@@ -48,41 +45,11 @@ namespace HandBrakeWPF.Services
/// Initializes a new instance of the <see cref="ScanServiceWrapper"/> class.
/// </summary>
/// <param name="userSettingService">
- /// The user setting service.
+ /// The user Setting Service.
/// </param>
public ScanServiceWrapper(IUserSettingService userSettingService)
{
- var useLibHb = userSettingService.GetUserSetting<bool>(UserSettingConstants.EnableLibHb);
- var useProcessIsolation =
- userSettingService.GetUserSetting<bool>(UserSettingConstants.EnableProcessIsolation);
- string port = userSettingService.GetUserSetting<string>(UserSettingConstants.ServerPort);
-
- if (useLibHb)
- {
- try
- {
- if (useProcessIsolation)
- {
- this.scanService = new IsolatedScanService(port);
- }
- else
- {
- HandbrakeInstance = new HandBrakeInstance();
- this.scanService = new LibScan(HandbrakeInstance);
- }
- }
- catch(Exception exc)
- {
- // Try to recover from errors.
- userSettingService.SetUserSetting(UserSettingConstants.EnableLibHb, false);
- throw new GeneralApplicationException("Unable to initialise LibHB or Background worker service", "Falling back to using HandBrakeCLI.exe. Setting has been reset", exc);
- }
- }
- else
- {
- this.scanService = new ScanService(userSettingService);
- }
-
+ this.scanService = new LibScan(userSettingService);
this.scanService.ScanCompleted += this.ScanServiceScanCompleted;
this.scanService.ScanStared += this.ScanServiceScanStared;
this.scanService.ScanStatusChanged += this.ScanServiceScanStatusChanged;
@@ -193,25 +160,6 @@ namespace HandBrakeWPF.Services
#region IScan
/// <summary>
- /// Take a Scan Log file, and process it as if it were from the CLI.
- /// </summary>
- /// <param name="path">
- /// The path to the log file.
- /// </param>
- public void DebugScanLog(string path)
- {
- this.scanService.DebugScanLog(path);
- }
-
- /// <summary>
- /// Shutdown the service.
- /// </summary>
- public void Shutdown()
- {
- this.scanService.Shutdown();
- }
-
- /// <summary>
/// Scan a Source Path.
/// Title 0: scan all
/// </summary>
diff --git a/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs b/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs
index 87a92824a..0debbbcce 100644
--- a/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs
+++ b/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs
@@ -78,7 +78,9 @@ namespace HandBrakeWPF.Startup
this.windsorContainer.Register(Component.For<IOptionsViewModel>().ImplementedBy<OptionsViewModel>().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));
-
+ this.windsorContainer.Register(Component.For<ICountdownAlertViewModel>().ImplementedBy<CountdownAlertViewModel>().LifeStyle.Is(LifestyleType.Singleton));
+
+ this.windsorContainer.Register(Component.For<IInstantViewModel>().ImplementedBy<InstantViewModel>().LifeStyle.Is(LifestyleType.Singleton));
// Tab Components
this.windsorContainer.Register(Component.For<IAudioViewModel>().ImplementedBy<AudioViewModel>().LifeStyle.Is(LifestyleType.Singleton));
diff --git a/win/CS/HandBrakeWPF/Themes/Generic.xaml b/win/CS/HandBrakeWPF/Themes/Generic.xaml
new file mode 100644
index 000000000..460177769
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Themes/Generic.xaml
@@ -0,0 +1,52 @@
+<ResourceDictionary
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
+ xmlns:splitButton="clr-namespace:HandBrakeWPF.Controls.SplitButton">
+
+ <Style TargetType="{x:Type splitButton:SplitMenuButton}" BasedOn="{StaticResource {x:Type Button}}">
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type splitButton:SplitMenuButton}">
+ <mwt:ButtonChrome x:Name="Chrome" Background="{TemplateBinding Control.Background}" BorderBrush="{TemplateBinding Control.BorderBrush}"
+ RenderDefaulted="{TemplateBinding Button.IsDefaulted}" RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}"
+ RenderPressed="{TemplateBinding ButtonBase.IsPressed}" SnapsToDevicePixels="True">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition/>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="Auto"/>
+ </Grid.ColumnDefinitions>
+
+ <ContentPresenter Content="{TemplateBinding ContentControl.Content}" ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
+ ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
+ Margin="5,0,5,0" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
+ VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" />
+
+ <Rectangle Grid.Column="1" Width="1" Fill="{TemplateBinding Foreground}" Opacity="0.4" Margin="0 4 0 4"/>
+
+ <Grid x:Name="SplitElement" Grid.Column="2" Background="Transparent">
+ <ContextMenuService.ContextMenu>
+ <ContextMenu ItemsSource="{Binding ItemSource, RelativeSource={RelativeSource TemplatedParent}}" Foreground="{TemplateBinding Foreground}" FlowDirection="{TemplateBinding FlowDirection}"/>
+ </ContextMenuService.ContextMenu>
+ <Path Data="M 0,0 L 8,0 L 4,4 Z" Fill="{TemplateBinding Foreground}" Margin="5 0 5 0" VerticalAlignment="Center"/>
+ </Grid>
+ </Grid>
+ </mwt:ButtonChrome>
+ <ControlTemplate.Triggers>
+ <Trigger Property="UIElement.IsKeyboardFocused" Value="True">
+ <Setter Property="mwt:ButtonChrome.RenderDefaulted" TargetName="Chrome" Value="True" />
+ </Trigger>
+ <Trigger Property="ToggleButton.IsChecked" Value="True">
+ <Setter Property="mwt:ButtonChrome.RenderPressed" TargetName="Chrome" Value="True" />
+ </Trigger>
+ <Trigger Property="UIElement.IsEnabled" Value="False">
+ <Setter Property="Control.Foreground" Value="#FFADADAD" />
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+
+</ResourceDictionary>
diff --git a/win/CS/HandBrakeWPF/UserSettingConstants.cs b/win/CS/HandBrakeWPF/UserSettingConstants.cs
index b9ce40b0c..b44ddd33a 100644
--- a/win/CS/HandBrakeWPF/UserSettingConstants.cs
+++ b/win/CS/HandBrakeWPF/UserSettingConstants.cs
@@ -241,6 +241,11 @@ namespace HandBrakeWPF
/// </summary>
public const string UseSystemColours = "UseSystemColours";
+ /// <summary>
+ /// The reset when done action.
+ /// </summary>
+ public const string ResetWhenDoneAction = "ResetWhenDoneAction";
+
#endregion
}
} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/ViewModels/AddPresetViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/AddPresetViewModel.cs
index 488f58d74..858f9cbda 100644
--- a/win/CS/HandBrakeWPF/ViewModels/AddPresetViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/AddPresetViewModel.cs
@@ -17,6 +17,7 @@ namespace HandBrakeWPF.ViewModels
using HandBrake.ApplicationServices.Services;
using HandBrake.ApplicationServices.Services.Interfaces;
using HandBrake.ApplicationServices.Utilities;
+ using HandBrake.Interop.Model.Encoding;
using HandBrakeWPF.Services.Interfaces;
using HandBrakeWPF.ViewModels.Interfaces;
@@ -65,7 +66,7 @@ namespace HandBrakeWPF.ViewModels
this.presetService = presetService;
this.errorService = errorService;
this.Title = "Add Preset";
- this.Preset = new Preset { IsBuildIn = false, IsDefault = false, Category = PresetService.UserPresetCatgoryName, UsePictureFilters = true};
+ this.Preset = new Preset { IsBuildIn = false, IsDefault = false, Category = PresetService.UserPresetCatgoryName, UsePictureFilters = true };
this.PictureSettingsModes = EnumHelper<PresetPictureSettingsMode>.GetEnumList();
}
@@ -127,10 +128,23 @@ namespace HandBrakeWPF.ViewModels
/// <param name="task">
/// The Encode Task.
/// </param>
+ /// <param name="title">
+ /// The title.
+ /// </param>
public void Setup(EncodeTask task, Title title)
{
this.Preset.Task = new EncodeTask(task);
this.selectedTitle = title;
+
+ switch (task.Anamorphic)
+ {
+ default:
+ this.SelectedPictureSettingMode = PresetPictureSettingsMode.Custom;
+ break;
+ case Anamorphic.Strict:
+ this.SelectedPictureSettingMode = PresetPictureSettingsMode.SourceMaximum;
+ break;
+ }
}
/// <summary>
@@ -146,11 +160,11 @@ namespace HandBrakeWPF.ViewModels
if (this.presetService.CheckIfPresetExists(this.Preset.Name))
{
- MessageBoxResult result = this.errorService.ShowMessageBox("A Preset with this name already exists. Would you like to overwrite it?", "Error", MessageBoxButton.YesNo, MessageBoxImage.Error);
- if (result == MessageBoxResult.No)
- {
- return;
- }
+ MessageBoxResult result = this.errorService.ShowMessageBox("A Preset with this name already exists. Would you like to overwrite it?", "Error", MessageBoxButton.YesNo, MessageBoxImage.Error);
+ if (result == MessageBoxResult.No)
+ {
+ return;
+ }
}
if (this.SelectedPictureSettingMode == PresetPictureSettingsMode.SourceMaximum && this.selectedTitle == null)
diff --git a/win/CS/HandBrakeWPF/ViewModels/AudioViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/AudioViewModel.cs
index ee9b09f31..800f7e180 100644
--- a/win/CS/HandBrakeWPF/ViewModels/AudioViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/AudioViewModel.cs
@@ -166,7 +166,7 @@ namespace HandBrakeWPF.ViewModels
{
this.NotifyOfPropertyChange(() => this.Task);
- if (Task.OutputFormat == OutputFormat.Mp4)
+ if (Task.OutputFormat == OutputFormat.Mp4 || this.Task.OutputFormat == OutputFormat.av_mp4)
{
foreach (AudioTrack track in this.Task.AudioTracks.Where(track => track.Encoder == AudioEncoder.ffflac || track.Encoder == AudioEncoder.Vorbis))
{
diff --git a/win/CS/HandBrakeWPF/ViewModels/CountdownAlertViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/CountdownAlertViewModel.cs
new file mode 100644
index 000000000..ca8901c7c
--- /dev/null
+++ b/win/CS/HandBrakeWPF/ViewModels/CountdownAlertViewModel.cs
@@ -0,0 +1,152 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="CountdownAlertViewModel.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 Countdown Alert View Model
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.ViewModels
+{
+ using System;
+ using System.Windows.Forms.VisualStyles;
+ using System.Windows.Threading;
+
+ using HandBrakeWPF.ViewModels.Interfaces;
+
+ /// <summary>
+ /// The Countdown Alert View Model
+ /// </summary>
+ public class CountdownAlertViewModel : ViewModelBase, ICountdownAlertViewModel
+ {
+ #region Private Fields
+
+ /// <summary>
+ /// The countdown time.
+ /// </summary>
+ private const int CountdownTime = 60;
+
+ /// <summary>
+ /// The action.
+ /// </summary>
+ private string action;
+
+ /// <summary>
+ /// The timer.
+ /// </summary>
+ private DispatcherTimer timer;
+
+ #endregion
+
+ #region Constructors and Destructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CountdownAlertViewModel"/> class.
+ /// </summary>
+ public CountdownAlertViewModel()
+ {
+ this.IsCancelled = false;
+
+ Caliburn.Micro.Execute.OnUIThread(
+ () =>
+ {
+ timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
+ timer.Tick += this.timer_Tick;
+
+ timer.Start();
+ });
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets or sets a value indicating whether is cancelled.
+ /// </summary>
+ public bool IsCancelled { get; set; }
+
+ /// <summary>
+ /// Gets the notice message.
+ /// </summary>
+ public string NoticeMessage
+ {
+ get
+ {
+ return string.Format("The following action '{0}' will occur in {1} seconds.", action, CountdownTime - this.Ticks);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the ticks.
+ /// </summary>
+ public int Ticks { get; set; }
+
+ #endregion
+
+ #region Public Methods and Operators
+
+ /// <summary>
+ /// The cancel.
+ /// </summary>
+ public void Cancel()
+ {
+ this.IsCancelled = true;
+ timer.Stop();
+ this.Ticks = 0;
+ this.TryClose();
+ }
+
+ /// <summary>
+ /// The proceed.
+ /// </summary>
+ public void Proceed()
+ {
+ this.IsCancelled = false;
+ timer.Stop();
+ this.Ticks = 0;
+ this.TryClose();
+ }
+
+ /// <summary>
+ /// The set action.
+ /// </summary>
+ /// <param name="actionMsg">
+ /// The action.
+ /// </param>
+ public void SetAction(string actionMsg)
+ {
+ this.Ticks = 0;
+ timer.Start();
+ this.action = actionMsg;
+ }
+
+ #endregion
+
+ #region Methods
+
+ /// <summary>
+ /// The timer_ tick.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void timer_Tick(object sender, EventArgs e)
+ {
+ this.Ticks = this.Ticks + 1;
+ this.NotifyOfPropertyChange(() => this.NoticeMessage);
+ if (this.Ticks > CountdownTime)
+ {
+ timer.Stop();
+ this.Ticks = 0;
+ this.TryClose();
+ }
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/ViewModels/EncoderOptionsViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/EncoderOptionsViewModel.cs
index f1da43828..d7ae4e498 100644
--- a/win/CS/HandBrakeWPF/ViewModels/EncoderOptionsViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/EncoderOptionsViewModel.cs
@@ -33,6 +33,7 @@ namespace HandBrakeWPF.ViewModels
public EncoderOptionsViewModel()
{
this.Task = new EncodeTask();
+ cachedOptions.Add(VideoEncoder.QuickSync, "async-depth=4");
}
/// <summary>
diff --git a/win/CS/HandBrakeWPF/ViewModels/FiltersViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/FiltersViewModel.cs
index fe9c4fabf..de08398bb 100644
--- a/win/CS/HandBrakeWPF/ViewModels/FiltersViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/FiltersViewModel.cs
@@ -26,6 +26,11 @@ namespace HandBrakeWPF.ViewModels
/// </summary>
public class FiltersViewModel : ViewModelBase, IFiltersViewModel
{
+ /// <summary>
+ /// The is deinterlace mode.
+ /// </summary>
+ private bool isDeinterlaceMode;
+
#region Constructors and Destructors
/// <summary>
@@ -41,6 +46,7 @@ namespace HandBrakeWPF.ViewModels
{
this.CurrentTask = new EncodeTask();
this.DeblockValue = 4; // OFF
+ this.IsDeinterlaceMode = true;
}
#endregion
@@ -233,6 +239,11 @@ namespace HandBrakeWPF.ViewModels
// Show / Hide the Custom Control
this.ShowDeinterlaceCustom = this.CurrentTask.Deinterlace == Deinterlace.Custom;
this.NotifyOfPropertyChange(() => this.ShowDeinterlaceCustom);
+
+ if (value != Deinterlace.Off)
+ {
+ this.IsDeinterlaceMode = true;
+ }
}
}
@@ -259,6 +270,11 @@ namespace HandBrakeWPF.ViewModels
// Show / Hide the Custom Control
this.ShowDecombCustom = this.CurrentTask.Decomb == Decomb.Custom;
this.NotifyOfPropertyChange(() => this.ShowDecombCustom);
+
+ if (value != Decomb.Off)
+ {
+ this.IsDeinterlaceMode = false;
+ }
}
}
@@ -324,6 +340,43 @@ namespace HandBrakeWPF.ViewModels
/// </summary>
public bool ShowDetelecineCustom { get; set; }
+ /// <summary>
+ /// Gets or sets a value indicating whether is deinterlace mode.
+ /// </summary>
+ public bool IsDeinterlaceMode
+ {
+ get
+ {
+ return this.isDeinterlaceMode;
+ }
+ set
+ {
+ if (!object.Equals(this.isDeinterlaceMode, value))
+ {
+ this.isDeinterlaceMode = value;
+ this.NotifyOfPropertyChange(() => this.IsDeinterlaceMode);
+
+ this.DeinterlaceControlText = value ? "Deinterlace:" : "Decomb:";
+
+ if (value)
+ {
+ this.SelectedDecomb = Decomb.Off;
+ }
+ else
+ {
+ this.SelectedDeInterlace = Deinterlace.Off;
+ }
+
+ this.NotifyOfPropertyChange(() => this.DeinterlaceControlText);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the deinterlace control text.
+ /// </summary>
+ public string DeinterlaceControlText { get; set; }
+
#endregion
#region Implemented Interfaces
diff --git a/win/CS/HandBrakeWPF/ViewModels/InstantViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/InstantViewModel.cs
new file mode 100644
index 000000000..8edfb3a87
--- /dev/null
+++ b/win/CS/HandBrakeWPF/ViewModels/InstantViewModel.cs
@@ -0,0 +1,1014 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="InstantViewModel.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 instant view model.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.ViewModels
+{
+ using System;
+ using System.Collections.Generic;
+ using System.ComponentModel;
+ using System.Diagnostics;
+ using System.Globalization;
+ using System.IO;
+ using System.Linq;
+ using System.Threading;
+ using System.Windows;
+
+ using Caliburn.Micro;
+
+ using HandBrake.ApplicationServices;
+ using HandBrake.ApplicationServices.EventArgs;
+ using HandBrake.ApplicationServices.Model;
+ using HandBrake.ApplicationServices.Parsing;
+ using HandBrake.ApplicationServices.Services.Interfaces;
+ using HandBrake.ApplicationServices.Utilities;
+
+ using HandBrakeWPF.Commands;
+ using HandBrakeWPF.Helpers;
+ using HandBrakeWPF.Model;
+ using HandBrakeWPF.Services.Interfaces;
+ using HandBrakeWPF.ViewModels.Interfaces;
+ using HandBrakeWPF.Views;
+
+ using Microsoft.Win32;
+
+ using Ookii.Dialogs.Wpf;
+
+ /// <summary>
+ /// The instant view model.
+ /// </summary>
+ public class InstantViewModel : ViewModelBase, IInstantViewModel
+ {
+ #region Constants and Fields
+
+ /// <summary>
+ /// The encode service.
+ /// </summary>
+ private readonly IEncodeServiceWrapper encodeService;
+
+ /// <summary>
+ /// The error service.
+ /// </summary>
+ private readonly IErrorService errorService;
+
+ /// <summary>
+ /// The preset service.
+ /// </summary>
+ private readonly IPresetService presetService;
+
+ /// <summary>
+ /// The queue processor.
+ /// </summary>
+ private readonly IQueueProcessor queueProcessor;
+
+ /// <summary>
+ /// The scan service.
+ /// </summary>
+ private readonly IScanServiceWrapper scanService;
+
+ /// <summary>
+ /// The shell view model.
+ /// </summary>
+ private readonly IShellViewModel shellViewModel;
+
+ /// <summary>
+ /// The update service.
+ /// </summary>
+ private readonly IUpdateService updateService;
+
+ /// <summary>
+ /// The user setting service.
+ /// </summary>
+ private readonly IUserSettingService userSettingService;
+
+ /// <summary>
+ /// Windows 7 API Pack wrapper
+ /// </summary>
+ private readonly Win7 windowsSeven = new Win7();
+
+ /// <summary>
+ /// The is encoding.
+ /// </summary>
+ private bool isEncoding;
+
+ /// <summary>
+ /// The last percentage complete value.
+ /// </summary>
+ private int lastEncodePercentage;
+
+ /// <summary>
+ /// The ordered by duration.
+ /// </summary>
+ private bool orderedByDuration;
+
+ /// <summary>
+ /// The ordered by title.
+ /// </summary>
+ private bool orderedByTitle;
+
+ /// <summary>
+ /// The output directory.
+ /// </summary>
+ private string outputDirectory;
+
+ /// <summary>
+ /// The program status label.
+ /// </summary>
+ private string programStatusLabel;
+
+ /// <summary>
+ /// The scanned source.
+ /// </summary>
+ private Source scannedSource;
+
+ /// <summary>
+ /// The selected preset.
+ /// </summary>
+ private Preset selectedPreset;
+
+ /// <summary>
+ /// The show status window.
+ /// </summary>
+ private bool showStatusWindow;
+
+ /// <summary>
+ /// The source label.
+ /// </summary>
+ private string sourceLabel;
+
+ /// <summary>
+ /// The status label.
+ /// </summary>
+ private string statusLabel;
+
+ #endregion
+
+ #region Constructors and Destructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="InstantViewModel"/> class.
+ /// </summary>
+ /// <param name="userSettingService">
+ /// The user setting service.
+ /// </param>
+ /// <param name="scanService">
+ /// The scan service.
+ /// </param>
+ /// <param name="encodeService">
+ /// The encode service.
+ /// </param>
+ /// <param name="presetService">
+ /// The preset service.
+ /// </param>
+ /// <param name="errorService">
+ /// The error service.
+ /// </param>
+ /// <param name="shellViewModel">
+ /// The shell view model.
+ /// </param>
+ /// <param name="updateService">
+ /// The update service.
+ /// </param>
+ /// <param name="notificationService">
+ /// The notification service.
+ /// </param>
+ /// <param name="whenDoneService">
+ /// The when done service.
+ /// </param>
+ public InstantViewModel(
+ IUserSettingService userSettingService,
+ IScanServiceWrapper scanService,
+ IEncodeServiceWrapper encodeService,
+ IPresetService presetService,
+ IErrorService errorService,
+ IShellViewModel shellViewModel,
+ IUpdateService updateService,
+ INotificationService notificationService,
+ IPrePostActionService whenDoneService)
+ {
+ this.userSettingService = userSettingService;
+ this.scanService = scanService;
+ this.encodeService = encodeService;
+ this.presetService = presetService;
+ this.errorService = errorService;
+ this.shellViewModel = shellViewModel;
+ this.updateService = updateService;
+
+ this.queueProcessor = IoC.Get<IQueueProcessor>();
+
+ // Setup Properties
+ this.TitleList = new BindingList<SelectionTitle>();
+ this.ScannedSource = new Source();
+
+ // Setup Events
+ this.scanService.ScanStared += this.ScanStared;
+ this.scanService.ScanCompleted += this.ScanCompleted;
+ this.scanService.ScanStatusChanged += this.ScanStatusChanged;
+ this.queueProcessor.JobProcessingStarted += this.QueueProcessorJobProcessingStarted;
+ this.queueProcessor.QueueCompleted += this.QueueCompleted;
+ this.queueProcessor.QueueChanged += this.QueueChanged;
+ this.queueProcessor.EncodeService.EncodeStatusChanged += this.EncodeStatusChanged;
+
+ this.Presets = this.presetService.Presets;
+ this.CancelScanCommand = new CancelScanCommand(this.scanService);
+ }
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets or sets the cancel scan command.
+ /// </summary>
+ public CancelScanCommand CancelScanCommand { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether IsEncoding.
+ /// </summary>
+ public bool IsEncoding
+ {
+ get
+ {
+ return this.isEncoding;
+ }
+
+ set
+ {
+ this.isEncoding = value;
+ this.NotifyOfPropertyChange(() => this.IsEncoding);
+ }
+ }
+
+ /// <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(() => this.OrderedByDuration);
+ }
+ }
+
+ /// <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(() => this.OrderedByTitle);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the output directory.
+ /// </summary>
+ public string OutputDirectory
+ {
+ get
+ {
+ return this.outputDirectory;
+ }
+ set
+ {
+ this.outputDirectory = value;
+ this.NotifyOfPropertyChange(() => this.OutputDirectory);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets Presets.
+ /// </summary>
+ public IEnumerable<Preset> Presets { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Program Status Toolbar Label
+ /// This indicates the status of HandBrake
+ /// </summary>
+ public string ProgramStatusLabel
+ {
+ get
+ {
+ return string.IsNullOrEmpty(this.programStatusLabel) ? "Ready" : this.programStatusLabel;
+ }
+
+ set
+ {
+ if (!Equals(this.programStatusLabel, value))
+ {
+ this.programStatusLabel = value;
+ this.NotifyOfPropertyChange(() => this.ProgramStatusLabel);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating progress percentage.
+ /// </summary>
+ public int ProgressPercentage { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Last Scanned Source
+ /// This object contains information about the scanned source.
+ /// </summary>
+ public Source ScannedSource
+ {
+ get
+ {
+ return this.scannedSource;
+ }
+
+ set
+ {
+ this.scannedSource = value;
+
+ this.NotifyOfPropertyChange("ScannedSource");
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets SelectedPreset.
+ /// </summary>
+ public Preset SelectedPreset
+ {
+ get
+ {
+ return this.selectedPreset;
+ }
+ set
+ {
+ this.selectedPreset = value;
+ this.NotifyOfPropertyChange(() => this.SelectedPreset);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether ShowStatusWindow.
+ /// </summary>
+ public bool ShowStatusWindow
+ {
+ get
+ {
+ return this.showStatusWindow;
+ }
+
+ set
+ {
+ this.showStatusWindow = value;
+ this.NotifyOfPropertyChange(() => this.ShowStatusWindow);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the Source Label
+ /// This indicates the status of scans.
+ /// </summary>
+ public string SourceLabel
+ {
+ get
+ {
+ return string.IsNullOrEmpty(this.sourceLabel) ? "Select 'Source' to continue" : this.sourceLabel;
+ }
+
+ set
+ {
+ if (!Equals(this.sourceLabel, value))
+ {
+ this.sourceLabel = value;
+ this.NotifyOfPropertyChange("SourceLabel");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets SourceName.
+ /// </summary>
+ public string SourceName
+ {
+ get
+ {
+ // Sanity Check
+ if (this.ScannedSource == null || this.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))
+ // {
+ // return Path.GetFileNameWithoutExtension(selectedTitle.SourceName);
+ // }
+
+ // Check if we have a Folder, if so, check if it's a DVD / Bluray drive and get the label.
+ if (this.ScannedSource.ScanPath.EndsWith("\\"))
+ {
+ foreach (DriveInformation item in GeneralUtilities.GetDrives())
+ {
+ if (item.RootDirectory.Contains(this.ScannedSource.ScanPath))
+ {
+ return item.VolumeLabel;
+ }
+ }
+ }
+
+ if (Path.GetFileNameWithoutExtension(this.ScannedSource.ScanPath) != "VIDEO_TS")
+ {
+ return Path.GetFileNameWithoutExtension(this.ScannedSource.ScanPath);
+ }
+
+ return Path.GetFileNameWithoutExtension(Path.GetDirectoryName(this.ScannedSource.ScanPath));
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the Program Status Toolbar Label
+ /// This indicates the status of HandBrake
+ /// </summary>
+ public string StatusLabel
+ {
+ get
+ {
+ return string.IsNullOrEmpty(this.statusLabel) ? "Ready" : this.statusLabel;
+ }
+
+ set
+ {
+ if (!Equals(this.statusLabel, value))
+ {
+ this.statusLabel = value;
+ this.NotifyOfPropertyChange(() => this.StatusLabel);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the selected titles.
+ /// </summary>
+ public BindingList<SelectionTitle> TitleList { get; set; }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// The Destination Path
+ /// </summary>
+ public void BrowseDestination()
+ {
+ var saveFileDialog = new SaveFileDialog
+ {
+ Filter = "mp4|*.mp4;*.m4v|mkv|*.mkv",
+ CheckPathExists = true,
+ AddExtension = true,
+ DefaultExt = ".mp4",
+ OverwritePrompt = true,
+ };
+
+ saveFileDialog.ShowDialog();
+ this.OutputDirectory = Path.GetDirectoryName(saveFileDialog.FileName);
+ }
+
+ /// <summary>
+ /// Cancel a Scan
+ /// </summary>
+ public void CancelScan()
+ {
+ this.scanService.Stop();
+ }
+
+ /// <summary>
+ /// File Scan
+ /// </summary>
+ public void FileScan()
+ {
+ var dialog = new VistaOpenFileDialog { Filter = "All files (*.*)|*.*" };
+ dialog.ShowDialog();
+ this.StartScan(dialog.FileName, 0);
+ }
+
+ /// <summary>
+ /// Support dropping a file onto the main window to scan.
+ /// </summary>
+ /// <param name="e">
+ /// The DragEventArgs.
+ /// </param>
+ public void FilesDroppedOnWindow(DragEventArgs e)
+ {
+ if (e.Data.GetDataPresent(DataFormats.FileDrop))
+ {
+ var fileNames = e.Data.GetData(DataFormats.FileDrop, true) as string[];
+ if (fileNames != null && fileNames.Any() &&
+ (File.Exists(fileNames[0]) || Directory.Exists(fileNames[0])))
+ {
+ this.StartScan(fileNames[0], 0);
+ }
+ }
+
+ e.Handled = true;
+ }
+
+ /// <summary>
+ /// Folder Scan
+ /// </summary>
+ public void FolderScan()
+ {
+ var dialog = new VistaFolderBrowserDialog
+ {
+ Description = "Please select a folder.",
+ UseDescriptionForTitle = true
+ };
+ dialog.ShowDialog();
+ this.StartScan(dialog.SelectedPath, 0);
+ }
+
+ /// <summary>
+ /// Launch the Help pages.
+ /// </summary>
+ public void LaunchHelp()
+ {
+ Process.Start("https://trac.handbrake.fr/wiki/HandBrakeGuide");
+ }
+
+ /// <summary>
+ /// The on load.
+ /// </summary>
+ public override void OnLoad()
+ {
+ // Check the CLI Executable.
+ CliCheckHelper.CheckCLIVersion();
+
+ // Perform an update check if required
+ // this.updateService.PerformStartupUpdateCheck(this.HandleUpdateCheckResults);
+
+ // Setup the presets.
+ this.presetService.Load();
+ if (this.presetService.CheckIfPresetsAreOutOfDate())
+ {
+ if (!this.userSettingService.GetUserSetting<bool>(UserSettingConstants.PresetNotification))
+ {
+ this.errorService.ShowMessageBox(
+ "HandBrake has determined your built-in presets are out of date... These presets will now be updated." +
+ Environment.NewLine +
+ "Your custom presets have not been updated so you may have to re-create these by deleting and re-adding them.",
+ "Preset Update",
+ MessageBoxButton.OK,
+ MessageBoxImage.Information);
+ }
+ }
+
+ this.SelectedPreset = this.presetService.DefaultPreset;
+
+ // Log Cleaning
+ if (this.userSettingService.GetUserSetting<bool>(UserSettingConstants.ClearOldLogs))
+ {
+ var clearLog = new Thread(() => GeneralUtilities.ClearLogFiles(30));
+ clearLog.Start();
+ }
+ base.OnLoad();
+ }
+
+ /// <summary>
+ /// Open the About Window
+ /// </summary>
+ public void OpenAboutApplication()
+ {
+ var command = new OpenOptionsScreenCommand();
+ command.Execute(OptionsTab.About);
+ }
+
+ /// <summary>
+ /// Open the Log Window
+ /// </summary>
+ public void OpenLogWindow()
+ {
+ Window window =
+ Application.Current.Windows.Cast<Window>().FirstOrDefault(x => x.GetType() == typeof(LogView));
+
+ if (window != null)
+ {
+ var logvm = (ILogViewModel)window.DataContext;
+ logvm.SelectedTab = this.IsEncoding ? 0 : 1;
+ window.Activate();
+ }
+ else
+ {
+ var logvm = IoC.Get<ILogViewModel>();
+ logvm.SelectedTab = this.IsEncoding ? 0 : 1;
+ this.WindowManager.ShowWindow(logvm);
+ }
+ }
+
+ /// <summary>
+ /// Open the Options Window
+ /// </summary>
+ public void OpenOptionsWindow()
+ {
+ this.shellViewModel.DisplayWindow(ShellWindow.OptionsWindow);
+ }
+
+ /// <summary>
+ /// The order by duration.
+ /// </summary>
+ public void OrderByDuration()
+ {
+ this.TitleList =
+ new BindingList<SelectionTitle>(this.TitleList.OrderByDescending(o => o.Title.Duration).ToList());
+ this.NotifyOfPropertyChange(() => this.TitleList);
+ this.OrderedByTitle = false;
+ this.OrderedByDuration = true;
+ }
+
+ /// <summary>
+ /// The order by title.
+ /// </summary>
+ public void OrderByTitle()
+ {
+ this.TitleList = new BindingList<SelectionTitle>(this.TitleList.OrderBy(o => o.Title.TitleNumber).ToList());
+ this.NotifyOfPropertyChange(() => this.TitleList);
+ this.OrderedByTitle = true;
+ this.OrderedByDuration = false;
+ }
+
+ /// <summary>
+ /// Pause an Encode
+ /// </summary>
+ public void PauseEncode()
+ {
+ this.queueProcessor.Pause();
+ }
+
+ /// <summary>
+ /// The select all.
+ /// </summary>
+ public void SelectAll()
+ {
+ foreach (SelectionTitle item in this.TitleList)
+ {
+ item.IsSelected = true;
+ }
+ }
+
+ /// <summary>
+ /// The setup.
+ /// </summary>
+ /// <param name="scannedSource">
+ /// The scanned source.
+ /// </param>
+ public void Setup(Source scannedSource)
+ {
+ this.TitleList.Clear();
+
+ if (scannedSource != null)
+ {
+ IEnumerable<Title> titles = this.orderedByTitle
+ ? scannedSource.Titles
+ : scannedSource.Titles.OrderByDescending(o => o.Duration).ToList();
+
+ foreach (Title item in titles)
+ {
+ var title = new SelectionTitle(item, item.SourceName) { IsSelected = true };
+ this.TitleList.Add(title);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Shutdown this View
+ /// </summary>
+ public void Shutdown()
+ {
+ // Shutdown Service
+ this.encodeService.Shutdown();
+
+ // Unsubscribe from Events.
+ this.scanService.ScanStared -= this.ScanStared;
+ this.scanService.ScanCompleted -= this.ScanCompleted;
+ this.scanService.ScanStatusChanged -= this.ScanStatusChanged;
+
+ this.queueProcessor.QueueCompleted -= this.QueueCompleted;
+ this.queueProcessor.QueueChanged -= this.QueueChanged;
+ this.queueProcessor.JobProcessingStarted -= this.QueueProcessorJobProcessingStarted;
+ this.queueProcessor.EncodeService.EncodeStatusChanged -= this.EncodeStatusChanged;
+ }
+
+ /// <summary>
+ /// Start an Encode
+ /// </summary>
+ public void StartEncode()
+ {
+ // if (this.queueProcessor.IsProcessing)
+ // {
+ // this.errorService.ShowMessageBox("HandBrake is already encoding.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ // return;
+ // }
+
+ //// Check if we already have jobs, and if we do, just start the queue.
+ // if (this.queueProcessor.Count != 0)
+ // {
+ // this.queueProcessor.Start();
+ // return;
+ // }
+
+ //// Otherwise, perform Santiy Checking then add to the queue and start if everything is ok.
+ // if (this.SelectedTitle == null)
+ // {
+ // this.errorService.ShowMessageBox("You must first scan a source.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ // return;
+ // }
+
+ // if (string.IsNullOrEmpty(this.Destination))
+ // {
+ // this.errorService.ShowMessageBox("The Destination field was empty.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ // return;
+ // }
+
+ // if (File.Exists(this.Destination))
+ // {
+ // MessageBoxResult result = this.errorService.ShowMessageBox("The current file already exists, do you wish to overwrite it?", "Question", MessageBoxButton.YesNo, MessageBoxImage.Question);
+ // if (result == MessageBoxResult.No)
+ // {
+ // return;
+ // }
+ // }
+
+ //// Create the Queue Task and Start Processing
+ // QueueTask task = new QueueTask
+ // {
+ // Task = new EncodeTask(this.CurrentTask),
+ // CustomQuery = false
+ // };
+ // this.queueProcessor.Add(task);
+ // this.queueProcessor.Start();
+ // this.IsEncoding = true;
+ }
+
+ /// <summary>
+ /// Start a Scan
+ /// </summary>
+ /// <param name="filename">
+ /// The filename.
+ /// </param>
+ /// <param name="title">
+ /// The title.
+ /// </param>
+ public void StartScan(string filename, int title)
+ {
+ if (!string.IsNullOrEmpty(filename))
+ {
+ this.scanService.Scan(
+ filename,
+ title,
+ this.UserSettingService.GetUserSetting<int>(ASUserSettingConstants.PreviewScanCount),
+ null);
+ }
+ }
+
+ /// <summary>
+ /// Stop an Encode.
+ /// </summary>
+ public void StopEncode()
+ {
+ this.queueProcessor.Pause();
+ this.encodeService.Stop();
+ }
+
+ /// <summary>
+ /// The select all.
+ /// </summary>
+ public void UnSelectAll()
+ {
+ foreach (SelectionTitle item in this.TitleList)
+ {
+ item.IsSelected = false;
+ }
+ }
+
+ #endregion
+
+ #region Methods
+
+ /// <summary>
+ /// The Encode Status has changed Handler
+ /// </summary>
+ /// <param name="sender">
+ /// The Sender
+ /// </param>
+ /// <param name="e">
+ /// The Encode Progress Event Args
+ /// </param>
+ private void EncodeStatusChanged(object sender, EncodeProgressEventArgs e)
+ {
+ int percent;
+ int.TryParse(Math.Round(e.PercentComplete).ToString(CultureInfo.InvariantCulture), out percent);
+
+ Execute.OnUIThread(
+ () =>
+ {
+ if (this.queueProcessor.EncodeService.IsEncoding)
+ {
+ string josPending = string.Empty;
+ if (!AppArguments.IsInstantHandBrake)
+ {
+ josPending = ", Pending Jobs {5}";
+ }
+
+ this.ProgramStatusLabel =
+ string.Format(
+ "{0:00.00}%, FPS: {1:000.0}, Avg FPS: {2:000.0}, Time Remaining: {3}, Elapsed: {4:hh\\:mm\\:ss}" +
+ josPending,
+ e.PercentComplete,
+ e.CurrentFrameRate,
+ e.AverageFrameRate,
+ e.EstimatedTimeLeft,
+ e.ElapsedTime,
+ this.queueProcessor.Count);
+
+ if (this.lastEncodePercentage != percent && this.windowsSeven.IsWindowsSeven)
+ {
+ this.windowsSeven.SetTaskBarProgress(percent);
+ }
+
+ this.lastEncodePercentage = percent;
+ this.ProgressPercentage = percent;
+ this.NotifyOfPropertyChange(() => this.ProgressPercentage);
+ }
+ else
+ {
+ this.ProgramStatusLabel = "Queue Finished";
+ this.IsEncoding = false;
+
+ if (this.windowsSeven.IsWindowsSeven)
+ {
+ this.windowsSeven.SetTaskBarProgressToNoProgress();
+ }
+ }
+ });
+ }
+
+ /// <summary>
+ /// The queue changed.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The EventArgs.
+ /// </param>
+ private void QueueChanged(object sender, EventArgs e)
+ {
+ Execute.OnUIThread(
+ () => { this.ProgramStatusLabel = string.Format("{0} Encodes Pending", this.queueProcessor.Count); });
+ }
+
+ /// <summary>
+ /// The Queue has completed handler
+ /// </summary>
+ /// <param name="sender">
+ /// The Sender
+ /// </param>
+ /// <param name="e">
+ /// The EventArgs
+ /// </param>
+ private void QueueCompleted(object sender, EventArgs e)
+ {
+ this.IsEncoding = false;
+
+ Execute.OnUIThread(
+ () =>
+ {
+ this.ProgramStatusLabel = "Queue Finished";
+ this.IsEncoding = false;
+
+ if (this.windowsSeven.IsWindowsSeven)
+ {
+ this.windowsSeven.SetTaskBarProgressToNoProgress();
+ }
+ });
+ }
+
+ /// <summary>
+ /// Handle the Queue Starting Event
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void QueueProcessorJobProcessingStarted(object sender, QueueProgressEventArgs e)
+ {
+ Execute.OnUIThread(
+ () =>
+ {
+ this.ProgramStatusLabel = "Preparing to encode ...";
+ this.IsEncoding = true;
+ });
+ }
+
+ /// <summary>
+ /// Handle the Scan Completed Event
+ /// </summary>
+ /// <param name="sender">
+ /// The Sender
+ /// </param>
+ /// <param name="e">
+ /// The EventArgs
+ /// </param>
+ private void ScanCompleted(object sender, ScanCompletedEventArgs e)
+ {
+ this.scanService.SouceData.CopyTo(this.ScannedSource);
+ this.NotifyOfPropertyChange(() => this.ScannedSource);
+
+ Execute.OnUIThread(
+ () =>
+ {
+ if (this.scannedSource != null)
+ {
+ this.Setup(this.scannedSource);
+ }
+
+ if (e.Successful)
+ {
+ this.NotifyOfPropertyChange(() => this.ScannedSource);
+ this.NotifyOfPropertyChange(() => this.ScannedSource.Titles);
+ }
+
+ this.ShowStatusWindow = false;
+ if (e.Successful)
+ {
+ this.SourceLabel = this.SourceName;
+ this.StatusLabel = "Scan Completed";
+ }
+ else if (e.Cancelled)
+ {
+ this.SourceLabel = "Scan Cancelled.";
+ this.StatusLabel = "Scan Cancelled.";
+ }
+ else if (e.Exception == null && e.ErrorInformation != null)
+ {
+ this.SourceLabel = "Scan failed: " + e.ErrorInformation;
+ this.StatusLabel = "Scan failed: " + e.ErrorInformation;
+ }
+ else
+ {
+ this.SourceLabel = "Scan Failed... See Activity Log for details.";
+ this.StatusLabel = "Scan Failed... See Activity Log for details.";
+ }
+ });
+ }
+
+ /// <summary>
+ /// Handle the Scan Started Event
+ /// </summary>
+ /// <param name="sender">
+ /// The Sender
+ /// </param>
+ /// <param name="e">
+ /// The EventArgs
+ /// </param>
+ private void ScanStared(object sender, EventArgs e)
+ {
+ Execute.OnUIThread(
+ () =>
+ {
+ this.StatusLabel = "Scanning source, please wait...";
+ this.ShowStatusWindow = true;
+ });
+ }
+
+ /// <summary>
+ /// Handle the Scan Status Changed Event.
+ /// </summary>
+ /// <param name="sender">
+ /// The Sender
+ /// </param>
+ /// <param name="e">
+ /// The EventArgs
+ /// </param>
+ private void ScanStatusChanged(object sender, ScanProgressEventArgs e)
+ {
+ this.SourceLabel = string.Format("Scanning Title {0} of {1} ({2}%)", e.CurrentTitle, e.Titles, e.Percentage);
+ this.StatusLabel = string.Format("Scanning Title {0} of {1} ({2}%)", e.CurrentTitle, e.Titles, e.Percentage);
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/ViewModels/Interfaces/ICountdownAlertViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/Interfaces/ICountdownAlertViewModel.cs
new file mode 100644
index 000000000..0dac356f3
--- /dev/null
+++ b/win/CS/HandBrakeWPF/ViewModels/Interfaces/ICountdownAlertViewModel.cs
@@ -0,0 +1,30 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="ICountdownAlertViewModel.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 Countdown Alert View Model Interface
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.ViewModels.Interfaces
+{
+ /// <summary>
+ /// The Countdown Alert View Model Interface
+ /// </summary>
+ public interface ICountdownAlertViewModel
+ {
+ /// <summary>
+ /// Gets a value indicating whether is cancelled.
+ /// </summary>
+ bool IsCancelled { get; }
+
+ /// <summary>
+ /// The set action.
+ /// </summary>
+ /// <param name="action">
+ /// The action.
+ /// </param>
+ void SetAction(string action);
+ }
+}
diff --git a/win/CS/HandBrakeWPF/ViewModels/Interfaces/IInstantViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IInstantViewModel.cs
new file mode 100644
index 000000000..5481865b8
--- /dev/null
+++ b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IInstantViewModel.cs
@@ -0,0 +1,18 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="IInstantViewModel.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>
+// Defines the IInstantViewModel type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.ViewModels.Interfaces
+{
+ /// <summary>
+ /// The InstantViewModel interface.
+ /// </summary>
+ public interface IInstantViewModel
+ {
+ }
+} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
index 4978ae1ed..6c2c554cf 100644
--- a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
@@ -473,7 +473,7 @@ namespace HandBrakeWPF.ViewModels
}
// 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))
+ if (selectedTitle != null && !string.IsNullOrEmpty(selectedTitle.SourceName) && !selectedTitle.SourceName.EndsWith("\\"))
{
return Path.GetFileNameWithoutExtension(selectedTitle.SourceName);
}
@@ -483,7 +483,7 @@ namespace HandBrakeWPF.ViewModels
{
foreach (DriveInformation item in GeneralUtilities.GetDrives())
{
- if (item.RootDirectory.Contains(this.ScannedSource.ScanPath))
+ if (item.RootDirectory.Contains(this.ScannedSource.ScanPath.Replace("\\\\", "\\")))
{
return item.VolumeLabel;
}
@@ -666,7 +666,7 @@ namespace HandBrakeWPF.ViewModels
{
return new List<OutputFormat>
{
- OutputFormat.Mp4, OutputFormat.Mkv
+ OutputFormat.av_mp4, OutputFormat.av_mkv, OutputFormat.Mp4, OutputFormat.Mkv
};
}
}
@@ -750,7 +750,7 @@ namespace HandBrakeWPF.ViewModels
}
this.NotifyOfPropertyChange(() => this.CurrentTask);
- this.Duration = this.selectedTitle.Duration.ToString();
+ this.Duration = this.selectedTitle.Duration.ToString("g");
// Setup the tab controls
this.SetupTabs();
@@ -861,7 +861,6 @@ namespace HandBrakeWPF.ViewModels
return;
}
-
this.SelectedStartPoint = 1;
this.SelectedEndPoint = selectedTitle.Chapters != null && selectedTitle.Chapters.Count > 0 ? selectedTitle.Chapters.Last().ChapterNumber : 1;
}
@@ -872,11 +871,10 @@ namespace HandBrakeWPF.ViewModels
return;
}
-
this.SelectedStartPoint = 0;
int timeInSeconds;
- if (int.TryParse(selectedTitle.Duration.TotalSeconds.ToString(CultureInfo.InvariantCulture), out timeInSeconds))
+ if (int.TryParse(Math.Round(selectedTitle.Duration.TotalSeconds, 0).ToString(CultureInfo.InvariantCulture), out timeInSeconds))
{
this.SelectedEndPoint = timeInSeconds;
}
@@ -896,7 +894,7 @@ namespace HandBrakeWPF.ViewModels
this.SelectedStartPoint = 0;
int totalFrames;
- if (int.TryParse(estimatedTotalFrames.ToString(CultureInfo.InvariantCulture), out totalFrames))
+ if (int.TryParse(Math.Round(estimatedTotalFrames, 0).ToString(CultureInfo.InvariantCulture), out totalFrames))
{
this.SelectedEndPoint = totalFrames;
}
@@ -925,7 +923,7 @@ namespace HandBrakeWPF.ViewModels
this.NotifyOfPropertyChange(() => IsMkv);
this.NotifyOfPropertyChange(() => SupportHardwareDecoding);
this.NotifyOfPropertyChange(() => SupportOpenCL);
- this.SetExtension(string.Format(".{0}", this.selectedOutputFormat.ToString().ToLower())); // TODO, tidy up
+ this.SetExtension(string.Format(".{0}", this.selectedOutputFormat.ToString().Replace("av_", string.Empty).ToLower())); // TODO, tidy up
this.VideoViewModel.RefreshTask();
this.AudioViewModel.RefreshTask();
@@ -968,6 +966,9 @@ namespace HandBrakeWPF.ViewModels
}
}
+ /// <summary>
+ /// Gets or sets a value indicating progress percentage.
+ /// </summary>
public int ProgressPercentage { get; set; }
#endregion
@@ -984,7 +985,11 @@ namespace HandBrakeWPF.ViewModels
// Perform an update check if required
this.updateService.PerformStartupUpdateCheck(this.HandleUpdateCheckResults);
+ // Show or Hide the Preset Panel.
+ this.IsPresetPanelShowing = this.userSettingService.GetUserSetting<bool>(UserSettingConstants.ShowPresetPanel);
+
// Setup the presets.
+ this.presetService.Load();
if (this.presetService.CheckIfPresetsAreOutOfDate())
if (!this.userSettingService.GetUserSetting<bool>(UserSettingConstants.PresetNotification))
this.errorService.ShowMessageBox("HandBrake has determined your built-in presets are out of date... These presets will now be updated." + Environment.NewLine +
@@ -992,15 +997,18 @@ namespace HandBrakeWPF.ViewModels
"Preset Update", MessageBoxButton.OK, MessageBoxImage.Information);
// Queue Recovery
- QueueRecoveryHelper.RecoverQueue(this.queueProcessor, this.errorService);
+ if (!AppArguments.IsInstantHandBrake)
+ {
+ QueueRecoveryHelper.RecoverQueue(this.queueProcessor, this.errorService);
+ }
this.SelectedPreset = this.presetService.DefaultPreset;
// Populate the Source menu with drives.
- this.SourceMenu = new BindingList<SourceMenuItem>(this.GenerateSourceMenu());
-
- // Show or Hide the Preset Panel.
- this.IsPresetPanelShowing = this.userSettingService.GetUserSetting<bool>(UserSettingConstants.ShowPresetPanel);
+ if (!AppArguments.IsInstantHandBrake)
+ {
+ this.SourceMenu = new BindingList<SourceMenuItem>(this.GenerateSourceMenu());
+ }
// Log Cleaning
if (userSettingService.GetUserSetting<bool>(UserSettingConstants.ClearOldLogs))
@@ -1016,7 +1024,6 @@ namespace HandBrakeWPF.ViewModels
public void Shutdown()
{
// Shutdown Service
- this.scanService.Shutdown();
this.encodeService.Shutdown();
// Unsubscribe from Events.
@@ -1237,7 +1244,7 @@ namespace HandBrakeWPF.ViewModels
/// </summary>
public void FileScan()
{
- VistaOpenFileDialog dialog = new VistaOpenFileDialog { Filter = "All files (*.*)|*.*" };
+ OpenFileDialog dialog = new OpenFileDialog { Filter = "All files (*.*)|*.*" };
dialog.ShowDialog();
this.StartScan(dialog.FileName, 0);
}
@@ -1269,7 +1276,7 @@ namespace HandBrakeWPF.ViewModels
/// </summary>
public void FileScanTitleSpecific()
{
- VistaOpenFileDialog dialog = new VistaOpenFileDialog { Filter = "All files (*.*)|*.*" };
+ OpenFileDialog dialog = new OpenFileDialog { Filter = "All files (*.*)|*.*" };
dialog.ShowDialog();
if (string.IsNullOrEmpty(dialog.FileName))
@@ -1398,21 +1405,6 @@ namespace HandBrakeWPF.ViewModels
MessageBoxImage.Information);
}
- /// <summary>
- /// The debug scan log.
- /// </summary>
- public void DebugScanLog()
- {
- VistaOpenFileDialog dialog = new VistaOpenFileDialog();
-
- dialog.ShowDialog();
-
- if (File.Exists(dialog.FileName))
- {
- this.scanService.DebugScanLog(dialog.FileName);
- }
- }
-
#endregion
#region Main Window Public Methods
@@ -1454,10 +1446,9 @@ namespace HandBrakeWPF.ViewModels
if (this.CurrentTask != null && !string.IsNullOrEmpty(this.CurrentTask.Destination))
{
- if (Directory.Exists(Path.GetDirectoryName(this.CurrentTask.Destination)))
- {
- saveFileDialog.InitialDirectory = Path.GetDirectoryName(this.CurrentTask.Destination) + "\\";
- }
+ saveFileDialog.InitialDirectory = Directory.Exists(Path.GetDirectoryName(this.CurrentTask.Destination))
+ ? Path.GetDirectoryName(this.CurrentTask.Destination) + "\\"
+ : null;
saveFileDialog.FileName = Path.GetFileName(this.CurrentTask.Destination);
}
@@ -1471,13 +1462,13 @@ namespace HandBrakeWPF.ViewModels
switch (Path.GetExtension(saveFileDialog.FileName))
{
case ".mkv":
- this.SelectedOutputFormat = OutputFormat.Mkv;
+ this.SelectedOutputFormat = OutputFormat.av_mkv;
break;
case ".mp4":
- this.SelectedOutputFormat = OutputFormat.Mp4;
+ this.SelectedOutputFormat = OutputFormat.av_mp4;
break;
case ".m4v":
- this.SelectedOutputFormat = OutputFormat.M4V;
+ this.SelectedOutputFormat = OutputFormat.av_mp4;
break;
}
@@ -1486,6 +1477,25 @@ namespace HandBrakeWPF.ViewModels
}
/// <summary>
+ /// The open destination directory.
+ /// </summary>
+ public void OpenDestinationDirectory()
+ {
+ if (!string.IsNullOrEmpty(this.Destination))
+ {
+ string directory = Path.GetDirectoryName(this.Destination);
+ if (!string.IsNullOrEmpty(directory))
+ {
+ Process.Start(directory);
+ }
+ else
+ {
+ Process.Start(AppDomain.CurrentDomain.BaseDirectory);
+ }
+ }
+ }
+
+ /// <summary>
/// Add a Preset
/// </summary>
public void PresetAdd()
@@ -1561,7 +1571,7 @@ namespace HandBrakeWPF.ViewModels
/// </summary>
public void PresetImport()
{
- VistaOpenFileDialog dialog = new VistaOpenFileDialog { Filter = "Plist (*.plist)|*.plist", CheckFileExists = true };
+ OpenFileDialog dialog = new OpenFileDialog() { Filter = "Plist (*.plist)|*.plist", CheckFileExists = true };
dialog.ShowDialog();
string filename = dialog.FileName;
@@ -1607,7 +1617,7 @@ namespace HandBrakeWPF.ViewModels
/// </summary>
public void PresetExport()
{
- VistaSaveFileDialog savefiledialog = new VistaSaveFileDialog
+ SaveFileDialog savefiledialog = new SaveFileDialog
{
Filter = "plist|*.plist",
CheckPathExists = true,
@@ -1626,7 +1636,7 @@ namespace HandBrakeWPF.ViewModels
PlistUtility.Export(
savefiledialog.FileName,
this.selectedPreset,
- userSettingService.GetUserSetting<int>(ASUserSettingConstants.HandBrakeBuild)
+ this.userSettingService.GetUserSetting<int>(ASUserSettingConstants.HandBrakeBuild)
.ToString(CultureInfo.InvariantCulture));
}
}
@@ -1813,12 +1823,12 @@ namespace HandBrakeWPF.ViewModels
switch (this.SelectedPointToPoint)
{
case PointToPointMode.Chapters:
- return this.SelectedTitle.CalculateDuration(this.SelectedStartPoint, this.SelectedEndPoint).ToString();
+ return this.SelectedTitle.CalculateDuration(this.SelectedStartPoint, this.SelectedEndPoint).ToString("g");
case PointToPointMode.Seconds:
- return TimeSpan.FromSeconds(startEndDuration).ToString();
+ return TimeSpan.FromSeconds(startEndDuration).ToString("g");
case PointToPointMode.Frames:
startEndDuration = startEndDuration / selectedTitle.Fps;
- return TimeSpan.FromSeconds(startEndDuration).ToString();
+ return TimeSpan.FromSeconds(Math.Round(startEndDuration, 2)).ToString("g");
}
return "--:--:--";
@@ -1955,15 +1965,20 @@ namespace HandBrakeWPF.ViewModels
Math.Round(e.PercentComplete).ToString(CultureInfo.InvariantCulture),
out percent);
-
Execute.OnUIThread(
() =>
{
if (this.queueProcessor.EncodeService.IsEncoding)
{
+ string josPending = string.Empty;
+ if (!AppArguments.IsInstantHandBrake)
+ {
+ josPending = ", Pending Jobs {5}";
+ }
+
this.ProgramStatusLabel =
string.Format(
- "{0:00.00}%, FPS: {1:000.0}, Avg FPS: {2:000.0}, Time Remaining: {3}, Elapsed: {4:hh\\:mm\\:ss}, Pending Jobs {5}",
+ "{0:00.00}%, FPS: {1:000.0}, Avg FPS: {2:000.0}, Time Remaining: {3}, Elapsed: {4:hh\\:mm\\:ss}" + josPending,
e.PercentComplete,
e.CurrentFrameRate,
e.AverageFrameRate,
@@ -2082,7 +2097,7 @@ namespace HandBrakeWPF.ViewModels
SourceMenuItem folderScan = new SourceMenuItem
{
- Image = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/HandBrake;component/Views/Images/folder.png")), Width = 16, Height = 16 },
+ IsOpenFolder = true,
Text = "Open Folder",
Command = new SourceMenuCommand(this.FolderScan),
IsDrive = false,
@@ -2090,7 +2105,7 @@ namespace HandBrakeWPF.ViewModels
};
SourceMenuItem fileScan = new SourceMenuItem
{
- Image = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/HandBrake;component/Views/Images/Movies.png")), Width = 16, Height = 16 },
+ IsOpenFolder = false,
Text = "Open File",
Command = new SourceMenuCommand(this.FileScan),
IsDrive = false,
@@ -2100,14 +2115,14 @@ namespace HandBrakeWPF.ViewModels
SourceMenuItem titleSpecific = new SourceMenuItem { Text = "Title Specific Scan" };
SourceMenuItem folderScanTitle = new SourceMenuItem
{
- Image = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/HandBrake;component/Views/Images/folder.png")), Width = 16, Height = 16 },
+ IsOpenFolder = true,
Text = "Open Folder",
Command = new SourceMenuCommand(this.FolderScanTitleSpecific),
IsDrive = false
};
SourceMenuItem fileScanTitle = new SourceMenuItem
{
- Image = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/HandBrake;component/Views/Images/Movies.png")), Width = 16, Height = 16 },
+ IsOpenFolder = false,
Text = "Open File",
Command = new SourceMenuCommand(this.FileScanTitleSpecific),
IsDrive = false
@@ -2126,7 +2141,6 @@ namespace HandBrakeWPF.ViewModels
select
new SourceMenuItem
{
- Image = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/HandBrake;component/Views/Images/disc_small.png")), Width = 16, Height = 16 },
Text = string.Format("{0} ({1})", item.RootDirectory, item.VolumeLabel),
Command = new SourceMenuCommand(() => this.ProcessDrive(driveInformation)),
Tag = item,
diff --git a/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs
index e1376363a..b84b6f922 100644
--- a/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs
@@ -363,6 +363,11 @@ namespace HandBrakeWPF.ViewModels
/// </summary>
private bool useSystemColoursForStyles;
+ /// <summary>
+ /// The reset when done action.
+ /// </summary>
+ private bool resetWhenDoneAction;
+
#endregion
#region Constructors and Destructors
@@ -441,6 +446,23 @@ namespace HandBrakeWPF.ViewModels
}
/// <summary>
+ /// Gets or sets a value indicating whether reset when done action.
+ /// </summary>
+ public bool ResetWhenDoneAction
+ {
+ get
+ {
+ return this.resetWhenDoneAction;
+ }
+
+ set
+ {
+ this.resetWhenDoneAction = value;
+ this.NotifyOfPropertyChange("ResetWhenDoneAction");
+ }
+ }
+
+ /// <summary>
/// Gets or sets CheckForUpdatesFrequencies.
/// </summary>
public BindingList<string> CheckForUpdatesFrequencies
@@ -1529,6 +1551,11 @@ namespace HandBrakeWPF.ViewModels
this.whenDoneOptions.Add("Log off");
this.whenDoneOptions.Add("Quit HandBrake");
this.WhenDone = userSettingService.GetUserSetting<string>("WhenCompleteAction");
+ if (this.userSettingService.GetUserSetting<bool>(UserSettingConstants.ResetWhenDoneAction))
+ {
+ this.WhenDone = "Do nothing";
+ this.userSettingService.SetUserSetting(UserSettingConstants.WhenCompleteAction, "Do nothing");
+ }
this.GrowlAfterEncode = userSettingService.GetUserSetting<bool>(UserSettingConstants.GrowlEncode);
this.GrowlAfterQueue = userSettingService.GetUserSetting<bool>(UserSettingConstants.GrowlQueue);
@@ -1537,6 +1564,7 @@ namespace HandBrakeWPF.ViewModels
this.SendFileToPath = this.userSettingService.GetUserSetting<string>(UserSettingConstants.SendFileTo) ?? string.Empty;
this.Arguments = this.userSettingService.GetUserSetting<string>(UserSettingConstants.SendFileToArgs) ?? string.Empty;
this.UseSystemColoursForStylesForStyles = this.userSettingService.GetUserSetting<bool>(UserSettingConstants.UseSystemColours);
+ this.ResetWhenDoneAction = this.userSettingService.GetUserSetting<bool>(UserSettingConstants.ResetWhenDoneAction);
// #############################
// Output Settings
@@ -1874,6 +1902,7 @@ namespace HandBrakeWPF.ViewModels
this.userSettingService.SetUserSetting(UserSettingConstants.SendFile, this.SendFileAfterEncode);
this.userSettingService.SetUserSetting(UserSettingConstants.SendFileToArgs, this.Arguments);
this.userSettingService.SetUserSetting(UserSettingConstants.UseSystemColours, this.UseSystemColoursForStylesForStyles);
+ this.userSettingService.SetUserSetting(UserSettingConstants.ResetWhenDoneAction, this.ResetWhenDoneAction);
/* Output Files */
this.userSettingService.SetUserSetting(UserSettingConstants.AutoNaming, this.AutomaticallyNameFiles);
diff --git a/win/CS/HandBrakeWPF/ViewModels/PictureSettingsViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/PictureSettingsViewModel.cs
index 87d0bb0c9..aa390eaa6 100644
--- a/win/CS/HandBrakeWPF/ViewModels/PictureSettingsViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/PictureSettingsViewModel.cs
@@ -11,7 +11,6 @@ namespace HandBrakeWPF.ViewModels
{
using System;
using System.Collections.Generic;
- using System.Drawing;
using System.Globalization;
using Caliburn.Micro;
@@ -19,10 +18,14 @@ namespace HandBrakeWPF.ViewModels
using HandBrake.ApplicationServices.Model;
using HandBrake.ApplicationServices.Parsing;
using HandBrake.ApplicationServices.Services.Interfaces;
+ using HandBrake.Interop.Model;
using HandBrake.Interop.Model.Encoding;
+ using HandBrakeWPF.Helpers;
using HandBrakeWPF.ViewModels.Interfaces;
+ using Size = System.Drawing.Size;
+
/// <summary>
/// The Picture Settings View Model
/// </summary>
@@ -151,6 +154,7 @@ namespace HandBrakeWPF.ViewModels
{
this.Task.Cropping.Bottom = value;
this.NotifyOfPropertyChange(() => this.CropBottom);
+ this.CropAdjust();
this.SetDisplaySize();
}
}
@@ -169,6 +173,7 @@ namespace HandBrakeWPF.ViewModels
{
this.Task.Cropping.Left = value;
this.NotifyOfPropertyChange(() => this.CropLeft);
+ this.CropAdjust();
this.SetDisplaySize();
}
}
@@ -187,6 +192,7 @@ namespace HandBrakeWPF.ViewModels
{
this.Task.Cropping.Right = value;
this.NotifyOfPropertyChange(() => this.CropRight);
+ this.CropAdjust();
this.SetDisplaySize();
}
}
@@ -205,6 +211,7 @@ namespace HandBrakeWPF.ViewModels
{
this.Task.Cropping.Top = value;
this.NotifyOfPropertyChange(() => this.CropTop);
+ this.CropAdjust();
this.SetDisplaySize();
}
}
@@ -387,9 +394,12 @@ namespace HandBrakeWPF.ViewModels
set
{
- this.Task.Anamorphic = value;
- this.AnamorphicAdjust();
- this.NotifyOfPropertyChange(() => this.SelectedAnamorphicMode);
+ if (!object.Equals(this.SelectedAnamorphicMode, value))
+ {
+ this.Task.Anamorphic = value;
+ this.AnamorphicAdjust();
+ this.NotifyOfPropertyChange(() => this.SelectedAnamorphicMode);
+ }
}
}
@@ -644,6 +654,7 @@ namespace HandBrakeWPF.ViewModels
// Do Nothing except reset the Max Width/Height
this.MaxWidth = this.sourceResolution.Width;
this.MaxHeight = this.sourceResolution.Height;
+ this.SelectedAnamorphicMode = preset.Task.Anamorphic;
break;
}
@@ -709,6 +720,24 @@ namespace HandBrakeWPF.ViewModels
this.sourceParValues = title.ParVal;
this.sourceResolution = title.Resolution;
+ // Update the cropping values, preffering those in the presets.
+ if (!preset.Task.HasCropping)
+ {
+ this.CropTop = title.AutoCropDimensions.Top;
+ this.CropBottom = title.AutoCropDimensions.Bottom;
+ this.CropLeft = title.AutoCropDimensions.Left;
+ this.CropRight = title.AutoCropDimensions.Right;
+ this.IsCustomCrop = false;
+ }
+ else
+ {
+ this.CropLeft = preset.Task.Cropping.Left;
+ this.CropRight = preset.Task.Cropping.Right;
+ this.CropTop = preset.Task.Cropping.Top;
+ this.CropBottom = preset.Task.Cropping.Bottom;
+ this.IsCustomCrop = true;
+ }
+
if (preset.PictureSettingsMode == PresetPictureSettingsMode.None)
{
// We have no instructions, so simply set it to the source.
@@ -737,7 +766,15 @@ namespace HandBrakeWPF.ViewModels
}
// Set the Width, and Maintain Aspect ratio. That should calc the Height for us.
- this.Width = preset.Task.Width ?? this.MaxWidth; // Note: This will be auto-corrected in the property if it's too large.
+ if (this.SelectedAnamorphicMode == Anamorphic.None)
+ {
+ this.Width = preset.Task.Width ?? (this.MaxWidth - this.CropLeft - this.CropRight);
+ // Note: This will be auto-corrected in the property if it's too large.
+ }
+ else
+ {
+ this.Width = preset.Task.Width ?? this.MaxWidth;
+ }
// If our height is too large, let it downscale the width for us by setting the height to the lower value.
if (!this.MaintainAspectRatio && this.Height > this.MaxHeight)
@@ -751,30 +788,14 @@ namespace HandBrakeWPF.ViewModels
}
}
- // Update the cropping values, preffering those in the presets.
- if (!preset.Task.HasCropping)
- {
- this.CropTop = title.AutoCropDimensions.Top;
- this.CropBottom = title.AutoCropDimensions.Bottom;
- this.CropLeft = title.AutoCropDimensions.Left;
- this.CropRight = title.AutoCropDimensions.Right;
- this.IsCustomCrop = false;
- }
- else
- {
- this.CropLeft = preset.Task.Cropping.Left;
- this.CropRight = preset.Task.Cropping.Right;
- this.CropTop = preset.Task.Cropping.Top;
- this.CropBottom = preset.Task.Cropping.Bottom;
- this.IsCustomCrop = true;
- }
-
// Set Screen Controls
this.SourceInfo = string.Format(
- "{0}x{1}, Aspect Ratio: {2:0.00}",
+ "{0}x{1}, Aspect Ratio: {2:0.00}, PAR: {3}/{4}",
title.Resolution.Width,
title.Resolution.Height,
- title.AspectRatio);
+ title.AspectRatio,
+ title.ParVal.Width,
+ title.ParVal.Height);
}
this.NotifyOfPropertyChange(() => this.Task);
@@ -787,17 +808,33 @@ namespace HandBrakeWPF.ViewModels
#region Methods
/// <summary>
+ /// The crop adjust.
+ /// </summary>
+ private void CropAdjust()
+ {
+ PictureSize.AnamorphicResult result = PictureSize.hb_set_anamorphic_size(this.GetPictureSettings(), this.GetPictureTitleInfo());
+ switch (this.SelectedAnamorphicMode)
+ {
+ case Anamorphic.None:
+ // this.Width = result.OutputWidth;
+ // this.Height = result.OutputHeight;
+ break;
+ case Anamorphic.Strict:
+ case Anamorphic.Loose:
+ case Anamorphic.Custom:
+ double dispWidth = Math.Round((result.OutputWidth * result.OutputParWidth / result.OutputParHeight), 0);
+ this.DisplaySize = this.sourceResolution.IsEmpty
+ ? string.Empty
+ : string.Format("Storage: {0}x{1}, Display: {2}x{3}", result.OutputWidth, result.OutputHeight, dispWidth, result.OutputHeight);
+ break;
+ }
+ }
+
+ /// <summary>
/// Adjust other values after the user has altered the anamorphic.
/// </summary>
private void AnamorphicAdjust()
{
- this.DisplaySize = this.sourceResolution.IsEmpty
- ? "No Title Selected"
- : string.Format(
- "{0}x{1}",
- this.CalculateAnamorphicSizes().Width,
- this.CalculateAnamorphicSizes().Height);
-
this.ShowDisplaySize = true;
this.ShowKeepAR = true;
switch (this.SelectedAnamorphicMode)
@@ -807,7 +844,7 @@ namespace HandBrakeWPF.ViewModels
this.HeightControlEnabled = true;
this.ShowCustomAnamorphicControls = false;
this.ShowModulus = true;
- this.ShowDisplaySize = false;
+ this.ShowDisplaySize = true;
this.ShowKeepAR = true;
this.SelectedModulus = 16; // Reset
if (this.Width == 0)
@@ -820,6 +857,8 @@ namespace HandBrakeWPF.ViewModels
this.Height = this.GetModulusValue(this.sourceResolution.Height - this.CropTop - this.CropBottom);
}
+ this.MaintainAspectRatio = true;
+
this.SetDisplaySize();
break;
case Anamorphic.Strict:
@@ -840,11 +879,10 @@ namespace HandBrakeWPF.ViewModels
this.HeightControlEnabled = false;
this.ShowCustomAnamorphicControls = false;
this.ShowModulus = true;
- if (this.Width == 0)
- {
- this.Width = this.sourceResolution.Width;
- }
- this.Height = 0;
+
+ // Reset to the source size.
+ this.Width = this.sourceResolution.Width;
+ this.Height = 0; // this.sourceResolution.Height - this.CropTop - this.CropBottom;
this.ShowKeepAR = false;
this.SetDisplaySize();
@@ -871,126 +909,26 @@ namespace HandBrakeWPF.ViewModels
this.DisplayWidth = (this.Width * this.ParWidth / this.ParHeight);
}
- //this.SetDisplaySize();
+ // this.SetDisplaySize();
break;
}
}
/// <summary>
- /// Calculate the Anamorphic Resolution for the selected title.
- /// </summary>
- /// <returns>
- /// A Size With Width/Height for this title.
- /// </returns>
- private Size CalculateAnamorphicSizes()
- {
- if (this.sourceResolution.IsEmpty)
- {
- return new Size(0, 0);
- }
-
- /* Set up some variables to make the math easier to follow. */
- int croppedWidth = this.sourceResolution.Width - this.CropLeft - this.CropRight;
- int croppedHeight = this.sourceResolution.Height - this.CropTop - this.CropBottom;
- double storageAspect = (double)croppedWidth / croppedHeight;
-
- /* Figure out what width the source would display at. */
- double sourceDisplayWidth = (double)croppedWidth * this.sourceParValues.Width / this.sourceParValues.Height;
-
- /*
- 3 different ways of deciding output dimensions:
- - 1: Strict anamorphic, preserve source dimensions
- - 2: Loose anamorphic, round to mod16 and preserve storage aspect ratio
- - 3: Power user anamorphic, specify everything
- */
- double calcHeight;
- switch (this.SelectedAnamorphicMode)
- {
- default:
- case Anamorphic.Strict:
-
- /* Strict anamorphic */
- double dispWidth = ((double)croppedWidth * this.sourceParValues.Width / this.sourceParValues.Height);
- dispWidth = Math.Round(dispWidth, 0);
- Size output = new Size((int)dispWidth, croppedHeight);
- return output;
-
- case Anamorphic.Loose:
-
- /* "Loose" anamorphic.
- - Uses mod16-compliant dimensions,
- - Allows users to set the width
- */
- double calcWidth = this.GetModulusValue(this.Width);
- calcHeight = (calcWidth / storageAspect) + 0.5;
- calcHeight = this.GetModulusValue(calcHeight); /* Time to get picture height that divide cleanly.*/
-
- /* The film AR is the source's display width / cropped source height.
- The output display width is the output height * film AR.
- The output PAR is the output display width / output storage width. */
- double pixelAspectWidth = calcHeight * sourceDisplayWidth / croppedHeight;
- double pixelAspectHeight = calcWidth;
-
- double disWidthLoose = (calcWidth * pixelAspectWidth / pixelAspectHeight);
- if (double.IsNaN(disWidthLoose))
- {
- disWidthLoose = 0;
- }
-
- return new Size((int)disWidthLoose, (int)calcHeight);
-
- case Anamorphic.Custom:
- // Get the User Interface Values
- double uIdisplayWidth;
- double.TryParse(this.DisplayWidth.ToString(CultureInfo.InvariantCulture), NumberStyles.Any, CultureInfo.InvariantCulture, out uIdisplayWidth);
-
- /* Anamorphic 3: Power User Jamboree - Set everything based on specified values */
- calcHeight = this.GetModulusValue(this.Height);
-
- if (this.MaintainAspectRatio)
- {
- return new Size((int)Math.Truncate(uIdisplayWidth), (int)calcHeight);
- }
-
- return new Size((int)Math.Truncate(uIdisplayWidth), (int)calcHeight);
- }
- }
-
- /// <summary>
- /// Correct the new value so that the result of the modulus of that value is 0
- /// </summary>
- /// <param name="oldValue">
- /// The old value.
- /// </param>
- /// <param name="newValue">
- /// The new value.
- /// </param>
- /// <returns>
- /// The Value corrected so that for a given modulus the result is 0
- /// </returns>
- private int CorrectForModulus(int oldValue, int newValue)
- {
- int remainder = newValue % 2;
- if (remainder == 0)
- {
- return newValue;
- }
-
- return newValue > oldValue ? newValue + remainder : newValue - remainder;
- }
-
- /// <summary>
/// Adjust other values after the user has altered one of the custom anamorphic settings
/// </summary>
private void CustomAnamorphicAdjust()
{
- if (this.MaintainAspectRatio && this.DisplayWidth != 0)
+ if (this.SelectedAnamorphicMode == Anamorphic.Custom)
{
- this.ParWidth = this.DisplayWidth;
- this.ParHeight = this.Width;
- }
+ if (this.MaintainAspectRatio && this.DisplayWidth != 0)
+ {
+ this.ParWidth = this.DisplayWidth;
+ this.ParHeight = this.Width;
+ }
- this.SetDisplaySize();
+ this.SetDisplaySize();
+ }
}
/// <summary>
@@ -1075,12 +1013,24 @@ namespace HandBrakeWPF.ViewModels
/// </summary>
private void SetDisplaySize()
{
- this.DisplaySize = this.sourceResolution.IsEmpty
- ? "No Title Selected"
- : string.Format(
- "{0}x{1}",
- this.CalculateAnamorphicSizes().Width,
- this.CalculateAnamorphicSizes().Height);
+ /*
+ * Handle Anamorphic Display
+ */
+ if (this.SelectedAnamorphicMode != Anamorphic.None)
+ {
+ PictureSize.AnamorphicResult result = PictureSize.hb_set_anamorphic_size(this.GetPictureSettings(), this.GetPictureTitleInfo());
+ double dispWidth = Math.Round((result.OutputWidth * result.OutputParWidth / result.OutputParHeight), 0);
+
+ this.DisplaySize = this.sourceResolution.IsEmpty
+ ? string.Empty
+ : string.Format("Output: {0}x{1}, Anamorphic: {2}x{3}", result.OutputWidth, result.OutputHeight, dispWidth, result.OutputHeight);
+ }
+ else
+ {
+ this.DisplaySize = this.sourceResolution.IsEmpty
+ ? string.Empty
+ : string.Format("Output: {0}x{1}", this.Width, this.Height);
+ }
}
/// <summary>
@@ -1159,6 +1109,60 @@ namespace HandBrakeWPF.ViewModels
return max.HasValue ? (value > max.Value ? max.Value : value) : value;
}
+ /// <summary>
+ /// The get picture title info.
+ /// </summary>
+ /// <returns>
+ /// The <see cref="PictureSize.PictureSettingsTitle"/>.
+ /// </returns>
+ private PictureSize.PictureSettingsTitle GetPictureTitleInfo()
+ {
+ PictureSize.PictureSettingsTitle title = new PictureSize.PictureSettingsTitle
+ {
+ Width = this.sourceResolution.Width,
+ Height = this.sourceResolution.Height,
+ ParW = this.sourceParValues.Width,
+ ParH = this.sourceParValues.Height,
+ Aspect = 0 // TODO
+ };
+
+ return title;
+ }
+
+ /// <summary>
+ /// The get picture settings.
+ /// </summary>
+ /// <returns>
+ /// The <see cref="PictureSize.PictureSettingsJob"/>.
+ /// </returns>
+ private PictureSize.PictureSettingsJob GetPictureSettings()
+ {
+ PictureSize.PictureSettingsJob job = new PictureSize.PictureSettingsJob
+ {
+ Width = this.Width,
+ Height = this.Height,
+ ItuPar = false,
+ Modulus = this.SelectedModulus,
+ ParW = this.ParWidth,
+ ParH = this.ParHeight,
+ MaxWidth = this.MaxWidth,
+ MaxHeight = this.MaxHeight,
+ KeepDisplayAspect = this.MaintainAspectRatio,
+ AnamorphicMode = this.SelectedAnamorphicMode,
+ DarWidth = 0,
+ DarHeight = 0,
+ Crop = new Cropping(this.CropTop, this.CropBottom, this.CropLeft, this.CropRight),
+ };
+
+ if (this.SelectedAnamorphicMode == Anamorphic.Loose)
+ {
+ job.ParW = sourceParValues.Width;
+ job.ParH = sourceParValues.Height;
+ }
+
+ return job;
+ }
+
#endregion
}
} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs
index 65f67c43a..972c46d94 100644
--- a/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs
@@ -242,7 +242,7 @@ namespace HandBrakeWPF.ViewModels
this.JobsPending = string.Format("{0} jobs pending", this.queueProcessor.Count);
this.IsEncoding = false;
- MessageBox.Show("The Queue has been pasued. The currently running job will run to completion and no further jobs will start.", "Queue",
+ MessageBox.Show("The Queue has been paused. The currently running job will run to completion and no further jobs will start.", "Queue",
MessageBoxButton.OK, MessageBoxImage.Information);
}
@@ -319,9 +319,10 @@ namespace HandBrakeWPF.ViewModels
DefaultExt = ".hbq",
AddExtension = true
};
- dialog.ShowDialog();
-
- this.queueProcessor.BackupQueue(dialog.FileName);
+ if (dialog.ShowDialog() == true)
+ {
+ this.queueProcessor.BackupQueue(dialog.FileName);
+ }
}
/// <summary>
@@ -330,9 +331,10 @@ namespace HandBrakeWPF.ViewModels
public void Import()
{
VistaOpenFileDialog dialog = new VistaOpenFileDialog { Filter = "HandBrake Queue Files (*.hbq)|*.hbq", CheckFileExists = true };
- dialog.ShowDialog();
-
- this.queueProcessor.RestoreQueue(dialog.FileName);
+ if (dialog.ShowDialog() == true)
+ {
+ this.queueProcessor.RestoreQueue(dialog.FileName);
+ }
}
/// <summary>
diff --git a/win/CS/HandBrakeWPF/ViewModels/ShellViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/ShellViewModel.cs
index 39fee77fd..162898f68 100644
--- a/win/CS/HandBrakeWPF/ViewModels/ShellViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/ShellViewModel.cs
@@ -15,7 +15,6 @@ namespace HandBrakeWPF.ViewModels
using HandBrake.ApplicationServices.Services.Interfaces;
- using HandBrakeWPF.Helpers;
using HandBrakeWPF.Model;
using HandBrakeWPF.Services.Interfaces;
using HandBrakeWPF.ViewModels.Interfaces;
@@ -42,6 +41,11 @@ namespace HandBrakeWPF.ViewModels
/// </summary>
private bool showOptions;
+ /// <summary>
+ /// The show instant.
+ /// </summary>
+ private bool showInstant;
+
#endregion
/// <summary>
@@ -53,8 +57,19 @@ namespace HandBrakeWPF.ViewModels
public ShellViewModel(IErrorService errorService)
{
this.errorService = errorService;
- this.showMainWindow = true;
- this.showOptions = false;
+
+ if (!AppArguments.IsInstantHandBrake)
+ {
+ this.showMainWindow = true;
+ this.showOptions = false;
+ this.showInstant = false;
+ }
+ else
+ {
+ this.showMainWindow = false;
+ this.showOptions = false;
+ this.showInstant = true;
+ }
}
/// <summary>
@@ -69,16 +84,25 @@ namespace HandBrakeWPF.ViewModels
{
this.ShowMainWindow = true;
this.ShowOptions = false;
+ this.ShowInstant = false;
}
else if (window == ShellWindow.OptionsWindow)
{
this.ShowOptions = true;
this.ShowMainWindow = false;
+ this.ShowInstant = false;
+ }
+ else if (window == ShellWindow.InstantMainWindow)
+ {
+ this.ShowInstant = true;
+ this.ShowOptions = false;
+ this.ShowMainWindow = false;
}
else
{
this.ShowMainWindow = true;
this.ShowOptions = false;
+ this.ShowInstant = false;
}
}
@@ -95,6 +119,11 @@ namespace HandBrakeWPF.ViewModels
public IOptionsViewModel OptionsViewModel { get; set; }
/// <summary>
+ /// Gets or sets the instant view model.
+ /// </summary>
+ public IInstantViewModel InstantViewModel { get; set; }
+
+ /// <summary>
/// Gets or sets a value indicating whether ShowMainWindow.
/// </summary>
public bool ShowMainWindow
@@ -127,13 +156,29 @@ namespace HandBrakeWPF.ViewModels
}
/// <summary>
+ /// Gets or sets a value indicating whether ShowInstant.
+ /// </summary>
+ public bool ShowInstant
+ {
+ get
+ {
+ return this.showInstant;
+ }
+ set
+ {
+ this.showInstant = value;
+ this.NotifyOfPropertyChange(() => this.ShowInstant);
+ }
+ }
+
+ /// <summary>
/// Gets WindowTitle.
/// </summary>
public string WindowTitle
{
get
{
- return "HandBrake";
+ return AppArguments.IsInstantHandBrake ? "Instant HandBrake" : "HandBrake";
}
}
diff --git a/win/CS/HandBrakeWPF/ViewModels/SubtitlesViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/SubtitlesViewModel.cs
index feabc08f3..8b93173a2 100644
--- a/win/CS/HandBrakeWPF/ViewModels/SubtitlesViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/SubtitlesViewModel.cs
@@ -385,7 +385,7 @@ namespace HandBrakeWPF.ViewModels
if ((source.SubtitleType == SubtitleType.PGS || source.SubtitleType == SubtitleType.VobSub) &&
this.Task != null &&
- (this.Task.OutputFormat == OutputFormat.Mp4 || this.Task.OutputFormat == OutputFormat.M4V))
+ (this.Task.OutputFormat == OutputFormat.Mp4 || this.Task.OutputFormat == OutputFormat.M4V || this.Task.OutputFormat == OutputFormat.av_mp4))
{
this.SelectBurnedInTrack(track);
}
diff --git a/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs
index a59c9c32f..bc07f57f5 100644
--- a/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs
@@ -14,6 +14,7 @@ namespace HandBrakeWPF.ViewModels
using System.ComponentModel;
using System.Globalization;
using System.Linq;
+ using System.Windows;
using Caliburn.Micro;
@@ -27,7 +28,6 @@ namespace HandBrakeWPF.ViewModels
using HandBrake.Interop.Model.Encoding.x264;
using HandBrakeWPF.Commands.Interfaces;
- using HandBrakeWPF.Model;
using HandBrakeWPF.Properties;
using HandBrakeWPF.ViewModels.Interfaces;
@@ -63,6 +63,16 @@ namespace HandBrakeWPF.ViewModels
private bool displayX264Options;
/// <summary>
+ /// The display qsv options.
+ /// </summary>
+ private bool displayQSVOptions;
+
+ /// <summary>
+ /// Backing field used to display / hide the h264 options
+ /// </summary>
+ private bool displayEncoderOptions;
+
+ /// <summary>
/// The quality max.
/// </summary>
private int qualityMax;
@@ -88,6 +98,11 @@ namespace HandBrakeWPF.ViewModels
private int x264PresetValue;
/// <summary>
+ /// The qsv preset value.
+ /// </summary>
+ private int qsvPresetValue;
+
+ /// <summary>
/// The extra arguments.
/// </summary>
private string extraArguments;
@@ -102,6 +117,11 @@ namespace HandBrakeWPF.ViewModels
/// </summary>
private bool useAdvancedTab;
+ /// <summary>
+ /// The display framerate controls.
+ /// </summary>
+ private bool displayNonQSVControls;
+
#endregion
#region Constructors and Destructors
@@ -126,6 +146,7 @@ namespace HandBrakeWPF.ViewModels
this.VideoEncoders = EnumHelper<VideoEncoder>.GetEnumList();
X264Presets = new BindingList<x264Preset>(EnumHelper<x264Preset>.GetEnumList().ToList());
+ QsvPresets = new BindingList<QsvPreset>(EnumHelper<QsvPreset>.GetEnumList().ToList());
H264Profiles = EnumHelper<x264Profile>.GetEnumList();
X264Tunes = EnumHelper<x264Tune>.GetEnumList().Where(t => t != x264Tune.Fastdecode);
this.H264Levels = Levels;
@@ -149,13 +170,17 @@ namespace HandBrakeWPF.ViewModels
{
get
{
- bool showAdvTabSetting =
- this.userSettingService.GetUserSetting<bool>(UserSettingConstants.ShowAdvancedTab);
+ bool showAdvTabSetting = this.userSettingService.GetUserSetting<bool>(UserSettingConstants.ShowAdvancedTab);
if (!showAdvTabSetting)
{
this.UseAdvancedTab = false;
}
+ if (this.SelectedVideoEncoder == VideoEncoder.QuickSync)
+ {
+ return false;
+ }
+
return showAdvTabSetting;
}
}
@@ -173,6 +198,17 @@ namespace HandBrakeWPF.ViewModels
{
if (!object.Equals(value, this.useAdvancedTab))
{
+ // Set the Advanced Tab up with the current settings, if we can.
+ if (value && !this.userSettingService.GetUserSetting<bool>(UserSettingConstants.DisableLibHbFeatures))
+ {
+ this.Task.AdvancedEncoderOptions = this.GetActualx264Query();
+ }
+
+ if (!value)
+ {
+ this.Task.AdvancedEncoderOptions = string.Empty;
+ }
+
this.useAdvancedTab = value;
this.Task.ShowAdvancedTab = value;
this.NotifyOfPropertyChange(() => this.UseAdvancedTab);
@@ -292,7 +328,7 @@ namespace HandBrakeWPF.ViewModels
{
get
{
- return 0.0.Equals(this.DisplayRF);
+ return 0.0.Equals(this.DisplayRF) && this.SelectedVideoEncoder == VideoEncoder.X264;
}
}
@@ -355,6 +391,7 @@ namespace HandBrakeWPF.ViewModels
case VideoEncoder.FFMpeg2:
this.Task.Quality = (32 - value);
break;
+ case VideoEncoder.QuickSync:
case VideoEncoder.X264:
double rfValue = 51.0 - value * cqStep;
rfValue = Math.Round(rfValue, 2);
@@ -383,6 +420,40 @@ namespace HandBrakeWPF.ViewModels
}
/// <summary>
+ /// Gets or sets a value indicating whether two pass.
+ /// </summary>
+ public bool TwoPass
+ {
+ get
+ {
+ return this.Task.TwoPass;
+ }
+
+ set
+ {
+ this.Task.TwoPass = value;
+ this.NotifyOfPropertyChange(() => this.TwoPass);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether turbo first pass.
+ /// </summary>
+ public bool TurboFirstPass
+ {
+ get
+ {
+ return this.Task.TurboFirstPass;
+ }
+
+ set
+ {
+ this.Task.TurboFirstPass = value;
+ this.NotifyOfPropertyChange(() => this.TurboFirstPass);
+ }
+ }
+
+ /// <summary>
/// Gets the rfqp.
/// </summary>
public string Rfqp
@@ -469,9 +540,23 @@ namespace HandBrakeWPF.ViewModels
// Hide the x264 controls when not needed.
this.DisplayX264Options = value == VideoEncoder.X264;
+ this.DisplayQSVOptions = value == VideoEncoder.QuickSync;
+ this.DisplayH264Options = value == VideoEncoder.X264 || value == VideoEncoder.QuickSync;
+ this.UseAdvancedTab = value != VideoEncoder.QuickSync && this.UseAdvancedTab;
+ this.DisplayNonQSVControls = value != VideoEncoder.QuickSync;
this.NotifyOfPropertyChange(() => this.Rfqp);
+ this.NotifyOfPropertyChange(() => this.ShowAdvancedTab);
+
this.NotifyOfPropertyChange(() => this.HighQualityLabel);
+ if (value == VideoEncoder.QuickSync)
+ {
+ this.IsConstantFramerate = true;
+ this.TwoPass = false;
+ this.TurboFirstPass = false;
+ this.Task.Framerate = null;
+ this.NotifyOfPropertyChange(() => SelectedFramerate);
+ }
}
}
@@ -507,7 +592,7 @@ namespace HandBrakeWPF.ViewModels
}
set
{
- if (!object.Equals(this.Task.AdvancedEncoderOptions, value))
+ if (!object.Equals(this.Task.ExtraAdvancedArguments, value))
{
this.Task.ExtraAdvancedArguments = value;
this.NotifyOfPropertyChange(() => this.ExtraArguments);
@@ -515,6 +600,23 @@ namespace HandBrakeWPF.ViewModels
}
}
}
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to display H264
+ /// </summary>
+ public bool DisplayH264Options
+ {
+ get
+ {
+ return this.displayEncoderOptions;
+ }
+ set
+ {
+ this.displayEncoderOptions = value;
+ this.NotifyOfPropertyChange(() => this.DisplayH264Options);
+ }
+ }
+
/// <summary>
/// Gets or sets a value indicating whether display x 264 options.
@@ -533,6 +635,40 @@ namespace HandBrakeWPF.ViewModels
}
}
+
+ /// <summary>
+ /// Gets or sets a value indicating whether to display qsv options.
+ /// </summary>
+ public bool DisplayQSVOptions
+ {
+ get
+ {
+ return this.displayQSVOptions;
+ }
+ set
+ {
+ this.displayQSVOptions = value;
+ this.NotifyOfPropertyChange(() => this.DisplayQSVOptions);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether display framerate controls.
+ /// </summary>
+ public bool DisplayNonQSVControls
+ {
+ get
+ {
+ return this.displayNonQSVControls;
+ }
+
+ set
+ {
+ this.displayNonQSVControls = value;
+ this.NotifyOfPropertyChange(() => this.DisplayNonQSVControls);
+ }
+ }
+
/// <summary>
/// Gets or sets the x 264 preset value.
/// </summary>
@@ -574,6 +710,45 @@ namespace HandBrakeWPF.ViewModels
}
}
}
+
+ /// <summary>
+ /// Gets or sets X264Preset.
+ /// </summary>
+ public QsvPreset QsvPreset
+ {
+ get
+ {
+ return this.Task.QsvPreset;
+ }
+ set
+ {
+ if (!object.Equals(this.QsvPreset, value))
+ {
+ this.Task.QsvPreset = value;
+ this.NotifyOfPropertyChange(() => this.QsvPreset);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the x 264 preset value.
+ /// </summary>
+ public int QsvPresetValue
+ {
+ get
+ {
+ return this.qsvPresetValue;
+ }
+ set
+ {
+ if (!object.Equals(this.QsvPresetValue, value))
+ {
+ this.qsvPresetValue = value;
+ this.QsvPreset = this.QsvPresets[value];
+ this.NotifyOfPropertyChange(() => this.QsvPresetValue);
+ }
+ }
+ }
/// <summary>
/// Gets or sets H264Profile.
@@ -666,6 +841,12 @@ namespace HandBrakeWPF.ViewModels
public BindingList<x264Preset> X264Presets { get; set; }
/// <summary>
+ /// Gets or sets QsvPreset.
+ /// </summary>
+ public BindingList<QsvPreset> QsvPresets { get; set; }
+
+
+ /// <summary>
/// Gets or sets X264Profiles.
/// </summary>
public IEnumerable<x264Profile> H264Profiles { get; set; }
@@ -691,6 +872,17 @@ namespace HandBrakeWPF.ViewModels
}
}
+ /// <summary>
+ /// Gets the qsv slider max.
+ /// </summary>
+ public int QsvSliderMax
+ {
+ get
+ {
+ return SystemInfo.IsHswOrNewer ? 2 : 1;
+ }
+ }
+
#endregion
#region Public Methods
@@ -763,6 +955,7 @@ namespace HandBrakeWPF.ViewModels
this.RF = 32 - cq;
}
break;
+ case VideoEncoder.QuickSync:
case VideoEncoder.X264:
double multiplier = 1.0 / cqStep;
@@ -801,6 +994,10 @@ namespace HandBrakeWPF.ViewModels
this.FastDecode = preset.Task.VideoEncoder == VideoEncoder.X264 && preset.Task.FastDecode;
this.ExtraArguments = preset.Task.ExtraAdvancedArguments;
+ this.QsvPresetValue = preset.Task.VideoEncoder == VideoEncoder.QuickSync
+ ? (int)preset.Task.QsvPreset
+ : SystemInfo.IsHswOrNewer ? (int)QsvPreset.Quality : (int)QsvPreset.Balanced;
+
this.UseAdvancedTab = !string.IsNullOrEmpty(preset.Task.AdvancedEncoderOptions) && this.ShowAdvancedTab;
}
}
@@ -832,6 +1029,7 @@ namespace HandBrakeWPF.ViewModels
this.NotifyOfPropertyChange(() => this.H264Profile);
this.NotifyOfPropertyChange(() => this.FastDecode);
this.NotifyOfPropertyChange(() => this.ExtraArguments);
+ this.NotifyOfPropertyChange(() => this.QsvPreset);
}
/// <summary>
@@ -842,7 +1040,14 @@ namespace HandBrakeWPF.ViewModels
/// </param>
public void SetEncoder(VideoEncoder encoder)
{
+ this.DisplayH264Options = encoder == VideoEncoder.X264 || encoder == VideoEncoder.QuickSync;
this.DisplayX264Options = encoder == VideoEncoder.X264;
+ this.DisplayQSVOptions = encoder == VideoEncoder.QuickSync;
+
+ if (encoder == VideoEncoder.QuickSync)
+ {
+ this.UseAdvancedTab = false;
+ }
}
/// <summary>
@@ -852,7 +1057,7 @@ namespace HandBrakeWPF.ViewModels
{
this.NotifyOfPropertyChange(() => this.Task);
- if (Task.OutputFormat == OutputFormat.Mp4 && this.SelectedVideoEncoder == VideoEncoder.Theora)
+ if ((Task.OutputFormat == OutputFormat.Mp4 || Task.OutputFormat == OutputFormat.av_mp4) && this.SelectedVideoEncoder == VideoEncoder.Theora)
{
this.SelectedVideoEncoder = VideoEncoder.X264;
}
@@ -873,6 +1078,14 @@ namespace HandBrakeWPF.ViewModels
this.canClear = true;
}
+ /// <summary>
+ /// The copy query.
+ /// </summary>
+ public void CopyQuery()
+ {
+ Clipboard.SetDataObject(this.SelectedVideoEncoder == VideoEncoder.X264 ? this.GetActualx264Query() : this.ExtraArguments);
+ }
+
#endregion
/// <summary>
@@ -890,6 +1103,7 @@ namespace HandBrakeWPF.ViewModels
this.QualityMax = 31;
break;
case VideoEncoder.X264:
+ case VideoEncoder.QuickSync:
this.QualityMin = 0;
this.QualityMax = (int)(51 / userSettingService.GetUserSetting<double>(UserSettingConstants.X264Step));
break;
diff --git a/win/CS/HandBrakeWPF/ViewModels/X264ViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/X264ViewModel.cs
index e981b3e02..94d425c7e 100644
--- a/win/CS/HandBrakeWPF/ViewModels/X264ViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/X264ViewModel.cs
@@ -187,6 +187,7 @@ namespace HandBrakeWPF.ViewModels
{
ShowX264AdvancedOptions = this.Task.ShowAdvancedTab;
this.NotifyOfPropertyChange(() => ShowX264AdvancedOptions);
+ this.NotifyOfPropertyChange(() => this.AdvancedOptionsString);
}
}
diff --git a/win/CS/HandBrakeWPF/Views/AddPresetView.xaml b/win/CS/HandBrakeWPF/Views/AddPresetView.xaml
index b49b439a6..0c398eaaf 100644
--- a/win/CS/HandBrakeWPF/Views/AddPresetView.xaml
+++ b/win/CS/HandBrakeWPF/Views/AddPresetView.xaml
@@ -5,7 +5,7 @@
xmlns:Converters="clr-namespace:HandBrakeWPF.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:Properties="clr-namespace:HandBrakeWPF.Properties"
+ xmlns:Properties="clr-namespace:HandBrakeWPF.Properties" xmlns:controls="clr-namespace:HandBrakeWPF.Controls"
Title="{Binding Title}"
Width="350"
ResizeMode="NoResize"
@@ -106,11 +106,13 @@
Orientation="Horizontal"
Visibility="{Binding ShowCustomInputs,
Converter={StaticResource boolToVisConverter}}">
- <TextBox Width="50" Text="{Binding CustomWidth}" />
+ <controls:NumberBox Width="60" Number="{Binding CustomWidth, Mode=TwoWay}" HorizontalAlignment="Left" Margin="0,0,0,5"
+ AllowEmpty="True" />
<TextBlock Margin="10,0,10,0"
FontWeight="Bold"
Text="X" />
- <TextBox Width="50" Text="{Binding CustomHeight}" />
+ <controls:NumberBox Width="60" Number="{Binding CustomHeight, Mode=TwoWay}" HorizontalAlignment="Left" Margin="0,0,0,5"
+ AllowEmpty="True" />
</StackPanel>
<CheckBox Grid.Row="4"
diff --git a/win/CS/HandBrakeWPF/Views/AudioView.xaml b/win/CS/HandBrakeWPF/Views/AudioView.xaml
index 99e0da02c..0b9dd5a8d 100644
--- a/win/CS/HandBrakeWPF/Views/AudioView.xaml
+++ b/win/CS/HandBrakeWPF/Views/AudioView.xaml
@@ -10,9 +10,12 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:NumericUpDown="clr-namespace:EagleBoost.Wpf.Presentation.Controls.NumericUpDown;assembly=EagleBoost.Wpf.Presentation"
xmlns:dropButton="clr-namespace:HandBrakeWPF.Controls.DropButton"
+ xmlns:splitButton="clr-namespace:HandBrakeWPF.Controls.SplitButton"
+ xmlns:controls="clr-namespace:HandBrakeWPF.Controls"
d:DesignHeight="170"
d:DesignWidth="616"
- mc:Ignorable="d">
+ mc:Ignorable="d"
+ x:Name="audioTab">
<UserControl.Resources>
<Conveters:EnumComboConverter x:Key="enumComboConverter" />
@@ -42,16 +45,14 @@
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
- <dropButton:DropButton Content="Add Track" FontWeight="Bold" Margin="0,0,10,0" Style="{StaticResource DropButtonStyle}">
- <dropButton:DropButton.DropDown>
- <ContextMenu>
- <MenuItem Header="Add New Track" cal:Message.Attach="[Event Click] = [Action Add]" />
- <MenuItem Header="Add All Remaining Tracks" cal:Message.Attach="[Event Click] = [Action AddAllRemaining]" />
- <MenuItem Header="Add All Remaining Selected Languages" cal:Message.Attach="[Event Click] = [Action AddAllRemainingForSelectedLanguages]" />
- </ContextMenu>
- </dropButton:DropButton.DropDown>
- </dropButton:DropButton>
-
+ <splitButton:SplitMenuButton Content="Add Track" cal:Message.Attach="[Event Click] = [Action Add]" FontWeight="Bold" Margin="0,0,10,0">
+ <splitButton:SplitMenuButton.ItemSource>
+ <MenuItem Header="Add New Track" cal:Message.Attach="[Event Click] = [Action Add]" />
+ <MenuItem Header="Add All Remaining Tracks" cal:Message.Attach="[Event Click] = [Action AddAllRemaining]" />
+ <MenuItem Header="Add All Remaining Selected Languages" cal:Message.Attach="[Event Click] = [Action AddAllRemainingForSelectedLanguages]" />
+ </splitButton:SplitMenuButton.ItemSource>
+ </splitButton:SplitMenuButton>
+
<Button MinWidth="65"
Margin="0,0,10,0"
cal:Message.Attach="[Event Click] = [Action Clear]"
@@ -82,7 +83,7 @@
IsChecked="{Binding Task.AllowedPassthruOptions.AudioAllowDTSHDPass}" />
<TextBlock Margin="5,0,5,0" Text="Fallback:" />
- <ComboBox Grid.Column="3" VerticalAlignment="Center"
+ <ComboBox VerticalAlignment="Center"
Width="100"
Height="22"
Margin="10,0,5,0">
@@ -125,7 +126,7 @@
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Margin" Value="0,0,0,1" />
<Style.Triggers>
- <DataTrigger Binding="{Binding UseSystemColours}" Value="False">
+ <DataTrigger Binding="{Binding DataContext.UseSystemColours, ElementName=audioTab}" Value="False">
<Setter Property="Background" Value="WhiteSmoke" />
</DataTrigger>
</Style.Triggers>
@@ -166,10 +167,10 @@
Source="Images/Movies.png" />
<!-- Settings -->
- <Grid Grid.Column="1" Grid.Row="0" HorizontalAlignment="Stretch">
+ <Grid Grid.Column="1" Grid.Row="0" HorizontalAlignment="Stretch" Margin="0,5,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="*" MaxWidth="160" />
+ <ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
@@ -183,33 +184,16 @@
<Grid.RowDefinitions>
<RowDefinition Height="28" />
- <RowDefinition Height="28" />
</Grid.RowDefinitions>
<!-- Row 1 -->
-
- <TextBlock Grid.Column="0"
- VerticalAlignment="Center"
- FontWeight="Bold"
- Text="Source" />
- <ComboBox Grid.Column="1"
- Height="22"
- MaxWidth="150"
- Margin="5,0,5,0"
- HorizontalAlignment="Stretch"
- ItemsSource="{Binding DataContext.SourceTracks,
- RelativeSource={RelativeSource FindAncestor,
- AncestorType={x:Type UserControl}}}"
+ <TextBlock Grid.Column="0" VerticalAlignment="Center" FontWeight="Bold" Text="Source" />
+ <ComboBox Grid.Column="1" Height="22" Width="100" Margin="5,0,5,0" HorizontalAlignment="Stretch"
+ ItemsSource="{Binding DataContext.SourceTracks, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
SelectedItem="{Binding ScannedTrack}" />
-
- <TextBlock Grid.Column="2"
- VerticalAlignment="Center"
- FontWeight="Bold"
- Text="Codec" />
- <ComboBox Grid.Column="3"
- Width="100"
- Height="22"
- Margin="5,0,5,0">
+
+ <TextBlock Grid.Column="2" VerticalAlignment="Center" FontWeight="Bold" Text="Codec" />
+ <ComboBox Grid.Column="3" Width="100" Height="22" Margin="5,0,5,0">
<ComboBox.SelectedItem>
<MultiBinding Converter="{StaticResource audioEncoderConverter}">
<Binding Path="Encoder" />
@@ -223,130 +207,34 @@
</ComboBox.ItemsSource>
</ComboBox>
- <TextBlock Grid.Column="4"
- VerticalAlignment="Center"
- FontWeight="Bold"
- Text="Bitrate"
- Visibility="{Binding CannotSetBitrate,
- Converter={StaticResource boolToVisConverter},
- ConverterParameter=true}" />
- <ComboBox Grid.Column="5"
- Width="70"
- Height="22"
- Margin="5,0,5,0"
- ItemsSource="{Binding TrackReference,
- Converter={StaticResource audioBitrateConverter}}"
+ <TextBlock Grid.Column="4" VerticalAlignment="Center" FontWeight="Bold" Text="Bitrate"
+ Visibility="{Binding CannotSetBitrate, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
+ <ComboBox Grid.Column="5" Width="55" Height="22" Margin="5,0,5,0" ItemsSource="{Binding TrackReference, Converter={StaticResource audioBitrateConverter}}"
SelectedItem="{Binding Bitrate}"
- Visibility="{Binding CannotSetBitrate,
- Converter={StaticResource boolToVisConverter},
- ConverterParameter=true}" />
-
- <TextBlock Grid.Column="6"
- VerticalAlignment="Center"
- FontWeight="Bold"
- Text="Samplerate"
- Visibility="{Binding IsPassthru,
- Converter={StaticResource boolToVisConverter},
- ConverterParameter=true}" />
- <ComboBox Grid.Column="7"
- Width="70"
- Height="22"
- Margin="5,0,5,0"
- ItemsSource="{Binding DataContext.SampleRates,
- RelativeSource={RelativeSource FindAncestor,
- AncestorType={x:Type UserControl}}}"
- SelectedItem="{Binding SampleRateDisplayValue}"
- Visibility="{Binding IsPassthru,
- Converter={StaticResource boolToVisConverter},
- ConverterParameter=true}" />
+ Visibility="{Binding CannotSetBitrate, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
+
<!-- Row 2 -->
- <TextBlock Grid.Row="1"
- Grid.Column="0"
- VerticalAlignment="Center"
- FontWeight="Bold"
- Text="Mixdown"
- Visibility="{Binding IsPassthru,
- Converter={StaticResource boolToVisConverter},
- ConverterParameter=true}" />
- <ComboBox Grid.Row="1"
- Grid.Column="1"
- Height="22"
- MaxWidth="300"
- Margin="5,0,5,0"
- HorizontalAlignment="Stretch"
- ItemsSource="{Binding DataContext.AudioMixdowns,
- Converter={StaticResource enumComboConverter},
- RelativeSource={RelativeSource FindAncestor,
- AncestorType={x:Type UserControl}}}"
- SelectedItem="{Binding MixDown,
- Converter={StaticResource enumComboConverter}}"
- Visibility="{Binding IsPassthru,
- Converter={StaticResource boolToVisConverter},
- ConverterParameter=true}" />
-
- <TextBlock Grid.Row="1"
- Grid.Column="2"
- VerticalAlignment="Center"
- FontWeight="Bold"
- Text="DRC"
- Visibility="{Binding IsPassthru,
- Converter={StaticResource boolToVisConverter},
- ConverterParameter=true}" />
-
- <NumericUpDown:NumericUpDown Name="drcNumericCtl"
- Grid.Row="1"
- Grid.Column="3"
- Width="45"
- Margin="5,0,5,0"
- HorizontalAlignment="Left"
- DecimalPlace="1"
- LargeChange="0.1"
- Maximum="4"
- Minimum="0"
- SmallChange="0.1"
- Visibility="{Binding IsPassthru,
- Converter={StaticResource boolToHiddenVisConverter},
- ConverterParameter=true}"
- Value="{Binding DRC,
- Mode=TwoWay}" />
+ <TextBlock Grid.Row="0" Grid.Column="6" VerticalAlignment="Center" FontWeight="Bold" Text="Mixdown"
+ Visibility="{Binding IsPassthru, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
+ <ComboBox Grid.Row="0" Grid.Column="7" Height="22" Width="120" Margin="5,0,5,0" HorizontalAlignment="Stretch"
+ ItemsSource="{Binding DataContext.AudioMixdowns, Converter={StaticResource enumComboConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
+ SelectedItem="{Binding MixDown, Converter={StaticResource enumComboConverter}}"
+ Visibility="{Binding IsPassthru, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
- <TextBlock Grid.Row="1"
- Grid.Column="4"
- VerticalAlignment="Center"
- FontWeight="Bold"
- Text="Gain"
- Visibility="{Binding IsPassthru,
- Converter={StaticResource boolToVisConverter},
- ConverterParameter=true}" />
- <NumericUpDown:NumericUpDown Name="gainNumericCtl"
- Grid.Row="1"
- Grid.Column="5"
- Width="45"
- Margin="5,0,5,0"
- HorizontalAlignment="Left"
- DecimalPlace="0"
- LargeChange="1"
- Maximum="20"
- Minimum="-20"
- SmallChange="1"
- Visibility="{Binding IsPassthru,
- Converter={StaticResource boolToHiddenVisConverter},
- ConverterParameter=true}"
- Value="{Binding Gain,
- Mode=TwoWay}" />
+
- <ToggleButton Name="advancedOptionsToggle" VerticalAlignment="Center" Grid.Column="6" Grid.Row="1" Grid.ColumnSpan="2"
- FontWeight="Bold" Height="22" Padding="4,0" HorizontalAlignment="Left" >
+ <ToggleButton Name="advancedOptionsToggle" VerticalAlignment="Center" Grid.Column="8" Grid.Row="0" Grid.ColumnSpan="2"
+ Padding="3,0" Height="22" HorizontalAlignment="Left" >
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
- <Setter Property="Content" Value="Show Advanced"/>
+ <Setter Property="Content" Value="Show"/>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
- <Setter Property="Content" Value="Hide Advanced"/>
+ <Setter Property="Content" Value="Hide"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
- <Setter Property="Content" Value="Show Advanced"/>
+ <Setter Property="Content" Value="Show"/>
</Trigger>
</Style.Triggers>
</Style>
@@ -371,10 +259,32 @@
<!-- Hidden Row -->
<Grid Grid.Column="1" Grid.Row="1" HorizontalAlignment="Stretch" Visibility="{Binding IsChecked, ElementName=advancedOptionsToggle, Converter={StaticResource boolToVisConverter}}">
<StackPanel Orientation="Horizontal" Margin="0,5,0,5" >
- <TextBlock Text="Track Name:" VerticalAlignment="Center" FontWeight="Bold" Margin="0,0,5,0" />
+
+ <TextBlock VerticalAlignment="Center" FontWeight="Bold" Text="Samplerate"
+ Visibility="{Binding IsPassthru, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
+ <ComboBox Width="70" Height="22" Margin="5,0,5,0"
+ ItemsSource="{Binding DataContext.SampleRates, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
+ SelectedItem="{Binding SampleRateDisplayValue}"
+ Visibility="{Binding IsPassthru, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
+
+ <TextBlock VerticalAlignment="Center" FontWeight="Bold" Text="DRC"
+ Visibility="{Binding IsPassthru, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
+
+ <controls:NumberBox Name="drcNumericCtl" Width="45" Margin="5,0,5,0" HorizontalAlignment="Left"
+ Minimum="0" Modulus="0.1" Maximum="4" Number="{Binding DRC, Mode=TwoWay}" UpdateBindingOnTextChange="True" ShowIncrementButtons="True" AllowEmpty="False"
+ Visibility="{Binding IsPassthru, Converter={StaticResource boolToHiddenVisConverter}, ConverterParameter=true}"/>
+
+ <TextBlock VerticalAlignment="Center" FontWeight="Bold" Text="Gain"
+ Visibility="{Binding IsPassthru, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
+
+ <controls:NumberBox Name="gainNumericCtl" Width="45" Margin="5,0,5,0" HorizontalAlignment="Left"
+ Minimum="-20" Modulus="1" Maximum="20" Number="{Binding Gain, Mode=TwoWay}" UpdateBindingOnTextChange="True" ShowIncrementButtons="True" AllowEmpty="False"
+ Visibility="{Binding IsPassthru, Converter={StaticResource boolToHiddenVisConverter}, ConverterParameter=true}"/>
+
+ <TextBlock Text="Track Name:" VerticalAlignment="Center" FontWeight="Bold" Margin="5,0,5,0" />
<TextBox Text="{Binding TrackName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="138" Height="22" />
- </StackPanel>
-
+
+ </StackPanel>
</Grid>
</Grid>
diff --git a/win/CS/HandBrakeWPF/Views/CountdownAlertView.xaml b/win/CS/HandBrakeWPF/Views/CountdownAlertView.xaml
new file mode 100644
index 000000000..121f43595
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Views/CountdownAlertView.xaml
@@ -0,0 +1,39 @@
+<Window x:Class="HandBrakeWPF.Views.CountdownAlertView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:cal="http://www.caliburnproject.org"
+ Title="When Done Action" MinHeight="130" MinWidth="400" WindowStartupLocation="CenterScreen" WindowStyle="None"
+ ShowActivated="True" ShowInTaskbar="True" SizeToContent="WidthAndHeight">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <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="../Views/Images/Advanced.png" />
+ <StackPanel VerticalAlignment="Center" Orientation="Vertical">
+ <TextBlock FontWeight="Bold" Text="When Done Action" />
+ </StackPanel>
+ </StackPanel>
+
+ <TextBlock Text="{Binding NoticeMessage}" Grid.Row="1" Margin="40,0,10,0"/>
+
+ <StackPanel Orientation="Horizontal" Grid.Row="2" Margin="0,10,10,5" HorizontalAlignment="Right">
+ <Button Content="Proceed" HorizontalAlignment="Right"
+ cal:Message.Attach="[Event Click] = [Action Proceed]" Padding="8,2" Margin="0,10,10,5"/>
+
+ <Button Content="Cancel Action" HorizontalAlignment="Right" Margin="0,10,10,5"
+ cal:Message.Attach="[Event Click] = [Action Cancel]" Padding="8,2" IsDefault="True" />
+ </StackPanel>
+
+ </Grid>
+</Window>
diff --git a/win/CS/HandBrakeWPF/Views/CountdownAlertView.xaml.cs b/win/CS/HandBrakeWPF/Views/CountdownAlertView.xaml.cs
new file mode 100644
index 000000000..b53ca2ba1
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Views/CountdownAlertView.xaml.cs
@@ -0,0 +1,27 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="CountdownAlertView.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 CountdownAlertView.xaml
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Views
+{
+ using System.Windows;
+
+ /// <summary>
+ /// Interaction logic for CountdownAlertView.xaml
+ /// </summary>
+ public partial class CountdownAlertView : Window
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CountdownAlertView"/> class.
+ /// </summary>
+ public CountdownAlertView()
+ {
+ this.InitializeComponent();
+ }
+ }
+}
diff --git a/win/CS/HandBrakeWPF/Views/FiltersView.xaml b/win/CS/HandBrakeWPF/Views/FiltersView.xaml
index 9c46aeabd..ed5993def 100644
--- a/win/CS/HandBrakeWPF/Views/FiltersView.xaml
+++ b/win/CS/HandBrakeWPF/Views/FiltersView.xaml
@@ -7,17 +7,24 @@
<UserControl.Resources>
<Converters:BooleanToVisibilityConverter x:Key="boolToVisConverter" />
<Converters:EnumComboConverter x:Key="boolComboConverter" />
+ <Converters:InverseBooleanConverter x:Key="inverseBooleanConverter" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
- <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
</Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+
<TextBlock Text="Filters" FontWeight="Bold" Margin="10,5,0,0" Grid.Row="0" ></TextBlock>
- <StackPanel Orientation="Vertical" Grid.Row="1" Margin="10,10,0,0">
+ <StackPanel Orientation="Vertical" Grid.Row="1" Grid.Column="0" Margin="10,10,0,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
@@ -29,43 +36,56 @@
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
- <ColumnDefinition Width="100" />
- <ColumnDefinition Width="130" />
+ <ColumnDefinition MinWidth="75" />
+ <ColumnDefinition MinWidth="160" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="Detelecine:" Grid.Row="0" Grid.Column="0" Margin="0,0,0,10" />
<ComboBox Width="120" Grid.Row="0" ItemsSource="{Binding DetelecineOptions, Converter={StaticResource boolComboConverter}}"
- SelectedItem="{Binding SelectedDetelecine, Converter={StaticResource boolComboConverter}}" Grid.Column="1" Margin="0,0,0,10"/>
+ SelectedItem="{Binding SelectedDetelecine, Converter={StaticResource boolComboConverter}}" Grid.Column="1" Margin="0,0,0,10"
+ HorizontalAlignment="Left"/>
<TextBox Width="120" Grid.Row="0" Grid.Column="2" Margin="0,0,0,10" Text="{Binding CustomDetelecine}"
Visibility="{Binding ShowDetelecineCustom, Converter={StaticResource boolToVisConverter}}"/>
- <TextBlock Text="Decomb:" Grid.Row="1" Grid.Column="0" Margin="0,0,0,10"/>
- <ComboBox Width="120" Grid.Row="1" ItemsSource="{Binding DecombOptions, Converter={StaticResource boolComboConverter}}"
- SelectedItem="{Binding SelectedDecomb, Converter={StaticResource boolComboConverter}}" Grid.Column="1" Margin="0,0,0,10"/>
- <TextBox Width="120" Grid.Row="1" Grid.Column="2" Margin="0,0,0,10" Text="{Binding CustomDecomb}"
+ <TextBlock Text="{Binding DeinterlaceControlText}" Grid.Row="1" Grid.Column="0" Margin="0,0,0,10" VerticalAlignment="Top"/>
+ <StackPanel Grid.Row="1" Grid.Column="1" >
+ <StackPanel Orientation="Horizontal">
+ <RadioButton GroupName="Interlace" Content="Deinterlace" IsChecked="{Binding IsDeinterlaceMode}" />
+ <RadioButton GroupName="Interlace" Content="Decomb" Margin="10,0,0,0" IsChecked="{Binding IsDeinterlaceMode, Converter={StaticResource inverseBooleanConverter}}" />
+ </StackPanel>
+
+ <ComboBox Width="120" ItemsSource="{Binding DecombOptions, Converter={StaticResource boolComboConverter}}" HorizontalAlignment="Left"
+ SelectedItem="{Binding SelectedDecomb, Converter={StaticResource boolComboConverter}}" Margin="0,0,0,10"
+ Visibility="{Binding IsDeinterlaceMode, Converter={StaticResource boolToVisConverter}, ConverterParameter=True}" />
+
+ <ComboBox Width="120" ItemsSource="{Binding DeInterlaceOptions, Converter={StaticResource boolComboConverter}}" HorizontalAlignment="Left"
+ SelectedItem="{Binding SelectedDeInterlace, Converter={StaticResource boolComboConverter}}" Margin="0,0,0,10"
+ Visibility="{Binding IsDeinterlaceMode, Converter={StaticResource boolToVisConverter}}" />
+ </StackPanel>
+
+ <TextBox Width="120" Grid.Row="1" Grid.Column="2" Text="{Binding CustomDecomb}" VerticalAlignment="Top"
Visibility="{Binding ShowDecombCustom, Converter={StaticResource boolToVisConverter}}" />
- <TextBlock Text="Deinterlace:" Grid.Row="2" Grid.Column="0" Margin="0,0,0,10"/>
- <ComboBox Width="120" Grid.Row="2" ItemsSource="{Binding DeInterlaceOptions, Converter={StaticResource boolComboConverter}}"
- SelectedItem="{Binding SelectedDeInterlace, Converter={StaticResource boolComboConverter}}" Grid.Column="1" Margin="0,0,0,10"/>
- <TextBox Width="120" Grid.Row="2" Grid.Column="2" Margin="0,0,0,10" Text="{Binding CustomDeinterlace}"
+ <TextBox Width="120" Grid.Row="1" Grid.Column="2" Text="{Binding CustomDeinterlace}" VerticalAlignment="Top"
Visibility="{Binding ShowDeinterlaceCustom, Converter={StaticResource boolToVisConverter}}" />
<TextBlock Text="Denoise:" Grid.Row="3" Grid.Column="0" Margin="0,0,0,10"/>
<ComboBox Width="120" Grid.Row="3" ItemsSource="{Binding DenoiseOptions, Converter={StaticResource boolComboConverter}}"
- SelectedItem="{Binding SelectedDenoise, Converter={StaticResource boolComboConverter}}" Grid.Column="1" Margin="0,0,0,10"/>
+ SelectedItem="{Binding SelectedDenoise, Converter={StaticResource boolComboConverter}}" Grid.Column="1" Margin="0,0,0,10"
+ HorizontalAlignment="Left"/>
<TextBox Width="120" Grid.Row="3" Grid.Column="2" Margin="0,0,0,10" Text="{Binding CustomDenoise}"
Visibility="{Binding ShowDenoiseCustom, Converter={StaticResource boolToVisConverter}}" />
<TextBlock Text="Deblock:" Grid.Row="4" Grid.Column="0" Margin="0,0,0,10"/>
- <Slider Width="120" Value="{Binding DeblockValue}" TickPlacement="BottomRight" Minimum="4" Maximum="15" Grid.Row="4" Grid.Column="1" Margin="0,0,0,10"/>
+ <Slider Width="120" Value="{Binding DeblockValue}" TickPlacement="BottomRight" Minimum="4" Maximum="15" Grid.Row="4" Grid.Column="1" Margin="0,0,0,10"
+ HorizontalAlignment="Left" />
<TextBlock Text="{Binding DeblockText}" Grid.Row="4" Grid.Column="2" Margin="0,0,0,10"/>
<CheckBox Content="Grayscale" IsChecked="{Binding Grayscale}" Grid.Row="5" Grid.Column="1" Margin="0,0,0,10"/>
</Grid>
</StackPanel>
-
+
</Grid>
</UserControl>
diff --git a/win/CS/HandBrakeWPF/Views/Images/Advanced.png b/win/CS/HandBrakeWPF/Views/Images/Advanced.png
new file mode 100644
index 000000000..25b648003
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Views/Images/Advanced.png
Binary files differ
diff --git a/win/CS/HandBrakeWPF/Views/InstantView.xaml b/win/CS/HandBrakeWPF/Views/InstantView.xaml
new file mode 100644
index 000000000..bb9bc1971
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Views/InstantView.xaml
@@ -0,0 +1,202 @@
+<UserControl x:Class="HandBrakeWPF.Views.InstantView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:cal="http://www.caliburnproject.org"
+ xmlns:controls="clr-namespace:HandBrakeWPF.Controls"
+ xmlns:converters="clr-namespace:HandBrakeWPF.Converters"
+ xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
+ mc:Ignorable="d"
+ cal:Message.Attach="[Event Loaded] = [Action Load]"
+ >
+
+ <i:Interaction.Triggers>
+ <i:EventTrigger EventName="Drop">
+ <cal:ActionMessage MethodName="FilesDroppedOnWindow">
+ <cal:Parameter Value="$eventArgs" />
+ </cal:ActionMessage>
+ </i:EventTrigger>
+ </i:Interaction.Triggers>
+
+ <UserControl.Resources>
+ <converters:BooleanToVisibilityConverter x:Key="boolToVisConverter" />
+ </UserControl.Resources>
+
+ <!-- Window Body -->
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+
+
+ <!-- Source -->
+ <StackPanel Orientation="Vertical" Grid.Row="0">
+ <!-- Source -->
+ <StackPanel Margin="10,5,5,5"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Stretch"
+ >
+ <StackPanel Orientation="Horizontal">
+ <Label Content="Source" FontWeight="Bold" />
+ </StackPanel>
+
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="8,10,0,10">
+
+ <TextBlock Text="Drag and Drop a file - OR - Open a " />
+ <Button cal:Message.Attach="[Event Click] = [Action FileScan]" Padding="8,2">
+ File
+ </Button>
+ <TextBlock Text="- OR -" FontWeight="Bold" Margin="10,0,10,0" />
+ <Button cal:Message.Attach="[Event Click] = [Action FolderScan]" Padding="8,2">
+ Folder
+ </Button>
+
+ </StackPanel>
+
+ <ListBox Grid.Row="2"
+ Margin="10,10,10,10"
+ MinHeight="150" MaxHeight="150"
+ 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="Deselect 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>
+ </StackPanel>
+ </StackPanel>
+
+
+ <!-- Destination -->
+ <StackPanel Grid.Row="1"
+ Margin="10,5,5,5"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Stretch"
+ >
+ <Label Content="Destination" FontWeight="Bold" />
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+ <Label Margin="8,0,0,0" Content="File" />
+ <TextBox Name="Destination"
+ Grid.Column="1"
+ Margin="8,0,0,0"
+ Text="{Binding OutputDirectory,
+ UpdateSourceTrigger=PropertyChanged}"
+ />
+ <Button Name="DestinationBrowser"
+ Grid.Column="2"
+ Margin="8,0,5,0"
+ Padding="8,2"
+ Content="Browse"
+ cal:Message.Attach="[Event Click] = [Action BrowseDestination]"
+ />
+ </Grid>
+ </StackPanel>
+
+ <!-- Opitons -->
+ <StackPanel Grid.Row="2"
+ Margin="10,5,5,5"
+ HorizontalAlignment="Stretch"
+ VerticalAlignment="Stretch"
+ >
+ <Label Content="Options" FontWeight="Bold" />
+
+ <StackPanel Orientation="Horizontal" Margin="8,0,0,0">
+ <TextBlock Text="Preset:" Margin="0,0,5,0" />
+ <ComboBox ItemsSource="{Binding Presets}" SelectedItem="{Binding SelectedPreset}" MinWidth="150" />
+ </StackPanel>
+
+ </StackPanel>
+
+
+ <!-- Buttons and Queueing -->
+ <Grid Grid.Row="3" Margin="10,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <Label Content="Start" FontWeight="Bold" Grid.Row="0" />
+ <Button Content="Start Encoding" cal:Message.Attach="[Event Click] = [Action StartEncode]" FontWeight="Bold" Grid.Row="1" Padding="8,2" HorizontalAlignment="Center"
+ Visibility="{Binding IsEncoding, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
+ <Button Content="Stop Encoding" cal:Message.Attach="[Event Click] = [Action StopEncode]" FontWeight="Bold" Grid.Row="1" Padding="8,2" HorizontalAlignment="Center"
+ Visibility="{Binding IsEncoding, Converter={StaticResource boolToVisConverter}, ConverterParameter=false}" />
+ </Grid>
+
+
+ <!-- StatusPanel -->
+ <controls:StatusPanel x:Name="loadingPanel"
+ Grid.Row="3"
+ Grid.RowSpan="2"
+ Height="70"
+ VerticalAlignment="Bottom"
+ Panel.ZIndex="10"
+ IsLoading="{Binding ShowStatusWindow}"
+ Message="{Binding StatusLabel}"
+ SubMessage="Please Wait ..."
+ />
+
+ <!-- Status Bar -->
+ <StatusBar Grid.Row="4" Grid.ColumnSpan="2" MinHeight="32" >
+
+ <ProgressBar Value="{Binding ProgressPercentage}" Visibility="{Binding IsEncoding, Converter={StaticResource boolToVisConverter}}"
+ Width="100" Height="18" VerticalAlignment="Center"/>
+ <Label VerticalAlignment="Center"
+ Content="{Binding Path=ProgramStatusLabel}" />
+
+ </StatusBar>
+
+ </Grid>
+</UserControl>
diff --git a/win/CS/HandBrakeWPF/Views/InstantView.xaml.cs b/win/CS/HandBrakeWPF/Views/InstantView.xaml.cs
new file mode 100644
index 000000000..8ca18aa87
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Views/InstantView.xaml.cs
@@ -0,0 +1,27 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="InstantView.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 InstantMainView.xaml
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Views
+{
+ using System.Windows.Controls;
+
+ /// <summary>
+ /// Interaction logic for InstantMainView.xaml
+ /// </summary>
+ public partial class InstantView : UserControl
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="InstantView"/> class.
+ /// </summary>
+ public InstantView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/win/CS/HandBrakeWPF/Views/MainView.xaml b/win/CS/HandBrakeWPF/Views/MainView.xaml
index cf7858859..cadccfcca 100644
--- a/win/CS/HandBrakeWPF/Views/MainView.xaml
+++ b/win/CS/HandBrakeWPF/Views/MainView.xaml
@@ -6,6 +6,7 @@
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:Micro="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro"
xmlns:attachedProperties="clr-namespace:HandBrakeWPF.AttachedProperties"
+ xmlns:handBrakeWpf="clr-namespace:HandBrakeWPF"
AllowDrop="True"
FontSize="11"
Micro:Message.Attach="[Event Loaded] = [Action Load]"
@@ -21,7 +22,7 @@
</i:EventTrigger>
</i:Interaction.Triggers>
- <UserControl.Resources>
+ <UserControl.Resources>
<Style TargetType="Button">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Padding" Value="5,1" />
@@ -179,7 +180,6 @@
<MenuItem Header="_Debug" Visibility="{Binding ShowDebugMenu, Converter={StaticResource boolToVisConverter}}" >
<MenuItem Header="_Show CLI Equiv" Micro:Message.Attach="[Event Click] = [Action ShowCliQuery]" />
- <MenuItem Header="_Debug Scan Log" Micro:Message.Attach="[Event Click] = [Action DebugScanLog]" />
</MenuItem>
</Menu>
@@ -191,8 +191,8 @@
ToolBar.OverflowMode="Never"
ToolBarTray.IsLocked="True"
>
- <Menu Background="Transparent" attachedProperties:DriveMenu.ShowAvailableDrives="true">
- <MenuItem ItemsSource="{Binding SourceMenu}">
+ <Menu Background="Transparent">
+ <MenuItem ItemsSource="{Binding SourceMenu}" attachedProperties:DriveMenu.ShowAvailableDrives="true">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<Image Width="32"
@@ -205,14 +205,30 @@
/>
</StackPanel>
</MenuItem.Header>
+ <MenuItem.Resources>
+ <Image x:Key="Movie" x:Shared="False" MaxWidth="16" SnapsToDevicePixels="True" Source="Images/Movies.png" />
+ <Image x:Key="Folder" x:Shared="False" MaxWidth="16" SnapsToDevicePixels="True" Source="Images/folder.png" />
+ <Image x:Key="Disc" x:Shared="False" MaxWidth="16" SnapsToDevicePixels="True" Source="Images/disc_small.png" />
+ </MenuItem.Resources>
<MenuItem.ItemContainerStyle>
- <Style TargetType="{x:Type MenuItem}">
+ <Style TargetType="{x:Type MenuItem}" x:Shared="True">
<Setter Property="Header" Value="{Binding Text}" />
- <Setter Property="MenuItem.Command" Value="{Binding Command}"/>
- <Setter Property="MenuItem.CommandParameter" Value="123"/>
+ <Setter Property="Command" Value="{Binding Command}"/>
<Setter Property="ItemsSource" Value="{Binding Children}" />
- <Setter Property="Icon" Value="{Binding Image}" />
<Setter Property="InputGestureText" Value="{Binding InputGestureText}" />
+ <Setter Property="Tag" Value="{Binding}" />
+
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Path=IsDisc}" Value="true">
+ <Setter Property="Icon" Value="{StaticResource Disc}"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Path=IsOpenFolder}" Value="true">
+ <Setter Property="Icon" Value="{StaticResource Folder}"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Path=IsOpenFile}" Value="true">
+ <Setter Property="Icon" Value="{StaticResource Movie}"/>
+ </DataTrigger>
+ </Style.Triggers>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
@@ -467,7 +483,13 @@
Margin="8,0,0,0"
Text="{Binding Destination,
UpdateSourceTrigger=PropertyChanged}"
- />
+ >
+ <TextBox.ContextMenu>
+ <ContextMenu>
+ <MenuItem Header="Open this Directory" Micro:Message.Attach="[Event Click] = [Action OpenDestinationDirectory]" />
+ </ContextMenu>
+ </TextBox.ContextMenu>
+ </TextBox>
<Button Name="DestinationBrowser"
Grid.Column="2"
Margin="8,0,0,0"
@@ -546,6 +568,7 @@
Margin="10,10,5,5"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
+ MinHeight="350" MinWidth="720"
>
<TabItem Name="pictureTab" Header="Picture">
<ContentControl x:Name="PictureSettingsViewModel" />
@@ -578,7 +601,7 @@
Header="Presets"
Margin="0,0,0,5"
Visibility="{Binding IsPresetPanelShowing, Converter={StaticResource boolToVisConverter}}">
-
+
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
diff --git a/win/CS/HandBrakeWPF/Views/OptionsView.xaml b/win/CS/HandBrakeWPF/Views/OptionsView.xaml
index 64d7389ad..923876b8e 100644
--- a/win/CS/HandBrakeWPF/Views/OptionsView.xaml
+++ b/win/CS/HandBrakeWPF/Views/OptionsView.xaml
@@ -97,7 +97,11 @@
<TextBlock Text="When Done" Grid.Column="0" FontSize="14" Margin="0,0,0,10" />
<StackPanel Orientation="Vertical" Grid.Column="1" Margin="20,0,0,0">
- <ComboBox Name="whenDone" ItemsSource="{Binding WhenDoneOptions}" SelectedItem="{Binding WhenDone}" Width="120" HorizontalAlignment="Left"></ComboBox>
+ <StackPanel Orientation="Horizontal">
+ <ComboBox Name="whenDone" ItemsSource="{Binding WhenDoneOptions}" SelectedItem="{Binding WhenDone}" Width="120" HorizontalAlignment="Left" />
+ <CheckBox Content="Reset to 'Do nothing' when the app is launched." VerticalAlignment="Center" Margin="10,0,0,0" IsChecked="{Binding ResetWhenDoneAction}" />
+ </StackPanel>
+
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
<CheckBox Content="Growl after Queue Completes" IsChecked="{Binding GrowlAfterEncode}" Margin="0,0,5,0"/>
@@ -143,7 +147,10 @@
<CheckBox Content="Always use System Colours (Requires Restart)"
ToolTip="Note: This option will always be on for systems with a High Contrast Theme selected." IsChecked="{Binding UseSystemColoursForStylesForStyles}" />
-
+ <CheckBox Content="Minimize to system tray (Requires Restart)" IsChecked="{Binding MinimiseToTray}" />
+ <CheckBox Content="Disable preset update notification on startup" IsChecked="{Binding DisablePresetUpdateCheckNotification}" />
+ <CheckBox Content="Always clear completed queue items after an encode completes" IsChecked="{Binding ClearQueueOnEncodeCompleted}" />
+ <CheckBox Content="Show Advanced Encoder Options Tab" IsChecked="{Binding ShowAdvancedTab}" />
</StackPanel>
</StackPanel>
</StackPanel>
@@ -173,7 +180,7 @@
<TextBlock VerticalAlignment="Center" Text="Format:" />
<TextBox Name="autoNameFormat" Text="{Binding AutonameFormat}" Width="180" ToolTip=" {Source} = Source Name, {Title} = Title Number, {Chapters} = Selected Chapters, {Date} = Todays Date," />
</StackPanel>
- <TextBlock Text="Available Options: {source} {title} {chapters} {date}" />
+ <TextBlock Text="Available Options: {source} {title} {chapters} {date} {time} {quality} {bitrate}" />
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
<CheckBox Content="Replace underscores with a space" IsChecked="{Binding RemoveUnderscores}"/>
@@ -304,10 +311,6 @@
<StackPanel Orientation="Vertical" Grid.Column="1" Margin="20,0,0,0">
<CheckBox Content="Prevent the system from sleeping while encoding" IsChecked="{Binding PreventSleep}" />
- <CheckBox Content="Minimize to system tray (Requires Restart)" IsChecked="{Binding MinimiseToTray}" />
- <CheckBox Content="Disable built-in preset update notification" IsChecked="{Binding DisablePresetUpdateCheckNotification}" />
- <CheckBox Content="Always clear completed queue items after an encode completes" IsChecked="{Binding ClearQueueOnEncodeCompleted}" />
- <CheckBox Content="Show Advanced Tab" IsChecked="{Binding ShowAdvancedTab}" />
<CheckBox Content="Disable LibHB Features" IsChecked="{Binding DisableLibHbFeatures}" />
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBlock Text="Number of picture previews to scan:" VerticalAlignment="Center" Width="250" />
@@ -380,8 +383,8 @@
<StackPanel Orientation="Vertical" Grid.Column="1" Margin="20,0,0,0">
- <CheckBox Content="Enable LibHB Scanning and Encoding (uses hb.dll instead of HandBrakeCLI.exe)" Margin="0,5,0,0" IsChecked="{Binding EnableLibHb}" />
- <CheckBox Content="Enable Process Isolation (Run Scans and Encodes via an intermediate service)" Margin="20,10,0,0" IsChecked="{Binding EnableProcessIsolation}" />
+ <CheckBox Content="Enable LibHB based Encoding (uses hb.dll instead of HandBrakeCLI.exe)" Margin="0,5,0,0" IsChecked="{Binding EnableLibHb}" />
+ <CheckBox Content="Enable Process Isolation (Run Encodes via an intermediate service)" Margin="20,10,0,0" IsChecked="{Binding EnableProcessIsolation}" />
<StackPanel Orientation="Horizontal" Margin="0,10,0,0" Grid.Column="1">
<TextBlock Text="Server Port:" VerticalAlignment="Center" />
<TextBox Width="50" MaxLength="5" Text="{Binding ServerPort}" />
diff --git a/win/CS/HandBrakeWPF/Views/PictureSettingsView.xaml b/win/CS/HandBrakeWPF/Views/PictureSettingsView.xaml
index c9aa0d69b..a808c76b4 100644
--- a/win/CS/HandBrakeWPF/Views/PictureSettingsView.xaml
+++ b/win/CS/HandBrakeWPF/Views/PictureSettingsView.xaml
@@ -93,11 +93,8 @@
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
- <Label Content="Display Size:" Grid.Row="0" Grid.Column="0"
- Visibility="{Binding ShowDisplaySize, Converter={StaticResource boolToVisConverter}}" />
<Label Content="{Binding DisplaySize}" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" Margin="0,0,0,5"
Visibility="{Binding ShowDisplaySize, Converter={StaticResource boolToVisConverter}}" />
@@ -108,7 +105,7 @@
<StackPanel Name="CropPanel" Margin="50,0,0,0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Label Content="Cropping" FontWeight="Bold" />
<RadioButton Content="Automatic" IsChecked="{Binding IsCustomCrop, Converter={StaticResource boolConverter}, ConverterParameter=true}" Margin="10,0,0,0"/>
- <RadioButton Content="Custom" IsChecked="{Binding IsCustomCrop}" Margin="10,0,0,0" />
+ <RadioButton Content="Custom" IsChecked="{Binding IsCustomCrop}" Margin="10,5,0,0" />
<Grid Margin="0,10,0,0">
<Grid.RowDefinitions>
diff --git a/win/CS/HandBrakeWPF/Views/QueueView.xaml b/win/CS/HandBrakeWPF/Views/QueueView.xaml
index d3df53451..dc6354ea5 100644
--- a/win/CS/HandBrakeWPF/Views/QueueView.xaml
+++ b/win/CS/HandBrakeWPF/Views/QueueView.xaml
@@ -9,7 +9,9 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:YourNamespace="clr-namespace:HandBrakeWPF.AttachedProperties"
xmlns:Audio="clr-namespace:HandBrakeWPF.Converters.Audio"
- xmlns:Subtitles="clr-namespace:HandBrakeWPF.Converters.Subtitles" Title="{Binding Title}"
+ xmlns:Subtitles="clr-namespace:HandBrakeWPF.Converters.Subtitles"
+ xmlns:video="clr-namespace:HandBrakeWPF.Converters.Video"
+ Title="{Binding Title}"
Width="700"
Height="500"
MinWidth="200"
@@ -26,6 +28,7 @@
<Converters:QueueStatusToVisibilityConverter x:Key="queueStatusVisConverter" />
<Audio:AudioQueueDisplayConverter x:Key="audioTrackDisplayConverter" />
<Subtitles:SubtitlesQueueDisplayConverter x:Key="subtitleTrackDisplayConverter" />
+ <video:EncoderOptionsTooltipConverter x:Key="encoderOptionsTooltipConverter" />
<Style x:Key="LongToolTipHolder" TargetType="FrameworkElement">
@@ -210,7 +213,7 @@
<TextBlock FontWeight="Bold" VerticalAlignment="Top" Grid.Row="5" Grid.Column="0" Text="Advanced: " />
- <TextBlock Text="{Binding Task.AdvancedEncoderOptions}" Grid.Row="5" Grid.Column="1" />
+ <TextBlock Text="{Binding Task, Converter={StaticResource encoderOptionsTooltipConverter}}" Grid.Row="5" Grid.Column="1" TextWrapping="Wrap" />
</Grid>
</Setter.Value>
@@ -297,48 +300,63 @@
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
- <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,
- Converter={StaticResource queueStatusVisConverter}}">
+ <Button Visibility="{Binding Status, Converter={StaticResource queueStatusVisConverter}}"
+ Grid.Row="0" Grid.Column="0" Margin="0,5,0,0">
+ <Button.Template>
+ <ControlTemplate>
+ <Image Width="20"
+ Height="20" VerticalAlignment="Center"
+ Source="Images/Refresh.ico"
+ ToolTip="Reset job status to Waiting.">
+ </Image>
+ </ControlTemplate>
+ </Button.Template>
<i:Interaction.Triggers>
- <i:EventTrigger EventName="MouseDown">
+ <i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="RetryJob">
<cal:Parameter Value="{Binding}" />
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
- </Image>
-
- <Image Width="20" Grid.Row="0" Grid.Column="1"
- Height="20"
- Margin="10,5,0,0"
- Source="Images/Options24.png"
- ToolTip="Edit this Job">
+ </Button>
+
+ <Button Grid.Row="0" Grid.Column="1" Margin="10,5,0,0">
+ <Button.Template>
+ <ControlTemplate>
+ <Image Width="20"
+ Height="20" VerticalAlignment="Center"
+ Source="Images/Options24.png"
+ ToolTip="Reset job status to Waiting.">
+ </Image>
+ </ControlTemplate>
+ </Button.Template>
<i:Interaction.Triggers>
- <i:EventTrigger EventName="MouseDown">
+ <i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="EditJob">
<cal:Parameter Value="{Binding}" />
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
- </Image>
-
- <Image Width="20" Grid.Row="0" Grid.Column="2"
- Height="20"
- Margin="10,5,0,0"
- Source="Images/delete.png"
- ToolTip="Remove this Job">
+ </Button>
+
+ <Button Grid.Row="0" Grid.Column="2" Margin="10,5,0,0">
+ <Button.Template>
+ <ControlTemplate>
+ <Image Width="20"
+ Height="20" VerticalAlignment="Center"
+ Source="Images/delete.png"
+ ToolTip="Reset job status to Waiting.">
+ </Image>
+ </ControlTemplate>
+ </Button.Template>
<i:Interaction.Triggers>
- <i:EventTrigger EventName="MouseDown">
+ <i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="RemoveJob">
<cal:Parameter Value="{Binding}" />
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
- </Image>
+ </Button>
</Grid>
diff --git a/win/CS/HandBrakeWPF/Views/QueueView.xaml.cs b/win/CS/HandBrakeWPF/Views/QueueView.xaml.cs
index f4af15fc3..ea01a20fb 100644
--- a/win/CS/HandBrakeWPF/Views/QueueView.xaml.cs
+++ b/win/CS/HandBrakeWPF/Views/QueueView.xaml.cs
@@ -12,7 +12,7 @@ namespace HandBrakeWPF.Views
using System.Windows;
/// <summary>
- /// Interaction logic for VideoView.xaml
+ /// Interaction logic for VideoView
/// </summary>
public partial class QueueView : Window
{
diff --git a/win/CS/HandBrakeWPF/Views/ShellView.xaml b/win/CS/HandBrakeWPF/Views/ShellView.xaml
index ae8d26747..84411cdca 100644
--- a/win/CS/HandBrakeWPF/Views/ShellView.xaml
+++ b/win/CS/HandBrakeWPF/Views/ShellView.xaml
@@ -3,17 +3,19 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Data="clr-namespace:System.Windows.Data;assembly=PresentationFramework"
xmlns:Converters="clr-namespace:HandBrakeWPF.Converters"
+ xmlns:views="clr-namespace:HandBrakeWPF.Views"
Title="{Data:Binding Path=WindowTitle}"
Width="1015"
- Height="670"
+ Height="675"
MinWidth="750"
- MinHeight="670"
+ MinHeight="675"
AllowDrop="True"
SnapsToDevicePixels="True"
UseLayoutRounding="True"
WindowStartupLocation="CenterScreen"
TextOptions.TextFormattingMode="Display"
Style="{StaticResource mainWindowStyle}"
+ x:Name="shellView"
>
<Window.Resources>
<Converters:BooleanToVisibilityConverter x:Key="boolToVisConverter" />
@@ -22,5 +24,8 @@
<Grid>
<ContentControl x:Name="MainViewModel" Visibility="{Binding ShowMainWindow, Converter={StaticResource boolToVisConverter}, ConverterParameter=false}" />
<ContentControl x:Name="OptionsViewModel" Visibility="{Binding ShowOptions, Converter={StaticResource boolToVisConverter}, ConverterParameter=false}" />
+
+ <views:InstantView DataContext="{Binding InstantViewModel}"
+ Visibility="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.ShowInstant, Converter={StaticResource boolToVisConverter}, ConverterParameter=false}" />
</Grid>
</Window>
diff --git a/win/CS/HandBrakeWPF/Views/ShellView.xaml.cs b/win/CS/HandBrakeWPF/Views/ShellView.xaml.cs
index b1eff7ddd..067446f12 100644
--- a/win/CS/HandBrakeWPF/Views/ShellView.xaml.cs
+++ b/win/CS/HandBrakeWPF/Views/ShellView.xaml.cs
@@ -82,6 +82,14 @@ namespace HandBrakeWPF.Views
{
this.TaskbarItemInfo = Win7.WindowsTaskbar;
}
+
+ // Window Sizing
+ if (AppArguments.IsInstantHandBrake)
+ {
+ this.SizeToContent = SizeToContent.WidthAndHeight;
+ this.MinHeight = 380;
+ this.MinWidth = 600;
+ }
}
/// <summary>
diff --git a/win/CS/HandBrakeWPF/Views/SubtitlesView.xaml b/win/CS/HandBrakeWPF/Views/SubtitlesView.xaml
index 2d6dc502a..f0d63b0e2 100644
--- a/win/CS/HandBrakeWPF/Views/SubtitlesView.xaml
+++ b/win/CS/HandBrakeWPF/Views/SubtitlesView.xaml
@@ -7,12 +7,13 @@
xmlns:dd="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop"
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"
xmlns:dropButton="clr-namespace:HandBrakeWPF.Controls.DropButton"
+ xmlns:splitButton="clr-namespace:HandBrakeWPF.Controls.SplitButton"
d:DesignHeight="153"
d:DesignWidth="319"
- mc:Ignorable="d">
+ mc:Ignorable="d"
+ x:Name="subTab">
<UserControl.Resources>
<Converters:BooleanToVisibilityConverter x:Key="booleanToVisConverter" />
</UserControl.Resources>
@@ -30,23 +31,20 @@
Text="Subtitles" />
<StackPanel Grid.Row="1" Margin="10,5,10,0" Orientation="Horizontal">
- <dropButton:DropButton Content="Add Track" FontWeight="Bold" Margin="0,0,10,0" Style="{StaticResource DropButtonStyle}">
- <dropButton:DropButton.DropDown>
- <ContextMenu>
- <MenuItem Header="Add New Track" cal:Message.Attach="[Event Click] = [Action Add]" />
- <MenuItem Header="Add All Remaining Tracks" cal:Message.Attach="[Event Click] = [Action AddAllRemaining]" />
- <MenuItem Header="Add All Remaining Closed Captions" cal:Message.Attach="[Event Click] = [Action AddAllClosedCaptions]" />
- <MenuItem Header="Add All Remaining Selected Languages" cal:Message.Attach="[Event Click] = [Action AddAllRemainingForSelectedLanguages]" />
- </ContextMenu>
- </dropButton:DropButton.DropDown>
- </dropButton:DropButton>
+ <splitButton:SplitMenuButton Content="Add Track" cal:Message.Attach="[Event Click] = [Action Add]" FontWeight="Bold" Margin="0,0,10,0">
+ <splitButton:SplitMenuButton.ItemSource>
+ <MenuItem Header="Add New Track" cal:Message.Attach="[Event Click] = [Action Add]" />
+ <MenuItem Header="Add All Remaining Tracks" cal:Message.Attach="[Event Click] = [Action AddAllRemaining]" />
+ <MenuItem Header="Add All Remaining Closed Captions" cal:Message.Attach="[Event Click] = [Action AddAllClosedCaptions]" />
+ <MenuItem Header="Add All Remaining Selected Languages" cal:Message.Attach="[Event Click] = [Action AddAllRemainingForSelectedLanguages]" />
+ </splitButton:SplitMenuButton.ItemSource>
+ </splitButton:SplitMenuButton>
<Button MinWidth="75"
cal:Message.Attach="[Event Click] = [Action Import]"
Content="Import SRT"
Margin="0,0,10,0"/>
<Button MinWidth="65"
- Grid.Column="3"
Margin="0,0,10,0"
cal:Message.Attach="[Event Click] = [Action Clear]"
Content="Clear" />
@@ -74,7 +72,7 @@
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Margin" Value="0,0,0,1" />
<Style.Triggers>
- <DataTrigger Binding="{Binding UseSystemColours}" Value="False">
+ <DataTrigger Binding="{Binding DataContext.UseSystemColours, ElementName=subTab}" Value="False">
<Setter Property="Background" Value="WhiteSmoke" />
</DataTrigger>
</Style.Triggers>
@@ -111,11 +109,12 @@
Margin="10,0,10,0"
Source="Images/Movies.png" />
- <!-- Settings -->
- <Grid Grid.Column="1" HorizontalAlignment="Stretch">
+ <!-- Standard Subtitle Settings -->
+ <Grid Grid.Column="1" HorizontalAlignment="Stretch" Margin="0,8,0,8"
+ Visibility="{Binding IsSrtSubtitle, Converter={StaticResource booleanToVisConverter}, ConverterParameter=true}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
- <ColumnDefinition Width="*" MaxWidth="300" />
+ <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
@@ -128,65 +127,20 @@
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
- <RowDefinition Height="28" />
- <RowDefinition Height="28" />
+ <RowDefinition Height="Auto" />
</Grid.RowDefinitions>
- <!-- Row 1 -->
+
+ <TextBlock Grid.Column="0" VerticalAlignment="Center" FontWeight="Bold" Text="Source" />
+ <ComboBox Grid.Column="1" Height="22" Width="200" Margin="5,0,5,0" HorizontalAlignment="Stretch"
+ ItemsSource="{Binding DataContext.SourceTracks, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
+ SelectedItem="{Binding SourceTrack}" />
- <TextBlock Grid.Column="0"
- VerticalAlignment="Center"
- FontWeight="Bold"
- Text="Source" />
- <ComboBox Grid.Column="1"
- Height="22"
- MaxWidth="300"
- Margin="5,0,5,0"
- HorizontalAlignment="Stretch"
- ItemsSource="{Binding DataContext.SourceTracks,
- RelativeSource={RelativeSource FindAncestor,
- AncestorType={x:Type UserControl}}}"
- SelectedItem="{Binding SourceTrack}"
- Visibility="{Binding IsSrtSubtitle,
- Converter={StaticResource booleanToVisConverter},
- ConverterParameter=true}" />
- <TextBlock Grid.Column="1"
- VerticalAlignment="Center"
- Text="{Binding SrtFileName}"
- Visibility="{Binding IsSrtSubtitle,
- Converter={StaticResource booleanToVisConverter},
- ConverterParameter=false}" />
-
- <TextBlock Grid.Column="2"
- VerticalAlignment="Center"
- FontWeight="Bold"
- Text="Forced Only"
- Visibility="{Binding IsSrtSubtitle,
- Converter={StaticResource booleanToVisConverter},
- ConverterParameter=true}" />
- <CheckBox Grid.Column="3"
- Margin="5,0,5,0"
- VerticalAlignment="Center"
- IsEnabled="{Binding CanBeForced}"
- IsChecked="{Binding Forced}"
- Visibility="{Binding IsSrtSubtitle,
- Converter={StaticResource booleanToVisConverter},
- ConverterParameter=true}" />
- <TextBlock Grid.Column="4"
- VerticalAlignment="Center"
- FontWeight="Bold"
- Text="Burn In"
- Visibility="{Binding IsSrtSubtitle,
- Converter={StaticResource booleanToVisConverter},
- ConverterParameter=true}" />
- <CheckBox Grid.Column="5"
- Margin="5,0,5,0"
- VerticalAlignment="Center"
- IsChecked="{Binding Burned}"
- IsEnabled="{Binding CanBeBurned}"
- Visibility="{Binding IsSrtSubtitle,
- Converter={StaticResource booleanToVisConverter},
- ConverterParameter=true}">
+ <TextBlock Grid.Column="2" VerticalAlignment="Center" FontWeight="Bold" Text="Forced Only" Margin="5,0,0,0" />
+ <CheckBox Grid.Column="3" Margin="5,0,5,0" VerticalAlignment="Center" IsEnabled="{Binding CanBeForced}" IsChecked="{Binding Forced}" />
+
+ <TextBlock Grid.Column="4" VerticalAlignment="Center" FontWeight="Bold" Text="Burn In" />
+ <CheckBox Grid.Column="5" Margin="5,0,5,0" VerticalAlignment="Center" IsChecked="{Binding Burned}" IsEnabled="{Binding CanBeBurned}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="SelectBurnedInTrack">
@@ -195,14 +149,9 @@
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
- <TextBlock Grid.Column="6"
- VerticalAlignment="Center"
- FontWeight="Bold"
- Text="Default" />
- <CheckBox Grid.Column="7"
- Margin="5,0,5,0"
- VerticalAlignment="Center"
- IsChecked="{Binding Default}">
+
+ <TextBlock Grid.Column="6" VerticalAlignment="Center" FontWeight="Bold" Text="Default" />
+ <CheckBox Grid.Column="7" Margin="5,0,5,0" VerticalAlignment="Center" IsChecked="{Binding Default}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="SelectDefaultTrack">
@@ -210,50 +159,60 @@
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
- </CheckBox>
+ </CheckBox>
+ </Grid>
+
+ <!-- SRT Subtitle Settings -->
+ <Grid Grid.Column="1" HorizontalAlignment="Stretch" Margin="0,8,0,8"
+ Visibility="{Binding IsSrtSubtitle, Converter={StaticResource booleanToVisConverter}, ConverterParameter=false}" >
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
- <!-- Row 2 -->
- <TextBlock Grid.Row="1"
- Grid.Column="0"
- VerticalAlignment="Center"
- FontWeight="Bold"
- Text="Language" />
- <ComboBox Grid.Row="1"
- Grid.Column="1"
- Height="22"
- MaxWidth="300"
- Margin="5,0,5,0"
- HorizontalAlignment="Stretch"
- IsEnabled="{Binding IsSrtSubtitle}"
- ItemsSource="{Binding DataContext.Langauges,
- RelativeSource={RelativeSource FindAncestor,
- AncestorType={x:Type UserControl}}}"
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+
+ <!-- Row 1 -->
+ <TextBlock Grid.Column="0" VerticalAlignment="Center" FontWeight="Bold" Text="Source" />
+ <TextBlock Grid.Column="1" VerticalAlignment="Center" Text="{Binding SrtFileName}" Margin="5,0,5,0" Width="80" TextWrapping="NoWrap" TextTrimming="WordEllipsis"
+ Visibility="{Binding IsSrtSubtitle, Converter={StaticResource booleanToVisConverter}, ConverterParameter=false}" />
+
+ <TextBlock Grid.Column="2" VerticalAlignment="Center" FontWeight="Bold" Text="Lang" />
+ <ComboBox Grid.Column="3" Height="22" Width="100" Margin="5,0,5,0" HorizontalAlignment="Stretch" IsEnabled="{Binding IsSrtSubtitle}"
+ ItemsSource="{Binding DataContext.Langauges, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
SelectedItem="{Binding SrtLang}" />
- <TextBlock Grid.Row="1"
- Grid.Column="2"
- VerticalAlignment="Center"
- FontWeight="Bold"
- Text="Char Code" />
- <ComboBox Grid.Row="1"
- Grid.Column="3"
- Width="100"
- Height="22"
- Margin="5,0,5,0"
- IsEnabled="{Binding IsSrtSubtitle}"
- ItemsSource="{Binding DataContext.CharacterCodes,
- RelativeSource={RelativeSource FindAncestor,
- AncestorType={x:Type UserControl}}}"
+
+ <TextBlock Grid.Column="4" VerticalAlignment="Center" FontWeight="Bold" Text="Char Code" />
+ <ComboBox Grid.Column="5" Width="75" Height="22" Margin="5,0,5,0" IsEnabled="{Binding IsSrtSubtitle}"
+ ItemsSource="{Binding DataContext.CharacterCodes, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
SelectedItem="{Binding SrtCharCode}" />
- <TextBlock Grid.Row="1"
- Grid.Column="4"
- VerticalAlignment="Center"
- FontWeight="Bold"
- Text="Offset (ms)" />
-
- <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}" />
+ <TextBlock Grid.Column="6" VerticalAlignment="Center" FontWeight="Bold" Text="Offset (ms)" />
+ <controls:NumberBox Grid.Column="7" Width="65" Height="24" Margin="5,0,5,0" Minimum="-900000" Maximum="900000"
+ IsEnabled="{Binding IsSrtSubtitle}" Number="{Binding SrtOffset, Mode=TwoWay}" />
+
+ <TextBlock Grid.Column="8" VerticalAlignment="Center" FontWeight="Bold" Text="Default" />
+ <CheckBox Grid.Column="9" Margin="5,0,5,0" VerticalAlignment="Center" IsChecked="{Binding Default}">
+ <i:Interaction.Triggers>
+ <i:EventTrigger EventName="Click">
+ <cal:ActionMessage MethodName="SelectDefaultTrack">
+ <cal:Parameter Value="{Binding}" />
+ </cal:ActionMessage>
+ </i:EventTrigger>
+ </i:Interaction.Triggers>
+ </CheckBox>
+
</Grid>
<!-- Delete -->
diff --git a/win/CS/HandBrakeWPF/Views/VideoView.xaml b/win/CS/HandBrakeWPF/Views/VideoView.xaml
index 7c617c2c1..fffbfd0b2 100644
--- a/win/CS/HandBrakeWPF/Views/VideoView.xaml
+++ b/win/CS/HandBrakeWPF/Views/VideoView.xaml
@@ -5,7 +5,9 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:Converters="clr-namespace:HandBrakeWPF.Converters"
xmlns:Video="clr-namespace:HandBrakeWPF.Converters.Video"
- xmlns:Properties="clr-namespace:HandBrakeWPF.Properties" mc:Ignorable="d" >
+ xmlns:Properties="clr-namespace:HandBrakeWPF.Properties"
+ xmlns:cal="http://www.caliburnproject.org"
+ mc:Ignorable="d" >
<UserControl.Resources>
<Converters:BooleanConverter x:Key="boolConverter" />
@@ -73,12 +75,18 @@
<StackPanel Orientation="Horizontal">
<TextBlock Text="Framerate (FPS):" VerticalAlignment="Top" Margin="0,5,0,0" Width="100"/>
<StackPanel Orientation="Vertical">
- <ComboBox Width="120" ItemsSource="{Binding Framerates}" SelectedItem="{Binding SelectedFramerate}" />
- <RadioButton Content="Constant Framerate" IsChecked="{Binding IsConstantFramerate}" Margin="0,10,0,0" />
- <RadioButton Content="Variable Framerate" IsChecked="{Binding IsVariableFramerate}" Margin="0,5,0,0"
+ <ComboBox Width="120" ItemsSource="{Binding Framerates}" SelectedItem="{Binding SelectedFramerate}"
+ Visibility="{Binding DisplayNonQSVControls, Converter={StaticResource boolToVisConverter}, ConverterParameter=false}" />
+ <TextBlock Text="Same as source" VerticalAlignment="Center" Margin="0,5,0,0"
+ Visibility="{Binding DisplayNonQSVControls, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}"/>
+
+ <StackPanel Orientation="Vertical" Visibility="{Binding DisplayNonQSVControls, Converter={StaticResource boolToVisConverter}}">
+ <RadioButton Content="Constant Framerate" IsChecked="{Binding IsConstantFramerate}" Margin="0,10,0,0" />
+ <RadioButton Content="Variable Framerate" IsChecked="{Binding IsVariableFramerate}" Margin="0,5,0,0"
Visibility="{Binding ShowPeakFramerate, Converter={StaticResource boolToVisConverter}, ConverterParameter=true}" />
- <RadioButton Content="Peak Framerate" IsChecked="{Binding IsPeakFramerate}" Margin="0,5,0,0"
+ <RadioButton Content="Peak Framerate" IsChecked="{Binding IsPeakFramerate}" Margin="0,5,0,0"
Visibility="{Binding ShowPeakFramerate, Converter={StaticResource boolToVisConverter}, ConverterParameter=false}" />
+ </StackPanel>
</StackPanel>
</StackPanel>
</StackPanel>
@@ -88,7 +96,7 @@
<TextBlock Text="Quality" FontWeight="Bold" Margin="0,0,0,10"/>
<StackPanel Orientation="Horizontal" Margin="0,0,0,10" >
- <RadioButton Content="Constant Quality:" IsChecked="{Binding IsConstantQuantity}" Margin="0,0,10,0"/>
+ <RadioButton Content="Constant Quality:" IsChecked="{Binding IsConstantQuantity}" Margin="0,0,10,0" Checked="qsv_preset_radiobutton"/>
<TextBlock Text="{Binding DisplayRF}" MinWidth="30" />
<TextBlock Text="{Binding Rfqp}" FontWeight="Bold" Margin="5,0,0,0" />
@@ -111,22 +119,21 @@
</Grid>
<StackPanel Orientation="Horizontal" Margin="0,0,0,10">
- <RadioButton Content="Avg Bitrate (kbps):" IsChecked="{Binding IsConstantQuantity, Converter={StaticResource boolConverter}, ConverterParameter=true}" Margin="0,0,10,0"/>
- <TextBox Width="75" Text="{Binding Task.VideoBitrate, UpdateSourceTrigger=PropertyChanged}"
- IsEnabled="{Binding IsConstantQuantity, Converter={StaticResource boolConverter}, ConverterParameter=true}" />
+ <RadioButton Content="Avg Bitrate (kbps):" IsChecked="{Binding IsConstantQuantity, Converter={StaticResource boolConverter}, ConverterParameter=true}" Margin="0,0,10,0" Checked="qsv_preset_radiobutton"/>
+ <TextBox Width="75" Text="{Binding Task.VideoBitrate, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding IsConstantQuantity, Converter={StaticResource boolConverter}, ConverterParameter=true}" />
</StackPanel>
- <StackPanel Orientation="Horizontal" Margin="30,0,0,0">
+ <StackPanel Orientation="Horizontal" Margin="30,0,0,0" Visibility="{Binding DisplayNonQSVControls, Converter={StaticResource boolToVisConverter}}">
<CheckBox Content="2-Pass Encoding" IsEnabled="{Binding IsConstantQuantity, Converter={StaticResource boolConverter}, ConverterParameter=true}"
- IsChecked="{Binding Task.TwoPass}" Margin="0,0,10,0" />
+ IsChecked="{Binding TwoPass}" Margin="0,0,10,0" />
<CheckBox Content="Turbo first pass" IsEnabled="{Binding IsConstantQuantity, Converter={StaticResource boolConverter}, ConverterParameter=true}"
- IsChecked="{Binding Task.TurboFirstPass}" />
+ IsChecked="{Binding TurboFirstPass}" />
</StackPanel>
</StackPanel>
<!-- H264 settings -->
- <Grid Grid.Row="1" Grid.ColumnSpan="2" Margin="0,20,0,0" Visibility="{Binding DisplayX264Options, Converter={StaticResource boolToVisConverter}}">
+ <Grid Grid.Row="1" Grid.ColumnSpan="2" Margin="0,20,0,0" Visibility="{Binding DisplayH264Options, Converter={StaticResource boolToVisConverter}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
@@ -138,8 +145,7 @@
<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 Grid.Row="2" Margin="0,5,0,0" IsEnabled="{Binding UseAdvancedTab, Converter={StaticResource inverseConverter}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
@@ -159,22 +165,36 @@
<!-- 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">
+ <TextBlock Text="x264 Preset:" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center"
+ Visibility="{Binding DisplayX264Options, Converter={StaticResource boolToVisConverter}}" />
+ <StackPanel Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" Orientation="Horizontal"
+ Visibility="{Binding DisplayX264Options, Converter={StaticResource boolToVisConverter}}" >
<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="x264 Tune:" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" Margin="0,10,0,0" />
+ <TextBlock Text="x264 Tune:" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" Margin="0,10,0,0"
+ Visibility="{Binding DisplayX264Options, Converter={StaticResource boolToVisConverter}}" />
<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}" />
+ ItemsSource="{Binding X264Tunes, Converter={StaticResource enumComboConverter}}"
+ SelectedItem="{Binding X264Tune, Converter={StaticResource enumComboConverter}}"
+ Visibility="{Binding DisplayX264Options, Converter={StaticResource boolToVisConverter}}"
+ 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"
- ToolTip="{x:Static Properties:Resources.Video_x264FastDecode}"/>
+ Visibility="{Binding DisplayX264Options, Converter={StaticResource boolToVisConverter}}"
+ ToolTip="{x:Static Properties:Resources.Video_x264FastDecode}"/>
+
+ <TextBlock Text="QSV Preset:" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center"
+ Visibility="{Binding DisplayQSVOptions, Converter={StaticResource boolToVisConverter}}" />
+ <StackPanel Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" Orientation="Horizontal"
+ Visibility="{Binding DisplayQSVOptions, Converter={StaticResource boolToVisConverter}}" >
+ <Slider Minimum="0" Maximum="{Binding QsvSliderMax}" Width="150" Value="{Binding QsvPresetValue, Mode=Default, UpdateSourceTrigger=PropertyChanged}"
+ IsSnapToTickEnabled="True" TickFrequency="1" TickPlacement="BottomRight" ValueChanged="qsv_preset_ValueChanged"/>
+ <TextBlock Text="{Binding QsvPreset, Converter={StaticResource enumComboConverter}}" Margin="5,0,0,0" />
+ </StackPanel>
<!-- Row 2-->
@@ -193,10 +213,18 @@
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" />
+ <TextBlock Text="Extra Options:" Grid.Row="4" Grid.Column="0" Margin="0,10,0,0" VerticalAlignment="Center" HorizontalAlignment="Left"
+ Visibility="{Binding DisplayX264Options, Converter={StaticResource boolToVisConverter}}" />
<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}" Style="{StaticResource LongToolTipHolder}" />
+ Height="30" MaxLines="2" Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="3" Margin="5,10,0,0" VerticalAlignment="Center"
+ ToolTip="{Binding FullOptionsTooltip}" Style="{StaticResource LongToolTipHolder}"
+ Visibility="{Binding DisplayX264Options, Converter={StaticResource boolToVisConverter}}" >
+ <TextBox.ContextMenu>
+ <ContextMenu>
+ <MenuItem Header="Copy Full Query" cal:Message.Attach="[Event Click] = [Action CopyQuery]" />
+ </ContextMenu>
+ </TextBox.ContextMenu>
+ </TextBox>
</Grid>
diff --git a/win/CS/HandBrakeWPF/Views/VideoView.xaml.cs b/win/CS/HandBrakeWPF/Views/VideoView.xaml.cs
index 8a0842a96..a285e490b 100644
--- a/win/CS/HandBrakeWPF/Views/VideoView.xaml.cs
+++ b/win/CS/HandBrakeWPF/Views/VideoView.xaml.cs
@@ -9,8 +9,19 @@
namespace HandBrakeWPF.Views
{
+ using System.Collections.Generic;
+ using System.Windows;
using System.Windows.Controls;
+ using Caliburn.Micro;
+
+ using HandBrake.ApplicationServices.Model;
+ using HandBrake.ApplicationServices.Utilities;
+ using HandBrake.Interop.Model.Encoding;
+
+ using HandBrakeWPF.ViewModels;
+ using HandBrakeWPF.ViewModels.Interfaces;
+
/// <summary>
/// Interaction logic for VideoView.xaml
/// </summary>
@@ -23,5 +34,80 @@ namespace HandBrakeWPF.Views
{
InitializeComponent();
}
+
+
+ private void qsv_preset_radiobutton(object sender, System.Windows.RoutedEventArgs e)
+ {
+ qsv_preset_ValueChanged(sender, null);
+ }
+
+ private void qsv_preset_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
+ {
+ VideoViewModel mvm = ((VideoViewModel)this.DataContext);
+ EncodeTask task = mvm.Task;
+
+ string addon = "";
+
+ if (SystemInfo.IsHswOrNewer)
+ {
+ if (task.VideoEncodeRateType == VideoEncodeRateType.ConstantQuality)
+ {
+ if (task.QsvPreset == QsvPreset.Balanced ||
+ task.QsvPreset == QsvPreset.Speed)
+ addon = "num-ref-frame=1";
+ }
+ if (task.VideoEncodeRateType == VideoEncodeRateType.AverageBitrate)
+ {
+ if (task.QsvPreset == QsvPreset.Quality)
+ addon = "lookahead=1:gop-ref-dist=3";
+ else
+ if (task.QsvPreset == QsvPreset.Balanced)
+ {
+ addon = "num-ref-frame=1:gop-ref-dist=1";
+ }
+ else
+ if (task.QsvPreset == QsvPreset.Speed)
+ addon = "gop-ref-dist=1";
+ }
+ }
+
+
+ string full_string = addon + ":";
+
+ IDictionary<string, string> newOptions = new Dictionary<string, string>();
+ string[] existingSegments = full_string.Split(':');
+ foreach (string existingSegment in existingSegments)
+ {
+ string optionName = existingSegment;
+ string optionValue = string.Empty;
+ int equalsIndex = existingSegment.IndexOf('=');
+ if (equalsIndex >= 0)
+ {
+ optionName = existingSegment.Substring(
+ 0, existingSegment.IndexOf("=", System.StringComparison.Ordinal));
+ optionValue = existingSegment.Substring(equalsIndex);
+ }
+
+ if (optionName != string.Empty)
+ {
+ if (newOptions.ContainsKey(optionName))
+ newOptions.Remove(optionName);
+ newOptions.Add(optionName, optionValue);
+ }
+ }
+
+ full_string = "";
+ foreach (KeyValuePair<string, string> entry in newOptions)
+ {
+ full_string += entry.Key;
+ if (entry.Value != string.Empty)
+ full_string += entry.Value;
+ full_string += ":";
+ }
+ full_string = full_string.TrimEnd(':');
+
+ task.AdvancedEncoderOptions = full_string;
+ task.NotifyOfPropertyChange(() => task.AdvancedEncoderOptions);
+ }
}
}