Skip to content

Commit f596acd

Browse files
0x5bfahishitetsuyaira2
authored
Code Quality: Remove ini-parser-netstandard dependency (#15654)
Co-authored-by: hishitetsu <66369541+hishitetsu@users.noreply.github.com> Co-authored-by: Yair <39923744+yaira2@users.noreply.github.com>
1 parent baf2fdf commit f596acd

File tree

8 files changed

+164
-54
lines changed

8 files changed

+164
-54
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) 2024 Files Community
2+
// Licensed under the MIT License. See the LICENSE.
3+
4+
namespace Files.App.Data.Contracts
5+
{
6+
/// <summary>
7+
/// Provides service to retrieve value from an INI file.
8+
/// </summary>
9+
public interface IWindowsIniService
10+
{
11+
/// <summary>
12+
/// Gets parsed data of INI file of a folder with each section.
13+
/// </summary>
14+
/// <remarks>
15+
/// While there's Win32API GetPrivateProfileString, this API can only used for single key.
16+
/// <br/>
17+
/// For more information about INI format, visit <a href="https://en.wikipedia.org/wiki/INI_file"/>.
18+
/// </remarks>
19+
/// <param name="filePath">The INI file to look up.</param>
20+
/// <param name="dataItem">The data class to hold the INI data.</param>
21+
/// <returns>Returns true if succeeded; otherwise, false.</returns>
22+
List<IniSectionDataItem> GetData(string filePath);
23+
}
24+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) 2024 Files Community
2+
// Licensed under the MIT License. See the LICENSE.
3+
4+
using System.Collections.Immutable;
5+
6+
namespace Files.App.Data.Items
7+
{
8+
/// <summary>
9+
/// Represents item of ini file's section.
10+
/// </summary>
11+
public class IniSectionDataItem
12+
{
13+
public string SectionName { get; set; } = "";
14+
15+
public IDictionary<string, string> Parameters { get; set; } = ImmutableDictionary<string, string>.Empty;
16+
}
17+
}

src/Files.App/Files.App.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@
6969
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
7070
<PackageReference Include="DiscUtils.Udf" Version="0.16.13" />
7171
<PackageReference Include="FluentFTP" Version="43.0.1" />
72-
<PackageReference Include="ini-parser-netstandard" Version="2.5.2" />
7372
<PackageReference Include="LibGit2Sharp" Version="0.30.0" />
7473
<PackageReference Include="MessageFormat" Version="7.1.0" />
7574
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="8.0.6" />

src/Files.App/Helpers/Application/AppLifecycleHelper.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ public static IHost ConfigureHost()
164164
.AddSingleton<ITagsContext, TagsContext>()
165165
.AddSingleton<ISidebarContext, SidebarContext>()
166166
// Services
167+
.AddSingleton<IWindowsIniService, WindowsIniService>()
167168
.AddSingleton<IAppThemeModeService, AppThemeModeService>()
168169
.AddSingleton<IDialogService, DialogService>()
169170
.AddSingleton<ICommonDialogService, CommonDialogService>()

src/Files.App/Helpers/Layout/AdaptiveLayoutHelpers.cs

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,24 @@
33

44
using Files.App.ViewModels.Previews;
55
using Files.Shared.Helpers;
6-
using IniParser.Model;
76
using Windows.Storage;
87
using static Files.App.Constants.AdaptiveLayout;
9-
using IO = System.IO;
108

119
namespace Files.App.Helpers
1210
{
1311
public static class AdaptiveLayoutHelpers
1412
{
15-
private static IFoldersSettingsService FoldersSettingsService { get; } = Ioc.Default.GetRequiredService<IFoldersSettingsService>();
1613
private static ILayoutSettingsService LayoutSettingsService { get; } = Ioc.Default.GetRequiredService<ILayoutSettingsService>();
14+
private static IContentPageContext ContentPageContext { get; } = Ioc.Default.GetRequiredService<IContentPageContext>();
1715

18-
public static void ApplyAdaptativeLayout(LayoutPreferencesManager folderSettings, string path, IList<ListedItem> filesAndFolders)
16+
public static void ApplyAdaptativeLayout(LayoutPreferencesManager folderSettings, IList<ListedItem> filesAndFolders)
1917
{
2018
if (LayoutSettingsService.SyncFolderPreferencesAcrossDirectories)
2119
return;
22-
if (string.IsNullOrWhiteSpace(path))
23-
return;
2420
if (folderSettings.IsLayoutModeFixed || !folderSettings.IsAdaptiveLayoutEnabled)
2521
return;
2622

27-
var layout = GetAdaptiveLayout(path, filesAndFolders);
23+
var layout = GetAdaptiveLayout(filesAndFolders);
2824
switch (layout)
2925
{
3026
case Layouts.Detail:
@@ -36,49 +32,33 @@ public static void ApplyAdaptativeLayout(LayoutPreferencesManager folderSettings
3632
}
3733
}
3834

39-
private static Layouts GetAdaptiveLayout(string path, IList<ListedItem> filesAndFolders)
35+
private static Layouts GetAdaptiveLayout(IList<ListedItem> filesAndFolders)
4036
{
41-
var pathLayout = GetPathLayout(path);
37+
var pathLayout = GetPathLayout();
4238
if (pathLayout is not Layouts.None)
4339
return pathLayout;
4440

4541
return GetContentLayout(filesAndFolders);
4642
}
4743

48-
private static Layouts GetPathLayout(string path)
44+
private static Layouts GetPathLayout()
4945
{
50-
var iniPath = IO.Path.Combine(path, "desktop.ini");
51-
52-
var iniContents = Win32Helper.ReadStringFromFile(iniPath)?.Trim();
53-
if (string.IsNullOrEmpty(iniContents))
46+
var desktopIni = ContentPageContext.ShellPage?.ShellViewModel.DesktopIni;
47+
if (desktopIni is null)
5448
return Layouts.None;
5549

56-
var parser = new IniParser.Parser.IniDataParser();
57-
parser.Configuration.ThrowExceptionsOnError = false;
58-
var data = parser.Parse(iniContents);
59-
if (data is null)
50+
var viewStateSection = desktopIni.FirstOrDefault(x => x.SectionName == "ViewState");
51+
if (viewStateSection is null)
6052
return Layouts.None;
6153

62-
var viewModeSection = data.Sections.FirstOrDefault(IsViewState);
63-
if (viewModeSection is null)
64-
return Layouts.None;
54+
var viewMode = viewStateSection.Parameters.FirstOrDefault(x => x.Key == "Mode").Value;
6555

66-
var folderTypeKey = viewModeSection.Keys.FirstOrDefault(IsFolderType);
67-
if (folderTypeKey is null)
68-
return Layouts.None;
69-
70-
return folderTypeKey.Value switch
56+
return viewMode switch
7157
{
7258
"Pictures" => Layouts.Grid,
7359
"Videos" => Layouts.Grid,
7460
_ => Layouts.Detail,
7561
};
76-
77-
static bool IsViewState(SectionData data)
78-
=> "ViewState".Equals(data.SectionName, StringComparison.OrdinalIgnoreCase);
79-
80-
static bool IsFolderType(KeyData data)
81-
=> "FolderType".Equals(data.KeyName, StringComparison.OrdinalIgnoreCase);
8262
}
8363

8464
private static Layouts GetContentLayout(IList<ListedItem> filesAndFolders)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright (c) 2024 Files Community
2+
// Licensed under the MIT License. See the LICENSE.
3+
4+
namespace Files.App.Services
5+
{
6+
/// <inheritdoc cref="IWindowsIniService"/>
7+
public sealed class WindowsIniService : IWindowsIniService
8+
{
9+
/// <inheritdoc/>
10+
public List<IniSectionDataItem> GetData(string filePath)
11+
{
12+
var iniPath = SystemIO.Path.Combine(filePath);
13+
if (!SystemIO.File.Exists(iniPath))
14+
return [];
15+
16+
var lines = Enumerable.Empty<string>().ToList();
17+
18+
try
19+
{
20+
lines = SystemIO.File.ReadLines(iniPath)
21+
.Where(line => !line.StartsWith(';') && !string.IsNullOrEmpty(line))
22+
.ToList();
23+
}
24+
catch (UnauthorizedAccessException)
25+
{
26+
return [];
27+
}
28+
29+
// Get sections
30+
var sections = lines
31+
.Where(line => line.StartsWith('[') && line.EndsWith(']'));
32+
33+
// Get section line indexes
34+
List<int> sectionLineIndexes = [];
35+
foreach (var section in sections)
36+
sectionLineIndexes.Add(lines.IndexOf(section));
37+
38+
List<IniSectionDataItem> dataItems = [];
39+
40+
for (int index = 0; index < sectionLineIndexes.Count; index++)
41+
{
42+
var sectionIndex = sectionLineIndexes[index];
43+
44+
var count =
45+
index + 1 == sectionLineIndexes.Count
46+
? (lines.Count - 1) - sectionIndex
47+
: sectionLineIndexes[index + 1] - sectionIndex;
48+
49+
if (count == 0)
50+
continue;
51+
52+
var range = lines.GetRange(sectionIndex + 1, count);
53+
54+
var sectionName = lines[sectionLineIndexes[index]].TrimStart('[').TrimEnd(']');
55+
56+
// Read data
57+
var parameters = range
58+
// Split the lines into key and value
59+
.Select(line => line.Split('='))
60+
// Validate
61+
.Where(parts => parts.Length == 2)
62+
// Gather as dictionary
63+
.ToDictionary(parts => parts[0].Trim(), parts => parts[1].Trim());
64+
65+
dataItems.Add(new()
66+
{
67+
SectionName = sectionName,
68+
Parameters = parameters,
69+
});
70+
}
71+
72+
return dataItems;
73+
}
74+
}
75+
}

src/Files.App/ViewModels/ShellViewModel.cs

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public sealed class ShellViewModel : ObservableObject, IDisposable
4747

4848
// Files and folders list for manipulating
4949
private ConcurrentCollection<ListedItem> filesAndFolders;
50+
private readonly IWindowsIniService WindowsIniService = Ioc.Default.GetRequiredService<IWindowsIniService>();
5051
private readonly IWindowsJumpListService jumpListService = Ioc.Default.GetRequiredService<IWindowsJumpListService>();
5152
private readonly IDialogService dialogService = Ioc.Default.GetRequiredService<IDialogService>();
5253
private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetRequiredService<IUserSettingsService>();
@@ -154,6 +155,8 @@ public GitProperties EnabledGitProperties
154155

155156
public bool IsValidGitDirectory { get; private set; }
156157

158+
public List<IniSectionDataItem> DesktopIni { get; private set; }
159+
157160
private StorageFolderWithPath? currentStorageFolder;
158161
private StorageFolderWithPath workingRoot;
159162

@@ -1443,7 +1446,7 @@ private async Task RapidAddItemsToCollectionAsync(string path, string? previousD
14431446
ItemLoadStatusChanged?.Invoke(this, new ItemLoadStatusChangedEventArgs() { Status = ItemLoadStatusChangedEventArgs.ItemLoadStatus.Complete, PreviousDirectory = previousDir, Path = path });
14441447
IsLoadingItems = false;
14451448

1446-
AdaptiveLayoutHelpers.ApplyAdaptativeLayout(folderSettings, WorkingDirectory, filesAndFolders.ToList());
1449+
AdaptiveLayoutHelpers.ApplyAdaptativeLayout(folderSettings, filesAndFolders.ToList());
14471450
}
14481451
finally
14491452
{
@@ -1736,6 +1739,7 @@ await Task.Run(async () =>
17361739
await OrderFilesAndFoldersAsync();
17371740
await ApplyFilesAndFoldersChangesAsync();
17381741
await dispatcherQueue.EnqueueOrInvokeAsync(CheckForSolutionFile, Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
1742+
await dispatcherQueue.EnqueueOrInvokeAsync(GetDesktopIniFileData, Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
17391743
await dispatcherQueue.EnqueueOrInvokeAsync(CheckForBackgroundImage, Microsoft.UI.Dispatching.DispatcherQueuePriority.Low);
17401744
});
17411745

@@ -1797,51 +1801,61 @@ private void CheckForSolutionFile()
17971801
.FirstOrDefault()?.ItemPath;
17981802
}
17991803

1804+
private void GetDesktopIniFileData()
1805+
{
1806+
var path = Path.Combine(WorkingDirectory, "desktop.ini");
1807+
DesktopIni = WindowsIniService.GetData(path);
1808+
}
1809+
18001810
public void CheckForBackgroundImage()
18011811
{
1802-
var iniPath = Path.Combine(WorkingDirectory, "desktop.ini");
1803-
if (!File.Exists(iniPath))
1812+
var filesAppSection = DesktopIni.FirstOrDefault(x => x.SectionName == "FilesApp");
1813+
if (filesAppSection is null || folderSettings.LayoutMode is FolderLayoutModes.ColumnView)
1814+
{
1815+
FolderBackgroundImageSource = null;
18041816
return;
1805-
1806-
// Read data
1807-
var lines = File.ReadLines(iniPath);
1808-
var keys = lines.Select(line => line.Split('='))
1809-
.Where(parts => parts.Length == 2)
1810-
.ToDictionary(parts => parts[0].Trim(), parts => parts[1].Trim());
1817+
}
18111818

18121819
// Image source
1813-
if (folderSettings.LayoutMode is not FolderLayoutModes.ColumnView && keys.TryGetValue("Files_BackgroundImage", out var backgroundImage))
1820+
var backgroundImage = filesAppSection.Parameters.FirstOrDefault(x => x.Key == "Files_BackgroundImage").Value;
1821+
if (string.IsNullOrEmpty(backgroundImage))
1822+
{
1823+
FolderBackgroundImageSource = null;
1824+
return;
1825+
}
1826+
else
1827+
{
18141828
FolderBackgroundImageSource = new BitmapImage
18151829
{
18161830
UriSource = new Uri(backgroundImage, UriKind.RelativeOrAbsolute),
18171831
CreateOptions = BitmapCreateOptions.IgnoreImageCache
18181832
};
1819-
else
1820-
{
1821-
FolderBackgroundImageSource = null;
1822-
return;
18231833
}
18241834

18251835
// Opacity
1826-
if (keys.TryGetValue("Files_BackgroundOpacity", out var backgroundOpacity) && float.TryParse(backgroundOpacity, out var opacity))
1836+
var backgroundOpacity = filesAppSection.Parameters.FirstOrDefault(x => x.Key == "Files_BackgroundOpacity").Value;
1837+
if (float.TryParse(backgroundOpacity, out var opacity))
18271838
FolderBackgroundImageOpacity = opacity;
18281839
else
18291840
FolderBackgroundImageOpacity = 1f;
18301841

18311842
// Stretch
1832-
if (keys.TryGetValue("Files_BackgroundFit", out var backgroundFit) && Enum.TryParse<Stretch>(backgroundFit, out var fit))
1843+
var backgroundFit = filesAppSection.Parameters.FirstOrDefault(x => x.Key == "Files_BackgroundFit").Value;
1844+
if (Enum.TryParse<Stretch>(backgroundFit, out var fit))
18331845
FolderBackgroundImageFit = fit;
18341846
else
18351847
FolderBackgroundImageFit = Stretch.UniformToFill;
18361848

1837-
// VerticalAlignment
1838-
if (keys.TryGetValue("Files_BackgroundVerticalAlignment", out var verticalAlignment) && Enum.TryParse<VerticalAlignment>(verticalAlignment, out var vAlignment))
1849+
// Vertical alignment
1850+
var verticalAlignment = filesAppSection.Parameters.FirstOrDefault(x => x.Key == "Files_BackgroundVerticalAlignment").Value;
1851+
if (Enum.TryParse<VerticalAlignment>(verticalAlignment, out var vAlignment))
18391852
FolderBackgroundImageVerticalAlignment = vAlignment;
18401853
else
18411854
FolderBackgroundImageVerticalAlignment = VerticalAlignment.Center;
18421855

1843-
// HorizontalAlignment
1844-
if (keys.TryGetValue("Files_BackgroundHorizontalAlignment", out var horizontalAlignment) && Enum.TryParse<HorizontalAlignment>(horizontalAlignment, out var hAlignment))
1856+
// Horizontal alignment
1857+
var horizontalAlignment = filesAppSection.Parameters.FirstOrDefault(x => x.Key == "Files_BackgroundHorizontalAlignment").Value;
1858+
if (Enum.TryParse<HorizontalAlignment>(horizontalAlignment, out var hAlignment))
18451859
FolderBackgroundImageHorizontalAlignment = hAlignment;
18461860
else
18471861
FolderBackgroundImageHorizontalAlignment = HorizontalAlignment.Center;

src/Files.App/Views/Shells/ModernShellPage.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ protected override void FolderSettings_LayoutPreferencesUpdateRequired(object se
7272

7373
LayoutPreferencesManager.SetLayoutPreferencesForPath(ShellViewModel.WorkingDirectory, e.LayoutPreference);
7474
if (e.IsAdaptiveLayoutUpdateRequired)
75-
AdaptiveLayoutHelpers.ApplyAdaptativeLayout(InstanceViewModel.FolderSettings, ShellViewModel.WorkingDirectory, ShellViewModel.FilesAndFolders.ToList());
75+
AdaptiveLayoutHelpers.ApplyAdaptativeLayout(InstanceViewModel.FolderSettings, ShellViewModel.FilesAndFolders.ToList());
7676
}
7777

7878
protected override void OnNavigatedTo(NavigationEventArgs eventArgs)

0 commit comments

Comments
 (0)