The Labs \ Source Viewer \ SSCLI \ System.ComponentModel \ CultureComparer

  1. //------------------------------------------------------------------------------
  2. // <copyright file="CultureInfoConverter.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. /*
  16. */
  17. namespace System.ComponentModel
  18. {
  19.     using Microsoft.Win32;
  20.     using System.Collections;
  21.     using System.ComponentModel.Design.Serialization;
  22.     using System.Diagnostics;
  23.     using System.Globalization;
  24.     using System.Reflection;
  25.     using System.Runtime.Serialization.Formatters;
  26.     using System.Runtime.Remoting;
  27.     using System.Runtime.InteropServices;
  28.     using System.Threading;
  29.     using System.Security.Permissions;
  30.    
  31.     /// <devdoc>
  32.     /// <para>Provides a type converter to convert <see cref='System.Globalization.CultureInfo'/>
  33.     /// objects to and from various other representations.</para>
  34.     /// </devdoc>
  35.     [HostProtection(SharedState = true)]
  36.     public class CultureInfoConverter : TypeConverter
  37.     {
  38.        
  39.         private StandardValuesCollection values;
  40.        
  41.         /// <devdoc>
  42.         /// Retrieves the "default" name for our culture.
  43.         /// </devdoc>
  44.         private string DefaultCultureString {
  45.             get { return SR.GetString(SR.CultureInfoConverterDefaultCultureString); }
  46.         }
  47.        
  48.         /// <devdoc>
  49.         /// <para>
  50.         /// Gets a value indicating whether this converter can
  51.         /// convert an object in the given source type to a System.Globalization.CultureInfo
  52.         /// object using
  53.         /// the specified context.
  54.         /// </para>
  55.         /// </devdoc>
  56.         public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
  57.         {
  58.             if (sourceType == typeof(string)) {
  59.                 return true;
  60.             }
  61.             return base.CanConvertFrom(context, sourceType);
  62.         }
  63.        
  64.         /// <devdoc>
  65.         /// <para>Gets a value indicating whether this converter can
  66.         /// convert an object to the given destination type using the context.</para>
  67.         /// </devdoc>
  68.         public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
  69.         {
  70.             if (destinationType == typeof(InstanceDescriptor)) {
  71.                 return true;
  72.             }
  73.             return base.CanConvertTo(context, destinationType);
  74.         }
  75.        
  76.         /// <devdoc>
  77.         /// <para>
  78.         /// Converts the specified value object to a <see cref='System.Globalization.CultureInfo'/>
  79.         /// object.
  80.         /// </para>
  81.         /// </devdoc>
  82.         public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
  83.         {
  84.            
  85.             if (value is string) {
  86.                 string text = (string)value;
  87.                 CultureInfo retVal = null;
  88.                
  89.                 CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture;
  90.                
  91.                 if (culture != null && culture.Equals(CultureInfo.InvariantCulture)) {
  92.                     Thread.CurrentThread.CurrentUICulture = culture;
  93.                 }
  94.                
  95.                 try {
  96.                     // Look for the default culture info.
  97.                     //
  98.                     if (text == null || text.Length == 0 || string.Compare(text, DefaultCultureString, true, CultureInfo.CurrentCulture) == 0) {
  99.                         retVal = CultureInfo.InvariantCulture;
  100.                     }
  101.                    
  102.                     // Now look in our set of installed cultures.
  103.                     //
  104.                     if (retVal == null) {
  105.                         ICollection values = GetStandardValues(context);
  106.                         IEnumerator e = values.GetEnumerator();
  107.                         while (e.MoveNext()) {
  108.                             CultureInfo info = (CultureInfo)e.Current;
  109.                             if (info != null && string.Compare(info.DisplayName, text, true, CultureInfo.CurrentCulture) == 0) {
  110.                                 retVal = info;
  111.                                 break;
  112.                             }
  113.                         }
  114.                     }
  115.                    
  116.                     // Now try to create a new culture info from this value
  117.                     //
  118.                     if (retVal == null) {
  119.                         try {
  120.                             retVal = new CultureInfo(text);
  121.                         }
  122.                         catch {
  123.                         }
  124.                     }
  125.                    
  126.                     // Finally, try to find a partial match
  127.                     //
  128.                     if (retVal == null) {
  129.                         text = text.ToLower(CultureInfo.CurrentCulture);
  130.                         IEnumerator e = values.GetEnumerator();
  131.                         while (e.MoveNext()) {
  132.                             CultureInfo info = (CultureInfo)e.Current;
  133.                             if (info != null && info.DisplayName.ToLower(CultureInfo.CurrentCulture).StartsWith(text)) {
  134.                                 retVal = info;
  135.                                 break;
  136.                             }
  137.                         }
  138.                     }
  139.                 }
  140.                
  141.                 finally {
  142.                     Thread.CurrentThread.CurrentUICulture = currentUICulture;
  143.                 }
  144.                
  145.                 // No good. We can't support it.
  146.                 //
  147.                 if (retVal == null) {
  148.                     throw new ArgumentException(SR.GetString(SR.CultureInfoConverterInvalidCulture, (string)value));
  149.                 }
  150.                 return retVal;
  151.             }
  152.            
  153.             return base.ConvertFrom(context, culture, value);
  154.         }
  155.        
  156.         /// <devdoc>
  157.         /// <para>
  158.         /// Converts the given
  159.         /// value object to the
  160.         /// specified destination type.
  161.         /// </para>
  162.         /// </devdoc>
  163.         public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
  164.         {
  165.             if (destinationType == null) {
  166.                 throw new ArgumentNullException("destinationType");
  167.             }
  168.            
  169.             if (destinationType == typeof(string)) {
  170.                
  171.                 string retVal;
  172.                 CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture;
  173.                
  174.                 if (culture != null && culture.Equals(CultureInfo.InvariantCulture)) {
  175.                     Thread.CurrentThread.CurrentUICulture = culture;
  176.                 }
  177.                
  178.                 try {
  179.                     if (value == null || value == CultureInfo.InvariantCulture) {
  180.                         retVal = DefaultCultureString;
  181.                     }
  182.                     else {
  183.                         retVal = ((CultureInfo)value).DisplayName;
  184.                     }
  185.                 }
  186.                 finally {
  187.                     Thread.CurrentThread.CurrentUICulture = currentUICulture;
  188.                 }
  189.                
  190.                 return retVal;
  191.             }
  192.             if (destinationType == typeof(InstanceDescriptor) && value is CultureInfo) {
  193.                 CultureInfo c = (CultureInfo)value;
  194.                 ConstructorInfo ctor = typeof(CultureInfo).GetConstructor(new Type[] {typeof(string)});
  195.                 if (ctor != null) {
  196.                     return new InstanceDescriptor(ctor, new object[] {c.Name});
  197.                 }
  198.             }
  199.            
  200.             return base.ConvertTo(context, culture, value, destinationType);
  201.         }
  202.        
  203.         /// <devdoc>
  204.         /// <para>
  205.         /// Gets a collection of standard values collection for a System.Globalization.CultureInfo
  206.         /// object using the specified context.
  207.         /// </para>
  208.         /// </devdoc>
  209.         public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
  210.         {
  211.             if (values == null) {
  212.                 CultureInfo[] installedCultures = CultureInfo.GetCultures(CultureTypes.SpecificCultures | CultureTypes.NeutralCultures);
  213.                
  214.                 // Add Culture.InvariantCulture for a default culture, then sort the array.
  215.                 CultureInfo[] array = new CultureInfo[installedCultures.Length + 1];
  216.                 Array.Copy(installedCultures, array, installedCultures.Length);
  217.                 Array.Sort(array, new CultureComparer());
  218.                 Debug.Assert(array[0] == null);
  219.                 if (array[0] == null) {
  220.                     //we replace null with the real default culture because there are code paths
  221.                     // where the propgrid will send values from this returned array directly -- instead
  222.                     // of converting it to a string and then back to a value (which this relied on).
  223.                     array[0] = CultureInfo.InvariantCulture;
  224.                     //null isn't the value here -- invariantculture is.
  225.                 }
  226.                
  227.                 values = new StandardValuesCollection(array);
  228.             }
  229.            
  230.             return values;
  231.         }
  232.        
  233.         /// <devdoc>
  234.         /// <para>
  235.         /// Gets a value indicating whether the list of standard values returned from
  236.         /// System.ComponentModel.CultureInfoConverter.GetStandardValues is an exclusive list.
  237.         /// </para>
  238.         /// </devdoc>
  239.         public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
  240.         {
  241.             return false;
  242.         }
  243.        
  244.         /// <devdoc>
  245.         /// <para>
  246.         /// Gets a value indicating whether this object supports a
  247.         /// standard set of values that can be picked from a list using the specified
  248.         /// context.
  249.         /// </para>
  250.         /// </devdoc>
  251.         public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
  252.         {
  253.             return true;
  254.         }
  255.        
  256.         /// <devdoc>
  257.         /// IComparer object used for sorting CultureInfos
  258.         /// WARNING: If you change where null is positioned, then you must fix CultureConverter.GetStandardValues!
  259.         /// </devdoc>
  260.         private class CultureComparer : IComparer
  261.         {
  262.            
  263.             public int Compare(object item1, object item2)
  264.             {
  265.                
  266.                 if (item1 == null) {
  267.                    
  268.                     // If both are null, then they are equal
  269.                     //
  270.                     if (item2 == null) {
  271.                         return 0;
  272.                     }
  273.                    
  274.                     // Otherwise, item1 is null, but item2 is valid (greater)
  275.                     //
  276.                     return -1;
  277.                 }
  278.                
  279.                 if (item2 == null) {
  280.                    
  281.                     // item2 is null, so item 1 is greater
  282.                     //
  283.                     return 1;
  284.                 }
  285.                
  286.                 string itemName1 = ((CultureInfo)item1).DisplayName;
  287.                 string itemName2 = ((CultureInfo)item2).DisplayName;
  288.                
  289.                 CompareInfo compInfo = (CultureInfo.CurrentCulture).CompareInfo;
  290.                 return compInfo.Compare(itemName1, itemName2, CompareOptions.StringSort);
  291.             }
  292.         }
  293.     }
  294. }

Developer Fusion