diff --git a/GUI/GUIMod.cs b/GUI/GUIMod.cs index 0ebc9e2223..09bed28684 100644 --- a/GUI/GUIMod.cs +++ b/GUI/GUIMod.cs @@ -222,6 +222,31 @@ public CkanModule ToModule() return null; } + /// + /// Set the properties to match a change set element. + /// Doesn't update grid, use SetInstallChecked or SetUpgradeChecked + /// if you need to update the grid. + /// + /// Type of change + public void SetRequestedChange(GUIModChangeType change) + { + switch (change) + { + case GUIModChangeType.Install: + IsInstallChecked = true; + IsUpgradeChecked = false; + break; + case GUIModChangeType.Remove: + IsInstallChecked = false; + IsUpgradeChecked = false; + break; + case GUIModChangeType.Update: + IsInstallChecked = true; + IsUpgradeChecked = true; + break; + } + } + public static implicit operator CkanModule(GUIMod mod) { return mod.ToModule(); diff --git a/GUI/MainModList.cs b/GUI/MainModList.cs index 85e72b14a6..e4ce47d2e3 100644 --- a/GUI/MainModList.cs +++ b/GUI/MainModList.cs @@ -14,11 +14,6 @@ namespace CKAN { public partial class Main { - private void UpdateFilters(Main control) - { - Util.Invoke(control, _UpdateFilters); - } - private IEnumerable _SortRowsByColumn(IEnumerable rows) { switch (this.configuration.SortByColumnIndex) @@ -97,9 +92,15 @@ private long InstallDateSorter(DataGridViewRow row) return -(row.Tag as GUIMod)?.InstallDate?.Ticks ?? 0; } + private void UpdateFilters(Main control) + { + Util.Invoke(control, _UpdateFilters); + } + private void _UpdateFilters() { - if (ModList == null) return; + if (ModList == null) + return; // Each time a row in DataGridViewRow is changed, DataGridViewRow updates the view. Which is slow. // To make the filtering process faster, Copy the list of rows. Filter out the hidden and replace the @@ -138,12 +139,12 @@ private void _UpdateFilters() } } - public void UpdateModsList(Boolean repo_updated = false, List mc = null) + public void UpdateModsList(Boolean repo_updated = false, IEnumerable mc = null) { Util.Invoke(this, () => _UpdateModsList(repo_updated, mc ?? new List())); } - private void _UpdateModsList(bool repo_updated, List mc) + private void _UpdateModsList(bool repo_updated, IEnumerable mc) { log.Info("Updating the mod list"); @@ -164,6 +165,17 @@ private void _UpdateModsList(bool repo_updated, List mc) .Select(m => new GUIMod(m, registry, versionCriteria, true)) ); + if (mc != null) + { + foreach (ModChange change in mc) + { + // Propagate IsInstallChecked and IsUpgradeChecked to the next generation + gui_mods.FirstOrDefault( + mod => mod.Identifier == change.Mod.Identifier + )?.SetRequestedChange(change.ChangeType); + } + } + var old_modules = mainModList.Modules.ToDictionary(m => m, m => m.IsIncompatible); if (repo_updated) { @@ -195,9 +207,8 @@ private void _UpdateModsList(bool repo_updated, List mc) } } - // Update our mod listing. If we're doing a repo update, then we don't refresh - // all (in case the user has selected changes they wish to apply). - mainModList.ConstructModList(gui_mods.ToList(), mc, !repo_updated, configuration.HideEpochs, configuration.HideV); + // Update our mod listing + mainModList.ConstructModList(gui_mods.ToList(), mc, configuration.HideEpochs, configuration.HideV); mainModList.Modules = new ReadOnlyCollection( mainModList.full_list_of_mod_rows.Values.Select(row => row.Tag as GUIMod).ToList()); @@ -673,39 +684,22 @@ public int CountModsByFilter(GUIModFilter filter) /// /// Constructs the mod list suitable for display to the user. - /// This manipulates full_list_of_mod_rows as it runs, and by default - /// will only update entries which have changed or were previously missing. - /// (Set refreshAll to force update everything.) + /// Manipulates full_list_of_mod_rows. /// - /// The mod list. /// A list of modules that may require updating - /// If set to true then always rebuild the list from scratch + /// Changes the user has made /// If true, remove epochs from the displayed versions - public IEnumerable ConstructModList(IEnumerable modules, List mc = null, bool refreshAll = false, bool hideEpochs = false, bool hideV = false) - { - - if (refreshAll || full_list_of_mod_rows == null) - { - full_list_of_mod_rows = new Dictionary(); - } - - // We're only going to update the status of rows that either don't already exist, - // or which exist but have changed their latest version - // or whose installation status has changed - // - // TODO: Will this catch a mod where the latest version number remains the same, but - // another part of the metadata (eg: dependencies or description) has changed? - IEnumerable rowsToUpdate = modules.Where( - mod => !full_list_of_mod_rows.ContainsKey(mod.Identifier) || - mod.LatestVersion != (full_list_of_mod_rows[mod.Identifier].Tag as GUIMod)?.LatestVersion || - mod.IsInstalled != (full_list_of_mod_rows[mod.Identifier].Tag as GUIMod)?.IsInstalled); - - // Let's update our list! - foreach (var mod in rowsToUpdate) - { - full_list_of_mod_rows.Remove(mod.Identifier); - full_list_of_mod_rows.Add(mod.Identifier, MakeRow(mod, mc, hideEpochs, hideV)); - } + /// If true, strip 'v' prefix from versions + /// The mod list + public IEnumerable ConstructModList( + IEnumerable modules, IEnumerable mc = null, + bool hideEpochs = false, bool hideV = false) + { + List changes = mc?.ToList(); + full_list_of_mod_rows = modules.ToDictionary( + gm => gm.Identifier, + gm => MakeRow(gm, changes, hideEpochs, hideV) + ); return full_list_of_mod_rows.Values; } diff --git a/GUI/MainRepo.cs b/GUI/MainRepo.cs index fd5c1de5a7..c66f7a441d 100644 --- a/GUI/MainRepo.cs +++ b/GUI/MainRepo.cs @@ -91,7 +91,7 @@ private void PostUpdateRepo(object sender, RunWorkerCompletedEventArgs e) { if ((e.Result as int? ?? 0) > 0) { - UpdateModsList(repo_updated: true); + UpdateModsList(true, ChangeSet); AddStatusMessage("Repositories successfully updated."); ShowRefreshQuestion(); HideWaitDialog(true);