PageRenderTime 123ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Resources/PdnResources.cs

https://bitbucket.org/tuldok89/openpdn
C# | 402 lines | 302 code | 72 blank | 28 comment | 38 complexity | 564b685ea7062033db7fce5f571c1551 MD5 | raw file
  1. /////////////////////////////////////////////////////////////////////////////////
  2. // Paint.NET //
  3. // Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
  4. // Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
  5. // See src/Resources/Files/License.txt for full licensing and attribution //
  6. // details. //
  7. // . //
  8. /////////////////////////////////////////////////////////////////////////////////
  9. using System.Linq;
  10. using PaintDotNet.Base;
  11. using PaintDotNet.SystemLayer;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Diagnostics;
  15. using System.Drawing;
  16. using System.Drawing.Imaging;
  17. using System.Globalization;
  18. using System.IO;
  19. using System.Reflection;
  20. using System.Resources;
  21. namespace PaintDotNet
  22. {
  23. public static class PdnResources
  24. {
  25. private const string OurNamespace = "PaintDotNet";
  26. private static Assembly _ourAssembly;
  27. private static string[] _localeDirs;
  28. private static CultureInfo _pdnCulture;
  29. private static string _resourcesDir;
  30. public static string ResourcesDir
  31. {
  32. get { return _resourcesDir ?? (_resourcesDir = Path.GetDirectoryName(typeof (PdnResources).Assembly.Location)); }
  33. set
  34. {
  35. _resourcesDir = value;
  36. Initialize();
  37. }
  38. }
  39. public static CultureInfo Culture
  40. {
  41. get
  42. {
  43. return _pdnCulture;
  44. }
  45. set
  46. {
  47. System.Threading.Thread.CurrentThread.CurrentUICulture = value;
  48. Initialize();
  49. }
  50. }
  51. private static void Initialize()
  52. {
  53. Strings = CreateResourceManager();
  54. _ourAssembly = Assembly.GetExecutingAssembly();
  55. _pdnCulture = CultureInfo.CurrentUICulture;
  56. _localeDirs = GetLocaleDirs();
  57. }
  58. static PdnResources()
  59. {
  60. Initialize();
  61. }
  62. public static void SetNewCulture(string newLocaleName)
  63. {
  64. // TODO, HACK: post-3.0 we must refactor and have an actual user data manager that can handle all this renaming
  65. string oldUserDataPath = PdnInfo.UserDataPath;
  66. string oldPaletteDirName = GetString("ColorPalettes.UserDataSubDirName");
  67. // END HACK
  68. var newCI = new CultureInfo(newLocaleName);
  69. Settings.CurrentUser.SetString("LanguageName", newLocaleName);
  70. Culture = newCI;
  71. // TODO, HACK: finish up renaming
  72. string newUserDataPath = PdnInfo.UserDataPath;
  73. string newPaletteDirName = GetString("ColorPalettes.UserDataSubDirName");
  74. // 1. rename user data dir from old localized name to new localized name
  75. if (oldUserDataPath != newUserDataPath)
  76. {
  77. try
  78. {
  79. Directory.Move(oldUserDataPath, newUserDataPath);
  80. }
  81. catch (Exception)
  82. {
  83. }
  84. }
  85. // 2. rename palette dir from old localized name (in new localized user data path) to new localized name
  86. string oldPalettePath = Path.Combine(newUserDataPath, oldPaletteDirName);
  87. string newPalettePath = Path.Combine(newUserDataPath, newPaletteDirName);
  88. if (oldPalettePath == newPalettePath)
  89. {
  90. }
  91. else
  92. {
  93. try
  94. {
  95. Directory.Move(oldPalettePath, newPalettePath);
  96. }
  97. catch (Exception)
  98. {
  99. }
  100. }
  101. // END HACK
  102. }
  103. public static string[] GetInstalledLocales()
  104. {
  105. const string left = "PaintDotNet.Strings.3";
  106. const string right = ".resources";
  107. string ourDir = ResourcesDir;
  108. const string fileSpec = left + "*" + right;
  109. string[] pathNames = Directory.GetFiles(ourDir, fileSpec);
  110. var locales = new List<string>();
  111. foreach (string sansLeft in from pathName in pathNames
  112. let dirName = Path.GetDirectoryName(pathName)
  113. select Path.GetFileName(pathName)
  114. into fileName where fileName != null select fileName.Substring(0, fileName.Length - right.Length)
  115. into sansRight select sansRight.Substring(left.Length))
  116. {
  117. string locale;
  118. if (sansLeft.Length > 0 && sansLeft[0] == '.')
  119. {
  120. locale = sansLeft.Substring(1);
  121. }
  122. else if (sansLeft.Length == 0)
  123. {
  124. locale = "en-US";
  125. }
  126. else
  127. {
  128. locale = sansLeft;
  129. }
  130. try
  131. {
  132. // Ensure this locale can create a valid CultureInfo object.
  133. var ci = new CultureInfo(locale);
  134. }
  135. catch (Exception)
  136. {
  137. // Skip past invalid locales -- don't let them crash us
  138. continue;
  139. }
  140. locales.Add(locale);
  141. }
  142. return locales.ToArray();
  143. }
  144. public static string[] GetLocaleNameChain()
  145. {
  146. var names = new List<string>();
  147. CultureInfo ci = _pdnCulture;
  148. while (ci.Name != string.Empty)
  149. {
  150. names.Add(ci.Name);
  151. ci = ci.Parent;
  152. }
  153. return names.ToArray();
  154. }
  155. private static string[] GetLocaleDirs()
  156. {
  157. const string rootDirName = "Resources";
  158. string appDir = ResourcesDir;
  159. string rootDir = Path.Combine(appDir, rootDirName);
  160. var dirs = new List<string>();
  161. CultureInfo ci = _pdnCulture;
  162. while (ci.Name != string.Empty)
  163. {
  164. string localeDir = Path.Combine(rootDir, ci.Name);
  165. if (Directory.Exists(localeDir))
  166. {
  167. dirs.Add(localeDir);
  168. }
  169. ci = ci.Parent;
  170. }
  171. return dirs.ToArray();
  172. }
  173. private static ResourceManager CreateResourceManager()
  174. {
  175. const string stringsFileName = "PaintDotNet.Strings.3";
  176. ResourceManager rm = ResourceManager.CreateFileBasedResourceManager(stringsFileName, ResourcesDir, null);
  177. return rm;
  178. }
  179. public static ResourceManager Strings { get; private set; }
  180. public static string GetString(string stringName)
  181. {
  182. string theString = Strings.GetString(stringName, _pdnCulture);
  183. if (theString == null)
  184. {
  185. Debug.WriteLine(stringName + " not found");
  186. }
  187. return theString;
  188. }
  189. public static Stream GetResourceStream(string fileName)
  190. {
  191. Stream stream = (from t in _localeDirs
  192. select Path.Combine(t, fileName)
  193. into filePath where File.Exists(filePath) select new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)).FirstOrDefault();
  194. if (stream == null)
  195. {
  196. string fullName = OurNamespace + "." + fileName;
  197. stream = _ourAssembly.GetManifestResourceStream(fullName);
  198. }
  199. return stream;
  200. }
  201. public static Image GetImageBmpOrPng(string fileNameNoExt)
  202. {
  203. // using Path.ChangeExtension is not what we want; quite often filenames are "Icons.BlahBlahBlah"
  204. string fileNameBmp = fileNameNoExt + ".bmp";
  205. Image image = GetImage(fileNameBmp);
  206. if (image == null)
  207. {
  208. string fileNamePng = fileNameNoExt + ".png";
  209. image = GetImage(fileNamePng);
  210. }
  211. return image;
  212. }
  213. public static Image GetImage(string fileName)
  214. {
  215. Stream stream = GetResourceStream(fileName);
  216. Image image = null;
  217. if (stream != null)
  218. {
  219. image = LoadImage(stream);
  220. }
  221. return image;
  222. }
  223. private sealed class PdnImageResource
  224. : ImageResource
  225. {
  226. private readonly string _name;
  227. private static readonly Dictionary<string, ImageResource> Images;
  228. protected override Image Load()
  229. {
  230. return GetImage(_name);
  231. }
  232. public static ImageResource Get(string name)
  233. {
  234. ImageResource ir;
  235. if (!Images.TryGetValue(name, out ir))
  236. {
  237. ir = new PdnImageResource(name);
  238. Images.Add(name, ir);
  239. }
  240. return ir;
  241. }
  242. static PdnImageResource()
  243. {
  244. Images = new Dictionary<string, ImageResource>();
  245. }
  246. private PdnImageResource(string name)
  247. {
  248. _name = name;
  249. }
  250. }
  251. public static ImageResource GetImageResource(string fileName)
  252. {
  253. return PdnImageResource.Get(fileName);
  254. }
  255. public static Icon GetIcon(string fileName)
  256. {
  257. Stream stream = GetResourceStream(fileName);
  258. Icon icon = null;
  259. if (stream != null)
  260. {
  261. icon = new Icon(stream);
  262. }
  263. return icon;
  264. }
  265. public static Icon GetIconFromImage(string fileName)
  266. {
  267. Stream stream = GetResourceStream(fileName);
  268. Icon icon = null;
  269. if (stream != null)
  270. {
  271. Image image = LoadImage(stream);
  272. icon = Icon.FromHandle(((Bitmap)image).GetHicon());
  273. image.Dispose();
  274. stream.Close();
  275. }
  276. return icon;
  277. }
  278. private static bool CheckForSignature(Stream input, IList<byte> signature)
  279. {
  280. long oldPos = input.Position;
  281. var inputSig = new byte[signature.Count];
  282. int amountRead = input.Read(inputSig, 0, inputSig.Length);
  283. bool foundSig = false;
  284. if (amountRead == signature.Count)
  285. {
  286. foundSig = true;
  287. for (int i = 0; i < signature.Count; ++i)
  288. {
  289. foundSig &= (signature[i] == inputSig[i]);
  290. }
  291. }
  292. input.Position = oldPos;
  293. return foundSig;
  294. }
  295. public static bool IsGdiPlusImageAllowed(Stream input)
  296. {
  297. var wmfSig = new byte[] { 0xd7, 0xcd, 0xc6, 0x9a };
  298. var emfSig = new byte[] { 0x01, 0x00, 0x00, 0x00 };
  299. // Check for and explicitely block WMF and EMF images
  300. return !(CheckForSignature(input, emfSig) || CheckForSignature(input, wmfSig));
  301. }
  302. public static Image LoadImage(string fileName)
  303. {
  304. using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
  305. {
  306. return LoadImage(stream);
  307. }
  308. }
  309. /// <summary>
  310. /// Loads an image from the given stream. The stream must be seekable.
  311. /// </summary>
  312. /// <param name="input">The Stream to load the image from.</param>
  313. public static Image LoadImage(Stream input)
  314. {
  315. /*
  316. if (!IsGdiPlusImageAllowed(input))
  317. {
  318. throw new IOException("File format is not supported");
  319. }
  320. */
  321. Image image = Image.FromStream(input);
  322. if (image.RawFormat == ImageFormat.Wmf || image.RawFormat == ImageFormat.Emf)
  323. {
  324. image.Dispose();
  325. throw new IOException("File format isn't supported");
  326. }
  327. return image;
  328. }
  329. }
  330. }