diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1b02bedffe..0b7e6bc2a0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -26,6 +26,7 @@ All notable changes to this project will be documented in this file.
- [GUI] Fix checkbox sorting (#3297 by: HebaruSan; reviewed: DasSkelett)
- [GUI] Handle incompatible force-installed dependencies of recommendations (#3305 by: HebaruSan; reviewed: DasSkelett)
- [Multiple] Don't warn about incompatible DLCs, fix conflict highlighting with DLC installed (#3304 by: HebaruSan; reviewed: DasSkelett)
+- [Multiple] Fixes for GUI and .ckan-installed modules (#3307 by: DasSkelett; reviewed: HebaruSan)
### Internal
diff --git a/ConsoleUI/ConsoleCKAN.cs b/ConsoleUI/ConsoleCKAN.cs
index 0e34799f13..c8d2dbd38c 100644
--- a/ConsoleUI/ConsoleCKAN.cs
+++ b/ConsoleUI/ConsoleCKAN.cs
@@ -16,7 +16,7 @@ public class ConsoleCKAN {
///
public ConsoleCKAN(GameInstanceManager mgr, string themeName, bool debug)
{
- if (ConsoleTheme.Themes.TryGetValue(themeName, out ConsoleTheme theme))
+ if (ConsoleTheme.Themes.TryGetValue(themeName ?? "default", out ConsoleTheme theme))
{
// GameInstanceManager only uses its IUser object to construct game instance objects,
// which only use it to inform the user about the creation of the CKAN/ folder.
@@ -40,7 +40,7 @@ public ConsoleCKAN(GameInstanceManager mgr, string themeName, bool debug)
}
}
if (manager.CurrentInstance != null) {
- new ModListScreen(manager, debug).Run(theme);
+ new ModListScreen(manager, debug, theme).Run(theme);
}
new ExitScreen().Run(theme);
diff --git a/ConsoleUI/ModListScreen.cs b/ConsoleUI/ModListScreen.cs
index 96c11a0de8..cbc5555375 100644
--- a/ConsoleUI/ModListScreen.cs
+++ b/ConsoleUI/ModListScreen.cs
@@ -17,7 +17,7 @@ public class ModListScreen : ConsoleScreen {
///
/// Game instance manager object containing the current instance
/// True if debug options should be available, false otherwise
- public ModListScreen(GameInstanceManager mgr, bool dbg)
+ public ModListScreen(GameInstanceManager mgr, bool dbg, ConsoleTheme _theme)
{
debug = dbg;
manager = mgr;
@@ -25,7 +25,7 @@ public ModListScreen(GameInstanceManager mgr, bool dbg)
moduleList = new ConsoleListBox(
1, 4, -1, -2,
- GetAllMods(),
+ GetAllMods(_theme),
new List>() {
new ConsoleListBoxColumn() {
Header = "",
@@ -205,7 +205,7 @@ public ModListScreen(GameInstanceManager mgr, bool dbg)
}
return true;
});
-
+
moduleList.AddTip("F8", "Mark auto-installed",
() => moduleList.Selection != null && !moduleList.Selection.IsDLC
&& (!registry.InstalledModule(moduleList.Selection.identifier)?.AutoInstalled ?? false)
@@ -265,7 +265,7 @@ public ModListScreen(GameInstanceManager mgr, bool dbg)
null,
new ConsoleMenuOption("Refresh mod list", "F5, Ctrl+R",
"Refresh the list of mods",
- true, UpdateRegistry),
+ true, (ConsoleTheme th) => UpdateRegistry(th)),
new ConsoleMenuOption("Upgrade all", "Ctrl+U",
"Mark all available updates for installation",
true, UpgradeAll, null, null, HasAnyUpgradeable()),
@@ -328,7 +328,7 @@ protected override string CenterHeader()
private bool ImportDownloads(ConsoleTheme theme)
{
DownloadImportDialog.ImportDownloads(theme, manager.CurrentInstance, manager.Cache, plan);
- RefreshList();
+ RefreshList(theme);
return true;
}
@@ -393,7 +393,7 @@ private bool ViewSuggestions(ConsoleTheme theme)
}
}
if (needRefresh) {
- RefreshList();
+ RefreshList(theme);
}
} else {
RaiseError("Installed mods have no unsatisfied recommendations or suggestions.");
@@ -414,7 +414,7 @@ private int daysSinceUpdated(string filename)
return (DateTime.Now - File.GetLastWriteTime(filename)).Days;
}
- private bool UpdateRegistry(ConsoleTheme theme)
+ private bool UpdateRegistry(ConsoleTheme theme, bool showNewModsPrompt = true)
{
ProgressScreen ps = new ProgressScreen("Updating Registry", "Checking for updates");
LaunchSubScreen(theme, ps, (ConsoleTheme th) => {
@@ -447,11 +447,11 @@ private bool UpdateRegistry(ConsoleTheme theme)
}
}
});
- if (recent.Count > 0 && RaiseYesNoDialog(newModPrompt(recent.Count))) {
+ if (showNewModsPrompt && recent.Count > 0 && RaiseYesNoDialog(newModPrompt(recent.Count))) {
searchBox.Clear();
moduleList.FilterString = searchBox.Value = "~n";
}
- RefreshList();
+ RefreshList(theme);
return true;
}
@@ -481,7 +481,7 @@ private bool SelectInstall(ConsoleTheme theme)
if (!prevInst.Equals(manager.CurrentInstance)) {
plan.Reset();
registry = RegistryManager.Instance(manager.CurrentInstance).registry;
- RefreshList();
+ RefreshList(theme);
}
return true;
}
@@ -492,17 +492,23 @@ private bool EditAuthTokens(ConsoleTheme theme)
return true;
}
- private void RefreshList()
+ private void RefreshList(ConsoleTheme theme)
{
- moduleList.SetData(GetAllMods(true));
+ // In the constructor this is called while moduleList is being populated, just do nothing in this case.
+ // ModListScreen -> moduleList = (GetAllMods ...) -> UpdateRegistry -> RefreshList
+ moduleList?.SetData(GetAllMods(theme,true));
}
private List allMods = null;
- private List GetAllMods(bool force = false)
+ private List GetAllMods(ConsoleTheme theme, bool force = false)
{
ScanForMods();
if (allMods == null || force) {
+ if (!registry?.HasAnyAvailable() ?? false)
+ {
+ UpdateRegistry(theme, false);
+ }
allMods = new List(registry.CompatibleModules(manager.CurrentInstance.VersionCriteria()));
foreach (InstalledModule im in registry.InstalledModules) {
CkanModule m = null;
@@ -546,7 +552,7 @@ private bool Help(ConsoleTheme theme)
private bool ApplyChanges(ConsoleTheme theme)
{
LaunchSubScreen(theme, new InstallScreen(manager, plan, debug));
- RefreshList();
+ RefreshList(theme);
return true;
}
@@ -598,9 +604,9 @@ private long totalInstalledDownloadSize()
return total;
}
- private GameInstanceManager manager;
- private IRegistryQuerier registry;
- private bool debug;
+ private GameInstanceManager manager;
+ private Registry registry;
+ private bool debug;
private ConsoleField searchBox;
private ConsoleListBox moduleList;
@@ -839,7 +845,7 @@ public enum InstallStatus {
/// This mod is installed and not upgradeable or planned to be removed
///
Installed,
-
+
///
/// Like Installed, but can be auto-removed if depending mods are removed
///
diff --git a/Core/ModuleInstaller.cs b/Core/ModuleInstaller.cs
index 3c016494a9..e3d4009ff2 100644
--- a/Core/ModuleInstaller.cs
+++ b/Core/ModuleInstaller.cs
@@ -1347,7 +1347,7 @@ IRegistryQuerier registry
{
RelationshipResolver resolver = new RelationshipResolver(
toInstall,
- null,
+ toInstall.Select(m => registry.InstalledModule(m.identifier)?.Module).Where(m => m != null),
opts, registry, ksp.VersionCriteria()
);
diff --git a/Core/Net/NetAsyncDownloader.cs b/Core/Net/NetAsyncDownloader.cs
index c31794bd45..f2367edd40 100644
--- a/Core/Net/NetAsyncDownloader.cs
+++ b/Core/Net/NetAsyncDownloader.cs
@@ -356,6 +356,8 @@ private void FileProgressReport(int index, int percent, long bytesDownloaded, lo
foreach (NetAsyncDownloaderDownloadPart t in downloads.ToList())
{
+ if (t == null)
+ continue;
if (t.bytesLeft > 0)
{
totalBytesPerSecond += t.bytesPerSecond;
@@ -366,6 +368,9 @@ private void FileProgressReport(int index, int percent, long bytesDownloaded, lo
}
foreach (Net.DownloadTarget t in queuedDownloads.ToList())
{
+ // Somehow managed to get a NullRef for t here
+ if (t == null)
+ continue;
totalBytesLeft += t.size;
totalSize += t.size;
}
diff --git a/Core/Registry/IRegistryQuerier.cs b/Core/Registry/IRegistryQuerier.cs
index 1a4e6e87bb..46b272e0f1 100644
--- a/Core/Registry/IRegistryQuerier.cs
+++ b/Core/Registry/IRegistryQuerier.cs
@@ -194,7 +194,7 @@ public static bool HasUpdate(this IRegistryQuerier querier, string identifier, G
{
RelationshipResolver resolver = new RelationshipResolver(
new CkanModule[] { newest_version },
- null,
+ new CkanModule[] { querier.InstalledModule(identifier).Module },
new RelationshipResolverOptions()
{
with_recommends = false,
diff --git a/Core/Relationships/RelationshipResolver.cs b/Core/Relationships/RelationshipResolver.cs
index 87fd39ddca..9b45e04ee9 100644
--- a/Core/Relationships/RelationshipResolver.cs
+++ b/Core/Relationships/RelationshipResolver.cs
@@ -247,9 +247,9 @@ private void AddModulesToInstall(IEnumerable modules)
{
log.DebugFormat("Preparing to resolve relationships for {0} {1}", module.identifier, module.version);
- //Need to check against installed mods and those to install.
- var mods = modlist.Values.Concat(installed_modules).Where(listed_mod => listed_mod.ConflictsWith(module));
- foreach (CkanModule listed_mod in mods)
+ // Need to check against installed mods and those to install.
+ var conflictingModules = modlist.Values.Concat(installed_modules).Where(listed_mod => listed_mod.ConflictsWith(module));
+ foreach (CkanModule listed_mod in conflictingModules)
{
if (options.proceed_with_inconsistencies)
{
diff --git a/GUI/Controls/AllModVersions.cs b/GUI/Controls/AllModVersions.cs
index 2641c598a9..5586ca737a 100644
--- a/GUI/Controls/AllModVersions.cs
+++ b/GUI/Controls/AllModVersions.cs
@@ -122,6 +122,11 @@ public GUIMod SelectedModule
visibleGuiModule.PropertyChanged += visibleGuiModule_PropertyChanged;
}
}
+ VersionsListView.Items.Clear();
+ if (value == null)
+ {
+ return;
+ }
// Get all the data; can put this in bg if slow
GameInstance currentInstance = Main.Instance.Manager.CurrentInstance;
@@ -139,16 +144,28 @@ public GUIMod SelectedModule
}
catch (ModuleNotFoundKraken)
{
- // No versions to be shown, abort and hope an auto refresh happens
+ // Identifier unknown to registry, maybe installed from local .ckan
+ allAvailableVersions = new Dictionary();
+ }
+
+ // Take the module associated with GUIMod, if any, and append it to the list if it's not already there.
+ var installedModule = value.InstalledMod?.Module;
+ if (installedModule != null && !allAvailableVersions.ContainsKey(installedModule))
+ {
+ allAvailableVersions.Add(installedModule, installable(installer, installedModule, registry));
+ }
+
+ if (!allAvailableVersions.Any())
+ {
return;
}
+
ModuleVersion installedVersion = registry.InstalledVersion(value.Identifier);
// Update UI; must be in fg
ignoreItemCheck = true;
bool latestCompatibleVersionAlreadyFound = false;
- VersionsListView.Items.Clear();
// Only show checkboxes for non-DLC modules
VersionsListView.CheckBoxes = !value.ToModule().IsDLC;
diff --git a/GUI/Controls/ManageMods.Designer.cs b/GUI/Controls/ManageMods.Designer.cs
index 1e4ac0a7b5..294b8e574e 100644
--- a/GUI/Controls/ManageMods.Designer.cs
+++ b/GUI/Controls/ManageMods.Designer.cs
@@ -1,4 +1,6 @@
-namespace CKAN
+using System.Windows.Forms;
+
+namespace CKAN
{
partial class ManageMods
{
@@ -98,6 +100,7 @@ private void InitializeComponent()
this.FilterToolButton,
this.NavBackwardToolButton,
this.NavForwardToolButton});
+ this.menuStrip2.CanOverflow = true;
this.menuStrip2.Location = new System.Drawing.Point(0, 0);
this.menuStrip2.Name = "menuStrip2";
this.menuStrip2.Size = new System.Drawing.Size(5876, 48);
@@ -110,6 +113,7 @@ private void InitializeComponent()
this.launchGameToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
this.launchGameToolStripMenuItem.Name = "launchGameToolStripMenuItem";
this.launchGameToolStripMenuItem.Size = new System.Drawing.Size(146, 56);
+ this.launchGameToolStripMenuItem.Overflow = ToolStripItemOverflow.AsNeeded;
this.launchGameToolStripMenuItem.Click += new System.EventHandler(this.launchGameToolStripMenuItem_Click);
resources.ApplyResources(this.launchGameToolStripMenuItem, "launchGameToolStripMenuItem");
//
@@ -119,6 +123,7 @@ private void InitializeComponent()
this.RefreshToolButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
this.RefreshToolButton.Name = "RefreshToolButton";
this.RefreshToolButton.Size = new System.Drawing.Size(114, 56);
+ this.RefreshToolButton.Overflow = ToolStripItemOverflow.AsNeeded;
this.RefreshToolButton.Click += new System.EventHandler(this.RefreshToolButton_Click);
resources.ApplyResources(this.RefreshToolButton, "RefreshToolButton");
//
@@ -128,6 +133,7 @@ private void InitializeComponent()
this.UpdateAllToolButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
this.UpdateAllToolButton.Name = "UpdateAllToolButton";
this.UpdateAllToolButton.Size = new System.Drawing.Size(232, 56);
+ this.UpdateAllToolButton.Overflow = ToolStripItemOverflow.AsNeeded;
this.UpdateAllToolButton.Click += new System.EventHandler(this.MarkAllUpdatesToolButton_Click);
resources.ApplyResources(this.UpdateAllToolButton, "UpdateAllToolButton");
//
@@ -137,6 +143,7 @@ private void InitializeComponent()
this.ApplyToolButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
this.ApplyToolButton.Name = "ApplyToolButton";
this.ApplyToolButton.Size = new System.Drawing.Size(173, 56);
+ this.ApplyToolButton.Overflow = ToolStripItemOverflow.AsNeeded;
this.ApplyToolButton.Click += new System.EventHandler(this.ApplyToolButton_Click);
resources.ApplyResources(this.ApplyToolButton, "ApplyToolButton");
//
@@ -161,6 +168,7 @@ private void InitializeComponent()
this.FilterToolButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
this.FilterToolButton.Name = "FilterToolButton";
this.FilterToolButton.Size = new System.Drawing.Size(201, 56);
+ this.FilterToolButton.Overflow = ToolStripItemOverflow.AsNeeded;
resources.ApplyResources(this.FilterToolButton, "FilterToolButton");
//
// FilterCompatibleButton
@@ -253,6 +261,7 @@ private void InitializeComponent()
this.NavBackwardToolButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
this.NavBackwardToolButton.Name = "NavBackwardToolButton";
this.NavBackwardToolButton.Size = new System.Drawing.Size(44, 56);
+ this.NavBackwardToolButton.Overflow = ToolStripItemOverflow.AsNeeded;
this.NavBackwardToolButton.Click += new System.EventHandler(this.NavBackwardToolButton_Click);
resources.ApplyResources(this.NavBackwardToolButton, "NavBackwardToolButton");
//
@@ -262,6 +271,7 @@ private void InitializeComponent()
this.NavForwardToolButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
this.NavForwardToolButton.Name = "NavForwardToolButton";
this.NavForwardToolButton.Size = new System.Drawing.Size(44, 56);
+ this.NavForwardToolButton.Overflow = ToolStripItemOverflow.AsNeeded;
this.NavForwardToolButton.Click += new System.EventHandler(this.NavForwardToolButton_Click);
resources.ApplyResources(this.NavForwardToolButton, "NavForwardToolButton");
//
diff --git a/GUI/Controls/ManageMods.cs b/GUI/Controls/ManageMods.cs
index 76eb2492a1..36106baa26 100644
--- a/GUI/Controls/ManageMods.cs
+++ b/GUI/Controls/ManageMods.cs
@@ -786,8 +786,21 @@ public void ClearChangeSet()
{
mod.SetInstallChecked(row, Installed, mod.IsInstalled);
}
+ else if (mod.SelectedMod != mod.InstalledMod?.Module)
+ {
+ mod.SelectedMod = mod.InstalledMod?.Module;
+ }
mod.SetUpgradeChecked(row, UpdateCol, false);
mod.SetReplaceChecked(row, ReplaceCol, false);
+ // Marking a mod as AutoInstalled can immediately queue it for removal if there is no dependent mod.
+ // Reset the state of the AutoInstalled checkbox for these by deducing it from the changeset.
+ if (mod.InstalledMod != null &&
+ ChangeSet.Contains(new ModChange(mod.InstalledMod?.Module, GUIModChangeType.Remove,
+ new SelectionReason.NoLongerUsed()))
+ )
+ {
+ mod.SetAutoInstallChecked(row, AutoInstalled, false);
+ }
}
}
diff --git a/GUI/Controls/ModInfo.cs b/GUI/Controls/ModInfo.cs
index 714eeeb3fb..5084358d43 100644
--- a/GUI/Controls/ModInfo.cs
+++ b/GUI/Controls/ModInfo.cs
@@ -140,7 +140,7 @@ private void UpdateModInfo(GUIMod gui_module)
Util.Invoke(MetadataModuleAuthorTextBox, () => MetadataModuleAuthorTextBox.Text = gui_module.Authors);
Util.Invoke(MetadataIdentifierTextBox, () => MetadataIdentifierTextBox.Text = module.identifier);
- Util.Invoke(MetadataModuleReleaseStatusTextBox, () =>
+ Util.Invoke(MetadataModuleReleaseStatusTextBox, () =>
{
if (module.release_status == null)
{
diff --git a/GUI/Controls/Wait.Designer.cs b/GUI/Controls/Wait.Designer.cs
index 51b994eca0..8f6715cb71 100644
--- a/GUI/Controls/Wait.Designer.cs
+++ b/GUI/Controls/Wait.Designer.cs
@@ -37,18 +37,19 @@ private void InitializeComponent()
this.BottomButtonPanel = new System.Windows.Forms.Panel();
this.CancelCurrentActionButton = new System.Windows.Forms.Button();
this.RetryCurrentActionButton = new System.Windows.Forms.Button();
+ this.OkButton = new System.Windows.Forms.Button();
this.SuspendLayout();
- //
+ //
// TopPanel
- //
+ //
this.TopPanel.Controls.Add(this.MessageTextBox);
this.TopPanel.Controls.Add(this.DialogProgressBar);
this.TopPanel.Dock = System.Windows.Forms.DockStyle.Top;
this.TopPanel.Name = "TopPanel";
this.TopPanel.Size = new System.Drawing.Size(500, 85);
- //
+ //
// MessageTextBox
- //
+ //
this.MessageTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right))); this.MessageTextBox.BackColor = System.Drawing.SystemColors.Control;
this.MessageTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
@@ -62,9 +63,9 @@ private void InitializeComponent()
this.MessageTextBox.TabIndex = 0;
this.MessageTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
resources.ApplyResources(this.MessageTextBox, "MessageTextBox");
- //
+ //
// DialogProgressBar
- //
+ //
this.DialogProgressBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.DialogProgressBar.Location = new System.Drawing.Point(5, 45);
@@ -75,9 +76,9 @@ private void InitializeComponent()
this.DialogProgressBar.Size = new System.Drawing.Size(490, 25);
this.DialogProgressBar.Style = System.Windows.Forms.ProgressBarStyle.Marquee;
this.DialogProgressBar.TabIndex = 1;
- //
+ //
// LogTextBox
- //
+ //
this.LogTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.LogTextBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.LogTextBox.Location = new System.Drawing.Point(14, 89);
@@ -89,41 +90,54 @@ private void InitializeComponent()
this.LogTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.LogTextBox.Size = new System.Drawing.Size(500, 400);
this.LogTextBox.TabIndex = 2;
- //
+ //
// BottomButtonPanel
- //
- this.BottomButtonPanel.Controls.Add(this.CancelCurrentActionButton);
+ //
this.BottomButtonPanel.Controls.Add(this.RetryCurrentActionButton);
+ this.BottomButtonPanel.Controls.Add(this.CancelCurrentActionButton);
+ this.BottomButtonPanel.Controls.Add(this.OkButton);
this.BottomButtonPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
this.BottomButtonPanel.Name = "BottomButtonPanel";
this.BottomButtonPanel.Size = new System.Drawing.Size(500, 40);
- //
+ //
// RetryCurrentActionButton
- //
+ //
this.RetryCurrentActionButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.RetryCurrentActionButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
- this.RetryCurrentActionButton.Location = new System.Drawing.Point(266, 5);
+ this.RetryCurrentActionButton.Location = new System.Drawing.Point(149, 5);
this.RetryCurrentActionButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.RetryCurrentActionButton.Name = "RetryCurrentActionButton";
this.RetryCurrentActionButton.Size = new System.Drawing.Size(112, 30);
this.RetryCurrentActionButton.TabIndex = 3;
this.RetryCurrentActionButton.Click += new System.EventHandler(this.RetryCurrentActionButton_Click);
resources.ApplyResources(this.RetryCurrentActionButton, "RetryCurrentActionButton");
- //
+ //
// CancelCurrentActionButton
- //
+ //
this.CancelCurrentActionButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.CancelCurrentActionButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
- this.CancelCurrentActionButton.Location = new System.Drawing.Point(383, 5);
+ this.CancelCurrentActionButton.Location = new System.Drawing.Point(266, 5);
this.CancelCurrentActionButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.CancelCurrentActionButton.Name = "CancelCurrentActionButton";
this.CancelCurrentActionButton.Size = new System.Drawing.Size(112, 30);
this.CancelCurrentActionButton.TabIndex = 4;
this.CancelCurrentActionButton.Click += new System.EventHandler(this.CancelCurrentActionButton_Click);
resources.ApplyResources(this.CancelCurrentActionButton, "CancelCurrentActionButton");
- //
+ //
+ // OkButton
+ //
+ this.OkButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.OkButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.OkButton.Location = new System.Drawing.Point(383, 5);
+ this.OkButton.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
+ this.OkButton.Name = "OkButton";
+ this.OkButton.Size = new System.Drawing.Size(112, 30);
+ this.OkButton.TabIndex = 5;
+ this.OkButton.Click += new System.EventHandler(this.OkButton_Click);
+ resources.ApplyResources(this.OkButton, "OkButton");
+ //
// Wait
- //
+ //
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Controls.Add(this.LogTextBox);
this.Controls.Add(this.TopPanel);
@@ -146,5 +160,6 @@ private void InitializeComponent()
private System.Windows.Forms.Panel BottomButtonPanel;
private System.Windows.Forms.Button RetryCurrentActionButton;
private System.Windows.Forms.Button CancelCurrentActionButton;
+ private System.Windows.Forms.Button OkButton;
}
}
diff --git a/GUI/Controls/Wait.cs b/GUI/Controls/Wait.cs
index b2016bfb2a..36bda98f82 100644
--- a/GUI/Controls/Wait.cs
+++ b/GUI/Controls/Wait.cs
@@ -17,6 +17,7 @@ public Wait()
public event Action OnRetry;
public event Action OnCancel;
+ public event Action OnOk;
public bool RetryEnabled
{
@@ -199,6 +200,7 @@ public void Reset(bool cancelable)
ProgressIndeterminate = true;
RetryCurrentActionButton.Enabled = false;
CancelCurrentActionButton.Enabled = cancelable;
+ OkButton.Enabled = false;
MessageTextBox.Text = Properties.Resources.MainWaitPleaseWait;
});
}
@@ -212,6 +214,7 @@ public void Finish(bool success)
ProgressIndeterminate = false;
RetryCurrentActionButton.Enabled = !success;
CancelCurrentActionButton.Enabled = false;
+ OkButton.Enabled = true;
});
}
@@ -250,5 +253,13 @@ private void CancelCurrentActionButton_Click(object sender, EventArgs e)
Util.Invoke(this, () =>
CancelCurrentActionButton.Enabled = false);
}
+
+ private void OkButton_Click(object sender, EventArgs e)
+ {
+ if (OnOk != null)
+ {
+ OnOk();
+ }
+ }
}
}
diff --git a/GUI/Controls/Wait.resx b/GUI/Controls/Wait.resx
index 4ac4273fb8..e273d4364b 100644
--- a/GUI/Controls/Wait.resx
+++ b/GUI/Controls/Wait.resx
@@ -119,5 +119,6 @@
Cancel
Retry
+ OK
Waiting for operation to complete
diff --git a/GUI/Dialogs/ManageGameInstancesDialog.cs b/GUI/Dialogs/ManageGameInstancesDialog.cs
index 2158b625d7..4a04afafb0 100644
--- a/GUI/Dialogs/ManageGameInstancesDialog.cs
+++ b/GUI/Dialogs/ManageGameInstancesDialog.cs
@@ -19,7 +19,7 @@ public partial class ManageGameInstancesDialog : Form
Filter = GameFolderFilter(Main.Instance.Manager),
Multiselect = false
};
-
+
///
/// Generate filter string for OpenFileDialog
///
@@ -213,7 +213,7 @@ private void GameInstancesListView_Click(object sender, MouseEventArgs e)
private void OpenDirectoryMenuItem_Click(object sender, EventArgs e)
{
- string path = GameInstancesListView.SelectedItems[0].SubItems[2].Text;
+ string path = _manager.Instances[(string) GameInstancesListView.SelectedItems[0].Tag].GameDir();
if (!Directory.Exists(path))
{
diff --git a/GUI/Main/Main.Designer.cs b/GUI/Main/Main.Designer.cs
index 2fb74ff161..17e51b02fe 100644
--- a/GUI/Main/Main.Designer.cs
+++ b/GUI/Main/Main.Designer.cs
@@ -401,9 +401,9 @@ private void InitializeComponent()
this.ManageModsTabPage.Size = new System.Drawing.Size(1536, 948);
this.ManageModsTabPage.TabIndex = 3;
resources.ApplyResources(this.ManageModsTabPage, "ManageModsTabPage");
- //
+ //
// ManageMods
- //
+ //
this.ManageMods.Dock = System.Windows.Forms.DockStyle.Fill;
this.ManageMods.Location = new System.Drawing.Point(0, 0);
this.ManageMods.Margin = new System.Windows.Forms.Padding(0,0,0,0);
@@ -467,6 +467,7 @@ private void InitializeComponent()
this.Wait.TabIndex = 32;
this.Wait.OnRetry += Wait_OnRetry;
this.Wait.OnCancel += Wait_OnCancel;
+ this.Wait.OnOk += Wait_OnOk;
//
// ChooseRecommendedModsTabPage
//
diff --git a/GUI/Main/MainChangeset.cs b/GUI/Main/MainChangeset.cs
index db2935f90c..51d59d51cd 100644
--- a/GUI/Main/MainChangeset.cs
+++ b/GUI/Main/MainChangeset.cs
@@ -1,3 +1,4 @@
+using System;
using System.Linq;
using System.Collections.Generic;
using System.Windows.Forms;
@@ -37,13 +38,22 @@ private void Changeset_OnConfirmChanges()
// 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.
- installWorker.RunWorkerAsync(
- new KeyValuePair, RelationshipResolverOptions>(
- ManageMods.mainModList.ComputeUserChangeSet(RegistryManager.Instance(Main.Instance.CurrentInstance).registry).ToList(),
- RelationshipResolver.DependsOnlyOpts()
- )
- );
+ try
+ {
+ installWorker.RunWorkerAsync(
+ new KeyValuePair, RelationshipResolverOptions>(
+ ManageMods.mainModList
+ .ComputeUserChangeSet(RegistryManager.Instance(Main.Instance.CurrentInstance).registry)
+ .ToList(),
+ RelationshipResolver.DependsOnlyOpts()
+ )
+ );
+ }
+ catch (InvalidOperationException)
+ {
+ // Thrown if it's already busy, can happen if the user fouble-clicks the button. Ignore it.
+ // More thread-safe than checking installWorker.IsBusy beforehand.
+ }
}
-
}
}
diff --git a/GUI/Main/MainInstall.cs b/GUI/Main/MainInstall.cs
index e879dd83d4..09ed64db22 100644
--- a/GUI/Main/MainInstall.cs
+++ b/GUI/Main/MainInstall.cs
@@ -142,6 +142,8 @@ out Dictionary> supporters
if (installCanceled)
{
+ Util.Invoke(this, () => Enabled = true);
+ Util.Invoke(menuStrip1, () => menuStrip1.Enabled = true);
tabController.ShowTab("ManageModsTabPage");
e.Result = new KeyValuePair(false, opts.Key);
return;
@@ -236,6 +238,8 @@ out Dictionary> supporters
{
// User cancelled, get out
tabController.ShowTab("ManageModsTabPage");
+ Util.Invoke(this, () => Enabled = true);
+ Util.Invoke(menuStrip1, () => menuStrip1.Enabled = true);
e.Result = new KeyValuePair(false, opts.Key);
return;
}
@@ -291,7 +295,11 @@ private void OnModInstalled(CkanModule mod)
private void PostInstallMods(object sender, RunWorkerCompletedEventArgs e)
{
- tabController.SetTabLock(false);
+ okCallback = () =>
+ {
+ ManageMods.UpdateModsList(null);
+ okCallback = null;
+ };
if (e.Error != null)
{
@@ -410,7 +418,10 @@ private void PostInstallMods(object sender, RunWorkerCompletedEventArgs e)
}
}
- // install successful
+ Util.Invoke(this, () => Enabled = true);
+ Util.Invoke(menuStrip1, () => menuStrip1.Enabled = true);
+ tabController.SetTabLock(false);
+
AddStatusMessage(Properties.Resources.MainInstallSuccess);
HideWaitDialog(true);
}
@@ -434,9 +445,6 @@ private void PostInstallMods(object sender, RunWorkerCompletedEventArgs e)
}
}
}
-
- Util.Invoke(this, () => Enabled = true);
- Util.Invoke(menuStrip1, () => menuStrip1.Enabled = true);
}
}
}
diff --git a/GUI/Main/MainWait.cs b/GUI/Main/MainWait.cs
index eb23a69c19..bddfaf3334 100644
--- a/GUI/Main/MainWait.cs
+++ b/GUI/Main/MainWait.cs
@@ -6,6 +6,7 @@ namespace CKAN
public partial class Main
{
private Action cancelCallback;
+ private Action okCallback;
public void ShowWaitDialog(bool cancelable = true)
{
@@ -87,5 +88,16 @@ public void Wait_OnCancel()
cancelCallback();
}
}
+
+ public void Wait_OnOk()
+ {
+ if (okCallback != null)
+ {
+ okCallback();
+ }
+ Util.Invoke(this, () => Enabled = true);
+ Util.Invoke(menuStrip1, () => menuStrip1.Enabled = true);
+ tabController.SetTabLock(false);
+ }
}
}
diff --git a/GUI/Model/GUIMod.cs b/GUI/Model/GUIMod.cs
index b45152d09d..6737390908 100644
--- a/GUI/Model/GUIMod.cs
+++ b/GUI/Model/GUIMod.cs
@@ -12,7 +12,7 @@ public sealed class GUIMod : INotifyPropertyChanged
{
private CkanModule Mod { get; set; }
private CkanModule LatestCompatibleMod { get; set; }
- private InstalledModule InstalledMod { get; set; }
+ public InstalledModule InstalledMod { get; private set; }
///
/// The module of the checkbox that is checked in the MainAllModVersions list if any,
@@ -141,6 +141,8 @@ public GUIMod(InstalledModule instMod, IRegistryQuerier registry, GameVersionCri
{
LatestVersion = InstalledVersion;
}
+ // For mods not known to the registry LatestCompatibleMod is null, however the installed module might be compatible
+ IsIncompatible = incompatible ?? LatestCompatibleMod == null && !instMod.Module.IsCompatibleKSP(current_game_version);
}
///
@@ -268,6 +270,12 @@ public void UpdateIsCached()
IsCached = Main.Instance.Manager.Cache.IsMaybeCachedZip(Mod);
}
+ ///
+ /// Get the CkanModule associated with this GUIMod.
+ /// See for a method that doesn't throw.
+ ///
+ /// The CkanModule associated with this GUIMod
+ /// Thrown if no CkanModule is associated
public CkanModule ToCkanModule()
{
if (!IsCKAN)
@@ -276,6 +284,10 @@ public CkanModule ToCkanModule()
return mod;
}
+ ///
+ /// Get the CkanModule associated with this GUIMod.
+ ///
+ /// The CkanModule associated with this GUIMod or null if there is none
public CkanModule ToModule()
{
return Mod;