Skip to content

Commit be8263d

Browse files
authored
Implement DateCreated column (#3123)
1 parent bca3b4b commit be8263d

File tree

12 files changed

+157
-24
lines changed

12 files changed

+157
-24
lines changed

Common/ShellFileItem.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public class ShellFileItem
1010
public string FilePath;
1111
public DateTime RecycleDate;
1212
public DateTime ModifiedDate;
13+
public DateTime CreatedDate;
1314
public string FileSize;
1415
public ulong FileSizeBytes;
1516
public string FileType;
@@ -20,14 +21,15 @@ public ShellFileItem()
2021

2122
public ShellFileItem(
2223
bool isFolder, string recyclePath, string fileName, string filePath,
23-
DateTime recycleDate, DateTime modifiedDate, string fileSize, ulong fileSizeBytes, string fileType)
24+
DateTime recycleDate, DateTime modifiedDate, DateTime createdDate, string fileSize, ulong fileSizeBytes, string fileType)
2425
{
2526
this.IsFolder = isFolder;
2627
this.RecyclePath = recyclePath;
2728
this.FileName = fileName;
2829
this.FilePath = filePath;
2930
this.RecycleDate = recycleDate;
3031
this.ModifiedDate = modifiedDate;
32+
this.CreatedDate = createdDate;
3133
this.FileSize = fileSize;
3234
this.FileSizeBytes = fileSizeBytes;
3335
this.FileType = fileType;

Files.Launcher/Program.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ private static ShellFileItem GetRecycleBinItem(ShellItem folderItem)
658658
bool isFolder = folderItem.IsFolder && Path.GetExtension(folderItem.Name) != ".zip";
659659
if (folderItem.Properties == null)
660660
{
661-
return new ShellFileItem(isFolder, recyclePath, fileName, filePath, DateTime.Now, DateTime.Now, null, 0, null);
661+
return new ShellFileItem(isFolder, recyclePath, fileName, filePath, DateTime.Now, DateTime.Now, DateTime.MinValue, null, 0, null);
662662
}
663663
folderItem.Properties.TryGetValue<System.Runtime.InteropServices.ComTypes.FILETIME?>(
664664
Ole32.PROPERTYKEY.System.Recycle.DateDeleted, out var fileTime);
@@ -671,7 +671,7 @@ private static ShellFileItem GetRecycleBinItem(ShellItem folderItem)
671671
folderItem.Properties.GetPropertyString(Ole32.PROPERTYKEY.System.Size) : null;
672672
folderItem.Properties.TryGetValue<string>(
673673
Ole32.PROPERTYKEY.System.ItemTypeText, out var fileType);
674-
return new ShellFileItem(isFolder, recyclePath, fileName, filePath, recycleDate, modifiedDate, fileSize, fileSizeBytes ?? 0, fileType);
674+
return new ShellFileItem(isFolder, recyclePath, fileName, filePath, recycleDate, modifiedDate, DateTime.MinValue, fileSize, fileSizeBytes ?? 0, fileType);
675675
}
676676

677677
private static void HandleApplicationsLaunch(IEnumerable<string> applications, AppServiceRequestReceivedEventArgs args)

Files/Enums/SortOption.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ public enum SortOption : byte
44
{
55
Name,
66
DateModified,
7+
DateCreated,
78
Size,
89
FileType,
910
OriginalPath,

Files/Interacts/Interaction.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,12 @@ public async Task<bool> OpenPath(string path, FilesystemItemType? itemType = nul
616616
queryOptions.SortOrder.Add(sortEntry);
617617
break;
618618

619+
case Enums.SortOption.DateCreated:
620+
sortEntry.PropertyName = "System.DateCreated";
621+
queryOptions.SortOrder.Clear();
622+
queryOptions.SortOrder.Add(sortEntry);
623+
break;
624+
619625
//Unfortunately this is unsupported | Remarks: https://docs.microsoft.com/en-us/uwp/api/windows.storage.search.queryoptions.sortorder?view=winrt-19041
620626
//case Enums.SortOption.Size:
621627

Files/Strings/en-US/Resources.resw

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1851,4 +1851,10 @@
18511851
<data name="DriveTypeVirtualDrive" xml:space="preserve">
18521852
<value>Virtual Drive</value>
18531853
</data>
1854-
</root>
1854+
<data name="BaseLayoutContextFlyoutSortByDateCreated.Text" xml:space="preserve">
1855+
<value>Date created</value>
1856+
</data>
1857+
<data name="DateCreatedColumn.Header" xml:space="preserve">
1858+
<value>Date created</value>
1859+
</data>
1860+
</root>

Files/ViewModels/ItemViewModel.cs

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ public async void UpdateSortOptionStatus()
180180
NotifyPropertyChanged(nameof(IsSortedBySize));
181181
NotifyPropertyChanged(nameof(IsSortedByOriginalPath));
182182
NotifyPropertyChanged(nameof(IsSortedByDateDeleted));
183+
NotifyPropertyChanged(nameof(IsSortedByDateCreated));
183184
await OrderFilesAndFoldersAsync();
184185
await ApplyFilesAndFoldersChangesAsync();
185186
}
@@ -244,6 +245,19 @@ public bool IsSortedByDate
244245
}
245246
}
246247

248+
public bool IsSortedByDateCreated
249+
{
250+
get => FolderSettings.DirectorySortOption == SortOption.DateCreated;
251+
set
252+
{
253+
if (value)
254+
{
255+
FolderSettings.DirectorySortOption = SortOption.DateCreated;
256+
NotifyPropertyChanged(nameof(IsSortedByDateCreated));
257+
}
258+
}
259+
}
260+
247261
public bool IsSortedByType
248262
{
249263
get => FolderSettings.DirectorySortOption == SortOption.FileType;
@@ -586,6 +600,10 @@ private Task OrderFilesAndFoldersAsync()
586600
orderFunc = item => item.ItemDateModifiedReal;
587601
break;
588602

603+
case SortOption.DateCreated:
604+
orderFunc = item => item.ItemDateCreatedReal;
605+
break;
606+
589607
case SortOption.FileType:
590608
orderFunc = item => item.ItemType;
591609
break;
@@ -1042,6 +1060,7 @@ public async Task EnumerateItemsFromSpecialFolderAsync(string path)
10421060
ItemPropertiesInitialized = true,
10431061
ItemName = ApplicationData.Current.LocalSettings.Values.Get("RecycleBin_Title", "Recycle Bin"),
10441062
ItemDateModifiedReal = DateTimeOffset.Now, // Fake for now
1063+
ItemDateCreatedReal = DateTimeOffset.MinValue, // Fake for now
10451064
ItemType = "FileFolderListItem".GetLocalized(),
10461065
LoadFolderGlyph = true,
10471066
FileImage = null,
@@ -1169,12 +1188,14 @@ await DialogDisplayHelper.ShowDialogAsync(
11691188

11701189
if (enumFromStorageFolder)
11711190
{
1191+
var basicProps = await rootFolder.GetBasicPropertiesAsync();
1192+
var extraProps = await basicProps.RetrievePropertiesAsync(new [] {"System.DateCreated"});
11721193
CurrentFolder = new ListedItem(rootFolder.FolderRelativeId, returnformat)
11731194
{
11741195
PrimaryItemAttribute = StorageItemTypes.Folder,
11751196
ItemPropertiesInitialized = true,
11761197
ItemName = rootFolder.Name,
1177-
ItemDateModifiedReal = (await rootFolder.GetBasicPropertiesAsync()).DateModified,
1198+
ItemDateModifiedReal = basicProps.DateModified,
11781199
ItemType = rootFolder.DisplayType,
11791200
LoadFolderGlyph = true,
11801201
FileImage = null,
@@ -1184,6 +1205,10 @@ await DialogDisplayHelper.ShowDialogAsync(
11841205
FileSize = null,
11851206
FileSizeBytes = 0
11861207
};
1208+
if (DateTimeOffset.TryParse(extraProps["System.DateCreated"] as string, out var dateCreated))
1209+
{
1210+
CurrentFolder.ItemDateCreatedReal = dateCreated;
1211+
}
11871212
await EnumFromStorageFolderAsync(path, skipItems);
11881213
return true;
11891214
}
@@ -1198,13 +1223,20 @@ await DialogDisplayHelper.ShowDialogAsync(
11981223
return (hFileTsk, findDataTsk);
11991224
}).WithTimeoutAsync(TimeSpan.FromSeconds(5));
12001225

1201-
DateTime itemDate = DateTime.UtcNow;
1226+
var itemModifiedDate = DateTime.UtcNow;
1227+
var itemCreatedDate = DateTime.MinValue;
12021228
try
12031229
{
1204-
FileTimeToSystemTime(ref findData.ftLastWriteTime, out SYSTEMTIME systemTimeOutput);
1205-
itemDate = new DateTime(
1206-
systemTimeOutput.Year, systemTimeOutput.Month, systemTimeOutput.Day,
1207-
systemTimeOutput.Hour, systemTimeOutput.Minute, systemTimeOutput.Second, systemTimeOutput.Milliseconds,
1230+
FileTimeToSystemTime(ref findData.ftLastWriteTime, out var systemModifiedTimeOutput);
1231+
itemModifiedDate = new DateTime(
1232+
systemModifiedTimeOutput.Year, systemModifiedTimeOutput.Month, systemModifiedTimeOutput.Day,
1233+
systemModifiedTimeOutput.Hour, systemModifiedTimeOutput.Minute, systemModifiedTimeOutput.Second, systemModifiedTimeOutput.Milliseconds,
1234+
DateTimeKind.Utc);
1235+
1236+
FileTimeToSystemTime(ref findData.ftCreationTime, out SYSTEMTIME systemCreatedTimeOutput);
1237+
itemCreatedDate = new DateTime(
1238+
systemCreatedTimeOutput.Year, systemCreatedTimeOutput.Month, systemCreatedTimeOutput.Day,
1239+
systemCreatedTimeOutput.Hour, systemCreatedTimeOutput.Minute, systemCreatedTimeOutput.Second, systemCreatedTimeOutput.Milliseconds,
12081240
DateTimeKind.Utc);
12091241
}
12101242
catch (ArgumentException) { }
@@ -1222,7 +1254,8 @@ await DialogDisplayHelper.ShowDialogAsync(
12221254
PrimaryItemAttribute = StorageItemTypes.Folder,
12231255
ItemPropertiesInitialized = true,
12241256
ItemName = Path.GetFileName(path.TrimEnd('\\')),
1225-
ItemDateModifiedReal = itemDate,
1257+
ItemDateModifiedReal = itemModifiedDate,
1258+
ItemDateCreatedReal = itemCreatedDate,
12261259
ItemType = "FileFolderListItem".GetLocalized(),
12271260
LoadFolderGlyph = true,
12281261
FileImage = null,
@@ -1697,6 +1730,7 @@ public ListedItem AddFileOrFolderFromShellFile(ShellFileItem item, string dateRe
16971730
PrimaryItemAttribute = StorageItemTypes.Folder,
16981731
ItemName = item.FileName,
16991732
ItemDateModifiedReal = item.ModifiedDate,
1733+
ItemDateCreatedReal = item.CreatedDate,
17001734
ItemDateDeletedReal = item.RecycleDate,
17011735
ItemType = item.FileType,
17021736
IsHiddenItem = false,
@@ -1749,6 +1783,7 @@ public ListedItem AddFileOrFolderFromShellFile(ShellFileItem item, string dateRe
17491783
Opacity = 1,
17501784
ItemName = itemName,
17511785
ItemDateModifiedReal = item.ModifiedDate,
1786+
ItemDateCreatedReal = item.CreatedDate,
17521787
ItemDateDeletedReal = item.RecycleDate,
17531788
ItemType = item.FileType,
17541789
ItemPath = item.RecyclePath, // this is the true path on disk so other stuff can work as is
@@ -1911,13 +1946,20 @@ private ListedItem AddFolder(WIN32_FIND_DATA findData, string pathRoot, string d
19111946
return null;
19121947
}
19131948

1914-
DateTime itemDate;
1949+
DateTime itemModifiedDate;
1950+
DateTime itemCreatedDate;
19151951
try
19161952
{
1917-
FileTimeToSystemTime(ref findData.ftLastWriteTime, out SYSTEMTIME systemTimeOutput);
1918-
itemDate = new DateTime(
1919-
systemTimeOutput.Year, systemTimeOutput.Month, systemTimeOutput.Day,
1920-
systemTimeOutput.Hour, systemTimeOutput.Minute, systemTimeOutput.Second, systemTimeOutput.Milliseconds,
1953+
FileTimeToSystemTime(ref findData.ftLastWriteTime, out SYSTEMTIME systemModifiedTimeOutput);
1954+
itemModifiedDate = new DateTime(
1955+
systemModifiedTimeOutput.Year, systemModifiedTimeOutput.Month, systemModifiedTimeOutput.Day,
1956+
systemModifiedTimeOutput.Hour, systemModifiedTimeOutput.Minute, systemModifiedTimeOutput.Second, systemModifiedTimeOutput.Milliseconds,
1957+
DateTimeKind.Utc);
1958+
1959+
FileTimeToSystemTime(ref findData.ftCreationTime, out SYSTEMTIME systemCreatedTimeOutput);
1960+
itemCreatedDate = new DateTime(
1961+
systemCreatedTimeOutput.Year, systemCreatedTimeOutput.Month, systemCreatedTimeOutput.Day,
1962+
systemCreatedTimeOutput.Hour, systemCreatedTimeOutput.Minute, systemCreatedTimeOutput.Second, systemCreatedTimeOutput.Milliseconds,
19211963
DateTimeKind.Utc);
19221964
}
19231965
catch (ArgumentException)
@@ -1939,7 +1981,8 @@ private ListedItem AddFolder(WIN32_FIND_DATA findData, string pathRoot, string d
19391981
{
19401982
PrimaryItemAttribute = StorageItemTypes.Folder,
19411983
ItemName = findData.cFileName,
1942-
ItemDateModifiedReal = itemDate,
1984+
ItemDateModifiedReal = itemModifiedDate,
1985+
ItemDateCreatedReal = itemCreatedDate,
19431986
ItemType = "FileFolderListItem".GetLocalized(),
19441987
LoadFolderGlyph = true,
19451988
FileImage = null,
@@ -2129,14 +2172,16 @@ public void AddItemsToCollectionAsync(string path, string previousDir, bool useC
21292172
private async Task<ListedItem> AddFolderAsync(StorageFolder folder, string dateReturnFormat)
21302173
{
21312174
var basicProperties = await folder.GetBasicPropertiesAsync();
2132-
2175+
var extraProps = await basicProperties.RetrievePropertiesAsync(new[] { "System.DateCreated" });
2176+
DateTimeOffset.TryParse(extraProps["System.DateCreated"] as string, out var dateCreated);
21332177
if (!addFilesCTS.IsCancellationRequested)
21342178
{
21352179
return new ListedItem(folder.FolderRelativeId, dateReturnFormat)
21362180
{
21372181
PrimaryItemAttribute = StorageItemTypes.Folder,
21382182
ItemName = folder.Name,
21392183
ItemDateModifiedReal = basicProperties.DateModified,
2184+
ItemDateCreatedReal = dateCreated,
21402185
ItemType = folder.DisplayType,
21412186
IsHiddenItem = false,
21422187
Opacity = 1,
@@ -2156,10 +2201,12 @@ private async Task<ListedItem> AddFolderAsync(StorageFolder folder, string dateR
21562201
private async Task<ListedItem> AddFileAsync(StorageFile file, string dateReturnFormat, bool suppressThumbnailLoading = false)
21572202
{
21582203
var basicProperties = await file.GetBasicPropertiesAsync();
2204+
var extraProperties = await basicProperties.RetrievePropertiesAsync(new [] { "System.DateCreated" });
21592205
// Display name does not include extension
21602206
var itemName = string.IsNullOrEmpty(file.DisplayName) || shouldDisplayFileExtensions ?
21612207
file.Name : file.DisplayName;
2162-
var itemDate = basicProperties.DateModified;
2208+
var itemModifiedDate = basicProperties.DateModified;
2209+
DateTimeOffset.TryParse(extraProperties["System.DateCreated"] as string, out var itemCreatedDate);
21632210
var itemPath = string.IsNullOrEmpty(file.Path) ? Path.Combine(currentStorageFolder.Path, file.Name) : file.Path;
21642211
var itemSize = ByteSize.FromBytes(basicProperties.Size).ToBinaryString().ConvertSizeAbbreviation();
21652212
var itemSizeBytes = basicProperties.Size;
@@ -2247,7 +2294,8 @@ private async Task<ListedItem> AddFileAsync(StorageFile file, string dateReturnF
22472294
LoadFileIcon = itemThumbnailImgVis,
22482295
LoadFolderGlyph = itemFolderImgVis,
22492296
ItemName = itemName,
2250-
ItemDateModifiedReal = itemDate,
2297+
ItemDateModifiedReal = itemModifiedDate,
2298+
ItemDateCreatedReal = itemCreatedDate,
22512299
ItemType = itemType,
22522300
ItemPath = itemPath,
22532301
FileSize = itemSize,

Files/ViewModels/Properties/FileProperties.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public override void GetBaseProperties()
5252
ViewModel.ItemPath = (Item as RecycleBinItem)?.ItemOriginalFolder ??
5353
(Path.IsPathRooted(Item.ItemPath) ? Path.GetDirectoryName(Item.ItemPath) : Item.ItemPath);
5454
ViewModel.ItemModifiedTimestamp = Item.ItemDateModified;
55+
ViewModel.ItemCreatedTimestamp = Item.ItemDateCreated;
5556
//ViewModel.FileIconSource = Item.FileImage;
5657
ViewModel.LoadFolderGlyph = Item.LoadFolderGlyph;
5758
ViewModel.LoadUnknownTypeGlyph = Item.LoadUnknownTypeGlyph;

Files/ViewModels/Properties/FolderProperties.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public override void GetBaseProperties()
4242
ViewModel.ItemPath = (Item as RecycleBinItem)?.ItemOriginalFolder ??
4343
(Path.IsPathRooted(Item.ItemPath) ? Path.GetDirectoryName(Item.ItemPath) : Item.ItemPath);
4444
ViewModel.ItemModifiedTimestamp = Item.ItemDateModified;
45+
ViewModel.ItemCreatedTimestamp = Item.ItemDateCreated;
4546
//ViewModel.FileIconSource = Item.FileImage;
4647
ViewModel.LoadFolderGlyph = Item.LoadFolderGlyph;
4748
ViewModel.LoadUnknownTypeGlyph = Item.LoadUnknownTypeGlyph;

Files/ViewModels/SettingsViewModel.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,15 @@ public bool ShowDateColumn
281281
set => Set(value);
282282
}
283283

284+
/// <summary>
285+
/// Gets or sets a value indicating whether or not the date created column should be visible.
286+
/// </summary>
287+
public bool ShowDateCreatedColumn
288+
{
289+
get => Get(false);
290+
set => Set(value);
291+
}
292+
284293
/// <summary>
285294
/// Gets or sets a value indicating whether or not the type column should be visible.
286295
/// </summary>

0 commit comments

Comments
 (0)