diff --git a/CHANGELOG.md b/CHANGELOG.md index 2081bae7cb..617fc89b54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file. - [GUI] Remove duplicate Install changes for upgrades (#3706 by: HebaruSan; reviewed: techman83) - [GUI] Fix GUI freeze with non-empty changeset at startup (#3708 by: HebaruSan; reviewed: techman83) +- [GUI] Use changeset tab for reinstall (#3726 by: HebaruSan; reviewed: techman83) ### Internal diff --git a/GUI/Controls/Changeset.cs b/GUI/Controls/Changeset.cs index 3c75ecd5c6..c58d84efed 100644 --- a/GUI/Controls/Changeset.cs +++ b/GUI/Controls/Changeset.cs @@ -17,6 +17,7 @@ public Changeset() public void LoadChangeset(List changes, List AlertLabels) { + changeset = changes; alertLabels = AlertLabels; ChangesListView.Items.Clear(); if (changes != null) @@ -46,7 +47,7 @@ public ListView.SelectedListViewItemCollection SelectedItems public event Action OnSelectedItemsChanged; - public event Action OnConfirmChanges; + public event Action> OnConfirmChanges; public event Action OnCancelChanges; private void ChangesListView_SelectedIndexChanged(object sender, EventArgs e) @@ -56,11 +57,12 @@ private void ChangesListView_SelectedIndexChanged(object sender, EventArgs e) private void ConfirmChangesButton_Click(object sender, EventArgs e) { - OnConfirmChanges?.Invoke(); + OnConfirmChanges?.Invoke(changeset); } private void CancelChangesButton_Click(object sender, EventArgs e) { + changeset = null; OnCancelChanges?.Invoke(true); } @@ -92,6 +94,7 @@ private ListViewItem makeItem(ModChange change) }; } + private List changeset; private List alertLabels; } } diff --git a/GUI/Controls/ManageMods.cs b/GUI/Controls/ManageMods.cs index c5c11b85db..b5d639700f 100644 --- a/GUI/Controls/ManageMods.cs +++ b/GUI/Controls/ManageMods.cs @@ -9,6 +9,7 @@ using log4net; +using CKAN.Extensions; using CKAN.Versioning; namespace CKAN.GUI @@ -995,37 +996,42 @@ private void reinstallToolStripMenuItem_Click(object sender, EventArgs e) if (module == null || !module.IsCKAN) return; - YesNoDialog reinstallDialog = new YesNoDialog(); - string confirmationText = string.Format(Properties.Resources.MainReinstallConfirm, module.Name); - if (reinstallDialog.ShowYesNoDialog(Main.Instance, confirmationText) == DialogResult.No) - return; - IRegistryQuerier registry = RegistryManager.Instance(Main.Instance.CurrentInstance).registry; - // Build the list of changes, first the mod to remove: - List toReinstall = new List() - { - new ModChange(module.ToModule(), GUIModChangeType.Remove) - }; - // Then everything we need to re-install: - var revdep = registry.FindReverseDependencies(new List() { module.Identifier }); + // Find everything we need to re-install + var revdep = registry.FindReverseDependencies(new List() { module.Identifier }) + .Select(ident => registry.InstalledModule(ident)) + .ToHashSet(); var goners = revdep.Union( registry.FindRemovableAutoInstalled( registry.InstalledModules - .Where(im => !revdep.Contains(im.identifier)) + .Where(im => !revdep.Contains(im)) .ToList(), - Main.Instance.CurrentInstance.VersionCriteria()) - .Select(im => im.Module.identifier)); - foreach (string id in goners) - { - toReinstall.Add(new ModChange( - (mainModList.full_list_of_mod_rows[id]?.Tag as GUIMod).ToModule(), - GUIModChangeType.Install)); - } - if (StartChangeSet != null) - { - StartChangeSet(toReinstall); - } + Main.Instance.CurrentInstance.VersionCriteria())); + + // Build the list of changes + StartChangeSet?.Invoke(goners + .SelectMany(instMod => instMod.AutoInstalled + ? new ModChange[] + { + new ModChange(instMod.Module, GUIModChangeType.Remove), + // Let resolver find it so the auto-installed flag is set + } + : new ModChange[] + { + new ModChange(instMod.Module, GUIModChangeType.Remove), + new ModChange( + // Install current available mod from registry, if found + registry.GetModuleByVersion(instMod.identifier, instMod.Module.version) + ?? instMod.Module, + GUIModChangeType.Install, + // Preserve auto-installed checkbox + instMod.AutoInstalled + // We don't use the depending mod here, so just fake it + ? (SelectionReason)new SelectionReason.Depends(module.ToModule()) + : new SelectionReason.UserRequested()), + }) + .ToList()); } private void purgeContentsToolStripMenuItem_Click(object sender, EventArgs e) diff --git a/GUI/Main/Main.cs b/GUI/Main/Main.cs index b1c3a6f645..5475429b2e 100644 --- a/GUI/Main/Main.cs +++ b/GUI/Main/Main.cs @@ -706,7 +706,7 @@ private void ManageMods_OnChangeSetChanged(List changeset) if (changeset != null && changeset.Any()) { tabController.ShowTab("ChangesetTabPage", 1, false); - UpdateChangesDialog(changeset.ToList()); + UpdateChangesDialog(changeset); auditRecommendationsMenuItem.Enabled = false; } else @@ -862,9 +862,8 @@ private void GameExit(GameInstance inst) // This is used by Reinstall private void ManageMods_StartChangeSet(List changeset) { - Wait.StartWaiting(InstallMods, PostInstallMods, true, - new KeyValuePair, RelationshipResolverOptions>( - changeset, RelationshipResolver.DependsOnlyOpts())); + UpdateChangesDialog(changeset); + tabController.ShowTab("ChangesetTabPage", 1); } private void RefreshModList(Dictionary oldModules = null) diff --git a/GUI/Main/MainChangeset.cs b/GUI/Main/MainChangeset.cs index e968eb4c4c..486248f9ca 100644 --- a/GUI/Main/MainChangeset.cs +++ b/GUI/Main/MainChangeset.cs @@ -31,23 +31,20 @@ private void Changeset_OnCancelChanges(bool reset) tabController.ShowTab("ManageModsTabPage"); } - private void Changeset_OnConfirmChanges() + private void Changeset_OnConfirmChanges(List changeset) { DisableMainWindow(); - - // Using the changeset passed in can cause issues with versions. - // An example is Mechjeb for FAR at 25/06/2015 with a 1.0.2 install. - // TODO Work out why this is. try { Wait.StartWaiting(InstallMods, PostInstallMods, true, new KeyValuePair, RelationshipResolverOptions>( - ManageMods.mainModList - .ComputeUserChangeSet(RegistryManager.Instance(CurrentInstance).registry, CurrentInstance.VersionCriteria()) + changeset + .Where(change => + // Skip dependencies so auto-installed checkbox is set + !(change.Reasons.Any(reason => + reason is SelectionReason.Depends))) .ToList(), - RelationshipResolver.DependsOnlyOpts() - ) - ); + RelationshipResolver.DependsOnlyOpts())); } catch (InvalidOperationException) {