diff --git a/src/UniGetUI.PAckageEngine.Interfaces/IPackageDetails.cs b/src/UniGetUI.PAckageEngine.Interfaces/IPackageDetails.cs index b7f1481560..607d4b35c0 100644 --- a/src/UniGetUI.PAckageEngine.Interfaces/IPackageDetails.cs +++ b/src/UniGetUI.PAckageEngine.Interfaces/IPackageDetails.cs @@ -94,5 +94,14 @@ public interface IPackageDetails /// /// An asynchronous task that can be awaited public Task Load(); + + public List Dependencies { get; } + + public struct Dependency + { + public string Name; + public string Version; + public bool Mandatory; + } } } diff --git a/src/UniGetUI.PackageEngine.Enums/ManagerCapabilities.cs b/src/UniGetUI.PackageEngine.Enums/ManagerCapabilities.cs index 0eda3bfc7a..02b5d209d3 100644 --- a/src/UniGetUI.PackageEngine.Enums/ManagerCapabilities.cs +++ b/src/UniGetUI.PackageEngine.Enums/ManagerCapabilities.cs @@ -25,6 +25,7 @@ public struct ManagerCapabilities public bool CanRemoveDataOnUninstall = false; public bool CanDownloadInstaller = false; public bool CanUninstallPreviousVersionsAfterUpdate = false; + public bool CanListDependencies = false; public bool SupportsCustomVersions = false; public bool SupportsCustomArchitectures = false; public string[] SupportedCustomArchitectures = []; diff --git a/src/UniGetUI.PackageEngine.Managers.Chocolatey/Chocolatey.cs b/src/UniGetUI.PackageEngine.Managers.Chocolatey/Chocolatey.cs index 406a924dbb..e16bc0b086 100644 --- a/src/UniGetUI.PackageEngine.Managers.Chocolatey/Chocolatey.cs +++ b/src/UniGetUI.PackageEngine.Managers.Chocolatey/Chocolatey.cs @@ -32,6 +32,7 @@ public Chocolatey() CanSkipIntegrityChecks = true, CanRunInteractively = true, SupportsCustomVersions = true, + CanListDependencies = true, SupportsCustomArchitectures = true, SupportedCustomArchitectures = [Architecture.x86], SupportsPreRelease = true, diff --git a/src/UniGetUI.PackageEngine.Managers.Dotnet/DotNet.cs b/src/UniGetUI.PackageEngine.Managers.Dotnet/DotNet.cs index 2d988d182f..fd5ef25d2f 100644 --- a/src/UniGetUI.PackageEngine.Managers.Dotnet/DotNet.cs +++ b/src/UniGetUI.PackageEngine.Managers.Dotnet/DotNet.cs @@ -30,6 +30,7 @@ public DotNet() SupportsCustomArchitectures = true, SupportedCustomArchitectures = [Architecture.x86, Architecture.x64, Architecture.arm64, Architecture.arm32], SupportsPreRelease = true, + CanListDependencies = true, SupportsCustomLocations = true, SupportsCustomPackageIcons = true, SupportsCustomVersions = true, diff --git a/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGet.cs b/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGet.cs index fd6d36351b..e162d67d9f 100644 --- a/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGet.cs +++ b/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGet.cs @@ -18,20 +18,19 @@ public abstract class BaseNuGet : PackageManager public sealed override void Initialize() { - if (DetailsHelper is not BaseNuGetDetailsHelper) + static void ThrowIC(string name) { - throw new InvalidOperationException("NuGet-based package managers must not reassign the PackageDetailsProvider property"); + throw new InvalidOperationException($"NuGet-based package managers must have Capabilities.{name} set to true"); } - if (!Capabilities.SupportsCustomVersions) + if (DetailsHelper is not BaseNuGetDetailsHelper) { - throw new InvalidOperationException("NuGet-based package managers must support custom versions"); + throw new InvalidOperationException("NuGet-based package managers must not reassign the PackageDetailsProvider property"); } - if (!Capabilities.SupportsCustomPackageIcons) - { - throw new InvalidOperationException("NuGet-based package managers must support custom versions"); - } + if (!Capabilities.SupportsCustomVersions) ThrowIC(nameof(Capabilities.SupportsCustomVersions)); + if (!Capabilities.SupportsCustomPackageIcons) ThrowIC(nameof(Capabilities.SupportsCustomPackageIcons)); + if (!Capabilities.CanListDependencies) ThrowIC(nameof(Capabilities.CanListDependencies)); base.Initialize(); } diff --git a/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGetDetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGetDetailsHelper.cs index 6f7eba03ab..6a9faf4a71 100644 --- a/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGetDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Generic.NuGet/BaseNuGetDetailsHelper.cs @@ -107,6 +107,25 @@ protected override void GetDetails_UnSafe(IPackageDetails details) break; } + details.Dependencies.Clear(); + foreach (Match match in Regex.Matches(PackageManifestContents, + @"([^<]+)")) + { + foreach (var dep in match.Groups[1].ToString().Split('|')) + { + if(string.IsNullOrEmpty(dep)) + continue; + else if (dep.StartsWith("::")) + details.Dependencies.Add(new() { Name = dep.TrimStart(':'), Version = "", Mandatory = true }); + else + details.Dependencies.Add(new() + { + Name = dep.Split(':')[0], Version = dep.Split(':')[1].TrimEnd(':'), Mandatory = true + }); + } + } + + logger.Close(0); return; } diff --git a/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgDetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgDetailsHelper.cs index d916ef6d94..f21adf92e9 100644 --- a/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Npm/Helpers/NpmPkgDetailsHelper.cs @@ -61,6 +61,47 @@ protected override void GetDetails_UnSafe(IPackageDetails details) details.InstallerHash = contents?["dist"]?["integrity"]?.ToString(); + details.Dependencies.Clear(); + HashSet addedDeps = new(); + foreach (var rawDep in (contents?["dependencies"]?.AsObject() ?? [])) + { + if(addedDeps.Contains(rawDep.Key)) continue; + addedDeps.Add(rawDep.Key); + + details.Dependencies.Add(new() + { + Name = rawDep.Key, + Version = rawDep.Value?.GetValue() ?? "", + Mandatory = true, + }); + } + + foreach (var rawDep in (contents?["devDependencies"]?.AsObject() ?? [])) + { + if(addedDeps.Contains(rawDep.Key)) continue; + addedDeps.Add(rawDep.Key); + + details.Dependencies.Add(new() + { + Name = rawDep.Key, + Version = rawDep.Value?.GetValue() ?? "", + Mandatory = false, + }); + } + + foreach (var rawDep in (contents?["peerDependencies"]?.AsObject() ?? [])) + { + if(addedDeps.Contains(rawDep.Key)) continue; + addedDeps.Add(rawDep.Key); + + details.Dependencies.Add(new() + { + Name = rawDep.Key, + Version = rawDep.Value?.GetValue() ?? "", + Mandatory = false, + }); + } + logger.AddToStdErr(p.StandardError.ReadToEnd()); p.WaitForExit(); logger.Close(p.ExitCode); diff --git a/src/UniGetUI.PackageEngine.Managers.Npm/Npm.cs b/src/UniGetUI.PackageEngine.Managers.Npm/Npm.cs index 66d2c0a207..ffc10c742a 100644 --- a/src/UniGetUI.PackageEngine.Managers.Npm/Npm.cs +++ b/src/UniGetUI.PackageEngine.Managers.Npm/Npm.cs @@ -23,6 +23,7 @@ public Npm() SupportsCustomVersions = true, CanDownloadInstaller = true, SupportsCustomScopes = true, + CanListDependencies = true, SupportsPreRelease = true, SupportsProxy = ProxySupport.No, SupportsProxyAuth = false diff --git a/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgDetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgDetailsHelper.cs index f6fe219ecf..3748500f85 100644 --- a/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Pip/Helpers/PipPkgDetailsHelper.cs @@ -55,6 +55,19 @@ protected override void GetDetails_UnSafe(IPackageDetails details) } details.Tags = Tags.ToArray(); } + + details.Dependencies.Clear(); + foreach (var rawDep in (info?["requires_dist"]?.AsArray() ?? [])) + { + string line = rawDep?.GetValue().Split(';')[0] ?? ""; + string name = line.Split(['>', '<', '=', '!'])[0]; + details.Dependencies.Add(new() + { + Name = name, + Version = line[name.Length..], + Mandatory = true, + }); + } } JsonObject? url = contents?["url"] as JsonObject; diff --git a/src/UniGetUI.PackageEngine.Managers.Pip/Pip.cs b/src/UniGetUI.PackageEngine.Managers.Pip/Pip.cs index 86d9277e77..2edf6ebbe3 100644 --- a/src/UniGetUI.PackageEngine.Managers.Pip/Pip.cs +++ b/src/UniGetUI.PackageEngine.Managers.Pip/Pip.cs @@ -50,6 +50,7 @@ public Pip() SupportsCustomScopes = true, CanDownloadInstaller = true, SupportsPreRelease = true, + CanListDependencies = true, SupportsProxy = ProxySupport.Yes, SupportsProxyAuth = true }; diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell/PowerShell.cs b/src/UniGetUI.PackageEngine.Managers.PowerShell/PowerShell.cs index 02ebe707f8..226daea319 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell/PowerShell.cs +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell/PowerShell.cs @@ -25,6 +25,7 @@ public PowerShell() SupportsCustomVersions = true, CanDownloadInstaller = true, SupportsCustomScopes = true, + CanListDependencies = true, SupportsCustomSources = true, SupportsPreRelease = true, SupportsCustomPackageIcons = true, diff --git a/src/UniGetUI.PackageEngine.Managers.PowerShell7/PowerShell7.cs b/src/UniGetUI.PackageEngine.Managers.PowerShell7/PowerShell7.cs index c8c353a81a..28a88538b4 100644 --- a/src/UniGetUI.PackageEngine.Managers.PowerShell7/PowerShell7.cs +++ b/src/UniGetUI.PackageEngine.Managers.PowerShell7/PowerShell7.cs @@ -26,6 +26,7 @@ public PowerShell7() SupportsCustomSources = true, SupportsPreRelease = true, CanDownloadInstaller = true, + CanListDependencies = true, SupportsCustomPackageIcons = true, CanUninstallPreviousVersionsAfterUpdate = true, Sources = new SourceCapabilities diff --git a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgDetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgDetailsHelper.cs index 96e7ea8639..bdd068b5cb 100644 --- a/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Scoop/Helpers/ScoopPkgDetailsHelper.cs @@ -157,9 +157,64 @@ protected override void GetDetails_UnSafe(IPackageDetails details) out var releaseNotesUrl)) details.ReleaseNotesUrl = releaseNotesUrl; + details.Dependencies.Clear(); + _getDepends(details, contents); + _getSuggests(details, contents); + logger.Close(0); } + private static void _getSuggests(IPackageDetails details, JsonObject? contents) + { + foreach (var rawDep in (contents?["suggest"]?.AsObject() ?? [])) + { + List innerDeps = []; + + if(rawDep.Value is JsonValue value) innerDeps.Add(value.GetValue()); + else + { + foreach (var iDep in rawDep.Value?.AsArray() ?? []) + { + string? val = iDep?.GetValue(); + if(val is not null) innerDeps.Add(val); + } + } + + foreach(var val in innerDeps) + details.Dependencies.Add(new() + { + Name = val, + Version = "", + Mandatory = false, + }); + } + } + + private static void _getDepends(IPackageDetails details, JsonObject? contents) + { + var node = contents?["depends"]; + List innerDeps = []; + + + if(node is JsonValue value) innerDeps.Add(value.GetValue()); + else + { + foreach (var iDep in node?.AsArray() ?? []) + { + string? val = iDep?.GetValue(); + if(val is not null) innerDeps.Add(val); + } + } + + foreach(var val in innerDeps) + details.Dependencies.Add(new() + { + Name = val, + Version = "", + Mandatory = true, + }); + } + protected override CacheableIcon? GetIcon_UnSafe(IPackage package) { throw new NotImplementedException(); diff --git a/src/UniGetUI.PackageEngine.Managers.Scoop/Scoop.cs b/src/UniGetUI.PackageEngine.Managers.Scoop/Scoop.cs index 23ef755898..484790c1af 100644 --- a/src/UniGetUI.PackageEngine.Managers.Scoop/Scoop.cs +++ b/src/UniGetUI.PackageEngine.Managers.Scoop/Scoop.cs @@ -51,6 +51,7 @@ public Scoop() CanRunAsAdmin = true, CanSkipIntegrityChecks = true, CanDownloadInstaller = true, + CanListDependencies = true, CanRemoveDataOnUninstall = true, SupportsCustomArchitectures = true, SupportedCustomArchitectures = [Architecture.x86, Architecture.x64, Architecture.arm64], diff --git a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgDetailsHelper.cs b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgDetailsHelper.cs index 0adc4fe8c1..e11e9d6618 100644 --- a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgDetailsHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Helpers/VcpkgPkgDetailsHelper.cs @@ -54,6 +54,16 @@ protected override void GetDetails_UnSafe(IPackageDetails details) details.Tags = Tags.ToArray(); + details.Dependencies.Clear(); + foreach (var iDep in contents?["dependencies"]?.AsArray() ?? []) + { + string? val = iDep?.GetValue(); + if (val is not null) + { + details.Dependencies.Add(new() { Name = val, Version = "", Mandatory = true, }); + } + } + logger.Close(0); } diff --git a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Vcpkg.cs b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Vcpkg.cs index d2f75d8966..07bef3111a 100644 --- a/src/UniGetUI.PackageEngine.Managers.Vcpkg/Vcpkg.cs +++ b/src/UniGetUI.PackageEngine.Managers.Vcpkg/Vcpkg.cs @@ -42,6 +42,7 @@ public Vcpkg() { CanRunAsAdmin = true, SupportsCustomSources = true, + CanListDependencies = true, SupportsProxy = ProxySupport.No, SupportsProxyAuth = false, }; diff --git a/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/BundledWinGetHelper.cs b/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/BundledWinGetHelper.cs index fc95aca774..ff7d1605f7 100644 --- a/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/BundledWinGetHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/BundledWinGetHelper.cs @@ -461,6 +461,8 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) bool IsLoadingDescription = false; bool IsLoadingReleaseNotes = false; bool IsLoadingTags = false; + bool IsCapturingDependencies = false; + details.Dependencies.Clear(); foreach (string __line in output) { try @@ -484,6 +486,16 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) { details.Tags = details.Tags.Append(line.Trim()).ToArray(); } + else if (line.StartsWith(" ") && IsCapturingDependencies) + { + line = line.Trim(); + details.Dependencies.Add(new() + { + Name = line.Split(' ')[0], + Version = line.Contains('[') ? line.Split('[')[1].TrimEnd(']'): "", + Mandatory = true + }); + } // Stop loading multiline fields else if (IsLoadingDescription) @@ -498,6 +510,10 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) { IsLoadingTags = false; } + else if (IsCapturingDependencies) + { + IsCapturingDependencies = false; + } // Check for single-line fields if (line.Contains("Publisher:")) @@ -556,6 +572,10 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) details.Tags = []; IsLoadingTags = true; } + else if (line.Contains("- Package Dependencies")) + { + IsCapturingDependencies = true; + } } catch (Exception e) { diff --git a/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/NativeWinGetHelper.cs b/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/NativeWinGetHelper.cs index 4aa99d47b3..26a558db6f 100644 --- a/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/NativeWinGetHelper.cs +++ b/src/UniGetUI.PackageEngine.Managers.WinGet/ClientHelpers/NativeWinGetHelper.cs @@ -396,6 +396,8 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) logger.Error(process.StandardError.ReadToEnd()); + bool capturingDependencies = false; + details.Dependencies.Clear(); // Parse the output foreach (string __line in output) { @@ -419,6 +421,20 @@ public void GetPackageDetails_UnSafe(IPackageDetails details) { details.InstallerType = line.Split(":")[1].Trim(); } + else if (line.Contains("- Package Dependencies")) + { + capturingDependencies = true; + } + else if (__line.Contains(" ") && capturingDependencies) + { + details.Dependencies.Add(new() + { + Name = line.Split(' ')[0], + Version = line.Contains('[') ? line.Split('[')[1].TrimEnd(']'): "", + Mandatory = true + }); + } + else if (!__line.Contains(" ")) capturingDependencies = false; } catch (Exception e) { diff --git a/src/UniGetUI.PackageEngine.Managers.WinGet/WinGet.cs b/src/UniGetUI.PackageEngine.Managers.WinGet/WinGet.cs index 17e44f306e..442b3c4947 100644 --- a/src/UniGetUI.PackageEngine.Managers.WinGet/WinGet.cs +++ b/src/UniGetUI.PackageEngine.Managers.WinGet/WinGet.cs @@ -43,6 +43,7 @@ public WinGet() CanRunInteractively = true, SupportsCustomVersions = true, CanDownloadInstaller = true, + CanListDependencies = true, SupportsCustomArchitectures = true, SupportedCustomArchitectures = [Architecture.x86, Architecture.x64, Architecture.arm64], SupportsCustomScopes = true, diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/PackageDetails.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/PackageDetails.cs index 3095257add..fcb956d4ce 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/PackageDetails.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/PackageDetails.cs @@ -94,6 +94,8 @@ public class PackageDetails : IPackageDetails /// public string[] Tags { get; set; } = []; + public List Dependencies { get; set; } = []; + public PackageDetails(IPackage package) { Package = package; diff --git a/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml b/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml index 6ba6aa7e13..74737375fe 100644 --- a/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml +++ b/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml @@ -120,6 +120,9 @@ Helo (Helo) + Update date: + Helo + SOURCE_LABEL: Helo @@ -324,8 +327,10 @@ - Update date: - Helo + Dependencies: + + + Release Notes: Helo diff --git a/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs b/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs index 2371103a7d..0382817943 100644 --- a/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs +++ b/src/UniGetUI/Pages/DialogPages/PackageDetailsPage.xaml.cs @@ -1,4 +1,5 @@ using System.Collections.ObjectModel; +using System.Text; using Windows.UI; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; @@ -94,6 +95,9 @@ public PackageDetailsPage(IPackage package, OperationType role, TEL_InstallRefer SetTextToItem(DownloadInstaller_Button, CoreTools.Translate("Download installer")); SetTextToItem(UpdateDate_Label, CoreTools.Translate("Last updated:") + " "); SetTextToItem(UpdateDate_Content, LoadingString); + SetTextToItem(Dependencies_Label, CoreTools.Translate("Dependencies:") + " "); + DependenciesParagraph.Inlines.Clear(); + DependenciesParagraph.Inlines.Add(new Run() { Text = LoadingString, Foreground = new SolidColorBrush(color: Color.FromArgb(255, 127, 127, 127)), }); SetTextToItem(ReleaseNotes_Label, CoreTools.Translate("Release notes") + ": "); SetTextToItem(ReleaseNotes_Content, LoadingString); SetTextToItem(ReleaseNotesUrl_Label, CoreTools.Translate("Release notes URL") + ": "); @@ -372,6 +376,52 @@ public async Task LoadInformation() SetTextToItem(ReleaseNotes_Content, details.ReleaseNotes); SetTextToItem(ReleaseNotesUrl_Content, details.ReleaseNotesUrl); + if (!details.Package.Manager.Capabilities.CanListDependencies) + { + DependenciesParagraph.Inlines.Clear(); + DependenciesParagraph.Inlines.Add(new Run() + { + Text = CoreTools.Translate("Not available"), + Foreground = new SolidColorBrush(color: Color.FromArgb(255, 127, 127, 127)), + }); + } + else if (details.Dependencies.Any()) + { + DependenciesParagraph.Inlines.Clear(); + + foreach (var dep in details.Dependencies) + { + DependenciesParagraph.Inlines.Add(new Run() + { + Text = $"  • {dep.Name}", + FontStyle = dep.Mandatory? FontStyle.Normal : FontStyle.Italic, + FontWeight = new FontWeight(600) + }); + + string line = $" ("; + if (dep.Version.Any()) line += CoreTools.Translate("Version:") + $" {dep.Version}, "; + line += $"{(dep.Mandatory ? CoreTools.Translate("mandatory") : CoreTools.Translate("optional"))})"; + + DependenciesParagraph.Inlines.Add(new Run() + { + Text = line, + FontStyle = dep.Mandatory? FontStyle.Normal : FontStyle.Italic, + }); + DependenciesParagraph.Inlines.Add(new LineBreak()); + } + if(DependenciesParagraph.Inlines.Any() && DependenciesParagraph.Inlines.Last() is LineBreak) + DependenciesParagraph.Inlines.RemoveAt(DependenciesParagraph.Inlines.Count-1); + } + else + { + DependenciesParagraph.Inlines.Clear(); + DependenciesParagraph.Inlines.Add(new Run() + { + Text = CoreTools.Translate("\tNo dependencies specified"), + Foreground = new SolidColorBrush(color: Color.FromArgb(255, 127, 127, 127)), + }); + } + ShowableTags.Clear(); foreach (string tag in details.Tags) {