diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f6844dedb2..a247679f18 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -144,7 +144,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.release_data.outputs.upload_url }} - asset_path: _build/out/AutoUpdater/Release/bin/AutoUpdater.exe + asset_path: _build/repack/Release/AutoUpdater.exe asset_name: AutoUpdater.exe asset_content_type: application/vnd.microsoft.portable-executable diff --git a/AutoUpdate/CKAN-autoupdate.csproj b/AutoUpdate/CKAN-autoupdate.csproj index 7ca711475a..55cf555e7c 100644 --- a/AutoUpdate/CKAN-autoupdate.csproj +++ b/AutoUpdate/CKAN-autoupdate.csproj @@ -1,45 +1,36 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project> <PropertyGroup> - <AssemblyName>AutoUpdater</AssemblyName> + <AssemblyName>CKAN-AutoUpdateHelper</AssemblyName> <OutputPath>..\_build\out\$(AssemblyName)\$(Configuration)\bin\</OutputPath> <BaseIntermediateOutputPath>..\_build\out\$(AssemblyName)\$(Configuration)\obj\</BaseIntermediateOutputPath> </PropertyGroup> - <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" /> <PropertyGroup> - <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <ProjectGuid>{E5B1C768-349E-4DAF-A134-56E4ECF1EEEF}</ProjectGuid> <OutputType>Exe</OutputType> - <RootNamespace>AutoUpdater</RootNamespace> + <RootNamespace>CKAN.AutoUpdateHelper</RootNamespace> + <GenerateAssemblyInfo>false</GenerateAssemblyInfo> + <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> + <Deterministic>true</Deterministic> + <Configurations>Debug;Release</Configurations> + <Prefer32Bit>false</Prefer32Bit> + <LangVersion>7</LangVersion> <ApplicationIcon>..\assets\ckan.ico</ApplicationIcon> + <TargetFramework>net45</TargetFramework> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <FileAlignment>512</FileAlignment> - <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> - <Deterministic>true</Deterministic> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> - <Prefer32Bit>false</Prefer32Bit> - <LangVersion>7</LangVersion> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> - <DebugSymbols>true</DebugSymbols> - <DebugType>full</DebugType> - <Optimize>false</Optimize> - <DefineConstants>DEBUG;TRACE</DefineConstants> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> - <DebugType>pdbonly</DebugType> - <Optimize>true</Optimize> - <DefineConstants>TRACE</DefineConstants> </PropertyGroup> <ItemGroup> <Reference Include="System" /> <Reference Include="System.Core" /> <Reference Include="System.Windows.Forms" /> </ItemGroup> + <ItemGroup> + <PackageReference Include="ILRepack" Version="2.0.18" /> + <PackageReference Include="ILRepack.MSBuild.Task" Version="2.0.13" /> + </ItemGroup> <ItemGroup> <Compile Include="..\_build\meta\GlobalAssemblyVersionInfo.cs"> <Link>Properties\GlobalAssemblyVersionInfo.cs</Link> @@ -47,15 +38,31 @@ <Compile Include="..\GlobalAssemblyInfo.cs"> <Link>Properties\GlobalAssemblyInfo.cs</Link> </Compile> - <Compile Include="Main.cs" /> - <Compile Include="Properties\AssemblyInfo.cs" /> </ItemGroup> <ItemGroup> <None Include="App.config" /> </ItemGroup> - <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" /> <Target Name="BeforeBuild"> <Exec Command="powershell ../build.ps1 Generate-GlobalAssemblyVersionInfo" Condition="!Exists('../_build/meta/GlobalAssemblyVersionInfo.cs') And '$(OS)' == 'Windows_NT'" /> <Exec Command="sh ../build Generate-GlobalAssemblyVersionInfo" Condition="!Exists('../_build/meta/GlobalAssemblyVersionInfo.cs') And '$(OS)' == 'Unix'" /> </Target> -</Project> \ No newline at end of file + <Target Name="ILRepack" AfterTargets="Build"> + <ItemGroup> + <InputAssemblies Include="fr-FR\$(AssemblyName).resources.dll" /> + <InputAssemblies Include="ru-RU\$(AssemblyName).resources.dll" /> + </ItemGroup> + <ILRepack OutputAssembly="AutoUpdater.exe" + MainAssembly="$(AssemblyName).exe" + InputAssemblies="@(InputAssemblies)" + OutputType="$(OutputType)" + WorkingDirectory="$(OutputPath)" + Internalize="true" + Parallel="true" /> + <ItemGroup> + <Repacked Include="$(OutputPath)AutoUpdater.*" /> + </ItemGroup> + <Copy SourceFiles="@(Repacked)" + DestinationFolder="..\_build\repack\$(Configuration)" /> + </Target> +</Project> diff --git a/AutoUpdate/Main.cs b/AutoUpdate/Main.cs index 2349d0a5c7..bf9c59e2e2 100644 --- a/AutoUpdate/Main.cs +++ b/AutoUpdate/Main.cs @@ -16,7 +16,7 @@ * AutoUpdate.exe <running CKAN PID> <running CKAN path> <updated CKAN path> <launch> */ -namespace AutoUpdater +namespace CKAN.AutoUpdateHelper { public class Program { @@ -26,7 +26,7 @@ public static int Main(string[] args) if (args.Length != 4) { - ReportError("Usage: AutoUpdater.exe pid oldPath newPath [no]launch"); + ReportError("{0}: AutoUpdater.exe pid oldPath newPath [no]launch", Properties.Resources.Usage); return ExitBADOPT; } @@ -39,7 +39,7 @@ public static int Main(string[] args) if (!File.Exists(updated_path)) { - ReportError($"Downloaded ckan.exe not found at: {updated_path}"); + ReportError(Properties.Resources.DownloadNotFound, updated_path); return ExitBADOPT; } @@ -71,7 +71,7 @@ public static int Main(string[] args) } catch (Exception exc) { - ReportError($"Failed to wait for CKAN to close: {exc.Message}"); + ReportError(Properties.Resources.FailedToWait, exc.Message); return ExitERROR; } @@ -86,7 +86,7 @@ public static int Main(string[] args) { if (retry == maxRetries - 1) { - ReportError($"Failed to delete {local_path}: {exc.Message}"); + ReportError(Properties.Resources.FailedToDelete, local_path, exc.Message); if (fromGui) { // Launch the old EXE that we can't delete @@ -172,20 +172,21 @@ private static bool IsOnWindows() /// <param name="e">Info about the exception</param> private static void UnhandledExceptionEventHandler(Object sender, UnhandledExceptionEventArgs e) { - ReportError($"Unhandled exception:\r\n{e.ExceptionObject}"); + ReportError(Properties.Resources.UnhandledException, e.ExceptionObject); } /// <summary> /// It's nice to tell the user when something goes wrong! /// </summary> /// <param name="err">Description of the problem that happened</param> - private static void ReportError(string err) + private static void ReportError(string message, params object[] args) { + string err = string.Format(message, args); Console.Error.WriteLine(err); if (fromGui) { // Show a popup in case the console isn't open - MessageBox.Show(err, "Fatal AutoUpdater Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageBox.Show(err, Properties.Resources.FatalErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); } } diff --git a/AutoUpdate/Properties/AssemblyInfo.cs b/AutoUpdate/Properties/AssemblyInfo.cs index 750441911a..95d9d1fb74 100644 --- a/AutoUpdate/Properties/AssemblyInfo.cs +++ b/AutoUpdate/Properties/AssemblyInfo.cs @@ -1,4 +1,10 @@ -using System.Reflection; +using System.Resources; +using System.Reflection; +using System.Runtime.CompilerServices; -[assembly: AssemblyTitle("AutoUpdater")] +[assembly: AssemblyTitle("CKAN-AutoUpdater")] [assembly: AssemblyDescription("CKAN Auto-update Executable")] +[assembly: NeutralResourcesLanguage("en-GB")] + +[assembly: InternalsVisibleTo("Tests")] +[assembly: InternalsVisibleTo("CKAN.Tests")] diff --git a/AutoUpdate/Properties/Resources.Designer.cs b/AutoUpdate/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..10ca3ba154 --- /dev/null +++ b/AutoUpdate/Properties/Resources.Designer.cs @@ -0,0 +1,82 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. (I WISH!) +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace CKAN.AutoUpdateHelper.Properties { + using System; + + + /// <summary> + /// A strongly-typed resource class, for looking up localized strings, etc. + /// </summary> + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { } + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) + { + resourceMan = new SingleAssemblyResourceManager("CKAN.AutoUpdateHelper.Properties.Resources", typeof(Resources).Assembly); + } + return resourceMan; + } + } + + /// <summary> + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + internal static string Usage { + get { return (string)(ResourceManager.GetObject("Usage", resourceCulture)); } + } + internal static string DownloadNotFound { + get { return (string)(ResourceManager.GetObject("DownloadNotFound", resourceCulture)); } + } + internal static string FailedToWait { + get { return (string)(ResourceManager.GetObject("FailedToWait", resourceCulture)); } + } + internal static string FailedToDelete { + get { return (string)(ResourceManager.GetObject("FailedToDelete", resourceCulture)); } + } + internal static string UnhandledException { + get { return (string)(ResourceManager.GetObject("UnhandledException", resourceCulture)); } + } + internal static string FatalErrorTitle { + get { return (string)(ResourceManager.GetObject("FatalErrorTitle", resourceCulture)); } + } + + } +} diff --git a/AutoUpdate/Properties/Resources.fr-FR.resx b/AutoUpdate/Properties/Resources.fr-FR.resx new file mode 100644 index 0000000000..c446321325 --- /dev/null +++ b/AutoUpdate/Properties/Resources.fr-FR.resx @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="Usage" xml:space="preserve"><value>Utilisation</value></data> + <data name="DownloadNotFound" xml:space="preserve"><value>Le fichier téléchargé ckan.exe n'a pas été trouvé à : {0}</value></data> + <data name="FailedToWait" xml:space="preserve"><value>Impossible d'attendre que CKAN se ferme : {0}</value></data> + <data name="FailedToDelete" xml:space="preserve"><value>Échec de la suppression de {0} : {1}</value></data> + <data name="UnhandledException" xml:space="preserve"><value>Exception non-gérée : +{0}</value></data> + <data name="FatalErrorTitle" xml:space="preserve"><value>Erreur fatale de la mise à jour automatique</value></data> +</root> diff --git a/AutoUpdate/Properties/Resources.resx b/AutoUpdate/Properties/Resources.resx new file mode 100644 index 0000000000..26edfc58f9 --- /dev/null +++ b/AutoUpdate/Properties/Resources.resx @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="Usage" xml:space="preserve"><value>Usage</value></data> + <data name="DownloadNotFound" xml:space="preserve"><value>Downloaded ckan.exe not found at: {0}</value></data> + <data name="FailedToWait" xml:space="preserve"><value>Failed to wait for CKAN to close: {0}</value></data> + <data name="FailedToDelete" xml:space="preserve"><value>Failed to delete {0}: {1}</value></data> + <data name="UnhandledException" xml:space="preserve"><value>Unhandled exception: +{0}</value></data> + <data name="FatalErrorTitle" xml:space="preserve"><value>Fatal AutoUpdater Error</value></data> +</root> diff --git a/AutoUpdate/Properties/Resources.ru-RU.resx b/AutoUpdate/Properties/Resources.ru-RU.resx new file mode 100644 index 0000000000..e756420925 --- /dev/null +++ b/AutoUpdate/Properties/Resources.ru-RU.resx @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="Usage" xml:space="preserve"><value>Использование</value></data> + <data name="DownloadNotFound" xml:space="preserve"><value>Загруженный ckan.exe не найден по пути: {0}</value></data> + <data name="FailedToWait" xml:space="preserve"><value>Не удалось дождаться закрытия CKAN: {0}</value></data> + <data name="FailedToDelete" xml:space="preserve"><value>Не удалось удалить {0}: {1}</value></data> + <data name="UnhandledException" xml:space="preserve"><value>Необработанное исключение: +{0}</value></data> + <data name="FatalErrorTitle" xml:space="preserve"><value>Критическая ошибка AutoUpdater</value></data> +</root> diff --git a/AutoUpdate/SingleAssemblyResourceManager.cs b/AutoUpdate/SingleAssemblyResourceManager.cs new file mode 100644 index 0000000000..b7d6321317 --- /dev/null +++ b/AutoUpdate/SingleAssemblyResourceManager.cs @@ -0,0 +1,58 @@ +using System.IO; +using System.Globalization; +using System.Resources; +using System.Collections; +using System.Reflection; +using System.Collections.Generic; + +namespace CKAN.AutoUpdateHelper +{ + // Thanks and credit to this guy: https://stackoverflow.com/q/1952638/2422988 + + class SingleAssemblyResourceManager : ResourceManager + { + public SingleAssemblyResourceManager(string basename, Assembly assembly) : base(basename, assembly) + { + } + + protected override ResourceSet InternalGetResourceSet(CultureInfo culture, + bool createIfNotExists, bool tryParents) + { + ResourceSet rs; + if (!myResourceSets.TryGetValue(culture, out rs)) + { + // Lazy-load default language (without caring about duplicate assignment in race conditions, no harm done) + if (neutralResourcesCulture == null) + { + neutralResourcesCulture = GetNeutralResourcesLanguage(this.MainAssembly); + } + + // If we're asking for the default language, then ask for the + // invariant (non-specific) resources. + if (neutralResourcesCulture.Equals(culture)) + { + culture = CultureInfo.InvariantCulture; + } + string resourceFileName = GetResourceFileName(culture); + + Stream store = this.MainAssembly.GetManifestResourceStream(resourceFileName); + + // If we found the appropriate resources in the local assembly + if (store != null) + { + rs = new ResourceSet(store); + // Save for later + myResourceSets.Add(culture, rs); + } + else + { + rs = base.InternalGetResourceSet(culture, createIfNotExists, tryParents); + } + } + return rs; + } + + private CultureInfo neutralResourcesCulture; + private Dictionary<CultureInfo, ResourceSet> myResourceSets = new Dictionary<CultureInfo, ResourceSet>(); + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fc8a0c34c..bf7ad6b224 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. - [GUI] Context sensitive help (#3563 by: HebaruSan; reviewed: techman83) - [Multiple] Add install size to metadata and display in clients (#3568 by: HebaruSan; reviewed: techman83) - [CLI] Create a system menu entry for command prompt (#3622 by: HebaruSan; reviewed: techman83) +- [Multiple] Internationalize Core, CmdLine, ConsoleUI, and AutoUpdater (#3482 by: HebaruSan; reviewed: techman83) ## Bugfixes diff --git a/Cmdline/Action/AuthToken.cs b/Cmdline/Action/AuthToken.cs index d5bd9ff60c..71222c5497 100644 --- a/Cmdline/Action/AuthToken.cs +++ b/Cmdline/Action/AuthToken.cs @@ -66,6 +66,8 @@ public int RunSubCommand(GameInstanceManager manager, CommonOptions opts, SubCom private int listAuthTokens(CommonOptions opts) { + string hostHeader = Properties.Resources.AuthTokenHostHeader; + string tokenHeader = Properties.Resources.AuthTokenTokenHeader; List<string> hosts = new List<string>(ServiceLocator.Container.Resolve<IConfiguration>().GetAuthTokenHosts()); if (hosts.Count > 0) { @@ -119,11 +121,8 @@ private int removeAuthToken(RemoveAuthTokenOptions opts) return Exit.OK; } - private const string hostHeader = "Host"; - private const string tokenHeader = "Token"; - - private IUser user; - private static readonly ILog log = LogManager.GetLogger(typeof(AuthToken)); + private IUser user; + private static readonly ILog log = LogManager.GetLogger(typeof(AuthToken)); } internal class AuthTokenSubOptions : VerbCommandOptions @@ -145,8 +144,8 @@ public string GetUsage(string verb) ht.AddPreOptionsLine(" "); if (string.IsNullOrEmpty(verb)) { - ht.AddPreOptionsLine("ckan authtoken - Manage authentication tokens"); - ht.AddPreOptionsLine($"Usage: ckan authtoken <command> [options]"); + ht.AddPreOptionsLine($"ckan authtoken - {Properties.Resources.AuthTokenHelpSummary}"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan authtoken <{Properties.Resources.Command}> [{Properties.Resources.Options}]"); } else { @@ -154,13 +153,13 @@ public string GetUsage(string verb) switch (verb) { case "add": - ht.AddPreOptionsLine($"Usage: ckan authtoken {verb} [options] host token"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan authtoken {verb} [{Properties.Resources.Options}] host token"); break; case "remove": - ht.AddPreOptionsLine($"Usage: ckan authtoken {verb} [options] host"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan authtoken {verb} [{Properties.Resources.Options}] host"); break; case "list": - ht.AddPreOptionsLine($"Usage: ckan authtoken {verb} [options]"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan authtoken {verb} [{Properties.Resources.Options}]"); break; } } diff --git a/Cmdline/Action/Available.cs b/Cmdline/Action/Available.cs index ae445fe6d9..4b8becd8ff 100644 --- a/Cmdline/Action/Available.cs +++ b/Cmdline/Action/Available.cs @@ -12,16 +12,17 @@ public Available(IUser user) this.user = user; } - public int RunCommand(CKAN.GameInstance ksp, object raw_options) + public int RunCommand(CKAN.GameInstance instance, object raw_options) { AvailableOptions opts = (AvailableOptions)raw_options; - IRegistryQuerier registry = RegistryManager.Instance(ksp).registry; + IRegistryQuerier registry = RegistryManager.Instance(instance).registry; var compatible = registry - .CompatibleModules(ksp.VersionCriteria()) + .CompatibleModules(instance.VersionCriteria()) .Where(m => !m.IsDLC); - user.RaiseMessage("Modules compatible with KSP {0}", ksp.Version()); + user.RaiseMessage(string.Format(Properties.Resources.AvailableHeader, + instance.game.ShortName, instance.Version())); user.RaiseMessage(""); if (opts.detail) diff --git a/Cmdline/Action/Cache.cs b/Cmdline/Action/Cache.cs index 36c43f8de9..a61f3e6bad 100644 --- a/Cmdline/Action/Cache.cs +++ b/Cmdline/Action/Cache.cs @@ -34,8 +34,8 @@ public string GetUsage(string verb) ht.AddPreOptionsLine(" "); if (string.IsNullOrEmpty(verb)) { - ht.AddPreOptionsLine("ckan cache - Manage the download cache path of CKAN"); - ht.AddPreOptionsLine($"Usage: ckan cache <command> [options]"); + ht.AddPreOptionsLine($"ckan cache - {Properties.Resources.CacheHelpSummary}"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan cache <{Properties.Resources.Command}> [{Properties.Resources.Options}]"); } else { @@ -44,10 +44,10 @@ public string GetUsage(string verb) { // First the commands with one string argument case "set": - ht.AddPreOptionsLine($"Usage: ckan cache {verb} [options] path"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan cache {verb} [{Properties.Resources.Options}] path"); break; case "setlimit": - ht.AddPreOptionsLine($"Usage: ckan cache {verb} [options] megabytes"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan cache {verb} [{Properties.Resources.Options}] megabytes"); break; // Now the commands with only --flag type options @@ -56,7 +56,7 @@ public string GetUsage(string verb) case "reset": case "showlimit": default: - ht.AddPreOptionsLine($"Usage: ckan cache {verb} [options]"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan cache {verb} [{Properties.Resources.Options}]"); break; } } @@ -135,7 +135,7 @@ public int RunSubCommand(GameInstanceManager mgr, CommonOptions opts, SubCommand break; default: - user.RaiseMessage("Unknown command: cache {0}", option); + user.RaiseMessage("{0}: cache {1}", Properties.Resources.UnknownCommand, option); exitCode = Exit.BADOPT; break; } @@ -156,7 +156,7 @@ private int SetCacheDirectory(SetOptions options) { if (string.IsNullOrEmpty(options.Path)) { - user.RaiseError("set <path> - argument missing, perhaps you forgot it?"); + user.RaiseError("set <{0}> - {1}", Properties.Resources.Path, Properties.Resources.ArgumentMissing); return Exit.BADOPT; } @@ -164,13 +164,13 @@ private int SetCacheDirectory(SetOptions options) if (manager.TrySetupCache(options.Path, out failReason)) { IConfiguration cfg = ServiceLocator.Container.Resolve<IConfiguration>(); - user.RaiseMessage($"Download cache set to {cfg.DownloadCacheDir}"); + user.RaiseMessage(Properties.Resources.CacheSet, cfg.DownloadCacheDir); printCacheInfo(); return Exit.OK; } else { - user.RaiseError($"Invalid path: {failReason}"); + user.RaiseError(Properties.Resources.CacheInvalidPath, failReason); return Exit.BADOPT; } } @@ -178,7 +178,7 @@ private int SetCacheDirectory(SetOptions options) private int ClearCacheDirectory(CommonOptions options) { manager.Cache.RemoveAll(); - user.RaiseMessage("Download cache cleared."); + user.RaiseMessage(Properties.Resources.CacheCleared); printCacheInfo(); return Exit.OK; } @@ -189,12 +189,12 @@ private int ResetCacheDirectory(CommonOptions options) if (manager.TrySetupCache("", out failReason)) { IConfiguration cfg = ServiceLocator.Container.Resolve<IConfiguration>(); - user.RaiseMessage($"Download cache reset to {cfg.DownloadCacheDir}"); + user.RaiseMessage(Properties.Resources.CacheReset, cfg.DownloadCacheDir); printCacheInfo(); } else { - user.RaiseError($"Can't reset cache path: {failReason}"); + user.RaiseError(Properties.Resources.CacheResetFailed, failReason); } return Exit.OK; } @@ -208,7 +208,7 @@ private int ShowCacheSizeLimit(CommonOptions options) } else { - user.RaiseMessage("Unlimited"); + user.RaiseMessage(Properties.Resources.CacheUnlimited); } return Exit.OK; } @@ -232,11 +232,11 @@ private void printCacheInfo() int fileCount; long bytes; manager.Cache.GetSizeInfo(out fileCount, out bytes); - user.RaiseMessage($"{fileCount} files, {CkanModule.FmtSize(bytes)}"); + user.RaiseMessage(Properties.Resources.CacheInfo, fileCount, CkanModule.FmtSize(bytes)); } + private IUser user; private GameInstanceManager manager; - private IUser user; private static readonly ILog log = LogManager.GetLogger(typeof(Cache)); } diff --git a/Cmdline/Action/Compare.cs b/Cmdline/Action/Compare.cs index 328358a8a7..46b7182bf9 100644 --- a/Cmdline/Action/Compare.cs +++ b/Cmdline/Action/Compare.cs @@ -18,7 +18,7 @@ public int RunCommand(object rawOptions) if (options.Left != null && options.Right != null) { - var leftVersion = new ModuleVersion(options.Left); + var leftVersion = new ModuleVersion(options.Left); var rightVersion = new ModuleVersion(options.Right); int compareResult = leftVersion.CompareTo(rightVersion); @@ -29,29 +29,24 @@ public int RunCommand(object rawOptions) } else if (compareResult == 0) { - user.RaiseMessage( - "\"{0}\" and \"{1}\" are the same versions.", leftVersion, rightVersion); + user.RaiseMessage(Properties.Resources.CompareSame, leftVersion, rightVersion); } else if (compareResult < 0) { - user.RaiseMessage( - "\"{0}\" is lower than \"{1}\".", leftVersion, rightVersion); + user.RaiseMessage(Properties.Resources.CompareLower, leftVersion, rightVersion); } else if (compareResult > 0) { - user.RaiseMessage( - "\"{0}\" is higher than \"{1}\".", leftVersion, rightVersion); + user.RaiseMessage(Properties.Resources.CompareHigher, leftVersion, rightVersion); } else { - user.RaiseMessage( - "Usage: ckan compare version1 version2"); + user.RaiseMessage("{0}: ckan compare version1 version2", Properties.Resources.Usage); } } else { - user.RaiseMessage( - "Usage: ckan compare version1 version2"); + user.RaiseMessage("{0}: ckan compare version1 version2", Properties.Resources.Usage); return Exit.BADOPT; } diff --git a/Cmdline/Action/Compat.cs b/Cmdline/Action/Compat.cs index d86d39d61a..0818730f67 100644 --- a/Cmdline/Action/Compat.cs +++ b/Cmdline/Action/Compat.cs @@ -24,8 +24,8 @@ public string GetUsage(string verb) ht.AddPreOptionsLine(" "); if (string.IsNullOrEmpty(verb)) { - ht.AddPreOptionsLine("ckan compat - Manage KSP version compatibility"); - ht.AddPreOptionsLine($"Usage: ckan compat <command> [options]"); + ht.AddPreOptionsLine($"ckan compat - {Properties.Resources.CompatHelpSummary}"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan compat <{Properties.Resources.Command}> [{Properties.Resources.Options}]"); } else { @@ -35,13 +35,13 @@ public string GetUsage(string verb) // First the commands with one string argument case "add": case "forget": - ht.AddPreOptionsLine($"Usage: ckan compat {verb} [options] version"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan compat {verb} [{Properties.Resources.Options}] version"); break; // Now the commands with only --flag type options case "list": default: - ht.AddPreOptionsLine($"Usage: ckan compat {verb} [options]"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan compat {verb} [{Properties.Resources.Options}]"); break; } } @@ -86,12 +86,12 @@ public int RunSubCommand(GameInstanceManager manager, CommonOptions opts, SubCom { case "list": { - var ksp = MainClass.GetGameInstance(_kspManager); + var instance = MainClass.GetGameInstance(_kspManager); - const string versionHeader = "Version"; - const string actualHeader = "Actual"; + string versionHeader = Properties.Resources.CompatVersionHeader; + string actualHeader = Properties.Resources.CompatActualHeader; - var output = ksp + var output = instance .GetCompatibleVersions() .Select(i => new { @@ -102,7 +102,7 @@ public int RunSubCommand(GameInstanceManager manager, CommonOptions opts, SubCom output.Add(new { - Version = ksp.Version(), + Version = instance.Version(), Actual = true }); @@ -135,29 +135,29 @@ public int RunSubCommand(GameInstanceManager manager, CommonOptions opts, SubCom foreach (var line in output) { - _user.RaiseMessage(string.Format(columnFormat, + _user.RaiseMessage(columnFormat, line.Version.ToString().PadRight(versionWidth), line.Actual.ToString().PadRight(actualWidth) - )); + ); } } break; case "add": { - var ksp = MainClass.GetGameInstance(_kspManager); + var instance = MainClass.GetGameInstance(_kspManager); var addOptions = (CompatAddOptions)suboptions; GameVersion GameVersion; if (GameVersion.TryParse(addOptions.Version, out GameVersion)) { - var newCompatibleVersion = ksp.GetCompatibleVersions(); + var newCompatibleVersion = instance.GetCompatibleVersions(); newCompatibleVersion.Add(GameVersion); - ksp.SetCompatibleVersions(newCompatibleVersion); + instance.SetCompatibleVersions(newCompatibleVersion); } else { - _user.RaiseError("ERROR: Invalid KSP version."); + _user.RaiseError(Properties.Resources.CompatInvalid); exitCode = Exit.ERROR; } } @@ -165,27 +165,27 @@ public int RunSubCommand(GameInstanceManager manager, CommonOptions opts, SubCom case "forget": { - var ksp = MainClass.GetGameInstance(_kspManager); + var instance = MainClass.GetGameInstance(_kspManager); var addOptions = (CompatForgetOptions)suboptions; GameVersion GameVersion; if (GameVersion.TryParse(addOptions.Version, out GameVersion)) { - if (GameVersion != ksp.Version()) + if (GameVersion != instance.Version()) { - var newCompatibleVersion = ksp.GetCompatibleVersions(); + var newCompatibleVersion = instance.GetCompatibleVersions(); newCompatibleVersion.RemoveAll(i => i == GameVersion); - ksp.SetCompatibleVersions(newCompatibleVersion); + instance.SetCompatibleVersions(newCompatibleVersion); } else { - _user.RaiseError("ERROR: Cannot forget actual KSP version."); + _user.RaiseError(Properties.Resources.CompatCantForget); exitCode = Exit.ERROR; } } else { - _user.RaiseError("ERROR: Invalid KSP version."); + _user.RaiseError(Properties.Resources.CompatInvalid); exitCode = Exit.ERROR; } } @@ -200,7 +200,7 @@ public int RunSubCommand(GameInstanceManager manager, CommonOptions opts, SubCom return exitCode; } + private IUser _user; private GameInstanceManager _kspManager; - private IUser _user; } } diff --git a/Cmdline/Action/Filter.cs b/Cmdline/Action/Filter.cs index 4ceb741934..aca59458e9 100644 --- a/Cmdline/Action/Filter.cs +++ b/Cmdline/Action/Filter.cs @@ -60,7 +60,7 @@ public int RunSubCommand(GameInstanceManager mgr, CommonOptions opts, SubCommand break; default: - user.RaiseMessage("Unknown command: filter {0}", option); + user.RaiseMessage("{0}: filter {1}", Properties.Resources.UnknownCommand, option); exitCode = Exit.BADOPT; break; } @@ -78,7 +78,7 @@ private int ListFilters(FilterListOptions opts, string verb) } var cfg = ServiceLocator.Container.Resolve<Configuration.IConfiguration>(); - user.RaiseMessage("Global filters:"); + user.RaiseMessage(Properties.Resources.FilterListGlobalHeader); foreach (string filter in cfg.GlobalInstallFilters) { user.RaiseMessage("\t- {0}", filter); @@ -86,7 +86,7 @@ private int ListFilters(FilterListOptions opts, string verb) user.RaiseMessage(""); var instance = MainClass.GetGameInstance(manager); - user.RaiseMessage("Instance filters:"); + user.RaiseMessage(Properties.Resources.FilterListInstanceHeader); foreach (string filter in instance.InstallFilters) { user.RaiseMessage("\t- {0}", filter); @@ -98,7 +98,7 @@ private int AddFilters(FilterAddOptions opts, string verb) { if (opts.filters.Count < 1) { - user.RaiseMessage("Usage: ckan filter {0} filter1 [filter2 ...]", verb); + user.RaiseMessage("{0}: ckan filter {1} filter1 [filter2 ...]", Properties.Resources.Usage, verb); return Exit.BADOPT; } @@ -117,7 +117,7 @@ private int AddFilters(FilterAddOptions opts, string verb) if (duplicates.Length > 0) { user.RaiseError( - "Global filters already set: {0}", + Properties.Resources.FilterAddGlobalDuplicateError, string.Join(", ", duplicates) ); return Exit.BADOPT; @@ -139,7 +139,7 @@ private int AddFilters(FilterAddOptions opts, string verb) if (duplicates.Length > 0) { user.RaiseError( - "Instance filters already set: {0}", + Properties.Resources.FilterAddInstanceDuplicateError, string.Join(", ", duplicates) ); return Exit.BADOPT; @@ -159,7 +159,7 @@ private int RemoveFilters(FilterRemoveOptions opts, string verb) { if (opts.filters.Count < 1) { - user.RaiseMessage("Usage: ckan filter {0} filter1 [filter2 ...]", verb); + user.RaiseMessage("{0}: ckan filter {1} filter1 [filter2 ...]", Properties.Resources.Usage, verb); return Exit.BADOPT; } @@ -178,7 +178,7 @@ private int RemoveFilters(FilterRemoveOptions opts, string verb) if (notFound.Length > 0) { user.RaiseError( - "Global filters not found: {0}", + Properties.Resources.FilterRemoveGlobalNotFoundError, string.Join(", ", notFound) ); return Exit.BADOPT; @@ -199,7 +199,7 @@ private int RemoveFilters(FilterRemoveOptions opts, string verb) if (notFound.Length > 0) { user.RaiseError( - "Instance filters not found: {0}", + Properties.Resources.FilterRemoveInstanceNotFoundError, string.Join(", ", notFound) ); return Exit.BADOPT; @@ -239,8 +239,8 @@ public string GetUsage(string verb) ht.AddPreOptionsLine(" "); if (string.IsNullOrEmpty(verb)) { - ht.AddPreOptionsLine("ckan filter - View or edit installation filters"); - ht.AddPreOptionsLine($"Usage: ckan filter <command> [options]"); + ht.AddPreOptionsLine($"ckan filter - {Properties.Resources.FilterHelpSummary}"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan filter <{Properties.Resources.Command}> [{Properties.Resources.Options}]"); } else { @@ -248,15 +248,15 @@ public string GetUsage(string verb) switch (verb) { case "list": - ht.AddPreOptionsLine($"Usage: ckan filter {verb}"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan filter {verb}"); break; case "add": - ht.AddPreOptionsLine($"Usage: ckan filter {verb} [options] filter1 [filter2 ...]"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan filter {verb} [{Properties.Resources.Options}] filter1 [filter2 ...]"); break; case "remove": - ht.AddPreOptionsLine($"Usage: ckan filter {verb} [options] filter1 [filter2 ...]"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan filter {verb} [{Properties.Resources.Options}] filter1 [filter2 ...]"); break; } } diff --git a/Cmdline/Action/GameInstance.cs b/Cmdline/Action/GameInstance.cs index 44bbef3a73..8d8198f3c9 100644 --- a/Cmdline/Action/GameInstance.cs +++ b/Cmdline/Action/GameInstance.cs @@ -41,8 +41,8 @@ public string GetUsage(string verb) ht.AddPreOptionsLine(" "); if (string.IsNullOrEmpty(verb)) { - ht.AddPreOptionsLine("ckan instance - Manage game instances"); - ht.AddPreOptionsLine($"Usage: ckan instance <command> [options]"); + ht.AddPreOptionsLine($"ckan instance - {Properties.Resources.InstanceHelpSummary}"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan instance <{Properties.Resources.Command}> [{Properties.Resources.Options}]"); } else { @@ -51,19 +51,19 @@ public string GetUsage(string verb) { // First the commands with three string arguments case "fake": - ht.AddPreOptionsLine($"Usage: ckan instance {verb} [options] name path version [--MakingHistory <version>] [--BreakingGround <version>]"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan instance {verb} [{Properties.Resources.Options}] name path version [--MakingHistory <version>] [--BreakingGround <version>]"); break; case "clone": - ht.AddPreOptionsLine($"Usage: ckan instance {verb} [options] instanceNameOrPath newname newpath"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan instance {verb} [{Properties.Resources.Options}] instanceNameOrPath newname newpath"); break; // Second the commands with two string arguments case "add": - ht.AddPreOptionsLine($"Usage: ckan instance {verb} [options] name url"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan instance {verb} [{Properties.Resources.Options}] name url"); break; case "rename": - ht.AddPreOptionsLine($"Usage: ckan instance {verb} [options] oldname newname"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan instance {verb} [{Properties.Resources.Options}] oldname newname"); break; // Now the commands with one string argument @@ -71,13 +71,13 @@ public string GetUsage(string verb) case "forget": case "use": case "default": - ht.AddPreOptionsLine($"Usage: ckan instance {verb} [options] name"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan instance {verb} [{Properties.Resources.Options}] name"); break; // Now the commands with only --flag type options case "list": default: - ht.AddPreOptionsLine($"Usage: ckan instance {verb} [options]"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan instance {verb} [{Properties.Resources.Options}]"); break; } @@ -207,7 +207,7 @@ public int RunSubCommand(GameInstanceManager manager, CommonOptions opts, SubCom break; default: - User.RaiseMessage("Unknown command: instance {0}", option); + User.RaiseMessage("{0}: instance {1}", Properties.Resources.UnknownCommand, option); exitCode = Exit.BADOPT; break; } @@ -216,8 +216,8 @@ public int RunSubCommand(GameInstanceManager manager, CommonOptions opts, SubCom return exitCode; } + private IUser User { get; set; } private GameInstanceManager Manager { get; set; } - private IUser User { get; set; } #region option functions @@ -230,46 +230,48 @@ private int ListInstalls() .Select(i => new { Name = i.Key, - Version = i.Value.Version()?.ToString() ?? "<NONE>", - Default = i.Value.Name == Manager.AutoStartInstance ? "Yes" : "No", + Version = i.Value.Version()?.ToString() ?? Properties.Resources.InstanceListNoVersion, + Default = i.Value.Name == Manager.AutoStartInstance + ? Properties.Resources.InstanceListYes + : Properties.Resources.InstanceListNo, Path = i.Value.GameDir() }) .ToList(); - const string nameHeader = "Name"; - const string versionHeader = "Version"; - const string defaultHeader = "Default"; - const string pathHeader = "Path"; + string nameHeader = Properties.Resources.InstanceListNameHeader; + string versionHeader = Properties.Resources.InstanceListVersionHeader; + string defaultHeader = Properties.Resources.InstanceListDefaultHeader; + string pathHeader = Properties.Resources.InstanceListPathHeader; - var nameWidth = Enumerable.Repeat(nameHeader, 1).Concat(output.Select(i => i.Name)).Max(i => i.Length); + var nameWidth = Enumerable.Repeat(nameHeader, 1).Concat(output.Select(i => i.Name)).Max(i => i.Length); var versionWidth = Enumerable.Repeat(versionHeader, 1).Concat(output.Select(i => i.Version)).Max(i => i.Length); var defaultWidth = Enumerable.Repeat(defaultHeader, 1).Concat(output.Select(i => i.Default)).Max(i => i.Length); - var pathWidth = Enumerable.Repeat(pathHeader, 1).Concat(output.Select(i => i.Path)).Max(i => i.Length); + var pathWidth = Enumerable.Repeat(pathHeader, 1).Concat(output.Select(i => i.Path)).Max(i => i.Length); const string columnFormat = "{0} {1} {2} {3}"; - User.RaiseMessage(string.Format(columnFormat, + User.RaiseMessage(columnFormat, nameHeader.PadRight(nameWidth), versionHeader.PadRight(versionWidth), defaultHeader.PadRight(defaultWidth), pathHeader.PadRight(pathWidth) - )); + ); - User.RaiseMessage(string.Format(columnFormat, + User.RaiseMessage(columnFormat, new string('-', nameWidth), new string('-', versionWidth), new string('-', defaultWidth), new string('-', pathWidth) - )); + ); foreach (var line in output) { - User.RaiseMessage(string.Format(columnFormat, - line.Name.PadRight(nameWidth), - line.Version.PadRight(versionWidth), - line.Default.PadRight(defaultWidth), - line.Path.PadRight(pathWidth) - )); + User.RaiseMessage(columnFormat, + line.Name.PadRight(nameWidth), + line.Version.PadRight(versionWidth), + line.Default.PadRight(defaultWidth), + line.Path.PadRight(pathWidth) + ); } return Exit.OK; @@ -279,13 +281,13 @@ private int AddInstall(AddOptions options) { if (options.name == null || options.path == null) { - User.RaiseMessage("add <name> <path> - argument missing, perhaps you forgot it?"); + User.RaiseMessage("add <name> <{0}> - {1}", Properties.Resources.Path, Properties.Resources.ArgumentMissing); return Exit.BADOPT; } if (Manager.HasInstance(options.name)) { - User.RaiseMessage("Install with name \"{0}\" already exists, aborting..", options.name); + User.RaiseMessage(Properties.Resources.InstanceAddDuplicate, options.name); return Exit.BADOPT; } @@ -293,12 +295,12 @@ private int AddInstall(AddOptions options) { string path = options.path; Manager.AddInstance(path, options.name, User); - User.RaiseMessage("Added \"{0}\" with root \"{1}\" to known installs", options.name, options.path); + User.RaiseMessage(Properties.Resources.InstanceAdded, options.name, options.path); return Exit.OK; } catch (NotKSPDirKraken ex) { - User.RaiseMessage("Sorry, {0} does not appear to be a game instance", ex.path); + User.RaiseMessage(Properties.Resources.InstanceNotInstance, ex.path); return Exit.BADOPT; } } @@ -307,7 +309,8 @@ private int CloneInstall(CloneOptions options) { if (options.nameOrPath == null || options.new_name == null || options.new_path == null) { - User.RaiseMessage("instance clone <nameOrPathExistingInstance> <newName> <newPath> - argument(s) missing"); + User.RaiseMessage("instance clone <nameOrPathExistingInstance> <newName> <newPath> - {0}", + Properties.Resources.ArgumentMissing); return Exit.BADOPT; } @@ -375,13 +378,13 @@ private int CloneInstall(CloneOptions options) } catch (NoGameInstanceKraken) { - User.RaiseError(String.Format("No instance with this name or at this path: {0}\n See below for a list of known instances:\n", instanceNameOrPath)); + User.RaiseError(Properties.Resources.InstanceCloneNotFound, instanceNameOrPath); ListInstalls(); return Exit.ERROR; } catch (InstanceNameTakenKraken kraken) { - User.RaiseError("This instance name is already taken: {0}", kraken.instName); + User.RaiseError(Properties.Resources.InstanceDuplicate, kraken.instName); return Exit.BADOPT; } @@ -394,8 +397,7 @@ private int CloneInstall(CloneOptions options) } else { - User.RaiseMessage("Something went wrong. Please look if the new directory has been created.\n", - "Try to add the new instance manually with \"ckan instance add\".\n"); + User.RaiseMessage(Properties.Resources.InstanceCloneFailed); return Exit.ERROR; } } @@ -404,19 +406,19 @@ private int RenameInstall(RenameOptions options) { if (options.old_name == null || options.new_name == null) { - User.RaiseMessage("rename <old_name> <new_name> - argument missing, perhaps you forgot it?"); + User.RaiseMessage("rename <old_name> <new_name> - {0}", Properties.Resources.ArgumentMissing); return Exit.BADOPT; } if (!Manager.HasInstance(options.old_name)) { - User.RaiseMessage("Couldn't find install with name \"{0}\", aborting..", options.old_name); + User.RaiseMessage(Properties.Resources.InstanceNotFound, options.old_name); return Exit.BADOPT; } Manager.RenameInstance(options.old_name, options.new_name); - User.RaiseMessage("Successfully renamed \"{0}\" to \"{1}\"", options.old_name, options.new_name); + User.RaiseMessage(Properties.Resources.InstanceRenamed, options.old_name, options.new_name); return Exit.OK; } @@ -424,19 +426,19 @@ private int ForgetInstall(ForgetOptions options) { if (options.name == null) { - User.RaiseMessage("forget <name> - argument missing, perhaps you forgot it?"); + User.RaiseMessage("forget <name> - {0}", Properties.Resources.ArgumentMissing); return Exit.BADOPT; } if (!Manager.HasInstance(options.name)) { - User.RaiseMessage("Couldn't find install with name \"{0}\", aborting..", options.name); + User.RaiseMessage(Properties.Resources.InstanceNotFound, options.name); return Exit.BADOPT; } Manager.RemoveInstance(options.name); - User.RaiseMessage("Successfully removed \"{0}\"", options.name); + User.RaiseMessage(Properties.Resources.InstanceForgot, options.name); return Exit.OK; } @@ -447,7 +449,7 @@ private int SetDefaultInstall(DefaultOptions options) if (name == null) { // No input argument from the user. Present a list of the possible instances. - string message = "default <name> - argument missing, please select from the list below."; + string message = $"default <name> - {Properties.Resources.InstanceDefaultArgumentMissing}"; // Check if there is a default instance. string defaultInstance = Manager.Configuration.AutoStartInstance; @@ -465,7 +467,7 @@ private int SetDefaultInstall(DefaultOptions options) { var instance = Manager.Instances.ElementAt(i); - keys[i + defaultInstancePresent] = String.Format("\"{0}\" - {1}", instance.Key, instance.Value.GameDir()); + keys[i + defaultInstancePresent] = string.Format("\"{0}\" - {1}", instance.Key, instance.Value.GameDir()); } // Mark the default instance for the user. @@ -495,7 +497,7 @@ private int SetDefaultInstall(DefaultOptions options) if (!Manager.Instances.ContainsKey(name)) { - User.RaiseMessage("Couldn't find install with name \"{0}\", aborting..", name); + User.RaiseMessage(Properties.Resources.InstanceNotFound, name); return Exit.BADOPT; } @@ -505,11 +507,11 @@ private int SetDefaultInstall(DefaultOptions options) } catch (NotKSPDirKraken k) { - User.RaiseMessage("Sorry, {0} does not appear to be a game instance", k.path); + User.RaiseMessage(Properties.Resources.InstanceNotInstance, k.path); return Exit.BADOPT; } - User.RaiseMessage("Successfully set \"{0}\" as the default game instance", name); + User.RaiseMessage(Properties.Resources.InstanceDefaultSet, name); return Exit.OK; } @@ -522,22 +524,22 @@ private int FakeNewGameInstance(FakeOptions options) int error() { log.Debug("Instance faking failed, see console output for details."); - User.RaiseMessage("--Error--"); return Exit.ERROR; } int badArgument() { log.Debug("Instance faking failed: bad argument(s). See console output for details."); - User.RaiseMessage("--Error: bad argument(s)--"); + User.RaiseMessage(Properties.Resources.InstanceFakeBadArguments); return Exit.BADOPT; } if (options.name == null || options.path == null || options.version == null) { - User.RaiseMessage("instance fake <name> <path> <version> " + - "[--MakingHistory <version>] [--BreakingGround <version>] - argument(s) missing"); + User.RaiseMessage("instance fake <name> <{0}> <version> " + + "[--MakingHistory <version>] [--BreakingGround <version>] - {1}", + Properties.Resources.Path, Properties.Resources.ArgumentMissing); return badArgument(); } @@ -558,7 +560,7 @@ int badArgument() } else { - User.RaiseError("Please check the Making History DLC version argument - Format it like Maj.Min.Patch - e.g. 1.1.0"); + User.RaiseError(Properties.Resources.InstanceFakeMakingHistory); return badArgument(); } } @@ -570,7 +572,7 @@ int badArgument() } else { - User.RaiseError("Please check the Breaking Ground DLC version argument - Format it like Maj.Min.Patch - e.g. 1.1.0"); + User.RaiseError(Properties.Resources.InstanceFakeBreakingGround); return badArgument(); } } @@ -583,7 +585,7 @@ int badArgument() catch (FormatException) { // Thrown if there is anything besides numbers and points in the version string or a different syntactic error. - User.RaiseError("Please check the version argument - Format it like Maj.Min.Patch[.Build] - e.g. 1.6.0 or 1.2.2.1622"); + User.RaiseError(Properties.Resources.InstanceFakeVersion); return badArgument(); } @@ -594,17 +596,17 @@ int badArgument() } catch (BadGameVersionKraken) { - User.RaiseError("Couldn't find a valid game version for your input.\n" + - "Make sure to enter the at least the version major and minor values in the form Maj.Min - e.g. 1.5"); + User.RaiseError(Properties.Resources.InstanceFakeBadGameVersion); return badArgument(); } catch (CancelledActionKraken) { - User.RaiseError("Selection cancelled! Please call 'ckan instance fake' again."); + User.RaiseError(Properties.Resources.InstanceFakeCancelled); return error(); } - User.RaiseMessage(String.Format("Creating new fake game instance {0} at {1} with version {2}", installName, path, version.ToString())); + User.RaiseMessage(Properties.Resources.InstanceFakeCreating, + installName, path, version.ToString()); log.Debug("Faking instance..."); try @@ -613,13 +615,13 @@ int badArgument() Manager.FakeInstance(new KerbalSpaceProgram(), installName, path, version, dlcs); if (setDefault) { - User.RaiseMessage("Setting new instance to default..."); + User.RaiseMessage(Properties.Resources.InstanceFakeDefault); Manager.SetAutoStart(installName); } } catch (InstanceNameTakenKraken kraken) { - User.RaiseError("This instance name is already taken: {0}", kraken.instName); + User.RaiseError(Properties.Resources.InstanceDuplicate, kraken.instName); return badArgument(); } catch (BadInstallLocationKraken kraken) @@ -639,6 +641,7 @@ int badArgument() // Something went wrong adding the new instance to the registry, // most likely because the newly created directory is somehow not valid. log.Error(kraken); + User.RaiseError(kraken.Message); return error(); } catch (InvalidKSPInstanceKraken) @@ -652,13 +655,12 @@ int badArgument() // No need to test if valid, because this is done in AddInstance(). if (Manager.HasInstance(installName)) { - User.RaiseMessage("--Done--"); + User.RaiseMessage(Properties.Resources.InstanceFakeDone); return Exit.OK; } else { - User.RaiseError("Something went wrong. Try to add the instance yourself with \"ckan instance add\".", - "Also look if the new directory has been created."); + User.RaiseError(Properties.Resources.InstanceFakeFailed); return error(); } } diff --git a/Cmdline/Action/Import.cs b/Cmdline/Action/Import.cs index 044d9170a7..7934290e98 100644 --- a/Cmdline/Action/Import.cs +++ b/Cmdline/Action/Import.cs @@ -39,7 +39,7 @@ public int RunCommand(CKAN.GameInstance ksp, object options) HashSet<FileInfo> toImport = GetFiles(opts); if (toImport.Count < 1) { - user.RaiseMessage("Usage: ckan import path [path2, ...]"); + user.RaiseMessage($"{Properties.Resources.Usage}: ckan import {Properties.Resources.Path} [path2, ...]"); return Exit.ERROR; } else @@ -64,7 +64,7 @@ ref possibleConfigOnlyDirs } catch (Exception ex) { - user.RaiseError("Import error: {0}", ex.Message); + user.RaiseError(Properties.Resources.ImportError, ex.Message); return Exit.ERROR; } } @@ -100,7 +100,7 @@ private void AddFile(HashSet<FileInfo> files, string filename) } else { - user.RaiseMessage("File not found: {0}", filename); + user.RaiseMessage(Properties.Resources.ImportNotFound, filename); } } diff --git a/Cmdline/Action/Install.cs b/Cmdline/Action/Install.cs index 0f20276b20..8f662580da 100644 --- a/Cmdline/Action/Install.cs +++ b/Cmdline/Action/Install.cs @@ -27,12 +27,12 @@ public Install(GameInstanceManager mgr, IUser user) /// <summary> /// Installs a module, if available /// </summary> - /// <param name="ksp">Game instance into which to install</param> + /// <param name="instance">Game instance into which to install</param> /// <param name="raw_options">Command line options object</param> /// <returns> /// Exit code for shell environment /// </returns> - public int RunCommand(CKAN.GameInstance ksp, object raw_options) + public int RunCommand(CKAN.GameInstance instance, object raw_options) { InstallOptions options = (InstallOptions) raw_options; @@ -55,8 +55,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) else { // We have no further ideas as what we can do with this Uri, tell the user. - user.RaiseError("Can not find file \"{0}\".", ckan_file); - user.RaiseError("Exiting."); + user.RaiseError(Properties.Resources.InstallNotFound, ckan_file); return Exit.ERROR; } } @@ -84,7 +83,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) // Parse the JSON file. try { - CkanModule m = MainClass.LoadCkanFromFile(ksp, filename); + CkanModule m = MainClass.LoadCkanFromFile(instance, filename); options.modules.Add($"{m.identifier}={m.version}"); } catch (Kraken kraken) @@ -101,14 +100,14 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) } else { - Search.AdjustModulesCase(ksp, options.modules); + Search.AdjustModulesCase(instance, options.modules); } if (options.modules.Count == 0) { // What? No files specified? user.RaiseMessage( - "Usage: ckan install [--with-suggests] [--with-all-suggests] [--no-recommends] [--headless] Mod [Mod2, ...]"); + $"{Properties.Resources.Usage}: ckan install [--with-suggests] [--with-all-suggests] [--no-recommends] [--headless] Mod [Mod2, ...]"); return Exit.BADOPT; } @@ -127,7 +126,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) install_ops.without_enforce_consistency = true; } - RegistryManager regMgr = RegistryManager.Instance(ksp); + RegistryManager regMgr = RegistryManager.Instance(instance); List<string> modules = options.modules; for (bool done = false; !done; ) @@ -136,7 +135,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) try { HashSet<string> possibleConfigOnlyDirs = null; - var installer = new ModuleInstaller(ksp, manager.Cache, user); + var installer = new ModuleInstaller(instance, manager.Cache, user); installer.InstallList(modules, install_ops, regMgr, ref possibleConfigOnlyDirs); user.RaiseMessage(""); done = true; @@ -144,32 +143,27 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) catch (DependencyNotSatisfiedKraken ex) { user.RaiseError(ex.Message); - user.RaiseMessage("If you're lucky, you can do a `ckan update` and try again."); - user.RaiseMessage("Try `ckan install --no-recommends` to skip installation of recommended modules."); - user.RaiseMessage("Or `ckan install --allow-incompatible` to ignore module compatibility."); + user.RaiseMessage(Properties.Resources.InstallTryAgain); return Exit.ERROR; } catch (ModuleNotFoundKraken ex) { if (ex.version == null) { - user.RaiseError("Module {0} required but it is not listed in the index, or not available for your version of KSP.", - ex.module); + user.RaiseError(Properties.Resources.InstallUnversionedDependencyNotSatisfied, + ex.module, instance.game.ShortName); } else { - user.RaiseError("Module {0} {1} required but it is not listed in the index, or not available for your version of KSP.", - ex.module, ex.version); + user.RaiseError(Properties.Resources.InstallVersionedDependencyNotSatisfied, + ex.module, ex.version, instance.game.ShortName); } - user.RaiseMessage("If you're lucky, you can do a `ckan update` and try again."); - user.RaiseMessage("Try `ckan install --no-recommends` to skip installation of recommended modules."); - user.RaiseMessage("Or `ckan install --allow-incompatible` to ignore module compatibility."); + user.RaiseMessage(Properties.Resources.InstallTryAgain); return Exit.ERROR; } catch (BadMetadataKraken ex) { - user.RaiseError("Bad metadata detected for module {0}: {1}", - ex.module, ex.Message); + user.RaiseError(Properties.Resources.InstallBadMetadata, ex.module, ex.Message); return Exit.ERROR; } catch (TooManyModsProvideKraken ex) @@ -204,49 +198,29 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) { if (ex.owningModule != null) { - user.RaiseError( - "Oh 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", + user.RaiseError(Properties.Resources.InstallFileConflictOwned, ex.filename, ex.installingModule, ex.owningModule, - Meta.GetVersion(VersionFormat.Full) - ); + Meta.GetVersion(VersionFormat.Full)); } else { - user.RaiseError( - "Oh 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, 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 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 - ); + user.RaiseError(Properties.Resources.InstallFileConflictUnowned, + ex.installingModule, ex.filename); } - user.RaiseMessage("Your GameData has been returned to its original state."); + user.RaiseMessage(Properties.Resources.InstallGamedataReturned, instance.game.PrimaryModDirectoryRelative); return Exit.ERROR; } catch (InconsistentKraken ex) { // The prettiest Kraken formats itself for us. user.RaiseError(ex.InconsistenciesPretty); - user.RaiseMessage("Install canceled. Your files have been returned to their initial state."); + user.RaiseMessage(Properties.Resources.InstallCancelled); return Exit.ERROR; } catch (CancelledActionKraken k) { - user.RaiseError("Installation aborted: {0}", k.Message); + user.RaiseError(Properties.Resources.InstallAborted, k.Message); return Exit.ERROR; } catch (MissingCertificateKraken kraken) @@ -258,13 +232,12 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) catch (DownloadThrottledKraken kraken) { user.RaiseError(kraken.ToString()); - user.RaiseMessage("Try the authtoken command. See {0} for details.", - kraken.infoUrl); + user.RaiseMessage(Properties.Resources.InstallTryAuthToken, kraken.infoUrl); return Exit.ERROR; } catch (DownloadErrorsKraken) { - user.RaiseError("One or more files failed to download, stopped."); + user.RaiseError(Properties.Resources.InstallDownloadFailed); return Exit.ERROR; } catch (ModuleDownloadErrorsKraken kraken) @@ -279,15 +252,14 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) } catch (ModuleIsDLCKraken kraken) { - user.RaiseError("CKAN can't install expansion '{0}' for you.", - kraken.module.name); + user.RaiseError(Properties.Resources.InstallDLC, kraken.module.name); var res = kraken?.module?.resources; var storePagesMsg = new Uri[] { res?.store, res?.steamstore } .Where(u => u != null) .Aggregate("", (a, b) => $"{a}\r\n- {b}"); if (!string.IsNullOrEmpty(storePagesMsg)) { - user.RaiseMessage($"To install this expansion, purchase it from one of its store pages:\r\n{storePagesMsg}"); + user.RaiseMessage(Properties.Resources.InstallDLCStorePage, storePagesMsg); } return Exit.ERROR; } diff --git a/Cmdline/Action/List.cs b/Cmdline/Action/List.cs index 04b0220202..9f28713902 100644 --- a/Cmdline/Action/List.cs +++ b/Cmdline/Action/List.cs @@ -18,11 +18,11 @@ public List(IUser user) this.user = user; } - public int RunCommand(CKAN.GameInstance ksp, object raw_options) + public int RunCommand(CKAN.GameInstance instance, object raw_options) { ListOptions options = (ListOptions) raw_options; - IRegistryQuerier registry = RegistryManager.Instance(ksp).registry; + IRegistryQuerier registry = RegistryManager.Instance(instance).registry; ExportFileType? exportFileType = null; @@ -32,16 +32,19 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) if (exportFileType == null) { - user.RaiseError("Unknown export format: {0}", options.export); + user.RaiseError(Properties.Resources.ListUnknownFormat, options.export); } } if (!(options.porcelain) && exportFileType == null) { - user.RaiseMessage("\r\nKSP found at {0}\r\n", ksp.GameDir()); - user.RaiseMessage("KSP Version: {0}\r\n", ksp.Version()); - - user.RaiseMessage("Installed Modules:\r\n"); + user.RaiseMessage(""); + user.RaiseMessage(Properties.Resources.ListGameFound, instance.game.ShortName, instance.GameDir()); + user.RaiseMessage(""); + user.RaiseMessage(Properties.Resources.ListGameVersion, instance.game.ShortName, instance.Version()); + user.RaiseMessage(""); + user.RaiseMessage(Properties.Resources.ListGameModulesHeader); + user.RaiseMessage(""); } if (exportFileType == null) @@ -70,7 +73,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) { // Check if upgrades are available, and show appropriately. log.DebugFormat("Check if upgrades are available for {0}", mod.Key); - CkanModule latest = registry.LatestAvailable(mod.Key, ksp.VersionCriteria()); + CkanModule latest = registry.LatestAvailable(mod.Key, instance.VersionCriteria()); CkanModule current = registry.GetInstalledVersion(mod.Key); InstalledModule inst = registry.InstalledModule(mod.Key); @@ -79,12 +82,15 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) // Not compatible! log.InfoFormat("Latest {0} is not compatible", mod.Key); bullet = "X"; - if ( current == null ) log.DebugFormat( " {0} installed version not found in registry", mod.Key); + if (current == null) + { + log.DebugFormat(" {0} installed version not found in registry", mod.Key); + } // Check if mod is replaceable if (current.replaced_by != null) { - ModuleReplacement replacement = registry.GetReplacement(mod.Key, ksp.VersionCriteria()); + ModuleReplacement replacement = registry.GetReplacement(mod.Key, instance.VersionCriteria()); if (replacement != null) { // Replaceable! @@ -101,7 +107,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) // Check if mod is replaceable if (current.replaced_by != null) { - ModuleReplacement replacement = registry.GetReplacement(latest.identifier, ksp.VersionCriteria()); + ModuleReplacement replacement = registry.GetReplacement(latest.identifier, instance.VersionCriteria()); if (replacement != null) { // Replaceable! @@ -135,7 +141,8 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) if (!(options.porcelain) && exportFileType == null) { - user.RaiseMessage("\r\nLegend: -: Up to date. +:Auto-installed. X: Incompatible. ^: Upgradable. >: Replaceable\r\n A: Autodetected. ?: Unknown. *: Broken. "); + user.RaiseMessage(""); + user.RaiseMessage(Properties.Resources.ListLegend); // Broken mods are in a state that CKAN doesn't understand, and therefore can't handle automatically } diff --git a/Cmdline/Action/Mark.cs b/Cmdline/Action/Mark.cs index da793fb372..19e73f524c 100644 --- a/Cmdline/Action/Mark.cs +++ b/Cmdline/Action/Mark.cs @@ -46,15 +46,15 @@ public int RunSubCommand(GameInstanceManager mgr, CommonOptions opts, SubCommand switch (option) { case "auto": - exitCode = MarkAuto((MarkAutoOptions)suboptions, true, option, "auto-installed"); + exitCode = MarkAuto((MarkAutoOptions)suboptions, true, option, Properties.Resources.MarkAutoInstalled); break; case "user": - exitCode = MarkAuto((MarkAutoOptions)suboptions, false, option, "user-selected"); + exitCode = MarkAuto((MarkAutoOptions)suboptions, false, option, Properties.Resources.MarkUserSelected); break; default: - user.RaiseMessage("Unknown command: mark {0}", option); + user.RaiseMessage(Properties.Resources.MarkUnknownCommand, option); exitCode = Exit.BADOPT; break; } @@ -67,7 +67,7 @@ private int MarkAuto(MarkAutoOptions opts, bool value, string verb, string descr { if (opts.modules.Count < 1) { - user.RaiseMessage("Usage: ckan mark {0} Mod [Mod2 ...]", verb); + user.RaiseMessage("{0}: ckan mark {1} Mod [Mod2 ...]", Properties.Resources.Usage, verb); return Exit.BADOPT; } @@ -86,15 +86,15 @@ private int MarkAuto(MarkAutoOptions opts, bool value, string verb, string descr InstalledModule im = regMgr.registry.InstalledModule(id); if (im == null) { - user.RaiseError("{0} is not installed.", id); + user.RaiseError(Properties.Resources.MarkNotInstalled, id); } else if (im.AutoInstalled == value) { - user.RaiseError("{0} is already marked as {1}.", id, descrip); + user.RaiseError(Properties.Resources.MarkAlready, id, descrip); } else { - user.RaiseMessage("Marking {0} as {1}...", id, descrip); + user.RaiseMessage(Properties.Resources.Marking, id, descrip); try { im.AutoInstalled = value; @@ -102,7 +102,7 @@ private int MarkAuto(MarkAutoOptions opts, bool value, string verb, string descr } catch (ModuleIsDLCKraken kraken) { - user.RaiseMessage($"Can't mark expansion '{kraken.module.name}' as auto-installed."); + user.RaiseMessage(Properties.Resources.MarkDLC, kraken.module.name); return Exit.BADOPT; } } @@ -110,13 +110,13 @@ private int MarkAuto(MarkAutoOptions opts, bool value, string verb, string descr if (needSave) { regMgr.Save(false); - user.RaiseMessage("Changes made!"); + user.RaiseMessage(Properties.Resources.MarkChanged); } return Exit.OK; } + private IUser user { get; set; } private GameInstanceManager manager { get; set; } - private IUser user { get; set; } private static readonly ILog log = LogManager.GetLogger(typeof(Mark)); } @@ -137,20 +137,20 @@ public string GetUsage(string verb) ht.AddPreOptionsLine(" "); if (string.IsNullOrEmpty(verb)) { - ht.AddPreOptionsLine("ckan mark - Edit flags on modules"); - ht.AddPreOptionsLine($"Usage: ckan mark <command> [options]"); + ht.AddPreOptionsLine($"ckan mark - {Properties.Resources.MarkHelpSummary}"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan mark <{Properties.Resources.Command}> [{Properties.Resources.Options}]"); } else { - ht.AddPreOptionsLine("ksp " + verb + " - " + GetDescription(verb)); + ht.AddPreOptionsLine("mark " + verb + " - " + GetDescription(verb)); switch (verb) { case "auto": - ht.AddPreOptionsLine($"Usage: ckan mark {verb} [options] Mod [Mod2 ...]"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan mark {verb} [{Properties.Resources.Options}] Mod [Mod2 ...]"); break; case "user": - ht.AddPreOptionsLine($"Usage: ckan mark {verb} [options] Mod [Mod2 ...]"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan mark {verb} [{Properties.Resources.Options}] Mod [Mod2 ...]"); break; } } diff --git a/Cmdline/Action/Prompt.cs b/Cmdline/Action/Prompt.cs index 62a9d88b02..b9cd803636 100644 --- a/Cmdline/Action/Prompt.cs +++ b/Cmdline/Action/Prompt.cs @@ -24,10 +24,7 @@ public int RunCommand(object raw_options) // Print an intro if not in headless mode if (!headless) { - Console.WriteLine("Welcome to CKAN!"); - Console.WriteLine(""); - Console.WriteLine("To get help, type help and press enter."); - Console.WriteLine(""); + Console.WriteLine(Properties.Resources.PromptWelcome, exitCommand); } ReadLine.AutoCompletionHandler = GetSuggestions; bool done = false; @@ -38,8 +35,9 @@ public int RunCommand(object raw_options) { Console.Write( manager.CurrentInstance != null - ? $"CKAN {Meta.GetVersion()}: {manager.CurrentInstance.game.ShortName} {manager.CurrentInstance.Version()} ({manager.CurrentInstance.Name})> " - : $"CKAN {Meta.GetVersion()}> " + ? string.Format(Properties.Resources.PromptWithInstance, + Meta.GetVersion(), manager.CurrentInstance.game.ShortName, manager.CurrentInstance.Version(), manager.CurrentInstance.Name) + : string.Format(Properties.Resources.PromptWithoutInstance, Meta.GetVersion()) ); } try @@ -66,9 +64,7 @@ public int RunCommand(object raw_options) } catch (NoGameInstanceKraken) { - Console.WriteLine(""); - Console.WriteLine("No game instance selected, identifier completion not available."); - Console.WriteLine("Use the `instance default` command to choose an instance."); + Console.WriteLine(Properties.Resources.CompletionNotAvailable); } } return Exit.OK; diff --git a/Cmdline/Action/Remove.cs b/Cmdline/Action/Remove.cs index d25a186707..c8770b2aa8 100644 --- a/Cmdline/Action/Remove.cs +++ b/Cmdline/Action/Remove.cs @@ -27,15 +27,15 @@ public Remove(GameInstanceManager mgr, IUser user) /// <summary> /// Uninstalls a module, if it exists. /// </summary> - /// <param name="ksp">Game instance from which to remove</param> + /// <param name="instance">Game instance from which to remove</param> /// <param name="raw_options">Command line options object</param> /// <returns> /// Exit code for shell environment /// </returns> - public int RunCommand(CKAN.GameInstance ksp, object raw_options) + public int RunCommand(CKAN.GameInstance instance, object raw_options) { RemoveOptions options = (RemoveOptions) raw_options; - RegistryManager regMgr = RegistryManager.Instance(ksp); + RegistryManager regMgr = RegistryManager.Instance(instance); // Use one (or more!) regex to select the modules to remove if (options.regex) @@ -77,39 +77,38 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) try { HashSet<string> possibleConfigOnlyDirs = null; - var installer = new ModuleInstaller(ksp, manager.Cache, user); - Search.AdjustModulesCase(ksp, options.modules); + var installer = new ModuleInstaller(instance, manager.Cache, user); + Search.AdjustModulesCase(instance, options.modules); installer.UninstallList(options.modules, ref possibleConfigOnlyDirs, regMgr); user.RaiseMessage(""); } catch (ModNotInstalledKraken kraken) { - user.RaiseMessage("I can't do that, {0} isn't installed.", kraken.mod); - user.RaiseMessage("Try `ckan list` for a list of installed mods."); + user.RaiseMessage(Properties.Resources.RemoveNotInstalled, kraken.mod); return Exit.BADOPT; } catch (ModuleIsDLCKraken kraken) { - user.RaiseMessage($"CKAN can't remove expansion '{kraken.module.name}' for you."); + user.RaiseMessage(Properties.Resources.RemoveDLC, kraken.module.name); var res = kraken?.module?.resources; var storePagesMsg = new Uri[] { res?.store, res?.steamstore } .Where(u => u != null) .Aggregate("", (a, b) => $"{a}\r\n- {b}"); if (!string.IsNullOrEmpty(storePagesMsg)) { - user.RaiseMessage($"To remove this expansion, follow the instructions for the store page from which you purchased it:\r\n{storePagesMsg}"); + user.RaiseMessage(Properties.Resources.RemoveDLCStorePage, storePagesMsg); } return Exit.BADOPT; } catch (CancelledActionKraken k) { - user.RaiseMessage("Remove aborted: {0}", k.Message); + user.RaiseMessage(Properties.Resources.RemoveCancelled, k.Message); return Exit.ERROR; } } else { - user.RaiseMessage("No mod selected, nothing to do"); + user.RaiseMessage(Properties.Resources.RemoveNothing); return Exit.BADOPT; } diff --git a/Cmdline/Action/Repair.cs b/Cmdline/Action/Repair.cs index 9468f1adf2..d91ad9ef93 100644 --- a/Cmdline/Action/Repair.cs +++ b/Cmdline/Action/Repair.cs @@ -16,8 +16,8 @@ public string GetUsage(string verb) ht.AddPreOptionsLine(" "); if (string.IsNullOrEmpty(verb)) { - ht.AddPreOptionsLine("ckan repair - Attempt various automatic repairs"); - ht.AddPreOptionsLine($"Usage: ckan repair <command> [options]"); + ht.AddPreOptionsLine($"ckan repair - {Properties.Resources.RepairHelpSummary}"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan repair <{Properties.Resources.Command}> [{Properties.Resources.Options}]"); } else { @@ -27,7 +27,7 @@ public string GetUsage(string verb) // Commands with only --flag type options case "registry": default: - ht.AddPreOptionsLine($"Usage: ckan repair {verb} [options]"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan repair {verb} [{Properties.Resources.Options}]"); break; } } @@ -66,7 +66,7 @@ public int RunSubCommand(GameInstanceManager manager, CommonOptions opts, SubCom break; default: - User.RaiseMessage("Unknown command: repair {0}", option); + User.RaiseMessage(Properties.Resources.RepairUnknownCommand, option); exitCode = Exit.BADOPT; break; } @@ -85,7 +85,7 @@ private int Registry(CKAN.GameInstance ksp) RegistryManager manager = RegistryManager.Instance(ksp); manager.registry.Repair(); manager.Save(); - User.RaiseMessage("Registry repairs attempted. Hope it helped."); + User.RaiseMessage(Properties.Resources.Repaired); return Exit.OK; } } diff --git a/Cmdline/Action/Replace.cs b/Cmdline/Action/Replace.cs index 8631e72a79..060744d48b 100644 --- a/Cmdline/Action/Replace.cs +++ b/Cmdline/Action/Replace.cs @@ -20,19 +20,19 @@ public Replace(CKAN.GameInstanceManager mgr, IUser user) private GameInstanceManager manager; - public int RunCommand(CKAN.GameInstance ksp, object raw_options) + public int RunCommand(CKAN.GameInstance instance, object raw_options) { ReplaceOptions options = (ReplaceOptions) raw_options; if (options.ckan_file != null) { - options.modules.Add(MainClass.LoadCkanFromFile(ksp, options.ckan_file).identifier); + options.modules.Add(MainClass.LoadCkanFromFile(instance, options.ckan_file).identifier); } if (options.modules.Count == 0 && ! options.replace_all) { // What? No mods specified? - User.RaiseMessage("Usage: ckan replace Mod [Mod2, ...]"); + User.RaiseMessage("{0}: ckan replace Mod [Mod2, ...]", Properties.Resources.Usage); User.RaiseMessage(" or ckan replace --all"); return Exit.BADOPT; } @@ -46,7 +46,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) allow_incompatible = options.allow_incompatible }; - var regMgr = RegistryManager.Instance(ksp); + var regMgr = RegistryManager.Instance(instance); var registry = regMgr.registry; var to_replace = new List<ModuleReplacement>(); @@ -70,7 +70,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) log.DebugFormat("Testing {0} {1} for possible replacement", mod.Key, mod.Value); // Check if replacement is available - ModuleReplacement replacement = registry.GetReplacement(mod.Key, ksp.VersionCriteria()); + ModuleReplacement replacement = registry.GetReplacement(mod.Key, instance.VersionCriteria()); if (replacement != null) { // Replaceable @@ -102,7 +102,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) try { // Check if replacement is available - ModuleReplacement replacement = registry.GetReplacement(modToReplace.identifier, ksp.VersionCriteria()); + ModuleReplacement replacement = registry.GetReplacement(modToReplace.identifier, instance.VersionCriteria()); if (replacement != null) { // Replaceable @@ -131,25 +131,27 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) } catch (ModuleNotFoundKraken kraken) { - User.RaiseMessage("Module {0} not found", kraken.module); + User.RaiseMessage(Properties.Resources.ReplaceModuleNotFound, kraken.module); } } } if (to_replace.Count() != 0) { - User.RaiseMessage("\r\nReplacing modules...\r\n"); + User.RaiseMessage(""); + User.RaiseMessage(Properties.Resources.Replacing); + User.RaiseMessage(""); foreach (ModuleReplacement r in to_replace) { - User.RaiseMessage("Replacement {0} {1} found for {2} {3}", + User.RaiseMessage(Properties.Resources.ReplaceFound, r.ReplaceWith.identifier, r.ReplaceWith.version, r.ToReplace.identifier, r.ToReplace.version); } - bool ok = User.RaiseYesNoDialog("Continue?"); + bool ok = User.RaiseYesNoDialog(Properties.Resources.ReplaceContinuePrompt); if (!ok) { - User.RaiseMessage("Replacements canceled at user request."); + User.RaiseMessage(Properties.Resources.ReplaceCancelled); return Exit.ERROR; } @@ -157,17 +159,18 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) try { HashSet<string> possibleConfigOnlyDirs = null; - new ModuleInstaller(ksp, manager.Cache, User).Replace(to_replace, replace_ops, new NetAsyncModulesDownloader(User, manager.Cache), ref possibleConfigOnlyDirs, regMgr); + new ModuleInstaller(instance, manager.Cache, User).Replace(to_replace, replace_ops, new NetAsyncModulesDownloader(User, manager.Cache), ref possibleConfigOnlyDirs, regMgr); User.RaiseMessage(""); } catch (DependencyNotSatisfiedKraken ex) { - User.RaiseMessage("Dependencies not satisfied for replacement, {0} requires {1} {2} but it is not listed in the index, or not available for your version of KSP.", ex.parent, ex.module, ex.version); + User.RaiseMessage(Properties.Resources.ReplaceDependencyNotSatisfied, + ex.parent, ex.module, ex.version, instance.game.ShortName); } } else { - User.RaiseMessage("No replacements found."); + User.RaiseMessage(Properties.Resources.ReplaceNotFound); return Exit.OK; } diff --git a/Cmdline/Action/Repo.cs b/Cmdline/Action/Repo.cs index dbabc7c865..d357e6bed9 100644 --- a/Cmdline/Action/Repo.cs +++ b/Cmdline/Action/Repo.cs @@ -34,8 +34,8 @@ public string GetUsage(string verb) ht.AddPreOptionsLine(" "); if (string.IsNullOrEmpty(verb)) { - ht.AddPreOptionsLine("ckan repo - Manage CKAN repositories"); - ht.AddPreOptionsLine($"Usage: ckan repo <command> [options]"); + ht.AddPreOptionsLine($"ckan repo - {Properties.Resources.RepoHelpSummary}"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan repo <{Properties.Resources.Command}> [{Properties.Resources.Options}]"); } else { @@ -44,21 +44,21 @@ public string GetUsage(string verb) { // First the commands with two arguments case "add": - ht.AddPreOptionsLine($"Usage: ckan repo {verb} [options] name url"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan repo {verb} [{Properties.Resources.Options}] name url"); break; // Then the commands with one argument case "remove": case "forget": case "default": - ht.AddPreOptionsLine($"Usage: ckan repo {verb} [options] name"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan repo {verb} [{Properties.Resources.Options}] name"); break; // Now the commands with only --flag type options case "available": case "list": default: - ht.AddPreOptionsLine($"Usage: ckan repo {verb} [options]"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan repo {verb} [{Properties.Resources.Options}]"); break; } } @@ -148,7 +148,7 @@ public int RunSubCommand(GameInstanceManager manager, CommonOptions opts, SubCom break; default: - User.RaiseMessage("Unknown command: repo {0}", option); + User.RaiseMessage(Properties.Resources.RepoUnknownCommand, option); exitCode = Exit.BADOPT; break; } @@ -170,7 +170,7 @@ private RepositoryList FetchMasterRepositoryList(Uri master_uri = null) private int AvailableRepositories() { - User.RaiseMessage("Listing all (canonical) available CKAN repositories:"); + User.RaiseMessage(Properties.Resources.RepoAvailableHeader); RepositoryList repositories; try @@ -179,7 +179,7 @@ private int AvailableRepositories() } catch { - User.RaiseError("Couldn't fetch CKAN repositories master list from {0}", MainClass.GetGameInstance(Manager).game.RepositoryListURL.ToString()); + User.RaiseError(Properties.Resources.RepoAvailableFailed, MainClass.GetGameInstance(Manager).game.RepositoryListURL.ToString()); return Exit.ERROR; } @@ -200,7 +200,7 @@ private int AvailableRepositories() private int ListRepositories() { var manager = RegistryManager.Instance(MainClass.GetGameInstance(Manager)); - User.RaiseMessage("Listing all known repositories:"); + User.RaiseMessage(Properties.Resources.RepoListHeader); SortedDictionary<string, Repository> repositories = manager.registry.Repositories; int maxNameLen = 0; @@ -223,7 +223,7 @@ private int AddRepository(RepoAddOptions options) if (options.name == null) { - User.RaiseMessage("add <name> [ <uri> ] - argument missing, perhaps you forgot it?"); + User.RaiseMessage("add <name> [ <uri> ] - {0}", Properties.Resources.ArgumentMissing); return Exit.BADOPT; } @@ -237,7 +237,7 @@ private int AddRepository(RepoAddOptions options) } catch { - User.RaiseError("Couldn't fetch CKAN repositories master list from {0}", Manager.CurrentInstance.game.RepositoryListURL.ToString()); + User.RaiseError(Properties.Resources.RepoAvailableFailed, Manager.CurrentInstance.game.RepositoryListURL.ToString()); return Exit.ERROR; } @@ -253,7 +253,7 @@ private int AddRepository(RepoAddOptions options) // Nothing found in the master list? if (options.uri == null) { - User.RaiseMessage("Name {0} not found in master list, please provide name and uri.", options.name); + User.RaiseMessage(Properties.Resources.RepoAddNotFound, options.name); return Exit.BADOPT; } } @@ -263,13 +263,13 @@ private int AddRepository(RepoAddOptions options) if (repositories.ContainsKey(options.name)) { - User.RaiseMessage("Repository with name \"{0}\" already exists, aborting..", options.name); + User.RaiseMessage(Properties.Resources.RepoAddDuplicate, options.name); return Exit.BADOPT; } repositories.Add(options.name, new Repository(options.name, options.uri)); - User.RaiseMessage("Added repository '{0}' - '{1}'", options.name, options.uri); + User.RaiseMessage(Properties.Resources.RepoAdded, options.name, options.uri); manager.Save(); return Exit.OK; @@ -279,7 +279,7 @@ private int ForgetRepository(RepoForgetOptions options) { if (options.name == null) { - User.RaiseError("forget <name> - argument missing, perhaps you forgot it?"); + User.RaiseError("forget <name> - {0}", Properties.Resources.ArgumentMissing); return Exit.BADOPT; } @@ -295,14 +295,14 @@ private int ForgetRepository(RepoForgetOptions options) name = repos.Keys.FirstOrDefault(repo => repo.Equals(options.name, StringComparison.OrdinalIgnoreCase)); if (name == null) { - User.RaiseMessage("Couldn't find repository with name \"{0}\", aborting..", options.name); + User.RaiseMessage(Properties.Resources.RepoForgetNotFound, options.name); return Exit.BADOPT; } - User.RaiseMessage("Removing insensitive match \"{0}\"", name); + User.RaiseMessage(Properties.Resources.RepoForgetRemoving, name); } registry.Repositories.Remove(name); - User.RaiseMessage("Successfully removed \"{0}\"", options.name); + User.RaiseMessage(Properties.Resources.RepoForgetRemoved, options.name); manager.Save(); return Exit.OK; @@ -314,7 +314,7 @@ private int DefaultRepository(RepoDefaultOptions options) if (options.uri == null) { - User.RaiseMessage("default <uri> - argument missing, perhaps you forgot it?"); + User.RaiseMessage("default <uri> - {0}", Properties.Resources.ArgumentMissing); return Exit.BADOPT; } @@ -329,7 +329,7 @@ private int DefaultRepository(RepoDefaultOptions options) repositories.Add(Repository.default_ckan_repo_name, new Repository( Repository.default_ckan_repo_name, options.uri)); - User.RaiseMessage("Set {0} repository to '{1}'", Repository.default_ckan_repo_name, options.uri); + User.RaiseMessage(Properties.Resources.RepoSet, Repository.default_ckan_repo_name, options.uri); manager.Save(); return Exit.OK; diff --git a/Cmdline/Action/Search.cs b/Cmdline/Action/Search.cs index 5fc4d40c95..508481669c 100644 --- a/Cmdline/Action/Search.cs +++ b/Cmdline/Action/Search.cs @@ -22,8 +22,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) // Check the input. if (String.IsNullOrWhiteSpace(options.search_term) && String.IsNullOrWhiteSpace(options.author_term)) { - user.RaiseError("No search term?"); - + user.RaiseError(Properties.Resources.SearchNoTerm); return Exit.BADOPT; } @@ -37,7 +36,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) // Show how many matches we have. if (options.all && !String.IsNullOrWhiteSpace(options.author_term)) { - user.RaiseMessage("Found {0} compatible and {1} incompatible mods matching \"{2}\" by \"{3}\".", + user.RaiseMessage(Properties.Resources.SearchFoundByAuthorWithIncompat, matching_compatible.Count().ToString(), matching_incompatible.Count().ToString(), options.search_term, @@ -45,21 +44,21 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) } else if (options.all && String.IsNullOrWhiteSpace(options.author_term)) { - user.RaiseMessage("Found {0} compatible and {1} incompatible mods matching \"{2}\".", + user.RaiseMessage(Properties.Resources.SearchFoundWithIncompat, matching_compatible.Count().ToString(), matching_incompatible.Count().ToString(), options.search_term); } else if (!options.all && !String.IsNullOrWhiteSpace(options.author_term)) { - user.RaiseMessage("Found {0} compatible mods matching \"{1}\" by \"{2}\".", + user.RaiseMessage(Properties.Resources.SearchFoundByAuthor, matching_compatible.Count().ToString(), options.search_term, options.author_term); } else if (!options.all && String.IsNullOrWhiteSpace(options.author_term)) { - user.RaiseMessage("Found {0} compatible mods matching \"{1}\".", + user.RaiseMessage(Properties.Resources.SearchFound, matching_compatible.Count().ToString(), options.search_term); } @@ -72,10 +71,10 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) if (options.detail) { - user.RaiseMessage("Matching compatible mods:"); + user.RaiseMessage(Properties.Resources.SearchCompatibleModsHeader); foreach (CkanModule mod in matching_compatible) { - user.RaiseMessage("* {0} ({1}) - {2} by {3} - {4}", + user.RaiseMessage(Properties.Resources.SearchCompatibleMod, mod.identifier, mod.version, mod.name, @@ -85,13 +84,13 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) if (matching_incompatible.Any()) { - user.RaiseMessage("Matching incompatible mods:"); + user.RaiseMessage(Properties.Resources.SearchIncompatibleModsHeader); foreach (CkanModule mod in matching_incompatible) { Registry.GetMinMaxVersions(new List<CkanModule> { mod } , out _, out _, out var minKsp, out var maxKsp); string GameVersion = Versioning.GameVersionRange.VersionSpan(ksp.game, minKsp, maxKsp).ToString(); - user.RaiseMessage("* {0} ({1} - {2}) - {3} by {4} - {5}", + user.RaiseMessage(Properties.Resources.SearchIncompatibleMod, mod.identifier, mod.version, GameVersion, diff --git a/Cmdline/Action/Show.cs b/Cmdline/Action/Show.cs index 7bd6e4cce0..a4364cf5f5 100644 --- a/Cmdline/Action/Show.cs +++ b/Cmdline/Action/Show.cs @@ -14,19 +14,19 @@ public Show(IUser user) this.user = user; } - public int RunCommand(CKAN.GameInstance ksp, object raw_options) + public int RunCommand(CKAN.GameInstance instance, object raw_options) { ShowOptions options = (ShowOptions) raw_options; if (options.modules == null || options.modules.Count < 1) { // empty argument - user.RaiseMessage("show <module> - module name argument missing, perhaps you forgot it?"); + user.RaiseMessage("show <module> - {0}", Properties.Resources.ArgumentMissing); return Exit.BADOPT; } int combined_exit_code = Exit.OK; // Check installed modules for an exact match. - var registry = RegistryManager.Instance(ksp).registry; + var registry = RegistryManager.Instance(instance).registry; foreach (string modName in options.modules) { var installedModuleToShow = registry.InstalledModule(modName); @@ -39,7 +39,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) ); if (options.with_versions) { - ShowVersionTable(ksp, registry.AvailableByIdentifier(installedModuleToShow.identifier).ToList()); + ShowVersionTable(instance, registry.AvailableByIdentifier(installedModuleToShow.identifier).ToList()); } user.RaiseMessage(""); continue; @@ -48,7 +48,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) // Module was not installed, look for an exact match in the available modules, // either by "name" (the user-friendly display name) or by identifier CkanModule moduleToShow = registry - .CompatibleModules(ksp.VersionCriteria()) + .CompatibleModules(instance.VersionCriteria()) .SingleOrDefault( mod => mod.name == modName || mod.identifier == modName @@ -56,22 +56,20 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) if (moduleToShow == null) { // No exact match found. Try to look for a close match for this KSP version. - user.RaiseMessage( - "{0} not installed or compatible with {1} {2}.", + user.RaiseMessage(Properties.Resources.ShowNotInstalledOrCompatible, modName, - ksp.game.ShortName, - string.Join(", ", ksp.VersionCriteria().Versions.Select(v => v.ToString())) - ); - user.RaiseMessage("Looking for close matches in compatible mods..."); + instance.game.ShortName, + string.Join(", ", instance.VersionCriteria().Versions.Select(v => v.ToString()))); + user.RaiseMessage(Properties.Resources.ShowLookingForClose); Search search = new Search(user); - var matches = search.PerformSearch(ksp, modName); + var matches = search.PerformSearch(instance, modName); // Display the results of the search. if (!matches.Any()) { // No matches found. - user.RaiseMessage("No close matches found."); + user.RaiseMessage(Properties.Resources.ShowNoClose); combined_exit_code = CombineExitCodes(combined_exit_code, Exit.BADOPT); user.RaiseMessage(""); continue; @@ -79,7 +77,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) else if (matches.Count() == 1) { // If there is only 1 match, display it. - user.RaiseMessage("Found 1 close match: {0}", matches[0].name); + user.RaiseMessage(Properties.Resources.ShowFoundOne, matches[0].name); user.RaiseMessage(""); moduleToShow = matches[0]; @@ -88,9 +86,8 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) { // Display the found close matches. int selection = user.RaiseSelectionDialog( - "Close matches:", - matches.Select(m => m.name).ToArray() - ); + Properties.Resources.ShowClosePrompt, + matches.Select(m => m.name).ToArray()); user.RaiseMessage(""); if (selection < 0) { @@ -109,7 +106,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) ); if (options.with_versions) { - ShowVersionTable(ksp, registry.AvailableByIdentifier(moduleToShow.identifier).ToList()); + ShowVersionTable(instance, registry.AvailableByIdentifier(moduleToShow.identifier).ToList()); } user.RaiseMessage(""); } @@ -136,7 +133,7 @@ private int ShowMod(InstalledModule module, ShowOptions opts) } user.RaiseMessage(""); - user.RaiseMessage("Showing {0} installed files:", files.Count); + user.RaiseMessage(Properties.Resources.ShowFilesHeader, files.Count); foreach (string file in files) { user.RaiseMessage(" - {0}", file); @@ -177,33 +174,33 @@ private int ShowMod(CkanModule module, ShowOptions opts) { #region General info (author, version...) user.RaiseMessage(""); - user.RaiseMessage("Module info:"); - user.RaiseMessage(" Version:\t{0}", module.version); + user.RaiseMessage(Properties.Resources.ShowModuleInfoHeader); + user.RaiseMessage(Properties.Resources.ShowVersion, module.version); if (module.author != null) { - user.RaiseMessage(" Authors:\t{0}", string.Join(", ", module.author)); + user.RaiseMessage(Properties.Resources.ShowAuthor, string.Join(", ", module.author)); } else { // Did you know that authors are optional in the spec? // You do now. #673. - user.RaiseMessage(" Authors:\tUNKNOWN"); + user.RaiseMessage(Properties.Resources.ShowAuthorUnknown); } if (module.release_status != null) { - user.RaiseMessage(" Status:\t{0}", module.release_status); + user.RaiseMessage(Properties.Resources.ShowStatus, module.release_status); } - user.RaiseMessage(" License:\t{0}", string.Join(", ", module.license)); + user.RaiseMessage(Properties.Resources.ShowLicence, string.Join(", ", module.license)); if (module.Tags != null && module.Tags.Count > 0) { // Need an extra space before the tab to line up with other fields - user.RaiseMessage(" Tags: \t{0}", string.Join(", ", module.Tags)); + user.RaiseMessage(Properties.Resources.ShowTags, string.Join(", ", module.Tags)); } if (module.localizations != null && module.localizations.Length > 0) { - user.RaiseMessage(" Languages:\t{0}", string.Join(", ", module.localizations.OrderBy(l => l))); + user.RaiseMessage(Properties.Resources.ShowLanguages, string.Join(", ", module.localizations.OrderBy(l => l))); } #endregion } @@ -214,7 +211,7 @@ private int ShowMod(CkanModule module, ShowOptions opts) if (module.depends != null && module.depends.Count > 0) { user.RaiseMessage(""); - user.RaiseMessage("Depends:"); + user.RaiseMessage(Properties.Resources.ShowDependsHeader); foreach (RelationshipDescriptor dep in module.depends) { user.RaiseMessage(" - {0}", RelationshipToPrintableString(dep)); @@ -224,7 +221,7 @@ private int ShowMod(CkanModule module, ShowOptions opts) if (module.recommends != null && module.recommends.Count > 0) { user.RaiseMessage(""); - user.RaiseMessage("Recommends:"); + user.RaiseMessage(Properties.Resources.ShowRecommendsHeader); foreach (RelationshipDescriptor dep in module.recommends) { user.RaiseMessage(" - {0}", RelationshipToPrintableString(dep)); @@ -234,7 +231,7 @@ private int ShowMod(CkanModule module, ShowOptions opts) if (module.suggests != null && module.suggests.Count > 0) { user.RaiseMessage(""); - user.RaiseMessage("Suggests:"); + user.RaiseMessage(Properties.Resources.ShowSuggestsHeader); foreach (RelationshipDescriptor dep in module.suggests) { user.RaiseMessage(" - {0}", RelationshipToPrintableString(dep)); @@ -244,7 +241,7 @@ private int ShowMod(CkanModule module, ShowOptions opts) if (module.provides != null && module.provides.Count > 0) { user.RaiseMessage(""); - user.RaiseMessage("Provides:"); + user.RaiseMessage(Properties.Resources.ShowProvidesHeader); foreach (string prov in module.provides) { user.RaiseMessage(" - {0}", prov); @@ -256,42 +253,42 @@ private int ShowMod(CkanModule module, ShowOptions opts) if (!opts.without_resources && module.resources != null) { user.RaiseMessage(""); - user.RaiseMessage("Resources:"); + user.RaiseMessage(Properties.Resources.ShowResourcesHeader); if (module.resources.homepage != null) { - user.RaiseMessage(" Home page:\t{0}", Uri.EscapeUriString(module.resources.homepage.ToString())); + user.RaiseMessage(Properties.Resources.ShowHomePage, Uri.EscapeUriString(module.resources.homepage.ToString())); } if (module.resources.manual != null) { - user.RaiseMessage(" Manual:\t{0}", Uri.EscapeUriString(module.resources.manual.ToString())); + user.RaiseMessage(Properties.Resources.ShowManual, Uri.EscapeUriString(module.resources.manual.ToString())); } if (module.resources.spacedock != null) { - user.RaiseMessage(" SpaceDock:\t{0}", Uri.EscapeUriString(module.resources.spacedock.ToString())); + user.RaiseMessage(Properties.Resources.ShowSpaceDock, Uri.EscapeUriString(module.resources.spacedock.ToString())); } if (module.resources.repository != null) { - user.RaiseMessage(" Repository:\t{0}", Uri.EscapeUriString(module.resources.repository.ToString())); + user.RaiseMessage(Properties.Resources.ShowRepository, Uri.EscapeUriString(module.resources.repository.ToString())); } if (module.resources.bugtracker != null) { - user.RaiseMessage(" Bug tracker:\t{0}", Uri.EscapeUriString(module.resources.bugtracker.ToString())); + user.RaiseMessage(Properties.Resources.ShowBugTracker, Uri.EscapeUriString(module.resources.bugtracker.ToString())); } if (module.resources.curse != null) { - user.RaiseMessage(" Curse:\t{0}", Uri.EscapeUriString(module.resources.curse.ToString())); + user.RaiseMessage(Properties.Resources.ShowCurse, Uri.EscapeUriString(module.resources.curse.ToString())); } if (module.resources.store != null) { - user.RaiseMessage(" Store:\t{0}", Uri.EscapeUriString(module.resources.store.ToString())); + user.RaiseMessage(Properties.Resources.ShowStore, Uri.EscapeUriString(module.resources.store.ToString())); } if (module.resources.steamstore != null) { - user.RaiseMessage(" Steam store:\t{0}", Uri.EscapeUriString(module.resources.steamstore.ToString())); + user.RaiseMessage(Properties.Resources.ShowSteamStore, Uri.EscapeUriString(module.resources.steamstore.ToString())); } if (module.resources.remoteAvc != null) { - user.RaiseMessage(" Version file:\t{0}", Uri.EscapeUriString(module.resources.remoteAvc.ToString())); + user.RaiseMessage(Properties.Resources.ShowVersionFile, Uri.EscapeUriString(module.resources.remoteAvc.ToString())); } } @@ -302,7 +299,7 @@ private int ShowMod(CkanModule module, ShowOptions opts) string file_name = CkanModule.StandardName(module.identifier, module.version); user.RaiseMessage(""); - user.RaiseMessage("Filename: {0}", file_uri_hash + "-" + file_name); + user.RaiseMessage(Properties.Resources.ShowFileName, file_uri_hash + "-" + file_name); } return Exit.OK; @@ -323,7 +320,10 @@ private void ShowVersionTable(CKAN.GameInstance inst, List<CkanModule> modules) Registry.GetMinMaxVersions(new List<CkanModule>() { m }, out _, out _, out minKsp, out maxKsp); return GameVersionRange.VersionSpan(inst.game, minKsp, maxKsp); }).ToList(); - string[] headers = new string[] { "Version", "Game Versions" }; + string[] headers = new string[] { + Properties.Resources.ShowVersionHeader, + Properties.Resources.ShowGameVersionsHeader + }; int versionLength = Math.Max(headers[0].Length, versions.Max(v => v.Length)); int gameVersionLength = Math.Max(headers[1].Length, gameVersions.Max(v => v.Length)); user.RaiseMessage(""); diff --git a/Cmdline/Action/Update.cs b/Cmdline/Action/Update.cs index cbb8d5bd8b..7bb669663a 100644 --- a/Cmdline/Action/Update.cs +++ b/Cmdline/Action/Update.cs @@ -22,12 +22,12 @@ public Update(GameInstanceManager mgr, IUser user) /// <summary> /// Update the registry /// </summary> - /// <param name="ksp">Game instance to update</param> + /// <param name="instance">Game instance to update</param> /// <param name="raw_options">Command line options object</param> /// <returns> /// Exit code for shell environment /// </returns> - public int RunCommand(CKAN.GameInstance ksp, object raw_options) + public int RunCommand(CKAN.GameInstance instance, object raw_options) { UpdateOptions options = (UpdateOptions) raw_options; @@ -36,8 +36,8 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) if (options.list_changes) { // Get a list of compatible modules prior to the update. - var registry = RegistryManager.Instance(ksp).registry; - compatible_prior = registry.CompatibleModules(ksp.VersionCriteria()).ToList(); + var registry = RegistryManager.Instance(instance).registry; + compatible_prior = registry.CompatibleModules(instance.VersionCriteria()).ToList(); } // If no repository is selected, select all. @@ -50,16 +50,16 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) { if (options.update_all) { - UpdateRepository(ksp); + UpdateRepository(instance); } else { - UpdateRepository(ksp, options.repo); + UpdateRepository(instance, options.repo); } } catch (ReinstallModuleKraken rmk) { - Upgrade.UpgradeModules(manager, user, ksp, false, rmk.Modules); + Upgrade.UpgradeModules(manager, user, instance, false, rmk.Modules); } catch (MissingCertificateKraken kraken) { @@ -70,8 +70,8 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) if (options.list_changes) { - var registry = RegistryManager.Instance(ksp).registry; - PrintChanges(compatible_prior, registry.CompatibleModules(ksp.VersionCriteria()).ToList()); + var registry = RegistryManager.Instance(instance).registry; + PrintChanges(compatible_prior, registry.CompatibleModules(instance.VersionCriteria()).ToList()); } return Exit.OK; @@ -92,25 +92,26 @@ private void PrintChanges(List<CkanModule> modules_prior, List<CkanModule> modul var removed = new HashSet<CkanModule>(prior.Except(post, new NameComparer())); - var unchanged = post.Intersect(prior);//Default compare includes versions + // Default compare includes versions + var unchanged = post.Intersect(prior); var updated = post.Except(unchanged).Except(added).Except(removed).ToList(); // Print the changes. - user.RaiseMessage("Found {0} new modules, {1} removed modules and {2} updated modules.", added.Count(), removed.Count(), updated.Count()); + user.RaiseMessage(Properties.Resources.UpdateChangesSummary, added.Count(), removed.Count(), updated.Count()); if (added.Count > 0) { - PrintModules("New modules [Name (CKAN identifier)]:", added); + PrintModules(Properties.Resources.UpdateAddedHeader, added); } if (removed.Count > 0) { - PrintModules("Removed modules [Name (CKAN identifier)]:", removed); + PrintModules(Properties.Resources.UpdateRemovedHeader, removed); } if (updated.Count > 0) { - PrintModules("Updated modules [Name (CKAN identifier)]:", updated); + PrintModules(Properties.Resources.UpdateUpdatedHeader, updated); } } @@ -145,17 +146,17 @@ private void PrintModules(string message, IEnumerable<CkanModule> modules) /// <summary> /// Updates the repository. /// </summary> - /// <param name="ksp">The KSP instance to work on.</param> + /// <param name="instance">The KSP instance to work on.</param> /// <param name="repository">Repository to update. If null all repositories are used.</param> - private void UpdateRepository(CKAN.GameInstance ksp, string repository = null) + private void UpdateRepository(CKAN.GameInstance instance, string repository = null) { - RegistryManager registry_manager = RegistryManager.Instance(ksp); + RegistryManager registry_manager = RegistryManager.Instance(instance); var updated = repository == null - ? CKAN.Repo.UpdateAllRepositories(registry_manager, ksp, manager.Cache, user) != CKAN.RepoUpdateResult.Failed - : CKAN.Repo.Update(registry_manager, ksp, user, repository); + ? CKAN.Repo.UpdateAllRepositories(registry_manager, instance, manager.Cache, user) != CKAN.RepoUpdateResult.Failed + : CKAN.Repo.Update(registry_manager, instance, user, repository); - user.RaiseMessage("Updated information on {0} compatible modules", registry_manager.registry.CompatibleModules(ksp.VersionCriteria()).Count()); + user.RaiseMessage(Properties.Resources.UpdateSummary, registry_manager.registry.CompatibleModules(instance.VersionCriteria()).Count()); } } } diff --git a/Cmdline/Action/Upgrade.cs b/Cmdline/Action/Upgrade.cs index 246a65ecd0..e359c5689e 100644 --- a/Cmdline/Action/Upgrade.cs +++ b/Cmdline/Action/Upgrade.cs @@ -21,31 +21,31 @@ public class Upgrade : ICommand /// <param name="user">IUser object for interaction</param> public Upgrade(GameInstanceManager mgr, IUser user) { - manager = mgr; - User = user; + manager = mgr; + User = user; } /// <summary> /// Upgrade an installed module /// </summary> - /// <param name="ksp">Game instance from which to remove</param> + /// <param name="instance">Game instance from which to remove</param> /// <param name="raw_options">Command line options object</param> /// <returns> /// Exit code for shell environment /// </returns> - public int RunCommand(CKAN.GameInstance ksp, object raw_options) + public int RunCommand(CKAN.GameInstance instance, object raw_options) { UpgradeOptions options = (UpgradeOptions) raw_options; if (options.ckan_file != null) { - options.modules.Add(MainClass.LoadCkanFromFile(ksp, options.ckan_file).identifier); + options.modules.Add(MainClass.LoadCkanFromFile(instance, options.ckan_file).identifier); } if (options.modules.Count == 0 && !options.upgrade_all) { // What? No files specified? - User.RaiseMessage("Usage: ckan upgrade Mod [Mod2, ...]"); + User.RaiseMessage("{0}: ckan upgrade Mod [Mod2, ...]", Properties.Resources.Usage); User.RaiseMessage(" or ckan upgrade --all"); if (AutoUpdate.CanUpdate) { @@ -56,27 +56,28 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) if (!options.upgrade_all && options.modules[0] == "ckan" && AutoUpdate.CanUpdate) { - User.RaiseMessage("Querying the latest CKAN version"); + User.RaiseMessage(Properties.Resources.UpgradeQueryingCKAN); AutoUpdate.Instance.FetchLatestReleaseInfo(); var latestVersion = AutoUpdate.Instance.latestUpdate.Version; var currentVersion = new ModuleVersion(Meta.GetVersion(VersionFormat.Short)); if (latestVersion.IsGreaterThan(currentVersion)) { - User.RaiseMessage("New CKAN version available - " + latestVersion); + User.RaiseMessage(Properties.Resources.UpgradeNewCKANAvailable, latestVersion); var releaseNotes = AutoUpdate.Instance.latestUpdate.ReleaseNotes; User.RaiseMessage(releaseNotes); - User.RaiseMessage("\r\n"); + User.RaiseMessage(""); + User.RaiseMessage(""); - if (User.RaiseYesNoDialog("Proceed with install?")) + if (User.RaiseYesNoDialog(Properties.Resources.UpgradeProceed)) { - User.RaiseMessage("Upgrading CKAN, please wait.."); + User.RaiseMessage(Properties.Resources.UpgradePleaseWait); AutoUpdate.Instance.StartUpdateProcess(false); } } else { - User.RaiseMessage("You already have the latest version."); + User.RaiseMessage(Properties.Resources.UpgradeAlreadyHaveLatest); } return Exit.OK; @@ -84,7 +85,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) try { - var regMgr = RegistryManager.Instance(ksp); + var regMgr = RegistryManager.Instance(instance); var registry = regMgr.registry; if (options.upgrade_all) { @@ -95,7 +96,7 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) try { // Check if upgrades are available - var latest = registry.LatestAvailable(mod.Key, ksp.VersionCriteria()); + var latest = registry.LatestAvailable(mod.Key, instance.VersionCriteria()); // This may be an unindexed mod. If so, // skip rather than crash. See KSP-CKAN/CKAN#841. @@ -119,23 +120,23 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) mod.Key); } } - UpgradeModules(manager, User, ksp, true, to_upgrade); + UpgradeModules(manager, User, instance, true, to_upgrade); } else { - Search.AdjustModulesCase(ksp, options.modules); - UpgradeModules(manager, User, ksp, options.modules); + Search.AdjustModulesCase(instance, options.modules); + UpgradeModules(manager, User, instance, options.modules); } User.RaiseMessage(""); } catch (CancelledActionKraken k) { - User.RaiseMessage("Upgrade aborted: {0}", k.Message); + User.RaiseMessage(Properties.Resources.UpgradeAborted, k.Message); return Exit.ERROR; } catch (ModuleNotFoundKraken kraken) { - User.RaiseMessage("Module {0} not found", kraken.module); + User.RaiseMessage(Properties.Resources.UpgradeNotFound, kraken.module); return Exit.ERROR; } catch (InconsistentKraken kraken) @@ -145,14 +146,14 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) } catch (ModuleIsDLCKraken kraken) { - User.RaiseMessage($"CKAN can't upgrade expansion '{kraken.module.name}' for you."); + User.RaiseMessage(Properties.Resources.UpgradeDLC, kraken.module.name); var res = kraken?.module?.resources; var storePagesMsg = new Uri[] { res?.store, res?.steamstore } .Where(u => u != null) .Aggregate("", (a, b) => $"{a}\r\n- {b}"); if (!string.IsNullOrEmpty(storePagesMsg)) { - User.RaiseMessage($"To upgrade this expansion, download any updates from the store page from which you purchased it:\r\n{storePagesMsg}"); + User.RaiseMessage(Properties.Resources.UpgradeDLCStorePage, storePagesMsg); } return Exit.ERROR; } @@ -165,11 +166,11 @@ public int RunCommand(CKAN.GameInstance ksp, object raw_options) /// </summary> /// <param name="manager">Game instance manager to use</param> /// <param name="user">IUser object for output</param> - /// <param name="ksp">Game instance to use</param> + /// <param name="instance">Game instance to use</param> /// <param name="modules">List of modules to upgrade</param> - public static void UpgradeModules(GameInstanceManager manager, IUser user, CKAN.GameInstance ksp, bool ConfirmPrompt, List<CkanModule> modules) + public static void UpgradeModules(GameInstanceManager manager, IUser user, CKAN.GameInstance instance, bool ConfirmPrompt, List<CkanModule> modules) { - UpgradeModules(manager, user, ksp, + UpgradeModules(manager, user, instance, (ModuleInstaller installer, NetAsyncModulesDownloader downloader, RegistryManager regMgr, ref HashSet<string> possibleConfigOnlyDirs) => installer.Upgrade(modules, downloader, ref possibleConfigOnlyDirs, regMgr, true, true, ConfirmPrompt), @@ -182,11 +183,11 @@ public static void UpgradeModules(GameInstanceManager manager, IUser user, CKAN. /// </summary> /// <param name="manager">Game instance manager to use</param> /// <param name="user">IUser object for output</param> - /// <param name="ksp">Game instance to use</param> + /// <param name="instance">Game instance to use</param> /// <param name="identsAndVersions">List of identifier[=version] to upgrade</param> - public static void UpgradeModules(GameInstanceManager manager, IUser user, CKAN.GameInstance ksp, List<string> identsAndVersions) + public static void UpgradeModules(GameInstanceManager manager, IUser user, CKAN.GameInstance instance, List<string> identsAndVersions) { - UpgradeModules(manager, user, ksp, + UpgradeModules(manager, user, instance, (ModuleInstaller installer, NetAsyncModulesDownloader downloader, RegistryManager regMgr, ref HashSet<string> possibleConfigOnlyDirs) => installer.Upgrade(identsAndVersions, downloader, ref possibleConfigOnlyDirs, regMgr, true), @@ -205,18 +206,18 @@ public static void UpgradeModules(GameInstanceManager manager, IUser user, CKAN. /// </summary> /// <param name="manager">Game instance manager to use</param> /// <param name="user">IUser object for output</param> - /// <param name="ksp">Game instance to use</param> + /// <param name="instance">Game instance to use</param> /// <param name="attemptUpgradeCallback">Function to call to try to perform the actual upgrade, may throw TooManyModsProvideKraken</param> /// <param name="addUserChoiceCallback">Function to call when the user has requested a new module added to the change set in response to TooManyModsProvideKraken</param> private static void UpgradeModules( - GameInstanceManager manager, IUser user, CKAN.GameInstance ksp, + GameInstanceManager manager, IUser user, CKAN.GameInstance instance, AttemptUpgradeAction attemptUpgradeCallback, System.Action<CkanModule> addUserChoiceCallback) { using (TransactionScope transact = CkanTransaction.CreateTransactionScope()) { - var installer = new ModuleInstaller(ksp, manager.Cache, user); + var installer = new ModuleInstaller(instance, manager.Cache, user); var downloader = new NetAsyncModulesDownloader(user, manager.Cache); - var regMgr = RegistryManager.Instance(ksp); + var regMgr = RegistryManager.Instance(instance); HashSet<string> possibleConfigOnlyDirs = null; bool done = false; while (!done) diff --git a/Cmdline/CKAN-cmdline.csproj b/Cmdline/CKAN-cmdline.csproj index daf863e5e8..ecab63f86f 100644 --- a/Cmdline/CKAN-cmdline.csproj +++ b/Cmdline/CKAN-cmdline.csproj @@ -1,40 +1,27 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project> <PropertyGroup> - <AssemblyName>CmdLine</AssemblyName> + <AssemblyName>CKAN-CmdLine</AssemblyName> <OutputPath>..\_build\out\$(AssemblyName)\$(Configuration)\bin\</OutputPath> <BaseIntermediateOutputPath>..\_build\out\$(AssemblyName)\$(Configuration)\obj\</BaseIntermediateOutputPath> </PropertyGroup> - <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" /> <PropertyGroup> - <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <ProjectGuid>{E97D81F6-85E2-4F1F-906D-BE21766602E5}</ProjectGuid> <OutputType>Exe</OutputType> <RootNamespace>CKAN.CmdLine</RootNamespace> + <GenerateAssemblyInfo>false</GenerateAssemblyInfo> + <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> + <Deterministic>true</Deterministic> + <Configurations>Debug;Release</Configurations> + <Prefer32Bit>false</Prefer32Bit> + <LangVersion>7</LangVersion> + <TargetFramework>net45</TargetFramework> <StartupObject>CKAN.CmdLine.MainClass</StartupObject> <ApplicationIcon>..\assets\ckan.ico</ApplicationIcon> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <FileAlignment>512</FileAlignment> - <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> - <Deterministic>true</Deterministic> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> - <Prefer32Bit>false</Prefer32Bit> - <LangVersion>7</LangVersion> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> - <DebugSymbols>true</DebugSymbols> - <DebugType>full</DebugType> - <Optimize>false</Optimize> - <DefineConstants>DEBUG;TRACE</DefineConstants> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> - <DebugType>pdbonly</DebugType> - <Optimize>true</Optimize> - <DefineConstants>TRACE</DefineConstants> </PropertyGroup> <ItemGroup> <PackageReference Include="Autofac" Version="4.9.4" /> @@ -54,34 +41,6 @@ <Compile Include="..\GlobalAssemblyInfo.cs"> <Link>Properties\GlobalAssemblyInfo.cs</Link> </Compile> - <Compile Include="Action\AuthToken.cs" /> - <Compile Include="Action\Available.cs" /> - <Compile Include="Action\Cache.cs" /> - <Compile Include="Action\Compare.cs" /> - <Compile Include="Action\Compat.cs" /> - <Compile Include="Action\Filter.cs" /> - <Compile Include="Action\ICommand.cs" /> - <Compile Include="Action\Import.cs" /> - <Compile Include="Action\Install.cs" /> - <Compile Include="Action\ISubCommand.cs" /> - <Compile Include="Action\GameInstance.cs" /> - <Compile Include="Action\List.cs" /> - <Compile Include="Action\Mark.cs" /> - <Compile Include="Action\Prompt.cs" /> - <Compile Include="Action\Remove.cs" /> - <Compile Include="Action\Repair.cs" /> - <Compile Include="Action\Replace.cs" /> - <Compile Include="Action\Repo.cs" /> - <Compile Include="Action\Search.cs" /> - <Compile Include="Action\Show.cs" /> - <Compile Include="Action\Update.cs" /> - <Compile Include="Action\Upgrade.cs" /> - <Compile Include="ConsoleUser.cs" /> - <Compile Include="Exit.cs" /> - <Compile Include="Main.cs" /> - <Compile Include="Options.cs" /> - <Compile Include="ProgressReporter.cs" /> - <Compile Include="Properties\AssemblyInfo.cs" /> </ItemGroup> <ItemGroup> <None Include="app.config" /> @@ -101,11 +60,12 @@ </ProjectReference> </ItemGroup> <ItemGroup> + <None Include="app.config" /> <Content Include="log4net.xml"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup> - <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" /> <Target Name="BeforeBuild"> <Exec Command="powershell ../build.ps1 Generate-GlobalAssemblyVersionInfo" Condition="!Exists('../_build/meta/GlobalAssemblyVersionInfo.cs') And '$(OS)' == 'Windows_NT'" /> <Exec Command="sh ../build Generate-GlobalAssemblyVersionInfo" Condition="!Exists('../_build/meta/GlobalAssemblyVersionInfo.cs') And '$(OS)' == 'Unix'" /> diff --git a/Cmdline/ConsoleUser.cs b/Cmdline/ConsoleUser.cs index 4e596a5a9f..a4e7f249fd 100644 --- a/Cmdline/ConsoleUser.cs +++ b/Cmdline/ConsoleUser.cs @@ -20,7 +20,7 @@ public class ConsoleUser : IUser /// Initializes a new instance of the <see cref="T:CKAN.CmdLine.ConsoleUser"/> class. /// </summary> /// <param name="headless">If set to <c>true</c>, supress interactive dialogs like Yes/No-Dialog or SelectionDialog</param> - public ConsoleUser (bool headless) + public ConsoleUser(bool headless) { Headless = headless; } @@ -42,7 +42,7 @@ public bool RaiseYesNoDialog(string question) return true; } - Console.Write("\r\n{0} [Y/n] ", question); + Console.Write("\r\n{0} {1} ", question, Properties.Resources.UserYesNoPromptSuffix); while (true) { var input = Console.In.ReadLine(); @@ -55,11 +55,11 @@ public bool RaiseYesNoDialog(string question) input = input.ToLower().Trim(); - if (input.Equals("y") || input.Equals("yes")) + if (input.Equals(Properties.Resources.UserYesNoY) || input.Equals(Properties.Resources.UserYesNoYes)) { return true; } - if (input.Equals("n") || input.Equals("no")) + if (input.Equals(Properties.Resources.UserYesNoN) || input.Equals(Properties.Resources.UserYesNoNo)) { return false; } @@ -69,7 +69,7 @@ public bool RaiseYesNoDialog(string question) return true; } - Console.Write("Invalid input. Please enter yes or no"); + Console.Write(Properties.Resources.UserYesNoInvalid); } } @@ -154,23 +154,16 @@ public int RaiseSelectionDialog(string message, params object[] args) RaiseMessage(CurrentRow); } - // Create message string. - string output = String.Format("Enter a number between {0} and {1} (To cancel press \"c\" or \"n\".", 1, args.Length); - - if (defaultSelection >= 0) - { - output += String.Format(" \"Enter\" will select {0}.", defaultSelection + 1); - } - - output += "): "; - - RaiseMessage(output); - bool valid = false; int result = 0; while (!valid) { + // Print message string + RaiseMessage(defaultSelection >= 0 + ? string.Format(Properties.Resources.UserSelectionPromptWithDefault, 1, args.Length, defaultSelection + 1) + : string.Format(Properties.Resources.UserSelectionPromptWithoutDefault,1, args.Length)); + // Wait for input from the command line. string input = Console.In.ReadLine(); @@ -183,57 +176,47 @@ public int RaiseSelectionDialog(string message, params object[] args) input = input.Trim().ToLower(); // Check for default selection. - if (String.IsNullOrEmpty(input)) + if (String.IsNullOrEmpty(input) && defaultSelection >= 0) { - if (defaultSelection >= 0) - { - return defaultSelection; - } + return defaultSelection; } // Check for cancellation characters. - if (input == "c" || input == "n") + if (input == Properties.Resources.UserSelectionC || input == Properties.Resources.UserSelectionN) { - RaiseMessage("Selection cancelled."); - + RaiseMessage(Properties.Resources.UserSelectionCancelled); return return_cancel; } // Attempt to parse the input. try { - result = Convert.ToInt32(input); + // The list we provide is index 1 based, but the array is index 0 based. + result = Convert.ToInt32(input) - 1; } catch (FormatException) { - RaiseMessage("The input is not a number."); + RaiseMessage(Properties.Resources.UserSelectionNotNumber); continue; } catch (OverflowException) { - RaiseMessage("The number in the input is too large."); + RaiseMessage(Properties.Resources.UserSelectionTooLarge); continue; } // Check the input against the boundaries. - if (result > args.Length) + if (result > args.Length - 1) { - RaiseMessage("The number in the input is too large."); - RaiseMessage(output); - + RaiseMessage(Properties.Resources.UserSelectionTooLarge); continue; } - else if (result < 1) + else if (result < 0) { - RaiseMessage("The number in the input is too small."); - RaiseMessage(output); - + RaiseMessage(Properties.Resources.UserSelectionTooSmall); continue; } - // The list we provide is index 1 based, but the array is index 0 based. - result--; - // We have checked for all errors and have gotten a valid result. Stop the input loop. valid = true; } @@ -279,8 +262,7 @@ public void RaiseProgress(string message, int percent) if (!Headless || percent != previousPercent) { // The \r at the front here causes download messages to *overwrite* each other. - Console.Write( - "\r{0} - {1}% ", message, percent); + Console.Write("\r{0} - {1}% ", message, percent); previousPercent = percent; } } diff --git a/Cmdline/Main.cs b/Cmdline/Main.cs index 6b27f97972..69374010b8 100644 --- a/Cmdline/Main.cs +++ b/Cmdline/Main.cs @@ -152,7 +152,8 @@ public static int Execute(GameInstanceManager manager, CommonOptions opts, strin public static int AfterHelp() { // Our help screen will already be shown. Let's add some extra data. - new ConsoleUser(false).RaiseMessage("You are using CKAN version {0}", Meta.GetVersion(VersionFormat.Full)); + new ConsoleUser(false).RaiseMessage( + Properties.Resources.MainVersion, Meta.GetVersion(VersionFormat.Full)); return Exit.BADOPT; } @@ -234,7 +235,7 @@ private static int RunSimpleAction(Options cmdline, CommonOptions options, strin return (new Compare(user)).RunCommand(cmdline.options); default: - user.RaiseMessage("Unknown command, try --help"); + user.RaiseMessage(Properties.Resources.MainUnknownCommand); return Exit.BADOPT; } } @@ -266,8 +267,7 @@ internal static CkanModule LoadCkanFromFile(CKAN.GameInstance current_instance, private static int printMissingInstanceError(IUser user) { - user.RaiseMessage("I don't know where a game instance is installed."); - user.RaiseMessage("Use 'ckan instance help' for assistance in setting this."); + user.RaiseMessage(Properties.Resources.MainMissingInstance); return Exit.ERROR; } @@ -276,7 +276,7 @@ private static int Gui(GameInstanceManager manager, GuiOptions options, string[] // TODO: Sometimes when the GUI exits, we get a System.ArgumentException, // but trying to catch it here doesn't seem to help. Dunno why. - GUI.Main_(args, manager, options.ShowConsole); + GUI.GUI.Main_(args, manager, options.ShowConsole); return Exit.OK; } @@ -317,13 +317,11 @@ private static int Scan(CKAN.GameInstance inst, IUser user, string next_command if (next_command == null) { user.RaiseError(kraken.InconsistenciesPretty); - user.RaiseError("The repo has not been saved."); + user.RaiseError(Properties.Resources.ScanNotSaved); } else { - user.RaiseMessage("Preliminary scanning shows that the install is in a inconsistent state."); - user.RaiseMessage("Use ckan.exe scan for more details"); - user.RaiseMessage("Proceeding with {0} in case it fixes it.\r\n", next_command); + user.RaiseMessage(Properties.Resources.ScanPreliminaryInconsistent, next_command); } return Exit.ERROR; diff --git a/Cmdline/Options.cs b/Cmdline/Options.cs index bc9edccfef..8e95bb1d2e 100644 --- a/Cmdline/Options.cs +++ b/Cmdline/Options.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Linq; using System.Reflection; using System.Collections.Generic; using System.Text.RegularExpressions; @@ -124,40 +125,49 @@ public string GetUsage(string verb) HelpText ht = HelpText.AutoBuild(this, verb); // Add a usage prefix line - ht.AddPreOptionsLine(" "); if (string.IsNullOrEmpty(verb)) { - ht.AddPreOptionsLine($"Usage: ckan <command> [options]"); + ht.AddPreOptionsLine(" "); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan <{Properties.Resources.Command}> [{Properties.Resources.Options}]"); } else { - ht.AddPreOptionsLine(verb + " - " + GetDescription(verb)); + string descr = GetDescription(verb); + if (!string.IsNullOrEmpty(descr)) + { + ht.AddPreOptionsLine(" "); + ht.AddPreOptionsLine($"ckan {verb} - {descr}"); + } switch (verb) { - // First the commands that deal with mods + // Commands that don't need a header + case "help": + break; + + // Commands that deal with mods case "add": case "install": case "remove": case "uninstall": case "upgrade": - ht.AddPreOptionsLine($"Usage: ckan {verb} [options] modules"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan {verb} [{Properties.Resources.Options}] modules"); break; case "show": - ht.AddPreOptionsLine($"Usage: ckan {verb} [options] module"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan {verb} [{Properties.Resources.Options}] module"); break; - // Now the commands with other string arguments + // Commands with other string arguments case "search": - ht.AddPreOptionsLine($"Usage: ckan {verb} [options] substring"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan {verb} [{Properties.Resources.Options}] substring"); break; case "compare": - ht.AddPreOptionsLine($"Usage: ckan {verb} [options] version1 version2"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan {verb} [{Properties.Resources.Options}] version1 version2"); break; case "import": - ht.AddPreOptionsLine($"Usage: ckan {verb} [options] paths"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan {verb} [{Properties.Resources.Options}] paths"); break; - // Now the commands with only --flag type options + // Commands with only --flag type options case "gui": case "available": case "list": @@ -166,7 +176,7 @@ public string GetUsage(string verb) case "clean": case "version": default: - ht.AddPreOptionsLine($"Usage: ckan {verb} [options]"); + ht.AddPreOptionsLine($"{Properties.Resources.Usage}: ckan {verb} [{Properties.Resources.Options}]"); break; } } @@ -179,15 +189,11 @@ public abstract class VerbCommandOptions { protected string GetDescription(string verb) { - var info = this.GetType().GetProperties(); - foreach (var property in info) - { - BaseOptionAttribute attrib = (BaseOptionAttribute)Attribute.GetCustomAttribute( - property, typeof(BaseOptionAttribute), false); - if (attrib != null && attrib.LongName == verb) - return attrib.HelpText; - } - return ""; + return GetType().GetProperties() + .Select(property => (BaseOptionAttribute)Attribute.GetCustomAttribute( + property, typeof(BaseOptionAttribute), false)) + .FirstOrDefault(attrib => attrib?.LongName == verb) + ?.HelpText; } } @@ -230,12 +236,12 @@ public virtual int Handle(GameInstanceManager manager, IUser user) { if (!AsRoot) { - user.RaiseError("You are trying to run CKAN as root.\r\nThis is a bad idea and there is absolutely no good reason to do it. Please run CKAN from a user account (or use --asroot if you are feeling brave)."); + user.RaiseError(Properties.Resources.OptionsRootError); return Exit.ERROR; } else { - user.RaiseMessage("Warning: Running CKAN as root!"); + user.RaiseMessage(Properties.Resources.OptionsRootWarning); } } @@ -298,12 +304,9 @@ private static void CheckMonoVersion(IUser user, int rec_major, int rec_minor, i if (major < rec_major || (major == rec_major && minor < rec_minor)) { - user.RaiseMessage( - "Warning. Detected mono runtime of {0} is less than the recommended version of {1}\r\n", + user.RaiseMessage(Properties.Resources.OptionsMonoWarning, String.Join(".", major, minor, patch), - String.Join(".", rec_major, rec_minor, rec_patch) - ); - user.RaiseMessage("Update recommend\r\n"); + String.Join(".", rec_major, rec_minor, rec_patch)); } } } @@ -333,7 +336,7 @@ public override int Handle(GameInstanceManager manager, IUser user) // User provided game instance if (Gamedir != null && Instance != null) { - user.RaiseMessage("--instance and --gamedir can't be specified at the same time"); + user.RaiseMessage(Properties.Resources.OptionsInstanceAndGameDir); return Exit.BADOPT; } @@ -352,12 +355,12 @@ public override int Handle(GameInstanceManager manager, IUser user) } catch (NotKSPDirKraken k) { - user.RaiseMessage("Sorry, {0} does not appear to be a game instance", k.path); + user.RaiseMessage(Properties.Resources.InstanceNotInstance, k.path); return Exit.BADOPT; } catch (InvalidKSPInstanceKraken k) { - user.RaiseMessage("Invalid game instance specified \"{0}\", use '--gamedir' to specify by path, or 'instance list' to see known game instances", k.instance); + user.RaiseMessage(Properties.Resources.OptionsInvalidInstance, k.instance); return Exit.BADOPT; } } @@ -387,7 +390,7 @@ public SubCommandOptions(string[] args) internal class InstallOptions : InstanceSpecificOptions { - [OptionArray('c', "ckanfiles", HelpText = "Local CKAN files to process")] + [OptionArray('c', "ckanfiles", HelpText = "Local CKAN files or URLs to process")] public string[] ckan_files { get; set; } [Option("no-recommends", DefaultValue = false, HelpText = "Do not install recommended modules")] diff --git a/Cmdline/ProgressReporter.cs b/Cmdline/ProgressReporter.cs index 655eddff18..02989d0cfe 100644 --- a/Cmdline/ProgressReporter.cs +++ b/Cmdline/ProgressReporter.cs @@ -16,10 +16,8 @@ public static void FormattedDownloads(string message, int progress, IUser user) { if (Regex.IsMatch(message, "download", RegexOptions.IgnoreCase)) { - user.RaiseMessage( - // The \r at the front here causes download messages to *overwrite* each other. - String.Format("\r{0} - {1}% ", message, progress) - ); + // The \r at the front causes download messages to *overwrite* each other. + user.RaiseMessage("\r{0} - {1}% ", message, progress); } else { @@ -31,4 +29,3 @@ public static void FormattedDownloads(string message, int progress, IUser user) } } } - diff --git a/Cmdline/Properties/AssemblyInfo.cs b/Cmdline/Properties/AssemblyInfo.cs index 3e3faac6af..f4caa4ba48 100644 --- a/Cmdline/Properties/AssemblyInfo.cs +++ b/Cmdline/Properties/AssemblyInfo.cs @@ -1,4 +1,10 @@ +using System.Resources; using System.Reflection; +using System.Runtime.CompilerServices; -[assembly: AssemblyTitle("CKAN")] // TODO: Does not match assembly name +[assembly: AssemblyTitle("CKAN-CmdLine")] [assembly: AssemblyDescription("CKAN CLI Client")] +[assembly: NeutralResourcesLanguage("en-GB")] + +[assembly: InternalsVisibleTo("Tests")] +[assembly: InternalsVisibleTo("CKAN.Tests")] diff --git a/Cmdline/Properties/Resources.Designer.cs b/Cmdline/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..269c9a939d --- /dev/null +++ b/Cmdline/Properties/Resources.Designer.cs @@ -0,0 +1,688 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. (I WISH!) +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace CKAN.CmdLine.Properties { + using System; + + + /// <summary> + /// A strongly-typed resource class, for looking up localized strings, etc. + /// </summary> + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { } + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) + { + resourceMan = new SingleAssemblyResourceManager("CKAN.CmdLine.Properties.Resources", typeof(Resources).Assembly); + } + return resourceMan; + } + } + + /// <summary> + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + internal static string Usage { + get { return (string)(ResourceManager.GetObject("Usage", resourceCulture)); } + } + internal static string Command { + get { return (string)(ResourceManager.GetObject("Command", resourceCulture)); } + } + internal static string UnknownCommand { + get { return (string)(ResourceManager.GetObject("UnknownCommand", resourceCulture)); } + } + internal static string Options { + get { return (string)(ResourceManager.GetObject("Options", resourceCulture)); } + } + internal static string ArgumentMissing { + get { return (string)(ResourceManager.GetObject("ArgumentMissing", resourceCulture)); } + } + internal static string Path { + get { return (string)(ResourceManager.GetObject("Path", resourceCulture)); } + } + + internal static string MainVersion { + get { return (string)(ResourceManager.GetObject("MainVersion", resourceCulture)); } + } + internal static string MainUnknownCommand { + get { return (string)(ResourceManager.GetObject("MainUnknownCommand", resourceCulture)); } + } + internal static string MainMissingInstance { + get { return (string)(ResourceManager.GetObject("MainMissingInstance", resourceCulture)); } + } + internal static string OptionsRootError { + get { return (string)(ResourceManager.GetObject("OptionsRootError", resourceCulture)); } + } + internal static string OptionsRootWarning { + get { return (string)(ResourceManager.GetObject("OptionsRootWarning", resourceCulture)); } + } + internal static string OptionsMonoWarning { + get { return (string)(ResourceManager.GetObject("OptionsMonoWarning", resourceCulture)); } + } + internal static string OptionsInstanceAndGameDir { + get { return (string)(ResourceManager.GetObject("OptionsInstanceAndGameDir", resourceCulture)); } + } + internal static string OptionsInvalidInstance { + get { return (string)(ResourceManager.GetObject("OptionsInvalidInstance", resourceCulture)); } + } + internal static string InstanceNotInstance { + get { return (string)(ResourceManager.GetObject("InstanceNotInstance", resourceCulture)); } + } + internal static string InstanceDuplicate { + get { return (string)(ResourceManager.GetObject("InstanceDuplicate", resourceCulture)); } + } + + internal static string UserYesNoPromptSuffix { + get { return (string)(ResourceManager.GetObject("UserYesNoPromptSuffix", resourceCulture)); } + } + internal static string UserYesNoY { + get { return (string)(ResourceManager.GetObject("UserYesNoY", resourceCulture)); } + } + internal static string UserYesNoYes { + get { return (string)(ResourceManager.GetObject("UserYesNoYes", resourceCulture)); } + } + internal static string UserYesNoN { + get { return (string)(ResourceManager.GetObject("UserYesNoN", resourceCulture)); } + } + internal static string UserYesNoNo { + get { return (string)(ResourceManager.GetObject("UserYesNoNo", resourceCulture)); } + } + internal static string UserYesNoInvalid { + get { return (string)(ResourceManager.GetObject("UserYesNoInvalid", resourceCulture)); } + } + internal static string UserSelectionPromptWithDefault { + get { return (string)(ResourceManager.GetObject("UserSelectionPromptWithDefault", resourceCulture)); } + } + internal static string UserSelectionPromptWithoutDefault { + get { return (string)(ResourceManager.GetObject("UserSelectionPromptWithoutDefault", resourceCulture)); } + } + internal static string UserSelectionC { + get { return (string)(ResourceManager.GetObject("UserSelectionC", resourceCulture)); } + } + internal static string UserSelectionN { + get { return (string)(ResourceManager.GetObject("UserSelectionN", resourceCulture)); } + } + internal static string UserSelectionCancelled { + get { return (string)(ResourceManager.GetObject("UserSelectionCancelled", resourceCulture)); } + } + internal static string UserSelectionNotNumber { + get { return (string)(ResourceManager.GetObject("UserSelectionNotNumber", resourceCulture)); } + } + internal static string UserSelectionTooLarge { + get { return (string)(ResourceManager.GetObject("UserSelectionTooLarge", resourceCulture)); } + } + internal static string UserSelectionTooSmall { + get { return (string)(ResourceManager.GetObject("UserSelectionTooSmall", resourceCulture)); } + } + + internal static string AuthTokenHostHeader { + get { return (string)(ResourceManager.GetObject("AuthTokenHostHeader", resourceCulture)); } + } + internal static string AuthTokenTokenHeader { + get { return (string)(ResourceManager.GetObject("AuthTokenTokenHeader", resourceCulture)); } + } + internal static string AuthTokenHelpSummary { + get { return (string)(ResourceManager.GetObject("AuthTokenHelpSummary", resourceCulture)); } + } + + internal static string AvailableHeader { + get { return (string)(ResourceManager.GetObject("AvailableHeader", resourceCulture)); } + } + + internal static string CacheHelpSummary { + get { return (string)(ResourceManager.GetObject("CacheHelpSummary", resourceCulture)); } + } + internal static string CacheSet { + get { return (string)(ResourceManager.GetObject("CacheSet", resourceCulture)); } + } + internal static string CacheInvalidPath { + get { return (string)(ResourceManager.GetObject("CacheInvalidPath", resourceCulture)); } + } + internal static string CacheCleared { + get { return (string)(ResourceManager.GetObject("CacheCleared", resourceCulture)); } + } + internal static string CacheReset { + get { return (string)(ResourceManager.GetObject("CacheReset", resourceCulture)); } + } + internal static string CacheResetFailed { + get { return (string)(ResourceManager.GetObject("CacheResetFailed", resourceCulture)); } + } + internal static string CacheUnlimited { + get { return (string)(ResourceManager.GetObject("CacheUnlimited", resourceCulture)); } + } + internal static string CacheInfo { + get { return (string)(ResourceManager.GetObject("CacheInfo", resourceCulture)); } + } + + internal static string CompareSame { + get { return (string)(ResourceManager.GetObject("CompareSame", resourceCulture)); } + } + internal static string CompareLower { + get { return (string)(ResourceManager.GetObject("CompareLower", resourceCulture)); } + } + internal static string CompareHigher { + get { return (string)(ResourceManager.GetObject("CompareHigher", resourceCulture)); } + } + internal static string CompatHelpSummary { + get { return (string)(ResourceManager.GetObject("CompatHelpSummary", resourceCulture)); } + } + internal static string CompatVersionHeader { + get { return (string)(ResourceManager.GetObject("CompatVersionHeader", resourceCulture)); } + } + internal static string CompatActualHeader { + get { return (string)(ResourceManager.GetObject("CompatActualHeader", resourceCulture)); } + } + internal static string CompatInvalid { + get { return (string)(ResourceManager.GetObject("CompatInvalid", resourceCulture)); } + } + internal static string CompatCantForget { + get { return (string)(ResourceManager.GetObject("CompatCantForget", resourceCulture)); } + } + + internal static string InstanceHelpSummary { + get { return (string)(ResourceManager.GetObject("InstanceHelpSummary", resourceCulture)); } + } + internal static string InstanceListNoVersion { + get { return (string)(ResourceManager.GetObject("InstanceListNoVersion", resourceCulture)); } + } + internal static string InstanceListYes { + get { return (string)(ResourceManager.GetObject("InstanceListYes", resourceCulture)); } + } + internal static string InstanceListNo { + get { return (string)(ResourceManager.GetObject("InstanceListNo", resourceCulture)); } + } + internal static string InstanceListNameHeader { + get { return (string)(ResourceManager.GetObject("InstanceListNameHeader", resourceCulture)); } + } + internal static string InstanceListVersionHeader { + get { return (string)(ResourceManager.GetObject("InstanceListVersionHeader", resourceCulture)); } + } + internal static string InstanceListDefaultHeader { + get { return (string)(ResourceManager.GetObject("InstanceListDefaultHeader", resourceCulture)); } + } + internal static string InstanceListPathHeader { + get { return (string)(ResourceManager.GetObject("InstanceListPathHeader", resourceCulture)); } + } + internal static string InstanceAddDuplicate { + get { return (string)(ResourceManager.GetObject("InstanceAddDuplicate", resourceCulture)); } + } + internal static string InstanceAdded { + get { return (string)(ResourceManager.GetObject("InstanceAdded", resourceCulture)); } + } + internal static string InstanceCloneNotFound { + get { return (string)(ResourceManager.GetObject("InstanceCloneNotFound", resourceCulture)); } + } + internal static string InstanceCloneFailed { + get { return (string)(ResourceManager.GetObject("InstanceCloneFailed", resourceCulture)); } + } + internal static string InstanceNotFound { + get { return (string)(ResourceManager.GetObject("InstanceNotFound", resourceCulture)); } + } + internal static string InstanceRenamed { + get { return (string)(ResourceManager.GetObject("InstanceRenamed", resourceCulture)); } + } + internal static string InstanceForgot { + get { return (string)(ResourceManager.GetObject("InstanceForgot", resourceCulture)); } + } + internal static string InstanceDefaultArgumentMissing { + get { return (string)(ResourceManager.GetObject("InstanceDefaultArgumentMissing", resourceCulture)); } + } + internal static string InstanceDefaultSet { + get { return (string)(ResourceManager.GetObject("InstanceDefaultSet", resourceCulture)); } + } + internal static string InstanceFakeFailed { + get { return (string)(ResourceManager.GetObject("InstanceFakeFailed", resourceCulture)); } + } + internal static string InstanceFakeBadArguments { + get { return (string)(ResourceManager.GetObject("InstanceFakeBadArguments", resourceCulture)); } + } + internal static string InstanceFakeMakingHistory { + get { return (string)(ResourceManager.GetObject("InstanceFakeMakingHistory", resourceCulture)); } + } + internal static string InstanceFakeBreakingGround { + get { return (string)(ResourceManager.GetObject("InstanceFakeBreakingGround", resourceCulture)); } + } + internal static string InstanceFakeVersion { + get { return (string)(ResourceManager.GetObject("InstanceFakeVersion", resourceCulture)); } + } + internal static string InstanceFakeBadGameVersion { + get { return (string)(ResourceManager.GetObject("InstanceFakeBadGameVersion", resourceCulture)); } + } + internal static string InstanceFakeCancelled { + get { return (string)(ResourceManager.GetObject("InstanceFakeCancelled", resourceCulture)); } + } + internal static string InstanceFakeCreating { + get { return (string)(ResourceManager.GetObject("InstanceFakeCreating", resourceCulture)); } + } + internal static string InstanceFakeDefault { + get { return (string)(ResourceManager.GetObject("InstanceFakeDefault", resourceCulture)); } + } + internal static string InstanceFakeDone { + get { return (string)(ResourceManager.GetObject("InstanceFakeDone", resourceCulture)); } + } + + internal static string ImportError { + get { return (string)(ResourceManager.GetObject("ImportError", resourceCulture)); } + } + internal static string ImportNotFound { + get { return (string)(ResourceManager.GetObject("ImportNotFound", resourceCulture)); } + } + + internal static string InstallNotFound { + get { return (string)(ResourceManager.GetObject("InstallNotFound", resourceCulture)); } + } + internal static string InstallTryAgain { + get { return (string)(ResourceManager.GetObject("InstallTryAgain", resourceCulture)); } + } + internal static string InstallUnversionedDependencyNotSatisfied { + get { return (string)(ResourceManager.GetObject("InstallUnversionedDependencyNotSatisfied", resourceCulture)); } + } + internal static string InstallVersionedDependencyNotSatisfied { + get { return (string)(ResourceManager.GetObject("InstallVersionedDependencyNotSatisfied", resourceCulture)); } + } + internal static string InstallBadMetadata { + get { return (string)(ResourceManager.GetObject("InstallBadMetadata", resourceCulture)); } + } + internal static string InstallFileConflictOwned { + get { return (string)(ResourceManager.GetObject("InstallFileConflictOwned", resourceCulture)); } + } + internal static string InstallFileConflictUnowned { + get { return (string)(ResourceManager.GetObject("InstallFileConflictUnowned", resourceCulture)); } + } + internal static string InstallGamedataReturned { + get { return (string)(ResourceManager.GetObject("InstallGamedataReturned", resourceCulture)); } + } + internal static string InstallCancelled { + get { return (string)(ResourceManager.GetObject("InstallCancelled", resourceCulture)); } + } + internal static string InstallAborted { + get { return (string)(ResourceManager.GetObject("InstallAborted", resourceCulture)); } + } + internal static string InstallTryAuthToken { + get { return (string)(ResourceManager.GetObject("InstallTryAuthToken", resourceCulture)); } + } + internal static string InstallDownloadFailed { + get { return (string)(ResourceManager.GetObject("InstallDownloadFailed", resourceCulture)); } + } + internal static string InstallDLC { + get { return (string)(ResourceManager.GetObject("InstallDLC", resourceCulture)); } + } + internal static string InstallDLCStorePage { + get { return (string)(ResourceManager.GetObject("InstallDLCStorePage", resourceCulture)); } + } + + internal static string ListUnknownFormat { + get { return (string)(ResourceManager.GetObject("ListUnknownFormat", resourceCulture)); } + } + internal static string ListGameFound { + get { return (string)(ResourceManager.GetObject("ListGameFound", resourceCulture)); } + } + internal static string ListGameVersion { + get { return (string)(ResourceManager.GetObject("ListGameVersion", resourceCulture)); } + } + internal static string ListGameModulesHeader { + get { return (string)(ResourceManager.GetObject("ListGameModulesHeader", resourceCulture)); } + } + internal static string ListLegend { + get { return (string)(ResourceManager.GetObject("ListLegend", resourceCulture)); } + } + + internal static string MarkHelpSummary { + get { return (string)(ResourceManager.GetObject("MarkHelpSummary", resourceCulture)); } + } + internal static string MarkUnknownCommand { + get { return (string)(ResourceManager.GetObject("MarkUnknownCommand", resourceCulture)); } + } + internal static string MarkNotInstalled { + get { return (string)(ResourceManager.GetObject("MarkNotInstalled", resourceCulture)); } + } + internal static string MarkAlready { + get { return (string)(ResourceManager.GetObject("MarkAlready", resourceCulture)); } + } + internal static string Marking { + get { return (string)(ResourceManager.GetObject("Marking", resourceCulture)); } + } + internal static string MarkDLC { + get { return (string)(ResourceManager.GetObject("MarkDLC", resourceCulture)); } + } + internal static string MarkChanged { + get { return (string)(ResourceManager.GetObject("MarkChanged", resourceCulture)); } + } + internal static string MarkAutoInstalled { + get { return (string)(ResourceManager.GetObject("MarkAutoInstalled", resourceCulture)); } + } + internal static string MarkUserSelected { + get { return (string)(ResourceManager.GetObject("MarkUserSelected", resourceCulture)); } + } + + internal static string PromptWelcome { + get { return (string)(ResourceManager.GetObject("PromptWelcome", resourceCulture)); } + } + internal static string PromptWithInstance { + get { return (string)(ResourceManager.GetObject("PromptWithInstance", resourceCulture)); } + } + internal static string PromptWithoutInstance { + get { return (string)(ResourceManager.GetObject("PromptWithoutInstance", resourceCulture)); } + } + + internal static string RemoveNotInstalled { + get { return (string)(ResourceManager.GetObject("RemoveNotInstalled", resourceCulture)); } + } + internal static string RemoveDLC { + get { return (string)(ResourceManager.GetObject("RemoveDLC", resourceCulture)); } + } + internal static string RemoveDLCStorePage { + get { return (string)(ResourceManager.GetObject("RemoveDLCStorePage", resourceCulture)); } + } + internal static string RemoveCancelled { + get { return (string)(ResourceManager.GetObject("RemoveCancelled", resourceCulture)); } + } + internal static string RemoveNothing { + get { return (string)(ResourceManager.GetObject("RemoveNothing", resourceCulture)); } + } + + internal static string RepairHelpSummary { + get { return (string)(ResourceManager.GetObject("RepairHelpSummary", resourceCulture)); } + } + internal static string RepairUnknownCommand { + get { return (string)(ResourceManager.GetObject("RepairUnknownCommand", resourceCulture)); } + } + internal static string Repaired { + get { return (string)(ResourceManager.GetObject("Repaired", resourceCulture)); } + } + internal static string ReplaceModuleNotFound { + get { return (string)(ResourceManager.GetObject("ReplaceModuleNotFound", resourceCulture)); } + } + internal static string Replacing { + get { return (string)(ResourceManager.GetObject("Replacing", resourceCulture)); } + } + internal static string ReplaceFound { + get { return (string)(ResourceManager.GetObject("ReplaceFound", resourceCulture)); } + } + internal static string ReplaceContinuePrompt { + get { return (string)(ResourceManager.GetObject("ReplaceContinuePrompt", resourceCulture)); } + } + internal static string ReplaceCancelled { + get { return (string)(ResourceManager.GetObject("ReplaceCancelled", resourceCulture)); } + } + internal static string ReplaceDependencyNotSatisfied { + get { return (string)(ResourceManager.GetObject("ReplaceDependencyNotSatisfied", resourceCulture)); } + } + internal static string ReplaceNotFound { + get { return (string)(ResourceManager.GetObject("ReplaceNotFound", resourceCulture)); } + } + + internal static string RepoHelpSummary { + get { return (string)(ResourceManager.GetObject("RepoHelpSummary", resourceCulture)); } + } + internal static string RepoUnknownCommand { + get { return (string)(ResourceManager.GetObject("RepoUnknownCommand", resourceCulture)); } + } + internal static string RepoAvailableHeader { + get { return (string)(ResourceManager.GetObject("RepoAvailableHeader", resourceCulture)); } + } + internal static string RepoAvailableFailed { + get { return (string)(ResourceManager.GetObject("RepoAvailableFailed", resourceCulture)); } + } + internal static string RepoListHeader { + get { return (string)(ResourceManager.GetObject("RepoListHeader", resourceCulture)); } + } + internal static string RepoAddNotFound { + get { return (string)(ResourceManager.GetObject("RepoAddNotFound", resourceCulture)); } + } + internal static string RepoAddDuplicate { + get { return (string)(ResourceManager.GetObject("RepoAddDuplicate", resourceCulture)); } + } + internal static string RepoAdded { + get { return (string)(ResourceManager.GetObject("RepoAdded", resourceCulture)); } + } + internal static string RepoForgetNotFound { + get { return (string)(ResourceManager.GetObject("RepoForgetNotFound", resourceCulture)); } + } + internal static string RepoForgetRemoving { + get { return (string)(ResourceManager.GetObject("RepoForgetRemoving", resourceCulture)); } + } + internal static string RepoForgetRemoved { + get { return (string)(ResourceManager.GetObject("RepoForgetRemoved", resourceCulture)); } + } + internal static string RepoSet { + get { return (string)(ResourceManager.GetObject("RepoSet", resourceCulture)); } + } + + internal static string SearchNoTerm { + get { return (string)(ResourceManager.GetObject("SearchNoTerm", resourceCulture)); } + } + internal static string SearchFoundByAuthorWithIncompat { + get { return (string)(ResourceManager.GetObject("SearchFoundByAuthorWithIncompat", resourceCulture)); } + } + internal static string SearchFoundWithIncompat { + get { return (string)(ResourceManager.GetObject("SearchFoundWithIncompat", resourceCulture)); } + } + internal static string SearchFoundByAuthor { + get { return (string)(ResourceManager.GetObject("SearchFoundByAuthor", resourceCulture)); } + } + internal static string SearchFound { + get { return (string)(ResourceManager.GetObject("SearchFound", resourceCulture)); } + } + internal static string SearchCompatibleModsHeader { + get { return (string)(ResourceManager.GetObject("SearchCompatibleModsHeader", resourceCulture)); } + } + internal static string SearchCompatibleMod { + get { return (string)(ResourceManager.GetObject("SearchCompatibleMod", resourceCulture)); } + } + internal static string SearchIncompatibleModsHeader { + get { return (string)(ResourceManager.GetObject("SearchIncompatibleModsHeader", resourceCulture)); } + } + internal static string SearchIncompatibleMod { + get { return (string)(ResourceManager.GetObject("SearchIncompatibleMod", resourceCulture)); } + } + internal static string ShowNotInstalledOrCompatible { + get { return (string)(ResourceManager.GetObject("ShowNotInstalledOrCompatible", resourceCulture)); } + } + internal static string ShowLookingForClose { + get { return (string)(ResourceManager.GetObject("ShowLookingForClose", resourceCulture)); } + } + internal static string ShowNoClose { + get { return (string)(ResourceManager.GetObject("ShowNoClose", resourceCulture)); } + } + internal static string ShowFoundOne { + get { return (string)(ResourceManager.GetObject("ShowFoundOne", resourceCulture)); } + } + internal static string ShowClosePrompt { + get { return (string)(ResourceManager.GetObject("ShowClosePrompt", resourceCulture)); } + } + internal static string ShowFilesHeader { + get { return (string)(ResourceManager.GetObject("ShowFilesHeader", resourceCulture)); } + } + internal static string ShowModuleInfoHeader { + get { return (string)(ResourceManager.GetObject("ShowModuleInfoHeader", resourceCulture)); } + } + internal static string ShowVersion { + get { return (string)(ResourceManager.GetObject("ShowVersion", resourceCulture)); } + } + internal static string ShowAuthor { + get { return (string)(ResourceManager.GetObject("ShowAuthor", resourceCulture)); } + } + internal static string ShowAuthorUnknown { + get { return (string)(ResourceManager.GetObject("ShowAuthorUnknown", resourceCulture)); } + } + internal static string ShowStatus { + get { return (string)(ResourceManager.GetObject("ShowStatus", resourceCulture)); } + } + internal static string ShowLicence { + get { return (string)(ResourceManager.GetObject("ShowLicence", resourceCulture)); } + } + internal static string ShowTags { + get { return (string)(ResourceManager.GetObject("ShowTags", resourceCulture)); } + } + internal static string ShowLanguages { + get { return (string)(ResourceManager.GetObject("ShowLanguages", resourceCulture)); } + } + internal static string ShowDependsHeader { + get { return (string)(ResourceManager.GetObject("ShowDependsHeader", resourceCulture)); } + } + internal static string ShowRecommendsHeader { + get { return (string)(ResourceManager.GetObject("ShowRecommendsHeader", resourceCulture)); } + } + internal static string ShowSuggestsHeader { + get { return (string)(ResourceManager.GetObject("ShowSuggestsHeader", resourceCulture)); } + } + internal static string ShowProvidesHeader { + get { return (string)(ResourceManager.GetObject("ShowProvidesHeader", resourceCulture)); } + } + internal static string ShowResourcesHeader { + get { return (string)(ResourceManager.GetObject("ShowResourcesHeader", resourceCulture)); } + } + internal static string ShowHomePage { + get { return (string)(ResourceManager.GetObject("ShowHomePage", resourceCulture)); } + } + internal static string ShowManual { + get { return (string)(ResourceManager.GetObject("ShowManual", resourceCulture)); } + } + internal static string ShowSpaceDock { + get { return (string)(ResourceManager.GetObject("ShowSpaceDock", resourceCulture)); } + } + internal static string ShowRepository { + get { return (string)(ResourceManager.GetObject("ShowRepository", resourceCulture)); } + } + internal static string ShowBugTracker { + get { return (string)(ResourceManager.GetObject("ShowBugTracker", resourceCulture)); } + } + internal static string ShowCurse { + get { return (string)(ResourceManager.GetObject("ShowCurse", resourceCulture)); } + } + internal static string ShowStore { + get { return (string)(ResourceManager.GetObject("ShowStore", resourceCulture)); } + } + internal static string ShowSteamStore { + get { return (string)(ResourceManager.GetObject("ShowSteamStore", resourceCulture)); } + } + internal static string ShowVersionFile { + get { return (string)(ResourceManager.GetObject("ShowVersionFile", resourceCulture)); } + } + internal static string ShowFileName { + get { return (string)(ResourceManager.GetObject("ShowFileName", resourceCulture)); } + } + internal static string ShowVersionHeader { + get { return (string)(ResourceManager.GetObject("ShowVersionHeader", resourceCulture)); } + } + internal static string ShowGameVersionsHeader { + get { return (string)(ResourceManager.GetObject("ShowGameVersionsHeader", resourceCulture)); } + } + + internal static string UpdateChangesSummary { + get { return (string)(ResourceManager.GetObject("UpdateChangesSummary", resourceCulture)); } + } + internal static string UpdateAddedHeader { + get { return (string)(ResourceManager.GetObject("UpdateAddedHeader", resourceCulture)); } + } + internal static string UpdateRemovedHeader { + get { return (string)(ResourceManager.GetObject("UpdateRemovedHeader", resourceCulture)); } + } + internal static string UpdateUpdatedHeader { + get { return (string)(ResourceManager.GetObject("UpdateUpdatedHeader", resourceCulture)); } + } + internal static string UpdateSummary { + get { return (string)(ResourceManager.GetObject("UpdateSummary", resourceCulture)); } + } + + internal static string UpgradeQueryingCKAN { + get { return (string)(ResourceManager.GetObject("UpgradeQueryingCKAN", resourceCulture)); } + } + internal static string UpgradeNewCKANAvailable { + get { return (string)(ResourceManager.GetObject("UpgradeNewCKANAvailable", resourceCulture)); } + } + internal static string UpgradeProceed { + get { return (string)(ResourceManager.GetObject("UpgradeProceed", resourceCulture)); } + } + internal static string UpgradePleaseWait { + get { return (string)(ResourceManager.GetObject("UpgradePleaseWait", resourceCulture)); } + } + internal static string UpgradeAlreadyHaveLatest { + get { return (string)(ResourceManager.GetObject("UpgradeAlreadyHaveLatest", resourceCulture)); } + } + internal static string UpgradeAborted { + get { return (string)(ResourceManager.GetObject("UpgradeAborted", resourceCulture)); } + } + internal static string UpgradeNotFound { + get { return (string)(ResourceManager.GetObject("UpgradeNotFound", resourceCulture)); } + } + internal static string UpgradeDLC { + get { return (string)(ResourceManager.GetObject("UpgradeDLC", resourceCulture)); } + } + internal static string UpgradeDLCStorePage { + get { return (string)(ResourceManager.GetObject("UpgradeDLCStorePage", resourceCulture)); } + } + + internal static string ScanNotSaved { + get { return (string)(ResourceManager.GetObject("ScanNotSaved", resourceCulture)); } + } + internal static string ScanPreliminaryInconsistent { + get { return (string)(ResourceManager.GetObject("ScanPreliminaryInconsistent", resourceCulture)); } + } + + internal static string FilterListGlobalHeader { + get { return (string)(ResourceManager.GetObject("FilterListGlobalHeader", resourceCulture)); } + } + internal static string FilterListInstanceHeader { + get { return (string)(ResourceManager.GetObject("FilterListInstanceHeader", resourceCulture)); } + } + internal static string FilterAddGlobalDuplicateError { + get { return (string)(ResourceManager.GetObject("FilterAddGlobalDuplicateError", resourceCulture)); } + } + internal static string FilterAddInstanceDuplicateError { + get { return (string)(ResourceManager.GetObject("FilterAddInstanceDuplicateError", resourceCulture)); } + } + internal static string FilterRemoveGlobalNotFoundError { + get { return (string)(ResourceManager.GetObject("FilterRemoveGlobalNotFoundError", resourceCulture)); } + } + internal static string FilterRemoveInstanceNotFoundError { + get { return (string)(ResourceManager.GetObject("FilterRemoveInstanceNotFoundError", resourceCulture)); } + } + internal static string FilterHelpSummary { + get { return (string)(ResourceManager.GetObject("FilterHelpSummary", resourceCulture)); } + } + + internal static string CompletionNotAvailable { + get { return (string)(ResourceManager.GetObject("CompletionNotAvailable", resourceCulture)); } + } + + } +} diff --git a/Cmdline/Properties/Resources.en-US.resx b/Cmdline/Properties/Resources.en-US.resx new file mode 100644 index 0000000000..b0fddd5121 --- /dev/null +++ b/Cmdline/Properties/Resources.en-US.resx @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="ShowLicence" xml:space="preserve"><value> License: {0}</value></data> +</root> diff --git a/Cmdline/Properties/Resources.fr-FR.resx b/Cmdline/Properties/Resources.fr-FR.resx new file mode 100644 index 0000000000..b1288b3b38 --- /dev/null +++ b/Cmdline/Properties/Resources.fr-FR.resx @@ -0,0 +1,368 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="Usage" xml:space="preserve"><value>Utilisation </value></data> + <data name="Command" xml:space="preserve"><value>commande</value></data> + <data name="UnknownCommand" xml:space="preserve"><value>Commande inconnue</value></data> + <data name="Options" xml:space="preserve"><value>options</value></data> + <data name="ArgumentMissing" xml:space="preserve"><value>argument manquant, peut-être l'avez-vous oublié ?</value></data> + <data name="Path" xml:space="preserve"><value>chemin</value></data> + <data name="MainVersion" xml:space="preserve"><value>Vous utilisez CKAN version {0}</value></data> + <data name="MainUnknownCommand" xml:space="preserve"><value>Commande inconnue, essayez --help</value></data> + <data name="MainMissingInstance" xml:space="preserve"><value>Je ne sais pas où l'instance de jeu est installée. +Utilisez 'ckan instance help' pour être aidé dans cette configuration.</value></data> + <data name="OptionsRootError" xml:space="preserve"><value>Vous essayer d'utiliser CKAN en tant que super-utilisateur. +C'est une mauvaise idée et il n'y a absolument aucune raison de le faire. Veuillez utilisez CKAN depuis un compte utilisateur (ou utilisez --asroot si vous aimez le risque).</value></data> + <data name="OptionsRootWarning" xml:space="preserve"><value>Attention : CKAN utilisé par un super-utilisateur !</value></data> + <data name="OptionsMonoWarning" xml:space="preserve"><value>Attention. Un runtime Mono {0} a été détecté, ce qui est inférieur à la version recommandée qui est {1}. +Mise à jour conseillée !</value></data> + <data name="OptionsInstanceAndGameDir" xml:space="preserve"><value>--instance et --gamedir ne peuvent pas être spécifiées en même temps</value></data> + <data name="OptionsInvalidInstance" xml:space="preserve"><value>Instance de jeu spécifiée invalide "{0}", utilisez '--gamedir' pour spécifier un chemin, ou 'instance list' pour voir les instances de jeu connues</value></data> + <data name="InstanceNotInstance" xml:space="preserve"><value>Désolé, {0} n'a pas l'air d'être une instance de jeu</value></data> + <data name="InstanceDuplicate" xml:space="preserve"><value>Ce nom d'instance est déjà pris : {0}</value></data> + <data name="UserYesNoPromptSuffix" xml:space="preserve"><value>[O/n]</value></data> + <data name="UserYesNoY" xml:space="preserve"><value>o</value></data> + <data name="UserYesNoYes" xml:space="preserve"><value>oui</value></data> + <data name="UserYesNoN" xml:space="preserve"><value>n</value></data> + <data name="UserYesNoNo" xml:space="preserve"><value>non</value></data> + <data name="UserYesNoInvalid" xml:space="preserve"><value>Saisie invalide. Veuillez entrer oui ou non</value></data> + <data name="UserSelectionPromptWithDefault" xml:space="preserve"><value>Entrez un nombre entre {0} et {1} (Pour annuler appuyez sur "c" ou "n". "Entré" va sélectionner {2}.) : </value></data> + <data name="UserSelectionPromptWithoutDefault" xml:space="preserve"><value>Entrez un nombre entre {0} et {1} (Pour annuler appuyez sur "c" ou "n".) : </value></data> + <data name="UserSelectionC" xml:space="preserve"><value>c</value></data> + <data name="UserSelectionN" xml:space="preserve"><value>n</value></data> + <data name="UserSelectionCancelled" xml:space="preserve"><value>Sélection annulée</value></data> + <data name="UserSelectionNotNumber" xml:space="preserve"><value>La saisie n'est pas un nombre</value></data> + <data name="UserSelectionTooLarge" xml:space="preserve"><value>Le nombre saisi est trop grand</value></data> + <data name="UserSelectionTooSmall" xml:space="preserve"><value>Le nombre saisi est trop petit</value></data> + <data name="AuthTokenHostHeader" xml:space="preserve"><value>Hôte</value></data> + <data name="AuthTokenTokenHeader" xml:space="preserve"><value>Jeton</value></data> + <data name="AuthTokenHelpSummary" xml:space="preserve"><value>Gérer les jetons d'authentification</value></data> + <data name="AvailableHeader" xml:space="preserve"><value>Modules compatible avec {0} {1}</value></data> + <data name="CacheHelpSummary" xml:space="preserve"><value>Gérer le chemin du cache des téléchargements de CKAN</value></data> + <data name="CacheSet" xml:space="preserve"><value>Cache des téléchargements réglé à {0}</value></data> + <data name="CacheInvalidPath" xml:space="preserve"><value>Chemin invalide : {0}</value></data> + <data name="CacheCleared" xml:space="preserve"><value>Cache des téléchargements nettoyé</value></data> + <data name="CacheReset" xml:space="preserve"><value>Cache des téléchargements réinitialisé à {0}</value></data> + <data name="CacheResetFailed" xml:space="preserve"><value>Impossible de réinitialiser le chemin du cache : {0}</value></data> + <data name="CacheUnlimited" xml:space="preserve"><value>Illimité</value></data> + <data name="CacheInfo" xml:space="preserve"><value>{0} fichiers, {1}</value></data> + <data name="CompareSame" xml:space="preserve"><value>"{0}" et "{1}" ont les mêmes versions.</value></data> + <data name="CompareLower" xml:space="preserve"><value>"{0}" est plus bas que "{1}".</value></data> + <data name="CompareHigher" xml:space="preserve"><value>"{0}" est plus haut que "{1}".</value></data> + <data name="CompatHelpSummary" xml:space="preserve"><value>Gérer les versions de jeu compatibles</value></data> + <data name="CompatVersionHeader" xml:space="preserve"><value>Version</value></data> + <data name="CompatActualHeader" xml:space="preserve"><value>Actuelle</value></data> + <data name="CompatInvalid" xml:space="preserve"><value>ERREUR : Version de jeu invalide</value></data> + <data name="CompatCantForget" xml:space="preserve"><value>ERREUR : Impossible d'oublier la version de jeu actuelle</value></data> + <data name="InstanceHelpSummary" xml:space="preserve"><value>Gérer les instances de jeu</value></data> + <data name="InstanceListNoVersion" xml:space="preserve"><value><AUCUNE></value></data> + <data name="InstanceListYes" xml:space="preserve"><value>Oui</value></data> + <data name="InstanceListNo" xml:space="preserve"><value>Non</value></data> + <data name="InstanceListNameHeader" xml:space="preserve"><value>Nom</value></data> + <data name="InstanceListVersionHeader" xml:space="preserve"><value>Version</value></data> + <data name="InstanceListDefaultHeader" xml:space="preserve"><value>Défaut</value></data> + <data name="InstanceListPathHeader" xml:space="preserve"><value>Chemin</value></data> + <data name="InstanceAddDuplicate" xml:space="preserve"><value>Une installation avec le nom "{0}" existe déjà, annulation</value></data> + <data name="InstanceAdded" xml:space="preserve"><value>Ajout de "{0}" de racine "{1}" aux installations connues</value></data> + <data name="InstanceCloneNotFound" xml:space="preserve"><value>Aucune instance avec ce nom ou avec ce chemin : {0} +Voir ci-dessous une liste des instances connues : +</value></data> + <data name="InstanceCloneFailed" xml:space="preserve"><value>Quelque chose s'est mal passé. Veuillez vérifier que le nouveau dossier a bien été créé. +Essayez d'ajouter l'instance manuellement avec "ckan instance add". +</value></data> + <data name="InstanceNotFound" xml:space="preserve"><value>Impossible de trouver une installation avec le nom "{0}", annulation</value></data> + <data name="InstanceRenamed" xml:space="preserve"><value>"{0}" a été renommée "{1}" avec succès</value></data> + <data name="InstanceForgot" xml:space="preserve"><value>"{0}" a été retirée avec succès</value></data> + <data name="InstanceDefaultArgumentMissing" xml:space="preserve"><value>argument manquant, veuillez sélectionnez depuis la liste ci-dessous</value></data> + <data name="InstanceDefaultSet" xml:space="preserve"><value>"{0}" a été définie comme instance de jeu par défaut</value></data> + <data name="InstanceFakeFailed" xml:space="preserve"><value>Quelque chose s'est mal passé. Essayez d'ajouter l'instance manuellement avec "ckan instance add". Vérifiez aussi si le nouveau dossier a bien été créé.</value></data> + <data name="InstanceFakeBadArguments" xml:space="preserve"><value>--Erreur: mauvais argument·s--</value></data> + <data name="InstanceFakeMakingHistory" xml:space="preserve"><value>Veuillez vérifier l'argument de version du DLC Making History - Le format est du type Maj.Min.Patch - ex: 1.1.0</value></data> + <data name="InstanceFakeBreakingGround" xml:space="preserve"><value>Veuillez vérifier l'argument de version du DLC Breaking Ground - Le format est du type Maj.Min.Patch - ex: 1.1.0</value></data> + <data name="InstanceFakeVersion" xml:space="preserve"><value>Veuillez vérifier l'argument de version - Le format est du type Maj.Min.Patch[.Build] - ex: 1.6.0 ou 1.2.2.1622</value></data> + <data name="InstanceFakeBadGameVersion" xml:space="preserve"><value>Impossible de trouver une version de jeu valide pour votre saisie. +Soyez sûr d'avoir saisi au moins les valeurs de version majeure et mineure au format Maj.Min - ex: 1.5</value></data> + <data name="InstanceFakeCancelled" xml:space="preserve"><value>Sélection annulée ! Veuillez saisir 'ckan instance fake' à nouveau</value></data> + <data name="InstanceFakeCreating" xml:space="preserve"><value>Création d'une instance de jeu artificielle {0} à {1} de version {2}</value></data> + <data name="InstanceFakeDefault" xml:space="preserve"><value>Définition de la nouvelle instance comme par défaut...</value></data> + <data name="InstanceFakeDone" xml:space="preserve"><value>--Fini--</value></data> + <data name="ImportError" xml:space="preserve"><value>Erreur d'importation : {0}</value></data> + <data name="ImportNotFound" xml:space="preserve"><value>Fichier introuvable : {0}</value></data> + <data name="InstallNotFound" xml:space="preserve"><value>Fichier introuvable, sortie : {0}</value></data> + <data name="InstallTryAgain" xml:space="preserve"><value>Si vous êtes chanceux, vous pouvez taper `ckan update` et réessayer. +Essayez `ckan install --no-recommends` pour ignorer l'installation des modules recommandés. +Ou `ckan install --allow-incompatible` pour ignorer la compatibilité des modules.</value></data> + <data name="InstallUnversionedDependencyNotSatisfied" xml:space="preserve"><value>Le module {0} est requis mais il n'est pas listé dans l'index, ou indisponible pour votre version de {1}</value></data> + <data name="InstallVersionedDependencyNotSatisfied" xml:space="preserve"><value>Le module {0} {1} est requis mais il n'est pas listé dans l'index, ou indisponible pour votre version de {2}</value></data> + <data name="InstallBadMetadata" xml:space="preserve"><value>Mauvaises métadonnées détectées pour le module {0} : {1}</value></data> + <data name="InstallFileConflictOwned" xml:space="preserve"><value>Oh non ! Nous avons essayé de remplacer un fichier appartenant à un autre mod ! +Veuillez taper `ckan update` puis réessayez. + +Si ce problème se produit de nouveau, c'est peut-être un bogue d'emballage. +Veuillez le signaler à : + +https://github.com/KSP-CKAN/NetKAN/issues/new + +Veuillez inclure les informations suivantes dans votre rapport : + +Fichier : {0} +Mod en installation : {1} +Mod propriétaire : {2} +Version CKAN : {3} +</value></data> + <data name="InstallFileConflictUnowned" xml:space="preserve"><value>Oh non ! + +On dirait que vous essayez d'installer un mod qui est déjà installé, +ou qui est en conflit avec un autre mod déjà installé. + +Par mesure de précaution, CKAN ne remplace ou n'altère *jamais* +un fichier qu'il n'a pas installé lui-même. + +Si vous souhaitez installer {0} avec CKAN, +alors veuillez désinstaller manuellement le mod auquel appartient : + +{1} + +et réessayez. +</value></data> + <data name="InstallGamedataReturned" xml:space="preserve"><value>Votre {0} a été remis dans son état original</value></data> + <data name="InstallCancelled" xml:space="preserve"><value>Installation annulée. Vos fichiers ont remis dans leur état initial.</value></data> + <data name="InstallAborted" xml:space="preserve"><value>Installation annulée : {0}</value></data> + <data name="InstallTryAuthToken" xml:space="preserve"><value>Essayez la commande authtoken . Regardez {0} pour plus de détails.</value></data> + <data name="InstallDownloadFailed" xml:space="preserve"><value>Un ou plusieurs fichier·s n'ont pu être téléchargés, arrêt</value></data> + <data name="InstallDLC" xml:space="preserve"><value>CKAN ne peut pas installer l'extension '{0}' pour vous.</value></data> + <data name="InstallDLCStorePage" xml:space="preserve"><value>Pour installer cette extension, achetez-la depuis l'une de ces boutiques : +{0}</value></data> + <data name="ListUnknownFormat" xml:space="preserve"><value>Format d'exportation inconnu : {0}</value></data> + <data name="ListGameFound" xml:space="preserve"><value>{0} trouvé à : {1}</value></data> + <data name="ListGameVersion" xml:space="preserve"><value>Version de {0} : {1}</value></data> + <data name="ListGameModulesHeader" xml:space="preserve"><value>Modules installés :</value></data> + <data name="ListLegend" xml:space="preserve"><value>Légende : -: À jour. +: Auto-installé. X: Incompatible. ^: À mettre à jour. >: Remplaçable. + A: Auto-détecté. ?: Inconnu. *: Cassé.</value></data> + <data name="MarkHelpSummary" xml:space="preserve"><value>Éditer les attributs des modules</value></data> + <data name="MarkUnknownCommand" xml:space="preserve"><value>Commande inconnue : mark {0}</value></data> + <data name="MarkNotInstalled" xml:space="preserve"><value>{0} n'est pas installé</value></data> + <data name="MarkAlready" xml:space="preserve"><value>{0} est déjà marqué comme {1}</value></data> + <data name="Marking" xml:space="preserve"><value>Marquage de {0} comme {1}...</value></data> + <data name="MarkDLC" xml:space="preserve"><value>Impossible de marquer l'extension '{0}' comme auto-installé</value></data> + <data name="MarkChanged" xml:space="preserve"><value>Changements complétés !</value></data> + <data name="MarkAutoInstalled" xml:space="preserve"><value>auto-installé</value></data> + <data name="MarkUserSelected" xml:space="preserve"><value>Sélectionné par l'utilisateur</value></data> + <data name="PromptWelcome" xml:space="preserve"><value>Bienvenue sur CKAN! + +Pour obtenir de l'aide, tapez help et appuyez sur entré. Pour quitter, tapez {0} et appuyez sur entré. +</value></data> + <data name="PromptWithInstance" xml:space="preserve"><value>CKAN {0} : {1} {2} ({3})> </value></data> + <data name="PromptWithoutInstance" xml:space="preserve"><value>CKAN {0}> </value></data> + <data name="RemoveNotInstalled" xml:space="preserve"><value>Impossible, {0} n'est pas installé. +Essayez `ckan list` pour une liste des mods installés.</value></data> + <data name="RemoveDLC" xml:space="preserve"><value>CKAN ne peut pas retirer l'extension '{0}' pour vous.</value></data> + <data name="RemoveDLCStorePage" xml:space="preserve"><value>Pour retirer cette extension, suivez les instructions pour la boutique depuis laquelle vous l'avez achetée : +{0}</value></data> + <data name="RemoveCancelled" xml:space="preserve"><value>Retrait annulé : {0}</value></data> + <data name="RemoveNothing" xml:space="preserve"><value>Aucun mod sélectionné, rien à faire</value></data> + <data name="RepairHelpSummary" xml:space="preserve"><value>Essayer des réparations automatiques diverses</value></data> + <data name="RepairUnknownCommand" xml:space="preserve"><value>Commande inconnue : repair {0}</value></data> + <data name="Repaired" xml:space="preserve"><value>Les réparations du registre ont été tentées. Nous espérons qu'elles ont marché.</value></data> + <data name="ReplaceModuleNotFound" xml:space="preserve"><value>Module {0} introuvable</value></data> + <data name="Replacing" xml:space="preserve"><value>Remplacement des modules...</value></data> + <data name="ReplaceFound" xml:space="preserve"><value>Le remplacement {0} {1} a été trouvé pour {2} {3}</value></data> + <data name="ReplaceContinuePrompt" xml:space="preserve"><value>Continuer ?</value></data> + <data name="ReplaceCancelled" xml:space="preserve"><value>Remplacements annulés à la demande de l'utilisateur</value></data> + <data name="ReplaceDependencyNotSatisfied" xml:space="preserve"><value>Dépendances insatisfaites pour le remplacement, {0} nécessite {1} {2} mais il n'est pas listé dans l'index, ou indisponible pour votre version de {3}</value></data> + <data name="ReplaceNotFound" xml:space="preserve"><value>Aucun remplacement trouvé</value></data> + <data name="RepoHelpSummary" xml:space="preserve"><value>Gérer les répertoires CKAN</value></data> + <data name="RepoUnknownCommand" xml:space="preserve"><value>Commande inconnue : repo {0}</value></data> + <data name="RepoAvailableHeader" xml:space="preserve"><value>Liste de tous les répertoires officiels de CKAN :</value></data> + <data name="RepoAvailableFailed" xml:space="preserve"><value>Impossible d'obtenir la liste maîtresse des répertoires CKAN depuis {0}</value></data> + <data name="RepoListHeader" xml:space="preserve"><value>Liste de tous les répertoires connus :</value></data> + <data name="RepoAddNotFound" xml:space="preserve"><value>Le nom {0} n'a pas été trouvé dans la liste maîtresse, veuillez fournir un nom et une adresse</value></data> + <data name="RepoAddDuplicate" xml:space="preserve"><value>Un répertoire avec le nom "{0}" existe déjà, annulation</value></data> + <data name="RepoAdded" xml:space="preserve"><value>Ajout du répertoire '{0}' - '{1}'</value></data> + <data name="RepoForgetNotFound" xml:space="preserve"><value>Impossible de trouver un répertoire avec le nom "{0}", annulation</value></data> + <data name="RepoForgetRemoving" xml:space="preserve"><value>Retrait du résultat insensible à la casse "{0}"</value></data> + <data name="RepoForgetRemoved" xml:space="preserve"><value>Retrait de "{0}" avec succès</value></data> + <data name="RepoSet" xml:space="preserve"><value>Mettre {0} le répertoire à '{1}'</value></data> + <data name="SearchNoTerm" xml:space="preserve"><value>Aucun terme à chercher ?</value></data> + <data name="SearchFoundByAuthorWithIncompat" xml:space="preserve"><value>{0} mod·s compatible·s et {1} mod·s incompatible·s correspondent à "{2}" par "{3}"</value></data> + <data name="SearchFoundWithIncompat" xml:space="preserve"><value>{0} mod·s compatible·s et {1} mod·s incompatible·s correspondent à "{2}"</value></data> + <data name="SearchFoundByAuthor" xml:space="preserve"><value>{0} mod·s compatible·s correspond·ent à "{1}" par "{2}"</value></data> + <data name="SearchFound" xml:space="preserve"><value>{0} mod·s compatible·s correspond·ent à "{1}"</value></data> + <data name="SearchCompatibleModsHeader" xml:space="preserve"><value>Mods compatibles correspondants :</value></data> + <data name="SearchCompatibleMod" xml:space="preserve"><value>* {0} ({1}) - {2} par {3} - {4}</value></data> + <data name="SearchIncompatibleModsHeader" xml:space="preserve"><value>Mods incompatibles correspondants :</value></data> + <data name="SearchIncompatibleMod" xml:space="preserve"><value>* {0} ({1} - {2}) - {3} par {4} - {5}</value></data> + <data name="ShowNotInstalledOrCompatible" xml:space="preserve"><value>{0} n'est pas installé ou incompatible avec {1} {2}</value></data> + <data name="ShowLookingForClose" xml:space="preserve"><value>Recherche de concordances proches parmi les mods compatibles...</value></data> + <data name="ShowNoClose" xml:space="preserve"><value>Aucune concordance proche trouvée</value></data> + <data name="ShowFoundOne" xml:space="preserve"><value>Une correspondance proche a été trouvée : {0}</value></data> + <data name="ShowClosePrompt" xml:space="preserve"><value>Correspondances proches :</value></data> + <data name="ShowFilesHeader" xml:space="preserve"><value>Affichage de {0} fichiers installés :</value></data> + <data name="ShowModuleInfoHeader" xml:space="preserve"><value>Info du module :</value></data> + <data name="ShowVersion" xml:space="preserve"><value> Version : {0}</value></data> + <data name="ShowAuthor" xml:space="preserve"><value> Auteur·s : {0}</value></data> + <data name="ShowAuthorUnknown" xml:space="preserve"><value> Auteur : INCONNU</value></data> + <data name="ShowStatus" xml:space="preserve"><value> Statut : {0}</value></data> + <data name="ShowLicence" xml:space="preserve"><value> Licence : {0}</value></data> + <data name="ShowTags" xml:space="preserve"><value> Étiquettes : {0}</value></data> + <data name="ShowLanguages" xml:space="preserve"><value> Langues : {0}</value></data> + <data name="ShowDependsHeader" xml:space="preserve"><value>Dépend de :</value></data> + <data name="ShowRecommendsHeader" xml:space="preserve"><value>Recommande :</value></data> + <data name="ShowSuggestsHeader" xml:space="preserve"><value>Suggère :</value></data> + <data name="ShowProvidesHeader" xml:space="preserve"><value>Fournit :</value></data> + <data name="ShowResourcesHeader" xml:space="preserve"><value>Ressources :</value></data> + <data name="ShowHomePage" xml:space="preserve"><value> Page principale : {0}</value></data> + <data name="ShowManual" xml:space="preserve"><value> Manuel : {0}</value></data> + <data name="ShowSpaceDock" xml:space="preserve"><value> SpaceDock : {0}</value></data> + <data name="ShowRepository" xml:space="preserve"><value> Répertoire : {0}</value></data> + <data name="ShowBugTracker" xml:space="preserve"><value> Traqueur de bogues : {0}</value></data> + <data name="ShowCurse" xml:space="preserve"><value> Curse : {0}</value></data> + <data name="ShowStore" xml:space="preserve"><value> Boutique : {0}</value></data> + <data name="ShowSteamStore" xml:space="preserve"><value> Magasin Steam : {0}</value></data> + <data name="ShowVersionFile" xml:space="preserve"><value> Fichier Version : {0}</value></data> + <data name="ShowFileName" xml:space="preserve"><value>Nom du fichier : {0}</value></data> + <data name="ShowVersionHeader" xml:space="preserve"><value>Version</value></data> + <data name="ShowGameVersionsHeader" xml:space="preserve"><value>Versions de Jeu</value></data> + <data name="UpdateChangesSummary" xml:space="preserve"><value>{0} nouveaux modules, {1} modules retirés and {2} modules mis à jour ont été trouvés</value></data> + <data name="UpdateAddedHeader" xml:space="preserve"><value>Nouveaux modules [Nom (identifiant CKAN)] :</value></data> + <data name="UpdateRemovedHeader" xml:space="preserve"><value>Modules retirés [Nom (identifiant CKAN)] :</value></data> + <data name="UpdateUpdatedHeader" xml:space="preserve"><value>Modules mis à jour [Nom (identifiant CKAN)] :</value></data> + <data name="UpdateSummary" xml:space="preserve"><value>Informations sur {0} modules compatibles mises à jour</value></data> + <data name="UpgradeQueryingCKAN" xml:space="preserve"><value>Requête de la dernière version CKAN</value></data> + <data name="UpgradeNewCKANAvailable" xml:space="preserve"><value>Nouvelle version de CKAN disponible - {0}</value></data> + <data name="UpgradeProceed" xml:space="preserve"><value>Poursuivre l'installation ?</value></data> + <data name="UpgradePleaseWait" xml:space="preserve"><value>Mise à niveau de CKAN, veuillez patienter...</value></data> + <data name="UpgradeAlreadyHaveLatest" xml:space="preserve"><value>Vous avez déjà la dernière version</value></data> + <data name="UpgradeAborted" xml:space="preserve"><value>Mise à niveau annulée : {0}</value></data> + <data name="UpgradeNotFound" xml:space="preserve"><value>Le module {0} est introuvable</value></data> + <data name="UpgradeDLC" xml:space="preserve"><value>CKAN ne peut pas mettre à niveau l'extension '{0}' pour vous</value></data> + <data name="UpgradeDLCStorePage" xml:space="preserve"><value>Pour mettre à niveau cette extension, téléchargez les éventuelles mises à jour depuis la boutique où vous l'avez achetée : +{0}</value></data> + <data name="ScanNotSaved" xml:space="preserve"><value>Le répertoire n'a pas été sauvegardé</value></data> + <data name="ScanPreliminaryInconsistent" xml:space="preserve"><value>L'analyse préliminaire montre que l'installation est dans un état incohérent. +Utilisez ckan.exe scan pour plus de détails +Exécution de {0} au cas où cela réglerai le problème.</value></data> + <data name="FilterListGlobalHeader" xml:space="preserve"><value>Filtres globaux :</value></data> + <data name="FilterListInstanceHeader" xml:space="preserve"><value>Filtre d'instance Instance :</value></data> + <data name="FilterAddGlobalDuplicateError" xml:space="preserve"><value>Filtres globaux existant déjà : {0}</value></data> + <data name="FilterAddInstanceDuplicateError" xml:space="preserve"><value>Filtres d'instance existant déjà : {0}</value></data> + <data name="FilterRemoveGlobalNotFoundError" xml:space="preserve"><value>Filtres globaux introuvables : {0}</value></data> + <data name="FilterRemoveInstanceNotFoundError" xml:space="preserve"><value>Filtres d'instance introuvables : {0}</value></data> + <data name="FilterHelpSummary" xml:space="preserve"><value>Afficher ou modifier les filtres d'installation</value></data> +</root> diff --git a/Cmdline/Properties/Resources.resx b/Cmdline/Properties/Resources.resx new file mode 100644 index 0000000000..10ab523c94 --- /dev/null +++ b/Cmdline/Properties/Resources.resx @@ -0,0 +1,372 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="Usage" xml:space="preserve"><value>Usage</value></data> + <data name="Command" xml:space="preserve"><value>command</value></data> + <data name="UnknownCommand" xml:space="preserve"><value>Unknown command</value></data> + <data name="Options" xml:space="preserve"><value>options</value></data> + <data name="ArgumentMissing" xml:space="preserve"><value>argument missing, perhaps you forgot it?</value></data> + <data name="Path" xml:space="preserve"><value>path</value></data> + <data name="MainVersion" xml:space="preserve"><value>You are using CKAN version {0}</value></data> + <data name="MainUnknownCommand" xml:space="preserve"><value>Unknown command, try --help</value></data> + <data name="MainMissingInstance" xml:space="preserve"><value>I don't know where a game instance is installed. +Use 'ckan instance help' for assistance in setting this.</value></data> + <data name="OptionsRootError" xml:space="preserve"><value>You are trying to run CKAN as root. +This is a bad idea and there is absolutely no good reason to do it. Please run CKAN from a user account (or use --asroot if you are feeling brave).</value></data> + <data name="OptionsRootWarning" xml:space="preserve"><value>Warning: Running CKAN as root!</value></data> + <data name="OptionsMonoWarning" xml:space="preserve"><value>Warning. Detected mono runtime of {0} is less than the recommended version of {1}. +Update recommended!</value></data> + <data name="OptionsInstanceAndGameDir" xml:space="preserve"><value>--instance and --gamedir can't be specified at the same time</value></data> + <data name="OptionsInvalidInstance" xml:space="preserve"><value>Invalid game instance specified "{0}", use '--gamedir' to specify by path, or 'instance list' to see known game instances</value></data> + <data name="InstanceNotInstance" xml:space="preserve"><value>Sorry, {0} does not appear to be a game instance</value></data> + <data name="InstanceDuplicate" xml:space="preserve"><value>This instance name is already taken: {0}</value></data> + <data name="UserYesNoPromptSuffix" xml:space="preserve"><value>[Y/n]</value></data> + <data name="UserYesNoY" xml:space="preserve"><value>y</value></data> + <data name="UserYesNoYes" xml:space="preserve"><value>yes</value></data> + <data name="UserYesNoN" xml:space="preserve"><value>n</value></data> + <data name="UserYesNoNo" xml:space="preserve"><value>no</value></data> + <data name="UserYesNoInvalid" xml:space="preserve"><value>Invalid input. Please enter yes or no</value></data> + <data name="UserSelectionPromptWithDefault" xml:space="preserve"><value>Enter a number between {0} and {1} (To cancel press "c" or "n". "Enter" will select {2}.): </value></data> + <data name="UserSelectionPromptWithoutDefault" xml:space="preserve"><value>Enter a number between {0} and {1} (To cancel press "c" or "n".): </value></data> + <data name="UserSelectionC" xml:space="preserve"><value>c</value></data> + <data name="UserSelectionN" xml:space="preserve"><value>n</value></data> + <data name="UserSelectionCancelled" xml:space="preserve"><value>Selection cancelled</value></data> + <data name="UserSelectionNotNumber" xml:space="preserve"><value>The input is not a number</value></data> + <data name="UserSelectionTooLarge" xml:space="preserve"><value>The number in the input is too large</value></data> + <data name="UserSelectionTooSmall" xml:space="preserve"><value>The number in the input is too small</value></data> + <data name="AuthTokenHostHeader" xml:space="preserve"><value>Host</value></data> + <data name="AuthTokenTokenHeader" xml:space="preserve"><value>Token</value></data> + <data name="AuthTokenHelpSummary" xml:space="preserve"><value>Manage authentication tokens</value></data> + <data name="AvailableHeader" xml:space="preserve"><value>Modules compatible with {0} {1}</value></data> + <data name="CacheHelpSummary" xml:space="preserve"><value>Manage the download cache path of CKAN</value></data> + <data name="CacheSet" xml:space="preserve"><value>Download cache set to {0}</value></data> + <data name="CacheInvalidPath" xml:space="preserve"><value>Invalid path: {0}</value></data> + <data name="CacheCleared" xml:space="preserve"><value>Download cache cleared</value></data> + <data name="CacheReset" xml:space="preserve"><value>Download cache reset to {0}</value></data> + <data name="CacheResetFailed" xml:space="preserve"><value>Can't reset cache path: {0}</value></data> + <data name="CacheUnlimited" xml:space="preserve"><value>Unlimited</value></data> + <data name="CacheInfo" xml:space="preserve"><value>{0} files, {1}</value></data> + <data name="CompareSame" xml:space="preserve"><value>"{0}" and "{1}" are the same versions.</value></data> + <data name="CompareLower" xml:space="preserve"><value>"{0}" is lower than "{1}".</value></data> + <data name="CompareHigher" xml:space="preserve"><value>"{0}" is higher than "{1}".</value></data> + <data name="CompatHelpSummary" xml:space="preserve"><value>Manage game version compatibility</value></data> + <data name="CompatVersionHeader" xml:space="preserve"><value>Version</value></data> + <data name="CompatActualHeader" xml:space="preserve"><value>Actual</value></data> + <data name="CompatInvalid" xml:space="preserve"><value>ERROR: Invalid game version</value></data> + <data name="CompatCantForget" xml:space="preserve"><value>ERROR: Cannot forget actual game version</value></data> + <data name="InstanceHelpSummary" xml:space="preserve"><value>Manage game instances</value></data> + <data name="InstanceListNoVersion" xml:space="preserve"><value><NONE></value></data> + <data name="InstanceListYes" xml:space="preserve"><value>Yes</value></data> + <data name="InstanceListNo" xml:space="preserve"><value>No</value></data> + <data name="InstanceListNameHeader" xml:space="preserve"><value>Name</value></data> + <data name="InstanceListVersionHeader" xml:space="preserve"><value>Version</value></data> + <data name="InstanceListDefaultHeader" xml:space="preserve"><value>Default</value></data> + <data name="InstanceListPathHeader" xml:space="preserve"><value>Path</value></data> + <data name="InstanceAddDuplicate" xml:space="preserve"><value>Install with name "{0}" already exists, aborting</value></data> + <data name="InstanceAdded" xml:space="preserve"><value>Added "{0}" with root "{1}" to known installs</value></data> + <data name="InstanceCloneNotFound" xml:space="preserve"><value>No instance with this name or at this path: {0} +See below for a list of known instances: +</value></data> + <data name="InstanceCloneFailed" xml:space="preserve"><value>Something went wrong. Please look if the new directory has been created. +Try to add the new instance manually with "ckan instance add". +</value></data> + <data name="InstanceNotFound" xml:space="preserve"><value>Couldn't find install with name "{0}", aborting</value></data> + <data name="InstanceRenamed" xml:space="preserve"><value>Successfully renamed "{0}" to "{1}"</value></data> + <data name="InstanceForgot" xml:space="preserve"><value>Successfully Removed "{0}"</value></data> + <data name="InstanceDefaultArgumentMissing" xml:space="preserve"><value>argument missing, please select from the list below</value></data> + <data name="InstanceDefaultSet" xml:space="preserve"><value>Successfully set "{0}" as the default game instance</value></data> + <data name="InstanceFakeFailed" xml:space="preserve"><value>Something went wrong. Try to add the instance yourself with "ckan instance add". Also look if the new directory has been created.</value></data> + <data name="InstanceFakeBadArguments" xml:space="preserve"><value>--Error: bad argument(s)--</value></data> + <data name="InstanceFakeMakingHistory" xml:space="preserve"><value>Please check the Making History DLC version argument - Format it like Maj.Min.Patch - e.g. 1.1.0</value></data> + <data name="InstanceFakeBreakingGround" xml:space="preserve"><value>Please check the Breaking Ground DLC version argument - Format it like Maj.Min.Patch - e.g. 1.1.0</value></data> + <data name="InstanceFakeVersion" xml:space="preserve"><value>Please check the version argument - Format it like Maj.Min.Patch[.Build] - e.g. 1.6.0 or 1.2.2.1622</value></data> + <data name="InstanceFakeBadGameVersion" xml:space="preserve"><value>Couldn't find a valid game version for your input. +Make sure to enter at least the version major and minor values in the form Maj.Min - e.g. 1.5</value></data> + <data name="InstanceFakeCancelled" xml:space="preserve"><value>Selection cancelled! Please call 'ckan instance fake' again</value></data> + <data name="InstanceFakeCreating" xml:space="preserve"><value>Creating new fake game instance {0} at {1} with version {2}</value></data> + <data name="InstanceFakeDefault" xml:space="preserve"><value>Setting new instance to default...</value></data> + <data name="InstanceFakeDone" xml:space="preserve"><value>--Done--</value></data> + <data name="ImportError" xml:space="preserve"><value>Import error: {0}</value></data> + <data name="ImportNotFound" xml:space="preserve"><value>File not found: {0}</value></data> + <data name="InstallNotFound" xml:space="preserve"><value>File not found, exiting: {0}</value></data> + <data name="InstallTryAgain" xml:space="preserve"><value>If you're lucky, you can do a `ckan update` and try again. +Try `ckan install --no-recommends` to skip installation of recommended modules. +Or `ckan install --allow-incompatible` to ignore module compatibility.</value></data> + <data name="InstallUnversionedDependencyNotSatisfied" xml:space="preserve"><value>Module {0} required but it is not listed in the index, or not available for your version of {1}</value></data> + <data name="InstallVersionedDependencyNotSatisfied" xml:space="preserve"><value>Module {0} {1} required but it is not listed in the index, or not available for your version of {2}</value></data> + <data name="InstallBadMetadata" xml:space="preserve"><value>Bad metadata detected for module {0}: {1}</value></data> + <data name="InstallFileConflictOwned" xml:space="preserve"><value>Oh no! We tried to overwrite a file owned by another mod! +Please try a `ckan update` and try again. + +If this problem re-occurs, then it maybe a packaging bug. +Please report it at: + +https://github.com/KSP-CKAN/NetKAN/issues/new + +Please including the following information in your report: + +File : {0} +Installing Mod : {1} +Owning Mod : {2} +CKAN Version : {3} +</value></data> + <data name="InstallFileConflictUnowned" xml:space="preserve"><value>Oh no! + +It looks like you're trying to install a mod which is already installed, +or which conflicts with another mod which is already installed. + +As a safety feature, CKAN will *never* overwrite or alter a file +that it did not install itself. + +If you wish to install {0} via CKAN, +then please manually uninstall the mod which owns: + +{1} + +and try again. +</value></data> + <data name="InstallGamedataReturned" xml:space="preserve"><value>Your {0} has been returned to its original state</value></data> + <data name="InstallCancelled" xml:space="preserve"><value>Install canceled. Your files have been returned to their initial state.</value></data> + <data name="InstallAborted" xml:space="preserve"><value>Installation aborted: {0}</value></data> + <data name="InstallTryAuthToken" xml:space="preserve"><value>Try the authtoken command. See {0} for details.</value></data> + <data name="InstallDownloadFailed" xml:space="preserve"><value>One or more files failed to download, stopped</value></data> + <data name="InstallDLC" xml:space="preserve"><value>CKAN can't install expansion '{0}' for you.</value></data> + <data name="InstallDLCStorePage" xml:space="preserve"><value>To install this expansion, purchase it from one of its store pages: +{0}</value></data> + <data name="ListUnknownFormat" xml:space="preserve"><value>Unknown export format: {0}</value></data> + <data name="ListGameFound" xml:space="preserve"><value>{0} found at: {1}</value></data> + <data name="ListGameVersion" xml:space="preserve"><value>{0} version: {1}</value></data> + <data name="ListGameModulesHeader" xml:space="preserve"><value>Installed modules:</value></data> + <data name="ListLegend" xml:space="preserve"><value>Legend: -: Up to date. +:Auto-installed. X: Incompatible. ^: Upgradable. >: Replaceable + A: Autodetected. ?: Unknown. *: Broken.</value></data> + <data name="MarkHelpSummary" xml:space="preserve"><value>Edit flags on modules</value></data> + <data name="MarkUnknownCommand" xml:space="preserve"><value>Unknown command: mark {0}</value></data> + <data name="MarkNotInstalled" xml:space="preserve"><value>{0} is not installed</value></data> + <data name="MarkAlready" xml:space="preserve"><value>{0} is already marked as {1}</value></data> + <data name="Marking" xml:space="preserve"><value>Marking {0} as {1}...</value></data> + <data name="MarkDLC" xml:space="preserve"><value>Can't mark expansion '{0}' as auto-installed</value></data> + <data name="MarkChanged" xml:space="preserve"><value>Changes made!</value></data> + <data name="MarkAutoInstalled" xml:space="preserve"><value>auto-installed</value></data> + <data name="MarkUserSelected" xml:space="preserve"><value>user-selected</value></data> + <data name="PromptWelcome" xml:space="preserve"><value>Welcome to CKAN! + +To get help, type help and press enter. To quit, type {0} and press enter. +Press tab to auto-complete commands and modules. +</value></data> + <data name="PromptWithInstance" xml:space="preserve"><value>CKAN {0}: {1} {2} ({3})> </value></data> + <data name="PromptWithoutInstance" xml:space="preserve"><value>CKAN {0}> </value></data> + <data name="RemoveNotInstalled" xml:space="preserve"><value>I can't do that, {0} isn't installed. +Try `ckan list` for a list of installed mods.</value></data> + <data name="RemoveDLC" xml:space="preserve"><value>CKAN can't remove expansion '{0}' for you.</value></data> + <data name="RemoveDLCStorePage" xml:space="preserve"><value>To remove this expansion, follow the instructions for the store page from which you purchased it: +{0}</value></data> + <data name="RemoveCancelled" xml:space="preserve"><value>Remove aborted: {0}</value></data> + <data name="RemoveNothing" xml:space="preserve"><value>No mod selected, nothing to do</value></data> + <data name="RepairHelpSummary" xml:space="preserve"><value>Attempt various automatic repairs</value></data> + <data name="RepairUnknownCommand" xml:space="preserve"><value>Unknown command: repair {0}</value></data> + <data name="Repaired" xml:space="preserve"><value>Registry repairs attempted. Hope it helped.</value></data> + <data name="ReplaceModuleNotFound" xml:space="preserve"><value>Module {0} not found</value></data> + <data name="Replacing" xml:space="preserve"><value>Replacing modules...</value></data> + <data name="ReplaceFound" xml:space="preserve"><value>Replacement {0} {1} found for {2} {3}</value></data> + <data name="ReplaceContinuePrompt" xml:space="preserve"><value>Continue?</value></data> + <data name="ReplaceCancelled" xml:space="preserve"><value>Replacements canceled at user request</value></data> + <data name="ReplaceDependencyNotSatisfied" xml:space="preserve"><value>Dependencies not satisfied for replacement, {0} requires {1} {2} but it is not listed in the index, or not available for your version of {3}</value></data> + <data name="ReplaceNotFound" xml:space="preserve"><value>No replacements found</value></data> + <data name="RepoHelpSummary" xml:space="preserve"><value>Manage CKAN repositories</value></data> + <data name="RepoUnknownCommand" xml:space="preserve"><value>Unknown command: repo {0}</value></data> + <data name="RepoAvailableHeader" xml:space="preserve"><value>Listing all (canonical) available CKAN repositories:</value></data> + <data name="RepoAvailableFailed" xml:space="preserve"><value>Couldn't fetch CKAN repositories master list from {0}</value></data> + <data name="RepoListHeader" xml:space="preserve"><value>Listing all known repositories:</value></data> + <data name="RepoAddNotFound" xml:space="preserve"><value>Name {0} not found in master list, please provide name and uri</value></data> + <data name="RepoAddDuplicate" xml:space="preserve"><value>Repository with name "{0}" already exists, aborting</value></data> + <data name="RepoAdded" xml:space="preserve"><value>Added repository '{0}' - '{1}'</value></data> + <data name="RepoForgetNotFound" xml:space="preserve"><value>Couldn't find repository with name "{0}", aborting</value></data> + <data name="RepoForgetRemoving" xml:space="preserve"><value>Removing insensitive match "{0}"</value></data> + <data name="RepoForgetRemoved" xml:space="preserve"><value>Successfully removed "{0}"</value></data> + <data name="RepoSet" xml:space="preserve"><value>Set {0} repository to '{1}'</value></data> + <data name="SearchNoTerm" xml:space="preserve"><value>No search term?</value></data> + <data name="SearchFoundByAuthorWithIncompat" xml:space="preserve"><value>Found {0} compatible and {1} incompatible mods matching "{2}" by "{3}"</value></data> + <data name="SearchFoundWithIncompat" xml:space="preserve"><value>Found {0} compatible and {1} incompatible mods matching "{2}"</value></data> + <data name="SearchFoundByAuthor" xml:space="preserve"><value>Found {0} compatible mods matching "{1}" by "{2}"</value></data> + <data name="SearchFound" xml:space="preserve"><value>Found {0} compatible mods matching "{1}"</value></data> + <data name="SearchCompatibleModsHeader" xml:space="preserve"><value>Matching compatible mods:</value></data> + <data name="SearchCompatibleMod" xml:space="preserve"><value>* {0} ({1}) - {2} by {3} - {4}</value></data> + <data name="SearchIncompatibleModsHeader" xml:space="preserve"><value>Matching incompatible mods:</value></data> + <data name="SearchIncompatibleMod" xml:space="preserve"><value>* {0} ({1} - {2}) - {3} by {4} - {5}</value></data> + <data name="ShowNotInstalledOrCompatible" xml:space="preserve"><value>{0} not installed or compatible with {1} {2}</value></data> + <data name="ShowLookingForClose" xml:space="preserve"><value>Looking for close matches in compatible mods...</value></data> + <data name="ShowNoClose" xml:space="preserve"><value>No close matches found</value></data> + <data name="ShowFoundOne" xml:space="preserve"><value>Found 1 close match: {0}</value></data> + <data name="ShowClosePrompt" xml:space="preserve"><value>Close matches:</value></data> + <data name="ShowFilesHeader" xml:space="preserve"><value>Showing {0} installed files:</value></data> + <data name="ShowModuleInfoHeader" xml:space="preserve"><value>Module info:</value></data> + <data name="ShowVersion" xml:space="preserve"><value> Version: {0}</value></data> + <data name="ShowAuthor" xml:space="preserve"><value> Authors: {0}</value></data> + <data name="ShowAuthorUnknown" xml:space="preserve"><value> Authors: UNKNOWN</value></data> + <data name="ShowStatus" xml:space="preserve"><value> Status: {0}</value></data> + <data name="ShowLicence" xml:space="preserve"><value> Licence: {0}</value></data> + <data name="ShowTags" xml:space="preserve"><value> Tags: {0}</value></data> + <data name="ShowLanguages" xml:space="preserve"><value> Languages: {0}</value></data> + <data name="ShowDependsHeader" xml:space="preserve"><value>Depends:</value></data> + <data name="ShowRecommendsHeader" xml:space="preserve"><value>Recommends:</value></data> + <data name="ShowSuggestsHeader" xml:space="preserve"><value>Suggests:</value></data> + <data name="ShowProvidesHeader" xml:space="preserve"><value>Provides:</value></data> + <data name="ShowResourcesHeader" xml:space="preserve"><value>Resources:</value></data> + <data name="ShowHomePage" xml:space="preserve"><value> Home page: {0}</value></data> + <data name="ShowManual" xml:space="preserve"><value> Manual: {0}</value></data> + <data name="ShowSpaceDock" xml:space="preserve"><value> SpaceDock: {0}</value></data> + <data name="ShowRepository" xml:space="preserve"><value> Repository: {0}</value></data> + <data name="ShowBugTracker" xml:space="preserve"><value> Bug tracker: {0}</value></data> + <data name="ShowCurse" xml:space="preserve"><value> Curse: {0}</value></data> + <data name="ShowStore" xml:space="preserve"><value> Store: {0}</value></data> + <data name="ShowSteamStore" xml:space="preserve"><value> Steam store: {0}</value></data> + <data name="ShowVersionFile" xml:space="preserve"><value> Version file: {0}</value></data> + <data name="ShowFileName" xml:space="preserve"><value>Filename: {0}</value></data> + <data name="ShowVersionHeader" xml:space="preserve"><value>Version</value></data> + <data name="ShowGameVersionsHeader" xml:space="preserve"><value>Game Versions</value></data> + <data name="UpdateChangesSummary" xml:space="preserve"><value>Found {0} new modules, {1} removed modules and {2} updated modules</value></data> + <data name="UpdateAddedHeader" xml:space="preserve"><value>New modules [Name (CKAN identifier)]:</value></data> + <data name="UpdateRemovedHeader" xml:space="preserve"><value>Removed modules [Name (CKAN identifier)]:</value></data> + <data name="UpdateUpdatedHeader" xml:space="preserve"><value>Updated modules [Name (CKAN identifier)]:</value></data> + <data name="UpdateSummary" xml:space="preserve"><value>Updated information on {0} compatible modules</value></data> + <data name="UpgradeQueryingCKAN" xml:space="preserve"><value>Querying the latest CKAN version</value></data> + <data name="UpgradeNewCKANAvailable" xml:space="preserve"><value>New CKAN version available - {0}</value></data> + <data name="UpgradeProceed" xml:space="preserve"><value>Proceed with install?</value></data> + <data name="UpgradePleaseWait" xml:space="preserve"><value>Upgrading CKAN, please wait...</value></data> + <data name="UpgradeAlreadyHaveLatest" xml:space="preserve"><value>You already have the latest version</value></data> + <data name="UpgradeAborted" xml:space="preserve"><value>Upgrade aborted: {0}</value></data> + <data name="UpgradeNotFound" xml:space="preserve"><value>Module {0} not found</value></data> + <data name="UpgradeDLC" xml:space="preserve"><value>CKAN can't upgrade expansion '{0}' for you</value></data> + <data name="UpgradeDLCStorePage" xml:space="preserve"><value>To upgrade this expansion, download any updates from the store page from which you purchased it: +{0}</value></data> + <data name="ScanNotSaved" xml:space="preserve"><value>The repo has not been saved</value></data> + <data name="ScanPreliminaryInconsistent" xml:space="preserve"><value>Preliminary scanning shows that the install is in a inconsistent state. +Use ckan.exe scan for more details +Proceeding with {0} in case it fixes it.</value></data> + <data name="FilterListGlobalHeader" xml:space="preserve"><value>Global filters:</value></data> + <data name="FilterListInstanceHeader" xml:space="preserve"><value>Instance filters:</value></data> + <data name="FilterAddGlobalDuplicateError" xml:space="preserve"><value>Global filters already set: {0}</value></data> + <data name="FilterAddInstanceDuplicateError" xml:space="preserve"><value>Instance filters already set: {0}</value></data> + <data name="FilterRemoveGlobalNotFoundError" xml:space="preserve"><value>Global filters not found: {0}</value></data> + <data name="FilterRemoveInstanceNotFoundError" xml:space="preserve"><value>Instance filters not found: {0}</value></data> + <data name="FilterHelpSummary" xml:space="preserve"><value>View or edit installation filters</value></data> + <data name="CompletionNotAvailable" xml:space="preserve"><value> +No game instance selected, identifier completion not available. +Use the `instance default` command to choose an instance.</value></data> +</root> diff --git a/Cmdline/Properties/Resources.ru-RU.resx b/Cmdline/Properties/Resources.ru-RU.resx new file mode 100644 index 0000000000..8197cf96bc --- /dev/null +++ b/Cmdline/Properties/Resources.ru-RU.resx @@ -0,0 +1,361 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="Usage" xml:space="preserve"><value>Использование</value></data> + <data name="Command" xml:space="preserve"><value>команда</value></data> + <data name="UnknownCommand" xml:space="preserve"><value>Неизвестная команда</value></data> + <data name="Options" xml:space="preserve"><value>параметры</value></data> + <data name="ArgumentMissing" xml:space="preserve"><value>отсутствует параметр</value></data> + <data name="Path" xml:space="preserve"><value>путь</value></data> + <data name="MainVersion" xml:space="preserve"><value>Вы используете CKAN версии {0}</value></data> + <data name="MainUnknownCommand" xml:space="preserve"><value>Неизвестная команда, --help для справки</value></data> + <data name="MainMissingInstance" xml:space="preserve"><value>CKAN не знает, где установлена сборка игры. +Используйте 'ckan instance help' для справки.</value></data> + <data name="OptionsRootError" xml:space="preserve"><value>Вы пытаетесь запустить CKAN с правами администратора. +Пожалуйста, запускайте CKAN с правами обычного пользователя (либо, если это действительно необходимо, используйте --asroot).</value></data> + <data name="OptionsRootWarning" xml:space="preserve"><value>Внимание: CKAN запущен с правами администратора!</value></data> + <data name="OptionsMonoWarning" xml:space="preserve"><value>Винмание. Обнаруженная версия mono {0} ниже, чем рекомендуемая версия {1}. +Рекомендовано обновление!</value></data> + <data name="OptionsInstanceAndGameDir" xml:space="preserve"><value>--instance и --gamedir не могут быть заданы в одно и то же время</value></data> + <data name="OptionsInvalidInstance" xml:space="preserve"><value>Указана неверная сборка "{0}", используйте '--gamedir' для указания пути, либо 'instance list' для просмотра сборок игры</value></data> + <data name="InstanceNotInstance" xml:space="preserve"><value>Извините, {0} не являтся сборкой игры</value></data> + <data name="InstanceDuplicate" xml:space="preserve"><value>Данное имя сборки уже занято: {0}</value></data> + <data name="UserYesNoPromptSuffix" xml:space="preserve"><value>[Д/н]</value></data> + <data name="UserYesNoY" xml:space="preserve"><value>д</value></data> + <data name="UserYesNoYes" xml:space="preserve"><value>да</value></data> + <data name="UserYesNoN" xml:space="preserve"><value>н</value></data> + <data name="UserYesNoNo" xml:space="preserve"><value>нет</value></data> + <data name="UserYesNoInvalid" xml:space="preserve"><value>Пожалуйста, введите «да» или «нет»</value></data> + <data name="UserSelectionPromptWithDefault" xml:space="preserve"><value>Введите число между {0} и {1} (Для отмены нажмите "о" или "н". "Enter" выберет {2}.): </value></data> + <data name="UserSelectionPromptWithoutDefault" xml:space="preserve"><value>Введите число между {0} и {1} (Для отмены нажмите "о" или "н".): </value></data> + <data name="UserSelectionC" xml:space="preserve"><value>о</value></data> + <data name="UserSelectionN" xml:space="preserve"><value>н</value></data> + <data name="UserSelectionCancelled" xml:space="preserve"><value>Выбор отменён</value></data> + <data name="UserSelectionNotNumber" xml:space="preserve"><value>Введенное значение не является числом</value></data> + <data name="UserSelectionTooLarge" xml:space="preserve"><value>Введённое число слишком велико</value></data> + <data name="UserSelectionTooSmall" xml:space="preserve"><value>Введённое число слишком мало</value></data> + <data name="AuthTokenHostHeader" xml:space="preserve"><value>Хост</value></data> + <data name="AuthTokenTokenHeader" xml:space="preserve"><value>Токен</value></data> + <data name="AuthTokenHelpSummary" xml:space="preserve"><value>Управление токенами аутентификации</value></data> + <data name="AvailableHeader" xml:space="preserve"><value>Модули, совместимые с {0} {1}</value></data> + <data name="CacheHelpSummary" xml:space="preserve"><value>Управление папкой кэша загрузок CKAN</value></data> + <data name="CacheSet" xml:space="preserve"><value>Кэш загрузок находится в {0}</value></data> + <data name="CacheInvalidPath" xml:space="preserve"><value>Неверный путь: {0}</value></data> + <data name="CacheCleared" xml:space="preserve"><value>Кэш загрузок очищен</value></data> + <data name="CacheReset" xml:space="preserve"><value>Кэш загрузок сброшен в {0}</value></data> + <data name="CacheResetFailed" xml:space="preserve"><value>Не удалось сбросить путь к кэшу: {0}</value></data> + <data name="CacheUnlimited" xml:space="preserve"><value>Неограничено</value></data> + <data name="CacheInfo" xml:space="preserve"><value>{0} файлов, {1}</value></data> + <data name="CompareSame" xml:space="preserve"><value>"{0}" и "{1}" одинаковы.</value></data> + <data name="CompareLower" xml:space="preserve"><value>"{0}" ниже, чем "{1}".</value></data> + <data name="CompareHigher" xml:space="preserve"><value>"{0}" выше, чем "{1}".</value></data> + <data name="CompatHelpSummary" xml:space="preserve"><value>Управление версиями игры</value></data> + <data name="CompatVersionHeader" xml:space="preserve"><value>Версия</value></data> + <data name="CompatActualHeader" xml:space="preserve"><value>Актуальная</value></data> + <data name="CompatInvalid" xml:space="preserve"><value>ОШИБКА: Неверно указана версия игры</value></data> + <data name="CompatCantForget" xml:space="preserve"><value>ОШИБКА: Не удалось забыть актуальную версию игры</value></data> + <data name="InstanceHelpSummary" xml:space="preserve"><value>Управление сборками игры</value></data> + <data name="InstanceListNoVersion" xml:space="preserve"><value><НЕТ></value></data> + <data name="InstanceListYes" xml:space="preserve"><value>Да</value></data> + <data name="InstanceListNo" xml:space="preserve"><value>Нет</value></data> + <data name="InstanceListNameHeader" xml:space="preserve"><value>Имя</value></data> + <data name="InstanceListVersionHeader" xml:space="preserve"><value>Версия</value></data> + <data name="InstanceListDefaultHeader" xml:space="preserve"><value>По умолч.</value></data> + <data name="InstanceListPathHeader" xml:space="preserve"><value>Путь</value></data> + <data name="InstanceAddDuplicate" xml:space="preserve"><value>Сборка с именем "{0}" уже существует, операция не выполнена</value></data> + <data name="InstanceAdded" xml:space="preserve"><value>Добавлена "{0}" с корнем "{1}"</value></data> + <data name="InstanceCloneNotFound" xml:space="preserve"><value>Не найдено сборок с таким именем или по такому пути: {0} +Проверьте список известных сборок: +</value></data> + <data name="InstanceCloneFailed" xml:space="preserve"><value>Что-то пошло не так. Проверьте, произошло ли создание новой папки. +Попробуйте вручную добавить сборку с помощью "ckan instance add". +</value></data> + <data name="InstanceNotFound" xml:space="preserve"><value>Не удалось найти сборку с именем "{0}", операция не выполнена</value></data> + <data name="InstanceRenamed" xml:space="preserve"><value>Сборка "{0}" переименована в "{1}"</value></data> + <data name="InstanceForgot" xml:space="preserve"><value>Сборка "{0}" удалена</value></data> + <data name="InstanceDefaultArgumentMissing" xml:space="preserve"><value>отсуствует параметр, выберите из списка ниже</value></data> + <data name="InstanceDefaultSet" xml:space="preserve"><value>"{0}" установлена как сборка по умолчанию</value></data> + <data name="InstanceFakeFailed" xml:space="preserve"><value>Что-то пошло не так. Попробуйте вручную добавить сборку с помощью "ckan instance add". Проверьте, была ли создана новая папка.</value></data> + <data name="InstanceFakeBadArguments" xml:space="preserve"><value>--Ошибка: неверный(-е) параметр(-ы)--</value></data> + <data name="InstanceFakeMakingHistory" xml:space="preserve"><value>Проверьте параметр версии DLC Making History - правильный формат: Maj.Min.Patch - пример: 1.1.0</value></data> + <data name="InstanceFakeBreakingGround" xml:space="preserve"><value>Проверьте параметр версии DLC Breaking Ground - правильный формат: Maj.Min.Patch - пример: 1.1.0</value></data> + <data name="InstanceFakeVersion" xml:space="preserve"><value>Проверьте параметр версии игры - правильный формат: Maj.Min.Patch[.Build] - пример: 1.6.0 или 1.2.2.1622</value></data> + <data name="InstanceFakeBadGameVersion" xml:space="preserve"><value>Не удалось найти соответствующую версию игры. +Проверьте формат введённой версии - правильный формат: Maj.Min - пример: 1.5</value></data> + <data name="InstanceFakeCancelled" xml:space="preserve"><value>Выбор отменён! Снова вызовите 'ckan instance fake'</value></data> + <data name="InstanceFakeCreating" xml:space="preserve"><value>Создание новой псевдосборки "{0}" по пути {1} с версией {2}</value></data> + <data name="InstanceFakeDefault" xml:space="preserve"><value>Setting new instance to default...</value></data> + <data name="InstanceFakeDone" xml:space="preserve"><value>--Готово--</value></data> + <data name="ImportError" xml:space="preserve"><value>Ошибка импортирования: {0}</value></data> + <data name="ImportNotFound" xml:space="preserve"><value>Файл не найден: {0}</value></data> + <data name="InstallNotFound" xml:space="preserve"><value>Файл не найден, выход: {0}</value></data> + <data name="InstallTryAgain" xml:space="preserve"><value>Попробуйте совершить `ckan update` и попытайтесь заново. +Используйте `ckan install --no-recommends`, чтобы пропустить установку рекомендуемых модулей. +Либо используйте `ckan install --allow-incompatible`, чтобы игнорировать проблемы совместимости.</value></data> + <data name="InstallUnversionedDependencyNotSatisfied" xml:space="preserve"><value>Необходим модуль {0}, но он отсутствует в указателе либо недоступен для вашей версии {1}</value></data> + <data name="InstallVersionedDependencyNotSatisfied" xml:space="preserve"><value>Необходим модуль {0} {1}, но он отсутствует в указателе либо недоступен для вашей версии {2}</value></data> + <data name="InstallBadMetadata" xml:space="preserve"><value>Обнаружены некорректные метаданные для модуля {0}: {1}</value></data> + <data name="InstallFileConflictOwned" xml:space="preserve"><value>О нет! Была произведена попытка перезаписать файл, принадлежащий другой модификации! +Произведите `ckan update` и попытайтесь заново. + +Если проблема повторяется, это может означать ошибку упаковки пакета. +Пожалуйста, отправьте отчёт об ошибке на: + +https://github.com/KSP-CKAN/NetKAN/issues/new + +Включите в отчёт следующую информацию: + +File : {0} (Файл) +Installing Mod : {1} (Устанавливающаяся модификация) +Owning Mod : {2} (Модификация-владелец файла) +CKAN Version : {3} (Версия CKAN) +</value></data> + <data name="InstallFileConflictUnowned" xml:space="preserve"><value>О нет! + +Похоже, что вы пытаетесь установить модификацию, которая уже установлена +или конфликтует с другой уже установленной модификацией. + +В качестве меры безопасности CKAN *никогда* не меняет файлы, +которые не установила сама. + +Если вы хотите установить {0} с помощью CKAN, +вручную удалите модификацию, которой принадлежит файл: + +{1} + +и попытайтесь заново. +</value></data> + <data name="InstallGamedataReturned" xml:space="preserve"><value>{0} возвращена в изначальное состояние</value></data> + <data name="InstallCancelled" xml:space="preserve"><value>Установка отменена. Ваши файлы возвращены в изначальное состояние.</value></data> + <data name="InstallAborted" xml:space="preserve"><value>Установка отменена: {0}</value></data> + <data name="InstallTryAuthToken" xml:space="preserve"><value>Используйте команду authtoken. Используйте {0} для справки.</value></data> + <data name="InstallDownloadFailed" xml:space="preserve"><value>Не удалось загрузить один или несколько файлов, остановка</value></data> + <data name="InstallDLC" xml:space="preserve"><value>CKAN не может установить дополнение '{0}'.</value></data> + <data name="InstallDLCStorePage" xml:space="preserve"><value>Для установки дополнений приобретите их в соответствующем магазине: +{0}</value></data> + <data name="ListUnknownFormat" xml:space="preserve"><value>Неизвестный формат экспорта: {0}</value></data> + <data name="ListGameFound" xml:space="preserve"><value>{0} найден по пути: {1}</value></data> + <data name="ListGameVersion" xml:space="preserve"><value>{0} версия: {1}</value></data> + <data name="ListGameModulesHeader" xml:space="preserve"><value>Установленные модули:</value></data> + <data name="ListLegend" xml:space="preserve"><value>Legend: -: Обновлено. +: Авто-уст. X: Несовместимо. ^: Возм. обнов. >: Есть замена + A: Обнаружено. ?: Неизв. *: Поврежд.</value></data> + <data name="MarkHelpSummary" xml:space="preserve"><value>Изменение флагов модулей</value></data> + <data name="MarkUnknownCommand" xml:space="preserve"><value>Неизвестная команда: mark {0}</value></data> + <data name="MarkNotInstalled" xml:space="preserve"><value>{0} не установлен</value></data> + <data name="MarkAlready" xml:space="preserve"><value>{0} уже отмечен как {1}</value></data> + <data name="Marking" xml:space="preserve"><value>Отметка {0} как {1}...</value></data> + <data name="MarkDLC" xml:space="preserve"><value>Дополнение '{0}' нельзя отметить как авто-устанавливаемое</value></data> + <data name="MarkChanged" xml:space="preserve"><value>Изменения совершены!</value></data> + <data name="MarkAutoInstalled" xml:space="preserve"><value>авто-устанавливаемое</value></data> + <data name="MarkUserSelected" xml:space="preserve"><value>выбранное пользователем</value></data> + <data name="PromptWelcome" xml:space="preserve"><value>Добро пожаловать в CKAN! + +Для справки введите `help` и нажмите Enter. Чтобы выйти, введите {0} и нажмите Enter. +</value></data> + <data name="PromptWithInstance" xml:space="preserve"><value>CKAN {0}: {1} {2} ({3})> </value></data> + <data name="PromptWithoutInstance" xml:space="preserve"><value>CKAN {0}> </value></data> + <data name="RemoveNotInstalled" xml:space="preserve"><value>Невозможно выполнить, {0} не установлена. +Используйте `ckan list` для вывода списка установленных модификаций.</value></data> + <data name="RemoveDLC" xml:space="preserve"><value>CKAN не может удалить дополнение '{0}'.</value></data> + <data name="RemoveDLCStorePage" xml:space="preserve"><value>Чтобы удалить дополнение, следуйте инструкциям на странице магазина, где оно было приобретено: +{0}</value></data> + <data name="RemoveCancelled" xml:space="preserve"><value>Удаление отменено: {0}</value></data> + <data name="RemoveNothing" xml:space="preserve"><value>Не выбрано ни обной модификации</value></data> + <data name="RepairHelpSummary" xml:space="preserve"><value>Способы автоматического восстановления</value></data> + <data name="RepairUnknownCommand" xml:space="preserve"><value>Неизвестная команда: repair {0}</value></data> + <data name="Repaired" xml:space="preserve"><value>Произведена попытка восстановления реестра.</value></data> + <data name="ReplaceModuleNotFound" xml:space="preserve"><value>Модуль {0} не найден</value></data> + <data name="Replacing" xml:space="preserve"><value>Замена модулей...</value></data> + <data name="ReplaceFound" xml:space="preserve"><value>Для {2} {3} найден заменяющий модуль {0} {1}</value></data> + <data name="ReplaceContinuePrompt" xml:space="preserve"><value>Продолжить?</value></data> + <data name="ReplaceCancelled" xml:space="preserve"><value>Операция замены отменена по запросу пользователя</value></data> + <data name="ReplaceDependencyNotSatisfied" xml:space="preserve"><value>Не удовлетворены зависимости для замены, {0} требует {1} {2}, но его нет в указателе либо он недоступен для вашей версии {3}</value></data> + <data name="ReplaceNotFound" xml:space="preserve"><value>Замен не найдено</value></data> + <data name="RepoHelpSummary" xml:space="preserve"><value>Управление репозиториями CKAN</value></data> + <data name="RepoUnknownCommand" xml:space="preserve"><value>Неизвестная команда: repo {0}</value></data> + <data name="RepoAvailableHeader" xml:space="preserve"><value>Все доступные (основные) репозитории CKAN:</value></data> + <data name="RepoAvailableFailed" xml:space="preserve"><value>Не удалось загрузить список репозиториев CKAN из {0}</value></data> + <data name="RepoListHeader" xml:space="preserve"><value>Список известных репозиториев:</value></data> + <data name="RepoAddNotFound" xml:space="preserve"><value>{0} не найден в основном списке, предоставьте имя и URI</value></data> + <data name="RepoAddDuplicate" xml:space="preserve"><value>Репозиторий с именем "{0}" уже существует, операция не выполнена</value></data> + <data name="RepoAdded" xml:space="preserve"><value>Добавлен репозиторий '{0}' - '{1}'</value></data> + <data name="RepoForgetNotFound" xml:space="preserve"><value>Не удалось найти репозиторий с именем "{0}", операция не выполнена</value></data> + <data name="RepoForgetRemoving" xml:space="preserve"><value>Удаление нечувствительного совпадения "{0}"</value></data> + <data name="RepoForgetRemoved" xml:space="preserve"><value>"{0}" успешно удален</value></data> + <data name="RepoSet" xml:space="preserve"><value>Репозиторий {0} установлен в '{1}'</value></data> + <data name="SearchNoTerm" xml:space="preserve"><value>Отсутствует запрос?</value></data> + <data name="SearchFoundByAuthorWithIncompat" xml:space="preserve"><value>Найдено {0} совместимых и {1} несовместимых модификаций, совпадающих с "{2}" от "{3}"</value></data> + <data name="SearchFoundWithIncompat" xml:space="preserve"><value>Найдено {0} совместимых и {1} несовместимых модификаций, совпадающих с "{2}"</value></data> + <data name="SearchFoundByAuthor" xml:space="preserve"><value>Найдено {0} совместимых модификаций, совпадающих с "{1}" от "{2}"</value></data> + <data name="SearchFound" xml:space="preserve"><value>Найдено {0} совместимых модификаций, совпадающих с "{1}"</value></data> + <data name="SearchCompatibleModsHeader" xml:space="preserve"><value>Совпадающие совместимые модификации:</value></data> + <data name="SearchCompatibleMod" xml:space="preserve"><value>* {0} ({1}) - {2} от {3} - {4}</value></data> + <data name="SearchIncompatibleModsHeader" xml:space="preserve"><value>Совпадающие несовместимые модификации:</value></data> + <data name="SearchIncompatibleMod" xml:space="preserve"><value>* {0} ({1} - {2}) - {3} от {4} - {5}</value></data> + <data name="ShowNotInstalledOrCompatible" xml:space="preserve"><value>{0} не установлена или несовместима с {1} {2}</value></data> + <data name="ShowLookingForClose" xml:space="preserve"><value>Поиск совпадений в совместимых модификациях...</value></data> + <data name="ShowNoClose" xml:space="preserve"><value>Совпадений не найдено</value></data> + <data name="ShowFoundOne" xml:space="preserve"><value>Найдено одно совпадение: {0}</value></data> + <data name="ShowClosePrompt" xml:space="preserve"><value>Совпадения:</value></data> + <data name="ShowFilesHeader" xml:space="preserve"><value>Показ {0} установленных файлов:</value></data> + <data name="ShowModuleInfoHeader" xml:space="preserve"><value>Информация о модуле:</value></data> + <data name="ShowVersion" xml:space="preserve"><value> Версия: {0}</value></data> + <data name="ShowAuthor" xml:space="preserve"><value> Авторы: {0}</value></data> + <data name="ShowAuthorUnknown" xml:space="preserve"><value> Авторы: НЕИЗВЕСТНО</value></data> + <data name="ShowStatus" xml:space="preserve"><value> Статус: {0}</value></data> + <data name="ShowLicence" xml:space="preserve"><value> Лицензия: {0}</value></data> + <data name="ShowTags" xml:space="preserve"><value> Теги: {0}</value></data> + <data name="ShowLanguages" xml:space="preserve"><value> Языки: {0}</value></data> + <data name="ShowDependsHeader" xml:space="preserve"><value>Зависит:</value></data> + <data name="ShowRecommendsHeader" xml:space="preserve"><value>Рекоммендует:</value></data> + <data name="ShowSuggestsHeader" xml:space="preserve"><value>Предлагает:</value></data> + <data name="ShowProvidesHeader" xml:space="preserve"><value>Предоставляет:</value></data> + <data name="ShowResourcesHeader" xml:space="preserve"><value>Ресурсы:</value></data> + <data name="ShowHomePage" xml:space="preserve"><value> Страница: {0}</value></data> + <data name="ShowManual" xml:space="preserve"><value> Инструкция: {0}</value></data> + <data name="ShowSpaceDock" xml:space="preserve"><value> SpaceDock: {0}</value></data> + <data name="ShowRepository" xml:space="preserve"><value> Репозиторий: {0}</value></data> + <data name="ShowBugTracker" xml:space="preserve"><value> Багтрекер: {0}</value></data> + <data name="ShowCurse" xml:space="preserve"><value> Curse: {0}</value></data> + <data name="ShowStore" xml:space="preserve"><value> Магазин: {0}</value></data> + <data name="ShowSteamStore" xml:space="preserve"><value> Магазин Steam: {0}</value></data> + <data name="ShowVersionFile" xml:space="preserve"><value> Файл версии: {0}</value></data> + <data name="ShowFileName" xml:space="preserve"><value>Имя файла: {0}</value></data> + <data name="ShowVersionHeader" xml:space="preserve"><value>Версия</value></data> + <data name="ShowGameVersionsHeader" xml:space="preserve"><value>Версии игры</value></data> + <data name="UpdateChangesSummary" xml:space="preserve"><value>Найдено {0} новых модулей, {1} удалённых модулей и {2} обновлённых модулей</value></data> + <data name="UpdateAddedHeader" xml:space="preserve"><value>Новые модули [Имя (идентификатор CKAN)]:</value></data> + <data name="UpdateRemovedHeader" xml:space="preserve"><value>Удалённые модули [Имя (идентификатор CKAN)]:</value></data> + <data name="UpdateUpdatedHeader" xml:space="preserve"><value>Обновлённые модули [Имя (идентификатор CKAN)]:</value></data> + <data name="UpdateSummary" xml:space="preserve"><value>Обновлены сведения о {0} совместимых модулях</value></data> + <data name="UpgradeQueryingCKAN" xml:space="preserve"><value>Запрос последней версии CKAN</value></data> + <data name="UpgradeNewCKANAvailable" xml:space="preserve"><value>Доступна новая версия CKAN - {0}</value></data> + <data name="UpgradeProceed" xml:space="preserve"><value>Продолжить установку?</value></data> + <data name="UpgradePleaseWait" xml:space="preserve"><value>Обновление CKAN, пожалуйста, подождите...</value></data> + <data name="UpgradeAlreadyHaveLatest" xml:space="preserve"><value>Ваша версия уже является последней</value></data> + <data name="UpgradeAborted" xml:space="preserve"><value>Обновление отменено: {0}</value></data> + <data name="UpgradeNotFound" xml:space="preserve"><value>Модуль {0} не найден</value></data> + <data name="UpgradeDLC" xml:space="preserve"><value>CKAN не может обновить дополнение '{0}'u</value></data> + <data name="UpgradeDLCStorePage" xml:space="preserve"><value>Для обновления дополнений загрузите их со страницы магазина, в котором они были приобретены: +{0}</value></data> + <data name="ScanNotSaved" xml:space="preserve"><value>Репозиторий не сохранён</value></data> + <data name="ScanPreliminaryInconsistent" xml:space="preserve"><value>Предварительное сканирование показывает, что сборка находится в несогласованном состоянии. +Используйте ckan.exe для сканирования. +Продолжение использования {0}.</value></data> +</root> diff --git a/Cmdline/SingleAssemblyResourceManager.cs b/Cmdline/SingleAssemblyResourceManager.cs new file mode 100644 index 0000000000..f7345f9aac --- /dev/null +++ b/Cmdline/SingleAssemblyResourceManager.cs @@ -0,0 +1,58 @@ +using System.IO; +using System.Globalization; +using System.Resources; +using System.Collections; +using System.Reflection; +using System.Collections.Generic; + +namespace CKAN.CmdLine +{ + // Thanks and credit to this guy: https://stackoverflow.com/q/1952638/2422988 + + class SingleAssemblyResourceManager : ResourceManager + { + public SingleAssemblyResourceManager(string basename, Assembly assembly) : base(basename, assembly) + { + } + + protected override ResourceSet InternalGetResourceSet(CultureInfo culture, + bool createIfNotExists, bool tryParents) + { + ResourceSet rs; + if (!myResourceSets.TryGetValue(culture, out rs)) + { + // Lazy-load default language (without caring about duplicate assignment in race conditions, no harm done) + if (neutralResourcesCulture == null) + { + neutralResourcesCulture = GetNeutralResourcesLanguage(this.MainAssembly); + } + + // If we're asking for the default language, then ask for the + // invariant (non-specific) resources. + if (neutralResourcesCulture.Equals(culture)) + { + culture = CultureInfo.InvariantCulture; + } + string resourceFileName = GetResourceFileName(culture); + + Stream store = this.MainAssembly.GetManifestResourceStream(resourceFileName); + + // If we found the appropriate resources in the local assembly + if (store != null) + { + rs = new ResourceSet(store); + // Save for later + myResourceSets.Add(culture, rs); + } + else + { + rs = base.InternalGetResourceSet(culture, createIfNotExists, tryParents); + } + } + return rs; + } + + private CultureInfo neutralResourcesCulture; + private Dictionary<CultureInfo, ResourceSet> myResourceSets = new Dictionary<CultureInfo, ResourceSet>(); + } +} diff --git a/ConsoleUI/AuthTokenAddDialog.cs b/ConsoleUI/AuthTokenAddDialog.cs index 03d109dd6c..3d6f606966 100644 --- a/ConsoleUI/AuthTokenAddDialog.cs +++ b/ConsoleUI/AuthTokenAddDialog.cs @@ -15,7 +15,7 @@ public class AuthTokenAddDialog : ConsoleDialog { /// </summary> public AuthTokenAddDialog() : base() { - CenterHeader = () => "Create Authentication Key"; + CenterHeader = () => Properties.Resources.AuthTokenAddTitle; int top = (Console.WindowHeight - height) / 2; SetDimensions(6, top, -6, top + height - 1); @@ -27,7 +27,7 @@ public AuthTokenAddDialog() : base() AddObject(new ConsoleLabel( l + 2, t + 2, l + 2 + labelW, - () => "Host:", + () => Properties.Resources.AuthTokenAddHost, th => th.PopupBg, th => th.PopupFg )); @@ -35,13 +35,13 @@ public AuthTokenAddDialog() : base() hostEntry = new ConsoleField( l + 2 + labelW + wPad, t + 2, r - 3 ) { - GhostText = () => "<Enter a host name>" + GhostText = () => Properties.Resources.AuthTokenAddHostGhostText }; AddObject(hostEntry); AddObject(new ConsoleLabel( l + 2, t + 4, l + 2 + labelW, - () => "Token:", + () => Properties.Resources.AuthTokenAddToken, th => th.PopupBg, th => th.PopupFg )); @@ -49,14 +49,14 @@ public AuthTokenAddDialog() : base() tokenEntry = new ConsoleField( l + 2 + labelW + wPad, t + 4, r - 3 ) { - GhostText = () => "<Enter an authentication token>" + GhostText = () => Properties.Resources.AuthTokenAddTokenGhostText }; AddObject(tokenEntry); - AddTip("Esc", "Cancel"); + AddTip(Properties.Resources.Esc, Properties.Resources.Cancel); AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => false); - AddTip("Enter", "Accept", validKey); + AddTip(Properties.Resources.Enter, Properties.Resources.Accept, validKey); AddBinding(Keys.Enter, (object sender, ConsoleTheme theme) => { if (validKey()) { ServiceLocator.Container.Resolve<IConfiguration>().SetAuthToken(hostEntry.Value, tokenEntry.Value); @@ -81,7 +81,10 @@ private bool validKey() private ConsoleField tokenEntry; private const int wPad = 2; - private const int labelW = 6; + private int labelW => Math.Max(6, Math.Max( + Properties.Resources.AuthTokenAddHost.Length, + Properties.Resources.AuthTokenAddToken.Length + )); private const int height = 7; } diff --git a/ConsoleUI/AuthTokenListScreen.cs b/ConsoleUI/AuthTokenListScreen.cs index d3747252a8..7ead4bb9f5 100644 --- a/ConsoleUI/AuthTokenListScreen.cs +++ b/ConsoleUI/AuthTokenListScreen.cs @@ -18,14 +18,14 @@ public class AuthTokenScreen : ConsoleScreen { public AuthTokenScreen() : base() { mainMenu = new ConsolePopupMenu(new List<ConsoleMenuOption>() { - new ConsoleMenuOption("Make a GitHub API token", "", - "Open the web page for creating GitHub API authentication tokens", + new ConsoleMenuOption(Properties.Resources.AuthTokenListGitHubLink, "", + Properties.Resources.AuthTokenListGitHubLinkTip, true, openGitHubURL) }); AddObject(new ConsoleLabel( 1, 2, -1, - () => "Authentication tokens for downloads:" + () => Properties.Resources.AuthTokenListLabel )); tokenList = new ConsoleListBox<string>( @@ -33,18 +33,18 @@ public AuthTokenScreen() : base() new List<string>(ServiceLocator.Container.Resolve<IConfiguration>().GetAuthTokenHosts()), new List<ConsoleListBoxColumn<string>>() { new ConsoleListBoxColumn<string>() { - Header = "Host", + Header = Properties.Resources.AuthTokenListHostHeader, Width = 20, Renderer = (string s) => s }, new ConsoleListBoxColumn<string>() { - Header = "Token", + Header = Properties.Resources.AuthTokenListTokenHeader, Width = 50, Renderer = (string s) => { string token; return ServiceLocator.Container.Resolve<IConfiguration>().TryGetAuthToken(s, out token) ? token - : missingTokenValue; + : Properties.Resources.AuthTokenListMissingToken; } } }, @@ -54,15 +54,15 @@ public AuthTokenScreen() : base() AddObject(new ConsoleLabel( 3, -1, -1, - () => "NOTE: These values are private! Do not share screenshots of this screen!", + () => Properties.Resources.AuthTokenListWarning, null, th => th.AlertFrameFg )); - AddTip("Esc", "Back"); + AddTip(Properties.Resources.Esc, Properties.Resources.Back); AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => false); - tokenList.AddTip("A", "Add"); + tokenList.AddTip("A", Properties.Resources.Add); tokenList.AddBinding(Keys.A, (object sender, ConsoleTheme theme) => { AuthTokenAddDialog ad = new AuthTokenAddDialog(); ad.Run(theme); @@ -71,7 +71,7 @@ public AuthTokenScreen() : base() return true; }); - tokenList.AddTip("R", "Remove", () => tokenList.Selection != null); + tokenList.AddTip("R", Properties.Resources.Remove, () => tokenList.Selection != null); tokenList.AddBinding(Keys.R, (object sender, ConsoleTheme theme) => { if (tokenList.Selection != null) { ServiceLocator.Container.Resolve<IConfiguration>().SetAuthToken(tokenList.Selection, null); @@ -94,7 +94,7 @@ protected override string LeftHeader() /// </summary> protected override string CenterHeader() { - return "Authentication Tokens"; + return Properties.Resources.AuthTokenListTitle; } private bool openGitHubURL(ConsoleTheme theme) @@ -105,8 +105,7 @@ private bool openGitHubURL(ConsoleTheme theme) private ConsoleListBox<string> tokenList; - private const string missingTokenValue = "<ERROR>"; - private static readonly Uri githubTokenURL = new Uri("https://github.com/settings/tokens"); + private static readonly Uri githubTokenURL = new Uri("https://github.com/settings/tokens"); } } diff --git a/ConsoleUI/CKAN-ConsoleUI.csproj b/ConsoleUI/CKAN-ConsoleUI.csproj index ecbb0b4262..cf61fd57b0 100644 --- a/ConsoleUI/CKAN-ConsoleUI.csproj +++ b/ConsoleUI/CKAN-ConsoleUI.csproj @@ -1,40 +1,28 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project> <PropertyGroup> <AssemblyName>CKAN-ConsoleUI</AssemblyName> <OutputPath>..\_build\out\$(AssemblyName)\$(Configuration)\bin\</OutputPath> <BaseIntermediateOutputPath>..\_build\out\$(AssemblyName)\$(Configuration)\obj\</BaseIntermediateOutputPath> </PropertyGroup> - <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" /> <PropertyGroup> - <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <ProjectGuid>{DA5C7023-9A3B-4204-AE2F-BBA6C388B436}</ProjectGuid> - <OutputType>WinExe</OutputType> - <RootNamespace>CKAN</RootNamespace> + <OutputType>Exe</OutputType> + <RootNamespace>CKAN.ConsoleUI</RootNamespace> + <GenerateAssemblyInfo>false</GenerateAssemblyInfo> + <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> + <Deterministic>true</Deterministic> + <Configurations>Debug;Release</Configurations> + <Prefer32Bit>false</Prefer32Bit> + <LangVersion>7</LangVersion> + <TargetFramework>net45</TargetFramework> <ApplicationIcon>..\assets\ckan.ico</ApplicationIcon> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <FileAlignment>512</FileAlignment> - <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> - <Deterministic>true</Deterministic> - <DocumentationFile>$(OutputPath)$(AssemblyName).xml</DocumentationFile> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> - <Prefer32Bit>false</Prefer32Bit> - <LangVersion>7</LangVersion> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> - <DebugSymbols>true</DebugSymbols> - <DebugType>full</DebugType> - <Optimize>false</Optimize> - <DefineConstants>DEBUG;TRACE</DefineConstants> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> - <DebugType>pdbonly</DebugType> - <Optimize>true</Optimize> - <DefineConstants>TRACE</DefineConstants> + <DocumentationFile>$(OutputPath)$(AssemblyName).xml</DocumentationFile> + <TreatWarningsAsErrors>true</TreatWarningsAsErrors> </PropertyGroup> <ItemGroup> <PackageReference Include="Autofac" Version="4.9.4" /> @@ -45,6 +33,12 @@ <Reference Include="System.ServiceModel" /> <Reference Include="System.Transactions" /> </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\Core\CKAN-core.csproj"> + <Project>{3B9AEA22-FA3B-4E43-9283-EABDD81CF271}</Project> + <Name>CKAN-core</Name> + </ProjectReference> + </ItemGroup> <ItemGroup> <Compile Include="..\_build\meta\GlobalAssemblyVersionInfo.cs"> <Link>Properties\GlobalAssemblyVersionInfo.cs</Link> @@ -52,72 +46,13 @@ <Compile Include="..\GlobalAssemblyInfo.cs"> <Link>Properties\GlobalAssemblyInfo.cs</Link> </Compile> - <Compile Include="AuthTokenAddDialog.cs" /> - <Compile Include="AuthTokenListScreen.cs" /> - <Compile Include="CompatibleVersionDialog.cs" /> - <Compile Include="ConsoleCKAN.cs" /> - <Compile Include="DependencyScreen.cs" /> - <Compile Include="DownloadImportDialog.cs" /> - <Compile Include="ExitScreen.cs" /> - <Compile Include="InstallFilterAddDialog.cs" /> - <Compile Include="InstallFiltersScreen.cs" /> - <Compile Include="InstallScreen.cs" /> - <Compile Include="GameInstanceAddScreen.cs" /> - <Compile Include="GameInstanceEditScreen.cs" /> - <Compile Include="GameInstanceListScreen.cs" /> - <Compile Include="GameInstanceScreen.cs" /> - <Compile Include="ModInfoScreen.cs" /> - <Compile Include="ModListHelpDialog.cs" /> - <Compile Include="ModListScreen.cs" /> - <Compile Include="Program.cs" /> - <Compile Include="ProgressScreen.cs" /> - <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="Properties\Settings.Designer.cs"> - <AutoGen>True</AutoGen> - <DependentUpon>Settings.settings</DependentUpon> - <DesignTimeSharedInput>True</DesignTimeSharedInput> - </Compile> - <Compile Include="RepoAddScreen.cs" /> - <Compile Include="RepoEditScreen.cs" /> - <Compile Include="RepoScreen.cs" /> - <Compile Include="SplashScreen.cs" /> - <Compile Include="Toolkit\ConsoleButton.cs" /> - <Compile Include="Toolkit\ConsoleChoiceDialog.cs" /> - <Compile Include="Toolkit\ConsoleDialog.cs" /> - <Compile Include="Toolkit\ConsoleDoubleFrame.cs" /> - <Compile Include="Toolkit\ConsoleField.cs" /> - <Compile Include="Toolkit\ConsoleFileMultiSelectDialog.cs" /> - <Compile Include="Toolkit\ConsoleFrame.cs" /> - <Compile Include="Toolkit\ConsoleLabel.cs" /> - <Compile Include="Toolkit\ConsoleListBox.cs" /> - <Compile Include="Toolkit\ConsoleMessageDialog.cs" /> - <Compile Include="Toolkit\ConsolePopupMenu.cs" /> - <Compile Include="Toolkit\ConsoleProgressBar.cs" /> - <Compile Include="Toolkit\ConsoleScreen.cs" /> - <Compile Include="Toolkit\ConsoleTextBox.cs" /> - <Compile Include="Toolkit\ConsoleTheme.cs" /> - <Compile Include="Toolkit\Formatting.cs" /> - <Compile Include="Toolkit\Keys.cs" /> - <Compile Include="Toolkit\ScreenContainer.cs" /> - <Compile Include="Toolkit\ScreenObject.cs" /> - <Compile Include="Toolkit\Symbols.cs" /> </ItemGroup> <ItemGroup> <None Include="App.config" /> - <None Include="Properties\Settings.settings"> - <Generator>SettingsSingleFileGenerator</Generator> - <LastGenOutput>Settings.Designer.cs</LastGenOutput> - </None> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\Core\CKAN-core.csproj"> - <Project>{3B9AEA22-FA3B-4E43-9283-EABDD81CF271}</Project> - <Name>CKAN-core</Name> - </ProjectReference> </ItemGroup> - <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" /> <Target Name="BeforeBuild"> <Exec Command="powershell ../build.ps1 Generate-GlobalAssemblyVersionInfo" Condition="!Exists('../_build/meta/GlobalAssemblyVersionInfo.cs') And '$(OS)' == 'Windows_NT'" /> <Exec Command="sh ../build Generate-GlobalAssemblyVersionInfo" Condition="!Exists('../_build/meta/GlobalAssemblyVersionInfo.cs') And '$(OS)' == 'Unix'" /> </Target> -</Project> \ No newline at end of file +</Project> diff --git a/ConsoleUI/CompatibleVersionDialog.cs b/ConsoleUI/CompatibleVersionDialog.cs index f878748de0..dbcd9fc760 100644 --- a/ConsoleUI/CompatibleVersionDialog.cs +++ b/ConsoleUI/CompatibleVersionDialog.cs @@ -30,7 +30,7 @@ public CompatibleVersionDialog(IGame game) : base() options, new List<ConsoleListBoxColumn<GameVersion>>() { new ConsoleListBoxColumn<GameVersion>() { - Header = "Predefined Version", + Header = Properties.Resources.CompatibleVersionsListHeader, Width = r - l - 5, Renderer = v => v.ToString(), Comparer = (v1, v2) => v1.CompareTo(v2) @@ -39,7 +39,7 @@ public CompatibleVersionDialog(IGame game) : base() 0, 0, ListSortDirection.Descending ); AddObject(choices); - choices.AddTip("Enter", "Select version"); + choices.AddTip(Properties.Resources.Enter, Properties.Resources.CompatibleVersionsListAcceptTip); choices.AddBinding(Keys.Enter, (object sender, ConsoleTheme theme) => { choice = choices.Selection; return false; @@ -48,10 +48,10 @@ public CompatibleVersionDialog(IGame game) : base() manualEntry = new ConsoleField( l + 2, b - 2, r - 2 ) { - GhostText = () => "<Enter a version>" + GhostText = () => Properties.Resources.CompatibleVersionsGhostText }; AddObject(manualEntry); - manualEntry.AddTip("Enter", "Accept value", () => GameVersion.TryParse(manualEntry.Value, out choice)); + manualEntry.AddTip(Properties.Resources.Enter, Properties.Resources.CompatibleVersionsEntryAcceptTip, () => GameVersion.TryParse(manualEntry.Value, out choice)); manualEntry.AddBinding(Keys.Enter, (object sender, ConsoleTheme theme) => { if (GameVersion.TryParse(manualEntry.Value, out choice)) { // Good value, done running @@ -62,13 +62,13 @@ public CompatibleVersionDialog(IGame game) : base() } }); - AddTip("Esc", "Cancel"); + AddTip(Properties.Resources.Esc, Properties.Resources.Cancel); AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => { choice = null; return false; }); - CenterHeader = () => "Select Compatible Version"; + CenterHeader = () => Properties.Resources.CompatibleVersionsTitle; } /// <summary> diff --git a/ConsoleUI/ConsoleCKAN.cs b/ConsoleUI/ConsoleCKAN.cs index c8d2dbd38c..779c1c857f 100644 --- a/ConsoleUI/ConsoleCKAN.cs +++ b/ConsoleUI/ConsoleCKAN.cs @@ -48,8 +48,8 @@ public ConsoleCKAN(GameInstanceManager mgr, string themeName, bool debug) } else { - Console.WriteLine("No such theme: {0}", themeName); - Console.WriteLine("Available themes: {0}", string.Join(", ", + Console.WriteLine(Properties.Resources.ThemeNotFound, themeName); + Console.WriteLine(Properties.Resources.ThemeList, string.Join(", ", ConsoleTheme.Themes.Keys.OrderBy(th => th))); } } diff --git a/ConsoleUI/DependencyScreen.cs b/ConsoleUI/DependencyScreen.cs index 4040df4177..3b8349e185 100644 --- a/ConsoleUI/DependencyScreen.cs +++ b/ConsoleUI/DependencyScreen.cs @@ -30,7 +30,7 @@ public DependencyScreen(GameInstanceManager mgr, ChangePlan cp, HashSet<string> AddObject(new ConsoleLabel( 1, 2, -1, - () => "Additional mods are recommended or suggested:" + () => Properties.Resources.RecommendationsLabel )); HashSet<CkanModule> sourceModules = new HashSet<CkanModule>(); @@ -46,30 +46,30 @@ public DependencyScreen(GameInstanceManager mgr, ChangePlan cp, HashSet<string> new List<Dependency>(dependencies.Values), new List<ConsoleListBoxColumn<Dependency>>() { new ConsoleListBoxColumn<Dependency>() { - Header = "Install", + Header = Properties.Resources.RecommendationsInstallHeader, Width = 7, Renderer = (Dependency d) => StatusSymbol(d.module) }, new ConsoleListBoxColumn<Dependency>() { - Header = "Name", + Header = Properties.Resources.RecommendationsNameHeader, Width = 36, Renderer = (Dependency d) => d.module.ToString() }, new ConsoleListBoxColumn<Dependency>() { - Header = "Sources", + Header = Properties.Resources.RecommendationsSourcesHeader, Width = 42, Renderer = (Dependency d) => string.Join(", ", d.dependents) } }, 1, 0, ListSortDirection.Descending ); - dependencyList.AddTip("+", "Toggle"); + dependencyList.AddTip("+", Properties.Resources.Toggle); dependencyList.AddBinding(Keys.Plus, (object sender, ConsoleTheme theme) => { ChangePlan.toggleContains(accepted, dependencyList.Selection.module); return true; }); - dependencyList.AddTip("Ctrl+A", "Select all"); + dependencyList.AddTip($"{Properties.Resources.Ctrl}+A", Properties.Resources.SelectAll); dependencyList.AddBinding(Keys.CtrlA, (object sender, ConsoleTheme theme) => { foreach (var kvp in dependencies) { if (!accepted.Contains(kvp.Key)) { @@ -79,13 +79,13 @@ public DependencyScreen(GameInstanceManager mgr, ChangePlan cp, HashSet<string> return true; }); - dependencyList.AddTip("Ctrl+D", "Deselect all", () => accepted.Count > 0); + dependencyList.AddTip($"{Properties.Resources.Ctrl}+D", Properties.Resources.DeselectAll, () => accepted.Count > 0); dependencyList.AddBinding(Keys.CtrlD, (object sender, ConsoleTheme theme) => { accepted.Clear(); return true; }); - dependencyList.AddTip("Enter", "Details"); + dependencyList.AddTip(Properties.Resources.Enter, Properties.Resources.Details); dependencyList.AddBinding(Keys.Enter, (object sender, ConsoleTheme theme) => { if (dependencyList.Selection != null) { LaunchSubScreen(theme, new ModInfoScreen( @@ -99,7 +99,7 @@ public DependencyScreen(GameInstanceManager mgr, ChangePlan cp, HashSet<string> AddObject(dependencyList); - AddTip("Esc", "Cancel"); + AddTip(Properties.Resources.Esc, Properties.Resources.Cancel); AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => { // Add everything to rejected foreach (var kvp in dependencies) { @@ -108,7 +108,7 @@ public DependencyScreen(GameInstanceManager mgr, ChangePlan cp, HashSet<string> return false; }); - AddTip("F9", "Accept"); + AddTip("F9", Properties.Resources.Accept); AddBinding(Keys.F9, (object sender, ConsoleTheme theme) => { foreach (CkanModule mod in accepted) { plan.Install.Add(mod); @@ -136,7 +136,7 @@ protected override string LeftHeader() /// </summary> protected override string CenterHeader() { - return "Recommendations & Suggestions"; + return Properties.Resources.RecommendationsTitle; } /// <summary> @@ -197,21 +197,19 @@ private IEnumerable<string> ReplacementIdentifiers(IEnumerable<string> replaced_ private string StatusSymbol(CkanModule mod) { - if (accepted.Contains(mod)) { - return installing; - } else { - return notinstalled; - } + return accepted.Contains(mod) + ? installing + : notinstalled; } private HashSet<CkanModule> accepted = new HashSet<CkanModule>(); - private HashSet<string> rejected; + private HashSet<string> rejected; - private IRegistryQuerier registry; - private GameInstanceManager manager; - private ModuleInstaller installer; - private ChangePlan plan; - private bool debug; + private IRegistryQuerier registry; + private GameInstanceManager manager; + private ModuleInstaller installer; + private ChangePlan plan; + private bool debug; private Dictionary<CkanModule, Dependency> dependencies = new Dictionary<CkanModule, Dependency>(); private ConsoleListBox<Dependency> dependencyList; @@ -228,17 +226,17 @@ public class Dependency { /// <summary> /// Identifier of mod /// </summary> - public CkanModule module; + public CkanModule module; /// <summary> /// True if we default to installing, false otherwise /// </summary> - public bool defaultInstall; + public bool defaultInstall; /// <summary> /// List of mods that recommended or suggested this mod /// </summary> - public List<string> dependents = new List<string>(); + public List<string> dependents = new List<string>(); } } diff --git a/ConsoleUI/DownloadImportDialog.cs b/ConsoleUI/DownloadImportDialog.cs index 5161d05689..e9e9cde8ec 100644 --- a/ConsoleUI/DownloadImportDialog.cs +++ b/ConsoleUI/DownloadImportDialog.cs @@ -21,15 +21,17 @@ public static class DownloadImportDialog { public static void ImportDownloads(ConsoleTheme theme, GameInstance gameInst, NetModuleCache cache, ChangePlan cp) { ConsoleFileMultiSelectDialog cfmsd = new ConsoleFileMultiSelectDialog( - "Import Downloads", + Properties.Resources.ImportSelectTitle, FindDownloadsPath(gameInst), "*.zip", - "Import" + Properties.Resources.ImportSelectHeader ); HashSet<FileInfo> files = cfmsd.Run(theme); if (files.Count > 0) { - ProgressScreen ps = new ProgressScreen("Importing Downloads", "Calculating..."); + ProgressScreen ps = new ProgressScreen( + Properties.Resources.ImportProgressTitle, + Properties.Resources.ImportProgressMessage); ModuleInstaller inst = new ModuleInstaller(gameInst, cache, ps); ps.Run(theme, (ConsoleTheme th) => inst.ImportFiles(files, ps, (CkanModule mod) => cp.Install.Add(mod), RegistryManager.Instance(gameInst).registry)); diff --git a/ConsoleUI/ExitScreen.cs b/ConsoleUI/ExitScreen.cs index 77c8b88732..2dead81959 100644 --- a/ConsoleUI/ExitScreen.cs +++ b/ConsoleUI/ExitScreen.cs @@ -1,4 +1,6 @@ using System; +using System.Linq; +using System.Collections.Generic; using CKAN.ConsoleUI.Toolkit; namespace CKAN.ConsoleUI { @@ -45,56 +47,36 @@ private void Draw(ConsoleTheme theme) } Console.Clear(); - FancyLinePiece ckanPiece = new FancyLinePiece("CKAN", theme.ExitInnerBg, theme.ExitHighlightFg); - + // Specially formatted snippets + var ckanPiece = new FancyLinePiece("CKAN", theme.ExitInnerBg, theme.ExitHighlightFg); + var ckanVersionPiece = new FancyLinePiece($"CKAN {Meta.GetVersion()}", theme.ExitInnerBg, theme.ExitHighlightFg); + var releaseLinkPiece = new FancyLinePiece("https://github.com/KSP-CKAN/CKAN/releases/latest", theme.ExitInnerBg, theme.ExitLinkFg); + var issuesLinkPiece = new FancyLinePiece("https://github.com/KSP-CKAN/CKAN/issues", theme.ExitInnerBg, theme.ExitLinkFg); + var authorsLinkPiece = new FancyLinePiece("https://github.com/KSP-CKAN/CKAN/graphs/contributors", theme.ExitInnerBg, theme.ExitLinkFg); + FancyLinePiece[][] lines = new FancyLinePiece[][] { + new FancyLinePiece(Properties.Resources.ExitTitle, theme.ExitInnerBg, theme.ExitNormalFg) + .Replace("{0}", ckanPiece).ToArray(), new FancyLinePiece[] { - ckanPiece, - new FancyLinePiece(", the Comprehensive Kerbal Archive Network", theme.ExitInnerBg, theme.ExitNormalFg) - }, new FancyLinePiece[] { new FancyLinePiece( new string(Symbols.horizLine, Console.WindowWidth - 2 -2 * horizMargin), theme.ExitInnerBg, theme.ExitNormalFg) - }, new FancyLinePiece[] { - new FancyLinePiece("YOU ARE USING ", theme.ExitInnerBg, theme.ExitNormalFg), - new FancyLinePiece($"CKAN {Meta.GetVersion()}", theme.ExitInnerBg, theme.ExitHighlightFg), - new FancyLinePiece(".", theme.ExitInnerBg, theme.ExitNormalFg) - }, new FancyLinePiece[] { - }, new FancyLinePiece[] { - new FancyLinePiece("Thanks for downloading ", theme.ExitInnerBg, theme.ExitNormalFg), - ckanPiece, - new FancyLinePiece(". We hope you have as", theme.ExitInnerBg, theme.ExitNormalFg) - }, new FancyLinePiece[] { - new FancyLinePiece("much fun using it as we had (and have) making it.", theme.ExitInnerBg, theme.ExitNormalFg) - }, new FancyLinePiece[] { - }, new FancyLinePiece[] { - new FancyLinePiece("If you have paid for ", theme.ExitInnerBg, theme.ExitNormalFg), - ckanPiece, - new FancyLinePiece(", try to get your money back,", theme.ExitInnerBg, theme.ExitNormalFg) - }, new FancyLinePiece[] { - new FancyLinePiece("because you can download ", theme.ExitInnerBg, theme.ExitNormalFg), - ckanPiece, - new FancyLinePiece(" for free from", theme.ExitInnerBg, theme.ExitNormalFg) - }, new FancyLinePiece[] { - new FancyLinePiece("https://github.com/KSP-CKAN/CKAN/releases/latest", theme.ExitInnerBg, theme.ExitLinkFg) - }, new FancyLinePiece[] { - }, new FancyLinePiece[] { - new FancyLinePiece("If you have any problems using ", theme.ExitInnerBg, theme.ExitNormalFg), - ckanPiece, - new FancyLinePiece(", please send us an issue at", theme.ExitInnerBg, theme.ExitNormalFg) - }, new FancyLinePiece[] { - new FancyLinePiece("https://github.com/KSP-CKAN/CKAN/issues", theme.ExitInnerBg, theme.ExitLinkFg) - }, new FancyLinePiece[] { - }, new FancyLinePiece[] { - ckanPiece, - new FancyLinePiece(" WAS CREATED BY THE ", theme.ExitInnerBg, theme.ExitNormalFg), - ckanPiece, - new FancyLinePiece(" AUTHORS:", theme.ExitInnerBg, theme.ExitNormalFg) - }, new FancyLinePiece[] { - new FancyLinePiece("https://github.com/KSP-CKAN/CKAN/graphs/contributors", theme.ExitInnerBg, theme.ExitLinkFg) - }, new FancyLinePiece[] { - } - }; + }, + }.Concat( + // Parse the single multi-line resource into array of array of FancyLinePiece + Properties.Resources.ExitBody.Split(new string[] { "\r\n" }, StringSplitOptions.None) + // Each line generates one array of FancyLinePiece + .Select(ln => new FancyLinePiece(ln, theme.ExitInnerBg, theme.ExitNormalFg) + // This turns one FancyLinePiece into a sequence + .Replace("{0}", ckanPiece) + // From here on we go from sequence to sequence, flattening at each step + .SelectMany(flp => flp.Replace("{1}", ckanVersionPiece)) + .SelectMany(flp => flp.Replace("{2}", releaseLinkPiece)) + .SelectMany(flp => flp.Replace("{3}", issuesLinkPiece)) + .SelectMany(flp => flp.Replace("{4}", authorsLinkPiece)) + .ToArray() + ) + ).ToArray(); for (int i = 0; i < lines.Length; ++i) { drawLine(theme, i, lines[i]); @@ -149,6 +131,49 @@ public FancyLinePiece(string text, ConsoleColor bg, ConsoleColor fg) Foreground = fg; } + /// <summary> + /// Replace found tokens with a FancyLinePiece + /// </summary> + /// <param name="tokens">Values for which to search the string</param> + /// <param name="replacement">FancyLinePiece that should take the place of the tokens</param> + /// <returns> + /// FancyLinePiece array containing replacement where the tokens used to be + /// </returns> + public IEnumerable<FancyLinePiece> Replace(string[] tokens, FancyLinePiece replacement) + { + // Lambas can't yield return, and a separate method couldn't access our inputs + IEnumerable<FancyLinePiece> InjectReplacement(string p, int i) + { + if (i > 0) { + // Return the replacement in between elements that weren't the token + yield return replacement; + } + if (p.Length > 0) { + // Skip empty pieces + yield return new FancyLinePiece(p, Background, Foreground); + } + } + // We need to keep empty pieces from the split to handle tokens at the start + var pieces = Text.Split(tokens, StringSplitOptions.None); + return pieces.Length <= 1 + // Stop making new objects if no tokens found + ? Enumerable.Repeat<FancyLinePiece>(this, 1) + : pieces.SelectMany(InjectReplacement); + } + + /// <summary> + /// Replace found token with a FancyLinePiece + /// </summary> + /// <param name="token">Value for which to search the string</param> + /// <param name="replacement">FancyLinePiece that should take the place of the token</param> + /// <returns> + /// FancyLinePiece array containing replacement where the token used to be + /// </returns> + public IEnumerable<FancyLinePiece> Replace(string token, FancyLinePiece replacement) + { + return Replace(new string[] { token }, replacement); + } + /// <summary> /// Draw this piece at the current cursor location. /// </summary> diff --git a/ConsoleUI/GameInstanceAddScreen.cs b/ConsoleUI/GameInstanceAddScreen.cs index 290bf620c4..b882e40cec 100644 --- a/ConsoleUI/GameInstanceAddScreen.cs +++ b/ConsoleUI/GameInstanceAddScreen.cs @@ -17,7 +17,7 @@ public GameInstanceAddScreen(GameInstanceManager mgr) : base(mgr) { AddObject(new ConsoleLabel( labelWidth, pathRow + 1, -1, - () => $"Example: {examplePath}", + () => string.Format(Properties.Resources.InstanceAddExample, examplePath), null, th => th.DimLabelFg )); } @@ -39,7 +39,7 @@ protected override bool Valid() /// </summary> protected override string CenterHeader() { - return "Add Game Instance"; + return Properties.Resources.InstanceAddTitle; } /// <summary> diff --git a/ConsoleUI/GameInstanceEditScreen.cs b/ConsoleUI/GameInstanceEditScreen.cs index 4ac8a6ff07..360be8920f 100644 --- a/ConsoleUI/GameInstanceEditScreen.cs +++ b/ConsoleUI/GameInstanceEditScreen.cs @@ -45,8 +45,8 @@ public GameInstanceEditScreen(GameInstanceManager mgr, GameInstance k) // 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", + () => Properties.Resources.InstanceEditRepoFrameTitle, + () => Properties.Resources.InstanceEditCompatFrameTitle, th => th.LabelFg )); @@ -55,15 +55,15 @@ public GameInstanceEditScreen(GameInstanceManager mgr, GameInstance k) new List<Repository>(repoEditList.Values), new List<ConsoleListBoxColumn<Repository>>() { new ConsoleListBoxColumn<Repository>() { - Header = "Index", + Header = Properties.Resources.InstanceEditRepoIndexHeader, Renderer = r => r.priority.ToString(), Width = 7 }, new ConsoleListBoxColumn<Repository>() { - Header = "Name", + Header = Properties.Resources.InstanceEditRepoNameHeader, Renderer = r => r.name, Width = 16 }, new ConsoleListBoxColumn<Repository>() { - Header = "URL", + Header = Properties.Resources.InstanceEditRepoURLHeader, Renderer = r => r.uri.ToString(), Width = 50 } @@ -71,13 +71,13 @@ public GameInstanceEditScreen(GameInstanceManager mgr, GameInstance k) 1, 0, ListSortDirection.Ascending ); AddObject(repoList); - repoList.AddTip("A", "Add"); + repoList.AddTip("A", Properties.Resources.Add); repoList.AddBinding(Keys.A, (object sender, ConsoleTheme theme) => { LaunchSubScreen(theme, new RepoAddScreen(ksp.game, repoEditList)); repoList.SetData(new List<Repository>(repoEditList.Values)); return true; }); - repoList.AddTip("R", "Remove"); + repoList.AddTip("R", Properties.Resources.Remove); repoList.AddBinding(Keys.R, (object sender, ConsoleTheme theme) => { int oldPrio = repoList.Selection.priority; repoEditList.Remove(repoList.Selection.name); @@ -90,13 +90,13 @@ public GameInstanceEditScreen(GameInstanceManager mgr, GameInstance k) repoList.SetData(new List<Repository>(repoEditList.Values)); return true; }); - repoList.AddTip("E", "Edit"); + repoList.AddTip("E", Properties.Resources.Edit); repoList.AddBinding(Keys.E, (object sender, ConsoleTheme theme) => { LaunchSubScreen(theme, new RepoEditScreen(ksp.game, repoEditList, repoList.Selection)); repoList.SetData(new List<Repository>(repoEditList.Values)); return true; }); - repoList.AddTip("-", "Up"); + repoList.AddTip("-", Properties.Resources.Up); repoList.AddBinding(Keys.Minus, (object sender, ConsoleTheme theme) => { if (repoList.Selection.priority > 0) { Repository prev = SortedDictFind(repoEditList, @@ -109,7 +109,7 @@ public GameInstanceEditScreen(GameInstanceManager mgr, GameInstance k) } return true; }); - repoList.AddTip("+", "Down"); + repoList.AddTip("+", Properties.Resources.Down); repoList.AddBinding(Keys.Plus, (object sender, ConsoleTheme theme) => { Repository next = SortedDictFind(repoEditList, r => r.priority == repoList.Selection.priority + 1); @@ -126,7 +126,7 @@ public GameInstanceEditScreen(GameInstanceManager mgr, GameInstance k) compatEditList, new List<ConsoleListBoxColumn<GameVersion>>() { new ConsoleListBoxColumn<GameVersion>() { - Header = "Version", + Header = Properties.Resources.InstanceEditCompatVersionHeader, Width = 10, Renderer = v => v.ToString(), Comparer = (a, b) => a.CompareTo(b) @@ -136,7 +136,7 @@ public GameInstanceEditScreen(GameInstanceManager mgr, GameInstance k) ); AddObject(compatList); - compatList.AddTip("A", "Add"); + compatList.AddTip("A", Properties.Resources.Add); compatList.AddBinding(Keys.A, (object sender, ConsoleTheme theme) => { CompatibleVersionDialog vd = new CompatibleVersionDialog(ksp.game); GameVersion newVersion = vd.Run(theme); @@ -147,7 +147,7 @@ public GameInstanceEditScreen(GameInstanceManager mgr, GameInstance k) } return true; }); - compatList.AddTip("R", "Remove", () => compatList.Selection != null); + compatList.AddTip("R", Properties.Resources.Remove, () => compatList.Selection != null); compatList.AddBinding(Keys.R, (object sender, ConsoleTheme theme) => { compatEditList.Remove(compatList.Selection); compatList.SetData(compatEditList); @@ -159,7 +159,7 @@ public GameInstanceEditScreen(GameInstanceManager mgr, GameInstance k) // Notify the user that the registry doesn't parse AddObject(new ConsoleLabel( 1, repoFrameTop, -1, - () => $"Failed to extract mod list sources from {ksp.Name}." + () => string.Format(Properties.Resources.InstanceEditRegistryParseError, ksp.Name) )); } @@ -180,7 +180,7 @@ private static V SortedDictFind<K, V>(SortedDictionary<K, V> dict, Func<V, bool> /// </summary> protected override string CenterHeader() { - return "Edit Game Instance"; + return Properties.Resources.InstanceEditTitle; } /// <summary> diff --git a/ConsoleUI/GameInstanceListScreen.cs b/ConsoleUI/GameInstanceListScreen.cs index d72d20fd74..ceca90932a 100644 --- a/ConsoleUI/GameInstanceListScreen.cs +++ b/ConsoleUI/GameInstanceListScreen.cs @@ -23,7 +23,7 @@ public GameInstanceListScreen(GameInstanceManager mgr, bool first = false) AddObject(new ConsoleLabel( 1, 2, -1, - () => "Select or add a game instance:" + () => Properties.Resources.InstanceListLabel )); instanceList = new ConsoleListBox<GameInstance>( @@ -31,24 +31,24 @@ public GameInstanceListScreen(GameInstanceManager mgr, bool first = false) manager.Instances.Values, new List<ConsoleListBoxColumn<GameInstance>>() { new ConsoleListBoxColumn<GameInstance>() { - Header = "Default", + Header = Properties.Resources.InstanceListDefaultHeader, Width = 7, Renderer = StatusSymbol }, new ConsoleListBoxColumn<GameInstance>() { - Header = "Name", + Header = Properties.Resources.InstanceListNameHeader, Width = 20, Renderer = k => k.Name }, new ConsoleListBoxColumn<GameInstance>() { - Header = "Game", + Header = Properties.Resources.InstanceListGameHeader, Width = 5, Renderer = k => k.game.ShortName }, new ConsoleListBoxColumn<GameInstance>() { - Header = "Version", + Header = Properties.Resources.InstanceListVersionHeader, Width = 12, - Renderer = k => k.Version()?.ToString() ?? noVersion, + Renderer = k => k.Version()?.ToString() ?? Properties.Resources.InstanceListNoVersion, Comparer = (a, b) => a.Version()?.CompareTo(b.Version() ?? GameVersion.Any) ?? 1 }, new ConsoleListBoxColumn<GameInstance>() { - Header = "Path", + Header = Properties.Resources.InstanceListPathHeader, Width = 70, Renderer = k => k.GameDir() } @@ -57,19 +57,19 @@ public GameInstanceListScreen(GameInstanceManager mgr, bool first = false) ); if (first) { - AddTip("Ctrl+Q", "Quit"); + AddTip($"{Properties.Resources.Ctrl}+Q", Properties.Resources.Quit); AddBinding(Keys.AltX, (object sender, ConsoleTheme theme) => false); AddBinding(Keys.CtrlQ, (object sender, ConsoleTheme theme) => false); } else { - AddTip("Esc", "Quit"); + AddTip(Properties.Resources.Esc, Properties.Resources.Quit); AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => false); } - AddTip("Enter", "Select"); + AddTip(Properties.Resources.Enter, Properties.Resources.Select); AddBinding(Keys.Enter, (object sender, ConsoleTheme theme) => { ConsoleMessageDialog d = new ConsoleMessageDialog( - $"Loading instance {instanceList.Selection.Name}...", + string.Format(Properties.Resources.InstanceListLoadingInstance, instanceList.Selection.Name), new List<string>() ); @@ -87,23 +87,23 @@ public GameInstanceListScreen(GameInstanceManager mgr, bool first = false) } }); - instanceList.AddTip("A", "Add"); + instanceList.AddTip("A", Properties.Resources.Add); instanceList.AddBinding(Keys.A, (object sender, ConsoleTheme theme) => { LaunchSubScreen(theme, new GameInstanceAddScreen(manager)); instanceList.SetData(manager.Instances.Values); return true; }); - instanceList.AddTip("R", "Remove"); + instanceList.AddTip("R", Properties.Resources.Remove); instanceList.AddBinding(Keys.R, (object sender, ConsoleTheme theme) => { manager.RemoveInstance(instanceList.Selection.Name); instanceList.SetData(manager.Instances.Values); return true; }); - instanceList.AddTip("E", "Edit"); + instanceList.AddTip("E", Properties.Resources.Edit); instanceList.AddBinding(Keys.E, (object sender, ConsoleTheme theme) => { ConsoleMessageDialog d = new ConsoleMessageDialog( - $"Loading instance {instanceList.Selection.Name}...", + string.Format(Properties.Resources.InstanceListLoadingInstance, instanceList.Selection.Name), new List<string>() ); TryGetInstance(theme, instanceList.Selection, (ConsoleTheme th) => { d.Run(theme, (ConsoleTheme thm) => {}); }); @@ -114,7 +114,7 @@ public GameInstanceListScreen(GameInstanceManager mgr, bool first = false) return true; }); - instanceList.AddTip("D", "Default"); + instanceList.AddTip("D", Properties.Resources.InstanceListDefaultToggle); instanceList.AddBinding(Keys.D, (object sender, ConsoleTheme theme) => { string name = instanceList.Selection.Name; if (name == manager.AutoStartInstance) { @@ -124,8 +124,8 @@ public GameInstanceListScreen(GameInstanceManager mgr, bool first = false) manager.SetAutoStart(name); } catch (NotKSPDirKraken k) { ConsoleMessageDialog errd = new ConsoleMessageDialog( - $"Error loading {k.path}:\n{k.Message}", - new List<string>() {"OK"} + string.Format(Properties.Resources.InstanceListLoadingError, k.path, k.Message), + new List<string>() { Properties.Resources.OK } ); errd.Run(theme); } @@ -150,7 +150,7 @@ protected override string LeftHeader() /// </summary> protected override string CenterHeader() { - return "Game Instances"; + return Properties.Resources.InstanceListTitle; } /// <summary> @@ -158,7 +158,7 @@ protected override string CenterHeader() /// </summary> protected override string MenuTip() { - return "Sort"; + return Properties.Resources.Sort; } /// <summary> @@ -185,11 +185,11 @@ public static bool TryGetInstance(ConsoleTheme theme, GameInstance ksp, Action<C } catch (RegistryInUseKraken k) { ConsoleMessageDialog md = new ConsoleMessageDialog( - $"Lock file with live process ID found at {k.lockfilePath}\n\n" - + "This means that another instance of CKAN probably is accessing this instance." - + " You can delete the file to continue, but data corruption is very likely.\n\n" - + "Do you want to delete this lock file to force access?", - new List<string>() {"Cancel", "Force"} + string.Format(Properties.Resources.InstanceListLocked, k.lockfilePath), + new List<string>() { + Properties.Resources.Cancel, + Properties.Resources.Force + } ); if (md.Run(theme) == 1) { // Delete it @@ -203,8 +203,8 @@ public static bool TryGetInstance(ConsoleTheme theme, GameInstance ksp, Action<C } catch (NotKSPDirKraken k) { ConsoleMessageDialog errd = new ConsoleMessageDialog( - $"Error loading {ksp.GameDir()}:\n{k.Message}", - new List<string>() {"OK"} + string.Format(Properties.Resources.InstanceListLoadingError, ksp.GameDir(), k.Message), + new List<string>() { Properties.Resources.OK } ); errd.Run(theme); return false; @@ -212,8 +212,8 @@ public static bool TryGetInstance(ConsoleTheme theme, GameInstance ksp, Action<C } catch (Exception e) { ConsoleMessageDialog errd = new ConsoleMessageDialog( - $"Error loading {Path.Combine(ksp.CkanDir(), "registry.json")}:\n{e.Message}", - new List<string>() {"OK"} + string.Format(Properties.Resources.InstanceListLoadingError, Path.Combine(ksp.CkanDir(), "registry.json"), e.Message), + new List<string>() { Properties.Resources.OK } ); errd.Run(theme); return false; @@ -236,7 +236,6 @@ private string StatusSymbol(GameInstance k) private GameInstanceManager manager; private ConsoleListBox<GameInstance> instanceList; - private const string noVersion = "<NONE>"; private static readonly string defaultMark = Symbols.checkmark; } diff --git a/ConsoleUI/GameInstanceScreen.cs b/ConsoleUI/GameInstanceScreen.cs index 6be65334f7..060368527a 100644 --- a/ConsoleUI/GameInstanceScreen.cs +++ b/ConsoleUI/GameInstanceScreen.cs @@ -1,3 +1,4 @@ +using System; using System.IO; using CKAN.ConsoleUI.Toolkit; @@ -18,7 +19,7 @@ protected GameInstanceScreen(GameInstanceManager mgr, string initName = "", stri { manager = mgr; - AddTip("F2", "Accept"); + AddTip("F2", Properties.Resources.Accept); AddBinding(Keys.F2, (object sender, ConsoleTheme theme) => { if (Valid()) { Save(); @@ -30,22 +31,22 @@ protected GameInstanceScreen(GameInstanceManager mgr, string initName = "", stri } }); - AddTip("Esc", "Cancel"); + AddTip(Properties.Resources.Esc, Properties.Resources.Cancel); AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => { // Discard changes return false; }); name = new ConsoleField(labelWidth, nameRow, -1, initName) { - GhostText = () => "<Enter the name to use for this game instance>" + GhostText = () => Properties.Resources.InstanceNameGhostText }; path = new ConsoleField(labelWidth, pathRow, -1, initPath) { - GhostText = () => "<Enter the location of this game instance on disk>" + GhostText = () => Properties.Resources.InstancePathGhostText }; - AddObject(new ConsoleLabel(1, nameRow, labelWidth, () => "Name:")); + AddObject(new ConsoleLabel(1, nameRow, labelWidth, () => Properties.Resources.InstanceNameLabel)); AddObject(name); - AddObject(new ConsoleLabel(1, pathRow, labelWidth, () => "Path to game instance:")); + AddObject(new ConsoleLabel(1, pathRow, labelWidth, () => Properties.Resources.InstancePathLabel)); AddObject(path); } @@ -76,12 +77,12 @@ protected bool nameValid() { if (string.IsNullOrEmpty(name.Value)) { // Complain about empty name - RaiseError("Name cannot be empty!"); + RaiseError(Properties.Resources.InstanceNameEmptyError); SetFocus(name); return false; } else if (manager.HasInstance(name.Value)) { // Complain about duplicate name - RaiseError($"{name.Value} already exists!"); + RaiseError(Properties.Resources.InstanceNameDuplicateError, name.Value); SetFocus(name); return false; } else { @@ -108,7 +109,7 @@ protected bool pathValid() // Pretend DirectoryInfo constructed an instance that made IsGameInstanceDir return false } // Complain about non-KSP path - RaiseError("Path does not correspond to a game folder!"); + RaiseError(Properties.Resources.InstancePathNotGameFolderError); SetFocus(path); return false; } @@ -130,7 +131,10 @@ protected bool pathValid() /// <summary> /// Number of columns reserved at left of screen for labels /// </summary> - protected const int labelWidth = 24; + protected int labelWidth => Math.Max(24, Math.Max( + Properties.Resources.InstanceNameLabel.Length, + Properties.Resources.InstancePathLabel.Length + )); private const int nameRow = 2; /// <summary> /// Y coordinate of path field diff --git a/ConsoleUI/InstallFilterAddDialog.cs b/ConsoleUI/InstallFilterAddDialog.cs index 748a23d9de..94d5c500f6 100644 --- a/ConsoleUI/InstallFilterAddDialog.cs +++ b/ConsoleUI/InstallFilterAddDialog.cs @@ -28,22 +28,22 @@ public InstallFilterAddDialog() : base() manualEntry = new ConsoleField( l + 2, b - 2, r - 2 ) { - GhostText = () => "<Enter a filter>" + GhostText = () => Properties.Resources.FilterAddGhostText }; AddObject(manualEntry); - manualEntry.AddTip("Enter", "Accept value"); + manualEntry.AddTip(Properties.Resources.Enter, Properties.Resources.FilterAddAcceptTip); manualEntry.AddBinding(Keys.Enter, (object sender, ConsoleTheme theme) => { choice = manualEntry.Value; return false; }); - AddTip("Esc", "Cancel"); + AddTip(Properties.Resources.Esc, Properties.Resources.Cancel); AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => { choice = null; return false; }); - CenterHeader = () => "Add Filter"; + CenterHeader = () => Properties.Resources.FilterAddTitle; } /// <summary> diff --git a/ConsoleUI/InstallFiltersScreen.cs b/ConsoleUI/InstallFiltersScreen.cs index e633e1acdf..6c71031c02 100644 --- a/ConsoleUI/InstallFiltersScreen.cs +++ b/ConsoleUI/InstallFiltersScreen.cs @@ -7,8 +7,16 @@ namespace CKAN.ConsoleUI { + /// <summary> + /// A screen for editing the global and instance install filters + /// </summary> public class InstallFiltersScreen : ConsoleScreen { + /// <summary> + /// Initialize the screen + /// </summary> + /// <param name="globalConfig">Object holding the global configuration</param> + /// <param name="instance">The current instance</param> public InstallFiltersScreen(IConfiguration globalConfig, GameInstance instance) { this.globalConfig = globalConfig; @@ -16,21 +24,21 @@ public InstallFiltersScreen(IConfiguration globalConfig, GameInstance instance) globalFilters = globalConfig.GlobalInstallFilters.ToList(); instanceFilters = instance.InstallFilters.ToList(); - AddTip("F2", "Accept"); + AddTip("F2", Properties.Resources.Accept); AddBinding(Keys.F2, (object sender, ConsoleTheme theme) => { Save(); // Close screen return false; }); - AddTip("Esc", "Cancel"); + AddTip(Properties.Resources.Esc, Properties.Resources.Cancel); AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => { // Discard changes return false; }); mainMenu = new ConsolePopupMenu(new List<ConsoleMenuOption>() { - new ConsoleMenuOption("Add MiniAVC", "", - "Prevent MiniAVC from being installed", + new ConsoleMenuOption(Properties.Resources.FiltersAddMiniAVCMenu, "", + Properties.Resources.FiltersAddMiniAVCMenuTip, true, AddMiniAVC), }); @@ -41,7 +49,7 @@ public InstallFiltersScreen(IConfiguration globalConfig, GameInstance instance) globalFilters, new List<ConsoleListBoxColumn<string>>() { new ConsoleListBoxColumn<string>() { - Header = "Global Filters", + Header = Properties.Resources.FiltersGlobalHeader, Width = 40, Renderer = f => f, } @@ -49,12 +57,12 @@ public InstallFiltersScreen(IConfiguration globalConfig, GameInstance instance) 0 ); AddObject(globalList); - globalList.AddTip("A", "Add"); + globalList.AddTip("A", Properties.Resources.Add); globalList.AddBinding(Keys.A, (object sender, ConsoleTheme theme) => { AddFilter(theme, globalList, globalFilters); return true; }); - globalList.AddTip("R", "Remove"); + globalList.AddTip("R", Properties.Resources.Remove); globalList.AddBinding(Keys.R, (object sender, ConsoleTheme theme) => { RemoveFilter(globalList, globalFilters); return true; @@ -64,7 +72,7 @@ public InstallFiltersScreen(IConfiguration globalConfig, GameInstance instance) instanceFilters, new List<ConsoleListBoxColumn<string>>() { new ConsoleListBoxColumn<string>() { - Header = "Instance Filters", + Header = Properties.Resources.FiltersInstanceHeader, Width = 40, Renderer = f => f, } @@ -72,12 +80,12 @@ public InstallFiltersScreen(IConfiguration globalConfig, GameInstance instance) 0 ); AddObject(instanceList); - instanceList.AddTip("A", "Add"); + instanceList.AddTip("A", Properties.Resources.Add); instanceList.AddBinding(Keys.A, (object sender, ConsoleTheme theme) => { AddFilter(theme, instanceList, instanceFilters); return true; }); - instanceList.AddTip("R", "Remove"); + instanceList.AddTip("R", Properties.Resources.Remove); instanceList.AddBinding(Keys.R, (object sender, ConsoleTheme theme) => { RemoveFilter(instanceList, instanceFilters); return true; @@ -97,7 +105,7 @@ protected override string LeftHeader() /// </summary> protected override string CenterHeader() { - return "Installation Filters"; + return Properties.Resources.FiltersTitle; } private bool AddMiniAVC(ConsoleTheme theme) diff --git a/ConsoleUI/InstallScreen.cs b/ConsoleUI/InstallScreen.cs index d8233a2230..2b0f0dd36c 100644 --- a/ConsoleUI/InstallScreen.cs +++ b/ConsoleUI/InstallScreen.cs @@ -18,8 +18,8 @@ public class InstallScreen : ProgressScreen { /// <param name="dbg">True if debug options should be available, false otherwise</param> public InstallScreen(GameInstanceManager mgr, ChangePlan cp, bool dbg) : base( - "Installing, Updating, and Removing Mods", - "Calculating..." + Properties.Resources.InstallTitle, + Properties.Resources.InstallMessage ) { debug = dbg; @@ -93,19 +93,17 @@ public override void Run(ConsoleTheme theme, Action<ConsoleTheme> process = null RaiseError(ex.Message); } catch (FileExistsKraken ex) { if (ex.owningModule != null) { - RaiseMessage($"{ex.installingModule} tried to install {ex.filename}, but {ex.owningModule} has already installed it."); - RaiseMessage($"Please report this problem at https://github.com/KSP-CKAN/NetKAN/issues/new/choose"); + RaiseMessage(Properties.Resources.InstallOwnedFileConflict, ex.installingModule, ex.filename, ex.owningModule); } else { - RaiseMessage($"{ex.installingModule} tried to install {ex.filename}, but it is already installed."); - RaiseMessage($"Please manually uninstall the mod that owns this file to install {ex.installingModule}."); + RaiseMessage(Properties.Resources.InstallUnownedFileConflict, ex.installingModule, ex.filename, ex.installingModule); } - RaiseError("Game files reverted."); + RaiseError(Properties.Resources.InstallFilesReverted); } catch (DownloadErrorsKraken ex) { RaiseError(ex.ToString()); } catch (ModuleDownloadErrorsKraken ex) { RaiseError(ex.ToString()); } catch (DownloadThrottledKraken ex) { - if (RaiseYesNoDialog($"{ex.ToString()}\n\nEdit authentication tokens now?")) { + if (RaiseYesNoDialog(string.Format(Properties.Resources.InstallAuthTokenPrompt, ex.ToString()))) { if (ex.infoUrl != null) { ModInfoScreen.LaunchURL(theme, ex.infoUrl); } @@ -119,7 +117,7 @@ public override void Run(ConsoleTheme theme, Action<ConsoleTheme> process = null ConsoleChoiceDialog<CkanModule> ch = new ConsoleChoiceDialog<CkanModule>( ex.Message, - "Name", + Properties.Resources.InstallTooManyModsNameHeader, ex.modules, (CkanModule mod) => mod.ToString() ); @@ -132,13 +130,13 @@ public override void Run(ConsoleTheme theme, Action<ConsoleTheme> process = null } } catch (BadMetadataKraken ex) { - RaiseError($"Bad metadata detected for {ex.module}: {ex.Message}"); + RaiseError(Properties.Resources.InstallBadMetadata, ex.module, ex.Message); } catch (DependencyNotSatisfiedKraken ex) { - RaiseError($"{ex.parent} requires {ex.module}, but it is not listed in the index, or not available for your version of the game.\r\n{ex.Message}"); + RaiseError(Properties.Resources.InstallUnsatisfiedDependency, ex.parent, ex.module, ex.Message); } catch (ModuleNotFoundKraken ex) { - RaiseError($"Module {ex.module} required but it is not listed in the index, or not available for your version of the game.\r\n{ex.Message}"); + RaiseError(Properties.Resources.InstallModuleNotFound, ex.module, ex.Message); } catch (ModNotInstalledKraken ex) { - RaiseError($"{ex.mod} is not installed, can't remove"); + RaiseError(Properties.Resources.InstallNotInstalled, ex.mod); } catch (DllLocationMismatchKraken ex) { RaiseError(ex.Message); } @@ -148,7 +146,7 @@ public override void Run(ConsoleTheme theme, Action<ConsoleTheme> process = null private void OnModInstalled(CkanModule mod) { - RaiseMessage($"{Symbols.checkmark} Successfully installed {mod.name} {ModuleInstaller.StripEpoch(mod.version)}"); + RaiseMessage(Properties.Resources.InstallModInstalled, Symbols.checkmark, mod.name, ModuleInstaller.StripEpoch(mod.version)); } private IEnumerable<ModuleReplacement> AllReplacements(IEnumerable<string> identifiers) diff --git a/ConsoleUI/ModInfoScreen.cs b/ConsoleUI/ModInfoScreen.cs index 832ace4bc9..db7231d7ae 100644 --- a/ConsoleUI/ModInfoScreen.cs +++ b/ConsoleUI/ModInfoScreen.cs @@ -38,7 +38,7 @@ public ModInfoScreen(GameInstanceManager mgr, ChangePlan cp, CkanModule m, bool )); AddObject(new ConsoleLabel( 1, 2, -1, - () => $"By {string.Join(", ", mod.author)}" + () => string.Format(Properties.Resources.ModInfoAuthors, string.Join(", ", mod.author)) )); AddObject(new ConsoleFrame( @@ -49,7 +49,7 @@ public ModInfoScreen(GameInstanceManager mgr, ChangePlan cp, CkanModule m, bool )); AddObject(new ConsoleLabel( 3, 4, 11, - () => "License:", + () => Properties.Resources.ModInfoLicence, null, th => th.DimLabelFg )); @@ -60,7 +60,7 @@ public ModInfoScreen(GameInstanceManager mgr, ChangePlan cp, CkanModule m, bool )); AddObject(new ConsoleLabel( 3, 5, 12, - () => "Download:", + () => Properties.Resources.ModInfoDownload, null, th => th.DimLabelFg )); @@ -91,7 +91,7 @@ public ModInfoScreen(GameInstanceManager mgr, ChangePlan cp, CkanModule m, bool AddObject(new ConsoleFrame( 1, Math.Max(depsBot, versBot) + 1, -1, -1, - () => "Description", + () => Properties.Resources.ModInfoDescriptionFrame, th => th.NormalFrameFg, false )); @@ -108,15 +108,14 @@ public ModInfoScreen(GameInstanceManager mgr, ChangePlan cp, CkanModule m, bool } AddObject(tb); if (!ChangePlan.IsAnyAvailable(registry, mod.identifier)) { - tb.AddLine("\r\nNOTE: This mod is installed but no longer available."); - tb.AddLine("If you uninstall it, CKAN will not be able to re-install it."); + tb.AddLine(Properties.Resources.ModInfoUnavailableWarning); } tb.AddScrollBindings(this); - AddTip("Esc", "Back"); + AddTip(Properties.Resources.Esc, Properties.Resources.Back); AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => false); - AddTip("Ctrl+D", "Download to cache (does not install)", + AddTip($"{Properties.Resources.Ctrl}+D", Properties.Resources.ModInfoDownloadToCache, () => !manager.Cache.IsMaybeCachedZip(mod) && !mod.IsDLC ); AddBinding(Keys.CtrlD, (object sender, ConsoleTheme theme) => { @@ -131,49 +130,49 @@ public ModInfoScreen(GameInstanceManager mgr, ChangePlan cp, CkanModule m, bool if (mod.resources.homepage != null) { opts.Add(new ConsoleMenuOption( - "Home page", "", "Open the home page URL in a browser", + Properties.Resources.ModInfoHomePage, "", Properties.Resources.ModInfoHomePageTip, true, th => LaunchURL(th, mod.resources.homepage) )); } if (mod.resources.repository != null) { opts.Add(new ConsoleMenuOption( - "Repository", "", "Open the repository URL in a browser", + Properties.Resources.ModInfoRepository, "", Properties.Resources.ModInfoRepositoryTip, true, th => LaunchURL(th, mod.resources.repository) )); } if (mod.resources.bugtracker != null) { opts.Add(new ConsoleMenuOption( - "Bugtracker", "", "Open the bug tracker URL in a browser", + Properties.Resources.ModInfoBugtracker, "", Properties.Resources.ModInfoBugtrackerTip, true, th => LaunchURL(th, mod.resources.bugtracker) )); } if (mod.resources.spacedock != null) { opts.Add(new ConsoleMenuOption( - "SpaceDock", "", "Open the SpaceDock URL in a browser", + Properties.Resources.ModInfoSpaceDock, "", Properties.Resources.ModInfoSpaceDockTip, true, th => LaunchURL(th, mod.resources.spacedock) )); } if (mod.resources.curse != null) { opts.Add(new ConsoleMenuOption( - "Curse", "", "Open the Curse URL in a browser", + Properties.Resources.ModInfoCurse, "", Properties.Resources.ModInfoCurseTip, true, th => LaunchURL(th, mod.resources.curse) )); } if (mod.resources.store != null) { opts.Add(new ConsoleMenuOption( - "Store", "", "Open the Store URL in a browser", + Properties.Resources.ModInfoStore, "", Properties.Resources.ModInfoStoreTip, true, th => LaunchURL(th, mod.resources.store) )); } if (mod.resources.steamstore != null) { opts.Add(new ConsoleMenuOption( - "Steam Store", "", "Open the Steam Store URL in a browser", + Properties.Resources.ModInfoSteamStore, "", Properties.Resources.ModInfoSteamStoreTip, true, th => LaunchURL(th, mod.resources.steamstore) )); @@ -181,7 +180,7 @@ public ModInfoScreen(GameInstanceManager mgr, ChangePlan cp, CkanModule m, bool if (debug) { opts.Add(null); opts.Add(new ConsoleMenuOption( - "DEBUG: View metadata", "", "Display the full registry data for this mod", + Properties.Resources.ModInfoViewMetadata, "", Properties.Resources.ModInfoViewMetadataTip, true, ViewMetadata )); @@ -206,7 +205,7 @@ protected override string LeftHeader() /// </summary> protected override string CenterHeader() { - return "Mod Details"; + return Properties.Resources.ModInfoTitle; } /// <summary> @@ -214,15 +213,15 @@ protected override string CenterHeader() /// </summary> protected override string MenuTip() { - return "Links"; + return Properties.Resources.ModInfoMenuTip; } private bool ViewMetadata(ConsoleTheme theme) { ConsoleMessageDialog md = new ConsoleMessageDialog( $"\"{mod.identifier}\": {registry.GetAvailableMetadata(mod.identifier)}", - new List<string> {"OK"}, - () => $"{mod.name} Metadata", + new List<string> { Properties.Resources.OK }, + () => string.Format(Properties.Resources.ModInfoViewMetadataTitle, mod.name), TextAlign.Left ); md.Run(theme); @@ -247,7 +246,7 @@ public static bool LaunchURL(ConsoleTheme theme, Uri u) // support launching URLs! .NET's API design has painted us into a corner. // So instead we display a popup dialog for the garbage to print all over, // then wait 1.5 seconds and refresh the screen when it closes. - ConsoleMessageDialog d = new ConsoleMessageDialog("Launching...", new List<string>()); + ConsoleMessageDialog d = new ConsoleMessageDialog(Properties.Resources.ModInfoURLLaunching, new List<string>()); d.Run(theme, (ConsoleTheme th) => { Utilities.ProcessStartURL(u.ToString()); System.Threading.Thread.Sleep(1500); @@ -269,14 +268,14 @@ private int addDependencies(int top = 8) AddObject(new ConsoleFrame( 1, top, midL, top + h - 1, - () => "Dependencies", + () => Properties.Resources.ModInfoDependenciesFrame, th => th.NormalFrameFg, false )); if (numDeps > 0) { AddObject(new ConsoleLabel( 3, top + 1, 3 + lblW - 1, - () => $"Required ({numDeps}):", + () => string.Format(Properties.Resources.ModInfoRequiredLabel, numDeps), null, th => th.DimLabelFg )); @@ -299,7 +298,7 @@ private int addDependencies(int top = 8) if (numConfs > 0) { AddObject(new ConsoleLabel( 3, top + 1 + depsH, 3 + lblW - 1, - () => $"Conflicts ({numConfs}):", + () => string.Format(Properties.Resources.ModInfoConflictsLabel, numConfs), null, th => th.DimLabelFg )); @@ -367,7 +366,7 @@ private int addVersionDisplay() // Show replaced_by addVersionBox( boxLeft, boxTop, boxRight, boxTop + boxH - 1, - () => $"Replaced by {mr.ReplaceWith.identifier}", + () => string.Format(Properties.Resources.ModInfoReplacedBy, mr.ReplaceWith.identifier), th => th.AlertFrameFg, false, new List<CkanModule>() {mr.ReplaceWith} @@ -376,7 +375,9 @@ private int addVersionDisplay() addVersionBox( boxLeft, boxTop, boxRight, boxTop + boxH - 1, - () => $"Installed {instTime?.ToString("d") ?? "manually"}", + () => instTime.HasValue + ? string.Format(Properties.Resources.ModInfoInstalledOn, instTime.Value.ToString("d")) + : Properties.Resources.ModInfoInstalledManually, th => th.ActiveFrameFg, true, new List<CkanModule>() {inst} @@ -387,7 +388,9 @@ private int addVersionDisplay() addVersionBox( boxLeft, boxTop, boxRight, boxTop + boxH - 1, - () => $"Latest/Installed {instTime?.ToString("d") ?? "manually"}", + () => instTime.HasValue + ? string.Format(Properties.Resources.ModInfoLatestInstalledOn, instTime.Value.ToString("d")) + : Properties.Resources.ModInfoLatestInstalledManually, th => th.ActiveFrameFg, true, new List<CkanModule>() {inst} @@ -401,7 +404,7 @@ private int addVersionDisplay() addVersionBox( boxLeft, boxTop, boxRight, boxTop + boxH - 1, - () => "Latest Version", + () => Properties.Resources.ModInfoLatestVersion, th => th.AlertFrameFg, false, new List<CkanModule>() {latest} @@ -410,7 +413,9 @@ private int addVersionDisplay() addVersionBox( boxLeft, boxTop, boxRight, boxTop + boxH - 1, - () => $"Installed {instTime?.ToString("d") ?? "manually"}", + () => instTime.HasValue + ? string.Format(Properties.Resources.ModInfoInstalledOn, instTime.Value.ToString("d")) + : Properties.Resources.ModInfoInstalledManually, th => th.ActiveFrameFg, true, new List<CkanModule>() {inst} @@ -422,7 +427,7 @@ private int addVersionDisplay() addVersionBox( boxLeft, boxTop, boxRight, boxTop + boxH - 1, - () => "Latest Version", + () => Properties.Resources.ModInfoLatestVersion, th => th.NormalFrameFg, false, new List<CkanModule>() {latest} @@ -435,7 +440,7 @@ private int addVersionDisplay() addVersionBox( boxLeft, boxTop, boxRight, boxTop + boxH - 1, - () => "Other Versions", + () => Properties.Resources.ModInfoOtherVersions, th => th.NormalFrameFg, false, others @@ -451,7 +456,9 @@ private int addVersionDisplay() // of the old info about it from when we installed it addVersionBox( boxLeft, boxTop, boxRight, boxTop + boxH - 1, - () => $"UNAVAILABLE/Installed {instTime?.ToString("d") ?? "manually"}", + () => instTime.HasValue + ? string.Format(Properties.Resources.ModInfoUnavailableInstalledOn, instTime.Value.ToString("d")) + : Properties.Resources.ModInfoUnavailableInstalledManually, th => th.AlertFrameFg, true, new List<CkanModule>() {mod} @@ -487,7 +494,7 @@ private void addVersionBox(int l, int t, int r, int b, Func<string> title, Func< )); AddObject(new ConsoleLabel( l + 2, t + 2, r - 2, - () => "Compatible with:", + () => Properties.Resources.ModInfoCompatibleWith, null, th => th.DimLabelFg )); @@ -506,7 +513,7 @@ private string HostedOn() string dl = mod.download?.ToString() ?? ""; foreach (var kvp in hostDomains) { if (dl.IndexOf(kvp.Key, StringComparison.CurrentCultureIgnoreCase) >= 0) { - return $"Hosted on {kvp.Value}"; + return string.Format(Properties.Resources.ModInfoHostedOn, kvp.Value); } } if (mod.resources != null) { @@ -514,7 +521,7 @@ private string HostedOn() string bt = mod.resources.bugtracker.ToString(); foreach (var kvp in hostDomains) { if (bt.IndexOf(kvp.Key, StringComparison.CurrentCultureIgnoreCase) >= 0) { - return $"Report bugs on {kvp.Value}"; + return string.Format(Properties.Resources.ModInfoReportBugsOn, kvp.Value); } } } @@ -522,7 +529,7 @@ private string HostedOn() string rep = mod.resources.repository.ToString(); foreach (var kvp in hostDomains) { if (rep.IndexOf(kvp.Key, StringComparison.CurrentCultureIgnoreCase) >= 0) { - return $"Repository on {kvp.Value}"; + return string.Format(Properties.Resources.ModInfoRepositoryOn, kvp.Value); } } } @@ -530,20 +537,15 @@ private string HostedOn() string hp = mod.resources.homepage.ToString(); foreach (var kvp in hostDomains) { if (hp.IndexOf(kvp.Key, StringComparison.CurrentCultureIgnoreCase) >= 0) { - return $"Home page on {kvp.Value}"; + return string.Format(Properties.Resources.ModInfoHomePageOn, kvp.Value); } } } if (mod.resources.store != null || mod.resources.steamstore != null) { - List<string> stores = new List<string>(); - if (mod.resources.store != null) { - stores.Add("KSP store"); - } - if (mod.resources.steamstore != null) { - stores.Add("Steam store"); - } - return $"Buy from {string.Join(" or ", stores)}"; + return mod.resources.steamstore == null ? Properties.Resources.ModInfoBuyFromKSPStore + : mod.resources.store == null ? Properties.Resources.ModInfoBuyFromSteamStore + : Properties.Resources.ModInfoBuyFromKSPStoreOrSteamStore; } } return mod.download?.Host ?? ""; @@ -551,7 +553,7 @@ private string HostedOn() private void Download(ConsoleTheme theme) { - ProgressScreen ps = new ProgressScreen($"Downloading {mod.identifier}"); + ProgressScreen ps = new ProgressScreen(string.Format(Properties.Resources.ModInfoDownloading, mod.identifier)); NetAsyncModulesDownloader dl = new NetAsyncModulesDownloader(ps, manager.Cache); ModuleInstaller inst = new ModuleInstaller(manager.CurrentInstance, manager.Cache, ps); LaunchSubScreen( @@ -561,10 +563,10 @@ private void Download(ConsoleTheme theme) try { dl.DownloadModules(new List<CkanModule> {mod}); if (!manager.Cache.IsMaybeCachedZip(mod)) { - ps.RaiseError("Download failed, file is corrupted"); + ps.RaiseError(Properties.Resources.ModInfoDownloadFailed); } } catch (Exception ex) { - ps.RaiseError($"Download failed: {ex}"); + ps.RaiseError(Properties.Resources.ModInfoDownloadFailed, ex); } } ); diff --git a/ConsoleUI/ModListHelpDialog.cs b/ConsoleUI/ModListHelpDialog.cs index ade60c16b0..5f110337ff 100644 --- a/ConsoleUI/ModListHelpDialog.cs +++ b/ConsoleUI/ModListHelpDialog.cs @@ -1,4 +1,6 @@ using System; +using System.Linq; +using System.Text; using CKAN.ConsoleUI.Toolkit; namespace CKAN.ConsoleUI { @@ -27,20 +29,26 @@ public ModListHelpDialog() : base() th => th.PopupFg ); AddObject(symbolTb); - symbolTb.AddLine("Status Symbols"); - symbolTb.AddLine("=============="); - symbolTb.AddLine($"{installed} Installed"); - symbolTb.AddLine($"{autoInstalled} Auto-installed"); - symbolTb.AddLine($"{upgradable} Upgradeable"); - symbolTb.AddLine($"{autodetected} Manually installed"); - symbolTb.AddLine($"{replaceable} Replaceable"); - symbolTb.AddLine($"! Unavailable"); + symbolTb.AddLine(LeftRightTable( + Properties.Resources.ModListHelpSymbolHeader, + new Tuple<string, string>[] { + new Tuple<string, string>(installed, Properties.Resources.ModListHelpInstalled), + new Tuple<string, string>(autoInstalled, Properties.Resources.ModListHelpAutoInstalled), + new Tuple<string, string>(upgradable, Properties.Resources.ModListHelpUpgradeable), + new Tuple<string, string>(autodetected, Properties.Resources.ModListHelpManuallyInstalled), + new Tuple<string, string>(replaceable, Properties.Resources.ModListHelpReplaceable), + new Tuple<string, string>("!", Properties.Resources.ModListHelpUnavailable), + } + )); symbolTb.AddLine(" "); - symbolTb.AddLine("Basic Keys"); - symbolTb.AddLine("=========="); - symbolTb.AddLine("Tab Move focus"); - symbolTb.AddLine("Cursor keys Select row"); - symbolTb.AddLine("Escape Clear search"); + symbolTb.AddLine(LeftRightTable( + Properties.Resources.ModListHelpBasicKeysHeader, + new Tuple<string, string>[] { + new Tuple<string, string>(Properties.Resources.Tab, Properties.Resources.ModListHelpMoveFocus), + new Tuple<string, string>(Properties.Resources.CursorKeys, Properties.Resources.ModListHelpSelectRow), + new Tuple<string, string>(Properties.Resources.Esc, Properties.Resources.ModListHelpClearSearch), + } + )); ConsoleTextBox searchTb = new ConsoleTextBox( Console.WindowWidth / 2 + 1, GetTop() + 3, GetRight() - 2, GetBottom() - 4, @@ -50,22 +58,43 @@ public ModListHelpDialog() : base() th => th.PopupFg ); AddObject(searchTb); - searchTb.AddLine("Special Searches"); - searchTb.AddLine("================"); - searchTb.AddLine("@author Mods by author"); - searchTb.AddLine("~i Installed mods"); - searchTb.AddLine("~u Upgradeable mods"); - searchTb.AddLine("~dname Depend on name"); - searchTb.AddLine("~cname Conflict w/ name"); - searchTb.AddLine("~n New mods"); + searchTb.AddLine(LeftRightTable( + Properties.Resources.ModListHelpSpecialSearchesHeader, + new Tuple<string, string>[] { + new Tuple<string, string>($"@{Properties.Resources.ModListHelpAuthor}", Properties.Resources.ModListHelpSearchAuthor), + new Tuple<string, string>("~i", Properties.Resources.ModListHelpSearchInstalled), + new Tuple<string, string>("~u", Properties.Resources.ModListHelpSearchUpgradeable), + new Tuple<string, string>($"~d{Properties.Resources.ModListHelpName}", Properties.Resources.ModListHelpSearchDepends), + new Tuple<string, string>($"~c{Properties.Resources.ModListHelpName}", Properties.Resources.ModListHelpSearchConflicts), + new Tuple<string, string>("~n", Properties.Resources.ModListHelpSearchNew), + } + )); AddObject(new ConsoleButton( btnL, GetBottom() - 2, btnL + btnW - 1, - "OK", + Properties.Resources.OK, Quit )); } + private string LeftRightTable(string header, Tuple<string, string>[] rows) + { + int leftW = rows.Max(r => r.Item1.Length); + int rightW = rows.Max(r => r.Item2.Length); + int fullW = Math.Max(leftW + rightW + tableSpacing, header.Length); + int midW = fullW - leftW - rightW; + StringBuilder sb = new StringBuilder(); + sb.AppendLine(header); + sb.AppendLine(new string('=', fullW)); + string mid = new string(' ', midW); + foreach (var row in rows) { + sb.AppendLine(row.Item1.PadRight(leftW) + mid + row.Item2.PadLeft(rightW)); + } + return sb.ToString(); + } + + private const int tableSpacing = 2; + private static readonly string installed = Symbols.checkmark; private static readonly string autoInstalled = Symbols.feminineOrdinal; private static readonly string upgradable = Symbols.greaterEquals; diff --git a/ConsoleUI/ModListScreen.cs b/ConsoleUI/ModListScreen.cs index a2290a6889..45ae2735a3 100644 --- a/ConsoleUI/ModListScreen.cs +++ b/ConsoleUI/ModListScreen.cs @@ -36,17 +36,17 @@ public ModListScreen(GameInstanceManager mgr, bool dbg, ConsoleTheme regTheme) Width = 1, Renderer = StatusSymbol }, new ConsoleListBoxColumn<CkanModule>() { - Header = "Name", + Header = Properties.Resources.ModListNameHeader, Width = 44, Renderer = m => m.name ?? "" }, new ConsoleListBoxColumn<CkanModule>() { - Header = "Version", + Header = Properties.Resources.ModListVersionHeader, Width = 10, Renderer = m => ModuleInstaller.StripEpoch(m.version?.ToString() ?? ""), Comparer = (a, b) => a.version.CompareTo(b.version) }, new ConsoleListBoxColumn<CkanModule>() { - Header = "Max game version", - Width = 17, + Header = Properties.Resources.ModListMaxGameVersionHeader, + Width = 20, Renderer = m => registry.LatestCompatibleKSP(m.identifier)?.ToString() ?? "", Comparer = (a, b) => registry.LatestCompatibleKSP(a.identifier).CompareTo(registry.LatestCompatibleKSP(b.identifier)) } @@ -113,8 +113,8 @@ public ModListScreen(GameInstanceManager mgr, bool dbg, ConsoleTheme regTheme) searchBox = new ConsoleField(-searchWidth, 2, -1) { GhostText = () => Focused() == searchBox - ? "<Type to search>" - : "<Ctrl+F to search>" + ? Properties.Resources.ModListSearchFocusedGhostText + : Properties.Resources.ModListSearchUnfocusedGhostText }; searchBox.OnChange += (ConsoleField sender, string newValue) => { moduleList.FilterString = newValue; @@ -122,7 +122,7 @@ public ModListScreen(GameInstanceManager mgr, bool dbg, ConsoleTheme regTheme) AddObject(new ConsoleLabel( 1, 2, -searchWidth - 2, - () => $"{moduleList.VisibleRowCount()} mods" + () => string.Format(Properties.Resources.ModListCount, moduleList.VisibleRowCount()) )); AddObject(searchBox); AddObject(moduleList); @@ -158,7 +158,7 @@ public ModListScreen(GameInstanceManager mgr, bool dbg, ConsoleTheme regTheme) return true; }); - moduleList.AddTip("Enter", "Details", + moduleList.AddTip(Properties.Resources.Enter, Properties.Resources.Details, () => moduleList.Selection != null ); moduleList.AddBinding(Keys.Enter, (object sender, ConsoleTheme theme) => { @@ -170,15 +170,15 @@ public ModListScreen(GameInstanceManager mgr, bool dbg, ConsoleTheme regTheme) // Conditionally show only one of these based on selected mod status - moduleList.AddTip("+", "Install", + moduleList.AddTip("+", Properties.Resources.ModListInstallTip, () => moduleList.Selection != null && !moduleList.Selection.IsDLC && !registry.IsInstalled(moduleList.Selection.identifier, false) ); - moduleList.AddTip("+", "Upgrade", + moduleList.AddTip("+", Properties.Resources.ModListUpgradeTip, () => moduleList.Selection != null && !moduleList.Selection.IsDLC && registry.HasUpdate(moduleList.Selection.identifier, manager.CurrentInstance.VersionCriteria()) ); - moduleList.AddTip("+", "Replace", + moduleList.AddTip("+", Properties.Resources.ModListReplaceTip, () => moduleList.Selection != null && registry.GetReplacement(moduleList.Selection.identifier, manager.CurrentInstance.VersionCriteria()) != null ); @@ -196,7 +196,7 @@ public ModListScreen(GameInstanceManager mgr, bool dbg, ConsoleTheme regTheme) return true; }); - moduleList.AddTip("-", "Remove", + moduleList.AddTip("-", Properties.Resources.ModListRemoveTip, () => moduleList.Selection != null && !moduleList.Selection.IsDLC && registry.IsInstalled(moduleList.Selection.identifier, false) && !registry.IsAutodetected(moduleList.Selection.identifier) @@ -210,11 +210,11 @@ public ModListScreen(GameInstanceManager mgr, bool dbg, ConsoleTheme regTheme) return true; }); - moduleList.AddTip("F8", "Mark auto-installed", + moduleList.AddTip("F8", Properties.Resources.ModListAutoInstTip, () => moduleList.Selection != null && !moduleList.Selection.IsDLC && (!registry.InstalledModule(moduleList.Selection.identifier)?.AutoInstalled ?? false) ); - moduleList.AddTip("F8", "Mark user-selected", + moduleList.AddTip("F8", Properties.Resources.ModListUserSelectedTip, () => moduleList.Selection != null && !moduleList.Selection.IsDLC && (registry.InstalledModule(moduleList.Selection.identifier)?.AutoInstalled ?? false) ); @@ -227,7 +227,7 @@ public ModListScreen(GameInstanceManager mgr, bool dbg, ConsoleTheme regTheme) return true; }); - AddTip("F9", "Apply changes", plan.NonEmpty); + AddTip("F9", Properties.Resources.ModListApplyChangesTip, plan.NonEmpty); AddBinding(Keys.F9, (object sender, ConsoleTheme theme) => { ApplyChanges(theme); return true; @@ -236,7 +236,7 @@ public ModListScreen(GameInstanceManager mgr, bool dbg, ConsoleTheme regTheme) // Show total download size of all installed mods AddObject(new ConsoleLabel( 1, -1, searchWidth, - () => $"{CkanModule.FmtSize(totalInstalledDownloadSize())} installed", + () => string.Format(Properties.Resources.ModListSizeOnDisk, CkanModule.FmtSize(totalInstalledDownloadSize())), null, th => th.DimLabelFg )); @@ -246,68 +246,64 @@ public ModListScreen(GameInstanceManager mgr, bool dbg, ConsoleTheme regTheme) () => { int days = daysSinceUpdated(registryFilePath()); return days < 1 ? "" - : days == 1 ? $"Updated at least {days} day ago" - : $"Updated at least {days} days ago"; + : days == 1 ? string.Format(Properties.Resources.ModListUpdatedDayAgo, days) + : string.Format(Properties.Resources.ModListUpdatedDaysAgo, days); }, null, (ConsoleTheme th) => { int daysSince = daysSinceUpdated(registryFilePath()); - if (daysSince < daysTillStale) { - return th.RegistryUpToDate; - } else if (daysSince < daystillVeryStale) { - return th.RegistryStale; - } else { - return th.RegistryVeryStale; - } + return daysSince < daysTillStale ? th.RegistryUpToDate + : daysSince < daystillVeryStale ? th.RegistryStale + : th.RegistryVeryStale; } )); List<ConsoleMenuOption> opts = new List<ConsoleMenuOption>() { - new ConsoleMenuOption("Sort...", "", - "Change the sorting of the list of mods", + new ConsoleMenuOption(Properties.Resources.ModListSortMenu, "", + Properties.Resources.ModListSortMenuTip, true, null, null, moduleList.SortMenu()), null, - new ConsoleMenuOption("Refresh mod list", "F5, Ctrl+R", - "Refresh the list of mods", + new ConsoleMenuOption(Properties.Resources.ModListRefreshMenu, $"F5, {Properties.Resources.Ctrl}+R", + Properties.Resources.ModListRefreshMenuTip, true, (ConsoleTheme th) => UpdateRegistry(th)), - new ConsoleMenuOption("Upgrade all", "Ctrl+U", - "Mark all available updates for installation", + new ConsoleMenuOption(Properties.Resources.ModListUpgradeMenu, $"{Properties.Resources.Ctrl}+U", + Properties.Resources.ModListUpgradeMenuTip, true, UpgradeAll, null, null, HasAnyUpgradeable()), - new ConsoleMenuOption("Audit recommendations", "", - "List mods suggested and recommended by installed mods", + new ConsoleMenuOption(Properties.Resources.ModListAuditRecsMenu, "", + Properties.Resources.ModListAuditRecsMenuTip, true, ViewSuggestions), - new ConsoleMenuOption("Import downloads...", "", - "Select manually downloaded mods to import into CKAN", + new ConsoleMenuOption(Properties.Resources.ModListImportMenu, "", + Properties.Resources.ModListImportMenuTip, true, ImportDownloads), - new ConsoleMenuOption("Export installed...", "", - "Save your mod list", + new ConsoleMenuOption(Properties.Resources.ModListExportMenu, "", + Properties.Resources.ModListExportMenuTip, true, ExportInstalled), null, - new ConsoleMenuOption("Game instance settings...", "", - "Configure the current game instance", + new ConsoleMenuOption(Properties.Resources.ModListInstanceSettingsMenu, "", + Properties.Resources.ModListInstanceSettingsMenuTip, true, InstanceSettings), - new ConsoleMenuOption("Select game instance...", "", - "Switch to a different game instance", + new ConsoleMenuOption(Properties.Resources.ModListSelectInstanceMenu, "", + Properties.Resources.ModListSelectInstanceMenuTip, true, SelectInstall), - new ConsoleMenuOption("Authentication tokens...", "", - "Edit authentication tokens sent to download servers", + new ConsoleMenuOption(Properties.Resources.ModListAuthTokenMenu, "", + Properties.Resources.ModListAuthTokenMenuTip, true, EditAuthTokens), - new ConsoleMenuOption("Installation filters...", "", - "Edit list of files and folders to exclude from installation", + new ConsoleMenuOption(Properties.Resources.ModListFilterMenu, "", + Properties.Resources.ModListFilterMenuTip, true, EditInstallFilters), null, - new ConsoleMenuOption("Help", helpKey, - "Tips & tricks", + new ConsoleMenuOption(Properties.Resources.ModListHelpMenu, helpKey, + Properties.Resources.ModListHelpMenuTip, true, Help), null, - new ConsoleMenuOption("Quit", "Ctrl+Q", - "Exit to DOS", + new ConsoleMenuOption(Properties.Resources.ModListQuitMenu, $"{Properties.Resources.Ctrl}+Q", + Properties.Resources.ModListQuitMenuTip, true, (ConsoleTheme th) => false) }; if (debug) { opts.Add(null); - opts.Add(new ConsoleMenuOption("DEBUG: Capture key...", "", - "Print details of how your system reports a keystroke for debugging", + opts.Add(new ConsoleMenuOption(Properties.Resources.ModListCaptureKeyMenu, "", + Properties.Resources.ModListCaptureKeyMenuTip, true, CaptureKey)); } mainMenu = new ConsolePopupMenu(opts); @@ -333,7 +329,7 @@ protected override string CenterHeader() // an option other than F1 for terminals that open their own help. private static readonly string helpKey = Platform.IsMac ? "F1" - : "F1, Alt+H"; + : $"F1, {Properties.Resources.Alt}+H"; private bool ImportDownloads(ConsoleTheme theme) { @@ -345,13 +341,13 @@ private bool ImportDownloads(ConsoleTheme theme) private bool CaptureKey(ConsoleTheme theme) { ConsoleKeyInfo k = default(ConsoleKeyInfo); - ConsoleMessageDialog keyprompt = new ConsoleMessageDialog("Press a key", new List<string>()); + ConsoleMessageDialog keyprompt = new ConsoleMessageDialog(Properties.Resources.ModListPressAKey, new List<string>()); keyprompt.Run(theme, (ConsoleTheme th) => { k = Console.ReadKey(true); }); ConsoleMessageDialog output = new ConsoleMessageDialog( $"Key: {k.Key,18}\nKeyChar: 0x{(int)k.KeyChar:x2}\nModifiers: {k.Modifiers,12}", - new List<string> {"OK"} + new List<string> { Properties.Resources.OK } ); output.Run(theme); return true; @@ -406,7 +402,7 @@ private bool ViewSuggestions(ConsoleTheme theme) RefreshList(theme); } } else { - RaiseError("Installed mods have no unsatisfied recommendations or suggestions."); + RaiseError(Properties.Resources.ModListAuditNotFound); } } catch (ModuleNotFoundKraken k) { RaiseError($"{k.module} {k.version}: {k.Message}"); @@ -426,7 +422,10 @@ private int daysSinceUpdated(string filename) private bool UpdateRegistry(ConsoleTheme theme, bool showNewModsPrompt = true) { - ProgressScreen ps = new ProgressScreen("Updating Registry", "Checking for updates"); + ProgressScreen ps = new ProgressScreen( + Properties.Resources.ModListUpdateRegistryTitle, + Properties.Resources.ModListUpdateRegistryMessage + ); LaunchSubScreen(theme, ps, (ConsoleTheme th) => { HashSet<string> availBefore = new HashSet<string>( Array.ConvertAll<CkanModule, string>( @@ -474,8 +473,8 @@ private bool UpdateRegistry(ConsoleTheme theme, bool showNewModsPrompt = true) private string newModPrompt(int howMany) { return howMany == 1 - ? $"{howMany} new mod available since last update. Show it?" - : $"{howMany} new mods available since last update. Show them?"; + ? string.Format(Properties.Resources.ModListNewMod, howMany) + : string.Format(Properties.Resources.ModListNewMods, howMany); } private bool ScanForMods() @@ -484,7 +483,7 @@ private bool ScanForMods() manager.CurrentInstance.Scan(); } catch (InconsistentKraken ex) { // Warn about inconsistent state - RaiseError(ex.InconsistenciesPretty + " The repo has not been saved."); + RaiseError(Properties.Resources.ModListScanBad, ex.InconsistenciesPretty); } return true; } @@ -591,11 +590,11 @@ private bool ExportInstalled(ConsoleTheme theme) RegistryManager.Instance(manager.CurrentInstance).Save(true); string path = Path.Combine( manager.CurrentInstance.CkanDir(), - $"installed-{manager.CurrentInstance.Name}.ckan" + $"{Properties.Resources.ModListExportPrefix}-{manager.CurrentInstance.Name}.ckan" ); - RaiseError($"Mod list exported to {path}"); + RaiseError(Properties.Resources.ModListExported, path); } catch (Exception ex) { - RaiseError($"Export failed: {ex.Message}"); + RaiseError(Properties.Resources.ModListExportFailed, ex.Message); } return true; } @@ -675,7 +674,10 @@ private long totalInstalledDownloadSize() private ChangePlan plan = new ChangePlan(); private HashSet<string> recent = new HashSet<string>(); - private const int searchWidth = 30; + private int searchWidth => Math.Max(30, Math.Max( + Properties.Resources.ModListSearchFocusedGhostText.Length, + Properties.Resources.ModListSearchUnfocusedGhostText.Length + )); private const int daysTillStale = 7; private const int daystillVeryStale = 30; diff --git a/ConsoleUI/ProgressScreen.cs b/ConsoleUI/ProgressScreen.cs index 593975e716..e36e609eb2 100644 --- a/ConsoleUI/ProgressScreen.cs +++ b/ConsoleUI/ProgressScreen.cs @@ -21,8 +21,8 @@ public ProgressScreen(string descrip, string initMsg = "") // A nice frame to take up some of the blank space at the top AddObject(new ConsoleDoubleFrame( 1, 2, -1, -1, 8, - () => "Progress", - () => "Messages", + () => Properties.Resources.ProgressTitle, + () => Properties.Resources.ProgressMessages, // Cheating because our IUser handler needs a theme context th => { yesNoTheme = th; return th.NormalFrameFg; } )); @@ -74,7 +74,10 @@ public override bool RaiseYesNoDialog(string question) ConsoleMessageDialog d = new ConsoleMessageDialog( // The installer's questions include embedded newlines for spacing in CmdLine question.Trim(), - new List<string>() {"Yes", "No"}, + new List<string>() { + Properties.Resources.Yes, + Properties.Resources.No + }, null, TextAlign.Center, -Console.WindowHeight / 2 @@ -89,7 +92,7 @@ public override bool RaiseYesNoDialog(string question) }); // Scroll messages - d.AddTip("Cursor keys", "Scroll messages"); + d.AddTip(Properties.Resources.CursorKeys, Properties.Resources.ScrollMessages); messages.AddScrollBindings(d, true); bool val = d.Run(yesNoTheme) == 0; diff --git a/ConsoleUI/Properties/AssemblyInfo.cs b/ConsoleUI/Properties/AssemblyInfo.cs index 241d366188..7c6c544480 100644 --- a/ConsoleUI/Properties/AssemblyInfo.cs +++ b/ConsoleUI/Properties/AssemblyInfo.cs @@ -1,4 +1,10 @@ +using System.Resources; using System.Reflection; +using System.Runtime.CompilerServices; [assembly: AssemblyTitle("CKAN-ConsoleUI")] [assembly: AssemblyDescription("CKAN ConsoleUI Client")] +[assembly: NeutralResourcesLanguage("en-GB")] + +[assembly: InternalsVisibleTo("Tests")] +[assembly: InternalsVisibleTo("CKAN.Tests")] diff --git a/ConsoleUI/Properties/Resources.Designer.cs b/ConsoleUI/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..bd5668ad29 --- /dev/null +++ b/ConsoleUI/Properties/Resources.Designer.cs @@ -0,0 +1,844 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. (I WISH!) +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace CKAN.ConsoleUI.Properties { + using System; + + + /// <summary> + /// A strongly-typed resource class, for looking up localized strings, etc. + /// </summary> + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { } + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) + { + resourceMan = new SingleAssemblyResourceManager("CKAN.ConsoleUI.Properties.Resources", typeof(Resources).Assembly); + } + return resourceMan; + } + } + + /// <summary> + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + internal static string Accept { + get { return (string)(ResourceManager.GetObject("Accept", resourceCulture)); } + } + internal static string Cancel { + get { return (string)(ResourceManager.GetObject("Cancel", resourceCulture)); } + } + internal static string DefaultGhostText { + get { return (string)(ResourceManager.GetObject("DefaultGhostText", resourceCulture)); } + } + internal static string Ascending { + get { return (string)(ResourceManager.GetObject("Ascending", resourceCulture)); } + } + internal static string AscendingSortTip { + get { return (string)(ResourceManager.GetObject("AscendingSortTip", resourceCulture)); } + } + internal static string Descending { + get { return (string)(ResourceManager.GetObject("Descending", resourceCulture)); } + } + internal static string DescendingSortTip { + get { return (string)(ResourceManager.GetObject("DescendingSortTip", resourceCulture)); } + } + internal static string ColumnNumber { + get { return (string)(ResourceManager.GetObject("ColumnNumber", resourceCulture)); } + } + internal static string ColumnNumberSortTip { + get { return (string)(ResourceManager.GetObject("ColumnNumberSortTip", resourceCulture)); } + } + internal static string ColumnNameSortTip { + get { return (string)(ResourceManager.GetObject("ColumnNameSortTip", resourceCulture)); } + } + internal static string CursorKeys { + get { return (string)(ResourceManager.GetObject("CursorKeys", resourceCulture)); } + } + internal static string Scroll { + get { return (string)(ResourceManager.GetObject("Scroll", resourceCulture)); } + } + internal static string ScrollMessages { + get { return (string)(ResourceManager.GetObject("ScrollMessages", resourceCulture)); } + } + internal static string Menu { + get { return (string)(ResourceManager.GetObject("Menu", resourceCulture)); } + } + internal static string Yes { + get { return (string)(ResourceManager.GetObject("Yes", resourceCulture)); } + } + internal static string No { + get { return (string)(ResourceManager.GetObject("No", resourceCulture)); } + } + internal static string OK { + get { return (string)(ResourceManager.GetObject("OK", resourceCulture)); } + } + internal static string Force { + get { return (string)(ResourceManager.GetObject("Force", resourceCulture)); } + } + internal static string Tab { + get { return (string)(ResourceManager.GetObject("Tab", resourceCulture)); } + } + internal static string Enter { + get { return (string)(ResourceManager.GetObject("Enter", resourceCulture)); } + } + internal static string Esc { + get { return (string)(ResourceManager.GetObject("Esc", resourceCulture)); } + } + internal static string Ctrl { + get { return (string)(ResourceManager.GetObject("Ctrl", resourceCulture)); } + } + internal static string Alt { + get { return (string)(ResourceManager.GetObject("Alt", resourceCulture)); } + } + internal static string Back { + get { return (string)(ResourceManager.GetObject("Back", resourceCulture)); } + } + internal static string Quit { + get { return (string)(ResourceManager.GetObject("Quit", resourceCulture)); } + } + internal static string Add { + get { return (string)(ResourceManager.GetObject("Add", resourceCulture)); } + } + internal static string Remove { + get { return (string)(ResourceManager.GetObject("Remove", resourceCulture)); } + } + internal static string Edit { + get { return (string)(ResourceManager.GetObject("Edit", resourceCulture)); } + } + internal static string Sort { + get { return (string)(ResourceManager.GetObject("Sort", resourceCulture)); } + } + internal static string Toggle { + get { return (string)(ResourceManager.GetObject("Toggle", resourceCulture)); } + } + internal static string Select { + get { return (string)(ResourceManager.GetObject("Select", resourceCulture)); } + } + internal static string SelectAll { + get { return (string)(ResourceManager.GetObject("SelectAll", resourceCulture)); } + } + internal static string DeselectAll { + get { return (string)(ResourceManager.GetObject("DeselectAll", resourceCulture)); } + } + internal static string Details { + get { return (string)(ResourceManager.GetObject("Details", resourceCulture)); } + } + internal static string Up { + get { return (string)(ResourceManager.GetObject("Up", resourceCulture)); } + } + internal static string Down { + get { return (string)(ResourceManager.GetObject("Down", resourceCulture)); } + } + internal static string FileSelectDirectory { + get { return (string)(ResourceManager.GetObject("FileSelectDirectory", resourceCulture)); } + } + internal static string FileSelectCountFooter { + get { return (string)(ResourceManager.GetObject("FileSelectCountFooter", resourceCulture)); } + } + internal static string FileSelectNameHeader { + get { return (string)(ResourceManager.GetObject("FileSelectNameHeader", resourceCulture)); } + } + internal static string FileSelectSizeHeader { + get { return (string)(ResourceManager.GetObject("FileSelectSizeHeader", resourceCulture)); } + } + internal static string FileSelectTimestampHeader { + get { return (string)(ResourceManager.GetObject("FileSelectTimestampHeader", resourceCulture)); } + } + internal static string FileSelectChangeDirectory { + get { return (string)(ResourceManager.GetObject("FileSelectChangeDirectory", resourceCulture)); } + } + internal static string FileSelectSelect { + get { return (string)(ResourceManager.GetObject("FileSelectSelect", resourceCulture)); } + } + internal static string FileSelectImport { + get { return (string)(ResourceManager.GetObject("FileSelectImport", resourceCulture)); } + } + internal static string FileSelectDirSize { + get { return (string)(ResourceManager.GetObject("FileSelectDirSize", resourceCulture)); } + } + internal static string AuthTokenListTitle { + get { return (string)(ResourceManager.GetObject("AuthTokenListTitle", resourceCulture)); } + } + internal static string AuthTokenListGitHubLink { + get { return (string)(ResourceManager.GetObject("AuthTokenListGitHubLink", resourceCulture)); } + } + internal static string AuthTokenListGitHubLinkTip { + get { return (string)(ResourceManager.GetObject("AuthTokenListGitHubLinkTip", resourceCulture)); } + } + internal static string AuthTokenListLabel { + get { return (string)(ResourceManager.GetObject("AuthTokenListLabel", resourceCulture)); } + } + internal static string AuthTokenListHostHeader { + get { return (string)(ResourceManager.GetObject("AuthTokenListHostHeader", resourceCulture)); } + } + internal static string AuthTokenListTokenHeader { + get { return (string)(ResourceManager.GetObject("AuthTokenListTokenHeader", resourceCulture)); } + } + internal static string AuthTokenListWarning { + get { return (string)(ResourceManager.GetObject("AuthTokenListWarning", resourceCulture)); } + } + internal static string AuthTokenListMissingToken { + get { return (string)(ResourceManager.GetObject("AuthTokenListMissingToken", resourceCulture)); } + } + internal static string AuthTokenAddTitle { + get { return (string)(ResourceManager.GetObject("AuthTokenAddTitle", resourceCulture)); } + } + internal static string AuthTokenAddHost { + get { return (string)(ResourceManager.GetObject("AuthTokenAddHost", resourceCulture)); } + } + internal static string AuthTokenAddHostGhostText { + get { return (string)(ResourceManager.GetObject("AuthTokenAddHostGhostText", resourceCulture)); } + } + internal static string AuthTokenAddToken { + get { return (string)(ResourceManager.GetObject("AuthTokenAddToken", resourceCulture)); } + } + internal static string AuthTokenAddTokenGhostText { + get { return (string)(ResourceManager.GetObject("AuthTokenAddTokenGhostText", resourceCulture)); } + } + internal static string CompatibleVersionsTitle { + get { return (string)(ResourceManager.GetObject("CompatibleVersionsTitle", resourceCulture)); } + } + internal static string CompatibleVersionsListHeader { + get { return (string)(ResourceManager.GetObject("CompatibleVersionsListHeader", resourceCulture)); } + } + internal static string CompatibleVersionsListAcceptTip { + get { return (string)(ResourceManager.GetObject("CompatibleVersionsListAcceptTip", resourceCulture)); } + } + internal static string CompatibleVersionsGhostText { + get { return (string)(ResourceManager.GetObject("CompatibleVersionsGhostText", resourceCulture)); } + } + internal static string CompatibleVersionsEntryAcceptTip { + get { return (string)(ResourceManager.GetObject("CompatibleVersionsEntryAcceptTip", resourceCulture)); } + } + internal static string ThemeNotFound { + get { return (string)(ResourceManager.GetObject("ThemeNotFound", resourceCulture)); } + } + internal static string ThemeList { + get { return (string)(ResourceManager.GetObject("ThemeList", resourceCulture)); } + } + internal static string RecommendationsLabel { + get { return (string)(ResourceManager.GetObject("RecommendationsLabel", resourceCulture)); } + } + internal static string RecommendationsInstallHeader { + get { return (string)(ResourceManager.GetObject("RecommendationsInstallHeader", resourceCulture)); } + } + internal static string RecommendationsNameHeader { + get { return (string)(ResourceManager.GetObject("RecommendationsNameHeader", resourceCulture)); } + } + internal static string RecommendationsSourcesHeader { + get { return (string)(ResourceManager.GetObject("RecommendationsSourcesHeader", resourceCulture)); } + } + internal static string RecommendationsTitle { + get { return (string)(ResourceManager.GetObject("RecommendationsTitle", resourceCulture)); } + } + internal static string ImportSelectTitle { + get { return (string)(ResourceManager.GetObject("ImportSelectTitle", resourceCulture)); } + } + internal static string ImportSelectHeader { + get { return (string)(ResourceManager.GetObject("ImportSelectHeader", resourceCulture)); } + } + internal static string ImportProgressTitle { + get { return (string)(ResourceManager.GetObject("ImportProgressTitle", resourceCulture)); } + } + internal static string ImportProgressMessage { + get { return (string)(ResourceManager.GetObject("ImportProgressMessage", resourceCulture)); } + } + internal static string InstanceNameLabel { + get { return (string)(ResourceManager.GetObject("InstanceNameLabel", resourceCulture)); } + } + internal static string InstanceNameGhostText { + get { return (string)(ResourceManager.GetObject("InstanceNameGhostText", resourceCulture)); } + } + internal static string InstancePathGhostText { + get { return (string)(ResourceManager.GetObject("InstancePathGhostText", resourceCulture)); } + } + internal static string InstancePathLabel { + get { return (string)(ResourceManager.GetObject("InstancePathLabel", resourceCulture)); } + } + internal static string InstanceNameEmptyError { + get { return (string)(ResourceManager.GetObject("InstanceNameEmptyError", resourceCulture)); } + } + internal static string InstanceNameDuplicateError { + get { return (string)(ResourceManager.GetObject("InstanceNameDuplicateError", resourceCulture)); } + } + internal static string InstancePathNotGameFolderError { + get { return (string)(ResourceManager.GetObject("InstancePathNotGameFolderError", resourceCulture)); } + } + internal static string InstanceAddExample { + get { return (string)(ResourceManager.GetObject("InstanceAddExample", resourceCulture)); } + } + internal static string InstanceAddTitle { + get { return (string)(ResourceManager.GetObject("InstanceAddTitle", resourceCulture)); } + } + internal static string InstanceEditTitle { + get { return (string)(ResourceManager.GetObject("InstanceEditTitle", resourceCulture)); } + } + internal static string InstanceEditRepoFrameTitle { + get { return (string)(ResourceManager.GetObject("InstanceEditRepoFrameTitle", resourceCulture)); } + } + internal static string InstanceEditCompatFrameTitle { + get { return (string)(ResourceManager.GetObject("InstanceEditCompatFrameTitle", resourceCulture)); } + } + internal static string InstanceEditRepoIndexHeader { + get { return (string)(ResourceManager.GetObject("InstanceEditRepoIndexHeader", resourceCulture)); } + } + internal static string InstanceEditRepoNameHeader { + get { return (string)(ResourceManager.GetObject("InstanceEditRepoNameHeader", resourceCulture)); } + } + internal static string InstanceEditRepoURLHeader { + get { return (string)(ResourceManager.GetObject("InstanceEditRepoURLHeader", resourceCulture)); } + } + internal static string InstanceEditCompatVersionHeader { + get { return (string)(ResourceManager.GetObject("InstanceEditCompatVersionHeader", resourceCulture)); } + } + internal static string InstanceEditRegistryParseError { + get { return (string)(ResourceManager.GetObject("InstanceEditRegistryParseError", resourceCulture)); } + } + internal static string InstanceListTitle { + get { return (string)(ResourceManager.GetObject("InstanceListTitle", resourceCulture)); } + } + internal static string InstanceListLabel { + get { return (string)(ResourceManager.GetObject("InstanceListLabel", resourceCulture)); } + } + internal static string InstanceListDefaultHeader { + get { return (string)(ResourceManager.GetObject("InstanceListDefaultHeader", resourceCulture)); } + } + internal static string InstanceListNameHeader { + get { return (string)(ResourceManager.GetObject("InstanceListNameHeader", resourceCulture)); } + } + internal static string InstanceListGameHeader { + get { return (string)(ResourceManager.GetObject("InstanceListGameHeader", resourceCulture)); } + } + internal static string InstanceListVersionHeader { + get { return (string)(ResourceManager.GetObject("InstanceListVersionHeader", resourceCulture)); } + } + internal static string InstanceListPathHeader { + get { return (string)(ResourceManager.GetObject("InstanceListPathHeader", resourceCulture)); } + } + internal static string InstanceListLoadingInstance { + get { return (string)(ResourceManager.GetObject("InstanceListLoadingInstance", resourceCulture)); } + } + internal static string InstanceListDefaultToggle { + get { return (string)(ResourceManager.GetObject("InstanceListDefaultToggle", resourceCulture)); } + } + internal static string InstanceListLoadingError { + get { return (string)(ResourceManager.GetObject("InstanceListLoadingError", resourceCulture)); } + } + internal static string InstanceListLocked { + get { return (string)(ResourceManager.GetObject("InstanceListLocked", resourceCulture)); } + } + internal static string InstanceListNoVersion { + get { return (string)(ResourceManager.GetObject("InstanceListNoVersion", resourceCulture)); } + } + internal static string InstallTitle { + get { return (string)(ResourceManager.GetObject("InstallTitle", resourceCulture)); } + } + internal static string InstallMessage { + get { return (string)(ResourceManager.GetObject("InstallMessage", resourceCulture)); } + } + internal static string InstallOwnedFileConflict { + get { return (string)(ResourceManager.GetObject("InstallOwnedFileConflict", resourceCulture)); } + } + internal static string InstallUnownedFileConflict { + get { return (string)(ResourceManager.GetObject("InstallUnownedFileConflict", resourceCulture)); } + } + internal static string InstallFilesReverted { + get { return (string)(ResourceManager.GetObject("InstallFilesReverted", resourceCulture)); } + } + internal static string InstallAuthTokenPrompt { + get { return (string)(ResourceManager.GetObject("InstallAuthTokenPrompt", resourceCulture)); } + } + internal static string InstallTooManyModsNameHeader { + get { return (string)(ResourceManager.GetObject("InstallTooManyModsNameHeader", resourceCulture)); } + } + internal static string InstallBadMetadata { + get { return (string)(ResourceManager.GetObject("InstallBadMetadata", resourceCulture)); } + } + internal static string InstallUnsatisfiedDependency { + get { return (string)(ResourceManager.GetObject("InstallUnsatisfiedDependency", resourceCulture)); } + } + internal static string InstallModuleNotFound { + get { return (string)(ResourceManager.GetObject("InstallModuleNotFound", resourceCulture)); } + } + internal static string InstallNotInstalled { + get { return (string)(ResourceManager.GetObject("InstallNotInstalled", resourceCulture)); } + } + internal static string InstallModInstalled { + get { return (string)(ResourceManager.GetObject("InstallModInstalled", resourceCulture)); } + } + internal static string ModInfoTitle { + get { return (string)(ResourceManager.GetObject("ModInfoTitle", resourceCulture)); } + } + internal static string ModInfoMenuTip { + get { return (string)(ResourceManager.GetObject("ModInfoMenuTip", resourceCulture)); } + } + internal static string ModInfoAuthors { + get { return (string)(ResourceManager.GetObject("ModInfoAuthors", resourceCulture)); } + } + internal static string ModInfoLicence { + get { return (string)(ResourceManager.GetObject("ModInfoLicence", resourceCulture)); } + } + internal static string ModInfoDownload { + get { return (string)(ResourceManager.GetObject("ModInfoDownload", resourceCulture)); } + } + internal static string ModInfoDescriptionFrame { + get { return (string)(ResourceManager.GetObject("ModInfoDescriptionFrame", resourceCulture)); } + } + internal static string ModInfoUnavailableWarning { + get { return (string)(ResourceManager.GetObject("ModInfoUnavailableWarning", resourceCulture)); } + } + internal static string ModInfoDownloadToCache { + get { return (string)(ResourceManager.GetObject("ModInfoDownloadToCache", resourceCulture)); } + } + internal static string ModInfoHomePage { + get { return (string)(ResourceManager.GetObject("ModInfoHomePage", resourceCulture)); } + } + internal static string ModInfoHomePageTip { + get { return (string)(ResourceManager.GetObject("ModInfoHomePageTip", resourceCulture)); } + } + internal static string ModInfoRepository { + get { return (string)(ResourceManager.GetObject("ModInfoRepository", resourceCulture)); } + } + internal static string ModInfoRepositoryTip { + get { return (string)(ResourceManager.GetObject("ModInfoRepositoryTip", resourceCulture)); } + } + internal static string ModInfoBugtracker { + get { return (string)(ResourceManager.GetObject("ModInfoBugtracker", resourceCulture)); } + } + internal static string ModInfoBugtrackerTip { + get { return (string)(ResourceManager.GetObject("ModInfoBugtrackerTip", resourceCulture)); } + } + internal static string ModInfoSpaceDock { + get { return (string)(ResourceManager.GetObject("ModInfoSpaceDock", resourceCulture)); } + } + internal static string ModInfoSpaceDockTip { + get { return (string)(ResourceManager.GetObject("ModInfoSpaceDockTip", resourceCulture)); } + } + internal static string ModInfoCurse { + get { return (string)(ResourceManager.GetObject("ModInfoCurse", resourceCulture)); } + } + internal static string ModInfoCurseTip { + get { return (string)(ResourceManager.GetObject("ModInfoCurseTip", resourceCulture)); } + } + internal static string ModInfoStore { + get { return (string)(ResourceManager.GetObject("ModInfoStore", resourceCulture)); } + } + internal static string ModInfoStoreTip { + get { return (string)(ResourceManager.GetObject("ModInfoStoreTip", resourceCulture)); } + } + internal static string ModInfoSteamStore { + get { return (string)(ResourceManager.GetObject("ModInfoSteamStore", resourceCulture)); } + } + internal static string ModInfoSteamStoreTip { + get { return (string)(ResourceManager.GetObject("ModInfoSteamStoreTip", resourceCulture)); } + } + internal static string ModInfoViewMetadata { + get { return (string)(ResourceManager.GetObject("ModInfoViewMetadata", resourceCulture)); } + } + internal static string ModInfoViewMetadataTip { + get { return (string)(ResourceManager.GetObject("ModInfoViewMetadataTip", resourceCulture)); } + } + internal static string ModInfoViewMetadataTitle { + get { return (string)(ResourceManager.GetObject("ModInfoViewMetadataTitle", resourceCulture)); } + } + internal static string ModInfoURLLaunching { + get { return (string)(ResourceManager.GetObject("ModInfoURLLaunching", resourceCulture)); } + } + internal static string ModInfoDependenciesFrame { + get { return (string)(ResourceManager.GetObject("ModInfoDependenciesFrame", resourceCulture)); } + } + internal static string ModInfoRequiredLabel { + get { return (string)(ResourceManager.GetObject("ModInfoRequiredLabel", resourceCulture)); } + } + internal static string ModInfoConflictsLabel { + get { return (string)(ResourceManager.GetObject("ModInfoConflictsLabel", resourceCulture)); } + } + internal static string ModInfoReplacedBy { + get { return (string)(ResourceManager.GetObject("ModInfoReplacedBy", resourceCulture)); } + } + internal static string ModInfoInstalledOn { + get { return (string)(ResourceManager.GetObject("ModInfoInstalledOn", resourceCulture)); } + } + internal static string ModInfoInstalledManually { + get { return (string)(ResourceManager.GetObject("ModInfoInstalledManually", resourceCulture)); } + } + internal static string ModInfoLatestInstalledOn { + get { return (string)(ResourceManager.GetObject("ModInfoLatestInstalledOn", resourceCulture)); } + } + internal static string ModInfoLatestInstalledManually { + get { return (string)(ResourceManager.GetObject("ModInfoLatestInstalledManually", resourceCulture)); } + } + internal static string ModInfoLatestVersion { + get { return (string)(ResourceManager.GetObject("ModInfoLatestVersion", resourceCulture)); } + } + internal static string ModInfoOtherVersions { + get { return (string)(ResourceManager.GetObject("ModInfoOtherVersions", resourceCulture)); } + } + internal static string ModInfoUnavailableInstalledOn { + get { return (string)(ResourceManager.GetObject("ModInfoUnavailableInstalledOn", resourceCulture)); } + } + internal static string ModInfoUnavailableInstalledManually { + get { return (string)(ResourceManager.GetObject("ModInfoUnavailableInstalledManually", resourceCulture)); } + } + internal static string ModInfoCompatibleWith { + get { return (string)(ResourceManager.GetObject("ModInfoCompatibleWith", resourceCulture)); } + } + internal static string ModInfoHostedOn { + get { return (string)(ResourceManager.GetObject("ModInfoHostedOn", resourceCulture)); } + } + internal static string ModInfoReportBugsOn { + get { return (string)(ResourceManager.GetObject("ModInfoReportBugsOn", resourceCulture)); } + } + internal static string ModInfoRepositoryOn { + get { return (string)(ResourceManager.GetObject("ModInfoRepositoryOn", resourceCulture)); } + } + internal static string ModInfoHomePageOn { + get { return (string)(ResourceManager.GetObject("ModInfoHomePageOn", resourceCulture)); } + } + internal static string ModInfoBuyFromKSPStore { + get { return (string)(ResourceManager.GetObject("ModInfoBuyFromKSPStore", resourceCulture)); } + } + internal static string ModInfoBuyFromSteamStore { + get { return (string)(ResourceManager.GetObject("ModInfoBuyFromSteamStore", resourceCulture)); } + } + internal static string ModInfoBuyFromKSPStoreOrSteamStore { + get { return (string)(ResourceManager.GetObject("ModInfoBuyFromKSPStoreOrSteamStore", resourceCulture)); } + } + internal static string ModInfoDownloading { + get { return (string)(ResourceManager.GetObject("ModInfoDownloading", resourceCulture)); } + } + internal static string ModInfoDownloadCorrupted { + get { return (string)(ResourceManager.GetObject("ModInfoDownloadCorrupted", resourceCulture)); } + } + internal static string ModInfoDownloadFailed { + get { return (string)(ResourceManager.GetObject("ModInfoDownloadFailed", resourceCulture)); } + } + internal static string ProgressTitle { + get { return (string)(ResourceManager.GetObject("ProgressTitle", resourceCulture)); } + } + internal static string ProgressMessages { + get { return (string)(ResourceManager.GetObject("ProgressMessages", resourceCulture)); } + } + internal static string SplashLoading { + get { return (string)(ResourceManager.GetObject("SplashLoading", resourceCulture)); } + } + internal static string SplashPressAnyKey { + get { return (string)(ResourceManager.GetObject("SplashPressAnyKey", resourceCulture)); } + } + internal static string RepoNameLabel { + get { return (string)(ResourceManager.GetObject("RepoNameLabel", resourceCulture)); } + } + internal static string RepoNameGhostText { + get { return (string)(ResourceManager.GetObject("RepoNameGhostText", resourceCulture)); } + } + internal static string RepoURLLabel { + get { return (string)(ResourceManager.GetObject("RepoURLLabel", resourceCulture)); } + } + internal static string RepoURLGhostText { + get { return (string)(ResourceManager.GetObject("RepoURLGhostText", resourceCulture)); } + } + internal static string RepoImportTip { + get { return (string)(ResourceManager.GetObject("RepoImportTip", resourceCulture)); } + } + internal static string RepoTitle { + get { return (string)(ResourceManager.GetObject("RepoTitle", resourceCulture)); } + } + internal static string RepoNameEmptyError { + get { return (string)(ResourceManager.GetObject("RepoNameEmptyError", resourceCulture)); } + } + internal static string RepoNameDuplicateError { + get { return (string)(ResourceManager.GetObject("RepoNameDuplicateError", resourceCulture)); } + } + internal static string RepoURLEmptyError { + get { return (string)(ResourceManager.GetObject("RepoURLEmptyError", resourceCulture)); } + } + internal static string ModListNameHeader { + get { return (string)(ResourceManager.GetObject("ModListNameHeader", resourceCulture)); } + } + internal static string ModListVersionHeader { + get { return (string)(ResourceManager.GetObject("ModListVersionHeader", resourceCulture)); } + } + internal static string ModListMaxGameVersionHeader { + get { return (string)(ResourceManager.GetObject("ModListMaxGameVersionHeader", resourceCulture)); } + } + internal static string ModListSearchFocusedGhostText { + get { return (string)(ResourceManager.GetObject("ModListSearchFocusedGhostText", resourceCulture)); } + } + internal static string ModListSearchUnfocusedGhostText { + get { return (string)(ResourceManager.GetObject("ModListSearchUnfocusedGhostText", resourceCulture)); } + } + internal static string ModListCount { + get { return (string)(ResourceManager.GetObject("ModListCount", resourceCulture)); } + } + internal static string ModListSizeOnDisk { + get { return (string)(ResourceManager.GetObject("ModListSizeOnDisk", resourceCulture)); } + } + internal static string ModListInstallTip { + get { return (string)(ResourceManager.GetObject("ModListInstallTip", resourceCulture)); } + } + internal static string ModListUpgradeTip { + get { return (string)(ResourceManager.GetObject("ModListUpgradeTip", resourceCulture)); } + } + internal static string ModListReplaceTip { + get { return (string)(ResourceManager.GetObject("ModListReplaceTip", resourceCulture)); } + } + internal static string ModListRemoveTip { + get { return (string)(ResourceManager.GetObject("ModListRemoveTip", resourceCulture)); } + } + internal static string ModListAutoInstTip { + get { return (string)(ResourceManager.GetObject("ModListAutoInstTip", resourceCulture)); } + } + internal static string ModListUserSelectedTip { + get { return (string)(ResourceManager.GetObject("ModListUserSelectedTip", resourceCulture)); } + } + internal static string ModListApplyChangesTip { + get { return (string)(ResourceManager.GetObject("ModListApplyChangesTip", resourceCulture)); } + } + internal static string ModListUpdatedDayAgo { + get { return (string)(ResourceManager.GetObject("ModListUpdatedDayAgo", resourceCulture)); } + } + internal static string ModListUpdatedDaysAgo { + get { return (string)(ResourceManager.GetObject("ModListUpdatedDaysAgo", resourceCulture)); } + } + internal static string ModListSortMenu { + get { return (string)(ResourceManager.GetObject("ModListSortMenu", resourceCulture)); } + } + internal static string ModListSortMenuTip { + get { return (string)(ResourceManager.GetObject("ModListSortMenuTip", resourceCulture)); } + } + internal static string ModListRefreshMenu { + get { return (string)(ResourceManager.GetObject("ModListRefreshMenu", resourceCulture)); } + } + internal static string ModListRefreshMenuTip { + get { return (string)(ResourceManager.GetObject("ModListRefreshMenuTip", resourceCulture)); } + } + internal static string ModListUpgradeMenu { + get { return (string)(ResourceManager.GetObject("ModListUpgradeMenu", resourceCulture)); } + } + internal static string ModListUpgradeMenuTip { + get { return (string)(ResourceManager.GetObject("ModListUpgradeMenuTip", resourceCulture)); } + } + internal static string ModListAuditRecsMenu { + get { return (string)(ResourceManager.GetObject("ModListAuditRecsMenu", resourceCulture)); } + } + internal static string ModListAuditRecsMenuTip { + get { return (string)(ResourceManager.GetObject("ModListAuditRecsMenuTip", resourceCulture)); } + } + internal static string ModListImportMenu { + get { return (string)(ResourceManager.GetObject("ModListImportMenu", resourceCulture)); } + } + internal static string ModListImportMenuTip { + get { return (string)(ResourceManager.GetObject("ModListImportMenuTip", resourceCulture)); } + } + internal static string ModListExportMenu { + get { return (string)(ResourceManager.GetObject("ModListExportMenu", resourceCulture)); } + } + internal static string ModListExportMenuTip { + get { return (string)(ResourceManager.GetObject("ModListExportMenuTip", resourceCulture)); } + } + internal static string ModListInstanceSettingsMenu { + get { return (string)(ResourceManager.GetObject("ModListInstanceSettingsMenu", resourceCulture)); } + } + internal static string ModListInstanceSettingsMenuTip { + get { return (string)(ResourceManager.GetObject("ModListInstanceSettingsMenuTip", resourceCulture)); } + } + internal static string ModListSelectInstanceMenu { + get { return (string)(ResourceManager.GetObject("ModListSelectInstanceMenu", resourceCulture)); } + } + internal static string ModListSelectInstanceMenuTip { + get { return (string)(ResourceManager.GetObject("ModListSelectInstanceMenuTip", resourceCulture)); } + } + internal static string ModListAuthTokenMenu { + get { return (string)(ResourceManager.GetObject("ModListAuthTokenMenu", resourceCulture)); } + } + internal static string ModListAuthTokenMenuTip { + get { return (string)(ResourceManager.GetObject("ModListAuthTokenMenuTip", resourceCulture)); } + } + internal static string ModListHelpMenu { + get { return (string)(ResourceManager.GetObject("ModListHelpMenu", resourceCulture)); } + } + internal static string ModListFilterMenu { + get { return (string)(ResourceManager.GetObject("ModListFilterMenu", resourceCulture)); } + } + internal static string ModListFilterMenuTip { + get { return (string)(ResourceManager.GetObject("ModListFilterMenuTip", resourceCulture)); } + } + internal static string ModListHelpMenuTip { + get { return (string)(ResourceManager.GetObject("ModListHelpMenuTip", resourceCulture)); } + } + internal static string ModListQuitMenu { + get { return (string)(ResourceManager.GetObject("ModListQuitMenu", resourceCulture)); } + } + internal static string ModListQuitMenuTip { + get { return (string)(ResourceManager.GetObject("ModListQuitMenuTip", resourceCulture)); } + } + internal static string ModListCaptureKeyMenu { + get { return (string)(ResourceManager.GetObject("ModListCaptureKeyMenu", resourceCulture)); } + } + internal static string ModListCaptureKeyMenuTip { + get { return (string)(ResourceManager.GetObject("ModListCaptureKeyMenuTip", resourceCulture)); } + } + internal static string ModListPressAKey { + get { return (string)(ResourceManager.GetObject("ModListPressAKey", resourceCulture)); } + } + internal static string ModListAuditNotFound { + get { return (string)(ResourceManager.GetObject("ModListAuditNotFound", resourceCulture)); } + } + internal static string ModListUpdateRegistryTitle { + get { return (string)(ResourceManager.GetObject("ModListUpdateRegistryTitle", resourceCulture)); } + } + internal static string ModListUpdateRegistryMessage { + get { return (string)(ResourceManager.GetObject("ModListUpdateRegistryMessage", resourceCulture)); } + } + internal static string ModListNewMod { + get { return (string)(ResourceManager.GetObject("ModListNewMod", resourceCulture)); } + } + internal static string ModListNewMods { + get { return (string)(ResourceManager.GetObject("ModListNewMods", resourceCulture)); } + } + internal static string ModListScanBad { + get { return (string)(ResourceManager.GetObject("ModListScanBad", resourceCulture)); } + } + internal static string ModListExportPrefix { + get { return (string)(ResourceManager.GetObject("ModListExportPrefix", resourceCulture)); } + } + internal static string ModListExported { + get { return (string)(ResourceManager.GetObject("ModListExported", resourceCulture)); } + } + internal static string ModListExportFailed { + get { return (string)(ResourceManager.GetObject("ModListExportFailed", resourceCulture)); } + } + internal static string ModListHelpSymbolHeader { + get { return (string)(ResourceManager.GetObject("ModListHelpSymbolHeader", resourceCulture)); } + } + internal static string ModListHelpInstalled { + get { return (string)(ResourceManager.GetObject("ModListHelpInstalled", resourceCulture)); } + } + internal static string ModListHelpAutoInstalled { + get { return (string)(ResourceManager.GetObject("ModListHelpAutoInstalled", resourceCulture)); } + } + internal static string ModListHelpUpgradeable { + get { return (string)(ResourceManager.GetObject("ModListHelpUpgradeable", resourceCulture)); } + } + internal static string ModListHelpManuallyInstalled { + get { return (string)(ResourceManager.GetObject("ModListHelpManuallyInstalled", resourceCulture)); } + } + internal static string ModListHelpReplaceable { + get { return (string)(ResourceManager.GetObject("ModListHelpReplaceable", resourceCulture)); } + } + internal static string ModListHelpUnavailable { + get { return (string)(ResourceManager.GetObject("ModListHelpUnavailable", resourceCulture)); } + } + internal static string ModListHelpBasicKeysHeader { + get { return (string)(ResourceManager.GetObject("ModListHelpBasicKeysHeader", resourceCulture)); } + } + internal static string ModListHelpMoveFocus { + get { return (string)(ResourceManager.GetObject("ModListHelpMoveFocus", resourceCulture)); } + } + internal static string ModListHelpSelectRow { + get { return (string)(ResourceManager.GetObject("ModListHelpSelectRow", resourceCulture)); } + } + internal static string ModListHelpClearSearch { + get { return (string)(ResourceManager.GetObject("ModListHelpClearSearch", resourceCulture)); } + } + internal static string ModListHelpSpecialSearchesHeader { + get { return (string)(ResourceManager.GetObject("ModListHelpSpecialSearchesHeader", resourceCulture)); } + } + internal static string ModListHelpAuthor { + get { return (string)(ResourceManager.GetObject("ModListHelpAuthor", resourceCulture)); } + } + internal static string ModListHelpName { + get { return (string)(ResourceManager.GetObject("ModListHelpName", resourceCulture)); } + } + internal static string ModListHelpSearchAuthor { + get { return (string)(ResourceManager.GetObject("ModListHelpSearchAuthor", resourceCulture)); } + } + internal static string ModListHelpSearchInstalled { + get { return (string)(ResourceManager.GetObject("ModListHelpSearchInstalled", resourceCulture)); } + } + internal static string ModListHelpSearchUpgradeable { + get { return (string)(ResourceManager.GetObject("ModListHelpSearchUpgradeable", resourceCulture)); } + } + internal static string ModListHelpSearchDepends { + get { return (string)(ResourceManager.GetObject("ModListHelpSearchDepends", resourceCulture)); } + } + internal static string ModListHelpSearchConflicts { + get { return (string)(ResourceManager.GetObject("ModListHelpSearchConflicts", resourceCulture)); } + } + internal static string ModListHelpSearchNew { + get { return (string)(ResourceManager.GetObject("ModListHelpSearchNew", resourceCulture)); } + } + + internal static string FiltersAddMiniAVCMenu { + get { return (string)(ResourceManager.GetObject("FiltersAddMiniAVCMenu", resourceCulture)); } + } + internal static string FiltersAddMiniAVCMenuTip { + get { return (string)(ResourceManager.GetObject("FiltersAddMiniAVCMenuTip", resourceCulture)); } + } + internal static string FiltersGlobalHeader { + get { return (string)(ResourceManager.GetObject("FiltersGlobalHeader", resourceCulture)); } + } + internal static string FiltersInstanceHeader { + get { return (string)(ResourceManager.GetObject("FiltersInstanceHeader", resourceCulture)); } + } + internal static string FiltersTitle { + get { return (string)(ResourceManager.GetObject("FiltersTitle", resourceCulture)); } + } + + internal static string FilterAddGhostText { + get { return (string)(ResourceManager.GetObject("FilterAddGhostText", resourceCulture)); } + } + internal static string FilterAddAcceptTip { + get { return (string)(ResourceManager.GetObject("FilterAddAcceptTip", resourceCulture)); } + } + internal static string FilterAddTitle { + get { return (string)(ResourceManager.GetObject("FilterAddTitle", resourceCulture)); } + } + + internal static string ExitTitle { + get { return (string)(ResourceManager.GetObject("ExitTitle", resourceCulture)); } + } + internal static string ExitBody { + get { return (string)(ResourceManager.GetObject("ExitBody", resourceCulture)); } + } + + } +} diff --git a/ConsoleUI/Properties/Resources.en-US.resx b/ConsoleUI/Properties/Resources.en-US.resx new file mode 100644 index 0000000000..9022706a71 --- /dev/null +++ b/ConsoleUI/Properties/Resources.en-US.resx @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="ModInfoLicence" xml:space="preserve"><value>License:</value></data> +</root> diff --git a/ConsoleUI/Properties/Resources.fr-FR.resx b/ConsoleUI/Properties/Resources.fr-FR.resx new file mode 100644 index 0000000000..10fd355b6e --- /dev/null +++ b/ConsoleUI/Properties/Resources.fr-FR.resx @@ -0,0 +1,396 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="Accept" xml:space="preserve"><value>Accepter</value></data> + <data name="Cancel" xml:space="preserve"><value>Annuler</value></data> + <data name="DefaultGhostText" xml:space="preserve"><value><Entrez une valeur></value></data> + <data name="Ascending" xml:space="preserve"><value>Croissant</value></data> + <data name="AscendingSortTip" xml:space="preserve"><value>Trier la liste par ordre croissant</value></data> + <data name="Descending" xml:space="preserve"><value>Décroissant</value></data> + <data name="DescendingSortTip" xml:space="preserve"><value>Trier la liste par ordre décroissant</value></data> + <data name="ColumnNumber" xml:space="preserve"><value>Colonne #{0}</value></data> + <data name="ColumnNumberSortTip" xml:space="preserve"><value>Trier la liste par colonne #{0}</value></data> + <data name="ColumnNameSortTip" xml:space="preserve"><value>Trier la liste par la colonne {0}</value></data> + <data name="CursorKeys" xml:space="preserve"><value>Touches de curseur</value></data> + <data name="Scroll" xml:space="preserve"><value>Curseur</value></data> + <data name="ScrollMessages" xml:space="preserve"><value>Messages de Curseurs</value></data> + <data name="Menu" xml:space="preserve"><value>Menu</value></data> + <data name="Yes" xml:space="preserve"><value>Oui (Y)</value></data> + <data name="No" xml:space="preserve"><value>Non (N)</value></data> + <data name="OK" xml:space="preserve"><value>OK</value></data> + <data name="Force" xml:space="preserve"><value>Forcer</value></data> + <data name="Tab" xml:space="preserve"><value>Tabulation</value></data> + <data name="Enter" xml:space="preserve"><value>Entré</value></data> + <data name="Esc" xml:space="preserve"><value>Échappe</value></data> + <data name="Ctrl" xml:space="preserve"><value>Ctrl</value></data> + <data name="Alt" xml:space="preserve"><value>Alt</value></data> + <data name="Back" xml:space="preserve"><value>Retour</value></data> + <data name="Quit" xml:space="preserve"><value>Quitter</value></data> + <data name="Add" xml:space="preserve"><value>Ajouter</value></data> + <data name="Remove" xml:space="preserve"><value>Retirer</value></data> + <data name="Edit" xml:space="preserve"><value>Éditer</value></data> + <data name="Sort" xml:space="preserve"><value>Trier</value></data> + <data name="Toggle" xml:space="preserve"><value>Changer</value></data> + <data name="Select" xml:space="preserve"><value>Sélectionner</value></data> + <data name="SelectAll" xml:space="preserve"><value>Sélectionner tout</value></data> + <data name="DeselectAll" xml:space="preserve"><value>désélectionner tout</value></data> + <data name="Details" xml:space="preserve"><value>Détails</value></data> + <data name="Up" xml:space="preserve"><value>Haut</value></data> + <data name="Down" xml:space="preserve"><value>Bas</value></data> + <data name="FileSelectDirectory" xml:space="preserve"><value>Dossier</value></data> + <data name="FileSelectCountFooter" xml:space="preserve"><value>{0} sélectionné, {1}</value></data> + <data name="FileSelectNameHeader" xml:space="preserve"><value>Nom</value></data> + <data name="FileSelectSizeHeader" xml:space="preserve"><value>Taille</value></data> + <data name="FileSelectTimestampHeader" xml:space="preserve"><value>Accédé</value></data> + <data name="FileSelectChangeDirectory" xml:space="preserve"><value>Changer de dossier</value></data> + <data name="FileSelectSelect" xml:space="preserve"><value>Sélectionner</value></data> + <data name="FileSelectImport" xml:space="preserve"><value>Importer</value></data> + <data name="FileSelectDirSize" xml:space="preserve"><value><DOSSIER></value></data> + <data name="AuthTokenListTitle" xml:space="preserve"><value>Jetons d'Authentification</value></data> + <data name="AuthTokenListGitHubLink" xml:space="preserve"><value>Créer un jeton pour l'API GitHub</value></data> + <data name="AuthTokenListGitHubLinkTip" xml:space="preserve"><value>Ouvrir une page web pour créer un jeton d'authentification pour l'API GitHub</value></data> + <data name="AuthTokenListLabel" xml:space="preserve"><value>Jeton d'authentification pour les téléchargements :</value></data> + <data name="AuthTokenListHostHeader" xml:space="preserve"><value>Hôte</value></data> + <data name="AuthTokenListTokenHeader" xml:space="preserve"><value>Jeton</value></data> + <data name="AuthTokenListWarning" xml:space="preserve"><value>NOTE: Ces valeurs sont privées ! Ne partagez pas une capture de cet écran !</value></data> + <data name="AuthTokenListMissingToken" xml:space="preserve"><value><ERREUR></value></data> + <data name="AuthTokenAddTitle" xml:space="preserve"><value>Créer une clé d'authentification</value></data> + <data name="AuthTokenAddHost" xml:space="preserve"><value>Hôte :</value></data> + <data name="AuthTokenAddHostGhostText" xml:space="preserve"><value><Entrez un nom d'hôte></value></data> + <data name="AuthTokenAddToken" xml:space="preserve"><value>Jeton :</value></data> + <data name="AuthTokenAddTokenGhostText" xml:space="preserve"><value><Entrez un jeton d'authentification></value></data> + <data name="CompatibleVersionsTitle" xml:space="preserve"><value>Sélectionnez les Versions Compatibles</value></data> + <data name="CompatibleVersionsListHeader" xml:space="preserve"><value>Version Prédéfinie</value></data> + <data name="CompatibleVersionsListAcceptTip" xml:space="preserve"><value>Sélectionner cette version</value></data> + <data name="CompatibleVersionsGhostText" xml:space="preserve"><value><Entrez une version></value></data> + <data name="CompatibleVersionsEntryAcceptTip" xml:space="preserve"><value>Accepter cette value</value></data> + <data name="ThemeNotFound" xml:space="preserve"><value>Impossible de trouver ce thème : {0}</value></data> + <data name="ThemeList" xml:space="preserve"><value>Thèmes disponibles : {0}</value></data> + <data name="RecommendationsLabel" xml:space="preserve"><value>Des mods additionnels sont recommandés ou suggérés :</value></data> + <data name="RecommendationsInstallHeader" xml:space="preserve"><value>Installer</value></data> + <data name="RecommendationsNameHeader" xml:space="preserve"><value>Nom</value></data> + <data name="RecommendationsSourcesHeader" xml:space="preserve"><value>Sources</value></data> + <data name="RecommendationsTitle" xml:space="preserve"><value>Recommandations & Suggestions</value></data> + <data name="ImportSelectTitle" xml:space="preserve"><value>Importer les téléchargements</value></data> + <data name="ImportSelectHeader" xml:space="preserve"><value>Importer</value></data> + <data name="ImportProgressTitle" xml:space="preserve"><value>Importation des Téléchargements</value></data> + <data name="ImportProgressMessage" xml:space="preserve"><value>Calcul en cours...</value></data> + <data name="InstanceNameLabel" xml:space="preserve"><value>Nom :</value></data> + <data name="InstanceNameGhostText" xml:space="preserve"><value><Entrez le nom à utiliser pour cette instance de jeu></value></data> + <data name="InstancePathGhostText" xml:space="preserve"><value><Entrez l'emplacement de cette instance de jeu sur le disque></value></data> + <data name="InstancePathLabel" xml:space="preserve"><value>Chemin de l'instance :</value></data> + <data name="InstanceNameEmptyError" xml:space="preserve"><value>Le nom ne peut pas être vide !</value></data> + <data name="InstanceNameDuplicateError" xml:space="preserve"><value>{0} existe déjà !</value></data> + <data name="InstancePathNotGameFolderError" xml:space="preserve"><value>Le chemin ne correspond à un dossier de jeu !</value></data> + <data name="InstanceAddExample" xml:space="preserve"><value>Exemple : {0}</value></data> + <data name="InstanceAddTitle" xml:space="preserve"><value>Ajouter Instance de Jeu</value></data> + <data name="InstanceEditTitle" xml:space="preserve"><value>Éditer Instance de Jeu</value></data> + <data name="InstanceEditRepoFrameTitle" xml:space="preserve"><value>Sources de la Liste de Mods</value></data> + <data name="InstanceEditCompatFrameTitle" xml:space="preserve"><value>Versions Compatibles Additionnelles</value></data> + <data name="InstanceEditRepoIndexHeader" xml:space="preserve"><value>Index</value></data> + <data name="InstanceEditRepoNameHeader" xml:space="preserve"><value>Nom</value></data> + <data name="InstanceEditRepoURLHeader" xml:space="preserve"><value>Adresse</value></data> + <data name="InstanceEditCompatVersionHeader" xml:space="preserve"><value>Version</value></data> + <data name="InstanceEditRegistryParseError" xml:space="preserve"><value>Échec de l'extraction des sources de la liste de mods à partir de {0}.</value></data> + <data name="InstanceListTitle" xml:space="preserve"><value>Instances de Jeu</value></data> + <data name="InstanceListLabel" xml:space="preserve"><value>Sélectionner ou ajouter une instance de jeu :</value></data> + <data name="InstanceListDefaultHeader" xml:space="preserve"><value>Défaut</value></data> + <data name="InstanceListNameHeader" xml:space="preserve"><value>Nom</value></data> + <data name="InstanceListGameHeader" xml:space="preserve"><value>Jeu</value></data> + <data name="InstanceListVersionHeader" xml:space="preserve"><value>Version</value></data> + <data name="InstanceListPathHeader" xml:space="preserve"><value>Chemin</value></data> + <data name="InstanceListLoadingInstance" xml:space="preserve"><value>Chargement de l'instance {0}...</value></data> + <data name="InstanceListDefaultToggle" xml:space="preserve"><value>Défaut</value></data> + <data name="InstanceListLoadingError" xml:space="preserve"><value>Erreur lors du chargement de {0} : +{1}</value></data> + <data name="InstanceListLocked" xml:space="preserve"><value>Fichier verrou avec un ID de processus actif à {0} + +Cela veut probablement dire qu'une autre instance de CKAN s'occupe de cette instance. Vous pouvez supprimer ce fichier pour continuer, mais cela risque fortement de corrompre des données. + +Voulez-vous supprimez ce fichier verrou pour forcer l'accès ?</value></data> + <data name="InstanceListNoVersion" xml:space="preserve"><value><AUCUNE></value></data> + <data name="InstallTitle" xml:space="preserve"><value>Installation, Mise à Jour, et Retrait de Mods</value></data> + <data name="InstallMessage" xml:space="preserve"><value>Calcul en cours...</value></data> + <data name="InstallOwnedFileConflict" xml:space="preserve"><value>{0} a essayé d'installer {1}, mais {2} l'a déjà installé. +Veuillez signaler ce problème à https://github.com/KSP-CKAN/NetKAN/issues/new/choose</value></data> + <data name="InstallUnownedFileConflict" xml:space="preserve"><value>{0} a essayé d'installer {1}, mais {2} l'a déjà installé. +Veuillez désinstaller manuellement le mod auquel ce fichier appartient pour pouvoir installer {2}.</value></data> + <data name="InstallFilesReverted" xml:space="preserve"><value>Retour en arrière des fichiers de jeu.</value></data> + <data name="InstallAuthTokenPrompt" xml:space="preserve"><value>{0} + +Éditer les jetons d'authentification maintenant ?</value></data> + <data name="InstallTooManyModsNameHeader" xml:space="preserve"><value>Nom</value></data> + <data name="InstallBadMetadata" xml:space="preserve"><value>Métadonnées incorrectes détectées pour {0} : {1}</value></data> + <data name="InstallUnsatisfiedDependency" xml:space="preserve"><value>{0} nécessite {1}, mais il n'est pas listé dans l'index, ou indisponible pour votre version de jeu. +{2}</value></data> + <data name="InstallModuleNotFound" xml:space="preserve"><value>Le module {0} est requis mais il n'est pas listé dans l'index, ou indisponible pour votre version de jeu. +{1}</value></data> + <data name="InstallNotInstalled" xml:space="preserve"><value>{0} n'est pas installé, impossible de le retirer</value></data> + <data name="InstallModInstalled" xml:space="preserve"><value>{0} installé avec succès {1} {2}</value></data> + <data name="ModInfoTitle" xml:space="preserve"><value>Détails du Mod</value></data> + <data name="ModInfoMenuTip" xml:space="preserve"><value>Liens</value></data> + <data name="ModInfoAuthors" xml:space="preserve"><value>Par {0}</value></data> + <data name="ModInfoLicence" xml:space="preserve"><value>Licence :</value></data> + <data name="ModInfoDownload" xml:space="preserve"><value>Taille :</value></data> + <data name="ModInfoDescriptionFrame" xml:space="preserve"><value>Description</value></data> + <data name="ModInfoUnavailableWarning" xml:space="preserve"><value> +NOTE : Ce mod est installé mais n'est plus disponible. +Si vous le retirez, CKAN ne pourra pas le réinstaller.</value></data> + <data name="ModInfoDownloadToCache" xml:space="preserve"><value>Télécharger dans le cache (sans installer)</value></data> + <data name="ModInfoHomePage" xml:space="preserve"><value>Page Principale</value></data> + <data name="ModInfoHomePageTip" xml:space="preserve"><value>Ouvrir le lien de la page principale dans un navigateur</value></data> + <data name="ModInfoRepository" xml:space="preserve"><value>Répertoire</value></data> + <data name="ModInfoRepositoryTip" xml:space="preserve"><value>Ouvrir le lien du répertoire dans un navigateur</value></data> + <data name="ModInfoBugtracker" xml:space="preserve"><value>Traqueur de Bogues</value></data> + <data name="ModInfoBugtrackerTip" xml:space="preserve"><value>Ouvrir le lien du traqueur de bogues dans un navigateur</value></data> + <data name="ModInfoSpaceDock" xml:space="preserve"><value>SpaceDock</value></data> + <data name="ModInfoSpaceDockTip" xml:space="preserve"><value>Ouvrir le lien SpaceDock dans un navigateur</value></data> + <data name="ModInfoCurse" xml:space="preserve"><value>Curse</value></data> + <data name="ModInfoCurseTip" xml:space="preserve"><value>Ouvrir le lien Curse dans un navigateur</value></data> + <data name="ModInfoStore" xml:space="preserve"><value>Boutique</value></data> + <data name="ModInfoStoreTip" xml:space="preserve"><value>Ouvrir le lien de la boutique dans un navigateur</value></data> + <data name="ModInfoSteamStore" xml:space="preserve"><value>Magasin Steam</value></data> + <data name="ModInfoSteamStoreTip" xml:space="preserve"><value>Ouvrir le lien du magasin Steam dans un navigateur</value></data> + <data name="ModInfoViewMetadata" xml:space="preserve"><value>DÉBOGAGE : Voir les métadonnées</value></data> + <data name="ModInfoViewMetadataTip" xml:space="preserve"><value>Montrer toutes les données du registre pour ce mod</value></data> + <data name="ModInfoViewMetadataTitle" xml:space="preserve"><value>{0} Métadonnées</value></data> + <data name="ModInfoURLLaunching" xml:space="preserve"><value>Lancement...</value></data> + <data name="ModInfoDependenciesFrame" xml:space="preserve"><value>Dépendances</value></data> + <data name="ModInfoRequiredLabel" xml:space="preserve"><value>Requis ({0}) :</value></data> + <data name="ModInfoConflictsLabel" xml:space="preserve"><value>En conflit avec ({0}) :</value></data> + <data name="ModInfoReplacedBy" xml:space="preserve"><value>Remplacé par {0} :</value></data> + <data name="ModInfoInstalledOn" xml:space="preserve"><value>Installé le {0}</value></data> + <data name="ModInfoInstalledManually" xml:space="preserve"><value>Installé manuellement</value></data> + <data name="ModInfoLatestInstalledOn" xml:space="preserve"><value>Dernier/Installé {0}</value></data> + <data name="ModInfoLatestInstalledManually" xml:space="preserve"><value>Dernier/Installé manuellement</value></data> + <data name="ModInfoLatestVersion" xml:space="preserve"><value>Dernière Version</value></data> + <data name="ModInfoOtherVersions" xml:space="preserve"><value>Autres Versions</value></data> + <data name="ModInfoUnavailableInstalledOn" xml:space="preserve"><value>INDISPONIBLE/Installé {0}</value></data> + <data name="ModInfoUnavailableInstalledManually" xml:space="preserve"><value>INDISPONIBLE/Installé manuellement</value></data> + <data name="ModInfoCompatibleWith" xml:space="preserve"><value>Compatible avec :</value></data> + <data name="ModInfoHostedOn" xml:space="preserve"><value>Hébergé sur {0}</value></data> + <data name="ModInfoReportBugsOn" xml:space="preserve"><value>Signaler les bogues sur {0}</value></data> + <data name="ModInfoRepositoryOn" xml:space="preserve"><value>Répertoire sur {0}</value></data> + <data name="ModInfoHomePageOn" xml:space="preserve"><value>Page principale sur {0}</value></data> + <data name="ModInfoBuyFromKSPStore" xml:space="preserve"><value>Acheter depuis la boutique KSP</value></data> + <data name="ModInfoBuyFromSteamStore" xml:space="preserve"><value>Acheter depuis le magasin Steam</value></data> + <data name="ModInfoBuyFromKSPStoreOrSteamStore" xml:space="preserve"><value>Acheter depuis les boutiques KSP ou Steam</value></data> + <data name="ModInfoDownloading" xml:space="preserve"><value>Téléchargement de {0}</value></data> + <data name="ModInfoDownloadCorrupted" xml:space="preserve"><value>Échec du téléchargement, le fichier est corrompu</value></data> + <data name="ModInfoDownloadFailed" xml:space="preserve"><value>Échec du téléchargement : {0}</value></data> + <data name="ProgressTitle" xml:space="preserve"><value>Progression</value></data> + <data name="ProgressMessages" xml:space="preserve"><value>Messages</value></data> + <data name="SplashLoading" xml:space="preserve"><value>Chargement...</value></data> + <data name="SplashPressAnyKey" xml:space="preserve"><value>Appuyez sur n'importe quelle touche pour continuer</value></data> + <data name="RepoNameLabel" xml:space="preserve"><value>Nom :</value></data> + <data name="RepoNameGhostText" xml:space="preserve"><value><Entrez le nom à utiliser pour ce répertoire></value></data> + <data name="RepoURLLabel" xml:space="preserve"><value>Lien :</value></data> + <data name="RepoURLGhostText" xml:space="preserve"><value><Entrez le lien de ce répertoire></value></data> + <data name="RepoImportTip" xml:space="preserve"><value>Importer les valeurs depuis la source par défaut de la liste de mods {0}</value></data> + <data name="RepoTitle" xml:space="preserve"><value>Éditer la Source de la Liste de Mods</value></data> + <data name="RepoNameEmptyError" xml:space="preserve"><value>Le nom ne peut pas être vide !</value></data> + <data name="RepoNameDuplicateError" xml:space="preserve"><value>{0} existe déjà !</value></data> + <data name="RepoURLEmptyError" xml:space="preserve"><value>Le lien ne peut pas être vide !</value></data> + <data name="ModListNameHeader" xml:space="preserve"><value>Nom</value></data> + <data name="ModListVersionHeader" xml:space="preserve"><value>Version</value></data> + <data name="ModListMaxGameVersionHeader" xml:space="preserve"><value>Version de jeu max</value></data> + <data name="ModListSearchFocusedGhostText" xml:space="preserve"><value><Taper pour faire une recherche></value></data> + <data name="ModListSearchUnfocusedGhostText" xml:space="preserve"><value><Ctrl+F pour faire une recherche></value></data> + <data name="ModListCount" xml:space="preserve"><value>{0} mods</value></data> + <data name="ModListSizeOnDisk" xml:space="preserve"><value>{0} installés</value></data> + <data name="ModListInstallTip" xml:space="preserve"><value>Installer</value></data> + <data name="ModListUpgradeTip" xml:space="preserve"><value>Mettre à Jour</value></data> + <data name="ModListReplaceTip" xml:space="preserve"><value>Remplacer</value></data> + <data name="ModListRemoveTip" xml:space="preserve"><value>Retirer</value></data> + <data name="ModListAutoInstTip" xml:space="preserve"><value>Marquer le mod comme auto-installé</value></data> + <data name="ModListUserSelectedTip" xml:space="preserve"><value>Marquer le mod sélectionné comme installé par l'utilisateur</value></data> + <data name="ModListApplyChangesTip" xml:space="preserve"><value>Appliquer les changements</value></data> + <data name="ModListUpdatedDayAgo" xml:space="preserve"><value>Mis à jour il y a au moins {0} jour</value></data> + <data name="ModListUpdatedDaysAgo" xml:space="preserve"><value>Mis à jour il y a au moins {0} jours</value></data> + <data name="ModListSortMenu" xml:space="preserve"><value>Trier...</value></data> + <data name="ModListSortMenuTip" xml:space="preserve"><value>Changer le tri de la liste de mods</value></data> + <data name="ModListRefreshMenu" xml:space="preserve"><value>Rafraîchir liste de mods</value></data> + <data name="ModListRefreshMenuTip" xml:space="preserve"><value>Rafraîchir la liste de mods</value></data> + <data name="ModListUpgradeMenu" xml:space="preserve"><value>Tout mettre à niveau</value></data> + <data name="ModListUpgradeMenuTip" xml:space="preserve"><value>Marquer toutes les mises à jour prêtes à être installées</value></data> + <data name="ModListAuditRecsMenu" xml:space="preserve"><value>Auditionner les recommandations</value></data> + <data name="ModListAuditRecsMenuTip" xml:space="preserve"><value>Liste de tous les mods suggérés ou recommandés par les mods installés</value></data> + <data name="ModListImportMenu" xml:space="preserve"><value>Importer des téléchargements...</value></data> + <data name="ModListImportMenuTip" xml:space="preserve"><value>Sélectionnez des mods téléchargés manuellement à importer dans CKAN</value></data> + <data name="ModListExportMenu" xml:space="preserve"><value>Exporter les mods installés...</value></data> + <data name="ModListExportMenuTip" xml:space="preserve"><value>Sauvegarde de votre liste de mods installés</value></data> + <data name="ModListInstanceSettingsMenu" xml:space="preserve"><value>Paramètres de l'instance de jeu...</value></data> + <data name="ModListInstanceSettingsMenuTip" xml:space="preserve"><value>Configurer l'instance de jeu actuelle</value></data> + <data name="ModListSelectInstanceMenu" xml:space="preserve"><value>Sélectionner une instance de jeu...</value></data> + <data name="ModListSelectInstanceMenuTip" xml:space="preserve"><value>Passer à une instance de jeu différente</value></data> + <data name="ModListAuthTokenMenu" xml:space="preserve"><value>Jeton d'authentification...</value></data> + <data name="ModListAuthTokenMenuTip" xml:space="preserve"><value>Éditer les jetons d'authentication envoyés aux serveurs de téléchargements</value></data> + <data name="ModListHelpMenu" xml:space="preserve"><value>Aide</value></data> + <data name="ModListHelpMenuTip" xml:space="preserve"><value>Trucs & astuces</value></data> + <data name="ModListQuitMenu" xml:space="preserve"><value>Quitter</value></data> + <data name="ModListQuitMenuTip" xml:space="preserve"><value>Sortir vers DOS</value></data> + <data name="ModListCaptureKeyMenu" xml:space="preserve"><value>DÉBOGAGE : Enregistrer les touches...</value></data> + <data name="ModListCaptureKeyMenuTip" xml:space="preserve"><value>Afficher les détails sur comment votre système signale les touches pressées, pour le débogage</value></data> + <data name="ModListPressAKey" xml:space="preserve"><value>Appuyez sur une touche</value></data> + <data name="ModListAuditNotFound" xml:space="preserve"><value>Les mods installés n'ont aucune recommandations ou suggestions supplémentaires.</value></data> + <data name="ModListUpdateRegistryTitle" xml:space="preserve"><value>Mise à Jour du Registre</value></data> + <data name="ModListUpdateRegistryMessage" xml:space="preserve"><value>Recherche de mises à jour</value></data> + <data name="ModListNewMod" xml:space="preserve"><value>{0} nouveau mod depuis la dernière mise à jour. L'afficher ?</value></data> + <data name="ModListNewMods" xml:space="preserve"><value>{0} nouveaux mods depuis la dernière mise à jour. Les afficher ?</value></data> + <data name="ModListScanBad" xml:space="preserve"><value>{0} Le répertoire n'a pas été sauvegardé.</value></data> + <data name="ModListExportPrefix" xml:space="preserve"><value>installer</value></data> + <data name="ModListExported" xml:space="preserve"><value>Liste de mods exportée vers {0}</value></data> + <data name="ModListExportFailed" xml:space="preserve"><value>Échec de l'export : {0}</value></data> + <data name="ModListHelpSymbolHeader" xml:space="preserve"><value>Symboles de statut</value></data> + <data name="ModListHelpInstalled" xml:space="preserve"><value>Installé</value></data> + <data name="ModListHelpAutoInstalled" xml:space="preserve"><value>Auto-installé</value></data> + <data name="ModListHelpUpgradeable" xml:space="preserve"><value>À mettre à jour</value></data> + <data name="ModListHelpManuallyInstalled" xml:space="preserve"><value>Manuellement installé</value></data> + <data name="ModListHelpReplaceable" xml:space="preserve"><value>Remplaçable</value></data> + <data name="ModListHelpUnavailable" xml:space="preserve"><value>Indisponible</value></data> + <data name="ModListHelpBasicKeysHeader" xml:space="preserve"><value>Touches de base</value></data> + <data name="ModListHelpMoveFocus" xml:space="preserve"><value>Changer l'attention</value></data> + <data name="ModListHelpSelectRow" xml:space="preserve"><value>Sélectionner la colonne</value></data> + <data name="ModListHelpClearSearch" xml:space="preserve"><value>Effacer la recherche</value></data> + <data name="ModListHelpSpecialSearchesHeader" xml:space="preserve"><value>Recherches Spéciales</value></data> + <data name="ModListHelpAuthor" xml:space="preserve"><value>auteur</value></data> + <data name="ModListHelpName" xml:space="preserve"><value>nom</value></data> + <data name="ModListHelpSearchAuthor" xml:space="preserve"><value>Mods par auteur</value></data> + <data name="ModListHelpSearchInstalled" xml:space="preserve"><value>Mods installés</value></data> + <data name="ModListHelpSearchUpgradeable" xml:space="preserve"><value>Mods à mettre à jour</value></data> + <data name="ModListHelpSearchDepends" xml:space="preserve"><value>Dépend de nom</value></data> + <data name="ModListHelpSearchConflicts" xml:space="preserve"><value>Conflit avec nom</value></data> + <data name="ModListHelpSearchNew" xml:space="preserve"><value>Nouveaux mods</value></data> + <data name="ExitTitle" xml:space="preserve"><value>{0}, le Réseau Compréhensif des Archives Kerbals</value></data> + <data name="ExitBody" xml:space="preserve"><value>Vous utilisez {1}. + +Merci d'avoir téléchargé {0}. Nous espérons que vous avez eu autant +de plaisir à l'utiliser que nous en avons eu (et avons) à le développer. + +Si vous avez payé pour {0}, essayez d'en avoir pour votre argent, +car vous pouvez télécharger {0} gratuitement sur +{2} + +Si vous rencontrez des problèmes en utilisant {0}, veuillez nous le signaler sur +{3} + +{0} A ÉTÉ CRÉÉ PAR LES AUTEURS DE {0} : +{4} +</value></data> +</root> diff --git a/ConsoleUI/Properties/Resources.resx b/ConsoleUI/Properties/Resources.resx new file mode 100644 index 0000000000..80c1d6628b --- /dev/null +++ b/ConsoleUI/Properties/Resources.resx @@ -0,0 +1,406 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="Accept" xml:space="preserve"><value>Accept</value></data> + <data name="Cancel" xml:space="preserve"><value>Cancel</value></data> + <data name="DefaultGhostText" xml:space="preserve"><value><Enter a value></value></data> + <data name="Ascending" xml:space="preserve"><value>Ascending</value></data> + <data name="AscendingSortTip" xml:space="preserve"><value>Sort the list in ascending order</value></data> + <data name="Descending" xml:space="preserve"><value>Descending</value></data> + <data name="DescendingSortTip" xml:space="preserve"><value>Sort the list in descending order</value></data> + <data name="ColumnNumber" xml:space="preserve"><value>Column #{0}</value></data> + <data name="ColumnNumberSortTip" xml:space="preserve"><value>Sort the list by column #{0}</value></data> + <data name="ColumnNameSortTip" xml:space="preserve"><value>Sort the list by the {0} column</value></data> + <data name="CursorKeys" xml:space="preserve"><value>Cursor keys</value></data> + <data name="Scroll" xml:space="preserve"><value>Scroll</value></data> + <data name="ScrollMessages" xml:space="preserve"><value>Scroll Messages</value></data> + <data name="Menu" xml:space="preserve"><value>Menu</value></data> + <data name="Yes" xml:space="preserve"><value>Yes</value></data> + <data name="No" xml:space="preserve"><value>No</value></data> + <data name="OK" xml:space="preserve"><value>OK</value></data> + <data name="Force" xml:space="preserve"><value>Force</value></data> + <data name="Tab" xml:space="preserve"><value>Tab</value></data> + <data name="Enter" xml:space="preserve"><value>Enter</value></data> + <data name="Esc" xml:space="preserve"><value>Esc</value></data> + <data name="Ctrl" xml:space="preserve"><value>Ctrl</value></data> + <data name="Alt" xml:space="preserve"><value>Alt</value></data> + <data name="Back" xml:space="preserve"><value>Back</value></data> + <data name="Quit" xml:space="preserve"><value>Quit</value></data> + <data name="Add" xml:space="preserve"><value>Add</value></data> + <data name="Remove" xml:space="preserve"><value>Remove</value></data> + <data name="Edit" xml:space="preserve"><value>Edit</value></data> + <data name="Sort" xml:space="preserve"><value>Sort</value></data> + <data name="Toggle" xml:space="preserve"><value>Toggle</value></data> + <data name="Select" xml:space="preserve"><value>Select</value></data> + <data name="SelectAll" xml:space="preserve"><value>Select all</value></data> + <data name="DeselectAll" xml:space="preserve"><value>Deselect all</value></data> + <data name="Details" xml:space="preserve"><value>Details</value></data> + <data name="Up" xml:space="preserve"><value>Up</value></data> + <data name="Down" xml:space="preserve"><value>Down</value></data> + <data name="FileSelectDirectory" xml:space="preserve"><value>Directory</value></data> + <data name="FileSelectCountFooter" xml:space="preserve"><value>{0} selected, {1}</value></data> + <data name="FileSelectNameHeader" xml:space="preserve"><value>Name</value></data> + <data name="FileSelectSizeHeader" xml:space="preserve"><value>Size</value></data> + <data name="FileSelectTimestampHeader" xml:space="preserve"><value>Accessed</value></data> + <data name="FileSelectChangeDirectory" xml:space="preserve"><value>Change directory</value></data> + <data name="FileSelectSelect" xml:space="preserve"><value>Select</value></data> + <data name="FileSelectImport" xml:space="preserve"><value>Import</value></data> + <data name="FileSelectDirSize" xml:space="preserve"><value><DIR></value></data> + <data name="AuthTokenListTitle" xml:space="preserve"><value>Authentication Tokens</value></data> + <data name="AuthTokenListGitHubLink" xml:space="preserve"><value>Make a GitHub API token</value></data> + <data name="AuthTokenListGitHubLinkTip" xml:space="preserve"><value>Open the web page for creating GitHub API authentication tokens</value></data> + <data name="AuthTokenListLabel" xml:space="preserve"><value>Authentication tokens for downloads:</value></data> + <data name="AuthTokenListHostHeader" xml:space="preserve"><value>Host</value></data> + <data name="AuthTokenListTokenHeader" xml:space="preserve"><value>Token</value></data> + <data name="AuthTokenListWarning" xml:space="preserve"><value>NOTE: These values are private! Do not share screenshots of this screen!</value></data> + <data name="AuthTokenListMissingToken" xml:space="preserve"><value><ERROR></value></data> + <data name="AuthTokenAddTitle" xml:space="preserve"><value>Create Authentication Key</value></data> + <data name="AuthTokenAddHost" xml:space="preserve"><value>Host:</value></data> + <data name="AuthTokenAddHostGhostText" xml:space="preserve"><value><Enter a host name></value></data> + <data name="AuthTokenAddToken" xml:space="preserve"><value>Token:</value></data> + <data name="AuthTokenAddTokenGhostText" xml:space="preserve"><value><Enter an authentication token></value></data> + <data name="CompatibleVersionsTitle" xml:space="preserve"><value>Select Compatible Version</value></data> + <data name="CompatibleVersionsListHeader" xml:space="preserve"><value>Predefined Version</value></data> + <data name="CompatibleVersionsListAcceptTip" xml:space="preserve"><value>Select version</value></data> + <data name="CompatibleVersionsGhostText" xml:space="preserve"><value><Enter a version></value></data> + <data name="CompatibleVersionsEntryAcceptTip" xml:space="preserve"><value>Accept value</value></data> + <data name="ThemeNotFound" xml:space="preserve"><value>No such theme: {0}</value></data> + <data name="ThemeList" xml:space="preserve"><value>Available themes: {0}</value></data> + <data name="RecommendationsLabel" xml:space="preserve"><value>Additional mods are recommended or suggested:</value></data> + <data name="RecommendationsInstallHeader" xml:space="preserve"><value>Install</value></data> + <data name="RecommendationsNameHeader" xml:space="preserve"><value>Name</value></data> + <data name="RecommendationsSourcesHeader" xml:space="preserve"><value>Sources</value></data> + <data name="RecommendationsTitle" xml:space="preserve"><value>Recommendations & Suggestions</value></data> + <data name="ImportSelectTitle" xml:space="preserve"><value>Import Downloads</value></data> + <data name="ImportSelectHeader" xml:space="preserve"><value>Import</value></data> + <data name="ImportProgressTitle" xml:space="preserve"><value>Importing Downloads</value></data> + <data name="ImportProgressMessage" xml:space="preserve"><value>Calculating...</value></data> + <data name="InstanceNameLabel" xml:space="preserve"><value>Name:</value></data> + <data name="InstanceNameGhostText" xml:space="preserve"><value><Enter the name to use for this game instance></value></data> + <data name="InstancePathGhostText" xml:space="preserve"><value><Enter the location of this game instance on disk></value></data> + <data name="InstancePathLabel" xml:space="preserve"><value>Path to game instance:</value></data> + <data name="InstanceNameEmptyError" xml:space="preserve"><value>Name cannot be empty!</value></data> + <data name="InstanceNameDuplicateError" xml:space="preserve"><value>{0} already exists!</value></data> + <data name="InstancePathNotGameFolderError" xml:space="preserve"><value>Path does not correspond to a game folder!</value></data> + <data name="InstanceAddExample" xml:space="preserve"><value>Example: {0}</value></data> + <data name="InstanceAddTitle" xml:space="preserve"><value>Add Game Instance</value></data> + <data name="InstanceEditTitle" xml:space="preserve"><value>Edit Game Instance</value></data> + <data name="InstanceEditRepoFrameTitle" xml:space="preserve"><value>Mod List Sources</value></data> + <data name="InstanceEditCompatFrameTitle" xml:space="preserve"><value>Additional Compatible Versions</value></data> + <data name="InstanceEditRepoIndexHeader" xml:space="preserve"><value>Index</value></data> + <data name="InstanceEditRepoNameHeader" xml:space="preserve"><value>Name</value></data> + <data name="InstanceEditRepoURLHeader" xml:space="preserve"><value>URL</value></data> + <data name="InstanceEditCompatVersionHeader" xml:space="preserve"><value>Version</value></data> + <data name="InstanceEditRegistryParseError" xml:space="preserve"><value>Failed to extract mod list sources from {0}.</value></data> + <data name="InstanceListTitle" xml:space="preserve"><value>Game Instances</value></data> + <data name="InstanceListLabel" xml:space="preserve"><value>Select or add a game instance:</value></data> + <data name="InstanceListDefaultHeader" xml:space="preserve"><value>Default</value></data> + <data name="InstanceListNameHeader" xml:space="preserve"><value>Name</value></data> + <data name="InstanceListGameHeader" xml:space="preserve"><value>Game</value></data> + <data name="InstanceListVersionHeader" xml:space="preserve"><value>Version</value></data> + <data name="InstanceListPathHeader" xml:space="preserve"><value>Path</value></data> + <data name="InstanceListLoadingInstance" xml:space="preserve"><value>Loading instance {0}...</value></data> + <data name="InstanceListDefaultToggle" xml:space="preserve"><value>Default</value></data> + <data name="InstanceListLoadingError" xml:space="preserve"><value>Error loading {0}: +{1}</value></data> + <data name="InstanceListLocked" xml:space="preserve"><value>Lock file with live process ID found at {0} + +This means that another instance of CKAN probably is accessing this instance. You can delete the file to continue, but data corruption is very likely. + +Do you want to delete this lock file to force access?</value></data> + <data name="InstanceListNoVersion" xml:space="preserve"><value><NONE></value></data> + <data name="InstallTitle" xml:space="preserve"><value>Installing, Upgrading, and Removing Mods</value></data> + <data name="InstallMessage" xml:space="preserve"><value>Calculating...</value></data> + <data name="InstallOwnedFileConflict" xml:space="preserve"><value>{0} tried to install {1}, but {2} has already installed it. +Please report this problem at https://github.com/KSP-CKAN/NetKAN/issues/new/choose</value></data> + <data name="InstallUnownedFileConflict" xml:space="preserve"><value>{0} tried to install {1}, but it is already installed. +Please manually uninstall the mod that owns this file to install {2}.</value></data> + <data name="InstallFilesReverted" xml:space="preserve"><value>Game files reverted.</value></data> + <data name="InstallAuthTokenPrompt" xml:space="preserve"><value>{0} + +Edit authentication tokens now?</value></data> + <data name="InstallTooManyModsNameHeader" xml:space="preserve"><value>Name</value></data> + <data name="InstallBadMetadata" xml:space="preserve"><value>Bad metadata detected for {0}: {1}</value></data> + <data name="InstallUnsatisfiedDependency" xml:space="preserve"><value>{0} requires {1}, but it is not listed in the index, or not available for your version of the game. +{2}</value></data> + <data name="InstallModuleNotFound" xml:space="preserve"><value>Module {0} required but it is not listed in the index, or not available for your version of the game. +{1}</value></data> + <data name="InstallNotInstalled" xml:space="preserve"><value>{0} is not installed, can't remove</value></data> + <data name="InstallModInstalled" xml:space="preserve"><value>{0} Successfully installed {1} {2}</value></data> + <data name="ModInfoTitle" xml:space="preserve"><value>Mod Details</value></data> + <data name="ModInfoMenuTip" xml:space="preserve"><value>Links</value></data> + <data name="ModInfoAuthors" xml:space="preserve"><value>By {0}</value></data> + <data name="ModInfoLicence" xml:space="preserve"><value>Licence:</value></data> + <data name="ModInfoDownload" xml:space="preserve"><value>Download:</value></data> + <data name="ModInfoDescriptionFrame" xml:space="preserve"><value>Description</value></data> + <data name="ModInfoUnavailableWarning" xml:space="preserve"><value> +NOTE: This mod is installed but no longer available. +If you uninstall it, CKAN will not be able to re-install it.</value></data> + <data name="ModInfoDownloadToCache" xml:space="preserve"><value>Download to cache (does not install)</value></data> + <data name="ModInfoHomePage" xml:space="preserve"><value>Home page</value></data> + <data name="ModInfoHomePageTip" xml:space="preserve"><value>Open the home page URL in a browser</value></data> + <data name="ModInfoRepository" xml:space="preserve"><value>Repository</value></data> + <data name="ModInfoRepositoryTip" xml:space="preserve"><value>Open the repository URL in a browser</value></data> + <data name="ModInfoBugtracker" xml:space="preserve"><value>Bugtracker</value></data> + <data name="ModInfoBugtrackerTip" xml:space="preserve"><value>Open the bug tracker URL in a browser</value></data> + <data name="ModInfoSpaceDock" xml:space="preserve"><value>SpaceDock</value></data> + <data name="ModInfoSpaceDockTip" xml:space="preserve"><value>Open the SpaceDock URL in a browser</value></data> + <data name="ModInfoCurse" xml:space="preserve"><value>Curse</value></data> + <data name="ModInfoCurseTip" xml:space="preserve"><value>Open the Curse URL in a browser</value></data> + <data name="ModInfoStore" xml:space="preserve"><value>Store</value></data> + <data name="ModInfoStoreTip" xml:space="preserve"><value>Open the Store URL in a browser</value></data> + <data name="ModInfoSteamStore" xml:space="preserve"><value>Steam Store</value></data> + <data name="ModInfoSteamStoreTip" xml:space="preserve"><value>Open the Steam Store URL in a browser</value></data> + <data name="ModInfoViewMetadata" xml:space="preserve"><value>DEBUG: View metadata</value></data> + <data name="ModInfoViewMetadataTip" xml:space="preserve"><value>Display the full registry data for this mod</value></data> + <data name="ModInfoViewMetadataTitle" xml:space="preserve"><value>{0} Metadata</value></data> + <data name="ModInfoURLLaunching" xml:space="preserve"><value>Launching...</value></data> + <data name="ModInfoDependenciesFrame" xml:space="preserve"><value>Dependencies</value></data> + <data name="ModInfoRequiredLabel" xml:space="preserve"><value>Required ({0}):</value></data> + <data name="ModInfoConflictsLabel" xml:space="preserve"><value>Conflicts ({0}):</value></data> + <data name="ModInfoReplacedBy" xml:space="preserve"><value>Replaced by {0}:</value></data> + <data name="ModInfoInstalledOn" xml:space="preserve"><value>Installed {0}</value></data> + <data name="ModInfoInstalledManually" xml:space="preserve"><value>Installed manually</value></data> + <data name="ModInfoLatestInstalledOn" xml:space="preserve"><value>Latest/Installed {0}</value></data> + <data name="ModInfoLatestInstalledManually" xml:space="preserve"><value>Latest/Installed manually</value></data> + <data name="ModInfoLatestVersion" xml:space="preserve"><value>Latest Version</value></data> + <data name="ModInfoOtherVersions" xml:space="preserve"><value>Other Versions</value></data> + <data name="ModInfoUnavailableInstalledOn" xml:space="preserve"><value>UNAVAILABLE/Installed {0}</value></data> + <data name="ModInfoUnavailableInstalledManually" xml:space="preserve"><value>UNAVAILABLE/Installed manually</value></data> + <data name="ModInfoCompatibleWith" xml:space="preserve"><value>Compatible with:</value></data> + <data name="ModInfoHostedOn" xml:space="preserve"><value>Hosted on {0}</value></data> + <data name="ModInfoReportBugsOn" xml:space="preserve"><value>Report bugs on {0}</value></data> + <data name="ModInfoRepositoryOn" xml:space="preserve"><value>Repository on {0}</value></data> + <data name="ModInfoHomePageOn" xml:space="preserve"><value>Home page on {0}</value></data> + <data name="ModInfoBuyFromKSPStore" xml:space="preserve"><value>Buy from KSP store</value></data> + <data name="ModInfoBuyFromSteamStore" xml:space="preserve"><value>Buy from Steam store</value></data> + <data name="ModInfoBuyFromKSPStoreOrSteamStore" xml:space="preserve"><value>Buy from KSP store or Steam store</value></data> + <data name="ModInfoDownloading" xml:space="preserve"><value>Downloading {0}</value></data> + <data name="ModInfoDownloadCorrupted" xml:space="preserve"><value>Download failed, file is corrupted</value></data> + <data name="ModInfoDownloadFailed" xml:space="preserve"><value>Download failed: {0}</value></data> + <data name="ProgressTitle" xml:space="preserve"><value>Progress</value></data> + <data name="ProgressMessages" xml:space="preserve"><value>Messages</value></data> + <data name="SplashLoading" xml:space="preserve"><value>Loading...</value></data> + <data name="SplashPressAnyKey" xml:space="preserve"><value>Press any key to continue</value></data> + <data name="RepoNameLabel" xml:space="preserve"><value>Name:</value></data> + <data name="RepoNameGhostText" xml:space="preserve"><value><Enter the name to use for this repository></value></data> + <data name="RepoURLLabel" xml:space="preserve"><value>URL:</value></data> + <data name="RepoURLGhostText" xml:space="preserve"><value><Enter the URL of this repository></value></data> + <data name="RepoImportTip" xml:space="preserve"><value>Import values from default mod list source {0}</value></data> + <data name="RepoTitle" xml:space="preserve"><value>Edit Mod List Source</value></data> + <data name="RepoNameEmptyError" xml:space="preserve"><value>Name cannot be empty!</value></data> + <data name="RepoNameDuplicateError" xml:space="preserve"><value>{0} already exists!</value></data> + <data name="RepoURLEmptyError" xml:space="preserve"><value>URL cannot be empty!</value></data> + <data name="ModListNameHeader" xml:space="preserve"><value>Name</value></data> + <data name="ModListVersionHeader" xml:space="preserve"><value>Version</value></data> + <data name="ModListMaxGameVersionHeader" xml:space="preserve"><value>Max game version</value></data> + <data name="ModListSearchFocusedGhostText" xml:space="preserve"><value><Type to search></value></data> + <data name="ModListSearchUnfocusedGhostText" xml:space="preserve"><value><Ctrl+F to search></value></data> + <data name="ModListCount" xml:space="preserve"><value>{0} mods</value></data> + <data name="ModListSizeOnDisk" xml:space="preserve"><value>{0} installed</value></data> + <data name="ModListInstallTip" xml:space="preserve"><value>Install</value></data> + <data name="ModListUpgradeTip" xml:space="preserve"><value>Upgrade</value></data> + <data name="ModListReplaceTip" xml:space="preserve"><value>Replace</value></data> + <data name="ModListRemoveTip" xml:space="preserve"><value>Remove</value></data> + <data name="ModListAutoInstTip" xml:space="preserve"><value>Mark auto-installed</value></data> + <data name="ModListUserSelectedTip" xml:space="preserve"><value>Mark user-selected</value></data> + <data name="ModListApplyChangesTip" xml:space="preserve"><value>Apply changes</value></data> + <data name="ModListUpdatedDayAgo" xml:space="preserve"><value>Updated at least {0} day ago</value></data> + <data name="ModListUpdatedDaysAgo" xml:space="preserve"><value>Updated at least {0} days ago</value></data> + <data name="ModListSortMenu" xml:space="preserve"><value>Sort...</value></data> + <data name="ModListSortMenuTip" xml:space="preserve"><value>Change the sorting of the list of mods</value></data> + <data name="ModListRefreshMenu" xml:space="preserve"><value>Refresh mod list</value></data> + <data name="ModListRefreshMenuTip" xml:space="preserve"><value>Refresh the list of mods</value></data> + <data name="ModListUpgradeMenu" xml:space="preserve"><value>Upgrade all</value></data> + <data name="ModListUpgradeMenuTip" xml:space="preserve"><value>Mark all available updates for installation</value></data> + <data name="ModListAuditRecsMenu" xml:space="preserve"><value>Audit recommendations</value></data> + <data name="ModListAuditRecsMenuTip" xml:space="preserve"><value>List mods suggested and recommended by installed mods</value></data> + <data name="ModListImportMenu" xml:space="preserve"><value>Import downloads...</value></data> + <data name="ModListImportMenuTip" xml:space="preserve"><value>Select manually downloaded mods to import into CKAN</value></data> + <data name="ModListExportMenu" xml:space="preserve"><value>Export installed...</value></data> + <data name="ModListExportMenuTip" xml:space="preserve"><value>Save your mod list</value></data> + <data name="ModListInstanceSettingsMenu" xml:space="preserve"><value>Game instance settings...</value></data> + <data name="ModListInstanceSettingsMenuTip" xml:space="preserve"><value>Configure the current game instance</value></data> + <data name="ModListSelectInstanceMenu" xml:space="preserve"><value>Select game instance...</value></data> + <data name="ModListSelectInstanceMenuTip" xml:space="preserve"><value>Switch to a different game instance</value></data> + <data name="ModListAuthTokenMenu" xml:space="preserve"><value>Authentication tokens...</value></data> + <data name="ModListAuthTokenMenuTip" xml:space="preserve"><value>Edit authentication tokens sent to download servers</value></data> + <data name="ModListFilterMenu" xml:space="preserve"><value>Installation filters...</value></data> + <data name="ModListFilterMenuTip" xml:space="preserve"><value>Edit list of files and folders to exclude from installation</value></data> + <data name="ModListHelpMenu" xml:space="preserve"><value>Help</value></data> + <data name="ModListHelpMenuTip" xml:space="preserve"><value>Tips & tricks</value></data> + <data name="ModListQuitMenu" xml:space="preserve"><value>Quit</value></data> + <data name="ModListQuitMenuTip" xml:space="preserve"><value>Exit to DOS</value></data> + <data name="ModListCaptureKeyMenu" xml:space="preserve"><value>DEBUG: Capture key...</value></data> + <data name="ModListCaptureKeyMenuTip" xml:space="preserve"><value>Print details of how your system reports a keystroke for debugging</value></data> + <data name="ModListPressAKey" xml:space="preserve"><value>Press a key</value></data> + <data name="ModListAuditNotFound" xml:space="preserve"><value>Installed mods have no unsatisfied recommendations or suggestions.</value></data> + <data name="ModListUpdateRegistryTitle" xml:space="preserve"><value>Updating Registry</value></data> + <data name="ModListUpdateRegistryMessage" xml:space="preserve"><value>Checking for updates</value></data> + <data name="ModListNewMod" xml:space="preserve"><value>{0} new mod available since last update. Show it?</value></data> + <data name="ModListNewMods" xml:space="preserve"><value>{0} new mods available since last update. Show them?</value></data> + <data name="ModListScanBad" xml:space="preserve"><value>{0} The repo has not been saved.</value></data> + <data name="ModListExportPrefix" xml:space="preserve"><value>install</value></data> + <data name="ModListExported" xml:space="preserve"><value>Mod list exported to {0}</value></data> + <data name="ModListExportFailed" xml:space="preserve"><value>Export failed: {0}</value></data> + <data name="ModListHelpSymbolHeader" xml:space="preserve"><value>Status Symbols</value></data> + <data name="ModListHelpInstalled" xml:space="preserve"><value>Installed</value></data> + <data name="ModListHelpAutoInstalled" xml:space="preserve"><value>Auto-installed</value></data> + <data name="ModListHelpUpgradeable" xml:space="preserve"><value>Upgradeable</value></data> + <data name="ModListHelpManuallyInstalled" xml:space="preserve"><value>Manually installed</value></data> + <data name="ModListHelpReplaceable" xml:space="preserve"><value>Replaceable</value></data> + <data name="ModListHelpUnavailable" xml:space="preserve"><value>Unavailable</value></data> + <data name="ModListHelpBasicKeysHeader" xml:space="preserve"><value>Basic Keys</value></data> + <data name="ModListHelpMoveFocus" xml:space="preserve"><value>Move focus</value></data> + <data name="ModListHelpSelectRow" xml:space="preserve"><value>Select row</value></data> + <data name="ModListHelpClearSearch" xml:space="preserve"><value>Clear search</value></data> + <data name="ModListHelpSpecialSearchesHeader" xml:space="preserve"><value>Special Searches</value></data> + <data name="ModListHelpAuthor" xml:space="preserve"><value>author</value></data> + <data name="ModListHelpName" xml:space="preserve"><value>name</value></data> + <data name="ModListHelpSearchAuthor" xml:space="preserve"><value>Mods by author</value></data> + <data name="ModListHelpSearchInstalled" xml:space="preserve"><value>Installed mods</value></data> + <data name="ModListHelpSearchUpgradeable" xml:space="preserve"><value>Upgradeable mods</value></data> + <data name="ModListHelpSearchDepends" xml:space="preserve"><value>Depend on name</value></data> + <data name="ModListHelpSearchConflicts" xml:space="preserve"><value>Conflict w/ name</value></data> + <data name="ModListHelpSearchNew" xml:space="preserve"><value>New mods</value></data> + <data name="FiltersTitle" xml:space="preserve"><value>Installation Filters</value></data> + <data name="FiltersAddMiniAVCMenu" xml:space="preserve"><value>Add MiniAVC</value></data> + <data name="FiltersAddMiniAVCMenuTip" xml:space="preserve"><value>Prevent MiniAVC from being installed</value></data> + <data name="FiltersGlobalHeader" xml:space="preserve"><value>Global Filters</value></data> + <data name="FiltersInstanceHeader" xml:space="preserve"><value>Instance Filters</value></data> + <data name="FilterAddGhostText" xml:space="preserve"><value><Enter a filter></value></data> + <data name="FilterAddAcceptTip" xml:space="preserve"><value>Accept value</value></data> + <data name="FilterAddTitle" xml:space="preserve"><value>Add Filter</value></data> + <data name="ExitTitle" xml:space="preserve"><value>{0}, the Comprehensive Kerbal Archive Network</value></data> + <data name="ExitBody" xml:space="preserve"><value>YOU ARE USING {1}. + +Thanks for downloading {0}. We hope you have as +much fun using it as we had (and have) making it. + +If you have paid for {0}, try to get your money back, +because you can download {0} for free from +{2} + +If you have any problems using {0}, please send us an issue at +{3} + +{0} WAS CREATED BY THE {0} AUTHORS: +{4} +</value></data> +</root> diff --git a/ConsoleUI/Properties/Resources.ru-RU.resx b/ConsoleUI/Properties/Resources.ru-RU.resx new file mode 100644 index 0000000000..8a8b0185a6 --- /dev/null +++ b/ConsoleUI/Properties/Resources.ru-RU.resx @@ -0,0 +1,389 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="Accept" xml:space="preserve"><value>Принять</value></data> + <data name="Cancel" xml:space="preserve"><value>Отмена</value></data> + <data name="DefaultGhostText" xml:space="preserve"><value><Введите значение></value></data> + <data name="Ascending" xml:space="preserve"><value>По возрастанию</value></data> + <data name="AscendingSortTip" xml:space="preserve"><value>Сортировка списка по возрастанию</value></data> + <data name="Descending" xml:space="preserve"><value>По убыванию</value></data> + <data name="DescendingSortTip" xml:space="preserve"><value>Сортировка списка по убыванию</value></data> + <data name="ColumnNumber" xml:space="preserve"><value>Столбец №{0}</value></data> + <data name="ColumnNumberSortTip" xml:space="preserve"><value>Сортировка списка по столбцу №{0}</value></data> + <data name="ColumnNameSortTip" xml:space="preserve"><value>Сортировка списка по столбцу «{0}» </value></data> + <data name="CursorKeys" xml:space="preserve"><value>Стрелки</value></data> + <data name="Scroll" xml:space="preserve"><value>Прокрутка</value></data> + <data name="ScrollMessages" xml:space="preserve"><value>Прокрутка сообщений</value></data> + <data name="Menu" xml:space="preserve"><value>Меню</value></data> + <data name="Yes" xml:space="preserve"><value>Да</value></data> + <data name="No" xml:space="preserve"><value>Нет</value></data> + <data name="OK" xml:space="preserve"><value>OK</value></data> + <data name="Force" xml:space="preserve"><value>Принуд.</value></data> + <data name="Tab" xml:space="preserve"><value>Tab</value></data> + <data name="Enter" xml:space="preserve"><value>Enter</value></data> + <data name="Esc" xml:space="preserve"><value>Esc</value></data> + <data name="Ctrl" xml:space="preserve"><value>Ctrl</value></data> + <data name="Alt" xml:space="preserve"><value>Alt</value></data> + <data name="Back" xml:space="preserve"><value>Назад</value></data> + <data name="Quit" xml:space="preserve"><value>Выйти</value></data> + <data name="Add" xml:space="preserve"><value>Добавить</value></data> + <data name="Remove" xml:space="preserve"><value>Удалить</value></data> + <data name="Edit" xml:space="preserve"><value>Изменить</value></data> + <data name="Sort" xml:space="preserve"><value>Сортировка</value></data> + <data name="Toggle" xml:space="preserve"><value>Переключить</value></data> + <data name="Select" xml:space="preserve"><value>Выбрать</value></data> + <data name="SelectAll" xml:space="preserve"><value>Выбрать все</value></data> + <data name="DeselectAll" xml:space="preserve"><value>Снять выделение</value></data> + <data name="Details" xml:space="preserve"><value>Подробно</value></data> + <data name="Up" xml:space="preserve"><value>Вверх</value></data> + <data name="Down" xml:space="preserve"><value>Вниз</value></data> + <data name="AuthTokenListTitle" xml:space="preserve"><value>Токены аутентификации</value></data> + <data name="AuthTokenListGitHubLink" xml:space="preserve"><value>Создать токен GitHub API</value></data> + <data name="AuthTokenListGitHubLinkTip" xml:space="preserve"><value>Открытие страницы для создания токенов аутентификации GitHub API</value></data> + <data name="AuthTokenListLabel" xml:space="preserve"><value>Токены аутентификации для загрузок:</value></data> + <data name="AuthTokenListHostHeader" xml:space="preserve"><value>Хост</value></data> + <data name="AuthTokenListTokenHeader" xml:space="preserve"><value>Токен</value></data> + <data name="AuthTokenListWarning" xml:space="preserve"><value>ВНИМАНИЕ: Не делитесь ни с кем этими значениями!</value></data> + <data name="AuthTokenListMissingToken" xml:space="preserve"><value><ОШИБКА></value></data> + <data name="AuthTokenAddTitle" xml:space="preserve"><value>Создать ключ аутентификации</value></data> + <data name="AuthTokenAddHost" xml:space="preserve"><value>Хост:</value></data> + <data name="AuthTokenAddHostGhostText" xml:space="preserve"><value><Введите имя хоста></value></data> + <data name="AuthTokenAddToken" xml:space="preserve"><value>Токен:</value></data> + <data name="AuthTokenAddTokenGhostText" xml:space="preserve"><value><Введите токен аутентификации></value></data> + <data name="CompatibleVersionsTitle" xml:space="preserve"><value>Выбор совместимой версии</value></data> + <data name="CompatibleVersionsListHeader" xml:space="preserve"><value>Версия игры</value></data> + <data name="CompatibleVersionsListAcceptTip" xml:space="preserve"><value>Выбор версии</value></data> + <data name="CompatibleVersionsGhostText" xml:space="preserve"><value><Введите номер версии></value></data> + <data name="CompatibleVersionsEntryAcceptTip" xml:space="preserve"><value>Принять значеие</value></data> + <data name="ThemeNotFound" xml:space="preserve"><value>Тема «{0}» не существует</value></data> + <data name="ThemeList" xml:space="preserve"><value>Доступные темы: {0}</value></data> + <data name="RecommendationsLabel" xml:space="preserve"><value>Рекомендуются или предлагаются дополнительные модификации:</value></data> + <data name="RecommendationsInstallHeader" xml:space="preserve"><value>Уст.</value></data> + <data name="RecommendationsNameHeader" xml:space="preserve"><value>Название</value></data> + <data name="RecommendationsSourcesHeader" xml:space="preserve"><value>Источники</value></data> + <data name="RecommendationsTitle" xml:space="preserve"><value>Рекомендации и предложения</value></data> + <data name="ImportSelectTitle" xml:space="preserve"><value>Импорт загруженных модификаций</value></data> + <data name="ImportSelectHeader" xml:space="preserve"><value>Импорт</value></data> + <data name="ImportProgressTitle" xml:space="preserve"><value>Импортирование загрузок</value></data> + <data name="ImportProgressMessage" xml:space="preserve"><value>Вычисление...</value></data> + <data name="InstanceNameLabel" xml:space="preserve"><value>Название:</value></data> + <data name="InstanceNameGhostText" xml:space="preserve"><value><Введите название данной сборки></value></data> + <data name="InstancePathGhostText" xml:space="preserve"><value><Введите путь к сборке></value></data> + <data name="InstancePathLabel" xml:space="preserve"><value>Расположение сборки:</value></data> + <data name="InstanceNameEmptyError" xml:space="preserve"><value>Имя не может быть пустым!</value></data> + <data name="InstanceNameDuplicateError" xml:space="preserve"><value>Сборка «{0}» уже существует!</value></data> + <data name="InstancePathNotGameFolderError" xml:space="preserve"><value>Путь не является папкой с игрой!</value></data> + <data name="InstanceAddExample" xml:space="preserve"><value>Пример: {0}</value></data> + <data name="InstanceAddTitle" xml:space="preserve"><value>Добавить сборку игры</value></data> + <data name="InstanceEditTitle" xml:space="preserve"><value>Изменить сборку игры</value></data> + <data name="InstanceEditRepoFrameTitle" xml:space="preserve"><value>Источники списка модификаций</value></data> + <data name="InstanceEditCompatFrameTitle" xml:space="preserve"><value>Дополнительные совместимые версии игры</value></data> + <data name="InstanceEditRepoIndexHeader" xml:space="preserve"><value>Указ.</value></data> + <data name="InstanceEditRepoNameHeader" xml:space="preserve"><value>Название</value></data> + <data name="InstanceEditRepoURLHeader" xml:space="preserve"><value>URL</value></data> + <data name="InstanceEditCompatVersionHeader" xml:space="preserve"><value>Версия</value></data> + <data name="InstanceEditRegistryParseError" xml:space="preserve"><value>Не удалось извлечь источники списка модификаций из {0}.</value></data> + <data name="InstanceListTitle" xml:space="preserve"><value>Сборки игры</value></data> + <data name="InstanceListLabel" xml:space="preserve"><value>Выберите или добавьте сборку игры:</value></data> + <data name="InstanceListDefaultHeader" xml:space="preserve"><value>Умл.</value></data> + <data name="InstanceListNameHeader" xml:space="preserve"><value>Название</value></data> + <data name="InstanceListGameHeader" xml:space="preserve"><value>Игра</value></data> + <data name="InstanceListVersionHeader" xml:space="preserve"><value>Версия</value></data> + <data name="InstanceListPathHeader" xml:space="preserve"><value>Путь</value></data> + <data name="InstanceListLoadingInstance" xml:space="preserve"><value>Загрузка сборки «{0}»...</value></data> + <data name="InstanceListDefaultToggle" xml:space="preserve"><value>По умолчанию</value></data> + <data name="InstanceListLoadingError" xml:space="preserve"><value>Ошибка загрузки «{0}»: +{1}</value></data> + <data name="InstanceListLocked" xml:space="preserve"><value>Блокирующий файл с ID процесса найден в {0} + +Это может означать, что другой процесс CKAN работает с этой сборкой. +Вы можете удалить этот файл, но в таком случае вероятно повреждение данных. + +Хотите ли вы удалить блокирующий файл для получения доступа?</value></data> + <data name="InstanceListNoVersion" xml:space="preserve"><value><НЕТ></value></data> + <data name="InstallTitle" xml:space="preserve"><value>Установка, обновление и удаление модификаций</value></data> + <data name="InstallMessage" xml:space="preserve"><value>Вычисление...</value></data> + <data name="InstallOwnedFileConflict" xml:space="preserve"><value>{0} пытался установить {1}, но {2} уже установил его. +Пожалуйста, сообщите о проблеме по адресу https://github.com/KSP-CKAN/NetKAN/issues/new/choose</value></data> + <data name="InstallUnownedFileConflict" xml:space="preserve"><value>{0} пытался установить {1}, но он был уже установлен. +Для установки {2} вручную удалите модификацию, которой принадлежит этот файл.</value></data> + <data name="InstallFilesReverted" xml:space="preserve"><value>Файлы игры возвращены.</value></data> + <data name="InstallAuthTokenPrompt" xml:space="preserve"><value>{0} + +Изменить токены аутентификации?</value></data> + <data name="InstallTooManyModsNameHeader" xml:space="preserve"><value>Название</value></data> + <data name="InstallBadMetadata" xml:space="preserve"><value>Найдены некорректные метаданные {0}: {1}</value></data> + <data name="InstallUnsatisfiedDependency" xml:space="preserve"><value>{0} требует {1}, но он отсутствует в указателе или недоступен для вашей версии игры. +{2}</value></data> + <data name="InstallModuleNotFound" xml:space="preserve"><value>Требуется модуль {0}, но он отсутствует в указателе или недоступен для вашей версии игры. +{1}</value></data> + <data name="InstallNotInstalled" xml:space="preserve"><value>{0} не установлен, невозможно удалить</value></data> + <data name="InstallModInstalled" xml:space="preserve"><value>{0} Успешно установлен {1} {2}</value></data> + <data name="ModInfoTitle" xml:space="preserve"><value>О модификации</value></data> + <data name="ModInfoMenuTip" xml:space="preserve"><value>Ссылки</value></data> + <data name="ModInfoAuthors" xml:space="preserve"><value>Автор: {0}</value></data> + <data name="ModInfoLicence" xml:space="preserve"><value>Лицензия:</value></data> + <data name="ModInfoDownload" xml:space="preserve"><value>Размер:</value></data> + <data name="ModInfoDescriptionFrame" xml:space="preserve"><value>Описание модификации</value></data> + <data name="ModInfoUnavailableWarning" xml:space="preserve"><value> +ВНИМАНИЕ: Эта модификация установлена, но более не доступна. +Если вы удалите её, CKAN не сможет её переустановить.</value></data> + <data name="ModInfoDownloadToCache" xml:space="preserve"><value>Загрузить в кэш (без установки)</value></data> + <data name="ModInfoHomePage" xml:space="preserve"><value>Страница</value></data> + <data name="ModInfoHomePageTip" xml:space="preserve"><value>Открыть домашнюю страницу в браузере</value></data> + <data name="ModInfoRepository" xml:space="preserve"><value>Репозиторий</value></data> + <data name="ModInfoRepositoryTip" xml:space="preserve"><value>Открыть страницу репозитория в браузере</value></data> + <data name="ModInfoBugtracker" xml:space="preserve"><value>Багтрекер</value></data> + <data name="ModInfoBugtrackerTip" xml:space="preserve"><value>Открыть страницу багтрекера в браузере</value></data> + <data name="ModInfoSpaceDock" xml:space="preserve"><value>SpaceDock</value></data> + <data name="ModInfoSpaceDockTip" xml:space="preserve"><value>Открыть страницу SpaceDock в браузере</value></data> + <data name="ModInfoCurse" xml:space="preserve"><value>Curse</value></data> + <data name="ModInfoCurseTip" xml:space="preserve"><value>Открыть страницу Curse в браузере</value></data> + <data name="ModInfoStore" xml:space="preserve"><value>Магазин</value></data> + <data name="ModInfoStoreTip" xml:space="preserve"><value>Открыть страницу магазина в браузере</value></data> + <data name="ModInfoSteamStore" xml:space="preserve"><value>Магазин Steam</value></data> + <data name="ModInfoSteamStoreTip" xml:space="preserve"><value>Открыть страницу магазина Steam в браузере</value></data> + <data name="ModInfoViewMetadata" xml:space="preserve"><value>ОТЛАДКА: Просмотр метаданных</value></data> + <data name="ModInfoViewMetadataTip" xml:space="preserve"><value>Просмотр всех данных реестра для этой модификации</value></data> + <data name="ModInfoViewMetadataTitle" xml:space="preserve"><value>Метаданные {0}</value></data> + <data name="ModInfoURLLaunching" xml:space="preserve"><value>Запуск...</value></data> + <data name="ModInfoDependenciesFrame" xml:space="preserve"><value>Зависимости</value></data> + <data name="ModInfoRequiredLabel" xml:space="preserve"><value>Требует ({0}):</value></data> + <data name="ModInfoConflictsLabel" xml:space="preserve"><value>Конфликтует ({0}):</value></data> + <data name="ModInfoReplacedBy" xml:space="preserve"><value>Заменяется {0}:</value></data> + <data name="ModInfoInstalledOn" xml:space="preserve"><value>Установлен {0}</value></data> + <data name="ModInfoInstalledManually" xml:space="preserve"><value>Установлен вручную</value></data> + <data name="ModInfoLatestInstalledOn" xml:space="preserve"><value>Последняя версия/Установлен {0}</value></data> + <data name="ModInfoLatestInstalledManually" xml:space="preserve"><value>Последняя версия/Установлен вручную</value></data> + <data name="ModInfoLatestVersion" xml:space="preserve"><value>Последняя версия</value></data> + <data name="ModInfoOtherVersions" xml:space="preserve"><value>Другие версии</value></data> + <data name="ModInfoUnavailableInstalledOn" xml:space="preserve"><value>НЕДОСТУПЕН/Установлен {0}</value></data> + <data name="ModInfoUnavailableInstalledManually" xml:space="preserve"><value>НЕДОСТУПЕН/Установлен вручную</value></data> + <data name="ModInfoCompatibleWith" xml:space="preserve"><value>Совместимо с:</value></data> + <data name="ModInfoHostedOn" xml:space="preserve"><value>Находится в {0}</value></data> + <data name="ModInfoReportBugsOn" xml:space="preserve"><value>Сообщать об ошибках в {0}</value></data> + <data name="ModInfoRepositoryOn" xml:space="preserve"><value>Репозиторий в {0}</value></data> + <data name="ModInfoHomePageOn" xml:space="preserve"><value>Домашняя страница в {0}</value></data> + <data name="ModInfoBuyFromKSPStore" xml:space="preserve"><value>Купить в магазине KSP</value></data> + <data name="ModInfoBuyFromSteamStore" xml:space="preserve"><value>Купить в магазине Steam</value></data> + <data name="ModInfoBuyFromKSPStoreOrSteamStore" xml:space="preserve"><value>Купить в магазине KSP или Steam</value></data> + <data name="ModInfoDownloading" xml:space="preserve"><value>Загрузка «{0}»</value></data> + <data name="ModInfoDownloadCorrupted" xml:space="preserve"><value>Загрузка не завершена, файл повреждён</value></data> + <data name="ModInfoDownloadFailed" xml:space="preserve"><value>Загрузка не завершена: {0}</value></data> + <data name="ProgressTitle" xml:space="preserve"><value>Выполнение операции</value></data> + <data name="ProgressMessages" xml:space="preserve"><value>Сообщения</value></data> + <data name="SplashLoading" xml:space="preserve"><value>Загрузка...</value></data> + <data name="SplashPressAnyKey" xml:space="preserve"><value>Для продолжения нажмите любую клавишу</value></data> + <data name="RepoNameLabel" xml:space="preserve"><value>Название:</value></data> + <data name="RepoNameGhostText" xml:space="preserve"><value><Введите имя для данного репозитория></value></data> + <data name="RepoURLLabel" xml:space="preserve"><value>URL:</value></data> + <data name="RepoURLGhostText" xml:space="preserve"><value><Введите адрес репозитория></value></data> + <data name="RepoImportTip" xml:space="preserve"><value>Импорт значений из источника списка модификаций по умолчанию «{0}»</value></data> + <data name="RepoTitle" xml:space="preserve"><value>Изменить источник списка модификаций</value></data> + <data name="RepoNameEmptyError" xml:space="preserve"><value>Имя не может быть пустым!</value></data> + <data name="RepoNameDuplicateError" xml:space="preserve"><value>Репозиторий «{0}» уже существует!</value></data> + <data name="RepoURLEmptyError" xml:space="preserve"><value>Адрес не может быть пустым!</value></data> + <data name="ModListNameHeader" xml:space="preserve"><value>Название</value></data> + <data name="ModListVersionHeader" xml:space="preserve"><value>Версия</value></data> + <data name="ModListMaxGameVersionHeader" xml:space="preserve"><value>Макс.вер.</value></data> + <data name="ModListSearchFocusedGhostText" xml:space="preserve"><value><Введите текст для поиска...></value></data> + <data name="ModListSearchUnfocusedGhostText" xml:space="preserve"><value><Нажмите Ctrl+F для поиска></value></data> + <data name="ModListCount" xml:space="preserve"><value>{0} модификаций</value></data> + <data name="ModListSizeOnDisk" xml:space="preserve"><value>Занимает {0}</value></data> + <data name="ModListInstallTip" xml:space="preserve"><value>Установить</value></data> + <data name="ModListUpgradeTip" xml:space="preserve"><value>Обновить</value></data> + <data name="ModListReplaceTip" xml:space="preserve"><value>Заменить</value></data> + <data name="ModListRemoveTip" xml:space="preserve"><value>Удалить</value></data> + <data name="ModListAutoInstTip" xml:space="preserve"><value>Отметить как автоустановленное</value></data> + <data name="ModListUserSelectedTip" xml:space="preserve"><value>Отметить как выбранное</value></data> + <data name="ModListApplyChangesTip" xml:space="preserve"><value>Применить изменения</value></data> + <data name="ModListUpdatedDayAgo" xml:space="preserve"><value>Обновлено как минимум {0} день назад</value></data> + <data name="ModListUpdatedDaysAgo" xml:space="preserve"><value>Обновлено как минимум {0} дней назад</value></data> + <data name="ModListSortMenu" xml:space="preserve"><value>Сортировка...</value></data> + <data name="ModListSortMenuTip" xml:space="preserve"><value>Изменение сортировки списка модификаций</value></data> + <data name="ModListRefreshMenu" xml:space="preserve"><value>Обновить список модификаций</value></data> + <data name="ModListRefreshMenuTip" xml:space="preserve"><value>Обновление списка модификаций</value></data> + <data name="ModListUpgradeMenu" xml:space="preserve"><value>Обновить все модификации</value></data> + <data name="ModListUpgradeMenuTip" xml:space="preserve"><value>Установка всех возможных обновлений</value></data> + <data name="ModListAuditRecsMenu" xml:space="preserve"><value>Проверить рекомендации</value></data> + <data name="ModListAuditRecsMenuTip" xml:space="preserve"><value>Открытие списка модификаций, рекомендованных установленными модификациями</value></data> + <data name="ModListImportMenu" xml:space="preserve"><value>Импортировать загруженные модификации...</value></data> + <data name="ModListImportMenuTip" xml:space="preserve"><value>Импорт загруженных вручную модификаций в CKAN</value></data> + <data name="ModListExportMenu" xml:space="preserve"><value>Экспортировать модификации...</value></data> + <data name="ModListExportMenuTip" xml:space="preserve"><value>Сохранение списка установленных модификаций на диск</value></data> + <data name="ModListInstanceSettingsMenu" xml:space="preserve"><value>Настройки сборки игры...</value></data> + <data name="ModListInstanceSettingsMenuTip" xml:space="preserve"><value>Конфигурация текущей сборки игры</value></data> + <data name="ModListSelectInstanceMenu" xml:space="preserve"><value>Выбор сборки игры...</value></data> + <data name="ModListSelectInstanceMenuTip" xml:space="preserve"><value>Переключение на другую сборку игры</value></data> + <data name="ModListAuthTokenMenu" xml:space="preserve"><value>Токены аутентификации...</value></data> + <data name="ModListAuthTokenMenuTip" xml:space="preserve"><value>Изменение токенов аутентификации, отправляемых на серверы загрузки</value></data> + <data name="ModListHelpMenu" xml:space="preserve"><value>Помощь</value></data> + <data name="ModListHelpMenuTip" xml:space="preserve"><value>Подсказки по использованию CKAN</value></data> + <data name="ModListQuitMenu" xml:space="preserve"><value>Выйти</value></data> + <data name="ModListQuitMenuTip" xml:space="preserve"><value>Выход из программы</value></data> + <data name="ModListCaptureKeyMenu" xml:space="preserve"><value>ОТЛАДКА: Захват нажатий...</value></data> + <data name="ModListCaptureKeyMenuTip" xml:space="preserve"><value>Отладочная информация о том, как система отображает нажатия клавиш</value></data> + <data name="ModListPressAKey" xml:space="preserve"><value>Нажмите клавишу</value></data> + <data name="ModListAuditNotFound" xml:space="preserve"><value>Нет рекомендаций от установленных модификаций.</value></data> + <data name="ModListUpdateRegistryTitle" xml:space="preserve"><value>Обновление реестра</value></data> + <data name="ModListUpdateRegistryMessage" xml:space="preserve"><value>Проверка обновлений</value></data> + <data name="ModListNewMod" xml:space="preserve"><value>С последнего обновления доступна {0} новая модификация. Показать?</value></data> + <data name="ModListNewMods" xml:space="preserve"><value>С последнего обновления доступны {0} новые модификации. Показать?</value></data> + <data name="ModListScanBad" xml:space="preserve"><value>{0} Репозиторий не сохранён.</value></data> + <data name="ModListExportPrefix" xml:space="preserve"><value>установленные</value></data> + <data name="ModListExported" xml:space="preserve"><value>Список модификаций экспортирован в {0}</value></data> + <data name="ModListExportFailed" xml:space="preserve"><value>Экспорт не удался: {0}</value></data> + <data name="ModListHelpSymbolHeader" xml:space="preserve"><value>Символы статуса</value></data> + <data name="ModListHelpInstalled" xml:space="preserve"><value>Установлен</value></data> + <data name="ModListHelpAutoInstalled" xml:space="preserve"><value>Автоустановлен</value></data> + <data name="ModListHelpUpgradeable" xml:space="preserve"><value>Возм. обновление</value></data> + <data name="ModListHelpManuallyInstalled" xml:space="preserve"><value>Уст. вручную</value></data> + <data name="ModListHelpReplaceable" xml:space="preserve"><value>Возможна замена</value></data> + <data name="ModListHelpUnavailable" xml:space="preserve"><value>Недоступен</value></data> + <data name="ModListHelpBasicKeysHeader" xml:space="preserve"><value>Основные клавиши</value></data> + <data name="ModListHelpMoveFocus" xml:space="preserve"><value>Переместить фокус</value></data> + <data name="ModListHelpSelectRow" xml:space="preserve"><value>Выбрать строку</value></data> + <data name="ModListHelpClearSearch" xml:space="preserve"><value>Очистить строку поиска</value></data> + <data name="ModListHelpSpecialSearchesHeader" xml:space="preserve"><value>Особые параметры поиска</value></data> + <data name="ModListHelpAuthor" xml:space="preserve"><value>автор</value></data> + <data name="ModListHelpName" xml:space="preserve"><value>имя</value></data> + <data name="ModListHelpSearchAuthor" xml:space="preserve"><value>Модификации автора</value></data> + <data name="ModListHelpSearchInstalled" xml:space="preserve"><value>Установленные мод-ии</value></data> + <data name="ModListHelpSearchUpgradeable" xml:space="preserve"><value>Мод. с возм. обновления</value></data> + <data name="ModListHelpSearchDepends" xml:space="preserve"><value>Зависящие от</value></data> + <data name="ModListHelpSearchConflicts" xml:space="preserve"><value>Конфликтующие с</value></data> + <data name="ModListHelpSearchNew" xml:space="preserve"><value>Новые модификации</value></data> + <data name="ExitTitle" xml:space="preserve"><value>{0}, Всекербальская сеть архивов</value></data> + <data name="ExitBody" xml:space="preserve"><value>ВЫ ИСПОЛЬЗУЕТЕ {1}. + +Спасибо за загрузку {0}. Надеемся, вам нравится +использовать её так же, как нам её создавать. + +Если вы заплатили за {0}, попытайтесь вернуть деньги, +так как её можно бесплатно загрузить с +{2} + +Если у вас возникают проблемы с использованием {0}, +пожалуйста, отправьте отчёт об ошибке на +{3} + +СОЗДАТЕЛИ {0}: +{4} +</value></data> +</root> diff --git a/ConsoleUI/Properties/Settings.Designer.cs b/ConsoleUI/Properties/Settings.Designer.cs deleted file mode 100644 index 1312cb453b..0000000000 --- a/ConsoleUI/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// </auto-generated> -//------------------------------------------------------------------------------ - -namespace CKAN.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.3.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/ConsoleUI/Properties/Settings.settings b/ConsoleUI/Properties/Settings.settings deleted file mode 100644 index 8e615f25fd..0000000000 --- a/ConsoleUI/Properties/Settings.settings +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version='1.0' encoding='utf-8'?> -<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)"> - <Profiles /> - <Settings /> -</SettingsFile> \ No newline at end of file diff --git a/ConsoleUI/RepoScreen.cs b/ConsoleUI/RepoScreen.cs index 0317516d5e..5fb671cae6 100644 --- a/ConsoleUI/RepoScreen.cs +++ b/ConsoleUI/RepoScreen.cs @@ -23,18 +23,18 @@ protected RepoScreen(IGame game, SortedDictionary<string, Repository> reps, stri defaultRepos = RepositoryList.DefaultRepositories(game); name = new ConsoleField(labelWidth, nameRow, -1, initName) { - GhostText = () => "<Enter the name to use for this repository>" + GhostText = () => Properties.Resources.RepoNameGhostText }; url = new ConsoleField(labelWidth, urlRow, -1, initUrl) { - GhostText = () => "<Enter the URL of this repository>" + GhostText = () => Properties.Resources.RepoURLGhostText }; - AddObject(new ConsoleLabel(1, nameRow, labelWidth, () => "Name:")); + AddObject(new ConsoleLabel(1, nameRow, labelWidth, () => Properties.Resources.RepoNameLabel)); AddObject(name); - AddObject(new ConsoleLabel(1, urlRow, labelWidth, () => "URL:")); + AddObject(new ConsoleLabel(1, urlRow, labelWidth, () => Properties.Resources.RepoURLLabel)); AddObject(url); - AddTip("F2", "Accept"); + AddTip("F2", Properties.Resources.Accept); AddBinding(Keys.F2, (object sender, ConsoleTheme theme) => { if (Valid()) { Save(); @@ -44,7 +44,7 @@ protected RepoScreen(IGame game, SortedDictionary<string, Repository> reps, stri } }); - AddTip("Esc", "Cancel"); + AddTip(Properties.Resources.Esc, Properties.Resources.Cancel); AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => { return false; }); @@ -56,7 +56,7 @@ protected RepoScreen(IGame game, SortedDictionary<string, Repository> reps, stri // This variable will be remembered correctly in our lambdas later Repository repo = r; opts.Add(new ConsoleMenuOption( - repo.name, "", $"Import values from default mod list source {repo.name}", + repo.name, "", string.Format(Properties.Resources.RepoImportTip, repo.name), true, (ConsoleTheme theme) => { name.Value = repo.name; name.Position = name.Value.Length; @@ -83,7 +83,7 @@ protected override string LeftHeader() /// </summary> protected override string CenterHeader() { - return "Edit Mod List Source"; + return Properties.Resources.RepoTitle; } /// <summary> @@ -108,11 +108,11 @@ protected override string CenterHeader() protected bool nameValid() { if (string.IsNullOrEmpty(name.Value)) { - RaiseError("Name cannot be empty!"); + RaiseError(Properties.Resources.RepoNameEmptyError); SetFocus(name); return false; } else if (editList.ContainsKey(name.Value)) { - RaiseError($"{name.Value} already exists!"); + RaiseError(Properties.Resources.RepoNameDuplicateError, name.Value); SetFocus(name); return false; } else { @@ -131,7 +131,7 @@ protected bool nameValid() protected bool urlValid() { if (string.IsNullOrEmpty(url.Value)) { - RaiseError("URL cannot be empty!"); + RaiseError(Properties.Resources.RepoURLEmptyError); SetFocus(url); return false; } @@ -154,7 +154,10 @@ protected bool urlValid() private RepositoryList defaultRepos; - private const int labelWidth = 8; + private int labelWidth => Math.Max(8, Math.Max( + Properties.Resources.RepoNameLabel.Length, + Properties.Resources.RepoURLLabel.Length + )); private const int nameRow = 3; private const int urlRow = 5; } diff --git a/ConsoleUI/SingleAssemblyResourceManager.cs b/ConsoleUI/SingleAssemblyResourceManager.cs new file mode 100644 index 0000000000..3f512754b8 --- /dev/null +++ b/ConsoleUI/SingleAssemblyResourceManager.cs @@ -0,0 +1,58 @@ +using System.IO; +using System.Globalization; +using System.Resources; +using System.Collections; +using System.Reflection; +using System.Collections.Generic; + +namespace CKAN.ConsoleUI +{ + // Thanks and credit to this guy: https://stackoverflow.com/q/1952638/2422988 + + class SingleAssemblyResourceManager : ResourceManager + { + public SingleAssemblyResourceManager(string basename, Assembly assembly) : base(basename, assembly) + { + } + + protected override ResourceSet InternalGetResourceSet(CultureInfo culture, + bool createIfNotExists, bool tryParents) + { + ResourceSet rs; + if (!myResourceSets.TryGetValue(culture, out rs)) + { + // Lazy-load default language (without caring about duplicate assignment in race conditions, no harm done) + if (neutralResourcesCulture == null) + { + neutralResourcesCulture = GetNeutralResourcesLanguage(this.MainAssembly); + } + + // If we're asking for the default language, then ask for the + // invariant (non-specific) resources. + if (neutralResourcesCulture.Equals(culture)) + { + culture = CultureInfo.InvariantCulture; + } + string resourceFileName = GetResourceFileName(culture); + + Stream store = this.MainAssembly.GetManifestResourceStream(resourceFileName); + + // If we found the appropriate resources in the local assembly + if (store != null) + { + rs = new ResourceSet(store); + // Save for later + myResourceSets.Add(culture, rs); + } + else + { + rs = base.InternalGetResourceSet(culture, createIfNotExists, tryParents); + } + } + return rs; + } + + private CultureInfo neutralResourcesCulture; + private Dictionary<CultureInfo, ResourceSet> myResourceSets = new Dictionary<CultureInfo, ResourceSet>(); + } +} diff --git a/ConsoleUI/SplashScreen.cs b/ConsoleUI/SplashScreen.cs index a912cf65ee..0a747d4011 100644 --- a/ConsoleUI/SplashScreen.cs +++ b/ConsoleUI/SplashScreen.cs @@ -86,9 +86,9 @@ private void Draw(ConsoleTheme theme, bool pressAny = false) drawCentered(19, "https://github.com/KSP-CKAN/CKAN/graphs/contributors"); if (pressAny) { - drawCentered(21, "Press any key to continue"); + drawCentered(21, Properties.Resources.SplashPressAnyKey); } else { - drawCentered(21, "Loading..."); + drawCentered(21, Properties.Resources.SplashLoading); } } diff --git a/ConsoleUI/Toolkit/ConsoleChoiceDialog.cs b/ConsoleUI/Toolkit/ConsoleChoiceDialog.cs index cafd0c12d2..a9f493629b 100644 --- a/ConsoleUI/Toolkit/ConsoleChoiceDialog.cs +++ b/ConsoleUI/Toolkit/ConsoleChoiceDialog.cs @@ -59,12 +59,12 @@ public ConsoleChoiceDialog(string m, string hdr, List<ChoiceT> c, Func<ChoiceT, 0, 0, ListSortDirection.Ascending ); - choices.AddTip("Enter", "Accept"); + choices.AddTip(Properties.Resources.Enter, Properties.Resources.Accept); choices.AddBinding(Keys.Enter, (object sender, ConsoleTheme theme) => { return false; }); - choices.AddTip("Esc", "Cancel"); + choices.AddTip(Properties.Resources.Esc, Properties.Resources.Cancel); choices.AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => { cancelled = true; return false; diff --git a/ConsoleUI/Toolkit/ConsoleField.cs b/ConsoleUI/Toolkit/ConsoleField.cs index 33d1ce8263..9e13ab1cf3 100644 --- a/ConsoleUI/Toolkit/ConsoleField.cs +++ b/ConsoleUI/Toolkit/ConsoleField.cs @@ -27,7 +27,7 @@ public ConsoleField(int l, int t, int r, string val = "") /// <summary> /// Function returning text to show when field is empty /// </summary> - public Func<string> GhostText = () => "<Enter a value>"; + public Func<string> GhostText = () => Properties.Resources.DefaultGhostText; /// <summary> /// Current value displayed in field /// </summary> diff --git a/ConsoleUI/Toolkit/ConsoleFileMultiSelectDialog.cs b/ConsoleUI/Toolkit/ConsoleFileMultiSelectDialog.cs index 255334fdea..1597e2eec9 100644 --- a/ConsoleUI/Toolkit/ConsoleFileMultiSelectDialog.cs +++ b/ConsoleUI/Toolkit/ConsoleFileMultiSelectDialog.cs @@ -34,7 +34,7 @@ public ConsoleFileMultiSelectDialog(string title, string startPath, string filPa AddObject(new ConsoleLabel( left + 2, top + 2, left + 2 + labelW - 1, - () => $"Directory:", + () => Properties.Resources.FileSelectDirectory, th => th.PopupBg, th => th.PopupFg )); @@ -48,7 +48,7 @@ public ConsoleFileMultiSelectDialog(string title, string startPath, string filPa AddObject(new ConsoleLabel( left + 2, bottom - 1, right - 2, - () => $"{chosenFiles.Count} selected, {CkanModule.FmtSize(totalChosenSize())}", + () => string.Format(Properties.Resources.FileSelectCountFooter, chosenFiles.Count, CkanModule.FmtSize(totalChosenSize())), th => th.PopupBg, th => th.PopupFg )); @@ -63,12 +63,12 @@ public ConsoleFileMultiSelectDialog(string title, string startPath, string filPa Width = 8, Renderer = getRowSymbol }, new ConsoleListBoxColumn<FileSystemInfo>() { - Header = "Name", + Header = Properties.Resources.FileSelectNameHeader, Width = 36, Renderer = getRowName, Comparer = compareNames }, new ConsoleListBoxColumn<FileSystemInfo>() { - Header = "Size", + Header = Properties.Resources.FileSelectSizeHeader, // Longest: "1023.1 KB" Width = 9, Renderer = (FileSystemInfo fi) => getLength(fi), @@ -79,7 +79,7 @@ public ConsoleFileMultiSelectDialog(string title, string startPath, string filPa : (fb == null ? 1 : fa.Length.CompareTo(fb.Length)); } }, new ConsoleListBoxColumn<FileSystemInfo>() { - Header = "Accessed", + Header = Properties.Resources.FileSelectTimestampHeader, Width = 10, Renderer = (FileSystemInfo fi) => fi.LastWriteTime.ToString("yyyy-MM-dd"), Comparer = (a, b) => a.LastWriteTime.CompareTo(b.LastWriteTime) @@ -89,25 +89,25 @@ public ConsoleFileMultiSelectDialog(string title, string startPath, string filPa ); AddObject(fileList); - AddTip("Esc", "Cancel"); + AddTip(Properties.Resources.Esc, Properties.Resources.Cancel); AddBinding(Keys.Escape, (object sender, ConsoleTheme theme) => { chosenFiles.Clear(); return false; }); - AddTip("F10", "Sort"); + AddTip("F10", Properties.Resources.Sort); AddBinding(Keys.F10, (object sender, ConsoleTheme theme) => { fileList.SortMenu().Run(theme, right - 2, top + 2); DrawBackground(theme); return true; }); - AddTip("Enter", "Change directory", () => fileList.Selection != null && isDir(fileList.Selection)); - AddTip("Enter", "Select", () => fileList.Selection != null && !isDir(fileList.Selection)); + AddTip(Properties.Resources.Enter, Properties.Resources.FileSelectChangeDirectory, () => fileList.Selection != null && isDir(fileList.Selection)); + AddTip(Properties.Resources.Enter, Properties.Resources.FileSelectSelect, () => fileList.Selection != null && !isDir(fileList.Selection)); AddBinding(Keys.Enter, (object sender, ConsoleTheme theme) => selectRow()); AddBinding(Keys.Space, (object sender, ConsoleTheme theme) => selectRow()); - AddTip("Ctrl+A", "Select all"); + AddTip($"{Properties.Resources.Ctrl}+A", Properties.Resources.SelectAll); AddBinding(Keys.CtrlA, (object sender, ConsoleTheme theme) => { foreach (FileSystemInfo fi in contents) { if (!isDir(fi)) { @@ -120,7 +120,7 @@ public ConsoleFileMultiSelectDialog(string title, string startPath, string filPa return true; }); - AddTip("Ctrl+D", "Deselect all", () => chosenFiles.Count > 0); + AddTip($"{Properties.Resources.Ctrl}+D", Properties.Resources.DeselectAll, () => chosenFiles.Count > 0); AddBinding(Keys.CtrlD, (object sender, ConsoleTheme theme) => { if (chosenFiles.Count > 0) { chosenFiles.Clear(); @@ -128,7 +128,7 @@ public ConsoleFileMultiSelectDialog(string title, string startPath, string filPa return true; }); - AddTip("F9", "Import", () => chosenFiles.Count > 0); + AddTip("F9", Properties.Resources.FileSelectImport, () => chosenFiles.Count > 0); AddBinding(Keys.F9, (object sender, ConsoleTheme theme) => { return false; }); @@ -228,13 +228,13 @@ private static bool pathEquals(FileSystemInfo a, FileSystemInfo b) private string getLength(FileSystemInfo fi) { if (isDir(fi)) { - return dirSize; + return Properties.Resources.FileSelectDirSize; } else { FileInfo file = fi as FileInfo; if (file != null) { return CkanModule.FmtSize(file.Length); } else { - return dirSize; + return Properties.Resources.FileSelectDirSize; } } } @@ -308,10 +308,9 @@ private int compareNames(FileSystemInfo a, FileSystemInfo b) private string filePattern; private static readonly string chosen = Symbols.checkmark; - private const string dirSize = "<DIR>"; private const int idealW = 76; - private const int labelW = 12; + private int labelW => Properties.Resources.FileSelectDirectory.Length; private const int hPad = 2; private const int top = 2; private const int bottom = -2; diff --git a/ConsoleUI/Toolkit/ConsoleListBox.cs b/ConsoleUI/Toolkit/ConsoleListBox.cs index f7e29eccef..38c4b6d44c 100644 --- a/ConsoleUI/Toolkit/ConsoleListBox.cs +++ b/ConsoleUI/Toolkit/ConsoleListBox.cs @@ -294,18 +294,24 @@ public ConsolePopupMenu SortMenu() if (sortMenu == null) { List<ConsoleMenuOption> opts = new List<ConsoleMenuOption>() { new ConsoleMenuOption( - "Ascending", "", - "Sort the list in ascending order", + Properties.Resources.Ascending, "", + Properties.Resources.AscendingSortTip, true, - (ConsoleTheme theme) => { SortDirection = ListSortDirection.Ascending; return true; }, - () => { return sortDir == ListSortDirection.Ascending; } + (ConsoleTheme theme) => { + SortDirection = ListSortDirection.Ascending; + return true; + }, + () => sortDir == ListSortDirection.Ascending ), new ConsoleMenuOption( - "Descending", "", - "Sort the list in descending order", + Properties.Resources.Descending, "", + Properties.Resources.DescendingSortTip, true, - (ConsoleTheme theme) => { SortDirection = ListSortDirection.Descending; return true;}, - () => { return sortDir == ListSortDirection.Descending; } + (ConsoleTheme theme) => { + SortDirection = ListSortDirection.Descending; + return true; + }, + () => sortDir == ListSortDirection.Descending ), null }; @@ -314,15 +320,18 @@ public ConsolePopupMenu SortMenu() int newIndex = i; opts.Add(new ConsoleMenuOption( string.IsNullOrEmpty(columns[i].Header) - ? $"Column #{i+1}" + ? string.Format(Properties.Resources.ColumnNumber, i + 1) : columns[i].Header, "", string.IsNullOrEmpty(columns[i].Header) - ? $"Sort the list by column #{i+1}" - : $"Sort the list by the {columns[i].Header} column", + ? string.Format(Properties.Resources.ColumnNumberSortTip, i + 1) + : string.Format(Properties.Resources.ColumnNameSortTip, columns[i].Header), true, - (ConsoleTheme theme) => { SortColumnIndex = newIndex; return true; }, - () => { return sortColIndex == newIndex; } + (ConsoleTheme theme) => { + SortColumnIndex = newIndex; + return true; + }, + () => sortColIndex == newIndex )); } sortMenu = new ConsolePopupMenu(opts); diff --git a/ConsoleUI/Toolkit/ConsoleMessageDialog.cs b/ConsoleUI/Toolkit/ConsoleMessageDialog.cs index ca8848b0ec..ef8126ce06 100644 --- a/ConsoleUI/Toolkit/ConsoleMessageDialog.cs +++ b/ConsoleUI/Toolkit/ConsoleMessageDialog.cs @@ -76,7 +76,7 @@ public ConsoleMessageDialog(string m, List<string> btns, Func<string> hdr = null if (messageLines.Count > boxH) { // Scroll - AddTip("Cursor keys", "Scroll"); + AddTip(Properties.Resources.CursorKeys, Properties.Resources.Scroll); tb.AddScrollBindings(this); } diff --git a/ConsoleUI/Toolkit/ConsoleScreen.cs b/ConsoleUI/Toolkit/ConsoleScreen.cs index 04060f9524..7eeb1cf8e5 100644 --- a/ConsoleUI/Toolkit/ConsoleScreen.cs +++ b/ConsoleUI/Toolkit/ConsoleScreen.cs @@ -65,7 +65,7 @@ protected virtual string CenterHeader() /// </summary> protected virtual string MenuTip() { - return "Menu"; + return Properties.Resources.Menu; } /// <summary> @@ -94,7 +94,10 @@ public virtual bool RaiseYesNoDialog(string question) { ConsoleMessageDialog d = new ConsoleMessageDialog( string.Join("", messagePieces) + question, - new List<string>() {"Yes", "No"} + new List<string>() { + Properties.Resources.Yes, + Properties.Resources.No + } ); d.AddBinding(Keys.Y, (object sender, ConsoleTheme theme) => { d.PressButton(0); @@ -144,7 +147,7 @@ public void RaiseError(string message, params object[] args) { ConsoleMessageDialog d = new ConsoleMessageDialog( string.Join("", messagePieces) + string.Format(message, args), - new List<string>() {"OK"} + new List<string>() { Properties.Resources.OK } ); messagePieces.Clear(); d.Run(userTheme); @@ -267,7 +270,7 @@ private static string LeftCenterRight(string left, string center, string right, } private ConsoleTheme userTheme; - private static readonly string hamburger = $" {Symbols.hamburger} "; + private static readonly string hamburger = $" {Symbols.hamburger} "; } } diff --git a/Core/CKANPathUtils.cs b/Core/CKANPathUtils.cs index 08ab99c28c..030b675cec 100644 --- a/Core/CKANPathUtils.cs +++ b/Core/CKANPathUtils.cs @@ -144,12 +144,14 @@ public static string ToRelative(string path, string root) if (!Path.IsPathRooted(path)) { - throw new PathErrorKraken(path, $"{path} is not an absolute path"); + throw new PathErrorKraken(path, string.Format( + Properties.Resources.PathUtilsNotAbsolute, path)); } if (!path.StartsWith(root, StringComparison.CurrentCultureIgnoreCase)) { - throw new PathErrorKraken(path, $"Oh snap. {path} isn't inside {root}"); + throw new PathErrorKraken(path, string.Format( + Properties.Resources.PathUtilsNotInside, path, root)); } // Strip off the root, then remove any slashes at the beginning @@ -176,7 +178,7 @@ public static string ToAbsolute(string path, string root) { throw new PathErrorKraken( path, - String.Format("{0} is already absolute", path) + String.Format(Properties.Resources.PathUtilsAlreadyAbsolute, path) ); } @@ -184,7 +186,7 @@ public static string ToAbsolute(string path, string root) { throw new PathErrorKraken( root, - String.Format("{0} isn't an absolute root", root) + String.Format(Properties.Resources.PathUtilsNotRoot, root) ); } diff --git a/Core/Converters/JsonRelationshipConverter.cs b/Core/Converters/JsonRelationshipConverter.cs index e66a5180e6..53182711dc 100644 --- a/Core/Converters/JsonRelationshipConverter.cs +++ b/Core/Converters/JsonRelationshipConverter.cs @@ -30,7 +30,8 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist { if (child.Property(forbiddenPropertyName) != null) { - throw new Kraken($"`any_of` should not be combined with `{forbiddenPropertyName}`"); + throw new Kraken(string.Format( + Properties.Resources.JsonRelationshipConverterAnyOfCombined, forbiddenPropertyName)); } } rels.Add(child.ToObject<AnyOfRelationshipDescriptor>()); diff --git a/Core/GameInstance.cs b/Core/GameInstance.cs index bbc00c8cf1..98d918c328 100644 --- a/Core/GameInstance.cs +++ b/Core/GameInstance.cs @@ -102,13 +102,13 @@ private void SetupCkanDirectories(bool scan = true) if (!Directory.Exists(CkanDir())) { - User.RaiseMessage("Setting up CKAN for the first time..."); - User.RaiseMessage("Creating {0}", CkanDir()); + User.RaiseMessage(Properties.Resources.GameInstanceSettingUp); + User.RaiseMessage(Properties.Resources.GameInstanceCreatingDir, CkanDir()); txFileMgr.CreateDirectory(CkanDir()); if (scan) { - User.RaiseMessage("Scanning for installed mods..."); + User.RaiseMessage(Properties.Resources.GameInstanceScanning); Scan(); } } @@ -117,7 +117,7 @@ private void SetupCkanDirectories(bool scan = true) if (!Directory.Exists(InstallHistoryDir())) { - User.RaiseMessage("Creating {0}", InstallHistoryDir()); + User.RaiseMessage(Properties.Resources.GameInstanceCreatingDir, InstallHistoryDir()); txFileMgr.CreateDirectory(InstallHistoryDir()); } @@ -318,8 +318,8 @@ public string CkanDir() { if (!Valid) { - log.Error("Could not find KSP version"); - throw new NotKSPDirKraken(gameDir, "Could not find KSP version in buildID.txt or readme.txt"); + log.Error("Could not find game version"); + throw new NotKSPDirKraken(gameDir, Properties.Resources.GameInstanceVersionNotFound); } return CKANPathUtils.NormalizePath( Path.Combine(GameDir(), "CKAN")); @@ -475,7 +475,7 @@ public string DllPathToIdentifier(string relative_path) public override string ToString() { - return $"{game.ShortName} Install: {gameDir}"; + return string.Format(Properties.Resources.GameInstanceToString, game.ShortName, gameDir); } public bool Equals(GameInstance other) diff --git a/Core/GameInstanceManager.cs b/Core/GameInstanceManager.cs index b93e63793f..a0df024e20 100644 --- a/Core/GameInstanceManager.cs +++ b/Core/GameInstanceManager.cs @@ -107,7 +107,7 @@ internal GameInstance _GetPreferredInstance() if (path != null) { - GameInstance portableInst = new GameInstance(game, path, "portable", User); + GameInstance portableInst = new GameInstance(game, path, Properties.Resources.GameInstanceManagerPortable, User); if (portableInst.Valid) { return portableInst; @@ -156,7 +156,7 @@ public GameInstance FindAndRegisterDefaultInstance() { string gamedir = GameInstance.FindGameDir(game); GameInstance foundInst = new GameInstance( - game, gamedir, $"Auto {game.ShortName}", User); + game, gamedir, string.Format(Properties.Resources.GameInstanceManagerAuto, game.ShortName), User); if (foundInst.Valid) { var inst = AddInstance(foundInst); @@ -230,7 +230,8 @@ public void CloneInstance(GameInstance existingInstance, string newName, string } if (!existingInstance.Valid) { - throw new NotKSPDirKraken(existingInstance.GameDir(), "The specified instance is not a valid KSP instance."); + throw new NotKSPDirKraken(existingInstance.GameDir(), string.Format( + Properties.Resources.GameInstanceCloneInvalid, existingInstance.game.ShortName)); } log.Debug("Copying directory."); @@ -264,11 +265,12 @@ public void FakeInstance(IGame game, string newName, string newPath, GameVersion if (!version.InBuildMap(game)) { - throw new BadGameVersionKraken(String.Format("The specified KSP version is not a known version: {0}", version.ToString())); + throw new BadGameVersionKraken(string.Format( + Properties.Resources.GameInstanceFakeBadVersion, game.ShortName, version)); } if (Directory.Exists(newPath) && (Directory.GetFiles(newPath).Length != 0 || Directory.GetDirectories(newPath).Length != 0)) { - throw new BadInstallLocationKraken("The specified folder already exists and is not empty."); + throw new BadInstallLocationKraken(Properties.Resources.GameInstanceFakeNotEmpty); } log.DebugFormat("Creating folder structure and text files at {0} for KSP version {1}", Path.GetFullPath(newPath), version.ToString()); @@ -307,7 +309,8 @@ public void FakeInstance(IGame game, string newName, string newPath, GameVersion if (!dlcDetector.AllowedOnBaseVersion(version)) throw new WrongGameVersionKraken( version, - String.Format("KSP version {0} or above is needed for {1} DLC.", + string.Format(Properties.Resources.GameInstanceFakeDLCNotAllowed, + game.ShortName, dlcDetector.ReleaseGameVersion, dlcDetector.IdentifierBaseName )); @@ -335,13 +338,13 @@ public void FakeInstance(IGame game, string newName, string newPath, GameVersion /// <exception cref="CKAN.Kraken">Could not find a valid name.</exception> public string GetNextValidInstanceName(string name) { - // Check if the current name is valid. + // Check if the current name is valid if (InstanceNameIsValid(name)) { return name; } - // Try appending a number to the name. + // Try appending a number to the name var validName = Enumerable.Repeat(name, 1000) .Select((s, i) => s + " (" + i + ")") .FirstOrDefault(InstanceNameIsValid); @@ -350,7 +353,7 @@ public string GetNextValidInstanceName(string name) return validName; } - // Check if a name with the current timestamp is valid. + // Check if a name with the current timestamp is valid validName = name + " (" + DateTime.Now + ")"; if (InstanceNameIsValid(validName)) @@ -358,8 +361,8 @@ public string GetNextValidInstanceName(string name) return validName; } - // Give up. - throw new Kraken("Could not return a valid name for the new instance."); + // Give up + throw new Kraken(Properties.Resources.GameInstanceNoValidName); } /// <summary> @@ -432,7 +435,7 @@ public void SetCurrentInstanceByPath(string path) case 1: GameInstance ksp = new GameInstance( - matchingGames.First(), path, "custom", User); + matchingGames.First(), path, Properties.Resources.GameInstanceByPathName, User); if (ksp.Valid) { CurrentInstance = ksp; @@ -461,7 +464,7 @@ public GameInstance InstanceAt(string path, string name) case 1: return new GameInstance( - matchingGames.First(), path, "custom", User); + matchingGames.First(), path, Properties.Resources.GameInstanceByPathName, User); default: // TODO: Prompt user to choose @@ -572,7 +575,7 @@ public bool TrySetupCache(string path, out string failureReason) } catch (DirectoryNotFoundKraken) { - failureReason = $"{path} does not exist"; + failureReason = string.Format(Properties.Resources.GameInstancePathNotFound, path); return false; } catch (PathErrorKraken ex) diff --git a/Core/ModuleInstaller.cs b/Core/ModuleInstaller.cs index 324bd4337a..d07042cf5a 100644 --- a/Core/ModuleInstaller.cs +++ b/Core/ModuleInstaller.cs @@ -53,7 +53,7 @@ public ModuleInstaller(GameInstance ksp, NetModuleCache cache, IUser user) /// </summary> public string Download(CkanModule module, string filename) { - User.RaiseProgress(String.Format("Downloading \"{0}\"", module.download), 0); + User.RaiseProgress(string.Format(Properties.Resources.ModuleInstallerDownloading, module.download), 0); return Download(module, filename, Cache); } @@ -74,7 +74,7 @@ public static string Download(CkanModule module, string filename, NetModuleCache /// and returns the downloaded copy otherwise. /// /// If no filename is provided, the module's standard name will be used. - /// Chcecks the CKAN cache first. + /// Checks the CKAN cache first. /// </summary> public string CachedOrDownload(CkanModule module, string filename = null) { @@ -132,7 +132,7 @@ public void InstallList(ICollection<CkanModule> modules, RelationshipResolverOpt // TODO: Break this up into smaller pieces! It's huge! if (modules.Count == 0) { - User.RaiseProgress("Nothing to install.", 100); + User.RaiseProgress(Properties.Resources.ModuleInstallerNothingToInstall, 100); return; } var resolver = new RelationshipResolver(modules, null, options, registry_manager.registry, ksp.VersionCriteria()); @@ -142,7 +142,8 @@ public void InstallList(ICollection<CkanModule> modules, RelationshipResolverOpt // TODO: All this user-stuff should be happening in another method! // We should just be installing mods as a transaction. - User.RaiseMessage("About to install:\r\n"); + User.RaiseMessage(Properties.Resources.ModuleInstallerAboutToInstall); + User.RaiseMessage(""); foreach (CkanModule module in modsToInstall) { @@ -158,13 +159,13 @@ public void InstallList(ICollection<CkanModule> modules, RelationshipResolverOpt } else { - User.RaiseMessage(" * {0} {1} (cached)", module.name, module.version); + User.RaiseMessage(Properties.Resources.ModuleInstallerModuleCached, module.name, module.version); } } if (ConfirmPrompt && !User.RaiseYesNoDialog("Continue?")) { - throw new CancelledActionKraken("User declined install list"); + throw new CancelledActionKraken(Properties.Resources.ModuleInstallerUserDeclined); } if (downloads.Count > 0) @@ -185,17 +186,17 @@ public void InstallList(ICollection<CkanModule> modules, RelationshipResolverOpt // The post-install steps start at 70%, so count up to 60% for installation int percent_complete = (i * 60) / modsToInstall.Count; - User.RaiseProgress(String.Format("Installing mod \"{0}\"", modsToInstall[i]), + User.RaiseProgress(string.Format(Properties.Resources.ModuleInstallerInstallingMod, modsToInstall[i]), percent_complete); Install(modsToInstall[i], resolver.IsAutoInstalled(modsToInstall[i]), registry_manager.registry, ref possibleConfigOnlyDirs); } - User.RaiseProgress("Updating registry", 70); + User.RaiseProgress(Properties.Resources.ModuleInstallerUpdatingRegistry, 70); registry_manager.Save(!options.without_enforce_consistency); - User.RaiseProgress("Committing filesystem changes", 80); + User.RaiseProgress(Properties.Resources.ModuleInstallerCommitting, 80); transaction.Complete(); @@ -208,12 +209,14 @@ public void InstallList(ICollection<CkanModule> modules, RelationshipResolverOpt // We can scan GameData as a separate transaction. Installing the mods // leaves everything consistent, and this is just gravy. (And ScanGameData // acts as a Tx, anyway, so we don't need to provide our own.) - User.RaiseProgress("Rescanning GameData", 90); + User.RaiseProgress( + string.Format(Properties.Resources.ModuleInstallerRescanning, ksp.game.PrimaryModDirectoryRelative), + 90); log.Debug("Scanning after install"); ksp.Scan(); } - User.RaiseProgress("Done!", 100); + User.RaiseProgress(Properties.Resources.ModuleInstallerDone, 100); } /// <summary> @@ -264,7 +267,7 @@ private void Install(CkanModule module, bool autoInstalled, Registry registry, r // TODO: This really should be handled by higher-up code. if (version != null && !(version is UnmanagedModuleVersion)) { - User.RaiseMessage(" {0} {1} already installed, skipped", module.identifier, version); + User.RaiseMessage(Properties.Resources.ModuleInstallerAlreadyInstalled, module.identifier, version); return; } @@ -276,7 +279,7 @@ private void Install(CkanModule module, bool autoInstalled, Registry registry, r { throw new FileNotFoundKraken( null, - String.Format("Trying to install {0}, but it's not downloaded or download is corrupted", module) + string.Format(Properties.Resources.ModuleInstallerZIPNotInCache, module) ); } @@ -308,11 +311,11 @@ private static void CheckKindInstallationKraken(CkanModule module) { if (module.IsMetapackage) { - throw new BadCommandKraken("Metapackages cannot be installed!"); + throw new BadCommandKraken(Properties.Resources.ModuleInstallerMetapackage); } if (module.IsDLC) { - throw new BadCommandKraken("DLC cannot be installed!"); + throw new BadCommandKraken(Properties.Resources.ModuleInstallerDLC); } } @@ -358,7 +361,8 @@ private IEnumerable<string> InstallModule(CkanModule module, string zip_filename { // Manually installed DLL is somewhere else where we're not installing files, // probable bad install, alert user and abort - throw new DllLocationMismatchKraken(dll, $"DLL for module {module.identifier} found at {dll}, but it's not where CKAN would install it. Aborting to prevent multiple copies of the same mod being installed. To install this module, uninstall it manually and try again."); + throw new DllLocationMismatchKraken(dll, string.Format( + Properties.Resources.ModuleInstallerBadDLLLocation, module.identifier, dll)); } // Delete the manually installed DLL transaction-style because we believe we'll be replacing it var toDelete = ksp.ToAbsoluteGameDir(dll); @@ -377,14 +381,16 @@ private IEnumerable<string> InstallModule(CkanModule module, string zip_filename var fileMsg = conflicting .OrderBy(c => c.Value) .Aggregate("", (a, b) => - $"{a}\r\n- {ksp.ToRelativeGameDir(b.Key.destination)} ({(b.Value ? "same" : "DIFFERENT")})"); - if (User.RaiseYesNoDialog($"Module {module.name} wants to overwrite the following manually installed files:\r\n{fileMsg}\r\n\r\nOverwrite?")) + $"{a}\r\n- {ksp.ToRelativeGameDir(b.Key.destination)} ({(b.Value ? Properties.Resources.ModuleInstallerFileSame : Properties.Resources.ModuleInstallerFileDifferent)})"); + if (User.RaiseYesNoDialog(string.Format( + Properties.Resources.ModuleInstallerOverwrite, module.name, fileMsg))) { DeleteConflictingFiles(conflicting.Select(f => f.Key)); } else { - throw new CancelledActionKraken($"Not overwriting manually installed files, can't install {module.name}."); + throw new CancelledActionKraken(string.Format( + Properties.Resources.ModuleInstallerOverwriteCancelled, module.name)); } } } @@ -603,7 +609,7 @@ internal static string CopyZipEntry(ZipFile zipfile, ZipEntry entry, string full // We don't allow for the overwriting of files. See #208. if (file_transaction.FileExists(fullPath)) { - throw new FileExistsKraken(fullPath, string.Format("Trying to write '{0}' but it already exists.", fullPath)); + throw new FileExistsKraken(fullPath, string.Format(Properties.Resources.ModuleInstallerFileExists, fullPath)); } // Snapshot whatever was there before. If there's nothing, this will just @@ -680,7 +686,8 @@ public void UninstallList( return; } - User.RaiseMessage("About to remove:\r\n"); + User.RaiseMessage(Properties.Resources.ModuleInstallerAboutToRemove); + User.RaiseMessage(""); foreach (string mod in goners) { @@ -688,9 +695,9 @@ public void UninstallList( User.RaiseMessage(" * {0} {1}", module.Module.name, module.Module.version); } - if (ConfirmPrompt && !User.RaiseYesNoDialog("Continue?")) + if (ConfirmPrompt && !User.RaiseYesNoDialog(Properties.Resources.ModuleInstallerContinuePrompt)) { - throw new CancelledActionKraken("Mod removal aborted at user request"); + throw new CancelledActionKraken(Properties.Resources.ModuleInstallerRemoveAborted); } using (var transaction = CkanTransaction.CreateTransactionScope()) @@ -699,7 +706,9 @@ public void UninstallList( foreach (string mod in goners) { int percent_complete = (step++ * 100) / goners.Count; - User.RaiseProgress($"Removing {mod}...", percent_complete); + User.RaiseProgress( + string.Format(Properties.Resources.ModuleInstallerRemovingMod, mod), + percent_complete); Uninstall(mod, ref possibleConfigOnlyDirs, registry_manager.registry); } @@ -710,7 +719,7 @@ public void UninstallList( transaction.Complete(); } - User.RaiseProgress("Done!", 100); + User.RaiseProgress(Properties.Resources.ModuleInstallerDone, 100); } /// <summary> @@ -935,7 +944,9 @@ public void AddRemove(ref HashSet<string> possibleConfigOnlyDirs, RegistryManage { // The post-install steps start at 80%, so count up to 70% for installation int percent_complete = (step++ * 70) / totSteps; - User.RaiseProgress($"Removing \"{instMod.Module}\"", percent_complete); + User.RaiseProgress( + string.Format(Properties.Resources.ModuleInstallerRemovingMod, instMod.Module), + percent_complete); Uninstall(instMod.Module.identifier, ref possibleConfigOnlyDirs, registry_manager.registry); } @@ -943,14 +954,16 @@ public void AddRemove(ref HashSet<string> possibleConfigOnlyDirs, RegistryManage { var previous = remove?.FirstOrDefault(im => im.Module.identifier == module.identifier); int percent_complete = (step++ * 70) / totSteps; - User.RaiseProgress($"Installing \"{module}\"", percent_complete); + User.RaiseProgress( + string.Format(Properties.Resources.ModuleInstallerInstallingMod, module), + percent_complete); Install(module, previous?.AutoInstalled ?? false, registry_manager.registry, ref possibleConfigOnlyDirs); } - User.RaiseProgress("Updating registry", 80); + User.RaiseProgress(Properties.Resources.ModuleInstallerUpdatingRegistry, 80); registry_manager.Save(enforceConsistency); - User.RaiseProgress("Committing filesystem changes", 90); + User.RaiseProgress(Properties.Resources.ModuleInstallerCommitting, 90); tx.Complete(); EnforceCacheSizeLimit(registry_manager.registry); @@ -998,7 +1011,8 @@ public void Upgrade(IEnumerable<CkanModule> modules, IDownloader netAsyncDownloa modules = resolver.ModList(); } - User.RaiseMessage("About to upgrade:\r\n"); + User.RaiseMessage(Properties.Resources.ModuleInstallerAboutToUpgrade); + User.RaiseMessage(""); // Our upgrade involves removing everything that's currently installed, then // adding everything that needs installing (which may involve new mods to @@ -1015,7 +1029,7 @@ public void Upgrade(IEnumerable<CkanModule> modules, IDownloader netAsyncDownloa { if (!Cache.IsMaybeCachedZip(module)) { - User.RaiseMessage(" * Install: {0} {1} ({2}, {3})", + User.RaiseMessage(Properties.Resources.ModuleInstallerUpgradeInstallingUncached, module.name, module.version, module.download.Host, @@ -1024,7 +1038,7 @@ public void Upgrade(IEnumerable<CkanModule> modules, IDownloader netAsyncDownloa } else { - User.RaiseMessage(" * Install: {0} {1} (cached)", + User.RaiseMessage(Properties.Resources.ModuleInstallerUpgradeInstallingCached, module.name, module.version); } } @@ -1036,19 +1050,19 @@ public void Upgrade(IEnumerable<CkanModule> modules, IDownloader netAsyncDownloa CkanModule installed = installed_mod.Module; if (installed.version.IsEqualTo(module.version)) { - User.RaiseMessage(" * Re-install: {0} {1}", + User.RaiseMessage(Properties.Resources.ModuleInstallerUpgradeReinstalling, module.name, module.version); } else if (installed.version.IsGreaterThan(module.version)) { - User.RaiseMessage(" * Downgrade: {0} from {1} to {2}", + User.RaiseMessage(Properties.Resources.ModuleInstallerUpgradeDowngrading, module.name, installed.version, module.version); } else { if (!Cache.IsMaybeCachedZip(module)) { - User.RaiseMessage(" * Upgrade: {0} {1} to {2} ({3}, {4})", + User.RaiseMessage(Properties.Resources.ModuleInstallerUpgradeUpgradingUncached, module.name, installed.version, module.version, @@ -1058,16 +1072,16 @@ public void Upgrade(IEnumerable<CkanModule> modules, IDownloader netAsyncDownloa } else { - User.RaiseMessage(" * Upgrade: {0} {1} to {2} (cached)", + User.RaiseMessage(Properties.Resources.ModuleInstallerUpgradeUpgradingCached, module.name, installed.version, module.version); } } } } - if (ConfirmPrompt && !User.RaiseYesNoDialog("Continue?")) + if (ConfirmPrompt && !User.RaiseYesNoDialog(Properties.Resources.ModuleInstallerContinuePrompt)) { - throw new CancelledActionKraken("User declined upgrade list"); + throw new CancelledActionKraken(Properties.Resources.ModuleInstallerUpgradeUserDeclined); } // Start by making sure we've downloaded everything. @@ -1080,7 +1094,7 @@ public void Upgrade(IEnumerable<CkanModule> modules, IDownloader netAsyncDownloa to_remove, enforceConsistency ); - User.RaiseProgress("Done!", 100); + User.RaiseProgress(Properties.Resources.ModuleInstallerDone, 100); } /// <summary> @@ -1120,10 +1134,14 @@ public void Replace(IEnumerable<ModuleReplacement> replacements, RelationshipRes //Maybe ModuleNotInstalled ? if (registry_manager.registry.IsAutodetected(ident)) { - throw new ModuleNotFoundKraken(ident, repl.ToReplace.version.ToString(), String.Format("Can't replace {0} as it was not installed by CKAN. \r\n Please remove manually before trying to install it.", ident)); + throw new ModuleNotFoundKraken(ident, + repl.ToReplace.version.ToString(), + string.Format(Properties.Resources.ModuleInstallerReplaceAutodetected, ident)); } - throw new ModuleNotFoundKraken(ident, repl.ToReplace.version.ToString(), String.Format("Can't replace {0} as it is not installed. Please attempt to install {1} instead.", ident, repl.ReplaceWith.identifier)); + throw new ModuleNotFoundKraken(ident, + repl.ToReplace.version.ToString(), + string.Format(Properties.Resources.ModuleInstallerReplaceNotInstalled, ident, repl.ReplaceWith.identifier)); } else { @@ -1170,7 +1188,7 @@ public void Replace(IEnumerable<ModuleReplacement> replacements, RelationshipRes modsToRemove, enforceConsistency ); - User.RaiseProgress("Done!", 100); + User.RaiseProgress(Properties.Resources.ModuleInstallerDone, 100); } #endregion @@ -1432,7 +1450,7 @@ public void ImportFiles(HashSet<FileInfo> files, IUser user, Action<CkanModule> foreach (FileInfo f in files) { int percent = i * 100 / files.Count; - user.RaiseProgress($"Importing {f.Name}... ({percent}%)", percent); + user.RaiseProgress(string.Format(Properties.Resources.ModuleInstallerImporting, f.Name, percent), percent); // Calc SHA-1 sum string sha1 = Cache.GetFileHashSha1(f.FullName); // Find SHA-1 sum in registry (potentially multiple) @@ -1448,22 +1466,25 @@ public void ImportFiles(HashSet<FileInfo> files, IUser user, Action<CkanModule> } if (Cache.IsMaybeCachedZip(mod)) { - user.RaiseMessage("Already cached: {0}", f.Name); + user.RaiseMessage(Properties.Resources.ModuleInstallerImportAlreadyCached, f.Name); } else { - user.RaiseMessage($"Importing {mod.identifier} {StripEpoch(mod.version)}..."); + user.RaiseMessage(Properties.Resources.ModuleInstallerImportingMod, + mod.identifier, StripEpoch(mod.version)); Cache.Store(mod, f.FullName); } } } else { - user.RaiseMessage("Not found in index: {0}", f.Name); + user.RaiseMessage(Properties.Resources.ModuleInstallerImportNotFound, f.Name); } ++i; } - if (installable.Count > 0 && user.RaiseYesNoDialog($"Install {installable.Count} compatible imported mods in game instance {ksp.Name} ({ksp.GameDir()})?")) + if (installable.Count > 0 && user.RaiseYesNoDialog(string.Format( + Properties.Resources.ModuleInstallerImportInstallPrompt, + installable.Count, ksp.Name, ksp.GameDir()))) { // Install the imported mods foreach (CkanModule mod in installable) @@ -1471,7 +1492,8 @@ public void ImportFiles(HashSet<FileInfo> files, IUser user, Action<CkanModule> installMod(mod); } } - if (allowDelete && deletable.Count > 0 && user.RaiseYesNoDialog($"Import complete. Delete {deletable.Count} old files?")) + if (allowDelete && deletable.Count > 0 && user.RaiseYesNoDialog(string.Format( + Properties.Resources.ModuleInstallerImportDeletePrompt, deletable.Count))) { // Delete old files foreach (FileInfo f in deletable) diff --git a/Core/Net/AutoUpdate.cs b/Core/Net/AutoUpdate.cs index 9da567263a..1793a8aea6 100644 --- a/Core/Net/AutoUpdate.cs +++ b/Core/Net/AutoUpdate.cs @@ -137,7 +137,7 @@ public void StartUpdateProcess(bool launchCKANAfterUpdate, IUser user = null) { if (!IsFetched()) { - throw new Kraken("We have not fetched the release info yet. Can't update."); + throw new Kraken(Properties.Resources.AutoUpdateNotFetched); } var pid = Process.GetCurrentProcess().Id; diff --git a/Core/Net/Net.cs b/Core/Net/Net.cs index 8366a522ac..6e4bd96563 100644 --- a/Core/Net/Net.cs +++ b/Core/Net/Net.cs @@ -83,7 +83,7 @@ public static string Download(string url, out string etag, string filename = nul TxFileManager FileTransaction = new TxFileManager(); user = user ?? new NullUser(); - user.RaiseMessage("Downloading {0}", url); + user.RaiseMessage(Properties.Resources.NetDownloading, url); // Generate a temporary file if none is provided. if (filename == null) @@ -130,7 +130,9 @@ public static string Download(string url, out string etag, string filename = nul // Look for an exception regarding the authentication. if (Regex.IsMatch(exc.ToString(), "The authentication or decryption has failed.")) { - throw new MissingCertificateKraken("Failed downloading " + url, exc); + throw new MissingCertificateKraken( + string.Format(Properties.Resources.NetMissingCertFailed, url), + exc); } // Not the exception we were looking for! Throw it further upwards! @@ -277,7 +279,7 @@ public static Uri ResolveRedirect(Uri uri) } else { - throw new Kraken("Invalid URL in Location header: " + location); + throw new Kraken(string.Format(Properties.Resources.NetInvalidLocation, location)); } } } diff --git a/Core/Net/NetAsyncDownloader.cs b/Core/Net/NetAsyncDownloader.cs index d600dc5ed5..f529d58ea5 100644 --- a/Core/Net/NetAsyncDownloader.cs +++ b/Core/Net/NetAsyncDownloader.cs @@ -155,7 +155,7 @@ private void DownloadModule(Net.DownloadTarget target) downloads.Add(dl); // Encode spaces to avoid confusing URL parsers - User.RaiseMessage("Downloading \"{0}\"", + User.RaiseMessage(Properties.Resources.NetAsyncDownloaderDownloading, dl.target.url.ToString().Replace(" ", "%20")); // Schedule for us to get back progress reports. @@ -237,7 +237,7 @@ public void DownloadAndWait(ICollection<Net.DownloadTarget> urls) } // Signal to the caller that the user cancelled the download. - throw new CancelledActionKraken("Download cancelled by user"); + throw new CancelledActionKraken(Properties.Resources.NetAsyncDownloaderCancelled); } // Check to see if we've had any errors. If so, then release the kraken! @@ -367,7 +367,7 @@ private void FileProgressReport(int index, int percent, long bytesDownloaded, lo { // Math.Ceiling was added to avoid showing 0 MiB left when finishing User.RaiseProgress( - String.Format("{0}/sec - downloading - {1} left", + String.Format(Properties.Resources.NetAsyncDownloaderProgress, CkanModule.FmtSize(totalBytesPerSecond), CkanModule.FmtSize(totalBytesLeft)), totalPercentage); @@ -389,7 +389,7 @@ private void FileDownloadComplete(int index, Exception error) { log.InfoFormat("Trying fallback URL: {0}", downloads[index].target.fallbackUrl); // Encode spaces to avoid confusing URL parsers - User.RaiseMessage("Failed to download \"{0}\", trying fallback \"{1}\"", + User.RaiseMessage(Properties.Resources.NetAsyncDownloaderTryingFallback, downloads[index].target.url.ToString().Replace(" ", "%20"), downloads[index].target.fallbackUrl.ToString().Replace(" ", "%20") ); diff --git a/Core/Net/NetFileCache.cs b/Core/Net/NetFileCache.cs index 6aec3f94cd..fd45a0d35e 100644 --- a/Core/Net/NetFileCache.cs +++ b/Core/Net/NetFileCache.cs @@ -63,7 +63,8 @@ public NetFileCache(string path) // Basic validation, our cache has to exist. if (!Directory.Exists(cachePath)) { - throw new DirectoryNotFoundKraken(cachePath, $"Cannot find cache directory: {cachePath}"); + throw new DirectoryNotFoundKraken(cachePath, string.Format( + Properties.Resources.NetFileCacheCannotFind, cachePath)); } // Establish a watch on our cache. This means we can cache the directory contents, @@ -443,7 +444,9 @@ public static bool ZipValid(string filename, out string invalidReason) if (st != null && !st.EntryValid && !string.IsNullOrEmpty(msg)) { // Capture the error string so we can return it - zipErr = $"Error in step {st.Operation} for {st.Entry?.Name}: {msg}"; + zipErr = string.Format( + Properties.Resources.NetFileCacheZipError, + st.Operation, st.Entry?.Name, msg); } })) { @@ -452,14 +455,14 @@ public static bool ZipValid(string filename, out string invalidReason) } else { - invalidReason = zipErr ?? "ZipFile.TestArchive(true) returned false"; + invalidReason = zipErr ?? Properties.Resources.NetFileCacheZipTestArchiveFalse; return false; } } } else { - invalidReason = "Null file name"; + invalidReason = Properties.Resources.NetFileCacheNullFileName; return false; } } @@ -477,7 +480,7 @@ public static bool ZipValid(string filename, out string invalidReason) catch (NotSupportedException nse) when (Platform.IsMono) { // SharpZipLib throws this if your locale isn't installed on Mono - invalidReason = $"{nse.Message}\r\n\r\nInstall the `mono-complete` package or equivalent for your operating system."; + invalidReason = string.Format(Properties.Resources.NetFileCacheMonoNotSupported, nse.Message); return false; } } diff --git a/Core/Net/NetModuleCache.cs b/Core/Net/NetModuleCache.cs index 6075255b81..8eb66d2bfc 100644 --- a/Core/Net/NetModuleCache.cs +++ b/Core/Net/NetModuleCache.cs @@ -123,14 +123,16 @@ public string Store(CkanModule module, string path, string description = null, b // Check file size if (module.download_size > 0 && fi.Length != module.download_size) - throw new InvalidModuleFileKraken(module, path, - $"{module}: {path} has length {fi.Length}, should be {module.download_size}"); + throw new InvalidModuleFileKraken(module, path, string.Format( + Properties.Resources.NetModuleCacheBadLength, + module, path, fi.Length, module.download_size)); // Check valid CRC string invalidReason; if (!NetFileCache.ZipValid(path, out invalidReason)) - throw new InvalidModuleFileKraken(module, path, - $"{module}: {path} is not a valid ZIP file: {invalidReason}"); + throw new InvalidModuleFileKraken(module, path, string.Format( + Properties.Resources.NetModuleCacheNotValidZIP, + module, path, invalidReason)); // Some older metadata doesn't have hashes if (module.download_hash != null) @@ -138,14 +140,16 @@ public string Store(CkanModule module, string path, string description = null, b // Check SHA1 match string sha1 = GetFileHashSha1(path); if (sha1 != module.download_hash.sha1) - throw new InvalidModuleFileKraken(module, path, - $"{module}: {path} has SHA1 {sha1}, should be {module.download_hash.sha1}"); + throw new InvalidModuleFileKraken(module, path, string.Format( + Properties.Resources.NetModuleCacheMismatchSHA1, + module, path, sha1, module.download_hash.sha1)); // Check SHA256 match string sha256 = GetFileHashSha256(path); if (sha256 != module.download_hash.sha256) - throw new InvalidModuleFileKraken(module, path, - $"{module}: {path} has SHA256 {sha256}, should be {module.download_hash.sha256}"); + throw new InvalidModuleFileKraken(module, path, string.Format( + Properties.Resources.NetModuleCacheMismatchSHA256, + module, path, sha256, module.download_hash.sha256)); } // If no exceptions, then everything is fine diff --git a/Core/Net/Repo.cs b/Core/Net/Repo.cs index 42a022464d..823a38acfc 100644 --- a/Core/Net/Repo.cs +++ b/Core/Net/Repo.cs @@ -37,18 +37,18 @@ public static class Repo public static RepoUpdateResult UpdateAllRepositories(RegistryManager registry_manager, GameInstance ksp, NetModuleCache cache, IUser user) { SortedDictionary<string, Repository> sortedRepositories = registry_manager.registry.Repositories; - user.RaiseProgress("Checking for updates", 0); + user.RaiseProgress(Properties.Resources.NetRepoCheckingForUpdates, 0); if (sortedRepositories.Values.All(repo => !string.IsNullOrEmpty(repo.last_server_etag) && repo.last_server_etag == Net.CurrentETag(repo.uri))) { - user.RaiseProgress("Already up to date", 100); - user.RaiseMessage("No changes since last update"); + user.RaiseProgress(Properties.Resources.NetRepoAlreadyUpToDate, 100); + user.RaiseMessage(Properties.Resources.NetRepoNoChanges); return RepoUpdateResult.NoChanges; } List<CkanModule> allAvail = new List<CkanModule>(); int index = 0; foreach (KeyValuePair<string, Repository> repository in sortedRepositories) { - user.RaiseProgress($"Updating {repository.Value.name}", + user.RaiseProgress(string.Format(Properties.Resources.NetRepoUpdating, repository.Value.name), 10 + 80 * index / sortedRepositories.Count); SortedDictionary<string, int> downloadCounts; string newETag; @@ -65,7 +65,7 @@ public static RepoUpdateResult UpdateAllRepositories(RegistryManager registry_ma // Merge all the lists allAvail.AddRange(avail); repository.Value.last_server_etag = newETag; - user.RaiseMessage("Updated {0} ({1} modules)", + user.RaiseMessage(Properties.Resources.NetRepoUpdated, repository.Value.name, avail.Count); } ++index; @@ -73,7 +73,7 @@ public static RepoUpdateResult UpdateAllRepositories(RegistryManager registry_ma // Save allAvail to the registry if we found anything if (allAvail.Count > 0) { - user.RaiseProgress("Saving modules to registry", 90); + user.RaiseProgress(Properties.Resources.NetRepoSaving, 90); using (var transaction = CkanTransaction.CreateTransactionScope()) { // Save our changes. @@ -92,14 +92,14 @@ public static RepoUpdateResult UpdateAllRepositories(RegistryManager registry_ma // Registry.CompatibleModules is slow, just return success, // caller can check it if it's really needed - user.RaiseProgress("Registry saved", 100); - user.RaiseMessage("Repositories updated"); + user.RaiseProgress(Properties.Resources.NetRepoSaved, 100); + user.RaiseMessage(Properties.Resources.NetRepoUpdatedAll); return RepoUpdateResult.Updated; } else { // Return failure - user.RaiseMessage("No modules found!"); + user.RaiseMessage(Properties.Resources.NetRepoNoModules); return RepoUpdateResult.Failed; } } @@ -121,7 +121,7 @@ private static List<CkanModule> UpdateRegistry(Uri repo, GameInstance ksp, IUser } catch (System.Net.WebException ex) { - user.RaiseError("Failed to download {0}: {1}", repo, ex.Message); + user.RaiseError(Properties.Resources.NetRepoFailedDownload, repo, ex.Message); currentETag = null; return null; } @@ -203,12 +203,7 @@ private static void HandleModuleChanges(List<CkanModule> metadataChanges, IUser sb.AppendLine(string.Format("- {0} {1}", module.identifier, module.version)); } - if (user.RaiseYesNoDialog(string.Format(@"The following mods have had their metadata changed since last update: - -{0} -You should reinstall them in order to preserve consistency with the repository. - -Do you wish to reinstall now?", sb))) + if (user.RaiseYesNoDialog(string.Format(Properties.Resources.NetRepoChangedModulesReinstallPrompt, sb))) { throw new ReinstallModuleKraken(metadataChanges); } @@ -530,7 +525,7 @@ private static void ShowUserInconsistencies(Registry registry, IUser user) { var sanityMessage = new StringBuilder(); - sanityMessage.AppendLine("The following inconsistencies were found:"); + sanityMessage.AppendLine(Properties.Resources.NetRepoInconsistenciesHeader); foreach (var sanityError in sanityErrors) { sanityMessage.Append("- "); diff --git a/Core/Properties/AssemblyInfo.cs b/Core/Properties/AssemblyInfo.cs index 9b100a5b1b..824627d0ad 100644 --- a/Core/Properties/AssemblyInfo.cs +++ b/Core/Properties/AssemblyInfo.cs @@ -1,8 +1,10 @@ +using System.Resources; using System.Reflection; using System.Runtime.CompilerServices; [assembly: AssemblyTitle("CKAN")] [assembly: AssemblyDescription("CKAN Core")] +[assembly: NeutralResourcesLanguage("en-GB")] [assembly: InternalsVisibleTo("Tests")] [assembly: InternalsVisibleTo("CKAN.Tests")] diff --git a/Core/Properties/Resources.Designer.cs b/Core/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..229d653537 --- /dev/null +++ b/Core/Properties/Resources.Designer.cs @@ -0,0 +1,561 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. (I WISH!) +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace CKAN.Properties { + using System; + + + /// <summary> + /// A strongly-typed resource class, for looking up localized strings, etc. + /// </summary> + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { } + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) + { + resourceMan = new SingleAssemblyResourceManager("CKAN.Properties.Resources", typeof(Resources).Assembly); + } + return resourceMan; + } + } + + /// <summary> + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + internal static string AutoUpdateNotFetched { + get { return (string)(ResourceManager.GetObject("AutoUpdateNotFetched", resourceCulture)); } + } + + internal static string NetDownloading { + get { return (string)(ResourceManager.GetObject("NetDownloading", resourceCulture)); } + } + internal static string NetMissingCertFailed { + get { return (string)(ResourceManager.GetObject("NetMissingCertFailed", resourceCulture)); } + } + internal static string NetInvalidLocation { + get { return (string)(ResourceManager.GetObject("NetInvalidLocation", resourceCulture)); } + } + + internal static string NetAsyncDownloaderDownloading { + get { return (string)(ResourceManager.GetObject("NetAsyncDownloaderDownloading", resourceCulture)); } + } + internal static string NetAsyncDownloaderCancelled { + get { return (string)(ResourceManager.GetObject("NetAsyncDownloaderCancelled", resourceCulture)); } + } + internal static string NetAsyncDownloaderProgress { + get { return (string)(ResourceManager.GetObject("NetAsyncDownloaderProgress", resourceCulture)); } + } + internal static string NetAsyncDownloaderTryingFallback { + get { return (string)(ResourceManager.GetObject("NetAsyncDownloaderTryingFallback", resourceCulture)); } + } + + internal static string NetFileCacheCannotFind { + get { return (string)(ResourceManager.GetObject("NetFileCacheCannotFind", resourceCulture)); } + } + internal static string NetFileCacheZipError { + get { return (string)(ResourceManager.GetObject("NetFileCacheZipError", resourceCulture)); } + } + internal static string NetFileCacheZipTestArchiveFalse { + get { return (string)(ResourceManager.GetObject("NetFileCacheZipTestArchiveFalse", resourceCulture)); } + } + internal static string NetFileCacheNullFileName { + get { return (string)(ResourceManager.GetObject("NetFileCacheNullFileName", resourceCulture)); } + } + internal static string NetFileCacheMonoNotSupported { + get { return (string)(ResourceManager.GetObject("NetFileCacheMonoNotSupported", resourceCulture)); } + } + internal static string NetModuleCacheBadLength { + get { return (string)(ResourceManager.GetObject("NetModuleCacheBadLength", resourceCulture)); } + } + internal static string NetModuleCacheNotValidZIP { + get { return (string)(ResourceManager.GetObject("NetModuleCacheNotValidZIP", resourceCulture)); } + } + internal static string NetModuleCacheMismatchSHA1 { + get { return (string)(ResourceManager.GetObject("NetModuleCacheMismatchSHA1", resourceCulture)); } + } + internal static string NetModuleCacheMismatchSHA256 { + get { return (string)(ResourceManager.GetObject("NetModuleCacheMismatchSHA256", resourceCulture)); } + } + + internal static string NetRepoCheckingForUpdates { + get { return (string)(ResourceManager.GetObject("NetRepoCheckingForUpdates", resourceCulture)); } + } + internal static string NetRepoAlreadyUpToDate { + get { return (string)(ResourceManager.GetObject("NetRepoAlreadyUpToDate", resourceCulture)); } + } + internal static string NetRepoNoChanges { + get { return (string)(ResourceManager.GetObject("NetRepoNoChanges", resourceCulture)); } + } + internal static string NetRepoUpdating { + get { return (string)(ResourceManager.GetObject("NetRepoUpdating", resourceCulture)); } + } + internal static string NetRepoUpdated { + get { return (string)(ResourceManager.GetObject("NetRepoUpdated", resourceCulture)); } + } + internal static string NetRepoSaving { + get { return (string)(ResourceManager.GetObject("NetRepoSaving", resourceCulture)); } + } + internal static string NetRepoSaved { + get { return (string)(ResourceManager.GetObject("NetRepoSaved", resourceCulture)); } + } + internal static string NetRepoUpdatedAll { + get { return (string)(ResourceManager.GetObject("NetRepoUpdatedAll", resourceCulture)); } + } + internal static string NetRepoNoModules { + get { return (string)(ResourceManager.GetObject("NetRepoNoModules", resourceCulture)); } + } + internal static string NetRepoFailedDownload { + get { return (string)(ResourceManager.GetObject("NetRepoFailedDownload", resourceCulture)); } + } + internal static string NetRepoChangedModulesReinstallPrompt { + get { return (string)(ResourceManager.GetObject("NetRepoChangedModulesReinstallPrompt", resourceCulture)); } + } + internal static string NetRepoInconsistenciesHeader { + get { return (string)(ResourceManager.GetObject("NetRepoInconsistenciesHeader", resourceCulture)); } + } + + internal static string JsonRelationshipConverterAnyOfCombined { + get { return (string)(ResourceManager.GetObject("JsonRelationshipConverterAnyOfCombined", resourceCulture)); } + } + + internal static string RegistryFileConflict { + get { return (string)(ResourceManager.GetObject("RegistryFileConflict", resourceCulture)); } + } + internal static string RegistryFileNotRemoved { + get { return (string)(ResourceManager.GetObject("RegistryFileNotRemoved", resourceCulture)); } + } + internal static string RegistryManagerDirectoryNotFound { + get { return (string)(ResourceManager.GetObject("RegistryManagerDirectoryNotFound", resourceCulture)); } + } + internal static string RegistryManagerExportFilenamePrefix { + get { return (string)(ResourceManager.GetObject("RegistryManagerExportFilenamePrefix", resourceCulture)); } + } + internal static string RegistryManagerDefaultModpackAbstract { + get { return (string)(ResourceManager.GetObject("RegistryManagerDefaultModpackAbstract", resourceCulture)); } + } + + internal static string CkanModuleDeserialisationError { + get { return (string)(ResourceManager.GetObject("CkanModuleDeserialisationError", resourceCulture)); } + } + internal static string CkanModuleUnsupportedSpec { + get { return (string)(ResourceManager.GetObject("CkanModuleUnsupportedSpec", resourceCulture)); } + } + internal static string CkanModuleMissingRequired { + get { return (string)(ResourceManager.GetObject("CkanModuleMissingRequired", resourceCulture)); } + } + internal static string CkanModuleKspVersionMixed { + get { return (string)(ResourceManager.GetObject("CkanModuleKspVersionMixed", resourceCulture)); } + } + internal static string CkanModuleNotAvailable { + get { return (string)(ResourceManager.GetObject("CkanModuleNotAvailable", resourceCulture)); } + } + internal static string CkanModuleNotInstalledOrAvailable { + get { return (string)(ResourceManager.GetObject("CkanModuleNotInstalledOrAvailable", resourceCulture)); } + } + internal static string CkanModuleAllVersions { + get { return (string)(ResourceManager.GetObject("CkanModuleAllVersions", resourceCulture)); } + } + + internal static string LicenceInvalid { + get { return (string)(ResourceManager.GetObject("LicenceInvalid", resourceCulture)); } + } + + internal static string ModuleInstallDescriptorMustHaveInstallTo { + get { return (string)(ResourceManager.GetObject("ModuleInstallDescriptorMustHaveInstallTo", resourceCulture)); } + } + internal static string ModuleInstallDescriptorRequireFileFind { + get { return (string)(ResourceManager.GetObject("ModuleInstallDescriptorRequireFileFind", resourceCulture)); } + } + internal static string ModuleInstallDescriptorTooManyFileFind { + get { return (string)(ResourceManager.GetObject("ModuleInstallDescriptorTooManyFileFind", resourceCulture)); } + } + internal static string ModuleInstallDescriptorTooManyFilterInclude { + get { return (string)(ResourceManager.GetObject("ModuleInstallDescriptorTooManyFilterInclude", resourceCulture)); } + } + internal static string ModuleInstallDescriptorInvalidInstallPath { + get { return (string)(ResourceManager.GetObject("ModuleInstallDescriptorInvalidInstallPath", resourceCulture)); } + } + internal static string ModuleInstallDescriptorUnknownInstallPath { + get { return (string)(ResourceManager.GetObject("ModuleInstallDescriptorUnknownInstallPath", resourceCulture)); } + } + internal static string ModuleInstallDescriptorNoFilesFound { + get { return (string)(ResourceManager.GetObject("ModuleInstallDescriptorNoFilesFound", resourceCulture)); } + } + internal static string ModuleInstallDescriptorAsNoPathSeparators { + get { return (string)(ResourceManager.GetObject("ModuleInstallDescriptorAsNoPathSeparators", resourceCulture)); } + } + + internal static string RelationshipDescriptorMinVersionOnly { + get { return (string)(ResourceManager.GetObject("RelationshipDescriptorMinVersionOnly", resourceCulture)); } + } + internal static string RelationshipDescriptorMaxVersionOnly { + get { return (string)(ResourceManager.GetObject("RelationshipDescriptorMaxVersionOnly", resourceCulture)); } + } + internal static string RelationshipDescriptorAnyOfJoiner { + get { return (string)(ResourceManager.GetObject("RelationshipDescriptorAnyOfJoiner", resourceCulture)); } + } + + internal static string ReleaseStatusInvalid { + get { return (string)(ResourceManager.GetObject("ReleaseStatusInvalid", resourceCulture)); } + } + + internal static string RepositoryDefaultName { + get { return (string)(ResourceManager.GetObject("RepositoryDefaultName", resourceCulture)); } + } + + internal static string CkanModuleVersionToString { + get { return (string)(ResourceManager.GetObject("CkanModuleVersionToString", resourceCulture)); } + } + + internal static string GameVersionYalovAny { + get { return (string)(ResourceManager.GetObject("GameVersionYalovAny", resourceCulture)); } + } + internal static string GameVersionSelectNeedOne { + get { return (string)(ResourceManager.GetObject("GameVersionSelectNeedOne", resourceCulture)); } + } + internal static string GameVersionSelectHeader { + get { return (string)(ResourceManager.GetObject("GameVersionSelectHeader", resourceCulture)); } + } + internal static string GameVersionSelectBuildHeader { + get { return (string)(ResourceManager.GetObject("GameVersionSelectBuildHeader", resourceCulture)); } + } + internal static string GameVersionNotKnown { + get { return (string)(ResourceManager.GetObject("GameVersionNotKnown", resourceCulture)); } + } + internal static string GameVersionCriteriaToString { + get { return (string)(ResourceManager.GetObject("GameVersionCriteriaToString", resourceCulture)); } + } + internal static string GameVersionRangeMinOnly { + get { return (string)(ResourceManager.GetObject("GameVersionRangeMinOnly", resourceCulture)); } + } + internal static string GameVersionRangeMaxOnly { + get { return (string)(ResourceManager.GetObject("GameVersionRangeMaxOnly", resourceCulture)); } + } + + internal static string ProvidesModuleVersionToString { + get { return (string)(ResourceManager.GetObject("ProvidesModuleVersionToString", resourceCulture)); } + } + + internal static string UnmanagedModuleVersionUnknown { + get { return (string)(ResourceManager.GetObject("UnmanagedModuleVersionUnknown", resourceCulture)); } + } + internal static string UnmanagedModuleVersionKnown { + get { return (string)(ResourceManager.GetObject("UnmanagedModuleVersionKnown", resourceCulture)); } + } + + internal static string PathUtilsNotAbsolute { + get { return (string)(ResourceManager.GetObject("PathUtilsNotAbsolute", resourceCulture)); } + } + internal static string PathUtilsNotInside { + get { return (string)(ResourceManager.GetObject("PathUtilsNotInside", resourceCulture)); } + } + internal static string PathUtilsAlreadyAbsolute { + get { return (string)(ResourceManager.GetObject("PathUtilsAlreadyAbsolute", resourceCulture)); } + } + internal static string PathUtilsNotRoot { + get { return (string)(ResourceManager.GetObject("PathUtilsNotRoot", resourceCulture)); } + } + + internal static string GameInstanceSettingUp { + get { return (string)(ResourceManager.GetObject("GameInstanceSettingUp", resourceCulture)); } + } + internal static string GameInstanceCreatingDir { + get { return (string)(ResourceManager.GetObject("GameInstanceCreatingDir", resourceCulture)); } + } + internal static string GameInstanceScanning { + get { return (string)(ResourceManager.GetObject("GameInstanceScanning", resourceCulture)); } + } + internal static string GameInstanceVersionNotFound { + get { return (string)(ResourceManager.GetObject("GameInstanceVersionNotFound", resourceCulture)); } + } + internal static string GameInstanceToString { + get { return (string)(ResourceManager.GetObject("GameInstanceToString", resourceCulture)); } + } + + internal static string GameInstanceManagerPortable { + get { return (string)(ResourceManager.GetObject("GameInstanceManagerPortable", resourceCulture)); } + } + internal static string GameInstanceManagerAuto { + get { return (string)(ResourceManager.GetObject("GameInstanceManagerAuto", resourceCulture)); } + } + internal static string GameInstanceCloneInvalid { + get { return (string)(ResourceManager.GetObject("GameInstanceCloneInvalid", resourceCulture)); } + } + internal static string GameInstanceFakeBadVersion { + get { return (string)(ResourceManager.GetObject("GameInstanceFakeBadVersion", resourceCulture)); } + } + internal static string GameInstanceFakeNotEmpty { + get { return (string)(ResourceManager.GetObject("GameInstanceFakeNotEmpty", resourceCulture)); } + } + internal static string GameInstanceFakeDLCNotAllowed { + get { return (string)(ResourceManager.GetObject("GameInstanceFakeDLCNotAllowed", resourceCulture)); } + } + internal static string GameInstanceNoValidName { + get { return (string)(ResourceManager.GetObject("GameInstanceNoValidName", resourceCulture)); } + } + internal static string GameInstanceByPathName { + get { return (string)(ResourceManager.GetObject("GameInstanceByPathName", resourceCulture)); } + } + internal static string GameInstancePathNotFound { + get { return (string)(ResourceManager.GetObject("GameInstancePathNotFound", resourceCulture)); } + } + + internal static string ModuleInstallerDownloading { + get { return (string)(ResourceManager.GetObject("ModuleInstallerDownloading", resourceCulture)); } + } + internal static string ModuleInstallerNothingToInstall { + get { return (string)(ResourceManager.GetObject("ModuleInstallerNothingToInstall", resourceCulture)); } + } + internal static string ModuleInstallerAboutToInstall { + get { return (string)(ResourceManager.GetObject("ModuleInstallerAboutToInstall", resourceCulture)); } + } + internal static string ModuleInstallerModuleCached { + get { return (string)(ResourceManager.GetObject("ModuleInstallerModuleCached", resourceCulture)); } + } + internal static string ModuleInstallerUserDeclined { + get { return (string)(ResourceManager.GetObject("ModuleInstallerUserDeclined", resourceCulture)); } + } + internal static string ModuleInstallerInstallingMod { + get { return (string)(ResourceManager.GetObject("ModuleInstallerInstallingMod", resourceCulture)); } + } + internal static string ModuleInstallerUpdatingRegistry { + get { return (string)(ResourceManager.GetObject("ModuleInstallerUpdatingRegistry", resourceCulture)); } + } + internal static string ModuleInstallerCommitting { + get { return (string)(ResourceManager.GetObject("ModuleInstallerCommitting", resourceCulture)); } + } + internal static string ModuleInstallerRescanning { + get { return (string)(ResourceManager.GetObject("ModuleInstallerRescanning", resourceCulture)); } + } + internal static string ModuleInstallerDone { + get { return (string)(ResourceManager.GetObject("ModuleInstallerDone", resourceCulture)); } + } + internal static string ModuleInstallerAlreadyInstalled { + get { return (string)(ResourceManager.GetObject("ModuleInstallerAlreadyInstalled", resourceCulture)); } + } + internal static string ModuleInstallerZIPNotInCache { + get { return (string)(ResourceManager.GetObject("ModuleInstallerZIPNotInCache", resourceCulture)); } + } + internal static string ModuleInstallerMetapackage { + get { return (string)(ResourceManager.GetObject("ModuleInstallerMetapackage", resourceCulture)); } + } + internal static string ModuleInstallerDLC { + get { return (string)(ResourceManager.GetObject("ModuleInstallerDLC", resourceCulture)); } + } + internal static string ModuleInstallerBadDLLLocation { + get { return (string)(ResourceManager.GetObject("ModuleInstallerBadDLLLocation", resourceCulture)); } + } + internal static string ModuleInstallerFileSame { + get { return (string)(ResourceManager.GetObject("ModuleInstallerFileSame", resourceCulture)); } + } + internal static string ModuleInstallerFileDifferent { + get { return (string)(ResourceManager.GetObject("ModuleInstallerFileDifferent", resourceCulture)); } + } + internal static string ModuleInstallerOverwrite { + get { return (string)(ResourceManager.GetObject("ModuleInstallerOverwrite", resourceCulture)); } + } + internal static string ModuleInstallerOverwriteCancelled { + get { return (string)(ResourceManager.GetObject("ModuleInstallerOverwriteCancelled", resourceCulture)); } + } + internal static string ModuleInstallerFileExists { + get { return (string)(ResourceManager.GetObject("ModuleInstallerFileExists", resourceCulture)); } + } + internal static string ModuleInstallerAboutToRemove { + get { return (string)(ResourceManager.GetObject("ModuleInstallerAboutToRemove", resourceCulture)); } + } + internal static string ModuleInstallerContinuePrompt { + get { return (string)(ResourceManager.GetObject("ModuleInstallerContinuePrompt", resourceCulture)); } + } + internal static string ModuleInstallerRemoveAborted { + get { return (string)(ResourceManager.GetObject("ModuleInstallerRemoveAborted", resourceCulture)); } + } + internal static string ModuleInstallerRemovingMod { + get { return (string)(ResourceManager.GetObject("ModuleInstallerRemovingMod", resourceCulture)); } + } + internal static string ModuleInstallerAboutToUpgrade { + get { return (string)(ResourceManager.GetObject("ModuleInstallerAboutToUpgrade", resourceCulture)); } + } + internal static string ModuleInstallerUpgradeInstallingUncached { + get { return (string)(ResourceManager.GetObject("ModuleInstallerUpgradeInstallingUncached", resourceCulture)); } + } + internal static string ModuleInstallerUpgradeInstallingCached { + get { return (string)(ResourceManager.GetObject("ModuleInstallerUpgradeInstallingCached", resourceCulture)); } + } + internal static string ModuleInstallerUpgradeReinstalling { + get { return (string)(ResourceManager.GetObject("ModuleInstallerUpgradeReinstalling", resourceCulture)); } + } + internal static string ModuleInstallerUpgradeDowngrading { + get { return (string)(ResourceManager.GetObject("ModuleInstallerUpgradeDowngrading", resourceCulture)); } + } + internal static string ModuleInstallerUpgradeUpgradingUncached { + get { return (string)(ResourceManager.GetObject("ModuleInstallerUpgradeUpgradingUncached", resourceCulture)); } + } + internal static string ModuleInstallerUpgradeUpgradingCached { + get { return (string)(ResourceManager.GetObject("ModuleInstallerUpgradeUpgradingCached", resourceCulture)); } + } + internal static string ModuleInstallerUpgradeUserDeclined { + get { return (string)(ResourceManager.GetObject("ModuleInstallerUpgradeUserDeclined", resourceCulture)); } + } + + internal static string ModuleInstallerReplaceAutodetected { + get { return (string)(ResourceManager.GetObject("ModuleInstallerReplaceAutodetected", resourceCulture)); } + } + internal static string ModuleInstallerReplaceNotInstalled { + get { return (string)(ResourceManager.GetObject("ModuleInstallerReplaceNotInstalled", resourceCulture)); } + } + internal static string ModuleInstallerImporting { + get { return (string)(ResourceManager.GetObject("ModuleInstallerImporting", resourceCulture)); } + } + internal static string ModuleInstallerImportAlreadyCached { + get { return (string)(ResourceManager.GetObject("ModuleInstallerImportAlreadyCached", resourceCulture)); } + } + internal static string ModuleInstallerImportingMod { + get { return (string)(ResourceManager.GetObject("ModuleInstallerImportingMod", resourceCulture)); } + } + internal static string ModuleInstallerImportNotFound { + get { return (string)(ResourceManager.GetObject("ModuleInstallerImportNotFound", resourceCulture)); } + } + internal static string ModuleInstallerImportInstallPrompt { + get { return (string)(ResourceManager.GetObject("ModuleInstallerImportInstallPrompt", resourceCulture)); } + } + internal static string ModuleInstallerImportDeletePrompt { + get { return (string)(ResourceManager.GetObject("ModuleInstallerImportDeletePrompt", resourceCulture)); } + } + + internal static string KrakenDependencyNotSatisfied { + get { return (string)(ResourceManager.GetObject("KrakenDependencyNotSatisfied", resourceCulture)); } + } + internal static string KrakenDependencyModuleNotFound { + get { return (string)(ResourceManager.GetObject("KrakenDependencyModuleNotFound", resourceCulture)); } + } + internal static string KrakenParentDependencyNotSatisfied { + get { return (string)(ResourceManager.GetObject("KrakenParentDependencyNotSatisfied", resourceCulture)); } + } + internal static string KrakenAny { + get { return (string)(ResourceManager.GetObject("KrakenAny", resourceCulture)); } + } + internal static string KrakenProvidedByMoreThanOne { + get { return (string)(ResourceManager.GetObject("KrakenProvidedByMoreThanOne", resourceCulture)); } + } + internal static string KrakenInconsistenciesHeader { + get { return (string)(ResourceManager.GetObject("KrakenInconsistenciesHeader", resourceCulture)); } + } + internal static string KrakenMissingDependency { + get { return (string)(ResourceManager.GetObject("KrakenMissingDependency", resourceCulture)); } + } + internal static string KrakenConflictsWith { + get { return (string)(ResourceManager.GetObject("KrakenConflictsWith", resourceCulture)); } + } + internal static string KrakenDownloadErrorsHeader { + get { return (string)(ResourceManager.GetObject("KrakenDownloadErrorsHeader", resourceCulture)); } + } + internal static string KrakenModuleDownloadErrorsHeader { + get { return (string)(ResourceManager.GetObject("KrakenModuleDownloadErrorsHeader", resourceCulture)); } + } + internal static string KrakenModuleDownloadError { + get { return (string)(ResourceManager.GetObject("KrakenModuleDownloadError", resourceCulture)); } + } + internal static string KrakenNotInstalled { + get { return (string)(ResourceManager.GetObject("KrakenNotInstalled", resourceCulture)); } + } + internal static string KrakenMissingCertificateUnix { + get { return (string)(ResourceManager.GetObject("KrakenMissingCertificateUnix", resourceCulture)); } + } + internal static string KrakenMissingCertificateNotUnix { + get { return (string)(ResourceManager.GetObject("KrakenMissingCertificateNotUnix", resourceCulture)); } + } + internal static string KrakenDownloadThrottled { + get { return (string)(ResourceManager.GetObject("KrakenDownloadThrottled", resourceCulture)); } + } + internal static string KrakenAlreadyRunning { + get { return (string)(ResourceManager.GetObject("KrakenAlreadyRunning", resourceCulture)); } + } + internal static string KrakenReinstallModule { + get { return (string)(ResourceManager.GetObject("KrakenReinstallModule", resourceCulture)); } + } + + internal static string RelationshipResolverConflictsWith { + get { return (string)(ResourceManager.GetObject("RelationshipResolverConflictsWith", resourceCulture)); } + } + internal static string RelationshipResolverRequiredButResolver { + get { return (string)(ResourceManager.GetObject("RelationshipResolverRequiredButResolver", resourceCulture)); } + } + internal static string RelationshipResolverRequiredButInstalled { + get { return (string)(ResourceManager.GetObject("RelationshipResolverRequiredButInstalled", resourceCulture)); } + } + internal static string RelationshipResolverAnUnmanaged { + get { return (string)(ResourceManager.GetObject("RelationshipResolverAnUnmanaged", resourceCulture)); } + } + internal static string RelationshipResolverUnmanaged { + get { return (string)(ResourceManager.GetObject("RelationshipResolverUnmanaged", resourceCulture)); } + } + internal static string RelationshipResolverModNotInList { + get { return (string)(ResourceManager.GetObject("RelationshipResolverModNotInList", resourceCulture)); } + } + internal static string RelationshipResolverInstalledReason { + get { return (string)(ResourceManager.GetObject("RelationshipResolverInstalledReason", resourceCulture)); } + } + internal static string RelationshipResolverUserReason { + get { return (string)(ResourceManager.GetObject("RelationshipResolverUserReason", resourceCulture)); } + } + internal static string RelationshipResolverNoLongerUsedReason { + get { return (string)(ResourceManager.GetObject("RelationshipResolverNoLongerUsedReason", resourceCulture)); } + } + internal static string RelationshipResolverReplacementReason { + get { return (string)(ResourceManager.GetObject("RelationshipResolverReplacementReason", resourceCulture)); } + } + internal static string RelationshipResolverSuggestedReason { + get { return (string)(ResourceManager.GetObject("RelationshipResolverSuggestedReason", resourceCulture)); } + } + internal static string RelationshipResolverDependsReason { + get { return (string)(ResourceManager.GetObject("RelationshipResolverDependsReason", resourceCulture)); } + } + internal static string RelationshipResolverRecommendedReason { + get { return (string)(ResourceManager.GetObject("RelationshipResolverRecommendedReason", resourceCulture)); } + } + + internal static string SanityCheckerUnsatisfiedDependency { + get { return (string)(ResourceManager.GetObject("SanityCheckerUnsatisfiedDependency", resourceCulture)); } + } + internal static string SanityCheckerConflictsWith { + get { return (string)(ResourceManager.GetObject("SanityCheckerConflictsWith", resourceCulture)); } + } + } +} diff --git a/Core/Properties/Resources.de-DE.resx b/Core/Properties/Resources.de-DE.resx new file mode 100644 index 0000000000..a00076a67a --- /dev/null +++ b/Core/Properties/Resources.de-DE.resx @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="RelationshipResolverUserReason" xml:space="preserve"><value>Neue Mod-Installation ausgewählt vom Nutzer</value></data> +</root> diff --git a/Core/Properties/Resources.en-US.resx b/Core/Properties/Resources.en-US.resx new file mode 100644 index 0000000000..ccb337634e --- /dev/null +++ b/Core/Properties/Resources.en-US.resx @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="CkanModuleDeserialisationError" xml:space="preserve"><value>JSON deserialization error: {0}</value></data> + <data name="LicenceInvalid" xml:space="preserve"><value>The license {0} is invalid</value></data> +</root> diff --git a/Core/Properties/Resources.fr-FR.resx b/Core/Properties/Resources.fr-FR.resx new file mode 100644 index 0000000000..3caccd36b1 --- /dev/null +++ b/Core/Properties/Resources.fr-FR.resx @@ -0,0 +1,297 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="AutoUpdateNotFetched" xml:space="preserve"><value>Nous n'avons pas encore reçu les informations de publication. Impossible de mettre à jour.</value></data> + <data name="NetDownloading" xml:space="preserve"><value>Téléchargement de {0}</value></data> + <data name="NetMissingCertFailed" xml:space="preserve"><value>Échec du téléchargement de {0}</value></data> + <data name="NetInvalidLocation" xml:space="preserve"><value>Adresse invalide dans l'en-tête d'emplacement : {0}</value></data> + <data name="NetAsyncDownloaderDownloading" xml:space="preserve"><value>Téléchargement de "{0}"</value></data> + <data name="NetAsyncDownloaderCancelled" xml:space="preserve"><value>Téléchargement annulé par l'utilisateur</value></data> + <data name="NetAsyncDownloaderProgress" xml:space="preserve"><value>{0}/sec - téléchargement en cours - {1} restant</value></data> + <data name="NetAsyncDownloaderTryingFallback" xml:space="preserve"><value>Échec du téléchargement de "{0}", essai du lien de secours "{1}"</value></data> + <data name="NetFileCacheCannotFind" xml:space="preserve"><value>Impossible de trouver le dossier du cache : {0}</value></data> + <data name="NetFileCacheZipError" xml:space="preserve"><value>Erreur à l'étape {0} pour {1} : {2}</value></data> + <data name="NetFileCacheZipTestArchiveFalse" xml:space="preserve"><value>ZipFile.TestArchive(true) a renvoyé faux</value></data> + <data name="NetFileCacheNullFileName" xml:space="preserve"><value>Nom de fichier null</value></data> + <data name="NetFileCacheMonoNotSupported" xml:space="preserve"><value>{0} + +Installez le paquet `mono-complete` ou un équivalent pour votre système d'exploitation.</value></data> + <data name="NetModuleCacheBadLength" xml:space="preserve"><value>{0} : {1} a une longueur de {2}, au lieu de {3}</value></data> + <data name="NetModuleCacheNotValidZIP" xml:space="preserve"><value>{0} : {1} n'est pas un fichier ZIP valide : {2}</value></data> + <data name="NetModuleCacheMismatchSHA1" xml:space="preserve"><value>{0} : {1} a un SHA1 de {2}, au lieu de {3}</value></data> + <data name="NetModuleCacheMismatchSHA256" xml:space="preserve"><value>{0} : {1} a un SHA256 {2}, au lieu de {3}</value></data> + <data name="NetRepoCheckingForUpdates" xml:space="preserve"><value>Recherche de mises à jour</value></data> + <data name="NetRepoAlreadyUpToDate" xml:space="preserve"><value>Déjà à jour</value></data> + <data name="NetRepoNoChanges" xml:space="preserve"><value>Aucun changement depuis la dernière mise à jour</value></data> + <data name="NetRepoUpdating" xml:space="preserve"><value>Mise à jour de {0}</value></data> + <data name="NetRepoUpdated" xml:space="preserve"><value>{0} a été mis à jour ({1} modules)</value></data> + <data name="NetRepoSaving" xml:space="preserve"><value>Sauvegarde des modules dans le registre</value></data> + <data name="NetRepoSaved" xml:space="preserve"><value>Registre mis à jour</value></data> + <data name="NetRepoUpdatedAll" xml:space="preserve"><value>Répertoire mis à jour</value></data> + <data name="NetRepoNoModules" xml:space="preserve"><value>Aucun module trouvé !</value></data> + <data name="NetRepoFailedDownload" xml:space="preserve"><value>Échec du téléchargement de {0} : {1}</value></data> + <data name="NetRepoChangedModulesReinstallPrompt" xml:space="preserve"><value>Les mods suivants ont eu leur métadonnées changées depuis la dernière mis à jour : + +{0} +Vous devriez les réinstaller pour préserver la cohérence avec le répertoire. + +Souhaitez-vous réinstaller maintenant ?</value></data> + <data name="NetRepoInconsistenciesHeader" xml:space="preserve"><value>Les incohérences suivantes ont été trouvées :</value></data> + <data name="JsonRelationshipConverterAnyOfCombined" xml:space="preserve"><value>`any_of` ne devrait pas être combiné avec `{0}`</value></data> + <data name="RegistryFileConflict" xml:space="preserve"><value>{0} souhaite installer {1}, mais ce fichier appartient à {2}</value></data> + <data name="RegistryFileNotRemoved" xml:space="preserve"><value>{0} appartient à {1} mais n'a pas été supprimé !</value></data> + <data name="RegistryManagerDirectoryNotFound" xml:space="preserve"><value>Impossible de trouver un dossier dans {0}</value></data> + <data name="RegistryManagerExportFilenamePrefix" xml:space="preserve"><value>installé</value></data> + <data name="RegistryManagerDefaultModpackAbstract" xml:space="preserve"><value>Une liste des modules installés sur l'instance KSP {0} </value></data> + <data name="CkanModuleDeserialisationError" xml:space="preserve"><value>Erreur de désérialisation JSON : {0}</value></data> + <data name="CkanModuleUnsupportedSpec" xml:space="preserve"><value>{0} nécessite CKAN {1}, impossible de le lire.</value></data> + <data name="CkanModuleMissingRequired" xml:space="preserve"><value>{0} ne possède pas le champ obligatoire {1}</value></data> + <data name="CkanModuleKspVersionMixed" xml:space="preserve"><value>ksp_version mélangé avec ksp_version_(min|max)</value></data> + <data name="CkanModuleNotAvailable" xml:space="preserve"><value>Le module {0} version {1} n'est pas disponible</value></data> + <data name="CkanModuleNotInstalledOrAvailable" xml:space="preserve"><value>Le module {0} n'est pas installé ou indisponible</value></data> + <data name="CkanModuleAllVersions" xml:space="preserve"><value>Toutes les versions</value></data> + <data name="LicenceInvalid" xml:space="preserve"><value>La licence {0} est invalide</value></data> + <data name="ModuleInstallDescriptorMustHaveInstallTo" xml:space="preserve"><value>L'instance d'installation doit avoir une instruction install_to</value></data> + <data name="ModuleInstallDescriptorRequireFileFind" xml:space="preserve"><value>L'instance d'installation doit avoir une instruction file, find, ou find_regexp</value></data> + <data name="ModuleInstallDescriptorTooManyFileFind" xml:space="preserve"><value>L'instance d'installation doit inclure une seul instruction file, find, ou find_regexp</value></data> + <data name="ModuleInstallDescriptorTooManyFilterInclude" xml:space="preserve"><value>L'instance d'installation peut contenir une instruction filter ou include_only, mais pas les deux</value></data> + <data name="ModuleInstallDescriptorInvalidInstallPath" xml:space="preserve"><value>Chemin d'installation invalide : {0}</value></data> + <data name="ModuleInstallDescriptorUnknownInstallPath" xml:space="preserve"><value>install_to inconnu : {0}</value></data> + <data name="ModuleInstallDescriptorNoFilesFound" xml:space="preserve"><value>Aucun fichier correspondant à {0} n'a été trouvé pour installer !</value></data> + <data name="ModuleInstallDescriptorAsNoPathSeparators" xml:space="preserve"><value>`as` peut ne pas inclure les séparateurs de chemin</value></data> + <data name="RelationshipDescriptorMinVersionOnly" xml:space="preserve"><value>{0} {1} ou plus récente</value></data> + <data name="RelationshipDescriptorMaxVersionOnly" xml:space="preserve"><value>{0} {1} ou plus ancienne</value></data> + <data name="RelationshipDescriptorAnyOfJoiner" xml:space="preserve"><value>{0} OU {1}</value></data> + <data name="ReleaseStatusInvalid" xml:space="preserve"><value>{0} n'est pas un statut de publication valide</value></data> + <data name="RepositoryDefaultName" xml:space="preserve"><value>défaut</value></data> + <data name="CkanModuleVersionToString" xml:space="preserve"><value>{0} alias {1}</value></data> + <data name="GameVersionYalovAny" xml:space="preserve"><value>toutes</value></data> + <data name="GameVersionSelectNeedOne" xml:space="preserve"><value>Nécessite au moins un nombre Majeur et Mineur</value></data> + <data name="GameVersionSelectHeader" xml:space="preserve"><value>La version spécifiée n'est pas unique, veuillez en choisir une :</value></data> + <data name="GameVersionSelectBuildHeader" xml:space="preserve"><value>Le numéro de build est inconnu pour ce patch. Veuillez en sélectionner un :</value></data> + <data name="GameVersionNotKnown" xml:space="preserve"><value>Cette version est inconnue de CKAN.</value></data> + <data name="GameVersionCriteriaToString" xml:space="preserve"><value>[Versions : {0}]</value></data> + <data name="GameVersionRangeMinOnly" xml:space="preserve"><value>{0} {1} ou plus ancienne</value></data> + <data name="GameVersionRangeMaxOnly" xml:space="preserve"><value>{0} {1} ou plus récente</value></data> + <data name="ProvidesModuleVersionToString" xml:space="preserve"><value>{0} (fourni par {1})</value></data> + <data name="UnmanagedModuleVersionUnknown" xml:space="preserve"><value>(non géré)</value></data> + <data name="UnmanagedModuleVersionKnown" xml:space="preserve"><value>{0} (non géré)</value></data> + <data name="PathUtilsNotAbsolute" xml:space="preserve"><value>{0} n'est pas un chemin absolu</value></data> + <data name="PathUtilsNotInside" xml:space="preserve"><value>Oh zut. {0} n'est pas dans {1}</value></data> + <data name="PathUtilsAlreadyAbsolute" xml:space="preserve"><value>{0} est déjà absolu</value></data> + <data name="PathUtilsNotRoot" xml:space="preserve"><value>{0} n'est pas une racine absolu</value></data> + <data name="GameInstanceSettingUp" xml:space="preserve"><value>Mise en place de CKAN pour la première fois...</value></data> + <data name="GameInstanceCreatingDir" xml:space="preserve"><value>Création de {0}</value></data> + <data name="GameInstanceScanning" xml:space="preserve"><value>Analyse des mods installés...</value></data> + <data name="GameInstanceVersionNotFound" xml:space="preserve"><value>Version de jeu introuvable</value></data> + <data name="GameInstanceToString" xml:space="preserve"><value>{0} Installation : {1}</value></data> + <data name="GameInstanceManagerPortable" xml:space="preserve"><value>portable</value></data> + <data name="GameInstanceManagerAuto" xml:space="preserve"><value>Auto {0}</value></data> + <data name="GameInstanceCloneInvalid" xml:space="preserve"><value>L'instance spécifiée n'est pas une instance {0} valide</value></data> + <data name="GameInstanceFakeBadVersion" xml:space="preserve"><value>La version spécifiée {0} n'est pas une version connue : {1}</value></data> + <data name="GameInstanceFakeNotEmpty" xml:space="preserve"><value>Le dossier spécifié existe déjà est n'est pas vide</value></data> + <data name="GameInstanceFakeDLCNotAllowed" xml:space="preserve"><value>{0} version {1} ou plus récent est nécessaire pour le DLC {2}</value></data> + <data name="GameInstanceNoValidName" xml:space="preserve"><value>Impossible de renvoyer un nom valide pour la nouvelle instance</value></data> + <data name="GameInstanceByPathName" xml:space="preserve"><value>personnalisé</value></data> + <data name="GameInstancePathNotFound" xml:space="preserve"><value>{0} n'existe pas</value></data> + <data name="ModuleInstallerDownloading" xml:space="preserve"><value>Téléchargement de "{0}"</value></data> + <data name="ModuleInstallerNothingToInstall" xml:space="preserve"><value>Rien à installer</value></data> + <data name="ModuleInstallerAboutToInstall" xml:space="preserve"><value>Vont être installés :</value></data> + <data name="ModuleInstallerModuleCached" xml:space="preserve"><value> * {0} {1} (en cache)</value></data> + <data name="ModuleInstallerUserDeclined" xml:space="preserve"><value>L'utilisateur a refusé la liste d'installation</value></data> + <data name="ModuleInstallerInstallingMod" xml:space="preserve"><value>Installation du mod "{0}"</value></data> + <data name="ModuleInstallerUpdatingRegistry" xml:space="preserve"><value>Mise à jour du registre</value></data> + <data name="ModuleInstallerCommitting" xml:space="preserve"><value>Validation des changements du système de fichiers</value></data> + <data name="ModuleInstallerRescanning" xml:space="preserve"><value>Nouvelle analyse de {0}</value></data> + <data name="ModuleInstallerDone" xml:space="preserve"><value>Terminé !</value></data> + <data name="ModuleInstallerAlreadyInstalled" xml:space="preserve"><value>{0} {1} déjà installé, ignoré</value></data> + <data name="ModuleInstallerZIPNotInCache" xml:space="preserve"><value>Tentative d'installation de {0}, mais il n'est pas téléchargé ou le téléchargement est corrompu</value></data> + <data name="ModuleInstallerMetapackage" xml:space="preserve"><value>Les Métapaquets ne peuvent pas être installés !</value></data> + <data name="ModuleInstallerDLC" xml:space="preserve"><value>Un DLC ne peut pas être installé !</value></data> + <data name="ModuleInstallerBadDLLLocation" xml:space="preserve"><value>Le DLL du module {0} a été trouvé à {1}, mais ce n'est pas là où CKAN l'installerait. Annulation pour éviter que plusieurs copies du même mod soient installées. Pour installer ce module, désinstallez-le manuellement puis réessayez.</value></data> + <data name="ModuleInstallerFileSame" xml:space="preserve"><value>Pareil</value></data> + <data name="ModuleInstallerFileDifferent" xml:space="preserve"><value>DIFFÉRENT</value></data> + <data name="ModuleInstallerOverwrite" xml:space="preserve"><value>Le module {0} veut remplacer les fichiers manuellement installés suivants : + +{1} + +Remplacer ?</value></data> + <data name="ModuleInstallerOverwriteCancelled" xml:space="preserve"><value>Interdiction de remplacer les fichiers manuellement installés, impossible d'installer {0}</value></data> + <data name="ModuleInstallerFileExists" xml:space="preserve"><value>Tentative d'écrire {0} mais il existe déjà</value></data> + <data name="ModuleInstallerAboutToRemove" xml:space="preserve"><value>Vont être désinstallés :</value></data> + <data name="ModuleInstallerContinuePrompt" xml:space="preserve"><value>Continuer ?</value></data> + <data name="ModuleInstallerRemoveAborted" xml:space="preserve"><value>Désinstallation du mod annulée à la demande l'utilisateur</value></data> + <data name="ModuleInstallerRemovingMod" xml:space="preserve"><value>Désinstallation de {0}...</value></data> + <data name="ModuleInstallerAboutToUpgrade" xml:space="preserve"><value>Vont être mis à jour :</value></data> + <data name="ModuleInstallerUpgradeInstallingUncached" xml:space="preserve"><value> * Installation : {0} {1} ({2}, {3})</value></data> + <data name="ModuleInstallerUpgradeInstallingCached" xml:space="preserve"><value> * Installation : {0} {1} (en cache)</value></data> + <data name="ModuleInstallerUpgradeReinstalling" xml:space="preserve"><value> * Réinstallation : {0} {1}</value></data> + <data name="ModuleInstallerUpgradeDowngrading" xml:space="preserve"><value> * Rétrogradation : {0} de {1} vers {2}</value></data> + <data name="ModuleInstallerUpgradeUpgradingUncached" xml:space="preserve"><value> * Mise à jour : {0} {1} vers {2} ({3}, {4})</value></data> + <data name="ModuleInstallerUpgradeUpgradingCached" xml:space="preserve"><value> * Mise à jour : {0} {1} vers {2} (en cache)</value></data> + <data name="ModuleInstallerUpgradeUserDeclined" xml:space="preserve"><value>L'utilisateur a refusé la liste de mise à jour</value></data> + <data name="ModuleInstallerReplaceAutodetected" xml:space="preserve"><value>Impossible de remplacer {0} car il n'a pas été installé par CKAN. +Veuillez le retirer manuellement avant d'essayer de l'installer.</value></data> + <data name="ModuleInstallerReplaceNotInstalled" xml:space="preserve"><value>Impossible de remplacer {0} car il n'est pas installé. Veuillez essayer d'installer {1} à la place.</value></data> + <data name="ModuleInstallerImporting" xml:space="preserve"><value>Importation de {0}... ({1}%)</value></data> + <data name="ModuleInstallerImportAlreadyCached" xml:space="preserve"><value>Already cached : {0}</value></data> + <data name="ModuleInstallerImportingMod" xml:space="preserve"><value>Importing {0} {1}...</value></data> + <data name="ModuleInstallerImportNotFound" xml:space="preserve"><value>Introuvable dans l'index : {0}</value></data> + <data name="ModuleInstallerImportInstallPrompt" xml:space="preserve"><value>Installer {0} les mods importés compatibles dans l'instance de jeu {1} ({2}) ?</value></data> + <data name="ModuleInstallerImportDeletePrompt" xml:space="preserve"><value>Importation terminée. Supprimer {0} vieux fichiers ?</value></data> + <data name="KrakenDependencyNotSatisfied" xml:space="preserve"><value>La dépendance sur {0} version {1} n'est pas satisfaite</value></data> + <data name="KrakenDependencyModuleNotFound" xml:space="preserve"><value>Module introuvable : {0} {1}</value></data> + <data name="KrakenParentDependencyNotSatisfied" xml:space="preserve"><value>La dépendance de {0} sur {1} version {2} n'est pas satisfaite</value></data> + <data name="KrakenAny" xml:space="preserve"><value>(any)</value></data> + <data name="KrakenProvidedByMoreThanOne" xml:space="preserve"><value>Le module {0} est fourni par plusieurs modules possibles. Veuillez en choisir un parmi les suivants :</value></data> + <data name="KrakenInconsistenciesHeader" xml:space="preserve"><value>Les incohérences suivantes ont été trouvées :</value></data> + <data name="KrakenMissingDependency" xml:space="preserve"><value>{0} n'a pas sa dépendance {1}</value></data> + <data name="KrakenConflictsWith" xml:space="preserve"><value>{0} est en conflit avec {1}</value></data> + <data name="KrakenDownloadErrorsHeader" xml:space="preserve"><value>Oh oh, Les choses suivantes se sont mal passées lors du téléchargement...</value></data> + <data name="KrakenModuleDownloadErrorsHeader" xml:space="preserve"><value>Un ou plusieurs téléchargement·s ont échoué :</value></data> + <data name="KrakenModuleDownloadError" xml:space="preserve"><value>Erreur lors du téléchargement de {0} : {1}</value></data> + <data name="KrakenNotInstalled" xml:space="preserve"><value>Le module {0} n'est pas installé !</value></data> + <data name="KrakenMissingCertificateUnix" xml:space="preserve"><value>Oh non ! Le téléchargement a échoué avec une erreur de certificat ! + +Consultez cette page pour obtenir de l'aide : +https://github.com/KSP-CKAN/CKAN/wiki/SSL-certificate-errors</value></data> + <data name="KrakenMissingCertificateNotUnix" xml:space="preserve"><value>Oh non ! Le téléchargement a échoué avec une erreur de certificat !</value></data> + <data name="KrakenDownloadThrottled" xml:space="preserve"><value>Le téléchargement depuis {0} a été bridé. +Pensez à ajouter un jeton d'authentication pour augmenter la limite avant bridage.</value></data> + <data name="KrakenAlreadyRunning" xml:space="preserve"><value>CKAN est déjà lancé pour cette instance ! + +Si vous êtes certain que ce n'est pas le cas, alors supprimez : +"{0}"</value></data> + <data name="KrakenReinstallModule" xml:space="preserve"><value>Changement de Métadonnées, réinstallation recommandée : {0}</value></data> + <data name="RelationshipResolverConflictsWith" xml:space="preserve"><value>{0} est en conflit avec {1}</value></data> + <data name="RelationshipResolverRequiredButResolver" xml:space="preserve"><value>{0} nécessaire, mais une version incompatible est dans le résolveur</value></data> + <data name="RelationshipResolverRequiredButInstalled" xml:space="preserve"><value>{0} nécessaire, mais une version incompatible est installée</value></data> + <data name="RelationshipResolverAnUnmanaged" xml:space="preserve"><value>Un DLL ou DLC non-géré</value></data> + <data name="RelationshipResolverUnmanaged" xml:space="preserve"><value>Non-géré</value></data> + <data name="RelationshipResolverModNotInList" xml:space="preserve"><value>Le mod {0} n'est pas dans la liste</value></data> + <data name="RelationshipResolverInstalledReason" xml:space="preserve"><value>Installé actuellement</value></data> + <data name="RelationshipResolverUserReason" xml:space="preserve"><value>Demandé par l'utilisateur</value></data> + <data name="RelationshipResolverNoLongerUsedReason" xml:space="preserve"><value>Auto-installé, le module qui en dépendait a été désinstallé</value></data> + <data name="RelationshipResolverReplacementReason" xml:space="preserve"><value>Remplacement de {0}</value></data> + <data name="RelationshipResolverSuggestedReason" xml:space="preserve"><value>Suggéré par {0}</value></data> + <data name="RelationshipResolverDependsReason" xml:space="preserve"><value>Pour satisfaire la dépendance de {0}</value></data> + <data name="RelationshipResolverRecommendedReason" xml:space="preserve"><value>Recommandé par {0}</value></data> + <data name="SanityCheckerUnsatisfiedDependency" xml:space="preserve"><value>{0} a une dépendance non-satisfaite : {1} n'est pas installé</value></data> + <data name="SanityCheckerConflictsWith" xml:space="preserve"><value>{0} est en conflit avec {1}</value></data> +</root> diff --git a/Core/Properties/Resources.pt-BR.resx b/Core/Properties/Resources.pt-BR.resx new file mode 100644 index 0000000000..8498c3ad09 --- /dev/null +++ b/Core/Properties/Resources.pt-BR.resx @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="RelationshipResolverUserReason" xml:space="preserve"><value>Nova instalação de mod selecionada pelo usuário</value></data> +</root> diff --git a/Core/Properties/Resources.resx b/Core/Properties/Resources.resx new file mode 100644 index 0000000000..32e0ac7ec2 --- /dev/null +++ b/Core/Properties/Resources.resx @@ -0,0 +1,297 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="AutoUpdateNotFetched" xml:space="preserve"><value>We have not fetched the release info yet. Can't update.</value></data> + <data name="NetDownloading" xml:space="preserve"><value>Downloading {0}</value></data> + <data name="NetMissingCertFailed" xml:space="preserve"><value>Failed downloading {0}</value></data> + <data name="NetInvalidLocation" xml:space="preserve"><value>Invalid URL in Location header: {0}</value></data> + <data name="NetAsyncDownloaderDownloading" xml:space="preserve"><value>Downloading "{0}"</value></data> + <data name="NetAsyncDownloaderCancelled" xml:space="preserve"><value>Download cancelled by user</value></data> + <data name="NetAsyncDownloaderProgress" xml:space="preserve"><value>{0}/sec - downloading - {1} left</value></data> + <data name="NetAsyncDownloaderTryingFallback" xml:space="preserve"><value>Failed to download "{0}", trying fallback "{1}"</value></data> + <data name="NetFileCacheCannotFind" xml:space="preserve"><value>Cannot find cache directory: {0}</value></data> + <data name="NetFileCacheZipError" xml:space="preserve"><value>Error in step {0} for {1}: {2}</value></data> + <data name="NetFileCacheZipTestArchiveFalse" xml:space="preserve"><value>ZipFile.TestArchive(true) returned false</value></data> + <data name="NetFileCacheNullFileName" xml:space="preserve"><value>Null file name</value></data> + <data name="NetFileCacheMonoNotSupported" xml:space="preserve"><value>{0} + +Install the `mono-complete` package or equivalent for your operating system.</value></data> + <data name="NetModuleCacheBadLength" xml:space="preserve"><value>{0}: {1} has length {2}, should be {3}</value></data> + <data name="NetModuleCacheNotValidZIP" xml:space="preserve"><value>{0}: {1} is not a valid ZIP file: {2}</value></data> + <data name="NetModuleCacheMismatchSHA1" xml:space="preserve"><value>{0}: {1} has SHA1 {2}, should be {3}</value></data> + <data name="NetModuleCacheMismatchSHA256" xml:space="preserve"><value>{0}: {1} has SHA256 {2}, should be {3}</value></data> + <data name="NetRepoCheckingForUpdates" xml:space="preserve"><value>Checking for updates</value></data> + <data name="NetRepoAlreadyUpToDate" xml:space="preserve"><value>Already up to date</value></data> + <data name="NetRepoNoChanges" xml:space="preserve"><value>No changes since last update</value></data> + <data name="NetRepoUpdating" xml:space="preserve"><value>Updating {0}</value></data> + <data name="NetRepoUpdated" xml:space="preserve"><value>Updated {0} ({1} modules)</value></data> + <data name="NetRepoSaving" xml:space="preserve"><value>Saving modules to registry</value></data> + <data name="NetRepoSaved" xml:space="preserve"><value>Registry saved</value></data> + <data name="NetRepoUpdatedAll" xml:space="preserve"><value>Repositories updated</value></data> + <data name="NetRepoNoModules" xml:space="preserve"><value>No modules found!</value></data> + <data name="NetRepoFailedDownload" xml:space="preserve"><value>Failed to download {0}: {1}</value></data> + <data name="NetRepoChangedModulesReinstallPrompt" xml:space="preserve"><value>The following mods have had their metadata changed since last update: + +{0} +You should reinstall them in order to preserve consistency with the repository. + +Do you wish to reinstall now?</value></data> + <data name="NetRepoInconsistenciesHeader" xml:space="preserve"><value>The following inconsistencies were found:</value></data> + <data name="JsonRelationshipConverterAnyOfCombined" xml:space="preserve"><value>`any_of` should not be combined with `{0}`</value></data> + <data name="RegistryFileConflict" xml:space="preserve"><value>{0} wishes to install {1}, but this file is registered to {2}</value></data> + <data name="RegistryFileNotRemoved" xml:space="preserve"><value>{0} is registered to {1} but has not been removed!</value></data> + <data name="RegistryManagerDirectoryNotFound" xml:space="preserve"><value>Can't find a directory in {0}</value></data> + <data name="RegistryManagerExportFilenamePrefix" xml:space="preserve"><value>installed</value></data> + <data name="RegistryManagerDefaultModpackAbstract" xml:space="preserve"><value>A list of modules installed on the {0} KSP instance</value></data> + <data name="CkanModuleDeserialisationError" xml:space="preserve"><value>JSON deserialisation error: {0}</value></data> + <data name="CkanModuleUnsupportedSpec" xml:space="preserve"><value>{0} requires CKAN {1}, we can't read it.</value></data> + <data name="CkanModuleMissingRequired" xml:space="preserve"><value>{0} missing required field {1}</value></data> + <data name="CkanModuleKspVersionMixed" xml:space="preserve"><value>ksp_version mixed with ksp_version_(min|max)</value></data> + <data name="CkanModuleNotAvailable" xml:space="preserve"><value>Module {0} version {1} not available</value></data> + <data name="CkanModuleNotInstalledOrAvailable" xml:space="preserve"><value>Module {0} not installed or available</value></data> + <data name="CkanModuleAllVersions" xml:space="preserve"><value>All versions</value></data> + <data name="LicenceInvalid" xml:space="preserve"><value>The licence {0} is invalid</value></data> + <data name="ModuleInstallDescriptorMustHaveInstallTo" xml:space="preserve"><value>Install stanzas must have an install_to</value></data> + <data name="ModuleInstallDescriptorRequireFileFind" xml:space="preserve"><value>Install stanzas require either a file, find, or find_regexp directive</value></data> + <data name="ModuleInstallDescriptorTooManyFileFind" xml:space="preserve"><value>Install stanzas must only include one of file, find, or find_regexp directive</value></data> + <data name="ModuleInstallDescriptorTooManyFilterInclude" xml:space="preserve"><value>Install stanzas can only contain filter or include_only directives, not both</value></data> + <data name="ModuleInstallDescriptorInvalidInstallPath" xml:space="preserve"><value>Invalid installation path: {0}</value></data> + <data name="ModuleInstallDescriptorUnknownInstallPath" xml:space="preserve"><value>Unknown install_to: {0}</value></data> + <data name="ModuleInstallDescriptorNoFilesFound" xml:space="preserve"><value>No files found matching {0} to install!</value></data> + <data name="ModuleInstallDescriptorAsNoPathSeparators" xml:space="preserve"><value>`as` may not include path separators</value></data> + <data name="RelationshipDescriptorMinVersionOnly" xml:space="preserve"><value>{0} {1} or later</value></data> + <data name="RelationshipDescriptorMaxVersionOnly" xml:space="preserve"><value>{0} {1} or earlier</value></data> + <data name="RelationshipDescriptorAnyOfJoiner" xml:space="preserve"><value>{0} OR {1}</value></data> + <data name="ReleaseStatusInvalid" xml:space="preserve"><value>{0} is not a valid release status</value></data> + <data name="RepositoryDefaultName" xml:space="preserve"><value>default</value></data> + <data name="CkanModuleVersionToString" xml:space="preserve"><value>{0} aka {1}</value></data> + <data name="GameVersionYalovAny" xml:space="preserve"><value>any</value></data> + <data name="GameVersionSelectNeedOne" xml:space="preserve"><value>Needs at least Major and Minor</value></data> + <data name="GameVersionSelectHeader" xml:space="preserve"><value>The specified version is not unique, please select one:</value></data> + <data name="GameVersionSelectBuildHeader" xml:space="preserve"><value>The build number is not known for this patch. Please select one:</value></data> + <data name="GameVersionNotKnown" xml:space="preserve"><value>The version is not known to CKAN.</value></data> + <data name="GameVersionCriteriaToString" xml:space="preserve"><value>[Versions: {0}]</value></data> + <data name="GameVersionRangeMinOnly" xml:space="preserve"><value>{0} {1} and earlier</value></data> + <data name="GameVersionRangeMaxOnly" xml:space="preserve"><value>{0} {1} and later</value></data> + <data name="ProvidesModuleVersionToString" xml:space="preserve"><value>{0} (provided by {1})</value></data> + <data name="UnmanagedModuleVersionUnknown" xml:space="preserve"><value>(unmanaged)</value></data> + <data name="UnmanagedModuleVersionKnown" xml:space="preserve"><value>{0} (unmanaged)</value></data> + <data name="PathUtilsNotAbsolute" xml:space="preserve"><value>{0} is not an absolute path</value></data> + <data name="PathUtilsNotInside" xml:space="preserve"><value>Oh snap. {0} isn't inside {1}</value></data> + <data name="PathUtilsAlreadyAbsolute" xml:space="preserve"><value>{0} is already absolute</value></data> + <data name="PathUtilsNotRoot" xml:space="preserve"><value>{0} isn't an absolute root</value></data> + <data name="GameInstanceSettingUp" xml:space="preserve"><value>Setting up CKAN for the first time...</value></data> + <data name="GameInstanceCreatingDir" xml:space="preserve"><value>Creating {0}</value></data> + <data name="GameInstanceScanning" xml:space="preserve"><value>Scanning for installed mods...</value></data> + <data name="GameInstanceVersionNotFound" xml:space="preserve"><value>Game version not found</value></data> + <data name="GameInstanceToString" xml:space="preserve"><value>{0} Install: {1}</value></data> + <data name="GameInstanceManagerPortable" xml:space="preserve"><value>portable</value></data> + <data name="GameInstanceManagerAuto" xml:space="preserve"><value>Auto {0}</value></data> + <data name="GameInstanceCloneInvalid" xml:space="preserve"><value>The specified instance is not a valid {0} instance</value></data> + <data name="GameInstanceFakeBadVersion" xml:space="preserve"><value>The specified {0} version is not a known version: {1}</value></data> + <data name="GameInstanceFakeNotEmpty" xml:space="preserve"><value>The specified folder already exists and is not empty</value></data> + <data name="GameInstanceFakeDLCNotAllowed" xml:space="preserve"><value>{0} version {1} or above is needed for {2} DLC</value></data> + <data name="GameInstanceNoValidName" xml:space="preserve"><value>Could not return a valid name for the new instance</value></data> + <data name="GameInstanceByPathName" xml:space="preserve"><value>custom</value></data> + <data name="GameInstancePathNotFound" xml:space="preserve"><value>{0} does not exist</value></data> + <data name="ModuleInstallerDownloading" xml:space="preserve"><value>Downloading "{0}"</value></data> + <data name="ModuleInstallerNothingToInstall" xml:space="preserve"><value>Nothing to install</value></data> + <data name="ModuleInstallerAboutToInstall" xml:space="preserve"><value>About to install:</value></data> + <data name="ModuleInstallerModuleCached" xml:space="preserve"><value> * {0} {1} (cached)</value></data> + <data name="ModuleInstallerUserDeclined" xml:space="preserve"><value>User declined install list</value></data> + <data name="ModuleInstallerInstallingMod" xml:space="preserve"><value>Installing mod "{0}"</value></data> + <data name="ModuleInstallerUpdatingRegistry" xml:space="preserve"><value>Updating registry</value></data> + <data name="ModuleInstallerCommitting" xml:space="preserve"><value>Committing filesystem changes</value></data> + <data name="ModuleInstallerRescanning" xml:space="preserve"><value>Rescanning {0}</value></data> + <data name="ModuleInstallerDone" xml:space="preserve"><value>Done!</value></data> + <data name="ModuleInstallerAlreadyInstalled" xml:space="preserve"><value>{0} {1} already installed, skipped</value></data> + <data name="ModuleInstallerZIPNotInCache" xml:space="preserve"><value>Trying to install {0}, but it's not downloaded or download is corrupted</value></data> + <data name="ModuleInstallerMetapackage" xml:space="preserve"><value>Metapackages cannot be installed!</value></data> + <data name="ModuleInstallerDLC" xml:space="preserve"><value>DLC cannot be installed!</value></data> + <data name="ModuleInstallerBadDLLLocation" xml:space="preserve"><value>DLL for module {0} found at {1}, but it's not where CKAN would install it. Aborting to prevent multiple copies of the same mod being installed. To install this module, uninstall it manually and try again.</value></data> + <data name="ModuleInstallerFileSame" xml:space="preserve"><value>same</value></data> + <data name="ModuleInstallerFileDifferent" xml:space="preserve"><value>DIFFERENT</value></data> + <data name="ModuleInstallerOverwrite" xml:space="preserve"><value>Module {0} wants to overwrite the following manually installed files: + +{1} + +Overwrite?</value></data> + <data name="ModuleInstallerOverwriteCancelled" xml:space="preserve"><value>Not overwriting manually installed files, can't install {0}</value></data> + <data name="ModuleInstallerFileExists" xml:space="preserve"><value>Trying to write {0} but it already exists</value></data> + <data name="ModuleInstallerAboutToRemove" xml:space="preserve"><value>About to remove:</value></data> + <data name="ModuleInstallerContinuePrompt" xml:space="preserve"><value>Continue?</value></data> + <data name="ModuleInstallerRemoveAborted" xml:space="preserve"><value>Mod removal aborted at user request</value></data> + <data name="ModuleInstallerRemovingMod" xml:space="preserve"><value>Removing {0}...</value></data> + <data name="ModuleInstallerAboutToUpgrade" xml:space="preserve"><value>About to upgrade:</value></data> + <data name="ModuleInstallerUpgradeInstallingUncached" xml:space="preserve"><value> * Install: {0} {1} ({2}, {3})</value></data> + <data name="ModuleInstallerUpgradeInstallingCached" xml:space="preserve"><value> * Install: {0} {1} (cached)</value></data> + <data name="ModuleInstallerUpgradeReinstalling" xml:space="preserve"><value> * Re-install: {0} {1}</value></data> + <data name="ModuleInstallerUpgradeDowngrading" xml:space="preserve"><value> * Downgrade: {0} from {1} to {2}</value></data> + <data name="ModuleInstallerUpgradeUpgradingUncached" xml:space="preserve"><value> * Upgrade: {0} {1} to {2} ({3}, {4})</value></data> + <data name="ModuleInstallerUpgradeUpgradingCached" xml:space="preserve"><value> * Upgrade: {0} {1} to {2} (cached)</value></data> + <data name="ModuleInstallerUpgradeUserDeclined" xml:space="preserve"><value>User declined upgrade list</value></data> + <data name="ModuleInstallerReplaceAutodetected" xml:space="preserve"><value>Can't replace {0} as it was not installed by CKAN. +Please remove manually before trying to install it.</value></data> + <data name="ModuleInstallerReplaceNotInstalled" xml:space="preserve"><value>Can't replace {0} as it is not installed. Please attempt to install {1} instead.</value></data> + <data name="ModuleInstallerImporting" xml:space="preserve"><value>Importing {0}... ({1}%)</value></data> + <data name="ModuleInstallerImportAlreadyCached" xml:space="preserve"><value>Already cached: {0}</value></data> + <data name="ModuleInstallerImportingMod" xml:space="preserve"><value>Importing {0} {1}...</value></data> + <data name="ModuleInstallerImportNotFound" xml:space="preserve"><value>Not found in index: {0}</value></data> + <data name="ModuleInstallerImportInstallPrompt" xml:space="preserve"><value>Install {0} compatible imported mods in game instance {1} ({2})?</value></data> + <data name="ModuleInstallerImportDeletePrompt" xml:space="preserve"><value>Import complete. Delete {0} old files?</value></data> + <data name="KrakenDependencyNotSatisfied" xml:space="preserve"><value>Dependency on {0} version {1} not satisfied</value></data> + <data name="KrakenDependencyModuleNotFound" xml:space="preserve"><value>Module not found: {0} {1}</value></data> + <data name="KrakenParentDependencyNotSatisfied" xml:space="preserve"><value>{0} dependency on {1} version {2} not satisfied</value></data> + <data name="KrakenAny" xml:space="preserve"><value>(any)</value></data> + <data name="KrakenProvidedByMoreThanOne" xml:space="preserve"><value>Module {0} is provided by more than one available module. Please choose one of the following:</value></data> + <data name="KrakenInconsistenciesHeader" xml:space="preserve"><value>The following inconsistencies were found:</value></data> + <data name="KrakenMissingDependency" xml:space="preserve"><value>{0} missing dependency {1}</value></data> + <data name="KrakenConflictsWith" xml:space="preserve"><value>{0} conflicts with {1}</value></data> + <data name="KrakenDownloadErrorsHeader" xml:space="preserve"><value>Uh oh, the following things went wrong when downloading...</value></data> + <data name="KrakenModuleDownloadErrorsHeader" xml:space="preserve"><value>One or more downloads were unsuccessful:</value></data> + <data name="KrakenModuleDownloadError" xml:space="preserve"><value>Error downloading {0}: {1}</value></data> + <data name="KrakenNotInstalled" xml:space="preserve"><value>Module {0} is not installed!</value></data> + <data name="KrakenMissingCertificateUnix" xml:space="preserve"><value>Oh no! Our download failed with a certificate error! + +Consult this page for help: +{0}</value></data> + <data name="KrakenMissingCertificateNotUnix" xml:space="preserve"><value>Oh no! Our download failed with a certificate error!</value></data> + <data name="KrakenDownloadThrottled" xml:space="preserve"><value>Download from {0} was throttled. +Consider adding an authentication token to increase the throttling limit.</value></data> + <data name="KrakenAlreadyRunning" xml:space="preserve"><value>CKAN is already running for this instance! + +If you're certain this is not the case, then delete: +"{0}"</value></data> + <data name="KrakenReinstallModule" xml:space="preserve"><value>Metadata changed, reinstallation recommended: {0}</value></data> + <data name="RelationshipResolverConflictsWith" xml:space="preserve"><value>{0} conflicts with {1}</value></data> + <data name="RelationshipResolverRequiredButResolver" xml:space="preserve"><value>{0} required, but an incompatible version is in the resolver</value></data> + <data name="RelationshipResolverRequiredButInstalled" xml:space="preserve"><value>{0} required, but an incompatible version is installed</value></data> + <data name="RelationshipResolverAnUnmanaged" xml:space="preserve"><value>an unmanaged DLL or DLC</value></data> + <data name="RelationshipResolverUnmanaged" xml:space="preserve"><value>Unmanaged</value></data> + <data name="RelationshipResolverModNotInList" xml:space="preserve"><value>Mod {0} is not in the list</value></data> + <data name="RelationshipResolverInstalledReason" xml:space="preserve"><value>Currently installed</value></data> + <data name="RelationshipResolverUserReason" xml:space="preserve"><value>Requested by user</value></data> + <data name="RelationshipResolverNoLongerUsedReason" xml:space="preserve"><value>Auto-installed, depending modules removed</value></data> + <data name="RelationshipResolverReplacementReason" xml:space="preserve"><value>Replacing {0}</value></data> + <data name="RelationshipResolverSuggestedReason" xml:space="preserve"><value>Suggested by {0}</value></data> + <data name="RelationshipResolverDependsReason" xml:space="preserve"><value>To satisfy dependency from {0}</value></data> + <data name="RelationshipResolverRecommendedReason" xml:space="preserve"><value>Recommended by {0}</value></data> + <data name="SanityCheckerUnsatisfiedDependency" xml:space="preserve"><value>{0} has an unsatisfied dependency: {1} is not installed</value></data> + <data name="SanityCheckerConflictsWith" xml:space="preserve"><value>{0} conflicts with {1}</value></data> +</root> diff --git a/Core/Properties/Resources.ru-RU.resx b/Core/Properties/Resources.ru-RU.resx new file mode 100644 index 0000000000..90557b3910 --- /dev/null +++ b/Core/Properties/Resources.ru-RU.resx @@ -0,0 +1,297 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="AutoUpdateNotFetched" xml:space="preserve"><value>Не загружена информация об обновлении.</value></data> + <data name="NetDownloading" xml:space="preserve"><value>Загрузка {0}</value></data> + <data name="NetMissingCertFailed" xml:space="preserve"><value>Не удалось загрузить {0}</value></data> + <data name="NetInvalidLocation" xml:space="preserve"><value>Неверный URL в заголовке расположения: {0}</value></data> + <data name="NetAsyncDownloaderDownloading" xml:space="preserve"><value>Загрузка «{0}»</value></data> + <data name="NetAsyncDownloaderCancelled" xml:space="preserve"><value>Загрузка отменена пользователем</value></data> + <data name="NetAsyncDownloaderProgress" xml:space="preserve"><value>{0}/сек — загружается — осталось {1}</value></data> + <data name="NetAsyncDownloaderTryingFallback" xml:space="preserve"><value>Не удалось загрузить «{0}», будет использоваться альтернативный источник "{1}"</value></data> + <data name="NetFileCacheCannotFind" xml:space="preserve"><value>Не удалось найти папку кэша: {0}</value></data> + <data name="NetFileCacheZipError" xml:space="preserve"><value>Ошибка в шаге {0} для {1}: {2}</value></data> + <data name="NetFileCacheZipTestArchiveFalse" xml:space="preserve"><value>ZipFile.TestArchive(true) вернуло false</value></data> + <data name="NetFileCacheNullFileName" xml:space="preserve"><value>Пустое имя файла</value></data> + <data name="NetFileCacheMonoNotSupported" xml:space="preserve"><value>{0} + +Установите пакет `mono-complete` или его эквивалент для вашей ОС.</value></data> + <data name="NetModuleCacheBadLength" xml:space="preserve"><value>{0}: {1} имеет длину {2}, должно быть {3}</value></data> + <data name="NetModuleCacheNotValidZIP" xml:space="preserve"><value>{0}: {1} не является корректным ZIP-файлом: {2}</value></data> + <data name="NetModuleCacheMismatchSHA1" xml:space="preserve"><value>{0}: SHA1 для {1} — {2}, должно быть {3}</value></data> + <data name="NetModuleCacheMismatchSHA256" xml:space="preserve"><value>{0}: SHA256 для {1} — {2}, должно быть {3}</value></data> + <data name="NetRepoCheckingForUpdates" xml:space="preserve"><value>Поиск обновлений</value></data> + <data name="NetRepoAlreadyUpToDate" xml:space="preserve"><value>Уже обновлено</value></data> + <data name="NetRepoNoChanges" xml:space="preserve"><value>Нет изменений с последнего обновления</value></data> + <data name="NetRepoUpdating" xml:space="preserve"><value>Обновление «{0}»</value></data> + <data name="NetRepoUpdated" xml:space="preserve"><value>Обновлён «{0}» ({1} модулей)</value></data> + <data name="NetRepoSaving" xml:space="preserve"><value>Сохранение модулей в реестр</value></data> + <data name="NetRepoSaved" xml:space="preserve"><value>Реестр сохранён</value></data> + <data name="NetRepoUpdatedAll" xml:space="preserve"><value>Репозитории обновлены</value></data> + <data name="NetRepoNoModules" xml:space="preserve"><value>Не найдено ни одного модуля!</value></data> + <data name="NetRepoFailedDownload" xml:space="preserve"><value>Не удалось загрузить «{0}»: {1}</value></data> + <data name="NetRepoChangedModulesReinstallPrompt" xml:space="preserve"><value>С последнего обновления были изменены метаданные следующих модификаций: + +{0} +Ради сохранения согласованности с репозиторием рекомендуется их переустановка. + +Хотите ли вы переустановить их сейчас?</value></data> + <data name="NetRepoInconsistenciesHeader" xml:space="preserve"><value>Найдены следующие несоответствия:</value></data> + <data name="JsonRelationshipConverterAnyOfCombined" xml:space="preserve"><value>`any_of` не должно сочетаться с `{0}`</value></data> + <data name="RegistryFileConflict" xml:space="preserve"><value>{0} желает установить {1}, который принадлежит {2}</value></data> + <data name="RegistryFileNotRemoved" xml:space="preserve"><value>{0} принадлежит {1}, но всё ещё не удалён!</value></data> + <data name="RegistryManagerDirectoryNotFound" xml:space="preserve"><value>Не удаётся найти папку в {0}</value></data> + <data name="RegistryManagerExportFilenamePrefix" xml:space="preserve"><value>установленные</value></data> + <data name="RegistryManagerDefaultModpackAbstract" xml:space="preserve"><value>Список модулей, установленных в сборке «{0}»</value></data> + <data name="CkanModuleDeserialisationError" xml:space="preserve"><value>Ошибка десериализации JSON: {0}</value></data> + <data name="CkanModuleUnsupportedSpec" xml:space="preserve"><value>{0} требует CKAN {1}, не удаётся прочитать.</value></data> + <data name="CkanModuleMissingRequired" xml:space="preserve"><value>В {0} не заполнено требуемое поле {1}</value></data> + <data name="CkanModuleKspVersionMixed" xml:space="preserve"><value>ksp_version используется вместе с ksp_version_(min|max)</value></data> + <data name="CkanModuleNotAvailable" xml:space="preserve"><value>Версия {1} модуля «{0}» недоступна</value></data> + <data name="CkanModuleNotInstalledOrAvailable" xml:space="preserve"><value>Модуль «{0}» не установлен или недоступен</value></data> + <data name="CkanModuleAllVersions" xml:space="preserve"><value>Все версии</value></data> + <data name="LicenceInvalid" xml:space="preserve"><value>Лицензия на {0} не является подлинной</value></data> + <data name="ModuleInstallDescriptorMustHaveInstallTo" xml:space="preserve"><value>Установочные записи должны включать в себя install_to</value></data> + <data name="ModuleInstallDescriptorRequireFileFind" xml:space="preserve"><value>Установочные записи должны включать в себя инструкцию file, find или find_regexp</value></data> + <data name="ModuleInstallDescriptorTooManyFileFind" xml:space="preserve"><value>Установочные записи должны включать в себя только одну из инструкций file, find или find_regexp</value></data> + <data name="ModuleInstallDescriptorTooManyFilterInclude" xml:space="preserve"><value>Установочные записи должны включать в себя только инструкцию filter либо include_only directives</value></data> + <data name="ModuleInstallDescriptorInvalidInstallPath" xml:space="preserve"><value>Неверный путь установки: {0}</value></data> + <data name="ModuleInstallDescriptorUnknownInstallPath" xml:space="preserve"><value>Не найдена install_to: {0}</value></data> + <data name="ModuleInstallDescriptorNoFilesFound" xml:space="preserve"><value>Не найдено файлов для установки, совпадающих с {0}!</value></data> + <data name="ModuleInstallDescriptorAsNoPathSeparators" xml:space="preserve"><value>`as` не может включать разделители пути</value></data> + <data name="RelationshipDescriptorMinVersionOnly" xml:space="preserve"><value>{0} {1} или позднее</value></data> + <data name="RelationshipDescriptorMaxVersionOnly" xml:space="preserve"><value>{0} {1} или ранее</value></data> + <data name="RelationshipDescriptorAnyOfJoiner" xml:space="preserve"><value>{0} ИЛИ {1}</value></data> + <data name="ReleaseStatusInvalid" xml:space="preserve"><value>{0} не является корректным статусом</value></data> + <data name="RepositoryDefaultName" xml:space="preserve"><value>стандартный</value></data> + <data name="CkanModuleVersionToString" xml:space="preserve"><value>{0} или {1}</value></data> + <data name="GameVersionYalovAny" xml:space="preserve"><value>любая</value></data> + <data name="GameVersionSelectNeedOne" xml:space="preserve"><value>Нужно указать как минимум наибольшую или наименьшую версию</value></data> + <data name="GameVersionSelectHeader" xml:space="preserve"><value>Указанная версия не является единственной, выберите подходящую:</value></data> + <data name="GameVersionSelectBuildHeader" xml:space="preserve"><value>Номер сборки не соответствует данной версии, выберите подходящий:</value></data> + <data name="GameVersionNotKnown" xml:space="preserve"><value>Версия не известна CKAN.</value></data> + <data name="GameVersionCriteriaToString" xml:space="preserve"><value>[Версии: {0}]</value></data> + <data name="GameVersionRangeMinOnly" xml:space="preserve"><value>{0} {1} и ранее</value></data> + <data name="GameVersionRangeMaxOnly" xml:space="preserve"><value>{0} {1} и позднее</value></data> + <data name="ProvidesModuleVersionToString" xml:space="preserve"><value>{0} (предоставлено {1})</value></data> + <data name="UnmanagedModuleVersionUnknown" xml:space="preserve"><value>(не управляется)</value></data> + <data name="UnmanagedModuleVersionKnown" xml:space="preserve"><value>{0} (не управляется)</value></data> + <data name="PathUtilsNotAbsolute" xml:space="preserve"><value>{0} не является абсолютным путём</value></data> + <data name="PathUtilsNotInside" xml:space="preserve"><value>Ой! {0} не находится внутри {1}</value></data> + <data name="PathUtilsAlreadyAbsolute" xml:space="preserve"><value>Путь {0} уже является абсолютным</value></data> + <data name="PathUtilsNotRoot" xml:space="preserve"><value>{0} не является абсолютным корнем</value></data> + <data name="GameInstanceSettingUp" xml:space="preserve"><value>Первичная настройка CKAN...</value></data> + <data name="GameInstanceCreatingDir" xml:space="preserve"><value>Создание {0}</value></data> + <data name="GameInstanceScanning" xml:space="preserve"><value>Поиск установленных модификаций...</value></data> + <data name="GameInstanceVersionNotFound" xml:space="preserve"><value>Не найдена сборка игры</value></data> + <data name="GameInstanceToString" xml:space="preserve"><value>{0} Установка: {1}</value></data> + <data name="GameInstanceManagerPortable" xml:space="preserve"><value>портативная</value></data> + <data name="GameInstanceManagerAuto" xml:space="preserve"><value>Авто {0}</value></data> + <data name="GameInstanceCloneInvalid" xml:space="preserve"><value>Указанная сборка не является корректной сборкой {0}</value></data> + <data name="GameInstanceFakeBadVersion" xml:space="preserve"><value>Указанная версия {0} не является известной версией: {1}</value></data> + <data name="GameInstanceFakeNotEmpty" xml:space="preserve"><value>Указанная папка уже существует и не является пустой</value></data> + <data name="GameInstanceFakeDLCNotAllowed" xml:space="preserve"><value>Для DLC «{2}» необходим {0} версии {1} или выше</value></data> + <data name="GameInstanceNoValidName" xml:space="preserve"><value>Не удалось вернуть корректное имя для новой сборки</value></data> + <data name="GameInstanceByPathName" xml:space="preserve"><value>своя</value></data> + <data name="GameInstancePathNotFound" xml:space="preserve"><value>{0} не существует</value></data> + <data name="ModuleInstallerDownloading" xml:space="preserve"><value>Загружается «{0}»</value></data> + <data name="ModuleInstallerNothingToInstall" xml:space="preserve"><value>Нечего устанавливать</value></data> + <data name="ModuleInstallerAboutToInstall" xml:space="preserve"><value>Будут установлены:</value></data> + <data name="ModuleInstallerModuleCached" xml:space="preserve"><value> * {0} {1} (кэшировано)</value></data> + <data name="ModuleInstallerUserDeclined" xml:space="preserve"><value>Пользователь отклонил установку</value></data> + <data name="ModuleInstallerInstallingMod" xml:space="preserve"><value>Установка модификации «{0}»</value></data> + <data name="ModuleInstallerUpdatingRegistry" xml:space="preserve"><value>Обновление реестра</value></data> + <data name="ModuleInstallerCommitting" xml:space="preserve"><value>Осуществление изменений файловой системы</value></data> + <data name="ModuleInstallerRescanning" xml:space="preserve"><value>Повторный поиск {0}</value></data> + <data name="ModuleInstallerDone" xml:space="preserve"><value>Готово!</value></data> + <data name="ModuleInstallerAlreadyInstalled" xml:space="preserve"><value>{0} {1} уже установлен, пропуск</value></data> + <data name="ModuleInstallerZIPNotInCache" xml:space="preserve"><value>Попытка установить {0}, но она не была загружена или оказалась повреждена</value></data> + <data name="ModuleInstallerMetapackage" xml:space="preserve"><value>Метапакеты не могут быть установлены!</value></data> + <data name="ModuleInstallerDLC" xml:space="preserve"><value>DLC не могут быть установлены!</value></data> + <data name="ModuleInstallerBadDLLLocation" xml:space="preserve"><value>DLL для модуля «{0}» найдена в {1}, но не там, где её бы установил CKAN. Во избежание установки нескольких копий модификации операция отменена. Вручную удалите модуль и попробуйте снова.</value></data> + <data name="ModuleInstallerFileSame" xml:space="preserve"><value>тот же</value></data> + <data name="ModuleInstallerFileDifferent" xml:space="preserve"><value>ДРУГОЙ</value></data> + <data name="ModuleInstallerOverwrite" xml:space="preserve"><value>Модуль «{0}» желает перезаписать следующие файлы, установленные вручную: + +{1} + +Перезаписать?</value></data> + <data name="ModuleInstallerOverwriteCancelled" xml:space="preserve"><value>Установленные вручную файлы не перезаписаны, установка невозможна {0}</value></data> + <data name="ModuleInstallerFileExists" xml:space="preserve"><value>Совершена попытка записать {0}, но файл уже существует</value></data> + <data name="ModuleInstallerAboutToRemove" xml:space="preserve"><value>Будут удалены:</value></data> + <data name="ModuleInstallerContinuePrompt" xml:space="preserve"><value>Продолжить?</value></data> + <data name="ModuleInstallerRemoveAborted" xml:space="preserve"><value>Пользователь отменил удаление</value></data> + <data name="ModuleInstallerRemovingMod" xml:space="preserve"><value>Удаление {0}...</value></data> + <data name="ModuleInstallerAboutToUpgrade" xml:space="preserve"><value>Будут обновлены:</value></data> + <data name="ModuleInstallerUpgradeInstallingUncached" xml:space="preserve"><value> * Установка: {0} {1} ({2}, {3})</value></data> + <data name="ModuleInstallerUpgradeInstallingCached" xml:space="preserve"><value> * Установка: {0} {1} (кэшировано)</value></data> + <data name="ModuleInstallerUpgradeReinstalling" xml:space="preserve"><value> * Переустановка: {0} {1}</value></data> + <data name="ModuleInstallerUpgradeDowngrading" xml:space="preserve"><value> * Откат: {0} от {1} к {2}</value></data> + <data name="ModuleInstallerUpgradeUpgradingUncached" xml:space="preserve"><value> * Обновление: {0} {1} до {2} ({3}, {4})</value></data> + <data name="ModuleInstallerUpgradeUpgradingCached" xml:space="preserve"><value> * Обновление: {0} {1} до {2} (кэшировано)</value></data> + <data name="ModuleInstallerUpgradeUserDeclined" xml:space="preserve"><value>Пользователь отменил список обновления</value></data> + <data name="ModuleInstallerReplaceAutodetected" xml:space="preserve"><value>Невозможно заменить {0}, так как он не был установлен CKAN. +Удалите его вручную и попробуйте снова.</value></data> + <data name="ModuleInstallerReplaceNotInstalled" xml:space="preserve"><value>Невозможно заменить {0}, так как он не установлен. Сначала установите {1}.</value></data> + <data name="ModuleInstallerImporting" xml:space="preserve"><value>Импорт {0}... ({1}%)</value></data> + <data name="ModuleInstallerImportAlreadyCached" xml:space="preserve"><value>Уже кэшировано: {0}</value></data> + <data name="ModuleInstallerImportingMod" xml:space="preserve"><value>Импорт {0} {1}...</value></data> + <data name="ModuleInstallerImportNotFound" xml:space="preserve"><value>Не найдено в указателе: {0}</value></data> + <data name="ModuleInstallerImportInstallPrompt" xml:space="preserve"><value>Установить {0} совместимых импортированных модификаций в сборку игры {1} ({2})?</value></data> + <data name="ModuleInstallerImportDeletePrompt" xml:space="preserve"><value>Импортирование завершено. Удалить {0} старых файлов?</value></data> + <data name="KrakenDependencyNotSatisfied" xml:space="preserve"><value>Зависимость от {0} версии {1} не удовлетворена</value></data> + <data name="KrakenDependencyModuleNotFound" xml:space="preserve"><value>Модуль не найден: {0} {1}</value></data> + <data name="KrakenParentDependencyNotSatisfied" xml:space="preserve"><value>Зависимость {0} от {1} версии {2} не удовлетворена</value></data> + <data name="KrakenAny" xml:space="preserve"><value>(любая)</value></data> + <data name="KrakenProvidedByMoreThanOne" xml:space="preserve"><value>Модуль «{0}» предоставлен несколькими модулями. Выберите один из них:</value></data> + <data name="KrakenInconsistenciesHeader" xml:space="preserve"><value>Были найдены следующие несоответствия:</value></data> + <data name="KrakenMissingDependency" xml:space="preserve"><value>{0}: отсутствует зависимость {1}</value></data> + <data name="KrakenConflictsWith" xml:space="preserve"><value>{0} конфликтует с {1}</value></data> + <data name="KrakenDownloadErrorsHeader" xml:space="preserve"><value>Ой, при загрузке произошли следующие проблемы...</value></data> + <data name="KrakenModuleDownloadErrorsHeader" xml:space="preserve"><value>Одна или несколько загрузок завершились неудачно:</value></data> + <data name="KrakenModuleDownloadError" xml:space="preserve"><value>Ошибка загрузки {0}: {1}</value></data> + <data name="KrakenNotInstalled" xml:space="preserve"><value>Модуль «{0}» не установлен!</value></data> + <data name="KrakenMissingCertificateUnix" xml:space="preserve"><value>О нет! Загрузка не завершена из-за ошибки сертификата! + +Посетите эту страницу для получения справки: +https://github.com/KSP-CKAN/CKAN/wiki/SSL-certificate-errors</value></data> + <data name="KrakenMissingCertificateNotUnix" xml:space="preserve"><value>О нет! Загрузка не завершена из-за ошибки сертификата!</value></data> + <data name="KrakenDownloadThrottled" xml:space="preserve"><value>Загрузка из {0} была ограничена. +Для увеличения квоты добавьте токен аутентификации.</value></data> + <data name="KrakenAlreadyRunning" xml:space="preserve"><value>CKAN уже запущен для этой сборки! + +Если вы уверены, что это не так, удалите: +"{0}"</value></data> + <data name="KrakenReinstallModule" xml:space="preserve"><value>Метаданные изменены, рекомендуется переустановка: {0}</value></data> + <data name="RelationshipResolverConflictsWith" xml:space="preserve"><value>{0} конфликтует с {1}</value></data> + <data name="RelationshipResolverRequiredButResolver" xml:space="preserve"><value>Необходима {0}, но в ресольвере несовместимая версия</value></data> + <data name="RelationshipResolverRequiredButInstalled" xml:space="preserve"><value>Необходима {0}, но установлена несовместимая версия</value></data> + <data name="RelationshipResolverAnUnmanaged" xml:space="preserve"><value>неуправляемая DLL или DLC</value></data> + <data name="RelationshipResolverUnmanaged" xml:space="preserve"><value>Не управляется</value></data> + <data name="RelationshipResolverModNotInList" xml:space="preserve"><value>Модификация «{0}» не в списке</value></data> + <data name="RelationshipResolverInstalledReason" xml:space="preserve"><value>Установлено в данный момент</value></data> + <data name="RelationshipResolverUserReason" xml:space="preserve"><value>Запрошено пользователем</value></data> + <data name="RelationshipResolverNoLongerUsedReason" xml:space="preserve"><value>Установлено автоматически, зависящие модули удалены</value></data> + <data name="RelationshipResolverReplacementReason" xml:space="preserve"><value>Заменяет {0}</value></data> + <data name="RelationshipResolverSuggestedReason" xml:space="preserve"><value>Предложено {0}</value></data> + <data name="RelationshipResolverDependsReason" xml:space="preserve"><value>Для удовлетворения зависимости {0}</value></data> + <data name="RelationshipResolverRecommendedReason" xml:space="preserve"><value>Рекомендуется {0}</value></data> + <data name="SanityCheckerUnsatisfiedDependency" xml:space="preserve"><value>{0} имеет неудовлетворённую зависимость: {1} не установлен</value></data> + <data name="SanityCheckerConflictsWith" xml:space="preserve"><value>{0} конфликтует с {1}</value></data> +</root> diff --git a/Core/Properties/Resources.zh-CN.resx b/Core/Properties/Resources.zh-CN.resx new file mode 100644 index 0000000000..d0a23003e7 --- /dev/null +++ b/Core/Properties/Resources.zh-CN.resx @@ -0,0 +1,296 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="AutoUpdateNotFetched" xml:space="preserve"><value>未能拉取到发布信息。无法更新。</value></data> + <data name="NetDownloading" xml:space="preserve"><value>正在下载 {0} </value></data> + <data name="NetMissingCertFailed" xml:space="preserve"><value>下载 {0} 失败</value></data> + <data name="NetInvalidLocation" xml:space="preserve"><value>Location Header含有无效URL: {0}</value></data> + <data name="NetAsyncDownloaderDownloading" xml:space="preserve"><value>正在下载 "{0}" </value></data> + <data name="NetAsyncDownloaderCancelled" xml:space="preserve"><value>用户取消下载</value></data> + <data name="NetAsyncDownloaderProgress" xml:space="preserve"><value>{0}/s - 下载中 - 剩余 {1} </value></data> + <data name="NetAsyncDownloaderTryingFallback" xml:space="preserve"><value>下载 "{0}" 失败,尝试回滚到 "{1}"</value></data> + <data name="NetFileCacheCannotFind" xml:space="preserve"><value>无法找到缓存目录: {0}</value></data> + <data name="NetFileCacheZipError" xml:space="preserve"><value>在 {1} 的步骤 {0} 出现错误: {2}</value></data> + <data name="NetFileCacheZipTestArchiveFalse" xml:space="preserve"><value>ZipFile.TestArchive(true) 返回了 false</value></data> + <data name="NetFileCacheNullFileName" xml:space="preserve"><value>空文件名</value></data> + <data name="NetFileCacheMonoNotSupported" xml:space="preserve"><value>{0} + +请在您的操作系统安装 `mono-complete` 或其它等效应用。</value></data> + <data name="NetModuleCacheBadLength" xml:space="preserve"><value>{0}: {1} 的长度为 {2},但应该为 {3}</value></data> + <data name="NetModuleCacheNotValidZIP" xml:space="preserve"><value>{0}: {1} 并不是一个有效的 ZIP 文件: {2}</value></data> + <data name="NetModuleCacheMismatchSHA1" xml:space="preserve"><value>{0}: {1} 的 SHA1 值为 {2},但应该为 {3}</value></data> + <data name="NetModuleCacheMismatchSHA256" xml:space="preserve"><value>{0}: {1} 的 SHA256 值为 {2},但应该为 {3}</value></data> + <data name="NetRepoCheckingForUpdates" xml:space="preserve"><value>检查更新中</value></data> + <data name="NetRepoAlreadyUpToDate" xml:space="preserve"><value>已是最新版本</value></data> + <data name="NetRepoNoChanges" xml:space="preserve"><value>自上次更新以来无更改</value></data> + <data name="NetRepoUpdating" xml:space="preserve"><value>正在更新 {0}</value></data> + <data name="NetRepoUpdated" xml:space="preserve"><value>已更新 {0} ({1} 个模组)</value></data> + <data name="NetRepoSaving" xml:space="preserve"><value>保存模组到注册表中</value></data> + <data name="NetRepoSaved" xml:space="preserve"><value>注册表已保存</value></data> + <data name="NetRepoUpdatedAll" xml:space="preserve"><value>数据库已更新</value></data> + <data name="NetRepoNoModules" xml:space="preserve"><value>没有找到模组!</value></data> + <data name="NetRepoFailedDownload" xml:space="preserve"><value>下载 {0} 失败: {1}</value></data> + <data name="NetRepoChangedModulesReinstallPrompt" xml:space="preserve"><value>以下模组自上次更新后更改了它们的元数据: + +{0} +您应该重新安装它们以保持与数据库的一致性。 + +您想要现在重新安装吗?</value></data> + <data name="NetRepoInconsistenciesHeader" xml:space="preserve"><value>发现以下冲突:</value></data> + <data name="JsonRelationshipConverterAnyOfCombined" xml:space="preserve"><value>`any_of` 不应该与 `{0}` 结合使用</value></data> + <data name="RegistryFileConflict" xml:space="preserve"><value>{0} 想要安装 {1},但该文件已被 {2} 注册</value></data> + <data name="RegistryFileNotRemoved" xml:space="preserve"><value>{0} 已被 {1} 注册但还未被删除!</value></data> + <data name="RegistryManagerDirectoryNotFound" xml:space="preserve"><value>无法在 {0} 找到目录</value></data> + <data name="RegistryManagerExportFilenamePrefix" xml:space="preserve"><value>已安装</value></data> + <data name="RegistryManagerDefaultModpackAbstract" xml:space="preserve"><value>已安装在 KSP 实例 {0} 的模组列表</value></data> + <data name="CkanModuleDeserialisationError" xml:space="preserve"><value>JSON 反序列化错误: {0}</value></data> + <data name="CkanModuleUnsupportedSpec" xml:space="preserve"><value>{0} 需要 CKAN {1},我们无法读取它.</value></data> + <data name="CkanModuleMissingRequired" xml:space="preserve"><value>{0} 缺少需要的 field {1}</value></data> + <data name="CkanModuleKspVersionMixed" xml:space="preserve"><value>ksp_version 不能与 ksp_version_(min|max) 混用</value></data> + <data name="CkanModuleNotAvailable" xml:space="preserve"><value>模组 {0} 的版本 {1} 不可用</value></data> + <data name="CkanModuleNotInstalledOrAvailable" xml:space="preserve"><value>模组 {0} 未安装或不可用</value></data> + <data name="CkanModuleAllVersions" xml:space="preserve"><value>所有版本</value></data> + <data name="LicenceInvalid" xml:space="preserve"><value>许可 {0} 是无效的</value></data> + <data name="ModuleInstallDescriptorMustHaveInstallTo" xml:space="preserve"><value>Install 句法必须含有一个 install_to</value></data> + <data name="ModuleInstallDescriptorRequireFileFind" xml:space="preserve"><value>Install 句法必须含有 file, find, 或者 find_regexp 指令中的一个</value></data> + <data name="ModuleInstallDescriptorTooManyFileFind" xml:space="preserve"><value>Install 句法只能含有 file, find, 或者 find_regexp 指令中的一个</value></data> + <data name="ModuleInstallDescriptorTooManyFilterInclude" xml:space="preserve"><value>Install 句法只能含有 filter 或者 include_only 指令中的一个,而不是两个</value></data> + <data name="ModuleInstallDescriptorInvalidInstallPath" xml:space="preserve"><value>无效安装路径: {0}</value></data> + <data name="ModuleInstallDescriptorUnknownInstallPath" xml:space="preserve"><value>未知的 install_to: {0}</value></data> + <data name="ModuleInstallDescriptorNoFilesFound" xml:space="preserve"><value>没有找到匹配 {0} 的文件来安装!</value></data> + <data name="ModuleInstallDescriptorAsNoPathSeparators" xml:space="preserve"><value>`as` 不能含有路径分隔符</value></data> + <data name="RelationshipDescriptorMinVersionOnly" xml:space="preserve"><value>{0} {1} 或更新版本</value></data> + <data name="RelationshipDescriptorMaxVersionOnly" xml:space="preserve"><value>{0} {1} 或更旧版本</value></data> + <data name="RelationshipDescriptorAnyOfJoiner" xml:space="preserve"><value>{0} 或 {1}</value></data> + <data name="ReleaseStatusInvalid" xml:space="preserve"><value>{0} 不是有效的发布状态</value></data> + <data name="RepositoryDefaultName" xml:space="preserve"><value>默认数据库</value></data> + <data name="CkanModuleVersionToString" xml:space="preserve"><value>{0} aka {1}</value></data> + <data name="GameVersionYalovAny" xml:space="preserve"><value>任意版本</value></data> + <data name="GameVersionSelectNeedOne" xml:space="preserve"><value>需要 Major 和 Minor 中的至少一个</value></data> + <data name="GameVersionSelectHeader" xml:space="preserve"><value>选中的版本并不是独立的,请选择一个版本:</value></data> + <data name="GameVersionSelectBuildHeader" xml:space="preserve"><value>未在该版本中发现该 Build 版本号. 请选择一个 Build 版本:</value></data> + <data name="GameVersionNotKnown" xml:space="preserve"><value>CKAN 无法识别该版本</value></data> + <data name="GameVersionCriteriaToString" xml:space="preserve"><value>[版本: {0}]</value></data> + <data name="GameVersionRangeMinOnly" xml:space="preserve"><value>{0} {1} 及更旧版本</value></data> + <data name="GameVersionRangeMaxOnly" xml:space="preserve"><value>{0} {1} 及更新版本</value></data> + <data name="ProvidesModuleVersionToString" xml:space="preserve"><value>{0} (由 {1} 提供)</value></data> + <data name="UnmanagedModuleVersionUnknown" xml:space="preserve"><value>(未管理)</value></data> + <data name="UnmanagedModuleVersionKnown" xml:space="preserve"><value>{0} (未管理)</value></data> + <data name="PathUtilsNotAbsolute" xml:space="preserve"><value>{0} 并不是一个绝对路径</value></data> + <data name="PathUtilsNotInside" xml:space="preserve"><value> {0} 不在 {1} 中</value></data> + <data name="PathUtilsAlreadyAbsolute" xml:space="preserve"><value>{0} 已经是绝对路径</value></data> + <data name="PathUtilsNotRoot" xml:space="preserve"><value>{0} 不是绝对根路径</value></data> + <data name="GameInstanceSettingUp" xml:space="preserve"><value>首次配置 CKAN 中...</value></data> + <data name="GameInstanceCreatingDir" xml:space="preserve"><value>正在创建 {0}</value></data> + <data name="GameInstanceScanning" xml:space="preserve"><value>扫描已安装的模组中...</value></data> + <data name="GameInstanceVersionNotFound" xml:space="preserve"><value>未找到游戏版本</value></data> + <data name="GameInstanceToString" xml:space="preserve"><value>{0} 安装: {1}</value></data> + <data name="GameInstanceManagerPortable" xml:space="preserve"><value>可移动</value></data> + <data name="GameInstanceManagerAuto" xml:space="preserve"><value>自动 {0}</value></data> + <data name="GameInstanceCloneInvalid" xml:space="preserve"><value>所选实例并非有效的 {0} 实例</value></data> + <data name="GameInstanceFakeBadVersion" xml:space="preserve"><value>选中的 {0} 版本并非已知版本: {1}</value></data> + <data name="GameInstanceFakeNotEmpty" xml:space="preserve"><value>选中的文件夹已经存在且不是空文件夹</value></data> + <data name="GameInstanceFakeDLCNotAllowed" xml:space="preserve"><value>{0} 版本 {1} 或以上需要 {2} DLC</value></data> + <data name="GameInstanceNoValidName" xml:space="preserve"><value>无法为新实例返回有效的名称</value></data> + <data name="GameInstanceByPathName" xml:space="preserve"><value>自定义</value></data> + <data name="GameInstancePathNotFound" xml:space="preserve"><value>{0} 不存在</value></data> + <data name="ModuleInstallerDownloading" xml:space="preserve"><value>正在下载 "{0}"</value></data> + <data name="ModuleInstallerNothingToInstall" xml:space="preserve"><value>没有需要安装的</value></data> + <data name="ModuleInstallerAboutToInstall" xml:space="preserve"><value>中止安装:</value></data> + <data name="ModuleInstallerModuleCached" xml:space="preserve"><value> * {0} {1} (已缓存)</value></data> + <data name="ModuleInstallerUserDeclined" xml:space="preserve"><value>用户取消安装列表</value></data> + <data name="ModuleInstallerInstallingMod" xml:space="preserve"><value>安装模组 "{0}"</value></data> + <data name="ModuleInstallerUpdatingRegistry" xml:space="preserve"><value>正在更新注册表</value></data> + <data name="ModuleInstallerCommitting" xml:space="preserve"><value>正在提交文件系统更改</value></data> + <data name="ModuleInstallerRescanning" xml:space="preserve"><value>重新扫描 {0}</value></data> + <data name="ModuleInstallerDone" xml:space="preserve"><value>完成!</value></data> + <data name="ModuleInstallerAlreadyInstalled" xml:space="preserve"><value>{0} {1} 已经安装,跳过</value></data> + <data name="ModuleInstallerZIPNotInCache" xml:space="preserve"><value>尝试安装 {0},但它没有被下载或下载被中断了</value></data> + <data name="ModuleInstallerMetapackage" xml:space="preserve"><value>元安装包无法安装!</value></data> + <data name="ModuleInstallerDLC" xml:space="preserve"><value>DLC 无法安装!</value></data> + <data name="ModuleInstallerBadDLLLocation" xml:space="preserve"><value>在 {1} 发现了模组 {0} 的 DLL 文件 ,但 CKAN 无法在该位置安装它。正在中止安装以避免安装多个重复的模组。请手动卸载该模组并重试以安装它。</value></data> + <data name="ModuleInstallerFileSame" xml:space="preserve"><value>相同</value></data> + <data name="ModuleInstallerFileDifferent" xml:space="preserve"><value>不相同</value></data> + <data name="ModuleInstallerOverwrite" xml:space="preserve"><value>模组 {0} 想要覆盖以下手动安装文件: + +{1} + +覆盖吗?</value></data> + <data name="ModuleInstallerOverwriteCancelled" xml:space="preserve"><value>取消覆盖手动安装文件,无法安装 {0}</value></data> + <data name="ModuleInstallerFileExists" xml:space="preserve"><value>尝试写入 {0} 但它已经存在</value></data> + <data name="ModuleInstallerAboutToRemove" xml:space="preserve"><value>中止删除:</value></data> + <data name="ModuleInstallerContinuePrompt" xml:space="preserve"><value>继续?</value></data> + <data name="ModuleInstallerRemoveAborted" xml:space="preserve"><value>用户请求中止删除模组</value></data> + <data name="ModuleInstallerRemovingMod" xml:space="preserve"><value>正在删除 {0}...</value></data> + <data name="ModuleInstallerAboutToUpgrade" xml:space="preserve"><value>中止升级:</value></data> + <data name="ModuleInstallerUpgradeInstallingUncached" xml:space="preserve"><value> * 安装: {0} {1} ({2},{3})</value></data> + <data name="ModuleInstallerUpgradeInstallingCached" xml:space="preserve"><value> * 安装: {0} {1} (已缓存)</value></data> + <data name="ModuleInstallerUpgradeReinstalling" xml:space="preserve"><value> * 重新安装: {0} {1}</value></data> + <data name="ModuleInstallerUpgradeDowngrading" xml:space="preserve"><value> * 降级: {0} 从 {1} 到 {2}</value></data> + <data name="ModuleInstallerUpgradeUpgradingUncached" xml:space="preserve"><value> * 升级: {0} {1} 到 {2} ({3},{4})</value></data> + <data name="ModuleInstallerUpgradeUpgradingCached" xml:space="preserve"><value> * 升级: {0} {1} 到 {2} (已缓存)</value></data> + <data name="ModuleInstallerUpgradeUserDeclined" xml:space="preserve"><value>用户取消升级列表</value></data> + <data name="ModuleInstallerReplaceAutodetected" xml:space="preserve"><value>无法替换 {0} 因为它并不是由 CKAN 安装的。请在尝试安装前手动删除它。</value></data> + <data name="ModuleInstallerReplaceNotInstalled" xml:space="preserve"><value>无法替换 {0} 因为它还未安装。请尝试安装 {1}。</value></data> + <data name="ModuleInstallerImporting" xml:space="preserve"><value>导入 {0}... ({1}%)</value></data> + <data name="ModuleInstallerImportAlreadyCached" xml:space="preserve"><value>已缓存: {0}</value></data> + <data name="ModuleInstallerImportingMod" xml:space="preserve"><value>导入 {0} {1}...</value></data> + <data name="ModuleInstallerImportNotFound" xml:space="preserve"><value>未找到索引: {0}</value></data> + <data name="ModuleInstallerImportInstallPrompt" xml:space="preserve"><value>安装 {0} 个兼容的导入的模组到游戏实例 {1} ({2}) 吗?</value></data> + <data name="ModuleInstallerImportDeletePrompt" xml:space="preserve"><value>导入完成。 删除 {0} 个旧文件吗?</value></data> + <data name="KrakenDependencyNotSatisfied" xml:space="preserve"><value> {0} 版本 {1} 的依赖项未满足</value></data> + <data name="KrakenDependencyModuleNotFound" xml:space="preserve"><value>模组未找到: {0} {1}</value></data> + <data name="KrakenParentDependencyNotSatisfied" xml:space="preserve"><value>{0} 的依赖项 {1} 版本 {2} 未满足</value></data> + <data name="KrakenAny" xml:space="preserve"><value>(任意)</value></data> + <data name="KrakenProvidedByMoreThanOne" xml:space="preserve"><value>模组 {0} 由多个可用模组提供。请从下列列表中选择一个:</value></data> + <data name="KrakenInconsistenciesHeader" xml:space="preserve"><value>发现以下冲突:</value></data> + <data name="KrakenMissingDependency" xml:space="preserve"><value>{0} 缺少依赖 {1}</value></data> + <data name="KrakenConflictsWith" xml:space="preserve"><value>{0} 与 {1} 冲突</value></data> + <data name="KrakenDownloadErrorsHeader" xml:space="preserve"><value>Uh oh,下载时以下东西出现了问题...</value></data> + <data name="KrakenModuleDownloadErrorsHeader" xml:space="preserve"><value>一个或多个下载未能成功:</value></data> + <data name="KrakenModuleDownloadError" xml:space="preserve"><value>下载错误 {0}: {1}</value></data> + <data name="KrakenNotInstalled" xml:space="preserve"><value>模组 {0} 未安装!</value></data> + <data name="KrakenMissingCertificateUnix" xml:space="preserve"><value>Oh no! 我们的下载由于证书错误失败了! + +查看以下页面以获得帮助: +https://github.com/KSP-CKAN/CKAN/wiki/SSL-certificate-errors</value></data> + <data name="KrakenMissingCertificateNotUnix" xml:space="preserve"><value>Oh no! 我们的下载由于证书错误失败了!</value></data> + <data name="KrakenDownloadThrottled" xml:space="preserve"><value>从 {0} 下载时被限速了。 +请考虑添加一个验证 token 来提高限制速率。</value></data> + <data name="KrakenAlreadyRunning" xml:space="preserve"><value>CKAN 已经运行在该实例下了! + +如果您确定这里不是,请删除: +"{0}"</value></data> + <data name="KrakenReinstallModule" xml:space="preserve"><value>元数据已更改,推荐重新安装: {0}</value></data> + <data name="RelationshipResolverConflictsWith" xml:space="preserve"><value>{0} 与 {1} 冲突</value></data> + <data name="RelationshipResolverRequiredButResolver" xml:space="preserve"><value>需要 {0} ,但解析器内有一个不兼容版本</value></data> + <data name="RelationshipResolverRequiredButInstalled" xml:space="preserve"><value>需要 {0} ,但有一个已安装的不兼容版本</value></data> + <data name="RelationshipResolverAnUnmanaged" xml:space="preserve"><value>一个未管理的 DLL 或 DLC</value></data> + <data name="RelationshipResolverUnmanaged" xml:space="preserve"><value>未管理</value></data> + <data name="RelationshipResolverModNotInList" xml:space="preserve"><value>模组 {0} 不在列表中</value></data> + <data name="RelationshipResolverInstalledReason" xml:space="preserve"><value>已安装</value></data> + <data name="RelationshipResolverUserReason" xml:space="preserve"><value>用户请求</value></data> + <data name="RelationshipResolverNoLongerUsedReason" xml:space="preserve"><value>已自动安装,已删除依赖模组</value></data> + <data name="RelationshipResolverReplacementReason" xml:space="preserve"><value>正在替换 {0}</value></data> + <data name="RelationshipResolverSuggestedReason" xml:space="preserve"><value>由 {0} 建议</value></data> + <data name="RelationshipResolverDependsReason" xml:space="preserve"><value>满足 {0} 的依赖项</value></data> + <data name="RelationshipResolverRecommendedReason" xml:space="preserve"><value>由 {0} 推荐</value></data> + <data name="SanityCheckerUnsatisfiedDependency" xml:space="preserve"><value>{0} 有一个未满足的依赖项: {1} 未安装</value></data> + <data name="SanityCheckerConflictsWith" xml:space="preserve"><value>{0} 与 {1} 冲突</value></data> +</root> diff --git a/Core/Registry/Registry.cs b/Core/Registry/Registry.cs index 2aa9d53fc0..c1b6f4dca9 100644 --- a/Core/Registry/Registry.cs +++ b/Core/Registry/Registry.cs @@ -767,7 +767,7 @@ public void RegisterModule(CkanModule mod, IEnumerable<string> absolute_files, G // Woah! Registering an already owned file? Not cool! // (Although if it existed, we should have thrown a kraken well before this.) inconsistencies.Add(string.Format( - "{0} wishes to install {1}, but this file is registered to {2}", + Properties.Resources.RegistryFileConflict, mod.identifier, file, owner )); } @@ -819,7 +819,7 @@ public void DeregisterModule(GameInstance ksp, string module) foreach (var absolute_file in absolute_files.Where(File.Exists)) { inconsistencies.Add(string.Format( - "{0} is registered to {1} but has not been removed!", + Properties.Resources.RegistryFileNotRemoved, absolute_file, module)); } diff --git a/Core/Registry/RegistryManager.cs b/Core/Registry/RegistryManager.cs index 81d4fd3961..1d8bc8deac 100644 --- a/Core/Registry/RegistryManager.cs +++ b/Core/Registry/RegistryManager.cs @@ -409,7 +409,8 @@ public void Save(bool enforce_consistency = true) if (directoryPath == null) { log.ErrorFormat("Failed to save registry, invalid path: {0}", path); - throw new DirectoryNotFoundKraken(path, "Can't find a directory in " + path); + throw new DirectoryNotFoundKraken(path, string.Format( + Properties.Resources.RegistryManagerDirectoryNotFound, path)); } if (!Directory.Exists(directoryPath)) @@ -433,8 +434,8 @@ public void Save(bool enforce_consistency = true) ); } - public string LatestInstalledExportFilename() => $"installed-{ksp.SanitizedName}.ckan"; - public string HistoricInstalledExportFilename() => $"installed-{ksp.SanitizedName}-{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.ckan"; + public string LatestInstalledExportFilename() => $"{Properties.Resources.RegistryManagerExportFilenamePrefix}-{ksp.SanitizedName}.ckan"; + public string HistoricInstalledExportFilename() => $"{Properties.Resources.RegistryManagerExportFilenamePrefix}-{ksp.SanitizedName}-{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.ckan"; /// <summary> /// Save a custom .ckan file that contains all the currently @@ -475,7 +476,7 @@ public CkanModule GenerateModpack(bool recommends = false, bool with_versions = new ModuleVersion("v1.18"), Identifier.Sanitize(name), name, - $"A list of modules installed on the {kspInstanceName} KSP instance", + string.Format(Properties.Resources.RegistryManagerDefaultModpackAbstract, kspInstanceName), null, new List<string>() { System.Environment.UserName }, new List<License>() { new License("unknown") }, diff --git a/Core/Relationships/RelationshipResolver.cs b/Core/Relationships/RelationshipResolver.cs index 2dc82b380a..d30a56c70f 100644 --- a/Core/Relationships/RelationshipResolver.cs +++ b/Core/Relationships/RelationshipResolver.cs @@ -265,8 +265,9 @@ private void AddModulesToInstall(IEnumerable<CkanModule> modules) } else { - throw new InconsistentKraken( - $"{module} conflicts with {listed_mod}"); + throw new InconsistentKraken(string.Format( + Properties.Resources.RelationshipResolverConflictsWith, + module, listed_mod)); } } @@ -415,9 +416,9 @@ private void ResolveStanza(IEnumerable<RelationshipDescriptor> stanza, Selection } else { - throw new InconsistentKraken( - $"{descriptor} required, but an incompatible version is in the resolver" - ); + throw new InconsistentKraken(string.Format( + Properties.Resources.RelationshipResolverRequiredButResolver, + descriptor)); } } @@ -441,9 +442,9 @@ private void ResolveStanza(IEnumerable<RelationshipDescriptor> stanza, Selection } else { - throw new InconsistentKraken( - $"{descriptor} required, but an incompatible version is installed" - ); + throw new InconsistentKraken(string.Format( + Properties.Resources.RelationshipResolverRequiredButInstalled, + descriptor)); } } @@ -537,8 +538,9 @@ private void ResolveStanza(IEnumerable<RelationshipDescriptor> stanza, Selection } else { - throw new InconsistentKraken( - $"{conflicting_mod} conflicts with {candidate}"); + throw new InconsistentKraken(string.Format( + Properties.Resources.RelationshipResolverConflictsWith, + conflicting_mod, candidate)); } } } @@ -671,10 +673,12 @@ public Dictionary<CkanModule, String> ConflictList .Distinct()) .ToDictionary( kvp => kvp.Key, - kvp => $"{kvp.Key} conflicts with " + ( - kvp.Value.Count() == 0 - ? "an unmanaged DLL or DLC" - : string.Join(", ", kvp.Value))); + kvp => string.Format( + Properties.Resources.RelationshipResolverConflictsWith, + kvp.Key, ( + kvp.Value.Count() == 0 + ? Properties.Resources.RelationshipResolverAnUnmanaged + : string.Join(", ", kvp.Value)))); } } @@ -693,7 +697,7 @@ public string ReasonStringFor(CkanModule mod) if (mod == null) { // If we don't have a CkanModule, it must be a DLL or DLC - return "Unmanaged"; + return Properties.Resources.RelationshipResolverUnmanaged; } var reason = ReasonFor(mod); var is_root_type = reason.GetType() == typeof(SelectionReason.UserRequested) @@ -708,7 +712,9 @@ public SelectionReason ReasonFor(CkanModule mod) if (mod == null) throw new ArgumentNullException(); if (!reasons.ContainsKey(mod) && !ModList().Contains(mod)) { - throw new ArgumentException("Mod " + mod.identifier + " is not in the list"); + throw new ArgumentException(string.Format( + Properties.Resources.RelationshipResolverModNotInList, + mod.identifier)); } return reasons[mod]; @@ -755,7 +761,7 @@ public override CkanModule Parent public override string Reason { - get { return " Currently installed.\r\n"; } + get { return Properties.Resources.RelationshipResolverInstalledReason; } } } @@ -772,7 +778,7 @@ public override CkanModule Parent public override string Reason { - get { return " Requested by user.\r\n"; } + get { return Properties.Resources.RelationshipResolverUserReason; } } } @@ -780,7 +786,7 @@ public class NoLongerUsed: SelectionReason { public override string Reason { - get { return " Auto-installed, depending modules removed.\r\n"; } + get { return Properties.Resources.RelationshipResolverNoLongerUsedReason; } } } @@ -794,7 +800,7 @@ public Replacement(CkanModule module) public override string Reason { - get { return " Replacing " + Parent.name + ".\r\n"; } + get { return string.Format(Properties.Resources.RelationshipResolverReplacementReason, Parent.name); } } } @@ -808,7 +814,7 @@ public Suggested(CkanModule module) public override string Reason { - get { return " Suggested by " + Parent.name + ".\r\n"; } + get { return string.Format(Properties.Resources.RelationshipResolverSuggestedReason, Parent.name); } } } @@ -822,7 +828,7 @@ public Depends(CkanModule module) public override string Reason { - get { return " To satisfy dependency from " + Parent.name + ".\r\n"; } + get { return string.Format(Properties.Resources.RelationshipResolverDependsReason, Parent.name); } } } @@ -836,7 +842,7 @@ public Recommended(CkanModule module) public override string Reason { - get { return " Recommended by " + Parent.name + ".\r\n"; } + get { return string.Format(Properties.Resources.RelationshipResolverRecommendedReason, Parent.name); } } } } diff --git a/Core/Relationships/SanityChecker.cs b/Core/Relationships/SanityChecker.cs index 62b1e102f9..bfaf128002 100644 --- a/Core/Relationships/SanityChecker.cs +++ b/Core/Relationships/SanityChecker.cs @@ -30,11 +30,15 @@ IDictionary<string, ModuleVersion> dlc { foreach (var kvp in unmetDepends) { - errors.Add($"{kvp.Key} has an unsatisfied dependency: {kvp.Value} is not installed"); + errors.Add(string.Format( + Properties.Resources.SanityCheckerUnsatisfiedDependency, + kvp.Key, kvp.Value)); } foreach (var kvp in conflicts) { - errors.Add($"{kvp.Key} conflicts with {kvp.Value}"); + errors.Add(string.Format( + Properties.Resources.SanityCheckerConflictsWith, + kvp.Key, kvp.Value)); } } return errors; diff --git a/Core/SingleAssemblyResourceManager.cs b/Core/SingleAssemblyResourceManager.cs new file mode 100644 index 0000000000..54cc5879d6 --- /dev/null +++ b/Core/SingleAssemblyResourceManager.cs @@ -0,0 +1,58 @@ +using System.IO; +using System.Globalization; +using System.Resources; +using System.Collections; +using System.Reflection; +using System.Collections.Generic; + +namespace CKAN +{ + // Thanks and credit to this guy: https://stackoverflow.com/q/1952638/2422988 + + class SingleAssemblyResourceManager : ResourceManager + { + public SingleAssemblyResourceManager(string basename, Assembly assembly) : base(basename, assembly) + { + } + + protected override ResourceSet InternalGetResourceSet(CultureInfo culture, + bool createIfNotExists, bool tryParents) + { + ResourceSet rs; + if (!myResourceSets.TryGetValue(culture, out rs)) + { + // Lazy-load default language (without caring about duplicate assignment in race conditions, no harm done) + if (neutralResourcesCulture == null) + { + neutralResourcesCulture = GetNeutralResourcesLanguage(this.MainAssembly); + } + + // If we're asking for the default language, then ask for the + // invariant (non-specific) resources. + if (neutralResourcesCulture.Equals(culture)) + { + culture = CultureInfo.InvariantCulture; + } + string resourceFileName = GetResourceFileName(culture); + + Stream store = this.MainAssembly.GetManifestResourceStream(resourceFileName); + + // If we found the appropriate resources in the local assembly + if (store != null) + { + rs = new ResourceSet(store); + // Save for later + myResourceSets.Add(culture, rs); + } + else + { + rs = base.InternalGetResourceSet(culture, createIfNotExists, tryParents); + } + } + return rs; + } + + private CultureInfo neutralResourcesCulture; + private Dictionary<CultureInfo, ResourceSet> myResourceSets = new Dictionary<CultureInfo, ResourceSet>(); + } +} diff --git a/Core/Types/CkanModule.cs b/Core/Types/CkanModule.cs index 9117c51882..fc62df9b35 100644 --- a/Core/Types/CkanModule.cs +++ b/Core/Types/CkanModule.cs @@ -338,7 +338,9 @@ public CkanModule(string json, IGameComparator comparator) } catch (JsonException ex) { - throw new BadMetadataKraken(null, string.Format("JSON deserialization error: {0}", ex.Message), ex); + throw new BadMetadataKraken(null, + string.Format(Properties.Resources.CkanModuleDeserialisationError, ex.Message), + ex); } _comparator = comparator; CheckHealth(); @@ -352,7 +354,8 @@ private void CheckHealth() { if (!IsSpecSupported()) { - throw new UnsupportedKraken($"{this} requires CKAN {spec_version}, we can't read it."); + throw new UnsupportedKraken(string.Format( + Properties.Resources.CkanModuleUnsupportedSpec, this, spec_version)); } // Check everything in the spec is defined. @@ -371,7 +374,8 @@ private void CheckHealth() if (value == null) { - throw new BadMetadataKraken(null, $"{identifier} missing required field {field}"); + throw new BadMetadataKraken(null, string.Format( + Properties.Resources.CkanModuleMissingRequired, identifier, field)); } } } @@ -415,7 +419,7 @@ private void DeSerialisationFixes(StreamingContext like_i_could_care) if (ksp_version != null && (ksp_version_max != null || ksp_version_min != null)) { // KSP version mixed with min/max. - throw new InvalidModuleAttributesException("ksp_version mixed with ksp_version_(min|max)", this); + throw new InvalidModuleAttributesException(Properties.Resources.CkanModuleKspVersionMixed, this); } license = license ?? new List<License> { License.UnknownLicense }; @@ -450,7 +454,7 @@ public static CkanModule FromIDandVersion(IRegistryQuerier registry, string mod, if (module == null || (ksp_version != null && !module.IsCompatibleKSP(ksp_version))) throw new ModuleNotFoundKraken(ident, version, - string.Format("Module {0} version {1} not available", ident, version)); + string.Format(Properties.Resources.CkanModuleNotAvailable, ident, version)); } else { @@ -459,7 +463,7 @@ public static CkanModule FromIDandVersion(IRegistryQuerier registry, string mod, if (module == null) throw new ModuleNotFoundKraken(mod, null, - string.Format("Module {0} not installed or available", mod)); + string.Format(Properties.Resources.CkanModuleNotInstalledOrAvailable, mod)); } return module; } @@ -557,7 +561,7 @@ public string HighestCompatibleKSP() { GameVersion v = LatestCompatibleKSP(); if (v.IsAny) - return "All versions"; + return Properties.Resources.CkanModuleAllVersions; else return v.ToString(); } diff --git a/Core/Types/Kraken.cs b/Core/Types/Kraken.cs index b21540a9a0..4c730fa56f 100644 --- a/Core/Types/Kraken.cs +++ b/Core/Types/Kraken.cs @@ -60,14 +60,17 @@ public class ModuleNotFoundKraken : Kraken // TODO: Is there a way to set the stringify version of this? public ModuleNotFoundKraken(string module, string version, string reason, Exception innerException = null) - : base(reason ?? $"Dependency on {module} version {version} not satisfied", innerException) + : base( + reason ?? string.Format(Properties.Resources.KrakenDependencyNotSatisfied, module, version), + innerException) { this.module = module; this.version = version; } public ModuleNotFoundKraken(string module, string version = null) - : this(module, version, $"Module not found: {module} {version ?? ""}") + : this(module, version, + string.Format(Properties.Resources.KrakenDependencyModuleNotFound, module, version ?? "")) { } } @@ -92,7 +95,8 @@ public class DependencyNotSatisfiedKraken : ModuleNotFoundKraken public DependencyNotSatisfiedKraken(CkanModule parentModule, string module, string version = null, string reason = null, Exception innerException = null) : base(module, version, - reason ?? $"{parentModule.identifier} dependency on {module} version {version ?? "(any)"} not satisfied", + reason ?? string.Format(Properties.Resources.KrakenParentDependencyNotSatisfied, + parentModule.identifier, module, version ?? Properties.Resources.KrakenAny), innerException) { parent = parentModule; @@ -165,7 +169,7 @@ private static string FormatMessage(string requested, List<CkanModule> modules, { return choice_help_text ?? string.Format( - "Module {0} is provided by more than one available module. Please choose one of the following:", + Properties.Resources.KrakenProvidedByMoreThanOne, requested); } } @@ -182,7 +186,9 @@ public string InconsistenciesPretty { get { - return header + String.Join("\r\n", inconsistencies.Select(msg => $"* {msg}")); + return String.Join("\r\n", + new string[] { Properties.Resources.KrakenInconsistenciesHeader } + .Concat(inconsistencies.Select(msg => $"* {msg}"))); } } @@ -210,8 +216,6 @@ public override string ToString() { return InconsistenciesPretty + "\r\n\r\n" + StackTrace; } - - private const string header = "The following inconsistencies were found:\r\n"; } /// <summary> @@ -223,10 +227,10 @@ public BadRelationshipsKraken( ICollection<KeyValuePair<CkanModule, RelationshipDescriptor>> depends, ICollection<KeyValuePair<CkanModule, RelationshipDescriptor>> conflicts ) : base( - (depends?.Select(dep => $"{dep.Key} missing dependency {dep.Value}") + (depends?.Select(dep => string.Format(Properties.Resources.KrakenMissingDependency, dep.Key, dep.Value)) ?? new string[] {} ).Concat( - conflicts?.Select(conf => $"{conf.Key} conflicts with {conf.Value}") + conflicts?.Select(conf => string.Format(Properties.Resources.KrakenConflictsWith, conf.Key, conf.Value)) ?? new string[] {} ).ToArray() ) @@ -278,7 +282,9 @@ public DownloadErrorsKraken(List<KeyValuePair<int, Exception>> errors) : base() public override string ToString() { - return "Uh oh, the following things went wrong when downloading...\r\n\r\n" + String.Join("\r\n", exceptions); + return String.Join("\r\n", + new string[] { Properties.Resources.KrakenDownloadErrorsHeader, "" } + .Concat(exceptions.Select(e => e.ToString()))); } } @@ -318,13 +324,12 @@ public override string ToString() if (builder == null) { builder = new StringBuilder(); - builder.AppendLine("One or more downloads were unsuccessful:"); + builder.AppendLine(Properties.Resources.KrakenModuleDownloadErrorsHeader); builder.AppendLine(""); foreach (KeyValuePair<CkanModule, Exception> kvp in exceptions) { - builder.AppendLine( - $"Error downloading {kvp.Key.ToString()}: {kvp.Value.Message}" - ); + builder.AppendLine(string.Format( + Properties.Resources.KrakenModuleDownloadError, kvp.Key.ToString(), kvp.Value.Message)); } } return builder.ToString(); @@ -385,7 +390,7 @@ public class ModNotInstalledKraken : Kraken public override string Message { - get { return string.Format("Module {0} is not installed!", mod); } + get { return string.Format(Properties.Resources.KrakenNotInstalled, mod); } } // TODO: Since we override message, should we really allow users to pass in a reason @@ -419,16 +424,9 @@ public MissingCertificateKraken(string reason = null, Exception innerException = public override string ToString() { - if (Platform.IsUnix) - { - return "Oh no! Our download failed with a certificate error!\r\n\r\n" - + "Consult this page for help:\r\n\t" - + HelpURLs.CertificateErrors; - } - else - { - return "Oh no! Our download failed with a certificate error!"; - } + return Platform.IsUnix + ? string.Format(Properties.Resources.KrakenMissingCertificateUnix, HelpURLs.CertificateErrors) + : Properties.Resources.KrakenMissingCertificateNotUnix; } } @@ -445,7 +443,7 @@ public DownloadThrottledKraken(Uri url, Uri info) : base() public override string ToString() { - return $"Download from {throttledUrl.Host} was throttled.\r\nConsider adding an authentication token to increase the throtting limit."; + return string.Format(Properties.Resources.KrakenDownloadThrottled, throttledUrl.Host); } } @@ -461,7 +459,7 @@ public RegistryInUseKraken(string path, string reason = null, Exception inner_ex public override string ToString() { - return String.Format("CKAN is already running for this instance!\n\nIf you're certain this is not the case, then delete:\n\"{0}\"\n", lockfilePath); + return String.Format(Properties.Resources.KrakenAlreadyRunning, lockfilePath); } } @@ -592,7 +590,7 @@ public class ReinstallModuleKraken : Kraken public readonly List<CkanModule> Modules; public ReinstallModuleKraken(List<CkanModule> modules) - : base(string.Format("Metadata changed, reinstallation recommended: {0}", + : base(string.Format(Properties.Resources.KrakenReinstallModule, string.Join(", ", modules))) { Modules = modules; diff --git a/Core/Types/License.cs b/Core/Types/License.cs index f1eb38853d..88a2df4226 100644 --- a/Core/Types/License.cs +++ b/Core/Types/License.cs @@ -41,7 +41,7 @@ public License(string license) { throw new BadMetadataKraken( null, - string.Format("The license {0} is invalid", license) + string.Format(Properties.Resources.LicenceInvalid, license) ); } diff --git a/Core/Types/ModuleInstallDescriptor.cs b/Core/Types/ModuleInstallDescriptor.cs index 1e6167fc54..a194e745f1 100644 --- a/Core/Types/ModuleInstallDescriptor.cs +++ b/Core/Types/ModuleInstallDescriptor.cs @@ -73,7 +73,7 @@ internal void DeSerialisationFixes(StreamingContext like_i_could_care) // this check now that we're doing better json-fu above. if (install_to == null) { - throw new BadMetadataKraken(null, "Install stanzas must have an install_to"); + throw new BadMetadataKraken(null, Properties.Resources.ModuleInstallDescriptorMustHaveInstallTo); } var setCount = new[] { file, find, find_regexp }.Count(i => i != null); @@ -81,12 +81,12 @@ internal void DeSerialisationFixes(StreamingContext like_i_could_care) // Make sure we have either a `file`, `find`, or `find_regexp` stanza. if (setCount == 0) { - throw new BadMetadataKraken(null, "Install stanzas require either a file, find, or find_regexp directive"); + throw new BadMetadataKraken(null, Properties.Resources.ModuleInstallDescriptorRequireFileFind); } if (setCount > 1) { - throw new BadMetadataKraken(null, "Install stanzas must only include one of file, find, or find_regexp directives"); + throw new BadMetadataKraken(null, Properties.Resources.ModuleInstallDescriptorTooManyFileFind); } // Make sure only filter or include_only fields exist but not both at the same time @@ -95,7 +95,7 @@ internal void DeSerialisationFixes(StreamingContext like_i_could_care) if (filterCount > 0 && includeOnlyCount > 0) { - throw new BadMetadataKraken(null, "Install stanzas can only contain filter or include_only directives, not both"); + throw new BadMetadataKraken(null, Properties.Resources.ModuleInstallDescriptorTooManyFilterInclude); } // Normalize paths on load (note, doesn't cover assignment like in tests) @@ -242,7 +242,7 @@ private void EnsurePattern() } else { - throw new UnsupportedKraken("Install stanzas requires `file` or `find` or `find_regexp`."); + throw new UnsupportedKraken(Properties.Resources.ModuleInstallDescriptorRequireFileFind); } } } @@ -328,7 +328,8 @@ public List<InstallableFile> FindInstallableFiles(ZipFile zipfile, GameInstance // The installation path cannot contain updirs if (install_to.Contains("/../") || install_to.EndsWith("/..")) - throw new BadInstallLocationKraken("Invalid installation path: " + install_to); + throw new BadInstallLocationKraken(string.Format( + Properties.Resources.ModuleInstallDescriptorInvalidInstallPath, install_to)); if (ksp == null) { @@ -359,7 +360,8 @@ public List<InstallableFile> FindInstallableFiles(ZipFile zipfile, GameInstance } else { - throw new BadInstallLocationKraken("Unknown install_to " + install_to); + throw new BadInstallLocationKraken(string.Format( + Properties.Resources.ModuleInstallDescriptorUnknownInstallPath, install_to)); } break; } @@ -413,7 +415,8 @@ public List<InstallableFile> FindInstallableFiles(ZipFile zipfile, GameInstance if (files.Count == 0) { // We have null as the first argument here, because we don't know which module we're installing - throw new BadMetadataKraken(null, String.Format("No files found matching {0} to install!", DescribeMatch())); + throw new BadMetadataKraken(null, String.Format( + Properties.Resources.ModuleInstallDescriptorNoFilesFound, DescribeMatch())); } return files; @@ -462,7 +465,7 @@ internal string TransformOutputName(IGame game, string outputName, string instal { if (@as.Contains("/") || @as.Contains("\\")) { - throw new BadMetadataKraken(null, "`as` may not include path separators."); + throw new BadMetadataKraken(null, Properties.Resources.ModuleInstallDescriptorAsNoPathSeparators); } // Replace first path component with @as outputName = ReplaceFirstPiece(outputName, "/", @as); diff --git a/Core/Types/ModuleResolution.cs b/Core/Types/ModuleResolution.cs deleted file mode 100644 index ec4ecc0940..0000000000 --- a/Core/Types/ModuleResolution.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -namespace CKAN.Types -{ - public class ModuleResolution : IEnumerable<CkanModule> - { - public List<CkanModule> CachedModules { get; set; } - public List<CkanModule> UncachedModules { get; set; } - - public IEnumerable<CkanModule> All => CachedModules.Concat(UncachedModules); - - public int Count => CachedModules.Count + UncachedModules.Count; - - public ModuleResolution(IEnumerable<CkanModule> modules, Func<CkanModule, bool> isCached) - { - CachedModules = new List<CkanModule>(); - UncachedModules = new List<CkanModule>(); - - foreach (var module in modules) - { - if (isCached(module)) - { - CachedModules.Add(module); - } - else - { - UncachedModules.Add(module); - } - } - } - - public IEnumerator<CkanModule> GetEnumerator() - { - return All.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} diff --git a/Core/Types/RelationshipDescriptor.cs b/Core/Types/RelationshipDescriptor.cs index 6408244d6b..7c7d4c2b28 100644 --- a/Core/Types/RelationshipDescriptor.cs +++ b/Core/Types/RelationshipDescriptor.cs @@ -193,22 +193,6 @@ public override bool StartsWith(string prefix) return name.IndexOf(prefix, StringComparison.CurrentCultureIgnoreCase) == 0; } - /// <summary> - /// A user friendly message for what versions satisfies this descriptor. - /// </summary> - [JsonIgnore] - public string RequiredVersion - { - get - { - if (version != null) - return version.ToString(); - return string.Format("between {0} and {1} inclusive.", - min_version != null ? min_version.ToString() : "any version", - max_version != null ? max_version.ToString() : "any version"); - } - } - /// <summary> /// Generate a user readable description of the relationship /// </summary> @@ -224,9 +208,11 @@ public override string ToString() { return version != null ? $"{name} {version}" - : min_version != null && max_version != null ? $"{name} {min_version} -- {max_version}" - : min_version != null ? $"{name} {min_version} or later" - : max_version != null ? $"{name} {max_version} or earlier" + : min_version != null && max_version != null ? $"{name} {min_version}–{max_version}" + : min_version != null + ? string.Format(Properties.Resources.RelationshipDescriptorMinVersionOnly, name, min_version) + : max_version != null + ? string.Format(Properties.Resources.RelationshipDescriptorMaxVersionOnly, name, max_version) : name; } @@ -304,7 +290,8 @@ public override bool StartsWith(string prefix) public override string ToString() { return any_of?.Select(r => r.ToString()) - .Aggregate((a, b) => $"{a} OR {b}"); + .Aggregate((a, b) => + string.Format(Properties.Resources.RelationshipDescriptorAnyOfJoiner, a, b)); } } } diff --git a/Core/Types/ReleaseStatus.cs b/Core/Types/ReleaseStatus.cs index e513660287..aac8d0defe 100644 --- a/Core/Types/ReleaseStatus.cs +++ b/Core/Types/ReleaseStatus.cs @@ -46,7 +46,7 @@ public ReleaseStatus(string status) { throw new BadMetadataKraken( null, - String.Format("{0} is not a valid release status", status) + String.Format(Properties.Resources.ReleaseStatusInvalid, status) ); } @@ -58,4 +58,4 @@ public override string ToString() return status; } } -} \ No newline at end of file +} diff --git a/Core/Types/Repository.cs b/Core/Types/Repository.cs index dbc4df1aeb..6f0327f248 100644 --- a/Core/Types/Repository.cs +++ b/Core/Types/Repository.cs @@ -7,7 +7,7 @@ namespace CKAN { public class Repository : IEquatable<Repository> { - [JsonIgnore] public static readonly string default_ckan_repo_name = "default"; + [JsonIgnore] public static string default_ckan_repo_name => Properties.Resources.RepositoryDefaultName; public string name; public Uri uri; diff --git a/Core/Versioning/CkanModuleVersion.cs b/Core/Versioning/CkanModuleVersion.cs index 346575708e..1e07f8faf8 100644 --- a/Core/Versioning/CkanModuleVersion.cs +++ b/Core/Versioning/CkanModuleVersion.cs @@ -22,7 +22,7 @@ public CkanModuleVersion(string version, string name) : base(version) { Name = name; - _string = $"{base.ToString()} aka {Name}"; + _string = string.Format(Properties.Resources.CkanModuleVersionToString, base.ToString(), Name); } /// <summary> diff --git a/Core/Versioning/GameVersion.cs b/Core/Versioning/GameVersion.cs index 0d4a7b99df..192cb8e795 100644 --- a/Core/Versioning/GameVersion.cs +++ b/Core/Versioning/GameVersion.cs @@ -280,7 +280,7 @@ public string ToYalovString() // 1.99.99 || (_major == VersionsMax[""].Major && VersionsMax.TryGetValue($"{_major}", out value) && _minor >= UptoNines(value.Minor))) { - return "any"; + return Properties.Resources.GameVersionYalovAny; } else if (IsMinorDefined && VersionsMax.TryGetValue($"{_major}.{_minor}", out value) @@ -495,7 +495,7 @@ public bool InBuildMap(IGame game) /// </summary> /// <returns>A complete GameVersion object</returns> /// <param name="user">A IUser instance, to raise the corresponding dialog.</param> - public GameVersion RaiseVersionSelectionDialog (IGame game, IUser user) + public GameVersion RaiseVersionSelectionDialog(IGame game, IUser user) { if (IsFullyDefined && InBuildMap(game)) { @@ -505,7 +505,7 @@ public GameVersion RaiseVersionSelectionDialog (IGame game, IUser user) } else if (!IsMajorDefined || !IsMinorDefined) { - throw new BadGameVersionKraken("Needs at least Major and Minor"); + throw new BadGameVersionKraken(Properties.Resources.GameVersionSelectNeedOne); } else { @@ -514,7 +514,7 @@ public GameVersion RaiseVersionSelectionDialog (IGame game, IUser user) List<GameVersion> possibleVersions = new List<GameVersion>(); // Default message passed to RaiseSelectionDialog. - string message = "The specified version is not unique, please select one:"; + string message = Properties.Resources.GameVersionSelectHeader; // Find the versions which are part of the range. foreach (GameVersion ver in knownVersions) @@ -539,7 +539,7 @@ public GameVersion RaiseVersionSelectionDialog (IGame game, IUser user) // Only compare Major, Minor, Patch and adjust the message. else { - message = "The build number is not known for this patch. Please select one:"; + message = Properties.Resources.GameVersionSelectBuildHeader; if (Major == ver.Major && Minor == ver.Minor && Patch == ver.Patch) { possibleVersions.Add(ver); @@ -551,7 +551,7 @@ public GameVersion RaiseVersionSelectionDialog (IGame game, IUser user) if (possibleVersions.Count == 0) { // No version found in the map. Happens for future or other unknown versions. - throw new BadGameVersionKraken("The version is not known to CKAN."); + throw new BadGameVersionKraken(Properties.Resources.GameVersionNotKnown); } else if (possibleVersions.Count == 1) { diff --git a/Core/Versioning/GameVersionCriteria.cs b/Core/Versioning/GameVersionCriteria.cs index 0b603d3cf5..e33ead8c76 100644 --- a/Core/Versioning/GameVersionCriteria.cs +++ b/Core/Versioning/GameVersionCriteria.cs @@ -68,7 +68,7 @@ public override String ToString() { versionList.Add(version.ToString()); } - return "[Versions: " + String.Join( ", ", versionList) + "]"; + return string.Format(Properties.Resources.GameVersionCriteriaToString, string.Join( ", ", versionList)); } } } diff --git a/Core/Versioning/GameVersionRange.cs b/Core/Versioning/GameVersionRange.cs index 71382c6ba0..74ce3d94ad 100644 --- a/Core/Versioning/GameVersionRange.cs +++ b/Core/Versioning/GameVersionRange.cs @@ -107,8 +107,10 @@ private static string SameVersionString(GameVersion v) public static string VersionSpan(IGame game, GameVersion minKsp, GameVersion maxKsp) { return minKsp == maxKsp ? $"{game.ShortName} {SameVersionString(minKsp)}" - : minKsp.IsAny ? $"{game.ShortName} {maxKsp} and earlier" - : maxKsp.IsAny ? $"{game.ShortName} {minKsp} and later" + : minKsp.IsAny + ? string.Format(Properties.Resources.GameVersionRangeMinOnly, game.ShortName, maxKsp) + : maxKsp.IsAny + ? string.Format(Properties.Resources.GameVersionRangeMaxOnly, game.ShortName, minKsp) : $"{game.ShortName} {minKsp}–{maxKsp}"; } diff --git a/Core/Versioning/ProvidesModuleVersion.cs b/Core/Versioning/ProvidesModuleVersion.cs index 9ee347c394..8ec52cf448 100644 --- a/Core/Versioning/ProvidesModuleVersion.cs +++ b/Core/Versioning/ProvidesModuleVersion.cs @@ -15,7 +15,7 @@ public sealed class ProvidesModuleVersion : ModuleVersion /// <param name="version">The version of the providing module.</param> public ProvidesModuleVersion(string identifier, string version) : base(version) { - _string = $"{version} (provided by {identifier})"; + _string = string.Format(Properties.Resources.ProvidesModuleVersionToString, version, identifier); } /// <summary> diff --git a/Core/Versioning/UnmanagedModuleVersion.cs b/Core/Versioning/UnmanagedModuleVersion.cs index 1a7ac2f911..44f0113421 100644 --- a/Core/Versioning/UnmanagedModuleVersion.cs +++ b/Core/Versioning/UnmanagedModuleVersion.cs @@ -13,7 +13,9 @@ public sealed class UnmanagedModuleVersion : ModuleVersion public UnmanagedModuleVersion(string version) : base(version ?? "0") { IsUnknownVersion = version == null; - _string = version == null ? "(unmanaged)" : $"{version} (unmanaged)"; + _string = version == null + ? Properties.Resources.UnmanagedModuleVersionUnknown + : string.Format(Properties.Resources.UnmanagedModuleVersionKnown, version); } public override string ToString() diff --git a/GUI/CKAN-GUI.csproj b/GUI/CKAN-GUI.csproj index 3276e6e847..a091288891 100644 --- a/GUI/CKAN-GUI.csproj +++ b/GUI/CKAN-GUI.csproj @@ -11,7 +11,7 @@ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <ProjectGuid>{A79F9D54-315C-472B-928F-713A5860B2BE}</ProjectGuid> <OutputType>WinExe</OutputType> - <RootNamespace>CKAN</RootNamespace> + <RootNamespace>CKAN.GUI</RootNamespace> <ApplicationIcon>..\assets\ckan.ico</ApplicationIcon> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <FileAlignment>512</FileAlignment> @@ -937,37 +937,37 @@ <DependentUpon>..\..\Dialogs\PluginsDialog.cs</DependentUpon> </EmbeddedResource> <EmbeddedResource Include="Properties\Resources.resx"> - <LogicalName>CKAN.Properties.Resources.resources</LogicalName> + <LogicalName>CKAN.GUI.Properties.Resources.resources</LogicalName> <SubType>Designer</SubType> <Generator>ResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.cs</LastGenOutput> </EmbeddedResource> <EmbeddedResource Include="Properties\Resources.de-DE.resx"> - <LogicalName>CKAN.Properties.Resources.de-DE.resources</LogicalName> + <LogicalName>CKAN.GUI.Properties.Resources.de-DE.resources</LogicalName> <SubType>Designer</SubType> <Generator>ResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.cs</LastGenOutput> </EmbeddedResource> <EmbeddedResource Include="Properties\Resources.fr-FR.resx"> - <LogicalName>CKAN.Properties.Resources.fr-FR.resources</LogicalName> + <LogicalName>CKAN.GUI.Properties.Resources.fr-FR.resources</LogicalName> <SubType>Designer</SubType> <Generator>ResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.cs</LastGenOutput> </EmbeddedResource> <EmbeddedResource Include="Properties\Resources.zh-CN.resx"> - <LogicalName>CKAN.Properties.Resources.zh-CN.resources</LogicalName> + <LogicalName>CKAN.GUI.Properties.Resources.zh-CN.resources</LogicalName> <SubType>Designer</SubType> <Generator>ResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.cs</LastGenOutput> </EmbeddedResource> <EmbeddedResource Include="Properties\Resources.en-US.resx"> - <LogicalName>CKAN.Properties.Resources.en-US.resources</LogicalName> + <LogicalName>CKAN.GUI.Properties.Resources.en-US.resources</LogicalName> <SubType>Designer</SubType> <Generator>ResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.cs</LastGenOutput> </EmbeddedResource> <EmbeddedResource Include="Properties\Resources.pt-BR.resx"> - <LogicalName>CKAN.Properties.Resources.pt-BR.resources</LogicalName> + <LogicalName>CKAN.GUI.Properties.Resources.pt-BR.resources</LogicalName> <SubType>Designer</SubType> <Generator>ResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.cs</LastGenOutput> @@ -979,13 +979,13 @@ <LastGenOutput>Resources.Designer.cs</LastGenOutput> </EmbeddedResource> <EmbeddedResource Include="Properties\Resources.ru-RU.resx"> - <LogicalName>CKAN.Properties.Resources.ru-RU.resources</LogicalName> + <LogicalName>CKAN.GUI.Properties.Resources.ru-RU.resources</LogicalName> <SubType>Designer</SubType> <Generator>ResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.cs</LastGenOutput> </EmbeddedResource> <EmbeddedResource Include="Properties\Resources.ja-JP.resx"> - <LogicalName>CKAN.Properties.Resources.ja-JP.resources</LogicalName> + <LogicalName>CKAN.GUI.Properties.Resources.ja-JP.resources</LogicalName> <SubType>Designer</SubType> <Generator>ResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.cs</LastGenOutput> diff --git a/GUI/ControlFactory.cs b/GUI/ControlFactory.cs index 5dc14746a1..a37fbd0fc2 100644 --- a/GUI/ControlFactory.cs +++ b/GUI/ControlFactory.cs @@ -1,7 +1,7 @@ using System.Diagnostics; using System.Threading; -namespace CKAN +namespace CKAN.GUI { /// <summary> /// This class ensures that all controls are created from the same thread. diff --git a/GUI/Controls/AllModVersions.Designer.cs b/GUI/Controls/AllModVersions.Designer.cs index 0204f2bad0..aa271f8161 100644 --- a/GUI/Controls/AllModVersions.Designer.cs +++ b/GUI/Controls/AllModVersions.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class AllModVersions { diff --git a/GUI/Controls/AllModVersions.cs b/GUI/Controls/AllModVersions.cs index 46d94fba5c..8fc6e2e48e 100644 --- a/GUI/Controls/AllModVersions.cs +++ b/GUI/Controls/AllModVersions.cs @@ -7,7 +7,7 @@ using CKAN.Versioning; -namespace CKAN +namespace CKAN.GUI { public partial class AllModVersions : UserControl { diff --git a/GUI/Controls/Changeset.Designer.cs b/GUI/Controls/Changeset.Designer.cs index 9cc15111e4..a0a5703bca 100644 --- a/GUI/Controls/Changeset.Designer.cs +++ b/GUI/Controls/Changeset.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class Changeset { diff --git a/GUI/Controls/Changeset.cs b/GUI/Controls/Changeset.cs index 6511bda499..0503e69eb5 100644 --- a/GUI/Controls/Changeset.cs +++ b/GUI/Controls/Changeset.cs @@ -5,7 +5,7 @@ using System.Windows.Forms; using CKAN.Extensions; -namespace CKAN +namespace CKAN.GUI { public partial class Changeset : UserControl { @@ -102,7 +102,7 @@ private ListViewItem makeItem(ModChange change) return new ListViewItem(new string[] { change.NameAndStatus, - change.ChangeType.ToString(), + change.ChangeType.ToI18nString(), warnLbl != null ? string.Format( Properties.Resources.MainChangesetWarningInstallingModuleWithLabel, diff --git a/GUI/Controls/ChooseProvidedMods.Designer.cs b/GUI/Controls/ChooseProvidedMods.Designer.cs index 1436b66584..eef0a0552c 100644 --- a/GUI/Controls/ChooseProvidedMods.Designer.cs +++ b/GUI/Controls/ChooseProvidedMods.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class ChooseProvidedMods { diff --git a/GUI/Controls/ChooseProvidedMods.cs b/GUI/Controls/ChooseProvidedMods.cs index 33c38de114..a2610daaf3 100644 --- a/GUI/Controls/ChooseProvidedMods.cs +++ b/GUI/Controls/ChooseProvidedMods.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public partial class ChooseProvidedMods : UserControl { diff --git a/GUI/Controls/ChooseRecommendedMods.Designer.cs b/GUI/Controls/ChooseRecommendedMods.Designer.cs index 66b65590fd..3e4a6ac06e 100644 --- a/GUI/Controls/ChooseRecommendedMods.Designer.cs +++ b/GUI/Controls/ChooseRecommendedMods.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class ChooseRecommendedMods { diff --git a/GUI/Controls/ChooseRecommendedMods.cs b/GUI/Controls/ChooseRecommendedMods.cs index 493fb1a062..5dc5602e64 100644 --- a/GUI/Controls/ChooseRecommendedMods.cs +++ b/GUI/Controls/ChooseRecommendedMods.cs @@ -7,7 +7,7 @@ using CKAN.Extensions; using CKAN.Versioning; -namespace CKAN +namespace CKAN.GUI { public partial class ChooseRecommendedMods : UserControl { diff --git a/GUI/Controls/DeleteDirectories.Designer.cs b/GUI/Controls/DeleteDirectories.Designer.cs index 21be2d6c5e..d1c0f4982e 100644 --- a/GUI/Controls/DeleteDirectories.Designer.cs +++ b/GUI/Controls/DeleteDirectories.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class DeleteDirectories { diff --git a/GUI/Controls/DeleteDirectories.cs b/GUI/Controls/DeleteDirectories.cs index 5d89b7917e..4ca60fb9bf 100644 --- a/GUI/Controls/DeleteDirectories.cs +++ b/GUI/Controls/DeleteDirectories.cs @@ -6,7 +6,7 @@ using System.Windows.Forms; using CKAN.Extensions; -namespace CKAN +namespace CKAN.GUI { public partial class DeleteDirectories : UserControl { diff --git a/GUI/Controls/DropdownMenuButton.cs b/GUI/Controls/DropdownMenuButton.cs index d3d105945a..f99fe7c70e 100644 --- a/GUI/Controls/DropdownMenuButton.cs +++ b/GUI/Controls/DropdownMenuButton.cs @@ -2,7 +2,7 @@ using System.Drawing; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { /// <summary> /// Button with a Menu property that displays when you click diff --git a/GUI/Controls/EditModSearch.Designer.cs b/GUI/Controls/EditModSearch.Designer.cs index 4d5866e1b4..d59133353c 100644 --- a/GUI/Controls/EditModSearch.Designer.cs +++ b/GUI/Controls/EditModSearch.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class EditModSearch { @@ -34,9 +34,9 @@ private void InitializeComponent() this.ToolTip = new System.Windows.Forms.ToolTip(); this.FilterCombinedLabel = new System.Windows.Forms.Label(); this.FilterOrLabel = new System.Windows.Forms.Label(); - this.FilterCombinedTextBox = new CKAN.HintTextBox(); + this.FilterCombinedTextBox = new CKAN.GUI.HintTextBox(); this.ExpandButton = new System.Windows.Forms.CheckBox(); - this.SearchDetails = new CKAN.EditModSearchDetails(); + this.SearchDetails = new CKAN.GUI.EditModSearchDetails(); this.SuspendLayout(); // // ToolTip @@ -127,8 +127,8 @@ private void InitializeComponent() private System.Windows.Forms.ToolTip ToolTip; private System.Windows.Forms.Label FilterCombinedLabel; private System.Windows.Forms.Label FilterOrLabel; - private CKAN.HintTextBox FilterCombinedTextBox; + private CKAN.GUI.HintTextBox FilterCombinedTextBox; private System.Windows.Forms.CheckBox ExpandButton; - private CKAN.EditModSearchDetails SearchDetails; + private CKAN.GUI.EditModSearchDetails SearchDetails; } } diff --git a/GUI/Controls/EditModSearch.cs b/GUI/Controls/EditModSearch.cs index c34120bf89..366da72a37 100644 --- a/GUI/Controls/EditModSearch.cs +++ b/GUI/Controls/EditModSearch.cs @@ -6,7 +6,7 @@ using Timer = System.Windows.Forms.Timer; using log4net; -namespace CKAN +namespace CKAN.GUI { /// <summary> /// A control for displaying and editing a search of mods. diff --git a/GUI/Controls/EditModSearchDetails.Designer.cs b/GUI/Controls/EditModSearchDetails.Designer.cs index 66264bd87d..cbd5484dae 100644 --- a/GUI/Controls/EditModSearchDetails.Designer.cs +++ b/GUI/Controls/EditModSearchDetails.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class EditModSearchDetails { @@ -31,37 +31,37 @@ private void InitializeComponent() this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new SingleAssemblyComponentResourceManager(typeof(EditModSearchDetails)); this.FilterByNameLabel = new System.Windows.Forms.Label(); - this.FilterByNameTextBox = new CKAN.HintTextBox(); + this.FilterByNameTextBox = new CKAN.GUI.HintTextBox(); this.FilterByAuthorLabel = new System.Windows.Forms.Label(); - this.FilterByAuthorTextBox = new CKAN.HintTextBox(); + this.FilterByAuthorTextBox = new CKAN.GUI.HintTextBox(); this.FilterByDescriptionLabel = new System.Windows.Forms.Label(); - this.FilterByDescriptionTextBox = new CKAN.HintTextBox(); + this.FilterByDescriptionTextBox = new CKAN.GUI.HintTextBox(); this.FilterByLanguageLabel = new System.Windows.Forms.Label(); - this.FilterByLanguageTextBox = new CKAN.HintTextBox(); + this.FilterByLanguageTextBox = new CKAN.GUI.HintTextBox(); this.FilterByDependsLabel = new System.Windows.Forms.Label(); - this.FilterByDependsTextBox = new CKAN.HintTextBox(); + this.FilterByDependsTextBox = new CKAN.GUI.HintTextBox(); this.FilterByRecommendsLabel = new System.Windows.Forms.Label(); - this.FilterByRecommendsTextBox = new CKAN.HintTextBox(); + this.FilterByRecommendsTextBox = new CKAN.GUI.HintTextBox(); this.FilterBySuggestsLabel = new System.Windows.Forms.Label(); - this.FilterBySuggestsTextBox = new CKAN.HintTextBox(); + this.FilterBySuggestsTextBox = new CKAN.GUI.HintTextBox(); this.FilterByConflictsLabel = new System.Windows.Forms.Label(); - this.FilterByConflictsTextBox = new CKAN.HintTextBox(); + this.FilterByConflictsTextBox = new CKAN.GUI.HintTextBox(); this.FilterByTagsLabel = new System.Windows.Forms.Label(); - this.FilterByTagsTextBox = new CKAN.HintTextBox(); + this.FilterByTagsTextBox = new CKAN.GUI.HintTextBox(); this.FilterByLabelsLabel = new System.Windows.Forms.Label(); - this.FilterByLabelsTextBox = new CKAN.HintTextBox(); + this.FilterByLabelsTextBox = new CKAN.GUI.HintTextBox(); this.CompatibleLabel = new System.Windows.Forms.Label(); - this.CompatibleToggle = new CKAN.TriStateToggle(); + this.CompatibleToggle = new CKAN.GUI.TriStateToggle(); this.InstalledLabel = new System.Windows.Forms.Label(); - this.InstalledToggle = new CKAN.TriStateToggle(); + this.InstalledToggle = new CKAN.GUI.TriStateToggle(); this.CachedLabel = new System.Windows.Forms.Label(); - this.CachedToggle = new CKAN.TriStateToggle(); + this.CachedToggle = new CKAN.GUI.TriStateToggle(); this.NewlyCompatibleLabel = new System.Windows.Forms.Label(); - this.NewlyCompatibleToggle = new CKAN.TriStateToggle(); + this.NewlyCompatibleToggle = new CKAN.GUI.TriStateToggle(); this.UpgradeableLabel = new System.Windows.Forms.Label(); - this.UpgradeableToggle = new CKAN.TriStateToggle(); + this.UpgradeableToggle = new CKAN.GUI.TriStateToggle(); this.ReplaceableLabel = new System.Windows.Forms.Label(); - this.ReplaceableToggle = new CKAN.TriStateToggle(); + this.ReplaceableToggle = new CKAN.GUI.TriStateToggle(); this.SuspendLayout(); // // FilterByNameLabel @@ -448,36 +448,36 @@ private void InitializeComponent() #endregion private System.Windows.Forms.Label FilterByNameLabel; - internal CKAN.HintTextBox FilterByNameTextBox; + internal CKAN.GUI.HintTextBox FilterByNameTextBox; private System.Windows.Forms.Label FilterByAuthorLabel; - internal CKAN.HintTextBox FilterByAuthorTextBox; + internal CKAN.GUI.HintTextBox FilterByAuthorTextBox; private System.Windows.Forms.Label FilterByDescriptionLabel; - internal CKAN.HintTextBox FilterByDescriptionTextBox; + internal CKAN.GUI.HintTextBox FilterByDescriptionTextBox; private System.Windows.Forms.Label FilterByLanguageLabel; - internal CKAN.HintTextBox FilterByLanguageTextBox; + internal CKAN.GUI.HintTextBox FilterByLanguageTextBox; private System.Windows.Forms.Label FilterByDependsLabel; - internal CKAN.HintTextBox FilterByDependsTextBox; + internal CKAN.GUI.HintTextBox FilterByDependsTextBox; private System.Windows.Forms.Label FilterByRecommendsLabel; - internal CKAN.HintTextBox FilterByRecommendsTextBox; + internal CKAN.GUI.HintTextBox FilterByRecommendsTextBox; private System.Windows.Forms.Label FilterBySuggestsLabel; - internal CKAN.HintTextBox FilterBySuggestsTextBox; + internal CKAN.GUI.HintTextBox FilterBySuggestsTextBox; private System.Windows.Forms.Label FilterByConflictsLabel; - internal CKAN.HintTextBox FilterByConflictsTextBox; + internal CKAN.GUI.HintTextBox FilterByConflictsTextBox; private System.Windows.Forms.Label FilterByTagsLabel; - internal CKAN.HintTextBox FilterByTagsTextBox; + internal CKAN.GUI.HintTextBox FilterByTagsTextBox; private System.Windows.Forms.Label FilterByLabelsLabel; - internal CKAN.HintTextBox FilterByLabelsTextBox; + internal CKAN.GUI.HintTextBox FilterByLabelsTextBox; private System.Windows.Forms.Label CompatibleLabel; - internal CKAN.TriStateToggle CompatibleToggle; + internal CKAN.GUI.TriStateToggle CompatibleToggle; private System.Windows.Forms.Label InstalledLabel; - internal CKAN.TriStateToggle InstalledToggle; + internal CKAN.GUI.TriStateToggle InstalledToggle; private System.Windows.Forms.Label CachedLabel; - internal CKAN.TriStateToggle CachedToggle; + internal CKAN.GUI.TriStateToggle CachedToggle; private System.Windows.Forms.Label NewlyCompatibleLabel; - internal CKAN.TriStateToggle NewlyCompatibleToggle; + internal CKAN.GUI.TriStateToggle NewlyCompatibleToggle; private System.Windows.Forms.Label UpgradeableLabel; - internal CKAN.TriStateToggle UpgradeableToggle; + internal CKAN.GUI.TriStateToggle UpgradeableToggle; private System.Windows.Forms.Label ReplaceableLabel; - internal CKAN.TriStateToggle ReplaceableToggle; + internal CKAN.GUI.TriStateToggle ReplaceableToggle; } } diff --git a/GUI/Controls/EditModSearchDetails.cs b/GUI/Controls/EditModSearchDetails.cs index 370d5f03a9..ae69940bde 100644 --- a/GUI/Controls/EditModSearchDetails.cs +++ b/GUI/Controls/EditModSearchDetails.cs @@ -3,7 +3,7 @@ using System.Windows.Forms; using log4net; -namespace CKAN +namespace CKAN.GUI { /// <summary> /// A control for displaying and editing a search of mods. diff --git a/GUI/Controls/EditModSearches.Designer.cs b/GUI/Controls/EditModSearches.Designer.cs index 450a662ebc..9a5e12cd99 100644 --- a/GUI/Controls/EditModSearches.Designer.cs +++ b/GUI/Controls/EditModSearches.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class EditModSearches { diff --git a/GUI/Controls/EditModSearches.cs b/GUI/Controls/EditModSearches.cs index ce3e4eaba5..cf6f5b3590 100644 --- a/GUI/Controls/EditModSearches.cs +++ b/GUI/Controls/EditModSearches.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { /// <summary> /// A container control for the individual EditModSearch controls diff --git a/GUI/Controls/EditModpack.Designer.cs b/GUI/Controls/EditModpack.Designer.cs index 121725f132..e5a363e7a9 100644 --- a/GUI/Controls/EditModpack.Designer.cs +++ b/GUI/Controls/EditModpack.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class EditModpack { diff --git a/GUI/Controls/EditModpack.cs b/GUI/Controls/EditModpack.cs index a4156b2871..fa5ca963b3 100644 --- a/GUI/Controls/EditModpack.cs +++ b/GUI/Controls/EditModpack.cs @@ -8,7 +8,7 @@ using CKAN.GameVersionProviders; using CKAN.Types; -namespace CKAN +namespace CKAN.GUI { public partial class EditModpack : UserControl { diff --git a/GUI/Controls/HintTextBox.Designer.cs b/GUI/Controls/HintTextBox.Designer.cs index 3a491cce8c..2001a433fb 100644 --- a/GUI/Controls/HintTextBox.Designer.cs +++ b/GUI/Controls/HintTextBox.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class HintTextBox { @@ -36,7 +36,7 @@ private void InitializeComponent() this.ClearIcon.BackColor = System.Drawing.Color.Transparent; this.ClearIcon.Visible = false; this.ClearIcon.Cursor = System.Windows.Forms.Cursors.Hand; - this.ClearIcon.Image = global::CKAN.Properties.Resources.textClear; + this.ClearIcon.Image = global::CKAN.GUI.Properties.Resources.textClear; this.ClearIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; this.ClearIcon.Size = new System.Drawing.Size(18, 18); this.ClearIcon.Click += HintClearIcon_Click; diff --git a/GUI/Controls/HintTextBox.cs b/GUI/Controls/HintTextBox.cs index 9a7c491d2e..c1b25057af 100644 --- a/GUI/Controls/HintTextBox.cs +++ b/GUI/Controls/HintTextBox.cs @@ -2,7 +2,7 @@ using System.Drawing; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { /// <summary> /// A textbox which shows a "clear text" icon on the right side diff --git a/GUI/Controls/ManageMods.Designer.cs b/GUI/Controls/ManageMods.Designer.cs index 1a83ab9e49..3b366df6e9 100644 --- a/GUI/Controls/ManageMods.Designer.cs +++ b/GUI/Controls/ManageMods.Designer.cs @@ -1,6 +1,6 @@ using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { partial class ManageMods { @@ -53,7 +53,7 @@ private void InitializeComponent() this.FilterTagsToolButton = new System.Windows.Forms.ToolStripMenuItem(); this.NavBackwardToolButton = new System.Windows.Forms.ToolStripMenuItem(); this.NavForwardToolButton = new System.Windows.Forms.ToolStripMenuItem(); - this.EditModSearches = new CKAN.EditModSearches(); + this.EditModSearches = new CKAN.GUI.EditModSearches(); this.ModGrid = new System.Windows.Forms.DataGridView(); this.InstallAllCheckbox = new System.Windows.Forms.CheckBox(); this.Installed = new System.Windows.Forms.DataGridViewCheckBoxColumn(); @@ -119,7 +119,7 @@ private void InitializeComponent() // // launchGameToolStripMenuItem // - this.launchGameToolStripMenuItem.Image = global::CKAN.Properties.Resources.ksp; + this.launchGameToolStripMenuItem.Image = global::CKAN.GUI.Properties.Resources.ksp; this.launchGameToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; this.launchGameToolStripMenuItem.Name = "launchGameToolStripMenuItem"; this.launchGameToolStripMenuItem.Size = new System.Drawing.Size(146, 56); @@ -129,7 +129,7 @@ private void InitializeComponent() // // RefreshToolButton // - this.RefreshToolButton.Image = global::CKAN.Properties.Resources.refresh; + this.RefreshToolButton.Image = global::CKAN.GUI.Properties.Resources.refresh; this.RefreshToolButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; this.RefreshToolButton.Name = "RefreshToolButton"; this.RefreshToolButton.Size = new System.Drawing.Size(114, 56); @@ -139,7 +139,7 @@ private void InitializeComponent() // // UpdateAllToolButton // - this.UpdateAllToolButton.Image = global::CKAN.Properties.Resources.update; + this.UpdateAllToolButton.Image = global::CKAN.GUI.Properties.Resources.update; this.UpdateAllToolButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; this.UpdateAllToolButton.Name = "UpdateAllToolButton"; this.UpdateAllToolButton.Size = new System.Drawing.Size(232, 56); @@ -149,7 +149,7 @@ private void InitializeComponent() // // ApplyToolButton // - this.ApplyToolButton.Image = global::CKAN.Properties.Resources.apply; + this.ApplyToolButton.Image = global::CKAN.GUI.Properties.Resources.apply; this.ApplyToolButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; this.ApplyToolButton.Name = "ApplyToolButton"; this.ApplyToolButton.Size = new System.Drawing.Size(173, 56); @@ -174,7 +174,7 @@ private void InitializeComponent() this.FilterTagsToolButton, this.FilterLabelsToolButton}); this.FilterToolButton.DropDown.Opening += new System.ComponentModel.CancelEventHandler(FilterToolButton_DropDown_Opening); - this.FilterToolButton.Image = global::CKAN.Properties.Resources.filter; + this.FilterToolButton.Image = global::CKAN.GUI.Properties.Resources.filter; this.FilterToolButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; this.FilterToolButton.Name = "FilterToolButton"; this.FilterToolButton.Size = new System.Drawing.Size(201, 56); @@ -267,7 +267,7 @@ private void InitializeComponent() // // NavBackwardToolButton // - this.NavBackwardToolButton.Image = global::CKAN.Properties.Resources.backward; + this.NavBackwardToolButton.Image = global::CKAN.GUI.Properties.Resources.backward; this.NavBackwardToolButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; this.NavBackwardToolButton.Name = "NavBackwardToolButton"; this.NavBackwardToolButton.Size = new System.Drawing.Size(44, 56); @@ -277,7 +277,7 @@ private void InitializeComponent() // // NavForwardToolButton // - this.NavForwardToolButton.Image = global::CKAN.Properties.Resources.forward; + this.NavForwardToolButton.Image = global::CKAN.GUI.Properties.Resources.forward; this.NavForwardToolButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; this.NavForwardToolButton.Name = "NavForwardToolButton"; this.NavForwardToolButton.Size = new System.Drawing.Size(44, 56); @@ -608,6 +608,6 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem reinstallToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem downloadContentsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem purgeContentsToolStripMenuItem; - private CKAN.EditModSearches EditModSearches; + private CKAN.GUI.EditModSearches EditModSearches; } } diff --git a/GUI/Controls/ManageMods.cs b/GUI/Controls/ManageMods.cs index 464235d97f..c44a978cb5 100644 --- a/GUI/Controls/ManageMods.cs +++ b/GUI/Controls/ManageMods.cs @@ -8,7 +8,7 @@ using log4net; using CKAN.Versioning; -namespace CKAN +namespace CKAN.GUI { public partial class ManageMods : UserControl { diff --git a/GUI/Controls/ModInfo.Designer.cs b/GUI/Controls/ModInfo.Designer.cs index b45b5a812e..802c93d96b 100644 --- a/GUI/Controls/ModInfo.Designer.cs +++ b/GUI/Controls/ModInfo.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class ModInfo { @@ -71,7 +71,7 @@ private void InitializeComponent() this.ContentsOpenButton = new System.Windows.Forms.Button(); this.NotCachedLabel = new System.Windows.Forms.Label(); this.AllModVersionsTabPage = new System.Windows.Forms.TabPage(); - this.AllModVersions = new CKAN.AllModVersions(); + this.AllModVersions = new CKAN.GUI.AllModVersions(); this.ModInfoTabControl.SuspendLayout(); this.MetadataTabPage.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit(); @@ -455,17 +455,17 @@ private void InitializeComponent() // ImageList's default makes icons look like garbage ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit }; - this.DependsGraphTree.ImageList.Images.Add("Root", global::CKAN.Properties.Resources.ksp); - this.DependsGraphTree.ImageList.Images.Add("Depends", global::CKAN.Properties.Resources.star); - this.DependsGraphTree.ImageList.Images.Add("Recommends", global::CKAN.Properties.Resources.thumbup); - this.DependsGraphTree.ImageList.Images.Add("Suggests", global::CKAN.Properties.Resources.info); - this.DependsGraphTree.ImageList.Images.Add("Supports", global::CKAN.Properties.Resources.smile); - this.DependsGraphTree.ImageList.Images.Add("Conflicts", global::CKAN.Properties.Resources.alert); + this.DependsGraphTree.ImageList.Images.Add("Root", global::CKAN.GUI.Properties.Resources.ksp); + this.DependsGraphTree.ImageList.Images.Add("Depends", global::CKAN.GUI.Properties.Resources.star); + this.DependsGraphTree.ImageList.Images.Add("Recommends", global::CKAN.GUI.Properties.Resources.thumbup); + this.DependsGraphTree.ImageList.Images.Add("Suggests", global::CKAN.GUI.Properties.Resources.info); + this.DependsGraphTree.ImageList.Images.Add("Supports", global::CKAN.GUI.Properties.Resources.smile); + this.DependsGraphTree.ImageList.Images.Add("Conflicts", global::CKAN.GUI.Properties.Resources.alert); // // LegendDependsImage // this.LegendDependsImage.BackColor = System.Drawing.SystemColors.Window; - this.LegendDependsImage.Image = global::CKAN.Properties.Resources.star; + this.LegendDependsImage.Image = global::CKAN.GUI.Properties.Resources.star; this.LegendDependsImage.Location = new System.Drawing.Point(6, 3); this.LegendDependsImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.LegendDependsImage.ClientSize = new System.Drawing.Size(14, 14); @@ -473,7 +473,7 @@ private void InitializeComponent() // LegendRecommendsImage // this.LegendRecommendsImage.BackColor = System.Drawing.SystemColors.Window; - this.LegendRecommendsImage.Image = global::CKAN.Properties.Resources.thumbup; + this.LegendRecommendsImage.Image = global::CKAN.GUI.Properties.Resources.thumbup; this.LegendRecommendsImage.Location = new System.Drawing.Point(6, 21); this.LegendRecommendsImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.LegendRecommendsImage.ClientSize = new System.Drawing.Size(14, 14); @@ -481,7 +481,7 @@ private void InitializeComponent() // LegendSuggestsImage // this.LegendSuggestsImage.BackColor = System.Drawing.SystemColors.Window; - this.LegendSuggestsImage.Image = global::CKAN.Properties.Resources.info; + this.LegendSuggestsImage.Image = global::CKAN.GUI.Properties.Resources.info; this.LegendSuggestsImage.Location = new System.Drawing.Point(6, 39); this.LegendSuggestsImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.LegendSuggestsImage.ClientSize = new System.Drawing.Size(14, 14); @@ -489,7 +489,7 @@ private void InitializeComponent() // LegendSupportsImage // this.LegendSupportsImage.BackColor = System.Drawing.SystemColors.Window; - this.LegendSupportsImage.Image = global::CKAN.Properties.Resources.smile; + this.LegendSupportsImage.Image = global::CKAN.GUI.Properties.Resources.smile; this.LegendSupportsImage.Location = new System.Drawing.Point(6, 57); this.LegendSupportsImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.LegendSupportsImage.ClientSize = new System.Drawing.Size(14, 14); @@ -497,7 +497,7 @@ private void InitializeComponent() // LegendConflictsImage // this.LegendConflictsImage.BackColor = System.Drawing.SystemColors.Window; - this.LegendConflictsImage.Image = global::CKAN.Properties.Resources.alert; + this.LegendConflictsImage.Image = global::CKAN.GUI.Properties.Resources.alert; this.LegendConflictsImage.Location = new System.Drawing.Point(6, 75); this.LegendConflictsImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.LegendConflictsImage.ClientSize = new System.Drawing.Size(14, 14); @@ -683,6 +683,6 @@ private void InitializeComponent() private System.Windows.Forms.Button ContentsOpenButton; private System.Windows.Forms.Label NotCachedLabel; private System.Windows.Forms.TabPage AllModVersionsTabPage; - private AllModVersions AllModVersions; + private CKAN.GUI.AllModVersions AllModVersions; } } diff --git a/GUI/Controls/ModInfo.cs b/GUI/Controls/ModInfo.cs index 2abbc74a8e..4deffad168 100644 --- a/GUI/Controls/ModInfo.cs +++ b/GUI/Controls/ModInfo.cs @@ -7,7 +7,7 @@ using System.IO; using CKAN.Versioning; -namespace CKAN +namespace CKAN.GUI { public enum RelationshipType { diff --git a/GUI/Controls/PlayTime.Designer.cs b/GUI/Controls/PlayTime.Designer.cs index 002288a99a..9049caf031 100755 --- a/GUI/Controls/PlayTime.Designer.cs +++ b/GUI/Controls/PlayTime.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class PlayTime { diff --git a/GUI/Controls/PlayTime.cs b/GUI/Controls/PlayTime.cs index 09aaf27505..0a1acbca4f 100755 --- a/GUI/Controls/PlayTime.cs +++ b/GUI/Controls/PlayTime.cs @@ -8,7 +8,7 @@ using CKAN.Versioning; using CKAN.Extensions; -namespace CKAN +namespace CKAN.GUI { /// <summary> /// Show the user's play time in each instance and allow editing diff --git a/GUI/Controls/ThemedListView.cs b/GUI/Controls/ThemedListView.cs index a163dae20f..8e45e884f7 100644 --- a/GUI/Controls/ThemedListView.cs +++ b/GUI/Controls/ThemedListView.cs @@ -1,7 +1,7 @@ using System.Drawing; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { /// <summary> /// A ListView that obeys system colors to look less awful in a dark theme diff --git a/GUI/Controls/ThemedTabControl.cs b/GUI/Controls/ThemedTabControl.cs index 17503f4dac..90215ec0e5 100644 --- a/GUI/Controls/ThemedTabControl.cs +++ b/GUI/Controls/ThemedTabControl.cs @@ -2,7 +2,7 @@ using System.Drawing; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { /// <summary> /// A TabControl that obeys system colors to look less awful in a dark theme diff --git a/GUI/Controls/TransparentTextBox.cs b/GUI/Controls/TransparentTextBox.cs index 0022a9b80c..750e462a69 100644 --- a/GUI/Controls/TransparentTextBox.cs +++ b/GUI/Controls/TransparentTextBox.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { /// <summary> /// Create a new TransparentTextBox control that allows the backcolor of textboxes to be transparent. diff --git a/GUI/Controls/TriStateToggle.cs b/GUI/Controls/TriStateToggle.cs index 0bc4d3fdf2..deaaee2052 100644 --- a/GUI/Controls/TriStateToggle.cs +++ b/GUI/Controls/TriStateToggle.cs @@ -2,7 +2,7 @@ using System.Drawing; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public class TriStateToggle : UserControl { diff --git a/GUI/Controls/Wait.Designer.cs b/GUI/Controls/Wait.Designer.cs index d7e7f4b3ca..a48c506d8f 100644 --- a/GUI/Controls/Wait.Designer.cs +++ b/GUI/Controls/Wait.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class Wait { diff --git a/GUI/Controls/Wait.cs b/GUI/Controls/Wait.cs index 0cfe64a2e2..7fe1265fed 100644 --- a/GUI/Controls/Wait.cs +++ b/GUI/Controls/Wait.cs @@ -5,7 +5,7 @@ using System.Windows.Forms; using Timer = System.Windows.Forms.Timer; -namespace CKAN +namespace CKAN.GUI { public partial class Wait : UserControl { diff --git a/GUI/Dialogs/AboutDialog.Designer.cs b/GUI/Dialogs/AboutDialog.Designer.cs index 1e21bce130..5fbb5861d1 100644 --- a/GUI/Dialogs/AboutDialog.Designer.cs +++ b/GUI/Dialogs/AboutDialog.Designer.cs @@ -1,7 +1,7 @@ using System; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { partial class AboutDialog { diff --git a/GUI/Dialogs/AboutDialog.cs b/GUI/Dialogs/AboutDialog.cs index ce09e36761..1e515cfeff 100644 --- a/GUI/Dialogs/AboutDialog.cs +++ b/GUI/Dialogs/AboutDialog.cs @@ -1,6 +1,6 @@ using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public partial class AboutDialog : FormCompatibility { diff --git a/GUI/Dialogs/AskUserForAutoUpdatesDialog.Designer.cs b/GUI/Dialogs/AskUserForAutoUpdatesDialog.Designer.cs index 6c3711121a..ea4abcf781 100644 --- a/GUI/Dialogs/AskUserForAutoUpdatesDialog.Designer.cs +++ b/GUI/Dialogs/AskUserForAutoUpdatesDialog.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class AskUserForAutoUpdatesDialog { diff --git a/GUI/Dialogs/AskUserForAutoUpdatesDialog.cs b/GUI/Dialogs/AskUserForAutoUpdatesDialog.cs index f1df19bb23..65cfa1109e 100644 --- a/GUI/Dialogs/AskUserForAutoUpdatesDialog.cs +++ b/GUI/Dialogs/AskUserForAutoUpdatesDialog.cs @@ -1,6 +1,6 @@ using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public partial class AskUserForAutoUpdatesDialog : Form { diff --git a/GUI/Dialogs/CloneFakeGameDialog.Designer.cs b/GUI/Dialogs/CloneFakeGameDialog.Designer.cs index 93e89d9e8a..29c46fd177 100644 --- a/GUI/Dialogs/CloneFakeGameDialog.Designer.cs +++ b/GUI/Dialogs/CloneFakeGameDialog.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class CloneFakeGameDialog { diff --git a/GUI/Dialogs/CloneFakeGameDialog.cs b/GUI/Dialogs/CloneFakeGameDialog.cs index 7908e6a071..3399333d16 100644 --- a/GUI/Dialogs/CloneFakeGameDialog.cs +++ b/GUI/Dialogs/CloneFakeGameDialog.cs @@ -9,7 +9,7 @@ using CKAN.Versioning; using CKAN.Games; -namespace CKAN +namespace CKAN.GUI { /// <summary> /// The GUI implementation of clone and fake. diff --git a/GUI/Dialogs/CompatibleGameVersionsDialog.Designer.cs b/GUI/Dialogs/CompatibleGameVersionsDialog.Designer.cs index 75f0fb1965..da220e86d6 100644 --- a/GUI/Dialogs/CompatibleGameVersionsDialog.Designer.cs +++ b/GUI/Dialogs/CompatibleGameVersionsDialog.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class CompatibleGameVersionsDialog { diff --git a/GUI/Dialogs/CompatibleGameVersionsDialog.cs b/GUI/Dialogs/CompatibleGameVersionsDialog.cs index 60f37056ff..5e5e965670 100644 --- a/GUI/Dialogs/CompatibleGameVersionsDialog.cs +++ b/GUI/Dialogs/CompatibleGameVersionsDialog.cs @@ -8,7 +8,7 @@ using CKAN.Versioning; using CKAN.GameVersionProviders; -namespace CKAN +namespace CKAN.GUI { public partial class CompatibleGameVersionsDialog : Form { diff --git a/GUI/Dialogs/EditLabelsDialog.Designer.cs b/GUI/Dialogs/EditLabelsDialog.Designer.cs index 1f401219fc..213ad6b1f7 100644 --- a/GUI/Dialogs/EditLabelsDialog.Designer.cs +++ b/GUI/Dialogs/EditLabelsDialog.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class EditLabelsDialog { diff --git a/GUI/Dialogs/EditLabelsDialog.cs b/GUI/Dialogs/EditLabelsDialog.cs index 1f2dd8d3b9..6fffd78ae3 100644 --- a/GUI/Dialogs/EditLabelsDialog.cs +++ b/GUI/Dialogs/EditLabelsDialog.cs @@ -5,7 +5,7 @@ using System.Windows.Forms; using log4net; -namespace CKAN +namespace CKAN.GUI { public partial class EditLabelsDialog : Form { diff --git a/GUI/Dialogs/ErrorDialog.Designer.cs b/GUI/Dialogs/ErrorDialog.Designer.cs index 8244bc294f..b1c8562789 100644 --- a/GUI/Dialogs/ErrorDialog.Designer.cs +++ b/GUI/Dialogs/ErrorDialog.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class ErrorDialog { diff --git a/GUI/Dialogs/ErrorDialog.cs b/GUI/Dialogs/ErrorDialog.cs index 89db289f65..1dbc198d86 100644 --- a/GUI/Dialogs/ErrorDialog.cs +++ b/GUI/Dialogs/ErrorDialog.cs @@ -3,7 +3,7 @@ using System.Windows.Forms; using log4net; -namespace CKAN +namespace CKAN.GUI { public partial class ErrorDialog : Form { diff --git a/GUI/Dialogs/GameCommandLineOptionsDialog.Designer.cs b/GUI/Dialogs/GameCommandLineOptionsDialog.Designer.cs index 8f4cea8217..1f24601b7a 100644 --- a/GUI/Dialogs/GameCommandLineOptionsDialog.Designer.cs +++ b/GUI/Dialogs/GameCommandLineOptionsDialog.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class GameCommandLineOptionsDialog { diff --git a/GUI/Dialogs/GameCommandLineOptionsDialog.cs b/GUI/Dialogs/GameCommandLineOptionsDialog.cs index 3d85b80595..bd4c50a430 100644 --- a/GUI/Dialogs/GameCommandLineOptionsDialog.cs +++ b/GUI/Dialogs/GameCommandLineOptionsDialog.cs @@ -1,6 +1,6 @@ using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public partial class GameCommandLineOptionsDialog : Form diff --git a/GUI/Dialogs/InstallFiltersDialog.Designer.cs b/GUI/Dialogs/InstallFiltersDialog.Designer.cs index a24d2ed168..a3c7ae8470 100644 --- a/GUI/Dialogs/InstallFiltersDialog.Designer.cs +++ b/GUI/Dialogs/InstallFiltersDialog.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class InstallFiltersDialog { diff --git a/GUI/Dialogs/InstallFiltersDialog.cs b/GUI/Dialogs/InstallFiltersDialog.cs index 0b657bc4c3..8846b871fd 100644 --- a/GUI/Dialogs/InstallFiltersDialog.cs +++ b/GUI/Dialogs/InstallFiltersDialog.cs @@ -5,7 +5,7 @@ using CKAN.Configuration; -namespace CKAN +namespace CKAN.GUI { public partial class InstallFiltersDialog : Form { diff --git a/GUI/Dialogs/ManageGameInstancesDialog.Designer.cs b/GUI/Dialogs/ManageGameInstancesDialog.Designer.cs index 0bac64dbb6..200e76101b 100644 --- a/GUI/Dialogs/ManageGameInstancesDialog.Designer.cs +++ b/GUI/Dialogs/ManageGameInstancesDialog.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class ManageGameInstancesDialog { @@ -41,7 +41,7 @@ private void InitializeComponent() this.GamePlayTime = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.GameInstallPath = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.SelectButton = new System.Windows.Forms.Button(); - this.AddNewButton = new CKAN.DropdownMenuButton(); + this.AddNewButton = new CKAN.GUI.DropdownMenuButton(); this.AddNewMenu = new System.Windows.Forms.ContextMenuStrip(this.components); this.InstanceListContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); this.openDirectoryMenuItem = new System.Windows.Forms.ToolStripMenuItem(); diff --git a/GUI/Dialogs/ManageGameInstancesDialog.cs b/GUI/Dialogs/ManageGameInstancesDialog.cs index 3220fd40d2..cf4152fcf1 100644 --- a/GUI/Dialogs/ManageGameInstancesDialog.cs +++ b/GUI/Dialogs/ManageGameInstancesDialog.cs @@ -7,7 +7,7 @@ using CKAN.Versioning; -namespace CKAN +namespace CKAN.GUI { public partial class ManageGameInstancesDialog : Form { diff --git a/GUI/Dialogs/NewRepoDialog.Designer.cs b/GUI/Dialogs/NewRepoDialog.Designer.cs index 60b90b0163..dfc8e2b0d3 100644 --- a/GUI/Dialogs/NewRepoDialog.Designer.cs +++ b/GUI/Dialogs/NewRepoDialog.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class NewRepoDialog { diff --git a/GUI/Dialogs/NewRepoDialog.cs b/GUI/Dialogs/NewRepoDialog.cs index d55af89bf4..a51bf9012c 100644 --- a/GUI/Dialogs/NewRepoDialog.cs +++ b/GUI/Dialogs/NewRepoDialog.cs @@ -2,7 +2,7 @@ using System.Linq; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public partial class NewRepoDialog : Form { diff --git a/GUI/Dialogs/NewUpdateDialog.Designer.cs b/GUI/Dialogs/NewUpdateDialog.Designer.cs index f7b27594b8..a6185c2b0e 100644 --- a/GUI/Dialogs/NewUpdateDialog.Designer.cs +++ b/GUI/Dialogs/NewUpdateDialog.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class NewUpdateDialog { diff --git a/GUI/Dialogs/NewUpdateDialog.cs b/GUI/Dialogs/NewUpdateDialog.cs index c5f443b3b4..85aea2decf 100644 --- a/GUI/Dialogs/NewUpdateDialog.cs +++ b/GUI/Dialogs/NewUpdateDialog.cs @@ -1,6 +1,6 @@ using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public partial class NewUpdateDialog : Form { diff --git a/GUI/Dialogs/PluginsDialog.Designer.cs b/GUI/Dialogs/PluginsDialog.Designer.cs index d9d55b2f30..4820316f9d 100644 --- a/GUI/Dialogs/PluginsDialog.Designer.cs +++ b/GUI/Dialogs/PluginsDialog.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class PluginsDialog { diff --git a/GUI/Dialogs/PluginsDialog.cs b/GUI/Dialogs/PluginsDialog.cs index 3fdc83ce0e..cf189a4247 100644 --- a/GUI/Dialogs/PluginsDialog.cs +++ b/GUI/Dialogs/PluginsDialog.cs @@ -1,7 +1,7 @@ using System; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public partial class PluginsDialog : Form { diff --git a/GUI/Dialogs/RenameInstanceDialog.Designer.cs b/GUI/Dialogs/RenameInstanceDialog.Designer.cs index 57d370b4fb..1ba866d4a2 100644 --- a/GUI/Dialogs/RenameInstanceDialog.Designer.cs +++ b/GUI/Dialogs/RenameInstanceDialog.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class RenameInstanceDialog { diff --git a/GUI/Dialogs/RenameInstanceDialog.cs b/GUI/Dialogs/RenameInstanceDialog.cs index b6e7238e37..eab8d46edc 100644 --- a/GUI/Dialogs/RenameInstanceDialog.cs +++ b/GUI/Dialogs/RenameInstanceDialog.cs @@ -1,6 +1,6 @@ using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public partial class RenameInstanceDialog : Form { diff --git a/GUI/Dialogs/RenameInstanceDialog.resx b/GUI/Dialogs/RenameInstanceDialog.resx index afd112238e..96e018c806 100644 --- a/GUI/Dialogs/RenameInstanceDialog.resx +++ b/GUI/Dialogs/RenameInstanceDialog.resx @@ -116,7 +116,7 @@ </resheader> <resheader name="writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader>/> + </resheader> <data name="OKButton.Text" xml:space="preserve"><value>OK</value></data> <data name="CancelRenameInstanceButton.Text" xml:space="preserve"><value>Cancel</value></data> <data name="$this.Text" xml:space="preserve"><value>Rename installation</value></data> diff --git a/GUI/Dialogs/SelectionDialog.Designer.cs b/GUI/Dialogs/SelectionDialog.Designer.cs index 6a7cbef307..aa9bc5b22a 100644 --- a/GUI/Dialogs/SelectionDialog.Designer.cs +++ b/GUI/Dialogs/SelectionDialog.Designer.cs @@ -1,6 +1,6 @@ using System; -namespace CKAN +namespace CKAN.GUI { partial class SelectionDialog { diff --git a/GUI/Dialogs/SelectionDialog.cs b/GUI/Dialogs/SelectionDialog.cs index 1a8f04278b..d70a234ddf 100644 --- a/GUI/Dialogs/SelectionDialog.cs +++ b/GUI/Dialogs/SelectionDialog.cs @@ -1,7 +1,7 @@ using System; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public partial class SelectionDialog : Form { diff --git a/GUI/Dialogs/SettingsDialog.Designer.cs b/GUI/Dialogs/SettingsDialog.Designer.cs index d74feecf92..7e169a9c21 100644 --- a/GUI/Dialogs/SettingsDialog.Designer.cs +++ b/GUI/Dialogs/SettingsDialog.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class SettingsDialog { @@ -51,7 +51,7 @@ private void InitializeComponent() this.CacheLimit = new System.Windows.Forms.TextBox(); this.CacheLimitPostLabel = new System.Windows.Forms.Label(); this.ChangeCacheButton = new System.Windows.Forms.Button(); - this.ClearCacheButton = new CKAN.DropdownMenuButton(); + this.ClearCacheButton = new CKAN.GUI.DropdownMenuButton(); this.ClearCacheMenu = new System.Windows.Forms.ContextMenuStrip(this.components); this.PurgeToLimitMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.PurgeAllMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -668,7 +668,7 @@ private void InitializeComponent() private System.Windows.Forms.TextBox CacheLimit; private System.Windows.Forms.Label CacheLimitPostLabel; private System.Windows.Forms.Button ChangeCacheButton; - private CKAN.DropdownMenuButton ClearCacheButton; + private CKAN.GUI.DropdownMenuButton ClearCacheButton; private System.Windows.Forms.ContextMenuStrip ClearCacheMenu; private System.Windows.Forms.ToolStripMenuItem PurgeToLimitMenuItem; private System.Windows.Forms.ToolStripMenuItem PurgeAllMenuItem; diff --git a/GUI/Dialogs/SettingsDialog.cs b/GUI/Dialogs/SettingsDialog.cs index 739b24d451..882a4e901d 100644 --- a/GUI/Dialogs/SettingsDialog.cs +++ b/GUI/Dialogs/SettingsDialog.cs @@ -9,7 +9,7 @@ using CKAN.Versioning; using CKAN.Configuration; -namespace CKAN +namespace CKAN.GUI { public partial class SettingsDialog : Form { diff --git a/GUI/Dialogs/YesNoDialog.Designer.cs b/GUI/Dialogs/YesNoDialog.Designer.cs index dc99d70501..133d1a1c56 100644 --- a/GUI/Dialogs/YesNoDialog.Designer.cs +++ b/GUI/Dialogs/YesNoDialog.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class YesNoDialog { diff --git a/GUI/Dialogs/YesNoDialog.cs b/GUI/Dialogs/YesNoDialog.cs index d50a6a41b1..5b92ce04d6 100644 --- a/GUI/Dialogs/YesNoDialog.cs +++ b/GUI/Dialogs/YesNoDialog.cs @@ -3,7 +3,7 @@ using System.Windows.Forms; using System.Threading.Tasks; -namespace CKAN +namespace CKAN.GUI { public partial class YesNoDialog : Form { diff --git a/GUI/FlatToolStripRenderer.cs b/GUI/FlatToolStripRenderer.cs index c7054c2925..ad21418252 100644 --- a/GUI/FlatToolStripRenderer.cs +++ b/GUI/FlatToolStripRenderer.cs @@ -2,7 +2,7 @@ using System.Drawing; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { /// <summary> /// Custom toolstrip renderer that just fills the background with the BackColor. diff --git a/GUI/FormCompatibility.cs b/GUI/FormCompatibility.cs index 22b7d2c8b7..2732bf1023 100644 --- a/GUI/FormCompatibility.cs +++ b/GUI/FormCompatibility.cs @@ -1,7 +1,7 @@ using System.Drawing; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { /// <summary> /// Inheriting from this class ensures that forms are equally sized on Windows and on Linux/MacOSX diff --git a/GUI/GUIUser.cs b/GUI/GUIUser.cs index 9c97694726..2bb7e58aff 100644 --- a/GUI/GUIUser.cs +++ b/GUI/GUIUser.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { /// <summary> /// The GUI implementation of the IUser interface. diff --git a/GUI/Labels/ModuleLabel.cs b/GUI/Labels/ModuleLabel.cs index d986ee175d..3392ff6d72 100644 --- a/GUI/Labels/ModuleLabel.cs +++ b/GUI/Labels/ModuleLabel.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using Newtonsoft.Json; -namespace CKAN +namespace CKAN.GUI { [JsonObject(MemberSerialization.OptIn)] public class ModuleLabel diff --git a/GUI/Labels/ModuleLabelList.cs b/GUI/Labels/ModuleLabelList.cs index f2d2747e4e..f58e542c5c 100644 --- a/GUI/Labels/ModuleLabelList.cs +++ b/GUI/Labels/ModuleLabelList.cs @@ -6,7 +6,7 @@ using System.Runtime.Serialization; using Newtonsoft.Json; -namespace CKAN +namespace CKAN.GUI { [JsonObject(MemberSerialization.OptIn)] public class ModuleLabelList diff --git a/GUI/Localization/fr-FR/Changeset.fr-FR.resx b/GUI/Localization/fr-FR/Changeset.fr-FR.resx index a256a9b034..54a928dacf 100644 --- a/GUI/Localization/fr-FR/Changeset.fr-FR.resx +++ b/GUI/Localization/fr-FR/Changeset.fr-FR.resx @@ -120,6 +120,7 @@ <data name="Mod.Text" xml:space="preserve"><value>Mod</value></data> <data name="ChangeType.Text" xml:space="preserve"><value>Changement</value></data> <data name="Reason.Text" xml:space="preserve"><value>Raison de l'action</value></data> + <data name="BackButton.Text" xml:space="preserve"><value>Retour</value></data> <data name="CancelChangesButton.Text" xml:space="preserve"><value>Effacer</value></data> <data name="ConfirmChangesButton.Text" xml:space="preserve"><value>Appliquer</value></data> </root> diff --git a/GUI/Localization/fr-FR/CloneFakeGameDialog.fr-FR.resx b/GUI/Localization/fr-FR/CloneFakeGameDialog.fr-FR.resx index 93721ad380..3e29695931 100644 --- a/GUI/Localization/fr-FR/CloneFakeGameDialog.fr-FR.resx +++ b/GUI/Localization/fr-FR/CloneFakeGameDialog.fr-FR.resx @@ -132,7 +132,7 @@ <data name="labelNewName.Text" xml:space="preserve"><value>Nom de la nouvelle instance:</value></data> <data name="labelNewPath.Text" xml:space="preserve"><value>Chemin de la nouvelle instance:</value></data> <data name="buttonPathBrowser.Text" xml:space="preserve"><value>Parcourir</value></data> - <data name="checkBoxSetAsDefault.Text" xml:space="preserve"><value>Marquer comme par défaut</value></data> + <data name="checkBoxSetAsDefault.Text" xml:space="preserve"><value>Marquer par défaut</value></data> <data name="checkBoxSwitchInstance.Text" xml:space="preserve"><value>Basculer à la nouvelle instance</value></data> <data name="buttonOK.Text" xml:space="preserve"><value>Créer</value></data> <data name="buttonCancel.Text" xml:space="preserve"><value>Annuler</value></data> diff --git a/GUI/Localization/fr-FR/ManageGameInstancesDialog.fr-FR.resx b/GUI/Localization/fr-FR/ManageGameInstancesDialog.fr-FR.resx index 8882343cab..ec9c90a32b 100644 --- a/GUI/Localization/fr-FR/ManageGameInstancesDialog.fr-FR.resx +++ b/GUI/Localization/fr-FR/ManageGameInstancesDialog.fr-FR.resx @@ -121,7 +121,7 @@ <data name="AddToCKANMenuItem.Text" xml:space="preserve"><value>Ajouter une instance à CKAN</value></data> <data name="CloneFakeInstanceMenuItem.Text" xml:space="preserve"><value>Cloner ou falsifier une nouvelle instance</value></data> <data name="RenameButton.Text" xml:space="preserve"><value>Renommer</value></data> - <data name="SetAsDefaultCheckbox.Text" xml:space="preserve"><value>Marquer comme par défaut</value></data> + <data name="SetAsDefaultCheckbox.Text" xml:space="preserve"><value>Marquer par défaut</value></data> <data name="ForgetButton.Text" xml:space="preserve"><value>Oublier</value></data> <data name="$this.Text" xml:space="preserve"><value>Gérer les Instances de Jeu</value></data> </root> diff --git a/GUI/Localization/fr-FR/NewRepoDialog.fr-FR.resx b/GUI/Localization/fr-FR/NewRepoDialog.fr-FR.resx index a4baf9474e..c689de17b4 100644 --- a/GUI/Localization/fr-FR/NewRepoDialog.fr-FR.resx +++ b/GUI/Localization/fr-FR/NewRepoDialog.fr-FR.resx @@ -123,7 +123,7 @@ <data name="RepoOK.Text" xml:space="preserve"><value>&Ajouter</value></data> <data name="RepoNameHeader.Text" xml:space="preserve"><value>Nom</value></data> <data name="RepoURLHeader.Text" xml:space="preserve"><value>URL</value></data> - <data name="RepoNameLabel.Text" xml:space="preserve"><value>Nom:</value></data> - <data name="RepoUrlLabel.Text" xml:space="preserve"><value>URL:</value></data> + <data name="RepoNameLabel.Text" xml:space="preserve"><value>Nom :</value></data> + <data name="RepoUrlLabel.Text" xml:space="preserve"><value>URL :</value></data> <data name="$this.Text" xml:space="preserve"><value>Ajouter un répertoire</value></data> </root> diff --git a/GUI/Localization/fr-FR/RenameInstanceDialog.fr-FR.resx b/GUI/Localization/fr-FR/RenameInstanceDialog.fr-FR.resx index 965a17a8c5..db327b1947 100644 --- a/GUI/Localization/fr-FR/RenameInstanceDialog.fr-FR.resx +++ b/GUI/Localization/fr-FR/RenameInstanceDialog.fr-FR.resx @@ -116,7 +116,7 @@ </resheader> <resheader name="writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader>/> + </resheader> <data name="OKButton.Text" xml:space="preserve"><value>OK</value></data> <data name="CancelRenameInstanceButton.Text" xml:space="preserve"><value>Annuler</value></data> <data name="$this.Text" xml:space="preserve"><value>Renommer l'installation</value></data> diff --git a/GUI/Localization/ja-JP/RenameInstanceDialog.ja-JP.resx b/GUI/Localization/ja-JP/RenameInstanceDialog.ja-JP.resx index 2b51fd0a26..e597981158 100644 --- a/GUI/Localization/ja-JP/RenameInstanceDialog.ja-JP.resx +++ b/GUI/Localization/ja-JP/RenameInstanceDialog.ja-JP.resx @@ -116,7 +116,7 @@ </resheader> <resheader name="writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader>/> + </resheader> <data name="OKButton.Text" xml:space="preserve"><value>OK</value></data> <data name="CancelRenameInstanceButton.Text" xml:space="preserve"><value>取消</value></data> <data name="$this.Text" xml:space="preserve"><value>インスタンス名前変更</value></data> diff --git a/GUI/Localization/pt-BR/RenameInstanceDialog.pt-BR.resx b/GUI/Localization/pt-BR/RenameInstanceDialog.pt-BR.resx index e41f173170..36c980f931 100644 --- a/GUI/Localization/pt-BR/RenameInstanceDialog.pt-BR.resx +++ b/GUI/Localization/pt-BR/RenameInstanceDialog.pt-BR.resx @@ -116,7 +116,7 @@ </resheader> <resheader name="writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader>/> + </resheader> <data name="OKButton.Text" xml:space="preserve"><value>OK</value></data> <data name="CancelRenameInstanceButton.Text" xml:space="preserve"><value>Cancelar</value></data> <data name="$this.Text" xml:space="preserve"><value>Renomear Instalação</value></data> diff --git a/GUI/Localization/ru-RU/RenameInstanceDialog.ru-RU.resx b/GUI/Localization/ru-RU/RenameInstanceDialog.ru-RU.resx index 1310f93383..66f3779081 100644 --- a/GUI/Localization/ru-RU/RenameInstanceDialog.ru-RU.resx +++ b/GUI/Localization/ru-RU/RenameInstanceDialog.ru-RU.resx @@ -116,7 +116,7 @@ </resheader> <resheader name="writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader>/> + </resheader> <data name="OKButton.Text" xml:space="preserve"><value>OK</value></data> <data name="CancelRenameInstanceButton.Text" xml:space="preserve"><value>Отмена</value></data> <data name="$this.Text" xml:space="preserve"><value>Переименование сборки игры</value></data> diff --git a/GUI/Localization/zh-CN/RenameInstanceDialog.zh-CN.resx b/GUI/Localization/zh-CN/RenameInstanceDialog.zh-CN.resx index a1cdc2598a..947ba338ef 100644 --- a/GUI/Localization/zh-CN/RenameInstanceDialog.zh-CN.resx +++ b/GUI/Localization/zh-CN/RenameInstanceDialog.zh-CN.resx @@ -116,7 +116,7 @@ </resheader> <resheader name="writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> - </resheader>/> + </resheader> <data name="OKButton.Text" xml:space="preserve"><value>确认</value></data> <data name="CancelRenameInstanceButton.Text" xml:space="preserve"><value>取消</value></data> <data name="$this.Text" xml:space="preserve"><value>重命名当前安装</value></data> diff --git a/GUI/Main/Main.Designer.cs b/GUI/Main/Main.Designer.cs index 1ab575c6db..88dfc1addc 100644 --- a/GUI/Main/Main.Designer.cs +++ b/GUI/Main/Main.Designer.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { partial class Main { @@ -63,23 +63,23 @@ private void InitializeComponent() this.untaggedFilterToolStripSeparator = new System.Windows.Forms.ToolStripSeparator(); this.labelToolStripSeparator = new System.Windows.Forms.ToolStripSeparator(); this.editLabelsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ModInfo = new CKAN.ModInfo(); + this.ModInfo = new CKAN.GUI.ModInfo(); this.StatusLabel = new System.Windows.Forms.ToolStripStatusLabel(); this.StatusInstanceLabel = new System.Windows.Forms.ToolStripStatusLabel(); this.StatusProgress = new System.Windows.Forms.ToolStripProgressBar(); - this.MainTabControl = new CKAN.MainTabControl(); + this.MainTabControl = new CKAN.GUI.MainTabControl(); this.ManageModsTabPage = new System.Windows.Forms.TabPage(); - this.ManageMods = new CKAN.ManageMods(); + this.ManageMods = new CKAN.GUI.ManageMods(); this.ChangesetTabPage = new System.Windows.Forms.TabPage(); - this.Changeset = new CKAN.Changeset(); + this.Changeset = new CKAN.GUI.Changeset(); this.WaitTabPage = new System.Windows.Forms.TabPage(); - this.Wait = new CKAN.Wait(); + this.Wait = new CKAN.GUI.Wait(); this.ChooseRecommendedModsTabPage = new System.Windows.Forms.TabPage(); - this.ChooseRecommendedMods = new CKAN.ChooseRecommendedMods(); + this.ChooseRecommendedMods = new CKAN.GUI.ChooseRecommendedMods(); this.PlayTimeTabPage = new System.Windows.Forms.TabPage(); - this.PlayTime = new CKAN.PlayTime(); + this.PlayTime = new CKAN.GUI.PlayTime(); this.ChooseProvidedModsTabPage = new System.Windows.Forms.TabPage(); - this.ChooseProvidedMods = new CKAN.ChooseProvidedMods(); + this.ChooseProvidedMods = new CKAN.GUI.ChooseProvidedMods(); this.minimizeNotifyIcon = new System.Windows.Forms.NotifyIcon(this.components); this.minimizedContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); this.updatesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -97,9 +97,9 @@ private void InitializeComponent() this.quitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.viewPlayTimeStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.DeleteDirectoriesTabPage = new System.Windows.Forms.TabPage(); - this.DeleteDirectories = new CKAN.DeleteDirectories(); + this.DeleteDirectories = new CKAN.GUI.DeleteDirectories(); this.EditModpackTabPage = new System.Windows.Forms.TabPage(); - this.EditModpack = new CKAN.EditModpack(); + this.EditModpack = new CKAN.GUI.EditModpack(); this.menuStrip1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); this.splitContainer1.Panel1.SuspendLayout(); @@ -814,27 +814,27 @@ private void InitializeComponent() private System.Windows.Forms.ContextMenuStrip LabelsContextMenuStrip; private System.Windows.Forms.ToolStripSeparator labelToolStripSeparator; private System.Windows.Forms.ToolStripMenuItem editLabelsToolStripMenuItem; - private CKAN.ModInfo ModInfo; + private CKAN.GUI.ModInfo ModInfo; private System.Windows.Forms.ToolStripStatusLabel StatusLabel; private System.Windows.Forms.ToolStripStatusLabel StatusInstanceLabel; private System.Windows.Forms.ToolStripProgressBar StatusProgress; - private CKAN.MainTabControl MainTabControl; + private CKAN.GUI.MainTabControl MainTabControl; private System.Windows.Forms.TabPage ManageModsTabPage; - public CKAN.ManageMods ManageMods; + public CKAN.GUI.ManageMods ManageMods; private System.Windows.Forms.TabPage ChangesetTabPage; - private CKAN.Changeset Changeset; + private CKAN.GUI.Changeset Changeset; private System.Windows.Forms.TabPage WaitTabPage; - public CKAN.Wait Wait; + public CKAN.GUI.Wait Wait; private System.Windows.Forms.TabPage ChooseRecommendedModsTabPage; + private CKAN.GUI.ChooseRecommendedMods ChooseRecommendedMods; private System.Windows.Forms.TabPage PlayTimeTabPage; - private CKAN.ChooseRecommendedMods ChooseRecommendedMods; - private CKAN.PlayTime PlayTime; + private CKAN.GUI.PlayTime PlayTime; private System.Windows.Forms.TabPage ChooseProvidedModsTabPage; - private CKAN.ChooseProvidedMods ChooseProvidedMods; + private CKAN.GUI.ChooseProvidedMods ChooseProvidedMods; private System.Windows.Forms.TabPage DeleteDirectoriesTabPage; - private CKAN.DeleteDirectories DeleteDirectories; + private CKAN.GUI.DeleteDirectories DeleteDirectories; private System.Windows.Forms.TabPage EditModpackTabPage; - private CKAN.EditModpack EditModpack; + private CKAN.GUI.EditModpack EditModpack; private System.Windows.Forms.NotifyIcon minimizeNotifyIcon; private System.Windows.Forms.ContextMenuStrip minimizedContextMenuStrip; private System.Windows.Forms.ToolStripMenuItem updatesToolStripMenuItem; diff --git a/GUI/Main/Main.cs b/GUI/Main/Main.cs index d5ae565ea9..0feffd90b1 100644 --- a/GUI/Main/Main.cs +++ b/GUI/Main/Main.cs @@ -15,7 +15,7 @@ using CKAN.Extensions; using CKAN.Versioning; -namespace CKAN +namespace CKAN.GUI { public partial class Main : Form { diff --git a/GUI/Main/MainAutoUpdate.cs b/GUI/Main/MainAutoUpdate.cs index 60d2080ee5..6b35f52cf8 100644 --- a/GUI/Main/MainAutoUpdate.cs +++ b/GUI/Main/MainAutoUpdate.cs @@ -3,7 +3,7 @@ using System.Windows.Forms; using CKAN.Versioning; -namespace CKAN +namespace CKAN.GUI { public partial class Main { diff --git a/GUI/Main/MainChangeset.cs b/GUI/Main/MainChangeset.cs index 51d59d51cd..2193a1fd64 100644 --- a/GUI/Main/MainChangeset.cs +++ b/GUI/Main/MainChangeset.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public partial class Main { diff --git a/GUI/Main/MainDialogs.cs b/GUI/Main/MainDialogs.cs index 16464247db..294e207e7a 100644 --- a/GUI/Main/MainDialogs.cs +++ b/GUI/Main/MainDialogs.cs @@ -1,7 +1,7 @@ using System; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public partial class Main { diff --git a/GUI/Main/MainDownload.cs b/GUI/Main/MainDownload.cs index f3c8499fe9..641a0e4dd5 100644 --- a/GUI/Main/MainDownload.cs +++ b/GUI/Main/MainDownload.cs @@ -3,7 +3,7 @@ using System.ComponentModel; using System.Threading.Tasks; -namespace CKAN +namespace CKAN.GUI { public partial class Main { diff --git a/GUI/Main/MainExport.cs b/GUI/Main/MainExport.cs index 5f7ffa7b2e..425358c3a6 100644 --- a/GUI/Main/MainExport.cs +++ b/GUI/Main/MainExport.cs @@ -7,7 +7,7 @@ using CKAN.Exporters; using CKAN.Types; -namespace CKAN +namespace CKAN.GUI { public partial class Main { diff --git a/GUI/Main/MainImport.cs b/GUI/Main/MainImport.cs index 6b19dd6564..32d0dc7a5e 100644 --- a/GUI/Main/MainImport.cs +++ b/GUI/Main/MainImport.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public partial class Main { diff --git a/GUI/Main/MainInstall.cs b/GUI/Main/MainInstall.cs index 344c89236b..ac67ecdc66 100644 --- a/GUI/Main/MainInstall.cs +++ b/GUI/Main/MainInstall.cs @@ -5,7 +5,7 @@ using System.Linq; using CKAN.Extensions; -namespace CKAN +namespace CKAN.GUI { using ModChanges = List<ModChange>; public partial class Main diff --git a/GUI/Main/MainLabels.cs b/GUI/Main/MainLabels.cs index 90fe08bed6..263aa7da34 100644 --- a/GUI/Main/MainLabels.cs +++ b/GUI/Main/MainLabels.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using CKAN.Extensions; -namespace CKAN +namespace CKAN.GUI { public partial class Main { diff --git a/GUI/Main/MainProvides.cs b/GUI/Main/MainProvides.cs index 573ebc551a..ac13720205 100644 --- a/GUI/Main/MainProvides.cs +++ b/GUI/Main/MainProvides.cs @@ -1,6 +1,6 @@ using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public partial class Main { diff --git a/GUI/Main/MainRecommendations.cs b/GUI/Main/MainRecommendations.cs index 8ac806615f..a272c93c45 100644 --- a/GUI/Main/MainRecommendations.cs +++ b/GUI/Main/MainRecommendations.cs @@ -6,7 +6,7 @@ using CKAN.Extensions; using CKAN.Versioning; -namespace CKAN +namespace CKAN.GUI { using ModChanges = List<ModChange>; diff --git a/GUI/Main/MainRepo.cs b/GUI/Main/MainRepo.cs index e1c5f89934..464e2e7939 100644 --- a/GUI/Main/MainRepo.cs +++ b/GUI/Main/MainRepo.cs @@ -8,7 +8,7 @@ using CKAN.Configuration; using Autofac; -namespace CKAN +namespace CKAN.GUI { public partial class Main { diff --git a/GUI/Main/MainTabControl.cs b/GUI/Main/MainTabControl.cs index d839949479..efb6f25a1d 100644 --- a/GUI/Main/MainTabControl.cs +++ b/GUI/Main/MainTabControl.cs @@ -1,6 +1,6 @@ using System; -namespace CKAN +namespace CKAN.GUI { public class MainTabControl : ThemedTabControl { diff --git a/GUI/Main/MainTime.cs b/GUI/Main/MainTime.cs index d3204f63ee..d69a8dbecc 100644 --- a/GUI/Main/MainTime.cs +++ b/GUI/Main/MainTime.cs @@ -2,7 +2,7 @@ using System.Diagnostics; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public partial class Main { diff --git a/GUI/Main/MainTrayIcon.cs b/GUI/Main/MainTrayIcon.cs index 9118e765a4..44346d4c91 100644 --- a/GUI/Main/MainTrayIcon.cs +++ b/GUI/Main/MainTrayIcon.cs @@ -4,7 +4,7 @@ using CKAN.Configuration; using Autofac; -namespace CKAN +namespace CKAN.GUI { public partial class Main { diff --git a/GUI/Main/MainWait.cs b/GUI/Main/MainWait.cs index 4a4e84ad22..a70c5199aa 100644 --- a/GUI/Main/MainWait.cs +++ b/GUI/Main/MainWait.cs @@ -1,7 +1,7 @@ using System; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public partial class Main { diff --git a/GUI/Model/ExportOption.cs b/GUI/Model/ExportOption.cs index 6fb9148e8c..f92845867b 100644 --- a/GUI/Model/ExportOption.cs +++ b/GUI/Model/ExportOption.cs @@ -1,6 +1,6 @@ using CKAN.Types; -namespace CKAN +namespace CKAN.GUI { internal sealed class ExportOption { diff --git a/GUI/Model/GUIConfiguration.cs b/GUI/Model/GUIConfiguration.cs index ce47bc4461..17f49f7a2e 100644 --- a/GUI/Model/GUIConfiguration.cs +++ b/GUI/Model/GUIConfiguration.cs @@ -3,7 +3,7 @@ using System.IO; using System.Xml.Serialization; -namespace CKAN +namespace CKAN.GUI { [XmlRootAttribute("Configuration")] public class GUIConfiguration diff --git a/GUI/Model/GUIMod.cs b/GUI/Model/GUIMod.cs index 0a642bd584..fe2f254f0c 100644 --- a/GUI/Model/GUIMod.cs +++ b/GUI/Model/GUIMod.cs @@ -6,7 +6,7 @@ using System.Runtime.CompilerServices; using CKAN.Versioning; -namespace CKAN +namespace CKAN.GUI { public sealed class GUIMod : INotifyPropertyChanged { diff --git a/GUI/Model/ModChange.cs b/GUI/Model/ModChange.cs index 36219038e8..2cb1a30cbb 100644 --- a/GUI/Model/ModChange.cs +++ b/GUI/Model/ModChange.cs @@ -1,7 +1,7 @@ using System; using System.Linq; -namespace CKAN +namespace CKAN.GUI { public enum GUIModChangeType { @@ -12,6 +12,22 @@ public enum GUIModChangeType Replace = 4 } + public static class GUIModChangeTypeExtensions + { + public static string ToI18nString(this GUIModChangeType val) + { + switch (val) + { + case GUIModChangeType.None: return Properties.Resources.ChangeTypeNone; + case GUIModChangeType.Install: return Properties.Resources.ChangeTypeInstall; + case GUIModChangeType.Remove: return Properties.Resources.ChangeTypeRemove; + case GUIModChangeType.Update: return Properties.Resources.ChangeTypeUpdate; + case GUIModChangeType.Replace: return Properties.Resources.ChangeTypeReplace; + } + throw new NotImplementedException(val.ToString()); + } + } + /// <summary> /// Everything the GUI needs to know about a change, including /// the mod itself, the change we're making, and the reason why. @@ -56,7 +72,7 @@ public override int GetHashCode() public override string ToString() { - return $"{ChangeType} {Mod} ({Reason})"; + return $"{ChangeType.ToI18nString()} {Mod} ({Reason})"; } protected string modNameAndStatus(CkanModule m) @@ -81,18 +97,7 @@ public virtual string Description { get { - switch (ChangeType) - { - case GUIModChangeType.Install: - if (Reason is SelectionReason.UserRequested) - { - return Properties.Resources.MainChangesetNewInstall; - } - else goto default; - - default: - return Reason.Reason.Trim(); - } + return Reason.Reason.Trim(); } } } diff --git a/GUI/Model/ModList.cs b/GUI/Model/ModList.cs index f5e49b46fa..23a96af02a 100644 --- a/GUI/Model/ModList.cs +++ b/GUI/Model/ModList.cs @@ -9,7 +9,7 @@ using System.Windows.Forms; using CKAN.Versioning; -namespace CKAN +namespace CKAN.GUI { public enum GUIModFilter { diff --git a/GUI/Model/ModSearch.cs b/GUI/Model/ModSearch.cs index 05a5418b70..cc3d8df842 100644 --- a/GUI/Model/ModSearch.cs +++ b/GUI/Model/ModSearch.cs @@ -2,7 +2,7 @@ using System.Linq; using System.Collections.Generic; -namespace CKAN +namespace CKAN.GUI { /// <summary> /// An object representing a search to be performed of the mod list. diff --git a/GUI/NavigationHistory.cs b/GUI/NavigationHistory.cs index f9513070d4..efcf537e52 100644 --- a/GUI/NavigationHistory.cs +++ b/GUI/NavigationHistory.cs @@ -1,4 +1,4 @@ -namespace CKAN +namespace CKAN.GUI { using System; using System.Collections.Generic; diff --git a/GUI/Plugins/IGUIPlugin.cs b/GUI/Plugins/IGUIPlugin.cs index 9e29bea080..d12222bba4 100644 --- a/GUI/Plugins/IGUIPlugin.cs +++ b/GUI/Plugins/IGUIPlugin.cs @@ -1,7 +1,7 @@ using System; using CKAN.Versioning; -namespace CKAN +namespace CKAN.GUI { public abstract class IGUIPlugin { diff --git a/GUI/Plugins/PluginController.cs b/GUI/Plugins/PluginController.cs index 58b2c70c90..006a57343c 100644 --- a/GUI/Plugins/PluginController.cs +++ b/GUI/Plugins/PluginController.cs @@ -5,7 +5,7 @@ using System.Reflection; using log4net; -namespace CKAN +namespace CKAN.GUI { public class PluginController { diff --git a/GUI/Program.cs b/GUI/Program.cs index 56b229b18b..5ce4eae41c 100644 --- a/GUI/Program.cs +++ b/GUI/Program.cs @@ -2,7 +2,7 @@ using System.Linq; using System.Windows.Forms; -namespace CKAN +namespace CKAN.GUI { public static class GUI { @@ -42,7 +42,7 @@ public static void UnhandledExceptionEventHandler(Object sender, UnhandledExcept // Provide a stack backtrace, so our users and non-debugging devs can // see what's gone wrong. - CKAN.Main.Instance.ErrorDialog("Unhandled exception:\r\n{0} ", exception.ToString()); + CKAN.GUI.Main.Instance.ErrorDialog("Unhandled exception:\r\n{0} ", exception.ToString()); } } } diff --git a/GUI/Properties/Resources.Designer.cs b/GUI/Properties/Resources.Designer.cs index 753e97f53f..4dc22e3492 100644 --- a/GUI/Properties/Resources.Designer.cs +++ b/GUI/Properties/Resources.Designer.cs @@ -8,7 +8,7 @@ // </auto-generated> //------------------------------------------------------------------------------ -namespace CKAN.Properties { +namespace CKAN.GUI.Properties { using System; @@ -39,7 +39,7 @@ internal Resources() { } get { if (object.ReferenceEquals(resourceMan, null)) { - resourceMan = new SingleAssemblyResourceManager("CKAN.Properties.Resources", typeof(Resources).Assembly); + resourceMan = new SingleAssemblyResourceManager("CKAN.GUI.Properties.Resources", typeof(Resources).Assembly); } return resourceMan; } @@ -470,9 +470,6 @@ internal static string MainChangesetHostSize { internal static string MainChangesetUpdateSelected { get { return (string)(ResourceManager.GetObject("MainChangesetUpdateSelected", resourceCulture)); } } - internal static string MainChangesetNewInstall { - get { return (string)(ResourceManager.GetObject("MainChangesetNewInstall", resourceCulture)); } - } internal static string MainImportTitle { get { return (string)(ResourceManager.GetObject("MainImportTitle", resourceCulture)); } @@ -1033,5 +1030,20 @@ internal static string TotalPlayTime { get { return (string)(ResourceManager.GetObject("TotalPlayTime", resourceCulture)); } } + internal static string ChangeTypeNone { + get { return (string)(ResourceManager.GetObject("ChangeTypeNone", resourceCulture)); } + } + internal static string ChangeTypeInstall { + get { return (string)(ResourceManager.GetObject("ChangeTypeInstall", resourceCulture)); } + } + internal static string ChangeTypeRemove { + get { return (string)(ResourceManager.GetObject("ChangeTypeRemove", resourceCulture)); } + } + internal static string ChangeTypeUpdate { + get { return (string)(ResourceManager.GetObject("ChangeTypeUpdate", resourceCulture)); } + } + internal static string ChangeTypeReplace { + get { return (string)(ResourceManager.GetObject("ChangeTypeReplace", resourceCulture)); } + } } } diff --git a/GUI/Properties/Resources.de-DE.resx b/GUI/Properties/Resources.de-DE.resx index 35d746de6d..70a0241742 100644 --- a/GUI/Properties/Resources.de-DE.resx +++ b/GUI/Properties/Resources.de-DE.resx @@ -194,7 +194,6 @@ Möchten Sie es wirklich installieren?</value></data> <data name="AllModVersionsInstallNo" xml:space="preserve"><value>Abbrechen</value></data> <data name="MainChangesetMetapackage" xml:space="preserve"><value>{0} {1} (Metapacket)</value></data> <data name="MainChangesetUpdateSelected" xml:space="preserve"><value>Mod-Update ausgewählt vom Nutzer {0}.</value></data> - <data name="MainChangesetNewInstall" xml:space="preserve"><value>Neue Mod-Installation ausgewählt vom Nutzer.</value></data> <data name="MainImportTitle" xml:space="preserve"><value>Mod-Import</value></data> <data name="MainImportWaitTitle" xml:space="preserve"><value>Statuslog</value></data> <data name="MainInstallWaitTitle" xml:space="preserve"><value>Statuslog</value></data> diff --git a/GUI/Properties/Resources.fr-FR.resx b/GUI/Properties/Resources.fr-FR.resx index be8e56a89a..4b4ef51a7e 100644 --- a/GUI/Properties/Resources.fr-FR.resx +++ b/GUI/Properties/Resources.fr-FR.resx @@ -124,18 +124,18 @@ <data name="CloneFakeKspDialogEnterName" xml:space="preserve"><value>Veuillez entrer un nom pour la nouvelle instance.</value></data> <data name="CloneFakeKspDialogEnterPath" xml:space="preserve"><value>Veuillez entrer un chemin pour la nouvelle instance.</value></data> <data name="CloneFakeKspDialogCloningInstance" xml:space="preserve"><value>"Clonage de l'instance..."</value></data> - <data name="CloneFakeKspDialogDlcVersionMalformatted" xml:space="preserve"><value>La version pour le DLC {0} est mal mal-formatée. Essayez "1.0.0" par exemple.</value></data> - <data name="CloneFakeKspDialogInstanceNotValid" xml:space="preserve"><value>L'instance que vous voulez cloner n'est pas valide: {0}</value></data> - <data name="CloneFakeKspDialogDestinationNotEmpty" xml:space="preserve"><value>Le dossier de destination n'est pas vide: {0}</value></data> - <data name="CloneFakeKspDialogCloneFailed" xml:space="preserve"><value>Échec du clonage: {0}</value></data> + <data name="CloneFakeKspDialogDlcVersionMalformatted" xml:space="preserve"><value>La version pour le DLC {0} est mal formatée. Essayez "1.0.0" par exemple.</value></data> + <data name="CloneFakeKspDialogInstanceNotValid" xml:space="preserve"><value>L'instance que vous voulez cloner n'est pas valide : {0}</value></data> + <data name="CloneFakeKspDialogDestinationNotEmpty" xml:space="preserve"><value>Le dossier de destination n'est pas vide : {0}</value></data> + <data name="CloneFakeKspDialogCloneFailed" xml:space="preserve"><value>Échec du clonage : {0}</value></data> <data name="CloneFakeKspDialogSuccessfulClone" xml:space="preserve"><value>Instance clonée avec succès.</value></data> <data name="CloneFakeKspDialogCreatingInstance" xml:space="preserve"><value>Création de la nouvelle instance...</value></data> <data name="CloneFakeKspDialogNameAlreadyUsed" xml:space="preserve"><value>Ce nom est déjà utilisé.</value></data> - <data name="CloneFakeKspDialogFakeFailed" xml:space="preserve"><value>Échec de la création d'une fausse instance: {0}</value></data> + <data name="CloneFakeKspDialogFakeFailed" xml:space="preserve"><value>Échec de la création d'une instance artificielle : {0}</value></data> <data name="CloneFakeKspDialogSuccessfulCreate" xml:space="preserve"><value>Instance créée avec succès.</value></data> <data name="CompatibleGameVersionsDialogNone" xml:space="preserve"><value><AUCUNE></value></data> <data name="CompatibleGameVersionsDialogGameUpdated" xml:space="preserve"><value>Le jeu a été mis à jour depuis que vous avez défini les versions de jeu compatibles. Veuillez vérifier ces paramètres.</value></data> - <data name="CompatibleGameVersionsDialogVersionDetails" xml:space="preserve"><value>{0} (version de jeu précédente: {1})</value></data> + <data name="CompatibleGameVersionsDialogVersionDetails" xml:space="preserve"><value>{0} (version de jeu précédente : {1})</value></data> <data name="CompatibleGameVersionsDialogInvalidFormat" xml:space="preserve"><value>La version a un format invalide</value></data> <data name="CompatibleGameVersionsDialogErrorTitle" xml:space="preserve"><value>Erreur</value></data> <data name="ConfigurationParseError" xml:space="preserve"><value>Erreur en essayant d'interpréter "{0}"{1} @@ -144,7 +144,7 @@ Essayez de déplacer {2} en dehors de {3} et redémarrez CKAN.</value></data> <data name="GUIModUnknown" xml:space="preserve"><value>Inconnue</value></data> <data name="GUIModMethodNotCKAN" xml:space="preserve"><value>Cette Méthode ne peut pas être appelée sauf si IsCKAN</value></data> <data name="GUIModGameCompatibilityLong" xml:space="preserve"><value>{0} (en utilisant la version du mod {1})</value></data> - <data name="MainAutoUpdateFailed" xml:space="preserve"><value>Erreur durant la mis à jour auto:
{0}</value></data> + <data name="MainAutoUpdateFailed" xml:space="preserve"><value>Erreur durant la mise à jour auto :
{0}</value></data> <data name="MainQuitWithConflicts" xml:space="preserve"><value>Il y a des conflits. Voulez-vous vraiment quitter?

{0}</value></data> <data name="MainQuit" xml:space="preserve"><value>Quitter</value></data> <data name="MainGoBack" xml:space="preserve"><value>Revenir</value></data> @@ -152,7 +152,7 @@ Essayez de déplacer {2} en dehors de {3} et redémarrez CKAN.</value></data> <data name="MainQuitWithUnappliedChanges" xml:space="preserve"><value>Il y a des changements non pris en compte. Voulez-vous vraiment quitter? {0}</value></data> - <data name="MainUpgradingWaitTitle" xml:space="preserve"><value>Mis à jour de CKAN</value></data> + <data name="MainUpgradingWaitTitle" xml:space="preserve"><value>Mise à jour de CKAN</value></data> <data name="MainUpgradingTo" xml:space="preserve"><value>Mise à niveau de CKAN vers la {0}</value></data> <data name="MainDepNotSatisfied" xml:space="preserve"><value>{0} dépend de {1}, qui n'est pas compatible avec la version du jeu installée actuellement</value></data> <data name="MainFilterAll" xml:space="preserve"><value>Filtre (Tout)</value></data> @@ -168,7 +168,7 @@ Essayez de déplacer {2} en dehors de {3} et redémarrez CKAN.</value></data> <data name="MainFilterLabel" xml:space="preserve"><value>Label ({0})</value></data> <data name="MainFilterTag" xml:space="preserve"><value>Étiquette ({0})</value></data> <data name="MainFilterUntagged" xml:space="preserve"><value>Étiquette (sans étiquette)</value></data> - <data name="MainLaunchWithIncompatible" xml:space="preserve"><value>Certains modules installés sont incompatibles! Il pourrait être dangereux de lancer le jeu. Voulez-vous vraiment le lancer? + <data name="MainLaunchWithIncompatible" xml:space="preserve"><value>Certains modules installés sont incompatibles ! Il pourrait être dangereux de lancer le jeu. Voulez-vous vraiment le lancer ? {0}</value></data> <data name="MainLaunch" xml:space="preserve"><value>Lancement</value></data> @@ -183,12 +183,12 @@ Essayez de déplacer {2} en dehors de {3} et redémarrez CKAN.</value></data> <data name="MainCSV" xml:space="preserve"><value>Comma-separated values (*.csv)</value></data> <data name="MainTSV" xml:space="preserve"><value>Tab-separated values (*.tsv)</value></data> <data name="MainNotFound" xml:space="preserve"><value>Impossible de trouver.</value></data> - <data name="MainReinstallConfirm" xml:space="preserve"><value>Voulez-vous réinstaller {0}?</value></data> - <data name="MainCantInstallDLC" xml:space="preserve"><value>CKAN ne peut pas installer l'extension {0}!</value></data> - <data name="MainCorruptedRegistry" xml:space="preserve"><value>Registre corrompu archivé à {0}: {1} + <data name="MainReinstallConfirm" xml:space="preserve"><value>Voulez-vous réinstaller {0} ?</value></data> + <data name="MainCantInstallDLC" xml:space="preserve"><value>CKAN ne peut pas installer l'extension {0} !</value></data> + <data name="MainCorruptedRegistry" xml:space="preserve"><value>Registre corrompu archivé à {0} : {1} Cela veut dire que CKAN a oublié tous les mods que vous avez installé, mais ceux-ci sont toujours présents dans le dossier GameData. Vous pouvez les réinstaller en important le fichier {2}</value></data> - <data name="AllModVersionsInstallPrompt" xml:space="preserve"><value>{0} n'est pas supporté par votre version de jeu actuelle and pourraît ne pas marcher du tout. Si vous avez des problème avec, vous NE devez PAS demander de l'aide à ses développeurs. + <data name="AllModVersionsInstallPrompt" xml:space="preserve"><value>{0} n'est pas supporté par votre version de jeu actuelle et pourrait ne pas marcher du tout. Si vous avez des problème avec, vous NE devez PAS demander de l'aide à ses développeurs. Voulez-vous vraiment l'installer?</value></data> <data name="AllModVersionsInstallYes" xml:space="preserve"><value>Installer</value></data> @@ -196,29 +196,28 @@ Voulez-vous vraiment l'installer?</value></data> <data name="MainChangesetMetapackage" xml:space="preserve"><value>{0} {1} (méta-paquet)</value></data> <data name="MainChangesetCached" xml:space="preserve"><value>{0} {1} (en cache)</value></data> <data name="MainChangesetHostSize" xml:space="preserve"><value>{0} {1} ({2}, {3})</value></data> - <data name="MainChangesetUpdateSelected" xml:space="preserve"><value>Mis à jour sélectionnée par l'utilisateur à la version {0}.</value></data> - <data name="MainChangesetNewInstall" xml:space="preserve"><value>Nouvelle installation de mod sélectionnée par l'utilisateur.</value></data> + <data name="MainChangesetUpdateSelected" xml:space="preserve"><value>Mise à jour demandée vers la version {0}.</value></data> <data name="MainImportTitle" xml:space="preserve"><value>Importer des Mods</value></data> <data name="MainImportFilter" xml:space="preserve"><value>Mods (*.zip)|*.zip</value></data> <data name="MainImportWaitTitle" xml:space="preserve"><value>Registre</value></data> <data name="MainInstallWaitTitle" xml:space="preserve"><value>Registre</value></data> - <data name="MainInstallDepNotSatisfied" xml:space="preserve"><value>{0} requiert {1} mais il n'est pas listé dans l'index, ou non-disponible pour votre version de jeu.</value></data> - <data name="MainInstallNotFound" xml:space="preserve"><value>Le module {0} est requis mais il n'est pas listé dans l'index, ou non-disponible pour votre version de jeu.</value></data> - <data name="MainInstallBadMetadata" xml:space="preserve"><value>Mauvaises métadonnées détectées pour le module {0}: {1}</value></data> - <data name="MainInstallFileExists" xml:space="preserve"><value>Oh non! Nous avons essayé de remplacer un fichier appartenant à un autre mod! + <data name="MainInstallDepNotSatisfied" xml:space="preserve"><value>{0} nécessite {1} mais il n'est pas listé dans l'index, ou indisponible pour votre version de jeu.</value></data> + <data name="MainInstallNotFound" xml:space="preserve"><value>Le module {0} est requis mais il n'est pas listé dans l'index, ou indisponible pour votre version de jeu.</value></data> + <data name="MainInstallBadMetadata" xml:space="preserve"><value>Mauvaises métadonnées détectées pour le module {0} : {1}</value></data> + <data name="MainInstallFileExists" xml:space="preserve"><value>Oh non! Nous avons essayé de remplacer un fichier appartenant à un autre mod ! Veuillez essayer de mettre à jour CKAN puis de réessayer. -Si ce problème se produit de nouveau, il pourrait s'agir d'un bug d'empaquettement. +Si ce problème se produit de nouveau, il pourrait s'agir d'un bogue d'emballage. Veuillez le signaler à: https://github.com/KSP-CKAN/NetKAN/issues/new/choose -Veuillez inclure les informations suivantes dans votre rapport: +Veuillez inclure les informations suivantes dans votre rapport : -Fichier : {0} -Mod en cours d'installation: {1} -Mod propriétaire: {2} -Version CKAN : {3}</value></data> +Fichier : {0} +Mod à installer : {1} +Mod propriétaire : {2} +Version CKAN : {3}</value></data> <data name="MainInstallUnownedFileExists" xml:space="preserve"><value>Oh non! On dirait que vous essayez d'installer un mod qui est déjà installé, @@ -228,7 +227,7 @@ Par précaution, CKAN ne va *jamais* remplacer ou modifier un fichier qu'il n'a pas installé lui-même. Si vous souhaitez installer {0} via CKAN, -alors veuillez désinstaller manuellement le mod qui possède: +alors veuillez désinstaller manuellement le mod qui possède : {1} @@ -236,42 +235,42 @@ et essayez de nouveau.</value></data> <data name="MainInstallGameDataReverted" xml:space="preserve"><value>Votre dossier GameData a été remis dans son état initial.</value></data> <data name="MainInstallOpenSettingsPrompt" xml:space="preserve"><value>{0} -Ouvrir les paramètres maintenant?</value></data> +Ouvrir les paramètres maintenant ?</value></data> <data name="MainInstallOpenSettings" xml:space="preserve"><value>Ouvrir les paramètres</value></data> <data name="MainInstallNo" xml:space="preserve"><value>Non</value></data> <data name="MainInstallModSuccess" xml:space="preserve"><value>Le module "{0}" a été installé avec succès</value></data> - <data name="MainInstallSuccess" xml:space="preserve"><value>Succès!</value></data> + <data name="MainInstallSuccess" xml:space="preserve"><value>Succès !</value></data> <data name="MainInstallCancelTooLate" xml:space="preserve"><value>Annulation trop tardive, le processus est terminé!</value></data> <data name="MainInstallCancelAfterInstall" xml:space="preserve"><value>L'utilisateur a annulé le processus manuellement, mais tous les mods ont déjà été (Dés)installés/mis à niveau.</value></data> - <data name="MainInstallProcessComplete" xml:space="preserve"><value>Processus terminé!</value></data> - <data name="MainInstallProcessCanceled" xml:space="preserve"><value>Processus annulé par l'utilisateur!</value></data> - <data name="MainInstallCanceledManually" xml:space="preserve"><value>L'utilisateur a annulé le processus manuellement!</value></data> - <data name="MainInstallInstallCanceled" xml:space="preserve"><value>(Dés)Installation/Mise à niveau annulée!</value></data> - <data name="MainInstallErrorInstalling" xml:space="preserve"><value>Erreur lors de l'installation!</value></data> - <data name="MainInstallUnknownError" xml:space="preserve"><value>Une erreur inconnue s'est produite, veuillez réessayer!</value></data> + <data name="MainInstallProcessComplete" xml:space="preserve"><value>Processus terminé !</value></data> + <data name="MainInstallProcessCanceled" xml:space="preserve"><value>Processus annulé par l'utilisateur !</value></data> + <data name="MainInstallCanceledManually" xml:space="preserve"><value>L'utilisateur a annulé le processus manuellement !</value></data> + <data name="MainInstallInstallCanceled" xml:space="preserve"><value>(Dés)Installation/Mise à niveau annulée !</value></data> + <data name="MainInstallErrorInstalling" xml:space="preserve"><value>Erreur lors de l'installation !</value></data> + <data name="MainInstallUnknownError" xml:space="preserve"><value>Une erreur inconnue s'est produite, veuillez réessayer !</value></data> <data name="MainInstallKnownError" xml:space="preserve"><value>Si le message ci-dessus indique une erreur de téléchargement, veuillez réessayer. Sinon, veuillez signaler le problème pour que nous puissions investiguer. -Si vous suspectez un problème de métadonnées: https://github.com/KSP-CKAN/NetKAN/issues/new/choose -Si vous suspectez un problème client: https://github.com/KSP-CKAN/CKAN/issues/new/choose</value></data> - <data name="MainInstallFailed" xml:space="preserve"><value>Échec de l'installation!</value></data> - <data name="MainInstallProvidedBy" xml:space="preserve"><value>Le module {0} est fourni par plus qu'un seul module, veuillez choisir l'un des mods suivants:</value></data> +Si vous suspectez un problème de métadonnées : https://github.com/KSP-CKAN/NetKAN/issues/new/choose +Si vous suspectez un problème client : https://github.com/KSP-CKAN/CKAN/issues/new/choose</value></data> + <data name="MainInstallFailed" xml:space="preserve"><value>Échec de l'installation !</value></data> + <data name="MainInstallProvidedBy" xml:space="preserve"><value>Le module {0} est fourni par plusieurs modules, veuillez choisir l'un des mods suivants :</value></data> <data name="MainInstallCantInstallDLC" xml:space="preserve"><value>CKAN ne peut pas installer l'extension "{0}" pour vous.</value></data> <data name="ModInfoNSlashA" xml:space="preserve"><value>N/A</value></data> <data name="ModInfoVirtual" xml:space="preserve"><value>{0} (virtuel)</value></data> <data name="ModInfoNotIndexed" xml:space="preserve"><value>{0} (non indexé)</value></data> <data name="ModInfoNotCached" xml:space="preserve"><value>Ce mod n'est pas dans le cache, cliquez "télécharger" pour voir son contenu</value></data> <data name="ModInfoCached" xml:space="preserve"><value>Le module est dans le cache, aperçu disponible</value></data> - <data name="ModInfoHomepageLabel" xml:space="preserve"><value>Page principale:</value></data> - <data name="ModInfoSpaceDockLabel" xml:space="preserve"><value>SpaceDock:</value></data> - <data name="ModInfoCurseLabel" xml:space="preserve"><value>Curse:</value></data> - <data name="ModInfoRepositoryLabel" xml:space="preserve"><value>Répertoire:</value></data> - <data name="ModInfoBugTrackerLabel" xml:space="preserve"><value>Traqueur de bogues:</value></data> - <data name="ModInfoContinuousIntegrationLabel" xml:space="preserve"><value>Intégration continue:</value></data> - <data name="ModInfoLicenseLabel" xml:space="preserve"><value>Licence:</value></data> - <data name="ModInfoManualLabel" xml:space="preserve"><value>Manuel:</value></data> - <data name="ModInfoMetanetkanLabel" xml:space="preserve"><value>Métanetkan:</value></data> - <data name="ModInfoRemoteAvcLabel" xml:space="preserve"><value>Fichier version distant:</value></data> - <data name="ModInfoStoreLabel" xml:space="preserve"><value>Magasin:</value></data> - <data name="ModInfoSteamStoreLabel" xml:space="preserve"><value>Magasin Steam:</value></data> + <data name="ModInfoHomepageLabel" xml:space="preserve"><value>Page principale :</value></data> + <data name="ModInfoSpaceDockLabel" xml:space="preserve"><value>SpaceDock :</value></data> + <data name="ModInfoCurseLabel" xml:space="preserve"><value>Curse :</value></data> + <data name="ModInfoRepositoryLabel" xml:space="preserve"><value>Répertoire :</value></data> + <data name="ModInfoBugTrackerLabel" xml:space="preserve"><value>Traqueur de bogues :</value></data> + <data name="ModInfoContinuousIntegrationLabel" xml:space="preserve"><value>Intégration continue :</value></data> + <data name="ModInfoLicenseLabel" xml:space="preserve"><value>Licence :</value></data> + <data name="ModInfoManualLabel" xml:space="preserve"><value>Manuel :</value></data> + <data name="ModInfoMetanetkanLabel" xml:space="preserve"><value>Métanetkan :</value></data> + <data name="ModInfoRemoteAvcLabel" xml:space="preserve"><value>Fichier version distant :</value></data> + <data name="ModInfoStoreLabel" xml:space="preserve"><value>Magasin :</value></data> + <data name="ModInfoSteamStoreLabel" xml:space="preserve"><value>Magasin Steam :</value></data> <data name="MainModListWaitTitle" xml:space="preserve"><value>Chargement des modules</value></data> <data name="MainModListLoadingRegistry" xml:space="preserve"><value>Chargement du registre...</value></data> <data name="MainModListLoadingInstalled" xml:space="preserve"><value>Chargement des modules installés...</value></data> @@ -300,19 +299,19 @@ Si vous suspectez un problème client: https://github.com/KSP-CKAN/CKAN/issues/n <data name="MainRepoScanning" xml:space="preserve"><value>Détection des DLC et des modules installés manuellement...</value></data> <data name="MainRepoContacting" xml:space="preserve"><value>Contact du répertoire...</value></data> <data name="MainRepoUpdating" xml:space="preserve"><value>Mise à jour des répertoires...</value></data> - <data name="MainRepoFailedToConnect" xml:space="preserve"><value>Échec de la connection au répertoire. Exception: {0}</value></data> + <data name="MainRepoFailedToConnect" xml:space="preserve"><value>Échec de la connection au répertoire. Exception : {0}</value></data> <data name="MainRepoUpToDate" xml:space="preserve"><value>Répertoire déjà à jour.</value></data> - <data name="MainRepoFailed" xml:space="preserve"><value>Échec de la mise à jour du répertoire!</value></data> + <data name="MainRepoFailed" xml:space="preserve"><value>Échec de la mise à jour du répertoire !</value></data> <data name="MainRepoSuccess" xml:space="preserve"><value>Répertoires mis à jour avec succès.</value></data> - <data name="MainRepoAutoRefreshPrompt" xml:space="preserve"><value>Voulez-vous que CKAN rafraîchisse la liste de mod au lancement? (Vous pouvez toujours rafraîchir manuellement en utilisant le bouton en haut)</value></data> - <data name="MainRepoBalloonTipDetails" xml:space="preserve"><value>{0} mise(s) à jour disponible(s)</value></data> + <data name="MainRepoAutoRefreshPrompt" xml:space="preserve"><value>Voulez-vous que CKAN rafraîchisse la liste de mod au lancement ? (Vous pouvez toujours rafraîchir manuellement en utilisant le bouton en haut)</value></data> + <data name="MainRepoBalloonTipDetails" xml:space="preserve"><value>{0} mise·s à jour disponible·s</value></data> <data name="MainRepoBalloonTipTooltip" xml:space="preserve"><value>Cliquer pour mettre à niveau</value></data> <data name="MainTrayIconResume" xml:space="preserve"><value>Reprendre</value></data> <data name="MainTrayIconPause" xml:space="preserve"><value>Pause</value></data> <data name="MainTrayNoUpdates" xml:space="preserve"><value>Aucune mise à jour disponible</value></data> - <data name="MainTrayUpdatesAvailable" xml:space="preserve"><value>{0} mise(s) à jour disponible(s)</value></data> + <data name="MainTrayUpdatesAvailable" xml:space="preserve"><value>{0} mise·s à jour disponible·s</value></data> <data name="MainWaitPleaseWait" xml:space="preserve"><value>Veuillez patientez</value></data> - <data name="MainWaitDone" xml:space="preserve"><value>Terminé!</value></data> + <data name="MainWaitDone" xml:space="preserve"><value>Terminé !</value></data> <data name="ManageGameInstancesNotValid" xml:space="preserve"><value>Le répertoire {0} n'est pas un répertoire de jeu valide.</value></data> <data name="ManageGameInstancesDirectoryDeleted" xml:space="preserve"><value>Le répertoire "{0}" n'existe pas.</value></data> <data name="ManageGameInstancesNameColumnInvalid" xml:space="preserve"><value>{0} (INVALIDE)</value></data> @@ -320,12 +319,12 @@ Si vous suspectez un problème client: https://github.com/KSP-CKAN/CKAN/issues/n <data name="NewRepoDialogFailed" xml:space="preserve"><value>Échec de la récupération de la liste maître.</value></data> <data name="PluginsDialogFilter" xml:space="preserve"><value>Plugins CKAN (*.dll)|*.dll</value></data> <data name="SettingsDialogSummmary" xml:space="preserve"><value>{0} fichiers, {1}</value></data> - <data name="SettingsDialogSummaryInvalid" xml:space="preserve"><value>Chemin invalide: {0}</value></data> - <data name="SettingsDialogCacheDescrip" xml:space="preserve"><value>Choisissez un dossier pour stocker les téléchargements de mods de CKAN:</value></data> - <data name="SettingsDialogDeleteConfirm" xml:space="preserve"><value>Voulez-vous vraiment supprimer {0} fichiers en cache, libérant {1}?</value></data> + <data name="SettingsDialogSummaryInvalid" xml:space="preserve"><value>Chemin invalide : {0}</value></data> + <data name="SettingsDialogCacheDescrip" xml:space="preserve"><value>Choisissez un dossier pour stocker les téléchargements de mods de CKAN :</value></data> + <data name="SettingsDialogDeleteConfirm" xml:space="preserve"><value>Voulez-vous vraiment supprimer {0} fichiers en cache, libérant {1} ?</value></data> <data name="AddAuthTokenTitle" xml:space="preserve"><value>Ajouter un jeton d'authentification</value></data> - <data name="AddAuthTokenHost" xml:space="preserve"><value>Hôte:</value></data> - <data name="AddAuthTokenToken" xml:space="preserve"><value>Jeton:</value></data> + <data name="AddAuthTokenHost" xml:space="preserve"><value>Hôte :</value></data> + <data name="AddAuthTokenToken" xml:space="preserve"><value>Jeton :</value></data> <data name="AddAuthTokenAccept" xml:space="preserve"><value>&Ajouter</value></data> <data name="AddAuthTokenCancel" xml:space="preserve"><value>An&nuler</value></data> <data name="AddAuthTokenHostRequired" xml:space="preserve"><value>Le champ de l'hôte est requis.</value></data> @@ -334,18 +333,18 @@ Si vous suspectez un problème client: https://github.com/KSP-CKAN/CKAN/issues/n <data name="AddAuthTokenDupHost" xml:space="preserve"><value>{0} a déjà un jeton d'authentification.</value></data> <data name="SettingsDialogUpdateFailed" xml:space="preserve"><value>Erreur durant la mise à jour. Impossible de mettre à jour, car ckan.exe est en lecture-seule ou nous ne sommes pas autorisé à le remplacer. Veuillez mettre à jour manuellement via https://github.com/KSP-CKAN/CKAN/releases/latest.</value></data> - <data name="URLHandlersPrompt" xml:space="preserve"><value>CKAN requiert la permission d'ajouter un handler pour les URL ckan:// + <data name="URLHandlersPrompt" xml:space="preserve"><value>CKAN demande la permission d'ajouter un handler pour les adresses ckan:// Voulez-vous autoriser à faire cela? Si vous cliquer non, vous ne verrez plus ce message.</value></data> <data name="UtilCopyLink" xml:space="preserve"><value>&Copier l'adresse du lien</value></data> - <data name="StatusInstanceLabelText" xml:space="preserve"><value>Instance de jeu: {0} ({1} {2})</value></data> + <data name="StatusInstanceLabelText" xml:space="preserve"><value>Instance de jeu : {0} ({1} {2})</value></data> <data name="ModuleLabelListFavourites" xml:space="preserve"><value>Favoris</value></data> <data name="ModuleLabelListHidden" xml:space="preserve"><value>Caché</value></data> <data name="ModuleLabelListGlobal" xml:space="preserve"><value>Global</value></data> - <data name="EditLabelsDialogConfirmDelete" xml:space="preserve"><value>Êtes-vous sûr de vouloir supprimer {0}? Il sera ensuite impossible de retourner en arrière!</value></data> - <data name="EditLabelsDialogSavePrompt" xml:space="preserve"><value>Sauvegarder les changements?</value></data> - <data name="EditLabelsDialogNoRecord" xml:space="preserve"><value>Aucun registre en édition!</value></data> + <data name="EditLabelsDialogConfirmDelete" xml:space="preserve"><value>Êtes-vous sûr de vouloir supprimer {0} ? Il sera ensuite impossible de retourner en arrière !</value></data> + <data name="EditLabelsDialogSavePrompt" xml:space="preserve"><value>Sauvegarder les changements ?</value></data> + <data name="EditLabelsDialogNoRecord" xml:space="preserve"><value>Aucun registre en édition !</value></data> <data name="EditLabelsDialogNameRequired" xml:space="preserve"><value>Nom requis!</value></data> - <data name="EditLabelsDialogAlreadyExists" xml:space="preserve"><value>{0} existe déjà dans {1}!</value></data> + <data name="EditLabelsDialogAlreadyExists" xml:space="preserve"><value>{0} existe déjà dans {1} !</value></data> <data name="EditLabelsDialogDelete" xml:space="preserve"><value>Supprimer</value></data> <data name="EditLabelsDialogCancel" xml:space="preserve"><value>Annuler</value></data> <data name="EditLabelsDialogSave" xml:space="preserve"><value>Sauvegarder</value></data> @@ -359,19 +358,19 @@ Voulez-vous autoriser à faire cela? Si vous cliquer non, vous ne verrez plus ce <data name="EditLabelsToolTipRemoveOnChanges" xml:space="preserve"><value>Si coché, un module passant de incompatible à compatible sera retiré de ce label</value></data> <data name="EditLabelsToolTipAlertOnInstall" xml:space="preserve"><value>Si coché, le résumé des changements vous avertira si un mod s'apprête à être installé</value></data> <data name="EditLabelsToolTipRemoveOnInstall" xml:space="preserve"><value>Si coché, les modules seront retirés de ce label si ils sont installés</value></data> - <data name="MainLabelsUpdateMessage" xml:space="preserve"><value>Certains de vos modes surveillés ont été mis à jour: + <data name="MainLabelsUpdateMessage" xml:space="preserve"><value>Certains de vos modes surveillés ont été mis à jour : {0}</value></data> <data name="MainLabelsUpdateTitle" xml:space="preserve"><value>Notifications de mis à jour</value></data> <data name="MainLabelsUntagged" xml:space="preserve"><value>Sans étiquette ({0})</value></data> - <data name="EditModpackBadIdentifier" xml:space="preserve"><value>L'identifiant doit contenir UNIQUEMENT des letters, des nombres et des tirets, et doit commencer par une lettre ou un nombre</value></data> + <data name="EditModpackBadIdentifier" xml:space="preserve"><value>L'identifiant doit contenir UNIQUEMENT des lettres, des nombres et des tirets, et doit commencer par une lettre ou un nombre</value></data> <data name="EditModpackBadName" xml:space="preserve"><value>Nom requis</value></data> <data name="EditModpackBadVersion" xml:space="preserve"><value>Version requise</value></data> <data name="EditModpackBadGameVersions" xml:space="preserve"><value>Version de jeu minimum doit être inférieure ou égale à la version de jeu maximale</value></data> <data name="EditModpackTooltipIdentifier" xml:space="preserve"><value>Nom interne de ce modpack; lettres, nombres et tirets uniquement</value></data> - <data name="EditModpackTooltipName" xml:space="preserve"><value>Nom visible publiquement de ce modpack</value></data> + <data name="EditModpackTooltipName" xml:space="preserve"><value>Nom public de ce modpack</value></data> <data name="EditModpackTooltipAbstract" xml:space="preserve"><value>Courte description de ce modpack</value></data> - <data name="EditModpackTooltipVersion" xml:space="preserve"><value>Le numéro de version de ce modpack</value></data> + <data name="EditModpackTooltipVersion" xml:space="preserve"><value>Numéro de version de ce modpack</value></data> <data name="EditModpackTooltipGameVersionMin" xml:space="preserve"><value>Plus ancienne version de jeu compatible, vide pour toutes</value></data> <data name="EditModpackTooltipGameVersionMax" xml:space="preserve"><value>Dernière version de jeu compatible, vide pour toutes</value></data> <data name="EditModpackTooltipLicense" xml:space="preserve"><value>La licence de ce modpack</value></data> @@ -394,16 +393,20 @@ Voulez-vous autoriser à faire cela? Si vous cliquer non, vous ne verrez plus ce <data name="ModSearchTagPrefix" xml:space="preserve"><value>étiquette:</value></data> <data name="ModSearchLabelPrefix" xml:space="preserve"><value>label:</value></data> <data name="ModSearchYesPrefix" xml:space="preserve"><value>est:</value></data> - <data name="ModSearchNoPrefix" xml:space="preserve"><value>pas:</value></data> + <data name="ModSearchNoPrefix" xml:space="preserve"><value>non:</value></data> <data name="ModSearchCompatibleSuffix" xml:space="preserve"><value>compatible</value></data> <data name="ModSearchInstalledSuffix" xml:space="preserve"><value>installé</value></data> <data name="ModSearchCachedSuffix" xml:space="preserve"><value>cache</value></data> <data name="ModSearchNewlyCompatibleSuffix" xml:space="preserve"><value>nouveau</value></data> <data name="ModSearchUpgradeableSuffix" xml:space="preserve"><value>MàJ</value></data> - <data name="ModSearchReplaceableSuffix" xml:space="preserve"><value>remplacable</value></data> - + <data name="ModSearchReplaceableSuffix" xml:space="preserve"><value>remplaçable</value></data> <data name="EditModSearchTooltipExpandButton" xml:space="preserve"><value>Étendre ou réduire la taille du champ de recherche détaillé (Ctrl-Shift-F)</value></data> <data name="EditModSearchesTooltipAddSearchButton" xml:space="preserve"><value>Combiner une nouvelle recherche avec vos recherches actuelles</value></data> <data name="ManageModsInstallAllCheckboxTooltip" xml:space="preserve"><value>Décocher pour désinstaller tous les mods, cocher pour annuler les changements</value></data> <data name="TotalPlayTime" xml:space="preserve"><value>Votre Temps de Jeu Total: {0} Heures</value></data> + <data name="ChangeTypeNone" xml:space="preserve"><value>Aucun</value></data> + <data name="ChangeTypeInstall" xml:space="preserve"><value>Installation</value></data> + <data name="ChangeTypeRemove" xml:space="preserve"><value>Retrait</value></data> + <data name="ChangeTypeUpdate" xml:space="preserve"><value>Mise à jour</value></data> + <data name="ChangeTypeReplace" xml:space="preserve"><value>Remplacement</value></data> </root> diff --git a/GUI/Properties/Resources.ja-JP.resx b/GUI/Properties/Resources.ja-JP.resx index b7f5609495..f50c48fb46 100644 --- a/GUI/Properties/Resources.ja-JP.resx +++ b/GUI/Properties/Resources.ja-JP.resx @@ -198,7 +198,6 @@ Try to move {2} out of {3} and restart CKAN.</value></data> <data name="MainChangesetCached" xml:space="preserve"><value>{0} {1} (キャッシュ済)</value></data> <data name="MainChangesetHostSize" xml:space="preserve"><value>{0} {1} ({2}, {3})</value></data> <data name="MainChangesetUpdateSelected" xml:space="preserve"><value>選択されたものをバージョン{0}にアップデートする。</value></data> - <data name="MainChangesetNewInstall" xml:space="preserve"><value>New mod install selected by user.</value></data> <data name="MainImportTitle" xml:space="preserve"><value>Modインポート</value></data> <data name="MainImportFilter" xml:space="preserve"><value>Mod (*.zip)|*.zip</value></data> <data name="MainImportWaitTitle" xml:space="preserve"><value>ステータスログ</value></data> diff --git a/GUI/Properties/Resources.pt-BR.resx b/GUI/Properties/Resources.pt-BR.resx index 15d8b3cea8..fe979e9ed2 100644 --- a/GUI/Properties/Resources.pt-BR.resx +++ b/GUI/Properties/Resources.pt-BR.resx @@ -193,7 +193,6 @@ Você quer realmente instalá-la?</value></data> <data name="MainChangesetCached" xml:space="preserve"><value>{0} {1} (Em cache)</value></data> <data name="MainChangesetHostSize" xml:space="preserve"><value>{0} {1} ({2}, {3})</value></data> <data name="MainChangesetUpdateSelected" xml:space="preserve"><value>Atualização selecionada pelo usuário para a versão {0}.</value></data> - <data name="MainChangesetNewInstall" xml:space="preserve"><value>Nova instalação de mod selecionada pelo usuário.</value></data> <data name="MainImportTitle" xml:space="preserve"><value>Importar mods</value></data> <data name="MainImportFilter" xml:space="preserve"><value>Mods (*.zip)|*.zip</value></data> <data name="MainImportWaitTitle" xml:space="preserve"><value>Log de Status</value></data> diff --git a/GUI/Properties/Resources.resx b/GUI/Properties/Resources.resx index 553dafa016..3074340a50 100644 --- a/GUI/Properties/Resources.resx +++ b/GUI/Properties/Resources.resx @@ -218,7 +218,6 @@ Do you really want to install it?</value></data> <data name="MainChangesetCached" xml:space="preserve"><value>{0} {1} (cached)</value></data> <data name="MainChangesetHostSize" xml:space="preserve"><value>{0} {1} ({2}, {3})</value></data> <data name="MainChangesetUpdateSelected" xml:space="preserve"><value>Update selected by user to version {0}.</value></data> - <data name="MainChangesetNewInstall" xml:space="preserve"><value>New mod install selected by user.</value></data> <data name="MainImportTitle" xml:space="preserve"><value>Import Mods</value></data> <data name="MainImportFilter" xml:space="preserve"><value>Mods (*.zip)|*.zip</value></data> <data name="MainImportWaitTitle" xml:space="preserve"><value>Status log</value></data> @@ -432,4 +431,9 @@ Do you want to allow CKAN to do this? If you click no you won't see this message <data name="EditModSearchesTooltipAddSearchButton" xml:space="preserve"><value>Combine a new search with your current searches</value></data> <data name="ManageModsInstallAllCheckboxTooltip" xml:space="preserve"><value>Uncheck to uninstall all mods, check to clear change set</value></data> <data name="TotalPlayTime" xml:space="preserve"><value>Total play time: {0} hours</value></data> + <data name="ChangeTypeNone" xml:space="preserve"><value>None</value></data> + <data name="ChangeTypeInstall" xml:space="preserve"><value>Install</value></data> + <data name="ChangeTypeRemove" xml:space="preserve"><value>Remove</value></data> + <data name="ChangeTypeUpdate" xml:space="preserve"><value>Update</value></data> + <data name="ChangeTypeReplace" xml:space="preserve"><value>Replace</value></data> </root> diff --git a/GUI/Properties/Resources.ru-RU.resx b/GUI/Properties/Resources.ru-RU.resx index d1b35b1c1b..370db3cc34 100644 --- a/GUI/Properties/Resources.ru-RU.resx +++ b/GUI/Properties/Resources.ru-RU.resx @@ -196,7 +196,6 @@ <data name="MainChangesetCached" xml:space="preserve"><value>{0} {1} (загружено)</value></data> <data name="MainChangesetHostSize" xml:space="preserve"><value>{0} {1} ({2}, {3})</value></data> <data name="MainChangesetUpdateSelected" xml:space="preserve"><value>Обновить выбранное пользователем до версии {0}.</value></data> - <data name="MainChangesetNewInstall" xml:space="preserve"><value>Установка выбранной пользователем модификации.</value></data> <data name="MainImportTitle" xml:space="preserve"><value>Импортировать модификации</value></data> <data name="MainImportFilter" xml:space="preserve"><value>Модификации (*.zip)|*.zip</value></data> <data name="MainImportWaitTitle" xml:space="preserve"><value>Журнал</value></data> @@ -226,7 +225,7 @@ https://github.com/KSP-CKAN/NetKAN/issues/new/choose Похоже, что модификация, которую вы пытаетесь установить, уже установлена или конфликтует с уже установленной модификацией. -В качестве меры безопасности CKAN *никогда* не перезаписывает +В качестве меры безопасности CKAN *никогда* не перезаписывает или изменяет файлы, которые не установил сам. Если вы хотите установить {0} с помощью CKAN, diff --git a/GUI/Properties/Resources.zh-CN.resx b/GUI/Properties/Resources.zh-CN.resx index c25db31818..1116539100 100644 --- a/GUI/Properties/Resources.zh-CN.resx +++ b/GUI/Properties/Resources.zh-CN.resx @@ -192,7 +192,6 @@ <data name="MainChangesetCached" xml:space="preserve"><value>{0} {1} (cached)</value></data> <data name="MainChangesetHostSize" xml:space="preserve"><value>{0} {1} ({2}, {3})</value></data> <data name="MainChangesetUpdateSelected" xml:space="preserve"><value>用户选择更新到 {0} 版本.</value></data> - <data name="MainChangesetNewInstall" xml:space="preserve"><value>用户选择安装的新Mod.</value></data> <data name="MainImportTitle" xml:space="preserve"><value>导入Mod</value></data> <data name="MainImportFilter" xml:space="preserve"><value>Mods (*.zip)|*.zip</value></data> <data name="MainImportWaitTitle" xml:space="preserve"><value>状态日志</value></data> diff --git a/GUI/Properties/Settings.Designer.cs b/GUI/Properties/Settings.Designer.cs index 4f225e45d2..cef4a7f7fc 100644 --- a/GUI/Properties/Settings.Designer.cs +++ b/GUI/Properties/Settings.Designer.cs @@ -8,7 +8,7 @@ // </auto-generated> //------------------------------------------------------------------------------ -namespace CKAN.Properties { +namespace CKAN.GUI.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] diff --git a/GUI/SingleAssemblyComponentResourceManager.cs b/GUI/SingleAssemblyComponentResourceManager.cs index 2c14ffffdf..26869fa715 100644 --- a/GUI/SingleAssemblyComponentResourceManager.cs +++ b/GUI/SingleAssemblyComponentResourceManager.cs @@ -6,7 +6,7 @@ using System.Collections; using System.Collections.Generic; -namespace CKAN +namespace CKAN.GUI { // Thanks and credit to this guy: https://stackoverflow.com/q/1952638/2422988 diff --git a/GUI/SingleAssemblyResourceManager.cs b/GUI/SingleAssemblyResourceManager.cs index 54cc5879d6..39dbd44f9c 100644 --- a/GUI/SingleAssemblyResourceManager.cs +++ b/GUI/SingleAssemblyResourceManager.cs @@ -5,7 +5,7 @@ using System.Reflection; using System.Collections.Generic; -namespace CKAN +namespace CKAN.GUI { // Thanks and credit to this guy: https://stackoverflow.com/q/1952638/2422988 diff --git a/GUI/TabController.cs b/GUI/TabController.cs index 789b09b484..0044a5f74e 100644 --- a/GUI/TabController.cs +++ b/GUI/TabController.cs @@ -3,7 +3,7 @@ using System.Threading.Tasks; using System.Threading; -namespace CKAN +namespace CKAN.GUI { public class TabController diff --git a/GUI/URLHandlers.cs b/GUI/URLHandlers.cs index 1311125d11..f5ef13751b 100644 --- a/GUI/URLHandlers.cs +++ b/GUI/URLHandlers.cs @@ -8,7 +8,7 @@ using IniParser.Model; using log4net; -namespace CKAN +namespace CKAN.GUI { public static class URLHandlers { diff --git a/GUI/Util.cs b/GUI/Util.cs index 2caf80f682..ad60d6b6bc 100644 --- a/GUI/Util.cs +++ b/GUI/Util.cs @@ -4,7 +4,7 @@ using System.Drawing; using log4net; -namespace CKAN +namespace CKAN.GUI { using System.Runtime.InteropServices; using System.Windows.Forms; diff --git a/GUI/X11.cs b/GUI/X11.cs index d817735ac2..3af9a9d101 100644 --- a/GUI/X11.cs +++ b/GUI/X11.cs @@ -2,7 +2,7 @@ using System.Reflection; using System.Runtime.InteropServices; -namespace CKAN +namespace CKAN.GUI { public struct XClassHint { diff --git a/Tests/AutoUpdate/ResourcesTests.cs b/Tests/AutoUpdate/ResourcesTests.cs new file mode 100644 index 0000000000..049c76a10c --- /dev/null +++ b/Tests/AutoUpdate/ResourcesTests.cs @@ -0,0 +1,37 @@ +using System; +using System.Linq; +using System.Resources; +using System.Globalization; +using NUnit.Framework; + +namespace Tests.AutoUpdateHelper +{ + [TestFixture] + public class ResourcesTests + { + /// <summary> + /// .resx files should never have a $this.Language property because it + /// does not deserialize properly in Windows when serialized on Mono 6+ + /// + /// This test covers the AutoUpdate/Properties/Resources.resx files. + /// </summary> + [Test] + public void PropertiesResources_LanguageResource_NotSet() + { + // Arrange + ResourceManager resources = new CKAN.AutoUpdateHelper.SingleAssemblyResourceManager( + "CKAN.AutoUpdateHelper.Properties.Resources", typeof(CKAN.AutoUpdateHelper.Properties.Resources).Assembly); + + // Act/Assert + foreach (CultureInfo resourceCulture in cultures) + { + Assert.IsNull(resources.GetObject("$this.Language", resourceCulture)); + } + } + + // The cultures to test + private static CultureInfo[] cultures = CKAN.Utilities.AvailableLanguages + .Select(l => new CultureInfo(l)) + .ToArray(); + } +} diff --git a/Tests/CmdLine/ResourcesTests.cs b/Tests/CmdLine/ResourcesTests.cs new file mode 100644 index 0000000000..83c6dad3dd --- /dev/null +++ b/Tests/CmdLine/ResourcesTests.cs @@ -0,0 +1,37 @@ +using System; +using System.Linq; +using System.Resources; +using System.Globalization; +using NUnit.Framework; + +namespace Tests.CmdLine +{ + [TestFixture] + public class ResourcesTests + { + /// <summary> + /// .resx files should never have a $this.Language property because it + /// does not deserialize properly in Windows when serialized on Mono 6+ + /// + /// This test covers the CmdLine/Properties/Resources.resx files. + /// </summary> + [Test] + public void PropertiesResources_LanguageResource_NotSet() + { + // Arrange + ResourceManager resources = new CKAN.CmdLine.SingleAssemblyResourceManager( + "CKAN.CmdLine.Properties.Resources", typeof(CKAN.CmdLine.Properties.Resources).Assembly); + + // Act/Assert + foreach (CultureInfo resourceCulture in cultures) + { + Assert.IsNull(resources.GetObject("$this.Language", resourceCulture)); + } + } + + // The cultures to test + private static CultureInfo[] cultures = CKAN.Utilities.AvailableLanguages + .Select(l => new CultureInfo(l)) + .ToArray(); + } +} diff --git a/Tests/ConsoleUI/ResourcesTests.cs b/Tests/ConsoleUI/ResourcesTests.cs new file mode 100644 index 0000000000..c943590414 --- /dev/null +++ b/Tests/ConsoleUI/ResourcesTests.cs @@ -0,0 +1,37 @@ +using System; +using System.Linq; +using System.Resources; +using System.Globalization; +using NUnit.Framework; + +namespace Tests.ConsoleUI +{ + [TestFixture] + public class ResourcesTests + { + /// <summary> + /// .resx files should never have a $this.Language property because it + /// does not deserialize properly in Windows when serialized on Mono 6+ + /// + /// This test covers the ConsoleUI/Properties/Resources.resx files. + /// </summary> + [Test] + public void PropertiesResources_LanguageResource_NotSet() + { + // Arrange + ResourceManager resources = new CKAN.ConsoleUI.SingleAssemblyResourceManager( + "CKAN.ConsoleUI.Properties.Resources", typeof(CKAN.ConsoleUI.Properties.Resources).Assembly); + + // Act/Assert + foreach (CultureInfo resourceCulture in cultures) + { + Assert.IsNull(resources.GetObject("$this.Language", resourceCulture)); + } + } + + // The cultures to test + private static CultureInfo[] cultures = CKAN.Utilities.AvailableLanguages + .Select(l => new CultureInfo(l)) + .ToArray(); + } +} diff --git a/Tests/Core/Net/AutoUpdateTests.cs b/Tests/Core/Net/AutoUpdateTests.cs index c25455d839..eb3280ab76 100644 --- a/Tests/Core/Net/AutoUpdateTests.cs +++ b/Tests/Core/Net/AutoUpdateTests.cs @@ -22,7 +22,7 @@ public void FetchLatestReleaseInfo() // This is on by default in .NET 4.6, but not in 4.5. ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12; - var updater = AutoUpdate.Instance; + var updater = CKAN.AutoUpdate.Instance; // Is is a *really* basic test to just make sure we get release info // if we ask for it. diff --git a/Tests/Core/ResourcesTests.cs b/Tests/Core/ResourcesTests.cs new file mode 100644 index 0000000000..611992344e --- /dev/null +++ b/Tests/Core/ResourcesTests.cs @@ -0,0 +1,37 @@ +using System; +using System.Linq; +using System.Resources; +using System.Globalization; +using NUnit.Framework; + +namespace Tests.Core +{ + [TestFixture] + public class ResourcesTests + { + /// <summary> + /// .resx files should never have a $this.Language property because it + /// does not deserialize properly in Windows when serialized on Mono 6+ + /// + /// This test covers the Core/Properties/Resources.resx files. + /// </summary> + [Test] + public void PropertiesResources_LanguageResource_NotSet() + { + // Arrange + ResourceManager resources = new CKAN.SingleAssemblyResourceManager( + "CKAN.Properties.Resources", typeof(CKAN.Properties.Resources).Assembly); + + // Act/Assert + foreach (CultureInfo resourceCulture in cultures) + { + Assert.IsNull(resources.GetObject("$this.Language", resourceCulture)); + } + } + + // The cultures to test + private static CultureInfo[] cultures = CKAN.Utilities.AvailableLanguages + .Select(l => new CultureInfo(l)) + .ToArray(); + } +} diff --git a/Tests/GUI/GUIConfiguration.cs b/Tests/GUI/GUIConfiguration.cs index b2d8acc260..a1623688cc 100644 --- a/Tests/GUI/GUIConfiguration.cs +++ b/Tests/GUI/GUIConfiguration.cs @@ -1,5 +1,6 @@ using System.IO; using CKAN; +using CKAN.GUI; using NUnit.Framework; using Tests.Data; diff --git a/Tests/GUI/Model/GUIMod.cs b/Tests/GUI/Model/GUIMod.cs index 25e85e7fd8..18fabac8f5 100644 --- a/Tests/GUI/Model/GUIMod.cs +++ b/Tests/GUI/Model/GUIMod.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using CKAN; +using CKAN.GUI; using CKAN.Versioning; using NUnit.Framework; using Tests.Core; diff --git a/Tests/GUI/Model/ModList.cs b/Tests/GUI/Model/ModList.cs index cca875147e..bb1bc78643 100644 --- a/Tests/GUI/Model/ModList.cs +++ b/Tests/GUI/Model/ModList.cs @@ -10,6 +10,7 @@ using Tests.Data; using CKAN; +using CKAN.GUI; using CKAN.Versioning; namespace Tests.GUI diff --git a/Tests/GUI/NavigationHistoryTests.cs b/Tests/GUI/NavigationHistoryTests.cs index 0c0355f993..f42aa578f7 100644 --- a/Tests/GUI/NavigationHistoryTests.cs +++ b/Tests/GUI/NavigationHistoryTests.cs @@ -1,9 +1,10 @@ +using System; +using CKAN; +using CKAN.GUI; +using NUnit.Framework; + namespace Tests.GUI { - using System; - using CKAN; - using NUnit.Framework; - [TestFixture] public class NavigationHistoryTests { diff --git a/Tests/GUI/ResourcesTests.cs b/Tests/GUI/ResourcesTests.cs index 7f514ba3ea..642def7907 100644 --- a/Tests/GUI/ResourcesTests.cs +++ b/Tests/GUI/ResourcesTests.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Resources; using System.ComponentModel; using System.Globalization; using NUnit.Framework; @@ -12,42 +13,64 @@ public class ResourcesTests /// <summary> /// .resx files should never have a $this.Language property because it /// does not deserialize properly in Windows when serialized on Mono 6+ + /// + /// This test covers the GUI/Properties/Resources.resx files. + /// </summary> + [Test] + public void PropertiesResources_LanguageResource_NotSet() + { + // Arrange + ResourceManager resources = new CKAN.GUI.SingleAssemblyResourceManager( + "CKAN.GUI.Properties.Resources", typeof(CKAN.GUI.Properties.Resources).Assembly); + + // Act/Assert + foreach (CultureInfo resourceCulture in cultures) + { + Assert.IsNull(resources.GetObject("$this.Language", resourceCulture)); + } + } + + /// <summary> + /// .resx files should never have a $this.Language property because it + /// does not deserialize properly in Windows when serialized on Mono 6+ + /// + /// This test covers the controls and dialogs. /// </summary> [Test, // Controls - TestCase(typeof(CKAN.AllModVersions)), - TestCase(typeof(CKAN.Changeset)), - TestCase(typeof(CKAN.ChooseProvidedMods)), - TestCase(typeof(CKAN.ChooseRecommendedMods)), - TestCase(typeof(CKAN.DeleteDirectories)), - TestCase(typeof(CKAN.EditModpack)), - TestCase(typeof(CKAN.EditModSearch)), - TestCase(typeof(CKAN.HintTextBox)), - TestCase(typeof(CKAN.ManageMods)), - TestCase(typeof(CKAN.ModInfo)), - TestCase(typeof(CKAN.Wait)), + TestCase(typeof(CKAN.GUI.AllModVersions)), + TestCase(typeof(CKAN.GUI.Changeset)), + TestCase(typeof(CKAN.GUI.ChooseProvidedMods)), + TestCase(typeof(CKAN.GUI.ChooseRecommendedMods)), + TestCase(typeof(CKAN.GUI.DeleteDirectories)), + TestCase(typeof(CKAN.GUI.EditModpack)), + TestCase(typeof(CKAN.GUI.EditModSearch)), + TestCase(typeof(CKAN.GUI.HintTextBox)), + TestCase(typeof(CKAN.GUI.ManageMods)), + TestCase(typeof(CKAN.GUI.ModInfo)), + TestCase(typeof(CKAN.GUI.Wait)), // Dialogs - TestCase(typeof(CKAN.Main)), - TestCase(typeof(CKAN.AboutDialog)), - TestCase(typeof(CKAN.AskUserForAutoUpdatesDialog)), - TestCase(typeof(CKAN.CloneFakeGameDialog)), - TestCase(typeof(CKAN.CompatibleGameVersionsDialog)), - TestCase(typeof(CKAN.EditLabelsDialog)), - TestCase(typeof(CKAN.ErrorDialog)), - TestCase(typeof(CKAN.GameCommandLineOptionsDialog)), - TestCase(typeof(CKAN.ManageGameInstancesDialog)), - TestCase(typeof(CKAN.NewRepoDialog)), - TestCase(typeof(CKAN.NewUpdateDialog)), - TestCase(typeof(CKAN.PluginsDialog)), - TestCase(typeof(CKAN.RenameInstanceDialog)), - TestCase(typeof(CKAN.SelectionDialog)), - TestCase(typeof(CKAN.YesNoDialog)), + TestCase(typeof(CKAN.GUI.Main)), + TestCase(typeof(CKAN.GUI.AboutDialog)), + TestCase(typeof(CKAN.GUI.AskUserForAutoUpdatesDialog)), + TestCase(typeof(CKAN.GUI.CloneFakeGameDialog)), + TestCase(typeof(CKAN.GUI.CompatibleGameVersionsDialog)), + TestCase(typeof(CKAN.GUI.EditLabelsDialog)), + TestCase(typeof(CKAN.GUI.ErrorDialog)), + TestCase(typeof(CKAN.GUI.GameCommandLineOptionsDialog)), + TestCase(typeof(CKAN.GUI.ManageGameInstancesDialog)), + TestCase(typeof(CKAN.GUI.NewRepoDialog)), + TestCase(typeof(CKAN.GUI.NewUpdateDialog)), + TestCase(typeof(CKAN.GUI.PluginsDialog)), + TestCase(typeof(CKAN.GUI.RenameInstanceDialog)), + TestCase(typeof(CKAN.GUI.SelectionDialog)), + TestCase(typeof(CKAN.GUI.YesNoDialog)), ] public void ControlOrDialog_LanguageResource_NotSet(Type t) { // Arrange - ComponentResourceManager resources = new CKAN.SingleAssemblyComponentResourceManager(t); + ComponentResourceManager resources = new CKAN.GUI.SingleAssemblyComponentResourceManager(t); // Act/Assert foreach (CultureInfo resourceCulture in cultures) diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 5e23ce140b..01a614d6bf 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -30,7 +30,7 @@ </Otherwise> </Choose> <PropertyGroup Condition=" '$(TargetFramework)' == 'net5.0' "> - <DefaultItemExcludes>$(DefaultItemExcludes);NetKAN\**;GUI\**</DefaultItemExcludes> + <DefaultItemExcludes>$(DefaultItemExcludes);NetKAN\**;CmdLine\**;ConsoleUI\**;GUI\**;AutoUpdate\**</DefaultItemExcludes> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)' == 'Debug_NetCore' "> <DebugSymbols>true</DebugSymbols> @@ -74,7 +74,10 @@ <Choose> <When Condition=" '$(TargetFramework)' == 'net45' "> <ItemGroup> + <ProjectReference Include="..\Cmdline\CKAN-cmdline.csproj" /> + <ProjectReference Include="..\ConsoleUI\CKAN-ConsoleUI.csproj" /> <ProjectReference Include="..\GUI\CKAN-GUI.csproj" /> + <ProjectReference Include="..\AutoUpdate\CKAN-autoupdate.csproj" /> <ProjectReference Include="..\Netkan\CKAN-netkan.csproj" /> </ItemGroup> </When> diff --git a/build.cake b/build.cake index cdbc1421d6..a7a1ce85c1 100644 --- a/build.cake +++ b/build.cake @@ -262,16 +262,16 @@ Task("Repack-Ckan") .IsDependentOn("Build-DotNet") .Does(() => { - var cmdLineBinDirectory = outDirectory.Combine("CmdLine").Combine(configuration).Combine("bin"); + var cmdLineBinDirectory = outDirectory.Combine("CKAN-CmdLine").Combine(configuration).Combine("bin").Combine(buildNetFramework); var assemblyPaths = GetFiles(string.Format("{0}/*.dll", cmdLineBinDirectory)); assemblyPaths.Add(cmdLineBinDirectory.CombineWithFilePath("CKAN-GUI.exe")); assemblyPaths.Add(cmdLineBinDirectory.CombineWithFilePath("CKAN-ConsoleUI.exe")); assemblyPaths.Add(GetFiles(string.Format( "{0}/*/*.resources.dll", - outDirectory.Combine("CKAN-GUI").Combine(configuration).Combine("bin") + outDirectory.Combine("CKAN-CmdLine").Combine(configuration).Combine("bin").Combine(buildNetFramework) ))); - ILRepack(ckanFile, cmdLineBinDirectory.CombineWithFilePath("CmdLine.exe"), assemblyPaths, + ILRepack(ckanFile, cmdLineBinDirectory.CombineWithFilePath("CKAN-CmdLine.exe"), assemblyPaths, new ILRepackSettings { Libs = new List<DirectoryPath> { cmdLineBinDirectory.ToString() }, diff --git a/doc/building.md b/doc/building.md index d1c19d719e..5da51cc753 100644 --- a/doc/building.md +++ b/doc/building.md @@ -22,7 +22,7 @@ The following are the minimum requirements to build CKAN and NetKAN from source: ### Unix-like Systems - A POSIX compliant shell interpreter at `/bin/sh` - [Mono](http://www.mono-project.com/) >= 4.0.0 -- [cURL](https://curl.haxx.se/) accessible in PATH +- [cURL](https://curl.haxx.se/) accessible in PATH ### Windows Systems - PowerShell @@ -32,7 +32,7 @@ The following are the minimum requirements to build CKAN and NetKAN from source: ## Build Directory A core philosophy of the build system is that builds should be "clean", that is it should be easy to restore the source -directory to its original state after a build. As such **ALL** build artifacts should be output to a top-level +directory to its original state after a build. As such **ALL** build artifacts should be output to a top-level directory named `_build`. This directory is listed in `.gitignore` so that is not committed to source control. Removing this directory (`rm -r _build`) should return the source directory to its original state. Therefore any build artifacts that are output outside this directory should be considered a bug. @@ -195,13 +195,13 @@ The basic operation of the actual build process is as follows: - These are simple tests designed to make sure there isn't anything grossly wrong with the build. All they do is execute the repacked `ckan.exe` and `netkan.exe` and make sure their version output matches the expected output. -## Travis +## GitHub Workflows -Travis is the continuous integration (CI) environment that is used to automatically build CKAN and NetKAN. Travis's -configuration is controlled by `.travis.yml` in the top-level directory. Upon every push Travis will execute the cross -product of mono versions and build configurations. As there are currently three specified mono versions (`4.6.2`, -`4.2.4`, and `4.0.5`) and two specified build configurations (`Debug`, `Release`), Travis will execute *six* builds per -push. Travis's operation is pretty simple: +GitHub Workflows is the continuous integration (CI) environment that is used to automatically build CKAN and NetKAN. Its +configuration is controlled by `build.yml` in the `.github/workflows` directory. Upon every push GitHub will execute the cross +product of mono versions and build configurations. As there are currently five specified mono versions (`5.20`, +`6.4`, `6.6`, `6.8` and `latest`) and two specified build configurations (`Debug`, `Release`), GitHub will execute *six* builds per +push. GitHub's operation is pretty simple: - A bunch of packages are installed to make the build work. - Some commands are executed to simulate a graphical environment for testing. @@ -211,11 +211,11 @@ push. Travis's operation is pretty simple: thus behave nondeterministically (frustrating behavior for a CI system). - The built executables (`ckan.exe` and `netkan.exe`) are uploaded to Amazon S3 if the following conditions are met: - All previous steps were successful - - Its on the `master` branch + - It's on the `master` branch - The build configuraton is `Release` - - The mono version used is the latest (currently `4.6.2`) + - The mono version used is the latest - A GitHub release is generated if the following conditions are met: - All previous steps were successful - The commit is tagged - The build configuration is `Release` - - The mono version used is the latest (currently `4.6.2`) \ No newline at end of file + - The mono version used is the latest