/// <summary> /// Event handler for the KSPMAStarted event. /// Starts the app and mod update checks. /// </summary> protected static void KSPMAStarted(object sender) { EventDistributor.InvokeAsyncTaskStarted(Instance); ModSelectionController.View.ShowBusy = true; AsyncTask <bool> .DoWork(() => { // Auto KSP MA update check. OptionsController.Check4AppUpdates(); // Auto mod update check. OptionsController.Check4ModUpdates(true); return(true); }, (result, ex) => { EventDistributor.InvokeAsyncTaskDone(Instance); ModSelectionController.View.ShowBusy = false; if (ex != null) { Messenger.AddError(string.Format("Error during startup update checks! {0}", ex.Message), ex); } } ); }
/// <summary> /// Refreshes the Flags tab. /// Searches the KSP install dir for flags and adds them to the ListView. /// </summary> public static void RefreshFlagTab() { if (ignoreIndexChange) { return; } Messenger.AddInfo(Messages.MSG_FLAG_SCAN_STARTED); ignoreIndexChange = true; string lastFilter = View.SelectedFilter; View.ClearAll(); flags.Clear(); // add default Filter View.AddFilter(FILTER_ALL); View.AddFilter(FILTER_MYFLAG); View.ShowProcessingIcon = true; EventDistributor.InvokeAsyncTaskStarted(Instance); AsyncTask <bool> .DoWork(() => { SearchDir4FlagsDirs(KSPPathHelper.GetPath(KSPPaths.GameData)); return(true); }, (bool result, Exception ex) => { View.ShowProcessingIcon = false; EventDistributor.InvokeAsyncTaskDone(Instance); if (ex != null) { Messenger.AddError(Messages.MSG_ERROR_DURING_FLAG_SCAN, ex); } else { Messenger.AddInfo(Core.Messages.MSG_DONE); } if (lastFilter != null && (lastFilter == FILTER_ALL || lastFilter == FILTER_MYFLAG || View.GetGroup(lastFilter) != null)) { View.SelectedFilter = lastFilter; } else { View.SelectedFilter = FILTER_ALL; } ignoreIndexChange = false; View.FillListView(flags); }); }
private void Export() { List <ModNode> modsToExport = GetModsToExport(); if (modsToExport.Count <= 0) { MessageBox.Show(this, Messages.MSG_NO_MODS_TO_EXPORT, Messages.MSG_TITLE_ATTENTION); Messenger.AddInfo(Messages.MSG_NO_MODS_TO_EXPORT); } else { SaveFileDialog dlg = new SaveFileDialog(); dlg.InitialDirectory = OptionsController.DownloadPath; dlg.FileName = RemoveInvalidCharsFromPath(string.Format(MODPACK_FILENAME_TEMPLATE, DateTime.Now.ToShortDateString())); if (dlg.ShowDialog() == DialogResult.OK) { pbExport.Visible = true; AddMessage(string.Format(Messages.MSG_EXPORT_TO_0, dlg.FileName)); AsyncTask <bool> .DoWork(() => { ModPackHandler.MessageCallbackFunction = AddMessage; ModPackHandler.Export(modsToExport, dlg.FileName, cbIncludeMods.Checked); ModPackHandler.MessageCallbackFunction = null; return(true); }, (b, ex) => { pbExport.Visible = false; if (ex != null) { AddMessage(string.Format(Messages.MSG_ERROR_EXPORT_FAILED_0, ex.Message), true, ex); MessageBox.Show(this, string.Format(Messages.MSG_ERROR_EXPORT_FAILED_0, ex.Message), Messages.MSG_TITLE_ERROR); } else { AddMessage(Messages.MSG_EXPORT_DONE); Close(); } }); } else { AddMessage(Messages.MSG_EXPORT_ABORTED); } } }
/// <summary> /// Starts the backup of a directory. /// </summary> /// <param name="dir">The directory to backup.</param> /// <param name="name">Name of the backup file.</param> /// <param name="backupPath">The path to write the backup file to.</param> /// <param name="zipPath">Base path within the zip archive.</param> private static void BackupDirectoryAsync(string dir, string name = "", string backupPath = "", string zipPath = "") { try { string nameAuto; string backupPathAuto; string zipPathAuto; nameAuto = CreateBackupFilename(dir, out backupPathAuto, out zipPathAuto); if (string.IsNullOrEmpty(name)) { name = nameAuto; } if (string.IsNullOrEmpty(backupPath)) { backupPath = backupPathAuto; } if (string.IsNullOrEmpty(zipPath)) { zipPath = zipPathAuto; } if (!Directory.Exists(BackupPath)) { Directory.CreateDirectory(BackupPath); } if (Directory.Exists(dir)) { EventDistributor.InvokeAsyncTaskStarted(Instance); View.ShowProcessing = true; Messenger.AddInfo(Messages.MSG_BACKUP_STARTED); AsyncTask <string> .DoWork(() => BackupDir(dir, name, backupPath), BackupDirFinished); } else { Messenger.AddInfo(string.Format(Messages.MSG_BACKUP_SRC_FOLDER_NOT_FOUND, dir)); } } catch (Exception ex) { Messenger.AddError(string.Format(Messages.MSG_BACKUP_ERROR, ex.Message), ex); } }
/// <summary> /// Downloads the CKAN Repositories from CkanRepoManager.MasterRepoListURL. /// And updates the View. /// </summary> /// <param name="finishedCallback">Optional callback function. Will be called after finishing the async get.</param> public static void RefreshCkanRepositories(Action finishedCallback = null) { var parent = ModBrowserViewController.View; if (parent != null) { parent.ShowProcessing = true; } Messenger.AddInfo(Messages.MSG_REFRESHING_REPOSITORIES); EventDistributor.InvokeAsyncTaskStarted(Instance); AsyncTask <CkanRepositories> .DoWork(() => { return(CkanRepoManager.GetRepositoryList()); // CkanRepoManager.MasterRepoListURL); }, (result, ex) => { EventDistributor.InvokeAsyncTaskDone(Instance); if (parent != null) { parent.ShowProcessing = false; } if (ex != null) { Messenger.AddError(string.Format(Messages.MSG_ERROR_DURING_REFRESH_REPOSITORIES_0, ex.Message), ex); } else { // CkanRepository last = View.SelectedRepository; View.Repositories = result; View.SelectedRepository = result.repositories.FirstOrDefault(); // last; } Messenger.AddInfo(Messages.MSG_REFRESHING_REPOSITORIES_DONE); if (finishedCallback != null) { finishedCallback(); } }); }
/// <summary> /// Checks if all parts of the craft are installed. /// </summary> /// <param name="partList">The list of installed parts.</param> private static void Parts_ScanComplete(List <PartNode> partList) { View.ShowProcessingIcon = true; EventDistributor.InvokeAsyncTaskStarted(Instance); AsyncTask <bool> .DoWork(() => { Messenger.AddInfo(Messages.MSG_CRAFT_VALIDATION_STARTED); View.InvokeIfRequired(() => model.Nodes.Clear()); foreach (CraftNode craft in allCrafts) { Messenger.AddInfo(string.Format(Messages.MSG_VALIDATING_CRAFT_0, craft.Name)); Dictionary <string, CraftNode> alreadyCheckedParts = new Dictionary <string, CraftNode>(); foreach (CraftNode part in craft.Nodes) { string partName = part.Name.Substring(0, part.Name.IndexOf(" (")); string count = part.Name.Substring(partName.Length); if (alreadyCheckedParts.ContainsKey(part.Name)) { if (alreadyCheckedParts[part.Name] != null) { part.RelatedPart = alreadyCheckedParts[part.Name].RelatedPart; part.Name = part.RelatedPart.Title + count; craft.AddMod(part.RelatedPart.Mod); } continue; } else { bool found = false; foreach (PartNode instPart in partList) { if (instPart.Name.Replace("_", ".") == partName) { if (!alreadyCheckedParts.ContainsKey(instPart.Name)) { alreadyCheckedParts.Add(instPart.Name, part); } part.Name = instPart.Title + count; part.RelatedPart = instPart; part.AddMod(instPart.Mod); View.InvokeIfRequired(() => part.RelatedPart.AddRelatedCraft(craft)); craft.AddMod(instPart.Mod); found = true; break; } } if (!found) { alreadyCheckedParts.Add(part.Name, null); } } } if (craft.IsInvalidOrHasInvalidChilds) { Messenger.AddInfo(string.Format(Messages.MSG_VALIDATING_CRAFT_0_FAILED, craft.Name)); } else { Messenger.AddInfo(string.Format(Messages.MSG_VALIDATING_CRAFT_0_SUCCESSFUL, craft.Name)); } ////craft.SortPartsByDisplayText(); } return(true); }, (result, ex) => { View.ShowProcessingIcon = false; EventDistributor.InvokeAsyncTaskDone(Instance); PartsTabViewController.ScanComplete -= Parts_ScanComplete; if (ex != null) { MessageBox.Show(View.ParentForm, string.Format(Messages.MSG_ERROR_DURING_CRAFT_VALIDATION_0, ex.Message)); } else { RefreshTreeView(); } Messenger.AddInfo(Messages.MSG_CRAFT_VALIDATION_DONE); }); }
/// <summary> /// Scans the KSP install directory and sub directories for *.craft files. /// </summary> private static void ScanDir() { View.ShowProcessingIcon = true; EventDistributor.InvokeAsyncTaskStarted(Instance); ResetView(); AsyncTask <bool> .DoWork(() => { Messenger.AddInfo(Messages.MSG_CRAFT_SCAN_STARTED); // Get *.craft files from GameData folder. string gameDatePath = KSPPathHelper.GetPath(KSPPaths.GameData); string[] files = Directory.GetFiles(gameDatePath, EXTENSION_CRAFT, SearchOption.AllDirectories); // Get *.craft files from additional folders. string path1 = KSPPathHelper.GetPath(KSPPaths.VAB); string path2 = KSPPathHelper.GetPath(KSPPaths.SPH); string[] addPaths = new[] { path1, path2 }; foreach (var path in addPaths) { string[] files2 = Directory.GetFiles(path, EXTENSION_CRAFT, SearchOption.AllDirectories); int oldLength = files.Length; Array.Resize <string>(ref files, oldLength + files2.Length); Array.Copy(files2, 0, files, oldLength, files2.Length); } // Create CraftNodes from each file. var nodes = new List <CraftNode>(); if (files.Length > 0) { foreach (string file in files) { Messenger.AddInfo(string.Format(Messages.MSG_SCAN_FILE_0_FOR_CRAFTS, file)); var newNodes = CreateCraftEntry(file); foreach (var newNode in newNodes) { if (newNode != null && !string.IsNullOrEmpty(newNode.Name) && !nodes.Contains(newNode)) { nodes.Add(newNode); } } } } else { Messenger.AddInfo(string.Format(Messages.MSG_NO_CRAFTCFG_FOUND_0, gameDatePath)); } allCrafts.Clear(); foreach (CraftNode node in nodes) { allCrafts.Add(node); } Messenger.AddInfo(Messages.MSG_CRAFT_SCAN_DONE); return(true); }, (bool result, Exception ex) => { View.ShowProcessingIcon = false; EventDistributor.InvokeAsyncTaskDone(Instance); if (ex != null) { Messenger.AddError(string.Format(Messages.MSG_ERROR_DURING_CRAFT_READING_0, ex.Message), ex); } else { RefreshTreeView(); ValidateCrafts(); } }); }
/// <summary> /// Scans the KSP install directory and sub directories for *.craft files. /// </summary> private static void ScanDir() { allModFilter.Clear(); allModFilter.Add(All); allModFilter.Add(Squad); View.SelectedModFilter = All; model.Nodes.Clear(); View.ShowProcessingIcon = true; EventDistributor.InvokeAsyncTaskStarted(Instance); AsyncTask <bool> .DoWork(() => { Messenger.AddInfo(Messages.MSG_PART_SCAN_STARTED); // Get part.cfg files from GameData folder. string gameDatePath = KSPPathHelper.GetPath(KSPPaths.GameData); string[] files = Directory.GetFiles(gameDatePath, EXTENSION_CFG, SearchOption.AllDirectories); // Get part.cfg files from additional folders. string partsPath = KSPPathHelper.GetPath(KSPPaths.Parts); string[] addPaths = new[] { partsPath }; foreach (var path in addPaths) { string[] files2 = Directory.GetFiles(path, EXTENSION_CFG, SearchOption.AllDirectories); int oldLength = files.Length; Array.Resize <string>(ref files, oldLength + files2.Length); Array.Copy(files2, 0, files, oldLength, files2.Length); } // Create PartNodes from each file. var nodes = new List <PartNode>(); if (files.Length > 0) { foreach (string file in files) { Messenger.AddInfo(string.Format(Messages.MSG_SCAN_FILE_0_FOR_PARTS, file)); var newNodes = CreatePartNodes(file); foreach (var newNode in newNodes) { if (newNode != null && !string.IsNullOrEmpty(newNode.Name) && !nodes.Contains(newNode)) { nodes.Add(newNode); } } } } else { Messenger.AddInfo(string.Format(Messages.MSG_NO_PARTCFG_FOUND_0, gameDatePath)); } allNodes.Clear(); foreach (PartNode node in nodes) { allNodes.Add(node); } Messenger.AddInfo(Messages.MSG_PART_SCAN_DONE); return(true); }, (result, ex) => { View.ShowProcessingIcon = false; EventDistributor.InvokeAsyncTaskDone(Instance); if (ex != null) { Messenger.AddError(string.Format(Messages.MSG_ERROR_DURING_PART_READING_0, ex.Message), ex); } else { RefreshTreeView(); } if (ScanComplete != null) { ScanComplete(Parts); } }); }
public static void Refresh(RefreshType refreshType = RefreshType.Last) { model.Nodes.Clear(); if (refreshType == RefreshType.Last) { refreshType = LastRefresh; } View.ShowProcessing = true; EventDistributor.InvokeAsyncTaskStarted(Instance); AsyncTask <List <KsMod> > .DoWork( () => { List <KsMod> mods = null; switch (refreshType) { default: case RefreshType.New: mods = KerbalStuff.BrowseNew(View.Page); break; case RefreshType.Top: mods = KerbalStuff.BrowseTop(View.Page); break; case RefreshType.Featured: mods = KerbalStuff.BrowseFeatured(View.Page); break; case RefreshType.Browse: mods = KerbalStuff.Browse(View.Page); break; } return(mods); }, (result, ex) => { View.ShowProcessing = false; EventDistributor.InvokeAsyncTaskDone(Instance); if (ex != null) { Messenger.AddError(string.Format("Error during browsing KerbalStuff! {0}", ex), ex); } else { if (KerbalStuff.LastResponse == null || result == null) { Messenger.AddError("Error during browsing KerbalStuff! Empty result"); return; } View.MaxPages = KerbalStuff.LastResponse.pages; View.CountLabelText = string.Format("Mods per page: {0}", KerbalStuff.LastResponse.count); foreach (var mod in result) { model.Nodes.Add(new KerbalStuffNode(mod)); } } }); }
/// <summary> /// Downloads the Ckan Repository archive if necessary, creates a CkanArchive from it and populates the view. /// </summary> /// <param name="repo">The Ckan Repository to get the Archive for.</param> /// <param name="forceDownload">If false the download will be skipped if a Ckan Repository archive file already exists.</param> /// <param name="finishedCallback">Optional callback function. Will be called after finishing the async get.</param> public static void RefreshCkanArchive(CkanRepository repo, bool forceDownload = false, Action finishedCallback = null) { model.Nodes.Clear(); if (repo == null) { return; } if (!OptionsController.HasValidDownloadPath) { Messenger.AddInfo(Messages.MSG_DOWNLOADPATH_MISSING); OptionsController.SelectNewDownloadPath(); if (!OptionsController.HasValidDownloadPath) { return; } } var parent = View.Parent as ucModBrowserView; if (parent != null) { parent.ShowProcessing = true; } EventDistributor.InvokeAsyncTaskStarted(Instance); Messenger.AddInfo(string.Format(Messages.MSG_REFRESHING_REPOSITORY_ARCHIVE_0, repo.name)); AsyncTask <CkanArchive> .DoWork(() => { CkanArchive archive = null; if (!forceDownload && archives.ContainsKey(repo.name)) { Messenger.AddInfo(Messages.MSG_USING_CACHED_ARCHIVE); archive = archives[repo.name]; } else { var path = Path.Combine(OptionsController.DownloadPath, CkanArchiveFolder); if (!Directory.Exists(path)) { Messenger.AddInfo(Messages.MSG_CREATE_CKAN_ARCHIVE); Directory.CreateDirectory(path); } var filename = string.Format("{0}_{1}", repo.name, Path.GetFileName(repo.uri.AbsolutePath)); var fullpath = Path.Combine(path, filename); if (!forceDownload && File.Exists(fullpath)) { archive = CkanRepoManager.CreateRepositoryArchive(fullpath); } else { // TODO: Separate download and create archive in different AsyncTasks. if (CkanRepoManager.DownloadRepositoryArchive(repo, fullpath, null, OnDownloadProgressChanged)) { archive = CkanRepoManager.CreateRepositoryArchive(fullpath); } } } return(archive); }, (newArchive, ex) => { if (parent != null) { parent.ShowProcessing = false; } ModBrowserViewController.View.ShowProgressBar(false, 0); EventDistributor.InvokeAsyncTaskDone(Instance); if (ex != null) { Messenger.AddError(string.Format(Messages.MSG_ERROR_DURING_REFRESH_REPOSITORY_ARCHIVE_0, ex.Message), ex); } else { if (newArchive != null) { newArchive.Repository = repo; if (archives.ContainsKey(repo.name)) { archives[repo.name] = newArchive; } else { archives.Add(repo.name, newArchive); } model.AddArchive(newArchive); View.CountLabelText = string.Format(Messages.MSG_MODBROWSER_CKAN_COUNT_TEXT, newArchive.Mods.Count, model.Nodes.Count); FindInstalledMods(); } else { View.CountLabelText = string.Format(Messages.MSG_MODBROWSER_CKAN_COUNT_TEXT, 0, 0); } } Messenger.AddInfo(Messages.MSG_REFRESH_REPOSITORY_DONE); if (finishedCallback != null) { finishedCallback(); } }); }