PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/ToolboxProvider.cs

http://github.com/icsharpcode/SharpDevelop
C# | 298 lines | 242 code | 31 blank | 25 comment | 65 complexity | bac37765616d046a1b7ef02f4119da0a MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, CPL-1.0, LGPL-2.1
  1. // Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4. // software and associated documentation files (the "Software"), to deal in the Software
  5. // without restriction, including without limitation the rights to use, copy, modify, merge,
  6. // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7. // to whom the Software is furnished to do so, subject to the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be included in all copies or
  10. // substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  13. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  14. // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
  15. // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  16. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  17. // DEALINGS IN THE SOFTWARE.
  18. using System;
  19. using System.Collections.Generic;
  20. using System.Drawing.Design;
  21. using System.Diagnostics;
  22. using System.IO;
  23. using System.Linq;
  24. using System.Reflection;
  25. using ICSharpCode.Core;
  26. using ICSharpCode.NRefactory.TypeSystem;
  27. using ICSharpCode.FormsDesigner.Gui;
  28. using ICSharpCode.SharpDevelop;
  29. using ICSharpCode.SharpDevelop.Gui;
  30. using ICSharpCode.SharpDevelop.Project;
  31. using ICSharpCode.SharpDevelop.Widgets.SideBar;
  32. namespace ICSharpCode.FormsDesigner
  33. {
  34. public class ToolboxProvider
  35. {
  36. static ICSharpCode.FormsDesigner.Services.ToolboxService toolboxService = null;
  37. static SharpDevelopSideBar sideBar;
  38. static CustomComponentsSideTab customTab;
  39. static ComponentLibraryLoader componentLibraryLoader = new ComponentLibraryLoader();
  40. public static ComponentLibraryLoader ComponentLibraryLoader {
  41. get {
  42. return componentLibraryLoader;
  43. }
  44. }
  45. public static ICSharpCode.FormsDesigner.Services.ToolboxService ToolboxService {
  46. get {
  47. CreateToolboxService();
  48. return toolboxService;
  49. }
  50. }
  51. public static SharpDevelopSideBar FormsDesignerSideBar {
  52. get {
  53. CreateToolboxService();
  54. return sideBar;
  55. }
  56. }
  57. static void CreateToolboxService()
  58. {
  59. SD.MainThread.VerifyAccess();
  60. if (toolboxService == null) {
  61. sideBar = new SharpDevelopSideBar();
  62. LoadToolbox();
  63. toolboxService = new ICSharpCode.FormsDesigner.Services.ToolboxService();
  64. ReloadSideTabs(false);
  65. toolboxService.SelectedItemUsed += new EventHandler(SelectedToolUsedHandler);
  66. sideBar.SideTabDeleted += SideTabDeleted;
  67. }
  68. }
  69. static string componentLibraryFile = "SharpDevelopControlLibrary.sdcl";
  70. static string GlobalConfigFile {
  71. get {
  72. return PropertyService.DataDirectory + Path.DirectorySeparatorChar +
  73. "options" + Path.DirectorySeparatorChar +
  74. componentLibraryFile;
  75. }
  76. }
  77. static string UserConfigFile {
  78. get {
  79. return Path.Combine(PropertyService.ConfigDirectory, componentLibraryFile);
  80. }
  81. }
  82. public static void SaveToolbox()
  83. {
  84. componentLibraryLoader.SaveToolComponentLibrary(UserConfigFile);
  85. }
  86. public static void LoadToolbox()
  87. {
  88. if (!componentLibraryLoader.LoadToolComponentLibrary(UserConfigFile)) {
  89. if (!componentLibraryLoader.LoadToolComponentLibrary(GlobalConfigFile)) {
  90. MessageService.ShowWarning("${res:ICSharpCode.SharpDevelop.FormDesigner.ToolboxProvider.CantLoadSidbarComponentLibraryWarning}");
  91. }
  92. }
  93. }
  94. public static void ReloadSideTabs(bool doInsert)
  95. {
  96. CreateToolboxService();
  97. sideBar.Tabs.Clear();
  98. foreach (Category category in componentLibraryLoader.Categories) {
  99. if (category.IsEnabled) {
  100. try {
  101. SideTabDesigner newTab = new SideTabDesigner(sideBar, category, toolboxService);
  102. newTab.ItemRemoved += SideTabItemRemoved;
  103. newTab.ItemsExchanged += SideTabItemsExchanged;
  104. sideBar.Tabs.Add(newTab);
  105. } catch (Exception e) {
  106. SD.Log.Warn("Can't add tab : " + e);
  107. }
  108. }
  109. }
  110. if (customTab != null) {
  111. customTab.Dispose();
  112. }
  113. customTab = new CustomComponentsSideTab(sideBar, ResourceService.GetString("ICSharpCode.SharpDevelop.FormDesigner.ToolboxProvider.CustomComponents"), toolboxService);
  114. customTab.ItemRemoved += SideTabItemRemoved;
  115. customTab.ItemsExchanged += SideTabItemsExchanged;
  116. sideBar.Tabs.Add(customTab);
  117. sideBar.ActiveTab = customTab;
  118. // Clear selected toolbox item after reloading the tabs.
  119. toolboxService.SetSelectedToolboxItem(null);
  120. }
  121. static ICompilation GetCompilationForCurrentProject()
  122. {
  123. IProject project = SD.ProjectService.CurrentProject;
  124. if (project == null) return null;
  125. return SD.ParserService.GetCompilation(project);
  126. }
  127. static void SelectedToolUsedHandler(object sender, EventArgs e)
  128. {
  129. SD.Log.Debug("SelectedToolUsedHandler");
  130. SideTab tab = sideBar.ActiveTab;
  131. // try to add project reference
  132. if (sender is ICSharpCode.FormsDesigner.Services.ToolboxService) {
  133. ToolboxItem selectedItem = ((IToolboxService)sender).GetSelectedToolboxItem();
  134. if (tab is CustomComponentsSideTab) {
  135. if (selectedItem != null && selectedItem.TypeName != null) {
  136. SD.Log.Debug("Checking for reference to CustomComponent: " + selectedItem.TypeName);
  137. // Check current project has the custom component first.
  138. ICompilation currentCompilation = GetCompilationForCurrentProject();
  139. var typeName = new FullTypeName(selectedItem.TypeName);
  140. if (currentCompilation != null && currentCompilation.FindType(typeName).Kind == TypeKind.Unknown) {
  141. // Check other projects in the solution.
  142. SD.Log.Debug("Checking other projects in the solution.");
  143. IProject projectContainingType = FindProjectContainingType(typeName);
  144. if (projectContainingType != null) {
  145. AddProjectReferenceToProject(SD.ProjectService.CurrentProject, projectContainingType);
  146. }
  147. }
  148. }
  149. } else {
  150. if (selectedItem != null && selectedItem.AssemblyName != null) {
  151. IProject currentProject = ProjectService.CurrentProject;
  152. if (currentProject != null) {
  153. if (!ProjectContainsReference(currentProject, selectedItem.AssemblyName)) {
  154. AddReferenceToProject(currentProject, selectedItem.AssemblyName);
  155. }
  156. }
  157. }
  158. }
  159. }
  160. if (tab.Items.Count > 0) {
  161. tab.ChosenItem = tab.Items[0];
  162. }
  163. sideBar.Refresh();
  164. }
  165. static bool ProjectContainsReference(IProject project, AssemblyName referenceName)
  166. {
  167. LoggingService.Debug("Checking project has reference: " + referenceName.FullName);
  168. bool isAlreadyInRefFolder = false;
  169. foreach (ProjectItem projectItem in project.Items) {
  170. ReferenceProjectItem referenceItem = projectItem as ReferenceProjectItem;
  171. if (referenceItem != null) {
  172. if (referenceItem.ItemType == ItemType.Reference) {
  173. LoggingService.Debug("Checking project reference: " + referenceItem.Include);
  174. if (referenceItem.HintPath.Length > 0 && File.Exists(referenceItem.FileName)) {
  175. LoggingService.Debug("Checking assembly reference");
  176. AssemblyName assemblyName = GetAssemblyName(referenceItem.FileName);
  177. if (assemblyName != null && assemblyName.FullName == referenceName.FullName) {
  178. isAlreadyInRefFolder = true;
  179. break;
  180. }
  181. } else { // GAC reference.
  182. LoggingService.Debug("Checking GAC reference");
  183. if (referenceItem.Include == referenceName.FullName || referenceItem.Include == referenceName.Name) {
  184. LoggingService.Debug("Found existing GAC reference");
  185. isAlreadyInRefFolder = true;
  186. break;
  187. }
  188. }
  189. }
  190. }
  191. }
  192. return isAlreadyInRefFolder;
  193. }
  194. static AssemblyName GetAssemblyName(string fileName)
  195. {
  196. try {
  197. return AssemblyName.GetAssemblyName(fileName);
  198. } catch (Exception ex) {
  199. LoggingService.Debug(ex.ToString());
  200. }
  201. return null;
  202. }
  203. static void AddReferenceToProject(IProject project, AssemblyName referenceName)
  204. {
  205. LoggingService.Warn("Adding reference to project: " + referenceName.FullName);
  206. ReferenceProjectItem reference = new ReferenceProjectItem(project, "Reference");
  207. ToolComponent toolComponent = ToolboxProvider.ComponentLibraryLoader.GetToolComponent(referenceName.FullName);
  208. if (toolComponent == null || toolComponent.HintPath == null) {
  209. reference.Include = referenceName.FullName;
  210. LoggingService.Debug("Added GAC reference to project: " + reference.Include);
  211. } else {
  212. reference.Include = referenceName.FullName;
  213. reference.HintPath = FileUtility.GetRelativePath(project.Directory, toolComponent.FileName);
  214. LoggingService.Debug("Added assembly reference to project: " + reference.Include);
  215. }
  216. ProjectService.AddProjectItem(project, reference);
  217. project.Save();
  218. }
  219. /// <summary>
  220. /// Looks for the specified type in all the projects in the open solution
  221. /// excluding the current project.
  222. /// </summary>
  223. static IProject FindProjectContainingType(FullTypeName type)
  224. {
  225. IProject currentProject = SD.ProjectService.CurrentProject;
  226. if (currentProject == null) return null;
  227. foreach (IProject project in SD.ProjectService.CurrentSolution.Projects.Where(p => p != currentProject)) {
  228. if (project.ProjectContent.TopLevelTypeDefinitions.Any(t => t.FullTypeName == type)) {
  229. SD.Log.Debug("Found project containing type: " + project.FileName);
  230. return project;
  231. }
  232. }
  233. return null;
  234. }
  235. static void AddProjectReferenceToProject(IProject project, IProject referenceTo)
  236. {
  237. LoggingService.Warn("Adding project reference to project.");
  238. ProjectReferenceProjectItem reference = new ProjectReferenceProjectItem(project, referenceTo);
  239. ProjectService.AddProjectItem(project, reference);
  240. project.Save();
  241. }
  242. static void SideTabDeleted(object source, SideTabEventArgs e)
  243. {
  244. componentLibraryLoader.RemoveCategory(e.SideTab.Name);
  245. SaveToolbox();
  246. }
  247. static void SideTabItemRemoved(object source, SideTabItemEventArgs e)
  248. {
  249. SideTabDesigner tab = source as SideTabDesigner;
  250. ToolboxItem toolboxItem = e.Item.Tag as ToolboxItem;
  251. if (tab != null && toolboxItem != null) {
  252. componentLibraryLoader.DisableToolComponent(tab.Name, toolboxItem.TypeName);
  253. SaveToolbox();
  254. }
  255. }
  256. static void SideTabItemsExchanged(object source, SideTabItemExchangeEventArgs e)
  257. {
  258. SideTabDesigner tab = source as SideTabDesigner;
  259. ToolboxItem toolboxItem1 = e.Item1.Tag as ToolboxItem;
  260. ToolboxItem toolboxItem2 = e.Item2.Tag as ToolboxItem;
  261. if (tab != null && toolboxItem1 != null && toolboxItem2 != null) {
  262. componentLibraryLoader.ExchangeToolComponents(tab.Name, toolboxItem1.TypeName, toolboxItem2.TypeName);
  263. SaveToolbox();
  264. }
  265. }
  266. }
  267. }