PageRenderTime 47ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/ThemeOptionsControl.cs

#
C# | 272 lines | 234 code | 38 blank | 0 comment | 41 complexity | 52275be0442cd682c3787f8833573f15 MD5 | raw file
Possible License(s): Apache-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Threading;
  6. using System.Windows.Forms;
  7. using Microsoft.VisualStudio.ComponentModelHost;
  8. using Microsoft.VisualStudio.Editor;
  9. using Microsoft.VisualStudio.Shell;
  10. using Microsoft.VisualStudio.Text.Editor;
  11. using Microsoft.VisualStudio.TextManager.Interop;
  12. namespace IndentGuide {
  13. public partial class ThemeOptionsControl : UserControl {
  14. private readonly IndentGuideService Service;
  15. private readonly IVsTextManager TextManagerService;
  16. private readonly IVsEditorAdaptersFactoryService EditorAdapters;
  17. private static readonly List<IndentTheme> LocalThemes = new List<IndentTheme>();
  18. private static readonly List<IndentTheme> ChangedThemes = new List<IndentTheme>();
  19. private static readonly List<IndentTheme> DeletedThemes = new List<IndentTheme>();
  20. private readonly IThemeAwareDialog Child;
  21. public ThemeOptionsControl(IThemeAwareDialog child) {
  22. InitializeComponent();
  23. Child = child;
  24. var control = child as Control;
  25. Debug.Assert(Child != null);
  26. Debug.Assert(control != null);
  27. tableContent.Controls.Add(control);
  28. tableContent.SetColumn(control, 0);
  29. tableContent.SetRow(control, 1);
  30. Child.ThemeChanged += new EventHandler<ThemeEventArgs>(Child_ThemeChanged);
  31. var provider = ServiceProvider.GlobalProvider;
  32. Service = provider.GetService(typeof(SIndentGuide)) as IndentGuideService;
  33. Child.Service = (IIndentGuide)Service;
  34. TextManagerService = (IVsTextManager)provider.GetService(typeof(SVsTextManager));
  35. var componentModel = (IComponentModel)provider.GetService(typeof(SComponentModel));
  36. EditorAdapters = (IVsEditorAdaptersFactoryService)componentModel
  37. .GetService<IVsEditorAdaptersFactoryService>();
  38. }
  39. void Child_ThemeChanged(object sender, ThemeEventArgs e) {
  40. if (!ChangedThemes.Contains(e.Theme)) ChangedThemes.Add(e.Theme);
  41. }
  42. static int ActivationCount = 0;
  43. bool IsActive = false;
  44. internal void Activate() {
  45. if (!IsActive) {
  46. IsActive = true;
  47. if (Interlocked.Increment(ref ActivationCount) == 1) {
  48. try {
  49. LocalThemes.Clear();
  50. ChangedThemes.Clear();
  51. DeletedThemes.Clear();
  52. LocalThemes.Add(Service.DefaultTheme.Clone());
  53. LocalThemes.AddRange(Service.Themes.Values.Select(t => t.Clone()));
  54. UpdateThemeList();
  55. } catch (Exception ex) {
  56. Trace.WriteLine(string.Format("IndentGuide::Activate: {0}", ex));
  57. }
  58. }
  59. }
  60. UpdateThemeList();
  61. try {
  62. IVsTextView view = null;
  63. IWpfTextView wpfView = null;
  64. TextManagerService.GetActiveView(0, null, out view);
  65. if (view == null)
  66. CurrentContentType = null;
  67. else {
  68. wpfView = EditorAdapters.GetWpfTextView(view);
  69. CurrentContentType = wpfView.TextDataModel.ContentType.DisplayName;
  70. }
  71. } catch {
  72. CurrentContentType = null;
  73. }
  74. Child.Activate();
  75. ActiveTheme = LocalThemes.FirstOrDefault(theme => theme.ContentType == CurrentContentType);
  76. if (ActiveTheme == null)
  77. ActiveTheme = LocalThemes.FirstOrDefault(theme => theme.IsDefault);
  78. }
  79. internal void Apply() {
  80. Child.Apply();
  81. bool needsRefresh = false;
  82. if (ChangedThemes.Any()) {
  83. foreach (var theme in ChangedThemes) {
  84. theme.Apply();
  85. if (theme.IsDefault)
  86. Service.DefaultTheme = theme;
  87. else
  88. Service.Themes[theme.ContentType] = theme;
  89. }
  90. needsRefresh = true;
  91. ChangedThemes.Clear();
  92. }
  93. if (DeletedThemes.Any()) {
  94. foreach (var theme in DeletedThemes) {
  95. if (!theme.IsDefault)
  96. Service.Themes.Remove(theme.ContentType);
  97. }
  98. needsRefresh = true;
  99. DeletedThemes.Clear();
  100. }
  101. if (needsRefresh)
  102. Service.OnThemesChanged();
  103. }
  104. internal void Close() {
  105. if (Interlocked.Decrement(ref ActivationCount) == 0) {
  106. LocalThemes.Clear();
  107. ChangedThemes.Clear();
  108. DeletedThemes.Clear();
  109. }
  110. IsActive = false;
  111. }
  112. private static IndentTheme _ActiveTheme;
  113. protected IndentTheme ActiveTheme {
  114. get { return _ActiveTheme; }
  115. set {
  116. if (_ActiveTheme != value) {
  117. var old = _ActiveTheme;
  118. _ActiveTheme = value;
  119. Child.ActiveTheme = value;
  120. if (cmbTheme.SelectedItem != value)
  121. cmbTheme.SelectedItem = value;
  122. UpdateDisplay(_ActiveTheme, old);
  123. } else {
  124. UpdateDisplay(_ActiveTheme, _ActiveTheme);
  125. }
  126. }
  127. }
  128. private string _CurrentContentType;
  129. internal string CurrentContentType {
  130. get { return _CurrentContentType; }
  131. set {
  132. btnCustomizeThisContentType.Text = value ?? "";
  133. btnCustomizeThisContentType.Visible = (value != null);
  134. _CurrentContentType = value;
  135. }
  136. }
  137. private void btnCustomizeThisContentType_Click(object sender, EventArgs e) {
  138. try {
  139. var theme = LocalThemes.FirstOrDefault(t => t.ContentType != null &&
  140. t.ContentType.Equals(CurrentContentType, StringComparison.InvariantCultureIgnoreCase));
  141. if (theme == null) {
  142. if (ActiveTheme == null)
  143. theme = new IndentTheme();
  144. else
  145. theme = ActiveTheme.Clone();
  146. theme.ContentType = CurrentContentType;
  147. LocalThemes.Add(theme);
  148. ChangedThemes.Add(theme);
  149. DeletedThemes.RemoveAll(t => t.ContentType == theme.ContentType);
  150. UpdateThemeList();
  151. }
  152. cmbTheme.SelectedItem = theme;
  153. } catch (Exception ex) {
  154. Trace.WriteLine(string.Format("IndentGuide::btnCustomizeThisContentType_Click: {0}", ex));
  155. }
  156. }
  157. protected void UpdateThemeList() {
  158. try {
  159. LocalThemes.Sort();
  160. cmbTheme.Items.Clear();
  161. foreach (var theme in LocalThemes) {
  162. cmbTheme.Items.Add(theme);
  163. }
  164. cmbTheme.SelectedItem = ActiveTheme;
  165. } catch (Exception ex) {
  166. Trace.WriteLine(string.Format("IndentGuide::UpdateThemeList: {0}", ex));
  167. }
  168. }
  169. protected void LoadControlStrings(IEnumerable<Control> controls) {
  170. try {
  171. foreach (var control in controls) {
  172. try {
  173. control.Text = ResourceLoader.LoadString(control.Name) ?? control.Text;
  174. } catch (InvalidOperationException) { }
  175. if (control.Controls.Count > 0) {
  176. LoadControlStrings(control.Controls.OfType<Control>());
  177. }
  178. }
  179. } catch (Exception ex) {
  180. Trace.WriteLine(string.Format("IndentGuide::LoadControlStrings: {0}", ex));
  181. }
  182. }
  183. private void cmbTheme_Format(object sender, ListControlConvertEventArgs e) {
  184. try {
  185. e.Value = ((IndentTheme)e.ListItem).ContentType ?? IndentTheme.DefaultThemeName;
  186. } catch {
  187. e.Value = (e.ListItem ?? "(null)").ToString();
  188. }
  189. }
  190. protected void UpdateDisplay() {
  191. UpdateDisplay(ActiveTheme, ActiveTheme);
  192. }
  193. protected void UpdateDisplay(IndentTheme active, IndentTheme previous) {
  194. Child.Update(active, previous);
  195. }
  196. private void ThemeOptionsControl_Load(object sender, EventArgs e) {
  197. LoadControlStrings(Controls.OfType<Control>());
  198. toolTip.SetToolTip(btnCustomizeThisContentType, ResourceLoader.LoadString("tooltipCustomizeThisContentType"));
  199. }
  200. private void cmbTheme_SelectedIndexChanged(object sender, EventArgs e) {
  201. ActiveTheme = cmbTheme.SelectedItem as IndentTheme;
  202. if (ActiveTheme != null) {
  203. btnThemeDelete.Enabled = true;
  204. btnThemeDelete.Text = ResourceLoader.LoadString(ActiveTheme.IsDefault ? "btnThemeReset" : "btnThemeDelete");
  205. } else {
  206. btnThemeDelete.Enabled = false;
  207. btnThemeDelete.Text = ResourceLoader.LoadString("btnThemeReset");
  208. }
  209. UpdateDisplay();
  210. }
  211. private void btnThemeDelete_Click(object sender, EventArgs e) {
  212. if (ActiveTheme == null) return;
  213. try {
  214. if (ActiveTheme.IsDefault) {
  215. ChangedThemes.RemoveAll(theme => theme.IsDefault);
  216. LocalThemes.Remove(ActiveTheme);
  217. ActiveTheme = new IndentTheme();
  218. LocalThemes.Add(ActiveTheme);
  219. ChangedThemes.Add(ActiveTheme);
  220. UpdateThemeList();
  221. } else {
  222. DeletedThemes.Add(ActiveTheme);
  223. LocalThemes.Remove(ActiveTheme);
  224. int i = cmbTheme.SelectedIndex;
  225. cmbTheme.Items.Remove(ActiveTheme);
  226. if (i < cmbTheme.Items.Count) cmbTheme.SelectedIndex = i;
  227. else cmbTheme.SelectedIndex = cmbTheme.Items.Count - 1;
  228. }
  229. } catch (Exception ex) {
  230. Trace.WriteLine(string.Format("IndentGuide::btnThemeDelete_Click: {0}", ex));
  231. }
  232. }
  233. }
  234. }