/Main/Source/SandcastleBuilderUtils/Design/PresentationStyleTypeConverter.cs

# · C# · 237 lines · 116 code · 33 blank · 88 comment · 20 complexity · d8446992ee5fb7b22c331e326bebb7eb MD5 · raw file

  1. //=============================================================================
  2. // System : EWSoftware Design Time Attributes and Editors
  3. // File : PresenationStyleTypeConverter.cs
  4. // Author : Eric Woodruff (Eric@EWoodruff.us)
  5. // Updated : 04/09/2011
  6. // Note : Copyright 2007-2011, Eric Woodruff, All rights reserved
  7. // Compiler: Microsoft Visual C#
  8. //
  9. // This file contains a type converter that allows you to select a presentation
  10. // style folder from those currently installed in the .\Presentation folder
  11. // found in the main installation folder of Sandcastle.
  12. //
  13. // This code is published under the Microsoft Public License (Ms-PL). A copy
  14. // of the license should be distributed with the code. It can also be found
  15. // at the project website: http://SHFB.CodePlex.com. This notice, the
  16. // author's name, and all copyright notices must remain intact in all
  17. // applications, documentation, and source files.
  18. //
  19. // Version Date Who Comments
  20. // ============================================================================
  21. // 1.0.0.0 08/08/2006 EFW Created the code
  22. // 1.5.0.0 06/19/2007 EFW Updated for use with the June CTP
  23. //=============================================================================
  24. using System;
  25. using System.Collections.Generic;
  26. using System.ComponentModel;
  27. using System.Globalization;
  28. using System.IO;
  29. using System.Text.RegularExpressions;
  30. using SandcastleBuilder.Utils.BuildEngine;
  31. namespace SandcastleBuilder.Utils.Design
  32. {
  33. /// <summary>
  34. /// This type converter allows you to select a presentation style folder
  35. /// from those currently installed in the <b>.\Presentation</b> folder
  36. /// found in the main installation folder of Sandcastle.
  37. /// </summary>
  38. public sealed class PresentationStyleTypeConverter : StringConverter
  39. {
  40. #region Private data members
  41. //=====================================================================
  42. private static List<string> styles = new List<string>();
  43. private static StandardValuesCollection standardValues = InitializeStandardValues();
  44. #endregion
  45. #region Properties
  46. //=====================================================================
  47. #region Properties
  48. //=====================================================================
  49. /// <summary>
  50. /// This read-only property returns the values in the collection
  51. /// </summary>
  52. public static IEnumerable<string> StandardValues
  53. {
  54. get { return styles; }
  55. }
  56. #endregion
  57. /// <summary>
  58. /// This returns the default style
  59. /// </summary>
  60. /// <value>Returns <b>vs2005</b> if present. If not, it returns the
  61. /// first best match or, failing that, the first style in the list.</value>
  62. public static string DefaultStyle
  63. {
  64. get
  65. {
  66. string defaultStyle = "vs2005";
  67. if(!IsPresent(defaultStyle))
  68. defaultStyle = FirstMatching(defaultStyle);
  69. return defaultStyle;
  70. }
  71. }
  72. #endregion
  73. #region Methods
  74. //=====================================================================
  75. /// <summary>
  76. /// This is used to get the standard values by searching for the
  77. /// .NET Framework versions installed on the current system.
  78. /// </summary>
  79. private static StandardValuesCollection InitializeStandardValues()
  80. {
  81. string folder;
  82. try
  83. {
  84. // Try the DXROOT environment variable first
  85. folder = Environment.GetEnvironmentVariable("DXROOT");
  86. if(String.IsNullOrEmpty(folder) || !folder.Contains(@"\Sandcastle"))
  87. folder = String.Empty;
  88. // Try to find Sandcastle based on the path if not there
  89. if(folder.Length == 0)
  90. {
  91. Match m = Regex.Match(Environment.GetEnvironmentVariable("PATH"),
  92. @"[A-Z]:\\.[^;]+\\Sandcastle(?=\\Prod)", RegexOptions.IgnoreCase);
  93. // If not found in the path, search all fixed drives
  94. if(m.Success)
  95. folder = m.Value;
  96. else
  97. {
  98. folder = BuildProcess.FindOnFixedDrives(@"\Sandcastle");
  99. // If not found there, try the VS 2005 SDK folders
  100. if(folder.Length == 0)
  101. {
  102. folder = BuildProcess.FindSdkExecutable("MRefBuilder.exe");
  103. if(folder.Length != 0)
  104. folder = folder.Substring(0, folder.LastIndexOf('\\'));
  105. }
  106. }
  107. }
  108. if(folder.Length != 0)
  109. {
  110. folder += @"\Presentation";
  111. // The Shared folder is omitted as it contains files
  112. // common to all presentation styles.
  113. foreach(string s in Directory.EnumerateDirectories(folder))
  114. if(!s.EndsWith("Shared", StringComparison.Ordinal))
  115. styles.Add(s.Substring(s.LastIndexOf('\\') + 1));
  116. }
  117. }
  118. catch(Exception)
  119. {
  120. // Eat the exception. If we can't find Sandcastle here, the
  121. // build will fail too so the user will be notified then.
  122. }
  123. // Add the three basic styles as placeholders if nothing was found.
  124. // The build will fail but the project will still load.
  125. if(styles.Count == 0)
  126. {
  127. styles.Add("hana");
  128. styles.Add("Prototype");
  129. styles.Add("vs2005");
  130. }
  131. styles.Sort();
  132. return new StandardValuesCollection(styles);
  133. }
  134. /// <summary>
  135. /// This is overridden to return the values for the type converter's
  136. /// dropdown list.
  137. /// </summary>
  138. /// <param name="context">The format context object</param>
  139. /// <returns>Returns the standard values for the type</returns>
  140. public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
  141. {
  142. return standardValues;
  143. }
  144. /// <summary>
  145. /// This is overridden to indicate that the values are exclusive
  146. /// and values outside the list cannot be entered.
  147. /// </summary>
  148. /// <param name="context">The format context object</param>
  149. /// <returns>Always returns true</returns>
  150. public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
  151. {
  152. return true;
  153. }
  154. /// <summary>
  155. /// This is overridden to indicate that standard values are supported
  156. /// and can be chosen from a list.
  157. /// </summary>
  158. /// <param name="context">The format context object</param>
  159. /// <returns>Always returns true</returns>
  160. public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
  161. {
  162. return true;
  163. }
  164. /// <summary>
  165. /// This is used to find out if the specified style is present on the
  166. /// system.
  167. /// </summary>
  168. /// <param name="style">The style for which to look</param>
  169. /// <returns>True if present, false if not found</returns>
  170. public static bool IsPresent(string style)
  171. {
  172. return styles.Contains(style);
  173. }
  174. /// <summary>
  175. /// This is used to get the first style that matches case-insensitively
  176. /// or, failing that, starts with or contains the given value
  177. /// case-insensitively.
  178. /// </summary>
  179. /// <param name="style">The style for which to look</param>
  180. /// <returns>The best match or the first style if not found.</returns>
  181. public static string FirstMatching(string style)
  182. {
  183. string compareStyle;
  184. if(!String.IsNullOrEmpty(style))
  185. {
  186. // Try for a case-insensitive match first
  187. foreach(string s in styles)
  188. if(String.Compare(s, style, StringComparison.OrdinalIgnoreCase) == 0)
  189. return s;
  190. // Try for the closest match
  191. style = style.ToLower(CultureInfo.InvariantCulture);
  192. foreach(string s in styles)
  193. {
  194. compareStyle = s.ToLower(CultureInfo.InvariantCulture);
  195. if(compareStyle.StartsWith(style, StringComparison.Ordinal) || compareStyle.Contains(style))
  196. return s;
  197. }
  198. }
  199. // Not found, return the first style
  200. return styles[0];
  201. }
  202. #endregion
  203. }
  204. }