Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Show the "send to" option in the main menu #11329

Merged
merged 11 commits into from
Feb 17, 2023
23 changes: 21 additions & 2 deletions src/Files.App/BaseLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -713,11 +713,12 @@ private void AddNewFileTagsToMenu(CommandBarFlyout contextMenu)
private void AddShellItemsToMenu(List<ContextMenuFlyoutItemViewModel> shellMenuItems, CommandBarFlyout contextMenuFlyout, bool shiftPressed)
{
var openWithSubItems = ItemModelListToContextFlyoutHelper.GetMenuFlyoutItemsFromModel(ShellContextmenuHelper.GetOpenWithItems(shellMenuItems));
var sendToSubItems = ItemModelListToContextFlyoutHelper.GetMenuFlyoutItemsFromModel(ShellContextmenuHelper.GetSendToItems(shellMenuItems));
var mainShellMenuItems = shellMenuItems.RemoveFrom(!UserSettingsService.PreferencesSettingsService.MoveShellExtensionsToSubMenu ? int.MaxValue : shiftPressed ? 6 : 0);
var overflowShellMenuItemsUnfiltered = shellMenuItems.Except(mainShellMenuItems).ToList();
var overflowShellMenuItems = overflowShellMenuItemsUnfiltered.Where(
(x, i) => (x.ItemType == ItemType.Separator &&
overflowShellMenuItemsUnfiltered[i + 1 < overflowShellMenuItemsUnfiltered.Count ? i + 1 : i].ItemType == ItemType.Separator)
(x, i) => (x.ItemType == ItemType.Separator &&
overflowShellMenuItemsUnfiltered[i + 1 < overflowShellMenuItemsUnfiltered.Count ? i + 1 : i].ItemType != ItemType.Separator)
|| x.ItemType != ItemType.Separator).ToList();

var overflowItems = ItemModelListToContextFlyoutHelper.GetMenuFlyoutItemsFromModel(overflowShellMenuItems);
Expand Down Expand Up @@ -800,6 +801,24 @@ private void AddShellItemsToMenu(List<ContextMenuFlyoutItemViewModel> shellMenuI
openWithOverflow.Visibility = Visibility.Visible;
}

// Add items to sendto dropdown
var sendToOverflow = contextMenuFlyout.SecondaryCommands.FirstOrDefault(x => x is AppBarButton abb && (abb.Tag as string) == "SendToOverflow") as AppBarButton;

var sendTo = contextMenuFlyout.SecondaryCommands.FirstOrDefault(x => x is AppBarButton abb && (abb.Tag as string) == "SendTo") as AppBarButton;
if (sendToSubItems is not null && sendToOverflow is not null)
{
var flyout = (MenuFlyout)sendToOverflow.Flyout;

flyout.Items.Clear();

foreach (var item in sendToSubItems)
flyout.Items.Add(item);

sendToOverflow.Flyout = flyout;
sendTo.Visibility = Visibility.Collapsed;
sendToOverflow.Visibility = Visibility.Visible;
}

if (itemsControl is not null)
{
itemsControl.Items.OfType<FrameworkElement>().ForEach(item =>
Expand Down
24 changes: 24 additions & 0 deletions src/Files.App/Helpers/ContextFlyoutItemHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,30 @@ public static List<ContextMenuFlyoutItemViewModel> GetBaseItemMenuItems(BaseLayo
},
},
new ContextMenuFlyoutItemViewModel()
{
Text = "SendTo".GetLocalizedResource(),
Tag = "SendTo",
CollapseLabel = true,
ShowInSearchPage = true,
ShowItem = true
},
new ContextMenuFlyoutItemViewModel()
{
Text = "SendTo".GetLocalizedResource(),
Tag = "SendToOverflow",
IsHidden = true,
CollapseLabel = true,
Items = new List<ContextMenuFlyoutItemViewModel>() {
new()
{
Text = "Placeholder",
ShowInSearchPage = true,
}
},
ShowInSearchPage = true,
ShowItem = true
},
new ContextMenuFlyoutItemViewModel()
{
ItemType = ItemType.Separator,
Tag = "OverflowSeparator",
Expand Down
41 changes: 36 additions & 5 deletions src/Files.App/Helpers/ShellContextMenuHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using Microsoft.UI.Xaml.Media.Imaging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
Expand Down Expand Up @@ -138,6 +139,9 @@ public static void LoadMenuFlyoutItem(IList<ContextMenuFlyoutItemViewModel> menu
}
else if (!string.IsNullOrEmpty(menuFlyoutItem.Label) && menuFlyoutItem.SubItems.Where(x => x.Type != MenuItemType.MFT_SEPARATOR).Any())
{
if (string.Equals(menuFlyoutItem.Label, Win32API.ExtractStringFromDLL("shell32.dll", 30312)))
menuFlyoutItem.CommandString = "sendto";

var menuLayoutSubItem = new ContextMenuFlyoutItemViewModel()
{
Text = menuFlyoutItem.Label.Replace("&", "", StringComparison.Ordinal),
Expand All @@ -149,14 +153,14 @@ public static void LoadMenuFlyoutItem(IList<ContextMenuFlyoutItemViewModel> menu
}
else if (!string.IsNullOrEmpty(menuFlyoutItem.Label))
{
var menuLayoutItem = new ContextMenuFlyoutItemViewModel()
var menuLayoutItem = new ContextMenuFlyoutItemViewModel
{
Text = menuFlyoutItem.Label.Replace("&", "", StringComparison.Ordinal),
Tag = menuFlyoutItem,
BitmapIcon = image
BitmapIcon = image,
Command = new RelayCommand<object>(x => InvokeShellMenuItem(contextMenu, x)),
CommandParameter = menuFlyoutItem
};
menuLayoutItem.Command = new RelayCommand<object>(x => InvokeShellMenuItem(contextMenu, x));
menuLayoutItem.CommandParameter = menuFlyoutItem;
menuItemsListLocal.Insert(0, menuLayoutItem);
}
}
Expand Down Expand Up @@ -222,7 +226,20 @@ void InstallFont(string path, bool asAdmin)
return item?.Items;
}

public static async Task LoadShellMenuItems(string path, CommandBarFlyout itemContextMenuFlyout, ContextMenuOptions options = null, bool showOpenWithMenu = false)
public static List<ContextMenuFlyoutItemViewModel>? GetSendToItems(List<ContextMenuFlyoutItemViewModel> flyout)
{
var item = flyout.FirstOrDefault(x => x.Tag is Win32ContextMenuItem { CommandString: "sendto" });
if (item is not null)
flyout.Remove(item);
return item?.Items;
}

public static async Task LoadShellMenuItems(
string path,
CommandBarFlyout itemContextMenuFlyout,
ContextMenuOptions options = null,
bool showOpenWithMenu = false,
bool showSendToMenu = false)
{
try
{
Expand Down Expand Up @@ -269,6 +286,20 @@ public static async Task LoadShellMenuItems(string path, CommandBarFlyout itemCo
}
}

if (showSendToMenu)
{
var sendToItem = shellMenuItems.Where(x => (x.Tag as Win32ContextMenuItem)?.CommandString == "sendto").ToList().FirstOrDefault();
if (sendToItem is not null)
{
var (_, sendToItems) = ItemModelListToContextFlyoutHelper.GetAppBarItemsFromModel(new List<ContextMenuFlyoutItemViewModel>() { sendToItem });
var placeholder = itemContextMenuFlyout.SecondaryCommands.Where(x => Equals((x as AppBarButton)?.Tag, "SendToPlaceholder")).FirstOrDefault() as AppBarButton;
if (placeholder is not null)
placeholder.Visibility = Visibility.Collapsed;
itemContextMenuFlyout.SecondaryCommands.Insert(1, sendToItems.FirstOrDefault());
shellMenuItems.Remove(sendToItem);
}
}

if (!UserSettingsService.PreferencesSettingsService.MoveShellExtensionsToSubMenu)
{
var (_, secondaryElements) = ItemModelListToContextFlyoutHelper.GetAppBarItemsFromModel(shellMenuItems);
Expand Down
3 changes: 3 additions & 0 deletions src/Files.App/Strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,9 @@
<data name="BaseLayoutItemContextFlyoutOpenItemWith.Text" xml:space="preserve">
<value>Open With</value>
</data>
<data name="SendTo" xml:space="preserve">
<value>Send to</value>
</data>
<data name="FileNameTeachingTip.Subtitle" xml:space="preserve">
<value>The item name must not contain the following characters: \ / : * ? " &lt; &gt; |</value>
</data>
Expand Down
8 changes: 6 additions & 2 deletions src/Files.App/UserControls/SidebarControl.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,12 @@ private List<ContextMenuFlyoutItemViewModel> GetLocationItemMenuItems(INavigatio
new ContextMenuFlyoutItemViewModel()
{
Text = "OpenInNewPane".GetLocalizedResource(),
Glyph = "\uF117",
GlyphFontFamilyName = "CustomGlyph",
ColoredIcon = new ColoredIconModel()
{
BaseBackdropGlyph = "\uF056",
BaseLayerGlyph = "\uF03B",
OverlayLayerGlyph = "\uF03C",
},
Command = OpenInNewPaneCommand,
ShowItem = options.IsLocationItem && userSettingsService.PreferencesSettingsService.ShowOpenInNewPane
},
Expand Down
10 changes: 7 additions & 3 deletions src/Files.App/UserControls/Widgets/DrivesWidget.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public DrivesWidget()
MapNetworkDriveCommand = new AsyncRelayCommand(DoNetworkMapDrive);
DisconnectNetworkDriveCommand = new RelayCommand<DriveCardItem>(DisconnectNetworkDrive);
}

public override List<ContextMenuFlyoutItemViewModel> GetItemMenuItems(WidgetCardItem item, bool isPinned)
{
var options = (item.Item as DriveItem)?.MenuOptions;
Expand All @@ -163,8 +163,12 @@ public override List<ContextMenuFlyoutItemViewModel> GetItemMenuItems(WidgetCard
new ContextMenuFlyoutItemViewModel()
{
Text = "OpenInNewPane".GetLocalizedResource(),
Glyph = "\uF117",
GlyphFontFamilyName = "CustomGlyph",
ColoredIcon = new ColoredIconModel()
{
BaseBackdropGlyph = "\uF056",
BaseLayerGlyph = "\uF03B",
OverlayLayerGlyph = "\uF03C",
},
Command = OpenInNewPaneCommand,
CommandParameter = item,
ShowItem = userSettingsService.PreferencesSettingsService.ShowOpenInNewPane
Expand Down
8 changes: 6 additions & 2 deletions src/Files.App/UserControls/Widgets/QuickAccessWidget.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,12 @@ public override List<ContextMenuFlyoutItemViewModel> GetItemMenuItems(WidgetCard
new ContextMenuFlyoutItemViewModel()
{
Text = "OpenInNewPane".GetLocalizedResource(),
Glyph = "\uF117",
GlyphFontFamilyName = "CustomGlyph",
ColoredIcon = new ColoredIconModel()
{
BaseBackdropGlyph = "\uF056",
BaseLayerGlyph = "\uF03B",
OverlayLayerGlyph = "\uF03C",
},
Command = OpenInNewPaneCommand,
CommandParameter = item,
ShowItem = userSettingsService.PreferencesSettingsService.ShowOpenInNewPane
Expand Down
8 changes: 7 additions & 1 deletion src/Files.App/UserControls/Widgets/RecentFilesWidget.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ private void Grid_RightTapped(object sender, RightTappedRoutedEventArgs e)
secondaryElements.ForEach(i => itemContextMenuFlyout.SecondaryCommands.Add(i));
itemContextMenuFlyout.ShowAt(recentItemsGrid, new FlyoutShowOptions { Position = e.GetPosition(recentItemsGrid) });

_ = ShellContextmenuHelper.LoadShellMenuItems(item.Path, itemContextMenuFlyout, showOpenWithMenu: true);
_ = ShellContextmenuHelper.LoadShellMenuItems(item.Path, itemContextMenuFlyout, showOpenWithMenu: true, showSendToMenu: true);

e.Handled = true;
}
Expand All @@ -134,6 +134,12 @@ public override List<ContextMenuFlyoutItemViewModel> GetItemMenuItems(WidgetCard
IsEnabled = false
},
new ContextMenuFlyoutItemViewModel()
{
Text = "SendTo".GetLocalizedResource(),
Tag = "SendToPlaceholder",
IsEnabled = false
},
new ContextMenuFlyoutItemViewModel()
{
Text = "RecentItemRemove/Text".GetLocalizedResource(),
Glyph = "\uE738",
Expand Down