Add core classes.
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard1.6</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
32
Claunia.Localization.Core/Language.cs
Normal file
32
Claunia.Localization.Core/Language.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
namespace Claunia.Localization.Core
|
||||
{
|
||||
/// <summary>Enumerates programming languages for parameters</summary>
|
||||
public enum Language
|
||||
{
|
||||
C,
|
||||
ObjectiveC,
|
||||
CSharp,
|
||||
Shell,
|
||||
Python,
|
||||
Lisp,
|
||||
EmacsLisp,
|
||||
PythonBraced,
|
||||
Librep,
|
||||
Scheme,
|
||||
Smalltalk,
|
||||
Java,
|
||||
Awk,
|
||||
ObjectPascal,
|
||||
Ycp,
|
||||
Tcl,
|
||||
Perl,
|
||||
Php,
|
||||
GccInternal,
|
||||
GfcInternal,
|
||||
Qt,
|
||||
QtPlural,
|
||||
Kde,
|
||||
Boost,
|
||||
JavaScript
|
||||
}
|
||||
}
|
||||
101
Claunia.Localization.Core/Localization.cs
Normal file
101
Claunia.Localization.Core/Localization.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace Claunia.Localization.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the localization
|
||||
/// </summary>
|
||||
public class Localization
|
||||
{
|
||||
readonly ObservableCollection<Message> messages;
|
||||
readonly ObservableCollection<Translator> translators;
|
||||
|
||||
public Localization()
|
||||
{
|
||||
Creation = DateTime.UtcNow;
|
||||
LastWritten = DateTime.UtcNow;
|
||||
Project = new Project();
|
||||
Project.ProjectModified += OnModified;
|
||||
translators = new ObservableCollection<Translator>();
|
||||
Translators = new ReadOnlyObservableCollection<Translator>(translators);
|
||||
translators.CollectionChanged += OnModified;
|
||||
messages = new ObservableCollection<Message>();
|
||||
Messages = new ReadOnlyObservableCollection<Message>(messages);
|
||||
messages.CollectionChanged += OnModified;
|
||||
}
|
||||
|
||||
/// <summary>Date this localization has been created</summary>
|
||||
public DateTime Creation { get; }
|
||||
/// <summary>Date this localization has been modified</summary>
|
||||
public DateTime LastWritten { get; private set; }
|
||||
/// <summary>Project this localization belongs to</summary>
|
||||
public Project Project { get; }
|
||||
/// <summary>List of translators that have worked in this localization</summary>
|
||||
public ReadOnlyObservableCollection<Translator> Translators { get; }
|
||||
/// <summary>
|
||||
/// List of messages present in this localization
|
||||
/// </summary>
|
||||
public ReadOnlyObservableCollection<Message> Messages { get; }
|
||||
|
||||
void OnModified(object sender, EventArgs args)
|
||||
{
|
||||
LastWritten = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new translator to the localization
|
||||
/// </summary>
|
||||
/// <param name="name">Translator full name, english-form, in ASCII</param>
|
||||
/// <param name="email">Translator e-mail</param>
|
||||
/// <param name="nativeName">Translator full name, in native form</param>
|
||||
/// <returns>The new translator</returns>
|
||||
public Translator NewTranslator(string name, string email, string nativeName = null)
|
||||
{
|
||||
int id = translators.Max(t => t.Id) + 1;
|
||||
Translator translator = new Translator(id) {Name = name, Email = email};
|
||||
translator.Modified += OnModified;
|
||||
|
||||
translators.Add(translator);
|
||||
|
||||
return translator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a translator from the localization
|
||||
/// </summary>
|
||||
/// <param name="translator">Translator to remove</param>
|
||||
/// <returns><c>true</c> if the translator has been removed successfully, <c>false</c> otherwise</returns>
|
||||
public bool RemoveTranslator(Translator translator) => !(translator is null) && translators.Remove(translator);
|
||||
|
||||
/// <summary>
|
||||
/// Removes a translator from the localization
|
||||
/// </summary>
|
||||
/// <param name="id">ID of the translator to remove</param>
|
||||
/// <returns><c>true</c> if the translator has been removed successfully, <c>false</c> otherwise</returns>
|
||||
public bool RemoveTranslator(int id)
|
||||
{
|
||||
Translator translator = translators.FirstOrDefault(t => t.Id == id);
|
||||
return !(translator is null) && translators.Remove(translator);
|
||||
}
|
||||
|
||||
public Message NewMessage()
|
||||
{
|
||||
Message message = new Message();
|
||||
message.Modified += OnModified;
|
||||
|
||||
messages.Add(message);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
public bool RemoveMessage(Message message) => !(message is null) && messages.Remove(message);
|
||||
|
||||
public bool RemoveMessage(string id)
|
||||
{
|
||||
Message message = messages.FirstOrDefault(t => t.Id == id);
|
||||
return !(message is null) && messages.Remove(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
103
Claunia.Localization.Core/LocalizedString.cs
Normal file
103
Claunia.Localization.Core/LocalizedString.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Claunia.Localization.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represent a localized string
|
||||
/// </summary>
|
||||
public sealed class LocalizedString
|
||||
{
|
||||
readonly ObservableCollection<Plural> plurals;
|
||||
string comments;
|
||||
string locale;
|
||||
internal EventHandler Modified;
|
||||
string singular;
|
||||
int? translator;
|
||||
|
||||
internal LocalizedString()
|
||||
{
|
||||
plurals = new ObservableCollection<Plural>();
|
||||
plurals.CollectionChanged += (sender, args) => Modified?.Invoke(this, EventArgs.Empty);
|
||||
Plurals = new ReadOnlyObservableCollection<Plural>(plurals);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains the singular, or only, text for this string
|
||||
/// </summary>
|
||||
public string Singular
|
||||
{
|
||||
get => singular;
|
||||
set
|
||||
{
|
||||
singular = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Which locale this string is in. Format is ll_CC with ll as ISO 639-2 language code and CC as ISO 3166 two letter
|
||||
/// uppercase country code. _CC can be omitted.
|
||||
/// </summary>
|
||||
public string Locale
|
||||
{
|
||||
get => locale;
|
||||
set
|
||||
{
|
||||
locale = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ID of the translator, in this localization, that wrote this string
|
||||
/// </summary>
|
||||
public int? Translator
|
||||
{
|
||||
get => translator;
|
||||
set
|
||||
{
|
||||
translator = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Translator comments
|
||||
/// </summary>
|
||||
public string Comments
|
||||
{
|
||||
get => comments;
|
||||
set
|
||||
{
|
||||
comments = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Plural forms for this string
|
||||
/// </summary>
|
||||
public ReadOnlyObservableCollection<Plural> Plurals { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new plural in this message
|
||||
/// </summary>
|
||||
/// <returns>The newly initialized plural</returns>
|
||||
public Plural NewPlural()
|
||||
{
|
||||
Plural parameter = new Plural();
|
||||
parameter.Modified += Modified;
|
||||
plurals.Add(parameter);
|
||||
|
||||
return parameter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a plural
|
||||
/// </summary>
|
||||
/// <param name="parameter">The plural to remove</param>
|
||||
/// <returns><c>true</c> if the plural string has been removed successfully, <c>false</c> otherwise</returns>
|
||||
public bool RemovePlural(Plural parameter) => plurals.Remove(parameter);
|
||||
}
|
||||
}
|
||||
150
Claunia.Localization.Core/Message.cs
Normal file
150
Claunia.Localization.Core/Message.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Claunia.Localization.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represent a message and its translations
|
||||
/// </summary>
|
||||
public sealed class Message
|
||||
{
|
||||
readonly ObservableCollection<Parameter> parameters;
|
||||
readonly ObservableCollection<LocalizedString> translations;
|
||||
string comments;
|
||||
string context;
|
||||
string id;
|
||||
internal EventHandler Modified;
|
||||
string previousContext;
|
||||
string reference;
|
||||
|
||||
internal Message()
|
||||
{
|
||||
Source = new LocalizedString();
|
||||
Source.Modified += Modified;
|
||||
translations = new ObservableCollection<LocalizedString>();
|
||||
translations.CollectionChanged += (sender, args) => Modified?.Invoke(this, EventArgs.Empty);
|
||||
parameters = new ObservableCollection<Parameter>();
|
||||
parameters.CollectionChanged += (sender, args) => Modified?.Invoke(this, EventArgs.Empty);
|
||||
Translations = new ReadOnlyObservableCollection<LocalizedString>(translations);
|
||||
Parameters = new ReadOnlyObservableCollection<Parameter>(parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes the context where this message occurs
|
||||
/// </summary>
|
||||
public string Context
|
||||
{
|
||||
get => context;
|
||||
set
|
||||
{
|
||||
context = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes the context where the previous version of this message occurred
|
||||
/// </summary>
|
||||
public string PreviousContext
|
||||
{
|
||||
get => previousContext;
|
||||
set
|
||||
{
|
||||
previousContext = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Comments added by the original writer of the message
|
||||
/// </summary>
|
||||
public string Comments
|
||||
{
|
||||
get => comments;
|
||||
set
|
||||
{
|
||||
comments = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Source code line reference or equivalent
|
||||
/// </summary>
|
||||
public string Reference
|
||||
{
|
||||
get => reference;
|
||||
set
|
||||
{
|
||||
reference = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unique identifier of this message
|
||||
/// </summary>
|
||||
public string Id
|
||||
{
|
||||
get => id;
|
||||
set
|
||||
{
|
||||
id = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Original locale of this message
|
||||
/// </summary>
|
||||
public LocalizedString Source { get; }
|
||||
/// <summary>
|
||||
/// List of translations
|
||||
/// </summary>
|
||||
public ReadOnlyObservableCollection<LocalizedString> Translations { get; }
|
||||
/// <summary>
|
||||
/// List of parameters
|
||||
/// </summary>
|
||||
public ReadOnlyObservableCollection<Parameter> Parameters { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new localized string in this message
|
||||
/// </summary>
|
||||
/// <returns>The newly initialized localized string</returns>
|
||||
public LocalizedString NewLocalizedString()
|
||||
{
|
||||
LocalizedString localizedString = new LocalizedString();
|
||||
localizedString.Modified += Modified;
|
||||
translations.Add(localizedString);
|
||||
|
||||
return localizedString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a localized string
|
||||
/// </summary>
|
||||
/// <param name="localizedString">The localized string to remove</param>
|
||||
/// <returns><c>true</c> if the localized string has been removed successfully, <c>false</c> otherwise</returns>
|
||||
public bool RemoveLocalizedString(LocalizedString localizedString) => translations.Remove(localizedString);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new parameter in this message
|
||||
/// </summary>
|
||||
/// <returns>The newly initialized parameter</returns>
|
||||
public Parameter NewParameter()
|
||||
{
|
||||
Parameter parameter = new Parameter();
|
||||
parameter.Modified += Modified;
|
||||
parameters.Add(parameter);
|
||||
|
||||
return parameter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a parameter
|
||||
/// </summary>
|
||||
/// <param name="parameter">The parameter to remove</param>
|
||||
/// <returns><c>true</c> if the parameter string has been removed successfully, <c>false</c> otherwise</returns>
|
||||
public bool RemoveParameter(Parameter parameter) => parameters.Remove(parameter);
|
||||
}
|
||||
}
|
||||
97
Claunia.Localization.Core/Parameter.cs
Normal file
97
Claunia.Localization.Core/Parameter.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
|
||||
namespace Claunia.Localization.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Explanation of a parameter in a software string to help the translator understand the context and for translation
|
||||
/// helping software to be able to provide appropriate examples
|
||||
/// </summary>
|
||||
public class Parameter
|
||||
{
|
||||
string description;
|
||||
int index;
|
||||
Language language;
|
||||
long? maximum;
|
||||
long? minimum;
|
||||
internal EventHandler Modified;
|
||||
string type;
|
||||
|
||||
/// <summary>
|
||||
/// Index of parameter in source message
|
||||
/// </summary>
|
||||
public int Index
|
||||
{
|
||||
get => index;
|
||||
set
|
||||
{
|
||||
index = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Programming language for interpretation of messages
|
||||
/// </summary>
|
||||
public Language Language
|
||||
{
|
||||
get => language;
|
||||
set
|
||||
{
|
||||
language = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simple (single-word) description of parameter type
|
||||
/// </summary>
|
||||
public string Type
|
||||
{
|
||||
get => type;
|
||||
set
|
||||
{
|
||||
type = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimum value the parameter can get
|
||||
/// </summary>
|
||||
public long? Minimum
|
||||
{
|
||||
get => minimum;
|
||||
set
|
||||
{
|
||||
minimum = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maximum value the parameter can get
|
||||
/// </summary>
|
||||
public long? Maximum
|
||||
{
|
||||
get => maximum;
|
||||
set
|
||||
{
|
||||
maximum = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Description of the parameter
|
||||
/// </summary>
|
||||
public string Description
|
||||
{
|
||||
get => description;
|
||||
set
|
||||
{
|
||||
description = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
40
Claunia.Localization.Core/Plural.cs
Normal file
40
Claunia.Localization.Core/Plural.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace Claunia.Localization.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains the plural forms of a string
|
||||
/// </summary>
|
||||
public class Plural
|
||||
{
|
||||
int items;
|
||||
internal EventHandler Modified;
|
||||
string text;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum number (inclusive) of items named to use this plural form
|
||||
/// </summary>
|
||||
public int Items
|
||||
{
|
||||
get => items;
|
||||
set
|
||||
{
|
||||
items = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Plural form of the string
|
||||
/// </summary>
|
||||
public string Text
|
||||
{
|
||||
get => text;
|
||||
set
|
||||
{
|
||||
text = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Claunia.Localization.Core/Project.cs
Normal file
51
Claunia.Localization.Core/Project.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
|
||||
namespace Claunia.Localization.Core
|
||||
{
|
||||
public class Project
|
||||
{
|
||||
string name;
|
||||
|
||||
internal EventHandler ProjectModified;
|
||||
string url;
|
||||
string version;
|
||||
/// <summary>
|
||||
/// Project name
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get => name;
|
||||
set
|
||||
{
|
||||
name = value;
|
||||
ProjectModified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Project version
|
||||
/// </summary>
|
||||
public string Version
|
||||
{
|
||||
get => version;
|
||||
set
|
||||
{
|
||||
version = value;
|
||||
ProjectModified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Project URL
|
||||
/// </summary>
|
||||
public string Url
|
||||
{
|
||||
get => url;
|
||||
set
|
||||
{
|
||||
url = value;
|
||||
ProjectModified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
Claunia.Localization.Core/Translator.cs
Normal file
63
Claunia.Localization.Core/Translator.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
|
||||
namespace Claunia.Localization.Core
|
||||
{
|
||||
public class Translator
|
||||
{
|
||||
string email;
|
||||
internal EventHandler Modified;
|
||||
string name;
|
||||
string nativeName;
|
||||
|
||||
internal Translator(int id)
|
||||
{
|
||||
Id = id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Translator ID, unique in the corresponding localization, and sequential
|
||||
/// </summary>
|
||||
public int Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Translator e-mail
|
||||
/// </summary>
|
||||
public string Email
|
||||
{
|
||||
get => email;
|
||||
set
|
||||
{
|
||||
email = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Translator name, in ASCII, english form
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get => name;
|
||||
set
|
||||
{
|
||||
name = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Translator full name in native form
|
||||
/// </summary>
|
||||
public string NativeName
|
||||
{
|
||||
get => nativeName ?? Name;
|
||||
set
|
||||
{
|
||||
if(value == name) return;
|
||||
|
||||
nativeName = value;
|
||||
Modified?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Claunia.Localization", "Cla
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Claunia.Localization.Desktop", "Claunia.Localization\Claunia.Localization.Desktop\Claunia.Localization.Desktop.csproj", "{258FEA96-4E93-4C8F-94EF-1319F93B350D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Claunia.Localization.Core", "Claunia.Localization.Core\Claunia.Localization.Core.csproj", "{CFDFDFC7-9662-4C50-B86A-9E579ACD3DF9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -20,5 +22,9 @@ Global
|
||||
{258FEA96-4E93-4C8F-94EF-1319F93B350D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{258FEA96-4E93-4C8F-94EF-1319F93B350D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{258FEA96-4E93-4C8F-94EF-1319F93B350D}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{CFDFDFC7-9662-4C50-B86A-9E579ACD3DF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CFDFDFC7-9662-4C50-B86A-9E579ACD3DF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CFDFDFC7-9662-4C50-B86A-9E579ACD3DF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CFDFDFC7-9662-4C50-B86A-9E579ACD3DF9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Reference in New Issue
Block a user