--- /dev/null
+// --------------------------------------------------------------------------------------------------------------------\r
+// <copyright file="DriveMenu.cs" company="HandBrake Project (http://handbrake.fr)">\r
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.\r
+// </copyright>\r
+// <summary>\r
+// The drive menu.\r
+// </summary>\r
+// --------------------------------------------------------------------------------------------------------------------\r
+\r
+namespace HandBrakeWPF.AttachedProperties\r
+{\r
+ using System;\r
+ using System.Collections.Generic;\r
+ using System.Linq;\r
+ using System.Windows;\r
+ using System.Windows.Controls;\r
+ using System.Windows.Media.Imaging;\r
+\r
+ using HandBrake.ApplicationServices.Utilities;\r
+\r
+ using HandBrakeWPF.Commands;\r
+ using HandBrakeWPF.Model;\r
+ using HandBrakeWPF.ViewModels;\r
+\r
+ /// <summary>\r
+ /// The drive menu.\r
+ /// </summary>\r
+ public class DriveMenu\r
+ {\r
+ /// <summary>\r
+ /// The show available drives property.\r
+ /// </summary>\r
+ public static readonly DependencyProperty ShowAvailableDrivesProperty = DependencyProperty.RegisterAttached(\r
+ "ShowAvailableDrives",\r
+ typeof(Boolean),\r
+ typeof(DriveMenu),\r
+ new PropertyMetadata(false, OnShowAvailableDrivesChanged));\r
+\r
+ /// <summary>\r
+ /// The get show available drives.\r
+ /// </summary>\r
+ /// <param name="element">\r
+ /// The element.\r
+ /// </param>\r
+ /// <returns>\r
+ /// The <see cref="bool"/>.\r
+ /// </returns>\r
+ public static Boolean GetShowAvailableDrives(MenuItem element)\r
+ {\r
+ bool result;\r
+ return bool.TryParse(element.GetValue(ShowAvailableDrivesProperty).ToString(), out result) && result;\r
+ }\r
+\r
+ /// <summary>\r
+ /// The set show available drives.\r
+ /// </summary>\r
+ /// <param name="element">\r
+ /// The element.\r
+ /// </param>\r
+ /// <param name="value">\r
+ /// The value.\r
+ /// </param>\r
+ public static void SetShowAvailableDrives(MenuItem element, Boolean value)\r
+ {\r
+ element.SetValue(ShowAvailableDrivesProperty, value);\r
+ }\r
+\r
+ /// <summary>\r
+ /// The on show available drives changed.\r
+ /// </summary>\r
+ /// <param name="d">\r
+ /// The d.\r
+ /// </param>\r
+ /// <param name="e">\r
+ /// The e.\r
+ /// </param>\r
+ private static void OnShowAvailableDrivesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\r
+ {\r
+ Menu menu = d as Menu;\r
+ if (menu != null)\r
+ {\r
+ menu.PreviewMouseDown -= MenuMouseDown;\r
+ menu.PreviewMouseDown += MenuMouseDown;\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// The menu_ mouse down.\r
+ /// </summary>\r
+ /// <param name="sender">\r
+ /// The sender.\r
+ /// </param>\r
+ /// <param name="e">\r
+ /// The e.\r
+ /// </param>\r
+ private static void MenuMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)\r
+ {\r
+ Menu menu = sender as Menu;\r
+ if (menu != null)\r
+ {\r
+ MainViewModel mvm = menu.DataContext as MainViewModel;\r
+ if (mvm != null)\r
+ {\r
+ List<SourceMenuItem> remove = mvm.SourceMenu.Where(s => s.IsDrive).ToList();\r
+ foreach (var item in remove)\r
+ {\r
+ mvm.SourceMenu.Remove(item);\r
+ }\r
+\r
+ foreach (SourceMenuItem menuItem in from item in GeneralUtilities.GetDrives()\r
+ let driveInformation = item\r
+ select new SourceMenuItem\r
+ {\r
+ Image = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/HandBrake;component/Views/Images/disc_small.png")), Width = 16, Height = 16 },\r
+ Text = string.Format("{0} ({1})", item.RootDirectory, item.VolumeLabel),\r
+ Command = new SourceMenuCommand(() => mvm.ProcessDrive(driveInformation)),\r
+ Tag = item,\r
+ IsDrive = true\r
+ })\r
+ {\r
+ mvm.SourceMenu.Add(menuItem);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
<Generator>MSBuild:Compile</Generator>\r
<SubType>Designer</SubType>\r
</ApplicationDefinition>\r
+ <Compile Include="AttachedProperties\DriveMenu.cs" />\r
<Compile Include="AttachedProperties\MenuItemExtensions.cs" />\r
<Compile Include="Commands\CancelScanCommand.cs" />\r
<Compile Include="Commands\Interfaces\IAdvancedEncoderOptionsCommand.cs" />\r
<Compile Include="Helpers\GrowlCommunicator.cs" />\r
<Compile Include="Model\OptionsTab.cs" />\r
<Compile Include="Model\SelectionTitle.cs" />\r
- <Compile Include="Services\DriveDetectService.cs" />\r
<Compile Include="Services\EncodeServiceWrapper.cs" />\r
- <Compile Include="Services\Interfaces\IDriveDetectService.cs" />\r
<Compile Include="Model\ShellWindow.cs" />\r
<Compile Include="Model\SourceMenuItem.cs" />\r
<Compile Include="Model\UpdateCheckInformation.cs" />\r
/// </summary>\r
public ObservableCollection<SourceMenuItem> Children { get; set; }\r
\r
+ /// <summary>\r
+ /// Gets or sets a value indicating whether is drive.\r
+ /// </summary>\r
+ public bool IsDrive { get; set; }\r
+\r
/// <summary>\r
/// Gets or sets the tag.\r
/// </summary>\r
+++ /dev/null
-// --------------------------------------------------------------------------------------------------------------------\r
-// <copyright file="DriveDetectService.cs" company="HandBrake Project (http://handbrake.fr)">\r
-// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.\r
-// </copyright>\r
-// <summary>\r
-// Drive Detection Helper.\r
-// </summary>\r
-// --------------------------------------------------------------------------------------------------------------------\r
-\r
-namespace HandBrakeWPF.Services\r
-{\r
- using System;\r
- using System.Management;\r
- using System.Threading;\r
-\r
- using HandBrakeWPF.Services.Interfaces;\r
-\r
- /// <summary>\r
- /// Drive Detection Helper.\r
- /// </summary>\r
- public class DriveDetectService : IDriveDetectService\r
- {\r
- /// <summary>\r
- /// The watcher.\r
- /// </summary>\r
- private ManagementEventWatcher watcher;\r
-\r
- /// <summary>\r
- /// The detection action.\r
- /// </summary>\r
- private Action detectionAction;\r
-\r
- /// <summary>\r
- /// The start detection.\r
- /// </summary>\r
- /// <param name="action">\r
- /// The detection Action.\r
- /// </param>\r
- public void StartDetection(Action action)\r
- {\r
- ThreadPool.QueueUserWorkItem(\r
- delegate\r
- {\r
- this.detectionAction = action;\r
-\r
- var options = new ConnectionOptions { EnablePrivileges = true };\r
- var scope = new ManagementScope(@"root\CIMV2", options);\r
-\r
- try\r
- {\r
- var query = new WqlEventQuery\r
- {\r
- EventClassName = "__InstanceModificationEvent",\r
- WithinInterval = TimeSpan.FromSeconds(1),\r
- Condition = @"TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.DriveType = 5" // DriveType - 5: CDROM\r
- };\r
-\r
- this.watcher = new ManagementEventWatcher(scope, query);\r
- this.watcher.EventArrived += this.WatcherEventArrived;\r
- this.watcher.Start();\r
- }\r
- catch (Exception e)\r
- {\r
- Console.WriteLine(e.Message);\r
- }\r
- });\r
- }\r
-\r
- /// <summary>\r
- /// The close.\r
- /// </summary>\r
- public void Close()\r
- {\r
- if (watcher != null)\r
- {\r
- this.watcher.Stop();\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// The watcher_ event arrived.\r
- /// </summary>\r
- /// <param name="sender">\r
- /// The sender.\r
- /// </param>\r
- /// <param name="e">\r
- /// The EventArrivedEventArgs.\r
- /// </param>\r
- private void WatcherEventArrived(object sender, EventArrivedEventArgs e)\r
- {\r
- if (this.detectionAction != null)\r
- {\r
- this.detectionAction();\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-// --------------------------------------------------------------------------------------------------------------------\r
-// <copyright file="IDriveDetectService.cs" company="HandBrake Project (http://handbrake.fr)">\r
-// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.\r
-// </copyright>\r
-// <summary>\r
-// Defines the IDriveDetectService type.\r
-// </summary>\r
-// --------------------------------------------------------------------------------------------------------------------\r
-\r
-namespace HandBrakeWPF.Services.Interfaces\r
-{\r
- using System;\r
-\r
- /// <summary>\r
- /// The DriveDetectService interface.\r
- /// </summary>\r
- public interface IDriveDetectService\r
- {\r
- /// <summary>\r
- /// The start detection.\r
- /// </summary>\r
- /// <param name="action">\r
- /// The detection Action.\r
- /// </param>\r
- void StartDetection(Action action);\r
-\r
- /// <summary>\r
- /// Stop the watcher. Must be done before the app shuts down.\r
- /// </summary>\r
- void Close();\r
- }\r
-}
\ No newline at end of file
\r
// Services\r
this.windsorContainer.Register(Component.For<IUpdateService>().ImplementedBy<UpdateService>().LifeStyle.Is(LifestyleType.Singleton));\r
- this.windsorContainer.Register(Component.For<IDriveDetectService>().ImplementedBy<DriveDetectService>().LifeStyle.Is(LifestyleType.Singleton));\r
this.windsorContainer.Register(Component.For<IScanServiceWrapper>().ImplementedBy<ScanServiceWrapper>().LifeStyle.Is(LifestyleType.Singleton));\r
this.windsorContainer.Register(Component.For<IEncodeServiceWrapper>().ImplementedBy<EncodeServiceWrapper>().LifeStyle.Is(LifestyleType.Singleton));\r
this.windsorContainer.Register(Component.For<INotificationService>().ImplementedBy<NotificationService>().LifeStyle.Is(LifestyleType.Singleton));\r
{\r
using System;\r
using System.Collections.Generic;\r
+ using System.ComponentModel;\r
using System.Diagnostics;\r
using System.Globalization;\r
using System.IO;\r
/// </summary>\r
private readonly IUpdateService updateService;\r
\r
- /// <summary>\r
- /// The drive detect service.\r
- /// </summary>\r
- private readonly IDriveDetectService driveDetectService;\r
-\r
/// <summary>\r
/// Backing field for the user setting service.\r
/// </summary>\r
/// <summary>\r
/// The Source Menu Backing Field\r
/// </summary>\r
- private IEnumerable<SourceMenuItem> sourceMenu;\r
+ private BindingList<SourceMenuItem> sourceMenu;\r
\r
/// <summary>\r
/// The last percentage complete value.\r
/// <param name="updateService">\r
/// The update Service.\r
/// </param>\r
- /// <param name="driveDetectService">\r
- /// The drive Detect Service.\r
- /// </param>\r
/// <param name="notificationService">\r
/// The notification Service.\r
/// *** Leave in Constructor. *** \r
/// *** Leave in Constructor. *** \r
/// </param>\r
public MainViewModel(IUserSettingService userSettingService, IScanServiceWrapper scanService, IEncodeServiceWrapper encodeService, IPresetService presetService,\r
- IErrorService errorService, IShellViewModel shellViewModel, IUpdateService updateService, IDriveDetectService driveDetectService, INotificationService notificationService,\r
+ IErrorService errorService, IShellViewModel shellViewModel, IUpdateService updateService, INotificationService notificationService,\r
IPrePostActionService whenDoneService)\r
{\r
this.scanService = scanService;\r
this.errorService = errorService;\r
this.shellViewModel = shellViewModel;\r
this.updateService = updateService;\r
- this.driveDetectService = driveDetectService;\r
this.userSettingService = userSettingService;\r
this.queueProcessor = IoC.Get<IQueueProcessor>();\r
\r
/// <summary>\r
/// Gets or sets the source menu.\r
/// </summary>\r
- public IEnumerable<SourceMenuItem> SourceMenu\r
+ public BindingList<SourceMenuItem> SourceMenu\r
{\r
get\r
{\r
this.SelectedPreset = this.presetService.DefaultPreset;\r
\r
// Populate the Source menu with drives.\r
- this.SourceMenu = this.GenerateSourceMenu();\r
-\r
- this.driveDetectService.StartDetection(this.DriveTrayChanged);\r
+ this.SourceMenu = new BindingList<SourceMenuItem>(this.GenerateSourceMenu());\r
\r
// Log Cleaning\r
if (userSettingService.GetUserSetting<bool>(UserSettingConstants.ClearOldLogs))\r
public void Shutdown()\r
{\r
// Shutdown Service\r
- this.driveDetectService.Close();\r
-\r
this.scanService.Shutdown();\r
this.encodeService.Shutdown();\r
\r
/// <param name="item">\r
/// The item.\r
/// </param>\r
- private void ProcessDrive(object item)\r
+ public void ProcessDrive(object item)\r
{\r
if (item != null)\r
{\r
/// <returns>\r
/// The System.Collections.Generic.IEnumerable`1[T -> HandBrakeWPF.Model.SourceMenuItem].\r
/// </returns>\r
- private IEnumerable<SourceMenuItem> GenerateSourceMenu()\r
+ private IList<SourceMenuItem> GenerateSourceMenu()\r
{\r
List<SourceMenuItem> menuItems = new List<SourceMenuItem>();\r
\r
{\r
Image = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/HandBrake;component/Views/Images/folder.png")), Width = 16, Height = 16 },\r
Text = "Open Folder",\r
- Command = new SourceMenuCommand(this.FolderScan)\r
+ Command = new SourceMenuCommand(this.FolderScan),\r
+ IsDrive = false\r
};\r
SourceMenuItem fileScan = new SourceMenuItem\r
{\r
Image = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/HandBrake;component/Views/Images/Movies.png")), Width = 16, Height = 16 },\r
Text = "Open File",\r
- Command = new SourceMenuCommand(this.FileScan)\r
+ Command = new SourceMenuCommand(this.FileScan),\r
+ IsDrive = false\r
};\r
\r
SourceMenuItem titleSpecific = new SourceMenuItem { Text = "Title Specific Scan" };\r
{\r
Image = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/HandBrake;component/Views/Images/folder.png")), Width = 16, Height = 16 },\r
Text = "Open Folder",\r
- Command = new SourceMenuCommand(this.FolderScanTitleSpecific)\r
+ Command = new SourceMenuCommand(this.FolderScanTitleSpecific),\r
+ IsDrive = false\r
};\r
SourceMenuItem fileScanTitle = new SourceMenuItem\r
{\r
Image = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/HandBrake;component/Views/Images/Movies.png")), Width = 16, Height = 16 },\r
Text = "Open File",\r
- Command = new SourceMenuCommand(this.FileScanTitleSpecific)\r
+ Command = new SourceMenuCommand(this.FileScanTitleSpecific),\r
+ IsDrive = false\r
};\r
titleSpecific.Children.Add(folderScanTitle);\r
titleSpecific.Children.Add(fileScanTitle);\r
Image = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/HandBrake;component/Views/Images/disc_small.png")), Width = 16, Height = 16 },\r
Text = string.Format("{0} ({1})", item.RootDirectory, item.VolumeLabel),\r
Command = new SourceMenuCommand(() => this.ProcessDrive(driveInformation)),\r
- Tag = item\r
+ Tag = item,\r
+ IsDrive = true\r
});\r
\r
return menuItems;\r
}\r
\r
- /// <summary>\r
- /// The drive tray changed.\r
- /// </summary>\r
- private void DriveTrayChanged()\r
- {\r
- Caliburn.Micro.Execute.OnUIThread(() => this.SourceMenu = this.GenerateSourceMenu());\r
- }\r
-\r
/// <summary>\r
/// Allows the main window to respond to setting changes.\r
/// </summary>\r
xmlns:Converters="clr-namespace:HandBrakeWPF.Converters"\r
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"\r
xmlns:Micro="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro"\r
- AllowDrop="True"\r
+ xmlns:attachedProperties="clr-namespace:HandBrakeWPF.AttachedProperties"\r
+ AllowDrop="True"\r
Background="#FFF0F0F0"\r
FontSize="11"\r
Micro:Message.Attach="[Event Loaded] = [Action Load]"\r
ToolBar.OverflowMode="Never"\r
ToolBarTray.IsLocked="True"\r
>\r
- <Menu Background="Transparent">\r
+ <Menu Background="Transparent" attachedProperties:DriveMenu.ShowAvailableDrives="true">\r
<MenuItem ItemsSource="{Binding SourceMenu}">\r
<MenuItem.Header>\r
<StackPanel Orientation="Horizontal">\r