diff --git a/CHANGELOG.md b/CHANGELOG.md index 57c9f68e5..83ea77dc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. ## v1.35.3 +### Bugfixes + +- [GUI] Set focus better on Ctrl+F (#4230 by: HebaruSan) + ### Internal - [Netkan] Tests for Newtonsoft.Json's handling of octal literals in version files (#4227 by: HebaruSan) diff --git a/Cmdline/Action/Search.cs b/Cmdline/Action/Search.cs index d6d62d6b9..1b8262e75 100644 --- a/Cmdline/Action/Search.cs +++ b/Cmdline/Action/Search.cs @@ -70,8 +70,8 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) } // Present the results. - if (!matching_compatible.Any() - && (!options.all || !matching_incompatible.Any())) + if (matching_compatible.Count == 0 + && (!options.all || matching_incompatible.Count == 0)) { return Exit.OK; } @@ -89,7 +89,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) mod.@abstract); } - if (matching_incompatible.Any()) + if (matching_incompatible.Count != 0) { user.RaiseMessage(Properties.Resources.SearchIncompatibleModsHeader); foreach (CkanModule mod in matching_incompatible) diff --git a/Cmdline/Action/Show.cs b/Cmdline/Action/Show.cs index 64601f083..139af0bb4 100644 --- a/Cmdline/Action/Show.cs +++ b/Cmdline/Action/Show.cs @@ -68,7 +68,7 @@ public int RunCommand(CKAN.GameInstance instance, object raw_options) var matches = search.PerformSearch(instance, modName); // Display the results of the search. - if (!matches.Any()) + if (matches.Count == 0) { // No matches found. user.RaiseMessage(Properties.Resources.ShowNoClose); diff --git a/Core/GameInstanceManager.cs b/Core/GameInstanceManager.cs index b778ae556..c605b7cbc 100644 --- a/Core/GameInstanceManager.cs +++ b/Core/GameInstanceManager.cs @@ -133,7 +133,7 @@ public GameInstanceManager(IUser user, IConfiguration? configuration = null) // If we know of no instances, try to find one. // Otherwise, we know of too many instances! // We don't know which one to pick, so we return null. - return !instances.Any() ? FindAndRegisterDefaultInstances() : null; + return instances.Count == 0 ? FindAndRegisterDefaultInstances() : null; } /// @@ -145,7 +145,7 @@ public GameInstanceManager(IUser user, IConfiguration? configuration = null) /// public GameInstance? FindAndRegisterDefaultInstances() { - if (instances.Any()) + if (instances.Count != 0) { throw new KSPManagerKraken("Attempted to scan for defaults with instances"); } diff --git a/Core/ModuleInstaller.cs b/Core/ModuleInstaller.cs index d440a00e3..6b99ea9aa 100644 --- a/Core/ModuleInstaller.cs +++ b/Core/ModuleInstaller.cs @@ -779,7 +779,7 @@ public void UninstallList(IEnumerable mods, .ToList(); // If there is nothing to uninstall, skip out. - if (!goners.Any()) + if (goners.Count == 0) { return; } diff --git a/Core/Registry/Registry.cs b/Core/Registry/Registry.cs index d7c2df19e..dbfe47aca 100644 --- a/Core/Registry/Registry.cs +++ b/Core/Registry/Registry.cs @@ -1164,7 +1164,7 @@ public static IEnumerable FindReverseDependencies( // The empty list has no reverse dependencies // (Don't remove broken modules if we're only installing) - if (modulesToRemove.Any()) + if (modulesToRemove.Count != 0) { // All modules in the input are included in the output foreach (string starter in modulesToRemove) diff --git a/Core/Relationships/RelationshipResolver.cs b/Core/Relationships/RelationshipResolver.cs index 40c6aeb91..a79d95489 100644 --- a/Core/Relationships/RelationshipResolver.cs +++ b/Core/Relationships/RelationshipResolver.cs @@ -307,7 +307,7 @@ private void ResolveStanza(List? stanza, && reason is SelectionReason.RelationshipReason rel && MightBeInstallable(mod, rel.Parent, installed_modules)) .ToList(); - if (!candidates.Any()) + if (candidates.Count == 0) { // Nothing found, try again while simulating an empty mod list // Necessary for e.g. proceed_with_inconsistencies, conflicts will still be caught below @@ -319,7 +319,7 @@ private void ResolveStanza(List? stanza, .ToList(); } - if (!candidates.Any()) + if (candidates.Count == 0) { if (!soft_resolve && reason is SelectionReason.RelationshipReason rel) { @@ -645,7 +645,7 @@ public IEnumerable ConflictDescriptions conflictingModDescription(kvp.Key, null), conflictingModDescription(kvp.Value, null))); - public bool IsConsistent => !conflicts.Any(); + public bool IsConsistent => conflicts.Count == 0; public List ReasonsFor(CkanModule mod) => reasons.TryGetValue(mod, out List? r) diff --git a/Core/Relationships/SanityChecker.cs b/Core/Relationships/SanityChecker.cs index 089d99518..ff0d4766f 100644 --- a/Core/Relationships/SanityChecker.cs +++ b/Core/Relationships/SanityChecker.cs @@ -54,7 +54,7 @@ private static bool CheckConsistency(IEnumerable modules var dllSet = dlls?.ToHashSet(); UnmetDepends = FindUnsatisfiedDepends(modList, dllSet, dlc).ToList(); Conflicts = FindConflicting(modList, dllSet, dlc); - return !UnmetDepends.Any() && !Conflicts.Any(); + return UnmetDepends.Count == 0 && Conflicts.Count == 0; } /// diff --git a/GUI/Controls/Changeset.cs b/GUI/Controls/Changeset.cs index d7b7e01cd..a0d98489f 100644 --- a/GUI/Controls/Changeset.cs +++ b/GUI/Controls/Changeset.cs @@ -34,7 +34,7 @@ public void LoadChangeset(List changes, Dictionary? conflicts) { changeset = changes; - ConfirmChangesButton.Enabled = conflicts == null || !conflicts.Any(); + ConfirmChangesButton.Enabled = conflicts == null || conflicts.Count == 0; CloseTheGameLabel.Visible = changes?.Any(ch => DeletingChanges.Contains(ch.ChangeType)) ?? false; ChangesGrid.DataSource = new BindingList( diff --git a/GUI/Controls/ChooseRecommendedMods.cs b/GUI/Controls/ChooseRecommendedMods.cs index 9a6efb30a..2f5e358d8 100644 --- a/GUI/Controls/ChooseRecommendedMods.cs +++ b/GUI/Controls/ChooseRecommendedMods.cs @@ -157,7 +157,7 @@ private void MarkConflicts() ? Color.LightCoral : Color.Empty; } - RecommendedModsContinueButton.Enabled = !conflicts.Any(); + RecommendedModsContinueButton.Enabled = conflicts.Count == 0; OnConflictFound?.Invoke(string.Join("; ", resolver.ConflictDescriptions)); } catch (DependencyNotSatisfiedKraken k) diff --git a/GUI/Controls/ManageMods.cs b/GUI/Controls/ManageMods.cs index d6fca7c0c..9f7d2ae6e 100644 --- a/GUI/Controls/ManageMods.cs +++ b/GUI/Controls/ManageMods.cs @@ -19,7 +19,7 @@ namespace CKAN.GUI #if NET5_0_OR_GREATER [SupportedOSPlatform("windows")] #endif - public partial class ManageMods : UserControl + public partial class ManageMods : UserControl, ISearchableControl { public ManageMods() { @@ -144,7 +144,7 @@ private void ChangeSetUpdated() { Util.Invoke(this, () => { - if (ChangeSet != null && ChangeSet.Any()) + if (ChangeSet != null && ChangeSet.Count != 0) { ApplyToolButton.Enabled = true; } @@ -1900,17 +1900,8 @@ protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { switch (keyData) { - case Keys.Control | Keys.F: - ActiveControl = EditModSearches; - return true; - - case Keys.Control | Keys.Shift | Keys.F: - EditModSearches.ExpandCollapse(); - ActiveControl = EditModSearches; - return true; - case Keys.Control | Keys.S: - if (ChangeSet != null && ChangeSet.Any()) + if (ChangeSet != null && ChangeSet.Count != 0) { ApplyToolButton_Click(null, null); } @@ -1921,9 +1912,19 @@ protected override bool ProcessCmdKey(ref Message msg, Keys keyData) return base.ProcessCmdKey(ref msg, keyData); } + public void FocusSearch(bool expandCollapse = false) + { + ActiveControl = EditModSearches; + EditModSearches.Focus(); + if (expandCollapse) + { + EditModSearches.ExpandCollapse(); + } + } + public bool AllowClose() { - if (Conflicts != null && Conflicts.Any()) + if (Conflicts != null && Conflicts.Count != 0) { // Ask if they want to resolve conflicts string confDescrip = Conflicts diff --git a/GUI/Dialogs/ManageGameInstancesDialog.cs b/GUI/Dialogs/ManageGameInstancesDialog.cs index edd1c7e00..db477ce28 100644 --- a/GUI/Dialogs/ManageGameInstancesDialog.cs +++ b/GUI/Dialogs/ManageGameInstancesDialog.cs @@ -41,7 +41,7 @@ public ManageGameInstancesDialog(GameInstanceManager mgr, StartPosition = FormStartPosition.CenterScreen; } - if (!manager.Instances.Any()) + if (manager.Instances.Count == 0) { manager.FindAndRegisterDefaultInstances(); } diff --git a/GUI/ISearchableControl.cs b/GUI/ISearchableControl.cs new file mode 100644 index 000000000..e22b5178c --- /dev/null +++ b/GUI/ISearchableControl.cs @@ -0,0 +1,7 @@ +namespace CKAN.GUI +{ + public interface ISearchableControl + { + void FocusSearch(bool expandCollapse = false); + } +} diff --git a/GUI/Main/Main.cs b/GUI/Main/Main.cs index ebb4f2384..978a3ef7b 100644 --- a/GUI/Main/Main.cs +++ b/GUI/Main/Main.cs @@ -611,6 +611,38 @@ protected override void OnMove(EventArgs e) ManageMods?.ParentMoved(); } + private IEnumerable VisibleControls() + => (MainTabControl?.SelectedTab + ?.Controls + .OfType() + ?? Enumerable.Empty()) + .Concat(!splitContainer1.Panel2Collapsed + && ModInfo is T t + ? Enumerable.Repeat(t, 1) + : Enumerable.Empty()); + + protected override void OnKeyDown(KeyEventArgs e) + { + switch (e.KeyData) + { + case Keys.Control | Keys.F: + VisibleControls() + .FirstOrDefault() + ?.FocusSearch(false); + e.Handled = true; + break; + case Keys.Control | Keys.Shift | Keys.F: + VisibleControls() + .FirstOrDefault() + ?.FocusSearch(true); + e.Handled = true; + break; + default: + base.OnKeyDown(e); + break; + } + } + private void SetupDefaultSearch() { if (CurrentInstance != null && configuration != null) @@ -821,7 +853,7 @@ private void InstallFromCkanFiles(string[] files) .Select(gv => new GameVersion(gv.Major, gv.Minor)) .Distinct() .ToList(); - if (missing.Any() + if (missing.Count != 0 && YesNoDialog(string.Format(Properties.Resources.MetapackageAddCompatibilityPrompt, filesRange.ToSummaryString(CurrentInstance.game), crit.ToSummaryString(CurrentInstance.game)), @@ -841,7 +873,7 @@ private void InstallFromCkanFiles(string[] files) .ToHashSet(); // Get incompatible mods we're installing var myIncompat = toInstall.Where(mod => allIncompat.Contains(mod.identifier)).ToList(); - if (!myIncompat.Any() + if (myIncompat.Count == 0 // Confirm installation of incompatible like the Versions tab does || YesNoDialog(string.Format(Properties.Resources.ModpackInstallIncompatiblePrompt, string.Join(Environment.NewLine, myIncompat), @@ -943,7 +975,7 @@ private void ShowSelectionModInfo(ListView.SelectedListViewItemCollection select private void ManageMods_OnChangeSetChanged(List changeset, Dictionary conflicts) { - if (changeset != null && changeset.Any()) + if (changeset != null && changeset.Count != 0) { tabController.ShowTab("ChangesetTabPage", 1, false); UpdateChangesDialog( @@ -1069,7 +1101,7 @@ private void LaunchGame(string? command = null) var incomp = registry.IncompatibleInstalled(CurrentInstance.VersionCriteria()) .Where(m => !m.Module.IsDLC && !suppressedIdentifiers.Contains(m.identifier)) .ToList(); - if (incomp.Any() && CurrentInstance.Version() is GameVersion gv) + if (incomp.Count != 0 && CurrentInstance.Version() is GameVersion gv) { // Warn that it might not be safe to run game with incompatible modules installed string incompatDescrip = incomp diff --git a/GUI/Main/MainRecommendations.cs b/GUI/Main/MainRecommendations.cs index 8fe87c3dc..d4de5db07 100644 --- a/GUI/Main/MainRecommendations.cs +++ b/GUI/Main/MainRecommendations.cs @@ -62,7 +62,7 @@ private void AuditRecommendations(Registry registry, GameVersionCriteria version recommendations, suggestions, supporters); var result = ChooseRecommendedMods.Wait(); tabController.HideTab("ChooseRecommendedModsTabPage"); - if (result != null && result.Any()) + if (result != null && result.Count != 0) { Wait.StartWaiting(InstallMods, PostInstallMods, true, new InstallArgument( diff --git a/Netkan/Processors/QueueHandler.cs b/Netkan/Processors/QueueHandler.cs index b1b070e58..3c14c41af 100644 --- a/Netkan/Processors/QueueHandler.cs +++ b/Netkan/Processors/QueueHandler.cs @@ -92,7 +92,7 @@ private void handleMessages(string url, int howMany, int timeoutMinutes) VisibilityTimeout = (int)TimeSpan.FromMinutes(timeoutMinutes).TotalSeconds, MessageAttributeNames = new List() { "All" }, }).Result; - if (!resp.Messages.Any()) + if (resp.Messages.Count == 0) { log.Debug("No metadata in queue"); } @@ -261,7 +261,7 @@ private SendMessageBatchRequestEntry inflationMessage(Metadata? ckan, } ); } - if (warningAppender.Warnings.Any()) + if (warningAppender.Warnings.Count != 0) { attribs.Add( "WarningMessages", diff --git a/Netkan/Sources/Github/GithubApi.cs b/Netkan/Sources/Github/GithubApi.cs index d38b0f5fc..c9d1b21e8 100644 --- a/Netkan/Sources/Github/GithubApi.cs +++ b/Netkan/Sources/Github/GithubApi.cs @@ -82,7 +82,7 @@ public IEnumerable GetAllReleases(GithubRef reference) ghRel.PreRelease == reference.UsePrerelease // Skip releases without assets && ghRel.Assets != null - && ghRel.Assets.Any()) + && ghRel.Assets.Count != 0) // Insurance against GitHub returning them in the wrong order .OrderByDescending(ghRel => ghRel.PublishedAt) .ToList(); diff --git a/Netkan/Transformers/NetkanTransformer.cs b/Netkan/Transformers/NetkanTransformer.cs index 973c439a9..e103fe2f2 100644 --- a/Netkan/Transformers/NetkanTransformer.cs +++ b/Netkan/Transformers/NetkanTransformer.cs @@ -107,7 +107,7 @@ private static List InjectVersionedOverrideTransformers(List !AllowedCraftPath(inst.ToRelativeGameDir(f.destination))) .ToList(); - if (badCrafts.Any()) + if (badCrafts.Count != 0) { Log.WarnFormat( "Craft files installed outside Ships folder: {0}", diff --git a/Netkan/Validators/HarmonyValidator.cs b/Netkan/Validators/HarmonyValidator.cs index 6945cebbd..1c43f03b6 100644 --- a/Netkan/Validators/HarmonyValidator.cs +++ b/Netkan/Validators/HarmonyValidator.cs @@ -41,7 +41,7 @@ public void Validate(Metadata metadata) StringComparison.InvariantCultureIgnoreCase) != -1) .OrderBy(f => f) .ToList(); - bool bundlesHarmony = harmonyDLLs.Any(); + bool bundlesHarmony = harmonyDLLs.Count != 0; bool providesHarmony1 = mod.ProvidesList.Contains("Harmony1"); if (bundlesHarmony && !providesHarmony1) { diff --git a/Netkan/Validators/InstallsFilesValidator.cs b/Netkan/Validators/InstallsFilesValidator.cs index 9acd1aace..c312a3f69 100644 --- a/Netkan/Validators/InstallsFilesValidator.cs +++ b/Netkan/Validators/InstallsFilesValidator.cs @@ -48,7 +48,7 @@ public void Validate(Metadata metadata) && p.LastIndexOf($"/{dir}/", StringComparison.InvariantCultureIgnoreCase) > 0) .OrderBy(f => f) .ToList(); - if (gamedatas.Any()) + if (gamedatas.Count != 0) { var badPaths = string.Join("\r\n", gamedatas); throw new Kraken($"{dir} directory found within {dir}:\r\n{badPaths}"); @@ -60,7 +60,7 @@ public void Validate(Metadata metadata) .GroupBy(f => f) .SelectMany(grp => grp.Skip(1).OrderBy(f => f)) .ToList(); - if (duplicates.Any()) + if (duplicates.Count != 0) { var badPaths = string.Join("\r\n", duplicates); throw new Kraken($"Multiple files attempted to install to:\r\n{badPaths}"); @@ -75,7 +75,7 @@ public void Validate(Metadata metadata) .Distinct() .Where(incl => !allFiles.Any(f => f.Contains(incl))) .ToList(); - if (unmatchedIncludeOnlys.Any()) + if (unmatchedIncludeOnlys.Count != 0) { log.WarnFormat("No matches for includes_only: {0}", string.Join(", ", unmatchedIncludeOnlys)); diff --git a/Netkan/Validators/PluginsValidator.cs b/Netkan/Validators/PluginsValidator.cs index 6b9584e99..6e30c7b93 100644 --- a/Netkan/Validators/PluginsValidator.cs +++ b/Netkan/Validators/PluginsValidator.cs @@ -33,7 +33,7 @@ public void Validate(Metadata metadata) GameInstance inst = new GameInstance(_game, "/", "dummy", new NullUser()); var plugins = _moduleService.GetPlugins(mod, zip, inst).ToList(); - bool hasPlugin = plugins.Any(); + bool hasPlugin = plugins.Count != 0; if (hasPlugin) { var dllPaths = plugins @@ -45,7 +45,7 @@ public void Validate(Metadata metadata) .Where(ident => !string.IsNullOrEmpty(ident) && !identifiersToIgnore.Contains(ident)) .ToHashSet(); - if (dllIdentifiers.Any() && !dllIdentifiers.Contains(metadata.Identifier)) + if (dllIdentifiers.Count != 0 && !dllIdentifiers.Contains(metadata.Identifier)) { Log.WarnFormat( "No plugin matching the identifier, manual installations won't be detected: {0}", diff --git a/Netkan/Validators/SpaceWarpInfoValidator.cs b/Netkan/Validators/SpaceWarpInfoValidator.cs index af56f4c5d..896f449cf 100644 --- a/Netkan/Validators/SpaceWarpInfoValidator.cs +++ b/Netkan/Validators/SpaceWarpInfoValidator.cs @@ -49,7 +49,7 @@ public void Validate(Metadata metadata) StringComparer.InvariantCultureIgnoreCase)) ?? Enumerable.Empty()) .ToList(); - if (missingDeps.Any()) + if (missingDeps.Count != 0) { log.WarnFormat("Dependencies from swinfo.json missing from module: {0}", string.Join(", ", missingDeps)); diff --git a/Tests/Util.cs b/Tests/Util.cs index 5b72b8817..c59d4a263 100644 --- a/Tests/Util.cs +++ b/Tests/Util.cs @@ -63,7 +63,7 @@ public static void AssertNoAsyncVoidMethods(Assembly assembly) method.DeclaringType?.Name ?? "", method.Name)) .ToList(); - Assert.False(messages.Any(), + Assert.False(messages.Count != 0, "Async void methods found!" + Environment.NewLine + string.Join(Environment.NewLine, messages)); }