/// <summary> /// Draws the diagram. /// </summary> /// <param name="refresh">if set to <c>true</c> the diagram will redraw.</param> private void DrawDiagram(bool refresh) { if (this.myDiagramView == null) { return; } IHierarchyContextEnabled hierarchyElement = null; ModelElement element = null; object[] selectedElements = GetSelectedElements(); foreach (object obj in selectedElements) { if (null != (element = EditorUtility.ResolveContextInstance(obj, false) as ModelElement) && element.Store != null && !element.IsDeleted && null != (hierarchyElement = element as IHierarchyContextEnabled)) { if (hierarchyElement.HierarchyDisabled) { hierarchyElement = null; } else { break; } } } DrawDiagram(refresh, element, hierarchyElement); }
/// <summary> /// Gets the linked elements for the specified element. /// </summary> /// <param name="element">The element.</param> /// <param name="masterDictionary">A master dictionary of all elements</param> /// <param name="localDictionary">A local dictionary for this pass through. /// Allows us to track multiple passes while iterating through the elements of another dictionary.</param> /// <param name="generations">The generations.</param> private static void GetLinkedElements(IHierarchyContextEnabled element, Dictionary<IHierarchyContextEnabled, int> masterDictionary, ref Dictionary<IHierarchyContextEnabled, int> localDictionary, int generations) { ModelElement mel = (ModelElement)element; Type contextType = typeof(IHierarchyContextEnabled); foreach (DomainRoleInfo roleInfo in mel.GetDomainClass().AllDomainRolesPlayed) { DomainRoleInfo oppositeRole = roleInfo.OppositeDomainRole; Type oppositeType = oppositeRole.RolePlayer.ImplementationClass; if (!oppositeType.IsAbstract && contextType.IsAssignableFrom(oppositeType)) { foreach (ElementLink link in roleInfo.GetElementLinks(mel, true)) // Exclude derived, these will also be played roles and be picked up. { IHierarchyContextLinkFilter filter = link as IHierarchyContextLinkFilter; if (filter != null && !filter.ContinueHierachyWalking(roleInfo)) { continue; } ModelElement oppositeMel = oppositeRole.GetRolePlayer(link); if (oppositeMel == mel) { continue; } IHierarchyContextEnabled contextableElement = (IHierarchyContextEnabled)oppositeMel; // Cast must work, already checked at the type level int decrement = contextableElement.HierarchyContextDecrementCount; if (masterDictionary.Count == 1 && contextableElement.ForwardHierarchyContextTo != null) { decrement = 0; } GetRelatedContextableElementsHelper(contextableElement, masterDictionary, ref localDictionary, generations - decrement); } } } }
/// <summary> /// Places the object on the diagram. /// </summary> /// <param name="element">The element.</param> private void PlaceObject(IHierarchyContextEnabled element) { foreach (IHierarchyContextEnabled elem in GetRelatedContextableElements(element, myGenerations)) { if (elem.ForwardHierarchyContextTo != null) { continue; } myDiagram.PlaceORMElementOnDiagram(null, (ModelElement)elem, PointD.Empty, ORMPlacementOption.None, null, null); } }
/// <summary> /// Dont use this method. Use GetRelatedContextableElements instead. /// helper function for GetRelatedContextableElements. /// </summary> /// <param name="element">The element.</param> /// <param name="masterDictionary">A master dictionary of all elements</param> /// <param name="localDictionary">A local dictionary for this pass through. /// Allows us to track multiple passes while iterating through the elements of another dictionary.</param> /// <param name="generations">The generations.</param> private static void GetRelatedContextableElementsHelper(IHierarchyContextEnabled element, Dictionary <IHierarchyContextEnabled, int> masterDictionary, ref Dictionary <IHierarchyContextEnabled, int> localDictionary, int generations) { if (element == null) { return; } IHierarchyContextEnabled contextableElement = EditorUtility.ResolveContextInstance(element, false) as IHierarchyContextEnabled; if (contextableElement == null || contextableElement.HierarchyDisabled) { return; } int existingGenerations; if (!masterDictionary.TryGetValue(contextableElement, out existingGenerations)) { masterDictionary.Add(contextableElement, generations); if (localDictionary != masterDictionary) { (localDictionary ?? (localDictionary = new Dictionary <IHierarchyContextEnabled, int>())).Add(contextableElement, generations); } } else { if (existingGenerations >= generations) { return; } else { masterDictionary[contextableElement] = generations; if (localDictionary == null) { (localDictionary = new Dictionary <IHierarchyContextEnabled, int>()).Add(contextableElement, generations); } else if (localDictionary != masterDictionary && !localDictionary.ContainsKey(contextableElement)) { // Note that we don't actually use the generations value from // the local dictionary, there is no reason to update it. localDictionary.Add(contextableElement, generations); } } } IHierarchyContextEnabled forwardTo; if (null != (forwardTo = contextableElement.ForwardHierarchyContextTo)) { GetRelatedContextableElementsHelper(forwardTo, masterDictionary, ref localDictionary, generations); } if (generations > 0 && (masterDictionary.Count == 1 || contextableElement.ContinueWalkingHierarchyContext)) { GetLinkedElements(contextableElement, masterDictionary, ref localDictionary, generations); } }
/// <summary> /// Provide a notification when the selection container has been modified. The /// default implemention is empty. /// </summary> protected override void OnORMSelectionContainerChanged() { if (this.myDiagram != null) { if (null != Utility.ValidateStore(myDiagram.Store)) { myCurrentlySelectedObject = null; mySelectedPartitionId = null; this.RemoveDiagram(); } } DrawDiagram(); base.OnORMSelectionContainerChanged(); }
/// <summary> /// Gets the related contextable elements for the defined number of generations from specified element. /// </summary> /// <param name="element">The element.</param> /// <param name="generations">The numeber of generations out to go.</param> /// <returns>Sorted list of elements</returns> private static IList <IHierarchyContextEnabled> GetRelatedContextableElements(IHierarchyContextEnabled element, int generations) { Dictionary <IHierarchyContextEnabled, int> masterDictionary = new Dictionary <IHierarchyContextEnabled, int>(); GetRelatedContextableElementsHelper(element, masterDictionary, ref masterDictionary, generations); int nextPassCount = masterDictionary.Count; IHierarchyContextEnabled[] firstPassElements = new IHierarchyContextEnabled[nextPassCount]; masterDictionary.Keys.CopyTo(firstPassElements, 0); ICollection <IHierarchyContextEnabled> nextPassElements = firstPassElements; while (nextPassCount != 0) { Dictionary <IHierarchyContextEnabled, int> localDictionary = null; bool requestMinimum = generations == 0; generations = Math.Max(generations - 1, 0); foreach (IHierarchyContextEnabled nextPassElement in nextPassElements) { IEnumerable <IHierarchyContextEnabled> forcedContextElements = nextPassElement.GetForcedHierarchyContextElements(requestMinimum); if (forcedContextElements != null) { foreach (IHierarchyContextEnabled dependantContextableElement in forcedContextElements) { GetRelatedContextableElementsHelper(dependantContextableElement, masterDictionary, ref localDictionary, generations); } } } if (localDictionary != null) { nextPassElements = localDictionary.Keys; nextPassCount = nextPassElements.Count; } else { nextPassCount = 0; } } List <IHierarchyContextEnabled> retVal = new List <IHierarchyContextEnabled>(masterDictionary.Keys); retVal.Sort(HierarchyContextPlacePrioritySortComparer.Instance); return(retVal); }
private void DrawDiagram(bool refresh, ModelElement element, IHierarchyContextEnabled hierarchyElement) { bool storeChange = false; if (hierarchyElement == null && (myDiagram == null || (element != null && (storeChange = (element.Store != myDiagram.Store))))) { ModelElement selectedElement = element; element = myCurrentlySelectedObject as ModelElement; if (element != null && ((element.IsDeleted || element.Store == null) || storeChange)) { myCurrentlySelectedObject = null; mySelectedPartitionId = null; RemoveDiagram(); } hierarchyElement = myCurrentlySelectedObject; if (hierarchyElement == null && selectedElement != null && !selectedElement.IsDeleted && selectedElement.Store != null) { ORMModel attachToModel = selectedElement as ORMModel; if (attachToModel != null) { EnsureDiagram(attachToModel); } } } else if (hierarchyElement == myCurrentlySelectedObject && hierarchyElement != null && !refresh && (myDiagram != null && myDiagram.HasChildren)) { return; } if (hierarchyElement == null) { return; } myCurrentlySelectedObject = hierarchyElement; mySelectedPartitionId = ((ModelElement)hierarchyElement).Partition.AlternateId; ORMModel model = hierarchyElement.Model; if (model == null) { return; } this.EnsureDiagram(model); if (myDiagram == null) { return; } Store store = element.Store; IORMToolServices toolServices = (IORMToolServices)store; if (!toolServices.CanAddTransaction) { return; } using (Transaction t = store.TransactionManager.BeginTransaction("Draw Context Diagram")) { myDiagram.NestedChildShapes.Clear(); myDiagram.AutoPopulateShapes = true; PlaceObject(hierarchyElement); LinkedElementCollection<ShapeElement> collection = myDiagram.NestedChildShapes; LayoutManager bl = new LayoutManager(myDiagram, toolServices.GetLayoutEngine(typeof(ORMRadialLayoutEngine))); foreach (ShapeElement shape in collection) { bl.AddShape(shape, false); } bl.Layout(true); myDiagram.AutoPopulateShapes = false; if (t.HasPendingChanges) { t.Commit(); } } return; }