- Fixed exception handling for OnLoad method in selection form
- Made program selection validation more stable
- Reimplemented program selection caching with Usable boolean
- Fixed errors related to the treeNodes list by converting it into a method that gathers all nodes
This commit is contained in:
pointfeev 2022-01-18 11:24:11 -05:00
parent 83a4c5b888
commit ba1971d18e
7 changed files with 196 additions and 204 deletions

View file

@ -7,27 +7,27 @@ namespace CreamInstaller
{ {
public static bool OutputException(Exception e) public static bool OutputException(Exception e)
{ {
while (!(e.InnerException is null)) while (e.InnerException is not null)
{ {
e = e.InnerException; e = e.InnerException;
} }
string output = ""; string output = "";
string[] stackTrace = e.StackTrace?.Split('\n'); string[] stackTrace = e.StackTrace?.Split('\n');
if (!(stackTrace is null) && stackTrace.Length > 0) if (stackTrace is not null && stackTrace.Length > 0)
{ {
output += "STACK TRACE\n"; output += "STACK TRACE\n";
for (int i = 0; i < Math.Min(stackTrace.Length, 3); i++) for (int i = 0; i < Math.Min(stackTrace.Length, 3); i++)
{ {
string line = stackTrace[i]; string line = stackTrace[i];
if (!(line is null)) if (line is not null)
{ {
output += "\n " + line[line.IndexOf("at")..]; output += "\n " + line[line.IndexOf("at")..];
} }
} }
} }
string[] messageLines = e.Message?.Split('\n'); string[] messageLines = e.Message?.Split('\n');
if (!(messageLines is null) && messageLines.Length > 0) if (messageLines is not null && messageLines.Length > 0)
{ {
if (output.Length > 0) if (output.Length > 0)
{ {
@ -38,7 +38,7 @@ namespace CreamInstaller
for (int i = 0; i < messageLines.Length; i++) for (int i = 0; i < messageLines.Length; i++)
{ {
string line = messageLines[i]; string line = messageLines[i];
if (!(line is null)) if (line is not null)
{ {
output += "\n " + messageLines[i]; output += "\n " + messageLines[i];
} }

View file

@ -1,6 +1,7 @@
using Gameloop.Vdf.Linq; using Gameloop.Vdf.Linq;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
namespace CreamInstaller namespace CreamInstaller
@ -8,6 +9,7 @@ namespace CreamInstaller
public class ProgramSelection public class ProgramSelection
{ {
public bool Enabled = false; public bool Enabled = false;
public bool Usable = true;
public string Name; public string Name;
public string RootDirectory; public string RootDirectory;
@ -84,9 +86,23 @@ namespace CreamInstaller
All.Add(this); All.Add(this);
} }
public void Validate()
{
SteamApiDllDirectories.RemoveAll(directory => !Directory.Exists(directory));
if (!Directory.Exists(RootDirectory) || !SteamApiDllDirectories.Any())
{
All.Remove(this);
}
}
public static void ValidateAll()
{
All.ForEach(selection => selection.Validate());
}
public static List<ProgramSelection> All => Program.ProgramSelections; public static List<ProgramSelection> All => Program.ProgramSelections;
public static List<ProgramSelection> AllSafe => All.ToList(); public static List<ProgramSelection> AllSafe => All.FindAll(s => s.Usable);
public static List<ProgramSelection> AllSafeEnabled => AllSafe.FindAll(s => s.Enabled); public static List<ProgramSelection> AllSafeEnabled => AllSafe.FindAll(s => s.Enabled);

View file

@ -136,7 +136,7 @@ namespace CreamInstaller
goto restart; goto restart;
} }
if (appInfo is null || (!(appInfo.Value is VValue) && appInfo.Value.Children().ToList().Count == 0)) if (appInfo is null || (appInfo.Value is not VValue && appInfo.Value.Children().ToList().Count == 0))
{ {
return true; return true;
} }
@ -145,7 +145,7 @@ namespace CreamInstaller
if (type is null || type.ToString() == "Game") if (type is null || type.ToString() == "Game")
{ {
string buildid = appInfo.Value is VValue ? null : appInfo.Value["depots"]?["branches"]?[branch]?["buildid"]?.ToString(); string buildid = appInfo.Value is VValue ? null : appInfo.Value["depots"]?["branches"]?[branch]?["buildid"]?.ToString();
if (buildid is null && !(type is null)) if (buildid is null && type is not null)
{ {
return true; return true;
} }
@ -174,12 +174,12 @@ namespace CreamInstaller
public static List<int> ParseDlcAppIds(VProperty appInfo) public static List<int> ParseDlcAppIds(VProperty appInfo)
{ {
List<int> dlcIds = new(); List<int> dlcIds = new();
if (!(appInfo is VProperty)) if (appInfo is not VProperty)
{ {
return dlcIds; return dlcIds;
} }
if (!(appInfo.Value["extended"] is null)) if (appInfo.Value["extended"] is not null)
{ {
foreach (VProperty property in appInfo.Value["extended"]) foreach (VProperty property in appInfo.Value["extended"])
{ {
@ -196,7 +196,7 @@ namespace CreamInstaller
} }
} }
if (!(appInfo.Value["depots"] is null)) if (appInfo.Value["depots"] is not null)
{ {
foreach (VProperty _property in appInfo.Value["depots"]) foreach (VProperty _property in appInfo.Value["depots"])
{ {

View file

@ -5,7 +5,7 @@
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<ApplicationIcon>Resources\ini.ico</ApplicationIcon> <ApplicationIcon>Resources\ini.ico</ApplicationIcon>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract> <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<Version>2.1.0.1</Version> <Version>2.1.1.0</Version>
<PackageIcon>Resources\ini.ico</PackageIcon> <PackageIcon>Resources\ini.ico</PackageIcon>
<PackageIconUrl /> <PackageIconUrl />
<Description>Automatically generates and installs CreamAPI files for Steam games on the user's computer. It can also generate and install CreamAPI for the Paradox Launcher should the user select a Paradox Interactive game.</Description> <Description>Automatically generates and installs CreamAPI files for Steam games on the user's computer. It can also generate and install CreamAPI for the Paradox Launcher should the user select a Paradox Interactive game.</Description>

View file

@ -36,7 +36,6 @@ namespace CreamInstaller
{ {
return; return;
} }
userProgressBar.Value = value; userProgressBar.Value = value;
} }
@ -164,20 +163,15 @@ namespace CreamInstaller
private async Task Operate() private async Task Operate()
{ {
OperationsCount = ProgramSelection.AllSafeEnabled.Count; List<ProgramSelection> programSelections = ProgramSelection.AllSafeEnabled;
OperationsCount = programSelections.Count;
CompleteOperationsCount = 0; CompleteOperationsCount = 0;
foreach (ProgramSelection selection in ProgramSelection.AllSafe) foreach (ProgramSelection selection in programSelections)
{ {
if (!selection.Enabled)
{
continue;
}
if (!Program.IsProgramRunningDialog(this, selection)) if (!Program.IsProgramRunningDialog(this, selection))
{ {
throw new OperationCanceledException(); throw new OperationCanceledException();
} }
try try
{ {
await OperateFor(selection); await OperateFor(selection);

View file

@ -28,7 +28,7 @@ namespace CreamInstaller
private void StartProgram() private void StartProgram()
{ {
if (!(cancellationTokenSource is null)) if (cancellationTokenSource is not null)
{ {
cancellationTokenSource.Cancel(); cancellationTokenSource.Cancel();
cancellationTokenSource.Dispose(); cancellationTokenSource.Dispose();
@ -195,7 +195,7 @@ namespace CreamInstaller
} }
catch { } catch { }
if (!(updateManager is null) && updateManager.IsUpdatePrepared(latestVersion)) if (updateManager is not null && updateManager.IsUpdatePrepared(latestVersion))
{ {
updateManager.LaunchUpdater(latestVersion); updateManager.LaunchUpdater(latestVersion);
Application.Exit(); Application.Exit();

View file

@ -180,7 +180,18 @@ namespace CreamInstaller
return true; return true;
} }
private readonly List<TreeNode> treeNodes = new(); internal List<TreeNode> TreeNodes => GatherTreeNodes(selectionTreeView.Nodes);
private List<TreeNode> GatherTreeNodes(TreeNodeCollection nodeCollection)
{
List<TreeNode> treeNodes = new();
foreach (TreeNode rootNode in nodeCollection)
{
treeNodes.Add(rootNode);
treeNodes.AddRange(GatherTreeNodes(rootNode.Nodes));
}
return treeNodes;
}
internal List<Task> RunningTasks = new(); internal List<Task> RunningTasks = new();
private void GetCreamApiApplicablePrograms(IProgress<int> progress) private void GetCreamApiApplicablePrograms(IProgress<int> progress)
@ -217,6 +228,7 @@ namespace CreamInstaller
string branch = program.Item3; string branch = program.Item3;
int buildId = program.Item4; int buildId = program.Item4;
string directory = program.Item5; string directory = program.Item5;
ProgramSelection selection = ProgramSelection.FromAppId(appId);
if (Program.Canceled) if (Program.Canceled)
{ {
return; return;
@ -236,6 +248,11 @@ namespace CreamInstaller
} }
if (blockedGame) if (blockedGame)
{ {
if (selection is not null)
{
selection.Enabled = false;
selection.Usable = false;
}
continue; continue;
} }
} }
@ -315,7 +332,8 @@ namespace CreamInstaller
return; return;
} }
ProgramSelection selection = ProgramSelection.FromAppId(appId) ?? new(); selection ??= new();
selection.Usable = true;
selection.Name = name; selection.Name = name;
selection.RootDirectory = directory; selection.RootDirectory = directory;
selection.SteamAppId = appId; selection.SteamAppId = appId;
@ -347,14 +365,12 @@ namespace CreamInstaller
return; return;
} }
TreeNode programNode = treeNodes.Find(s => s.Name == "" + appId) ?? new(); TreeNode programNode = TreeNodes.Find(s => s.Name == "" + appId) ?? new();
programNode.Name = "" + appId; programNode.Name = "" + appId;
programNode.Text = /*(appId > 0 ? $"[{appId}] " : "") +*/ name; programNode.Text = /*(appId > 0 ? $"[{appId}] " : "") +*/ name;
programNode.Checked = selection.Enabled; programNode.Checked = selection.Enabled;
programNode.Remove(); programNode.Remove();
selectionTreeView.Nodes.Add(programNode); selectionTreeView.Nodes.Add(programNode);
treeNodes.Remove(programNode);
treeNodes.Add(programNode);
if (appId == 0) // paradox launcher if (appId == 0) // paradox launcher
{ {
// maybe add game and/or dlc choice here? // maybe add game and/or dlc choice here?
@ -374,14 +390,12 @@ namespace CreamInstaller
selection.SelectedSteamDlc[dlcApp.Key] = dlcApp.Value; selection.SelectedSteamDlc[dlcApp.Key] = dlcApp.Value;
} }
TreeNode dlcNode = treeNodes.Find(s => s.Name == "" + dlcApp.Key) ?? new(); TreeNode dlcNode = TreeNodes.Find(s => s.Name == "" + dlcApp.Key) ?? new();
dlcNode.Name = "" + dlcApp.Key; dlcNode.Name = "" + dlcApp.Key;
dlcNode.Text = dlcApp.Value; dlcNode.Text = dlcApp.Value;
dlcNode.Checked = selection.SelectedSteamDlc.Contains(dlcApp); dlcNode.Checked = selection.SelectedSteamDlc.Contains(dlcApp);
dlcNode.Remove(); dlcNode.Remove();
programNode.Nodes.Add(dlcNode); programNode.Nodes.Add(dlcNode);
treeNodes.Remove(dlcNode);
treeNodes.Add(dlcNode);
} }
} }
}); });
@ -405,177 +419,162 @@ namespace CreamInstaller
private async void OnLoad(bool validating = false) private async void OnLoad(bool validating = false)
{ {
Program.Canceled = false; retry:
blockedGamesCheckBox.Enabled = false; try
blockProtectedHelpButton.Enabled = false;
cancelButton.Enabled = true;
scanButton.Enabled = false;
noneFoundLabel.Visible = false;
allCheckBox.Enabled = false;
installButton.Enabled = false;
uninstallButton.Enabled = installButton.Enabled;
selectionTreeView.Enabled = false;
label2.Visible = true;
progressBar1.Visible = true;
progressBar1.Value = 0;
groupBox1.Size = new(groupBox1.Size.Width, groupBox1.Size.Height - 44);
bool setup = true;
int maxProgress = 0;
int curProgress = 0;
Progress<int> progress = new();
IProgress<int> iProgress = progress;
progress.ProgressChanged += (sender, _progress) =>
{ {
if (_progress < 0) Program.Canceled = false;
blockedGamesCheckBox.Enabled = false;
blockProtectedHelpButton.Enabled = false;
cancelButton.Enabled = true;
scanButton.Enabled = false;
noneFoundLabel.Visible = false;
allCheckBox.Enabled = false;
installButton.Enabled = false;
uninstallButton.Enabled = installButton.Enabled;
selectionTreeView.Enabled = false;
label2.Visible = true;
progressBar1.Visible = true;
progressBar1.Value = 0;
groupBox1.Size = new(groupBox1.Size.Width, groupBox1.Size.Height - 44);
bool setup = true;
int maxProgress = 0;
int curProgress = 0;
Progress<int> progress = new();
IProgress<int> iProgress = progress;
progress.ProgressChanged += (sender, _progress) =>
{ {
maxProgress = -_progress; if (_progress < 0)
} {
else maxProgress = -_progress;
}
else
{
curProgress = _progress;
}
int p = Math.Max(Math.Min((int)((float)(curProgress / (float)maxProgress) * 100), 100), 0);
if (validating)
{
label2.Text = $"Validating . . . {p}% ({curProgress}/{maxProgress})";
}
else if (setup)
{
label2.Text = $"Setting up SteamCMD . . . {p}% ({curProgress}/{maxProgress})";
}
else
{
label2.Text = $"Gathering and caching your applicable games and their DLCs . . . {p}% ({curProgress}/{maxProgress})";
}
progressBar1.Value = p;
};
iProgress.Report(-1660); // not exact, number varies
int cur = 0;
iProgress.Report(cur);
if (!validating)
{ {
curProgress = _progress; label2.Text = "Setting up SteamCMD . . . ";
} }
int p = Math.Max(Math.Min((int)((float)(curProgress / (float)maxProgress) * 100), 100), 0); if (!Directory.Exists(SteamCMD.DirectoryPath))
if (validating)
{ {
label2.Text = $"Validating . . . {p}% ({curProgress}/{maxProgress})"; Directory.CreateDirectory(SteamCMD.DirectoryPath);
}
else if (setup)
{
label2.Text = $"Setting up SteamCMD . . . {p}% ({curProgress}/{maxProgress})";
}
else
{
label2.Text = $"Gathering and caching your applicable games and their DLCs . . . {p}% ({curProgress}/{maxProgress})";
} }
progressBar1.Value = p; FileSystemWatcher watcher = new(SteamCMD.DirectoryPath);
}; watcher.Changed += (sender, e) => iProgress.Report(++cur);
watcher.Filter = "*";
watcher.IncludeSubdirectories = true;
watcher.EnableRaisingEvents = true;
await Task.Run(() => SteamCMD.Setup());
watcher.Dispose();
iProgress.Report(-1660); // not exact, number varies setup = false;
int cur = 0; if (!validating)
iProgress.Report(cur);
if (!validating)
{
label2.Text = "Setting up SteamCMD . . . ";
}
if (!Directory.Exists(SteamCMD.DirectoryPath))
{
Directory.CreateDirectory(SteamCMD.DirectoryPath);
}
FileSystemWatcher watcher = new(SteamCMD.DirectoryPath);
watcher.Changed += (sender, e) => iProgress.Report(++cur);
watcher.Filter = "*";
watcher.IncludeSubdirectories = true;
watcher.EnableRaisingEvents = true;
await Task.Run(() => SteamCMD.Setup());
watcher.Dispose();
setup = false;
if (!validating)
{
selectionTreeView.Nodes.Clear();
Program.ProgramSelections.Clear();
label2.Text = "Gathering and caching your applicable games and their DLCs . . . ";
}
await Task.Run(() => GetCreamApiApplicablePrograms(iProgress));
ProgramSelection.All.ForEach(selection => selection.SteamApiDllDirectories.RemoveAll(directory => !Directory.Exists(directory)));
ProgramSelection.All.RemoveAll(selection => !Directory.Exists(selection.RootDirectory) || !selection.SteamApiDllDirectories.Any());
foreach (TreeNode treeNode in treeNodes)
{
if (treeNode.Parent is null && ProgramSelection.FromAppId(int.Parse(treeNode.Name)) is null)
{ {
treeNode.Remove(); label2.Text = "Gathering and caching your applicable games and their DLCs . . . ";
}
await Task.Run(() => GetCreamApiApplicablePrograms(iProgress));
ProgramSelection.ValidateAll();
TreeNodes.ForEach(node =>
{
if (node.Parent is null && ProgramSelection.FromAppId(int.Parse(node.Name)) is null)
{
node.Remove();
}
});
progressBar1.Value = 100;
groupBox1.Size = new(groupBox1.Size.Width, groupBox1.Size.Height + 44);
label2.Visible = false;
progressBar1.Visible = false;
selectionTreeView.Enabled = ProgramSelection.All.Any();
allCheckBox.Enabled = selectionTreeView.Enabled;
noneFoundLabel.Visible = !selectionTreeView.Enabled;
installButton.Enabled = ProgramSelection.AllSafeEnabled.Any();
uninstallButton.Enabled = installButton.Enabled;
cancelButton.Enabled = false;
scanButton.Enabled = true;
blockedGamesCheckBox.Enabled = true;
blockProtectedHelpButton.Enabled = true;
label2.Text = "Validating . . . ";
if (!validating && !Program.Canceled)
{
OnLoad(true);
} }
} }
//SetMinimumSizeFromTreeView(); catch (Exception e)
progressBar1.Value = 100;
groupBox1.Size = new(groupBox1.Size.Width, groupBox1.Size.Height + 44);
label2.Visible = false;
progressBar1.Visible = false;
selectionTreeView.Enabled = ProgramSelection.All.Any();
allCheckBox.Enabled = selectionTreeView.Enabled;
noneFoundLabel.Visible = !selectionTreeView.Enabled;
installButton.Enabled = ProgramSelection.AllSafeEnabled.Any();
uninstallButton.Enabled = installButton.Enabled;
cancelButton.Enabled = false;
scanButton.Enabled = true;
blockedGamesCheckBox.Enabled = true;
blockProtectedHelpButton.Enabled = true;
label2.Text = "Validating . . . ";
if (!validating && !Program.Canceled)
{ {
OnLoad(true); if (ExceptionHandler.OutputException(e))
{
goto retry;
}
Close();
} }
} }
/*private const int GWL_STYLE = -16;
private const int WS_VSCROLL = 0x00200000;
private const int WS_HSCROLL = 0x00100000;
[DllImport("user32.dll", ExactSpelling = false, CharSet = CharSet.Auto)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
private const int MINIMUM_SIZE_INCREMENT = 8;
private void SetMinimumSizeFromTreeView()
{
Dictionary<TreeNode, bool> expansionState = new();
foreach (TreeNode node in treeView1.Nodes) expansionState[node] = node.IsExpanded;
treeView1.ExpandAll();
Size minimumSize = MinimumSize;
Point point;
int style = GetWindowLong(treeView1.Handle, GWL_STYLE);
while ((style & WS_HSCROLL) != 0)
{
minimumSize.Width += MINIMUM_SIZE_INCREMENT;
point = Location;
point.X -= MINIMUM_SIZE_INCREMENT / 2;
Location = point;
MinimumSize = minimumSize;
style = GetWindowLong(treeView1.Handle, GWL_STYLE);
Update();
}
foreach (TreeNode node in treeView1.Nodes) if (!expansionState[node]) node.Collapse();
}*/
private void OnTreeViewNodeCheckedChanged(object sender, TreeViewEventArgs e) private void OnTreeViewNodeCheckedChanged(object sender, TreeViewEventArgs e)
{ {
if (e.Action == TreeViewAction.Unknown) if (e.Action == TreeViewAction.Unknown)
{ {
return; return;
} }
TreeNode node = e.Node;
ProgramSelection selection = ProgramSelection.FromAppId(int.Parse(e.Node.Name)); if (node is not null)
if (selection is null)
{ {
ProgramSelection.FromAppId(int.Parse(e.Node.Parent.Name)).ToggleDlc(int.Parse(e.Node.Name), e.Node.Checked); ProgramSelection selection = ProgramSelection.FromAppId(int.Parse(node.Name));
e.Node.Parent.Checked = e.Node.Parent.Nodes.Cast<TreeNode>().ToList().Any(treeNode => treeNode.Checked); if (selection is null)
}
else
{
if (selection.AllSteamDlc.Any())
{ {
selection.ToggleAllDlc(e.Node.Checked); TreeNode parent = node.Parent;
e.Node.Nodes.Cast<TreeNode>().ToList().ForEach(treeNode => treeNode.Checked = e.Node.Checked); if (parent is not null)
{
ProgramSelection.FromAppId(int.Parse(parent.Name)).ToggleDlc(int.Parse(node.Name), node.Checked);
parent.Checked = parent.Nodes.Cast<TreeNode>().ToList().Any(treeNode => treeNode.Checked);
}
} }
else else
{ {
selection.Enabled = e.Node.Checked; if (selection.AllSteamDlc.Any())
{
selection.ToggleAllDlc(node.Checked);
node.Nodes.Cast<TreeNode>().ToList().ForEach(treeNode => treeNode.Checked = node.Checked);
}
else
{
selection.Enabled = node.Checked;
}
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
allCheckBox.Checked = TreeNodes.TrueForAll(treeNode => treeNode.Checked);
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
} }
allCheckBox.CheckedChanged -= OnAllCheckBoxChanged;
allCheckBox.Checked = treeNodes.TrueForAll(treeNode => treeNode.Checked);
allCheckBox.CheckedChanged += OnAllCheckBoxChanged;
} }
installButton.Enabled = ProgramSelection.AllSafeEnabled.Any(); installButton.Enabled = ProgramSelection.AllSafeEnabled.Any();
uninstallButton.Enabled = installButton.Enabled; uninstallButton.Enabled = installButton.Enabled;
@ -612,26 +611,13 @@ namespace CreamInstaller
} }
} }
}; };
retry: OnLoad();
try
{
OnLoad();
}
catch (Exception e)
{
if (ExceptionHandler.OutputException(e))
{
goto retry;
}
Close();
}
} }
private static void PopulateParadoxLauncherDlc(ProgramSelection paradoxLauncher = null) private static void PopulateParadoxLauncherDlc(ProgramSelection paradoxLauncher = null)
{ {
paradoxLauncher ??= ProgramSelection.FromAppId(0); paradoxLauncher ??= ProgramSelection.FromAppId(0);
if (!(paradoxLauncher is null)) if (paradoxLauncher is not null)
{ {
paradoxLauncher.ExtraSteamAppIdDlc.Clear(); paradoxLauncher.ExtraSteamAppIdDlc.Clear();
foreach (ProgramSelection selection in ProgramSelection.AllSafeEnabled) foreach (ProgramSelection selection in ProgramSelection.AllSafeEnabled)
@ -640,12 +626,10 @@ namespace CreamInstaller
{ {
continue; continue;
} }
if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive") if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive")
{ {
continue; continue;
} }
paradoxLauncher.ExtraSteamAppIdDlc.Add(new(selection.SteamAppId, selection.Name, selection.SelectedSteamDlc)); paradoxLauncher.ExtraSteamAppIdDlc.Add(new(selection.SteamAppId, selection.Name, selection.SelectedSteamDlc));
} }
if (!paradoxLauncher.ExtraSteamAppIdDlc.Any()) if (!paradoxLauncher.ExtraSteamAppIdDlc.Any())
@ -656,12 +640,10 @@ namespace CreamInstaller
{ {
continue; continue;
} }
if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive") if (selection.AppInfo.Value["extended"]["publisher"].ToString() != "Paradox Interactive")
{ {
continue; continue;
} }
paradoxLauncher.ExtraSteamAppIdDlc.Add(new(selection.SteamAppId, selection.Name, selection.AllSteamDlc)); paradoxLauncher.ExtraSteamAppIdDlc.Add(new(selection.SteamAppId, selection.Name, selection.AllSteamDlc));
} }
} }
@ -671,7 +653,7 @@ namespace CreamInstaller
private static bool ParadoxLauncherDlcDialog(Form form) private static bool ParadoxLauncherDlcDialog(Form form)
{ {
ProgramSelection paradoxLauncher = ProgramSelection.FromAppId(0); ProgramSelection paradoxLauncher = ProgramSelection.FromAppId(0);
if (!(paradoxLauncher is null) && paradoxLauncher.Enabled) if (paradoxLauncher is not null && paradoxLauncher.Enabled)
{ {
PopulateParadoxLauncherDlc(paradoxLauncher); PopulateParadoxLauncherDlc(paradoxLauncher);
if (!paradoxLauncher.ExtraSteamAppIdDlc.Any()) if (!paradoxLauncher.ExtraSteamAppIdDlc.Any())
@ -691,7 +673,7 @@ namespace CreamInstaller
private void OnAccept(bool uninstall = false) private void OnAccept(bool uninstall = false)
{ {
if (ProgramSelection.All.Count > 0) if (ProgramSelection.All.Any())
{ {
foreach (ProgramSelection selection in ProgramSelection.AllSafeEnabled) foreach (ProgramSelection selection in ProgramSelection.AllSafeEnabled)
{ {
@ -700,12 +682,10 @@ namespace CreamInstaller
return; return;
} }
} }
if (ParadoxLauncherDlcDialog(this)) if (ParadoxLauncherDlcDialog(this))
{ {
return; return;
} }
Hide(); Hide();
InstallForm installForm = new(this, uninstall); InstallForm installForm = new(this, uninstall);
installForm.ShowDialog(); installForm.ShowDialog();
@ -745,19 +725,21 @@ namespace CreamInstaller
private void OnAllCheckBoxChanged(object sender, EventArgs e) private void OnAllCheckBoxChanged(object sender, EventArgs e)
{ {
bool shouldCheck = false; bool shouldCheck = false;
foreach (TreeNode treeNode in treeNodes) TreeNodes.ForEach(node =>
{ {
if (treeNode.Parent is null) if (node.Parent is null)
{ {
if (!treeNode.Checked) if (!node.Checked)
{ {
shouldCheck = true; shouldCheck = true;
} }
if (node.Checked != shouldCheck)
treeNode.Checked = shouldCheck; {
OnTreeViewNodeCheckedChanged(null, new(treeNode, TreeViewAction.ByMouse)); node.Checked = shouldCheck;
OnTreeViewNodeCheckedChanged(null, new(node, TreeViewAction.ByMouse));
}
} }
} });
allCheckBox.Checked = shouldCheck; allCheckBox.Checked = shouldCheck;
} }