PageRenderTime 40ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/Tum.PDE.LanguageDSL/Tum.PDE.LanguageDSL.Visualization/ViewModel/ModelTree/ModelTreeOperations.cs

#
C# | 262 lines | 157 code | 31 blank | 74 comment | 46 complexity | 91ca9f945d572b12b1efff7a1b08a096 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.VisualStudio.Modeling;
  6. namespace Tum.PDE.LanguageDSL.Visualization.ViewModel.ModelTree
  7. {
  8. /// <summary>
  9. /// Helper class.
  10. /// </summary>
  11. public class ModelTreeOperations
  12. {
  13. /// <summary>
  14. /// Adds a new embedding relationship instance betweend the given domain class as source and a new domain class
  15. /// as target (target is created by this method).
  16. /// </summary>
  17. /// <param name="source">Domain class acting as parent in the embedding relationship.</param>
  18. public static void AddNewEmbeddingRelationship(List<DomainClass> sources)
  19. {
  20. ModelTreeHelper.AddNewEmbeddingRelationship(sources);
  21. }
  22. /// <summary>
  23. /// Adds a new embedding relationship instance.
  24. /// </summary>
  25. /// <param name="source">Domain class representing the parent.</param>
  26. /// <param name="target">Domain class representing the child.</param>
  27. public static void AddNewEmbeddingRelationship(List<DomainClass> sources, AttributedDomainElement target)
  28. {
  29. ModelTreeHelper.AddNewEmbeddingRelationship(sources, target);
  30. }
  31. /// <summary>
  32. /// Adds a new referece relationship instance.
  33. /// </summary>
  34. /// <param name="source">Domain class representing the source.</param>
  35. /// <param name="target">Domain class representing the target.</param>
  36. public static void AddNewReferenceRelationship(List<DomainClass> sources, AttributedDomainElement target)
  37. {
  38. ModelTreeHelper.AddNewReferenceRelationship(sources, target);
  39. }
  40. /// <summary>
  41. /// Adds a new inheritance relationship instance for each source.
  42. /// </summary>
  43. /// <param name="sources">DomainClass to be the derived classes.</param>
  44. /// <param name="target">DomainClass to act as the base class.</param>
  45. public static void AddNewInheritanceRelationship(List<DomainClass> sources, DomainClass target)
  46. {
  47. ModelTreeHelper.AddNewInheritanceRelationship(sources, target);
  48. }
  49. /// <summary>
  50. /// Adds a new derived class to each of the given domain classes.
  51. /// </summary>
  52. /// <param name="sources">DomainClasses to add a derived from.</param>
  53. public static void AddNewInheritanceRelationshipNewDerivedClass(List<DomainClass> sources)
  54. {
  55. ModelTreeHelper.AddNewInheritanceRelationshipNewDerivedClass(sources);
  56. }
  57. /// <summary>
  58. /// Moves the children tree consisting of embedding, reference, inheritance and shape mapping nodes from the source
  59. /// element to the target element.
  60. ///
  61. /// Needs to be called within a modeling transaction!
  62. /// </summary>
  63. /// <param name="source">TreeNode to move the tree from.</param>
  64. /// <param name="target">TreeNode to move the tree to.</param>
  65. public static void MoveTree(TreeNode source, TreeNode target)
  66. {
  67. // copy sub tree
  68. for (int i = source.EmbeddingRSNodes.Count - 1; i >= 0; i--)
  69. source.EmbeddingRSNodes[i].TreeNode = target;
  70. for (int i = source.ReferenceRSNodes.Count - 1; i >= 0; i--)
  71. source.ReferenceRSNodes[i].TreeNode = target;
  72. for (int i = source.InheritanceNodes.Count - 1; i >= 0; i--)
  73. source.InheritanceNodes[i].TreeNode = target;
  74. for (int i = source.ShapeClassNodes.Count - 1; i >= 0; i--)
  75. source.ShapeClassNodes[i].TreeNode = target;
  76. }
  77. /// <summary>
  78. /// Verifies if the "bring tree here" command is applicable for the given node.
  79. /// </summary>
  80. /// <param name="node">TreeNode in question.</param>
  81. /// <returns>True if the command can be applied, False otherwise.</returns>
  82. public static bool CanBringTreeHere(TreeNode node)
  83. {
  84. if (node == null)
  85. return false;
  86. if (node.DomainElement == null)
  87. return false;
  88. if (node is RootNode) // Tree is already here
  89. return false;
  90. if (node.IsElementHolder) // Tree is already here
  91. return false;
  92. // try to find the domain class the node is holding in the parent embedding path, if its
  93. // not there, we can safely bring the tree to the node in question
  94. if (node is EmbeddingNode)
  95. {
  96. if (!CanBringTreeHere((node as EmbeddingNode).EmbeddingRSNode.TreeNode, node))
  97. return false;
  98. }
  99. else if (node is ReferenceNode)
  100. {
  101. if (!CanBringTreeHere((node as ReferenceNode).ReferenceRSNode.TreeNode, node))
  102. return false;
  103. }
  104. else if (node is InheritanceNode)
  105. {
  106. if (!CanBringTreeHere((node as InheritanceNode).TreeNode, node))
  107. return false;
  108. }
  109. else
  110. throw new NotSupportedException("node type in CanBringTreeHere");
  111. return true;
  112. }
  113. /// <summary>
  114. /// Verifies if the "bring tree here" command is applicable for the given node.
  115. /// </summary>
  116. /// <param name="currentNode">Current TreeNode used in the recursion.</param>
  117. /// <param name="node">TreeNode in question.</param>
  118. /// <returns>True if the command can be applied, False otherwise.</returns>
  119. private static bool CanBringTreeHere(TreeNode currentNode, TreeNode node)
  120. {
  121. if (currentNode.DomainElement.Id == node.DomainElement.Id)
  122. return false;
  123. if (currentNode is EmbeddingNode)
  124. {
  125. TreeNode parentNode = (currentNode as EmbeddingNode).EmbeddingRSNode.TreeNode;
  126. if (parentNode != null)
  127. if (!CanBringTreeHere(parentNode, node))
  128. return false;
  129. }
  130. else if (currentNode is ReferenceNode)
  131. {
  132. TreeNode parentNode = (currentNode as ReferenceNode).ReferenceRSNode.TreeNode;
  133. if (parentNode != null)
  134. if (!CanBringTreeHere(parentNode, node))
  135. return false;
  136. }
  137. else if (currentNode is InheritanceNode)
  138. {
  139. TreeNode parentNode = (currentNode as InheritanceNode).TreeNode;
  140. if (parentNode != null)
  141. if (!CanBringTreeHere(parentNode, node))
  142. return false;
  143. }
  144. else if (currentNode is RootNode)
  145. {
  146. // nothin to do here
  147. }
  148. else
  149. throw new NotSupportedException("node type in CanBringTreeHere");
  150. return true;
  151. }
  152. /// <summary>
  153. /// Verifies if the "split tree" command is applicable for the given node.
  154. /// </summary>
  155. /// <param name="node">TreeNode in question.</param>
  156. /// <returns>True if the command can be applied, False otherwise.</returns>
  157. public static bool CanSplitTree(TreeNode node)
  158. {
  159. if (node == null)
  160. return false;
  161. if (node.DomainElement == null)
  162. return false;
  163. if (node is RootNode)
  164. return false;
  165. if (node.IsElementHolder)
  166. return true;
  167. else
  168. return false;
  169. }
  170. /// <summary>
  171. /// Creates a new root node to "hold" the tree of the given node.
  172. ///
  173. /// Needs to be called within a modeling transaction!
  174. /// </summary>
  175. /// <param name="node">TreeNode to split the tree from.</param>
  176. public static void SplitTree(TreeNode node)
  177. {
  178. // create new root node
  179. RootNode rootNode = new RootNode(node.Store);
  180. rootNode.DomainElement = node.DomainElement;
  181. rootNode.IsElementHolder = true;
  182. rootNode.IsEmbeddingTreeExpanded = node.IsEmbeddingTreeExpanded;
  183. rootNode.IsInheritanceTreeExpanded = node.IsInheritanceTreeExpanded;
  184. rootNode.IsReferenceTreeExpanded = node.IsReferenceTreeExpanded;
  185. rootNode.IsShapeMappingTreeExpanded = node.IsShapeMappingTreeExpanded;
  186. // move tree
  187. MoveTree(node, rootNode);
  188. // add root node to the domain model tree for vizualisation
  189. rootNode.DomainElement.ParentModelContext.ViewContext.DomainModelTreeView.RootNodes.Add(rootNode);
  190. rootNode.DomainElement.ParentModelContext.ViewContext.DomainModelTreeView.ModelTreeNodes.Add(rootNode);
  191. // collapse the source node
  192. node.IsElementHolder = false;
  193. node.IsExpanded = false;
  194. }
  195. /// <summary>
  196. /// Moves the tree from the current holding node to the given node.
  197. ///
  198. /// Needs to be called within a modeling transaction!
  199. /// </summary>
  200. /// <param name="node">TreeNode to move the tree to.</param>
  201. public static void BringTreeHere(TreeNode node)
  202. {
  203. // find the element holder tree
  204. TreeNode elementHolderNode = null;
  205. foreach (TreeNode n in node.DomainElement.DomainModelTreeNodes)
  206. if (n.IsElementHolder)
  207. {
  208. elementHolderNode = n;
  209. break;
  210. }
  211. if (elementHolderNode == null)
  212. throw new ArgumentNullException("elementHolderNode");
  213. // move tree
  214. MoveTree(elementHolderNode, node);
  215. node.IsElementHolder = true;
  216. node.IsEmbeddingTreeExpanded = elementHolderNode.IsEmbeddingTreeExpanded;
  217. node.IsInheritanceTreeExpanded = elementHolderNode.IsInheritanceTreeExpanded;
  218. node.IsReferenceTreeExpanded = elementHolderNode.IsReferenceTreeExpanded;
  219. node.IsShapeMappingTreeExpanded = elementHolderNode.IsShapeMappingTreeExpanded;
  220. node.IsExpanded = true;
  221. // collapse source node
  222. if (elementHolderNode is RootNode)
  223. elementHolderNode.Delete();
  224. else
  225. {
  226. elementHolderNode.IsExpanded = false;
  227. elementHolderNode.IsElementHolder = false;
  228. }
  229. }
  230. }
  231. }