1 /* 2 *Copyright (C) 2018 Laurent Tréguier 3 * 4 *This file is part of DLS. 5 * 6 *DLS is free software: you can redistribute it and/or modify 7 *it under the terms of the GNU General Public License as published by 8 *the Free Software Foundation, either version 3 of the License, or 9 *(at your option) any later version. 10 * 11 *DLS is distributed in the hope that it will be useful, 12 *but WITHOUT ANY WARRANTY; without even the implied warranty of 13 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 *GNU General Public License for more details. 15 * 16 *You should have received a copy of the GNU General Public License 17 *along with DLS. If not, see <http://www.gnu.org/licenses/>. 18 * 19 */ 20 21 module dls.util.i18n; 22 23 public import dls.util.i18n.constants; 24 import dls.protocol.interfaces : MessageType; 25 import std.json : JSONValue; 26 27 private enum translationsJson = import("translations.json"); 28 private immutable JSONValue translations; 29 private immutable string locale; 30 private immutable defaultLocale = "en"; 31 32 shared static this() 33 { 34 import std.json : parseJSON; 35 36 translations = parseJSON(translationsJson); 37 locale = defaultLocale; 38 39 version (Windows) 40 { 41 import core.sys.windows.windef : DWORD, ERROR_SUCCESS, LONG, HKEY; 42 import core.sys.windows.winnt : KEY_READ; 43 import core.sys.windows.winreg : HKEY_USERS, RegOpenKeyExA, RegQueryValueExA; 44 import std..string : toStringz; 45 46 HKEY hKey; 47 48 if (RegOpenKeyExA(HKEY_USERS, toStringz(`.DEFAULT\Control Panel\International`), 49 0, KEY_READ, &hKey) != ERROR_SUCCESS) 50 { 51 return; 52 } 53 54 DWORD size = 32; 55 auto buffer = new char[size]; 56 57 if (RegQueryValueExA(hKey, toStringz("LocaleName"), null, null, 58 buffer.ptr, &size) != ERROR_SUCCESS) 59 { 60 return; 61 } 62 63 if (size >= 2) 64 { 65 locale = buffer[0 .. 2].idup; 66 } 67 } 68 else version (Posix) 69 { 70 import std.process : environment; 71 72 auto lang = environment.get("LANG", defaultLocale); 73 74 if (lang.length >= 2) 75 { 76 locale = lang[0 .. 2]; 77 } 78 } 79 else 80 { 81 static assert(false, "Platform not supported"); 82 } 83 } 84 85 string tr(Tr identifier, string[] args = []) 86 { 87 import std.conv : text; 88 import std.range : replace; 89 90 auto message = translations[identifier]; 91 auto localizedMessage = message[locale in message ? locale : defaultLocale].str; 92 93 foreach (i, arg; args) 94 { 95 localizedMessage = localizedMessage.replace('$' ~ text(i + 1), arg); 96 } 97 98 return localizedMessage; 99 } 100 101 MessageType trType(Tr message) 102 { 103 auto t = translations[message]; 104 return "_type" in t ? cast(MessageType) t["_type"].integer : MessageType.info; 105 }