Skip to content

Commit

Permalink
Add Context Menu for add native new files
Browse files Browse the repository at this point in the history
  • Loading branch information
egorozh committed Nov 1, 2021
1 parent a21765a commit 1577bcd
Show file tree
Hide file tree
Showing 23 changed files with 511 additions and 102 deletions.
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<Platforms>x64</Platforms>

<Version>0.2.8</Version>
<Version>0.2.9</Version>

<Company>X-Filer</Company>
<Product>X-Filer</Product>
Expand Down
2 changes: 1 addition & 1 deletion src/Plugins/XFiler.Base/XFiler.Base.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<PackageReference Include="MahApps.Metro" Version="2.4.7" />
<PackageReference Include="MahApps.Metro" Version="2.4.9" />
<PackageReference Include="PropertyChanged.Fody" Version="3.4.0">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
11 changes: 1 addition & 10 deletions src/SDK/XFiler.SDK/Behaviors/RegistryContextMenuBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,7 @@ public static bool GetRootItem(DependencyObject element)
public static readonly DependencyProperty SelectedItemsContainerProperty = DependencyProperty.Register(
nameof(SelectedItemsContainer), typeof(ObjectReference), typeof(RegistryContextMenuBehavior),
new PropertyMetadata(default(ObjectReference)));

//private static void PropsChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
//{
// if (d is RegistryContextMenuBehavior behavior)
// {
// if (behavior.NativeContextMenuLoader != null && behavior.FileInfoModel != null)
// behavior.LoadNativeContextMenuItems(behavior.NativeContextMenuLoader, behavior.FileInfoModel);
// }
//}


#endregion

#region Public Properties
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ public INativeContextMenuLoader NativeContextMenuLoader
set => SetValue(NativeContextMenuLoaderProperty, value);
}

public IReadOnlyList<IAddNewContextMenuModel> AddItems => NativeContextMenuLoader.AddItems;

public ICommand InvokeCommand => NativeContextMenuLoader.InvokeCommand;
public ICommand InvokeAddNewItemsCommand => NativeContextMenuLoader.InvokeAddNewItemsCommand;

public void Init() => NativeContextMenuLoader?.Init();

public IReadOnlyList<IRegistryContextMenuModel> CreateMenuItems(IEnumerable<string> selectedItems)
{
Expand Down
12 changes: 12 additions & 0 deletions src/SDK/XFiler.SDK/Services/ContextMenu/IAddNewContextMenuModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Windows.Controls;

namespace XFiler.SDK;

public interface IAddNewContextMenuModel
{
string Extension { get; }
string Name { get; }
byte[]? Data { get; }
string? Template { get; }
Image? Icon { get; }
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
using System.Collections.Generic;
using System.Windows.Input;
using System.Windows.Media;

namespace XFiler.SDK;

public interface INativeContextMenuLoader
{
IReadOnlyList<IAddNewContextMenuModel> AddItems { get; }
ICommand InvokeCommand { get; }
ICommand InvokeAddNewItemsCommand { get; }

IReadOnlyList<IRegistryContextMenuModel> CreateMenuItems(IEnumerable<string> selectedItems);
}

public interface IRegistryContextMenuModel
{
string Name { get; }
void Init();

ImageSource? Icon { get; }

IReadOnlyList<IRegistryContextMenuModel>? Children { get; }
IReadOnlyList<IRegistryContextMenuModel> CreateMenuItems(IEnumerable<string> selectedItems);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Collections.Generic;
using System.Windows.Media;

namespace XFiler.SDK;

public interface IRegistryContextMenuModel
{
string Name { get; }

ImageSource? Icon { get; }

IReadOnlyList<IRegistryContextMenuModel>? Children { get; }
}
23 changes: 12 additions & 11 deletions src/SDK/XFiler.SDK/Services/IDriveDetector.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
using System;

namespace XFiler.SDK
namespace XFiler.SDK;

public interface IDriveDetector
{
event Action<EventType, string> DriveChanged;

void Init();
}

public enum EventType
{
public interface IDriveDetector
{
event Action<EventType, string> DriveChanged;
}

public enum EventType
{
Added = 2,
Removed = 3
}
Added = 2,
Removed = 3
}
7 changes: 6 additions & 1 deletion src/SDK/XFiler.SDK/Services/IFileOperations.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

namespace XFiler.SDK;

Expand All @@ -19,4 +20,8 @@ void Delete(IReadOnlyList<FileSystemInfo> items, DirectoryInfo targetDirectory,
void CreateFolder(string targetFolder, string name = "Новая папка");

void CreateEmptyTextFile(string targetFolder, string name = "Новый текстовый документ");
}

Task<string> CreateFile(string targetFolder, string name, string extension);

Task<string> CreateFileFromTemplate(string targetFolder, string name, string extension, string template);
}
9 changes: 4 additions & 5 deletions src/SDK/XFiler.SDK/Services/ILaunchAtStartupService.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
namespace XFiler.SDK
namespace XFiler.SDK;

public interface ILaunchAtStartupService
{
public interface ILaunchAtStartupService
{
void Init();
}
void Init();
}
11 changes: 5 additions & 6 deletions src/SDK/XFiler.SDK/Services/IRestartService.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
namespace XFiler.SDK
namespace XFiler.SDK;

public interface IRestartService
{
public interface IRestartService
{
void RestartApplication();
void RestartApplication();

const string RestartKey = "/restart";
}
const string RestartKey = "/restart";
}
8 changes: 2 additions & 6 deletions src/SDK/XFiler.SDK/Services/IStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ public interface IStorage
string DbDirectory { get; }

string Bookmarks { get; }

string ContextMenuFolder { get; }

string ContextMenuTxtFile { get; }

string ContextMenuTxtFile2 { get; }

string ExtensionsDirectory { get; }
}
4 changes: 2 additions & 2 deletions src/SDK/XFiler.SDK/XFiler.SDK.csproj
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<PackageReference Include="Autofac" Version="6.2.0" />
<PackageReference Include="Autofac" Version="6.3.0" />
<PackageReference Include="DragablzF" Version="0.1.0.1" />
<PackageReference Include="gong-wpf-dragdrop" Version="2.4.2" />
<PackageReference Include="gong-wpf-dragdrop" Version="2.4.3" />
<PackageReference Include="PropertyChanged.Fody" Version="3.4.0">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<PackageReference Include="FluentWPF" Version="0.10.1" />
<PackageReference Include="MahApps.Metro" Version="2.4.7" />
<PackageReference Include="VirtualizingWrapPanel" Version="1.5.4" />
<PackageReference Include="FluentWPF" Version="0.10.2" />
<PackageReference Include="MahApps.Metro" Version="2.4.9" />
<PackageReference Include="VirtualizingWrapPanel" Version="1.5.5" />
<ProjectReference Include="..\..\SDK\XFiler.SDK\XFiler.SDK.csproj" />
</ItemGroup>

Expand Down
26 changes: 6 additions & 20 deletions src/XFiler/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using System.IO;
using System.Text;
using Autofac;
using Autofac;
using Hardcodet.Wpf.TaskbarNotification;
using SingleInstanceHelper;
using System.Text;
using XFiler.TrayIcon;

namespace XFiler;
Expand Down Expand Up @@ -35,9 +34,9 @@ protected override void OnStartup(StartupEventArgs e)
Host.Resolve<ILanguageService>().Init();
Host.Resolve<IThemeService>().Init();
Host.Resolve<ILaunchAtStartupService>().Init();

Host.Resolve<IDriveDetector>().DriveChanged += OnDriveChanged;

Host.Resolve<INativeContextMenuLoader>().Init();
Host.Resolve<IDriveDetector>().Init();
LoadNotifyIconResourceDictionary();

_trayIcon = FindResource("TrayIcon") as TaskbarIcon
Expand Down Expand Up @@ -99,20 +98,7 @@ private void LoadNotifyIconResourceDictionary()
is ResourceDictionary resourceDict)
resources.Add(resourceDict);
}

private void OnDriveChanged(EventType type, string driveName)
{
if (type == EventType.Added)
{
DirectoryInfo info = new(driveName);

var tab = Host.Resolve<Func<ITabFactory>>().Invoke().CreateExplorerTab(info);

if (tab != null)
Host.Resolve<IWindowFactory>().OpenTabInNewWindow(tab);
}
}


private void ShowArgs(IEnumerable<string> args)
{
StringBuilder sb = new();
Expand Down
116 changes: 116 additions & 0 deletions src/XFiler/Behaviors/AddNewContextMenuBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
using System.Windows.Controls;
using Microsoft.Xaml.Behaviors;

namespace XFiler;

internal sealed class AddNewContextMenuBehavior : Behavior<MenuItem>
{
#region Attached Properties

public static readonly DependencyProperty RootItemProperty = DependencyProperty.RegisterAttached(
"RootItem", typeof(bool), typeof(AddNewContextMenuBehavior),
new PropertyMetadata(false));

public static void SetRootItem(DependencyObject element, bool value)
=> element.SetValue(RootItemProperty, value);

public static bool GetRootItem(DependencyObject element)
=> (bool) element.GetValue(RootItemProperty);

#endregion

#region Dependency Properties

public static readonly DependencyProperty NativeContextMenuLoaderProperty = DependencyProperty.Register(
nameof(NativeContextMenuLoader), typeof(INativeContextMenuLoader),
typeof(AddNewContextMenuBehavior),
new PropertyMetadata(default(INativeContextMenuLoader)));

public static readonly DependencyProperty FileInfoModelProperty = DependencyProperty.Register(
nameof(FileInfoModel), typeof(IFileSystemModel),
typeof(AddNewContextMenuBehavior),
new PropertyMetadata(default(IFileSystemModel)));

#endregion

#region Public Properties

public INativeContextMenuLoader? NativeContextMenuLoader
{
get => (INativeContextMenuLoader) GetValue(NativeContextMenuLoaderProperty);
set => SetValue(NativeContextMenuLoaderProperty, value);
}

public IFileSystemModel? FileInfoModel
{
get => (IFileSystemModel) GetValue(FileInfoModelProperty);
set => SetValue(FileInfoModelProperty, value);
}

#endregion

protected override void OnAttached()
{
base.OnAttached();

AssociatedObject.Loaded += AssociatedObjectOnLoaded;
}

private void AssociatedObjectOnLoaded(object sender, RoutedEventArgs e)
{
AssociatedObject.Loaded -= AssociatedObjectOnLoaded;

if (NativeContextMenuLoader != null && FileInfoModel != null)
LoadNativeContextMenuItems(NativeContextMenuLoader, FileInfoModel);
}

#region Private Methods

private void LoadNativeContextMenuItems(INativeContextMenuLoader loader, IFileSystemModel parentInfo)
{
ClearOldItems();

var rootItem = AssociatedObject.Items.OfType<DependencyObject>()
.FirstOrDefault(GetRootItem);

var index = AssociatedObject.Items.Count;

if (rootItem != null)
index = AssociatedObject.Items.IndexOf(rootItem) + 1;

var models = loader.AddItems;

foreach (var model in models)
AssociatedObject.Items.Insert(index++, CreateRegistryMenuItem(loader, model, parentInfo));
}

private void ClearOldItems()
{
if (AssociatedObject.Items is { } items)
{
var oldItems = items.OfType<MenuItem>()
.Where(i => i.DataContext is IAddNewContextMenuModel)
.ToList();

foreach (var oldItem in oldItems)
AssociatedObject.Items.Remove(oldItem);
}
}

private static MenuItem CreateRegistryMenuItem(INativeContextMenuLoader loader, IAddNewContextMenuModel model,
IFileSystemModel parentModel)
{
MenuItem item = new()
{
Header = model.Name,
DataContext = model,
Command = loader.InvokeAddNewItemsCommand,
CommandParameter = new Tuple<IAddNewContextMenuModel, IFileSystemModel>(model, parentModel),
Icon = model.Icon,
};

return item;
}

#endregion
}
Loading

0 comments on commit 1577bcd

Please sign in to comment.