Skip to content

Commit 8e6290d

Browse files
authored
Properties: Optimize and split specific code to classes (#1315)
1 parent 5a0c751 commit 8e6290d

12 files changed

+544
-423
lines changed

Files/BaseLayout.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public BaseLayout()
115115
{
116116
this.Loaded += Page_Loaded;
117117
Page_Loaded(null, null);
118-
SelectedItemsPropertiesViewModel = new SelectedItemsPropertiesViewModel(null as ListedItem);
118+
SelectedItemsPropertiesViewModel = new SelectedItemsPropertiesViewModel();
119119
DirectoryPropertiesViewModel = new DirectoryPropertiesViewModel();
120120
// QuickLook Integration
121121
ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;

Files/Enums/PropertiesType.cs

Lines changed: 0 additions & 10 deletions
This file was deleted.

Files/Files.csproj

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@
178178
<Compile Include="Helpers\StringExtensions.cs" />
179179
<Compile Include="Helpers\BulkObservableCollection.cs" />
180180
<Compile Include="Helpers\ThemeHelper.cs" />
181+
<Compile Include="Helpers\Win32FindDataExtensions.cs" />
181182
<Compile Include="Program.cs" />
182183
<Compile Include="Helpers\RegistryReader.cs" />
183184
<Compile Include="ResourceController.cs" />
@@ -212,7 +213,6 @@
212213
<DependentUpon>RenameDialog.xaml</DependentUpon>
213214
</Compile>
214215
<Compile Include="Enums\FormFactorMode.cs" />
215-
<Compile Include="Enums\PropertiesType.cs" />
216216
<Compile Include="Enums\SidebarOpacity.cs" />
217217
<Compile Include="Enums\SortOption.cs" />
218218
<Compile Include="Enums\TimeStyle.cs" />
@@ -229,6 +229,11 @@
229229
<Compile Include="Filesystem\ListedItem.cs" />
230230
<Compile Include="Filesystem\INavigationControlItem.cs" />
231231
<Compile Include="Filesystem\LocationItem.cs" />
232+
<Compile Include="View Models\Properties\BaseProperties.cs" />
233+
<Compile Include="View Models\Properties\CombinedProperties.cs" />
234+
<Compile Include="View Models\Properties\DriveProperties.cs" />
235+
<Compile Include="View Models\Properties\FileProperties.cs" />
236+
<Compile Include="View Models\Properties\FolderProperties.cs" />
232237
<Compile Include="Views\LayoutModes\GenericFileBrowser.xaml.cs">
233238
<DependentUpon>GenericFileBrowser.xaml</DependentUpon>
234239
</Compile>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using static Files.Helpers.NativeFindStorageItemHelper;
2+
3+
namespace Files.Helpers
4+
{
5+
public static class Win32FindDataExtensions
6+
{
7+
private const long MAXDWORD = 4294967295;
8+
9+
public static long GetSize(this WIN32_FIND_DATA findData)
10+
{
11+
long fDataFSize = findData.nFileSizeLow;
12+
long fileSize;
13+
if (fDataFSize < 0 && findData.nFileSizeHigh > 0)
14+
{
15+
fileSize = fDataFSize + (MAXDWORD + 1) + (findData.nFileSizeHigh * (MAXDWORD + 1));
16+
}
17+
else
18+
{
19+
if (findData.nFileSizeHigh > 0)
20+
{
21+
fileSize = fDataFSize + (findData.nFileSizeHigh * (MAXDWORD + 1));
22+
}
23+
else if (fDataFSize < 0)
24+
{
25+
fileSize = fDataFSize + (MAXDWORD + 1);
26+
}
27+
else
28+
{
29+
fileSize = fDataFSize;
30+
}
31+
}
32+
33+
return fileSize;
34+
}
35+
}
36+
}

Files/View Models/ItemViewModel.cs

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,27 +1222,7 @@ private void AddFile(WIN32_FIND_DATA findData, string pathRoot)
12221222
systemTimeOutput.Second,
12231223
systemTimeOutput.Milliseconds,
12241224
DateTimeKind.Utc);
1225-
long fDataFSize = findData.nFileSizeLow;
1226-
long itemSizeBytes;
1227-
if (fDataFSize < 0 && findData.nFileSizeHigh > 0)
1228-
{
1229-
itemSizeBytes = fDataFSize + 4294967296 + (findData.nFileSizeHigh * 4294967296);
1230-
}
1231-
else
1232-
{
1233-
if (findData.nFileSizeHigh > 0)
1234-
{
1235-
itemSizeBytes = fDataFSize + (findData.nFileSizeHigh * 4294967296);
1236-
}
1237-
else if (fDataFSize < 0)
1238-
{
1239-
itemSizeBytes = fDataFSize + 4294967296;
1240-
}
1241-
else
1242-
{
1243-
itemSizeBytes = fDataFSize;
1244-
}
1245-
}
1225+
long itemSizeBytes = findData.GetSize();
12461226
var itemSize = ByteSize.FromBytes(itemSizeBytes).ToBinaryString().ConvertSizeAbbreviation();
12471227
string itemType = ResourceController.GetTranslation("ItemTypeFile");
12481228
string itemFileExtension = null;
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
using ByteSizeLib;
2+
using Files.Filesystem;
3+
using Files.Helpers;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.IO;
7+
using System.Threading;
8+
using System.Threading.Tasks;
9+
using Windows.Storage.FileProperties;
10+
using Windows.UI.Core;
11+
using static Files.Helpers.NativeFindStorageItemHelper;
12+
using FileAttributes = System.IO.FileAttributes;
13+
14+
namespace Files.View_Models.Properties
15+
{
16+
public abstract class BaseProperties
17+
{
18+
public SelectedItemsPropertiesViewModel ViewModel { get; set; }
19+
20+
public CancellationTokenSource TokenSource { get; set; }
21+
22+
public CoreDispatcher Dispatcher { get; set; }
23+
24+
public abstract void GetBaseProperties();
25+
26+
public abstract void GetSpecialProperties();
27+
28+
public async void GetOtherProperties(StorageItemContentProperties properties)
29+
{
30+
string dateAccessedProperty = "System.DateAccessed";
31+
string fileOwnerProperty = "System.FileOwner";
32+
List<string> propertiesName = new List<string>();
33+
propertiesName.Add(dateAccessedProperty);
34+
propertiesName.Add(fileOwnerProperty);
35+
IDictionary<string, object> extraProperties = await properties.RetrievePropertiesAsync(propertiesName);
36+
// Cannot get date and owner in MTP devices
37+
ViewModel.ItemAccessedTimestamp = ListedItem.GetFriendlyDate((DateTimeOffset)(extraProperties[dateAccessedProperty] ?? DateTimeOffset.Now));
38+
39+
if (App.AppSettings.ShowFileOwner)
40+
{
41+
// Cannot get date and owner in MTP devices
42+
ViewModel.ItemFileOwner = extraProperties[fileOwnerProperty]?.ToString();
43+
}
44+
}
45+
46+
public async Task<long> CalculateFolderSizeAsync(string path, CancellationToken token)
47+
{
48+
if (string.IsNullOrEmpty(path))
49+
{
50+
// In MTP devices calculating folder size would be too slow
51+
// Also should use StorageFolder methods instead of FindFirstFileExFromApp
52+
return 0;
53+
}
54+
55+
long size = 0;
56+
FINDEX_INFO_LEVELS findInfoLevel = FINDEX_INFO_LEVELS.FindExInfoBasic;
57+
int additionalFlags = FIND_FIRST_EX_LARGE_FETCH;
58+
59+
IntPtr hFile = FindFirstFileExFromApp(path + "\\*.*", findInfoLevel, out WIN32_FIND_DATA findData, FINDEX_SEARCH_OPS.FindExSearchNameMatch, IntPtr.Zero,
60+
additionalFlags);
61+
62+
var count = 0;
63+
if (hFile.ToInt64() != -1)
64+
{
65+
do
66+
{
67+
if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) != FileAttributes.Directory)
68+
{
69+
size += findData.GetSize();
70+
++count;
71+
ViewModel.FilesCount++;
72+
}
73+
else if (((FileAttributes)findData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory)
74+
{
75+
if (findData.cFileName != "." && findData.cFileName != "..")
76+
{
77+
var itemPath = Path.Combine(path, findData.cFileName);
78+
79+
size += await CalculateFolderSizeAsync(itemPath, token);
80+
++count;
81+
ViewModel.FoldersCount++;
82+
}
83+
}
84+
85+
if (size > ViewModel.ItemSizeBytes)
86+
{
87+
await Dispatcher.RunAsync(CoreDispatcherPriority.Low, () =>
88+
{
89+
ViewModel.ItemSizeBytes = size;
90+
ViewModel.ItemSize = ByteSize.FromBytes(size).ToBinaryString().ConvertSizeAbbreviation();
91+
SetItemsCountString();
92+
});
93+
}
94+
95+
if (token.IsCancellationRequested)
96+
{
97+
break;
98+
}
99+
} while (FindNextFile(hFile, out findData));
100+
FindClose(hFile);
101+
return size;
102+
}
103+
else
104+
{
105+
return 0;
106+
}
107+
}
108+
109+
public void SetItemsCountString()
110+
{
111+
ViewModel.FilesAndFoldersCountString = string.Format(
112+
ResourceController.GetTranslation("PropertiesFilesAndFoldersCountString"), ViewModel.FilesCount, ViewModel.FoldersCount);
113+
}
114+
}
115+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using ByteSizeLib;
2+
using Files.Filesystem;
3+
using Files.Helpers;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.IO;
7+
using System.Linq;
8+
using System.Threading;
9+
using System.Threading.Tasks;
10+
using Windows.Storage;
11+
using Windows.UI.Core;
12+
using Windows.UI.Xaml;
13+
14+
namespace Files.View_Models.Properties
15+
{
16+
class CombinedProperties : BaseProperties
17+
{
18+
public List<ListedItem> List { get; }
19+
20+
public CombinedProperties(SelectedItemsPropertiesViewModel viewModel, CancellationTokenSource tokenSource,
21+
CoreDispatcher coreDispatcher, List<ListedItem> listedItems)
22+
{
23+
ViewModel = viewModel;
24+
TokenSource = tokenSource;
25+
Dispatcher = coreDispatcher;
26+
List = listedItems;
27+
28+
GetBaseProperties();
29+
}
30+
31+
public override void GetBaseProperties()
32+
{
33+
if (List != null)
34+
{
35+
ViewModel.LoadCombinedItemsGlyph = true;
36+
if (List.All(x => x.ItemType.Equals(List.First().ItemType)))
37+
{
38+
ViewModel.ItemType = string.Format(ResourceController.GetTranslation("PropertiesDriveItemTypesEquals"), List.First().ItemType);
39+
}
40+
else
41+
{
42+
ViewModel.ItemType = ResourceController.GetTranslation("PropertiesDriveItemTypeDifferent");
43+
}
44+
ViewModel.ItemPath = string.Format(
45+
ResourceController.GetTranslation("PropertiesCombinedItemPath"), Path.GetDirectoryName(List.First().ItemPath));
46+
}
47+
}
48+
49+
public override async void GetSpecialProperties()
50+
{
51+
ViewModel.LastSeparatorVisibility = Visibility.Collapsed;
52+
ViewModel.ItemSizeVisibility = Visibility.Visible;
53+
54+
ViewModel.FilesCount += List.Where(x => x.PrimaryItemAttribute == StorageItemTypes.File).ToList().Count;
55+
ViewModel.FoldersCount += List.Where(x => x.PrimaryItemAttribute == StorageItemTypes.Folder).ToList().Count;
56+
57+
long totalSize = 0;
58+
long filesSize = List.Where(x => x.PrimaryItemAttribute == StorageItemTypes.File).Sum(x => x.FileSizeBytes);
59+
long foldersSize = 0;
60+
61+
ViewModel.ItemSizeProgressVisibility = Visibility.Visible;
62+
foreach (var item in List)
63+
{
64+
if (item.PrimaryItemAttribute == StorageItemTypes.Folder)
65+
{
66+
var fileSizeTask = Task.Run(async () =>
67+
{
68+
var size = await CalculateFolderSizeAsync(item.ItemPath, TokenSource.Token);
69+
return size;
70+
});
71+
try
72+
{
73+
foldersSize += await fileSizeTask;
74+
}
75+
catch (Exception ex)
76+
{
77+
NLog.LogManager.GetCurrentClassLogger().Error(ex, ex.Message);
78+
}
79+
}
80+
}
81+
ViewModel.ItemSizeProgressVisibility = Visibility.Collapsed;
82+
83+
totalSize = filesSize + foldersSize;
84+
ViewModel.ItemSize = ByteSize.FromBytes(totalSize).ToBinaryString().ConvertSizeAbbreviation()
85+
+ " (" + ByteSize.FromBytes(totalSize).Bytes.ToString("#,##0") + " " + ResourceController.GetTranslation("ItemSizeBytes") + ")";
86+
SetItemsCountString();
87+
}
88+
}
89+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using Files.Filesystem;
2+
using System;
3+
using System.Threading.Tasks;
4+
using Windows.Storage;
5+
using Windows.UI.Xaml;
6+
7+
namespace Files.View_Models.Properties
8+
{
9+
class DriveProperties : BaseProperties
10+
{
11+
public DriveItem Drive { get; }
12+
13+
public DriveProperties(SelectedItemsPropertiesViewModel viewModel, DriveItem driveItem)
14+
{
15+
ViewModel = viewModel;
16+
Drive = driveItem;
17+
18+
GetBaseProperties();
19+
}
20+
21+
public override void GetBaseProperties()
22+
{
23+
if (Drive != null)
24+
{
25+
ViewModel.DriveItemGlyphSource = Drive.Glyph;
26+
ViewModel.LoadDriveItemGlyph = true;
27+
ViewModel.ItemName = Drive.Text;
28+
ViewModel.ItemType = Drive.Type.ToString();
29+
}
30+
}
31+
32+
public override void GetSpecialProperties()
33+
{
34+
ViewModel.ItemAttributesVisibility = Visibility.Collapsed;
35+
StorageFolder diskRoot = Task.Run(async () => await ItemViewModel.GetFolderFromPathAsync(Drive.Path)).Result;
36+
37+
string freeSpace = "System.FreeSpace";
38+
string capacity = "System.Capacity";
39+
string fileSystem = "System.Volume.FileSystem";
40+
41+
try
42+
{
43+
var properties = Task.Run(async () =>
44+
{
45+
return await diskRoot.Properties.RetrievePropertiesAsync(new[] {
46+
freeSpace,
47+
capacity,
48+
fileSystem });
49+
}).Result;
50+
51+
ViewModel.DriveCapacityValue = (ulong)properties[capacity];
52+
ViewModel.DriveFreeSpaceValue = (ulong)properties[freeSpace];
53+
ViewModel.DriveUsedSpaceValue = ViewModel.DriveCapacityValue - ViewModel.DriveFreeSpaceValue;
54+
ViewModel.DriveFileSystem = (string)properties[fileSystem];
55+
}
56+
catch (Exception e)
57+
{
58+
ViewModel.LastSeparatorVisibility = Visibility.Collapsed;
59+
NLog.LogManager.GetCurrentClassLogger().Error(e, e.Message);
60+
}
61+
}
62+
}
63+
}

0 commit comments

Comments
 (0)