diff --git a/Cmdline/Action/Prompt.cs b/Cmdline/Action/Prompt.cs index 255d6b2be1..1f94d67603 100644 --- a/Cmdline/Action/Prompt.cs +++ b/Cmdline/Action/Prompt.cs @@ -202,7 +202,7 @@ private string[] GetInstIdentifiers(string prefix) CKAN.GameInstance inst = MainClass.GetGameInstance(manager); var registry = RegistryManager.Instance(inst, repoData).registry; return registry.Installed(false, false) - .Select(kvp => kvp.Key) + .Keys .Where(ident => ident.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase) && !registry.GetInstalledVersion(ident).IsDLC) .ToArray(); @@ -214,7 +214,7 @@ private static bool WantsGameInstances(TypeInfo ti) private string[] GetGameInstances(string prefix) => manager.Instances - .Select(kvp => kvp.Key) + .Keys .Where(ident => ident.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase)) .ToArray(); diff --git a/Cmdline/Action/Upgrade.cs b/Cmdline/Action/Upgrade.cs index 5d99c7feb2..69848c959f 100644 --- a/Cmdline/Action/Upgrade.cs +++ b/Cmdline/Action/Upgrade.cs @@ -193,9 +193,14 @@ public int RunCommand(CKAN.GameInstance instance, object raw_options) /// IUser object for output /// Game instance to use /// List of modules to upgrade - private void UpgradeModules(GameInstanceManager manager, IUser user, CKAN.GameInstance instance, bool ConfirmPrompt, List modules) + private void UpgradeModules(GameInstanceManager manager, + IUser user, + CKAN.GameInstance instance, + bool ConfirmPrompt, + List modules) { - UpgradeModules(manager, user, instance, repoData, + UpgradeModules( + manager, user, instance, repoData, (ModuleInstaller installer, NetAsyncModulesDownloader downloader, RegistryManager regMgr, ref HashSet possibleConfigOnlyDirs) => installer.Upgrade(modules, downloader, ref possibleConfigOnlyDirs, regMgr, true, true, ConfirmPrompt), @@ -210,9 +215,13 @@ private void UpgradeModules(GameInstanceManager manager, IUser user, CKAN.GameIn /// IUser object for output /// Game instance to use /// List of identifier[=version] to upgrade - private void UpgradeModules(GameInstanceManager manager, IUser user, CKAN.GameInstance instance, List identsAndVersions) + private void UpgradeModules(GameInstanceManager manager, + IUser user, + CKAN.GameInstance instance, + List identsAndVersions) { - UpgradeModules(manager, user, instance, repoData, + UpgradeModules( + manager, user, instance, repoData, (ModuleInstaller installer, NetAsyncModulesDownloader downloader, RegistryManager regMgr, ref HashSet possibleConfigOnlyDirs) => installer.Upgrade( identsAndVersions.Select(arg => CkanModule.FromIDandVersion( @@ -241,11 +250,12 @@ private void UpgradeModules(GameInstanceManager manager, IUser user, CKAN.GameIn /// Game instance to use /// Function to call to try to perform the actual upgrade, may throw TooManyModsProvideKraken /// Function to call when the user has requested a new module added to the change set in response to TooManyModsProvideKraken - private void UpgradeModules( - GameInstanceManager manager, IUser user, CKAN.GameInstance instance, - RepositoryDataManager repoData, - AttemptUpgradeAction attemptUpgradeCallback, - Action addUserChoiceCallback) + private void UpgradeModules(GameInstanceManager manager, + IUser user, + CKAN.GameInstance instance, + RepositoryDataManager repoData, + AttemptUpgradeAction attemptUpgradeCallback, + Action addUserChoiceCallback) { using (TransactionScope transact = CkanTransaction.CreateTransactionScope()) { var installer = new ModuleInstaller(instance, manager.Cache, user); diff --git a/ConsoleUI/InstallScreen.cs b/ConsoleUI/InstallScreen.cs index 83d42663c5..9ad7da2284 100644 --- a/ConsoleUI/InstallScreen.cs +++ b/ConsoleUI/InstallScreen.cs @@ -48,13 +48,14 @@ public override void Run(ConsoleTheme theme, Action process = null // Reset this so we stop unless an exception sets it to true retry = false; - RegistryManager regMgr = RegistryManager.Instance(manager.CurrentInstance, repoData); + var regMgr = RegistryManager.Instance(manager.CurrentInstance, repoData); + var registry = regMgr.registry; // GUI prompts user to choose recs/sugs, // CmdLine assumes recs and ignores sugs if (plan.Install.Count > 0) { // Track previously rejected optional dependencies and don't prompt for them again. - DependencyScreen ds = new DependencyScreen(manager, regMgr.registry, plan, rejected, debug); + DependencyScreen ds = new DependencyScreen(manager, registry, plan, rejected, debug); if (ds.HaveOptions()) { LaunchSubScreen(theme, ds); } diff --git a/GUI/Controls/ManageMods.cs b/GUI/Controls/ManageMods.cs index fa40800bd8..46f3147b96 100644 --- a/GUI/Controls/ManageMods.cs +++ b/GUI/Controls/ManageMods.cs @@ -340,13 +340,13 @@ private void labelMenuItem_Click(object sender, EventArgs e) private void editLabelsToolStripMenuItem_Click(object sender, EventArgs e) { - EditLabelsDialog eld = new EditLabelsDialog(Main.Instance.currentUser, Main.Instance.Manager, mainModList.ModuleLabels); + var eld = new EditLabelsDialog(Main.Instance.currentUser, Main.Instance.Manager, mainModList.ModuleLabels); eld.ShowDialog(this); eld.Dispose(); mainModList.ModuleLabels.Save(ModuleLabelList.DefaultPath); var inst = Main.Instance.CurrentInstance; var registry = RegistryManager.Instance(inst, repoData).registry; - foreach (GUIMod module in mainModList.Modules) + foreach (var module in mainModList.Modules) { mainModList.ReapplyLabels(module, Conflicts?.ContainsKey(module) ?? false, inst.Name, inst.game, registry); } @@ -1271,6 +1271,8 @@ private void _UpdateFilters() var inst = Main.Instance.CurrentInstance; var registry = RegistryManager.Instance(inst, repoData).registry; ModGrid.Rows.Clear(); + var instName = inst.Name; + var instGame = inst.game; rows.AsParallel().ForAll(row => row.Visible = mainModList.IsVisible((GUIMod)row.Tag, inst.Name, inst.game, registry)); @@ -1300,7 +1302,8 @@ private bool _UpdateModsList(Dictionary old_modules = null) { log.Info("Updating the mod list"); - var regMgr = RegistryManager.Instance(Main.Instance.CurrentInstance, repoData); + var inst = Main.Instance.CurrentInstance; + var regMgr = RegistryManager.Instance(inst, repoData); IRegistryQuerier registry = regMgr.registry; repoData.Prepopulate( @@ -1318,7 +1321,7 @@ private bool _UpdateModsList(Dictionary old_modules = null) regMgr.ScanUnmanagedFiles(); RaiseMessage?.Invoke(Properties.Resources.MainModListLoadingInstalled); - var versionCriteria = Main.Instance.CurrentInstance.VersionCriteria(); + var versionCriteria = inst.VersionCriteria(); var installedIdents = registry.InstalledModules .Select(im => im.identifier) @@ -1385,11 +1388,11 @@ private bool _UpdateModsList(Dictionary old_modules = null) RaiseMessage?.Invoke(Properties.Resources.MainModListPopulatingList); // Update our mod listing mainModList.ConstructModList(gui_mods, - Main.Instance.CurrentInstance.Name, - Main.Instance.CurrentInstance.game, + inst.Name, + inst.game, ChangeSet); - UpdateChangeSetAndConflicts(Main.Instance.CurrentInstance, registry); + UpdateChangeSetAndConflicts(inst, registry); RaiseMessage?.Invoke(Properties.Resources.MainModListUpdatingFilters); @@ -1663,10 +1666,10 @@ private int VersionPieceCompare(bool definedA, int valA, bool definedB, int valB ? (definedB ? valA.CompareTo(valB) : -1) : (definedB ? 1 : 0); - public void ResetFilterAndSelectModOnList(string key) + public void ResetFilterAndSelectModOnList(CkanModule module) { EditModSearches.Clear(); - FocusMod(key, true); + FocusMod(module.identifier, true); } public GUIMod SelectedModule => diff --git a/GUI/Controls/ModInfo.cs b/GUI/Controls/ModInfo.cs index 3e8b4b76da..b382393a66 100644 --- a/GUI/Controls/ModInfo.cs +++ b/GUI/Controls/ModInfo.cs @@ -21,6 +21,7 @@ public ModInfo() { InitializeComponent(); Contents.OnDownloadClick += gmod => OnDownloadClick?.Invoke(gmod); + Relationships.ModuleDoubleClicked += mod => ModuleDoubleClicked?.Invoke(mod); } public GUIMod SelectedModule @@ -54,6 +55,7 @@ public void RefreshModContentsTree() public event Action OnDownloadClick; public event Action OnChangeFilter; + public event Action ModuleDoubleClicked; protected override void OnResize(EventArgs e) { diff --git a/GUI/Controls/ModInfoTabs/Contents.cs b/GUI/Controls/ModInfoTabs/Contents.cs index f181e05752..18ccd38142 100644 --- a/GUI/Controls/ModInfoTabs/Contents.cs +++ b/GUI/Controls/ModInfoTabs/Contents.cs @@ -27,7 +27,6 @@ public GUIMod SelectedModule { set { - var module = value?.ToModule(); if (value != selectedModule) { selectedModule = value; @@ -93,7 +92,7 @@ private void _UpdateModContentsTree(CkanModule module, bool force = false) ContentsPreviewTree.Enabled = true; ContentsPreviewTree.Nodes.Clear(); var rootNode = ContentsPreviewTree.Nodes.Add("", module.ToString(), "folderZip", "folderZip"); - if (!Main.Instance.Manager.Cache.IsMaybeCachedZip(module)) + if (!manager.Cache.IsMaybeCachedZip(module)) { NotCachedLabel.Text = Properties.Resources.ModInfoNotCached; ContentsDownloadButton.Enabled = true; @@ -103,7 +102,7 @@ private void _UpdateModContentsTree(CkanModule module, bool force = false) else { rootNode.Text = Path.GetFileName( - Main.Instance.Manager.Cache.GetCachedFilename(module)); + manager.Cache.GetCachedFilename(module)); NotCachedLabel.Text = Properties.Resources.ModInfoCached; ContentsDownloadButton.Enabled = false; ContentsOpenButton.Enabled = true; @@ -114,7 +113,7 @@ private void _UpdateModContentsTree(CkanModule module, bool force = false) { var paths = new ModuleInstaller( manager.CurrentInstance, - Main.Instance.Manager.Cache, + manager.Cache, Main.Instance.currentUser) .GetModuleContentsList(module) // Load fully in bg diff --git a/GUI/Controls/ModInfoTabs/Relationships.cs b/GUI/Controls/ModInfoTabs/Relationships.cs index 3cce1470a0..7a8b1f2297 100644 --- a/GUI/Controls/ModInfoTabs/Relationships.cs +++ b/GUI/Controls/ModInfoTabs/Relationships.cs @@ -76,6 +76,8 @@ public GUIMod SelectedModule get => selectedModule; } + public event Action ModuleDoubleClicked; + private void UpdateModDependencyGraph(CkanModule module) { Util.Invoke(DependsGraphTree, () => _UpdateModDependencyGraph(module)); @@ -87,7 +89,7 @@ private void UpdateModDependencyGraph(CkanModule module) private void DependsGraphTree_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) { - Main.Instance.ManageMods.ResetFilterAndSelectModOnList(e.Node.Name); + ModuleDoubleClicked?.Invoke(e.Node.Tag as CkanModule); } private bool ImMyOwnGrandpa(TreeNode node) diff --git a/GUI/Dialogs/ErrorDialog.cs b/GUI/Dialogs/ErrorDialog.cs index 60155e8b33..74df290e63 100644 --- a/GUI/Dialogs/ErrorDialog.cs +++ b/GUI/Dialogs/ErrorDialog.cs @@ -24,7 +24,7 @@ public ErrorDialog() [ForbidGUICalls] public void ShowErrorDialog(string text, params object[] args) { - Util.Invoke(Main.Instance, () => + Util.Invoke(this, () => { log.ErrorFormat(text, args); // Append to previous text, if any diff --git a/GUI/Dialogs/ManageGameInstancesDialog.Designer.cs b/GUI/Dialogs/ManageGameInstancesDialog.Designer.cs index 98d4efcebb..c544559e77 100644 --- a/GUI/Dialogs/ManageGameInstancesDialog.Designer.cs +++ b/GUI/Dialogs/ManageGameInstancesDialog.Designer.cs @@ -250,7 +250,7 @@ private void InitializeComponent() private System.Windows.Forms.ColumnHeader GamePlayTime; private System.Windows.Forms.ColumnHeader GameInstallPath; private System.Windows.Forms.Button SelectButton; - private DropdownMenuButton AddNewButton; + private CKAN.GUI.DropdownMenuButton AddNewButton; private System.Windows.Forms.ContextMenuStrip AddNewMenu; private System.Windows.Forms.ContextMenuStrip InstanceListContextMenuStrip; private System.Windows.Forms.ToolStripMenuItem openDirectoryMenuItem; diff --git a/GUI/Dialogs/ManageGameInstancesDialog.cs b/GUI/Dialogs/ManageGameInstancesDialog.cs index 6ab1a9a74c..4ac33d6abf 100644 --- a/GUI/Dialogs/ManageGameInstancesDialog.cs +++ b/GUI/Dialogs/ManageGameInstancesDialog.cs @@ -18,7 +18,7 @@ namespace CKAN.GUI #endif public partial class ManageGameInstancesDialog : Form { - private readonly GameInstanceManager _manager = Main.Instance.Manager; + private static GameInstanceManager manager => Main.Instance.Manager; private readonly IUser _user; private RenameInstanceDialog _renameInstanceDialog; private readonly OpenFileDialog _instanceDialog = new OpenFileDialog() @@ -27,7 +27,7 @@ public partial class ManageGameInstancesDialog : Form CheckFileExists = false, CheckPathExists = false, InitialDirectory = Environment.CurrentDirectory, - Filter = GameFolderFilter(Main.Instance.Manager), + Filter = GameFolderFilter(manager), Multiselect = false }; @@ -59,9 +59,9 @@ public ManageGameInstancesDialog(bool centerScreen, IUser user) StartPosition = FormStartPosition.CenterScreen; } - if (!_manager.Instances.Any()) + if (!manager.Instances.Any()) { - _manager.FindAndRegisterDefaultInstances(); + manager.FindAndRegisterDefaultInstances(); } // Set the renderer for the AddNewMenu @@ -80,14 +80,14 @@ public void UpdateInstancesList() GameInstancesListView.Items.Clear(); UpdateButtonState(); - var allSameGame = _manager.Instances.Select(i => i.Value.game).Distinct().Count() <= 1; - var hasPlayTime = _manager.Instances.Any(instance => (instance.Value.playTime?.Time ?? TimeSpan.Zero) > TimeSpan.Zero); + var allSameGame = manager.Instances.Select(i => i.Value.game).Distinct().Count() <= 1; + var hasPlayTime = manager.Instances.Any(instance => (instance.Value.playTime?.Time ?? TimeSpan.Zero) > TimeSpan.Zero); AddOrRemoveColumn(GameInstancesListView, Game, !allSameGame, GameInstallVersion.Index); AddOrRemoveColumn(GameInstancesListView, GamePlayTime, hasPlayTime, GameInstallPath.Index); GameInstancesListView.Items.AddRange( - _manager.Instances.OrderByDescending(instance => instance.Value.game.FirstReleaseDate) + manager.Instances.OrderByDescending(instance => instance.Value.game.FirstReleaseDate) .ThenByDescending(instance => instance.Value.Version()) .ThenBy(instance => instance.Key) .Select(instance => new ListViewItem( @@ -119,7 +119,7 @@ private string[] rowItems(GameInstance instance, bool includeGame, bool includeP { !instance.Valid ? string.Format(Properties.Resources.ManageGameInstancesNameColumnInvalid, instance.Name) - : !(_manager.CurrentInstance?.Equals(instance) ?? false) && instance.IsMaybeLocked + : !(manager.CurrentInstance?.Equals(instance) ?? false) && instance.IsMaybeLocked ? string.Format(Properties.Resources.ManageGameInstancesNameColumnLocked, instance.Name) : instance.Name }; @@ -180,8 +180,8 @@ private void AddToCKANMenuItem_Click(object sender, EventArgs e) { instanceName = path; } - instanceName = _manager.GetNextValidInstanceName(instanceName); - _manager.AddInstance(path, instanceName, _user); + instanceName = manager.GetNextValidInstanceName(instanceName); + manager.AddInstance(path, instanceName, _user); UpdateInstancesList(); } catch (NotKSPDirKraken k) @@ -197,14 +197,14 @@ private void AddToCKANMenuItem_Click(object sender, EventArgs e) private void ImportFromSteamMenuItem_Click(object sender, EventArgs e) { - var currentDirs = _manager.Instances.Values + var currentDirs = manager.Instances.Values .Select(inst => inst.GameDir()) .ToHashSet(Platform.PathComparer); - var toAdd = _manager.FindDefaultInstances() - .Where(inst => !currentDirs.Contains(inst.GameDir())); + var toAdd = manager.FindDefaultInstances() + .Where(inst => !currentDirs.Contains(inst.GameDir())); foreach (var inst in toAdd) { - _manager.AddInstance(inst); + manager.AddInstance(inst); } UpdateInstancesList(); } @@ -213,7 +213,7 @@ private void CloneGameInstanceMenuItem_Click(object sender, EventArgs e) { var old_instance = Main.Instance.CurrentInstance; - var result = new CloneGameInstanceDialog(_manager, _user, (string)GameInstancesListView.SelectedItems[0].Tag).ShowDialog(this); + var result = new CloneGameInstanceDialog(manager, _user, (string)GameInstancesListView.SelectedItems[0].Tag).ShowDialog(this); if (result == DialogResult.OK && !Equals(old_instance, Main.Instance.CurrentInstance)) { DialogResult = DialogResult.OK; @@ -240,7 +240,7 @@ private void UseSelectedInstance() { try { - _manager.SetCurrentInstance(instName); + manager.SetCurrentInstance(instName); DialogResult = DialogResult.OK; Close(); } @@ -255,7 +255,7 @@ private void SetAsDefaultCheckbox_Click(object sender, EventArgs e) { if (SetAsDefaultCheckbox.Checked) { - _manager.ClearAutoStart(); + manager.ClearAutoStart(); SetAsDefaultCheckbox.Checked = false; return; } @@ -265,7 +265,7 @@ private void SetAsDefaultCheckbox_Click(object sender, EventArgs e) { try { - _manager.SetAutoStart(instName); + manager.SetAutoStart(instName); SetAsDefaultCheckbox.Checked = true; } catch (NotKSPDirKraken k) @@ -285,7 +285,7 @@ private void GameInstancesListView_SelectedIndexChanged(object sender, EventArgs } string instName = (string)GameInstancesListView.SelectedItems[0].Tag; - SetAsDefaultCheckbox.Checked = _manager.AutoStartInstance?.Equals(instName) ?? false; + SetAsDefaultCheckbox.Checked = manager.AutoStartInstance?.Equals(instName) ?? false; } private void GameInstancesListView_DoubleClick(object sender, EventArgs r) @@ -317,7 +317,7 @@ private void GameInstancesListView_KeyDown(object sender, KeyEventArgs e) private void OpenDirectoryMenuItem_Click(object sender, EventArgs e) { - string path = _manager.Instances[(string) GameInstancesListView.SelectedItems[0].Tag].GameDir(); + string path = manager.Instances[(string) GameInstancesListView.SelectedItems[0].Tag].GameDir(); if (!Directory.Exists(path)) { @@ -340,7 +340,7 @@ private void RenameButton_Click(object sender, EventArgs e) } // proceed with instance rename - _manager.RenameInstance(instance, _renameInstanceDialog.GetResult()); + manager.RenameInstance(instance, _renameInstanceDialog.GetResult()); UpdateInstancesList(); } @@ -348,7 +348,7 @@ private void Forget_Click(object sender, EventArgs e) { foreach (var instance in GameInstancesListView.SelectedItems.OfType().Select(item => item.Tag as string)) { - _manager.RemoveInstance(instance); + manager.RemoveInstance(instance); UpdateInstancesList(); } } @@ -356,8 +356,8 @@ private void Forget_Click(object sender, EventArgs e) private void UpdateButtonState() { RenameButton.Enabled = SelectButton.Enabled = SetAsDefaultCheckbox.Enabled = CloneGameInstanceMenuItem.Enabled = HasSelections; - ForgetButton.Enabled = HasSelections && (string)GameInstancesListView.SelectedItems[0].Tag != _manager.CurrentInstance?.Name; - ImportFromSteamMenuItem.Enabled = _manager.SteamLibrary.Games.Length > 0; + ForgetButton.Enabled = HasSelections && (string)GameInstancesListView.SelectedItems[0].Tag != manager.CurrentInstance?.Name; + ImportFromSteamMenuItem.Enabled = manager.SteamLibrary.Games.Length > 0; } } } diff --git a/GUI/Main/Main.cs b/GUI/Main/Main.cs index 832c112ec3..6265573493 100644 --- a/GUI/Main/Main.cs +++ b/GUI/Main/Main.cs @@ -101,6 +101,7 @@ public Main(string[] cmdlineArgs, GameInstanceManager mgr) InitializeComponent(); // React when the user clicks a tag or filter link in mod info ModInfo.OnChangeFilter += ManageMods.Filter; + ModInfo.ModuleDoubleClicked += ManageMods.ResetFilterAndSelectModOnList; repoData = ServiceLocator.Container.Resolve(); Instance = this; diff --git a/Tests/Core/Registry/Registry.cs b/Tests/Core/Registry/Registry.cs index 18f236b863..c012840627 100644 --- a/Tests/Core/Registry/Registry.cs +++ b/Tests/Core/Registry/Registry.cs @@ -19,7 +19,7 @@ public class RegistryTests private string repoDataDir; private static readonly GameVersionCriteria v0_24_2 = new GameVersionCriteria(GameVersion.Parse("0.24.2")); - private static readonly GameVersionCriteria v0_25_0 = new GameVersionCriteria (GameVersion.Parse("0.25.0")); + private static readonly GameVersionCriteria v0_25_0 = new GameVersionCriteria(GameVersion.Parse("0.25.0")); [SetUp] public void Setup() diff --git a/Tests/GUI/ThreadSafetyTests.cs b/Tests/GUI/ThreadSafetyTests.cs index 90528c7a15..b1114c03ce 100644 --- a/Tests/GUI/ThreadSafetyTests.cs +++ b/Tests/GUI/ThreadSafetyTests.cs @@ -7,6 +7,7 @@ using Mono.Cecil; using Mono.Cecil.Cil; using NUnit.Framework; + using CKAN.GUI.Attributes; namespace Tests.GUI