Skip to content
Open
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
9 changes: 9 additions & 0 deletions CFixer/CFixer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Xml" />
<Reference Include="Windows">
<HintPath>..\..\..\..\..\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral\Annotated\Windows.winmd</HintPath>
Expand Down Expand Up @@ -88,7 +89,9 @@
<Compile Include="Helpers\OSHelper.cs" />
<Compile Include="Helpers\Utils.cs" />
<Compile Include="Helpers\Logger.cs" />
<Compile Include="ILocalizedControl.cs" />
<Compile Include="IniStateManager.cs" />
<Compile Include="LocalizationManager.cs" />
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
Expand Down Expand Up @@ -207,6 +210,12 @@
<Content Include="AppIcon.ico" />
<None Include="AppIcon32.png" />
<None Include="AppIcon.png" />
<Content Include="lang\en-US.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="lang\zh-CN.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Expand Down
47 changes: 29 additions & 18 deletions CFixer/Features/FeatureManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;
using CFixer;

namespace CrapFixer
{
Expand Down Expand Up @@ -64,12 +65,17 @@ public static void LoadFeatures(TreeView tree)
/// </summary>
private static void AddNode(TreeNodeCollection treeNodes, FeatureNode featureNode)
{
string localizedName = featureNode.IsCategory
? LocalizationManager.LocalizeFeatureCategory(featureNode.Name)
: LocalizationManager.LocalizeFeatureName(featureNode);

string text = featureNode.IsCategory
? " " + featureNode.Name + " " // add extra space to avoid clipping
: featureNode.Name;
? " " + localizedName + " " // add extra space to avoid clipping
: localizedName;

TreeNode node = new TreeNode(text)
{
Name = featureNode.Name,
Tag = featureNode,
Checked = featureNode.DefaultChecked,
};
Expand All @@ -93,7 +99,7 @@ public static async Task AnalyzeAll(TreeNodeCollection nodes)
await AnalyzeCheckedRecursive(node);
}

Logger.Log("🔎 ANALYSIS COMPLETE", LogLevel.Info);
Logger.Log("ANALYSIS COMPLETE", LogLevel.Info);
Logger.Log(new string('=', 50), LogLevel.Info);

int ok = totalChecked - issuesFound;
Expand All @@ -119,8 +125,8 @@ private static async Task AnalyzeCheckedRecursive(TreeNode node)
issuesFound++;
node.ForeColor = Color.Red; // Mark as misconfigured
string category = node.Parent?.Text ?? "General";
Logger.Log($"[{category}] {fn.Name} - Not configured as recommended.");
Logger.Log($" {fn.Feature.GetFeatureDetails()}");
Logger.Log($"[{category}] {fn.Name} - Not configured as recommended.");
Logger.Log($" {fn.Feature.GetFeatureDetails()}");
// Log a separator when an issue was found
Logger.Log(new string('-', 50), LogLevel.Info);
}
Expand All @@ -147,10 +153,11 @@ public static async Task FixChecked(TreeNode node)
{
if (!fn.IsCategory && node.Checked && fn.Feature != null)
{
string displayName = LocalizationManager.LocalizeFeatureName(fn);
bool result = await fn.Feature.DoFeature();
Logger.Log(result
? $"🔧 {fn.Name} - Fixed"
: $"❌ {fn.Name} - ⚠️ Fix failed (This feature may require admin privileges)",
? $"{displayName} - Fixed"
: $"{displayName} - Fix failed (This feature may require admin privileges)",
result ? LogLevel.Info : LogLevel.Error);
}

Expand All @@ -168,11 +175,12 @@ public static void RestoreChecked(TreeNode node)
{
if (!fn.IsCategory && node.Checked && fn.Feature != null)
{
string displayName = LocalizationManager.LocalizeFeatureName(fn);
bool ok = fn.Feature.UndoFeature();
string category = node.Parent?.Text ?? "General";
Logger.Log(ok
? $"↩️ [{category}] {fn.Name} - Restored"
: $"[{category}] {fn.Name} - Restore failed",
? $"[{category}] {displayName} - Restored"
: $"[{category}] {displayName} - Restore failed",
ok ? LogLevel.Info : LogLevel.Error);
}

Expand All @@ -193,13 +201,13 @@ public static async void AnalyzeFeature(TreeNode node)

if (isOk)
{
Logger.Log($"Feature: {fn.Name} is properly configured.", LogLevel.Info);
Logger.Log($"Feature: {fn.Name} is properly configured.", LogLevel.Info);
}
else
{
string category = node.Parent?.Text ?? "General";
Logger.Log($"Feature: {fn.Name} requires attention.", LogLevel.Warning);
Logger.Log($" {fn.Feature.GetFeatureDetails()}");
Logger.Log($"Feature: {fn.Name} requires attention.", LogLevel.Warning);
Logger.Log($" {fn.Feature.GetFeatureDetails()}");
Logger.Log(new string('-', 50), LogLevel.Info);
}
}
Expand All @@ -223,11 +231,12 @@ public static async Task FixFeature(TreeNode node)
// Try to fix this node if it is NOT a category (i.e., a leaf node)
if (node.Tag is FeatureNode fn && !fn.IsCategory && fn.Feature != null)
{
string displayName = LocalizationManager.LocalizeFeatureName(fn);
// Always fix the selected leaf node, regardless of Checked
bool result = await fn.Feature.DoFeature();
Logger.Log(result
? $"🔧 {fn.Name} - Fixed"
: $"❌ {fn.Name} - ⚠️ Fix failed (This feature may require admin privileges)",
? $"{displayName} - Fixed"
: $"{displayName} - Fix failed (This feature may require admin privileges)",
result ? LogLevel.Info : LogLevel.Error);
}
else
Expand All @@ -251,10 +260,11 @@ public static void RestoreFeature(TreeNode node)
// Restore feature node regardless of Checked state
if (node.Tag is FeatureNode fn && !fn.IsCategory && fn.Feature != null)
{
string displayName = LocalizationManager.LocalizeFeatureName(fn);
bool ok = fn.Feature.UndoFeature();
Logger.Log(ok
? $"↩️ {fn.Name} - Restored"
: $"❌ {fn.Name} - Restore failed",
? $"{displayName} - Restored"
: $"{displayName} - Restore failed",
ok ? LogLevel.Info : LogLevel.Error);
}
else
Expand All @@ -278,10 +288,11 @@ public static void ShowHelp(TreeNode node)
// Show help for features
if (node?.Tag is FeatureNode fn && fn.Feature != null)
{
string displayName = LocalizationManager.LocalizeFeatureName(fn);
string info = fn.Feature.Info();
MessageBox.Show(
!string.IsNullOrEmpty(info) ? info : "No additional information available.",
$"Help: {fn.Name}",
$"Help: {displayName}",
MessageBoxButtons.OK,
MessageBoxIcon.Information);

Expand Down Expand Up @@ -309,7 +320,7 @@ public static void ShowHelp(TreeNode node)
// Show help for plugins
if (!PluginManager.ShowHelp(node))
{
MessageBox.Show("⚠️ No feature or plugin selected, or help info unavailable.",
MessageBox.Show("No feature or plugin selected, or help info unavailable.",
"Help",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
Expand Down
7 changes: 7 additions & 0 deletions CFixer/ILocalizedControl.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace CFixer
{
internal interface ILocalizedControl
{
void RefreshLocalization();
}
}
70 changes: 66 additions & 4 deletions CFixer/IniStateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ private static void AppendNodeStates(List<string> lines, TreeNodeCollection node
{
foreach (TreeNode node in nodes)
{
lines.Add($"{node.Text.Trim()}={node.Checked}");
string key = string.IsNullOrWhiteSpace(node.Name) ? node.Text.Trim() : node.Name.Trim();
lines.Add($"{key}={node.Checked}");
if (node.Nodes.Count > 0)
AppendNodeStates(lines, node.Nodes);
}
Expand Down Expand Up @@ -175,9 +176,11 @@ private static void ApplyStates(TreeNodeCollection nodes, Dictionary<string, boo
{
foreach (TreeNode node in nodes)
{
string nodeName = node.Text.Trim();
if (states.ContainsKey(nodeName))
node.Checked = states[nodeName];
string nodeKey = string.IsNullOrWhiteSpace(node.Name) ? node.Text.Trim() : node.Name.Trim();
if (states.ContainsKey(nodeKey))
node.Checked = states[nodeKey];
else if (states.ContainsKey(node.Text.Trim()))
node.Checked = states[node.Text.Trim()];

if (node.Nodes.Count > 0)
ApplyStates(node.Nodes, states);
Expand Down Expand Up @@ -240,6 +243,65 @@ public static Dictionary<string, bool> LoadViewSettings(string viewName)
return result;
}

// Saves an individual string setting in a specific section.
public static void SaveViewStringSetting(string viewName, string key, string value)
{
lock (FileLock)
{
var lines = File.Exists(IniPath) ? File.ReadAllLines(IniPath).ToList() : new List<string>();
var sectionData = LoadViewStringSettingsInternal(lines, viewName);
sectionData[key] = value;

RemoveSection(lines, viewName);
lines.Add($"[{viewName}]");
foreach (var kvp in sectionData)
{
lines.Add($"{kvp.Key}={kvp.Value}");
}

File.WriteAllLines(IniPath, lines);
}
}

// Loads one individual string setting from a section.
public static string LoadViewStringSetting(string viewName, string key, string defaultValue = "")
{
if (!File.Exists(IniPath)) return defaultValue;

var lines = File.ReadAllLines(IniPath).ToList();
var settings = LoadViewStringSettingsInternal(lines, viewName);
return settings.TryGetValue(key, out var value) ? value : defaultValue;
}

private static Dictionary<string, string> LoadViewStringSettingsInternal(List<string> lines, string viewName)
{
var result = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
bool inTargetSection = false;

foreach (var line in lines)
{
var trimmed = line.Trim();
if (string.IsNullOrWhiteSpace(trimmed)) continue;

if (trimmed.StartsWith("[") && trimmed.EndsWith("]"))
{
inTargetSection = trimmed.Equals($"[{viewName}]", StringComparison.OrdinalIgnoreCase);
continue;
}

if (!inTargetSection) continue;

var parts = trimmed.Split(new[] { '=' }, 2);
if (parts.Length != 2) continue;

var settingKey = parts[0].Trim();
var settingValue = parts[1].Trim();
result[settingKey] = settingValue;
}

return result;
}

// Checks if a setting exists in a specific section
public static bool IsViewSettingEnabled(string sectionName, string settingName)
{
Expand Down
Loading