PageRenderTime 71ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Dialogs/MimeTypePolicyOptionsSection.cs

https://github.com/louissalin/monodevelop
C# | 400 lines | 315 code | 55 blank | 30 comment | 65 complexity | 92c77ef7d4d4dd00363370e41abb8e31 MD5 | raw file
  1. //
  2. // IMimeTypePolicyOptionsPanel.cs
  3. //
  4. // Author:
  5. // Lluis Sanchez Gual <lluis@novell.com>
  6. //
  7. // Copyright (c) 2009 Novell, Inc (http://www.novell.com)
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining a copy
  10. // of this software and associated documentation files (the "Software"), to deal
  11. // in the Software without restriction, including without limitation the rights
  12. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. // copies of the Software, and to permit persons to whom the Software is
  14. // furnished to do so, subject to the following conditions:
  15. //
  16. // The above copyright notice and this permission notice shall be included in
  17. // all copies or substantial portions of the Software.
  18. //
  19. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. // THE SOFTWARE.
  26. using System;
  27. using System.Collections.Generic;
  28. using Gtk;
  29. using System.Linq;
  30. using Mono.Addins;
  31. using MonoDevelop.Core;
  32. using MonoDevelop.Ide.Gui.Dialogs;
  33. using MonoDevelop.Projects;
  34. using MonoDevelop.Projects.Policies;
  35. using MonoDevelop.Ide.Extensions;
  36. namespace MonoDevelop.Ide.Gui.Dialogs
  37. {
  38. class MimeTypePolicyOptionsSection: OptionsPanel
  39. {
  40. ComboBox policyCombo;
  41. ListStore store;
  42. PolicyBag bag;
  43. PolicySet polSet;
  44. bool loading = true;
  45. string mimeType;
  46. List<IMimeTypePolicyOptionsPanel> panels;
  47. MimeTypePanelData panelData;
  48. Notebook notebook;
  49. bool isRoot;
  50. HBox warningMessage;
  51. bool isGlobalPolicy;
  52. List<PolicySet> setsInCombo = new List<PolicySet> ();
  53. bool synchingPoliciesCombo;
  54. bool selectingPolicy;
  55. public MimeTypePolicyOptionsSection ()
  56. {
  57. }
  58. public override void Initialize (MonoDevelop.Ide.Gui.Dialogs.OptionsDialog dialog, object dataObject)
  59. {
  60. base.Initialize (dialog, dataObject);
  61. panelData = (MimeTypePanelData) dataObject;
  62. IPolicyProvider provider = panelData.DataObject as IPolicyProvider;
  63. if (provider == null) {
  64. provider = PolicyService.GetUserDefaultPolicySet ();
  65. isGlobalPolicy = true;
  66. }
  67. bag = provider.Policies as PolicyBag;
  68. polSet = provider.Policies as PolicySet;
  69. mimeType = panelData.MimeType;
  70. panelData.SectionPanel = this;
  71. isRoot = polSet != null || bag.IsRoot;
  72. if (IsCustomUserPolicy)
  73. isRoot = false;
  74. }
  75. public override Widget CreatePanelWidget ()
  76. {
  77. HBox hbox = new HBox (false, 6);
  78. Label label = new Label ();
  79. label.MarkupWithMnemonic = GettextCatalog.GetString ("_Policy:");
  80. hbox.PackStart (label, false, false, 0);
  81. store = new ListStore (typeof (string), typeof (PolicySet));
  82. policyCombo = new ComboBox (store);
  83. CellRenderer renderer = new CellRendererText ();
  84. policyCombo.PackStart (renderer, true);
  85. policyCombo.AddAttribute (renderer, "text", 0);
  86. label.MnemonicWidget = policyCombo;
  87. policyCombo.RowSeparatorFunc = (TreeModel model, TreeIter iter) =>
  88. ((string) model.GetValue (iter, 0)) == "--";
  89. hbox.PackStart (policyCombo, false, false, 0);
  90. VBox vbox = new VBox (false, 6);
  91. vbox.PackStart (hbox, false, false, 0);
  92. vbox.ShowAll ();
  93. // Warning message to be shown when the user modifies the default policy
  94. warningMessage = new HBox ();
  95. warningMessage.Spacing = 6;
  96. Image img = new Image (Gtk.Stock.DialogWarning, IconSize.LargeToolbar);
  97. warningMessage.PackStart (img, false, false, 0);
  98. Label wl = new Label (GettextCatalog.GetString ("Changes done in this section will only be applied to new projects. " +
  99. "Settings for existing projects can be modified in the project (or solution) options dialog."));
  100. wl.Xalign = 0;
  101. wl.Wrap = true;
  102. wl.WidthRequest = 450;
  103. warningMessage.PackStart (wl, true, true, 0);
  104. warningMessage.ShowAll ();
  105. warningMessage.Visible = false;
  106. vbox.PackEnd (warningMessage, false, false, 0);
  107. notebook = new Notebook ();
  108. // Get the panels for all mime types
  109. List<string> types = new List<string> ();
  110. types.AddRange (DesktopService.GetMimeTypeInheritanceChain (mimeType));
  111. panelData.SectionLoaded = true;
  112. panels = panelData.Panels;
  113. foreach (IMimeTypePolicyOptionsPanel panel in panelData.Panels) {
  114. panel.SetParentSection (this);
  115. Widget child = panel.CreateMimePanelWidget ();
  116. Label tlabel = new Label (panel.Label);
  117. label.Show ();
  118. child.Show ();
  119. Alignment align = new Alignment (0.5f, 0.5f, 1f, 1f);
  120. align.BorderWidth = 6;
  121. align.Add (child);
  122. align.Show ();
  123. notebook.AppendPage (align, tlabel);
  124. panel.LoadCurrentPolicy ();
  125. }
  126. notebook.Show ();
  127. vbox.PackEnd (notebook, true, true, 0);
  128. FillPolicies ();
  129. policyCombo.Active = 0;
  130. loading = false;
  131. if (!isRoot && panelData.UseParentPolicy) {
  132. //in this case "parent" is always first in the list
  133. policyCombo.Active = 0;
  134. notebook.Sensitive = false;
  135. } else {
  136. UpdateSelectedNamedPolicy ();
  137. }
  138. policyCombo.Changed += HandlePolicyComboChanged;
  139. return vbox;
  140. }
  141. void HandlePolicyComboChanged (object sender, EventArgs e)
  142. {
  143. if (loading || synchingPoliciesCombo)
  144. return;
  145. selectingPolicy = true;
  146. try {
  147. if (policyCombo.Active == 0 && !isRoot) {
  148. panelData.UseParentPolicy = true;
  149. notebook.Sensitive = false;
  150. }
  151. else {
  152. string activeName = policyCombo.ActiveText;
  153. PolicySet pset = PolicyService.GetPolicySet (activeName);
  154. if (pset != null)
  155. panelData.AssignPolicies (pset);
  156. else
  157. panelData.UseParentPolicy = false;
  158. notebook.Sensitive = true;
  159. }
  160. } finally {
  161. selectingPolicy = false;
  162. }
  163. }
  164. public void FillPolicies ()
  165. {
  166. if (selectingPolicy)
  167. return;
  168. ((ListStore)store).Clear ();
  169. if (IsCustomUserPolicy) {
  170. store.AppendValues (GettextCatalog.GetString ("System Default"), null);
  171. store.AppendValues ("--", null);
  172. } else if (!isRoot) {
  173. store.AppendValues (GettextCatalog.GetString ("Inherited Policy"), null);
  174. store.AppendValues ("--", null);
  175. }
  176. setsInCombo.Clear ();
  177. foreach (PolicySet set in panelData.GetSupportedPolicySets ()) {
  178. if (polSet != null && polSet.Name == set.Name)
  179. continue;
  180. store.AppendValues (set.Name, set);
  181. setsInCombo.Add (set);
  182. }
  183. if (setsInCombo.Count > 0)
  184. store.AppendValues ("--", null);
  185. store.AppendValues (GettextCatalog.GetString ("Custom"), null);
  186. }
  187. public void UpdateSelectedNamedPolicy ()
  188. {
  189. if (selectingPolicy)
  190. return;
  191. synchingPoliciesCombo = true;
  192. try {
  193. // Find a policy set which is common to all policy types
  194. if (!isRoot && panelData.UseParentPolicy) {
  195. policyCombo.Active = 0;
  196. return;
  197. }
  198. int active = -1;
  199. PolicySet matchedSet = panelData.GetMatchingSet (setsInCombo);
  200. TreeIter iter;
  201. int i = 0;
  202. if (matchedSet != null && store.GetIterFirst (out iter)) {
  203. do {
  204. PolicySet s2 = store.GetValue (iter, 1) as PolicySet;
  205. if (s2 != null && s2.Id == matchedSet.Id) {
  206. active = i;
  207. break;
  208. }
  209. i++;
  210. } while (store.IterNext (ref iter));
  211. }
  212. if (active != -1)
  213. policyCombo.Active = active;
  214. else
  215. policyCombo.Active = store.IterNChildren () - 1;
  216. warningMessage.Visible = isGlobalPolicy && panelData.Modified;
  217. } finally {
  218. synchingPoliciesCombo = false;
  219. }
  220. }
  221. bool IsCustomUserPolicy {
  222. get { return ParentDialog is MonoDevelop.Ide.Projects.DefaultPolicyOptionsDialog; }
  223. }
  224. public override bool IsVisible ()
  225. {
  226. return bag != null || polSet != null;
  227. }
  228. public override bool ValidateChanges ()
  229. {
  230. foreach (IMimeTypePolicyOptionsPanel panel in panels)
  231. if (!panel.ValidateChanges ())
  232. return false;
  233. return true;
  234. }
  235. public override void ApplyChanges ()
  236. {
  237. panelData.ApplyChanges ();
  238. }
  239. }
  240. class MimeTypePanelData
  241. {
  242. public string MimeType;
  243. public object DataObject;
  244. public string TypeDescription;
  245. public OptionsDialogSection Section;
  246. public MimeTypePolicyOptionsSection SectionPanel;
  247. public List<IMimeTypePolicyOptionsPanel> Panels;
  248. public bool SectionLoaded;
  249. public PolicyContainer PolicyContainer;
  250. public void ApplyChanges ()
  251. {
  252. if (UseParentPolicy) {
  253. foreach (IMimeTypePolicyOptionsPanel panel in Panels)
  254. panel.RemovePolicy (PolicyContainer);
  255. } else {
  256. foreach (IMimeTypePolicyOptionsPanel panel in Panels) {
  257. if (SectionLoaded)
  258. panel.ApplyChanges ();
  259. panel.StorePolicy ();
  260. }
  261. }
  262. }
  263. public PolicySet GetMatchingSet (IEnumerable<PolicySet> candidateSets)
  264. {
  265. // Find a policy set which is common to all policy types
  266. PolicySet matchedSet = null;
  267. bool firstMatch = true;
  268. foreach (IMimeTypePolicyOptionsPanel panel in Panels) {
  269. PolicySet s = panel.GetMatchingSet (candidateSets);
  270. if (firstMatch) {
  271. matchedSet = s;
  272. firstMatch = false;
  273. }
  274. else if (matchedSet != s) {
  275. matchedSet = null;
  276. break;
  277. }
  278. }
  279. return matchedSet;
  280. }
  281. public bool Modified {
  282. get {
  283. return Panels.Any (p => p.Modified);
  284. }
  285. }
  286. public IEnumerable<PolicySet> GetSupportedPolicySets ()
  287. {
  288. HashSet<PolicySet> commonSets = null;
  289. foreach (IMimeTypePolicyOptionsPanel panel in Panels) {
  290. HashSet<PolicySet> sets = new HashSet<PolicySet> ();
  291. foreach (PolicySet pset in panel.GetPolicySets ())
  292. sets.Add (pset);
  293. if (commonSets == null)
  294. commonSets = sets;
  295. else
  296. commonSets.IntersectWith (sets);
  297. }
  298. if (commonSets != null)
  299. return commonSets;
  300. else
  301. return new PolicySet[0];
  302. }
  303. bool useParentPolicy;
  304. public bool UseParentPolicy {
  305. get {
  306. return useParentPolicy;
  307. }
  308. set {
  309. if (useParentPolicy != value) {
  310. useParentPolicy = value;
  311. if (useParentPolicy) {
  312. foreach (IMimeTypePolicyOptionsPanel panel in Panels)
  313. panel.LoadParentPolicy ();
  314. }
  315. if (SectionLoaded)
  316. SectionPanel.UpdateSelectedNamedPolicy ();
  317. }
  318. }
  319. }
  320. public void SetUseParentPolicy (bool useParentPolicy, System.Type policyType, string scope)
  321. {
  322. if (useParentPolicy == this.useParentPolicy)
  323. return;
  324. this.useParentPolicy = useParentPolicy;
  325. if (useParentPolicy) {
  326. foreach (IMimeTypePolicyOptionsPanel panel in Panels) {
  327. if (panel.HandlesPolicyType (policyType, scope))
  328. panel.LoadParentPolicy ();
  329. }
  330. }
  331. if (SectionLoaded)
  332. SectionPanel.UpdateSelectedNamedPolicy ();
  333. }
  334. public void AssignPolicies (PolicySet pset)
  335. {
  336. useParentPolicy = false;
  337. foreach (IMimeTypePolicyOptionsPanel panel in Panels)
  338. panel.LoadSetPolicy (pset);
  339. if (SectionLoaded) {
  340. SectionPanel.FillPolicies ();
  341. SectionPanel.UpdateSelectedNamedPolicy ();
  342. }
  343. }
  344. }
  345. }