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; TaskCompletionSource <CkanModule> task = new TaskCompletionSource <CkanModule>(); Util.Invoke(this, () => { UpdateProvidedModsDialog(kraken, task); tabController.ShowTab("ChooseProvidedModsTabPage", 3); tabController.SetTabLock(true); }); var module = await task.Task; if (module == null) { last_mod_to_have_install_toggled.TryPeek(out mod); MarkModForInstall(mod.Identifier, uncheck: true); } Util.Invoke(this, () => { tabController.SetTabLock(false); tabController.HideTab("ChooseProvidedModsTabPage"); tabController.ShowTab("ManageModsTabPage"); }); if (module != null) { MarkModForInstall(module.identifier); } last_mod_to_have_install_toggled.TryPop(out mod); return(module); }
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 PostUpdateRepo(object sender, RunWorkerCompletedEventArgs e) { var resultPair = e.Result as KeyValuePair <RepoUpdateResult, Dictionary <string, bool> >?; RepoUpdateResult? result = resultPair?.Key; Dictionary <string, bool> oldModules = resultPair?.Value; switch (result) { case RepoUpdateResult.NoChanges: AddStatusMessage(Properties.Resources.MainRepoUpToDate); HideWaitDialog(true); // Load rows if grid empty, otherwise keep current if (ManageMods.ModGrid.Rows.Count < 1) { ManageMods.UpdateModsList(); } break; case RepoUpdateResult.Failed: AddStatusMessage(Properties.Resources.MainRepoFailed); HideWaitDialog(false); break; case RepoUpdateResult.Updated: default: ManageMods.UpdateModsList(oldModules); AddStatusMessage(Properties.Resources.MainRepoSuccess); ShowRefreshQuestion(); HideWaitDialog(true); UpgradeNotification(); break; } tabController.HideTab("WaitTabPage"); Util.Invoke(this, SwitchEnabledState); Util.Invoke(this, RecreateDialogs); Util.Invoke(this, ManageMods.ModGrid.Select); }
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)) { MarkModForInstall(mod.Identifier, true); } Util.Invoke(this, () => { tabController.SetTabLock(false); tabController.HideTab("ChooseProvidedModsTabPage"); tabController.ShowTab("ManageModsTabPage"); }); last_mod_to_have_install_toggled.TryPop(out mod); return(module); }
private void CurrentInstanceUpdated() { Util.Invoke(this, () => { Text = $"CKAN {Meta.GetVersion()} - KSP {CurrentInstance.Version()} -- {CurrentInstance.GameDir()}"; }); configuration = Configuration.LoadOrCreateConfiguration( Path.Combine(CurrentInstance.CkanDir(), "GUIConfig.xml") ); if (CurrentInstance.CompatibleVersionsAreFromDifferentKsp) { new CompatibleKspVersionsDialog(CurrentInstance, !actuallyVisible) .ShowDialog(); } UpdateModsList(); ChangeSet = null; Conflicts = null; Filter((GUIModFilter)configuration.ActiveFilter); }
private void LabelsAfterUpdate(IEnumerable <GUIMod> mods) { Util.Invoke(Main.Instance, () => { mods = mods.Memoize(); var notifLabs = mainModList.ModuleLabels.LabelsFor(CurrentInstance.Name) .Where(l => l.NotifyOnChange) .Memoize(); var toNotif = mods .Where(m => notifLabs.Any(l => l.ModuleIdentifiers.Contains(m.Identifier))) .Select(m => m.Name) .Memoize(); if (toNotif.Any()) { MessageBox.Show( string.Format( Properties.Resources.MainLabelsUpdateMessage, string.Join("\r\n", toNotif) ), Properties.Resources.MainLabelsUpdateTitle, MessageBoxButtons.OK ); } foreach (GUIMod mod in mods) { foreach (ModuleLabel l in mainModList.ModuleLabels.LabelsFor(CurrentInstance.Name) .Where(l => l.RemoveOnChange && l.ModuleIdentifiers.Contains(mod.Identifier))) { l.Remove(mod.Identifier); } } }); }
private void PostInstallMods(object sender, RunWorkerCompletedEventArgs e) { KeyValuePair <bool, ModChanges> result = (KeyValuePair <bool, ModChanges>)e.Result; UpdateModsList(false, result.Value); tabController.SetTabLock(false); if (result.Key) { if (modChangedCallback != null) { foreach (var mod in result.Value) { modChangedCallback(mod.Mod, mod.ChangeType); } } // install successful AddStatusMessage("Success!"); HideWaitDialog(true); tabController.HideTab("ChangesetTabPage"); ApplyToolButton.Enabled = false; } else { // there was an error // rollback user's choices but stay on the log dialog AddStatusMessage("Error!"); SetDescription("An error occurred, check the log for information"); Util.Invoke(DialogProgressBar, () => DialogProgressBar.Style = ProgressBarStyle.Continuous); Util.Invoke(DialogProgressBar, () => DialogProgressBar.Value = 0); } Util.Invoke(this, () => Enabled = true); Util.Invoke(menuStrip1, () => menuStrip1.Enabled = true); }
public void CurrentInstanceUpdated() { Util.Invoke(this, () => { Text = String.Format("CKAN {0} - KSP {1} -- {2}", Meta.Version(), CurrentInstance.Version(), CurrentInstance.GameDir()); KSPVersionLabel.Text = String.Format("Kerbal Space Program {0}", CurrentInstance.Version()); }); // Update the settings dialog to reflect the changes made. Util.Invoke(m_SettingsDialog, () => { m_SettingsDialog.UpdateDialog(); }); m_Configuration = Configuration.LoadOrCreateConfiguration ( Path.Combine(CurrentInstance.GameDir(), "CKAN/GUIConfig.xml"), Repo.default_ckan_repo.ToString() ); UpdateModsList(); ChangeSet = null; Conflicts = null; }
private void PostUpdateRepo(object sender, RunWorkerCompletedEventArgs e) { var resultPair = e.Result as KeyValuePair <RepoUpdateResult, Dictionary <string, bool> >?; RepoUpdateResult? result = resultPair?.Key; Dictionary <string, bool> oldModules = resultPair?.Value; switch (result) { case RepoUpdateResult.NoChanges: AddStatusMessage("Repositories already up to date."); HideWaitDialog(true); // Load rows if grid empty, otherwise keep current if (ModList.Rows.Count < 1) { UpdateModsList(ChangeSet); } break; case RepoUpdateResult.Failed: AddStatusMessage("Repository update failed!"); break; case RepoUpdateResult.Updated: default: UpdateModsList(ChangeSet, oldModules); AddStatusMessage("Repositories successfully updated."); ShowRefreshQuestion(); HideWaitDialog(true); UpgradeNotification(); break; } Util.Invoke(this, SwitchEnabledState); Util.Invoke(this, RecreateDialogs); Util.Invoke(this, ModList.Select); }
public void LoadProviders(string message, List <CkanModule> modules, NetModuleCache cache) { Util.Invoke(this, () => { ChooseProvidedModsLabel.Text = message; ChooseProvidedModsListView.Items.Clear(); ChooseProvidedModsListView.Items.AddRange(modules .Select(module => new ListViewItem(new string[] { cache.IsMaybeCachedZip(module) ? string.Format(Properties.Resources.MainChangesetCached, module.name, module.version) : string.Format(Properties.Resources.MainChangesetHostSize, module.name, module.version, module.download.Host ?? "", CkanModule.FmtSize(module.download_size)), module.@abstract }) { Tag = module, Checked = false }) .ToArray()); ChooseProvidedModsListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); ChooseProvidedModsContinueButton.Enabled = false; }); }
public void UpdateModsList(Boolean repo_updated = false, List <ModChange> mc = null) { Util.Invoke(this, () => _UpdateModsList(repo_updated, mc ?? new List <ModChange>())); }
public void MarkModForInstall(string identifier, bool uncheck = false) { Util.Invoke(this, () => _MarkModForInstall(identifier, uncheck)); }
public void MarkModForUpdate(string identifier) { Util.Invoke(this, () => _MarkModForUpdate(identifier)); }
private void UpdateFilters(Main control) { Util.Invoke(control, _UpdateFilters); }
private void CheckForConsistency() { Util.Invoke(this, _CheckForConsistency); }
private void _UpdateModsList(IEnumerable <ModChange> mc, Dictionary <string, bool> old_modules = null) { log.Info("Updating the mod list"); ResetProgress(); tabController.RenameTab("WaitTabPage", Properties.Resources.MainModListWaitTitle); ShowWaitDialog(false); tabController.SetTabLock(true); Util.Invoke(this, SwitchEnabledState); ClearLog(); AddLogMessage(Properties.Resources.MainModListLoadingRegistry); KspVersionCriteria versionCriteria = CurrentInstance.VersionCriteria(); IRegistryQuerier registry = RegistryManager.Instance(CurrentInstance).registry; AddLogMessage(Properties.Resources.MainModListLoadingInstalled); var gui_mods = new HashSet <GUIMod>(); gui_mods.UnionWith( registry.InstalledModules .Select(instMod => new GUIMod(instMod, registry, versionCriteria)) ); AddLogMessage(Properties.Resources.MainModListLoadingAvailable); gui_mods.UnionWith( registry.Available(versionCriteria) .Select(m => new GUIMod(m, registry, versionCriteria)) ); AddLogMessage(Properties.Resources.MainModListLoadingIncompatible); gui_mods.UnionWith( registry.Incompatible(versionCriteria) .Select(m => new GUIMod(m, registry, versionCriteria, true)) ); if (mc != null) { AddLogMessage(Properties.Resources.MainModListRestoringChangeset); foreach (ModChange change in mc) { // Propagate IsInstallChecked and IsUpgradeChecked to the next generation gui_mods.FirstOrDefault( mod => mod.Identifier == change.Mod.Identifier )?.SetRequestedChange(change.ChangeType); } } AddLogMessage(Properties.Resources.MainModListPreservingNew); if (old_modules != null) { foreach (GUIMod gm in gui_mods) { bool oldIncompat; if (old_modules.TryGetValue(gm.Identifier, out oldIncompat)) { // Found it; check if newly compatible if (!gm.IsIncompatible && oldIncompat) { gm.IsNew = true; } } else { // Newly indexed, show regardless of compatibility gm.IsNew = true; } } } else { // Copy the new mod flag from the old list. var old_new_mods = new HashSet <GUIMod>( mainModList.Modules.Where(m => m.IsNew)); foreach (var gui_mod in gui_mods.Where(m => old_new_mods.Contains(m))) { gui_mod.IsNew = true; } } AddLogMessage(Properties.Resources.MainModListPopulatingList); // Update our mod listing mainModList.ConstructModList(gui_mods.ToList(), mc, configuration.HideEpochs, configuration.HideV); mainModList.Modules = new ReadOnlyCollection <GUIMod>( mainModList.full_list_of_mod_rows.Values.Select(row => row.Tag as GUIMod).ToList()); AddLogMessage(Properties.Resources.MainModListUpdatingFilters); var has_any_updates = gui_mods.Any(mod => mod.HasUpdate); var has_any_installed = gui_mods.Any(mod => mod.IsInstalled); var has_any_replacements = gui_mods.Any(mod => mod.IsInstalled && mod.HasReplacement); //TODO Consider using smart enumeration pattern so stuff like this is easier Util.Invoke(menuStrip2, () => { FilterToolButton.DropDownItems[0].Text = String.Format(Properties.Resources.MainModListCompatible, mainModList.CountModsByFilter(GUIModFilter.Compatible)); FilterToolButton.DropDownItems[1].Text = String.Format(Properties.Resources.MainModListInstalled, mainModList.CountModsByFilter(GUIModFilter.Installed)); FilterToolButton.DropDownItems[2].Text = String.Format(Properties.Resources.MainModListUpgradeable, mainModList.CountModsByFilter(GUIModFilter.InstalledUpdateAvailable)); FilterToolButton.DropDownItems[3].Text = String.Format(Properties.Resources.MainModListReplaceable, mainModList.CountModsByFilter(GUIModFilter.Replaceable)); FilterToolButton.DropDownItems[4].Text = String.Format(Properties.Resources.MainModListCached, mainModList.CountModsByFilter(GUIModFilter.Cached)); FilterToolButton.DropDownItems[5].Text = String.Format(Properties.Resources.MainModListNewlyCompatible, mainModList.CountModsByFilter(GUIModFilter.NewInRepository)); FilterToolButton.DropDownItems[6].Text = String.Format(Properties.Resources.MainModListNotInstalled, mainModList.CountModsByFilter(GUIModFilter.NotInstalled)); FilterToolButton.DropDownItems[7].Text = String.Format(Properties.Resources.MainModListIncompatible, mainModList.CountModsByFilter(GUIModFilter.Incompatible)); FilterToolButton.DropDownItems[8].Text = String.Format(Properties.Resources.MainModListAll, mainModList.CountModsByFilter(GUIModFilter.All)); UpdateAllToolButton.Enabled = has_any_updates; }); UpdateFilters(this); // Hide update and replacement columns if not needed. // Write it to the configuration, else they are hidden agian after a filter change. // After the update / replacement, they are hidden again. Util.Invoke(ModList, () => { ModList.Columns["UpdateCol"].Visible = has_any_updates; ModList.Columns["AutoInstalled"].Visible = has_any_installed && !configuration.HiddenColumnNames.Contains("AutoInstalled"); ModList.Columns["ReplaceCol"].Visible = has_any_replacements; }); AddLogMessage(Properties.Resources.MainModListUpdatingTray); UpdateTrayInfo(); HideWaitDialog(true); tabController.HideTab("WaitTabPage"); tabController.SetTabLock(false); Util.Invoke(this, SwitchEnabledState); Util.Invoke(this, () => Main.Instance.ModList.Focus()); }
private void UpdateModsList(Boolean repo_updated = false) { Util.Invoke(this, () => _UpdateModsList(repo_updated)); }
/// <summary> /// React to switching to a new game instance /// </summary> /// <param name="allowRepoUpdate">true if a repo update is allowed if needed (e.g. on initial load), false otherwise</param> private void CurrentInstanceUpdated(bool allowRepoUpdate) { CurrentInstance.Scan(); Util.Invoke(this, () => { Text = $"CKAN {Meta.GetVersion()} - {CurrentInstance.game.ShortName} {CurrentInstance.Version()} -- {CurrentInstance.GameDir().Replace('/', Path.DirectorySeparatorChar)}"; StatusInstanceLabel.Text = string.Format( Properties.Resources.StatusInstanceLabelText, CurrentInstance.Name, CurrentInstance.game.ShortName, CurrentInstance.Version()?.ToString() ); }); configuration = GUIConfiguration.LoadOrCreateConfiguration( Path.Combine(CurrentInstance.CkanDir(), "GUIConfig.xml") ); if (CurrentInstance.CompatibleVersionsAreFromDifferentGameVersion) { new CompatibleGameVersionsDialog(CurrentInstance, !actuallyVisible) .ShowDialog(); } (RegistryManager.Instance(CurrentInstance).registry as Registry) ?.BuildTagIndex(ManageMods.mainModList.ModuleTags); bool repoUpdateNeeded = configuration.RefreshOnStartup || !RegistryManager.Instance(CurrentInstance).registry.HasAnyAvailable(); if (allowRepoUpdate) { // If not allowing, don't do anything if (repoUpdateNeeded) { // Update the filters after UpdateRepo() completed. // Since this happens with a backgroundworker, Filter() is added as callback for RunWorkerCompleted. // Remove it again after it ran, else it stays there and is added again and again. void filterUpdate(object sender, RunWorkerCompletedEventArgs e) { ManageMods.Filter( (GUIModFilter)configuration.ActiveFilter, ManageMods.mainModList.ModuleTags.Tags.GetOrDefault(configuration.TagFilter), ManageMods.mainModList.ModuleLabels.LabelsFor(CurrentInstance.Name) .FirstOrDefault(l => l.Name == configuration.CustomLabelFilter) ); m_UpdateRepoWorker.RunWorkerCompleted -= filterUpdate; } m_UpdateRepoWorker.RunWorkerCompleted += filterUpdate; ManageMods.ModGrid.Rows.Clear(); UpdateRepo(); } else { ManageMods.UpdateModsList(); ManageMods.Filter( (GUIModFilter)configuration.ActiveFilter, ManageMods.mainModList.ModuleTags.Tags.GetOrDefault(configuration.TagFilter), ManageMods.mainModList.ModuleLabels.LabelsFor(CurrentInstance.Name) .FirstOrDefault(l => l.Name == configuration.CustomLabelFilter) ); } } ManageMods.InstanceUpdated(CurrentInstance); }
public void AddLogMessage(string message) { Util.Invoke(LogTextBox, () => LogTextBox.AppendText(message + "\r\n")); }
private void UpdateModDependencyGraph(CkanModule module) { Util.Invoke(DependsGraphTree, () => _UpdateModDependencyGraph(module)); }
public void PostModCaching(object sender, RunWorkerCompletedEventArgs e) { Util.Invoke(this, () => _PostModCaching((CkanModule)e.Result)); }
private void PostInstallMods(object sender, RunWorkerCompletedEventArgs e) { tabController.SetTabLock(false); if (e.Error != null) { switch (e.Error) { case DependencyNotSatisfiedKraken exc: currentUser.RaiseMessage(Properties.Resources.MainInstallDepNotSatisfied, exc.parent, exc.module); break; case ModuleNotFoundKraken exc: currentUser.RaiseMessage(Properties.Resources.MainInstallNotFound, exc.module); break; case BadMetadataKraken exc: currentUser.RaiseMessage(Properties.Resources.MainInstallBadMetadata, exc.module, exc.Message); break; case FileExistsKraken exc: if (exc.owningModule != null) { currentUser.RaiseMessage( Properties.Resources.MainInstallFileExists, exc.filename, exc.installingModule, exc.owningModule, Meta.GetVersion() ); } else { currentUser.RaiseMessage( Properties.Resources.MainInstallUnownedFileExists, exc.installingModule, exc.filename ); } currentUser.RaiseMessage(Properties.Resources.MainInstallGameDataReverted); break; case InconsistentKraken exc: currentUser.RaiseMessage(exc.InconsistenciesPretty); break; case CancelledActionKraken exc: currentUser.RaiseMessage(exc.Message); installCanceled = true; break; case MissingCertificateKraken exc: currentUser.RaiseMessage(exc.ToString()); break; case DownloadThrottledKraken exc: string msg = exc.ToString(); currentUser.RaiseMessage(msg); if (YesNoDialog(string.Format(Properties.Resources.MainInstallOpenSettingsPrompt, msg), Properties.Resources.MainInstallOpenSettings, Properties.Resources.MainInstallNo)) { // Launch the URL describing this host's throttling practices, if any if (exc.infoUrl != null) { Utilities.ProcessStartURL(exc.infoUrl.ToString()); } // Now pretend they clicked the menu option for the settings Enabled = false; new SettingsDialog(currentUser).ShowDialog(); Enabled = true; } break; case ModuleDownloadErrorsKraken exc: currentUser.RaiseMessage(exc.ToString()); currentUser.RaiseError(exc.ToString()); break; case DirectoryNotFoundKraken exc: currentUser.RaiseMessage("\r\n{0}", exc.Message); break; case ModuleIsDLCKraken exc: string dlcMsg = string.Format(Properties.Resources.MainInstallCantInstallDLC, exc.module.name); currentUser.RaiseMessage(dlcMsg); currentUser.RaiseError(dlcMsg); break; } FailWaitDialog( Properties.Resources.MainInstallErrorInstalling, Properties.Resources.MainInstallKnownError, Properties.Resources.MainInstallFailed, false ); } else { // The Result property throws if InstallMods threw (!!!) KeyValuePair <bool, ModChanges> result = (KeyValuePair <bool, ModChanges>)e.Result; if (!installCanceled) { // Rebuilds the list of GUIMods ManageMods.UpdateModsList(null); if (modChangedCallback != null) { foreach (var mod in result.Value) { modChangedCallback(mod.Mod, mod.ChangeType); } } // install successful AddStatusMessage(Properties.Resources.MainInstallSuccess); HideWaitDialog(true); } else { // User cancelled the installation if (result.Key) { FailWaitDialog( Properties.Resources.MainInstallCancelTooLate, Properties.Resources.MainInstallCancelAfterInstall, Properties.Resources.MainInstallProcessComplete, true ); } else { FailWaitDialog( Properties.Resources.MainInstallProcessCanceled, Properties.Resources.MainInstallCanceledManually, Properties.Resources.MainInstallInstallCanceled, false ); } } } Util.Invoke(this, () => Enabled = true); Util.Invoke(menuStrip1, () => menuStrip1.Enabled = true); }
/// <summary> /// Shows the selection dialog. /// </summary> /// <returns>The selected index, -1 if canceled.</returns> /// <param name="message">Message.</param> /// <param name="args">Array of items to select from.</param> public int ShowSelectionDialog(string message, params object[] args) { int defaultSelection = -1; int return_cancel = -1; // Validate input. if (String.IsNullOrWhiteSpace(message)) { throw new Kraken("Passed message string must be non-empty."); } if (args.Length == 0) { throw new Kraken("Passed list of selection candidates must be non-empty."); } // Hide the default button unless we have a default option Util.Invoke(DefaultButton, DefaultButton.Hide); // Clear the item list. Util.Invoke(OptionsList, OptionsList.Items.Clear); // Check if we have a default option. if (args[0] is int) { // Check that the default selection makes sense. defaultSelection = (int)args[0]; if (defaultSelection < 0 || defaultSelection > args.Length - 1) { throw new Kraken("Passed default arguments is out of range of the selection candidates."); } // Extract the relevant arguments. object[] newArgs = new object[args.Length - 1]; for (int i = 1; i < args.Length; i++) { newArgs[i - 1] = args[i]; } args = newArgs; // Show the defaultButton. Util.Invoke(DefaultButton, DefaultButton.Show); } // Further data validation. foreach (object argument in args) { if (String.IsNullOrWhiteSpace(argument.ToString())) { throw new Kraken("Candidate may not be empty."); } } // Add all items to the OptionsList. for (int i = 0; i < args.Length; i++) { if (defaultSelection == i) { Util.Invoke(OptionsList, () => OptionsList.Items.Add(String.Concat(args[i].ToString(), " -- Default"))); } else { Util.Invoke(OptionsList, () => OptionsList.Items.Add(args[i].ToString())); } } // Write the message to the label. Util.Invoke(MessageLabel, () => MessageLabel.Text = message); // Now show the dialog and get the return values. DialogResult result = ShowDialog(); if (result == DialogResult.Yes) { // If pressed Defaultbutton return(defaultSelection); } else if (result == DialogResult.Cancel) { // If pressed CancelButton return(return_cancel); } else { return(currentSelected); } }
public void HideYesNoDialog() { Util.Invoke(this, Close); }
// this probably needs to be refactored private void InstallMods(object sender, DoWorkEventArgs e) { installCanceled = false; Wait.ClearLog(); var opts = (KeyValuePair <ModChanges, RelationshipResolverOptions>)e.Argument; RegistryManager registry_manager = RegistryManager.Instance(manager.CurrentInstance); Registry registry = registry_manager.registry; ModuleInstaller installer = ModuleInstaller.GetInstance(CurrentInstance, Manager.Cache, currentUser); // Avoid accumulating multiple event handlers installer.onReportModInstalled -= OnModInstalled; installer.onReportModInstalled += OnModInstalled; // setup progress callback // 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>(); // First compose sets of what the user wants installed, upgraded, and removed. foreach (ModChange change in opts.Key) { switch (change.ChangeType) { case GUIModChangeType.Remove: toUninstall.Add(change.Mod.identifier); break; case GUIModChangeType.Update: toUpgrade.Add(change.Mod.identifier); break; case GUIModChangeType.Install: toInstall.Add(change.Mod); break; case GUIModChangeType.Replace: ModuleReplacement repl = registry.GetReplacement(change.Mod, CurrentInstance.VersionCriteria()); if (repl != null) { toUninstall.Add(repl.ToReplace.identifier); toInstall.Add(repl.ReplaceWith); } break; } } // Prompt for recommendations and suggestions, if any if (installer.FindRecommendations( opts.Key.Where(ch => ch.ChangeType == GUIModChangeType.Install) .Select(ch => ch.Mod) .ToHashSet(), toInstall, registry, out Dictionary <CkanModule, Tuple <bool, List <string> > > recommendations, out Dictionary <CkanModule, List <string> > suggestions, out Dictionary <CkanModule, HashSet <string> > supporters )) { tabController.ShowTab("ChooseRecommendedModsTabPage", 3); ChooseRecommendedMods.LoadRecommendations( registry, CurrentInstance.VersionCriteria(), Manager.Cache, recommendations, suggestions, supporters); tabController.SetTabLock(true); var result = ChooseRecommendedMods.Wait(); if (result == null) { installCanceled = true; } else { toInstall.UnionWith(result); } tabController.SetTabLock(false); tabController.HideTab("ChooseRecommendedModsTabPage"); } if (installCanceled) { tabController.ShowTab("ManageModsTabPage"); e.Result = new KeyValuePair <bool, ModChanges>(false, opts.Key); return; } // Now let's make all our changes. Util.Invoke(this, () => { // Need to be on the GUI thread to get the translated string tabController.RenameTab("WaitTabPage", Properties.Resources.MainInstallWaitTitle); }); ShowWaitDialog(); tabController.SetTabLock(true); IDownloader downloader = new NetAsyncModulesDownloader(currentUser, Manager.Cache); downloader.Progress += Wait.SetModuleProgress; downloader.AllComplete += Wait.DownloadsComplete; cancelCallback = () => { downloader.CancelDownload(); installCanceled = true; }; HashSet <string> possibleConfigOnlyDirs = null; // checks if all actions were successfull bool processSuccessful = false; bool resolvedAllProvidedMods = false; // uninstall/installs/upgrades until every list is empty // if the queue is NOT empty, resolvedAllProvidedMods is set to false until the action is done while (!resolvedAllProvidedMods) { try { e.Result = new KeyValuePair <bool, ModChanges>(false, opts.Key); if (toUninstall.Count > 0) { processSuccessful = false; if (!installCanceled) { installer.UninstallList(toUninstall, ref possibleConfigOnlyDirs, registry_manager, false, toInstall); processSuccessful = true; } } if (toUpgrade.Count > 0) { processSuccessful = false; if (!installCanceled) { installer.Upgrade(toUpgrade, downloader, ref possibleConfigOnlyDirs, registry_manager); processSuccessful = true; } } if (toInstall.Count > 0) { processSuccessful = false; if (!installCanceled) { installer.InstallList(toInstall, opts.Value, registry_manager, ref possibleConfigOnlyDirs, downloader, false); processSuccessful = true; } } HandlePossibleConfigOnlyDirs(registry, possibleConfigOnlyDirs); e.Result = new KeyValuePair <bool, ModChanges>(processSuccessful, opts.Key); if (installCanceled) { return; } resolvedAllProvidedMods = true; } catch (TooManyModsProvideKraken k) { // Prompt user to choose which mod to use tabController.ShowTab("ChooseProvidedModsTabPage", 3); ChooseProvidedMods.LoadProviders(k.requested, k.modules, Manager.Cache); tabController.SetTabLock(true); CkanModule chosen = ChooseProvidedMods.Wait(); // Close the selection prompt tabController.SetTabLock(false); 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 tabController.ShowTab("WaitTabPage"); } else { // User cancelled, get out tabController.ShowTab("ManageModsTabPage"); e.Result = new KeyValuePair <bool, ModChanges>(false, opts.Key); return; } } } }
public void HideErrorDialog() { Util.Invoke(this, () => Close()); }
// this probably needs to be refactored private void InstallMods(object sender, DoWorkEventArgs e) { installCanceled = false; ClearLog(); var opts = (KeyValuePair <ModChanges, RelationshipResolverOptions>)e.Argument; IRegistryQuerier registry = RegistryManager.Instance(manager.CurrentInstance).registry; ModuleInstaller installer = ModuleInstaller.GetInstance(CurrentInstance, Manager.Cache, GUI.user); // Avoid accumulating multiple event handlers installer.onReportModInstalled -= OnModInstalled; installer.onReportModInstalled += OnModInstalled; // setup progress callback // 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>(); // First compose sets of what the user wants installed, upgraded, and removed. foreach (ModChange change in opts.Key) { switch (change.ChangeType) { case GUIModChangeType.Remove: toUninstall.Add(change.Mod.Identifier); break; case GUIModChangeType.Update: toUpgrade.Add(change.Mod.Identifier); break; case GUIModChangeType.Install: toInstall.Add(change.Mod.ToModule()); break; case GUIModChangeType.Replace: ModuleReplacement repl = registry.GetReplacement(change.Mod.ToModule(), CurrentInstance.VersionCriteria()); if (repl != null) { toUninstall.Add(repl.ToReplace.identifier); toInstall.Add(repl.ReplaceWith); } break; } } // Prompt for recommendations and suggestions, if any var recRows = getRecSugRows( opts.Key.Where(ch => ch.ChangeType == GUIModChangeType.Install) .Select(ch => ch.Mod.ToModule()), registry, toInstall ); if (recRows.Any()) { ShowRecSugDialog(recRows, toInstall); } tabController.HideTab("ChooseRecommendedModsTabPage"); if (installCanceled) { tabController.ShowTab("ManageModsTabPage"); e.Result = new KeyValuePair <bool, ModChanges>(false, opts.Key); return; } // Now let's make all our changes. tabController.RenameTab("WaitTabPage", "Status log"); ShowWaitDialog(); tabController.SetTabLock(true); IDownloader downloader = new NetAsyncModulesDownloader(GUI.user); cancelCallback = () => { downloader.CancelDownload(); installCanceled = true; }; // checks if all actions were successfull bool processSuccessful = false; bool resolvedAllProvidedMods = false; // uninstall/installs/upgrades until every list is empty // if the queue is NOT empty, resolvedAllProvidedMods is set to false until the action is done while (!resolvedAllProvidedMods) { try { e.Result = new KeyValuePair <bool, ModChanges>(false, opts.Key); if (toUninstall.Count > 0) { processSuccessful = false; if (!installCanceled) { installer.UninstallList(toUninstall, false, toInstall.Select(m => m.identifier)); processSuccessful = true; } } if (toUpgrade.Count > 0) { processSuccessful = false; if (!installCanceled) { installer.Upgrade(toUpgrade, downloader); processSuccessful = true; } } if (toInstall.Count > 0) { processSuccessful = false; if (!installCanceled) { installer.InstallList(toInstall, opts.Value, downloader, false); processSuccessful = true; } } e.Result = new KeyValuePair <bool, ModChanges>(processSuccessful, opts.Key); if (installCanceled) { return; } 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( "{0} requires {1} but it is not listed in the index, or not available for your version of KSP.", ex.parent, ex.module); return; } catch (ModuleNotFoundKraken ex) { GUI.user.RaiseMessage( "Module {0} required but it is not listed in the index, or not available for your version of KSP.", ex.module); return; } catch (BadMetadataKraken ex) { GUI.user.RaiseMessage("Bad metadata detected for module {0}: {1}", ex.module, ex.Message); return; } catch (FileExistsKraken ex) { if (ex.owningModule != null) { GUI.user.RaiseMessage( "\r\nOh no! We tried to overwrite a file owned by another mod!\r\n" + "Please try a `ckan update` and try again.\r\n\r\n" + "If this problem re-occurs, then it maybe a packaging bug.\r\n" + "Please report it at:\r\n\r\n" + "https://github.com/KSP-CKAN/NetKAN/issues/new\r\n\r\n" + "Please including the following information in your report:\r\n\r\n" + "File : {0}\r\n" + "Installing Mod : {1}\r\n" + "Owning Mod : {2}\r\n" + "CKAN Version : {3}\r\n", ex.filename, ex.installingModule, ex.owningModule, Meta.GetVersion() ); } else { GUI.user.RaiseMessage( "\r\n\r\nOh no!\r\n\r\n" + "It looks like you're trying to install a mod which is already installed,\r\n" + "or which conflicts with another mod which is already installed.\r\n\r\n" + "As a safety feature, the CKAN will *never* overwrite or alter a file\r\n" + "that it did not install itself.\r\n\r\n" + "If you wish to install {0} via the CKAN,\r\n" + "then please manually uninstall the mod which owns:\r\n\r\n" + "{1}\r\n\r\n" + "and try again.\r\n", ex.installingModule, ex.filename ); } GUI.user.RaiseMessage("Your GameData has been returned to its original state.\r\n"); return; } catch (InconsistentKraken ex) { // The prettiest Kraken formats itself for us. GUI.user.RaiseMessage(ex.InconsistenciesPretty); return; } catch (CancelledActionKraken) { return; } catch (MissingCertificateKraken kraken) { // Another very pretty kraken. GUI.user.RaiseMessage(kraken.ToString()); return; } catch (DownloadThrottledKraken kraken) { string msg = kraken.ToString(); GUI.user.RaiseMessage(msg); if (YesNoDialog($"{msg}\r\n\r\nOpen settings now?", "Open Settings", "No")) { // Launch the URL describing this host's throttling practices, if any if (kraken.infoUrl != null) { Process.Start(new ProcessStartInfo() { UseShellExecute = true, FileName = kraken.infoUrl.ToString() }); } // Now pretend they clicked the menu option for the settings Enabled = false; settingsDialog.ShowDialog(); Enabled = true; } return; } catch (ModuleDownloadErrorsKraken kraken) { GUI.user.RaiseMessage(kraken.ToString()); GUI.user.RaiseError(kraken.ToString()); return; } catch (DirectoryNotFoundKraken kraken) { GUI.user.RaiseMessage("\r\n{0}", kraken.Message); return; } catch (DllNotFoundException) { if (GUI.user.RaiseYesNoDialog("libcurl installation not found. Open wiki page for help?")) { Process.Start(new ProcessStartInfo() { UseShellExecute = true, FileName = "https://github.com/KSP-CKAN/CKAN/wiki/libcurl" }); } throw; } } }
public void SetDescription(string message) { Util.Invoke(MessageTextBox, () => MessageTextBox.Text = "(" + message + ")"); }
private void UpdateModContentsTree(CkanModule module) { Util.Invoke(ContentsPreviewTree, () => _UpdateModContentsTree(module)); }
public void ClearLog() { Util.Invoke(LogTextBox, () => LogTextBox.Text = ""); }