/// <summary> /// Implements <see cref="IModelingEventSubscriber.ManageModelingEventHandlers"/>. /// </summary> protected void ManageModelingEventHandlers(ModelingEventManager eventManager, EventSubscriberReasons reasons, EventHandlerAction action) { // UNDONE: If we delay attach user interface events (possible in the future for // external model scenarios), then we need to check ModelStateEvents here and // be more precise in which events are attached that affect model state such as // calculated shape size. Currently, this is only called without 'UserInterfaceEvents' // for unit-testing. if ((EventSubscriberReasons.DocumentLoaded | EventSubscriberReasons.UserInterfaceEvents) == (reasons & (EventSubscriberReasons.DocumentLoaded | EventSubscriberReasons.UserInterfaceEvents))) { Store store = Store; ORMDiagram.ManageEventHandlers(store, eventManager, action); ORMBaseShape.ManageEventHandlers(store, eventManager, action); ReadingShape.ManageEventHandlers(store, eventManager, action); ExternalConstraintShape.ManageEventHandlers(store, eventManager, action); RolePlayerLink.ManageEventHandlers(store, eventManager, action); ObjectTypeShape.ManageEventHandlers(store, eventManager, action); ORMBaseBinaryLinkShape.ManageEventHandlers(store, eventManager, action); FactTypeShape.ManageEventHandlers(store, eventManager, action); SubtypeLink.ManageEventHandlers(store, eventManager, action); } if (0 != (reasons & EventSubscriberReasons.DocumentLoaded)) { IORMToolServices services; IORMExtendableElementService extendableElementService; if (null != (services = Store as IORMToolServices) && null != (extendableElementService = services.ExtendableElementService)) { extendableElementService.RegisterExtensionRoles(new Guid[] { ORMDiagramHasExtensionElement.ExtensionDomainRoleId, ORMBaseShapeHasExtensionElement.ExtensionDomainRoleId }); } } }
/// <summary> /// An IMS event to track the shape element added to the associated /// diagram during this connect action. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void InternalConstraintAddedEvent(object sender, ElementAddedEventArgs e) { if (myAddedConstraint == null) { UniquenessConstraint candidate = e.ModelElement as UniquenessConstraint; if (candidate != null && candidate.IsInternal) { ORMDiagram d = Diagram as ORMDiagram; if (d != null) { // Find the shape associated with the fact type we added to LinkedElementCollection <FactType> candidateFacts = candidate.FactTypeCollection; if (candidateFacts.Count != 0) { FactTypeShape shape = d.FindShapeForElement(candidateFacts[0]) as FactTypeShape; if (shape != null) { myDropTargetShape = shape; myAddedConstraint = candidate; } } } } } }
private static void RoleNameVisibilityChangedEvent(object sender, ElementPropertyChangedEventArgs e) { FactTypeShape factTypeShape = (FactTypeShape)e.ModelElement; if (!factTypeShape.IsDeleted) { DisplayRoleNames display = factTypeShape.DisplayRoleNames; bool shouldBeVisible = display == DisplayRoleNames.On || (display == DisplayRoleNames.UserDefault && OptionsPage.CurrentRoleNameDisplay == RoleNameDisplay.On); foreach (ShapeElement childShape in factTypeShape.RelativeChildShapes) { RoleNameShape roleNameShape; if (null != (roleNameShape = childShape as RoleNameShape) && (shouldBeVisible ^ roleNameShape.IsVisible)) { if (shouldBeVisible) { roleNameShape.Show(); } else { roleNameShape.Hide(); } } } } }
/// <summary> /// Set this mouse action as the active action on the /// diagram of the given shape. /// </summary> /// <param name="attachToShape">The shape the constraint is being attached to.</param> /// <param name="constraint">The constraint being connected.</param> /// <param name="clientView">The active DiagramClientView</param> public void ChainMouseAction(FactTypeShape attachToShape, UniquenessConstraint constraint, DiagramClientView clientView) { DiagramView activeView = Diagram.ActiveDiagramView; if (activeView != null) { // Move on to the selection action clientView.ActiveMouseAction = this; // Now emulate a mouse click in the middle of the added constraint. The click // actions provide a starting point for the connect action, so a mouse move // provides a drag line. Point emulateClickPoint = clientView.WorldToDevice(attachToShape.GetAbsoluteConstraintAttachPoint(constraint, FactSetConstraint.GetLink(constraint, attachToShape.AssociatedFactType))); DiagramMouseEventArgs mouseEventArgs = new DiagramMouseEventArgs(new MouseEventArgs(MouseButtons.Left, 1, emulateClickPoint.X, emulateClickPoint.Y, 0), clientView); MouseDown(mouseEventArgs); Click(new DiagramPointEventArgs(emulateClickPoint.X, emulateClickPoint.Y, PointRelativeTo.Client, clientView)); MouseUp(mouseEventArgs); attachToShape.Invalidate(true); // An extra move lets us chain when the mouse is not on the design surface, // such as when we are being activated via the task list. MouseMove(mouseEventArgs); ORMDiagram.SelectToolboxItem(activeView, ResourceStrings.ToolboxInternalUniquenessConstraintItemId); FactTypeShape.ActiveInternalUniquenessConstraintConnectAction = this; } }
private void Reset() { mySelectedRoles = null; mySourceShape = null; myIUC = null; myLastMouseMoveItem = null; myPendingOnClickedAction = OnClickedAction.Normal; FactTypeShape.ActiveInternalUniquenessConstraintConnectAction = null; }
/// <summary> /// Set shape visibility for a role in the given fact type, fact type shape, and diagram /// </summary> private static void UpdateRoleNameDisplay(Role role, FactType factType, FactTypeShape factTypeShape, ORMDiagram diagram, bool shouldDisplay, bool shouldRemove, bool immediateNotification) { if (!shouldRemove && diagram != null) { diagram.FixUpLocalDiagram(factType, role); } LinkedElementCollection <ShapeElement> childShapes = factTypeShape.RelativeChildShapes; bool notifyUpdate = false; for (int i = childShapes.Count - 1; i >= 0; --i) { RoleNameShape roleNameShape; if (null != (roleNameShape = childShapes[i] as RoleNameShape)) { if (shouldRemove) { roleNameShape.Delete(); } else { if (shouldDisplay) { if (!roleNameShape.IsVisible) { if (immediateNotification) { roleNameShape.Show(); } else { notifyUpdate = true; } } } else if (roleNameShape.IsVisible) { if (immediateNotification) { roleNameShape.Hide(); } else { notifyUpdate = true; } roleNameShape.Size = SizeD.Empty; } } } } if (notifyUpdate) { factTypeShape.OnRoleNameVisibilityChanged(); } }
private static void DelayValidateFactTypeShapeSize(ModelElement element) { if (!element.IsDeleted) { FactTypeShape factTypeShape = (FactTypeShape)element; SizeD oldSize = factTypeShape.Size; factTypeShape.AutoResize(); if (oldSize == factTypeShape.Size) { ((IInvalidateDisplay)factTypeShape).InvalidateRequired(true); } } }
/// <summary> /// Set shape visibility for the given fact type, fact type shape, and diagram /// </summary> private static void UpdateRoleNameDisplay(FactType factType, FactTypeShape factTypeShape, ORMDiagram diagram, bool immediateNotification) { DisplayRoleNames display = factTypeShape.DisplayRoleNames; bool asObjectType = factTypeShape.DisplayAsObjectType; bool shouldDisplay = !asObjectType && display == DisplayRoleNames.On || (display == DisplayRoleNames.UserDefault && OptionsPage.CurrentRoleNameDisplay == RoleNameDisplay.On); bool shouldRemove = asObjectType || display == DisplayRoleNames.Off; foreach (RoleBase roleBase in factType.RoleCollection) { Role role = roleBase as Role; if (role != null && !string.IsNullOrEmpty(role.Name)) { UpdateRoleNameDisplay(role, factType, factTypeShape, diagram, shouldDisplay, shouldRemove, immediateNotification); } } }
/// <summary> /// DeletingRule: typeof(Microsoft.VisualStudio.Modeling.Diagrams.LinkConnectsToNode) /// External constraint shapes can only be drawn if they show all of their /// links, so automatically remove them if a connecting shape is removed. /// </summary> private static void VerifyConnectedShapeShapeDeletingRule(ElementDeletingEventArgs e) { LinkConnectsToNode connectLink = (LinkConnectsToNode)e.ModelElement; ExternalConstraintLink link; ModelElement linkMel; ModelElement shapeMel; if (null != (link = connectLink.Link as ExternalConstraintLink) && null != (linkMel = link.ModelElement) && !linkMel.IsDeleting) { NodeShape linkNode = connectLink.Nodes; ExternalConstraintShape constraintShape = linkNode as ExternalConstraintShape; NodeShape oppositeShape = null; // The ToShape (as opposed to FromShape) here needs to be in // sync with the code in ConfiguringAsChildOf if (constraintShape == null) { constraintShape = link.ToShape as ExternalConstraintShape; oppositeShape = linkNode; } else { oppositeShape = link.FromShape; } if (oppositeShape != null && constraintShape != null && null != (shapeMel = constraintShape.ModelElement) && !shapeMel.IsDeleting) { if (!constraintShape.IsDeleting) { FrameworkDomainModel.DelayValidateElement(constraintShape, DelayValidateExternalConstraintShapeFullyConnected); } // Delay, fact type shape size will not be accurate until deletion is completed. FactTypeShape factTypeShape = MultiShapeUtility.ResolvePrimaryShape(oppositeShape) as FactTypeShape; if (factTypeShape != null && !factTypeShape.IsDeleting) { FrameworkDomainModel.DelayValidateElement(factTypeShape, DelayValidateFactTypeShapeSize); } } } }
/// <summary> /// Place a newly added role name shape /// </summary> /// <param name="parent">Parent FactTypeShape</param> /// <param name="createdDuringViewFixup">Whether this shape was created as part of a view fixup</param> public override void PlaceAsChildOf(NodeShape parent, bool createdDuringViewFixup) { if (createdDuringViewFixup) { FactTypeShape factShape = (FactTypeShape)parent; double x = -0.2; double y = -0.2; FactType factType = factShape.AssociatedFactType; // Cascades RoleNameShapes for facts that contain more than one role LinkedElementCollection <RoleBase> roles = factShape.DisplayedRoleOrder; int roleIndex = roles.IndexOf((RoleBase)ModelElement); if (roleIndex != -1) { x += roleIndex * 0.15; y -= roleIndex * 0.15; } Location = new PointD(x, y); } }
/// <summary> /// Implements <see cref="IModelingEventSubscriber.ManageModelingEventHandlers"/>. /// </summary> protected void ManageModelingEventHandlers(ModelingEventManager eventManager, EventSubscriberReasons reasons, EventHandlerAction action) { // UNDONE: If we delay attach user interface events (possible in the future for // external model scenarios), then we need to check ModelStateEvents here and // be more precise in which events are attached that affect model state such as // calculated shape size. Currently, this is only called without 'UserInterfaceEvents' // for unit-testing. if ((EventSubscriberReasons.DocumentLoaded | EventSubscriberReasons.UserInterfaceEvents) == (reasons & (EventSubscriberReasons.DocumentLoaded | EventSubscriberReasons.UserInterfaceEvents))) { Store store = Store; ORMBaseShape.ManageEventHandlers(store, eventManager, action); ReadingShape.ManageEventHandlers(store, eventManager, action); ExternalConstraintShape.ManageEventHandlers(store, eventManager, action); RolePlayerLink.ManageEventHandlers(store, eventManager, action); ObjectTypeShape.ManageEventHandlers(store, eventManager, action); ORMBaseBinaryLinkShape.ManageEventHandlers(store, eventManager, action); FactTypeShape.ManageEventHandlers(store, eventManager, action); SubtypeLink.ManageEventHandlers(store, eventManager, action); } }
/// <summary> /// Constructor /// Creates a FactTypeShapeHasRoleDisplayOrder link in the same Partition as the given FactTypeShape /// </summary> /// <param name="source">FactTypeShape to use as the source of the relationship.</param> /// <param name="target">RoleBase to use as the target of the relationship.</param> public FactTypeShapeHasRoleDisplayOrder(FactTypeShape source, global::ORMSolutions.ORMArchitect.Core.ObjectModel.RoleBase target) : base((source != null ? source.Partition : null), new DslModeling::RoleAssignment[] { new DslModeling::RoleAssignment(FactTypeShapeHasRoleDisplayOrder.FactTypeShapeDomainRoleId, source), new DslModeling::RoleAssignment(FactTypeShapeHasRoleDisplayOrder.RoleDisplayOrderDomainRoleId, target) }, null) { }
public static DslModeling::LinkedElementCollection <global::ORMSolutions.ORMArchitect.Core.ObjectModel.RoleBase> GetRoleDisplayOrderCollection(FactTypeShape element) { return(new DslModeling::LinkedElementCollection <global::ORMSolutions.ORMArchitect.Core.ObjectModel.RoleBase>(element, FactTypeShapeDomainRoleId)); }
/// <summary> /// Add subtype links when possible /// </summary> /// <param name="element">An ModelHasFactType instance</param> /// <param name="store">The context store</param> /// <param name="notifyAdded">The listener to notify if elements are added during fixup</param> protected sealed override void ProcessElement(ModelHasFactType element, Store store, INotifyElementAdded notifyAdded) { SubtypeFact subTypeFact = element.FactType as SubtypeFact; ORMModel model; if (null != (subTypeFact = element.FactType as SubtypeFact) && !subTypeFact.IsDeleted && null != (model = subTypeFact.Model)) { ObjectType rolePlayer = subTypeFact.Subtype; FactType nestedFact = rolePlayer.NestedFactType; if (FactTypeShape.ShouldDrawObjectification(nestedFact)) { Diagram.FixUpDiagram(model, nestedFact); Diagram.FixUpDiagram(nestedFact, rolePlayer); } else { Diagram.FixUpDiagram(model, rolePlayer); } rolePlayer = subTypeFact.Supertype; nestedFact = rolePlayer.NestedFactType; if (FactTypeShape.ShouldDrawObjectification(nestedFact)) { Diagram.FixUpDiagram(model, nestedFact); Diagram.FixUpDiagram(nestedFact, rolePlayer); } else { Diagram.FixUpDiagram(model, rolePlayer); } object AllowMultipleShapes; Dictionary <object, object> topLevelContextInfo; bool containedAllowMultipleShapes; if (!(containedAllowMultipleShapes = (topLevelContextInfo = store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo).ContainsKey(AllowMultipleShapes = MultiShapeUtility.AllowMultipleShapes))) { topLevelContextInfo.Add(AllowMultipleShapes, null); } foreach (PresentationViewsSubject presentationViewsSubject in DomainRoleInfo.GetElementLinks <PresentationViewsSubject>(model, PresentationViewsSubject.SubjectDomainRoleId)) { ORMDiagram diagram; if ((diagram = presentationViewsSubject.Presentation as ORMDiagram) != null) { ObjectType subtype = subTypeFact.Subtype; // add a link shape for each object type shape on the diagram for the played role foreach (ObjectTypeShape shapeElement in MultiShapeUtility.FindAllShapesForElement <ObjectTypeShape>(diagram, subtype)) { diagram.FixUpLocalDiagram(subTypeFact); } FactType objectifiedFactType; if (null != (objectifiedFactType = subtype.NestedFactType)) { foreach (FactTypeShape shapeElement in MultiShapeUtility.FindAllShapesForElement <FactTypeShape>(diagram, objectifiedFactType)) { diagram.FixUpLocalDiagram(subTypeFact); } } } } if (!containedAllowMultipleShapes) { topLevelContextInfo.Remove(AllowMultipleShapes); } } }
/// <summary> /// Central function to return member variables to a clean state. /// Called by the constructor and the deactivation sequence. /// </summary> private void Reset() { myAddedConstraint = null; myDropTargetShape = null; }
/// <summary> /// Add a source shape or commit/cancel the action by forwarding the /// click to the base class, or modify the current role sequence by handling /// the click locally. /// </summary> /// <param name="e">MouseActionEventArgs</param> protected override void OnClicked(MouseActionEventArgs e) { switch (myPendingOnClickedAction) { case OnClickedAction.Commit: myPendingOnClickedAction = OnClickedAction.Normal; // Letting the click through to the base ConnectAction // at this point (a constraint is selected and a role has been // double-clicked) will force the connect action to finish. base.OnClicked(e); return; case OnClickedAction.CheckForCommit: myPendingOnClickedAction = OnClickedAction.Normal; break; } DiagramMouseEventArgs args = CurrentDiagramArgs as DiagramMouseEventArgs; if (args != null) { DiagramItem item = args.DiagramHitTestInfo.HitDiagramItem; ModelElement currentElement = null; foreach (ModelElement elem in item.RepresentedElements) { currentElement = elem; break; } UniquenessConstraint internalUniquenessConstraint; RoleBase roleBase; if (null != (internalUniquenessConstraint = currentElement as UniquenessConstraint) && internalUniquenessConstraint.IsInternal) { if (mySourceShape == null) { // Let the click through to the base to officially begin the drag action base.OnClicked(e); mySourceShape = item.Shape as FactTypeShape; myIUC = internalUniquenessConstraint; } } else if (mySourceShape != null) { if (null != (roleBase = currentElement as RoleBase)) { Role role = roleBase.Role; if (role.FactType == mySourceShape.AssociatedFactType) { // Add or remove the role IList <Role> roles = SelectedRoleCollection; int roleIndex = roles.IndexOf(role); bool forceRedraw = false; if (roleIndex >= 0) { // Only remove a role when the control key is down. Otherwise, // there is no way to double-click on a previously selected // role without turning it off, and this is a natural gesture. // Add shift key as well for discoverability. if (0 != (0xff00 & GetKeyState(Keys.ControlKey)) || 0 != (0xff00 & GetKeyState(Keys.ShiftKey))) { forceRedraw = true; roles.RemoveAt(roleIndex); } } else { forceRedraw = true; roles.Add(role); } if (mySourceShape != null) { myPendingOnClickedAction = OnClickedAction.CheckForCommit; } if (forceRedraw) { // Force the shape to redraw Debug.Assert(mySourceShape != null); //source shape should have been set mySourceShape.Invalidate(true); } } } else if (currentElement is ORMDiagram) { base.OnClicked(e); // Let through to allow a cancel } } } }