PageRenderTime 27ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/VfpMsBuildTarget/VsIntegration/SDK/Common/Source/CSharp/Project/SettingsPage.cs

#
C# | 431 lines | 346 code | 62 blank | 23 comment | 68 complexity | 4f1c1568a8714174da06079cdca8cc0f MD5 | raw file
  1. /***************************************************************************
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. This code is licensed under the Visual Studio SDK license terms.
  4. THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
  5. ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
  6. IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
  7. PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
  8. ***************************************************************************/
  9. using Microsoft.VisualStudio.OLE.Interop;
  10. using Microsoft.VisualStudio.Shell.Interop;
  11. using Microsoft.VisualStudio.Designer.Interfaces;
  12. using System;
  13. using System.Collections;
  14. using System.ComponentModel;
  15. using System.Drawing;
  16. using System.Globalization;
  17. using System.IO;
  18. using System.Runtime.InteropServices;
  19. using System.Windows.Forms;
  20. using System.Xml;
  21. using System.Diagnostics;
  22. using System.Security.Permissions;
  23. namespace Microsoft.VisualStudio.Package
  24. {
  25. /// <summary>
  26. /// The base class for property pages.
  27. /// </summary>
  28. [CLSCompliant(false), ComVisible(true)]
  29. public abstract class SettingsPage :
  30. Microsoft.VisualStudio.Package.LocalizableProperties,
  31. IPropertyPage
  32. {
  33. #region fields
  34. private Panel panel;
  35. private bool active;
  36. private bool dirty = false;
  37. private IPropertyPageSite site;
  38. private ProjectNode project;
  39. private ProjectConfig[] projectConfigs;
  40. private IVSMDPropertyGrid grid;
  41. private string name;
  42. #endregion
  43. #region properties
  44. [Browsable(false)]
  45. [AutomationBrowsable(false)]
  46. public string Name
  47. {
  48. get
  49. {
  50. return this.name;
  51. }
  52. set
  53. {
  54. this.name = value;
  55. }
  56. }
  57. [Browsable(false)]
  58. [AutomationBrowsable(false)]
  59. public ProjectNode ProjectMgr
  60. {
  61. get
  62. {
  63. return this.project;
  64. }
  65. }
  66. protected IVSMDPropertyGrid Grid
  67. {
  68. get { return this.grid; }
  69. }
  70. protected bool IsDirty
  71. {
  72. get
  73. {
  74. return this.dirty;
  75. }
  76. set
  77. {
  78. if (this.dirty != value)
  79. {
  80. this.dirty = value;
  81. if (this.site != null)
  82. site.OnStatusChange((uint)(this.dirty ? PropPageStatus.Dirty : PropPageStatus.Clean));
  83. }
  84. }
  85. }
  86. protected Panel ThePanel
  87. {
  88. get
  89. {
  90. return this.panel;
  91. }
  92. }
  93. #endregion
  94. #region abstract methods
  95. protected abstract void BindProperties();
  96. protected abstract int ApplyChanges();
  97. #endregion
  98. #region public methods
  99. public object GetTypedConfigProperty(string name, Type type)
  100. {
  101. string value = GetConfigProperty(name);
  102. if (string.IsNullOrEmpty(value)) return null;
  103. TypeConverter tc = TypeDescriptor.GetConverter(type);
  104. return tc.ConvertFromInvariantString(value);
  105. }
  106. public object GetTypedProperty(string name, Type type)
  107. {
  108. string value = GetProperty(name);
  109. if (string.IsNullOrEmpty(value)) return null;
  110. TypeConverter tc = TypeDescriptor.GetConverter(type);
  111. return tc.ConvertFromInvariantString(value);
  112. }
  113. public string GetProperty(string propertyName)
  114. {
  115. if (this.ProjectMgr != null)
  116. {
  117. string property = this.ProjectMgr.BuildProject.GlobalProperties[propertyName].Value;
  118. if (property != null)
  119. {
  120. return property;
  121. }
  122. }
  123. return String.Empty;
  124. }
  125. // relative to active configuration.
  126. public string GetConfigProperty(string propertyName)
  127. {
  128. if (this.ProjectMgr != null)
  129. {
  130. string unifiedResult = null;
  131. bool cacheNeedReset = true;
  132. for (int i = 0; i < this.projectConfigs.Length; i++)
  133. {
  134. ProjectConfig config = projectConfigs[i];
  135. string property = config.GetConfigurationProperty(propertyName, cacheNeedReset);
  136. cacheNeedReset = false;
  137. if (property != null)
  138. {
  139. string text = property.Trim();
  140. if (i == 0)
  141. unifiedResult = text;
  142. else if (unifiedResult != text)
  143. return ""; // tristate value is blank then
  144. }
  145. }
  146. return unifiedResult;
  147. }
  148. return String.Empty;
  149. }
  150. /// <summary>
  151. /// The set config property is robust in the sense that they will create the
  152. /// attributes if needed. If value is null it will set empty string.
  153. /// </summary>
  154. /// <param name="attrName"></param>
  155. /// <param name="value"></param>
  156. public void SetConfigProperty(string attrName, string value)
  157. {
  158. CCITracing.TraceCall();
  159. if (value == null)
  160. {
  161. value = String.Empty;
  162. }
  163. if (this.ProjectMgr != null)
  164. {
  165. for (int i = 0, n = this.projectConfigs.Length; i < n; i++)
  166. {
  167. ProjectConfig config = projectConfigs[i];
  168. config.SetConfigurationProperty(attrName, value);
  169. }
  170. this.ProjectMgr.SetProjectFileDirty(true);
  171. }
  172. }
  173. #endregion
  174. #region IPropertyPage methods.
  175. public virtual void Activate(IntPtr parent, RECT[] pRect, int bModal)
  176. {
  177. if (this.panel == null)
  178. {
  179. this.panel = new Panel();
  180. this.panel.Size = new Size(pRect[0].right - pRect[0].left, pRect[0].bottom - pRect[0].top);
  181. this.panel.Text = "Settings";// TODO localization
  182. this.panel.Visible = false;
  183. this.panel.Size = new Size(550, 300);
  184. this.panel.CreateControl();
  185. NativeMethods.SetParent(this.panel.Handle, parent);
  186. }
  187. if (this.grid == null && this.project != null && this.project.Site != null)
  188. {
  189. IVSMDPropertyBrowser pb = this.project.Site.GetService(typeof(IVSMDPropertyBrowser)) as IVSMDPropertyBrowser;
  190. this.grid = pb.CreatePropertyGrid();
  191. }
  192. if (this.grid != null)
  193. {
  194. this.active = true;
  195. Control cGrid = Control.FromHandle(new IntPtr(this.grid.Handle));
  196. cGrid.Parent = Control.FromHandle(parent);//this.panel;
  197. cGrid.Size = new Size(544, 294);
  198. cGrid.Location = new Point(3, 3);
  199. cGrid.Visible = true;
  200. this.grid.SetOption(_PROPERTYGRIDOPTION.PGOPT_TOOLBAR, false);
  201. this.grid.GridSort = _PROPERTYGRIDSORT.PGSORT_CATEGORIZED | _PROPERTYGRIDSORT.PGSORT_ALPHABETICAL;
  202. NativeMethods.SetParent(new IntPtr(this.grid.Handle), this.panel.Handle);
  203. UpdateObjects();
  204. }
  205. }
  206. public virtual int Apply()
  207. {
  208. if (IsDirty)
  209. {
  210. return this.ApplyChanges();
  211. }
  212. return VSConstants.S_OK;
  213. }
  214. public virtual void Deactivate()
  215. {
  216. if (null != this.panel)
  217. {
  218. this.panel.Dispose();
  219. this.panel = null;
  220. }
  221. this.active = false;
  222. }
  223. public virtual void GetPageInfo(PROPPAGEINFO[] arrInfo)
  224. {
  225. PROPPAGEINFO info = new PROPPAGEINFO();
  226. info.cb = (uint)Marshal.SizeOf(typeof(PROPPAGEINFO));
  227. info.dwHelpContext = 0;
  228. info.pszDocString = null;
  229. info.pszHelpFile = null;
  230. info.pszTitle = this.name;
  231. info.SIZE.cx = 550;
  232. info.SIZE.cy = 300;
  233. arrInfo[0] = info;
  234. }
  235. public virtual void Help(string helpDir)
  236. {
  237. }
  238. public virtual int IsPageDirty()
  239. {
  240. // Note this returns an HRESULT not a Bool.
  241. return (IsDirty ? (int)VSConstants.S_OK : (int)VSConstants.S_FALSE);
  242. }
  243. public virtual void Move(RECT[] arrRect)
  244. {
  245. RECT r = arrRect[0];
  246. this.panel.Location = new Point(r.left, r.top);
  247. this.panel.Size = new Size(r.right - r.left, r.bottom - r.top);
  248. }
  249. public virtual void SetObjects(uint count, object[] punk)
  250. {
  251. if (count > 0)
  252. {
  253. if (punk[0] is ProjectConfig)
  254. {
  255. ArrayList configs = new ArrayList();
  256. for (int i = 0; i < count; i++)
  257. {
  258. ProjectConfig config = (ProjectConfig)punk[i];
  259. if (this.project == null)
  260. {
  261. this.project = config.ProjectMgr;
  262. }
  263. configs.Add(config);
  264. }
  265. this.projectConfigs = (ProjectConfig[])configs.ToArray(typeof(ProjectConfig));
  266. }
  267. else if (punk[0] is NodeProperties)
  268. {
  269. if (this.project == null)
  270. {
  271. this.project = (punk[0] as NodeProperties).Node.ProjectMgr;
  272. }
  273. System.Collections.Generic.Dictionary<string, ProjectConfig> configsMap = new System.Collections.Generic.Dictionary<string, ProjectConfig>();
  274. for (int i = 0; i < count; i++)
  275. {
  276. NodeProperties property = (NodeProperties)punk[i];
  277. IVsCfgProvider provider;
  278. ErrorHandler.ThrowOnFailure(property.Node.ProjectMgr.GetCfgProvider(out provider));
  279. uint[] expected = new uint[1];
  280. ErrorHandler.ThrowOnFailure(provider.GetCfgs(0, null, expected, null));
  281. if (expected[0] > 0)
  282. {
  283. ProjectConfig[] configs = new ProjectConfig[expected[0]];
  284. uint[] actual = new uint[1];
  285. provider.GetCfgs(expected[0], configs, actual, null);
  286. foreach (ProjectConfig config in configs)
  287. {
  288. if (!configsMap.ContainsKey(config.ConfigName))
  289. {
  290. configsMap.Add(config.ConfigName, config);
  291. }
  292. }
  293. }
  294. }
  295. if (configsMap.Count > 0)
  296. {
  297. if (this.projectConfigs == null)
  298. {
  299. this.projectConfigs = new ProjectConfig[configsMap.Keys.Count];
  300. }
  301. configsMap.Values.CopyTo(this.projectConfigs, 0);
  302. }
  303. }
  304. }
  305. else
  306. {
  307. this.project = null;
  308. }
  309. if (this.active && this.project != null)
  310. {
  311. UpdateObjects();
  312. }
  313. }
  314. public virtual void SetPageSite(IPropertyPageSite theSite)
  315. {
  316. this.site = theSite;
  317. }
  318. public virtual void Show(uint cmd)
  319. {
  320. this.panel.Visible = true; // TODO: pass SW_SHOW* flags through
  321. this.panel.Show();
  322. }
  323. public virtual int TranslateAccelerator(MSG[] arrMsg)
  324. {
  325. MSG msg = arrMsg[0];
  326. if ((msg.message < NativeMethods.WM_KEYFIRST || msg.message > NativeMethods.WM_KEYLAST) && (msg.message < NativeMethods.WM_MOUSEFIRST || msg.message > NativeMethods.WM_MOUSELAST))
  327. return 1;
  328. return (NativeMethods.IsDialogMessageA(this.panel.Handle, ref msg)) ? 0 : 1;
  329. }
  330. #endregion
  331. #region helper methods
  332. protected ProjectConfig[] GetProjectConfigurations()
  333. {
  334. return this.projectConfigs;
  335. }
  336. protected void UpdateObjects()
  337. {
  338. if (this.projectConfigs != null && this.project != null)
  339. {
  340. // Demand unmanaged permissions in order to access unmanaged memory.
  341. new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
  342. IntPtr p = Marshal.GetIUnknownForObject(this);
  343. IntPtr ppUnk = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr)));
  344. try
  345. {
  346. Marshal.WriteIntPtr(ppUnk, p);
  347. this.BindProperties();
  348. // BUGBUG -- this is really bad casting a pointer to "int"...
  349. this.grid.SetSelectedObjects(1, ppUnk.ToInt32());
  350. this.grid.Refresh();
  351. }
  352. finally
  353. {
  354. if (ppUnk != IntPtr.Zero)
  355. {
  356. Marshal.FreeCoTaskMem(ppUnk);
  357. }
  358. if (p != IntPtr.Zero)
  359. {
  360. Marshal.Release(p);
  361. }
  362. }
  363. }
  364. }
  365. #endregion
  366. }
  367. }