/src/Resources/PdnResources.cs
C# | 402 lines | 302 code | 72 blank | 28 comment | 38 complexity | 564b685ea7062033db7fce5f571c1551 MD5 | raw file
- /////////////////////////////////////////////////////////////////////////////////
- // Paint.NET //
- // Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
- // Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
- // See src/Resources/Files/License.txt for full licensing and attribution //
- // details. //
- // . //
- /////////////////////////////////////////////////////////////////////////////////
-
- using System.Linq;
- using PaintDotNet.Base;
- using PaintDotNet.SystemLayer;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.Globalization;
- using System.IO;
- using System.Reflection;
- using System.Resources;
-
- namespace PaintDotNet
- {
- public static class PdnResources
- {
- private const string OurNamespace = "PaintDotNet";
- private static Assembly _ourAssembly;
- private static string[] _localeDirs;
- private static CultureInfo _pdnCulture;
- private static string _resourcesDir;
-
- public static string ResourcesDir
- {
- get { return _resourcesDir ?? (_resourcesDir = Path.GetDirectoryName(typeof (PdnResources).Assembly.Location)); }
-
- set
- {
- _resourcesDir = value;
- Initialize();
- }
- }
-
- public static CultureInfo Culture
- {
- get
- {
- return _pdnCulture;
- }
-
- set
- {
- System.Threading.Thread.CurrentThread.CurrentUICulture = value;
- Initialize();
- }
- }
-
- private static void Initialize()
- {
- Strings = CreateResourceManager();
- _ourAssembly = Assembly.GetExecutingAssembly();
- _pdnCulture = CultureInfo.CurrentUICulture;
- _localeDirs = GetLocaleDirs();
- }
-
- static PdnResources()
- {
- Initialize();
- }
-
- public static void SetNewCulture(string newLocaleName)
- {
- // TODO, HACK: post-3.0 we must refactor and have an actual user data manager that can handle all this renaming
- string oldUserDataPath = PdnInfo.UserDataPath;
- string oldPaletteDirName = GetString("ColorPalettes.UserDataSubDirName");
- // END HACK
-
- var newCI = new CultureInfo(newLocaleName);
- Settings.CurrentUser.SetString("LanguageName", newLocaleName);
- Culture = newCI;
-
- // TODO, HACK: finish up renaming
- string newUserDataPath = PdnInfo.UserDataPath;
- string newPaletteDirName = GetString("ColorPalettes.UserDataSubDirName");
-
- // 1. rename user data dir from old localized name to new localized name
- if (oldUserDataPath != newUserDataPath)
- {
- try
- {
- Directory.Move(oldUserDataPath, newUserDataPath);
- }
-
- catch (Exception)
- {
- }
- }
-
- // 2. rename palette dir from old localized name (in new localized user data path) to new localized name
- string oldPalettePath = Path.Combine(newUserDataPath, oldPaletteDirName);
- string newPalettePath = Path.Combine(newUserDataPath, newPaletteDirName);
-
- if (oldPalettePath == newPalettePath)
- {
- }
- else
- {
- try
- {
- Directory.Move(oldPalettePath, newPalettePath);
- }
-
- catch (Exception)
- {
- }
- }
- // END HACK
- }
-
- public static string[] GetInstalledLocales()
- {
- const string left = "PaintDotNet.Strings.3";
- const string right = ".resources";
- string ourDir = ResourcesDir;
- const string fileSpec = left + "*" + right;
- string[] pathNames = Directory.GetFiles(ourDir, fileSpec);
- var locales = new List<string>();
-
- foreach (string sansLeft in from pathName in pathNames
- let dirName = Path.GetDirectoryName(pathName)
- select Path.GetFileName(pathName)
- into fileName where fileName != null select fileName.Substring(0, fileName.Length - right.Length)
- into sansRight select sansRight.Substring(left.Length))
- {
- string locale;
-
- if (sansLeft.Length > 0 && sansLeft[0] == '.')
- {
- locale = sansLeft.Substring(1);
- }
- else if (sansLeft.Length == 0)
- {
- locale = "en-US";
- }
- else
- {
- locale = sansLeft;
- }
-
- try
- {
- // Ensure this locale can create a valid CultureInfo object.
- var ci = new CultureInfo(locale);
- }
-
- catch (Exception)
- {
- // Skip past invalid locales -- don't let them crash us
- continue;
- }
-
- locales.Add(locale);
- }
-
- return locales.ToArray();
- }
-
- public static string[] GetLocaleNameChain()
- {
- var names = new List<string>();
- CultureInfo ci = _pdnCulture;
-
- while (ci.Name != string.Empty)
- {
- names.Add(ci.Name);
- ci = ci.Parent;
- }
-
- return names.ToArray();
- }
-
- private static string[] GetLocaleDirs()
- {
- const string rootDirName = "Resources";
- string appDir = ResourcesDir;
- string rootDir = Path.Combine(appDir, rootDirName);
- var dirs = new List<string>();
-
- CultureInfo ci = _pdnCulture;
-
- while (ci.Name != string.Empty)
- {
- string localeDir = Path.Combine(rootDir, ci.Name);
-
- if (Directory.Exists(localeDir))
- {
- dirs.Add(localeDir);
- }
-
- ci = ci.Parent;
- }
-
- return dirs.ToArray();
- }
-
- private static ResourceManager CreateResourceManager()
- {
- const string stringsFileName = "PaintDotNet.Strings.3";
- ResourceManager rm = ResourceManager.CreateFileBasedResourceManager(stringsFileName, ResourcesDir, null);
- return rm;
- }
-
- public static ResourceManager Strings { get; private set; }
-
- public static string GetString(string stringName)
- {
- string theString = Strings.GetString(stringName, _pdnCulture);
-
- if (theString == null)
- {
- Debug.WriteLine(stringName + " not found");
- }
-
- return theString;
- }
-
- public static Stream GetResourceStream(string fileName)
- {
- Stream stream = (from t in _localeDirs
- select Path.Combine(t, fileName)
- into filePath where File.Exists(filePath) select new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)).FirstOrDefault();
-
- if (stream == null)
- {
- string fullName = OurNamespace + "." + fileName;
- stream = _ourAssembly.GetManifestResourceStream(fullName);
- }
-
- return stream;
- }
-
- public static Image GetImageBmpOrPng(string fileNameNoExt)
- {
- // using Path.ChangeExtension is not what we want; quite often filenames are "Icons.BlahBlahBlah"
- string fileNameBmp = fileNameNoExt + ".bmp";
- Image image = GetImage(fileNameBmp);
-
- if (image == null)
- {
- string fileNamePng = fileNameNoExt + ".png";
- image = GetImage(fileNamePng);
- }
-
- return image;
- }
-
- public static Image GetImage(string fileName)
- {
- Stream stream = GetResourceStream(fileName);
-
- Image image = null;
- if (stream != null)
- {
- image = LoadImage(stream);
- }
-
- return image;
- }
-
- private sealed class PdnImageResource
- : ImageResource
- {
- private readonly string _name;
- private static readonly Dictionary<string, ImageResource> Images;
-
- protected override Image Load()
- {
- return GetImage(_name);
- }
-
- public static ImageResource Get(string name)
- {
- ImageResource ir;
-
- if (!Images.TryGetValue(name, out ir))
- {
- ir = new PdnImageResource(name);
- Images.Add(name, ir);
- }
-
- return ir;
- }
-
- static PdnImageResource()
- {
- Images = new Dictionary<string, ImageResource>();
- }
-
- private PdnImageResource(string name)
- {
- _name = name;
- }
- }
-
- public static ImageResource GetImageResource(string fileName)
- {
- return PdnImageResource.Get(fileName);
- }
-
- public static Icon GetIcon(string fileName)
- {
- Stream stream = GetResourceStream(fileName);
- Icon icon = null;
-
- if (stream != null)
- {
- icon = new Icon(stream);
- }
-
- return icon;
- }
-
- public static Icon GetIconFromImage(string fileName)
- {
- Stream stream = GetResourceStream(fileName);
-
- Icon icon = null;
-
- if (stream != null)
- {
- Image image = LoadImage(stream);
- icon = Icon.FromHandle(((Bitmap)image).GetHicon());
- image.Dispose();
- stream.Close();
- }
-
- return icon;
- }
-
- private static bool CheckForSignature(Stream input, IList<byte> signature)
- {
- long oldPos = input.Position;
- var inputSig = new byte[signature.Count];
- int amountRead = input.Read(inputSig, 0, inputSig.Length);
-
- bool foundSig = false;
- if (amountRead == signature.Count)
- {
- foundSig = true;
-
- for (int i = 0; i < signature.Count; ++i)
- {
- foundSig &= (signature[i] == inputSig[i]);
- }
- }
-
- input.Position = oldPos;
- return foundSig;
- }
-
- public static bool IsGdiPlusImageAllowed(Stream input)
- {
- var wmfSig = new byte[] { 0xd7, 0xcd, 0xc6, 0x9a };
- var emfSig = new byte[] { 0x01, 0x00, 0x00, 0x00 };
-
- // Check for and explicitely block WMF and EMF images
- return !(CheckForSignature(input, emfSig) || CheckForSignature(input, wmfSig));
- }
-
- public static Image LoadImage(string fileName)
- {
- using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
- {
- return LoadImage(stream);
- }
- }
-
- /// <summary>
- /// Loads an image from the given stream. The stream must be seekable.
- /// </summary>
- /// <param name="input">The Stream to load the image from.</param>
- public static Image LoadImage(Stream input)
- {
- /*
- if (!IsGdiPlusImageAllowed(input))
- {
- throw new IOException("File format is not supported");
- }
- */
-
- Image image = Image.FromStream(input);
-
- if (image.RawFormat == ImageFormat.Wmf || image.RawFormat == ImageFormat.Emf)
- {
- image.Dispose();
- throw new IOException("File format isn't supported");
- }
-
- return image;
- }
- }
- }