From: <mcu...@us...> - 2012-03-26 22:42:04
|
Revision: 1483 http://orm.svn.sourceforge.net/orm/?rev=1483&view=rev Author: mcurland Date: 2012-03-26 22:41:58 +0000 (Mon, 26 Mar 2012) Log Message: ----------- * Fix unconstrained unary fact types displaying as binary fact types on reload. * Fix role name shapes appearing for fact types displayed as object types on reload. * Add option in 'Appearance' category to not display shape shadows if shape appears more than once. Modified Paths: -------------- trunk/ORMModel/Resources/ResourceStrings.cs trunk/ORMModel/ShapeModel/FactTypeShape.cs trunk/ORMModel/ShapeModel/ModelNoteShape.cs trunk/ORMModel/ShapeModel/ORMDiagram.resx trunk/ORMModel/ShapeModel/ObjectTypeShape.cs trunk/ORMModel/ShapeModel/RoleNameShape.cs trunk/ORMModel/Shell/OptionsPage.cs Modified: trunk/ORMModel/Resources/ResourceStrings.cs =================================================================== --- trunk/ORMModel/Resources/ResourceStrings.cs 2012-01-23 19:35:08 UTC (rev 1482) +++ trunk/ORMModel/Resources/ResourceStrings.cs 2012-03-26 22:41:58 UTC (rev 1483) @@ -349,6 +349,14 @@ /// </summary> public const string OptionsPagePropertyRoleNameDisplayDisplayNameId = "OptionsPage.Property.RoleNameDisplay.DisplayName"; /// <summary> + /// Description of the Role Name Display option + /// </summary> + public const string OptionsPagePropertyDisplayShadowsDescriptionId = "OptionsPage.Property.DisplayShadows.Description"; + /// <summary> + /// Display Name of the Role Name Display option + /// </summary> + public const string OptionsPagePropertyDisplayShadowsDisplayNameId = "OptionsPage.Property.DisplayShadows.DisplayName"; + /// <summary> /// Description of the Primary Delete Behavior /// </summary> public const string OptionsPagePropertyPrimaryDeleteBehaviorDescriptionId = "OptionsPage.Property.PrimaryDeleteBehavior.Description"; Modified: trunk/ORMModel/ShapeModel/FactTypeShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/FactTypeShape.cs 2012-01-23 19:35:08 UTC (rev 1482) +++ trunk/ORMModel/ShapeModel/FactTypeShape.cs 2012-03-26 22:41:58 UTC (rev 1483) @@ -572,6 +572,10 @@ /// </summary> protected void ConfiguringAsChildOf(NodeShape parentShape, bool createdDuringViewFixup) { + EnsureUnaryRoleDisplayOrder(); + } + private void EnsureUnaryRoleDisplayOrder() + { // Make sure the factType shape is prepared to display as a unary FactType factType; Role unaryRole; @@ -3276,7 +3280,7 @@ { get { - return ORMBaseShape.ElementHasMultiplePresentations(this); + return OptionsPage.CurrentDisplayShadows && ORMBaseShape.ElementHasMultiplePresentations(this); } } /// <summary> @@ -6852,6 +6856,7 @@ /// </summary> protected sealed override void ProcessElement(FactTypeShape element, Store store, INotifyElementAdded notifyAdded) { + element.EnsureUnaryRoleDisplayOrder(); PointD centerPoint = RolesShape.GetBounds(element).Center; element.RolesPosition = (element.DisplayOrientation != DisplayOrientation.Horizontal) ? centerPoint.X : centerPoint.Y; } Modified: trunk/ORMModel/ShapeModel/ModelNoteShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/ModelNoteShape.cs 2012-01-23 19:35:08 UTC (rev 1482) +++ trunk/ORMModel/ShapeModel/ModelNoteShape.cs 2012-03-26 22:41:58 UTC (rev 1483) @@ -99,7 +99,7 @@ { get { - return ORMBaseShape.ElementHasMultiplePresentations(this); + return OptionsPage.CurrentDisplayShadows && ORMBaseShape.ElementHasMultiplePresentations(this); } } /// <summary> Modified: trunk/ORMModel/ShapeModel/ORMDiagram.resx =================================================================== --- trunk/ORMModel/ShapeModel/ORMDiagram.resx 2012-01-23 19:35:08 UTC (rev 1482) +++ trunk/ORMModel/ShapeModel/ORMDiagram.resx 2012-03-26 22:41:58 UTC (rev 1483) @@ -719,6 +719,14 @@ <value xml:space="preserve">Show Description Tooltips</value> <comment xml:space="preserve">The display name for the display definition tooltips property.</comment> </data> + <data name="OptionsPage.Property.DisplayShadows.Description"> + <value xml:space="preserve">Control if shape shadows are displayed when an element is represented by multiple shapes.</value> + <comment xml:space="preserve">The description for the Display Role Names option.</comment> + </data> + <data name="OptionsPage.Property.DisplayShadows.DisplayName"> + <value xml:space="preserve">Display Shadows</value> + <comment xml:space="preserve">The display name for the Display Shadows option.</comment> + </data> <data name="OptionsPage.Property.DelayActivateModelBrowserLabelEdits.Description"> <value xml:space="preserve">Automatically activate inline text editors in the ORM Model Browser after a short delay when selected with the mouse. Text edits can be explicitly activated with the View.EditLabel command (generally associated with the F2 key).</value> <comment xml:space="preserve">The delay activate model browser label edits description.</comment> Modified: trunk/ORMModel/ShapeModel/ObjectTypeShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/ObjectTypeShape.cs 2012-01-23 19:35:08 UTC (rev 1482) +++ trunk/ORMModel/ShapeModel/ObjectTypeShape.cs 2012-03-26 22:41:58 UTC (rev 1483) @@ -104,7 +104,7 @@ { get { - return ORMBaseShape.ElementHasMultiplePresentations(this); + return OptionsPage.CurrentDisplayShadows && ORMBaseShape.ElementHasMultiplePresentations(this); } } /// <summary> Modified: trunk/ORMModel/ShapeModel/RoleNameShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/RoleNameShape.cs 2012-01-23 19:35:08 UTC (rev 1482) +++ trunk/ORMModel/ShapeModel/RoleNameShape.cs 2012-03-26 22:41:58 UTC (rev 1483) @@ -262,21 +262,10 @@ FactTypeShape fts = element as FactTypeShape; if (fts != null) { - bool shouldDisplay = false; - bool shouldRemove = false; - if (fts.DisplayRoleNames == DisplayRoleNames.UserDefault - && OptionsPage.CurrentRoleNameDisplay == RoleNameDisplay.On) - { - shouldDisplay = true; - } - else if (fts.DisplayRoleNames == DisplayRoleNames.On) - { - shouldDisplay = true; - } - else if (fts.DisplayRoleNames == DisplayRoleNames.Off) - { - shouldRemove = true; - } + DisplayRoleNames display = fts.DisplayRoleNames; + bool asObjectType = fts.DisplayAsObjectType; + bool shouldDisplay = !asObjectType && display == DisplayRoleNames.On || (display == DisplayRoleNames.UserDefault && OptionsPage.CurrentRoleNameDisplay == RoleNameDisplay.On); + bool shouldRemove = asObjectType || display == DisplayRoleNames.Off; foreach (RoleBase roleBase in fact.RoleCollection) { Role role = roleBase as Role; Modified: trunk/ORMModel/Shell/OptionsPage.cs =================================================================== --- trunk/ORMModel/Shell/OptionsPage.cs 2012-01-23 19:35:08 UTC (rev 1482) +++ trunk/ORMModel/Shell/OptionsPage.cs 2012-03-26 22:41:58 UTC (rev 1483) @@ -351,6 +351,10 @@ private static RoleNameDisplay myCurrentRoleNameDisplay = RoleNameDisplay_Default; private RoleNameDisplay myRoleNameDisplay = RoleNameDisplay_Default; + private const bool DisplayShadows_Default = true; + private static bool myCurrentDisplayShadows = DisplayShadows_Default; + private bool myDisplayShadows = DisplayShadows_Default; + private const PortableDataType DefaultDataType_Default = PortableDataType.Unspecified; private static PortableDataType myCurrentDefaultDataType = DefaultDataType_Default; private PortableDataType myDefaultDataType = DefaultDataType_Default; @@ -449,6 +453,7 @@ myCurrentObjectifiedFactDisplayShape = myObjectifiedFactDisplayShape; myCurrentMandatoryDotPlacement = myMandatoryDotPlacement; myCurrentRoleNameDisplay = myRoleNameDisplay; + myCurrentDisplayShadows = myDisplayShadows; myCurrentDefaultDataType = myDefaultDataType; myCurrentExternalConstraintRoleBarDisplay = myExternalConstraintRoleBarDisplay; myCurrentPrimaryDeleteBehavior = myPrimaryDeleteBehavior; @@ -477,6 +482,7 @@ myObjectifiedFactDisplayShape = myCurrentObjectifiedFactDisplayShape; myMandatoryDotPlacement = myCurrentMandatoryDotPlacement; myRoleNameDisplay = myCurrentRoleNameDisplay; + myDisplayShadows = myCurrentDisplayShadows; myDefaultDataType = myCurrentDefaultDataType; myExternalConstraintRoleBarDisplay = myCurrentExternalConstraintRoleBarDisplay; myPrimaryDeleteBehavior = myCurrentPrimaryDeleteBehavior; @@ -512,6 +518,7 @@ myCurrentObjectifiedFactDisplayShape == myObjectifiedFactDisplayShape && myCurrentObjectTypeDisplayShape == myObjectTypeDisplayShape && myCurrentRoleNameDisplay == myRoleNameDisplay && + myCurrentDisplayShadows == myDisplayShadows && myCurrentExternalConstraintRoleBarDisplay == myExternalConstraintRoleBarDisplay && myCurrentPreferredInternalUniquenessConstraintDisplay == myPreferredInternalUniquenessConstraintDisplay && myCurrentReadingDirectionIndicatorDisplay == myReadingDirectionIndicatorDisplay && @@ -547,6 +554,7 @@ myCurrentObjectifiedFactDisplayShape = myObjectifiedFactDisplayShape; myCurrentObjectTypeDisplayShape = myObjectTypeDisplayShape; myCurrentRoleNameDisplay = myRoleNameDisplay; + myCurrentDisplayShadows = myDisplayShadows; myCurrentExternalConstraintRoleBarDisplay = myExternalConstraintRoleBarDisplay; myCurrentDefaultDataType = myDefaultDataType; myCurrentPrimaryDeleteBehavior = myPrimaryDeleteBehavior; @@ -720,6 +728,27 @@ } /// <summary> + /// Display of shape shadow + /// </summary> + [DefaultValue(DisplayShadows_Default)] + [LocalizedCategory(ResourceStrings.OptionsPageCategoryAppearanceId)] + [LocalizedDescription(ResourceStrings.OptionsPagePropertyDisplayShadowsDescriptionId)] + [LocalizedDisplayName(ResourceStrings.OptionsPagePropertyDisplayShadowsDisplayNameId)] + public bool DisplayShadows + { + get { return myDisplayShadows; } + set { myDisplayShadows = value; } + } + + /// <summary> + /// Current VS session-wide setting for DisplayShadows + /// </summary> + public static bool CurrentDisplayShadows + { + get { return myCurrentDisplayShadows; } + } + + /// <summary> /// Default data type for value types /// </summary> [DefaultValue(DefaultDataType_Default)] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2012-05-19 05:13:13
|
Revision: 1488 http://orm.svn.sourceforge.net/orm/?rev=1488&view=rev Author: mcurland Date: 2012-05-19 05:13:06 +0000 (Sat, 19 May 2012) Log Message: ----------- * Fix crash attempting to verbalizer internal uniqueness constraints with no roles. * Switch ORMBaseShape.DisplaysMultiplePresentations to IDisplayMultiplePresentations in diagram framework code. Enables 'select on other diagram' commands to work with any shape type. Modified Paths: -------------- trunk/ORMModel/Framework/Diagrams/MultiShapeUtility.cs trunk/ORMModel/ObjectModel/Constraint.cs trunk/ORMModel/ShapeModel/FactTypeShape.cs trunk/ORMModel/ShapeModel/ModelNoteShape.cs trunk/ORMModel/ShapeModel/ORMBaseShape.cs trunk/ORMModel/ShapeModel/ObjectTypeShape.cs trunk/ORMModel/Shell/ORMDesignerCommandManager.cs trunk/ORMModel/Shell/ORMModelBrowser.cs Modified: trunk/ORMModel/Framework/Diagrams/MultiShapeUtility.cs =================================================================== --- trunk/ORMModel/Framework/Diagrams/MultiShapeUtility.cs 2012-04-25 04:01:27 UTC (rev 1487) +++ trunk/ORMModel/Framework/Diagrams/MultiShapeUtility.cs 2012-05-19 05:13:06 UTC (rev 1488) @@ -1257,6 +1257,97 @@ return retVal ?? shape; } #endregion //Link Configuration + #region Utility Methods + /// <summary> + /// Determines if a the model element backing the shape element + /// is represented by a shape of the same type elsewhere in the presentation + /// layer. If a derived shape displays multiple presentations, they should + /// implement the<see cref="IDisplayMultiplePresentations"/> interface. + /// </summary> + public static bool ElementHasMultiplePresentations(ShapeElement shapeElement) + { + ModelElement modelElement; + if (null != shapeElement && + null != (modelElement = shapeElement.ModelElement)) + { + LinkedElementCollection<PresentationElement> presentationElements = PresentationViewsSubject.GetPresentation(modelElement); + int pelCount = presentationElements.Count; + if (pelCount != 0) + { + Partition shapePartition = shapeElement.Partition; + Type thisType = shapeElement.GetType(); + for (int i = 0; i < pelCount; ++i) + { + PresentationElement pel = presentationElements[i]; + if (shapeElement != pel && shapePartition == pel.Partition && thisType.IsAssignableFrom(pel.GetType())) + { + return true; + } + } + } + } + return false; + } + /// <summary> + /// Iterate shapes associated with a given element + /// </summary> + /// <param name="modelElement">The parent element to iterate. Can be <see langword="null"/> if <paramref name="shapeElement"/> is specified.</param> + /// <param name="shapeElement">The shape to reference. Can be <see langword="null"/> if <paramref name="modelElement"/> is specified.</param> + /// <param name="onePerDiagram">True to filter the shapes to one per diagram</param> + /// <param name="visitor">A <see cref="Predicate{ShapeElement}"/> callback. + /// Return <see langword="true"/> to continue iteration.</param> + public static void VisitAssociatedShapes(ModelElement modelElement, ShapeElement shapeElement, bool onePerDiagram, Predicate<ShapeElement> visitor) + { + if (modelElement == null && shapeElement != null) + { + modelElement = shapeElement.ModelElement; + } + if (modelElement != null) + { + LinkedElementCollection<PresentationElement> presentationElements = PresentationViewsSubject.GetPresentation(modelElement); + int pelCount = presentationElements.Count; + if (pelCount != 0) + { + List<Diagram> visitedDiagrams = null; + Diagram visitedDiagram = null; + + Partition shapePartition = (shapeElement != null) ? shapeElement.Partition : modelElement.Partition; + Type thisType = (shapeElement != null) ? shapeElement.GetType() : typeof(ShapeElement); + for (int i = 0; i < pelCount; ++i) + { + PresentationElement pel = presentationElements[i]; + if (shapePartition == pel.Partition && thisType.IsAssignableFrom(pel.GetType())) + { + ShapeElement sel = pel as ShapeElement; + Diagram selDiagram = sel.Diagram; + if (!onePerDiagram || (visitedDiagram != selDiagram && (visitedDiagrams == null || !visitedDiagrams.Contains(selDiagram)))) + { + if (!visitor(sel)) + { + return; + } + if (onePerDiagram) + { + if (visitedDiagram == null) + { + visitedDiagram = selDiagram; + } + else + { + if (visitedDiagrams == null) + { + visitedDiagrams = new List<Diagram>(); + } + visitedDiagrams.Add(selDiagram); + } + } + } + } + } + } + } + } + #endregion // Utility Methods } #region Interfaces @@ -1349,5 +1440,15 @@ /// <returns>NodeShape</returns> NodeShape GetUniqueConnectorShape(ShapeElement oppositeShape, ModelElement ignoreLinkShapesFor); } + /// <summary> + /// Indicate that the shape changes its display when more + /// than one presentation is visible. Derived shapes should + /// use the <see cref="MultiShapeUtility.ElementHasMultiplePresentations"/> + /// method to determine when multiple presentations should be displayed. + /// </summary> + public interface IDisplayMultiplePresentations + { + // No methods + } #endregion //Interfaces } Modified: trunk/ORMModel/ObjectModel/Constraint.cs =================================================================== --- trunk/ORMModel/ObjectModel/Constraint.cs 2012-04-25 04:01:27 UTC (rev 1487) +++ trunk/ORMModel/ObjectModel/Constraint.cs 2012-05-19 05:13:06 UTC (rev 1488) @@ -7791,34 +7791,37 @@ #endregion // UniquenessConstraintChangeRule #region Verbalization /// <summary> - /// Helper function to defer mandatory verbalization by constraint arity + /// Helper function to defer uniqueness verbalization parts /// </summary> private void VerbalizeParts(TextWriter writer, IDictionary<Type, IVerbalizationSets> snippetsDictionary, IVerbalizationContext verbalizationContext, VerbalizationSign sign) { - UniquenessVerbalizerBase verbalize; - if ((bool)verbalizationContext.VerbalizationOptions[CoreVerbalizationOption.ShowDefaultConstraint]) + if (this.RoleCollection.Count != 0) { - verbalize = UniquenessPossibilityVerbalizer.GetVerbalizer(); - using ((IDisposable)verbalize) + UniquenessVerbalizerBase verbalize; + if ((bool)verbalizationContext.VerbalizationOptions[CoreVerbalizationOption.ShowDefaultConstraint]) { - verbalize.Initialize(this); - verbalizationContext.DeferVerbalization(verbalize, DeferVerbalizationOptions.None, null); + verbalize = UniquenessPossibilityVerbalizer.GetVerbalizer(); + using ((IDisposable)verbalize) + { + verbalize.Initialize(this); + verbalizationContext.DeferVerbalization(verbalize, DeferVerbalizationOptions.None, null); + } } - } - verbalize = UniquenessConstraintVerbalizer.GetVerbalizer(); - using ((IDisposable)verbalize) - { - verbalize.Initialize(this); - verbalizationContext.DeferVerbalization(verbalize, DeferVerbalizationOptions.None, null); - } - if (this.PreferredIdentifierFor != null) - { - verbalize = UniquenessPreferredVerbalizer.GetVerbalizer(); + verbalize = UniquenessConstraintVerbalizer.GetVerbalizer(); using ((IDisposable)verbalize) { verbalize.Initialize(this); verbalizationContext.DeferVerbalization(verbalize, DeferVerbalizationOptions.None, null); } + if (this.PreferredIdentifierFor != null) + { + verbalize = UniquenessPreferredVerbalizer.GetVerbalizer(); + using ((IDisposable)verbalize) + { + verbalize.Initialize(this); + verbalizationContext.DeferVerbalization(verbalize, DeferVerbalizationOptions.None, null); + } + } } } #region UniquenessVerbalizerBase class and partials for each mandatory classification Modified: trunk/ORMModel/ShapeModel/FactTypeShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/FactTypeShape.cs 2012-04-25 04:01:27 UTC (rev 1487) +++ trunk/ORMModel/ShapeModel/FactTypeShape.cs 2012-05-19 05:13:06 UTC (rev 1488) @@ -42,7 +42,7 @@ namespace ORMSolutions.ORMArchitect.Core.ShapeModel { #region FactTypeShape class - public partial class FactTypeShape : ICustomShapeFolding, IModelErrorActivation, IProvideConnectorShape, IProxyDisplayProvider, IRedirectVerbalization, IConfigureAsChildShape, IDynamicColorGeometryHost, IDynamicColorAlsoUsedBy, IConfigureableLinkEndpoint + public partial class FactTypeShape : ICustomShapeFolding, IModelErrorActivation, IProvideConnectorShape, IProxyDisplayProvider, IRedirectVerbalization, IConfigureAsChildShape, IDynamicColorGeometryHost, IDynamicColorAlsoUsedBy, IConfigureableLinkEndpoint, IDisplayMultiplePresentations { #region ConstraintBoxRoleActivity enum /// <summary> @@ -3280,20 +3280,10 @@ { get { - return OptionsPage.CurrentDisplayShadows && ORMBaseShape.ElementHasMultiplePresentations(this); + return OptionsPage.CurrentDisplayShadows && MultiShapeUtility.ElementHasMultiplePresentations(this); } } /// <summary> - /// Support automatic appearance updating when multiple presentations are present. - /// </summary> - public override bool DisplaysMultiplePresentations - { - get - { - return true; - } - } - /// <summary> /// Always highlight /// </summary> public override bool HasHighlighting Modified: trunk/ORMModel/ShapeModel/ModelNoteShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/ModelNoteShape.cs 2012-04-25 04:01:27 UTC (rev 1487) +++ trunk/ORMModel/ShapeModel/ModelNoteShape.cs 2012-05-19 05:13:06 UTC (rev 1488) @@ -32,7 +32,7 @@ namespace ORMSolutions.ORMArchitect.Core.ShapeModel { #region ModelNoteShape class - public partial class ModelNoteShape : IConfigureAsChildShape, IDynamicColorGeometryHost + public partial class ModelNoteShape : IConfigureAsChildShape, IDynamicColorGeometryHost, IDisplayMultiplePresentations { private static AutoSizeTextField myTextField; // Now combined in DSL InitialWidth and InitialHeight @@ -99,20 +99,10 @@ { get { - return OptionsPage.CurrentDisplayShadows && ORMBaseShape.ElementHasMultiplePresentations(this); + return OptionsPage.CurrentDisplayShadows && MultiShapeUtility.ElementHasMultiplePresentations(this); } } /// <summary> - /// Support automatic appearance updating when multiple presentations are present. - /// </summary> - public override bool DisplaysMultiplePresentations - { - get - { - return true; - } - } - /// <summary> /// Connect lines to the edge of the rectangular shape /// </summary> public override ShapeGeometry ShapeGeometry Modified: trunk/ORMModel/ShapeModel/ORMBaseShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/ORMBaseShape.cs 2012-04-25 04:01:27 UTC (rev 1487) +++ trunk/ORMModel/ShapeModel/ORMBaseShape.cs 2012-05-19 05:13:06 UTC (rev 1488) @@ -98,95 +98,6 @@ #endregion // MultipleShapesSupport #region Customize appearance /// <summary> - /// Determines if a the model element backing the shape element - /// is represented by a shape of the same type elsewhere in the presentation - /// layer. If a derived shape displays multiple presentations, they should - /// also override the <see cref="DisplaysMultiplePresentations"/> property. - /// </summary> - public static bool ElementHasMultiplePresentations(ShapeElement shapeElement) - { - ModelElement modelElement; - if (null != shapeElement && - null != (modelElement = shapeElement.ModelElement)) - { - LinkedElementCollection<PresentationElement> presentationElements = PresentationViewsSubject.GetPresentation(modelElement); - int pelCount = presentationElements.Count; - if (pelCount != 0) - { - Partition shapePartition = shapeElement.Partition; - Type thisType = shapeElement.GetType(); - for (int i = 0; i < pelCount; ++i) - { - PresentationElement pel = presentationElements[i]; - if (shapeElement != pel && shapePartition == pel.Partition && thisType.IsAssignableFrom(pel.GetType())) - { - return true; - } - } - } - } - return false; - } - /// <summary> - /// Iterate shapes associated with a given element - /// </summary> - /// <param name="modelElement">The parent element to iterate. Can be <see langword="null"/> if <paramref name="shapeElement"/> is specified.</param> - /// <param name="shapeElement">The shape to reference. Can be <see langword="null"/> if <paramref name="modelElement"/> is specified.</param> - /// <param name="onePerDiagram">True to filter the shapes to one per diagram</param> - /// <param name="visitor">A <see cref="Predicate{ShapeElement}"/> callback. - /// Return <see langword="true"/> to continue iteration.</param> - public static void VisitAssociatedShapes(ModelElement modelElement, ShapeElement shapeElement, bool onePerDiagram, Predicate<ShapeElement> visitor) - { - if (modelElement == null && shapeElement != null) - { - modelElement = shapeElement.ModelElement; - } - if (modelElement != null) - { - LinkedElementCollection<PresentationElement> presentationElements = PresentationViewsSubject.GetPresentation(modelElement); - int pelCount = presentationElements.Count; - if (pelCount != 0) - { - List<Diagram> visitedDiagrams = null; - Diagram visitedDiagram = null; - - Partition shapePartition = (shapeElement != null) ? shapeElement.Partition : modelElement.Partition; - Type thisType = (shapeElement != null) ? shapeElement.GetType() : typeof(ShapeElement); - for (int i = 0; i < pelCount; ++i) - { - PresentationElement pel = presentationElements[i]; - if (shapePartition == pel.Partition && thisType.IsAssignableFrom(pel.GetType())) - { - ShapeElement sel = pel as ShapeElement; - Diagram selDiagram = sel.Diagram; - if (!onePerDiagram || (visitedDiagram != selDiagram && (visitedDiagrams == null || !visitedDiagrams.Contains(selDiagram)))) - { - if (!visitor(sel)) - { - return; - } - if (onePerDiagram) - { - if (visitedDiagram == null) - { - visitedDiagram = selDiagram; - } - else - { - if (visitedDiagrams == null) - { - visitedDiagrams = new List<Diagram>(); - } - visitedDiagrams.Add(selDiagram); - } - } - } - } - } - } - } - } - /// <summary> /// Turn off the shadow by default /// </summary> /// <value>false</value> @@ -195,20 +106,6 @@ get { return false; } } /// <summary> - /// Indicate that the shape changes its display when more - /// than one presentation is visible. Derived shapes should - /// use the <see cref="ElementHasMultiplePresentations"/> method - /// to determine when multiple presentations should be displayed. - /// Default is <see langword="false"/> - /// </summary> - public virtual bool DisplaysMultiplePresentations - { - get - { - return false; - } - } - /// <summary> /// Default to no sides being resizable. /// </summary> public override NodeSides ResizableSides @@ -552,7 +449,7 @@ { ORMBaseShape shape = e.ModelElement as ORMBaseShape; ModelElement backingElement; - if (shape.DisplaysMultiplePresentations && + if (shape is IDisplayMultiplePresentations && null != (backingElement = shape.ModelElement)) { InvalidateRemainingShapes(backingElement, shape); @@ -561,16 +458,14 @@ private static void ShapeDeletedEvent(object sender, ElementDeletedEventArgs e) { PresentationViewsSubject link = e.ModelElement as PresentationViewsSubject; - ORMBaseShape shape; ModelElement backingElement; if (!(backingElement = link.Subject).IsDeleted && - null != (shape = link.Presentation as ORMBaseShape) && - shape.DisplaysMultiplePresentations) + link.Presentation is IDisplayMultiplePresentations) { InvalidateRemainingShapes(backingElement, null); } } - private static void InvalidateRemainingShapes(ModelElement backingElement, ORMBaseShape ignoreShape) + private static void InvalidateRemainingShapes(ModelElement backingElement, ShapeElement ignoreShape) { LinkedElementCollection<PresentationElement> pels = PresentationViewsSubject.GetPresentation(backingElement); int pelCount = pels.Count; @@ -579,9 +474,10 @@ for (int i = 0; i < pelCount; ++i) { PresentationElement pel = pels[i]; - ORMBaseShape updateShape; + ShapeElement updateShape; if (pel != ignoreShape && - null != (updateShape = pel as ORMBaseShape)) + null != (updateShape = pel as ShapeElement) && + updateShape is IDisplayMultiplePresentations) { updateShape.Invalidate(); } Modified: trunk/ORMModel/ShapeModel/ObjectTypeShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/ObjectTypeShape.cs 2012-04-25 04:01:27 UTC (rev 1487) +++ trunk/ORMModel/ShapeModel/ObjectTypeShape.cs 2012-05-19 05:13:06 UTC (rev 1488) @@ -36,7 +36,7 @@ namespace ORMSolutions.ORMArchitect.Core.ShapeModel { - public partial class ObjectTypeShape : IModelErrorActivation, IDynamicColorGeometryHost, IDynamicColorAlsoUsedBy, IConfigureableLinkEndpoint + public partial class ObjectTypeShape : IModelErrorActivation, IDynamicColorGeometryHost, IDynamicColorAlsoUsedBy, IConfigureableLinkEndpoint, IDisplayMultiplePresentations { #region Member Variables private static AutoSizeTextField myTextShapeField; @@ -104,20 +104,10 @@ { get { - return OptionsPage.CurrentDisplayShadows && ORMBaseShape.ElementHasMultiplePresentations(this); + return OptionsPage.CurrentDisplayShadows && MultiShapeUtility.ElementHasMultiplePresentations(this); } } /// <summary> - /// Support automatic appearance updating when multiple presentations are present. - /// </summary> - public override bool DisplaysMultiplePresentations - { - get - { - return true; - } - } - /// <summary> /// Switch between the standard solid pen and /// a dashed pen depending on the objectification settings /// </summary> Modified: trunk/ORMModel/Shell/ORMDesignerCommandManager.cs =================================================================== --- trunk/ORMModel/Shell/ORMDesignerCommandManager.cs 2012-04-25 04:01:27 UTC (rev 1487) +++ trunk/ORMModel/Shell/ORMDesignerCommandManager.cs 2012-05-19 05:13:06 UTC (rev 1488) @@ -34,6 +34,7 @@ using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using ORMSolutions.ORMArchitect.Framework; +using ORMSolutions.ORMArchitect.Framework.Diagrams; using ORMSolutions.ORMArchitect.Framework.Design; using ORMSolutions.ORMArchitect.Core.ObjectModel; using ORMSolutions.ORMArchitect.Core.ObjectModel.Design; @@ -978,10 +979,10 @@ toleratedCommands |= ORMDesignerCommands.AlignShapes; } } - ORMBaseShape shape; - if (null != (shape = (presentationElement as ORMBaseShape)) && - shape.DisplaysMultiplePresentations && - ORMBaseShape.ElementHasMultiplePresentations(shape)) + ShapeElement shape; + if (null != (shape = presentationElement as ShapeElement) && + shape is IDisplayMultiplePresentations && + MultiShapeUtility.ElementHasMultiplePresentations(shape)) { visibleCommands |= ORMDesignerCommands.DiagramList; enabledCommands |= ORMDesignerCommands.DiagramList; @@ -2797,7 +2798,7 @@ // other shapes on the first diagram ShapeElement firstShape = null; bool seenCurrent = false; - ORMBaseShape.VisitAssociatedShapes( + MultiShapeUtility.VisitAssociatedShapes( null, shape, false, @@ -2841,17 +2842,19 @@ IList selectedElements = myDesignerView.SelectedElements; if (selectedElements.Count >= 1) // Single-select command { - ORMBaseShape shape = selectedElements[0] as ORMBaseShape; - if (shape != null) + ShapeElement shape = selectedElements[0] as ShapeElement; + if (shape != null && + shape is IDisplayMultiplePresentations) { Diagram shapeDiagram = shape.Diagram; - ORMBaseShape.VisitAssociatedShapes( + MultiShapeUtility.VisitAssociatedShapes( null, shape, true, delegate(ShapeElement testShape) { - if (testShape.Diagram != shapeDiagram) + if (testShape.Diagram != shapeDiagram && + testShape is IDisplayMultiplePresentations) { if (diagramIndex == 0) { Modified: trunk/ORMModel/Shell/ORMModelBrowser.cs =================================================================== --- trunk/ORMModel/Shell/ORMModelBrowser.cs 2012-04-25 04:01:27 UTC (rev 1487) +++ trunk/ORMModel/Shell/ORMModelBrowser.cs 2012-05-19 05:13:06 UTC (rev 1488) @@ -33,6 +33,7 @@ using Microsoft.VisualStudio.VirtualTreeGrid; using ORMSolutions.ORMArchitect.Framework; using ORMSolutions.ORMArchitect.Framework.Design; +using ORMSolutions.ORMArchitect.Framework.Diagrams; using ORMSolutions.ORMArchitect.Framework.Shell; using ORMSolutions.ORMArchitect.Framework.Shell.DynamicSurveyTreeGrid; using ORMSolutions.ORMArchitect.Core.ObjectModel; @@ -173,7 +174,7 @@ null != (element = selectedNode as ModelElement)) { int diagramIndex = cmd.MatchedCommandId; - ORMBaseShape.VisitAssociatedShapes( + MultiShapeUtility.VisitAssociatedShapes( element, null, true, @@ -669,7 +670,7 @@ null != (element = elementReference.ReferencedElement as ModelElement) : null != (element = selectedNode as ModelElement)) { - ORMBaseShape.VisitAssociatedShapes( + MultiShapeUtility.VisitAssociatedShapes( element, null, true, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2012-10-04 01:30:35
|
Revision: 1493 http://orm.svn.sourceforge.net/orm/?rev=1493&view=rev Author: mcurland Date: 2012-10-04 01:30:28 +0000 (Thu, 04 Oct 2012) Log Message: ----------- Bug fixes for shape creation scenarios * ORMDiagram.AutoPopulateShapes (set during import scenarios) was no longer effective after changes in [1482] to reduce phantom shape creation. Add an additional fixup listener to automatically add object type and fact type shapes for all elements to a diagram when this property is set. * Duplicating a fact type shape with a connected role value constraint on the same diagram or in a different model did not recreate the rang link shape (the dotted line) for the new shape. * Cross-model dragging of value constraint shapes on both value type and fact type shapes reverted copied shape position to the default location. Modified Paths: -------------- trunk/ORMModel/Framework/DeserializationManager.cs trunk/ORMModel/Framework/Diagrams/MultiShapeUtility.cs trunk/ORMModel/ObjectModel/ORMModel.cs trunk/ORMModel/ShapeModel/ORMShape.DeserializationFixupListeners.cs trunk/ORMModel/ShapeModel/ReadingShape.cs trunk/ORMModel/ShapeModel/RoleNameShape.cs trunk/ORMModel/ShapeModel/ValueRangeShape.cs trunk/ORMModel/ShapeModel/ViewFixupRules.cs Modified: trunk/ORMModel/Framework/DeserializationManager.cs =================================================================== --- trunk/ORMModel/Framework/DeserializationManager.cs 2012-10-04 01:16:54 UTC (rev 1492) +++ trunk/ORMModel/Framework/DeserializationManager.cs 2012-10-04 01:30:28 UTC (rev 1493) @@ -326,21 +326,26 @@ /// <summary> /// The first standard fixup phase for loading presentation elements. /// </summary> - FirstPresentationElementPhase = ValidateStoredPresentationElements, + FirstPresentationElementPhase = AutoCreateStoredPresentationElements, + /// <summary> + /// Initialized automatically created stored presentation elements that + /// will be serialized with the model. + /// </summary> + AutoCreateStoredPresentationElements = 5100, /// <summary> /// Fixup stored presentation elements /// </summary> - ValidateStoredPresentationElements = 5100, + ValidateStoredPresentationElements = 5200, /// <summary> /// Validate presentation elements that are implicitly recreated /// if they are not serialized. /// </summary> - ValidateImplicitStoredPresentationElements = 5200, + ValidateImplicitStoredPresentationElements = 5300, /// <summary> /// Add any presentation elements that are implicit and not /// serialized with the model. /// </summary> - AddImplicitPresentationElements = 5300, + AddImplicitPresentationElements = 5400, /// <summary> /// The last standard fixup phase for loading presentation elements. /// </summary> Modified: trunk/ORMModel/Framework/Diagrams/MultiShapeUtility.cs =================================================================== --- trunk/ORMModel/Framework/Diagrams/MultiShapeUtility.cs 2012-10-04 01:16:54 UTC (rev 1492) +++ trunk/ORMModel/Framework/Diagrams/MultiShapeUtility.cs 2012-10-04 01:30:28 UTC (rev 1493) @@ -149,7 +149,8 @@ } } - if (allowMultipleShapesForChildren) + if (allowMultipleShapesForChildren && + (existingChildShape == null || existingChildShape is LinkShape || existingChildShape.ParentShape != existingParentShape)) { if (unparentedChildShape == null) { @@ -188,10 +189,10 @@ existingChildShape.OnBoundsFixup(BoundsFixupState.ViewFixup, 0, false); //fix up grand child shapes - ICollection GrandChildShapes = existingChildShape.GetChildElements(childElement); - foreach (ModelElement GrandChildShape in GrandChildShapes) + ICollection grandChildShapes = existingChildShape.GetChildElements(childElement); + foreach (ModelElement grandChildShape in grandChildShapes) { - existingChildShape.FixUpChildShapes(GrandChildShape); + existingChildShape.FixUpChildShapes(grandChildShape); } return existingChildShape; Modified: trunk/ORMModel/ObjectModel/ORMModel.cs =================================================================== --- trunk/ORMModel/ObjectModel/ORMModel.cs 2012-10-04 01:16:54 UTC (rev 1492) +++ trunk/ORMModel/ObjectModel/ORMModel.cs 2012-10-04 01:30:28 UTC (rev 1493) @@ -70,11 +70,15 @@ /// explicit, intrinsic, and implicit elements are in place. /// </summary> ValidateErrors = StandardFixupPhase.LastModelElementPhase + 200, - /// <summary> + /// <summary> + /// Create implicitly stored presentation elements + /// </summary> + AutoCreateStoredPresentationElements = StandardFixupPhase.AutoCreateStoredPresentationElements, + /// <summary> /// Fixup stored presentation elements /// </summary> ValidateStoredPresentationElements = StandardFixupPhase.ValidateStoredPresentationElements, - /// <summary> + /// <summary> /// Add any presentation elements that are implicit and not /// serialized with the model. /// </summary> Modified: trunk/ORMModel/ShapeModel/ORMShape.DeserializationFixupListeners.cs =================================================================== --- trunk/ORMModel/ShapeModel/ORMShape.DeserializationFixupListeners.cs 2012-10-04 01:16:54 UTC (rev 1492) +++ trunk/ORMModel/ShapeModel/ORMShape.DeserializationFixupListeners.cs 2012-10-04 01:30:28 UTC (rev 1493) @@ -38,7 +38,8 @@ yield return new DisplayValueTypeValueConstraintFixupListener(); yield return new DisplayRoleNameFixupListener(); yield return new DisplayModelNoteLinksFixupListener(); - yield return FactTypeShape.FixupListener; + yield return new DisplayAutoPopulatedShapesFixupListener(); + yield return FactTypeShape.FixupListener; yield return ReadingShape.FixupListener; yield return ObjectTypeShape.FixupListener; yield return ObjectifiedFactTypeNameShape.FixupListener; Modified: trunk/ORMModel/ShapeModel/ReadingShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/ReadingShape.cs 2012-10-04 01:16:54 UTC (rev 1492) +++ trunk/ORMModel/ShapeModel/ReadingShape.cs 2012-10-04 01:30:28 UTC (rev 1493) @@ -331,24 +331,27 @@ /// <param name="createdDuringViewFixup">Whether this shape was created as part of a view fixup</param> public override void PlaceAsChildOf(NodeShape parent, bool createdDuringViewFixup) { - FactTypeShape factTypeShape = (FactTypeShape)parent; - FactType factType; - Objectification objectification; AutoResize(); - SizeD size = Size; - double yOffset; - if (factTypeShape.ConstraintDisplayPosition == ConstraintDisplayPosition.Bottom && - (null == (factType = factTypeShape.AssociatedFactType) || - null == (objectification = factType.Objectification) || - objectification.IsImplied)) + if (createdDuringViewFixup) { - yOffset = -1.5 * size.Height; + FactTypeShape factTypeShape = (FactTypeShape)parent; + FactType factType; + Objectification objectification; + SizeD size = Size; + double yOffset; + if (factTypeShape.ConstraintDisplayPosition == ConstraintDisplayPosition.Bottom && + (null == (factType = factTypeShape.AssociatedFactType) || + null == (objectification = factType.Objectification) || + objectification.IsImplied)) + { + yOffset = -1.5 * size.Height; + } + else + { + yOffset = factTypeShape.Size.Height + .5 * size.Height; + } + Location = new PointD(0, yOffset); } - else - { - yOffset = factTypeShape.Size.Height + .5 * size.Height; - } - Location = new PointD(0, yOffset); } /// <summary> /// Overrides default implemenation to instantiate an Reading specific one. Modified: trunk/ORMModel/ShapeModel/RoleNameShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/RoleNameShape.cs 2012-10-04 01:16:54 UTC (rev 1492) +++ trunk/ORMModel/ShapeModel/RoleNameShape.cs 2012-10-04 01:30:28 UTC (rev 1493) @@ -96,19 +96,22 @@ /// <param name="createdDuringViewFixup">Whether this shape was created as part of a view fixup</param> public override void PlaceAsChildOf(NodeShape parent, bool 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) + if (createdDuringViewFixup) { - x += roleIndex * 0.15; - y -= roleIndex * 0.15; + 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); } - Location = new PointD(x, y); } /// <summary> /// Highlight both the name shape and the corresponding role box. Modified: trunk/ORMModel/ShapeModel/ValueRangeShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/ValueRangeShape.cs 2012-10-04 01:16:54 UTC (rev 1492) +++ trunk/ORMModel/ShapeModel/ValueRangeShape.cs 2012-10-04 01:30:28 UTC (rev 1493) @@ -180,12 +180,15 @@ public override void PlaceAsChildOf(NodeShape parent, bool createdDuringViewFixup) { AutoResize(); - SizeD size = Size; - RectangleD parentBounds = ParentShape.AbsoluteBoundingBox; - // Place slightly to the right. This will cause the label to - // track in this position due to a horizontal resize of the - // shape because of rename, etc - Location = new PointD(parentBounds.Width + .06, -1 * size.Height); + if (createdDuringViewFixup) + { + SizeD size = Size; + RectangleD parentBounds = ParentShape.AbsoluteBoundingBox; + // Place slightly to the right. This will cause the label to + // track in this position due to a horizontal resize of the + // shape because of rename, etc + Location = new PointD(parentBounds.Width + .06, -1 * size.Height); + } } /// <summary> /// Overrides default implemenation to instantiate an value constraint specific one. Modified: trunk/ORMModel/ShapeModel/ViewFixupRules.cs =================================================================== --- trunk/ORMModel/ShapeModel/ViewFixupRules.cs 2012-10-04 01:16:54 UTC (rev 1492) +++ trunk/ORMModel/ShapeModel/ViewFixupRules.cs 2012-10-04 01:30:28 UTC (rev 1493) @@ -794,8 +794,6 @@ ORMModel model = factType.Model; if (model != null) { - Diagram.FixUpDiagram(factType, roleValueConstraint); - object AllowMultipleShapes; Dictionary<object, object> topLevelContextInfo; bool containedAllowMultipleShapes; @@ -804,6 +802,8 @@ topLevelContextInfo.Add(AllowMultipleShapes, null); } + Diagram.FixUpDiagram(factType, roleValueConstraint); + foreach (PresentationViewsSubject presentationViewsSubject in DomainRoleInfo.GetElementLinks<PresentationViewsSubject>(model, PresentationViewsSubject.SubjectDomainRoleId)) { ORMDiagram diagram; @@ -813,7 +813,6 @@ foreach (ValueConstraintShape shapeElement in MultiShapeUtility.FindAllShapesForElement<ValueConstraintShape>(diagram, roleValueConstraint)) { diagram.FixUpLocalDiagram(link); - break; } } } @@ -880,7 +879,20 @@ if (null != (objectType = valueConstraint.ValueType) && null != (model = objectType.Model)) { + object AllowMultipleShapes; + Dictionary<object, object> topLevelContextInfo; + bool containedAllowMultipleShapes; + if (!(containedAllowMultipleShapes = (topLevelContextInfo = link.Store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo).ContainsKey(AllowMultipleShapes = MultiShapeUtility.AllowMultipleShapes))) + { + topLevelContextInfo.Add(AllowMultipleShapes, null); + } + Diagram.FixUpDiagram(objectType, valueConstraint); + + if (!containedAllowMultipleShapes) + { + topLevelContextInfo.Remove(AllowMultipleShapes); + } } } /// <summary> @@ -901,8 +913,6 @@ null != (objectType = uniquenessConstraint.PreferredIdentifierFor) && null != (model = objectType.Model)) { - Diagram.FixUpDiagram(objectType, roleValueConstraint); - object AllowMultipleShapes; Dictionary<object, object> topLevelContextInfo; bool containedAllowMultipleShapes; @@ -911,6 +921,7 @@ topLevelContextInfo.Add(AllowMultipleShapes, null); } + Diagram.FixUpDiagram(objectType, roleValueConstraint); Diagram.FixUpDiagram(model, link); if (!containedAllowMultipleShapes) @@ -1231,9 +1242,66 @@ } } #endregion // ModelNote fixup - #region ForceClearViewFixupDataListRuleClass - partial class ForceClearViewFixupDataListRuleClass + #region Auto populated diagram fixup + #region DisplayAutoPopulatedShapesFixupListener class + /// <summary> + /// A fixup class to create top-level shapes for auotmatically populated ORM diagrams. + /// </summary> + /// <remarks>This used to happen automatically when fixup listeners for implicit + /// links verified the existence of the shapes they were attaching too. However, this + /// had too many side effects, so we now check this condition explicitly on load.</remarks> + private sealed class DisplayAutoPopulatedShapesFixupListener : DeserializationFixupListener<ORMDiagram> { + /// <summary> + /// Create a new DisplayAutoPopulatedShapesFixupListener + /// </summary> + public DisplayAutoPopulatedShapesFixupListener() + : base((int)ORMDeserializationFixupPhase.AutoCreateStoredPresentationElements) + { + } + /// <summary> + /// Add top-level auto populated shapes to a diagram + /// </summary> + /// <param name="element">An ORMDiagram 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(ORMDiagram element, Store store, INotifyElementAdded notifyAdded) + { + if (element.AutoPopulateShapes) + { + IElementDirectory elementDir = store.ElementDirectory; + ShapeElement shape; + foreach (ObjectType objectType in elementDir.FindElements<ObjectType>(false)) + { + Objectification objectification; + if (!objectType.IsImplicitBooleanValue && + (null == (objectification = objectType.Objectification) || !objectification.IsImplied)) + { + if (null != (shape = element.FixUpLocalDiagram(element, objectType))) + { + notifyAdded.ElementAdded(shape, true); + } + } + } + foreach (FactType factType in elementDir.FindElements<FactType>(false)) + { + if (null == factType.ImpliedByObjectification) + { + if (null != (shape = element.FixUpLocalDiagram(element, factType))) + { + notifyAdded.ElementAdded(shape, true); + } + } + + } + } + } + } + #endregion // DisplayModelNoteLinksFixupListener class + #endregion // Auto populated diagram fixup + #region ForceClearViewFixupDataListRuleClass + partial class ForceClearViewFixupDataListRuleClass + { #region Dynamic Microsoft.VisualStudio.Modeling.Diagrams.Diagram.GetViewFixupDataListCount implementation private delegate int GetViewFixupDataListCountDelegate(Diagram @this); private static readonly GetViewFixupDataListCountDelegate GetViewFixupDataListCount = CreateGetViewFixupDataListCount(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2013-08-25 03:53:00
|
Revision: 1521 http://sourceforge.net/p/orm/code/1521 Author: mcurland Date: 2013-08-25 03:52:55 +0000 (Sun, 25 Aug 2013) Log Message: ----------- Miscellaneous bug fixes: * Context window not populating (broken by more stringent partition check in [1518]) * Added Ctrl-=-0 key bindings for zoom in/out/100%. Left in Ctrl-Shift-=-0 bindings as well, but Ctrl-Shift-0 is a system hotkey used for keyboard switching in and after Win7. * Sample population errors on disjunctive mandatory constraints could not be cleared if the constrained roles had different (compatible) role players. Added tests to look for subtype instances in the population. * Choosing the RequireUserModification option during database import caused a schema violation error during load. Modified Paths: -------------- trunk/ORMModel/ObjectModel/SamplePopulation.cs trunk/ORMModel/ShapeModel/ORMDiagram.cs trunk/ORMModel/Shell/Converters/OIALtoORM.xslt trunk/ORMModel/Shell/ORMContextWindow.cs trunk/ORMModel/Shell/PackageResources/PkgCmd.vsct Modified: trunk/ORMModel/ObjectModel/SamplePopulation.cs =================================================================== --- trunk/ORMModel/ObjectModel/SamplePopulation.cs 2013-07-28 22:58:39 UTC (rev 1520) +++ trunk/ORMModel/ObjectModel/SamplePopulation.cs 2013-08-25 03:52:55 UTC (rev 1521) @@ -3903,6 +3903,8 @@ if (null != (objectType = this.ObjectType)) { LinkedElementCollection<Role> playedRoles = objectType.PlayedRoleCollection; + LinkedElementCollection<EntityTypeSubtypeInstance> subtypeInstances = null; + bool retrievedSubtypeInstances = false; int playedRoleCount = playedRoles.Count; LinkedElementCollection<PopulationMandatoryError> errors = this.PopulationMandatoryErrorCollection; if (playedRoleCount == 0) @@ -4048,9 +4050,60 @@ } else { - ReadOnlyLinkedElementCollection<ObjectTypeInstance> roleInstances = (currentRole == constraintRole) ? currentRoleInstances : constraintRole.ObjectTypeInstanceCollection; - if (roleInstances.Contains(this)) + ReadOnlyLinkedElementCollection<ObjectTypeInstance> roleInstances; + ObjectTypeInstance findInstance; + if (currentRole == constraintRole) { + roleInstances = currentRoleInstances; + findInstance = this; + } + else + { + roleInstances = constraintRole.ObjectTypeInstanceCollection; + ObjectType roleType = constraintRole.RolePlayer; + if (roleType == objectType) + { + findInstance = this; + } + else + { + findInstance = null; + if (!retrievedSubtypeInstances) + { + retrievedSubtypeInstances = true; + EntityTypeInstance entityInstance; + EntityTypeSubtypeInstance subtypeInstance; + if (null != (entityInstance = this as EntityTypeInstance)) + { + subtypeInstances = entityInstance.EntityTypeSubtypeInstanceCollection; + } + else if (null != (subtypeInstance = this as EntityTypeSubtypeInstance)) + { + subtypeInstances = subtypeInstance.SupertypeInstance.EntityTypeSubtypeInstanceCollection; + } + if (subtypeInstances != null && + subtypeInstances.Count == 0) + { + subtypeInstances = null; + } + } + if (subtypeInstances != null) + { + foreach (EntityTypeSubtypeInstance subtypeInstance in subtypeInstances) + { + if (subtypeInstance.EntityTypeSubtype == roleType) + { + findInstance = subtypeInstance; + break; + } + } + } + } + } + //= (currentRole == constraintRole) ? currentRoleInstances : constraintRole.ObjectTypeInstanceCollection; + if (findInstance != null && + roleInstances.Contains(findInstance)) + { break; } } Modified: trunk/ORMModel/ShapeModel/ORMDiagram.cs =================================================================== --- trunk/ORMModel/ShapeModel/ORMDiagram.cs 2013-07-28 22:58:39 UTC (rev 1520) +++ trunk/ORMModel/ShapeModel/ORMDiagram.cs 2013-08-25 03:52:55 UTC (rev 1521) @@ -1087,6 +1087,17 @@ return element; } /// <summary> + /// Customizable test to determine if shapes should be + /// created for elements in a given partition. Allows a + /// diagram and the elements it is displaying to be in + /// different partitions. Implementations of this callback + /// should use the <see cref="Partition.AlternateId"/> property + /// of the provided partition instead of the <see cref="Partition"/> + /// instance so that drag-drop from others models is supported. + /// </summary> + [NonSerialized] + public Predicate<Partition> ForeignPartitionTest = null; + /// <summary> /// Check if the element has valid ownership for appearing /// on this diagram. Allows ORM elements to be used in structures /// outside the core model without appearing on a diagram. @@ -1097,7 +1108,11 @@ { // Use the partition id instead of the partition itself so that dragging // from other models is supported. - return element.Partition.AlternateId == this.Partition.AlternateId && !(element is IHasAlternateOwner); + Predicate<Partition> partitionTest = ForeignPartitionTest; + return (partitionTest != null ? + partitionTest(element.Partition) : + element.Partition.AlternateId == this.Partition.AlternateId) && + !(element is IHasAlternateOwner); } /// <summary> /// Called as a result of the FixUpDiagram calls Modified: trunk/ORMModel/Shell/Converters/OIALtoORM.xslt =================================================================== --- trunk/ORMModel/Shell/Converters/OIALtoORM.xslt 2013-07-28 22:58:39 UTC (rev 1520) +++ trunk/ORMModel/Shell/Converters/OIALtoORM.xslt 2013-08-25 03:52:55 UTC (rev 1521) @@ -72,7 +72,7 @@ <xsl:if test="$RequireReadingModification"> <orm:ModelErrors> <xsl:for-each select="$allFactTypes/orm:ReadingOrders/orm:ReadingOrder/orm:Readings/orm:Reading"> - <orm:ReadingRequiresUserModificationError id="ReadingRequiresUserModificationError.{@id}"> + <orm:ReadingRequiresUserModificationError Name="" id="ReadingRequiresUserModificationError.{@id}"> <orm:Reading ref="{@id}"/> </orm:ReadingRequiresUserModificationError> </xsl:for-each> Modified: trunk/ORMModel/Shell/ORMContextWindow.cs =================================================================== --- trunk/ORMModel/Shell/ORMContextWindow.cs 2013-07-28 22:58:39 UTC (rev 1520) +++ trunk/ORMModel/Shell/ORMContextWindow.cs 2013-08-25 03:52:55 UTC (rev 1521) @@ -571,6 +571,10 @@ using (Transaction t = store.TransactionManager.BeginTransaction("Create Context Diagram")) { diagram = new ORMDiagram(partition); + diagram.ForeignPartitionTest = delegate(Partition elementPartition) + { + return elementPartition.AlternateId == null; + }; diagram.Associate(myDiagramView); myDiagramView.HasWatermark = false; diagram.ModelElement = model; Modified: trunk/ORMModel/Shell/PackageResources/PkgCmd.vsct =================================================================== --- trunk/ORMModel/Shell/PackageResources/PkgCmd.vsct 2013-07-28 22:58:39 UTC (rev 1520) +++ trunk/ORMModel/Shell/PackageResources/PkgCmd.vsct 2013-08-25 03:52:55 UTC (rev 1521) @@ -944,8 +944,13 @@ <KeyBinding guid="guidORMDesignerCommandSet" id="cmdIdViewReferenceModeEditor" editor="guidORMDesignerEditor" key1="W" mod1="Control" key2="E" mod2="Control"/> <KeyBinding guid="guidORMDesignerCommandSet" id="cmdIdViewContextWindow" editor="guidORMDesignerEditor" key1="W" mod1="Control" key2="C" mod2="Control"/> <KeyBinding guid="guidORMDesignerCommandSet" id="cmdIdViewDiagramSpyWindow" editor="guidORMDesignerEditor" key1="W" mod1="Control" key2="D" mod2="Control"/> + <KeyBinding guid="guidORMDesignerCommandSet" id="cmdIdZoom100" editor="guidORMDesignerEditor" key1="48" mod1="Control"/> + <!-- Note that Control-Shift-0 is a default windows hotkey in and after Windows 7. This was the original setting, but the control-only + versionts needed to be added so that Zoom100 would have a normal hotkey. --> <KeyBinding guid="guidORMDesignerCommandSet" id="cmdIdZoom100" editor="guidORMDesignerEditor" key1="48" mod1="Control Shift"/> + <KeyBinding guid="guidORMDesignerCommandSet" id="cmdIdZoomIn" editor="guidORMDesignerEditor" key1="187" mod1="Control"/> <KeyBinding guid="guidORMDesignerCommandSet" id="cmdIdZoomIn" editor="guidORMDesignerEditor" key1="187" mod1="Control Shift"/> + <KeyBinding guid="guidORMDesignerCommandSet" id="cmdIdZoomOut" editor="guidORMDesignerEditor" key1="189" mod1="Control"/> <KeyBinding guid="guidORMDesignerCommandSet" id="cmdIdZoomOut" editor="guidORMDesignerEditor" key1="189" mod1="Control Shift"/> <!-- Fact editor key bindings--> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2014-05-09 03:57:34
|
Revision: 1545 http://sourceforge.net/p/orm/code/1545 Author: mcurland Date: 2014-05-09 03:57:29 +0000 (Fri, 09 May 2014) Log Message: ----------- Fix a couple of diagram tab issues. * Pressing the delete key while renaming a diagram tab would delete the selection on the current diagram instead of the selection in the text box. * If the page reorder dialog is opened from a specific diagram tab then initially select that diagram. Modified Paths: -------------- trunk/ORMModel/Framework/Shell/DiagramOrderDialog.cs trunk/ORMModel/Framework/Shell/MultiDiagramDocView.cs trunk/ORMModel/Framework/Shell/MultiDiagramDocViewControl.cs trunk/ORMModel/Shell/ORMDocView.cs Modified: trunk/ORMModel/Framework/Shell/DiagramOrderDialog.cs =================================================================== --- trunk/ORMModel/Framework/Shell/DiagramOrderDialog.cs 2014-04-19 01:32:20 UTC (rev 1544) +++ trunk/ORMModel/Framework/Shell/DiagramOrderDialog.cs 2014-05-09 03:57:29 UTC (rev 1545) @@ -335,8 +335,9 @@ #endregion // DiagramBranch class private static Size LastFormSize; private Diagram[] myDiagramOrder; + private int myInitialSelectionIndex; private ImageList myImages; - private DiagramOrderDialog(IList<Diagram> startingOrder, ImageList images) + private DiagramOrderDialog(IList<Diagram> startingOrder, Diagram selectedDiagram, ImageList images) { int diagramCount = startingOrder.Count; Diagram[] order = startingOrder as Diagram[]; @@ -346,6 +347,7 @@ startingOrder.CopyTo(order, 0); } myDiagramOrder = order; + myInitialSelectionIndex = (selectedDiagram != null) ? Array.IndexOf<Diagram>(order, selectedDiagram) : -1; myImages = images; InitializeComponent(); DiagramsList.ImageList = images; @@ -357,10 +359,11 @@ /// <param name="serviceProvider">A <see cref="IServiceProvider"/> used to parent the dialog</param> /// <param name="docData">The owning <see cref="ModelingDocData"/> of the diagrams being reordered</param> /// <param name="diagrams">A list of <see cref="Diagram"/> elements to reorder</param> + /// <param name="selectedDiagram">A <see cref="Diagram"/> to select when the dialog is initially displayed.</param> /// <param name="images">The diagram images to display. Images are keyed off the Guid of the diagram type (format "N")</param> - public static void ShowDialog(IServiceProvider serviceProvider, ModelingDocData docData, IList<Diagram> diagrams, ImageList images) + public static void ShowDialog(IServiceProvider serviceProvider, ModelingDocData docData, IList<Diagram> diagrams, Diagram selectedDiagram, ImageList images) { - DiagramOrderDialog orderDialog = new DiagramOrderDialog(diagrams, images); + DiagramOrderDialog orderDialog = new DiagramOrderDialog(diagrams, selectedDiagram, images); if (orderDialog.ShowDialog(Utility.GetDialogOwnerWindow(serviceProvider)) == DialogResult.OK) { DiagramDisplay.UpdateDiagramDisplayOrder(docData.Store, orderDialog.myDiagramOrder); @@ -376,6 +379,11 @@ tree.Root = new DiagramBranch(this); VirtualTreeControl treeControl = DiagramsList; treeControl.Tree = tree; + int selectIndex; + if (-1 != (selectIndex = myInitialSelectionIndex)) + { + treeControl.CurrentIndex = selectIndex; + } treeControl.Select(); } private int[] SelectedIndices Modified: trunk/ORMModel/Framework/Shell/MultiDiagramDocView.cs =================================================================== --- trunk/ORMModel/Framework/Shell/MultiDiagramDocView.cs 2014-04-19 01:32:20 UTC (rev 1544) +++ trunk/ORMModel/Framework/Shell/MultiDiagramDocView.cs 2014-05-09 03:57:29 UTC (rev 1545) @@ -355,7 +355,7 @@ /// <summary> /// Reorder the diagram tab pages /// </summary> - public void ReorderDiagrams() + public void ReorderDiagrams(Diagram selectedDiagram) { MultiDiagramDocViewControl docViewControl; TabControl.TabPageCollection pages; @@ -368,7 +368,7 @@ { diagrams[i] = ((DiagramTabPage)pages[i]).Diagram; } - DiagramOrderDialog.ShowDialog(ServiceProvider, DocData, diagrams, myDocViewControl.ImageList); + DiagramOrderDialog.ShowDialog(ServiceProvider, DocData, diagrams, selectedDiagram, myDocViewControl.ImageList); } } /// <summary> Modified: trunk/ORMModel/Framework/Shell/MultiDiagramDocViewControl.cs =================================================================== --- trunk/ORMModel/Framework/Shell/MultiDiagramDocViewControl.cs 2014-04-19 01:32:20 UTC (rev 1544) +++ trunk/ORMModel/Framework/Shell/MultiDiagramDocViewControl.cs 2014-05-09 03:57:29 UTC (rev 1545) @@ -449,23 +449,41 @@ { if (tabPage != null) { - InlineTabRenameTextBox renamingTextBox = myRenamingTextBox; + InlineTabRenameTextBox renamingTextBox; - if (renamingTextBox != null) + if (null != (renamingTextBox = myRenamingTextBox) && + renamingTextBox.RenamingTabPage == tabPage) { - if (renamingTextBox.RenamingTabPage == tabPage) + // If we already have an InlineTabRenameTextBox for this tab page, do nothing + return; + } + new InlineTabRenameTextBox(this, tabPage); + base.Invalidate(false); + } + } + private InlineTabRenameTextBox RenamingTextBox + { + get + { + return myRenamingTextBox; + } + set + { + InlineTabRenameTextBox current = myRenamingTextBox; + myRenamingTextBox = value; + if (current != null) + { + // If we already have an InlineTabRenameTextBox for a different tab page, save the changes and close it + current.Close(true); + if (value == null) { - // If we already have an InlineTabRenameTextBox for this tab page, do nothing - return; + DocView.ActiveInPlaceEditWindow = null; } - else - { - // If we already have an InlineTabRenameTextBox for a different tab page, save the changes and close it - renamingTextBox.Close(true); - } } - myRenamingTextBox = new InlineTabRenameTextBox(this, tabPage); - base.Invalidate(false); + if (value != null) + { + DocView.ActiveInPlaceEditWindow = value; + } } } #endregion // RenameTab method @@ -701,6 +719,7 @@ public InlineTabRenameTextBox(MultiDiagramDocViewControl docViewControl, DiagramTabPage renamingTabPage) { myDocViewControl = docViewControl; + docViewControl.RenamingTextBox = null; // Close anything existing prior to initialization RenamingTabPage = renamingTabPage; base.Parent = docViewControl.Parent; base.Visible = false; @@ -711,13 +730,14 @@ base.TextAlign = HorizontalAlignment.Center; base.BringToFront(); base.Focus(); + docViewControl.RenamingTextBox = this; // Associate the existing tab } protected sealed override void Dispose(bool disposing) { if (disposing) { - myDocViewControl.myRenamingTextBox = null; + myDocViewControl.RenamingTextBox = null; base.Parent = null; } base.Dispose(disposing); @@ -732,8 +752,11 @@ if (!mySavedChanges && saveChanges && base.Modified) { RenamingTabPage.Text = base.Text; - mySavedChanges = true; } + // Always mark changes as saved so that we respect the saveChanges + // parameter from the first Close call. Additional Close calls are + // possible in response to other events. + mySavedChanges = true; if (base.Focused) { // Give focus back to the DocViewControl, which will give it back to the active designer @@ -760,7 +783,6 @@ return base.ProcessDialogKey(keyData); } } - protected sealed override Padding DefaultMargin { get Modified: trunk/ORMModel/Shell/ORMDocView.cs =================================================================== --- trunk/ORMModel/Shell/ORMDocView.cs 2014-04-19 01:32:20 UTC (rev 1544) +++ trunk/ORMModel/Shell/ORMDocView.cs 2014-05-09 03:57:29 UTC (rev 1545) @@ -503,7 +503,7 @@ } private void ContextMenuPageOrderClick(object sender, EventArgs e) { - base.ReorderDiagrams(); + base.ReorderDiagrams(ContextMenuStrip.SelectedDiagram); } #endregion // Context Menu This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2014-11-21 16:29:24
|
Revision: 1550 http://sourceforge.net/p/orm/code/1550 Author: mcurland Date: 2014-11-21 16:29:21 +0000 (Fri, 21 Nov 2014) Log Message: ----------- Bug fixes: * Dragging fact types shapes from the model browser with attached role names and constraint shapes was creating multiple instances of each shape. This was a bad side effect of changes introduced and [1508] and [1527]. The MultiShapeUtility.ForceMultipleShapes directive is now removed and replaced with MultiShapeUtility.AllowMultipleShapes between creation and fixup of a new child shape resulting from an object browser drag operation. * Added modality checks to the intersection of simple mandatory and single column subset constraints. There was no handling for this. This was a targeted fix and does not fix mandatory modality issues with other set comparison constraints. * Don't serialized references to roles in the orm:PlayedRoles element if those roles are defined in an alternate partition. Continuation of work on [1519]. Modified Paths: -------------- trunk/ORMModel/Framework/FrameworkServices.cs trunk/ORMModel/ObjectModel/Constraint.cs trunk/ORMModel/ObjectModel/ORMCore.SerializationExtensions.cs trunk/ORMModel/ObjectModel/ORMCore.SerializationExtensions.xml trunk/ORMModel/ShapeModel/ORMDiagram.cs trunk/ORMModel/Shell/ORMDocView.cs Modified: trunk/ORMModel/Framework/FrameworkServices.cs =================================================================== --- trunk/ORMModel/Framework/FrameworkServices.cs 2014-08-07 06:25:14 UTC (rev 1549) +++ trunk/ORMModel/Framework/FrameworkServices.cs 2014-11-21 16:29:21 UTC (rev 1550) @@ -380,9 +380,9 @@ #endregion // AutomatedElementFilterService class #region ICreateSignalTransactionItems /// <summary> - /// Some model changes are used solely trigger other behavior within + /// Some model changes are used solely to trigger other behavior within /// a transaction. However, the system does not distinguish between - /// these changes an normal changes. If a signal occurs without a normal + /// these changes and normal changes. If a signal occurs without a normal /// change, then a transaction may appear to be meaningful to the user /// by displaying in the undo/redo stack even when no significant changes /// have occurred. A domain model class can implement this interface to @@ -400,7 +400,7 @@ /// </summary> /// <returns>Enumeration of domain property id/callback function pairs. /// If a callback function is not provided, then all changes of this - /// type can be ignored. Otherwise, the return true from the registered + /// type can be ignored. Otherwise, return true from the registered /// predicate to support a change.</returns> IEnumerable<KeyValuePair<Guid, Predicate<ElementPropertyChangedEventArgs>>> GetSignalPropertyChanges(); } Modified: trunk/ORMModel/ObjectModel/Constraint.cs =================================================================== --- trunk/ORMModel/ObjectModel/Constraint.cs 2014-08-07 06:25:14 UTC (rev 1549) +++ trunk/ORMModel/ObjectModel/Constraint.cs 2014-11-21 16:29:21 UTC (rev 1550) @@ -1459,6 +1459,8 @@ { return; } + IHasAlternateOwner toAlternateOwner; + object constraintOwner = (null == (toAlternateOwner = setConstraint as IHasAlternateOwner)) ? null : toAlternateOwner.UntypedAlternateOwner; int validationCount = validations.Count; ConstraintModality modality = setConstraint.Modality; for (int iValidation = 0; iValidation < validationCount; ++iValidation) @@ -1493,7 +1495,8 @@ IConstraint eligibleConstraint = eligibleSequence.Constraint; if (eligibleConstraint.ConstraintStorageStyle == ConstraintStorageStyle.SetConstraint && (modalityChange || validationInfo.TestModality(eligibleConstraint.Modality, modality)) && - Array.IndexOf<ConstraintType>(validationInfo.ConstraintTypesInPotentialConflict, constraintType) != -1) + Array.IndexOf<ConstraintType>(validationInfo.ConstraintTypesInPotentialConflict, constraintType) != -1 && + constraintOwner == ((null == (toAlternateOwner = eligibleConstraint as IHasAlternateOwner)) ? null : toAlternateOwner.UntypedAlternateOwner)) { // The delayed validation mechanism automatically takes care of any duplicate requests FrameworkDomainModel.DelayValidateElement(eligibleSequence, DelayValidateSetConstraintSubsetPattern); @@ -1504,6 +1507,36 @@ } break; default: + if (modalityChange) + { + // must also be validated. + IList<Role> roles = setConstraint.RoleCollection; + int roleCount = roles.Count; + for (int i = 0; i < roleCount; ++i) + { + Role selectedRole = roles[i]; + LinkedElementCollection<ConstraintRoleSequence> sequences = selectedRole.ConstraintRoleSequenceCollection; + int sequenceCount = sequences.Count; + for (int j = 0; j < sequenceCount; ++j) + { + ConstraintRoleSequence eligibleSequence = sequences[j]; + IConstraint eligibleConstraint; + if (eligibleSequence != setConstraint && + -1 != Array.IndexOf<ConstraintType>(validationInfo.ConstraintTypesInPotentialConflict, (eligibleConstraint = eligibleSequence.Constraint).ConstraintType)) + { + if (validationInfo.DomainRoleToError.HasValue) { + DelayValidateConstraintPatternError(setConstraint); + } + if (validationInfo.IntersectingDomainRoleToError.HasValue && + constraintOwner == ((null == (toAlternateOwner = eligibleConstraint as IHasAlternateOwner)) ? null : toAlternateOwner.UntypedAlternateOwner)) + { + DelayValidateConstraintPatternError(eligibleConstraint); + } + } + + } + } + } // Isn't a SetConstraint, move on break; } @@ -1563,7 +1596,7 @@ { IConstraint intersectingConstraint = intersectingSequence.Constraint; if (validationInfo.TestModality(modality, intersectingConstraint.Modality) && - (validationInfo.ConstraintTypesInPotentialConflict as IList<ConstraintType>).Contains(intersectingConstraint.ConstraintType)) + -1 != Array.IndexOf(validationInfo.ConstraintTypesInPotentialConflict, intersectingConstraint.ConstraintType)) { SetConstraint intersectingSetConstraint = (SetConstraint)intersectingSequence; LinkedElementCollection<Role> intersectingRoles = intersectingSetConstraint.RoleCollection; @@ -4715,7 +4748,7 @@ if (intersectingConstraint != setComparisonConstraint && constraintOwner == ((null == (toAlternateOwner = intersectingConstraint as IHasAlternateOwner)) ? null : toAlternateOwner.UntypedAlternateOwner) && validationInfo.TestModality(currentModality, intersectingConstraint.Modality) && - (validationInfo.ConstraintTypesInPotentialConflict as IList<ConstraintType>).Contains(intersectingConstraint.ConstraintType)) + -1 != Array.IndexOf<ConstraintType>(validationInfo.ConstraintTypesInPotentialConflict, intersectingConstraint.ConstraintType)) { if (constraintsToCheck == null) { @@ -4936,6 +4969,8 @@ object constraintOwner = (null == (toAlternateOwner = setComparisonConstraint as IHasAlternateOwner)) ? null : toAlternateOwner.UntypedAlternateOwner; int validationCount = validations.Count; ConstraintModality constraintModality = setComparisonConstraint.Modality; + LinkedElementCollection<SetComparisonConstraintRoleSequence> comparisonConstraintSequences = null; + int comparisonConstraintSequencesCount = 0; for (int iValidation = 0; iValidation < validationCount; ++iValidation) { IntersectingConstraintValidation validationInfo = validations[iValidation]; @@ -4962,8 +4997,11 @@ } break; case IntersectingConstraintPattern.SetComparisonConstraintSuperset: - LinkedElementCollection<SetComparisonConstraintRoleSequence> comparisonConstraintSequences = setComparisonConstraint.RoleSequenceCollection; - int comparisonConstraintSequencesCount = comparisonConstraintSequences.Count; + if (comparisonConstraintSequences == null) + { + comparisonConstraintSequences = setComparisonConstraint.RoleSequenceCollection; + comparisonConstraintSequencesCount = comparisonConstraintSequences.Count; + } for (int i = 0; i < comparisonConstraintSequencesCount; ++i) { SetComparisonConstraintRoleSequence comparisonConstraintSequence = comparisonConstraintSequences[i]; @@ -4985,7 +5023,7 @@ if (eligibleConstraint != setComparisonConstraint && constraintOwner == ((null == (toAlternateOwner = eligibleConstraint as IHasAlternateOwner)) ? null : toAlternateOwner.UntypedAlternateOwner) && (modalityChange || validationInfo.TestModality(constraintModality, eligibleConstraint.Modality)) && - (validationInfo.ConstraintTypesInPotentialConflict as IList<ConstraintType>).Contains(eligibleConstraint.ConstraintType) && + -1 != Array.IndexOf<ConstraintType>(validationInfo.ConstraintTypesInPotentialConflict, eligibleConstraint.ConstraintType) && !matchCallback(eligibleConstraint)) { return; @@ -4994,6 +5032,48 @@ } } break; + default: + if (modalityChange) + { + if (comparisonConstraintSequences == null) + { + comparisonConstraintSequences = setComparisonConstraint.RoleSequenceCollection; + comparisonConstraintSequencesCount = comparisonConstraintSequences.Count; + } + for (int i = 0; i < comparisonConstraintSequencesCount; ++i) + { + SetComparisonConstraintRoleSequence comparisonConstraintSequence = comparisonConstraintSequences[i]; + LinkedElementCollection<Role> sequenceRoles = comparisonConstraintSequence.RoleCollection; + int sequenceRoleCount = sequenceRoles.Count; + for (int j = 0; j < sequenceRoleCount; ++j) + { + Role selectedRole = sequenceRoles[j]; + LinkedElementCollection<ConstraintRoleSequence> sequences = selectedRole.ConstraintRoleSequenceCollection; + int sequenceCount = sequences.Count; + for (int k = 0; k < sequenceCount; ++k) + { + ConstraintRoleSequence eligibleSequence = sequences[k]; + IConstraint eligibleConstraint = eligibleSequence.Constraint; + if (eligibleConstraint != setComparisonConstraint && + -1 != Array.IndexOf<ConstraintType>(validationInfo.ConstraintTypesInPotentialConflict, eligibleConstraint.ConstraintType)) + { + if (validationInfo.DomainRoleToError.HasValue && + !matchCallback(setComparisonConstraint)) + { + return; + } + if (validationInfo.IntersectingDomainRoleToError.HasValue && + constraintOwner == ((null == (toAlternateOwner = eligibleConstraint as IHasAlternateOwner)) ? null : toAlternateOwner.UntypedAlternateOwner) && + !matchCallback(eligibleConstraint)) + { + return; + } + } + } + } + } + } + break; } } } @@ -11771,7 +11851,7 @@ //Implication new IntersectingConstraintValidation( IntersectingConstraintPattern.SubsetImpliedByMandatory, - IntersectingConstraintPatternOptions.None, + IntersectingConstraintPatternOptions.IntersectingConstraintModalityNotStronger, null, SetComparisonConstraintHasEqualityOrSubsetImpliedByMandatoryError.SetComparisonConstraintDomainRoleId, ConstraintType.Subset), @@ -11787,7 +11867,7 @@ //Bad ORM new IntersectingConstraintValidation( IntersectingConstraintPattern.SubsetContradictsMandatory, - IntersectingConstraintPatternOptions.None, + IntersectingConstraintPatternOptions.IntersectingConstraintModalityNotStronger, MandatoryConstraintHasNotWellModeledSubsetAndMandatoryError.MandatoryConstraintDomainRoleId, // UNDONE: CONSTRAINTINTERSECTION: This should be a many relationship SubsetConstraintHasNotWellModeledSubsetAndMandatoryError.SubsetConstraintDomainRoleId, ConstraintType.Subset), @@ -11986,7 +12066,7 @@ //Implication new IntersectingConstraintValidation( IntersectingConstraintPattern.SubsetImpliedByMandatory, - IntersectingConstraintPatternOptions.None, + IntersectingConstraintPatternOptions.IntersectingConstraintModalityNotWeaker, SetComparisonConstraintHasEqualityOrSubsetImpliedByMandatoryError.SetComparisonConstraintDomainRoleId, null, ConstraintType.SimpleMandatory), @@ -11994,7 +12074,7 @@ //Bad ORM new IntersectingConstraintValidation( IntersectingConstraintPattern.SubsetContradictsMandatory, - IntersectingConstraintPatternOptions.IntersectingConstraintModalityIgnored, + IntersectingConstraintPatternOptions.IntersectingConstraintModalityNotWeaker, SubsetConstraintHasNotWellModeledSubsetAndMandatoryError.SubsetConstraintDomainRoleId, MandatoryConstraintHasNotWellModeledSubsetAndMandatoryError.MandatoryConstraintDomainRoleId, // UNDONE: CONSTRAINTINTERSECTION: This should be a many relationship ConstraintType.SimpleMandatory), Modified: trunk/ORMModel/ObjectModel/ORMCore.SerializationExtensions.cs =================================================================== --- trunk/ORMModel/ObjectModel/ORMCore.SerializationExtensions.cs 2014-08-07 06:25:14 UTC (rev 1549) +++ trunk/ORMModel/ObjectModel/ORMCore.SerializationExtensions.cs 2014-11-21 16:29:21 UTC (rev 1550) @@ -1619,15 +1619,21 @@ if (roleId == ObjectTypePlaysRole.PlayedRoleDomainRoleId) { string name = "Role"; - if (DomainRoleInfo.GetRolePlayer(elementLink, ObjectTypePlaysRole.PlayedRoleDomainRoleId) is SubtypeMetaRole) + CustomSerializedElementWriteStyle writeStyle = CustomSerializedElementWriteStyle.Element; + if (elementLink.Partition.AlternateId != null) { + name = ""; + writeStyle = CustomSerializedElementWriteStyle.NotWritten; + } + else if (DomainRoleInfo.GetRolePlayer(elementLink, ObjectTypePlaysRole.PlayedRoleDomainRoleId) is SubtypeMetaRole) + { name = "SubtypeMetaRole"; } else if (DomainRoleInfo.GetRolePlayer(elementLink, ObjectTypePlaysRole.PlayedRoleDomainRoleId) is SupertypeMetaRole) { name = "SupertypeMetaRole"; } - return new CustomSerializedElementInfo(null, name, null, CustomSerializedElementWriteStyle.Element, null); + return new CustomSerializedElementInfo(null, name, null, writeStyle, null); } if (roleId == EntityTypeHasPreferredIdentifier.PreferredIdentifierDomainRoleId) { Modified: trunk/ORMModel/ObjectModel/ORMCore.SerializationExtensions.xml =================================================================== --- trunk/ORMModel/ObjectModel/ORMCore.SerializationExtensions.xml 2014-08-07 06:25:14 UTC (rev 1549) +++ trunk/ORMModel/ObjectModel/ORMCore.SerializationExtensions.xml 2014-11-21 16:29:21 UTC (rev 1550) @@ -332,6 +332,24 @@ <se:Embed RelationshipName="ValueTypeHasValueConstraint" RoleName="ValueConstraint"/> </se:Container> <se:Link Name="Role" RelationshipName="ObjectTypePlaysRole" RoleName="PlayedRole"> + <se:ConditionalName Name="" WriteStyle="NotWritten"> + <plx:binaryOperator type="identityInequality"> + <plx:left> + <plx:callInstance name="AlternateId" type="property"> + <plx:callObject> + <plx:callInstance name="Partition" type="property"> + <plx:callObject> + <plx:nameRef name="elementLink" type="parameter"/> + </plx:callObject> + </plx:callInstance> + </plx:callObject> + </plx:callInstance> + </plx:left> + <plx:right> + <plx:nullKeyword/> + </plx:right> + </plx:binaryOperator> + </se:ConditionalName> <se:ConditionalName Name="SubtypeMetaRole"> <plx:binaryOperator type="typeEquality"> <plx:left> Modified: trunk/ORMModel/ShapeModel/ORMDiagram.cs =================================================================== --- trunk/ORMModel/ShapeModel/ORMDiagram.cs 2014-08-07 06:25:14 UTC (rev 1549) +++ trunk/ORMModel/ShapeModel/ORMDiagram.cs 2014-11-21 16:29:21 UTC (rev 1550) @@ -380,6 +380,7 @@ } Dictionary<object, object> topLevelContextInfo = null; object placementKey; + bool tightenPlacementKey = false; switch (placementOption) { case ORMPlacementOption.AllowMultipleShapes: @@ -387,6 +388,7 @@ break; case ORMPlacementOption.CreateNewShape: placementKey = MultiShapeUtility.ForceMultipleShapes; + tightenPlacementKey = true; break; default: placementKey = null; @@ -443,6 +445,12 @@ } if (shapeElement != null) { + if (tightenPlacementKey) + { + // We only want to force create the top level element, not its child elements. + topLevelContextInfo.Remove(placementKey); + topLevelContextInfo.Add(placementKey = MultiShapeUtility.AllowMultipleShapes, null); + } // Perform preliminary fixup if (null != beforeStandardFixupCallback) { @@ -450,7 +458,7 @@ } if (factType != null) { - FixupFactType(crossStoreCopy ? (FactType)element : factType, (FactTypeShape)shapeElement, false); + FixupFactType(crossStoreCopy ? (FactType)element : factType, shapeElement as FactTypeShape, false); } else if (objectType != null) { @@ -527,6 +535,7 @@ } Dictionary<object, object> topLevelContextInfo = null; object placementKey; + bool tightenPlacementKey = false; switch (placementOption) { case ORMPlacementOption.AllowMultipleShapes: @@ -534,6 +543,7 @@ break; case ORMPlacementOption.CreateNewShape: placementKey = MultiShapeUtility.ForceMultipleShapes; + tightenPlacementKey = true; break; default: placementKey = null; @@ -550,6 +560,12 @@ } if (shapeElement != null && fixupShapeCallback != null) { + if (tightenPlacementKey) + { + // We only want to force create the top level element, not its child elements. + topLevelContextInfo.Remove(placementKey); + topLevelContextInfo.Add(placementKey = MultiShapeUtility.AllowMultipleShapes, null); + } fixupShapeCallback(elementToPlace, shapeElement); } if (placementKey != null) @@ -585,12 +601,16 @@ } private void FixupFactType(FactType factType, FactTypeShape factTypeShape, bool childShapesMerged) { + if (factTypeShape == null) + { + return; + } bool duplicateShape = false; Objectification objectification = factType.Objectification; ObjectType nestingType = (objectification != null) ? objectification.NestingType : null; bool lookForNonDisplayedRelatedTypes = false; bool haveNonDisplayedRelatedTypes = false; - if (childShapesMerged && factTypeShape != null && IsMergingExternalStore) + if (childShapesMerged && IsMergingExternalStore) { // Override this setting if we're merging from an external store, which // can produce a merge of a shape that does not have all of the elements @@ -631,6 +651,13 @@ } } } + + // Make sure the role name shape visibility is correct. Visibility + // settings do not survive a merge operation, so we need to check + // this explicitly regardless of merge state. + factTypeShape.UpdateRoleNameDisplay(); + + // Handle other shapes related to roles. LinkedElementCollection<RoleBase> roleCollection = factType.RoleCollection; int roleCount = roleCollection.Count; int? unaryRoleIndex = FactType.GetUnaryRoleIndex(roleCollection); @@ -668,49 +695,19 @@ FixupRelatedLinks(DomainRoleInfo.GetElementLinks<ElementLink>(role, FactSetComparisonConstraint.FactTypeDomainRoleId)); } - // Make sure the role name shape visibility is correct. Visibility - // settings do not survive a merge operation, so we need to check - // this explicitly regardless of merge state. - factTypeShape.UpdateRoleNameDisplay(); - // Get the role value constraint and the link to it. RoleHasValueConstraint valueConstraintLink = RoleHasValueConstraint.GetLinkToValueConstraint(role); UnaryRoleCardinalityConstraint unaryRoleCardinality = (unaryRole == role) ? unaryRole.Cardinality : null; if (!childShapesMerged) { - // Pick up the role shape - //check if we have a specific shape or need to use the model element - if (factTypeShape == null) - { - FixUpLocalDiagram(factType, role); - } - else - { - FixUpLocalDiagram(factTypeShape as ShapeElement, role); - } - if (valueConstraintLink != null) { - if (factTypeShape == null) - { - FixUpLocalDiagram(factType, valueConstraintLink.ValueConstraint); - } - else - { - FixUpLocalDiagram(factTypeShape as ShapeElement, valueConstraintLink.ValueConstraint); - } + FixUpLocalDiagram(factTypeShape as ShapeElement, valueConstraintLink.ValueConstraint); } if (unaryRoleCardinality != null) { - if (factTypeShape == null) - { - FixUpLocalDiagram(factType, unaryRoleCardinality); - } - else - { - FixUpLocalDiagram(factTypeShape as ShapeElement, unaryRoleCardinality); - } + FixUpLocalDiagram(factTypeShape as ShapeElement, unaryRoleCardinality); } } // Role player links are not part of the merge hierarchy, add them for both @@ -725,14 +722,7 @@ LinkedElementCollection<ReadingOrder> orders = factType.ReadingOrderCollection; if (orders.Count != 0) { - if (factTypeShape == null) - { - FixUpLocalDiagram(factType, orders[0]); - } - else - { - FixUpLocalDiagram(factTypeShape as ShapeElement, orders[0]); - } + FixUpLocalDiagram(factTypeShape as ShapeElement, orders[0]); } } if (!duplicateShape) @@ -743,28 +733,10 @@ { if (!childShapesMerged) { - ObjectifiedFactTypeNameShape nameShape; ValueConstraint valueConstraint = nestingType.FindValueConstraint(false); ObjectTypeCardinalityConstraint cardinalityConstraint = nestingType.Cardinality; - if (factTypeShape == null) + if (factTypeShape.DisplayAsObjectType) { - foreach (ShapeElement newShape in FixUpLocalDiagram(factType, nestingType)) - { - if (null != (nameShape = newShape as ObjectifiedFactTypeNameShape)) - { - if (valueConstraint != null) - { - FixUpLocalDiagram(nameShape, valueConstraint); - } - if (cardinalityConstraint != null) - { - FixUpLocalDiagram(nameShape, cardinalityConstraint); - } - } - } - } - else if (factTypeShape.DisplayAsObjectType) - { if (valueConstraint != null) { FixUpLocalDiagram(factTypeShape, valueConstraint); @@ -774,16 +746,11 @@ FixUpLocalDiagram(factTypeShape, cardinalityConstraint); } } - else if (null != (nameShape = FixUpLocalDiagram(factTypeShape as ShapeElement, nestingType) as ObjectifiedFactTypeNameShape)) + else { - if (valueConstraint != null) - { - FixUpLocalDiagram(nameShape, valueConstraint); - } - if (cardinalityConstraint != null) - { - FixUpLocalDiagram(nameShape, cardinalityConstraint); - } + // If this creates an objectified fact type name shape it will fix up + // its own children. + FixUpLocalDiagram(factTypeShape as ShapeElement, nestingType); } } if (!duplicateShape || haveNonDisplayedRelatedTypes) @@ -794,6 +761,10 @@ } private void FixupObjectType(ObjectType objectType, ObjectTypeShape objectTypeShape, bool childShapesMerged) { + if (objectTypeShape == null) + { + return; + } bool duplicateShape = false; bool lookForNonDisplayedRelatedTypes = false; bool haveNonDisplayedRelatedTypes = false; @@ -828,7 +799,7 @@ { FixupObjectTypeLinks(objectType, haveNonDisplayedRelatedTypes); } - if (!childShapesMerged || (objectTypeShape != null && IsMergingExternalStore)) + if (!childShapesMerged || IsMergingExternalStore) { // If the shape comes from the local store the source shape should always be // in sync. However, if the shape comes from an external store, then it may not @@ -837,26 +808,11 @@ ObjectTypeCardinalityConstraint cardinalityConstraint; if (null != (valueConstraint = objectType.FindValueConstraint(false))) { - //check if we have a specific shape or need to use the model element - if (objectTypeShape == null) - { - FixUpLocalDiagram(objectType, valueConstraint); - } - else - { - FixUpLocalDiagram(objectTypeShape as ShapeElement, valueConstraint); - } + FixUpLocalDiagram(objectTypeShape as ShapeElement, valueConstraint); } if (null != (cardinalityConstraint = objectType.Cardinality)) { - if (objectTypeShape == null) - { - FixUpLocalDiagram(objectType, cardinalityConstraint); - } - else - { - FixUpLocalDiagram(objectTypeShape as ShapeElement, cardinalityConstraint); - } + FixUpLocalDiagram(objectTypeShape as ShapeElement, cardinalityConstraint); } } } Modified: trunk/ORMModel/Shell/ORMDocView.cs =================================================================== --- trunk/ORMModel/Shell/ORMDocView.cs 2014-08-07 06:25:14 UTC (rev 1549) +++ trunk/ORMModel/Shell/ORMDocView.cs 2014-11-21 16:29:21 UTC (rev 1550) @@ -685,6 +685,12 @@ /// </summary> protected override void OnSelectionChanged(EventArgs e) { + if (Store == null) + { + // This gets occasional calls during shutdown, especially if VS + // has been sitting for a while. Do a sanity check before proceeding. + return; + } base.OnSelectionChanged(e); CommandManager.UpdateCommandStatus(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2014-12-31 03:54:55
|
Revision: 1556 http://sourceforge.net/p/orm/code/1556 Author: mcurland Date: 2014-12-31 03:54:52 +0000 (Wed, 31 Dec 2014) Log Message: ----------- * Enhance verbalization support for subqueries by removing redundant 'exists' clauses whenever possible. Extra 'exists' would appear as part of the verbalized subquery expansion if a subquery result role or parameter was used in a function or value constraint but not in a fact type within the subquery. * Block the context window from attempting to render subqueries. These would render poorly in most case, but actually crashed in the case of a subquery with a single result role. Modified Paths: -------------- trunk/ORMModel/ObjectModel/Constraint.cs trunk/ORMModel/ObjectModel/FactType.cs trunk/ORMModel/ObjectModel/HierarchyContext.cs trunk/ORMModel/ObjectModel/ObjectType.cs trunk/ORMModel/ObjectModel/Role.cs trunk/ORMModel/ObjectModel/RolePath.cs trunk/ORMModel/ObjectModel/Verbalization.cs trunk/ORMModel/Shell/ORMContextWindow.cs Modified: trunk/ORMModel/ObjectModel/Constraint.cs =================================================================== --- trunk/ORMModel/ObjectModel/Constraint.cs 2014-12-20 18:36:14 UTC (rev 1555) +++ trunk/ORMModel/ObjectModel/Constraint.cs 2014-12-31 03:54:52 UTC (rev 1556) @@ -1772,6 +1772,23 @@ return ContinueWalkingHierarchyContext; } } + bool IHierarchyContextEnabled.HierarchyDisabled + { + get + { + return HierarchyDisabled; + } + } + /// <summary> + /// Implements <see cref="IHierarchyContextEnabled.HierarchyDisabled"/> + /// </summary> + protected static bool HierarchyDisabled + { + get + { + return false; + } + } #endregion } #endregion // SetConstraint class @@ -3386,6 +3403,23 @@ return ContinueWalkingHierarchyContext; } } + bool IHierarchyContextEnabled.HierarchyDisabled + { + get + { + return HierarchyDisabled; + } + } + /// <summary> + /// Implements <see cref="IHierarchyContextEnabled.HierarchyDisabled"/> + /// </summary> + protected static bool HierarchyDisabled + { + get + { + return false; + } + } #endregion } #endregion // SetComparisonConstraint class Modified: trunk/ORMModel/ObjectModel/FactType.cs =================================================================== --- trunk/ORMModel/ObjectModel/FactType.cs 2014-12-20 18:36:14 UTC (rev 1555) +++ trunk/ORMModel/ObjectModel/FactType.cs 2014-12-31 03:54:52 UTC (rev 1556) @@ -3749,6 +3749,23 @@ return ResolvedModel; } } + bool IHierarchyContextEnabled.HierarchyDisabled + { + get + { + return HierarchyDisabled; + } + } + /// <summary> + /// Implements <see cref="IHierarchyContextEnabled.HierarchyDisabled"/> + /// </summary> + protected static bool HierarchyDisabled + { + get + { + return false; + } + } #endregion // IHierarchyContextEnabled Implementation #region UnaryFactTypeFixupListener /// <summary> Modified: trunk/ORMModel/ObjectModel/HierarchyContext.cs =================================================================== --- trunk/ORMModel/ObjectModel/HierarchyContext.cs 2014-12-20 18:36:14 UTC (rev 1555) +++ trunk/ORMModel/ObjectModel/HierarchyContext.cs 2014-12-31 03:54:52 UTC (rev 1556) @@ -100,6 +100,10 @@ /// </summary> /// <value>The place priority.</value> HierarchyContextPlacementPriority HierarchyContextPlacementPriority { get;} + /// <summary> + /// Return <see langword="true"/> if hierarchy navigation to this element is disabled. + /// </summary> + bool HierarchyDisabled { get;} } /// <summary> /// Implement this interface on an <see cref="ElementLink"/> connected to elements that Modified: trunk/ORMModel/ObjectModel/ObjectType.cs =================================================================== --- trunk/ORMModel/ObjectModel/ObjectType.cs 2014-12-20 18:36:14 UTC (rev 1555) +++ trunk/ORMModel/ObjectModel/ObjectType.cs 2014-12-31 03:54:52 UTC (rev 1556) @@ -5099,6 +5099,23 @@ return ResolvedModel; } } + bool IHierarchyContextEnabled.HierarchyDisabled + { + get + { + return HierarchyDisabled; + } + } + /// <summary> + /// Implements <see cref="IHierarchyContextEnabled.HierarchyDisabled"/> + /// </summary> + protected static bool HierarchyDisabled + { + get + { + return false; + } + } #endregion // IHierarchyContextEnabled Implementation #region IVerbalizeCustomChildren Implementation /// <summary> Modified: trunk/ORMModel/ObjectModel/Role.cs =================================================================== --- trunk/ORMModel/ObjectModel/Role.cs 2014-12-20 18:36:14 UTC (rev 1555) +++ trunk/ORMModel/ObjectModel/Role.cs 2014-12-31 03:54:52 UTC (rev 1556) @@ -1731,6 +1731,23 @@ { get { return ContinueWalkingHierarchyContext; } } + bool IHierarchyContextEnabled.HierarchyDisabled + { + get + { + return HierarchyDisabled; + } + } + /// <summary> + /// Implements <see cref="IHierarchyContextEnabled.HierarchyDisabled"/> + /// </summary> + protected bool HierarchyDisabled + { + get + { + return FactType is QueryBase; + } + } #endregion } partial class RoleBase : IModelErrorDisplayContext Modified: trunk/ORMModel/ObjectModel/RolePath.cs =================================================================== --- trunk/ORMModel/ObjectModel/RolePath.cs 2014-12-20 18:36:14 UTC (rev 1555) +++ trunk/ORMModel/ObjectModel/RolePath.cs 2014-12-31 03:54:52 UTC (rev 1556) @@ -5501,7 +5501,7 @@ } #endregion // FactTypeDerivationRule class #region QueryBase class - partial class QueryBase + partial class QueryBase : IHierarchyContextEnabled { /// <summary> /// Each query type has a different path to the <see cref="ORMModel"/> @@ -5552,6 +5552,25 @@ } } #endregion // Rule Methods + #region IHierarchyContextEnabled Implementation + bool IHierarchyContextEnabled.HierarchyDisabled + { + get + { + return HierarchyDisabled; + } + } + /// <summary> + /// Implements <see cref="IHierarchyContextEnabled.HierarchyDisabled"/> + /// </summary> + protected static new bool HierarchyDisabled + { + get + { + return true; + } + } + #endregion // IHierarchyContextEnabled Implementation } #endregion // QueryBase class #region Subquery class Modified: trunk/ORMModel/ObjectModel/Verbalization.cs =================================================================== --- trunk/ORMModel/ObjectModel/Verbalization.cs 2014-12-20 18:36:14 UTC (rev 1555) +++ trunk/ORMModel/ObjectModel/Verbalization.cs 2014-12-31 03:54:52 UTC (rev 1556) @@ -5805,14 +5805,26 @@ /// <param name="pathContext">The path context for this node.</param> /// <param name="parentNode">The parent <see cref="VerbalizationPlanNode"/> for the new node.</param> /// <param name="rootNode">A reference to the root node of the chain.</param> + /// <param name="pendingRequiredVariableKeys">Current required variable keys. Scope before value constraint.</param> /// <returns>New <see cref="VerbalizationPlanNode"/></returns> - public static VerbalizationPlanNode AddValueConstraintNode(ValueConstraint valueConstraint, object pathContext, VerbalizationPlanNode parentNode, ref VerbalizationPlanNode rootNode) + public static VerbalizationPlanNode AddValueConstraintNode(ValueConstraint valueConstraint, object pathContext, VerbalizationPlanNode parentNode, ref VerbalizationPlanNode rootNode, ref LinkedNode<object> pendingRequiredVariableKeys) { if (parentNode == null) { parentNode = AddBranchNode(VerbalizationPlanBranchType.Chain, VerbalizationPlanBranchRenderingStyle.OperatorSeparated, pathContext, null, ref rootNode); + if (pendingRequiredVariableKeys != null) + { + parentNode.RequireContextVariables(pendingRequiredVariableKeys); + pendingRequiredVariableKeys = null; + } } - return new ValueConstraintNode(pathContext, parentNode, valueConstraint); + ValueConstraintNode newNode = new ValueConstraintNode(pathContext, parentNode, valueConstraint); + if (pendingRequiredVariableKeys != null) + { + newNode.RequireContextVariables(pendingRequiredVariableKeys); + pendingRequiredVariableKeys = null; + } + return newNode; } /// <summary> /// Create and attach a new calculated condition node. @@ -5823,14 +5835,26 @@ /// <param name="pathContext">The path context for this node.</param> /// <param name="parentNode">The parent <see cref="VerbalizationPlanNode"/> for the new node.</param> /// <param name="rootNode">A reference to the root node of the chain.</param> + /// <param name="pendingRequiredVariableKeys">Pending required variable keys.</param> /// <returns>New <see cref="VerbalizationPlanNode"/></returns> - public static VerbalizationPlanNode AddCalculatedConditionNode(CalculatedPathValue calculatedCondition, bool restrictsSingleFactType, object pathContext, VerbalizationPlanNode parentNode, ref VerbalizationPlanNode rootNode) + public static VerbalizationPlanNode AddCalculatedConditionNode(CalculatedPathValue calculatedCondition, bool restrictsSingleFactType, object pathContext, VerbalizationPlanNode parentNode, ref VerbalizationPlanNode rootNode, ref LinkedNode<object> pendingRequiredVariableKeys) { if (parentNode == null) { parentNode = AddBranchNode(VerbalizationPlanBranchType.Chain, VerbalizationPlanBranchRenderingStyle.OperatorSeparated, pathContext, null, ref rootNode); + if (pendingRequiredVariableKeys != null) + { + parentNode.RequireContextVariables(pendingRequiredVariableKeys); + pendingRequiredVariableKeys = null; + } } - return new CalculatedConditionNode(pathContext, parentNode, calculatedCondition, restrictsSingleFactType); + CalculatedConditionNode newNode = new CalculatedConditionNode(pathContext, parentNode, calculatedCondition, restrictsSingleFactType); + if (pendingRequiredVariableKeys != null) + { + newNode.RequireContextVariables(pendingRequiredVariableKeys); + pendingRequiredVariableKeys = null; + } + return newNode; } /// <summary> /// Create and attach a new projection calculation node. @@ -5891,14 +5915,26 @@ /// <param name="pathContext">The path context for this node.</param> /// <param name="parentNode">The parent <see cref="VerbalizationPlanNode"/> for the new node.</param> /// <param name="rootNode">A reference to the root node of the chain.</param> + /// <param name="pendingRequiredVariableKeys">Current required variable keys. Scope before variable equivalence.</param> /// <returns>New <see cref="VerbalizationPlanNode"/></returns> - public static VerbalizationPlanNode AddVariableEquivalenceNode(IList<object> equivalentVariableKeys, object pathContext, VerbalizationPlanNode parentNode, ref VerbalizationPlanNode rootNode) + public static VerbalizationPlanNode AddVariableEquivalenceNode(IList<object> equivalentVariableKeys, object pathContext, VerbalizationPlanNode parentNode, ref VerbalizationPlanNode rootNode, ref LinkedNode<object> pendingRequiredVariableKeys) { if (parentNode == null) { parentNode = AddBranchNode(VerbalizationPlanBranchType.Chain, VerbalizationPlanBranchRenderingStyle.OperatorSeparated, pathContext, null, ref rootNode); + if (pendingRequiredVariableKeys != null) + { + parentNode.RequireContextVariables(pendingRequiredVariableKeys); + pendingRequiredVariableKeys = null; + } } - return new VariableEquivalenceNode(pathContext, parentNode, equivalentVariableKeys); + VariableEquivalenceNode newNode = new VariableEquivalenceNode(pathContext, parentNode, equivalentVariableKeys); + if (pendingRequiredVariableKeys != null) + { + parentNode.RequireContextVariables(pendingRequiredVariableKeys); + pendingRequiredVariableKeys = null; + } + return newNode; } /// <summary> /// Create and attach a new chained root variable node. @@ -6530,9 +6566,10 @@ } } } - private sealed class ValueConstraintNode : VerbalizationPlanNode + private sealed class ValueConstraintNode : RequireContextVariableNode { private readonly ValueConstraint myValueConstraint; + private bool myRenderedRequiredContextVariable; public ValueConstraintNode(object pathContext, VerbalizationPlanNode parentNode, ValueConstraint valueConstraint) : base(pathContext, parentNode) { @@ -6559,16 +6596,29 @@ return myValueConstraint; } } + public override bool RenderedRequiredContextVariable + { + get + { + return myRenderedRequiredContextVariable; + } + set + { + myRenderedRequiredContextVariable = value; + } + } } - private sealed class CalculatedConditionNode : VerbalizationPlanNode + private sealed class CalculatedConditionNode : RequireContextVariableNode { private readonly CalculatedPathValue myCondition; - private readonly bool myRestrictsSingleFactType; + private const int RestrictsSingleFactTypeBit = 0x1; + private const int RenderedRequiredContextVariablesBit = 0x2; + private int myFlags; public CalculatedConditionNode(object pathContext, VerbalizationPlanNode parentNode, CalculatedPathValue condition, bool restrictsSingleFactType) : base(pathContext, parentNode) { myCondition = condition; - myRestrictsSingleFactType = restrictsSingleFactType; + myFlags = restrictsSingleFactType ? RestrictsSingleFactTypeBit : 0; } public override VerbalizationPlanNodeType NodeType { @@ -6587,9 +6637,27 @@ { // A calculated condition node that restricts a single fact type // is verbalized immediately after the fact type instance. - return myRestrictsSingleFactType; + return 0 != (myFlags & RestrictsSingleFactTypeBit); } } + public override bool RenderedRequiredContextVariable + { + get + { + return 0 != (myFlags & RenderedRequiredContextVariablesBit); + } + set + { + if (value) + { + myFlags |= RenderedRequiredContextVariablesBit; + } + else + { + myFlags &= ~RenderedRequiredContextVariablesBit; + } + } + } } private sealed class ProjectedCalculationNode : VerbalizationPlanNode { @@ -6782,9 +6850,10 @@ } } } - private sealed class VariableEquivalenceNode : VerbalizationPlanNode + private sealed class VariableEquivalenceNode : RequireContextVariableNode { private readonly IList<object> myEquivalentVariableKeys; + private bool myRenderedRequiredContextVariable; public VariableEquivalenceNode(object pathContext, VerbalizationPlanNode parentNode, IList<object> equivalentVariableKeys) : base(pathContext, parentNode) { @@ -6804,6 +6873,17 @@ return myEquivalentVariableKeys; } } + public override bool RenderedRequiredContextVariable + { + get + { + return myRenderedRequiredContextVariable; + } + set + { + myRenderedRequiredContextVariable = value; + } + } } #endregion // Node type specific types } @@ -7099,17 +7179,21 @@ { equivalentVariableKeysByPath.TryGetValue(filteredPath, out equivalentVariables); } - if (equivalentVariables != null) + bool pushedForEquivalentVariables; + if (pushedForEquivalentVariables = (equivalentVariables != null)) { PushSplit(outerContext, VerbalizationPlanBranchType.AndSplit, ref pendingRequiredVariableKeys); } - InitializeRolePath(pathContext, pathOwner, filteredPath, keyDecorator, ref pendingRequiredVariableKeys); - if (equivalentVariables != null) + InitializeRolePath(pathContext, pathOwner, filteredPath, keyDecorator, ref pendingRequiredVariableKeys, ref equivalentVariables); + if (pushedForEquivalentVariables) { - int equivalentVariableSetCount = equivalentVariables.Count; - for (int j = 0; j < equivalentVariableSetCount; ++j) + if (equivalentVariables != null) { - VerbalizationPlanNode.AddVariableEquivalenceNode(equivalentVariables[j], outerContext, myCurrentBranchNode, ref myRootPlanNode); + int equivalentVariableSetCount = equivalentVariables.Count; + for (int j = 0; j < equivalentVariableSetCount; ++j) + { + VerbalizationPlanNode.AddVariableEquivalenceNode(equivalentVariables[j], outerContext, myCurrentBranchNode, ref myRootPlanNode, ref pendingRequiredVariableKeys); + } } PopSplit(VerbalizationPlanBranchType.AndSplit); } @@ -7121,7 +7205,7 @@ } } } - private void InitializeRolePath(object initialPathContext, RolePathOwner pathOwner, LeadRolePath leadRolePath, VariableKeyDecorator keyDecorator, ref LinkedNode<object> requiredVariableKeys) + private void InitializeRolePath(object initialPathContext, RolePathOwner pathOwner, LeadRolePath leadRolePath, VariableKeyDecorator keyDecorator, ref LinkedNode<object> requiredVariableKeys, ref IList<IList<object>> equivalentVariableSets) { LinkedElementCollection<CalculatedPathValue> pathConditions = leadRolePath.CalculatedConditionCollection; int pathConditionCount = pathConditions.Count; @@ -7152,6 +7236,7 @@ PathedRole pendingForSameFactType = null; InlineSubqueryRole pendingForSameFactTypeQueryRoleKey = null; LinkedNode<object> pendingRequiredVariableKeys = requiredVariableKeys; + IList<IList<object>> pendingEquivalentVariableSets = equivalentVariableSets; // A list (acting like a stack) to get the full history of the parent pathed roles. List<ReadOnlyCollection<PathedRole>> contextPathedRoles = null; List<RolePathObjectTypeRoot> contextPathRoots = null; @@ -7293,7 +7378,7 @@ PathConditionRoleValueConstraint valueConstraint = processPathedRole.ValueConstraint; if (valueConstraint != null) { - VerbalizationPlanNode.AddValueConstraintNode(valueConstraint, pathContext, contextChainNode, ref myRootPlanNode); + VerbalizationPlanNode.AddValueConstraintNode(valueConstraint, pathContext, contextChainNode, ref myRootPlanNode, ref pendingRequiredVariableKeys); } } @@ -7373,7 +7458,7 @@ // Although this is a single fact type, it occurs as part of a split // after the fact type has been defined, so the fact type is not immediately // before this one and we can't set the restrictsSingleFactType parameter to true. - VerbalizationPlanNode.AddCalculatedConditionNode(calculation, false, pathContext, contextChainNode, ref myRootPlanNode); + VerbalizationPlanNode.AddCalculatedConditionNode(calculation, false, pathContext, contextChainNode, ref myRootPlanNode, ref pendingRequiredVariableKeys); } } } @@ -7459,6 +7544,25 @@ if (unwinding) { contextPathRoots.RemoveAt(contextPathRoots.Count - 1); + if (pendingRequiredVariableKeys != null) + { + LinkedNode<object> variableKeyIterator = pendingRequiredVariableKeys; + RolePathCache cache = EnsureRolePathCache(); + while (variableKeyIterator != null) + { + RolePlayerVariableUse pendingUse; + if (useMap.TryGetValue(variableKeyIterator.Value, out pendingUse)) + { + ScopeVariable(pendingUse.PrimaryRolePlayerVariable, true); + } + variableKeyIterator = variableKeyIterator.Next; + } + ChainNewlyCalculatableConditions(pathConditions, ref processedPathConditions, ref pendingRequiredVariableKeys); + } + if (pendingEquivalentVariableSets != null) + { + ChainNewlySatisfiedVariableEquivalentNodes(ref pendingEquivalentVariableSets, ref pendingRequiredVariableKeys); + } while (pendingRequiredVariableKeys != null) { myCurrentBranchNode = VerbalizationPlanNode.AddVariableExistenceNode(pendingRequiredVariableKeys.Value, pathContext, myCurrentBranchNode, ref myRootPlanNode).ParentNode; @@ -7498,10 +7602,11 @@ pendingForSameFactType = null; pendingPathedRoles = null; } + bool variableAlreadyScoped = false; if (currentPath != leadRolePath) // Handled earlier, see notes above { pathNode = new RolePathNode(currentPathRoot, pathContext); - RegisterRolePlayerUse(currentPathRoot.RootObjectType, null, pathNode, pathNode); + RegisterRolePlayerUse(currentPathRoot.RootObjectType, null, pathNode, pathNode, out variableAlreadyScoped); } if (currentPathRoot.IsNegated) @@ -7521,9 +7626,9 @@ ValueConstraint valueConstraint; if (null != (valueConstraint = currentPathRoot.ValueConstraint)) { - myCurrentBranchNode = VerbalizationPlanNode.AddValueConstraintNode(valueConstraint, pathContext, myCurrentBranchNode, ref myRootPlanNode).ParentNode; + myCurrentBranchNode = VerbalizationPlanNode.AddValueConstraintNode(valueConstraint, pathContext, myCurrentBranchNode, ref myRootPlanNode, ref pendingRequiredVariableKeys).ParentNode; } - else + else if (!variableAlreadyScoped) { if (pendingRequiredVariableKeys == null) { @@ -7556,6 +7661,15 @@ } }); + equivalentVariableSets = pendingEquivalentVariableSets; + if (null != equivalentVariableSets) + { + // Equivalent variables are treat the same as additional path conditions. These are used if one variable + // is projected on multiple roles, which is handled by keeping the variables separate and then equating them. + // This produces the same result as an 'equals' function, but does not have a corresponding 'equals' in the tree. + ChainNewlySatisfiedVariableEquivalentNodes(ref equivalentVariableSets, ref pendingRequiredVariableKeys); + } + // Chain unprocessed condition nodes at the end if (pathConditionCount != 0) { @@ -7574,7 +7688,7 @@ contextChainNode = VerbalizationPlanNode.AddBranchNode(VerbalizationPlanBranchType.Chain, VerbalizationPlanBranchRenderingStyle.OperatorSeparated, initialPathContext, contextChainNode, ref myRootPlanNode); } } - VerbalizationPlanNode.AddCalculatedConditionNode(pathConditions[i], false, initialPathContext, contextChainNode, ref myRootPlanNode); + VerbalizationPlanNode.AddCalculatedConditionNode(pathConditions[i], false, initialPathContext, contextChainNode, ref myRootPlanNode, ref pendingRequiredVariableKeys); } } } @@ -8489,7 +8603,7 @@ addedFactTypeEntry = true; contextChainNode = EnsureChainNodeForFactTypeConditions(pathContext, factType, factTypeEntry, ref pendingRequiredVariableKeys); } - VerbalizationPlanNode.AddValueConstraintNode(valueConstraint, pathContext, contextChainNode, ref myRootPlanNode); + VerbalizationPlanNode.AddValueConstraintNode(valueConstraint, pathContext, contextChainNode, ref myRootPlanNode, ref pendingRequiredVariableKeys); } } @@ -8535,7 +8649,7 @@ contextChainNode = EnsureChainNodeForFactTypeConditions(pathContext, factType, factTypeEntry, ref pendingRequiredVariableKeys); } processedConditions[i] = true; - VerbalizationPlanNode.AddCalculatedConditionNode(calculation, true, pathContext, contextChainNode, ref myRootPlanNode); + VerbalizationPlanNode.AddCalculatedConditionNode(calculation, true, pathContext, contextChainNode, ref myRootPlanNode, ref pendingRequiredVariableKeys); } } } @@ -8787,7 +8901,7 @@ PushSplit(pathContext, VerbalizationPlanBranchType.AndSplit, ref pendingRequiredVariableKeys); contextConditionNode = myCurrentBranchNode; } - VerbalizationPlanNode.AddValueConstraintNode(valueConstraint, pathContext, contextConditionNode, ref myRootPlanNode); + VerbalizationPlanNode.AddValueConstraintNode(valueConstraint, pathContext, contextConditionNode, ref myRootPlanNode, ref pendingRequiredVariableKeys); } } @@ -8835,7 +8949,7 @@ contextConditionNode = myCurrentBranchNode; } processedConditions[i] = true; - VerbalizationPlanNode.AddCalculatedConditionNode(calculation, false, pathContext, contextConditionNode, ref myRootPlanNode); + VerbalizationPlanNode.AddCalculatedConditionNode(calculation, false, pathContext, contextConditionNode, ref myRootPlanNode, ref pendingRequiredVariableKeys); } } } @@ -9214,6 +9328,20 @@ /// Used to track which conditions have been processed.</param> private void ChainNewlyCalculatableConditions(LinkedElementCollection<CalculatedPathValue> pathConditions, ref BitTracker processedConditions) { + LinkedNode<object> pendingRequiredVariableKeys = null; + ChainNewlyCalculatableConditions(pathConditions, ref processedConditions, ref pendingRequiredVariableKeys); + } + /// <summary> + /// Add conditions that can now be calculated for newly scoped variables. + /// </summary> + /// <param name="pathConditions">Conditions for the path currently being processed. If there + /// are newly scoped variables and all variables required for a condition are satisfied, then + /// chain the calculations onto the current node.</param> + /// <param name="processedConditions">A <see cref="BitTracker"/> with one bit for each of the <paramref name="pathConditions"/>. + /// <param name="pendingRequiredVariableKeys">Pending variables to add with the first chained condition.</param> + /// Used to track which conditions have been processed.</param> + private void ChainNewlyCalculatableConditions(LinkedElementCollection<CalculatedPathValue> pathConditions, ref BitTracker processedConditions, ref LinkedNode<object> pendingRequiredVariableKeys) + { // If we introduced any scoped variables that are used in a function that is not // already used as a path condition and the parent node does not consider variables // scoped here to also be scoped outside this context, then we need to either state @@ -9239,6 +9367,7 @@ if (conditionCount != 0) { RolePathCache rolePathCache = default(RolePathCache); + int currentUsePhase = 0; Dictionary<object, RolePlayerVariableUse> useMap = null; for (int i = 0; i < conditionCount; ++i) { @@ -9254,18 +9383,22 @@ { useMap = myUseToVariableMap; rolePathCache = EnsureRolePathCache(); + currentUsePhase = CurrentQuantificationUsePhase; } RolePlayerVariableUse variableUse; - if (useMap.TryGetValue(rolePathCache.GetCorrelationRoot(testPathNode), out variableUse) && - !variableUse.PrimaryRolePlayerVariable.IsDescopedDuringPathCreation) + if (useMap.TryGetValue(CorrelationRootToContextBoundKey(rolePathCache.GetCorrelationRoot(testPathNode), pathContext), out variableUse)) { - return true; + RolePlayerVariable usedVariable = variableUse.PrimaryRolePlayerVariable; + if (usedVariable.HasBeenUsed(currentUsePhase, false) && !usedVariable.IsDescopedDuringPathCreation) + { + return true; + } } return false; }).GetValueOrDefault(false)) { processedConditions[i] = true; - VerbalizationPlanNode.AddCalculatedConditionNode(calculation, false, pathContext, chainNode, ref myRootPlanNode); + VerbalizationPlanNode.AddCalculatedConditionNode(calculation, false, pathContext, chainNode, ref myRootPlanNode, ref pendingRequiredVariableKeys); } } } @@ -9273,6 +9406,77 @@ } } /// <summary> + /// Add equivalence nodes that can now be calculated for newly scoped variables. + /// </summary> + /// <param name="equivalentVariableSets">Equivalent variable sets, represented by lists of variable keys. + /// <param name="pendingRequiredVariableKeys">Pending required variable keys.</param> + /// This will be cleared if it is emptied.</param> + private void ChainNewlySatisfiedVariableEquivalentNodes(ref IList<IList<object>> equivalentVariableSets, ref LinkedNode<object> pendingRequiredVariableKeys) + { + VerbalizationPlanNode chainNode = myCurrentBranchNode; + if (chainNode == null) + { + return; + } + switch (chainNode.BranchType) + { + case VerbalizationPlanBranchType.Chain: + case VerbalizationPlanBranchType.NegatedChain: + case VerbalizationPlanBranchType.AndSplit: + break; + default: + return; + } + object pathContext = chainNode.PathContext; + int setCount = equivalentVariableSets.Count; + // We might need to remove from the list, but we don't want to run + // it backwards, so track what we have removed. + BitTracker removedTracker = new BitTracker(setCount); + int removedCount = 0; + for (int i = 0; i < setCount; ++i) + { + IList<object> keys = equivalentVariableSets[i]; + int currentUsePhase = CurrentQuantificationUsePhase; + Dictionary<object, RolePlayerVariableUse> useMap = myUseToVariableMap; + RolePlayerVariableUse variableUse; + int j = 0; + int keyCount = keys.Count; + for (; j < keyCount; ++j) + { + RolePlayerVariable usedVariable; + if (!useMap.TryGetValue(keys[j], out variableUse) || + !(usedVariable = variableUse.PrimaryRolePlayerVariable).HasBeenUsed(currentUsePhase, false) || + usedVariable.IsDescopedDuringPathCreation) + { + break; + } + } + if (j == keyCount) + { + removedTracker[i] = true; + ++removedCount; + VerbalizationPlanNode.AddVariableEquivalenceNode(keys, pathContext, myCurrentBranchNode, ref myRootPlanNode, ref pendingRequiredVariableKeys); + } + } + if (removedCount != 0) + { + if (removedCount == setCount) + { + equivalentVariableSets = null; + } + else + { + for (int i = setCount - 1; i >= 0; --i) + { + if (removedTracker[i]) + { + equivalentVariableSets.RemoveAt(i); + } + } + } + } + } + /// <summary> /// Push a new negated chain node. /// </summary> private void PushNegatedChainNode(object pathContext, PathedRole negatedEntryRole, ref LinkedNode<object> pendingRequiredVariableKeys) @@ -9471,11 +9675,33 @@ /// <returns>New or existing variable</returns> private RolePlayerVariable RegisterRolePlayerUse(ObjectType rolePlayer, RolePlayerVariable joinToVariable, object usedFor, RolePathNode correlateWithNode) { + bool variableAlreadyScoped; + return RegisterRolePlayerUse(rolePlayer, joinToVariable, usedFor, correlateWithNode, out variableAlreadyScoped); + } + /// <summary> + /// Register a use of an object type before verbalization. All uses + /// must be registered to ensure correct subscripting. + /// </summary> + /// <param name="rolePlayer">The object type to use. If this is null, then the variable + /// is tracked as a missing role player.</param> + /// <param name="joinToVariable">An existing variable to join to. Directly joined variables + /// of compatible but different types get priority over correlated variables.</param> + /// <param name="usedFor">The object use. If this is <see langword="null"/>, then + /// this is a fully existential use of the role player.</param> + /// <param name="correlateWithNode">The <see cref="RolePathNode"/> to correlate this variable + /// with. The list of correlated variables is stored with the normalized root correlation + /// variable. This may be the same instance as <paramref name="usedFor"/> and should not + /// be pre-normalized before this call.</param> + /// <param name="variableAlreadyScoped">The returned variable was in used and scoped before this call.</param> + /// <returns>New or existing variable</returns> + private RolePlayerVariable RegisterRolePlayerUse(ObjectType rolePlayer, RolePlayerVariable joinToVariable, object usedFor, RolePathNode correlateWithNode, out bool variableAlreadyScoped) + { Dictionary<object, RolePlayerVariableUse> useMap = myUseToVariableMap; RolePlayerVariable existingVariable = null; bool addNewVariableToCorrelationRoot = false; RolePlayerVariableUse correlationRootVariableUse = default(RolePlayerVariableUse); object correlateWith = null; + variableAlreadyScoped = false; if (!correlateWithNode.IsEmpty && null != (correlateWith = EnsureRolePathCache().GetCorrelationRoot(correlateWithNode))) { @@ -9665,9 +9891,16 @@ } // Track use phase during registration to see if the root variable is // referenced by the path. - UseVariable(existingVariable, myLatestUsePhase, false); + if (!UseVariable(existingVariable, myLatestUsePhase, false)) + { + variableAlreadyScoped = true; + } // Determine if this variable is reentering scope - ScopeVariable(existingVariable, false); + if (ScopeVariable(existingVariable, false)) + { + // Overrides the phase setting + variableAlreadyScoped = false; + } return existingVariable; } else @@ -9799,7 +10032,8 @@ /// </summary> /// <param name="variable">The variable to put into scope</param> /// <param name="newVariable">True if the variable is newly created.</param> - private void ScopeVariable(RolePlayerVariable variable, bool newVariable) + /// <returns><see langword="true"/> if scoping changes.</returns> + private bool ScopeVariable(RolePlayerVariable variable, bool newVariable) { VerbalizationPlanNode currentBranchNode; if ((newVariable || variable.IsDescopedDuringPathCreation) && @@ -9813,7 +10047,9 @@ newlyScoped.SetNext(existingNewlyScoped, ref newlyScoped); } currentBranchNode.FirstNewlyScopeVariableNode = newlyScoped; + return true; } + return false; } private void PropagateNewVariableScopingUp(VerbalizationPlanNode branchNode) { @@ -10298,7 +10534,10 @@ variable.MinimizeHeadSubscripting = true; } } - firstUse = UseVariable(variable, CurrentQuantificationUsePhase, false); + int currentUsePhase = CurrentQuantificationUsePhase; + // Don't call UseVariable until after we've checked variable partnering as this can have the + // side effect of 'using' a variable by partnering it with a used variable of the same type. + bool unused = !variable.HasBeenUsed(currentUsePhase, false); Dictionary<RolePlayerVariable, LinkedNode<RolePlayerVariable>> customCorrelations; LinkedNode<RolePlayerVariable> customCorrelationNode; @@ -10308,7 +10547,7 @@ { // If we haven't already been paired with a custom correlation // then pair up now. - RolePlayerVariable partnerWithVariable = GetUnpairedPartnerVariable(variable, firstUse, customCorrelationNode); + RolePlayerVariable partnerWithVariable = GetUnpairedPartnerVariable(variable, unused, customCorrelationNode); while (partnerWithVariable != null) { GetPartneredSubscriptedRolePlayerName(variable, ref partnerWithVariable, false); @@ -10324,6 +10563,9 @@ } } } + + // Use the variable after partnering is complete. + firstUse = UseVariable(variable, currentUsePhase, false); if (retVal == null) { retVal = GetSubscriptedRolePlayerName(variable); Modified: trunk/ORMModel/Shell/ORMContextWindow.cs =================================================================== --- trunk/ORMModel/Shell/ORMContextWindow.cs 2014-12-20 18:36:14 UTC (rev 1555) +++ trunk/ORMModel/Shell/ORMContextWindow.cs 2014-12-31 03:54:52 UTC (rev 1556) @@ -258,7 +258,14 @@ !element.IsDeleted && null != (hierarchyElement = element as IHierarchyContextEnabled)) { - break; + if (hierarchyElement.HierarchyDisabled) + { + hierarchyElement = null; + } + else + { + break; + } } } DrawDiagram(refresh, element, hierarchyElement); @@ -425,7 +432,7 @@ return; } IHierarchyContextEnabled contextableElement = EditorUtility.ResolveContextInstance(element, false) as IHierarchyContextEnabled; - if (contextableElement == null) + if (contextableElement == null || contextableElement.HierarchyDisabled) { return; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |