// -------------------------------------------------------------------------------------------------------------------- // // This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. // // // The Options View Model // // -------------------------------------------------------------------------------------------------------------------- namespace HandBrakeWPF.ViewModels { using System; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Windows; using System.Windows.Media; using Caliburn.Micro; using HandBrake.Interop.Interop; using HandBrake.Interop.Model; using HandBrake.Interop.Utilities; using HandBrakeWPF.Model; using HandBrakeWPF.Model.Options; using HandBrakeWPF.Properties; using HandBrakeWPF.Services.Interfaces; using HandBrakeWPF.Utilities; using HandBrakeWPF.ViewModels.Interfaces; using Microsoft.Win32; using Ookii.Dialogs.Wpf; using Execute = Caliburn.Micro.Execute; using SystemInfo = HandBrake.Interop.Utilities.SystemInfo; /// /// The Options View Model /// public class OptionsViewModel : ViewModelBase, IOptionsViewModel { #region Constants and Fields private readonly IUserSettingService userSettingService; private readonly IUpdateService updateService; private readonly IErrorService errorService; private string arguments; private string autoNameDefaultPath; private bool automaticallyNameFiles; private string autonameFormat; private bool changeToTitleCase; private bool checkForUpdates; private UpdateCheck checkForUpdatesFrequency; private bool clearOldOlgs; private BindingList constantQualityGranularity = new BindingList(); private bool copyLogToEncodeDirectory; private bool copyLogToSepcficedLocation; private bool disableLibdvdNav; private string logDirectory; private BindingList logVerbosityOptions = new BindingList(); private long minLength; private bool minimiseToTray; private bool preventSleep; private BindingList previewPicturesToScan = new BindingList(); private bool removeUnderscores; private string selectedGranulairty; private Mp4Behaviour selectedMp4Extension; private int selectedPreviewCount; private ProcessPriority selectedPriority; private int selectedVerbosity; private bool sendFileAfterEncode; private string sendFileTo; private string sendFileToPath; private string vlcPath; private WhenDone whenDone; private bool clearQueueOnEncodeCompleted; private OptionsTab selectedTab; private string updateMessage; private bool updateAvailable; private int downloadProgressPercentage; private UpdateCheckInformation updateInfo; private bool removePunctuation; private bool resetWhenDoneAction; private bool enableQuickSyncDecoding; private bool pauseOnLowDiskspace; private long pauseOnLowDiskspaceLevel; private bool useQsvDecodeForNonQsvEnc; private bool showStatusInTitleBar; private bool showPreviewOnSummaryTab; private string whenDoneAudioFile; private bool playSoundWhenDone; private bool playSoundWhenQueueDone; private bool enableQuickSyncEncoding; private bool enableVceEncoder; private bool enableNvencEncoder; private InterfaceLanguage selectedLanguage; private bool showAddSelectionToQueue; private bool showAddAllToQueue; private int selectedOverwriteBehaviour; private int selectedCollisionBehaviour; private string prePostFilenameText; private bool showPrePostFilenameBox; private bool whenDonePerformActionImmediately; private bool useDarkTheme; private bool alwaysUseDefaultPath; // Experimental private int remoteServicePort; private bool remoteServiceEnabled; #endregion #region Constructors and Destructors /// /// Initializes a new instance of the class. /// /// /// The user Setting Service. /// /// /// The update Service. /// /// /// The about View Model. /// /// /// The error Service. /// public OptionsViewModel(IUserSettingService userSettingService, IUpdateService updateService, IAboutViewModel aboutViewModel, IErrorService errorService) { this.Title = "Options"; this.userSettingService = userSettingService; this.updateService = updateService; this.errorService = errorService; this.AboutViewModel = aboutViewModel; this.OnLoad(); this.SelectedTab = OptionsTab.General; this.UpdateMessage = Resources.OptionsViewModel_CheckForUpdatesMsg; } #endregion #region Window Properties /// /// Gets or sets SelectedTab. /// public OptionsTab SelectedTab { get { return this.selectedTab; } set { this.selectedTab = value; this.NotifyOfPropertyChange(() => this.SelectedTab); } } /// /// Gets or sets the about view model. /// public IAboutViewModel AboutViewModel { get; set; } #endregion #region Properties public bool IsUWP { get { return UwpDetect.IsUWP(); } } public bool IsNightly { get { return VersionHelper.IsNightly(); } } public bool IsWindows10 => HandBrakeWPF.Utilities.SystemInfo.IsWindows10(); #region General public BindingList InterfaceLanguages { get { return new BindingList(InterfaceLanguageUtilities.GetUserInterfaceLangauges()); } } public InterfaceLanguage SelectedLanguage { get => this.selectedLanguage; set { if (Equals(value, this.selectedLanguage)) return; this.selectedLanguage = value; this.NotifyOfPropertyChange(() => this.SelectedLanguage); } } /// /// Gets or sets a value indicating whether CheckForUpdates. /// public bool CheckForUpdates { get { return this.checkForUpdates; } set { this.checkForUpdates = value; this.NotifyOfPropertyChange("CheckForUpdates"); } } /// /// Gets or sets a value indicating whether reset when done action. /// public bool ResetWhenDoneAction { get { return this.resetWhenDoneAction; } set { this.resetWhenDoneAction = value; this.NotifyOfPropertyChange("ResetWhenDoneAction"); } } /// /// Gets or sets CheckForUpdatesFrequencies. /// public BindingList CheckForUpdatesFrequencies { get { return new BindingList(EnumHelper.GetEnumList().ToList()); } } /// /// Gets or sets a value indicating whether CheckForUpdatesFrequency. /// public UpdateCheck CheckForUpdatesFrequency { get { return this.checkForUpdatesFrequency; } set { this.checkForUpdatesFrequency = value; this.NotifyOfPropertyChange(() => this.CheckForUpdatesFrequency); } } /// /// Gets or sets Arguments. /// public string Arguments { get { return this.arguments; } set { this.arguments = value; this.NotifyOfPropertyChange("Arguments"); } } /// /// Gets or sets a value indicating whether SendFileAfterEncode. /// public bool SendFileAfterEncode { get { return this.sendFileAfterEncode; } set { this.sendFileAfterEncode = value; this.NotifyOfPropertyChange("SendFileAfterEncode"); } } /// /// Gets or sets SendFileTo. /// public string SendFileTo { get { return this.sendFileTo; } set { this.sendFileTo = value; this.NotifyOfPropertyChange("SendFileTo"); } } /// /// Gets or sets SendFileToPath. /// public string SendFileToPath { get { return this.sendFileToPath; } set { this.sendFileToPath = value; this.NotifyOfPropertyChange("SendFileToPath"); } } /// /// Gets or sets WhenDone. /// public WhenDone WhenDone { get { return this.whenDone; } set { this.whenDone = value; this.NotifyOfPropertyChange("WhenDone"); } } /// /// Gets WhenDoneOptions. /// public BindingList WhenDoneOptions { get { return new BindingList(EnumHelper.GetEnumList().ToList()); } } public bool WhenDonePerformActionImmediately { get => this.whenDonePerformActionImmediately; set { if (value == this.whenDonePerformActionImmediately) return; this.whenDonePerformActionImmediately = value; this.NotifyOfPropertyChange(() => this.WhenDonePerformActionImmediately); } } /// /// Gets or sets a value indicating whether to show encode status in the tile bar. /// public bool ShowStatusInTitleBar { get { return this.showStatusInTitleBar; } set { if (value == this.showStatusInTitleBar) return; this.showStatusInTitleBar = value; this.NotifyOfPropertyChange(() => this.ShowStatusInTitleBar); } } /// /// Gets or sets a value indicating whether to show previews in the summary tab. /// public bool ShowPreviewOnSummaryTab { get { return this.showPreviewOnSummaryTab; } set { if (value == this.showPreviewOnSummaryTab) return; this.showPreviewOnSummaryTab = value; this.NotifyOfPropertyChange(() => this.ShowPreviewOnSummaryTab); } } /// /// When Done Audio File /// public string WhenDoneAudioFile { get { return this.whenDoneAudioFile; } set { if (value == this.whenDoneAudioFile) return; this.whenDoneAudioFile = value; this.NotifyOfPropertyChange(() => this.WhenDoneAudioFile); } } /// /// When Done Audio File - File Path /// public string WhenDoneAudioFileFullPath { get; set; } /// /// Play a sound when an encode or queue finishes. /// public bool PlaySoundWhenDone { get { return this.playSoundWhenDone; } set { if (value == this.playSoundWhenDone) return; this.playSoundWhenDone = value; this.NotifyOfPropertyChange(() => this.PlaySoundWhenDone); } } public bool PlaySoundWhenQueueDone { get { return this.playSoundWhenQueueDone; } set { if (value == this.playSoundWhenQueueDone) return; this.playSoundWhenQueueDone = value; this.NotifyOfPropertyChange(() => this.PlaySoundWhenQueueDone); } } public bool ShowAddSelectionToQueue { get => this.showAddSelectionToQueue; set { if (value == this.showAddSelectionToQueue) return; this.showAddSelectionToQueue = value; this.NotifyOfPropertyChange(() => this.ShowAddSelectionToQueue); } } public bool ShowAddAllToQueue { get => this.showAddAllToQueue; set { if (value == this.showAddAllToQueue) return; this.showAddAllToQueue = value; this.NotifyOfPropertyChange(() => this.ShowAddAllToQueue); } } public bool UseDarkTheme { get => this.useDarkTheme; set { if (value == this.useDarkTheme) return; this.useDarkTheme = value; this.NotifyOfPropertyChange(() => this.UseDarkTheme); } } #endregion #region Output Files /// /// Gets or sets AutoNameDefaultPath. /// public string AutoNameDefaultPath { get { return this.autoNameDefaultPath; } set { this.autoNameDefaultPath = value; this.NotifyOfPropertyChange("AutoNameDefaultPath"); } } /// /// Gets or sets a value indicating whether AutomaticallyNameFiles. /// public bool AutomaticallyNameFiles { get { return this.automaticallyNameFiles; } set { this.automaticallyNameFiles = value; this.NotifyOfPropertyChange("AutomaticallyNameFiles"); } } /// /// Gets or sets AutonameFormat. /// public string AutonameFormat { get { return this.autonameFormat; } set { if (this.IsValidAutonameFormat(value, false)) { this.autonameFormat = value; } this.NotifyOfPropertyChange("AutonameFormat"); } } /// /// Gets or sets a value indicating whether ChangeToTitleCase. /// public bool ChangeToTitleCase { get { return this.changeToTitleCase; } set { this.changeToTitleCase = value; this.NotifyOfPropertyChange("ChangeToTitleCase"); } } /// /// Gets or sets a value indicating whether RemoveUnderscores. /// public bool RemoveUnderscores { get { return this.removeUnderscores; } set { this.removeUnderscores = value; this.NotifyOfPropertyChange("RemoveUnderscores"); } } public BindingList Mp4ExtensionOptions { get { return new BindingList(EnumHelper.GetEnumList().ToList()); } } /// /// Gets or sets SelectedMp4Extension. /// public Mp4Behaviour SelectedMp4Extension { get { return this.selectedMp4Extension; } set { this.selectedMp4Extension = value; this.NotifyOfPropertyChange(() => this.SelectedMp4Extension); } } /// /// Gets or sets a value indicating whether remove punctuation. /// public bool RemovePunctuation { get { return this.removePunctuation; } set { this.removePunctuation = value; this.NotifyOfPropertyChange(() => RemovePunctuation); } } public BindingList FileOverwriteBehaviourList { get; set; } public int SelectedOverwriteBehaviour { get => this.selectedOverwriteBehaviour; set { if (value == this.selectedOverwriteBehaviour) return; this.selectedOverwriteBehaviour = value; this.NotifyOfPropertyChange(() => this.SelectedOverwriteBehaviour); } } public BindingList AutonameFileCollisionBehaviours { get; set; } public int SelectedCollisionBehaviour { get => this.selectedCollisionBehaviour; set { if (value == this.selectedCollisionBehaviour) return; this.selectedCollisionBehaviour = value; this.ShowPrePostFilenameBox = this.selectedCollisionBehaviour >= 1; this.NotifyOfPropertyChange(() => this.SelectedCollisionBehaviour); } } public string PrePostFilenameText { get => this.prePostFilenameText; set { if (value == this.prePostFilenameText) return; if (this.IsValidAutonameFormat(value, false)) { this.prePostFilenameText = value; } this.NotifyOfPropertyChange(() => this.PrePostFilenameText); } } public bool ShowPrePostFilenameBox { get => this.showPrePostFilenameBox; set { if (value == this.showPrePostFilenameBox) return; this.showPrePostFilenameBox = value; this.NotifyOfPropertyChange(() => this.ShowPrePostFilenameBox); } } public bool AlwaysUseDefaultPath { get => this.alwaysUseDefaultPath; set { if (value == this.alwaysUseDefaultPath) { return; } this.alwaysUseDefaultPath = value; this.NotifyOfPropertyChange(() => this.AlwaysUseDefaultPath); } } #endregion #region Preview /// /// Gets or sets VLCPath. /// public string VLCPath { get { return this.vlcPath; } set { this.vlcPath = value; this.NotifyOfPropertyChange("VLCPath"); } } #endregion #region System and Logging /// /// Gets or sets a value indicating whether CopyLogToEncodeDirectory. /// public bool CopyLogToEncodeDirectory { get { return this.copyLogToEncodeDirectory; } set { this.copyLogToEncodeDirectory = value; this.NotifyOfPropertyChange("CopyLogToEncodeDirectory"); } } /// /// Gets or sets a value indicating whether CopyLogToSepcficedLocation. /// public bool CopyLogToSepcficedLocation { get { return this.copyLogToSepcficedLocation; } set { this.copyLogToSepcficedLocation = value; this.NotifyOfPropertyChange("CopyLogToSepcficedLocation"); } } /// /// Gets or sets a value indicating whether ClearOldOlgs. /// public bool ClearOldOlgs { get { return this.clearOldOlgs; } set { this.clearOldOlgs = value; this.NotifyOfPropertyChange("ClearOldOlgs"); } } /// /// Gets or sets LogDirectory. /// public string LogDirectory { get { return this.logDirectory; } set { this.logDirectory = value; this.NotifyOfPropertyChange("LogDirectory"); } } /// /// Gets or sets a value indicating whether PreventSleep. /// public bool PreventSleep { get { return this.preventSleep; } set { this.preventSleep = value; this.NotifyOfPropertyChange("PreventSleep"); } } /// /// Gets or sets a value indicating whether HandBrake should pause on low disk space. /// public bool PauseOnLowDiskspace { get { return this.pauseOnLowDiskspace; } set { this.pauseOnLowDiskspace = value; this.NotifyOfPropertyChange(() => this.PauseOnLowDiskspace); } } /// /// Get or sets the value that HB warns about low disk space. /// public long PauseOnLowDiskspaceLevel { get { return this.pauseOnLowDiskspaceLevel; } set { this.pauseOnLowDiskspaceLevel = value; this.NotifyOfPropertyChange(() => this.pauseOnLowDiskspaceLevel); } } public BindingList PriorityLevelOptions { get { return new BindingList(EnumHelper.GetEnumList().ToList()); } } /// /// Gets or sets a value indicating whether SelectedGranulairty. /// public string SelectedGranulairty { get { return this.selectedGranulairty; } set { this.selectedGranulairty = value; this.NotifyOfPropertyChange("SelectedGranulairty"); } } /// /// Gets or sets SelectedPriority. /// public ProcessPriority SelectedPriority { get { return this.selectedPriority; } set { this.selectedPriority = value; this.NotifyOfPropertyChange(); // Set the Process Priority switch (value) { case ProcessPriority.High: Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High; break; case ProcessPriority.AboveNormal: Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.AboveNormal; break; case ProcessPriority.Normal: Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.Normal; break; case ProcessPriority.BelowNormal: Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.BelowNormal; break; case ProcessPriority.Low: Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.Idle; break; default: Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.BelowNormal; break; } } } #endregion #region Advanced /// /// Gets or sets ConstantQualityGranularity. /// public BindingList ConstantQualityGranularity { get { return this.constantQualityGranularity; } set { this.constantQualityGranularity = value; this.NotifyOfPropertyChange("ConstantQualityGranularity"); } } /// /// Gets or sets a value indicating whether DisableLibdvdNav. /// public bool DisableLibdvdNav { get { return this.disableLibdvdNav; } set { this.disableLibdvdNav = value; this.NotifyOfPropertyChange("DisableLibdvdNav"); } } /// /// Gets or sets LogVerbosityOptions. /// public BindingList LogVerbosityOptions { get { return this.logVerbosityOptions; } set { this.logVerbosityOptions = value; this.NotifyOfPropertyChange("LogVerbosityOptions"); } } /// /// Gets or sets MinLength. /// public long MinLength { get { return this.minLength; } set { this.minLength = value; this.NotifyOfPropertyChange("MinLength"); } } /// /// Gets or sets a value indicating whether MinimiseToTray. /// public bool MinimiseToTray { get { return this.minimiseToTray; } set { this.minimiseToTray = value; this.NotifyOfPropertyChange("MinimiseToTray"); } } /// /// Gets or sets PreviewPicturesToScan. /// public BindingList PreviewPicturesToScan { get { return this.previewPicturesToScan; } set { this.previewPicturesToScan = value; this.NotifyOfPropertyChange("PreviewPicturesToScan"); } } /// /// Gets or sets SelectedPreviewCount. /// public int SelectedPreviewCount { get { return this.selectedPreviewCount; } set { this.selectedPreviewCount = value; this.NotifyOfPropertyChange("SelectedPreviewCount"); } } /// /// Gets or sets SelectedVerbosity. /// public int SelectedVerbosity { get { return this.selectedVerbosity; } set { this.selectedVerbosity = value; this.NotifyOfPropertyChange("SelectedVerbosity"); } } /// /// Gets or sets a value indicating whether ClearQueueOnEncodeCompleted. /// public bool ClearQueueOnEncodeCompleted { get { return this.clearQueueOnEncodeCompleted; } set { this.clearQueueOnEncodeCompleted = value; this.NotifyOfPropertyChange(() => this.ClearQueueOnEncodeCompleted); } } #endregion #region Video public bool EnableQuickSyncEncoding { get => this.enableQuickSyncEncoding && this.IsQuickSyncAvailable; set { if (value == this.enableQuickSyncEncoding) { return; } this.enableQuickSyncEncoding = value; this.NotifyOfPropertyChange(() => this.EnableQuickSyncEncoding); } } public bool EnableVceEncoder { get => this.enableVceEncoder && this.IsVceAvailable; set { if (value == this.enableVceEncoder) { return; } this.enableVceEncoder = value; this.NotifyOfPropertyChange(() => this.EnableVceEncoder); } } public bool EnableNvencEncoder { get => this.enableNvencEncoder && this.IsNvencAvailable; set { if (value == this.enableNvencEncoder) { return; } this.enableNvencEncoder = value; this.NotifyOfPropertyChange(() => this.EnableNvencEncoder); } } public bool EnableQuickSyncDecoding { get { return this.enableQuickSyncDecoding; } set { if (value.Equals(this.enableQuickSyncDecoding)) { return; } this.enableQuickSyncDecoding = value; this.NotifyOfPropertyChange(() => this.EnableQuickSyncDecoding); this.NotifyOfPropertyChange(() => this.IsUseQsvDecAvailable); } } public VideoScaler SelectedScalingMode { get; set; } public bool IsQuickSyncAvailable { get { return SystemInfo.IsQsvAvailable; } } public bool IsVceAvailable { get { return SystemInfo.IsVceH264Available; } } public bool IsNvencAvailable { get { return SystemInfo.IsNVEncH264Available; } } /// /// Gets a value indicating whether is use qsv dec available. /// public bool IsUseQsvDecAvailable { get { return IsQuickSyncAvailable && this.EnableQuickSyncDecoding; } } public bool UseQSVDecodeForNonQSVEnc { get { return this.useQsvDecodeForNonQsvEnc; } set { if (value == this.useQsvDecodeForNonQsvEnc) return; this.useQsvDecodeForNonQsvEnc = value; this.NotifyOfPropertyChange(() => this.UseQSVDecodeForNonQSVEnc); } } public BindingList ScalingOptions { get { return new BindingList(EnumHelper.GetEnumList().ToList()); } } public bool IsHardwareFallbackMode => HandBrakeUtils.IsInitNoHardware(); #endregion #endregion #region About HandBrake /// /// Gets Version. /// public string Version { get { return string.Format("{0}", VersionHelper.GetVersion()); } } /// /// Gets or sets UpdateMessage. /// public string UpdateMessage { get { return this.updateMessage; } set { this.updateMessage = value; this.NotifyOfPropertyChange(() => this.UpdateMessage); } } /// /// Gets or sets a value indicating whether UpdateAvailable. /// public bool UpdateAvailable { get { return this.updateAvailable; } set { this.updateAvailable = value; this.NotifyOfPropertyChange(() => this.UpdateAvailable); } } /// /// Gets or sets DownloadProgressPercentage. /// public int DownloadProgressPercentage { get { return this.downloadProgressPercentage; } set { this.downloadProgressPercentage = value; this.NotifyOfPropertyChange(() => this.DownloadProgressPercentage); } } #endregion // Experimental public bool RemoteServiceEnabled { get => this.remoteServiceEnabled; set { if (value == this.remoteServiceEnabled) { return; } this.remoteServiceEnabled = value; this.NotifyOfPropertyChange(() => this.RemoteServiceEnabled); } } public int RemoteServicePort { get => this.remoteServicePort; set { if (value == this.remoteServicePort) { return; } if (value > 32767 || value < 5000) { this.errorService.ShowMessageBox( Resources.OptionsView_RemotePortLimit, Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error); return; // Allow only valid ports, not in the ephemeral range } this.remoteServicePort = value; this.NotifyOfPropertyChange(() => this.RemoteServicePort); } } #region Public Methods /// /// Close this window. /// public void Close() { this.Save(); IShellViewModel shellViewModel = IoC.Get(); shellViewModel.DisplayWindow(ShellWindow.MainWindow); } /// /// Browse - Send File To /// public void BrowseSendFileTo() { OpenFileDialog dialog = new OpenFileDialog { Filter = "All files (*.*)|*.*", FileName = this.sendFileToPath }; bool? dialogResult = dialog.ShowDialog(); if (dialogResult.HasValue && dialogResult.Value) { this.SendFileTo = Path.GetFileNameWithoutExtension(dialog.FileName); this.sendFileToPath = dialog.FileName; } } /// /// Browse Auto Name Path /// public void BrowseAutoNamePath() { VistaFolderBrowserDialog dialog = new VistaFolderBrowserDialog { Description = Resources.OptionsView_SelectFolder, UseDescriptionForTitle = true, SelectedPath = this.AutoNameDefaultPath }; bool? dialogResult = dialog.ShowDialog(); if (dialogResult.HasValue && dialogResult.Value) { this.AutoNameDefaultPath = dialog.SelectedPath; } } /// /// Browse VLC Path /// public void BrowseVlcPath() { OpenFileDialog dialog = new OpenFileDialog { Filter = "All files (*.exe)|*.exe", FileName = this.VLCPath }; bool? dialogResult = dialog.ShowDialog(); if (dialogResult.HasValue && dialogResult.Value) { this.VLCPath = dialog.FileName; } } /// /// Browse - Log Path /// public void BrowseLogPath() { VistaFolderBrowserDialog dialog = new VistaFolderBrowserDialog { Description = Resources.OptionsView_SelectFolder, UseDescriptionForTitle = true, SelectedPath = this.LogDirectory }; bool? dialogResult = dialog.ShowDialog(); if (dialogResult.HasValue && dialogResult.Value) { this.LogDirectory = dialog.SelectedPath; } } /// /// View the Default Log Directory for HandBrake /// public void ViewLogDirectory() { string logDir = DirectoryUtilities.GetLogDirectory(); string windir = Environment.GetEnvironmentVariable("WINDIR"); Process prc = new Process { StartInfo = { FileName = windir + @"\explorer.exe", Arguments = logDir } }; prc.Start(); } /// /// Clear HandBrakes log directory. /// public void ClearLogHistory() { MessageBoxResult result = this.errorService.ShowMessageBox(Resources.OptionsView_ClearLogDirConfirm, Resources.OptionsView_ClearLogs, MessageBoxButton.YesNoCancel, MessageBoxImage.Question); if (result == MessageBoxResult.Yes) { GeneralUtilities.ClearLogFiles(0); this.errorService.ShowMessageBox(Resources.OptionsView_LogsCleared, Resources.OptionsView_Notice, MessageBoxButton.OK, MessageBoxImage.Information); } } /// /// Download an Update /// public void DownloadUpdate() { this.UpdateMessage = Resources.OptionsView_PreparingUpdate; this.updateService.DownloadFile(this.updateInfo.DownloadFile, this.updateInfo.Signature, this.DownloadComplete, this.DownloadProgress); } /// /// Check for updates /// public void PerformUpdateCheck() { this.UpdateMessage = Resources.OptionsView_CheckingForUpdates; this.updateService.CheckForUpdates(this.UpdateCheckComplete); } /// /// Browse - Send File To /// public void BrowseWhenDoneAudioFile() { OpenFileDialog dialog = new OpenFileDialog() { Filter = "All Files|*.wav;*.mp3", FileName = this.WhenDoneAudioFileFullPath }; bool? dialogResult = dialog.ShowDialog(); if (dialogResult.HasValue && dialogResult.Value) { this.WhenDoneAudioFile = Path.GetFileNameWithoutExtension(dialog.FileName); this.WhenDoneAudioFileFullPath = dialog.FileName; } else { this.WhenDoneAudioFile = null; this.WhenDoneAudioFileFullPath = null; } } public void PlayWhenDoneFile() { if (!string.IsNullOrEmpty(this.WhenDoneAudioFileFullPath) && File.Exists(this.WhenDoneAudioFileFullPath)) { var uri = new Uri(this.WhenDoneAudioFileFullPath, UriKind.RelativeOrAbsolute); var player = new MediaPlayer(); player.Open(uri); player.Play(); player.MediaFailed += (object sender, ExceptionEventArgs e) => { Debug.WriteLine(e); }; } else { this.errorService.ShowMessageBox( Resources.OptionsView_MediaFileNotSet, Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error); } } #endregion /// /// Load User Settings /// public override void OnLoad() { // ############################# // General // ############################# string culture = this.userSettingService.GetUserSetting(UserSettingConstants.UiLanguage); this.SelectedLanguage = InterfaceLanguageUtilities.FindInterfaceLanguage(culture); this.CheckForUpdates = this.userSettingService.GetUserSetting(UserSettingConstants.UpdateStatus); this.CheckForUpdatesFrequency = (UpdateCheck)this.userSettingService.GetUserSetting(UserSettingConstants.DaysBetweenUpdateCheck); this.ShowStatusInTitleBar = this.userSettingService.GetUserSetting(UserSettingConstants.ShowStatusInTitleBar); this.ShowPreviewOnSummaryTab = this.userSettingService.GetUserSetting(UserSettingConstants.ShowPreviewOnSummaryTab); this.ShowAddAllToQueue = this.userSettingService.GetUserSetting(UserSettingConstants.ShowAddAllToQueue); this.ShowAddSelectionToQueue = this.userSettingService.GetUserSetting(UserSettingConstants.ShowAddSelectionToQueue); this.UseDarkTheme = this.userSettingService.GetUserSetting(UserSettingConstants.UseDarkTheme); // ############################# // When Done // ############################# this.WhenDone = (WhenDone)this.userSettingService.GetUserSetting(UserSettingConstants.WhenCompleteAction); if (this.userSettingService.GetUserSetting(UserSettingConstants.ResetWhenDoneAction)) { this.WhenDone = WhenDone.DoNothing; } this.SendFileAfterEncode = this.userSettingService.GetUserSetting(UserSettingConstants.SendFile); this.SendFileTo = Path.GetFileNameWithoutExtension(this.userSettingService.GetUserSetting(UserSettingConstants.SendFileTo)) ?? string.Empty; this.SendFileToPath = this.userSettingService.GetUserSetting(UserSettingConstants.SendFileTo) ?? string.Empty; this.Arguments = this.userSettingService.GetUserSetting(UserSettingConstants.SendFileToArgs) ?? string.Empty; this.ResetWhenDoneAction = this.userSettingService.GetUserSetting(UserSettingConstants.ResetWhenDoneAction); this.WhenDonePerformActionImmediately = this.userSettingService.GetUserSetting(UserSettingConstants.WhenDonePerformActionImmediately); this.WhenDoneAudioFile = Path.GetFileNameWithoutExtension(this.userSettingService.GetUserSetting(UserSettingConstants.WhenDoneAudioFile)) ?? string.Empty; this.WhenDoneAudioFileFullPath = this.userSettingService.GetUserSetting(UserSettingConstants.WhenDoneAudioFile); this.PlaySoundWhenDone = this.userSettingService.GetUserSetting(UserSettingConstants.PlaySoundWhenDone); this.PlaySoundWhenQueueDone = this.userSettingService.GetUserSetting(UserSettingConstants.PlaySoundWhenQueueDone); // ############################# // Output Settings // ############################# // Enable auto naming feature.) this.AutomaticallyNameFiles = this.userSettingService.GetUserSetting(UserSettingConstants.AutoNaming); // Store the auto name path this.AutoNameDefaultPath = this.userSettingService.GetUserSetting(UserSettingConstants.AutoNamePath) ?? string.Empty; if (string.IsNullOrEmpty(this.autoNameDefaultPath)) this.AutoNameDefaultPath = Resources.OptionsView_SetDefaultLocationOutputFIle; // Store auto name format string anf = this.userSettingService.GetUserSetting(UserSettingConstants.AutoNameFormat) ?? string.Empty; this.AutonameFormat = this.IsValidAutonameFormat(anf, true) ? anf : "{source}-{title}"; // Use iPod/iTunes friendly .m4v extension for MP4 files. this.SelectedMp4Extension = (Mp4Behaviour)this.userSettingService.GetUserSetting(UserSettingConstants.UseM4v); // Remove Underscores this.RemoveUnderscores = this.userSettingService.GetUserSetting(UserSettingConstants.AutoNameRemoveUnderscore); // Title case this.ChangeToTitleCase = this.userSettingService.GetUserSetting(UserSettingConstants.AutoNameTitleCase); this.RemovePunctuation = this.userSettingService.GetUserSetting(UserSettingConstants.RemovePunctuation); // File Overwrite this.FileOverwriteBehaviourList = new BindingList(); this.FileOverwriteBehaviourList.Add(FileOverwriteBehaviour.Ask); this.FileOverwriteBehaviourList.Add(FileOverwriteBehaviour.ForceOverwrite); this.SelectedOverwriteBehaviour = this.userSettingService.GetUserSetting(UserSettingConstants.FileOverwriteBehaviour); // Collision behaviour this.AutonameFileCollisionBehaviours = new BindingList() { AutonameFileCollisionBehaviour.AppendNumber, AutonameFileCollisionBehaviour.Prefix, AutonameFileCollisionBehaviour.Postfix }; this.SelectedCollisionBehaviour = this.userSettingService.GetUserSetting(UserSettingConstants.AutonameFileCollisionBehaviour); this.PrePostFilenameText = this.userSettingService.GetUserSetting(UserSettingConstants.AutonameFilePrePostString); this.AlwaysUseDefaultPath = this.userSettingService.GetUserSetting(UserSettingConstants.AlwaysUseDefaultPath); // ############################# // Picture Tab // ############################# // VLC Path this.VLCPath = this.userSettingService.GetUserSetting(UserSettingConstants.VLCPath) ?? string.Empty; // ############################# // Video // ############################# this.EnableQuickSyncDecoding = this.userSettingService.GetUserSetting(UserSettingConstants.EnableQuickSyncDecoding); this.SelectedScalingMode = this.userSettingService.GetUserSetting(UserSettingConstants.ScalingMode); this.UseQSVDecodeForNonQSVEnc = this.userSettingService.GetUserSetting(UserSettingConstants.UseQSVDecodeForNonQSVEnc); this.EnableQuickSyncEncoding = this.userSettingService.GetUserSetting(UserSettingConstants.EnableQuickSyncEncoding); this.EnableVceEncoder = this.userSettingService.GetUserSetting(UserSettingConstants.EnableVceEncoder); this.EnableNvencEncoder = this.userSettingService.GetUserSetting(UserSettingConstants.EnableNvencEncoder); // ############################# // CLI // ############################# this.SelectedPriority = (ProcessPriority)userSettingService.GetUserSetting(UserSettingConstants.ProcessPriorityInt); this.PreventSleep = userSettingService.GetUserSetting(UserSettingConstants.PreventSleep); this.PauseOnLowDiskspace = userSettingService.GetUserSetting(UserSettingConstants.PauseOnLowDiskspace); this.PauseOnLowDiskspaceLevel = this.userSettingService.GetUserSetting(UserSettingConstants.PauseQueueOnLowDiskspaceLevel); // Log Verbosity Level this.logVerbosityOptions.Clear(); this.logVerbosityOptions.Add(0); this.logVerbosityOptions.Add(1); this.logVerbosityOptions.Add(2); this.SelectedVerbosity = userSettingService.GetUserSetting(UserSettingConstants.Verbosity); // Logs this.CopyLogToEncodeDirectory = userSettingService.GetUserSetting(UserSettingConstants.SaveLogWithVideo); this.CopyLogToSepcficedLocation = userSettingService.GetUserSetting(UserSettingConstants.SaveLogToCopyDirectory); // The saved log path this.LogDirectory = userSettingService.GetUserSetting(UserSettingConstants.SaveLogCopyDirectory) ?? string.Empty; this.ClearOldOlgs = this.userSettingService.GetUserSetting(UserSettingConstants.ClearOldLogs); // ############################# // Advanced // ############################# // Minimise to Tray this.MinimiseToTray = this.userSettingService.GetUserSetting(UserSettingConstants.MainWindowMinimize); this.ClearQueueOnEncodeCompleted = userSettingService.GetUserSetting(UserSettingConstants.ClearCompletedFromQueue); // Set the preview count this.PreviewPicturesToScan.Clear(); this.PreviewPicturesToScan.Add(10); this.PreviewPicturesToScan.Add(15); this.PreviewPicturesToScan.Add(20); this.PreviewPicturesToScan.Add(25); this.PreviewPicturesToScan.Add(30); this.PreviewPicturesToScan.Add(35); this.PreviewPicturesToScan.Add(40); this.PreviewPicturesToScan.Add(45); this.PreviewPicturesToScan.Add(50); this.PreviewPicturesToScan.Add(55); this.PreviewPicturesToScan.Add(60); this.SelectedPreviewCount = this.userSettingService.GetUserSetting(UserSettingConstants.PreviewScanCount); // x264 step this.ConstantQualityGranularity.Clear(); this.ConstantQualityGranularity.Add("1.00"); this.ConstantQualityGranularity.Add("0.50"); this.ConstantQualityGranularity.Add("0.25"); this.SelectedGranulairty = userSettingService.GetUserSetting(UserSettingConstants.X264Step).ToString("0.00", CultureInfo.InvariantCulture); // Min Title Length this.MinLength = this.userSettingService.GetUserSetting(UserSettingConstants.MinScanDuration); // Use dvdnav this.DisableLibdvdNav = userSettingService.GetUserSetting(UserSettingConstants.DisableLibDvdNav); // ############################# // Experimental // ############################# this.RemoteServiceEnabled = this.userSettingService.GetUserSetting(UserSettingConstants.RemoteServiceEnabled); this.RemoteServicePort = userSettingService.GetUserSetting(UserSettingConstants.RemoteServicePort); } /// /// Some settings can be changed outside of this window. This will refresh their UI controls. /// public void UpdateSettings() { this.WhenDone = (WhenDone)this.userSettingService.GetUserSetting(UserSettingConstants.WhenCompleteAction); } /// /// The goto tab. /// /// /// The tab. /// public void GotoTab(OptionsTab tab) { this.SelectedTab = tab; } /// /// Load / Update the user settings. /// protected override void OnActivate() { this.OnLoad(); base.OnActivate(); } /// /// Save the settings selected /// private void Save() { /* General */ this.userSettingService.SetUserSetting(UserSettingConstants.UpdateStatus, this.CheckForUpdates); this.userSettingService.SetUserSetting(UserSettingConstants.DaysBetweenUpdateCheck, this.CheckForUpdatesFrequency); this.userSettingService.SetUserSetting(UserSettingConstants.SendFileTo, this.SendFileToPath); this.userSettingService.SetUserSetting(UserSettingConstants.SendFile, this.SendFileAfterEncode); this.userSettingService.SetUserSetting(UserSettingConstants.SendFileToArgs, this.Arguments); this.userSettingService.SetUserSetting(UserSettingConstants.ShowStatusInTitleBar, this.ShowStatusInTitleBar); this.userSettingService.SetUserSetting(UserSettingConstants.ShowPreviewOnSummaryTab, this.ShowPreviewOnSummaryTab); this.userSettingService.SetUserSetting(UserSettingConstants.UseDarkTheme, this.UseDarkTheme); this.userSettingService.SetUserSetting(UserSettingConstants.UiLanguage, this.SelectedLanguage?.Culture); this.userSettingService.SetUserSetting(UserSettingConstants.ShowAddAllToQueue, this.ShowAddAllToQueue); this.userSettingService.SetUserSetting(UserSettingConstants.ShowAddSelectionToQueue, this.ShowAddSelectionToQueue); /* When Done */ this.userSettingService.SetUserSetting(UserSettingConstants.WhenCompleteAction, (int)this.WhenDone); this.userSettingService.SetUserSetting(UserSettingConstants.ResetWhenDoneAction, this.ResetWhenDoneAction); this.userSettingService.SetUserSetting(UserSettingConstants.WhenDonePerformActionImmediately, this.WhenDonePerformActionImmediately); this.userSettingService.SetUserSetting(UserSettingConstants.PlaySoundWhenDone, this.PlaySoundWhenDone); this.userSettingService.SetUserSetting(UserSettingConstants.PlaySoundWhenQueueDone, this.PlaySoundWhenQueueDone); this.userSettingService.SetUserSetting(UserSettingConstants.WhenDoneAudioFile, this.WhenDoneAudioFileFullPath); /* Output Files */ this.userSettingService.SetUserSetting(UserSettingConstants.AutoNaming, this.AutomaticallyNameFiles); this.userSettingService.SetUserSetting(UserSettingConstants.AutoNameFormat, this.AutonameFormat); this.userSettingService.SetUserSetting(UserSettingConstants.AutoNamePath, this.AutoNameDefaultPath); this.userSettingService.SetUserSetting(UserSettingConstants.UseM4v, (int)this.SelectedMp4Extension); this.userSettingService.SetUserSetting(UserSettingConstants.AutoNameRemoveUnderscore, this.RemoveUnderscores); this.userSettingService.SetUserSetting(UserSettingConstants.AutoNameTitleCase, this.ChangeToTitleCase); this.userSettingService.SetUserSetting(UserSettingConstants.RemovePunctuation, this.RemovePunctuation); this.userSettingService.SetUserSetting(UserSettingConstants.FileOverwriteBehaviour, this.SelectedOverwriteBehaviour); this.userSettingService.SetUserSetting(UserSettingConstants.AutonameFileCollisionBehaviour, this.SelectedCollisionBehaviour); this.userSettingService.SetUserSetting(UserSettingConstants.AutonameFilePrePostString, this.PrePostFilenameText); this.userSettingService.SetUserSetting(UserSettingConstants.AlwaysUseDefaultPath, this.AlwaysUseDefaultPath); /* Previews */ this.userSettingService.SetUserSetting(UserSettingConstants.VLCPath, this.VLCPath); /* Video */ this.userSettingService.SetUserSetting(UserSettingConstants.EnableQuickSyncDecoding, this.EnableQuickSyncDecoding); this.userSettingService.SetUserSetting(UserSettingConstants.ScalingMode, this.SelectedScalingMode); this.userSettingService.SetUserSetting(UserSettingConstants.UseQSVDecodeForNonQSVEnc, this.UseQSVDecodeForNonQSVEnc); this.userSettingService.SetUserSetting(UserSettingConstants.EnableQuickSyncEncoding, this.EnableQuickSyncEncoding); this.userSettingService.SetUserSetting(UserSettingConstants.EnableVceEncoder, this.EnableVceEncoder); this.userSettingService.SetUserSetting(UserSettingConstants.EnableNvencEncoder, this.EnableNvencEncoder); /* System and Logging */ this.userSettingService.SetUserSetting(UserSettingConstants.ProcessPriorityInt, this.SelectedPriority); this.userSettingService.SetUserSetting(UserSettingConstants.PreventSleep, this.PreventSleep); this.userSettingService.SetUserSetting(UserSettingConstants.PauseOnLowDiskspace, this.PauseOnLowDiskspace); this.userSettingService.SetUserSetting(UserSettingConstants.PauseQueueOnLowDiskspaceLevel, this.PauseOnLowDiskspaceLevel); this.userSettingService.SetUserSetting(UserSettingConstants.Verbosity, this.SelectedVerbosity); this.userSettingService.SetUserSetting(UserSettingConstants.SaveLogWithVideo, this.CopyLogToEncodeDirectory); this.userSettingService.SetUserSetting(UserSettingConstants.SaveLogToCopyDirectory, this.CopyLogToSepcficedLocation); this.userSettingService.SetUserSetting(UserSettingConstants.SaveLogCopyDirectory, this.LogDirectory); this.userSettingService.SetUserSetting(UserSettingConstants.ClearOldLogs, this.ClearOldOlgs); /* Advanced */ this.userSettingService.SetUserSetting(UserSettingConstants.MainWindowMinimize, this.MinimiseToTray); this.userSettingService.SetUserSetting(UserSettingConstants.ClearCompletedFromQueue, this.ClearQueueOnEncodeCompleted); this.userSettingService.SetUserSetting(UserSettingConstants.PreviewScanCount, this.SelectedPreviewCount); this.userSettingService.SetUserSetting(UserSettingConstants.X264Step, double.Parse(this.SelectedGranulairty, CultureInfo.InvariantCulture)); int value; if (int.TryParse(this.MinLength.ToString(CultureInfo.InvariantCulture), out value)) { this.userSettingService.SetUserSetting(UserSettingConstants.MinScanDuration, value); } this.userSettingService.SetUserSetting(UserSettingConstants.DisableLibDvdNav, this.DisableLibdvdNav); /* Experimental */ this.userSettingService.SetUserSetting(UserSettingConstants.RemoteServiceEnabled, this.RemoteServiceEnabled); this.userSettingService.SetUserSetting(UserSettingConstants.RemoteServicePort, this.RemoteServicePort); } /// /// Update Check Complete /// /// /// The info. /// private void UpdateCheckComplete(UpdateCheckInformation info) { this.updateInfo = info; if (info.NewVersionAvailable) { this.UpdateMessage = Resources.OptionsViewModel_NewUpdate; this.UpdateAvailable = true; } else if (Environment.Is64BitOperatingSystem && !System.Environment.Is64BitProcess) { this.UpdateMessage = Resources.OptionsViewModel_64bitAvailable; this.UpdateAvailable = true; } else { this.UpdateMessage = Resources.OptionsViewModel_NoNewUpdates; this.UpdateAvailable = false; } } /// /// Download Progress Action /// /// /// The info. /// private void DownloadProgress(DownloadStatus info) { if (info.TotalBytes == 0 || info.BytesRead == 0) { this.UpdateAvailable = false; this.UpdateMessage = info.WasSuccessful ? Resources.OptionsViewModel_UpdateDownloaded : Resources.OptionsViewModel_UpdateServiceUnavailable; return; } long p = (info.BytesRead * 100) / info.TotalBytes; int progress; int.TryParse(p.ToString(CultureInfo.InvariantCulture), out progress); this.DownloadProgressPercentage = progress; this.UpdateMessage = string.Format( "{0} {1}% - {2}k of {3}k", Resources.OptionsView_Downloading, this.DownloadProgressPercentage, (info.BytesRead / 1024), (info.TotalBytes / 1024)); } /// /// Download Complete Action /// /// /// The info. /// private void DownloadComplete(DownloadStatus info) { this.UpdateAvailable = false; this.UpdateMessage = info.WasSuccessful ? Resources.OptionsViewModel_UpdateDownloaded : info.Message; if (info.WasSuccessful) { Process.Start(Path.Combine(Path.GetTempPath(), "handbrake-setup.exe")); Execute.OnUIThread(() => Application.Current.Shutdown()); } } /// /// Validate the Autoname Fileformat string /// /// The format string /// Don't show an error dialog if true. /// True if valid private bool IsValidAutonameFormat(string input, bool isSilent) { if (string.IsNullOrEmpty(input)) { return true; } char[] invalidchars = Path.GetInvalidFileNameChars(); Array.Sort(invalidchars); foreach (var characterToTest in input) { if (Array.BinarySearch(invalidchars, characterToTest) >= 0) { if (!isSilent) { this.errorService.ShowMessageBox( Resources.OptionsView_InvalidFileFormatChars, Resources.Error, MessageBoxButton.OK, MessageBoxImage.Error); } return false; } } return true; } } }