Skip to content

Commit

Permalink
Add ability to drag & drop shortcuts and hidden files (only inside Fi…
Browse files Browse the repository at this point in the history
…les) (#5810)
  • Loading branch information
gave92 authored Aug 22, 2021
1 parent e75a0f7 commit 5946075
Show file tree
Hide file tree
Showing 23 changed files with 340 additions and 359 deletions.
42 changes: 27 additions & 15 deletions Files.Launcher/MessageHandlers/FileOperationsHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -464,24 +464,36 @@ await Win32API.StartSTATask(() =>
case "UpdateLink":
var linkSavePath = (string)message["filepath"];
var targetPath = (string)message["targetpath"];
if (linkSavePath.EndsWith(".lnk"))
try
{
var arguments = (string)message["arguments"];
var workingDirectory = (string)message["workingdir"];
var runAsAdmin = (bool)message["runasadmin"];
using var newLink = new ShellLink(targetPath, arguments, workingDirectory);
newLink.RunAsAdministrator = runAsAdmin;
newLink.SaveAs(linkSavePath); // Overwrite if exists
bool success = false;
if (linkSavePath.EndsWith(".lnk"))
{
var arguments = (string)message["arguments"];
var workingDirectory = (string)message["workingdir"];
var runAsAdmin = (bool)message["runasadmin"];
using var newLink = new ShellLink(targetPath, arguments, workingDirectory);
newLink.RunAsAdministrator = runAsAdmin;
newLink.SaveAs(linkSavePath); // Overwrite if exists
success = true;
}
else if (linkSavePath.EndsWith(".url"))
{
success = await Win32API.StartSTATask(() =>
{
var ipf = new Url.IUniformResourceLocator();
ipf.SetUrl(targetPath, Url.IURL_SETURL_FLAGS.IURL_SETURL_FL_GUESS_PROTOCOL);
(ipf as System.Runtime.InteropServices.ComTypes.IPersistFile).Save(linkSavePath, false); // Overwrite if exists
return true;
});
}
await Win32API.SendMessageAsync(connection, new ValueSet() { { "Success", success } }, message.Get("RequestID", (string)null));
}
else if (linkSavePath.EndsWith(".url"))
catch (Exception ex)
{
await Win32API.StartSTATask(() =>
{
var ipf = new Url.IUniformResourceLocator();
ipf.SetUrl(targetPath, Url.IURL_SETURL_FLAGS.IURL_SETURL_FL_GUESS_PROTOCOL);
(ipf as System.Runtime.InteropServices.ComTypes.IPersistFile).Save(linkSavePath, false); // Overwrite if exists
return true;
});
// Could not create shortcut
Program.Logger.Warn(ex, ex.Message);
await Win32API.SendMessageAsync(connection, new ValueSet() { { "Success", false } }, message.Get("RequestID", (string)null));
}
break;

Expand Down
67 changes: 36 additions & 31 deletions Files/BaseLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -761,17 +761,12 @@ protected virtual void Page_CharacterReceived(CoreWindow sender, CharacterReceiv
protected async void FileList_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
List<IStorageItem> selectedStorageItems = new List<IStorageItem>();
var result = (FilesystemResult)false;

foreach (var itemObj in e.Items)
{
var item = itemObj as ListedItem;
if (item == null || item is ShortcutItem)
{
// Can't drag shortcut items
continue;
}
e.Items.OfType<ListedItem>().ForEach(item => SelectedItems.Add(item));

SelectedItems.Add(item);
foreach (var item in e.Items.OfType<ListedItem>())
{
if (item is FtpItem ftpItem)
{
if (item.PrimaryItemAttribute == StorageItemTypes.File)
Expand All @@ -781,16 +776,32 @@ protected async void FileList_DragItemsStarting(object sender, DragItemsStarting
}
else if (item.PrimaryItemAttribute == StorageItemTypes.File)
{
await ParentShellPageInstance.FilesystemViewModel.GetFileFromPathAsync(item.ItemPath)
result = await ParentShellPageInstance.FilesystemViewModel.GetFileFromPathAsync(item.ItemPath)
.OnSuccess(t => selectedStorageItems.Add(t));
if (!result)
{
break;
}
}
else if (item.PrimaryItemAttribute == StorageItemTypes.Folder)
{
await ParentShellPageInstance.FilesystemViewModel.GetFolderFromPathAsync(item.ItemPath)
result = await ParentShellPageInstance.FilesystemViewModel.GetFolderFromPathAsync(item.ItemPath)
.OnSuccess(t => selectedStorageItems.Add(t));
if (!result)
{
break;
}
}
}

if (result.ErrorCode == FileSystemStatusCode.Unauthorized)
{
var itemList = e.Items.OfType<ListedItem>().Select(x => StorageItemHelpers.FromPathAndType(
x.ItemPath, x.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory));
e.Data.Properties["FileDrop"] = itemList.ToList();
return;
}

if (selectedStorageItems.Count == 1)
{
if (selectedStorageItems[0] is IStorageFile file)
Expand Down Expand Up @@ -853,37 +864,26 @@ protected async void Item_DragOver(object sender, DragEventArgs e)
}, TimeSpan.FromMilliseconds(1000), false);
}

if (e.DataView.Contains(StandardDataFormats.StorageItems))
if (Filesystem.FilesystemHelpers.HasDraggedStorageItems(e.DataView))
{
IReadOnlyList<IStorageItem> draggedItems;
try
{
draggedItems = await e.DataView.GetStorageItemsAsync();
}
catch (Exception ex) when ((uint)ex.HResult == 0x80040064 || (uint)ex.HResult == 0x8004006A)
{
// Handled by FTP
draggedItems = new List<IStorageItem>();
}
catch (Exception ex)
{
App.Logger.Warn(ex, ex.Message);
e.AcceptedOperation = DataPackageOperation.None;
deferral.Complete();
return;
}

e.Handled = true;

var (handledByFtp, draggedItems) = await Filesystem.FilesystemHelpers.GetDraggedStorageItems(e.DataView);

if (draggedItems.Any(draggedItem => draggedItem.Path == item.ItemPath))
{
e.AcceptedOperation = DataPackageOperation.None;
}
else if (!draggedItems.Any())
else if (handledByFtp)
{
e.DragUIOverride.IsCaptionVisible = true;
e.DragUIOverride.Caption = string.Format("CopyToFolderCaptionText".GetLocalized(), item.ItemName);
e.AcceptedOperation = DataPackageOperation.Copy;
}
else if (!draggedItems.Any())
{
e.AcceptedOperation = DataPackageOperation.None;
}
else
{
e.DragUIOverride.IsCaptionVisible = true;
Expand All @@ -892,6 +892,11 @@ protected async void Item_DragOver(object sender, DragEventArgs e)
e.DragUIOverride.Caption = $"{"OpenItemsWithCaptionText".GetLocalized()} {item.ItemName}";
e.AcceptedOperation = DataPackageOperation.Link;
} // Items from the same drive as this folder are dragged into this folder, so we move the items instead of copy
else if (e.Modifiers.HasFlag(DragDropModifiers.Alt) || e.Modifiers.HasFlag(DragDropModifiers.Control | DragDropModifiers.Shift))
{
e.DragUIOverride.Caption = string.Format("LinkToFolderCaptionText".GetLocalized(), item.ItemName);
e.AcceptedOperation = DataPackageOperation.Link;
}
else if (e.Modifiers.HasFlag(DragDropModifiers.Control))
{
e.DragUIOverride.Caption = string.Format("CopyToFolderCaptionText".GetLocalized(), item.ItemName);
Expand Down
7 changes: 6 additions & 1 deletion Files/Enums/FileOperationType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ public enum FileOperationType : byte
/// <summary>
/// A item has been deleted
/// </summary>
Delete = 8
Delete = 8,

/// <summary>
/// A link to an item has been created
/// </summary>
CreateLink = 9,
}
}
11 changes: 5 additions & 6 deletions Files/Filesystem/FilesystemOperations/FilesystemOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,6 @@ public FilesystemOperations(IShellPage associatedInstance)
break;
}

case FilesystemItemType.Symlink:
{
Debugger.Break();
throw new NotImplementedException();
}

default:
Debugger.Break();
break;
Expand Down Expand Up @@ -1159,5 +1153,10 @@ public async Task<IStorageHistory> DeleteItemsAsync(IEnumerable<IStorageItemWith
}
return null;
}

public Task<IStorageHistory> CreateShortcutItemsAsync(IEnumerable<IStorageItemWithPath> source, IEnumerable<string> destination, IProgress<float> progress, IProgress<FileSystemStatusCode> errorCode, CancellationToken token)
{
throw new NotImplementedException("Cannot create shortcuts in UWP.");
}
}
}
Loading

0 comments on commit 5946075

Please sign in to comment.