Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Files.Launcher/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,14 @@ private static async Task parseArguments(AppServiceRequestReceivedEventArgs args
await parseFileOperation(args);
break;

case "CheckCustomIcon":
var folderPath = (string)args.Request.Message["folderPath"];
var shfi = new Shell32.SHFILEINFO();
var ret = Shell32.SHGetFileInfo(folderPath, 0, ref shfi, Shell32.SHFILEINFO.Size, Shell32.SHGFI.SHGFI_ICONLOCATION);
var hasCustomIcon = ret != IntPtr.Zero && !shfi.szDisplayName.StartsWith(Environment.GetFolderPath(Environment.SpecialFolder.Windows));
await args.Request.SendResponseAsync(new ValueSet() { { "HasCustomIcon", hasCustomIcon } });
break;

default:
if (args.Request.Message.ContainsKey("Application"))
{
Expand Down
8 changes: 7 additions & 1 deletion Files/Filesystem/ListedItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ public class ListedItem : ObservableObject
public bool ItemPropertiesInitialized { get; set; } = false;
public string FolderTooltipText { get; set; }
public string FolderRelativeId { get; set; }
public bool LoadFolderGlyph { get; set; }
public bool ContainsFilesOrFolders { get; set; }
private bool _LoadFolderGlyph;
private bool _LoadFileIcon;

public Uri FolderIconSource
Expand All @@ -32,6 +32,12 @@ public Uri FolderIconSourceLarge
}
}

public bool LoadFolderGlyph
{
get => _LoadFolderGlyph;
set => SetProperty(ref _LoadFolderGlyph, value);
}

public bool LoadFileIcon
{
get => _LoadFileIcon;
Expand Down
2 changes: 1 addition & 1 deletion Files/UserControls/FileIcon.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
Height="{x:Bind ItemSize}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
x:Load="{x:Bind ViewModel.LoadFolderGlyph}"
x:Load="{x:Bind ViewModel.LoadFolderGlyph, Mode=OneWay}"
Stretch="Uniform">
<Image.Source>
<SvgImageSource
Expand Down
31 changes: 27 additions & 4 deletions Files/View Models/ItemViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,6 @@ public async void LoadExtendedItemProperties(ListedItem item, uint thumbnailSize
{
if (item.PrimaryItemAttribute == StorageItemTypes.File)
{
BitmapImage icon = new BitmapImage();
var matchingItem = _filesAndFolders.FirstOrDefault(x => x == item);
try
{
Expand All @@ -478,8 +477,8 @@ public async void LoadExtendedItemProperties(ListedItem item, uint thumbnailSize
{
if (Thumbnail != null)
{
matchingItem.FileImage = icon;
await icon.SetSourceAsync(Thumbnail);
matchingItem.FileImage = new BitmapImage();
await matchingItem.FileImage.SetSourceAsync(Thumbnail);
matchingItem.LoadUnknownTypeGlyph = false;
matchingItem.LoadFileIcon = true;
}
Expand Down Expand Up @@ -514,9 +513,33 @@ public async void LoadExtendedItemProperties(ListedItem item, uint thumbnailSize
var matchingItem = _filesAndFolders.FirstOrDefault(x => x == item);
try
{
StorageFolder matchingStorageItem = await StorageFileExtensions.GetFolderFromPathAsync(item.ItemPath, _workingRoot, _currentStorageFolder);
StorageFolder matchingStorageItem = await StorageFileExtensions.GetFolderFromPathAsync((item as ShortcutItem)?.TargetPath ?? item.ItemPath, _workingRoot, _currentStorageFolder);
if (matchingItem != null && matchingStorageItem != null)
{
if (App.Connection != null)
{
var value = new ValueSet();
value.Add("Arguments", "CheckCustomIcon");
value.Add("folderPath", matchingItem.ItemPath);
var response = await App.Connection.SendMessageAsync(value);
var hasCustomIcon = (response.Status == Windows.ApplicationModel.AppService.AppServiceResponseStatus.Success)
&& response.Message.Get("HasCustomIcon", false);
if (hasCustomIcon)
{
// Only set folder icon if it's a custom icon
using (var Thumbnail = await matchingStorageItem.GetThumbnailAsync(ThumbnailMode.SingleItem, thumbnailSize, ThumbnailOptions.UseCurrentScale))
{
if (Thumbnail != null)
{
matchingItem.FileImage = new BitmapImage();
await matchingItem.FileImage.SetSourceAsync(Thumbnail);
matchingItem.LoadUnknownTypeGlyph = false;
matchingItem.LoadFolderGlyph = false;
matchingItem.LoadFileIcon = true;
}
}
}
}
matchingItem.FolderRelativeId = matchingStorageItem.FolderRelativeId;
matchingItem.ItemType = matchingStorageItem.DisplayType;
var syncStatus = await CheckCloudDriveSyncStatus(matchingStorageItem);
Expand Down
138 changes: 86 additions & 52 deletions Files/View Models/Properties/FolderProperties.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using ByteSizeLib;
using Files.Enums;
using Files.Common;
using Files.Filesystem;
using Files.Helpers;
using Microsoft.Toolkit.Mvvm.Input;
Expand All @@ -11,8 +12,10 @@
using Windows.ApplicationModel.Core;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.Storage.FileProperties;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media.Imaging;

namespace Files.View_Models.Properties
{
Expand Down Expand Up @@ -76,80 +79,111 @@ public async override void GetSpecialProperties()
+ " (" + ByteSize.FromBytes(Item.FileSizeBytes).Bytes.ToString("#,##0") + " " + ResourceController.GetTranslation("ItemSizeBytes") + ")";
ViewModel.ItemCreatedTimestamp = Item.ItemDateCreated;
ViewModel.ItemAccessedTimestamp = Item.ItemDateAccessed;
// Can't show any other property
return;
if (Item.IsLinkItem || string.IsNullOrWhiteSpace(((ShortcutItem)Item).TargetPath))
{
// Can't show any other property
return;
}
}
ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
string returnformat = Enum.Parse<TimeStyle>(localSettings.Values[LocalSettings.DateTimeFormat].ToString()) == TimeStyle.Application ? "D" : "g";

StorageFolder storageFolder;
bool isItemSelected;
var parentDirectory = App.CurrentInstance.FilesystemViewModel.CurrentFolder;

StorageFolder storageFolder = null;
try
{
isItemSelected = await CoreApplication.MainView.ExecuteOnUIThreadAsync(() => App.CurrentInstance.ContentPage.IsItemSelected);
var isItemSelected = await CoreApplication.MainView.ExecuteOnUIThreadAsync(() => App.CurrentInstance?.ContentPage?.IsItemSelected ?? true);
if (isItemSelected)
{
storageFolder = await ItemViewModel.GetFolderFromPathAsync((Item as ShortcutItem)?.TargetPath ?? Item.ItemPath);
}
else if (!parentDirectory.ItemPath.StartsWith(App.AppSettings.RecycleBinPath))
{
storageFolder = await ItemViewModel.GetFolderFromPathAsync(parentDirectory.ItemPath);
}
}
catch
catch (Exception ex)
{
isItemSelected = true;
NLog.LogManager.GetCurrentClassLogger().Error(ex, ex.Message);
// Could not access folder, can't show any other property
return;
}

if (isItemSelected)
if (storageFolder != null)
{
storageFolder = await ItemViewModel.GetFolderFromPathAsync(Item.ItemPath);
ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
string returnformat = Enum.Parse<TimeStyle>(localSettings.Values[LocalSettings.DateTimeFormat].ToString()) == TimeStyle.Application ? "D" : "g";
ViewModel.ItemCreatedTimestamp = ListedItem.GetFriendlyDateFromFormat(storageFolder.DateCreated, returnformat);
LoadFolderIcon(storageFolder);
GetOtherProperties(storageFolder.Properties);
GetFolderSize(storageFolder, TokenSource.Token);
}
else
else if (parentDirectory.ItemPath.StartsWith(App.AppSettings.RecycleBinPath))
{
var parentDirectory = App.CurrentInstance.FilesystemViewModel.CurrentFolder;
if (parentDirectory.ItemPath.StartsWith(App.AppSettings.RecycleBinPath))
// GetFolderFromPathAsync cannot access recyclebin folder
if (App.Connection != null)
{
// GetFolderFromPathAsync cannot access recyclebin folder
if (App.Connection != null)
var value = new ValueSet();
value.Add("Arguments", "RecycleBin");
value.Add("action", "Query");
// Send request to fulltrust process to get recyclebin properties
var response = await App.Connection.SendMessageAsync(value);
if (response.Status == Windows.ApplicationModel.AppService.AppServiceResponseStatus.Success)
{
var value = new ValueSet();
value.Add("Arguments", "RecycleBin");
value.Add("action", "Query");
// Send request to fulltrust process to get recyclebin properties
var response = await App.Connection.SendMessageAsync(value);
if (response.Status == Windows.ApplicationModel.AppService.AppServiceResponseStatus.Success)
if (response.Message.TryGetValue("BinSize", out var binSize))
{
ViewModel.ItemSizeBytes = (long)binSize;
ViewModel.ItemSize = ByteSize.FromBytes((long)binSize).ToString();
ViewModel.ItemSizeVisibility = Visibility.Visible;
}
else
{
if (response.Message.TryGetValue("BinSize", out var binSize))
{
ViewModel.ItemSizeBytes = (long)binSize;
ViewModel.ItemSize = ByteSize.FromBytes((long)binSize).ToString();
ViewModel.ItemSizeVisibility = Visibility.Visible;
}
else
{
ViewModel.ItemSizeVisibility = Visibility.Collapsed;
}
if (response.Message.TryGetValue("NumItems", out var numItems))
{
ViewModel.FilesCount = (int)(long)numItems;
SetItemsCountString();
ViewModel.FilesAndFoldersCountVisibility = Visibility.Visible;
}
else
{
ViewModel.FilesAndFoldersCountVisibility = Visibility.Collapsed;
}
ViewModel.ItemCreatedTimestampVisibiity = Visibility.Collapsed;
ViewModel.ItemAccessedTimestampVisibility = Visibility.Collapsed;
ViewModel.ItemModifiedTimestampVisibility = Visibility.Collapsed;
ViewModel.ItemFileOwnerVisibility = Visibility.Collapsed;
ViewModel.LastSeparatorVisibility = Visibility.Collapsed;
ViewModel.ItemSizeVisibility = Visibility.Collapsed;
}
if (response.Message.TryGetValue("NumItems", out var numItems))
{
ViewModel.FilesCount = (int)(long)numItems;
SetItemsCountString();
ViewModel.FilesAndFoldersCountVisibility = Visibility.Visible;
}
else
{
ViewModel.FilesAndFoldersCountVisibility = Visibility.Collapsed;
}
ViewModel.ItemCreatedTimestampVisibiity = Visibility.Collapsed;
ViewModel.ItemAccessedTimestampVisibility = Visibility.Collapsed;
ViewModel.ItemModifiedTimestampVisibility = Visibility.Collapsed;
ViewModel.ItemFileOwnerVisibility = Visibility.Collapsed;
ViewModel.LastSeparatorVisibility = Visibility.Collapsed;
}
}
else
}
}

private async void LoadFolderIcon(StorageFolder storageFolder)
{
if (App.Connection != null)
{
var value = new ValueSet();
value.Add("Arguments", "CheckCustomIcon");
value.Add("folderPath", Item.ItemPath);
var response = await App.Connection.SendMessageAsync(value);
var hasCustomIcon = (response.Status == Windows.ApplicationModel.AppService.AppServiceResponseStatus.Success)
&& response.Message.Get("HasCustomIcon", false);
if (hasCustomIcon)
{
storageFolder = await ItemViewModel.GetFolderFromPathAsync(parentDirectory.ItemPath);
ViewModel.ItemCreatedTimestamp = ListedItem.GetFriendlyDateFromFormat(storageFolder.DateCreated, returnformat);
GetOtherProperties(storageFolder.Properties);
GetFolderSize(storageFolder, TokenSource.Token);
// Only set folder icon if it's a custom icon
using (var Thumbnail = await storageFolder.GetThumbnailAsync(ThumbnailMode.SingleItem, 80, ThumbnailOptions.UseCurrentScale))
{
BitmapImage icon = new BitmapImage();
if (Thumbnail != null)
{
ViewModel.FileIconSource = icon;
await icon.SetSourceAsync(Thumbnail);
ViewModel.LoadUnknownTypeGlyph = false;
ViewModel.LoadFolderGlyph = false;
ViewModel.LoadFileIcon = true;
}
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Files/Views/LayoutModes/GenericFileBrowser.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@
x:Name="FolderGlyphElement"
Width="24"
Height="24"
x:Load="{x:Bind LoadFolderGlyph}">
x:Load="{x:Bind LoadFolderGlyph, Mode=OneWay}">
<Image.Source>
<SvgImageSource
RasterizePixelHeight="128"
Expand Down
4 changes: 2 additions & 2 deletions Files/Views/LayoutModes/GridViewBrowser.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@
x:Name="FolderGlyph"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
x:Load="{x:Bind LoadFolderGlyph}"
x:Load="{x:Bind LoadFolderGlyph, Mode=OneWay}"
Stretch="Uniform">
<Image.Source>
<SvgImageSource
Expand Down Expand Up @@ -682,7 +682,7 @@
Height="74"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
x:Load="{x:Bind LoadFolderGlyph}"
x:Load="{x:Bind LoadFolderGlyph, Mode=OneWay}"
Stretch="Uniform">
<Image.Source>
<SvgImageSource
Expand Down
2 changes: 1 addition & 1 deletion Files/Views/Pages/PropertiesDetails.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
Height="70"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
x:Load="{x:Bind ViewModel.LoadFolderGlyph}"
x:Load="{x:Bind ViewModel.LoadFolderGlyph, Mode=OneWay}"
Stretch="Uniform">
<Image.Source>
<SvgImageSource
Expand Down