diff --git a/tabler.Logic/Classes/ItemSelected.cs b/tabler.Logic/Classes/ItemSelected.cs new file mode 100644 index 0000000..0e714d7 --- /dev/null +++ b/tabler.Logic/Classes/ItemSelected.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace tabler.Logic.Classes +{ + public class ItemSelected + { + public bool IsSelected { get; set; } + public string DisplayName { get; set; } + public string Key { get; set; } + + } +} diff --git a/tabler.Logic/Classes/Key.cs b/tabler.Logic/Classes/Key.cs index 0913f6b..27e935d 100644 --- a/tabler.Logic/Classes/Key.cs +++ b/tabler.Logic/Classes/Key.cs @@ -1,41 +1,309 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Windows.Media; +using System.Xml.Linq; using System.Xml.Serialization; +using tabler.Logic.Extensions; -namespace tabler.Logic.Classes { - public class Key { - +namespace tabler.Logic.Classes +{ + [DataContract] + [Serializable] //for copy paste action + public class Key + { + [DataMember] [XmlAttribute("ID")] public string Id { get; set; } + [DataMember] public string Original { get; set; } + [DataMember] public string English { get; set; } + [DataMember] public string German { get; set; } + [DataMember] public string French { get; set; } + [DataMember] public string Italian { get; set; } + [DataMember] public string Spanish { get; set; } + [DataMember] public string Portuguese { get; set; } + [DataMember] public string Polish { get; set; } + [DataMember] public string Czech { get; set; } + [DataMember] public string Hungarian { get; set; } + [DataMember] public string Russian { get; set; } + [DataMember] public string Turkish { get; set; } + [DataMember] public string Japanese { get; set; } + [DataMember] public string Chinesesimp { get; set; } + [DataMember] public string Chinese { get; set; } + [DataMember] public string Korean { get; set; } + + //[IgnoreDataMember] + //[XmlIgnore] + //[SoapIgnore] + //public string PackageName { get; set; } + //[IgnoreDataMember] + //[XmlIgnore] + //[SoapIgnore] + //public string ContainerName { get; set; } + + //[IgnoreDataMember] + //[XmlIgnore] + //[SoapIgnore] + //public bool IsComplete { get; set; } + + //[IgnoreDataMember] + //[XmlIgnore] + //[SoapIgnore] + //public string IsCompleteName { get { return IsComplete ? "Complete translation" : "Incomplete translation"; } } + + //private bool IsLanguageComplete(string nameofProp, string valuesOfProp, List languagesToHave) + //{ + // if (languagesToHave.Any(x => x == nameofProp)) + // { + // if (string.IsNullOrEmpty(valuesOfProp)) + // { + // return false; + // } + // } + // return true; + //} + + //public void UpdateIsComplete(List languagesToHave) + //{ + // if (!IsLanguageComplete(nameof(English), English, languagesToHave)) + // { + // IsComplete = false; + // return; + // }; + // if (!IsLanguageComplete(nameof(German), German, languagesToHave)) + // { + // IsComplete = false; + // return; + // }; + // if (!IsLanguageComplete(nameof(French), French, languagesToHave)) + // { + // IsComplete = false; + // return; + // }; + // if (!IsLanguageComplete(nameof(Italian), Italian, languagesToHave)) + // { + // IsComplete = false; + // return; + // }; + // if (!IsLanguageComplete(nameof(Spanish), Spanish, languagesToHave)) + // { + // IsComplete = false; + // return; + // }; + // if (!IsLanguageComplete(nameof(Portuguese), Portuguese, languagesToHave)) + // { + // IsComplete = false; + // return; + // }; + // if (!IsLanguageComplete(nameof(Polish), Polish, languagesToHave)) + // { + // IsComplete = false; + // return; + // }; + // if (!IsLanguageComplete(nameof(Czech), Czech, languagesToHave)) + // { + // IsComplete = false; + // return; + // }; + // if (!IsLanguageComplete(nameof(Hungarian), Hungarian, languagesToHave)) + // { + // IsComplete = false; + // return; + // }; + + // if (!IsLanguageComplete(nameof(Russian), Russian, languagesToHave)) + // { + // IsComplete = false; + // return; + // }; + + // if (!IsLanguageComplete(nameof(Turkish), Turkish, languagesToHave)) + // { + // IsComplete = false; + // return; + // }; + + // if (!IsLanguageComplete(nameof(Japanese), Japanese, languagesToHave)) + // { + // IsComplete = false; + // return; + // }; + + // if (!IsLanguageComplete(nameof(Chinesesimp), Chinesesimp, languagesToHave)) + // { + // IsComplete = false; + // return; + // }; + + // if (!IsLanguageComplete(nameof(Chinese), Chinese, languagesToHave)) + // { + // IsComplete = false; + // return; + // }; + // if (!IsLanguageComplete(nameof(Korean), Korean, languagesToHave)) + // { + // IsComplete = false; + // return; + // }; + + // IsComplete = true; + //} + + //public bool ContainsText(string value, bool searchOnlyInId, bool ignoreCase) + //{ + // var comp = StringComparison.InvariantCulture; + + // if (ignoreCase) + // { + // comp = StringComparison.InvariantCultureIgnoreCase; + // } + + // if (Id.ContainsEx(value, comp)) + // { + // return true; + // } + + // if (searchOnlyInId) + // { + // return false; + // } + + // if (English.ContainsEx(value, comp)) + // { + // return true; + // } + // if (German.ContainsEx(value, comp)) + // { + // return true; + // } + // if (French.ContainsEx(value, comp)) + // { + // return true; + // } + // if (Italian.ContainsEx(value, comp)) + // { + // return true; + // } + // if (Spanish.ContainsEx(value, comp)) + // { + // return true; + // } + // if (Portuguese.ContainsEx(value, comp)) + // { + // return true; + // } + // if (Polish.ContainsEx(value, comp)) + // { + // return true; + // } + // if (Czech.ContainsEx(value, comp)) + // { + // return true; + // } + // if (Hungarian.ContainsEx(value, comp)) + // { + // return true; + // } + // if (Russian.ContainsEx(value, comp)) + // { + // return true; + // } + // if (Turkish.ContainsEx(value, comp)) + // { + // return true; + // } + // if (Japanese.ContainsEx(value, comp)) + // { + // return true; + // } + // if (Chinesesimp.ContainsEx(value, comp)) + // { + // return true; + // } + // if (Chinese.ContainsEx(value, comp)) + // { + // return true; + // } + // if (Korean.ContainsEx(value, comp)) + // { + // return true; + // } + + // return false; + //} + + //internal XElement AsXElement(bool ignoreEmptyValues, List languagesToWrite) + //{ + // var res= new XElement("Key", new XAttribute("ID", Id)); + + // AddIfNecessary(res,"English", English, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "German", German, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Italian", Italian, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Spanish", Spanish, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Portuguese", Portuguese, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Polish", Polish, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Czech", Czech, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Hungarian", Hungarian, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Russian", Russian, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Turkish", Turkish, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Japanese", Japanese, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Chinesesimp", Chinesesimp, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Chinese", Chinese, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Korean", Korean, ignoreEmptyValues, languagesToWrite); + + // return res; + //} + + //private void AddIfNecessary(XElement parent,string nameOfKey , string valueOfKey, bool ignoreEmptyValues, List languagesToWrite) + //{ + // if (ignoreEmptyValues && string.IsNullOrEmpty(valueOfKey)) + // { + // return; + // } + + // if (!languagesToWrite.Contains(nameOfKey)) + // { + // return; + // } + + // parent.Add(new XElement(nameOfKey, valueOfKey)); + + + + //} + } } diff --git a/tabler.Logic/Classes/Package.cs b/tabler.Logic/Classes/Package.cs index c56011c..8279ec9 100644 --- a/tabler.Logic/Classes/Package.cs +++ b/tabler.Logic/Classes/Package.cs @@ -1,4 +1,7 @@ +using System; using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; using System.Xml.Serialization; namespace tabler.Logic.Classes { @@ -12,5 +15,10 @@ public class Package { [XmlElement("Key")] public List Keys { get; set; } + + //internal XElement AsXElement(bool ignoreEmptyValues, List languagesToWrite) + //{ + // return new XElement("Package", new XAttribute("name", Name), Keys.Select(x => x.AsXElement( ignoreEmptyValues, languagesToWrite)).ToList()); + //} } } diff --git a/tabler.Logic/Classes/Project.cs b/tabler.Logic/Classes/Project.cs index b33a553..b3bc6a2 100644 --- a/tabler.Logic/Classes/Project.cs +++ b/tabler.Logic/Classes/Project.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; using System.Xml.Serialization; namespace tabler.Logic.Classes { @@ -11,5 +13,54 @@ public class Project { [XmlElement("Package")] public List Packages { get; set; } + + //public XElement AsXelement(bool ignoreEmptyValues, List languagesToWrite) + //{ + // return new XElement("Project", new XAttribute("name", Name), Packages.Select(x => x.AsXElement(ignoreEmptyValues, languagesToWrite)).ToList()); + //} + //internal XElement AsXElement(bool ignoreEmptyValues, List languagesToWrite) + //{ + // return new XElement("Package", new XAttribute("name", Name), Keys.Select(x => x.AsXElement(ignoreEmptyValues, languagesToWrite)).ToList()); + //} + //internal XElement AsXElement(bool ignoreEmptyValues, List languagesToWrite) + //{ + // var res= new XElement("Key", new XAttribute("ID", Id)); + + // AddIfNecessary(res,"English", English, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "German", German, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Italian", Italian, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Spanish", Spanish, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Portuguese", Portuguese, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Polish", Polish, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Czech", Czech, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Hungarian", Hungarian, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Russian", Russian, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Turkish", Turkish, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Japanese", Japanese, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Chinesesimp", Chinesesimp, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Chinese", Chinese, ignoreEmptyValues, languagesToWrite); + // AddIfNecessary(res, "Korean", Korean, ignoreEmptyValues, languagesToWrite); + + // return res; + //} + + //private void AddIfNecessary(XElement parent,string nameOfKey , string valueOfKey, bool ignoreEmptyValues, List languagesToWrite) + //{ + // if (ignoreEmptyValues && string.IsNullOrEmpty(valueOfKey)) + // { + // return; + // } + + // if (!languagesToWrite.Contains(nameOfKey)) + // { + // return; + // } + + // parent.Add(new XElement(nameOfKey, valueOfKey)); + + + + //} + } } diff --git a/tabler.Logic/Classes/Settings.cs b/tabler.Logic/Classes/Settings.cs index 493c172..d336bdc 100644 --- a/tabler.Logic/Classes/Settings.cs +++ b/tabler.Logic/Classes/Settings.cs @@ -7,11 +7,19 @@ public Settings() // defaults IndentationSettings = IndentationSettings.Spaces; TabSize = 4; + Language = "de-DE"; + LastPathOfDataFiles = ""; + RemoveEmptyNodes = false; } public IndentationSettings IndentationSettings { get; set; } - public int TabSize { get; set; } + public string Language { get; set; } + public string LastPathOfDataFiles { get; set; } + public bool RemoveEmptyNodes { get; set; } + + + } public enum IndentationSettings diff --git a/tabler.Logic/Enums/LogTypeEnum.cs b/tabler.Logic/Enums/LogTypeEnum.cs new file mode 100644 index 0000000..d2fbffb --- /dev/null +++ b/tabler.Logic/Enums/LogTypeEnum.cs @@ -0,0 +1,9 @@ +namespace tabler.Logic.Enums +{ + public enum LogTypeEnum + { + General = 0, + Error = 1, + Internal = 2 + } +} diff --git a/tabler.Logic/Extensions/ExtensionMethods.cs b/tabler.Logic/Extensions/ExtensionMethods.cs new file mode 100644 index 0000000..0522f97 --- /dev/null +++ b/tabler.Logic/Extensions/ExtensionMethods.cs @@ -0,0 +1,13 @@ + +using System; + +namespace tabler.Logic.Extensions +{ + public static class ExtensionMethods + { + public static bool ContainsEx(this string source, string toCheck, StringComparison comp) + { + return source?.IndexOf(toCheck, comp) >= 0; + } + } +} diff --git a/tabler.Logic/Helper/ConfigHelper.cs b/tabler.Logic/Helper/ConfigHelper.cs index 7b2d945..7bdbd43 100644 --- a/tabler.Logic/Helper/ConfigHelper.cs +++ b/tabler.Logic/Helper/ConfigHelper.cs @@ -1,3 +1,4 @@ +using Polenter.Serialization; using System; using System.Collections.Generic; using System.IO; @@ -8,209 +9,51 @@ namespace tabler.Logic.Helper { - public class ConfigHelper + public static class ConfigHelper { - private const string LASTPATHTODATAFILES_NAME = "LastPathToDataFiles"; - private const string INDENTATION_NAME = "Indentation"; - private const string TABSIZE_NAME = "TabSize"; - private const string EMPTYNODES_NAME = "RemoveEmptyNodes"; + private static readonly FileInfo _fiConfig = new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"config\config.xml")); - private readonly FileInfo _fiConfig = new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"config\config.xml")); - private XDocument _xDocConfig; + public static Settings CurrentSettings { get; set; } - public ConfigHelper() + static ConfigHelper() { //create dir if (_fiConfig.Directory != null && _fiConfig.Directory.Exists == false) { _fiConfig.Directory.Create(); } - } - - - private XDocument CreateOrLoadConfig(bool forceCreation) - { - if (_xDocConfig != null && forceCreation == false) + if (!_fiConfig.Exists) { - return _xDocConfig; - } - - if (_fiConfig.Exists && forceCreation == false) - { - _xDocConfig = XDocument.Load(_fiConfig.FullName); + CurrentSettings = new Settings(); + SaveSettings(); } else { - var path = new XElement(LASTPATHTODATAFILES_NAME); - var indent = new XElement(INDENTATION_NAME, 0); - var tabsize = new XElement(TABSIZE_NAME, 4); - var removeEmptyNodes = new XElement(EMPTYNODES_NAME, true); - - var lstElements = new List {path, indent, tabsize, removeEmptyNodes}; - - _xDocConfig = new XDocument( - new XDeclaration("1.0", "utf-8", "yes"), - new XComment("Config file"), - new XElement("config", lstElements.ToArray())); - - SaveConfigXml(); - - return _xDocConfig; + LoadSettings(); } - - return null; } - - public void SetLastPathOfDataFiles(DirectoryInfo path) + public static void SaveSettings() { - if (path == null || path.Exists == false) + if (CurrentSettings == null) { return; } - - if (_xDocConfig == null) - { - CreateOrLoadConfig(false); - } - - - if (_xDocConfig != null) - { - var pathElement = _xDocConfig.Descendants().FirstOrDefault(d => d.Name == LASTPATHTODATAFILES_NAME); - - if (pathElement != null) - { - pathElement.Value = XmlConvert.EncodeName(path.FullName); - } - } - - SaveConfigXml(); - } - - public DirectoryInfo GetLastPathOfDataFiles() - { - if (_xDocConfig == null) - { - CreateOrLoadConfig(false); - } - - - if (_xDocConfig != null) - { - var pathElement = _xDocConfig.Descendants().FirstOrDefault(d => d.Name == LASTPATHTODATAFILES_NAME); - - if (pathElement != null) - { - var value = XmlConvert.DecodeName(pathElement.Value); - if (string.IsNullOrEmpty(value) == false) - { - return new DirectoryInfo(value); - } - } - else - { - CreateOrLoadConfig(true); - } - } - - return null; - } - - /// - /// Saves the xml to the file system - /// - private void SaveConfigXml() - { - if (_xDocConfig != null) - { - _xDocConfig.Save(_fiConfig.FullName); - } + var serializer = new SharpSerializer(); + serializer.Serialize(CurrentSettings, _fiConfig.FullName); } - /// - /// Read Settings from config file - /// - /// - public Settings GetSettings() + public static void LoadSettings() { - if (_xDocConfig == null) - { - CreateOrLoadConfig(false); - } - - if (_xDocConfig == null) - { - return null; - } - - var loadedSettings = new Settings(); - - var indentElement = _xDocConfig.Descendants().FirstOrDefault(d => d.Name == INDENTATION_NAME); - if (indentElement != null) + try { - try - { - loadedSettings.IndentationSettings = (IndentationSettings) Enum.Parse(typeof(IndentationSettings), indentElement.Value); - } - catch (Exception) - { - // in case of error, use the better method - loadedSettings.IndentationSettings = IndentationSettings.Spaces; - } + var serializer = new SharpSerializer(); + CurrentSettings = (Settings)serializer.Deserialize(_fiConfig.FullName); } - - var tabSizeElement = _xDocConfig.Descendants().FirstOrDefault(d => d.Name == TABSIZE_NAME); - if (tabSizeElement != null) + catch (Exception ex) { - loadedSettings.TabSize = int.Parse(tabSizeElement.Value); + Logger.LogEx(ex); } - - return loadedSettings; - } - - /// - /// Read Settings from config file - /// - /// - public bool SaveSettings(Settings settingsToSave) - { - if (settingsToSave == null) - { - return false; - } - - if (_xDocConfig == null) - { - CreateOrLoadConfig(false); - } - - if (_xDocConfig != null) - { - var indentElement = _xDocConfig.Descendants().FirstOrDefault(d => d.Name == INDENTATION_NAME); - if (indentElement != null) - { - indentElement.Value = settingsToSave.IndentationSettings.ToString(); - } - else - { - CreateOrLoadConfig(true); - } - - var tabSizeElement = _xDocConfig.Descendants().FirstOrDefault(d => d.Name == TABSIZE_NAME); - if (tabSizeElement != null) - { - tabSizeElement.Value = settingsToSave.TabSize.ToString(); - } - else - { - CreateOrLoadConfig(true); - } - - SaveConfigXml(); - return true; - } - - return false; - } + + } } } diff --git a/tabler.Logic/Helper/IProgress.cs b/tabler.Logic/Helper/IProgress.cs new file mode 100644 index 0000000..1512006 --- /dev/null +++ b/tabler.Logic/Helper/IProgress.cs @@ -0,0 +1,35 @@ +namespace tabler.Logic.Helper +{ + public delegate void CurrentProgressChanged(int progress, string currentAction); + public interface IProgress + { + int CurrentProgressValue { get; set; } + event CurrentProgressChanged ProgressChangedEvent; + string CurrentAction { get; set; } + } + + public class ProgressHelper : IProgress + { + public int CurrentProgressValue { get; set; } + public string CurrentAction { get; set; } + + public event CurrentProgressChanged ProgressChangedEvent; + + public void FireProgressChangedEvent(int progress, string currentAction) + { + CurrentProgressValue = progress; + CurrentAction = currentAction; + ProgressChangedEvent?.Invoke(progress, currentAction); + } + public void FireProgressNameChangedEvent(string currentAction) + { + FireProgressChangedEvent(CurrentProgressValue, currentAction); + } + public void FireProgressChangedEvent(int progress) + { + FireProgressChangedEvent(progress, CurrentAction); + } + + } + +} diff --git a/tabler.Logic/Helper/Logger.cs b/tabler.Logic/Helper/Logger.cs new file mode 100644 index 0000000..db5fddd --- /dev/null +++ b/tabler.Logic/Helper/Logger.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using tabler.Logic.Enums; + +namespace tabler.Logic.Helper +{ + public static class Logger + { + public delegate void LogMessageDelegate(string message); + + public static event LogMessageDelegate LogMessageArrived; + + public static void FireLogMessageArivedEvent(string message) + { + LogMessageArrived?.Invoke(message); + } + + public delegate void LogMessageWithTypeDelegate(string message, LogTypeEnum logType); + + public static event LogMessageWithTypeDelegate LogMessageWithTypeArrived; + + public static void FireLogMessageWithTyperArivedEvent(string message, LogTypeEnum logType) + { + LogMessageWithTypeArrived?.Invoke(message, logType); + } + public static void Log(string message, LogTypeEnum logType) + { + FireLogMessageArivedEvent(message); + FireLogMessageWithTyperArivedEvent(message, logType); + + } + public static void Log(string message) + { + Log(message, LogTypeEnum.General); + } + + /// + /// Logs the specified message. + /// + /// The message. + /// Type of the log. + public static void LogError(string message) + { + Log(message, LogTypeEnum.Error); + } + + public static void LogEx(Exception ex) + { + Log(ex.ToString(), LogTypeEnum.Error); + } + + public static void LogGeneral(string message) + { + Log(message, LogTypeEnum.General); + } + + public static void LogInternal(string message) + { + Log(message, LogTypeEnum.Internal); + } + + } +} diff --git a/tabler.Logic/Helper/StringtableHelper.cs b/tabler.Logic/Helper/StringtableHelper.cs index 2444a96..603af7f 100644 --- a/tabler.Logic/Helper/StringtableHelper.cs +++ b/tabler.Logic/Helper/StringtableHelper.cs @@ -11,13 +11,16 @@ namespace tabler.Logic.Helper { - public class StringtableHelper + + + public static class StringtableHelper { - private XmlReaderSettings _xmlReaderSettings; + private static XmlReaderSettings _xmlReaderSettings; - public XmlReaderSettings XmlReaderSettings + public static XmlReaderSettings XmlReaderSettings { - get { + get + { if (_xmlReaderSettings == null) { var settings = new XmlReaderSettings @@ -36,25 +39,32 @@ public XmlReaderSettings XmlReaderSettings /// /// /// - public IEnumerable ParseStringtables(IEnumerable allStringtableFiles) + public static IEnumerable ParseStringtables(IEnumerable allStringtableFiles) { var stringtables = new System.Collections.Concurrent.ConcurrentBag(); Parallel.ForEach(allStringtableFiles, currentFile => { - var stringtable = ParseXmlFile(currentFile); - ValidateStringtable(stringtable); - stringtables.Add(stringtable); + stringtables.Add(ParseStringtable(currentFile).Result); }); return stringtables.ToList(); } + public static async Task ParseStringtable(FileInfo stringtableFile) + { + var stringtable = await ParseXmlFile(stringtableFile); + ValidateStringtable(stringtable); + return stringtable; + } + + + /// /// /// /// /// - private Stringtable ParseXmlFile(FileInfo fileInfo) + private static async Task ParseXmlFile(FileInfo fileInfo) { var stringtable = new Stringtable { @@ -62,44 +72,54 @@ private Stringtable ParseXmlFile(FileInfo fileInfo) Name = fileInfo.Directory.Name }; - try - { - var ser = new XmlSerializer(typeof(Project)); - - using (var sr = new StreamReader(fileInfo.FullName)) + var res = await new TaskFactory().StartNew( + () => { - stringtable.FileHasBom = FileHelper.FileHasBom(sr.BaseStream); - using (var reader = XmlReader.Create(sr.BaseStream, XmlReaderSettings)) + try { - stringtable.Project = (Project) ser.Deserialize(reader); + var ser = new XmlSerializer(typeof(Project)); + + using (var sr = new StreamReader(fileInfo.FullName)) + { + stringtable.FileHasBom = FileHelper.FileHasBom(sr.BaseStream); + + using (var reader = XmlReader.Create(sr.BaseStream, XmlReaderSettings)) + { + stringtable.Project = (Project)ser.Deserialize(reader); + } + } } - } - } - catch (XmlException ex) - { - throw new GenericXmlException("", fileInfo.FullName, ex.Message); - } - catch (InvalidOperationException ex) - { - var message = new StringBuilder(); - message.Append(ex.Message); - if (ex.InnerException != null) - { - message.AppendLine().Append(ex.InnerException.Message); - } + catch (XmlException ex) + { + throw new GenericXmlException("", fileInfo.FullName, ex.Message); + } + catch (InvalidOperationException ex) + { + var message = new StringBuilder(); + message.Append(ex.Message); + if (ex.InnerException != null) + { + message.AppendLine().Append(ex.InnerException.Message); + } - throw new MalformedStringtableException(fileInfo.FullName, message.ToString()); - } + throw new MalformedStringtableException(fileInfo.FullName, message.ToString()); + } - return stringtable; + return stringtable; + + }); + + return res; } + + /// /// /// /// - private void ValidateStringtable(Stringtable stringtable) + private static void ValidateStringtable(Stringtable stringtable) { var duplicates = stringtable.AllKeys.GroupBy(k => k.Id).Where(g => g.Skip(1).Any()).ToList(); if (duplicates.Any()) @@ -110,74 +130,82 @@ private void ValidateStringtable(Stringtable stringtable) } } + + /// /// /// /// /// - public void SaveStringtableFiles(List filesByNameInDirectory, IEnumerable lstStringtables) + public static void SaveStringtableFiles(List filesByNameInDirectory, IEnumerable lstStringtables) { - var configHelper = new ConfigHelper(); - var settings = configHelper.GetSettings(); + Parallel.ForEach(filesByNameInDirectory, currentFileInfo => + { + var currentStringtable = lstStringtables.FirstOrDefault(x => string.Equals(x.Name.ToLowerInvariant(), currentFileInfo.Directory.Name.ToLowerInvariant(), StringComparison.OrdinalIgnoreCase)); + + SaveStringTableFile(currentFileInfo, currentStringtable); + }); + } + + public static void SaveStringTableFile(FileInfo currentFileInfo, Stringtable currentStringtable, List header) + { + if (currentStringtable == null) + { + return; + } + + if (!currentStringtable.HasChanges) + { + return; + } var dummyNamespace = new XmlSerializerNamespaces(); - dummyNamespace.Add("",""); + dummyNamespace.Add("", ""); - Parallel.ForEach(filesByNameInDirectory, currentFileInfo => + var xmlSettings = new XmlWriterSettings { - var currentStringtable = lstStringtables.FirstOrDefault(x => string.Equals(x.Name.ToLowerInvariant(), currentFileInfo.Directory.Name.ToLowerInvariant(), StringComparison.OrdinalIgnoreCase)); + Indent = true, + IndentChars = " ", + Encoding = new UTF8Encoding(currentStringtable.FileHasBom) + }; - if (currentStringtable == null) - { - return; - } + if (ConfigHelper.CurrentSettings.IndentationSettings == IndentationSettings.Spaces) + { + var indentChars = ""; - if (!currentStringtable.HasChanges) + for (var i = 0; i < ConfigHelper.CurrentSettings.TabSize; i++) { - return; + indentChars += " "; } + xmlSettings.IndentChars = indentChars; + } - var xmlSettings = new XmlWriterSettings - { - Indent = true, - IndentChars = " ", - Encoding = new UTF8Encoding(currentStringtable.FileHasBom) - }; - - if (settings != null) - { - if (settings.IndentationSettings == IndentationSettings.Spaces) - { - var indentChars = ""; + if (ConfigHelper.CurrentSettings.IndentationSettings == IndentationSettings.Tabs) + { + xmlSettings.IndentChars = "\t"; + } - for (var i = 0; i < settings.TabSize; i++) - { - indentChars += " "; - } + var xmlSerializer = new XmlSerializer(typeof(Project)); - xmlSettings.IndentChars = indentChars; - } + using (var writer = XmlWriter.Create(currentFileInfo.FullName, xmlSettings)) + { + xmlSerializer.Serialize(writer, currentStringtable.Project, dummyNamespace); - if (settings.IndentationSettings == IndentationSettings.Tabs) - { - xmlSettings.IndentChars = "\t"; - } + } - // TODO Remove empty nodes + File.AppendAllText(currentFileInfo.FullName, Environment.NewLine); - } + currentStringtable.HasChanges = false; - var xmlSerializer = new XmlSerializer(typeof(Project)); - using (var writer = XmlWriter.Create(currentFileInfo.FullName, xmlSettings)) - { - xmlSerializer.Serialize(writer, currentStringtable.Project,dummyNamespace); - } + } - File.AppendAllText(currentFileInfo.FullName, Environment.NewLine); + public static void SaveStringTableFile(FileInfo currentFileInfo, Stringtable currentStringtable) + { + SaveStringTableFile(currentFileInfo, currentStringtable, null); - currentStringtable.HasChanges = false; - }); } + + } } diff --git a/tabler.Logic/Helper/TranslationHelper.cs b/tabler.Logic/Helper/TranslationHelper.cs index f51b0e3..95641ab 100644 --- a/tabler.Logic/Helper/TranslationHelper.cs +++ b/tabler.Logic/Helper/TranslationHelper.cs @@ -16,8 +16,65 @@ public class TranslationHelper private readonly FileInfo _fiExcelFile; public TranslationComponents TranslationComponents; + public static List GetHeaders(Stringtable stringtable) + { + + var headers = new List(); + // Get list of all used languages + var allKeys = stringtable.Project.Packages.SelectMany(p => + { + var keys = new List(); + + if (p.Containers.Any()) + { + keys.AddRange(p.Containers.SelectMany(c => c.Keys)); + } + + keys.AddRange(p.Keys); + + return keys; + }); + + var keyPropertyInfos = typeof(Key).GetProperties(BindingFlags.Public | BindingFlags.Instance); + foreach (var key in allKeys) + { + foreach (var property in keyPropertyInfos) + { + if (property.Name.ToLowerInvariant() == COLUMN_IDNAME.ToLowerInvariant() || headers.Contains(property.Name)) + { + continue; + } - private List PrepareHeaders(IEnumerable stringtables) + var value = property.GetValue(key, null)?.ToString(); + if (value != null && !string.IsNullOrEmpty(value)) + { + headers.Add(property.Name); + } + } + } + + headers = headers.OrderBy(l => l).ToList(); + + var hasOriginal = false; + + if (headers.Any(x => x.ToLowerInvariant() == Languages.Original.ToString().ToLowerInvariant())) + { + hasOriginal = true; + headers.Remove(Languages.Original.ToString()); + headers.Insert(0, Languages.Original.ToString()); + } + + if (headers.Any(x => x.ToLowerInvariant() == Languages.English.ToString().ToLowerInvariant())) + { + headers.Remove(Languages.English.ToString()); + headers.Insert(hasOriginal ? 1 : 0, Languages.English.ToString()); + } + + headers.Insert(0, COLUMN_IDNAME); + + return headers; + } + public static List GetHeaders(IEnumerable stringtables) { var headers = new List(); @@ -86,13 +143,13 @@ private TranslationComponents GetTranslationComponents(DirectoryInfo lastPathToD return null; } - var sh = new StringtableHelper(); + var transComp = new TranslationComponents { - Stringtables = sh.ParseStringtables(allStringtableFiles) + Stringtables = StringtableHelper.ParseStringtables(allStringtableFiles) }; - transComp.Headers = PrepareHeaders(transComp.Stringtables); + transComp.Headers = GetHeaders(transComp.Stringtables); TranslationComponents = transComp; return TranslationComponents; @@ -106,8 +163,7 @@ private static bool SaveModInfosToXml(DirectoryInfo lastPathToDataFiles, IEnumer // too tired :D -> TODO var filesByNameInDirectory = FileSystemHelper.GetFilesByNameInDirectory(lastPathToDataFiles, STRINGTABLE_NAME, SearchOption.AllDirectories); - var sh = new StringtableHelper(); - sh.SaveStringtableFiles(filesByNameInDirectory, lstStringtables); + StringtableHelper.SaveStringtableFiles(filesByNameInDirectory, lstStringtables); return true; } diff --git a/tabler.Logic/packages.config b/tabler.Logic/packages.config index 5c42880..77e9bb0 100644 --- a/tabler.Logic/packages.config +++ b/tabler.Logic/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file diff --git a/tabler.Logic/tabler.Logic.csproj b/tabler.Logic/tabler.Logic.csproj index c3a3b1d..061b61a 100644 --- a/tabler.Logic/tabler.Logic.csproj +++ b/tabler.Logic/tabler.Logic.csproj @@ -34,8 +34,13 @@ ..\packages\Octokit.0.32.0\lib\net45\Octokit.dll + + ..\packages\SharpSerializer.3.0.1\lib\net452\Polenter.SharpSerializer.dll + + + @@ -46,6 +51,7 @@ + @@ -55,7 +61,11 @@ + + + + diff --git a/tabler.sln b/tabler.sln index ac59d15..bf47270 100644 --- a/tabler.sln +++ b/tabler.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27703.2042 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28803.452 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tabler", "tabler\tabler.csproj", "{FE0D5379-28A9-47F8-86F5-19100816A8D9}" EndProject @@ -12,6 +12,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tabler.Logic", "tabler.Logic\tabler.Logic.csproj", "{651801FA-F7AE-4F9B-9A7C-2DDEA5965440}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tabler.wpf", "tabler.wpf\tabler.wpf.csproj", "{A6677EF8-6AB9-4976-A218-89470EE4B9C9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -26,6 +28,10 @@ Global {651801FA-F7AE-4F9B-9A7C-2DDEA5965440}.Debug|Any CPU.Build.0 = Debug|Any CPU {651801FA-F7AE-4F9B-9A7C-2DDEA5965440}.Release|Any CPU.ActiveCfg = Release|Any CPU {651801FA-F7AE-4F9B-9A7C-2DDEA5965440}.Release|Any CPU.Build.0 = Release|Any CPU + {A6677EF8-6AB9-4976-A218-89470EE4B9C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A6677EF8-6AB9-4976-A218-89470EE4B9C9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A6677EF8-6AB9-4976-A218-89470EE4B9C9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A6677EF8-6AB9-4976-A218-89470EE4B9C9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/tabler.wpf/App.config b/tabler.wpf/App.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/tabler.wpf/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/tabler.wpf/Container/Key_ExtendedWithChangeTracking.cs b/tabler.wpf/Container/Key_ExtendedWithChangeTracking.cs new file mode 100644 index 0000000..5757477 --- /dev/null +++ b/tabler.wpf/Container/Key_ExtendedWithChangeTracking.cs @@ -0,0 +1,226 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Runtime.Serialization; +using System.Xml.Linq; +using tabler.Logic.Classes; +using tabler.Logic.Extensions; + +namespace tabler.wpf.Container +{ + [DataContract] + [Serializable] //for copy paste action + public class Key_ExtendedWithChangeTracking + { + [DataMember] + public Dictionary Languages { get; set; } = new Dictionary(); + + [DataMember] + public Dictionary SystemValues { get; set; } = new Dictionary(); + public bool HasChanged + { + get + { + return Languages.Values.Any(x => x.HasChanged) || SystemValues.Values.Any(x => x.HasChanged); + } + } + + public void ResetHasChanged() + { + foreach (var item in Languages.Values) + { + item.HasChanged = false; + } + foreach (var item in SystemValues.Values) + { + item.HasChanged = false; + } + } + + public bool IsComplete + { + get { return SystemValues[IsComplete_PropertyName].CurrentValue == "Complete" ? true : false; } + } + + public string PackageName + { + get { return SystemValues[PackageName_PropertyName].CurrentValue; } + } + + public string ProjectName + { + get { return SystemValues[Project_PropertyName].CurrentValue; } + } + + public string ContainerName + { + get { return SystemValues[ContainerName_PropertyName].CurrentValue; } + } + public string Id + { + get { return SystemValues[Id_PropertyName].CurrentValue; } + } + + public const string IsComplete_PropertyName = "IsComplete"; + public const string Id_PropertyName = "Id"; + public const string Original_PropertyName = "Original"; + public const string PackageName_PropertyName = "PackageName"; + public const string ContainerName_PropertyName = "ContainerName"; + public const string Project_PropertyName = "ProjectName"; + public Key_ExtendedWithChangeTracking() + { + + } + + public Key_ExtendedWithChangeTracking(Key key, string projectName, string packageName, string containerName) + { + SystemValues.Add(nameof(key.Id), new ChangeTrackerString(key.Id)); + SystemValues.Add(nameof(key.Original), new ChangeTrackerString(key.Original)); + SystemValues.Add(Project_PropertyName, new ChangeTrackerString(projectName)); + SystemValues.Add(PackageName_PropertyName, new ChangeTrackerString(packageName)); + SystemValues.Add(ContainerName_PropertyName, new ChangeTrackerString(containerName)); + SystemValues.Add(IsComplete_PropertyName, new ChangeTrackerString("false")); + + Languages.Add(nameof(key.Chinese), new ChangeTrackerString(key.Chinese)); + Languages.Add(nameof(key.Chinesesimp), new ChangeTrackerString(key.Chinesesimp)); + Languages.Add(nameof(key.Czech), new ChangeTrackerString(key.Czech)); + Languages.Add(nameof(key.English), new ChangeTrackerString(key.English)); + Languages.Add(nameof(key.French), new ChangeTrackerString(key.French)); + Languages.Add(nameof(key.German), new ChangeTrackerString(key.German)); + Languages.Add(nameof(key.Hungarian), new ChangeTrackerString(key.Hungarian)); + Languages.Add(nameof(key.Italian), new ChangeTrackerString(key.Italian)); + Languages.Add(nameof(key.Japanese), new ChangeTrackerString(key.Japanese)); + Languages.Add(nameof(key.Korean), new ChangeTrackerString(key.Korean)); + Languages.Add(nameof(key.Polish), new ChangeTrackerString(key.Polish)); + Languages.Add(nameof(key.Portuguese), new ChangeTrackerString(key.Portuguese)); + Languages.Add(nameof(key.Russian), new ChangeTrackerString(key.Russian)); + Languages.Add(nameof(key.Spanish), new ChangeTrackerString(key.Spanish)); + Languages.Add(nameof(key.Turkish), new ChangeTrackerString(key.Turkish)); + } + + public void Update_IsCompletedValue(List languagesToHave) + { + foreach (var language in languagesToHave) + { + if (string.IsNullOrEmpty(Languages[language].CurrentValue)) + { + SystemValues[IsComplete_PropertyName].CurrentValue = "Incomplete"; + return; + }; + } + + SystemValues[IsComplete_PropertyName].CurrentValue = "Complete"; + } + + public bool ContainsText(string value, bool searchOnlyInId, bool ignoreCase) + { + var comp = StringComparison.InvariantCulture; + + if (ignoreCase) + { + comp = StringComparison.InvariantCultureIgnoreCase; + } + + if (SystemValues[Id_PropertyName].CurrentValue.ContainsEx(value, comp)) + { + return true; + } + + if (searchOnlyInId) + { + return false; + } + + foreach (var language in Languages.Values) + { + if (language.CurrentValue.ContainsEx(value, comp)) + { + return true; + } + } + + + return false; + } + + internal XElement AsXElement(bool ignoreEmptyValues, List languagesToWrite) + { + var res = new XElement("Key", new XAttribute("ID", SystemValues[Id_PropertyName].CurrentValue)); + + foreach (var item in languagesToWrite) + { + AddIfNecessary(res, item, Languages[item].CurrentValue, ignoreEmptyValues); + } + + return res; + } + + private void AddIfNecessary(XElement parent, string nameOfKey, string valueOfKey, bool ignoreEmptyValues) + { + if (ignoreEmptyValues && string.IsNullOrEmpty(valueOfKey)) + { + return; + } + + parent.Add(new XElement(nameOfKey, valueOfKey)); + } + } + + //todo something generic + public class ChangeTrackerString : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + private void RaisePropertyChanged(string propName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); + } + + public string OriginalValue { get; set; } + private string _currentValue; + private bool _hasChanged; + + public ChangeTrackerString(string originalValue) + { + OriginalValue = originalValue; + _currentValue = OriginalValue; + } + + + public bool HasChanged { get => _hasChanged; set => _hasChanged = value; } + + + public string CurrentValue + { + get { return _currentValue; } + set + { + if (OriginalValue != value) + { + + _currentValue = value; + RaisePropertyChanged(nameof(CurrentValue)); + + if (HasChanged == false) + { + HasChanged = true; + RaisePropertyChanged(nameof(HasChanged)); + } + + } + else + { + if (HasChanged == true) + { + HasChanged = false; + RaisePropertyChanged(nameof(HasChanged)); + } + + } + } + } + + } + + +} diff --git a/tabler.wpf/Container/VersionInfoContainer.cs b/tabler.wpf/Container/VersionInfoContainer.cs new file mode 100644 index 0000000..bdd7519 --- /dev/null +++ b/tabler.wpf/Container/VersionInfoContainer.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using tabler.wpf.Helper; + +namespace tabler.wpf.Container +{ + public class VersionInfoContainer + { + + public VersionInfoContainer() + { + Fixes = new List(); + Features = new List(); + SpecialThanks = new List(); + } + + public DateTime ReleaseDate { get; set; } + + public string ReleaseDateStr => ReleaseDate.GetDateTimeString_yyyyMMddhhmmss(); + + + public string Version { get; set; } + public List Fixes { get; set; } + public List Features { get; set; } + public List SpecialThanks { get; set; } + + public string FixesStr => string.Join(Environment.NewLine, Fixes); + + public string FeaturesStr => string.Join(Environment.NewLine, Features); + + public string SpecialThanksStr => string.Join(",", SpecialThanks); + } +} diff --git a/tabler.wpf/Controls/DirectoryFilesOverviewControl.xaml b/tabler.wpf/Controls/DirectoryFilesOverviewControl.xaml new file mode 100644 index 0000000..155f1b5 --- /dev/null +++ b/tabler.wpf/Controls/DirectoryFilesOverviewControl.xaml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/tabler.wpf/Controls/DirectoryFilesOverviewControl.xaml.cs b/tabler.wpf/Controls/DirectoryFilesOverviewControl.xaml.cs new file mode 100644 index 0000000..7533dc3 --- /dev/null +++ b/tabler.wpf/Controls/DirectoryFilesOverviewControl.xaml.cs @@ -0,0 +1,66 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Windows.Controls; +using tabler.Logic.Helper; +using tabler.wpf.Helper; + +namespace tabler.wpf.Controls +{ + /// + /// Interaction logic for LanguageOverviewControl.xaml + /// + public partial class DirectoryFilesOverviewControl : UserControl + { + //private class ListViewWrapperClass : UserControl + //{ + + + + //} + + private List _listFileControls = new List(); + public DirectoryFilesOverviewControl() + { + InitializeComponent(); + } + private DirectoryInfo _di; + public void LoadDirectory(DirectoryInfo di) + { + _di = di; + + var files = di.GetFiles("*stringtable*.xml*", SearchOption.AllDirectories); + + //tc_MainPerProject.Items.Clear(); + + var ts = new StopWatch($"Loading {files.Length} translation files..."); + + foreach (var file in files) + { + var languageControl = new TranslationFileSingleControl(file); + _ = languageControl.LoadStringTableAsync(); + _listFileControls.Add(new ListViewWrapperClass(languageControl, $"{file.Directory.Name}\\{file.Name}")); + } + _listFileControls = _listFileControls.OrderBy(x => x.TranslationFileName).ToList(); + + lvSubProjects.ItemsSource = _listFileControls; + ts.StopAndLog(); + + } + + private void LvSubProjects_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (lvSubProjects.SelectedItem == null) + { + return; + } + var control = lvSubProjects.SelectedItem as ListViewWrapperClass; + if (control != null) + { + ccMainContent.Content = control.Control; + control.Control.Load(); + } + + } + } +} diff --git a/tabler.wpf/Controls/General_VersionInfo.xaml b/tabler.wpf/Controls/General_VersionInfo.xaml new file mode 100644 index 0000000..775cdad --- /dev/null +++ b/tabler.wpf/Controls/General_VersionInfo.xaml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tabler.wpf/Controls/General_VersionInfo.xaml.cs b/tabler.wpf/Controls/General_VersionInfo.xaml.cs new file mode 100644 index 0000000..4aed5ff --- /dev/null +++ b/tabler.wpf/Controls/General_VersionInfo.xaml.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Controls; +using tabler.wpf.Container; +using tabler.wpf.Helper; + +namespace tabler.wpf.Controls +{ + /// + /// Interaction logic for General_VersionInfo.xaml + /// + public partial class General_VersionInfo : UserControl + { + public General_VersionInfo() + { + InitializeComponent(); + + var lstVersions = new List(); + + _dgvVersionNumbers.SelectionMode = DataGridSelectionMode.Single; + + lstVersions.Add(CreateVersion00001()); + + _dgvVersionNumbers.ItemsSource = lstVersions; + + } + + private VersionInfoContainer CreateVersion00001() + { + var versionInfoContainer = new VersionInfoContainer + { + Version = "0.0.0.01", + ReleaseDate = new DateTime(2019, 9, 16) + }; + + versionInfoContainer.SpecialThanks.Add("Bux: for being very patient :D"); + + versionInfoContainer.Features.Add("- Initial release"); + + versionInfoContainer.Fixes.Add("- soon to come ;)"); + return versionInfoContainer; + } + + private string CreateResultStringFromVersionInfo(VersionInfoContainer version) + { + string result = string.Empty; + + result += "Version: " + version.Version + Environment.NewLine; + result += "ReleaseDate: " + version.ReleaseDate.ToString("yyyy.MM.dd") + Environment.NewLine; + if (!string.IsNullOrEmpty(version.SpecialThanksStr)) + { + result += "Special Thanks: " + version.SpecialThanksStr + Environment.NewLine; + } + + result += Environment.NewLine; + + result += "Features: " + Environment.NewLine; + result += "--------------------------------------------------------------------" + Environment.NewLine; + result += version.FeaturesStr + Environment.NewLine; + + + result += Environment.NewLine; + + result += "Bugfixes: " + Environment.NewLine; + result += "--------------------------------------------------------------------" + Environment.NewLine; + result += version.FixesStr + Environment.NewLine; + + result += Environment.NewLine; + + return result; + } + + private void _dgvVersionNumbers_OnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + + if (_dgvVersionNumbers.SelectedItems.Count > 0) + { + var items = _dgvVersionNumbers.GetSelectedBoundItems(); + if (items != null && items.Any()) + { + _tbVersionInfos.Text = CreateResultStringFromVersionInfo(items.First()); + } + } + } + } +} diff --git a/tabler.wpf/Controls/Helper_DataGridExtended.cs b/tabler.wpf/Controls/Helper_DataGridExtended.cs new file mode 100644 index 0000000..c662166 --- /dev/null +++ b/tabler.wpf/Controls/Helper_DataGridExtended.cs @@ -0,0 +1,119 @@ + +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using tabler.Logic.Helper; +using tabler.wpf.Helper; + +namespace tabler.wpf.Controls +{ + public class Helper_DataGridExtended : DataGrid + { + public Helper_DataGridExtended() + { + AutoGenerateColumns = false; + CanUserAddRows = false; + CanUserDeleteRows = false; + this.Initialized += (sender, args) => + { + + if (this.ContextMenu == null) + { + this.ContextMenu = new ContextMenu(); + } + var menu = new MenuItem { Header = "Switch copymode" }; + menu.Click += switchCopyMode; + this.ContextMenu.Items.Add(menu); + }; + //this.CommandBindings.Add(new CommandBinding(new Command() ) + + //CommandManager.RegisterClassCommandBinding(typeof(Helper_DataGridExtended), + // new CommandBinding(ApplicationCommands.Copy, + // new ExecutedRoutedEventHandler(OnExecutedCopy), + // new CanExecuteRoutedEventHandler(OnCanExecuteCopy))); + + //CommandManager.RegisterClassCommandBinding(typeof(Helper_DataGridExtended), + // new CommandBinding(ApplicationCommands.Paste, + // new ExecutedRoutedEventHandler(OnExecutedPaste), + // new CanExecuteRoutedEventHandler(OnCanExecutePaste))); + + //CommandManager.RegisterClassCommandBinding(typeof(DataGrid), + // new CommandBinding(ApplicationCommands.Paste, new ExecutedRoutedEventHandler(OnExecutedPaste), + // new CanExecuteRoutedEventHandler(OnCanExecutePaste))); + //CommandManager.RegisterClassCommandBinding(typeof(DataGridCell), + // new CommandBinding(ApplicationCommands.Paste, new ExecutedRoutedEventHandler(OnExecutedPaste), + // new CanExecuteRoutedEventHandler(OnCanExecutePaste))); + + //CommandManager.RegisterClassCommandBinding(typeof(DataGridColumn), + // new CommandBinding(ApplicationCommands.Paste, new ExecutedRoutedEventHandler(OnExecutedPaste), + // new CanExecuteRoutedEventHandler(OnCanExecutePaste))); + } + + //private void OnCanExecuteCopy(object sender, CanExecuteRoutedEventArgs args) + //{ + // args.CanExecute = true; + // args.Handled = true; + + //} + //private void OnExecutedCopy(object sender, ExecutedRoutedEventArgs args) + //{ + // var i = this.SelectedValue; + + //} + + + //private void OnCanExecutePaste(object sender, CanExecuteRoutedEventArgs args) + //{ + // args.CanExecute = CurrentCell != null; + // args.Handled = true; + //} + + //private void OnExecutedPaste(object sender, ExecutedRoutedEventArgs e) + //{ + // try + // { + + + // var k = ClipBoardHelper.GetKeyObjectFromClipboard(); + + // //if (!Clipboard.ContainsText()) + // //{ + // // return; + // //} + + // //var data = (string)Clipboard.GetData(DataFormats.UnicodeText); + + // //var cell = sender as DataGridCell; + // ////cell.IsEditing = true; + // //(cell.Content as TextBlock).Text = data; + // //cell.IsEditing = false; + // } + // catch (Exception ex) + // { + // Logger.LogEx(ex); + // } + //} + + + private void switchCopyMode(object sender, RoutedEventArgs e) + { + try + { + if (this.ClipboardCopyMode == DataGridClipboardCopyMode.IncludeHeader) + { + this.ClipboardCopyMode = DataGridClipboardCopyMode.ExcludeHeader; + } + else + { + this.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader; + } + Logger.LogGeneral($"Switched mode to: {this.ClipboardCopyMode}"); + } + catch (Exception ex) + { + Logger.LogError($"{nameof(Helper_DataGridExtended)}.{nameof(switchCopyMode)} Exception: {ex}"); + } + } + } +} diff --git a/tabler.wpf/Controls/Helper_LabelTextBox.xaml b/tabler.wpf/Controls/Helper_LabelTextBox.xaml new file mode 100644 index 0000000..524b0c8 --- /dev/null +++ b/tabler.wpf/Controls/Helper_LabelTextBox.xaml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + diff --git a/tabler.wpf/Controls/Helper_LabelTextBox.xaml.cs b/tabler.wpf/Controls/Helper_LabelTextBox.xaml.cs new file mode 100644 index 0000000..1c6c17e --- /dev/null +++ b/tabler.wpf/Controls/Helper_LabelTextBox.xaml.cs @@ -0,0 +1,128 @@ +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; + +namespace tabler.wpf.Controls +{ + /// + /// Interaction logic for Helper_LabelTextBox.xaml + /// + public partial class Helper_LabelTextBox : UserControl + { + public Helper_LabelTextBox() + { + InitializeComponent(); + + TextBox.MouseLeftButtonUp += (sender, args) => + { + if (DoClearOnClickIn || DoClearOnClickInOnce) + { + TextBox.Text = string.Empty; + DoClearOnClickInOnce = false; + } + }; + } + + public static readonly DependencyProperty DoClearOnClickInOnceProperty = DependencyProperty.Register( + "DoClearOnClickInOnce", typeof (bool), typeof (Helper_LabelTextBox), new PropertyMetadata(default(bool))); + + public bool DoClearOnClickInOnce + { + get { return (bool) GetValue(DoClearOnClickInOnceProperty); } + set { SetValue(DoClearOnClickInOnceProperty, value); } + } + + public static readonly DependencyProperty DoClearOnClickInProperty = DependencyProperty.Register( + "DoClearOnClickIn", typeof (bool), typeof (Helper_LabelTextBox), new PropertyMetadata(default(bool))); + + public bool DoClearOnClickIn + { + get { return (bool) GetValue(DoClearOnClickInProperty); } + set { SetValue(DoClearOnClickInProperty, value); } + } + public static readonly DependencyProperty IsReadonlyProperty = DependencyProperty.Register("IsReadonly", typeof(bool), typeof(Helper_LabelTextBox), new PropertyMetadata(default(bool))); + + public bool IsReadonly + { + get { return (bool)GetValue(IsReadonlyProperty); } + set { SetValue(IsReadonlyProperty, value);} + } + + public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register("Description", typeof(string), typeof(Helper_LabelTextBox), new PropertyMetadata(default(string))); + + public string Description + { + get { return (string)GetValue(DescriptionProperty); } + set { SetValue(DescriptionProperty, value); } + } + + public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(Helper_LabelTextBox), new PropertyMetadata(default(string))); + + + + public string Value + { + get { return (string)GetValue(ValueProperty); } + set { SetValue(ValueProperty, value); } + } + //public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register( + // "Description", typeof (string), typeof (Helper_LabelTextBox), new PropertyMetadata(default(string))); + + //public string Description + //{ + // get { return (string) GetValue(DescriptionProperty); } + // set { SetValue(DescriptionProperty, value); } + //} + + + //public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( + // "Value", typeof (string), typeof (Helper_LabelTextBox), new PropertyMetadata(default(string))); + + //public string Value + //{ + // get { return (string) GetValue(ValueProperty); } + // set { SetValue(ValueProperty, value); } + //} + + private void keyPressedinTextbox(object sender, KeyEventArgs e) + { + if (e.Key == Key.Enter) + { + EnterPressed?.Invoke(Value); + } + } + + public delegate void EnterPressedDelegate(string value); + public event EnterPressedDelegate EnterPressed; + + public delegate void CharactersEnteredCountDelegate(int value); + public event CharactersEnteredCountDelegate CharactersEnteredCount; + + public delegate void ThreeOrMoreCharactersEnteredDelegate(string value); + public event ThreeOrMoreCharactersEnteredDelegate ThreeOrMoreCharactersEntered; + + + public TextBox TextBox => TbValue; + public Label Label => LblDescription; + + private void TbValue_OnTextChanged(object sender, TextChangedEventArgs e) + { + Value = TextBox.Text; + var value = TextBox.Text; + + if (string.IsNullOrEmpty(value)) + { + value = String.Empty; + } + + CharactersEnteredCount?.Invoke(value.Length); + + if (value.Length >= 3) + { + ThreeOrMoreCharactersEntered?.Invoke(value); + } + + } + } +} diff --git a/tabler.wpf/Controls/Helper_LogMessages.xaml b/tabler.wpf/Controls/Helper_LogMessages.xaml new file mode 100644 index 0000000..bc70e6a --- /dev/null +++ b/tabler.wpf/Controls/Helper_LogMessages.xaml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + Pause autoscrolling + Show timestamp + + + Show general + Show internal + Show error + + + + + + + + + diff --git a/tabler.wpf/Controls/Helper_LogMessages.xaml.cs b/tabler.wpf/Controls/Helper_LogMessages.xaml.cs new file mode 100644 index 0000000..7a0ee5a --- /dev/null +++ b/tabler.wpf/Controls/Helper_LogMessages.xaml.cs @@ -0,0 +1,176 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using tabler.Logic.Enums; +using tabler.wpf.Helper; + +namespace tabler.wpf.Controls +{ + /// + /// Interaction logic for Helper_LogMessages.xaml + /// + public partial class Helper_LogMessages : UserControl, ICloneable + { + public ObservableCollection LogData { get; set; } = new ObservableCollection(); + + private List _lstGeneral = new List(); + private List _lstInternal = new List(); + private List _lstError = new List(); + + public delegate void LogMessageWithTypeDelegate(string message, LogTypeEnum logType); + + public event LogMessageWithTypeDelegate LogMessageWithTypeArrived; + + public void FireLogMessageWithTyperArivedEvent(string message, LogTypeEnum logType) + { + LogMessageWithTypeArrived?.Invoke(message, logType); + } + + public Helper_LogMessages() + { + InitializeComponent(); + } + + public void AddMessage(string message, LogTypeEnum logtype) + { + FireLogMessageWithTyperArivedEvent(message, logtype); + var row = new LogRow { DateTime = DateTime.Now, Message = message }; + + //if logging seem to be a problem, just make this asynch + Dispatcher.InvokeAsync(() => + { + AddMessage(row, logtype); + }); + + } + + private void AddMessage(LogRow row, LogTypeEnum logtype) + { + switch (logtype) + { + case LogTypeEnum.General: + _lstGeneral.Add(row); + if (cbShowGeneral.IsChecked.Value == false) + { + return; + } + + break; + case LogTypeEnum.Error: + _lstError.Add( row); + if (cbShowError.IsChecked.Value == false) + { + return; + } + break; + case LogTypeEnum.Internal: + _lstInternal.Add( row); + if (cbShowInternal.IsChecked.Value == false) + { + return; + } + break; + default: + throw new ArgumentOutOfRangeException(nameof(logtype), logtype, null); + } + + if (CbPauseScrolling.IsChecked.Value == false) + { + AddMessageToGrid(row); + } + + + } + + private void CbPauseScrollingGeneral_OnChecked(object sender, RoutedEventArgs e) + { + if (CbPauseScrolling.IsChecked.Value == false) + { + UpdateAllogs(); + } + } + + public class LogRow + { + public DateTime DateTime { get; set; } + public string Message { get; set; } + } + + private void UpdateLogsShowing(object sender, RoutedEventArgs e) + { + UpdateAllogs(); + + } + + public void UpdateAllogs() + { + var toShow = new List(); + + if (cbShowGeneral == null) + { + return; + } + + if (cbShowGeneral.IsChecked.Value) + { + toShow.AddRange(_lstGeneral); + } + if (cbShowInternal.IsChecked.Value) + { + toShow.AddRange(_lstInternal); + } + if (cbShowError.IsChecked.Value) + { + toShow.AddRange(_lstError); + } + + LogData.Clear(); + + toShow.OrderByDescending(x => x.DateTime).ToList().ForEach(AddMessageToGrid); + } + + private void AddMessageToGrid(LogRow logRow) + { + if (CbShowDatetime.IsChecked.Value) + { + LogData.Insert(0,new LogRow() {Message = $"{logRow.DateTime.GetDateTimeString_yyyyMMddhhmmss()}: {logRow.Message}"}); + } + else + { + LogData.Insert(0,logRow); + } + } + + public object Clone() + { + var clone = new Helper_LogMessages { _lstError = this._lstError.ToList(), _lstGeneral = _lstGeneral.ToList(), _lstInternal = _lstInternal.ToList() }; + this.LogMessageWithTypeArrived += clone.AddMessage; + + return clone; + + } + + private void CbShowDatetime_OnChecked(object sender, RoutedEventArgs e) + { + UpdateAllogs(); + } + + private void ResetAllMessages() + { + _lstInternal.Clear(); + _lstError.Clear(); + _lstGeneral.Clear(); + UpdateAllogs(); + + } + + private void BtnResetAllMessages_OnClick(object sender, RoutedEventArgs e) + { + ResetAllMessages(); + } + + } +} diff --git a/tabler.wpf/Controls/Helper_ProgressBar.xaml b/tabler.wpf/Controls/Helper_ProgressBar.xaml new file mode 100644 index 0000000..9d3cb01 --- /dev/null +++ b/tabler.wpf/Controls/Helper_ProgressBar.xaml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tabler.wpf/Controls/Helper_ProgressBar.xaml.cs b/tabler.wpf/Controls/Helper_ProgressBar.xaml.cs new file mode 100644 index 0000000..3caffd4 --- /dev/null +++ b/tabler.wpf/Controls/Helper_ProgressBar.xaml.cs @@ -0,0 +1,287 @@ +using System; +using System.Timers; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Threading; +using tabler.Logic.Helper; +using tabler.wpf.Helper; + +namespace tabler.wpf.Controls +{ + + /// + /// Interaction logic for Helper_ProgressBar.xaml + /// + public partial class Helper_ProgressBar : UserControl, IProgressBarControl + { + public Helper_ProgressBar() + { + InitializeComponent(); + _updateTimer = new Timer {Interval = 1000}; + _updateTimer.AutoReset = false; + _updateTimer.Start(); + _updateTimer.Elapsed += (sender, args) => + { + _updateTimer.Stop(); + UpdateProgressName(); + _updateTimer.Start(); + }; + this.Visibility = Visibility.Collapsed; + } + + private Timer _updateTimer; + + private string Name { get; set; } + + + public delegate void OperationNameChangedDelegate(string value); + + public event OperationNameChangedDelegate OperationNameChanged; + + private void FireOperationNameChangedEvent(string value) + { + OperationNameChanged?.Invoke(value); + } + + + public void SetOperationName(string name) + { + Name = name; + FireOperationNameChangedEvent(name); + } + + private int _currentValue; + private int _currentMax; + private int _currentMin; + + public bool HandleVisibility { get; set; } = false; + + private void UpdateProgressName() + { + if (Dispatcher.HasShutdownStarted) + { + return; + } + + try + { + Dispatcher.BeginInvoke(() => + { + try + { + //if not started or already done + if (_currentValue <= 0 || _currentValue >= _currentMax) + { + if (HandleVisibility) + { + if (Visibility != Visibility.Collapsed) + { + Visibility = Visibility.Collapsed; + } + } + + return ; + } + if (HandleVisibility) + { + //make visible + if (Visibility != Visibility.Visible) + { + Visibility = Visibility.Visible; + } + } + + + if (_currentMax != pbCurrentProgress.Maximum) + { + pbCurrentProgress.Maximum = _currentMax; + } + + if (_currentMin != pbCurrentProgress.Minimum) + { + pbCurrentProgress.Minimum = _currentMin; + } + + pbCurrentProgress.Value = _currentValue; + + try + { + if (_currentMax == 0) + { + //lblProgressStatusMessage.Content = Name; + lblProgressStatusMessage.Content = "0%"; + return; + } + + var percent = (int) ((int) (100*_currentValue)/_currentMax); + lblProgressStatusMessage.Content = Name + $" {((int) _currentValue).ToString()}/{((int) _currentMax) + " -> " + percent.ToString() + "%"}"; + } + catch (Exception ex) + { + Logger.LogError($"{nameof(Helper_ProgressBar)}.{nameof(UpdateProgressName)} Exception: {ex}"); + } + } + catch (Exception ex) + { + Logger.LogError($"{nameof(Helper_ProgressBar)}.{nameof(UpdateProgressName)} Exception: {ex}"); + } + },DispatcherPriority.Background); + + } + catch (Exception ex) + { + Logger.LogError($"{nameof(Helper_ProgressBar)}.{nameof(UpdateProgressName)} Exception: {ex}"); + } + + + } + + public void Reset() + { + try + { + _currentValue = 0; + } + catch (Exception ex) + { + Logger.LogError($"{nameof(Helper_ProgressBar)}.{nameof(Reset)} Exception: {ex}"); + } + + } + + + public delegate void ValueIncreasedDelegate(int value); + + public event ValueIncreasedDelegate ValueIncreased; + + private void FireValueIncreasedEvent(int value) + { + ValueIncreased?.Invoke(value); + } + + + public delegate void MaxChangedDelegate(int value, bool doReset); + + public event MaxChangedDelegate MaxChanged; + + private void FireMaxChangedEvent(int value, bool doReset) + { + MaxChanged?.Invoke(value, doReset); + } + + public void SetMax(int max, bool doReset) + { + try + { + FireMaxChangedEvent(max, doReset); + if (doReset) + { + Reset(); + } + + _currentMax = max; + } + catch (Exception ex) + { + Logger.LogError($"{nameof(Helper_ProgressBar)}.{nameof(SetMax)} Exception: {ex}"); + } + } + + private object _incLock = new object(); + + public void Increase(int value) + { + try + { + lock (_incLock) + { + if (_currentValue + value < _currentMin) + { + FireValueIncreasedEvent(_currentMin); + _currentValue = _currentMin; + return; + } + + if (_currentValue + value > _currentMax) + { + FireValueIncreasedEvent(_currentMax); + _currentValue = _currentMax; + return; + } + _currentValue += value; + FireValueIncreasedEvent(_currentValue); + } + } + catch (Exception ex) + { + Logger.LogError($"{nameof(Helper_ProgressBar)}.{nameof(Increase)} Exception: {ex}"); + } + } + + public void Set(int value) + { + try + { + lock (_incLock) + { + if (value < _currentMin) + { + FireValueIncreasedEvent(_currentMin); + _currentValue = _currentMin; + return; + } + + if (value > _currentMax) + { + FireValueIncreasedEvent(_currentMax); + _currentValue = _currentMax; + return; + } + _currentValue = value; + FireValueIncreasedEvent(_currentValue); + } + } + catch (Exception ex) + { + Logger.LogError($"{nameof(Helper_ProgressBar)}.{nameof(Increase)} Exception: {ex}"); + } + } + + + public void Increase() + { + Increase(1); + } + + public void Decrease(int value) + { + Increase(-value); + } + + public void Decrease() + { + Increase(-1); + } + + #region Implementation of IProgress + + /// + /// Values from 0-100 for whatever max is set currently + /// + /// + public void Report(double value) + { + try + { + var current = _currentMax * (value/100); + Set((int)current); + } + catch (Exception ex) + { + Logger.LogError($"{nameof(Helper_ProgressBar)}.{nameof(Report)} Report Exception: {ex}"); + } + } + + #endregion + } +} diff --git a/tabler.wpf/Controls/Helper_TabControlExtended.cs b/tabler.wpf/Controls/Helper_TabControlExtended.cs new file mode 100644 index 0000000..99552ba --- /dev/null +++ b/tabler.wpf/Controls/Helper_TabControlExtended.cs @@ -0,0 +1,35 @@ +using System.Windows.Controls; + +namespace tabler.wpf.Controls +{ + public class Helper_TabControlExtended : TabControl + { + public Helper_TabControlExtended() + { + + this.SelectionChanged += (sender, args) => + { + + if (this.SelectedItem == null) + { + return; + } + if (_lastSelectedTabItem == this.SelectedItem) + { + return; + } + + _lastSelectedTabItem = this.SelectedItem; + + if (_lastSelectedTabItem is Helper_TabItemExtended) + { + var ti = (Helper_TabItemExtended)_lastSelectedTabItem; + ti.FireTabItemSelectedEvent(); + } + }; + } + + private object _lastSelectedTabItem = null; + + } +} diff --git a/tabler.wpf/Controls/Helper_TabItemExtended.cs b/tabler.wpf/Controls/Helper_TabItemExtended.cs new file mode 100644 index 0000000..f2f8b5c --- /dev/null +++ b/tabler.wpf/Controls/Helper_TabItemExtended.cs @@ -0,0 +1,18 @@ +using System.Windows.Controls; + +namespace tabler.wpf.Controls +{ + public class Helper_TabItemExtended:TabItem + { + public delegate void TabItemSelectedDelegate(); + + public event TabItemSelectedDelegate TabItemSelected; + + public void FireTabItemSelectedEvent() + { + TabItemSelected?.Invoke(); + } + + + } +} diff --git a/tabler.wpf/Controls/ItemSelectControl.xaml b/tabler.wpf/Controls/ItemSelectControl.xaml new file mode 100644 index 0000000..9d23c23 --- /dev/null +++ b/tabler.wpf/Controls/ItemSelectControl.xaml @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/tabler.wpf/Controls/ItemSelectControl.xaml.cs b/tabler.wpf/Controls/ItemSelectControl.xaml.cs new file mode 100644 index 0000000..32efab3 --- /dev/null +++ b/tabler.wpf/Controls/ItemSelectControl.xaml.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using tabler.Logic.Classes; + +namespace tabler.wpf.Controls +{ + /// + /// Interaction logic for LanguageSelect.xaml + /// + public partial class ItemSelectControl : UserControl + { + + + public ItemSelectControl() + { + InitializeComponent(); + } + + public void SetItemsAndSelectedItems(List items) + { + lbMain.ItemsSource = null; + lbMain.ItemsSource = items; + + + } + + } +} diff --git a/tabler.wpf/Controls/ListViewWrapperClass.xaml b/tabler.wpf/Controls/ListViewWrapperClass.xaml new file mode 100644 index 0000000..165cef0 --- /dev/null +++ b/tabler.wpf/Controls/ListViewWrapperClass.xaml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + diff --git a/tabler.wpf/Controls/ListViewWrapperClass.xaml.cs b/tabler.wpf/Controls/ListViewWrapperClass.xaml.cs new file mode 100644 index 0000000..66353ef --- /dev/null +++ b/tabler.wpf/Controls/ListViewWrapperClass.xaml.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace tabler.wpf.Controls +{ + /// + /// Interaction logic for ListViewWrapperClass.xaml + /// + public partial class ListViewWrapperClass : UserControl , INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + private void RaisePropertyChanged(string propName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); + } + public ListViewWrapperClass(TranslationFileSingleControl control, string name) + { + InitializeComponent(); + this.pb_Progress.SetMax(100,true); + + Control = control; + this.pb_Progress.SetOperationName(""); + this.pb_Progress.Set(control.TranslationProgress.CurrentProgressValue); + Control.TranslationProgress.ProgressChangedEvent += TranslationProgress_ProgressChangedEvent; + TranslationFileName = name; + this.tbName.Content = name; + + } + + private void TranslationProgress_ProgressChangedEvent(int progress, string currentAction) + { + this.pb_Progress.Set(progress); + + } + + + + public TranslationFileSingleControl Control { get; set; } + + public string TranslationFileName { get; set; } + + + } +} diff --git a/tabler.wpf/Controls/LogMessages_Window.xaml b/tabler.wpf/Controls/LogMessages_Window.xaml new file mode 100644 index 0000000..1edf720 --- /dev/null +++ b/tabler.wpf/Controls/LogMessages_Window.xaml @@ -0,0 +1,20 @@ + + + + + + + + + + + + diff --git a/tabler.wpf/Controls/LogMessages_Window.xaml.cs b/tabler.wpf/Controls/LogMessages_Window.xaml.cs new file mode 100644 index 0000000..52ccfab --- /dev/null +++ b/tabler.wpf/Controls/LogMessages_Window.xaml.cs @@ -0,0 +1,30 @@ +using System.Windows; +using System.Windows.Controls; + +namespace tabler.wpf.Controls +{ + /// + /// Interaction logic for LogMessages_Window.xaml + /// + public partial class LogMessages_Window : Window + { + public LogMessages_Window() + { + InitializeComponent(); + } + + public LogMessages_Window(Helper_LogMessages control) + { + InitializeComponent(); + + SetMainControl(control); + control.UpdateAllogs(); + } + + private void SetMainControl(Control control) + { + grdMainContent.Children.Clear(); + grdMainContent.Children.Add(control); + } + } +} diff --git a/tabler.wpf/Controls/TranslationFileSingleControl.xaml b/tabler.wpf/Controls/TranslationFileSingleControl.xaml new file mode 100644 index 0000000..1bdfcfc --- /dev/null +++ b/tabler.wpf/Controls/TranslationFileSingleControl.xaml @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Group by Project + Group by Status + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tabler.wpf/Controls/TranslationFileSingleControl.xaml.cs b/tabler.wpf/Controls/TranslationFileSingleControl.xaml.cs new file mode 100644 index 0000000..a48fc03 --- /dev/null +++ b/tabler.wpf/Controls/TranslationFileSingleControl.xaml.cs @@ -0,0 +1,670 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using System.Xml; +using System.Xml.Linq; +using System.Xml.Serialization; +using tabler.Logic.Classes; +using tabler.Logic.Enums; +using tabler.Logic.Helper; +using tabler.wpf.Container; +using tabler.wpf.Helper; +using Key = tabler.Logic.Classes.Key; + +namespace tabler.wpf.Controls +{ + /// + /// Interaction logic for SingleLanguageTranslationControl.xaml + /// + public partial class TranslationFileSingleControl : UserControl + { + private CollectionViewSource _collViewSource = new CollectionViewSource(); + private class KeyCollection : ObservableCollection + { } + + private class Key_ExtendedWithChangeTrackingValueConverter : IValueConverter + { + private string _propertyName; + public Key_ExtendedWithChangeTrackingValueConverter(string systemValuesPropertyName) + { + _propertyName = systemValuesPropertyName; + } + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is Key_ExtendedWithChangeTracking key) + { + return ((Key_ExtendedWithChangeTracking)value).SystemValues[_propertyName].CurrentValue; + } + return value; + + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } + + private KeyCollection _keyCollection = new KeyCollection(); + public bool AlreadyLoaded { get; set; } = false; + public Stringtable StringTable { get; set; } + public FileInfo CurrentFile { get; set; } + public List Header { get; set; } + private bool _filteringDiabled = false; + + private PropertyGroupDescription _groupDescriptionPackageName = new PropertyGroupDescription(null, new Key_ExtendedWithChangeTrackingValueConverter(Key_ExtendedWithChangeTracking.PackageName_PropertyName)); + private PropertyGroupDescription _groupDescriptionIsComplete = new PropertyGroupDescription(null, new Key_ExtendedWithChangeTrackingValueConverter(Key_ExtendedWithChangeTracking.IsComplete_PropertyName)); + + public ProgressHelper TranslationProgress { get; set; } + + + #region CTOR and Load data + public TranslationFileSingleControl(FileInfo file) : this() + { + CurrentFile = file; + } + + public TranslationFileSingleControl() + { + InitializeComponent(); + + TranslationProgress = new ProgressHelper(); + _collViewSource.Source = _keyCollection; + _collViewSource.Filter += _collViewSource_Filter; + + if (_collViewSource.View.CanGroup == true) + { + _collViewSource.View.GroupDescriptions.Clear(); + _collViewSource.View.GroupDescriptions.Add(_groupDescriptionPackageName); + _collViewSource.View.GroupDescriptions.Add(_groupDescriptionIsComplete); + } + + dge_Main.ItemsSource = _collViewSource.View; + //dge_Main.ItemsSource = _keyCollection; + + var menu = new MenuItem { Header = "Copy complete row(s)" }; + menu.Click += copyCompleteRow; + this.dge_Main.ContextMenu.Items.Add(menu); + + menu = new MenuItem { Header = "Paste complete row(s)" }; + menu.Click += pasteCompleteRowBelowCurrentRow; ; + this.dge_Main.ContextMenu.Items.Add(menu); + + dge_Main.AddingNewItem += Dge_Main_AddingNewItem; + + } + + private void Dge_Main_AddingNewItem(object sender, AddingNewItemEventArgs e) + { + e.NewItem = new Key(); + } + + private bool _isLoadingStringtable; + private bool _doLoadAll; + + + + public async Task LoadStringTableAsync(bool doLoadAll = false) + { + if (StringTable == null) + { + //about 0.03 seconds + //var ts = new StopWatch($"LoadStringTableAsync {CurrentFile.Directory.Name}"); + //ts.Start(); + _isLoadingStringtable = true; + StringTable = await StringtableHelper.ParseStringtable(CurrentFile); + + foreach (var package in StringTable.Project.Packages) + { + foreach (var key in package.Keys) + { + _keyCollection.Add(new Key_ExtendedWithChangeTracking(key, StringTable.Project.Name, package.Name, string.Empty)); + } + foreach (var container in package.Containers) + { + foreach (var key in package.Keys) + { + _keyCollection.Add(new Key_ExtendedWithChangeTracking(key, StringTable.Project.Name, package.Name, container.Name)); + } + } + } + + var initHeader = TranslationHelper.GetHeaders(StringTable); + + var allItems = new List(); + + foreach (var languageName in Enum.GetNames(typeof(Languages))) + { + allItems.Add(new ItemSelected() + { + DisplayName = languageName, + IsSelected = initHeader.Any(x => x == languageName), + Key = languageName + }); + } + Header = allItems; + + UpdateIsCompleteFlag(); + + + UpdateTranslationProgress(); + + _isLoadingStringtable = false; + if (_doLoadAll || doLoadAll) + { + _doLoadAll = false; + Load(); + } + //ts.StopAndLog(); + + } + } + + private void UpdateTranslationProgress() + { + int progressValue = 0; + if (_keyCollection.Count == 0) + { + progressValue = 100; + } + else + { + progressValue =(int) (100 * ((double)_keyCollection.Count(x => x.IsComplete) / (double)_keyCollection.Count)); + if (progressValue < 0) + { + progressValue = 0; + } + if (progressValue > 100) + { + progressValue = 100; + } + } + + TranslationProgress.FireProgressChangedEvent(progressValue); + } + + public async void Load() + { + if (AlreadyLoaded) + { + return; + } + + if (_isLoadingStringtable) + { + _doLoadAll = true; + return; + } + + _isLoadingStringtable = false; + _doLoadAll = false; + try + { + AlreadyLoaded = true; + + var ts = new StopWatch($"Load {CurrentFile.Directory.Name}") + { + LogStart = true + }; + ts.Start(); + ResetAll(); + + await LoadStringTableAsync(); + + CreateTableColumns(); + ts.StopAndLog("CreateTableColumns done"); + + RefreshTableView(); + + var incomplete = _keyCollection.FirstOrDefault(x => x.IsComplete == false); + + if (incomplete != null) + { + dge_Main.ScrollIntoView(incomplete); + + } + + + ts.StopAndLog("RefreshTableView done"); + } + catch (Exception ex) + { + Logger.LogEx(ex); + } + } + + private void RefreshTableView() + { + _collViewSource.View.Refresh(); + } + + private void ResetAll() + { + AlreadyLoaded = false; + _keyCollection.Clear(); + this.StringTable = null; + dge_Main.Columns.Clear(); + + } + + + #endregion + + #region DataGridEvents + + private void _collViewSource_Filter(object sender, FilterEventArgs e) + { + var t = e.Item as Key_ExtendedWithChangeTracking; + + if (t != null) + { + if (string.IsNullOrEmpty(this.tbe_FilterAndSearchAll.Value) && string.IsNullOrEmpty(this.tbe_FilterAndSearchInId.Value)) + { + e.Accepted = true; + } + else + { + if (!string.IsNullOrEmpty(this.tbe_FilterAndSearchAll.Value)) + { + if (t.ContainsText(this.tbe_FilterAndSearchAll.Value, false, true)) + { + e.Accepted = true; + } + else + { + e.Accepted = false; + } + } + if (!string.IsNullOrEmpty(this.tbe_FilterAndSearchInId.Value)) + { + if (t.ContainsText(this.tbe_FilterAndSearchInId.Value, true, true)) + { + e.Accepted = true; + } + else + { + e.Accepted = false; + } + } + + } + } + } + + private void tbe_FilterAndSearchInId_changed(int value) + { + if (_filteringDiabled) + { + return; + } + _filteringDiabled = true; + tbe_FilterAndSearchAll.Value = ""; + _filteringDiabled = false; + _collViewSource.View.Refresh(); + } + + private void tbe_FilterAndSearchAll_3CharsAdded(int value) + { + if (_filteringDiabled) + { + return; + } + _filteringDiabled = true; + tbe_FilterAndSearchInId.Value = ""; + _filteringDiabled = false; + _collViewSource.View.Refresh(); + } + + private void cbGroupByProject_click(object sender, RoutedEventArgs e) + { + var existsAlready = this._collViewSource.View.GroupDescriptions.Any(x => x == _groupDescriptionPackageName); + + if (cbGroupByProject.IsChecked.GetValueOrDefault()) + { + if (existsAlready) + { + return; + } + + this._collViewSource.View.GroupDescriptions.Insert(0, _groupDescriptionPackageName); + } + else + { + if (existsAlready) + { + this._collViewSource.View.GroupDescriptions.Remove(_groupDescriptionPackageName); + } + } + + _collViewSource.View.Refresh(); + + } + + private void cbGroupByStatus_click(object sender, RoutedEventArgs e) + { + var existsAlready = this._collViewSource.View.GroupDescriptions.Any(x => x == _groupDescriptionIsComplete); + + if (cbGroupByStatus.IsChecked.GetValueOrDefault()) + { + if (existsAlready) + { + return; + } + + this._collViewSource.View.GroupDescriptions.Add(_groupDescriptionIsComplete); + } + else + { + if (existsAlready) + { + this._collViewSource.View.GroupDescriptions.Remove(_groupDescriptionIsComplete); + } + } + + //_collViewSource.View.Refresh(); + } + + #endregion + + #region ContextMenu actions + private void pasteCompleteRowBelowCurrentRow(object sender, RoutedEventArgs e) + { + var selected = this.dge_Main.SelectedCells.FirstOrDefault(); + if (selected == null) + { + Logger.LogGeneral("Please select a target row first."); + return; + } + + var keys = ClipBoardHelper.GetKeyObjectsFromClipboard(); + + if (keys == null || !keys.Any()) + { + return; + } + + //StringTable.Project.Packages.FirstOrDefault().Keys.AddRange(keys); + + } + + private void copyCompleteRow(object sender, RoutedEventArgs e) + { + var b = _collViewSource.IsLiveGrouping; + + var keys = this.dge_Main.SelectedCells.Select(x => x.Item).OfType().Distinct().ToList(); + if (keys != null && keys.Any()) + { + ClipBoardHelper.AddKeyObjectsToClipboard(keys); + } + } + + #endregion + + #region Buttons + + private void btnSave_click(object sender, RoutedEventArgs e) + { + if (CurrentFile == null) + { + return; + } + try + { + StringTable.HasChanges = true; + SaveStringTableFile(CurrentFile, StringTable.FileHasBom, this._keyCollection.ToList(), Header); + + } + catch (Exception ex) + { + Logger.LogEx(ex); + } + } + + private void SaveStringTableFile( + FileInfo currentFileInfo, + bool fileHasBom, + List currentKeys, + List header) + { + if (currentKeys == null) + { + return; + } + + if (!currentKeys.Any(x => x.HasChanged)) + { + return; + } + + var dummyNamespace = new XmlSerializerNamespaces(); + dummyNamespace.Add("", ""); + + var xmlSettings = new XmlWriterSettings + { + Indent = true, + IndentChars = " ", + Encoding = new UTF8Encoding(fileHasBom) + }; + + if (ConfigHelper.CurrentSettings.IndentationSettings == IndentationSettings.Spaces) + { + var indentChars = ""; + + for (var i = 0; i < ConfigHelper.CurrentSettings.TabSize; i++) + { + indentChars += " "; + } + + xmlSettings.IndentChars = indentChars; + } + + if (ConfigHelper.CurrentSettings.IndentationSettings == IndentationSettings.Tabs) + { + xmlSettings.IndentChars = "\t"; + } + + var projectGroups = _keyCollection.GroupBy(x => x.SystemValues[Key_ExtendedWithChangeTracking.Project_PropertyName].CurrentValue).ToList(); + + var languagesToWrite = header.Where(x => x.IsSelected).Select(x => x.Key).Distinct().ToList(); + + XDocument srcTree = new XDocument(new XDeclaration("1.0", "utf-8", "true")); + + foreach (var projectItems in projectGroups) + { + var project = new XElement("Project", new XAttribute("name", projectItems.Key)); + srcTree.Add(project); + var packages = projectItems.GroupBy(x => x.PackageName).ToList(); + + foreach (var package in packages) + { + XElement toAddTo = project; + if (!string.IsNullOrEmpty(package.Key)) + { + //we have packages + toAddTo = new XElement("Package", new XAttribute("name", package.Key)); + project.Add(toAddTo); + } + + foreach (var itemInPackage in package) + { + toAddTo.Add(itemInPackage.AsXElement(true, languagesToWrite)); + } + } + } + + using (var writer = XmlWriter.Create(currentFileInfo.FullName, xmlSettings)) + { + srcTree.Save(writer); + } + + foreach (var item in _keyCollection) + { + item.ResetHasChanged(); + } + } + + + private void btnReloadFile_click(object sender, RoutedEventArgs e) + { + ResetAll(); + + Load(); + } + + private void btnSelectLanguages_click(object sender, RoutedEventArgs e) + { + try + { + var ctrl = new ItemSelectControl(); + + ctrl.SetItemsAndSelectedItems(Header); + ctrl.ShowInNewWindow(true, this, "Select Languages"); + + SynchVisibleHeader(); + UpdateIsCompleteFlag(); + + } + catch (Exception ex) + { + Logger.LogEx(ex); + } + + } + + #endregion + + #region private methods + + private void CreateTableColumns() + { + + //AddColumns(new ItemSelected() { IsSelected = true, DisplayName = Key_ExtendedWithChangeTracking.IsComplete_PropertyName, Key = Key_ExtendedWithChangeTracking.IsComplete_PropertyName }); + AddColumns(new ItemSelected() + { + IsSelected = true, + DisplayName = Key_ExtendedWithChangeTracking.Id_PropertyName, + Key = Key_ExtendedWithChangeTracking.Id_PropertyName + }, "SystemValues"); + //AddColumns(new ItemSelected() { IsSelected = true, DisplayName = Key_ExtendedWithChangeTracking.Project_PropertyName, Key = Key_ExtendedWithChangeTracking.Project_PropertyName }); + + foreach (var header in Header) + { + AddColumns(header, "Languages"); + } + } + + private void AddColumns(ItemSelected header, string dictionaryInKey_ExtendedWithChangeTracking) + { + var binding = new Binding(header.Key); + binding.Mode = BindingMode.TwoWay; + var dgNew = new DataGridTextColumn + { + // bind to a dictionary property + Binding = new Binding(dictionaryInKey_ExtendedWithChangeTracking + "[" + header.Key + "].CurrentValue"), + Header = header.DisplayName, + Width = 100, + Visibility = header.IsSelected ? Visibility.Visible : Visibility.Collapsed, + }; + + //dgNew.PastingCellClipboardContent += DgNew_PastingCellClipboardContent; + //dgNew.CopyingCellClipboardContent += DgNew_CopyingCellClipboardContent; + + dge_Main.Columns.Add(dgNew); + } + + private void UpdateIsCompleteFlag() + { + var selectedHeader = Header.Where(x => x.IsSelected).Select(x => x.Key).ToList(); + + foreach (var item in _keyCollection) + { + item.Update_IsCompletedValue(selectedHeader); + } + + } + + private void SynchVisibleHeader() + { + try + { + foreach (var column in dge_Main.Columns.OfType()) + { + var header = Header.FirstOrDefault(x => x.Key == column.Header.ToString()); + + if (header == null) + { + continue; + } + + column.Visibility = header.IsSelected ? Visibility.Visible : Visibility.Collapsed; + } + } + catch (Exception ex) + { + Logger.LogEx(ex); + } + + } + + #endregion + + + + + + + //private void DgNew_CopyingCellClipboardContent(object sender, DataGridCellClipboardEventArgs e) + //{ + + // var i = e.Item; + // var k = i as Logic.Classes.Key; + // if (k != null) + // { + // ClipBoardHelper.AddKeyObjectToClipboard(k); + // } + //} + + //private void DgNew_PastingCellClipboardContent(object sender, DataGridCellClipboardEventArgs e) + //{ + // try + // { + // var k = ClipBoardHelper.GetKeyObjectFromClipboard(); + // if (k != null) + // { + + // } + + // //if (!Clipboard.ContainsText()) + // //{ + // // return; + // //} + + // //var data = Clipboard.GetData(DataFormats.UnicodeText); + + // //var datao = Clipboard.GetDataObject(); + // } + // catch (Exception ex) + // { + // Logger.LogEx(ex); + // } + + + //} + + + } +} diff --git a/tabler.wpf/ExampleData/TEST.xml b/tabler.wpf/ExampleData/TEST.xml new file mode 100644 index 0000000..7c31d42 --- /dev/null +++ b/tabler.wpf/ExampleData/TEST.xml @@ -0,0 +1,225 @@ + + + + + TEST + Windinformationen anzeigen + Afficher les info sur le vent + Mostra indicazioni del vento + Mostrar información del viento + Mostrar Informação do Vento + Pokaż inf. o wietrze + Zobrazit informace o větru + Széladatok mutatása + Показать информацию о ветре + + + Show Protractor + Winkelmesser anzeigen + Afficher le rapporteur + Mostra il rapportatore + Mostrar transportador + Mostrar Transferidor + Pokaż kątomierz + Zobrazit úhloměr + Szögmérő mutatása + Показать транспортир + + + Advanced Ballistics + Erweiterte Ballistik + Balística avanzada + Balística avançada + Zaawansowana balistyka + Pokročilá balistika + + + Advanced Ballistics + Erweiterte Ballistik + Balística avanzada + Balística avançada + Zaawansowana balistyka + Pokročilá balistika + + + Enables advanced ballistics + Aktiviert die erweiterte Ballistik + Activa la balística avanzada + Ativa balística avançada + Aktywuje zaawansowaną balistykę + Aktivuje pokročilou balistiku + + + Enabled For Snipers + Für Scharfschützen aktiviert + dth + Activada para francotiradores + Ativar para caçadores + Akt. dla snajperów + Povoleno pro odstřelovače + + + Enables advanced ballistics for non local snipers (when using high power optics) + Aktiviert die erweiterte Ballistik für nicht lokale Scharfschützen (bei Benutzung von Optiken mit starker Vergrößerung) + thf + Activa la balística avanzada para francotiradores no locales (cuando se usa una mira telescópica) + Ativa balística avançada para caçadores não locais (quando usando miras telescópicas) + Aktywuje zaawansowaną balistykę dla nielokalnych snajperów (kiedy używają optyki) + Aktivuje pokročilou balistiku pro nelokální odstřelovače (když používá výkonnou optiku) + + + Enabled For Group Members + Für Gruppenmitglieder aktiviert + dht + Activada para miembros de grupo + Ativada para membros do grupo + Akt. dla czł. grupy + Povoleno pro členy skupiny + + + Enables advanced ballistics for non local group members + Aktiviert die erweiterte Ballistik für nicht lokale Gruppenmitglieder + Activada la balística avanzada para miembros de grupo no locales + Ativa balística avançada para membros de grupo não locais + Aktywuje zaawansowaną balistykę dla nielokalnych członków grupy + Aktivuje pokročilou balistiku pro nelokální členy skupiny + + + Enabled For Everyone + Für jeden aktiviert + t + Activada para todos + Ativada para todos + Akt. dla wszystkich + Povoleno pro všechny + + + Enables advanced ballistics for all non local players (enabling this may degrade performance during heavy firefights in multiplayer) + Aktiviert die erweiterte Ballistik für alle nicht lokalen Spieler (das Aktivieren dieser Funktion kann zur Beeinträchtigung des Spielerlebnisses im Multiplayer führen) + hhf + Activada la balística avanzada para todos los jugadores no locales (activarlo puede degradar el rendimiento durante grandes tiroteos en multijugador). + Ativa balística avançada para todos os jogadores não locais (ativando isso pode degradar a performance durante troca de tiros intensas no multiplayer) + Aktywuje zaawansowaną balistykę dla wszystkich nielokalnych graczy (aktywacja tej opcji może spodowować spory spadek wydajności podczas ciężkiej wymiany ognia) + Aktivovat pokročilou balistiku pro všechny nelokální hráče (aktivace této možnosti způsobuje pokles snímu za sekundu během těžké přestřelky v multiplayeru) + + + Always Enabled For Group Members + Für Gruppenmitglieder immer aktiviert + Siempre activada para miembros de grupo + Sempre ativada para membros do grupo + Zawsze akt. dla czł. grupy + Vždy povoleno pro členy skupiny + + + Always enables advanced ballistics when a group member fires + Aktiviert die erweiterte Ballistik immer, wenn ein Gruppenmitglied schießt + h + Activada la balística avanzada siempre cuando miembros de grupo disparan + Sempre ative balística avançada quando um membro do grupo disparar + Aktywuje zaawansowaną balistykę dla wszystkich członków grupy + Aktivuje pokročilou balistiku pro členy skupiny + + + Disabled In FullAuto Mode + Beim vollautomatischen Feuern deaktiviert + htah + Desactivada en modo automático + Desabilitar no modo automático + Wył. podczas ognia auto. + Zakázáno v automatickém režimu střelby + + + Disables the advanced ballistics during full auto fire + Deaktiviert die erweiterte Ballistik beim vollautomatischen Feuern + Desactivada la balística avanzada durante el fuego automático + Desabilitar a balística avançada durante fogo automático + Dezaktywuje zaawansowaną balistykę podczas ognia automatycznego + Zákáže pokročilou balistiku během střelby v režimu automat + + + Enable Ammo Temperature Simulation + Simulation der Munitionstemperatur aktivieren + Activar simulación de temperatura de munición + Ativar simulação de temperatura de munição + Symulacja temp. amunicji + Povolit simulaci teploty munice + + + Muzzle velocity varies with ammo temperature + Munitionstemperatur hat Einfluss auf die Mündungsgeschwindigkeit + La velocidad de salida varía con la temperatura de la munición + A velocidade de saída varia com a temperatura da munição + Prędkość wylotowa pocisku jest zależna od temperatury amunicji + Úsťová rychlost je závislá na teplotě munice + + + Enable Barrel Length Simulation + Simulation der Lauflänge aktivieren + Habilitar la simulación de longitud del cañón + Ativar a simulação de comprimento do cano + Symulacja długości lufy + Povolit simulaci délky hlavně + + + Muzzle velocity varies with barrel length + Lauflänge beeinflusst Mündungsgeschwindigkeit + La velocidad de salidal varía con la longitud del cañón + A velocidade de saída caria com o comprimento do cano + Prędkość wylotowa pocisku jest zależna od długości lufy + Úsťová rychlost je závislá na délce hlavně + + + Enable Bullet Trace Effect + Geschossspureffekt aktivieren + Activar el efecto trazador de la bala + Ativa efeito traçante de projétil + Efekt smugi pocisku + Povolit efekt trasírek + + + Enables a bullet trace effect to high caliber bullets (only visible when looking through high power optics) + Aktiviere Geschossspureffekt für hohe Kaliber (bei Benutzung von Optiken mit starker Vergrößerung) + Activa el efecto trazador de la balas de gran calibre (solo visible cuando se mira a través de una mira telescópica) + Ativa o efeito traçante de projétil para projéteis de alto calibre (somente visível quando observado por miras telescópicas) + Aktywuje efekt smugi pocisku dla pocisków wysokokalibrowych (widoczne tylko podczas patrzenia przez optykę) + Aktivuje efekt trasírek z vysokokaliberních zbraní (viditelné pouze skrze výkonnou optiku) + + + Simulation Interval + Simulationsintervall + Intervalo de simulación + Intervalo da simulação + Interwał symulacji + Interval simulace + + + Defines the interval between every calculation step + Legt das Intervall zwischen den Berechnungsschritten fest + Define el intervalo entre cada cálculo + Define o intervalo entre cada cálculo + Określa interwał pomiędzy każdym krokiem kalkulacji + Určuje interval mezi každým výpočtem + + + Simulation Radius + Simulationsradius + Radio de simulación + Raio de simulação + Zasięg symulacji + Rozsah simulace + + + Defines the radius around the player (in meters) at which advanced ballistics are applied to projectiles + Gibt den Radius (in Metern) um den Spieler an, bei dem die erweiterte Ballistik auf Geschosse angewendet wird + Define el radio alrededor del jugador (en metros) en el cual se aplica la balística avanzada a los proyectiles + Define o raio ao redor do jogador (em metros) onde a balística avançada será aplicada aos projéteis + Określa obszar naokoło gracza (w metrach), na którym zaawansowana balistyka jest aplikowana dla pocisków + Určuje oblast kolem hráče (v metrech), kde je pokročilá balistika použita na projektil + + + Este módulo permite que você ative cálculos de balística avançada, fazendo a trajetória do projétil levar em consideração coisas como temperatura do ar, pressão atmosférica, umidade, força de Coriolis, a gravidade, o modelo da arma no qual o disparo é realizado e o tipo de munição. Tudo isso acrescenta-se a um balística muito precisa. + Moduł ten pozwala aktywować zaawansowaną balistykę biorącą przy obliczeniach trajektorii lotu pocisku pod uwagę takie rzeczy jak temperatura powietrza, ciśnienie atmosferyczne, wilgotność powietrza, siły Coriolisa i Eotvosa, grawitację a także broń z jakiej wykonywany jest strzał oraz rodzaj amunicji. Wszystko to sprowadza się na bardzo dokładne odwzorowanie balistyki. + Tento modul umožňuje aktivovat pokročilou balistiku, která vypočítává trajektorii kulky a bere do úvahy věci jako je teplota vzduchu, atmosférický tlak, vlhkost vzduchu, gravitaci, typ munice a zbraň, ze které je náboj vystřelen. To vše přispívá k velmi přesné balistice. + + + \ No newline at end of file diff --git a/tabler.wpf/ExampleData/TEST.xmlFILE b/tabler.wpf/ExampleData/TEST.xmlFILE new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tabler.wpf/ExampleData/TEST.xmlFILE @@ -0,0 +1 @@ + diff --git a/tabler.wpf/ExampleData/proj1/stringtable.xml b/tabler.wpf/ExampleData/proj1/stringtable.xml new file mode 100644 index 0000000..d11569f --- /dev/null +++ b/tabler.wpf/ExampleData/proj1/stringtable.xml @@ -0,0 +1,219 @@ + + + + + TEST + Windinformationen anzeigen + Afficher les info sur le vent + Mostra indicazioni del vento + Mostrar información del viento + Mostrar Informação do Vento + Pokaż inf. o wietrze + Zobrazit informace o větru + Széladatok mutatása + Показать информацию о ветре + + + Show Protractor + Winkelmesser anzeigen + Afficher le rapporteur + Mostra il rapportatore + Mostrar transportador + Mostrar Transferidor + Pokaż kątomierz + Zobrazit úhloměr + Szögmérő mutatása + Показать транспортир + + + Advanced Ballistics + Erweiterte Ballistik + Balística avanzada + Balística avançada + Zaawansowana balistyka + Pokročilá balistika + + + Advanced Ballistics + Erweiterte Ballistik + Balística avanzada + Balística avançada + Zaawansowana balistyka + Pokročilá balistika + + + Enables advanced ballistics + Aktiviert die erweiterte Ballistik + Activa la balística avanzada + Ativa balística avançada + Aktywuje zaawansowaną balistykę + Aktivuje pokročilou balistiku + + + Enabled For Snipers + Für Scharfschützen aktiviert + Activada para francotiradores + Ativar para caçadores + Akt. dla snajperów + Povoleno pro odstřelovače + + + Enables advanced ballistics for non local snipers (when using high power optics) + Aktiviert die erweiterte Ballistik für nicht lokale Scharfschützen (bei Benutzung von Optiken mit starker Vergrößerung) + Activa la balística avanzada para francotiradores no locales (cuando se usa una mira telescópica) + Ativa balística avançada para caçadores não locais (quando usando miras telescópicas) + Aktywuje zaawansowaną balistykę dla nielokalnych snajperów (kiedy używają optyki) + Aktivuje pokročilou balistiku pro nelokální odstřelovače (když používá výkonnou optiku) + + + Enabled For Group Members + Für Gruppenmitglieder aktiviert + Activada para miembros de grupo + Ativada para membros do grupo + Akt. dla czł. grupy + Povoleno pro členy skupiny + + + Enables advanced ballistics for non local group members + Aktiviert die erweiterte Ballistik für nicht lokale Gruppenmitglieder + Activada la balística avanzada para miembros de grupo no locales + Ativa balística avançada para membros de grupo não locais + Aktywuje zaawansowaną balistykę dla nielokalnych członków grupy + Aktivuje pokročilou balistiku pro nelokální členy skupiny + + + Enabled For Everyone + Für jeden aktiviert + Activada para todos + Ativada para todos + Akt. dla wszystkich + Povoleno pro všechny + + + Enables advanced ballistics for all non local players (enabling this may degrade performance during heavy firefights in multiplayer) + Aktiviert die erweiterte Ballistik für alle nicht lokalen Spieler (das Aktivieren dieser Funktion kann zur Beeinträchtigung des Spielerlebnisses im Multiplayer führen) + Activada la balística avanzada para todos los jugadores no locales (activarlo puede degradar el rendimiento durante grandes tiroteos en multijugador). + Ativa balística avançada para todos os jogadores não locais (ativando isso pode degradar a performance durante troca de tiros intensas no multiplayer) + Aktywuje zaawansowaną balistykę dla wszystkich nielokalnych graczy (aktywacja tej opcji może spodowować spory spadek wydajności podczas ciężkiej wymiany ognia) + Aktivovat pokročilou balistiku pro všechny nelokální hráče (aktivace této možnosti způsobuje pokles snímu za sekundu během těžké přestřelky v multiplayeru) + + + Always Enabled For Group Members + Für Gruppenmitglieder immer aktiviert + Siempre activada para miembros de grupo + Sempre ativada para membros do grupo + Zawsze akt. dla czł. grupy + Vždy povoleno pro členy skupiny + + + Always enables advanced ballistics when a group member fires + Aktiviert die erweiterte Ballistik immer, wenn ein Gruppenmitglied schießt + Activada la balística avanzada siempre cuando miembros de grupo disparan + Sempre ative balística avançada quando um membro do grupo disparar + Aktywuje zaawansowaną balistykę dla wszystkich członków grupy + Aktivuje pokročilou balistiku pro členy skupiny + + + Disabled In FullAuto Mode + Beim vollautomatischen Feuern deaktiviert + Desactivada en modo automático + Desabilitar no modo automático + Wył. podczas ognia auto. + Zakázáno v automatickém režimu střelby + + + Disables the advanced ballistics during full auto fire + Deaktiviert die erweiterte Ballistik beim vollautomatischen Feuern + Desactivada la balística avanzada durante el fuego automático + Desabilitar a balística avançada durante fogo automático + Dezaktywuje zaawansowaną balistykę podczas ognia automatycznego + Zákáže pokročilou balistiku během střelby v režimu automat + + + Enable Ammo Temperature Simulation + Simulation der Munitionstemperatur aktivieren + Activar simulación de temperatura de munición + Ativar simulação de temperatura de munição + Symulacja temp. amunicji + Povolit simulaci teploty munice + + + Muzzle velocity varies with ammo temperature + Munitionstemperatur hat Einfluss auf die Mündungsgeschwindigkeit + La velocidad de salida varía con la temperatura de la munición + A velocidade de saída varia com a temperatura da munição + Prędkość wylotowa pocisku jest zależna od temperatury amunicji + Úsťová rychlost je závislá na teplotě munice + + + Enable Barrel Length Simulation + Simulation der Lauflänge aktivieren + Habilitar la simulación de longitud del cañón + Ativar a simulação de comprimento do cano + Symulacja długości lufy + Povolit simulaci délky hlavně + + + Muzzle velocity varies with barrel length + Lauflänge beeinflusst Mündungsgeschwindigkeit + La velocidad de salidal varía con la longitud del cañón + A velocidade de saída caria com o comprimento do cano + Prędkość wylotowa pocisku jest zależna od długości lufy + Úsťová rychlost je závislá na délce hlavně + + + Enable Bullet Trace Effect + Geschossspureffekt aktivieren + Activar el efecto trazador de la bala + Ativa efeito traçante de projétil + Efekt smugi pocisku + Povolit efekt trasírek + + + Enables a bullet trace effect to high caliber bullets (only visible when looking through high power optics) + Aktiviere Geschossspureffekt für hohe Kaliber (bei Benutzung von Optiken mit starker Vergrößerung) + Activa el efecto trazador de la balas de gran calibre (solo visible cuando se mira a través de una mira telescópica) + Ativa o efeito traçante de projétil para projéteis de alto calibre (somente visível quando observado por miras telescópicas) + Aktywuje efekt smugi pocisku dla pocisków wysokokalibrowych (widoczne tylko podczas patrzenia przez optykę) + Aktivuje efekt trasírek z vysokokaliberních zbraní (viditelné pouze skrze výkonnou optiku) + + + Simulation Interval + Simulationsintervall + Intervalo de simulación + Intervalo da simulação + Interwał symulacji + Interval simulace + + + Defines the interval between every calculation step + Legt das Intervall zwischen den Berechnungsschritten fest + Define el intervalo entre cada cálculo + Define o intervalo entre cada cálculo + Określa interwał pomiędzy każdym krokiem kalkulacji + Určuje interval mezi každým výpočtem + + + Simulation Radius + Simulationsradius + Radio de simulación + Raio de simulação + Zasięg symulacji + Rozsah simulace + + + Defines the radius around the player (in meters) at which advanced ballistics are applied to projectiles + Gibt den Radius (in Metern) um den Spieler an, bei dem die erweiterte Ballistik auf Geschosse angewendet wird + Define el radio alrededor del jugador (en metros) en el cual se aplica la balística avanzada a los proyectiles + Define o raio ao redor do jogador (em metros) onde a balística avançada será aplicada aos projéteis + Określa obszar naokoło gracza (w metrach), na którym zaawansowana balistyka jest aplikowana dla pocisków + Určuje oblast kolem hráče (v metrech), kde je pokročilá balistika použita na projektil + + + + Este módulo permite que você ative cálculos de balística avançada, fazendo a trajetória do projétil levar em consideração coisas como temperatura do ar, pressão atmosférica, umidade, força de Coriolis, a gravidade, o modelo da arma no qual o disparo é realizado e o tipo de munição. Tudo isso acrescenta-se a um balística muito precisa. + Moduł ten pozwala aktywować zaawansowaną balistykę biorącą przy obliczeniach trajektorii lotu pocisku pod uwagę takie rzeczy jak temperatura powietrza, ciśnienie atmosferyczne, wilgotność powietrza, siły Coriolisa i Eotvosa, grawitację a także broń z jakiej wykonywany jest strzał oraz rodzaj amunicji. Wszystko to sprowadza się na bardzo dokładne odwzorowanie balistyki. + Tento modul umožňuje aktivovat pokročilou balistiku, která vypočítává trajektorii kulky a bere do úvahy věci jako je teplota vzduchu, atmosférický tlak, vlhkost vzduchu, gravitaci, typ munice a zbraň, ze které je náboj vystřelen. To vše přispívá k velmi přesné balistice. + + + diff --git a/tabler.wpf/ExampleData/proj2/stringtable.xml b/tabler.wpf/ExampleData/proj2/stringtable.xml new file mode 100644 index 0000000..1d05beb --- /dev/null +++ b/tabler.wpf/ExampleData/proj2/stringtable.xml @@ -0,0 +1,219 @@ + + + + + Show Wind Info + Pokaż inf. o wietrze + Mostra indicazioni del vento + Показать информацию о ветре + Afficher les info sur le vent + Mostrar información del viento + Windinformationen anzeigen + Széladatok mutatása + Zobrazit informace o větru + Mostrar Informação do Vento + + + Show Protractor + Pokaż kątomierz + Mostra il rapportatore + Показать транспортир + Afficher le rapporteur + Mostrar transportador + Winkelmesser anzeigen + Szögmérő mutatása + Zobrazit úhloměr + Mostrar Transferidor + + + Advanced Ballistics + Zaawansowana balistyka + Balística avanzada + Erweiterte Ballistik + Pokročilá balistika + Balística avançada + + + Advanced Ballistics + Zaawansowana balistyka + Balística avanzada + Erweiterte Ballistik + Pokročilá balistika + Balística avançada + + + Enables advanced ballistics + Aktywuje zaawansowaną balistykę + Activa la balística avanzada + Aktiviert die erweiterte Ballistik + Aktivuje pokročilou balistiku + Ativa balística avançada + + + Enabled For Snipers + Activada para francotiradores + Akt. dla snajperów + Für Scharfschützen aktiviert + Povoleno pro odstřelovače + Ativar para caçadores + + + Enables advanced ballistics for non local snipers (when using high power optics) + Activa la balística avanzada para francotiradores no locales (cuando se usa una mira telescópica) + Aktywuje zaawansowaną balistykę dla nielokalnych snajperów (kiedy używają optyki) + Aktiviert die erweiterte Ballistik für nicht lokale Scharfschützen (bei Benutzung von Optiken mit starker Vergrößerung) + Aktivuje pokročilou balistiku pro nelokální odstřelovače (když používá výkonnou optiku) + Ativa balística avançada para caçadores não locais (quando usando miras telescópicas) + + + Enabled For Group Members + Activada para miembros de grupo + Akt. dla czł. grupy + Für Gruppenmitglieder aktiviert + Povoleno pro členy skupiny + Ativada para membros do grupo + + + Enables advanced ballistics for non local group members + Activada la balística avanzada para miembros de grupo no locales + Aktywuje zaawansowaną balistykę dla nielokalnych członków grupy + Aktiviert die erweiterte Ballistik für nicht lokale Gruppenmitglieder + Aktivuje pokročilou balistiku pro nelokální členy skupiny + Ativa balística avançada para membros de grupo não locais + + + Enabled For Everyone + Activada para todos + Akt. dla wszystkich + Für jeden aktiviert + Povoleno pro všechny + Ativada para todos + + + Enables advanced ballistics for all non local players (enabling this may degrade performance during heavy firefights in multiplayer) + Activada la balística avanzada para todos los jugadores no locales (activarlo puede degradar el rendimiento durante grandes tiroteos en multijugador). + Aktywuje zaawansowaną balistykę dla wszystkich nielokalnych graczy (aktywacja tej opcji może spodowować spory spadek wydajności podczas ciężkiej wymiany ognia) + Aktiviert die erweiterte Ballistik für alle nicht lokalen Spieler (das Aktivieren dieser Funktion kann zur Beeinträchtigung des Spielerlebnisses im Multiplayer führen) + Aktivovat pokročilou balistiku pro všechny nelokální hráče (aktivace této možnosti způsobuje pokles snímu za sekundu během těžké přestřelky v multiplayeru) + Ativa balística avançada para todos os jogadores não locais (ativando isso pode degradar a performance durante troca de tiros intensas no multiplayer) + + + Always Enabled For Group Members + Zawsze akt. dla czł. grupy + Siempre activada para miembros de grupo + Für Gruppenmitglieder immer aktiviert + Vždy povoleno pro členy skupiny + Sempre ativada para membros do grupo + + + Always enables advanced ballistics when a group member fires + Aktywuje zaawansowaną balistykę dla wszystkich członków grupy + Activada la balística avanzada siempre cuando miembros de grupo disparan + Aktiviert die erweiterte Ballistik immer, wenn ein Gruppenmitglied schießt + Aktivuje pokročilou balistiku pro členy skupiny + Sempre ative balística avançada quando um membro do grupo disparar + + + Disabled In FullAuto Mode + Wył. podczas ognia auto. + Desactivada en modo automático + Beim vollautomatischen Feuern deaktiviert + Zakázáno v automatickém režimu střelby + Desabilitar no modo automático + + + Disables the advanced ballistics during full auto fire + Dezaktywuje zaawansowaną balistykę podczas ognia automatycznego + Desactivada la balística avanzada durante el fuego automático + Deaktiviert die erweiterte Ballistik beim vollautomatischen Feuern + Zákáže pokročilou balistiku během střelby v režimu automat + Desabilitar a balística avançada durante fogo automático + + + Enable Ammo Temperature Simulation + Symulacja temp. amunicji + Activar simulación de temperatura de munición + Simulation der Munitionstemperatur aktivieren + Povolit simulaci teploty munice + Ativar simulação de temperatura de munição + + + Muzzle velocity varies with ammo temperature + Prędkość wylotowa pocisku jest zależna od temperatury amunicji + La velocidad de salida varía con la temperatura de la munición + Munitionstemperatur hat Einfluss auf die Mündungsgeschwindigkeit + Úsťová rychlost je závislá na teplotě munice + A velocidade de saída varia com a temperatura da munição + + + Enable Barrel Length Simulation + Symulacja długości lufy + Habilitar la simulación de longitud del cañón + Simulation der Lauflänge aktivieren + Povolit simulaci délky hlavně + Ativar a simulação de comprimento do cano + + + Muzzle velocity varies with barrel length + Prędkość wylotowa pocisku jest zależna od długości lufy + La velocidad de salidal varía con la longitud del cañón + Lauflänge beeinflusst Mündungsgeschwindigkeit + Úsťová rychlost je závislá na délce hlavně + A velocidade de saída caria com o comprimento do cano + + + Enable Bullet Trace Effect + Efekt smugi pocisku + Activar el efecto trazador de la bala + Geschossspureffekt aktivieren + Povolit efekt trasírek + Ativa efeito traçante de projétil + + + Enables a bullet trace effect to high caliber bullets (only visible when looking through high power optics) + Aktywuje efekt smugi pocisku dla pocisków wysokokalibrowych (widoczne tylko podczas patrzenia przez optykę) + Activa el efecto trazador de la balas de gran calibre (solo visible cuando se mira a través de una mira telescópica) + Aktiviere Geschossspureffekt für hohe Kaliber (bei Benutzung von Optiken mit starker Vergrößerung) + Aktivuje efekt trasírek z vysokokaliberních zbraní (viditelné pouze skrze výkonnou optiku) + Ativa o efeito traçante de projétil para projéteis de alto calibre (somente visível quando observado por miras telescópicas) + + + Simulation Interval + Interwał symulacji + Intervalo de simulación + Simulationsintervall + Interval simulace + Intervalo da simulação + + + Defines the interval between every calculation step + Określa interwał pomiędzy każdym krokiem kalkulacji + Define el intervalo entre cada cálculo + Legt das Intervall zwischen den Berechnungsschritten fest + Určuje interval mezi každým výpočtem + Define o intervalo entre cada cálculo + + + Simulation Radius + Zasięg symulacji + Radio de simulación + Simulationsradius + Rozsah simulace + Raio de simulação + + + Defines the radius around the player (in meters) at which advanced ballistics are applied to projectiles + Określa obszar naokoło gracza (w metrach), na którym zaawansowana balistyka jest aplikowana dla pocisków + Define el radio alrededor del jugador (en metros) en el cual se aplica la balística avanzada a los proyectiles + Gibt den Radius (in Metern) um den Spieler an, bei dem die erweiterte Ballistik auf Geschosse angewendet wird + Určuje oblast kolem hráče (v metrech), kde je pokročilá balistika použita na projektil + Define o raio ao redor do jogador (em metros) onde a balística avançada será aplicada aos projéteis + + + + Moduł ten pozwala aktywować zaawansowaną balistykę biorącą przy obliczeniach trajektorii lotu pocisku pod uwagę takie rzeczy jak temperatura powietrza, ciśnienie atmosferyczne, wilgotność powietrza, siły Coriolisa i Eotvosa, grawitację a także broń z jakiej wykonywany jest strzał oraz rodzaj amunicji. Wszystko to sprowadza się na bardzo dokładne odwzorowanie balistyki. + Tento modul umožňuje aktivovat pokročilou balistiku, která vypočítává trajektorii kulky a bere do úvahy věci jako je teplota vzduchu, atmosférický tlak, vlhkost vzduchu, gravitaci, typ munice a zbraň, ze které je náboj vystřelen. To vše přispívá k velmi přesné balistice. + Este módulo permite que você ative cálculos de balística avançada, fazendo a trajetória do projétil levar em consideração coisas como temperatura do ar, pressão atmosférica, umidade, força de Coriolis, a gravidade, o modelo da arma no qual o disparo é realizado e o tipo de munição. Tudo isso acrescenta-se a um balística muito precisa. + + + \ No newline at end of file diff --git a/tabler.wpf/Helper/ClipBoardHelper.cs b/tabler.wpf/Helper/ClipBoardHelper.cs new file mode 100644 index 0000000..34c5580 --- /dev/null +++ b/tabler.wpf/Helper/ClipBoardHelper.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Threading; +using tabler.Logic.Classes; +using tabler.Logic.Helper; +using tabler.wpf.Container; + +namespace tabler.wpf.Helper +{ + public static class ClipBoardHelper + { + private static DataFormat GetDataFormatOfKey() + { + return DataFormats.GetDataFormat(typeof(List).FullName); + } + + public static void AddKeyObjectsToClipboard(List obj) + { + if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) + { + Logger.LogInternal($"To access the clipboard, the thread must be STA!"); + return; + } + + try + { + var format = GetDataFormatOfKey(); + IDataObject dataObj = new DataObject(); + dataObj.SetData(format.Name, obj, false); + Clipboard.SetDataObject(dataObj, false); + Logger.LogGeneral($"Added to clipboard: {obj.Count} format: {format.Id} format.name:{format.Name}"); + } + catch (Exception ex) + { + Logger.LogEx(ex); + } + } + + public static void AddKeyObjectToClipboard(Key_ExtendedWithChangeTracking obj) + { + AddKeyObjectsToClipboard(new List { obj }); + } + + public static List GetKeyObjectsFromClipboard() + { + if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) + { + Logger.LogInternal($"To access the clipboard, the thread must be STA!"); + return null; + } + List doc = null; + + try + { + var format = GetDataFormatOfKey(); + var dataObj = Clipboard.GetDataObject(); + Logger.LogGeneral($"Get from clipboard: format: {format.Id} format.name:{format.Name} :{Thread.CurrentThread.GetApartmentState()}"); + if (dataObj != null && dataObj.GetDataPresent(format.Name)) + { + var o = dataObj.GetData(format.Name); + doc = o as List; + Logger.LogGeneral($"Get key from clipboard SUCCESSS "); + } + else + { + Logger.LogGeneral($"Get key from clipboard failed :("); + } + + return doc; + } + catch (Exception ex) + { + Logger.LogEx(ex); + return null; + } + + } + + public static Key_ExtendedWithChangeTracking GetKeyObjectFromClipboard() + { + return GetKeyObjectsFromClipboard().FirstOrDefault(); + + } + } +} diff --git a/tabler.wpf/Helper/Converter/BoolInverter.cs b/tabler.wpf/Helper/Converter/BoolInverter.cs new file mode 100644 index 0000000..67de9a4 --- /dev/null +++ b/tabler.wpf/Helper/Converter/BoolInverter.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + +namespace tabler.wpf.Controls.Converter +{ + public class BoolInverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null) + { + return true; + } + + return !(bool)value; + + + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null) + { + return true; + } + return !(bool)value; + } + } +} diff --git a/tabler.wpf/Helper/Converter/BooleanNullableToBrushConverter.cs b/tabler.wpf/Helper/Converter/BooleanNullableToBrushConverter.cs new file mode 100644 index 0000000..601dcd4 --- /dev/null +++ b/tabler.wpf/Helper/Converter/BooleanNullableToBrushConverter.cs @@ -0,0 +1,96 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; +using System.Windows.Markup; +using System.Windows.Media; +using tabler.Logic.Helper; + +namespace tabler.wpf.Controls.Converter +{ + public class BooleanNullableToBrushConverter : MarkupExtension, IValueConverter + + { + public static readonly IValueConverter Instance = new BooleanNullableToBrushConverter(); + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + try + { + bool? bValue = null; + if (value is bool) + { + bValue = (bool)value; + } + else + { + var ut = Nullable.GetUnderlyingType(targetType); + if (ut != null && ut == typeof(bool)) + { + bValue = (bool?)value; + } + else + { + var s = value as string; + if (s != null) + { + var valueString = s.ToLowerInvariant(); + if (valueString == "true") + { + bValue = true; + } + if (valueString == "false") + { + bValue = false; + } + } + else + { + return DependencyProperty.UnsetValue; + } + } + } + + if (!bValue.HasValue) + { + return DependencyProperty.UnsetValue; + } + + if (bValue.Value) + { + return new SolidColorBrush(Colors.ForestGreen); + } + return new SolidColorBrush(Colors.Orange); + } + catch (Exception ex) + { + Logger.LogError($"{nameof(BooleanToVisibilityConverter)}.{nameof(Convert)} Exception: {ex}"); + } + + return Visibility.Visible; + } + + /// + /// Convert Visibility to boolean + /// + /// + /// + /// + /// + /// + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is Visibility) + { + return (Visibility)value == Visibility.Visible; + } + else + { + return false; + } + } + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } + } +} diff --git a/tabler.wpf/Helper/Converter/BooleanToVisibilityConverter.cs b/tabler.wpf/Helper/Converter/BooleanToVisibilityConverter.cs new file mode 100644 index 0000000..9fed458 --- /dev/null +++ b/tabler.wpf/Helper/Converter/BooleanToVisibilityConverter.cs @@ -0,0 +1,62 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; +using System.Windows.Markup; +using tabler.Logic.Helper; + +namespace tabler.wpf.Controls.Converter +{ + public class BooleanToVisibilityConverter : MarkupExtension, IValueConverter + + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + try + { + bool bValue = false; + if (value is bool) + { + bValue = (bool)value; + } + + if (parameter != null && (string)parameter == "true") + { + bValue = !bValue; + } + + return bValue ? Visibility.Visible : Visibility.Collapsed; + } + catch (Exception ex) + { + Logger.LogError($"{nameof(BooleanToVisibilityConverter)}.{nameof(Convert)} Exception: {ex}"); + } + + return Visibility.Visible; + } + + /// + /// Convert Visibility to boolean + /// + /// + /// + /// + /// + /// + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is Visibility) + { + return (Visibility)value == Visibility.Visible; + } + else + { + return false; + } + } + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } + } +} diff --git a/tabler.wpf/Helper/Converter/CompleteConverter.cs b/tabler.wpf/Helper/Converter/CompleteConverter.cs new file mode 100644 index 0000000..b9eb95f --- /dev/null +++ b/tabler.wpf/Helper/Converter/CompleteConverter.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + +namespace tabler.wpf.Helper.Converter +{ + public class CompleteConverter : IValueConverter + { + // This converter changes the value of a Tasks Complete status from true/false to a string value of + // "Complete"/"Active" for use in the row group header. + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + bool complete = (bool)value; + if (complete) + return "Translation Complete"; + else + return "Translation unfinished"; + } + + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + string strComplete = (string)value; + if (strComplete == "Complete") + return true; + else + return false; + } + } +} diff --git a/tabler.wpf/Helper/Converter/DateTimeDateConverter.cs b/tabler.wpf/Helper/Converter/DateTimeDateConverter.cs new file mode 100644 index 0000000..8c85d12 --- /dev/null +++ b/tabler.wpf/Helper/Converter/DateTimeDateConverter.cs @@ -0,0 +1,33 @@ +using System; +using System.Globalization; +using System.Windows.Data; +using System.Windows.Markup; + +namespace tabler.wpf.Controls.Converter +{ + public class DateTimeDateConverter : MarkupExtension, IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null) + { + return null; + } + return ((DateTime)value).Date.ToString("yyyyy-MM-dd"); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null) + { + return null; + } + return value; + } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } + } +} diff --git a/tabler.wpf/Helper/Converter/DateToStringConverter.cs b/tabler.wpf/Helper/Converter/DateToStringConverter.cs new file mode 100644 index 0000000..1ccb8a0 --- /dev/null +++ b/tabler.wpf/Helper/Converter/DateToStringConverter.cs @@ -0,0 +1,46 @@ +using System; +using System.Globalization; +using System.Windows.Data; +using System.Windows.Markup; +using tabler.wpf.Helper; + +namespace tabler.wpf.Controls.Converter +{ + public class DateToStringConverter : MarkupExtension, IValueConverter + + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is DateTime) + { + try + { + return ((DateTime)value).GetDateTimeString_yyyyMMddhhmmssms(); + } + catch (Exception) + { + return "error! DateToStringConverter value: " + value; + } + } + + return null; + } + + /// + /// Convert Visibility to boolean + /// + /// + /// + /// + /// + /// + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return null; + } + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } + } +} diff --git a/tabler.wpf/Helper/Converter/DoubleToStringConverterNoScientific.cs b/tabler.wpf/Helper/Converter/DoubleToStringConverterNoScientific.cs new file mode 100644 index 0000000..e3ce046 --- /dev/null +++ b/tabler.wpf/Helper/Converter/DoubleToStringConverterNoScientific.cs @@ -0,0 +1,54 @@ +using System; +using System.Globalization; +using System.Windows.Data; +using System.Windows.Markup; + +namespace tabler.wpf.Controls.Converter +{ + public class DoubleToStringConverterNoScientific : MarkupExtension, IValueConverter + + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null) + { + return string.Empty; + } + double valueDbl = 0; + + if (value is double) + { + valueDbl = (double)value; + } + if (value is int) + { + valueDbl = (int)value; + } + if (value is long) + { + valueDbl = (long)value; + } + + return valueDbl.ToString(".################"); + } + + /// + /// Convert Visibility to boolean + /// + /// + /// + /// + /// + /// + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + double change = 0; + double.TryParse((string)value, NumberStyles.Any, new NumberFormatInfo() { NumberDecimalSeparator = ",", PercentDecimalSeparator = ",", CurrencyDecimalSeparator = "," }, out change); + return change; + } + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } + } +} diff --git a/tabler.wpf/Helper/Converter/IsNullConverter.cs b/tabler.wpf/Helper/Converter/IsNullConverter.cs new file mode 100644 index 0000000..8de097b --- /dev/null +++ b/tabler.wpf/Helper/Converter/IsNullConverter.cs @@ -0,0 +1,37 @@ +using System; +using System.Globalization; +using System.Windows.Data; +using System.Windows.Markup; +namespace tabler.wpf.Controls.Converter +{ + public class LIsNullConverter : MarkupExtension, IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + + if (value == null) + { + return true; + } + + var isString = value is string; + + if (isString && string.IsNullOrEmpty(value.ToString())) + { + return true; + } + + return false; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return true; + } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } + } +} diff --git a/tabler.wpf/Helper/Converter/NegativeNumberToRedConverter.cs b/tabler.wpf/Helper/Converter/NegativeNumberToRedConverter.cs new file mode 100644 index 0000000..c23189b --- /dev/null +++ b/tabler.wpf/Helper/Converter/NegativeNumberToRedConverter.cs @@ -0,0 +1,72 @@ +using System; +using System.Drawing; +using System.Globalization; +using System.Windows; +using System.Windows.Data; +using System.Windows.Markup; +using System.Windows.Media; + +namespace tabler.wpf.Controls.Converter +{ + public class NegativeNumberToRedConverter : MarkupExtension, IValueConverter + + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null) + { + return string.Empty; + } + double valueDbl = 0; + + if (value is double) + { + valueDbl = (double)value; + + } + if (value is int) + { + valueDbl = (int)value; + } + if (value is long) + { + valueDbl = (long)value; + } + + if (valueDbl == 0 ) + { + return DependencyProperty.UnsetValue; + } + + if (valueDbl > 0 ) + { + return Brushes.MediumSeaGreen; + } + + if (valueDbl < 0) + { + return Brushes.Orange; + } + + return null; + + } + + /// + /// Convert Visibility to boolean + /// + /// + /// + /// + /// + /// + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return null; + } + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } + } +} diff --git a/tabler.wpf/Helper/Converter/StringToNumberConverter.cs b/tabler.wpf/Helper/Converter/StringToNumberConverter.cs new file mode 100644 index 0000000..2586ab9 --- /dev/null +++ b/tabler.wpf/Helper/Converter/StringToNumberConverter.cs @@ -0,0 +1,67 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; +using System.Windows.Markup; + +namespace tabler.wpf.Controls.Converter +{ + public class StringToNumberConverter : MarkupExtension, IValueConverter + + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null) + { + return string.Empty; + } + double valueDbl = 0; + + if (value is double) + { + valueDbl = (double)value; + } + if (value is int) + { + valueDbl = (int)value; + } + if (value is long) + { + valueDbl = (long)value; + } + + var s = value as string; + if (s != null) + { + if (double.TryParse(s, NumberStyles.Any, new NumberFormatInfo() {NumberDecimalSeparator = ",", PercentDecimalSeparator = ",", CurrencyDecimalSeparator = ","}, out valueDbl)) + {} + } + + if (valueDbl == 0) + { + return string.Empty; + return DependencyProperty.UnsetValue; + } + + return valueDbl; + + } + + /// + /// Convert Visibility to boolean + /// + /// + /// + /// + /// + /// + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return null; + } + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } + } +} diff --git a/tabler.wpf/Helper/Converter/ValueToBrushConverter.cs b/tabler.wpf/Helper/Converter/ValueToBrushConverter.cs new file mode 100644 index 0000000..6a8da2f --- /dev/null +++ b/tabler.wpf/Helper/Converter/ValueToBrushConverter.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Markup; +using System.Windows.Media; +using tabler.Logic.Helper; +using tabler.wpf.Container; + +namespace tabler.wpf.Helper.Converter +{ + public class ValueToBrushConverter : MarkupExtension, IValueConverter + + { + public static readonly IValueConverter Instance = new ValueToBrushConverter(); + private readonly static SolidColorBrush _textMissing = new SolidColorBrush(Colors.Orange); + private readonly static SolidColorBrush _textOk = new SolidColorBrush(Colors.LightGreen); + private readonly static SolidColorBrush _textChanged = new SolidColorBrush(Colors.LightYellow); + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + try + { + var cell = value as DataGridCell; + + var item = cell.DataContext as Key_ExtendedWithChangeTracking; + if (item != null ) + { + ChangeTrackerString valueString; + if (item.Languages.TryGetValue((string)cell.Column.Header, out valueString)) + { + if (string.IsNullOrEmpty(valueString.CurrentValue)) + { + return _textMissing; + } + if (valueString.HasChanged) + { + return _textChanged; + } + + return _textOk; + } + } + } + catch (Exception ex) + { + Logger.LogError($"{nameof(ValueToBrushConverter)}.{nameof(Convert)} Exception: {ex}"); + } + + return Visibility.Visible; + } + + /// + /// Convert Visibility to boolean + /// + /// + /// + /// + /// + /// + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return false; + } + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } + } +} diff --git a/tabler.wpf/Helper/Converter/VisibilityToBooleanConverter.cs b/tabler.wpf/Helper/Converter/VisibilityToBooleanConverter.cs new file mode 100644 index 0000000..6382a08 --- /dev/null +++ b/tabler.wpf/Helper/Converter/VisibilityToBooleanConverter.cs @@ -0,0 +1,37 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; +using System.Windows.Markup; + +namespace tabler.wpf.Controls.Converter +{ + public class VisibilityToBooleanConverter : MarkupExtension, IValueConverter + + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if ((Visibility)value == Visibility.Visible) + { + return true; + } + + return false; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + if ((bool)value) + { + return Visibility.Visible; + } + return Visibility.Collapsed; + + } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } + } +} diff --git a/tabler.wpf/Helper/ExtensionMethods.cs b/tabler.wpf/Helper/ExtensionMethods.cs new file mode 100644 index 0000000..2671662 --- /dev/null +++ b/tabler.wpf/Helper/ExtensionMethods.cs @@ -0,0 +1,624 @@ +using ICSharpCode.SharpZipLib.Core; +using ICSharpCode.SharpZipLib.Zip; +using Polenter.Serialization; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; + +namespace tabler.wpf.Helper +{ + public static class ExtensionMethods + { + #region Rounding numbers + + public static Double SafeRound(this Double value, int decimalPlaces) + { + return Math.Round(value, decimalPlaces); + } + + public static Double SafeRound(this Double value) + { + return Math.Round(value, 6); + } + + public static float SafeRound(this float value) + { + return (float)Math.Round(value, 6); + } + + public static float SafeRound(this float value, int decimalPlaces) + { + return (float)Math.Round(value, decimalPlaces); + } + + public static decimal SafeRound(this decimal value) + { + return Math.Round(value, 6); + } + + public static decimal SafeRound(this decimal value, int decimalPlaces) + { + return Math.Round(value, decimalPlaces); + } + + #endregion + public static String ToInvariantString(this Double value) + { + return value.ToString(CultureInfo.InvariantCulture); + } + + public static String ToInvariantString(this float value) + { + return value.ToString(CultureInfo.InvariantCulture); + } + + public static string GetDateTimeString_yyyyMMdd(this DateTime timestamp) + { + return timestamp.ToString("yyyy.MM.dd"); + } + + public static string GetDateTimeString_yyyyMMddHH(this DateTime timestamp) + { + return timestamp.ToString("yyyy.MM.dd HH"); + } + + public static string GetDateTimeString_yyyyMM(this DateTime timestamp) + { + return timestamp.ToString("yyyy.MM"); + } + + public static string GetDateTimeString_yyyyMMddhhmmssFtpReady(this DateTime timestamp) + { + return timestamp.ToString("yyyy_MM_dd_HH-mm-ss"); + } + + + public static string GetDateTimeString_ddMMyyyyhhmmss(this DateTime timestamp) + { + // 2016-05-19 15:16:17 + return timestamp.ToString("dd-MM-yyyy HH:mm:ss"); + } + + public static string GetDateTimeString_yyyyMMddhhmmssFileName(this DateTime timestamp) + { + return timestamp.ToString("yyyy.MM.dd_HH-mm-ss"); + } + + public static string GetDateTimeString_yyyyMMddhhmmssms(this DateTime timestamp) + { + return timestamp.ToString("yyyy.MM.dd HH:mm:ss:ffff"); + } + public static string GetDateTimeString_yyyyMMddhhmmss(this DateTime timestamp) + { + return timestamp.ToString("yyyy.MM.dd HH:mm:ss"); + } + + public static double ToDouble(this TextBox source, double defaultValue = 0) + { + double result = defaultValue; + + if (double.TryParse(source.Text, out result) == false) + { + result = defaultValue; + } + + return result; + } + + public static int ToInt(this TextBox source, int defaultValue = 0) + { + int result = defaultValue; + + if (int.TryParse(source.Text, out result) == false) + { + result = defaultValue; + } + + return result; + } + public static byte ToByte(this TextBox source, byte defaultValue = 0) + { + byte result = defaultValue; + + if (byte.TryParse(source.Text, out result) == false) + { + result = defaultValue; + } + + return result; + } + public static IEnumerable> Batch(this IEnumerable source, int batchSize) + { + using (var enumerator = source.GetEnumerator()) + while (enumerator.MoveNext()) + yield return YieldBatchElements(enumerator, batchSize - 1); + } + + private static IEnumerable YieldBatchElements( + IEnumerator source, int batchSize) + { + yield return source.Current; + for (int i = 0; i < batchSize && source.MoveNext(); i++) + yield return source.Current; + } + + + public static bool ExistsInString(this String value, + List searchValues, + List searchValuesNegative, + bool doOr, + bool doOrNegative, + ref List valuesThatMatched) + { + + var validRow = false; + + if (searchValues == null) + { + searchValues = new List(); + } + if (searchValuesNegative == null) + { + searchValuesNegative = new List(); + } + + //search positive + if (searchValues.Any() == false) + { + validRow = true; + } + else + { + if (doOr) + { + //OR + + foreach (string keyword in searchValues) + { + string temp = keyword.ToUpperInvariant(); + + if (value.Contains(temp)) + { + valuesThatMatched.Add(temp); + validRow = true; + //dont break here, beacuse maybe multiple filter are valid + //break; + } + } + + + + } + else + { + + //AND + foreach (string keyword in searchValues) + { + string temp = keyword.ToUpperInvariant(); + + validRow = true; + + if (value.Contains(temp) == false) + { + validRow = false; + break; + } + else + { + valuesThatMatched.Add(temp); + } + } + + + } + } + + + if (validRow == false) + { + return false; + } + + //SEARCH NEGATIVE + if (searchValuesNegative.Any() == false) + { + validRow = true; + } + else + { + if (doOrNegative) + { + //or neagtive + if (value.ContainsAny(searchValuesNegative)) + { + validRow = false; + } + } + else + { + //and negative + if (value.ContainsAll(searchValuesNegative)) + { + validRow = false; + } + } + + } + + return validRow; + } + + public static DateTime GetPreviousWorkDay(this DateTime date) + { + switch (date.DayOfWeek) + { + case DayOfWeek.Sunday: + return date.AddDays(-2); + case DayOfWeek.Monday: + return date.AddDays(-3); + default: + return date.AddDays(-1); + } + } + + + public static DateTime GetLastWeekday(this DateTime date, DayOfWeek weekDay) + { + DateTime lastDay = date.AddDays(-1); + while (lastDay.DayOfWeek != weekDay) + { + lastDay = lastDay.AddDays(-1); + } + return lastDay; + } + + public static DateTime GetNextWeekday(this DateTime date, DayOfWeek weekDay) + { + DateTime lastDay = date.AddDays(1); + while (lastDay.DayOfWeek != weekDay) + { + lastDay = lastDay.AddDays(1); + } + return lastDay; + } + + + + public static List GetSelectedBoundItems(this System.Windows.Controls.DataGrid dgv) + { + List result = null; + + dgv.Dispatcher.Invoke(() => + { + //check full rows + result = dgv.SelectedItems.OfType() + .Select(x => x.Item) + .OfType().Distinct().ToList(); + + + if (result.Any() == false) + { + //check in cells + result = dgv.SelectedCells.OfType() + .Select(x => x.Item) + .OfType().Distinct().ToList(); + } + }); + + return result; + } + + + public static string Compress(this string uncompressedString) + { + var compressedStream = new MemoryStream(); + var uncompressedStream = new MemoryStream(Encoding.UTF8.GetBytes(uncompressedString)); + + using (var compressorStream = new DeflateStream(compressedStream, CompressionMode.Compress, true)) + { + uncompressedStream.CopyTo(compressorStream); + } + + return Convert.ToBase64String(compressedStream.ToArray()); + } + + /// + /// Decompresses a deflate compressed, Base64 encoded string and returns an uncompressed string. + /// + /// String to decompress. + public static string Decompress(this string compressedString) + { + var decompressedStream = new MemoryStream(); + var compressedStream = new MemoryStream(Convert.FromBase64String(compressedString)); + + using (var decompressorStream = new DeflateStream(compressedStream, CompressionMode.Decompress)) + { + decompressorStream.CopyTo(decompressedStream); + } + + return Encoding.UTF8.GetString(decompressedStream.ToArray()); + } + + public static byte[] SerializeAndCompress(this object obj) + { + var ser = new SharpSerializer(new SharpSerializerBinarySettings() + { + IncludeAssemblyVersionInTypeName = false, + IncludePublicKeyTokenInTypeName = false, + Mode = BinarySerializationMode.SizeOptimized + }); + + using (MemoryStream ms = new MemoryStream()) + { + ser.Serialize(obj, ms); + return ms.ToArray(); + } + } + + + /// + /// zipLevel low:0 - high:9 ! + /// + /// + /// + /// + /// + public static MemoryStream ZipMemoryStream(this FileStream memStreamIn, string zipEntryName, int zipLevel = 3) + { + + MemoryStream outputMemStream = new MemoryStream(); + ZipOutputStream zipStream = new ZipOutputStream(outputMemStream); + + zipStream.SetLevel(zipLevel); //0-9, 9 being the highest level of compression + + ZipEntry newEntry = new ZipEntry(zipEntryName); + newEntry.DateTime = DateTime.Now; + + zipStream.PutNextEntry(newEntry); + + StreamUtils.Copy(memStreamIn, zipStream, new byte[4096]); + zipStream.CloseEntry(); + + zipStream.IsStreamOwner = false; // False stops the Close also Closing the underlying stream. + zipStream.Close(); // Must finish the ZipOutputStream before using outputMemStream. + + outputMemStream.Position = 0; + return outputMemStream; + + // Alternative outputs: + // ToArray is the cleaner and easiest to use correctly with the penalty of duplicating allocated memory. + //byte[] byteArrayOut = outputMemStream.ToArray(); + //return byteArrayOut; + //// GetBuffer returns a raw buffer raw and so you need to account for the true length yourself. + //byte[] byteArrayOut = outputMemStream.GetBuffer(); + //long len = outputMemStream.Length; + } + public static MemoryStream ZipMemoryStream(this List files, int zipLevel = 3) + { + + MemoryStream outputMemStream = new MemoryStream(); + ZipOutputStream zipStream = new ZipOutputStream(outputMemStream); + + zipStream.SetLevel(zipLevel); //0-9, 9 being the highest level of compression + + foreach (var fileInfo in files) + { + ZipEntry newEntry = new ZipEntry(fileInfo.Name); + newEntry.DateTime = fileInfo.LastWriteTime.ToUniversalTime(); + + zipStream.PutNextEntry(newEntry); + + StreamUtils.Copy(fileInfo.OpenRead(), zipStream, new byte[4096]); + zipStream.CloseEntry(); + + } + + zipStream.IsStreamOwner = false; // False stops the Close also Closing the underlying stream. + zipStream.Close(); // Must finish the ZipOutputStream before using outputMemStream. + + outputMemStream.Position = 0; + return outputMemStream; + + // Alternative outputs: + // ToArray is the cleaner and easiest to use correctly with the penalty of duplicating allocated memory. + //byte[] byteArrayOut = outputMemStream.ToArray(); + //return byteArrayOut; + //// GetBuffer returns a raw buffer raw and so you need to account for the true length yourself. + //byte[] byteArrayOut = outputMemStream.GetBuffer(); + //long len = outputMemStream.Length; + } + /// + /// zipLevel low:0 - high:9 ! + /// + /// + /// + /// + /// + public static byte[] ZipMemoryStream(this MemoryStream memStreamIn, string zipEntryName, int zipLevel) + { + + MemoryStream outputMemStream = new MemoryStream(); + ZipOutputStream zipStream = new ZipOutputStream(outputMemStream); + + zipStream.SetLevel(zipLevel); //0-9, 9 being the highest level of compression + + ZipEntry newEntry = new ZipEntry(zipEntryName); + newEntry.DateTime = DateTime.Now; + + zipStream.PutNextEntry(newEntry); + + StreamUtils.Copy(memStreamIn, zipStream, new byte[4096]); + zipStream.CloseEntry(); + + zipStream.IsStreamOwner = false; // False stops the Close also Closing the underlying stream. + zipStream.Close(); // Must finish the ZipOutputStream before using outputMemStream. + + outputMemStream.Position = 0; + //return outputMemStream; + + // Alternative outputs: + // ToArray is the cleaner and easiest to use correctly with the penalty of duplicating allocated memory. + byte[] byteArrayOut = outputMemStream.ToArray(); + return byteArrayOut; + //// GetBuffer returns a raw buffer raw and so you need to account for the true length yourself. + //byte[] byteArrayOut = outputMemStream.GetBuffer(); + //long len = outputMemStream.Length; + } + public static List UnzipFromStream(this Stream zipStream, string outFolder, IProgressBarControl progress = null) + { + ZipInputStream zipInputStream = new ZipInputStream(zipStream); + ZipEntry zipEntry = zipInputStream.GetNextEntry(); + + var lstFiles = new List(); + + while (zipEntry != null) + { + progress?.Increase(1); + progress?.SetOperationName($"Extracting file: {zipEntry.Name}"); + String entryFileName = zipEntry.Name; + // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName); + // Optionally match entrynames against a selection list here to skip as desired. + // The unpacked length is available in the zipEntry.Size property. + + byte[] buffer = new byte[4096]; // 4K is optimum + + // Manipulate the output filename here as desired. + String fullZipToPath = Path.Combine(outFolder, entryFileName); + string directoryName = Path.GetDirectoryName(fullZipToPath); + if (directoryName.Length > 0) + Directory.CreateDirectory(directoryName); + + // Skip directory entry + string fileName = Path.GetFileName(fullZipToPath); + if (fileName.Length == 0) + { + zipEntry = zipInputStream.GetNextEntry(); + continue; + } + + // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size + // of the file, but does not waste memory. + // The "using" will close the stream even if an exception occurs. + using (FileStream streamWriter = File.Create(fullZipToPath)) + { + StreamUtils.Copy(zipInputStream, streamWriter, buffer); + } + + var fi = new FileInfo(fullZipToPath); + if (fi.Exists) + { + File.SetLastWriteTimeUtc(fullZipToPath, zipEntry.DateTime); + lstFiles.Add(fi); + } + + zipEntry = zipInputStream.GetNextEntry(); + } + return lstFiles; + } + public static T DecompressAndDeserialize(this byte[] data) + { + var ser = new SharpSerializer(new SharpSerializerBinarySettings() + { + IncludeAssemblyVersionInTypeName = false, + IncludePublicKeyTokenInTypeName = false, + Mode = BinarySerializationMode.SizeOptimized + }); + + using (MemoryStream ms = new MemoryStream(data)) + { + return (T)ser.Deserialize(ms); + + } + + } + + + /// + /// Determines whether the specified value contains all. + /// + /// The value. + /// The LST values. + public static Boolean ContainsAll(this string value, List lstValues) + { + foreach (var lstValue in lstValues) + { + + if (value.Contains(lstValue) == false) + { + return false; + } + + } + + return true; + + } + + public static SortableBindingList ToSortableBindingList(this IEnumerable values) + { + + var newList = new SortableBindingList(); + newList.AddRange(values); + + return newList; + + } + + public static Boolean ContainsAny(this string value, List lstValues) + { + foreach (var lstValue in lstValues) + { + if (value.Contains(lstValue) == true) + { + return true; + } + } + return false; + } + + + public static void ShowInNewWindow(this Control control, bool isModal, Control parent, string title) + { + System.Windows.Window parentWindow = null; + if (parent != null) + { + parentWindow = System.Windows.Window.GetWindow(parent); + } + + control.ShowInNewWindow(isModal, parentWindow, title); + } + public static void ShowInNewWindow(this Control control, bool isModal, Window parent, string title) + { + var win = new Window(); + win.Title = title; + if (parent != null) + { + + win.Owner = parent; + } + + win.Content = control; + + if (isModal) + { + win.ShowDialog(); + } + else + { + win.Show(); + } + + + } + + } +} diff --git a/tabler.wpf/Helper/IProgressBarControl.cs b/tabler.wpf/Helper/IProgressBarControl.cs new file mode 100644 index 0000000..7f7ea99 --- /dev/null +++ b/tabler.wpf/Helper/IProgressBarControl.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace tabler.wpf.Helper +{ + public interface IProgressBarControl : IProgress + { + void Reset(); + void Increase(int value); + void Set(int value); + void Decrease(int value); + void SetMax(int max, bool doReset); + void SetOperationName(string name); + } +} diff --git a/tabler.wpf/Helper/ProgressLogger.cs b/tabler.wpf/Helper/ProgressLogger.cs new file mode 100644 index 0000000..3b85517 --- /dev/null +++ b/tabler.wpf/Helper/ProgressLogger.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using tabler.Logic.Helper; + +namespace tabler.wpf.Helper +{ + public class ProgressLogger + { + + public ProgressLogger(string name, int maxCount, DateTime? startDate = null, bool? logEstimatedTime = null) + { + if (maxCount > 0) + { + MaxItems = maxCount; + } + + Name = name; + + CurrentIndex = 0; + + if (startDate.GetValueOrDefault() != DateTime.MinValue) + { + StartDate = startDate.GetValueOrDefault(); + } + + if (logEstimatedTime.HasValue) + { + LogEstimatedTime = logEstimatedTime.Value; + } + } + + public ProgressLogger(string name, IList listItems, DateTime? startDate = null, bool? logEstimatedTime = null) : this(name, 0, startDate, logEstimatedTime) + { + + + if (listItems == null) return; + + MaxItems = listItems.Count; + + } + + public string Name { get; set; } + public int MaxItems { get; set; } + public int CurrentIndex { get; set; } + public double PercentageStartLogEstimatedTime { get; set; } = 1; + public DateTime StartDate { get; set; } = DateTime.UtcNow; + public bool LogEstimatedTime { get; set; } = true; + + public void IncAndLog(int? value = null) + { + IncIndex(value); + Log(); + } + + public void IncIndex(int? value = null) + { + CurrentIndex += value ?? 1; + } + + public void Log() + { + if (MaxItems <= 0 || CurrentIndex > MaxItems) + { + Logger.LogGeneral(Name + ": done"); + return; + } + + var percent = CurrentIndex / (double)MaxItems * 100; + + var message = $"{Name}: {CurrentIndex}/{MaxItems} ({percent.SafeRound(2)}%) "; + + if (LogEstimatedTime && percent > PercentageStartLogEstimatedTime) + { + var timeGoneSeconds = DateTime.UtcNow.Subtract(StartDate).TotalSeconds; + var secondsToGo = timeGoneSeconds * 100 / percent; + var timeUntil = StartDate.AddSeconds(secondsToGo); + var timeSpan = timeUntil.Subtract(DateTime.UtcNow); + + message += $" est.Time: {timeSpan.Days}d {timeSpan.Hours}h {timeSpan.Minutes}m {timeSpan.Seconds}s"; + } + Logger.LogGeneral(message); + } + + } +} diff --git a/tabler.wpf/Helper/ProgressLoggerControl.cs b/tabler.wpf/Helper/ProgressLoggerControl.cs new file mode 100644 index 0000000..644afc6 --- /dev/null +++ b/tabler.wpf/Helper/ProgressLoggerControl.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using tabler.wpf.Helper; + +namespace tabler.wpf.Helper +{ + + public class ProgressLoggerIProgressBarControl : ProgressLogger, IProgressBarControl + { + public ProgressLoggerIProgressBarControl(string name, int maxCount, DateTime? startDate = null, bool? logEstimatedTime = null) : base(name, maxCount, startDate, logEstimatedTime) + { + } + + public ProgressLoggerIProgressBarControl(string name, IList listItems, DateTime? startDate = null, bool? logEstimatedTime = null) : base(name, (IList)listItems, startDate, logEstimatedTime) + { + } + + #region Implementation of IProgress + + public void Report(double value) + { + Log(); + } + + #endregion + + #region Implementation of IProgressBarControl + + public void Reset() + { + CurrentIndex = 0; + } + + public void Increase(int value) + { + Increase(value); + Log(); + } + + public void Set(int value) + { + CurrentIndex = value; + Log(); + } + + public void Decrease(int value) + { + CurrentIndex -= value; + Log(); + } + + public void SetMax(int max, bool doReset) + { + MaxItems = max; + if (doReset) + { + Reset(); + } + } + + public void SetOperationName(string name) + { + if (string.IsNullOrEmpty(name)) + { + Name = name; + } + } + + #endregion + } +} diff --git a/tabler.wpf/Helper/ProgressLoggerForEach.cs b/tabler.wpf/Helper/ProgressLoggerForEach.cs new file mode 100644 index 0000000..aaa3c08 --- /dev/null +++ b/tabler.wpf/Helper/ProgressLoggerForEach.cs @@ -0,0 +1,160 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using tabler.Logic.Helper; + +namespace tabler.wpf.Helper +{ + public class ProgressLoggerForEach : ProgressLogger, IEnumerable, IEnumerator + { + public IList List { get; set; } + private IEnumerator _iEnumerator; + private Func _propertySelector; + + + public ProgressLoggerForEach(string name, IList listItems, DateTime? startDate = null, bool? logEstimatedTime = null, Func propertySelector = null) : base(name, (IList)listItems, startDate, logEstimatedTime) + { + + _propertySelector = propertySelector; + + if (listItems == null) return; + + + + MaxItems = listItems.Count; + List = listItems; + + _iEnumerator = listItems.GetEnumerator(); + + Name = name; + + CurrentIndex = 0; + + if (startDate.GetValueOrDefault() != DateTime.MinValue) + { + StartDate = startDate.GetValueOrDefault(); + } + + if (logEstimatedTime.HasValue) + { + LogEstimatedTime = logEstimatedTime.Value; + } + } + + public string Name { get; set; } + public int MaxItems { get; set; } + public int CurrentIndex { get; set; } + public double PercentageStartLogEstimatedTime { get; set; } = 1; + public DateTime StartDate { get; set; } = DateTime.UtcNow; + public bool LogEstimatedTime { get; set; } = true; + + public void IncAndLog(int? value = null) + { + IncIndex(value); + Log(); + } + + public void IncIndex(int? value = null) + { + CurrentIndex += value ?? 1; + } + + public void Log() + { + if (MaxItems <= 0 || CurrentIndex > MaxItems) + { + Logger.LogGeneral(Name + ": done"); + return; + } + + var percent = (((double)CurrentIndex / (double)MaxItems) * (double)100); + + var message = $"{Name}{GetCurrentObjectsName()}: {CurrentIndex}/{MaxItems} ({percent.SafeRound(2)}%) "; + + if (LogEstimatedTime && percent > PercentageStartLogEstimatedTime) + { + var timeGoneSeconds = DateTime.UtcNow.Subtract(StartDate).TotalSeconds; + var secondsToGo = (timeGoneSeconds * 100) / percent; + var timeUntil = StartDate.AddSeconds(secondsToGo); + var timeSpan = timeUntil.Subtract(DateTime.UtcNow); + + message += $" est.Time: {timeSpan.Days}d {timeSpan.Hours}h {timeSpan.Minutes}m {timeSpan.Seconds}s"; + } + Logger.LogGeneral(message); + } + + private string GetCurrentObjectsName() + { + if (_propertySelector == null || _iEnumerator.Current == null) + { + return null; + } + var ss = "." + new List { _iEnumerator.Current }.Select(_propertySelector).First(); + return ss; + } + + #region Implementation of IEnumerable + + IEnumerator IEnumerable.GetEnumerator() + { + return this; + } + + IEnumerator IEnumerable.GetEnumerator() + { + return this; + } + + #endregion + + #region Implementation of IDisposable + + public void Dispose() + { + _iEnumerator?.Dispose(); + _iEnumerator = null; + } + + #endregion + + #region Implementation of IEnumerator + + public bool MoveNext() + { + IncAndLog(); + + if (_iEnumerator != null) + { + return _iEnumerator.MoveNext(); + } + return false; + + } + + public void Reset() + { + _iEnumerator?.Reset(); + } + + object IEnumerator.Current + { + get { return Current; } + } + + public T Current + { + get + { + if (_iEnumerator == null) + { + return default(T); + } + return _iEnumerator.Current; + + } + } + + #endregion + } +} diff --git a/tabler.wpf/Helper/PropertyComparer.cs b/tabler.wpf/Helper/PropertyComparer.cs new file mode 100644 index 0000000..1a9450f --- /dev/null +++ b/tabler.wpf/Helper/PropertyComparer.cs @@ -0,0 +1,49 @@ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Reflection; + +namespace tabler.wpf.Helper +{ + public class PropertyComparer : IComparer + { + private readonly IComparer comparer; + private PropertyDescriptor propertyDescriptor; + private int reverse; + + public PropertyComparer(PropertyDescriptor property, ListSortDirection direction) + { + this.propertyDescriptor = property; + Type comparerForPropertyType = typeof(Comparer<>).MakeGenericType(property.PropertyType); + this.comparer = (IComparer)comparerForPropertyType.InvokeMember("Default", BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.Public, null, null, null); + this.SetListSortDirection(direction); + } + + #region IComparer Members + + public int Compare(T x, T y) + { + return this.reverse * this.comparer.Compare(this.propertyDescriptor.GetValue(x), this.propertyDescriptor.GetValue(y)); + } + + #endregion + + private void SetPropertyDescriptor(PropertyDescriptor descriptor) + { + this.propertyDescriptor = descriptor; + } + + private void SetListSortDirection(ListSortDirection direction) + { + this.reverse = direction == ListSortDirection.Ascending ? 1 : -1; + } + + public void SetPropertyAndDirection(PropertyDescriptor descriptor, ListSortDirection direction) + { + this.SetPropertyDescriptor(descriptor); + this.SetListSortDirection(direction); + } + } +} diff --git a/tabler.wpf/Helper/SearchLogFilesHelper.cs b/tabler.wpf/Helper/SearchLogFilesHelper.cs new file mode 100644 index 0000000..6fb380c --- /dev/null +++ b/tabler.wpf/Helper/SearchLogFilesHelper.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.ServiceModel; +using ayondo.Base.ExtensionMethods; +using AyondoWinFormHelper.BusinessLogic; +using AyondoWinFormHelper.Enums; +using AyondoWinFormHelper.LogFileApi; +using AyondoWinFormHelper.Wcf; + +namespace AyondoWinFormHelper.Helper +{ + public static class SearchLogFilesHelper + { + //private const string ServerUrlAdd = ".rz.ayondo.com"; + + public static List GetMessagesFromServiceWithRetries(string serverDns, LogFileType logFileType, DateTime from, DateTime to, List messagesToSearch, List messagesToIgnore) + { + if (messagesToSearch == null || messagesToSearch.Any() == false) + { + return new List() { new RowContainer() { Date = DateTime.MinValue, Value = "connection error", FileName = "error.xml", ValueUpperCase = "CONNECTION ERROR" } }; + + } + var include = messagesToSearch != null ? string.Join(",", messagesToSearch) : ""; + var exclude = messagesToIgnore != null ? string.Join(",", messagesToIgnore) : ""; + + var bRetry = true; + int tries = 1; + while (bRetry) + { + try + { + + OperationManager.LogGeneral($"Calling logs try:{tries} {serverDns} {logFileType} " + + $"{from.GetDateTimeString_yyyyMMddhhmmss()} - {to.GetDateTimeString_yyyyMMddhhmmss()} " + + $"params to include:{include} " + + $"params exclude: {exclude } "); + + if (AyondoServiceClients.WcfServiceAst(serverDns).LogfileAndSearch != null) + { + var result = AyondoServiceClients.WcfServiceAst(serverDns) + .LogfileAndSearch.Interface.Search(logFileType, + from, + to, + messagesToSearch, + messagesToIgnore, true, true, false, 1000, false); + + OperationManager.LogGeneral($"Results: {result.Count}"); + + + return result; + } + else + { + OperationManager.LogError($"{nameof(SearchLogFilesHelper)}.{nameof(GetMessagesFromServiceWithRetries)} LogfileAndSearch is null"); + } + } + catch (TimeoutException tex) + { + tries++; + if (tries > 6) + { + bRetry = false; + OperationManager.LogError($"{nameof(SearchLogFilesHelper)}.{nameof(GetMessagesFromServiceWithRetries)} Exception: {tex}"); + } + } + catch (CommunicationException cex) + { + tries++; + if (tries > 6) + { + bRetry = false; + OperationManager.LogError($"{nameof(SearchLogFilesHelper)}.{nameof(GetMessagesFromServiceWithRetries)} Exception: {cex}"); + } + } + catch (Exception ex) + { + bRetry = false; + OperationManager.LogError($"{nameof(SearchLogFilesHelper)}.{nameof(GetMessagesFromServiceWithRetries)} {serverDns} - {logFileType} - {from.GetDateTimeString_yyyyMMddhhmmss()} - {to.GetDateTimeString_yyyyMMddhhmmss()} Exception: {ex}"); + } + } + + return new List() { new RowContainer() { Date = DateTime.MinValue, Value = "connection error", FileName = "error.xml", ValueUpperCase = "CONNECTION ERROR" } }; + + } + } +} diff --git a/tabler.wpf/Helper/SortableBindingList.cs b/tabler.wpf/Helper/SortableBindingList.cs new file mode 100644 index 0000000..78f5c3f --- /dev/null +++ b/tabler.wpf/Helper/SortableBindingList.cs @@ -0,0 +1,110 @@ + +using System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace tabler.wpf.Helper +{ + public class SortableBindingList : BindingList + { + private readonly Dictionary> comparers; + private bool isSorted; + private ListSortDirection listSortDirection; + private PropertyDescriptor propertyDescriptor; + + + public void AddRange(IEnumerable lst) + { + + foreach (var currentItem in lst) + { + this.Items.Add(currentItem); + } + + } + + + public SortableBindingList() + : base(new List()) + { + this.comparers = new Dictionary>(); + } + + public SortableBindingList(IEnumerable enumeration) + : base(new List(enumeration)) + { + this.comparers = new Dictionary>(); + } + + protected override bool SupportsSortingCore + { + get { return true; } + } + + protected override bool IsSortedCore + { + get { return this.isSorted; } + } + + protected override PropertyDescriptor SortPropertyCore + { + get { return this.propertyDescriptor; } + } + + protected override ListSortDirection SortDirectionCore + { + get { return this.listSortDirection; } + } + + protected override bool SupportsSearchingCore + { + get { return true; } + } + + protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction) + { + List itemsList = (List)this.Items; + + Type propertyType = property.PropertyType; + PropertyComparer comparer; + if (!this.comparers.TryGetValue(propertyType, out comparer)) + { + comparer = new PropertyComparer(property, direction); + this.comparers.Add(propertyType, comparer); + } + + comparer.SetPropertyAndDirection(property, direction); + itemsList.Sort(comparer); + + this.propertyDescriptor = property; + this.listSortDirection = direction; + this.isSorted = true; + + this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); + } + + protected override void RemoveSortCore() + { + this.isSorted = false; + this.propertyDescriptor = base.SortPropertyCore; + this.listSortDirection = base.SortDirectionCore; + + this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); + } + + protected override int FindCore(PropertyDescriptor property, object key) + { + int count = this.Count; + for (int i = 0; i < count; ++i) + { + T element = this[i]; + if (property.GetValue(element).Equals(key)) + { + return i; + } + } + + return -1; + } + } +} diff --git a/tabler.wpf/Helper/StopWatch.cs b/tabler.wpf/Helper/StopWatch.cs new file mode 100644 index 0000000..0452d30 --- /dev/null +++ b/tabler.wpf/Helper/StopWatch.cs @@ -0,0 +1,100 @@ + +using System; +using tabler.Logic.Enums; +using tabler.Logic.Helper; + +namespace tabler.wpf.Helper +{ + /// + /// Class StopWatch. + /// + public class StopWatch + { + private DateTime _start; + //private string OperationName = "undefined"; + private LogTypeEnum _logType = LogTypeEnum.General; + private string _operationName = "undefined"; + + public string OperationName + { + get { return _operationName; } + set + { + _operationName = value; + + } + } + + /// + /// Initializes a new instance of the class. + /// + /// Description of the operation. + public StopWatch(string operationName) + { + OperationName = operationName; + Start(); + } + + public bool LogStart { get; set; } + public StopWatch(string operationName, bool logStart) : this(operationName) + { + LogStart = logStart; + } + + /// + /// Starts this instance. + /// + public void Start() + { + _start = DateTime.Now; + if (LogStart) + { + Logger.LogInternal($"Started operation: {OperationName}"); + _lastExecutionTimeInSeconds = null; + } + } + + private double? _lastExecutionTimeInSeconds ; + public double LastExecutionTimeInSeconds + { + get + { + if (_lastExecutionTimeInSeconds.HasValue) + { + return _lastExecutionTimeInSeconds.Value; + } + + return DateTime.Now.Subtract(_start).TotalSeconds; + + } + } + + /// + /// Stops this instance. + /// + public void StopAndLog() + { + StopAndLog(null); + } + public void StopAndLog(bool resetTimer) + { + StopAndLog(null,resetTimer); + } + public void StopAndLog(string name,bool resetTimer = true) + { + var tolog = OperationName; + if (!string.IsNullOrEmpty(name)) + { + tolog = name; + } + _lastExecutionTimeInSeconds = LastExecutionTimeInSeconds; + + Logger.Log($"Finished operation: {tolog} in seconds: {LastExecutionTimeInSeconds}", _logType); + if (resetTimer) + { + _start = DateTime.Now; + } + + } + } +} diff --git a/tabler.wpf/Helper/TranslationHelper.cs b/tabler.wpf/Helper/TranslationHelper.cs new file mode 100644 index 0000000..b73ce6f --- /dev/null +++ b/tabler.wpf/Helper/TranslationHelper.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Threading; + +namespace tabler.wpf.Helper +{ + public static class TranslationHelperRessources + { + + public static string GetString(string key, CultureInfo info ) + { + var profs = Properties.Resources.ResourceManager.GetString("HelloWorld", info); + return profs; + } + public static string GetString(string key) + { + var profs = Properties.Resources.ResourceManager.GetString("HelloWorld", System.Threading.Thread.CurrentThread.CurrentCulture); + return profs; + } + + } +} diff --git a/tabler.wpf/Images/Icon-16.png b/tabler.wpf/Images/Icon-16.png new file mode 100644 index 0000000..f2b1fe8 Binary files /dev/null and b/tabler.wpf/Images/Icon-16.png differ diff --git a/tabler.wpf/Images/Icon-16.psd b/tabler.wpf/Images/Icon-16.psd new file mode 100644 index 0000000..a53f6e4 Binary files /dev/null and b/tabler.wpf/Images/Icon-16.psd differ diff --git a/tabler.wpf/Images/Icon-256.png b/tabler.wpf/Images/Icon-256.png new file mode 100644 index 0000000..3ed1169 Binary files /dev/null and b/tabler.wpf/Images/Icon-256.png differ diff --git a/tabler.wpf/Images/Icon-256.psd b/tabler.wpf/Images/Icon-256.psd new file mode 100644 index 0000000..82f47ae Binary files /dev/null and b/tabler.wpf/Images/Icon-256.psd differ diff --git a/tabler.wpf/Images/Icon-32.png b/tabler.wpf/Images/Icon-32.png new file mode 100644 index 0000000..5422182 Binary files /dev/null and b/tabler.wpf/Images/Icon-32.png differ diff --git a/tabler.wpf/Images/Icon-32.psd b/tabler.wpf/Images/Icon-32.psd new file mode 100644 index 0000000..3a77822 Binary files /dev/null and b/tabler.wpf/Images/Icon-32.psd differ diff --git a/tabler.wpf/Images/Icon-48.png b/tabler.wpf/Images/Icon-48.png new file mode 100644 index 0000000..b1deff7 Binary files /dev/null and b/tabler.wpf/Images/Icon-48.png differ diff --git a/tabler.wpf/Images/Icon-48.psd b/tabler.wpf/Images/Icon-48.psd new file mode 100644 index 0000000..6f657da Binary files /dev/null and b/tabler.wpf/Images/Icon-48.psd differ diff --git a/tabler.wpf/Properties/AssemblyInfo.cs b/tabler.wpf/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..5e6ee70 --- /dev/null +++ b/tabler.wpf/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("tabler.wpf")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("tabler.wpf")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("0.0.0.1")] +[assembly: AssemblyFileVersion("0.0.0.1")] diff --git a/tabler.wpf/Properties/Resources.Designer.cs b/tabler.wpf/Properties/Resources.Designer.cs new file mode 100644 index 0000000..062d28e --- /dev/null +++ b/tabler.wpf/Properties/Resources.Designer.cs @@ -0,0 +1,244 @@ +//------------------------------------------------------------------------------ +// +// 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. +// +//------------------------------------------------------------------------------ + +namespace tabler.wpf.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public 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() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("tabler.wpf.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Current version is up to date. + /// + public static string GridUI_CheckForNewVersion_Current_version_is_up_to_date { + get { + return ResourceManager.GetString("GridUI_CheckForNewVersion_Current_version_is_up_to_date", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Download the new version at. + /// + public static string GridUI_CheckForNewVersion_Download_the_new_version_at { + get { + return ResourceManager.GetString("GridUI_CheckForNewVersion_Download_the_new_version_at", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New version available. + /// + public static string GridUI_CheckForNewVersion_New_version_available { + get { + return ResourceManager.GetString("GridUI_CheckForNewVersion_New_version_available", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Discard all changes?. + /// + public static string GridUI_Discard_all_changes { + get { + return ResourceManager.GetString("GridUI_Discard_all_changes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Duplicate Key(s) found. + ///Name: '{0}' + ///File: '{1}' + ///Entry: '{2}'. + /// + public static string GridUI_Duplicate_key_found { + get { + return ResourceManager.GetString("GridUI_Duplicate_key_found", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Duplicate Key Error. + /// + public static string GridUI_Duplicate_key_found_title { + get { + return ResourceManager.GetString("GridUI_Duplicate_key_found_title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Exit?. + /// + public static string GridUI_Exit { + get { + return ResourceManager.GetString("GridUI_Exit", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Generic XML Exception. + ///Name: '{0}' + ///File: '{1}' + ///Entry: '{2}'. + /// + public static string GridUI_Generic_xml_exception { + get { + return ResourceManager.GetString("GridUI_Generic_xml_exception", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to XML Exception. + /// + public static string GridUI_Generic_xml_exception_title { + get { + return ResourceManager.GetString("GridUI_Generic_xml_exception_title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Malformed Stringtable Encountered. + ///File: '{0}' + ///Message: '{1}' + /// + ///More information: https://community.bistudio.com/wiki/Stringtable.xml. + /// + public static string GridUI_Malformed_Stringtable_exception { + get { + return ResourceManager.GetString("GridUI_Malformed_Stringtable_exception", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Malformed Stringtable. + /// + public static string GridUI_Malformed_Stringtable_exception_title { + get { + return ResourceManager.GetString("GridUI_Malformed_Stringtable_exception_title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No 'stringtable.xml' files found.. + /// + public static string GridUI_No_stringtable_xml_files_found { + get { + return ResourceManager.GetString("GridUI_No_stringtable_xml_files_found", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open?. + /// + public static string GridUI_Open { + get { + return ResourceManager.GetString("GridUI_Open", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Successfully saved.. + /// + public static string GridUI_saveToolStripMenuItem_Click_Successfully_saved { + get { + return ResourceManager.GetString("GridUI_saveToolStripMenuItem_Click_Successfully_saved", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to default hello world. + /// + public static string HelloWorld { + get { + return ResourceManager.GetString("HelloWorld", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open language file(s). + /// + public static string MainUI_OpenFile { + get { + return ResourceManager.GetString("MainUI_OpenFile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save language file(s). + /// + public static string MainUI_SaveFile { + get { + return ResourceManager.GetString("MainUI_SaveFile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Languages. + /// + public static string TranslationProgress_AxisX_Title { + get { + return ResourceManager.GetString("TranslationProgress_AxisX_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Number of Missing Translations. + /// + public static string TranslationProgress_AxisY_Title { + get { + return ResourceManager.GetString("TranslationProgress_AxisY_Title", resourceCulture); + } + } + } +} diff --git a/tabler.wpf/Properties/Resources.de-DE.resx b/tabler.wpf/Properties/Resources.de-DE.resx new file mode 100644 index 0000000..39fe1c0 --- /dev/null +++ b/tabler.wpf/Properties/Resources.de-DE.resx @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Aktuelle Version ist auf dem neusten Stand + + + Neuere Version hier herunterladen + + + Neuere Version verfügbar + + + Änderungen verwerfen? + + + Doppelte(n) Key(s) gefunden. +Name: '{0}' +Datei: '{1}' +Eintrag: '{2}' + + + Doppelten Key gefunden + + + Beenden? + + + Allgemeiner XML-Fehler. +Name: '{0}' +Datei: '{1}' +Eintrag: '{2}' + + + XML-Fehler + + + Fehlerhaftes Format einer Stringtable-Datei gefunden. +Datei: '{0}' +Nachricht: '{1}' + +Mehr Informationen unter: https://community.bistudio.com/wiki/Stringtable.xml + + + Fehlerhaftes Stringtable Format + + + Keine 'stringtable.xml'-Dateien gefunden. + + + Öffnen? + + + Erfolgreich gespeichert + + + de helloworld + + + Datei(en) öffnen + + + Datei(en) speichern + + + Sprachen + + + Anzahl fehlender Übersetzungen + + \ No newline at end of file diff --git a/tabler.wpf/Properties/Resources.resx b/tabler.wpf/Properties/Resources.resx new file mode 100644 index 0000000..5d7ca20 --- /dev/null +++ b/tabler.wpf/Properties/Resources.resx @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Discard all changes? + + + Duplicate Key(s) found. +Name: '{0}' +File: '{1}' +Entry: '{2}' + + + Duplicate Key Error + + + Exit? + That's a question + + + Generic XML Exception. +Name: '{0}' +File: '{1}' +Entry: '{2}' + + + XML Exception + + + No 'stringtable.xml' files found. + + + New version available + + + Current version is up to date + + + Download the new version at + + + Successfully saved. + + + Languages + + + Number of Missing Translations + + + Malformed Stringtable Encountered. +File: '{0}' +Message: '{1}' + +More information: https://community.bistudio.com/wiki/Stringtable.xml + + + Malformed Stringtable + + + Open? + + + default hello world + + + Open language file(s) + + + Save language file(s) + + \ No newline at end of file diff --git a/tabler.wpf/Properties/Resources.ru-RU.resx b/tabler.wpf/Properties/Resources.ru-RU.resx new file mode 100644 index 0000000..d0c8522 --- /dev/null +++ b/tabler.wpf/Properties/Resources.ru-RU.resx @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Отменить все изменения? + + + Найден дублирующийся ключ. +Имя: '{0}' +Файл: '{1}' +Запись: '{2}' + + + Ошибка дублирующихся ключей + + + Выйти? + + + Общее XML-исключение. +Имя: '{0}' +Файл: '{1}' +Запись: '{2}' + + + XML-исключение + + + 'stringtable.xml' файлы не найдены. + + \ No newline at end of file diff --git a/tabler.wpf/Properties/Settings.Designer.cs b/tabler.wpf/Properties/Settings.Designer.cs new file mode 100644 index 0000000..6c9d016 --- /dev/null +++ b/tabler.wpf/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// 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. +// +//------------------------------------------------------------------------------ + +namespace tabler.wpf.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.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/tabler.wpf/Properties/Settings.settings b/tabler.wpf/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/tabler.wpf/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/tabler.wpf/Windows/App.xaml b/tabler.wpf/Windows/App.xaml new file mode 100644 index 0000000..7213210 --- /dev/null +++ b/tabler.wpf/Windows/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/tabler.wpf/Windows/App.xaml.cs b/tabler.wpf/Windows/App.xaml.cs new file mode 100644 index 0000000..4b81ba7 --- /dev/null +++ b/tabler.wpf/Windows/App.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace tabler.wpf +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } +} diff --git a/tabler.wpf/Windows/MainWindow.xaml b/tabler.wpf/Windows/MainWindow.xaml new file mode 100644 index 0000000..d26af31 --- /dev/null +++ b/tabler.wpf/Windows/MainWindow.xaml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tabler.wpf/Windows/MainWindow.xaml.cs b/tabler.wpf/Windows/MainWindow.xaml.cs new file mode 100644 index 0000000..b9be6be --- /dev/null +++ b/tabler.wpf/Windows/MainWindow.xaml.cs @@ -0,0 +1,158 @@ +using Microsoft.WindowsAPICodePack.Dialogs; +using System; +using System.Globalization; +using System.IO; +using System.Reflection; +using System.Windows; +using System.Windows.Markup; +using tabler.Logic.Classes; +using tabler.Logic.Helper; +using Control = System.Windows.Controls.Control; + +namespace tabler.wpf +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { + public readonly TranslationHelper TranslationHelper; + private ReleaseVersion _newerRelease; + + public MainWindow() + { + //The Internationalization Fix + FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag))); + + var culture = CultureInfo.GetCultureInfo(ConfigHelper.CurrentSettings.Language); + Dispatcher.Thread.CurrentCulture = culture; + Dispatcher.Thread.CurrentUICulture = culture; + + InitializeComponent(); + + Logger.LogMessageWithTypeArrived += ctrl_HelperLogMessages.AddMessage; + + TranslationHelper = new TranslationHelper(); + } + + private void btn_openLanguageFile(object sender, RoutedEventArgs e) + { + try + { + var dlg = new CommonOpenFileDialog(); + dlg.Title = "Select mod/mission folder, all stringtable.xml files in subfolders will be opened."; + dlg.IsFolderPicker = true; + dlg.AddToMostRecentlyUsedList = false; + dlg.AllowNonFileSystemItems = false; + dlg.DefaultDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyComputer); + dlg.EnsureFileExists = false; + dlg.EnsurePathExists = false; + dlg.EnsureReadOnly = false; + dlg.EnsureValidNames = false; + dlg.Multiselect = false; + dlg.ShowPlacesList = false; + + if (!string.IsNullOrEmpty(ConfigHelper.CurrentSettings.LastPathOfDataFiles)) + { + dlg.InitialDirectory = ConfigHelper.CurrentSettings.LastPathOfDataFiles; + } + + var result = dlg.ShowDialog(); + + if (result == CommonFileDialogResult.Ok) + { + ctrl_languageOverview.LoadDirectory(new DirectoryInfo(dlg.FileName));//);new System.IO.DirectoryInfo(@"I:\arbeit\GitHub\Mamilacan\tabler\tabler\tabler.wpf\ExampleData")); + if (ConfigHelper.CurrentSettings.LastPathOfDataFiles != dlg.FileName) + { + ConfigHelper.CurrentSettings.LastPathOfDataFiles = dlg.FileName; + ConfigHelper.SaveSettings(); + } + } + + } + catch (Exception ex) + { + Logger.LogEx(ex); + } + } + + private void btn_SaveLanguageFile(object sender, RoutedEventArgs e) + { + + + + + } + + private void btn_checkForNewVersion(object sender, RoutedEventArgs e) + { + CheckForNewVersion(); + } + + private void CheckForNewVersion() + { + try + { + var gh = new GitHubVersionHelper(); + var productVersion = Assembly.GetExecutingAssembly().GetName().Version; + + _newerRelease = gh.CheckForNewVersion(productVersion.ToString()); + + if (_newerRelease != null) + { + mi_getNewVersion.Visibility = Visibility.Visible; + Logger.LogGeneral($"{Resources["GridUI_CheckForNewVersion_New_version_available"]} -> {_newerRelease.Version}"); + Logger.LogGeneral($"{Resources["GridUI_CheckForNewVersion_Download_the_new_version_at"]}: {_newerRelease.HtmlUrl}"); + } + else + { + mi_getNewVersion.Visibility = Visibility.Collapsed; + Logger.LogGeneral($"{Resources["GridUI_CheckForNewVersion_Current_version_is_up_to_date"]} {productVersion}"); + } + } + catch (Exception ex) + { + Logger.LogError("Error: " + ex.Message); + } + } + + //private void comboBoxLanguage_SelectionChanged(object sender, SelectionChangedEventArgs e) + //{ + // try + // { + // var selectedItem = comboBoxLanguage.SelectedItem as ComboBoxItem; + + // var culture = CultureInfo.GetCultureInfo(selectedItem.Tag as string); + // // Properties.Resources.ResourceManager.GetString("HelloWorld", culture); + // Dispatcher.Thread.CurrentCulture = culture; + // Dispatcher.Thread.CurrentUICulture = culture; + // } + // catch (Exception ex) + // { + + // Logger.LogError(ex.ToString()); + // } + + //} + + private void Window_Loaded(object sender, RoutedEventArgs e) + { + + + } + + private void languageSelected(object sender, RoutedEventArgs e) + { + var selectedItem = sender as Control; + ConfigHelper.CurrentSettings.Language = selectedItem.Tag as string; + ConfigHelper.SaveSettings(); + Logger.LogGeneral($"Language changed to: {ConfigHelper.CurrentSettings.Language}. Restart required."); + + } + + private void btn_exit_click(object sender, RoutedEventArgs e) + { + this.Close(); + } + } +} diff --git a/tabler.wpf/WpfBinding.pdf b/tabler.wpf/WpfBinding.pdf new file mode 100644 index 0000000..c61bfc2 Binary files /dev/null and b/tabler.wpf/WpfBinding.pdf differ diff --git a/tabler.wpf/packages.config b/tabler.wpf/packages.config new file mode 100644 index 0000000..849a0a1 --- /dev/null +++ b/tabler.wpf/packages.config @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/tabler.wpf/tabler.wpf.csproj b/tabler.wpf/tabler.wpf.csproj new file mode 100644 index 0000000..12dd9fa --- /dev/null +++ b/tabler.wpf/tabler.wpf.csproj @@ -0,0 +1,239 @@ + + + + + Debug + AnyCPU + {A6677EF8-6AB9-4976-A218-89470EE4B9C9} + WinExe + tabler.wpf + tabler.wpf + v4.7.2 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + tabler.wpf.App + + + + ..\packages\SharpZipLib.1.2.0\lib\net45\ICSharpCode.SharpZipLib.dll + + + ..\packages\Microsoft-WindowsAPICodePack-Core.1.1.3.3\lib\net452\Microsoft.WindowsAPICodePack.dll + + + ..\packages\Microsoft-WindowsAPICodePack-Shell.1.1.3.3\lib\net452\Microsoft.WindowsAPICodePack.Shell.dll + + + ..\packages\SharpSerializer.3.0.1\lib\net452\Polenter.SharpSerializer.dll + + + + + + + + + + + + + + 4.0 + + + + + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + + + Helper_LabelTextBox.xaml + + + Helper_LogMessages.xaml + + + Helper_ProgressBar.xaml + + + + + ItemSelectControl.xaml + + + DirectoryFilesOverviewControl.xaml + + + ListViewWrapperClass.xaml + + + LogMessages_Window.xaml + + + TranslationFileSingleControl.xaml + + + + + + + + + + + App.xaml + Code + + + + + + + + + + + + + + General_VersionInfo.xaml + + + + + + + MainWindow.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + + PublicResXFileCodeGenerator + Resources.Designer.cs + Designer + + + + + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + + + + + + + + + + {651801fa-f7ae-4f9b-9a7c-2ddea5965440} + tabler.Logic + + + + + + + + + + + \ No newline at end of file diff --git a/tabler.wpf/xaml_codehelper.xml b/tabler.wpf/xaml_codehelper.xml new file mode 100644 index 0000000..dd633a0 --- /dev/null +++ b/tabler.wpf/xaml_codehelper.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/tabler/Classes/Logger.cs b/tabler/Classes/Logger.cs deleted file mode 100644 index d9c35cc..0000000 --- a/tabler/Classes/Logger.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Text; -using System.Timers; -using System.Windows.Forms; -using Timer = System.Timers.Timer; - -namespace tabler.Classes -{ - public static class Logger - { - private static readonly StringBuilder StringBuilderForLogging = new StringBuilder(); - public static TextBox TextBoxToLogIn; - - private static Timer _timer; - - public static void ClearLog() - { - StringBuilderForLogging.Clear(); - } - - public static void Log(string message) - { - if (TextBoxToLogIn == null) - { - return; - } - - if (_timer == null) - { - _timer = new Timer {Interval = 500}; - _timer.Elapsed += timer_Elapsed; - } - - StringBuilderForLogging.Insert(0, DateTime.Now.ToString("yyyy.MM.dd hh:mm:ss") + " - " + message + Environment.NewLine); - _timer.Start(); - } - - private static void timer_Elapsed(object sender, ElapsedEventArgs e) - { - _timer.Stop(); - - if (TextBoxToLogIn == null) - { - _timer.Start(); - } - - TextBoxToLogIn.UiThread(delegate { TextBoxToLogIn.Text = StringBuilderForLogging.ToString(); }); - - - _timer.Start(); - } - } -} diff --git a/tabler/Forms/GridUI.cs b/tabler/Forms/GridUI.cs index 5088902..e4cccca 100644 --- a/tabler/Forms/GridUI.cs +++ b/tabler/Forms/GridUI.cs @@ -17,7 +17,7 @@ namespace tabler { public partial class GridUI : Form { - private readonly ConfigHelper _configHelper; + public readonly TranslationHelper TranslationHelper; private GridUiHelper _gridUiHelper; private ReleaseVersion _newerRelease; @@ -27,9 +27,9 @@ public partial class GridUI : Form public GridUI() { InitializeComponent(); - _configHelper = new ConfigHelper(); + TranslationHelper = new TranslationHelper(); - Logger.TextBoxToLogIn = _tbLog; + } @@ -86,7 +86,7 @@ private void saveToolStripMenuItem_Click(object sender, EventArgs e) // start the process WaitingForm.ShowForm(this); - success = TranslationHelper.SaveGridData(_configHelper.GetLastPathOfDataFiles(), stringtables); + success = TranslationHelper.SaveGridData(new DirectoryInfo(ConfigHelper.CurrentSettings.LastPathOfDataFiles), stringtables); WaitingForm.CloseForm(); } @@ -230,21 +230,14 @@ private void hideTranslatedRowsToolStripMenuItem_Click(object sender, EventArgs private void OpenOpenModFolderDialog() { var curPath = ""; - - var lastPath = _configHelper.GetLastPathOfDataFiles(); - - if (lastPath != null) - { - curPath = lastPath.FullName; - } - + curPath = ConfigHelper.CurrentSettings.LastPathOfDataFiles; + var folderDialog = new CommonOpenFileDialog {IsFolderPicker = true}; if (string.IsNullOrEmpty(curPath) == false) { folderDialog.DefaultDirectory = curPath; } - if (folderDialog.ShowDialog() == CommonFileDialogResult.Ok) { tbModFolder.Text = folderDialog.FileName; @@ -284,8 +277,7 @@ private void StartParsingProcess(string folderName) removeLanguageToolStripMenuItem.Enabled = true; statisticsToolStripMenuItem.Enabled = true; - _configHelper.SetLastPathOfDataFiles(new DirectoryInfo(folderName)); - + ConfigHelper.CurrentSettings.LastPathOfDataFiles = folderName; _stringtablesLoaded = true; } catch (AggregateException ae) diff --git a/tabler/Forms/SettingsForm.cs b/tabler/Forms/SettingsForm.cs index e825b7f..f0278a7 100644 --- a/tabler/Forms/SettingsForm.cs +++ b/tabler/Forms/SettingsForm.cs @@ -27,19 +27,13 @@ protected override bool ProcessCmdKey(ref Message msg, Keys keyData) private void Settings_Load(object sender, EventArgs e) { - var configHelper = new ConfigHelper(); - - var settings = configHelper.GetSettings(); - - if (settings != null) - { - if (settings.IndentationSettings == IndentationSettings.Tabs) + if (ConfigHelper.CurrentSettings.IndentationSettings == IndentationSettings.Tabs) { rbIndentTabs.Checked = true; } - tbIndentation.Text = settings.TabSize.ToString(); - } + tbIndentation.Text = ConfigHelper.CurrentSettings.TabSize.ToString(); + } @@ -56,22 +50,19 @@ private void rbIndentTabs_CheckedChanged(object sender, EventArgs e) private void btnSaveSettings_Click(object sender, EventArgs e) { - var configHelper = new ConfigHelper(); - var newSettings = new Settings(); - if (rbIndentTabs.Checked) { - newSettings.IndentationSettings = IndentationSettings.Tabs; + ConfigHelper.CurrentSettings.IndentationSettings = IndentationSettings.Tabs; } if (rbIndentSpaces.Checked) { - newSettings.IndentationSettings = IndentationSettings.Spaces; + ConfigHelper.CurrentSettings.IndentationSettings = IndentationSettings.Spaces; //newSettings.TabSize = int tabSizeValue; if (int.TryParse(tbIndentation.Text, out tabSizeValue)) { - newSettings.TabSize = tabSizeValue; + ConfigHelper.CurrentSettings.TabSize = tabSizeValue; } else { @@ -79,8 +70,7 @@ private void btnSaveSettings_Click(object sender, EventArgs e) return; } } - - configHelper.SaveSettings(newSettings); + ConfigHelper.SaveSettings(); Close(); } } diff --git a/tabler/data/stringtable.xml b/tabler/data/stringtable.xml index ab424b7..6fa81f3 100644 --- a/tabler/data/stringtable.xml +++ b/tabler/data/stringtable.xml @@ -1,802 +1,219 @@ - - - - - - - - - - - - - - - - - - - - - stringtable.xml | ace3public Slack - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - Menu - - -

- - - ace3public - -

- - - -
- -
- -
- - - -
- - - -
- -

- 16KB XML snippet created on July 6th 2015. - This file is private. -

- - - Actions - - - - - - -
-
<?xml version="1.0" encoding="utf-8"?>
-<Project name="ACE">
-    <Package name="Advanced_Ballistics">
-        <Key ID="STR_ACE_Advanced_Ballistics_WindInfoKey">
-            <English>Show Wind Info</English>
-            <Polish>Pokaż inf. o wietrze</Polish>
-            <Italian>Mostra indicazioni del vento</Italian>
-            <Russian>Показать информацию о ветре</Russian>
-            <French>Afficher les info sur le vent</French>
-            <Spanish>Mostrar información del viento</Spanish>
-            <German>Windinformationen anzeigen</German>
-            <Hungarian>Széladatok mutatása</Hungarian>
-            <Czech>Zobrazit informace o větru</Czech>
-            <Portuguese>Mostrar Informação do Vento</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_ProtractorKey">
-            <English>Show Protractor</English>
-            <Polish>Pokaż kątomierz</Polish>
-            <Italian>Mostra il rapportatore</Italian>
-            <Russian>Показать транспортир</Russian>
-            <French>Afficher le rapporteur</French>
-            <Spanish>Mostrar transportador</Spanish>
-            <German>Winkelmesser anzeigen</German>
-            <Hungarian>Szögmérő mutatása</Hungarian>
-            <Czech>Zobrazit úhloměr</Czech>
-            <Portuguese>Mostrar Transferidor</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_DisplayName">
-            <English>Advanced Ballistics</English>
-            <Polish>Zaawansowana balistyka</Polish>
-            <Spanish>Balística avanzada</Spanish>
-            <German>Erweiterte Ballistik</German>
-            <Czech>Pokročilá balistika</Czech>
-            <Portuguese>Balística avançada</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_enabled_DisplayName">
-            <English>Advanced Ballistics</English>
-            <Polish>Zaawansowana balistyka</Polish>
-            <Spanish>Balística avanzada</Spanish>
-            <German>Erweiterte Ballistik</German>
-            <Czech>Pokročilá balistika</Czech>
-            <Portuguese>Balística avançada</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_enabled_Description">
-            <English>Enables advanced ballistics</English>
-            <Polish>Aktywuje zaawansowaną balistykę</Polish>
-            <Spanish>Activa la balística avanzada</Spanish>
-            <German>Aktiviert die erweiterte Ballistik</German>
-            <Czech>Aktivuje pokročilou balistiku</Czech>
-            <Portuguese>Ativa balística avançada</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_simulateForSnipers_DisplayName">
-            <English>Enabled For Snipers</English>
-            <Spanish>Activada para francotiradores</Spanish>
-            <Polish>Akt. dla snajperów</Polish>
-            <German>Für Scharfschützen aktiviert</German>
-            <Czech>Povoleno pro odstřelovače</Czech>
-            <Portuguese>Ativar para caçadores</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_simulateForSnipers_Description">
-            <English>Enables advanced ballistics for non local snipers (when using high power optics)</English>
-            <Spanish>Activa la balística avanzada para francotiradores no locales (cuando se usa una mira telescópica)</Spanish>
-            <Polish>Aktywuje zaawansowaną balistykę dla nielokalnych snajperów (kiedy używają optyki)</Polish>
-            <German>Aktiviert die erweiterte Ballistik für nicht lokale Scharfschützen (bei Benutzung von Optiken mit starker Vergrößerung)</German>
-            <Czech>Aktivuje pokročilou balistiku pro nelokální odstřelovače (když používá výkonnou optiku)</Czech>
-            <Portuguese>Ativa balística avançada para caçadores não locais (quando usando miras telescópicas)</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_simulateForGroupMembers_DisplayName">
-            <English>Enabled For Group Members</English>
-            <Spanish>Activada para miembros de grupo</Spanish>
-            <Polish>Akt. dla czł. grupy</Polish>
-            <German>Für Gruppenmitglieder aktiviert</German>
-            <Czech>Povoleno pro členy skupiny</Czech>
-            <Portuguese>Ativada para membros do grupo</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_simulateForGroupMembers_Description">
-            <English>Enables advanced ballistics for non local group members</English>
-            <Spanish>Activada la balística avanzada para miembros de grupo no locales</Spanish>
-            <Polish>Aktywuje zaawansowaną balistykę dla nielokalnych członków grupy</Polish>
-            <German>Aktiviert die erweiterte Ballistik für nicht lokale Gruppenmitglieder</German>
-            <Czech>Aktivuje pokročilou balistiku pro nelokální členy skupiny</Czech>
-            <Portuguese>Ativa balística avançada para membros de grupo não locais</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_simulateForEveryone_DisplayName">
-            <English>Enabled For Everyone</English>
-            <Spanish>Activada para todos</Spanish>
-            <Polish>Akt. dla wszystkich</Polish>
-            <German>Für jeden aktiviert</German>
-            <Czech>Povoleno pro všechny</Czech>
-            <Portuguese>Ativada para todos</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_simulateForEveryone_Description">
-            <English>Enables advanced ballistics for all non local players (enabling this may degrade performance during heavy firefights in multiplayer)</English>
-            <Spanish>Activada la balística avanzada para todos los jugadores no locales (activarlo puede degradar el rendimiento durante grandes tiroteos en multijugador).</Spanish>
-            <Polish>Aktywuje zaawansowaną balistykę dla wszystkich nielokalnych graczy (aktywacja tej opcji może spodowować spory spadek wydajności podczas ciężkiej wymiany ognia)</Polish>
-            <German>Aktiviert die erweiterte Ballistik für alle nicht lokalen Spieler (das Aktivieren dieser Funktion kann zur Beeinträchtigung des Spielerlebnisses im Multiplayer führen)</German>
-            <Czech>Aktivovat pokročilou balistiku pro všechny nelokální hráče (aktivace této možnosti způsobuje pokles snímu za sekundu během těžké přestřelky v multiplayeru)</Czech>
-            <Portuguese>Ativa balística avançada para todos os jogadores não locais (ativando isso pode degradar a performance durante troca de tiros intensas no multiplayer)</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_alwaysSimulateForGroupMembers_DisplayName">
-            <English>Always Enabled For Group Members</English>
-            <Polish>Zawsze akt. dla czł. grupy</Polish>
-            <Spanish>Siempre activada para miembros de grupo</Spanish>
-            <German>Für Gruppenmitglieder immer aktiviert</German>
-            <Czech>Vždy povoleno pro členy skupiny</Czech>
-            <Portuguese>Sempre ativada para membros do grupo</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_alwaysSimulateForGroupMembers_Description">
-            <English>Always enables advanced ballistics when a group member fires</English>
-            <Polish>Aktywuje zaawansowaną balistykę dla wszystkich członków grupy</Polish>
-            <Spanish>Activada la balística avanzada siempre cuando miembros de grupo disparan</Spanish>
-            <German>Aktiviert die erweiterte Ballistik immer, wenn ein Gruppenmitglied schießt</German>
-            <Czech>Aktivuje pokročilou balistiku pro členy skupiny</Czech>
-            <Portuguese>Sempre ative balística avançada quando um membro do grupo disparar</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_disabledInFullAutoMod_DisplayName">
-            <English>Disabled In FullAuto Mode</English>
-            <Polish>Wył. podczas ognia auto.</Polish>
-            <Spanish>Desactivada en modo automático</Spanish>
-            <German>Beim vollautomatischen Feuern deaktiviert</German>
-            <Czech>Zakázáno v automatickém režimu střelby</Czech>
-            <Portuguese>Desabilitar no modo automático</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_disabledInFullAutoMod_Description">
-            <English>Disables the advanced ballistics during full auto fire</English>
-            <Polish>Dezaktywuje zaawansowaną balistykę podczas ognia automatycznego</Polish>
-            <Spanish>Desactivada la balística avanzada durante el fuego automático</Spanish>
-            <German>Deaktiviert die erweiterte Ballistik beim vollautomatischen Feuern</German>
-            <Czech>Zákáže pokročilou balistiku během střelby v režimu automat</Czech>
-            <Portuguese>Desabilitar a balística avançada durante fogo automático</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_ammoTemperatureEnabled_DisplayName">
-            <English>Enable Ammo Temperature Simulation</English>
-            <Polish>Symulacja temp. amunicji</Polish>
-            <Spanish>Activar simulación de temperatura de munición</Spanish>
-            <German>Simulation der Munitionstemperatur aktivieren</German>
-            <Czech>Povolit simulaci teploty munice</Czech>
-            <Portuguese>Ativar simulação de temperatura de munição</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_ammoTemperatureEnabled_Description">
-            <English>Muzzle velocity varies with ammo temperature</English>
-            <Polish>Prędkość wylotowa pocisku jest zależna od temperatury amunicji</Polish>
-            <Spanish>La velocidad de salida varía con la temperatura de la munición</Spanish>
-            <German>Munitionstemperatur hat Einfluss auf die Mündungsgeschwindigkeit</German>
-            <Czech>Úsťová rychlost je závislá na teplotě munice</Czech>
-            <Portuguese>A velocidade de saída varia com a temperatura da munição</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_barrelLengthInfluenceEnabled_DisplayName">
-            <English>Enable Barrel Length Simulation</English>
-            <Polish>Symulacja długości lufy</Polish>
-            <Spanish>Habilitar la simulación de longitud del cañón</Spanish>
-            <German>Simulation der Lauflänge aktivieren</German>
-            <Czech>Povolit simulaci délky hlavně</Czech>
-            <Portuguese>Ativar a simulação de comprimento do cano</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_barrelLengthInfluenceEnabled_Description">
-            <English>Muzzle velocity varies with barrel length</English>
-            <Polish>Prędkość wylotowa pocisku jest zależna od długości lufy</Polish>
-            <Spanish>La velocidad de salidal varía con la longitud del cañón</Spanish>
-            <German>Lauflänge beeinflusst Mündungsgeschwindigkeit</German>
-            <Czech>Úsťová rychlost je závislá na délce hlavně</Czech>
-            <Portuguese>A velocidade de saída caria com o comprimento do cano</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_bulletTraceEnabled_DisplayName">
-            <English>Enable Bullet Trace Effect</English>
-            <Polish>Efekt smugi pocisku</Polish>
-            <Spanish>Activar el efecto trazador de la bala</Spanish>
-            <German>Geschossspureffekt aktivieren</German>
-            <Czech>Povolit efekt trasírek</Czech>
-            <Portuguese>Ativa efeito traçante de projétil</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_bulletTraceEnabled_Description">
-            <English>Enables a bullet trace effect to high caliber bullets (only visible when looking through high power optics)</English>
-            <Polish>Aktywuje efekt smugi pocisku dla pocisków wysokokalibrowych (widoczne tylko podczas patrzenia przez optykę)</Polish>
-            <Spanish>Activa el efecto trazador de la balas de gran calibre (solo visible cuando se mira a través de una mira telescópica)</Spanish>
-            <German>Aktiviere Geschossspureffekt für hohe Kaliber (bei Benutzung von Optiken mit starker Vergrößerung)</German>
-            <Czech>Aktivuje efekt trasírek z vysokokaliberních zbraní (viditelné pouze skrze výkonnou optiku)</Czech>
-            <Portuguese>Ativa o efeito traçante de projétil para projéteis de alto calibre (somente visível quando observado por miras telescópicas)</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_simulationInterval_DisplayName">
-            <English>Simulation Interval</English>
-            <Polish>Interwał symulacji</Polish>
-            <Spanish>Intervalo de simulación</Spanish>
-            <German>Simulationsintervall</German>
-            <Czech>Interval simulace</Czech>
-            <Portuguese>Intervalo da simulação</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_simulationInterval_Description">
-            <English>Defines the interval between every calculation step</English>
-            <Polish>Określa interwał pomiędzy każdym krokiem kalkulacji</Polish>
-            <Spanish>Define el intervalo entre cada cálculo</Spanish>
-            <German>Legt das Intervall zwischen den Berechnungsschritten fest</German>
-            <Czech>Určuje interval mezi každým výpočtem</Czech>
-            <Portuguese>Define o intervalo entre cada cálculo</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_simulationRadius_DisplayName">
-            <English>Simulation Radius</English>
-            <Polish>Zasięg symulacji</Polish>
-            <Spanish>Radio de simulación</Spanish>
-            <German>Simulationsradius</German>
-            <Czech>Rozsah simulace</Czech>
-            <Portuguese>Raio de simulação</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_simulationRadius_Description">
-            <English>Defines the radius around the player (in meters) at which advanced ballistics are applied to projectiles</English>
-            <Polish>Określa obszar naokoło gracza (w metrach), na którym zaawansowana balistyka jest aplikowana dla pocisków</Polish>
-            <Spanish>Define el radio alrededor del jugador (en metros) en el cual se aplica la balística avanzada a los proyectiles</Spanish>
-            <German>Gibt den Radius (in Metern) um den Spieler an, bei dem die erweiterte Ballistik auf Geschosse angewendet wird</German>
-            <Czech>Určuje oblast kolem hráče (v metrech), kde je pokročilá balistika použita na projektil</Czech>
-            <Portuguese>Define o raio ao redor do jogador (em metros) onde a balística avançada será aplicada aos projéteis</Portuguese>
-        </Key>
-        <Key ID="STR_ACE_Advanced_Ballistics_Description">
-            <English></English>
-            <Polish>Moduł ten pozwala aktywować zaawansowaną balistykę biorącą przy obliczeniach trajektorii lotu pocisku pod uwagę takie rzeczy jak temperatura powietrza, ciśnienie atmosferyczne, wilgotność powietrza, siły Coriolisa i Eotvosa, grawitację a także broń z jakiej wykonywany jest strzał oraz rodzaj amunicji. Wszystko to sprowadza się na bardzo dokładne odwzorowanie balistyki.</Polish>
-            <Czech>Tento modul umožňuje aktivovat pokročilou balistiku, která vypočítává trajektorii kulky a bere do úvahy věci jako je teplota vzduchu, atmosférický tlak, vlhkost vzduchu, gravitaci, typ munice a zbraň, ze které je náboj vystřelen. To vše přispívá k velmi přesné balistice.</Czech>
-            <Portuguese>Este módulo permite que você ative cálculos de balística avançada, fazendo a trajetória do projétil levar em consideração coisas como temperatura do ar, pressão atmosférica, umidade, força de Coriolis, a gravidade, o modelo da arma no qual o disparo é realizado e o tipo de munição. Tudo isso acrescenta-se a um balística muito precisa.</Portuguese>
-        </Key>
-    </Package>
-</Project>
- -

- -

- -
- -
-
-
-
-
-
- - - - - - - - cmd+enter to submit -
- - -
-
-
-
- - - - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + Show Wind Info + Pokaż inf. o wietrze + Mostra indicazioni del vento + Показать информацию о ветре + Afficher les info sur le vent + Mostrar información del viento + Windinformationen anzeigen + Széladatok mutatása + Zobrazit informace o větru + Mostrar Informação do Vento + + + Show Protractor + Pokaż kątomierz + Mostra il rapportatore + Показать транспортир + Afficher le rapporteur + Mostrar transportador + Winkelmesser anzeigen + Szögmérő mutatása + Zobrazit úhloměr + Mostrar Transferidor + + + Advanced Ballistics + Zaawansowana balistyka + Balística avanzada + Erweiterte Ballistik + Pokročilá balistika + Balística avançada + + + Advanced Ballistics + Zaawansowana balistyka + Balística avanzada + Erweiterte Ballistik + Pokročilá balistika + Balística avançada + + + Enables advanced ballistics + Aktywuje zaawansowaną balistykę + Activa la balística avanzada + Aktiviert die erweiterte Ballistik + Aktivuje pokročilou balistiku + Ativa balística avançada + + + Enabled For Snipers + Activada para francotiradores + Akt. dla snajperów + Für Scharfschützen aktiviert + Povoleno pro odstřelovače + Ativar para caçadores + + + Enables advanced ballistics for non local snipers (when using high power optics) + Activa la balística avanzada para francotiradores no locales (cuando se usa una mira telescópica) + Aktywuje zaawansowaną balistykę dla nielokalnych snajperów (kiedy używają optyki) + Aktiviert die erweiterte Ballistik für nicht lokale Scharfschützen (bei Benutzung von Optiken mit starker Vergrößerung) + Aktivuje pokročilou balistiku pro nelokální odstřelovače (když používá výkonnou optiku) + Ativa balística avançada para caçadores não locais (quando usando miras telescópicas) + + + Enabled For Group Members + Activada para miembros de grupo + Akt. dla czł. grupy + Für Gruppenmitglieder aktiviert + Povoleno pro členy skupiny + Ativada para membros do grupo + + + Enables advanced ballistics for non local group members + Activada la balística avanzada para miembros de grupo no locales + Aktywuje zaawansowaną balistykę dla nielokalnych członków grupy + Aktiviert die erweiterte Ballistik für nicht lokale Gruppenmitglieder + Aktivuje pokročilou balistiku pro nelokální členy skupiny + Ativa balística avançada para membros de grupo não locais + + + Enabled For Everyone + Activada para todos + Akt. dla wszystkich + Für jeden aktiviert + Povoleno pro všechny + Ativada para todos + + + Enables advanced ballistics for all non local players (enabling this may degrade performance during heavy firefights in multiplayer) + Activada la balística avanzada para todos los jugadores no locales (activarlo puede degradar el rendimiento durante grandes tiroteos en multijugador). + Aktywuje zaawansowaną balistykę dla wszystkich nielokalnych graczy (aktywacja tej opcji może spodowować spory spadek wydajności podczas ciężkiej wymiany ognia) + Aktiviert die erweiterte Ballistik für alle nicht lokalen Spieler (das Aktivieren dieser Funktion kann zur Beeinträchtigung des Spielerlebnisses im Multiplayer führen) + Aktivovat pokročilou balistiku pro všechny nelokální hráče (aktivace této možnosti způsobuje pokles snímu za sekundu během těžké přestřelky v multiplayeru) + Ativa balística avançada para todos os jogadores não locais (ativando isso pode degradar a performance durante troca de tiros intensas no multiplayer) + + + Always Enabled For Group Members + Zawsze akt. dla czł. grupy + Siempre activada para miembros de grupo + Für Gruppenmitglieder immer aktiviert + Vždy povoleno pro členy skupiny + Sempre ativada para membros do grupo + + + Always enables advanced ballistics when a group member fires + Aktywuje zaawansowaną balistykę dla wszystkich członków grupy + Activada la balística avanzada siempre cuando miembros de grupo disparan + Aktiviert die erweiterte Ballistik immer, wenn ein Gruppenmitglied schießt + Aktivuje pokročilou balistiku pro členy skupiny + Sempre ative balística avançada quando um membro do grupo disparar + + + Disabled In FullAuto Mode + Wył. podczas ognia auto. + Desactivada en modo automático + Beim vollautomatischen Feuern deaktiviert + Zakázáno v automatickém režimu střelby + Desabilitar no modo automático + + + Disables the advanced ballistics during full auto fire + Dezaktywuje zaawansowaną balistykę podczas ognia automatycznego + Desactivada la balística avanzada durante el fuego automático + Deaktiviert die erweiterte Ballistik beim vollautomatischen Feuern + Zákáže pokročilou balistiku během střelby v režimu automat + Desabilitar a balística avançada durante fogo automático + + + Enable Ammo Temperature Simulation + Symulacja temp. amunicji + Activar simulación de temperatura de munición + Simulation der Munitionstemperatur aktivieren + Povolit simulaci teploty munice + Ativar simulação de temperatura de munição + + + Muzzle velocity varies with ammo temperature + Prędkość wylotowa pocisku jest zależna od temperatury amunicji + La velocidad de salida varía con la temperatura de la munición + Munitionstemperatur hat Einfluss auf die Mündungsgeschwindigkeit + Úsťová rychlost je závislá na teplotě munice + A velocidade de saída varia com a temperatura da munição + + + Enable Barrel Length Simulation + Symulacja długości lufy + Habilitar la simulación de longitud del cañón + Simulation der Lauflänge aktivieren + Povolit simulaci délky hlavně + Ativar a simulação de comprimento do cano + + + Muzzle velocity varies with barrel length + Prędkość wylotowa pocisku jest zależna od długości lufy + La velocidad de salidal varía con la longitud del cañón + Lauflänge beeinflusst Mündungsgeschwindigkeit + Úsťová rychlost je závislá na délce hlavně + A velocidade de saída caria com o comprimento do cano + + + Enable Bullet Trace Effect + Efekt smugi pocisku + Activar el efecto trazador de la bala + Geschossspureffekt aktivieren + Povolit efekt trasírek + Ativa efeito traçante de projétil + + + Enables a bullet trace effect to high caliber bullets (only visible when looking through high power optics) + Aktywuje efekt smugi pocisku dla pocisków wysokokalibrowych (widoczne tylko podczas patrzenia przez optykę) + Activa el efecto trazador de la balas de gran calibre (solo visible cuando se mira a través de una mira telescópica) + Aktiviere Geschossspureffekt für hohe Kaliber (bei Benutzung von Optiken mit starker Vergrößerung) + Aktivuje efekt trasírek z vysokokaliberních zbraní (viditelné pouze skrze výkonnou optiku) + Ativa o efeito traçante de projétil para projéteis de alto calibre (somente visível quando observado por miras telescópicas) + + + Simulation Interval + Interwał symulacji + Intervalo de simulación + Simulationsintervall + Interval simulace + Intervalo da simulação + + + Defines the interval between every calculation step + Określa interwał pomiędzy każdym krokiem kalkulacji + Define el intervalo entre cada cálculo + Legt das Intervall zwischen den Berechnungsschritten fest + Určuje interval mezi každým výpočtem + Define o intervalo entre cada cálculo + + + Simulation Radius + Zasięg symulacji + Radio de simulación + Simulationsradius + Rozsah simulace + Raio de simulação + + + Defines the radius around the player (in meters) at which advanced ballistics are applied to projectiles + Określa obszar naokoło gracza (w metrach), na którym zaawansowana balistyka jest aplikowana dla pocisków + Define el radio alrededor del jugador (en metros) en el cual se aplica la balística avanzada a los proyectiles + Gibt den Radius (in Metern) um den Spieler an, bei dem die erweiterte Ballistik auf Geschosse angewendet wird + Určuje oblast kolem hráče (v metrech), kde je pokročilá balistika použita na projektil + Define o raio ao redor do jogador (em metros) onde a balística avançada será aplicada aos projéteis + + + + Moduł ten pozwala aktywować zaawansowaną balistykę biorącą przy obliczeniach trajektorii lotu pocisku pod uwagę takie rzeczy jak temperatura powietrza, ciśnienie atmosferyczne, wilgotność powietrza, siły Coriolisa i Eotvosa, grawitację a także broń z jakiej wykonywany jest strzał oraz rodzaj amunicji. Wszystko to sprowadza się na bardzo dokładne odwzorowanie balistyki. + Tento modul umožňuje aktivovat pokročilou balistiku, která vypočítává trajektorii kulky a bere do úvahy věci jako je teplota vzduchu, atmosférický tlak, vlhkost vzduchu, gravitaci, typ munice a zbraň, ze které je náboj vystřelen. To vše přispívá k velmi přesné balistice. + Este módulo permite que você ative cálculos de balística avançada, fazendo a trajetória do projétil levar em consideração coisas como temperatura do ar, pressão atmosférica, umidade, força de Coriolis, a gravidade, o modelo da arma no qual o disparo é realizado e o tipo de munição. Tudo isso acrescenta-se a um balística muito precisa. + + + \ No newline at end of file diff --git a/tabler/tabler.csproj b/tabler/tabler.csproj index 5058a7c..711d386 100644 --- a/tabler/tabler.csproj +++ b/tabler/tabler.csproj @@ -97,7 +97,6 @@
- Form