Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: KSP-CKAN/CKAN
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 9a17d25147a9
Choose a base ref
...
head repository: KSP-CKAN/CKAN
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 61708254eb03
Choose a head ref
  • 4 commits
  • 7 files changed
  • 2 contributors

Commits on Nov 16, 2018

  1. Copy the full SHA
    554d4ac View commit details

Commits on Nov 18, 2018

  1. Copy the full SHA
    9bd2b82 View commit details
  2. Copy the full SHA
    07ad596 View commit details

Commits on Nov 21, 2018

  1. Verified

    This commit was signed with the committer’s verified signature.
    Copy the full SHA
    6170825 View commit details
Showing with 405 additions and 220 deletions.
  1. +1 −0 CHANGELOG.md
  2. +2 −0 GUI/CKAN-GUI.csproj
  3. +12 −0 GUI/Main.Designer.cs
  4. +0 −17 GUI/Main.cs
  5. +14 −8 GUI/MainDialogs.cs
  6. +30 −195 GUI/MainInstall.cs
  7. +346 −0 GUI/MainRecommendations.cs
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file.
- [GUI] Minimize CKAN to tray and automatic refreshing (#2565 by: Olympic1; reviewed: HebaruSan)
- [GUI] Show mod info for change set, recs/sugs, and providers (#2556 by HebaruSan; reviewed: politas)
- [Netkan] Add Netkan option to overwrite cached files (#2582 by HebaruSan; reviewed: politas)
- [GUI] Show recommendations of installed modules in GUI (#2577 by HebaruSan; reviewed: politas)

### Bugfixes

2 changes: 2 additions & 0 deletions GUI/CKAN-GUI.csproj
Original file line number Diff line number Diff line change
@@ -168,6 +168,8 @@
<Compile Include="MainModList.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainRecommendations.cs">
</Compile>
<Compile Include="MainRepo.cs">
<SubType>Form</SubType>
</Compile>
12 changes: 12 additions & 0 deletions GUI/Main.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 0 additions & 17 deletions GUI/Main.cs
Original file line number Diff line number Diff line change
@@ -1018,11 +1018,6 @@ private void ChangesListView_SelectedIndexChanged(object sender, EventArgs e)
ShowSelectionModInfo(ChangesListView.SelectedItems);
}

private void RecommendedModsListView_SelectedIndexChanged(object sender, EventArgs e)
{
ShowSelectionModInfo(RecommendedModsListView.SelectedItems);
}

private void ChooseProvidedModsListView_SelectedIndexChanged(object sender, EventArgs e)
{
ShowSelectionModInfo(ChooseProvidedModsListView.SelectedItems);
@@ -1054,18 +1049,6 @@ private void MainTabControl_OnSelectedIndexChanged(object sender, EventArgs e)
}
}

private void RecommendedModsToggleCheckbox_CheckedChanged(object sender, EventArgs e)
{
var state = ((CheckBox)sender).Checked;
foreach (ListViewItem item in RecommendedModsListView.Items)
{
if (item.Checked != state)
item.Checked = state;
}

RecommendedModsListView.Refresh();
}

private void reportAnIssueToolStripMenuItem_Click(object sender, EventArgs e)
{
Process.Start("https://github.com/KSP-CKAN/NetKAN/issues/new");
22 changes: 14 additions & 8 deletions GUI/MainDialogs.cs
Original file line number Diff line number Diff line change
@@ -40,23 +40,29 @@ public bool YesNoDialog(string text)
return yesNoDialog.ShowYesNoDialog(text) == DialogResult.Yes;
}

//Ugly Hack. Possible fix is to alter the relationship provider so we can use a loop
//over reason for to find a user requested mod. Or, you know, pass in a handler to it.
// Ugly Hack. Possible fix is to alter the relationship provider so we can use a loop
// over reason for to find a user requested mod. Or, you know, pass in a handler to it.
private readonly ConcurrentStack<GUIMod> last_mod_to_have_install_toggled = new ConcurrentStack<GUIMod>();
public async Task<CkanModule> TooManyModsProvide(TooManyModsProvideKraken kraken)
{
//We want LMtHIT to be the last user selection. If we alter this handling a too many provides
// it needs to be reset so a potential second too many provides doesn't use the wrong mod.
GUIMod mod;

private async Task<CkanModule> TooManyModsProvideCore(TooManyModsProvideKraken kraken)
{
TaskCompletionSource<CkanModule> task = new TaskCompletionSource<CkanModule>();
Util.Invoke(this, () =>
{
UpdateProvidedModsDialog(kraken, task);
tabController.ShowTab("ChooseProvidedModsTabPage", 3);
tabController.SetTabLock(true);
});
var module = await task.Task;
return await task.Task;
}

public async Task<CkanModule> TooManyModsProvide(TooManyModsProvideKraken kraken)
{
// We want LMtHIT to be the last user selection. If we alter this handling a too many provides
// it needs to be reset so a potential second too many provides doesn't use the wrong mod.
GUIMod mod;

var module = await TooManyModsProvideCore(kraken);

if (module == null
&& last_mod_to_have_install_toggled.TryPeek(out mod))
225 changes: 30 additions & 195 deletions GUI/MainInstall.cs
Original file line number Diff line number Diff line change
@@ -19,9 +19,6 @@ public partial class Main
// this may happen on the recommended/suggested mods dialogs
private volatile bool installCanceled;

// this will be the final list of mods we want to install
private HashSet<CkanModule> toInstall = new HashSet<CkanModule>();

/// <summary>
/// Initiate the GUI installer flow for one specific module
/// </summary>
@@ -90,7 +87,8 @@ private void InstallMods(object sender, DoWorkEventArgs e) // this probably need
installer.onReportModInstalled += OnModInstalled;
// setup progress callback

toInstall = new HashSet<CkanModule>();
// this will be the final list of mods we want to install
HashSet<CkanModule> toInstall = new HashSet<CkanModule>();
var toUninstall = new HashSet<string>();
var toUpgrade = new HashSet<string>();

@@ -120,13 +118,13 @@ private void InstallMods(object sender, DoWorkEventArgs e) // this probably need
{
if (change.ChangeType == GUIModChangeType.Install)
{
AddMod(change.Mod.ToModule().recommends, recommended, change.Mod.Identifier, registry);
AddMod(change.Mod.ToModule().suggests, suggested, change.Mod.Identifier, registry);
AddMod(change.Mod.ToModule().recommends, recommended, change.Mod.Identifier, registry, toInstall);
AddMod(change.Mod.ToModule().suggests, suggested, change.Mod.Identifier, registry, toInstall);
}
}

ShowSelection(recommended);
ShowSelection(suggested, true);
ShowSelection(recommended, toInstall);
ShowSelection(suggested, toInstall, true);

tabController.HideTab("ChooseRecommendedModsTabPage");

@@ -174,6 +172,30 @@ private void InstallMods(object sender, DoWorkEventArgs e) // this probably need
}
resolvedAllProvidedMods = true;
}
catch (TooManyModsProvideKraken k)
{
// Prompt user to choose which mod to use
CkanModule chosen = TooManyModsProvideCore(k).Result;
// Close the selection prompt
Util.Invoke(this, () =>
{
tabController.ShowTab("WaitTabPage");
tabController.HideTab("ChooseProvidedModsTabPage");
});
if (chosen != null)
{
// User picked a mod, queue it up for installation
toInstall.Add(chosen);
// DON'T return so we can loop around and try the above InstallList call again
}
else
{
// User cancelled, get out
tabController.ShowTab("ManageModsTabPage");
e.Result = new KeyValuePair<bool, ModChanges>(false, opts.Key);
return;
}
}
catch (DependencyNotSatisfiedKraken ex)
{
GUI.user.RaiseMessage(
@@ -294,80 +316,6 @@ private void InstallMods(object sender, DoWorkEventArgs e) // this probably need
}
}

private void AddMod(
IEnumerable<RelationshipDescriptor> relations,
Dictionary<CkanModule, List<string>> chooseAble,
string identifier,
IRegistryQuerier registry)
{
if (relations == null)
return;
foreach (RelationshipDescriptor rel in relations)
{
List<CkanModule> providers = registry.LatestAvailableWithProvides(
rel.name,
CurrentInstance.VersionCriteria(),
rel
);
foreach (CkanModule provider in providers)
{
if (!registry.IsInstalled(provider.identifier)
&& !toInstall.Any(m => m.identifier == provider.identifier))
{
// We want to show this mod to the user. Add it.
List<string> dependers;
if (chooseAble.TryGetValue(provider, out dependers))
{
// Add the dependent mod to the list of reasons this dependency is shown.
dependers.Add(identifier);
}
else
{
// Add a new entry if this provider isn't listed yet.
chooseAble.Add(provider, new List<string>() { identifier });
}
}
}
}
}

private void ShowSelection(Dictionary<CkanModule, List<string>> selectable, bool suggest = false)
{
if (installCanceled)
return;

// If we're going to install something anyway, then don't list it in the
// recommended list, since they can't de-select it anyway.
// The ToList dance is because we need to modify the dictionary while iterating over it,
// and C# doesn't like that.
foreach (CkanModule module in selectable.Keys.ToList())
{
if (toInstall.Any(m => m.identifier == module.identifier))
{
selectable.Remove(module);
}
}

Dictionary<CkanModule, string> mods = GetShowableMods(selectable);

// If there are any mods that would be recommended, prompt the user to make
// selections.
if (mods.Any())
{
Util.Invoke(this, () => UpdateRecommendedDialog(mods, suggest));

tabController.ShowTab("ChooseRecommendedModsTabPage", 3);
tabController.SetTabLock(true);

lock (this)
{
Monitor.Wait(this);
}

tabController.SetTabLock(false);
}
}

private void OnModInstalled(CkanModule mod)
{
AddStatusMessage("Module \"{0}\" successfully installed", mod.name);
@@ -485,118 +433,5 @@ private void ChooseProvidedModsContinueButton_Click(object sender, EventArgs e)
}
}

/// <summary>
/// Tries to get every mod in the Dictionary, which can be installed
/// It also transforms the Recommender list to a string
/// </summary>
/// <param name="mods"></param>
/// <returns></returns>
private Dictionary<CkanModule, string> GetShowableMods(Dictionary<CkanModule, List<string>> mods)
{
Dictionary<CkanModule, string> modules = new Dictionary<CkanModule, string>();

var opts = new RelationshipResolverOptions
{
with_all_suggests = false,
with_recommends = false,
with_suggests = false,
without_enforce_consistency = false,
without_toomanyprovides_kraken = true
};

foreach (var pair in mods)
{
try
{
RelationshipResolver resolver = new RelationshipResolver(
new List<CkanModule> { pair.Key },
null,
opts,
RegistryManager.Instance(manager.CurrentInstance).registry,
CurrentInstance.VersionCriteria()
);

if (resolver.ModList().Any())
{
// Resolver was able to find a way to install, so show it to the user
modules.Add(pair.Key, String.Join(",", pair.Value.ToArray()));
}
}
catch { }
}
return modules;
}

private void UpdateRecommendedDialog(Dictionary<CkanModule, string> mods, bool suggested = false)
{
if (!suggested)
{
RecommendedDialogLabel.Text =
"The following modules have been recommended by one or more of the chosen modules:";
RecommendedModsListView.Columns[1].Text = "Recommended by:";
RecommendedModsToggleCheckbox.Text = "(De-)select all recommended mods.";
RecommendedModsToggleCheckbox.Checked=true;
tabController.RenameTab("ChooseRecommendedModsTabPage", "Choose recommended mods");
}
else
{
RecommendedDialogLabel.Text =
"The following modules have been suggested by one or more of the chosen modules:";
RecommendedModsListView.Columns[1].Text = "Suggested by:";
RecommendedModsToggleCheckbox.Text = "(De-)select all suggested mods.";
RecommendedModsToggleCheckbox.Checked=false;
tabController.RenameTab("ChooseRecommendedModsTabPage", "Choose suggested mods");
}

RecommendedModsListView.Items.Clear();
foreach (var pair in mods)
{
CkanModule module = pair.Key;
ListViewItem item = new ListViewItem()
{
Tag = module,
Checked = !suggested,
Text = Manager.Cache.IsMaybeCachedZip(pair.Key)
? $"{pair.Key.name} {pair.Key.version} (cached)"
: $"{pair.Key.name} {pair.Key.version} ({pair.Key.download.Host ?? ""}, {CkanModule.FmtSize(pair.Key.download_size)})"
};

ListViewItem.ListViewSubItem recommendedBy = new ListViewItem.ListViewSubItem() { Text = pair.Value };

item.SubItems.Add(recommendedBy);

ListViewItem.ListViewSubItem description = new ListViewItem.ListViewSubItem {Text = module.@abstract};

item.SubItems.Add(description);

RecommendedModsListView.Items.Add(item);
}
}

private void RecommendedModsContinueButton_Click(object sender, EventArgs e)
{
foreach (ListViewItem item in RecommendedModsListView.Items)
{
if (item.Checked)
{
toInstall.Add((CkanModule) item.Tag);
}
}

lock (this)
{
Monitor.Pulse(this);
}
}

private void RecommendedModsCancelButton_Click(object sender, EventArgs e)
{
installCanceled = true;

lock (this)
{
Monitor.Pulse(this);
}
}
}
}
Loading