Skip to content

Commit c01d483

Browse files
authored
Added Install Font button when selecting a font file (#7846)
1 parent db0a50e commit c01d483

File tree

11 files changed

+137
-20
lines changed

11 files changed

+137
-20
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.IO.Pipes;
5+
using System.Threading.Tasks;
6+
using System.Linq;
7+
using Files.Common;
8+
9+
namespace FilesFullTrust.MessageHandlers
10+
{
11+
public class InstallOperationsHandler : IMessageHandler
12+
{
13+
public void Initialize(PipeStream connection)
14+
{
15+
}
16+
17+
public async Task ParseArgumentsAsync(PipeStream connection, Dictionary<string, object> message, string arguments)
18+
{
19+
switch (arguments)
20+
{
21+
case "InstallOperation":
22+
await ParseInstallOperationAsync(connection, message);
23+
break;
24+
}
25+
}
26+
27+
private async Task ParseInstallOperationAsync(PipeStream connection, Dictionary<string, object> message)
28+
{
29+
switch (message.Get("installop", ""))
30+
{
31+
case "InstallFont":
32+
{
33+
var filePath = (string)message["filepath"];
34+
var fileExtension = (string)message["extension"];
35+
var isFont = new[] { ".fon", ".otf", ".ttc", ".ttf" }.Contains(fileExtension, StringComparer.OrdinalIgnoreCase);
36+
37+
if (isFont)
38+
{
39+
var userFontDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Microsoft", "Windows", "Fonts");
40+
var destName = Path.Combine(userFontDir, Path.GetFileName(filePath));
41+
Win32API.RunPowershellCommand($"-command \"Copy-Item '{filePath}' '{userFontDir}'; New-ItemProperty -Name '{Path.GetFileNameWithoutExtension(filePath)}' -Path 'HKCU:\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts' -PropertyType string -Value '{destName}'\"", false);
42+
}
43+
break;
44+
}
45+
}
46+
}
47+
48+
public void Dispose()
49+
{
50+
}
51+
}
52+
}

src/Files.Launcher/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ private static async Task Main(string[] args)
4848
messageHandlers.Add(new ContextMenuHandler());
4949
messageHandlers.Add(new QuickLookHandler());
5050
messageHandlers.Add(new Win32MessageHandler());
51+
messageHandlers.Add(new InstallOperationsHandler());
5152

5253
// Connect to app service and wait until the connection gets closed
5354
appServiceExit = new ManualResetEvent(false);

src/Files/Helpers/FileExtensionHelpers.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ public static bool IsImageFile(string fileExtensionToCheck)
1717
return false;
1818
}
1919

20-
return fileExtensionToCheck.Equals(".png", StringComparison.OrdinalIgnoreCase) ||
21-
fileExtensionToCheck.Equals(".jpg", StringComparison.OrdinalIgnoreCase) ||
22-
fileExtensionToCheck.Equals(".bmp", StringComparison.OrdinalIgnoreCase) ||
20+
return fileExtensionToCheck.Equals(".png", StringComparison.OrdinalIgnoreCase) ||
21+
fileExtensionToCheck.Equals(".jpg", StringComparison.OrdinalIgnoreCase) ||
22+
fileExtensionToCheck.Equals(".bmp", StringComparison.OrdinalIgnoreCase) ||
2323
fileExtensionToCheck.Equals(".jpeg", StringComparison.OrdinalIgnoreCase);
2424
}
2525

@@ -56,5 +56,25 @@ public static bool IsZipFile(string fileExtensionToCheck)
5656
fileExtensionToCheck.Equals(".msix", StringComparison.OrdinalIgnoreCase) ||
5757
fileExtensionToCheck.Equals(".msixbundle", StringComparison.OrdinalIgnoreCase);
5858
}
59+
60+
/// <summary>
61+
/// Check if the file extension is a font file.
62+
/// </summary>
63+
/// <param name="fileExtensionToCheck">The file extension to check.</param>
64+
/// <returns><c>true</c> if the fileExtensionToCheck is a font file;
65+
/// otherwise <c>false</c>.</returns>
66+
/// <remarks>Font file types are; fon, otf, ttc, ttf</remarks>
67+
public static bool IsFontFile(string fileExtensionToCheck)
68+
{
69+
if (string.IsNullOrEmpty(fileExtensionToCheck))
70+
{
71+
return false;
72+
}
73+
74+
return fileExtensionToCheck.Equals(".fon", StringComparison.OrdinalIgnoreCase) ||
75+
fileExtensionToCheck.Equals(".otf", StringComparison.OrdinalIgnoreCase) ||
76+
fileExtensionToCheck.Equals(".ttc", StringComparison.OrdinalIgnoreCase) ||
77+
fileExtensionToCheck.Equals(".ttf", StringComparison.OrdinalIgnoreCase);
78+
}
5979
}
6080
}

src/Files/Interacts/BaseLayoutCommandImplementationModel.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,25 @@ public async void DecompressArchiveToChildFolder()
786786
}
787787
}
788788

789+
public async void InstallFont()
790+
{
791+
foreach (ListedItem selectedItem in SlimContentPage.SelectedItems)
792+
{
793+
var connection = await AppServiceConnectionHelper.Instance;
794+
if (connection != null)
795+
{
796+
var value = new ValueSet
797+
{
798+
{ "Arguments", "InstallOperation" },
799+
{ "installop", "InstallFont" },
800+
{ "filepath", selectedItem.ItemPath },
801+
{ "extension", selectedItem.FileExtension },
802+
};
803+
await connection.SendMessageAsync(value);
804+
}
805+
}
806+
}
807+
789808
#endregion Command Implementation
790809
}
791810
}

src/Files/Interacts/BaseLayoutCommandsViewModel.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ private void InitializeCommands()
7272
DecompressArchiveCommand = new RelayCommand(CommandsModel.DecompressArchive);
7373
DecompressArchiveHereCommand = new RelayCommand(CommandsModel.DecompressArchiveHere);
7474
DecompressArchiveToChildFolderCommand = new RelayCommand(CommandsModel.DecompressArchiveToChildFolder);
75+
InstallFontCommand = new RelayCommand(CommandsModel.InstallFont);
7576
}
7677

7778
#endregion Command Initialization
@@ -168,6 +169,8 @@ private void InitializeCommands()
168169

169170
public ICommand DecompressArchiveToChildFolderCommand { get; private set; }
170171

172+
public ICommand InstallFontCommand { get; private set; }
173+
171174
#endregion Commands
172175

173176
#region IDisposable

src/Files/Interacts/IBaseLayoutCommandImplementationModel.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,5 +97,7 @@ public interface IBaseLayoutCommandImplementationModel : IDisposable
9797
void DecompressArchiveHere();
9898

9999
void DecompressArchiveToChildFolder();
100+
101+
void InstallFont();
100102
}
101103
}

src/Files/Strings/en-US/Resources.resw

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2729,4 +2729,7 @@ We use App Center to track which settings are being used, find bugs, and fix cra
27292729
<data name="ShowFolderSizesWarning" xml:space="preserve">
27302730
<value>Calculating folder sizes is resource intensive and may cause your CPU usage to increase.</value>
27312731
</data>
2732-
</root>
2732+
<data name="Install" xml:space="preserve">
2733+
<value>Install</value>
2734+
</data>
2735+
</root>

src/Files/UserControls/InnerNavigationToolbar.xaml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@
200200
<local:ColoredIcon BaseLayerGlyph="&#xF031;" OverlayLayerGlyph="&#xF032;" />
201201
</AppBarButton.Content>
202202
</AppBarButton>
203-
<AppBarSeparator x:Name="AdditionalActionSeparator" x:Load="{x:Bind ViewModel.HasAdditionnalAction, Mode=OneWay}" />
203+
<AppBarSeparator x:Name="AdditionalActionSeparator" x:Load="{x:Bind ViewModel.HasAdditionalAction, Mode=OneWay}" />
204204
<AppBarButton
205205
x:Name="EmptyRecycleBinButton"
206206
AccessKey="B"
@@ -226,8 +226,7 @@
226226
<FontIcon FontFamily="{StaticResource CustomGlyph}" Glyph="&#xF11A;" />
227227
</AppBarButton.Content>
228228
<AppBarButton.Flyout>
229-
<MenuFlyout Placement="Bottom"
230-
helpers:MenuFlyoutHelper.IsVisible="{x:Bind ViewModel.CanExtract, Mode=OneWay}">
229+
<MenuFlyout helpers:MenuFlyoutHelper.IsVisible="{x:Bind ViewModel.CanExtract, Mode=OneWay}" Placement="Bottom">
231230
<MenuFlyoutItem
232231
Command="{x:Bind ViewModel.ExtractCommand, Mode=OneWay}"
233232
IsEnabled="{x:Bind ViewModel.CanExtract, Mode=OneWay, FallbackValue=False}"
@@ -285,6 +284,17 @@
285284
<FontIcon Glyph="&#xE91B;" />
286285
</AppBarButton.Icon>
287286
</AppBarButton>
287+
<AppBarButton
288+
x:Name="InstallFontButton"
289+
x:Load="{x:Bind ViewModel.IsFont, Mode=OneWay, FallbackValue=False}"
290+
Command="{x:Bind ViewModel.InstallFontCommand, Mode=OneWay}"
291+
Label="{helpers:ResourceString Name=Install}"
292+
LabelPosition="Default"
293+
ToolTipService.ToolTip="{helpers:ResourceString Name=Install}">
294+
<AppBarButton.Icon>
295+
<FontIcon Glyph="&#xE185;" />
296+
</AppBarButton.Icon>
297+
</AppBarButton>
288298
</CommandBar.PrimaryCommands>
289299
</CommandBar>
290300
<CommandBar

src/Files/ViewModels/NavToolbarViewModel.cs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ public void SwitchSearchBoxVisibility()
679679

680680
public void UpdateAdditionnalActions()
681681
{
682-
OnPropertyChanged(nameof(HasAdditionnalAction));
682+
OnPropertyChanged(nameof(HasAdditionalAction));
683683
OnPropertyChanged(nameof(CanEmptyRecycleBin));
684684
}
685685

@@ -795,7 +795,7 @@ public void SearchRegion_LostFocus(object sender, RoutedEventArgs e)
795795
public ICommand CutCommand { get; set; }
796796

797797
public ICommand EmptyRecycleBinCommand { get; set; }
798-
798+
799799
public ICommand PropertiesCommand { get; set; }
800800

801801
public ICommand ExtractCommand { get; set; }
@@ -808,6 +808,8 @@ public void SearchRegion_LostFocus(object sender, RoutedEventArgs e)
808808

809809
public ICommand SetAsBackgroundCommand { get; set; }
810810

811+
public ICommand InstallFontCommand { get; set; }
812+
811813
public async Task SetPathBoxDropDownFlyoutAsync(MenuFlyout flyout, PathBoxItem pathItem, IShellPage shellPage)
812814
{
813815
var nextPathItemTitle = PathComponents[PathComponents.IndexOf(pathItem) + 1].Title;
@@ -1109,7 +1111,6 @@ public bool HasItem
11091111
OnPropertyChanged(nameof(CanEmptyRecycleBin));
11101112
}
11111113
}
1112-
11131114
}
11141115

11151116
private List<ListedItem> selectedItems;
@@ -1124,27 +1125,29 @@ public List<ListedItem> SelectedItems
11241125
OnPropertyChanged(nameof(CanCopy));
11251126
OnPropertyChanged(nameof(CanShare));
11261127
OnPropertyChanged(nameof(CanRename));
1127-
OnPropertyChanged(nameof(IsPowerShellScript));
11281128
OnPropertyChanged(nameof(CanViewProperties));
1129-
OnPropertyChanged(nameof(IsImage));
11301129
OnPropertyChanged(nameof(CanExtract));
11311130
OnPropertyChanged(nameof(ExtractToText));
1132-
OnPropertyChanged(nameof(HasAdditionnalAction));
1131+
OnPropertyChanged(nameof(IsPowerShellScript));
1132+
OnPropertyChanged(nameof(IsImage));
1133+
OnPropertyChanged(nameof(IsFont));
1134+
OnPropertyChanged(nameof(HasAdditionalAction));
11331135
}
11341136
}
11351137
}
11361138

1137-
public bool HasAdditionnalAction => InstanceViewModel.IsPageTypeRecycleBin || IsPowerShellScript || CanExtract || IsImage;
1138-
1139+
public bool HasAdditionalAction => InstanceViewModel.IsPageTypeRecycleBin || IsPowerShellScript || CanExtract || IsImage || IsFont;
1140+
11391141
public bool CanCopy => SelectedItems is not null && SelectedItems.Any();
11401142
public bool CanShare => SelectedItems is not null && SelectedItems.Any() && DataTransferManager.IsSupported() && !SelectedItems.Any(x => (x.IsShortcutItem && !x.IsLinkItem) || x.IsHiddenItem || (x.PrimaryItemAttribute == StorageItemTypes.Folder && !x.IsZipItem));
11411143
public bool CanRename => SelectedItems is not null && SelectedItems.Count == 1;
11421144
public bool CanViewProperties => SelectedItems is not null && SelectedItems.Any();
11431145
public bool CanEmptyRecycleBin => InstanceViewModel.IsPageTypeRecycleBin && HasItem;
1144-
public bool CanExtract => SelectedItems is not null && SelectedItems.Any() && FileExtensionHelpers.IsZipFile(SelectedItems.First().FileExtension);
1145-
public string ExtractToText => SelectedItems is not null && SelectedItems.Any() ? string.Format("ExtractToChildFolder".GetLocalized() + "\\", Path.GetFileNameWithoutExtension(selectedItems.First().ItemName)) : "ExtractToChildFolder".GetLocalized();
1146-
public bool IsPowerShellScript => SelectedItems is not null && SelectedItems.Any() && FileExtensionHelpers.IsPowerShellFile(SelectedItems.First().FileExtension);
1147-
public bool IsImage => SelectedItems is not null && SelectedItems.Any() && FileExtensionHelpers.IsImageFile(SelectedItems.First().FileExtension);
1146+
public bool CanExtract => SelectedItems is not null && SelectedItems.Count == 1 && FileExtensionHelpers.IsZipFile(SelectedItems.First().FileExtension);
1147+
public string ExtractToText => SelectedItems is not null && SelectedItems.Count == 1 ? string.Format("ExtractToChildFolder".GetLocalized() + "\\", Path.GetFileNameWithoutExtension(selectedItems.First().ItemName)) : "ExtractToChildFolder".GetLocalized();
1148+
public bool IsPowerShellScript => SelectedItems is not null && SelectedItems.Count == 1 && FileExtensionHelpers.IsPowerShellFile(SelectedItems.First().FileExtension);
1149+
public bool IsImage => SelectedItems is not null && SelectedItems.Count == 1 && FileExtensionHelpers.IsImageFile(SelectedItems.First().FileExtension);
1150+
public bool IsFont => SelectedItems is not null && SelectedItems.Any() && SelectedItems.All(x => FileExtensionHelpers.IsFontFile(x.FileExtension));
11481151

11491152
public void Dispose()
11501153
{

src/Files/Views/ColumnShellPage.xaml.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,13 @@ private void InitToolbarCommands()
219219
NavToolbarViewModel.DeleteCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.DeleteItemCommand.Execute(null));
220220
NavToolbarViewModel.CutCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.CutItemCommand.Execute(null));
221221
NavToolbarViewModel.EmptyRecycleBinCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.EmptyRecycleBinCommand.Execute(null));
222+
NavToolbarViewModel.RunWithPowerShellCommand = new RelayCommand(async () => await Win32Helpers.InvokeWin32ComponentAsync("powershell", this, PathNormalization.NormalizePath(SlimContentPage?.SelectedItem.ItemPath)));
222223
NavToolbarViewModel.PropertiesCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.ShowPropertiesCommand.Execute(null));
224+
NavToolbarViewModel.SetAsBackgroundCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.SetAsDesktopBackgroundItemCommand.Execute(null));
223225
NavToolbarViewModel.ExtractCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.DecompressArchiveCommand.Execute(null));
224226
NavToolbarViewModel.ExtractHereCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.DecompressArchiveHereCommand.Execute(null));
225227
NavToolbarViewModel.ExtractToCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.DecompressArchiveToChildFolderCommand.Execute(null));
228+
NavToolbarViewModel.InstallFontCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.InstallFontCommand.Execute(null));
226229
}
227230

228231
private void FolderSettings_LayoutPreferencesUpdateRequired(object sender, LayoutPreferenceEventArgs e)

0 commit comments

Comments
 (0)