Пример #1
0
        /// <summary>
        /// Save the changes.
        /// Similar to adding, except we have to remove the old instance,
        /// and there's an API specifically for renaming.
        /// </summary>
        protected override void Save()
        {
            if (repoEditList != null)
            {
                // Copy the temp list of repositories to the registry
                registry.Repositories = repoEditList;
                RegistryManager.Instance(ksp).Save();
            }
            if (compatEditList != null)
            {
                ksp.SetCompatibleVersions(compatEditList);
            }

            string oldName = KSPListScreen.InstallName(manager, ksp);

            if (path.Value != ksp.GameDir())
            {
                // If the path is changed, then we have to remove the old instance
                // and replace it with a new one, whether or not the name is changed.
                manager.RemoveInstance(oldName);
                manager.AddInstance(name.Value, new KSP(path.Value, new NullUser()));
            }
            else if (name.Value != oldName)
            {
                // If only the name changed, there's an API for that.
                manager.RenameInstance(KSPListScreen.InstallName(manager, ksp), name.Value);
            }
        }
Пример #2
0
 /// <summary>
 /// Return whether the fields are valid.
 /// Similar to adding, except leaving the fields unchanged is allowed.
 /// </summary>
 protected override bool Valid()
 {
     if (name.Value != KSPListScreen.InstallName(manager, ksp) &&
         !nameValid())
     {
         return(false);
     }
     if (path.Value != ksp.GameDir() &&
         !pathValid())
     {
         return(false);
     }
     return(true);
 }
Пример #3
0
 /// <summary>
 /// Show the splash screen and wait for a key press.
 /// </summary>
 public bool Run()
 {
     // If there's a default instance, try to get the lock for it.
     if (manager.GetPreferredInstance() != null &&
         !KSPListScreen.TryGetInstance(manager.CurrentInstance, () => Draw(false)))
     {
         Console.ResetColor();
         Console.Clear();
         Console.CursorVisible = true;
         return(false);
     }
     // Draw screen with press any key
     Draw(true);
     // Wait for a key
     Console.ReadKey(true);
     return(true);
 }
Пример #4
0
        /// <summary>
        /// Initialize the Screen
        /// </summary>
        /// <param name="mgr">KSP manager containing the instances</param>
        /// <param name="k">Instance to edit</param>
        public KSPEditScreen(KSPManager mgr, KSP k)
            : base(mgr, KSPListScreen.InstallName(mgr, k), k.GameDir())
        {
            ksp = k;
            try {
                // If we can't parse the registry, just leave the repo list blank
                registry = RegistryManager.Instance(ksp).registry;
            } catch { }

            // Show the repositories if we can
            if (registry != null)
            {
                // Need to edit a copy of the list so it doesn't save on cancel
                repoEditList = new SortedDictionary <string, Repository>();
                foreach (var kvp in registry.Repositories)
                {
                    repoEditList.Add(kvp.Key, new Repository(
                                         kvp.Value.name,
                                         kvp.Value.uri.ToString(),
                                         kvp.Value.priority
                                         ));
                }

                // Also edit copy of the compatible versions
                compatEditList = new List <KspVersion>(ksp.GetCompatibleVersions());

                // I'm not a huge fan of this layout, but I think it's better than just a label
                AddObject(new ConsoleDoubleFrame(
                              1, repoFrameTop, -1, compatFrameBottom, compatFrameTop,
                              () => $"Mod List Sources",
                              () => $"Additional Compatible Versions",
                              () => ConsoleTheme.Current.LabelFg
                              ));

                repoList = new ConsoleListBox <Repository>(
                    3, repoListTop, -3, repoListBottom,
                    new List <Repository>(repoEditList.Values),
                    new List <ConsoleListBoxColumn <Repository> >()
                {
                    new ConsoleListBoxColumn <Repository>()
                    {
                        Header   = "Index",
                        Renderer = r => r.priority.ToString(),
                        Width    = 7
                    }, new ConsoleListBoxColumn <Repository>()
                    {
                        Header   = "Name",
                        Renderer = r => r.name,
                        Width    = 16
                    }, new ConsoleListBoxColumn <Repository>()
                    {
                        Header   = "URL",
                        Renderer = r => r.uri.ToString(),
                        Width    = 50
                    }
                },
                    1, 0, ListSortDirection.Ascending
                    );
                AddObject(repoList);
                repoList.AddTip("A", "Add");
                repoList.AddBinding(Keys.A, (object sender) => {
                    LaunchSubScreen(new RepoAddScreen(repoEditList));
                    repoList.SetData(new List <Repository>(repoEditList.Values));
                    return(true);
                });
                repoList.AddTip("R", "Remove");
                repoList.AddBinding(Keys.R, (object sender) => {
                    int oldPrio = repoList.Selection.priority;
                    repoEditList.Remove(repoList.Selection.name);
                    // Reshuffle the priorities to fill
                    foreach (Repository r in repoEditList.Values)
                    {
                        if (r.priority > oldPrio)
                        {
                            --r.priority;
                        }
                    }
                    repoList.SetData(new List <Repository>(repoEditList.Values));
                    return(true);
                });
                repoList.AddTip("E", "Edit");
                repoList.AddBinding(Keys.E, (object sender) => {
                    LaunchSubScreen(new RepoEditScreen(repoEditList, repoList.Selection));
                    repoList.SetData(new List <Repository>(repoEditList.Values));
                    return(true);
                });
                repoList.AddTip("-", "Up");
                repoList.AddBinding(Keys.Minus, (object sender) => {
                    if (repoList.Selection.priority > 0)
                    {
                        Repository prev = SortedDictFind(repoEditList,
                                                         r => r.priority == repoList.Selection.priority - 1);
                        if (prev != null)
                        {
                            ++prev.priority;
                        }
                        --repoList.Selection.priority;
                        repoList.SetData(new List <Repository>(repoEditList.Values));
                    }
                    return(true);
                });
                repoList.AddTip("+", "Down");
                repoList.AddBinding(Keys.Plus, (object sender) => {
                    Repository next = SortedDictFind(repoEditList,
                                                     r => r.priority == repoList.Selection.priority + 1);
                    if (next != null)
                    {
                        --next.priority;
                    }
                    ++repoList.Selection.priority;
                    repoList.SetData(new List <Repository>(repoEditList.Values));
                    return(true);
                });

                compatList = new ConsoleListBox <KspVersion>(
                    3, compatListTop, -3, compatListBottom,
                    compatEditList,
                    new List <ConsoleListBoxColumn <KspVersion> >()
                {
                    new ConsoleListBoxColumn <KspVersion>()
                    {
                        Header   = "Version",
                        Width    = 10,
                        Renderer = v => v.ToString(),
                        Comparer = (a, b) => a.CompareTo(b)
                    }
                },
                    0, 0, ListSortDirection.Descending
                    );
                AddObject(compatList);

                compatList.AddTip("A", "Add");
                compatList.AddBinding(Keys.A, (object sender) => {
                    CompatibleVersionDialog vd = new CompatibleVersionDialog();
                    KspVersion newVersion      = vd.Run();
                    DrawBackground();
                    if (newVersion != null && !compatEditList.Contains(newVersion))
                    {
                        compatEditList.Add(newVersion);
                        compatList.SetData(compatEditList);
                    }
                    return(true);
                });
                compatList.AddTip("R", "Remove", () => compatList.Selection != null);
                compatList.AddBinding(Keys.R, (object sender) => {
                    compatEditList.Remove(compatList.Selection);
                    compatList.SetData(compatEditList);
                    return(true);
                });
            }
            else
            {
                // Notify the user that the registry doesn't parse
                AddObject(new ConsoleLabel(
                              1, repoFrameTop, -1,
                              () => $"Failed to extract mod list sources from {KSPListScreen.InstallName(manager, ksp)}."
                              ));
            }
        }
Пример #5
0
        /// <summary>
        /// Initialize the screen
        /// </summary>
        /// <param name="mgr">KSP manager object containing the current instance</param>
        /// <param name="dbg">True if debug options should be available, false otherwise</param>
        public ModListScreen(KSPManager mgr, bool dbg)
        {
            debug    = dbg;
            manager  = mgr;
            registry = RegistryManager.Instance(manager.CurrentInstance).registry;

            moduleList = new ConsoleListBox <CkanModule>(
                1, 4, -1, -2,
                GetAllMods(),
                new List <ConsoleListBoxColumn <CkanModule> >()
            {
                new ConsoleListBoxColumn <CkanModule>()
                {
                    Header   = "",
                    Width    = 1,
                    Renderer = StatusSymbol
                }, new ConsoleListBoxColumn <CkanModule>()
                {
                    Header   = "Name",
                    Width    = 44,
                    Renderer = m => m.name ?? ""
                }, new ConsoleListBoxColumn <CkanModule>()
                {
                    Header   = "Version",
                    Width    = 10,
                    Renderer = m => Formatting.StripEpoch(m.version?.ToString() ?? ""),
                    Comparer = (a, b) => a.version.CompareTo(b.version)
                }, new ConsoleListBoxColumn <CkanModule>()
                {
                    Header   = "Max KSP version",
                    Width    = 17,
                    Renderer = m => registry.LatestCompatibleKSP(m.identifier)?.ToString() ?? "",
                    Comparer = (a, b) => registry.LatestCompatibleKSP(a.identifier).CompareTo(registry.LatestCompatibleKSP(b.identifier))
                }
            },
                1, 0, ListSortDirection.Descending,
                (CkanModule m, string filter) => {
                if (filter.StartsWith("@"))
                {
                    string authorFilt = filter.Substring(1);
                    if (string.IsNullOrEmpty(authorFilt))
                    {
                        return(true);
                    }
                    else if (m.author != null)
                    {
                        foreach (string auth in m.author)
                        {
                            if (auth.IndexOf(authorFilt, StringComparison.CurrentCultureIgnoreCase) == 0)
                            {
                                return(true);
                            }
                        }
                    }
                    return(false);
                }
                else if (filter.StartsWith("~"))
                {
                    if (filter.Length <= 1)
                    {
                        // Don't blank the list for just "~" by itself
                        return(true);
                    }
                    else
                    {
                        switch (filter.Substring(1, 1))
                        {
                        case "i":
                            return(registry.IsInstalled(m.identifier, false));

                        case "u":
                            return(registry.HasUpdate(m.identifier, manager.CurrentInstance.VersionCriteria()));

                        case "n":
                            // Filter new
                            return(recent.Contains(m.identifier));

                        case "c":
                            if (m.conflicts != null)
                            {
                                string conflictsWith = filter.Substring(2);
                                // Search for mods depending on a given mod
                                foreach (var rel in m.conflicts)
                                {
                                    if (rel.name.IndexOf(conflictsWith, StringComparison.CurrentCultureIgnoreCase) == 0)
                                    {
                                        return(true);
                                    }
                                }
                            }
                            return(false);

                        case "d":
                            if (m.depends != null)
                            {
                                string dependsOn = filter.Substring(2);
                                // Search for mods depending on a given mod
                                foreach (var rel in m.depends)
                                {
                                    if (rel.name.IndexOf(dependsOn, StringComparison.CurrentCultureIgnoreCase) == 0)
                                    {
                                        return(true);
                                    }
                                }
                            }
                            return(false);
                        }
                    }
                    return(false);
                }
                else
                {
                    return(m.identifier.IndexOf(filter, StringComparison.CurrentCultureIgnoreCase) >= 0 ||
                           m.name.IndexOf(filter, StringComparison.CurrentCultureIgnoreCase) >= 0 ||
                           [email protected](filter, StringComparison.CurrentCultureIgnoreCase) >= 0);
                }
            }
                );

            searchBox = new ConsoleField(-searchWidth, 2, -1)
            {
                GhostText = () => Focused() == searchBox
                    ? "<Type to search>"
                    : "<Ctrl+F to search>"
            };
            searchBox.OnChange += (ConsoleField sender, string newValue) => {
                moduleList.FilterString = newValue;
            };

            AddObject(new ConsoleLabel(
                          1, 2, -searchWidth - 2,
                          () => $"{moduleList.VisibleRowCount()} mods"
                          ));
            AddObject(searchBox);
            AddObject(moduleList);

            AddBinding(Keys.CtrlQ, (object sender) => false);
            AddBinding(Keys.AltX, (object sender) => false);
            AddBinding(Keys.F1, (object sender) => Help());
            AddBinding(Keys.AltH, (object sender) => Help());
            AddBinding(Keys.F5, (object sender) => UpdateRegistry());
            AddBinding(Keys.CtrlR, (object sender) => UpdateRegistry());
            AddBinding(Keys.CtrlU, (object sender) => UpgradeAll());

            // Now a bunch of convenience shortcuts so you don't get stuck in the search box
            searchBox.AddBinding(Keys.PageUp, (object sender) => {
                SetFocus(moduleList);
                return(true);
            });
            searchBox.AddBinding(Keys.PageDown, (object sender) => {
                SetFocus(moduleList);
                return(true);
            });
            searchBox.AddBinding(Keys.Enter, (object sender) => {
                SetFocus(moduleList);
                return(true);
            });

            moduleList.AddBinding(Keys.CtrlF, (object sender) => {
                SetFocus(searchBox);
                return(true);
            });
            moduleList.AddBinding(Keys.Escape, (object sender) => {
                searchBox.Clear();
                return(true);
            });

            moduleList.AddTip("Enter", "Details",
                              () => moduleList.Selection != null
                              );
            moduleList.AddBinding(Keys.Enter, (object sender) => {
                if (moduleList.Selection != null)
                {
                    LaunchSubScreen(new ModInfoScreen(manager, plan, moduleList.Selection, debug));
                }
                return(true);
            });

            // Conditionally show only one of these based on selected mod status

            moduleList.AddTip("+", "Install",
                              () => moduleList.Selection != null &&
                              !registry.IsInstalled(moduleList.Selection.identifier, false)
                              );
            moduleList.AddTip("+", "Upgrade",
                              () => moduleList.Selection != null &&
                              registry.HasUpdate(moduleList.Selection.identifier, manager.CurrentInstance.VersionCriteria())
                              );
            moduleList.AddBinding(Keys.Plus, (object sender) => {
                if (moduleList.Selection != null)
                {
                    if (!registry.IsInstalled(moduleList.Selection.identifier, false))
                    {
                        plan.ToggleInstall(moduleList.Selection.identifier);
                    }
                    else if (registry.IsInstalled(moduleList.Selection.identifier, false) &&
                             registry.HasUpdate(moduleList.Selection.identifier, manager.CurrentInstance.VersionCriteria()))
                    {
                        plan.ToggleUpgrade(moduleList.Selection.identifier);
                    }
                }
                return(true);
            });

            moduleList.AddTip("-", "Remove",
                              () => moduleList.Selection != null &&
                              (registry.IsInstalled(moduleList.Selection.identifier, false))
                              );
            moduleList.AddBinding(Keys.Minus, (object sender) => {
                if (moduleList.Selection != null && registry.IsInstalled(moduleList.Selection.identifier, false))
                {
                    plan.ToggleRemove(moduleList.Selection.identifier);
                }
                return(true);
            });

            AddTip("F9", "Apply changes", plan.NonEmpty);
            AddBinding(Keys.F9, (object sender) => {
                ApplyChanges();
                return(true);
            });

            // Show total download size of all installed mods
            AddObject(new ConsoleLabel(
                          1, -1, searchWidth,
                          () => $"{Formatting.FmtSize(totalInstalledDownloadSize())} installed",
                          null,
                          () => ConsoleTheme.Current.DimLabelFg
                          ));

            AddObject(new ConsoleLabel(
                          -searchWidth, -1, -2,
                          () => {
                int days = daysSinceUpdated(registryFilePath());
                return(days < 1 ? ""
                        :  days == 1 ? $"Updated at least {days} day ago"
                        :              $"Updated at least {days} days ago");
            },
                          null,
                          () => {
                int daysSince = daysSinceUpdated(registryFilePath());
                if (daysSince < daysTillStale)
                {
                    return(ConsoleTheme.Current.RegistryUpToDate);
                }
                else if (daysSince < daystillVeryStale)
                {
                    return(ConsoleTheme.Current.RegistryStale);
                }
                else
                {
                    return(ConsoleTheme.Current.RegistryVeryStale);
                }
            }
                          ));

            List <ConsoleMenuOption> opts = new List <ConsoleMenuOption>()
            {
                new ConsoleMenuOption("Sort...", "",
                                      "Change the sorting of the list of mods",
                                      true, null, null, moduleList.SortMenu()),
                null,
                new ConsoleMenuOption("Refresh mod list", "F5, Ctrl+R",
                                      "Refresh the list of mods",
                                      true, UpdateRegistry),
                new ConsoleMenuOption("Upgrade all", "Ctrl+U",
                                      "Mark all available updates for installation",
                                      true, UpgradeAll),
                new ConsoleMenuOption("Audit recommendations", "",
                                      "List mods suggested and recommended by installed mods",
                                      true, ViewSuggestions),
                new ConsoleMenuOption("Scan KSP dir", "",
                                      "Check for manually installed mods",
                                      true, ScanForMods),
                new ConsoleMenuOption("Import downloads...", "",
                                      "Select manually downloaded mods to import into CKAN",
                                      true, ImportDownloads),
                new ConsoleMenuOption("Export installed...", "",
                                      "Save your mod list",
                                      true, ExportInstalled),
                null,
                new ConsoleMenuOption("Select KSP install...", "",
                                      "Switch to a different game instance",
                                      true, SelectInstall),
                null,
                new ConsoleMenuOption("Help", helpKey,
                                      "Tips & tricks",
                                      true, Help),
                null,
                new ConsoleMenuOption("Quit", "Ctrl+Q",
                                      "Exit to DOS",
                                      true, () => false)
            };

            if (debug)
            {
                opts.Add(null);
                opts.Add(new ConsoleMenuOption("DEBUG: Capture key...", "",
                                               "Print details of how your system reports a keystroke for debugging",
                                               true, CaptureKey));
            }
            mainMenu = new ConsolePopupMenu(opts);

            LeftHeader   = () => $"CKAN {Meta.GetVersion()}";
            CenterHeader = () => $"KSP {manager.CurrentInstance.Version().ToString()} ({KSPListScreen.InstallName(manager, manager.CurrentInstance)})";
        }