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 auto regKeyCStr = toStringz(`.DEFAULT\Control Panel\International`); 48 49 if (RegOpenKeyExA(HKEY_USERS, regKeyCStr, 0, KEY_READ, &hKey) != ERROR_SUCCESS) 50 { 51 return; 52 } 53 54 DWORD size = 32; 55 auto buffer = new char[size]; 56 auto localeNameCStr = toStringz("LocaleName"); 57 58 if (RegQueryValueExA(hKey, localeNameCStr, null, null, 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 locale = defaultLocale; 82 } 83 } 84 85 string tr(Tr identifier, string[] args = []) 86 { 87 import std.ascii : newline; 88 import std.conv : text; 89 import std.range : replace; 90 91 auto message = translations[identifier]; 92 auto localizedMessage = message[locale in message ? locale : defaultLocale].str; 93 94 foreach (i, arg; args) 95 { 96 localizedMessage = localizedMessage.replace('$' ~ text(i + 1), arg); 97 } 98 99 return localizedMessage.replace("$n", newline); 100 } 101 102 MessageType trType(Tr message) 103 { 104 auto t = translations[message]; 105 return "_type" in t ? cast(MessageType) t["_type"].integer : MessageType.info; 106 }