PageRenderTime 3914ms CodeModel.GetById 29ms RepoModel.GetById 2ms app.codeStats 0ms

/source/Firestarter.DB.Schema.UI/DatabaseInfoContextMenuController.cs

http://FireStarterModeller.codeplex.com
C# | 258 lines | 195 code | 46 blank | 17 comment | 37 complexity | f0084ece4d39dcda1befca99696465d4 MD5 | raw file
Possible License(s): LGPL-3.0
  1. using System;
  2. using System.Collections;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Windows.Forms;
  6. using FireStarter.Base;
  7. using Firestarter.DB.Schema.BO;
  8. using Habanero.Base;
  9. using Habanero.Base.Exceptions;
  10. using Habanero.BO;
  11. using Habanero.Faces.Base;
  12. using Habanero.Faces.Win;
  13. using DockStyle = Habanero.Faces.Base.DockStyle;
  14. using FormBorderStyle = Habanero.Faces.Base.FormBorderStyle;
  15. using FormStartPosition = Habanero.Faces.Base.FormStartPosition;
  16. namespace Firestarter.DB.Schema.UI
  17. {
  18. public class DatabaseInfoContextMenuController
  19. {
  20. public const string MERGE_RENAMED = "Merge renamed {0}...";
  21. public const string MENUITEM_TABLE = "table";
  22. public const string MENUITEM_COLUMN = "column";
  23. private IMainMenuHabanero _treeViewContextMenu;
  24. public DBDatabase Database { get; set; }
  25. public TreeViewWin TreeView { get; private set; }
  26. public IMainMenuHabanero TreeViewContextMenu
  27. {
  28. get { return _treeViewContextMenu; }
  29. }
  30. public DatabaseInfoContextMenuController(TreeViewWin treeView)
  31. {
  32. TreeView = treeView;
  33. TreeView.MouseClick += MouseClickEventHandler;
  34. }
  35. private void MouseClickEventHandler(object sender, MouseEventArgs e)
  36. {
  37. if (TreeView == null) return;
  38. if (e.Button != System.Windows.Forms.MouseButtons.Right) return;
  39. Point clickLocation = e.Location;
  40. ITreeNode node = GetTreeNode(TreeView, clickLocation);
  41. if (node == null) return;
  42. TreeView.SelectedNode = node;
  43. BindContextMenu(node);
  44. ShowContextMenu(TreeView, clickLocation);
  45. }
  46. protected virtual void ShowContextMenu(TreeViewWin treeView, Point clickLocation)
  47. {
  48. ((ContextMenu)_treeViewContextMenu).Show(treeView, clickLocation);
  49. }
  50. protected virtual ITreeNode GetTreeNode(TreeViewWin treeView, Point clickLocation)
  51. {
  52. return treeView.GetNodeAt(clickLocation) as ITreeNode;
  53. }
  54. private void BindContextMenu(ITreeNode node)
  55. {
  56. var selectedBo = node.Tag as IMergableBo;
  57. SetupMenuItem(selectedBo);
  58. }
  59. public void SetupMenuItem(IMergableBo selectedBo)
  60. {
  61. //In the future if more menu items are added or support for more BO Types is required then
  62. // you probably want to use a strategy pattern see GetAvailableBOs
  63. SetupContextMenu(); // This is called in the mouseClick event to rebuild the context menu
  64. // We need to do this to ensure that we don't end up attaching multiple events to the same
  65. // menu item event handler.
  66. DisableAllMenuItems();
  67. IMenuItem menuItem = GetMenuItem(selectedBo);
  68. if (menuItem == null) return;
  69. menuItem.Enabled = MenuItemShouldBeEnabled(selectedBo);
  70. menuItem.Click += delegate { ShowRenamedBoDialog(selectedBo); };
  71. }
  72. public IMenuItem GetMenuItem(IMergableBo selectedBo)
  73. {
  74. string menuItemName = GetMenuItemName(selectedBo);
  75. return FindMenuItemByName(menuItemName);
  76. }
  77. public static string GetMenuItemName(IMergableBo bo)
  78. {
  79. return string.Format(MERGE_RENAMED, GetBoDisplayText(bo));
  80. }
  81. private static string GetBoDisplayText(IMergableBo bo)
  82. {
  83. var table = bo as DBTable;
  84. if (table != null)
  85. {
  86. return MENUITEM_TABLE;
  87. }
  88. var column = bo as DBColumn;
  89. if (column != null)
  90. {
  91. return MENUITEM_COLUMN;
  92. }
  93. throw new HabaneroDeveloperException("Only DBTable and DBColumn can be used.");
  94. }
  95. public static bool MenuItemShouldBeEnabled(IMergableBo bo)
  96. {
  97. if (bo.PendingChangeType == ChangeType.Add || bo.PendingChangeType == ChangeType.Delete)
  98. {
  99. return true;
  100. }
  101. return false;
  102. }
  103. //Do not think you need to create both menu items but I can live with it
  104. private void SetupContextMenu()
  105. {
  106. var menu = new HabaneroMenu("TreeViewContext");
  107. menu.AddMenuItem(string.Format(MERGE_RENAMED, MENUITEM_TABLE));
  108. menu.AddMenuItem(string.Format(MERGE_RENAMED, MENUITEM_COLUMN));
  109. var contextMenuBuilderWin = new ContextMenuBuilderWin(GlobalUIRegistry.ControlFactory);
  110. contextMenuBuilderWin.BuildMainMenu(menu);
  111. _treeViewContextMenu = contextMenuBuilderWin.BuildMainMenu(menu);
  112. }
  113. private IMenuItem FindMenuItemByName(string menuItemName)
  114. {
  115. // Only need a simple search as the context menu currently doesn't have sub-menu's
  116. if (_treeViewContextMenu == null || _treeViewContextMenu.MenuItems.Count == 0) return null;
  117. return _treeViewContextMenu.MenuItems.FirstOrDefault(item => item.Text == menuItemName);
  118. }
  119. private static void ShowRenamedBoDialog(IMergableBo selectedBo)
  120. {
  121. if (selectedBo == null) return;
  122. var factory = GlobalUIRegistry.ControlFactory;
  123. var form = CreateForm(factory);
  124. var borderLayoutManager = factory.CreateBorderLayoutManager(form);
  125. var dialogControl = new MergeBOsControl()
  126. {
  127. Dock = (System.Windows.Forms.DockStyle)DockStyle.Fill,
  128. BoSelectedInTree = selectedBo
  129. };
  130. borderLayoutManager.AddControl(dialogControl);
  131. dialogControl.MergeableBoCombo.BusinessObjectCollection = GetPotentialRenamedBOsFor(selectedBo);
  132. if (dialogControl.MergeableBoCombo.BusinessObjectCollection == null) return;
  133. // if (dialogControl.MergeableBoCombo.BusinessObjectCollection == null) show No items Message and return
  134. //dialogControl.MergeableBoCombo.SelectedIndex = 0;
  135. form.Text = "Merge renamed item";
  136. form.ShowDialog();
  137. }
  138. private void DisableAllMenuItems()
  139. {
  140. if (_treeViewContextMenu == null) return;
  141. foreach (IMenuItem menuItem in (IEnumerable)_treeViewContextMenu.MenuItems)
  142. {
  143. menuItem.Enabled = false;
  144. }
  145. }
  146. private static IFormHabanero CreateForm(IControlFactory factory)
  147. {
  148. IFormHabanero form = factory.CreateForm();
  149. form.Size = new System.Drawing.Size(280, 130);
  150. form.FormBorderStyle = FormBorderStyle.FixedDialog;
  151. form.StartPosition = FormStartPosition.CenterParent;
  152. return form;
  153. }
  154. public static IBusinessObjectCollection GetPotentialRenamedBOsFor(IMergableBo selectedBo)
  155. {
  156. IBusinessObjectCollection availableBOs = GetAvailableBOs(selectedBo);
  157. return GetPotentialRenamedBOsFrom(availableBOs, selectedBo.ClassDef, selectedBo.PendingChangeType);
  158. }
  159. private static IBusinessObjectCollection GetAvailableBOs(IMergableBo selectedBo)
  160. {
  161. //If you ever need to extend this to more items then I would suggest that
  162. // you extract this method and GetMenuItemName method into a
  163. // strategy pattern.
  164. var selectedColumnBo = selectedBo as DBColumn;
  165. if (selectedColumnBo != null) return GetAvailableBOs(selectedColumnBo);
  166. var selectedTableBo = selectedBo as DBTable;
  167. if (selectedTableBo != null) return GetAvailableBOs(selectedTableBo);
  168. throw new HabaneroDeveloperException("Only DBTable and DBColumn mergableBo's should be evaluated.");
  169. }
  170. private static IBusinessObjectCollection GetAvailableBOs(DBTable selectedTableBo)
  171. {
  172. return selectedTableBo.Database.Tables;
  173. }
  174. private static IBusinessObjectCollection GetAvailableBOs(DBColumn selectedColumn)
  175. {
  176. return selectedColumn.Table.Columns;
  177. }
  178. private static IBusinessObjectCollection GetPotentialRenamedBOsFrom(IBusinessObjectCollection availableBOs, IClassDef classDef, ChangeType pendingChangeType)
  179. {
  180. ChangeType changeType = GetRenamingChangeTypeForSelectedBo(pendingChangeType);
  181. var potentialRenamedBOs = CreateCollectionOfType(classDef);
  182. foreach (IMergableBo availableBO in availableBOs)
  183. {
  184. if (availableBO.PendingChangeType == changeType) potentialRenamedBOs.Add(availableBO);
  185. }
  186. return potentialRenamedBOs;
  187. }
  188. private static ChangeType GetRenamingChangeTypeForSelectedBo(ChangeType pendingChangeType)
  189. {
  190. if (pendingChangeType == ChangeType.Add)
  191. {
  192. return ChangeType.Delete;
  193. }
  194. if (pendingChangeType == ChangeType.Delete)
  195. {
  196. return ChangeType.Add;
  197. }
  198. throw new HabaneroDeveloperException("Only ChangeTypes of Add and Delete are valid in renaming scenarios.");
  199. }
  200. /// <summary>
  201. /// Creates a Generic Collection of <see cref="IBusinessObjectCollection"/> of the Generic
  202. /// Type determined by the <paramref name="classDef"/>
  203. /// </summary>
  204. /// <param name="classDef">The ClassDef to use for the collection (and its <see cref="SelectQuery"/>)</param>
  205. /// <returns></returns>
  206. protected static IBusinessObjectCollection CreateCollectionOfType(IClassDef classDef)
  207. {
  208. Type boColType = typeof(BusinessObjectCollection<>).MakeGenericType(classDef.ClassType);
  209. return (IBusinessObjectCollection) Activator.CreateInstance(boColType, classDef);
  210. }
  211. }
  212. }