diff --git a/ConsoleUI/DependencyScreen.cs b/ConsoleUI/DependencyScreen.cs index 21f6b404d..b20b53d36 100644 --- a/ConsoleUI/DependencyScreen.cs +++ b/ConsoleUI/DependencyScreen.cs @@ -66,15 +66,20 @@ public DependencyScreen(GameInstanceManager mgr, Registry reg, ChangePlan cp, Ha ); dependencyList.AddTip("+", Properties.Resources.Toggle); dependencyList.AddBinding(Keys.Plus, (object sender, ConsoleTheme theme) => { - ChangePlan.toggleContains(accepted, dependencyList.Selection.module); + var mod = dependencyList.Selection.module; + if (accepted.Contains(mod) || TryWithoutConflicts(accepted.Append(mod))) { + ChangePlan.toggleContains(accepted, mod); + } return true; }); dependencyList.AddTip($"{Properties.Resources.Ctrl}+A", Properties.Resources.SelectAll); dependencyList.AddBinding(Keys.CtrlA, (object sender, ConsoleTheme theme) => { - foreach (var kvp in dependencies) { - if (!accepted.Contains(kvp.Key)) { - ChangePlan.toggleContains(accepted, kvp.Key); + if (TryWithoutConflicts(dependencies.Keys)) { + foreach (var kvp in dependencies) { + if (!accepted.Contains(kvp.Key)) { + ChangePlan.toggleContains(accepted, kvp.Key); + } } } return true; @@ -107,16 +112,15 @@ public DependencyScreen(GameInstanceManager mgr, Registry reg, ChangePlan cp, Ha AddTip("F9", Properties.Resources.Accept); AddBinding(Keys.F9, (object sender, ConsoleTheme theme) => { - foreach (CkanModule mod in accepted) { - plan.Install.Add(mod); - } - // Add the rest to rejected - foreach (var kvp in dependencies) { - if (!accepted.Contains(kvp.Key)) { - rejected.Add(kvp.Key.identifier); - } + if (TryWithoutConflicts(accepted)) { + plan.Install.UnionWith(accepted); + // Add the rest to rejected + rejected.UnionWith(dependencies.Keys + .Except(accepted) + .Select(m => m.identifier)); + return false; } - return false; + return true; }); } @@ -178,6 +182,36 @@ private string StatusSymbol(CkanModule mod) => accepted.Contains(mod) ? installing : notinstalled; + private bool TryWithoutConflicts(IEnumerable toAdd) + { + if (HasConflicts(toAdd, out List conflictDescriptions)) { + RaiseError("{0}", string.Join(Environment.NewLine, + conflictDescriptions)); + return false; + } + return true; + } + + private bool HasConflicts(IEnumerable toAdd, + out List descriptions) + { + try + { + var resolver = new RelationshipResolver( + plan.Install.Concat(toAdd).Distinct(), + plan.Remove.Select(ident => registry.InstalledModule(ident)?.Module), + RelationshipResolverOptions.ConflictsOpts(), registry, + manager.CurrentInstance.VersionCriteria()); + descriptions = resolver.ConflictDescriptions.ToList(); + return descriptions.Count > 0; + } + catch (DependencyNotSatisfiedKraken k) + { + descriptions = new List() { k.Message }; + return true; + } + } + private readonly HashSet accepted = new HashSet(); private readonly HashSet rejected; diff --git a/ConsoleUI/InstallScreen.cs b/ConsoleUI/InstallScreen.cs index 46c6e9987..969c49c83 100644 --- a/ConsoleUI/InstallScreen.cs +++ b/ConsoleUI/InstallScreen.cs @@ -81,7 +81,8 @@ public override void Run(ConsoleTheme theme, Action process = null registry.InstalledModules .Select(im => im.Module) .ToArray(), - plan.Install)) + plan.Install) + ?? m) .ToArray(); inst.InstallList(iList, resolvOpts, regMgr, ref possibleConfigOnlyDirs, dl); plan.Install.Clear();