From: <mcu...@us...> - 2008-08-13 00:32:31
|
Revision: 1314 http://orm.svn.sourceforge.net/orm/?rev=1314&view=rev Author: mcurland Date: 2008-08-13 00:32:41 +0000 (Wed, 13 Aug 2008) Log Message: ----------- Display and respect role order for internal uniqueness constraint editing. fixes #369 Modified Paths: -------------- trunk/ORMModel/ShapeModel/FactTypeShape.cs trunk/ORMModel/ShapeModel/InternalConstraintConnectAction.cs trunk/ORMModel/Shell/ORMDocView.cs Modified: trunk/ORMModel/ShapeModel/FactTypeShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/FactTypeShape.cs 2008-06-10 01:17:49 UTC (rev 1313) +++ trunk/ORMModel/ShapeModel/FactTypeShape.cs 2008-08-13 00:32:41 UTC (rev 1314) @@ -2385,7 +2385,20 @@ Pen pen = styleSet.GetPen(FactTypeShape.RoleBoxResource); int activeRoleIndex; ExternalConstraintConnectAction activeExternalAction = ActiveExternalConstraintConnectAction; + UniquenessConstraint activeInternalUniqueness = null; + LinkedElementCollection<Role> activeInternalUniquenessRoles = null; InternalUniquenessConstraintConnectAction activeInternalAction = ActiveInternalUniquenessConstraintConnectAction; + if (activeInternalAction != null) + { + if (activeInternalAction.SourceShape != parentFactShape) + { + activeInternalAction = null; + } + else + { + activeInternalUniqueness = activeInternalAction.ActiveConstraint; + } + } ORMDiagram currentDiagram = parentFactShape.Diagram as ORMDiagram; StringFormat stringFormat = null; Font connectActionFont = null; @@ -2419,8 +2432,10 @@ g.FillRectangle(roleCenterBrush, roleBounds.Left, roleBounds.Top, roleBounds.Width, roleBounds.Height); // There is an active ExternalConstraintConnectAction, and this role is currently in the action's role set. - if (activeExternalAction != null && - -1 != (activeRoleIndex = activeExternalAction.GetActiveRoleIndex(currentRole))) + if ((activeExternalAction != null && + -1 != (activeRoleIndex = activeExternalAction.GetActiveRoleIndex(currentRole))) || + (activeInternalAction != null && + -1 != (activeRoleIndex = activeInternalAction.GetActiveRoleIndex(currentRole)))) { // There is an active ExternalConstraintConnectAction, and this role is currently in the action's role set. DrawHighlight(g, styleSet, roleBounds, highlightThisRole); @@ -2459,11 +2474,11 @@ g.Restore(state); } } - // There is an active InternalUniquenessConstraintConnectAction, and this role is currently in the action's role set. - else if (activeInternalAction != null && -1 != (activeRoleIndex = activeInternalAction.GetActiveRoleIndex(currentRole))) + // There is an active InternalUniquenessConstraintConnectAction, and this role is removed from an existing constraint. + else if (activeInternalUniqueness != null && + (activeInternalUniquenessRoles ?? (activeInternalUniquenessRoles = activeInternalUniqueness.RoleCollection)).Contains(currentRole)) { - // There is an active InternalUniquenessConstraintConnectAction, and this role is currently in the action's role set. - DrawHighlight(g, styleSet, roleBounds, highlightThisRole); + parentFactShape.DrawHighlight(g, roleBounds, true, highlightThisRole); } else if (null != currentDiagram) { @@ -2487,22 +2502,10 @@ parentFactShape.DrawHighlight(g, roleBounds, true, highlightThisRole); SetComparisonConstraint mcec; SetConstraint scec; - bool drawIndexNumbers = false; string indexString = null; - if (activeExternalAction == null) + if (activeExternalAction == null || !activeExternalAction.InitialRoles.Contains(currentRole)) { - drawIndexNumbers = true; - } - else - { - if (activeExternalAction.InitialRoles.IndexOf(currentRole) < 0) - { - drawIndexNumbers = true; - } - } - if (drawIndexNumbers) - { if (null != (mcec = stickyConstraint as SetComparisonConstraint)) { LinkedElementCollection<SetComparisonConstraintRoleSequence> sequenceCollection = mcec.RoleSequenceCollection; Modified: trunk/ORMModel/ShapeModel/InternalConstraintConnectAction.cs =================================================================== --- trunk/ORMModel/ShapeModel/InternalConstraintConnectAction.cs 2008-06-10 01:17:49 UTC (rev 1313) +++ trunk/ORMModel/ShapeModel/InternalConstraintConnectAction.cs 2008-08-13 00:32:41 UTC (rev 1314) @@ -122,34 +122,38 @@ if (null != (iuConstraint = constraint as UniquenessConstraint) && iuConstraint.IsInternal) { - // The single-column constraint is its own role set, just add the roles + // Keep the collection ordered, this ends up as constraint order on objectified FactTypes LinkedElementCollection<Role> roles = iuConstraint.RoleCollection; - int currentCount = roles.Count; - int removedCount = 0; - for (int i = currentCount - 1; i >= 0; --i) + int existingRolesCount = roles.Count; + for (int i = existingRolesCount - 1; i >= 0; --i) { - Role currentRole = roles[i]; - int index = selectedRoles.IndexOf(currentRole); - if (index == -1) + Role testRole = roles[i]; + if (!selectedRoles.Contains(testRole)) { - roles.Remove(currentRole); + roles.Remove(testRole); + --existingRolesCount; } - else - { - selectedRoles[index] = null; - ++removedCount; - } } - if (removedCount < rolesCount) + for (int i = 0; i < rolesCount; ++i) { - for (int i = 0; i < rolesCount; ++i) + Role selectedRole = selectedRoles[i]; + int existingIndex = roles.IndexOf(selectedRole); + if (existingIndex == -1) { - Role r = selectedRoles[i]; - if (r != null) + if (i < existingRolesCount) { - roles.Add(r); + roles.Insert(i, selectedRole); } + else if (!roles.Contains(selectedRole)) + { + roles.Add(selectedRole); + } + ++existingRolesCount; } + else if (existingIndex != i) + { + roles.Move(existingIndex, i); + } } } } Modified: trunk/ORMModel/Shell/ORMDocView.cs =================================================================== --- trunk/ORMModel/Shell/ORMDocView.cs 2008-06-10 01:17:49 UTC (rev 1313) +++ trunk/ORMModel/Shell/ORMDocView.cs 2008-08-13 00:32:41 UTC (rev 1314) @@ -2351,7 +2351,8 @@ LinkedElementCollection<Role> constraintRoles = null; bool abort = false; IList selectedElements = SelectedElements; - for (int i = selectedElements.Count - 1; i >= 0; i--) + int selectedElementCount = selectedElements.Count; + for (int i = 0; i < selectedElementCount; ++i) { Role role = selectedElements[i] as Role; if (role != null) @@ -2362,13 +2363,14 @@ parentFact = testFact; UniquenessConstraint iuc = UniquenessConstraint.CreateInternalUniquenessConstraint(parentFact); constraintRoles = iuc.RoleCollection; + constraintRoles.Add(role); } else if (testFact != parentFact) { abort = true; // Transaction will rollback when it disposes if we don't commit break; } - if (!constraintRoles.Contains(role)) + else if (!constraintRoles.Contains(role)) { constraintRoles.Add(role); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2008-08-13 00:55:10
|
Revision: 1317 http://orm.svn.sourceforge.net/orm/?rev=1317&view=rev Author: mcurland Date: 2008-08-13 00:55:19 +0000 (Wed, 13 Aug 2008) Log Message: ----------- Allow multiple Snippets elements per Language element in verbalization customization files, automatically add base identifier options for explicitly targeted snippets (fixes assert in available snippets picker), and add a file watcher to reload modified snippets on next verbalization request. refs #315 Modified Paths: -------------- trunk/ORMModel/ObjectModel/Design/Editors/AvailableVerbalizationSnippetsPicker.cs trunk/ORMModel/ObjectModel/VerbalizationSnippetSetsManager.cs trunk/ORMModel/ObjectModel/VerbalizationUntypedSnippets.xsd trunk/ORMModel/Shell/ORMDocDataServices.cs Modified: trunk/ORMModel/ObjectModel/Design/Editors/AvailableVerbalizationSnippetsPicker.cs =================================================================== --- trunk/ORMModel/ObjectModel/Design/Editors/AvailableVerbalizationSnippetsPicker.cs 2008-08-13 00:47:52 UTC (rev 1316) +++ trunk/ORMModel/ObjectModel/Design/Editors/AvailableVerbalizationSnippetsPicker.cs 2008-08-13 00:55:19 UTC (rev 1317) @@ -513,7 +513,7 @@ TargetedTypeData[] typeData = new TargetedTypeData[targetedTypesCount]; for (int i = 0; i < targetedTypesCount; ++i) { - typeData[i] = new TargetedTypeData(GetVerbalizationTargetDisplayName(myTargetedTypes[firstTargetedType + 1].Target), firstTargetedType + i + 1); + typeData[i] = new TargetedTypeData(GetVerbalizationTargetDisplayName(myTargetedTypes[firstTargetedType + i + 1].Target), firstTargetedType + i + 1); } return new TypeBranchWithExplicitTargets(this, firstTargetedType, typeData); } Modified: trunk/ORMModel/ObjectModel/VerbalizationSnippetSetsManager.cs =================================================================== --- trunk/ORMModel/ObjectModel/VerbalizationSnippetSetsManager.cs 2008-08-13 00:47:52 UTC (rev 1316) +++ trunk/ORMModel/ObjectModel/VerbalizationSnippetSetsManager.cs 2008-08-13 00:55:19 UTC (rev 1317) @@ -664,7 +664,7 @@ myEnumTypeName = enumTypeName; myLangId = languageId; myId = id; - myDescription = null; + myDescription = description; myTarget = target ?? DefaultTarget; } #endregion // Constructors @@ -1533,6 +1533,15 @@ { // Fallback case, base is not defined baseSnippets = (IVerbalizationSets<TEnum>)processedSets[defaultSnippetsIdentifier]; + if (currentBaseId.Target != VerbalizationSnippetsIdentifier.DefaultTarget && + currentBaseId.IsTargetedDefaultIdentifier(currentBaseId.Target)) + { + if (string.IsNullOrEmpty(currentBaseId.Description)) + { + currentBaseId = new VerbalizationSnippetsIdentifier(currentBaseId.EnumTypeName, currentBaseId.Target, currentBaseId.LanguageId, currentBaseId.Id, defaultSnippetsIdentifier.Description); + } + processedSets.Add(currentBaseId, baseSnippets); + } } } Debug.Assert(baseSnippets != null); // Should always have some base at this point Modified: trunk/ORMModel/ObjectModel/VerbalizationUntypedSnippets.xsd =================================================================== --- trunk/ORMModel/ObjectModel/VerbalizationUntypedSnippets.xsd 2008-08-13 00:47:52 UTC (rev 1316) +++ trunk/ORMModel/ObjectModel/VerbalizationUntypedSnippets.xsd 2008-08-13 00:55:19 UTC (rev 1317) @@ -39,7 +39,7 @@ </xs:simpleType> <xs:complexType name="LanguageType"> <xs:sequence> - <xs:element name="Snippets" minOccurs="1" maxOccurs="1"> + <xs:element name="Snippets" minOccurs="1" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="Snippet" minOccurs="0" maxOccurs="unbounded"> @@ -105,7 +105,13 @@ <xs:element name="Languages"> <xs:complexType> <xs:sequence> - <xs:element name="Language" type="LanguageType" minOccurs="1" maxOccurs="unbounded"/> + <xs:element name="Language" type="LanguageType" minOccurs="1" maxOccurs="unbounded"> + <xs:unique name="SnippetsNameAndTargetUnique"> + <xs:selector xpath="ve:Snippets"/> + <xs:field xpath="@name"/> + <xs:field xpath="@target"/> + </xs:unique> + </xs:element> </xs:sequence> </xs:complexType> <xs:key name="LanguageCodeKey"> Modified: trunk/ORMModel/Shell/ORMDocDataServices.cs =================================================================== --- trunk/ORMModel/Shell/ORMDocDataServices.cs 2008-08-13 00:47:52 UTC (rev 1316) +++ trunk/ORMModel/Shell/ORMDocDataServices.cs 2008-08-13 00:55:19 UTC (rev 1317) @@ -39,6 +39,7 @@ using Neumont.Tools.ORM.ObjectModel; using Neumont.Tools.ORM.ShapeModel; using MSOLE = Microsoft.VisualStudio.OLE.Interop; +using System.IO; namespace Neumont.Tools.ORM.Shell { @@ -1122,6 +1123,9 @@ private IORMToolTaskProvider myTaskProvider; private string myLastVerbalizationSnippetsOptions; private IDictionary<string, IDictionary<Type, IVerbalizationSets>> myTargetedVerbalizationSnippets; + private uint myInstanceVerbalizationChangeCookie; + private static FileSystemWatcher myVerbalizationChangeWatcher; + private static uint myVerbalizationChangeCookie; private IDictionary<string, VerbalizationTargetData> myVerbalizationTargets; private IDictionary<Type, LayoutEngineData> myLayoutEngines; private int myCustomBlockCanAddTransactionCount; @@ -1230,7 +1234,7 @@ verbalizationOptions = ""; } bool loadTarget = false; - if (targetedSnippets == null || (currentSnippetsOptions == null || currentSnippetsOptions != verbalizationOptions)) + if (targetedSnippets == null || myInstanceVerbalizationChangeCookie != myVerbalizationChangeCookie || (currentSnippetsOptions == null || currentSnippetsOptions != verbalizationOptions)) { // UNDONE: See comments in LoadSnippetsDictionary about loading // a dictionary with all type/target combinations then wrapping it @@ -1242,6 +1246,7 @@ { targetedSnippets.Clear(); } + myInstanceVerbalizationChangeCookie = myVerbalizationChangeCookie; } else if (targetedSnippets != null) { @@ -1257,11 +1262,50 @@ if (targetedSnippets == null) { myTargetedVerbalizationSnippets = targetedSnippets = new Dictionary<string, IDictionary<Type, IVerbalizationSets>>(); + if (myVerbalizationChangeWatcher == null) + { + FileSystemWatcher changeWatcher = new FileSystemWatcher(ORMDesignerPackage.VerbalizationDirectory, "*.xml"); + changeWatcher.IncludeSubdirectories = true; + changeWatcher.NotifyFilter = NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.CreationTime; + FileSystemEventHandler handler = new FileSystemEventHandler(VerbalizationCustomizationsChanged); + changeWatcher.Created += handler; + changeWatcher.Changed += handler; + changeWatcher.Deleted += handler; + changeWatcher.Renamed += new RenamedEventHandler(VerbalizationCustomizationsRenamed); + changeWatcher.EnableRaisingEvents = true; + FileSystemWatcher useWatcher = System.Threading.Interlocked.CompareExchange<FileSystemWatcher>(ref myVerbalizationChangeWatcher, changeWatcher, null); + if (useWatcher != null) + { + changeWatcher.Dispose(); + } + } } targetedSnippets[target] = retVal; } return retVal; } + /// <summary> + /// Track changes to the verbalization dictionary so that we can + /// reload snippets files as they change. + /// </summary> + private static void VerbalizationCustomizationsChanged(object sender, FileSystemEventArgs e) + { + unchecked + { + ++myVerbalizationChangeCookie; + }; + } + /// <summary> + /// Track changes to the verbalization dictionary so that we can + /// reload snippets files as they change. + /// </summary> + private static void VerbalizationCustomizationsRenamed(object sender, RenamedEventArgs e) + { + unchecked + { + ++myVerbalizationChangeCookie; + }; + } IDictionary<Type, IVerbalizationSets> IORMToolServices.GetVerbalizationSnippetsDictionary(string target) { return GetVerbalizationSnippetsDictionary(target); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2008-08-14 21:36:15
|
Revision: 1320 http://orm.svn.sourceforge.net/orm/?rev=1320&view=rev Author: mcurland Date: 2008-08-14 21:36:23 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Fixed miscellaneous usability and display issues: * Track before/after roles in adjusting ReadingOrder collections when new roles are inserted. fixes #226 * Added 'forError' parameter to IProxyDisplayProvider.ElementDisplayedAs to selectively activate shapes depending on the error. Do not activate entity shapes for duplicate name errors on collapsed value types. #153 * Allow dragging with ModelNoteConnector action to make behavior consistent with SubtypeConnectorAction. #359 * Internal constraint boxes and vertical role boxes were reporting incorrect bounds to accessibility readers. refs #185 Also: * Added support for most FactType commands to a ReadingShape selection, including activating the ReadingEditor window. Alignment and layout commits intentionally omitted. * ReadingShape was not updating display RolePlayer names when the role player was changed or the name modified * ValueTypes acting as reference mode values could not be added to a diagram, even if the corresponding entity has no shape. Modified Paths: -------------- trunk/ORMModel/ObjectModel/FactType.cs trunk/ORMModel/ObjectModel/ModelError.cs trunk/ORMModel/ObjectModel/ReadingOrder.cs trunk/ORMModel/ShapeModel/FactTypeShape.cs trunk/ORMModel/ShapeModel/ModelNoteConnectAction.cs trunk/ORMModel/ShapeModel/ORMDiagram.cs trunk/ORMModel/ShapeModel/ORMShape.AttachRules.cs trunk/ORMModel/ShapeModel/ORMShape.AttachRules.xml trunk/ORMModel/ShapeModel/ReadingShape.cs trunk/ORMModel/ShapeModel/ViewFixupRules.cs trunk/ORMModel/Shell/FactEditor/FactEditorSaver.cs trunk/ORMModel/Shell/ORMDocDataServices.cs trunk/ORMModel/Shell/ORMDocView.cs Modified: trunk/ORMModel/ObjectModel/FactType.cs =================================================================== --- trunk/ORMModel/ObjectModel/FactType.cs 2008-08-13 00:58:40 UTC (rev 1319) +++ trunk/ORMModel/ObjectModel/FactType.cs 2008-08-14 21:36:23 UTC (rev 1320) @@ -61,6 +61,18 @@ #endregion // IFactConstraint interface public partial class FactType : INamedElementDictionaryChild, INamedElementDictionaryRemoteParent, IModelErrorOwner, IVerbalizeCustomChildren, IHierarchyContextEnabled { + #region Public token values + /// <summary> + /// A key to set in the top-level transaction context to indicate the role that + /// a newly added role should be added after. + /// </summary> + public static readonly object InsertAfterRoleKey = new object(); + /// <summary> + /// A key to set in the top-level transaction context to indicate the role that + /// a newly added role should be added before. + /// </summary> + public static readonly object InsertBeforeRoleKey = new object(); + #endregion // Public token values #region ReadingOrder acquisition /// <summary> /// Gets a reading order, first by trying to find it, if one doesn't exist Modified: trunk/ORMModel/ObjectModel/ModelError.cs =================================================================== --- trunk/ORMModel/ObjectModel/ModelError.cs 2008-08-13 00:58:40 UTC (rev 1319) +++ trunk/ORMModel/ObjectModel/ModelError.cs 2008-08-14 21:36:23 UTC (rev 1320) @@ -300,9 +300,12 @@ /// passed in element. /// </summary> /// <param name="element">The element to find a proxy for</param> + /// <param name="forError">The <see cref="ModelError"/> that is being displayed. + /// If the displayed as element does not display this error, then it should not + /// be identified as a proxy display.</param> /// <returns>The proxy display element. Return the element itself or null /// if there is no proxy.</returns> - ModelElement ElementDisplayedAs(ModelElement element); + ModelElement ElementDisplayedAs(ModelElement element, ModelError forError); } #endregion // IProxyDisplayProvider #region AssociatedErrorElementCallback delegate Modified: trunk/ORMModel/ObjectModel/ReadingOrder.cs =================================================================== --- trunk/ORMModel/ObjectModel/ReadingOrder.cs 2008-08-13 00:58:40 UTC (rev 1319) +++ trunk/ORMModel/ObjectModel/ReadingOrder.cs 2008-08-14 21:36:23 UTC (rev 1320) @@ -272,32 +272,92 @@ /// This allows it to be used by both the rule and to be called /// during post load model fixup. /// </summary> - private static void ValidateReadingOrdersRoleCollection(FactType theFact, RoleBase addedRole) + private static void ValidateReadingOrdersRoleCollection(FactType factType, RoleBase addedRole) { - Debug.Assert(theFact.Store.TransactionManager.InTransaction); + Debug.Assert(factType.Store.TransactionManager.InTransaction); - LinkedElementCollection<ReadingOrder> readingOrders = theFact.ReadingOrderCollection; - int orderCount = readingOrders.Count; - if (orderCount != 0) + LinkedElementCollection<ReadingOrder> readingOrders; + int orderCount; + if (null == factType.UnaryRole && + 0 != (orderCount = (readingOrders = factType.ReadingOrderCollection).Count)) { - bool isUnaryFactType = theFact.UnaryRole != null; + bool checkedContext = false; + bool insertAfter = false; + RoleBase insertBeside = null; + IFormatProvider formatProvider = CultureInfo.InvariantCulture; for (int i = 0; i < orderCount; ++i) { ReadingOrder ord = readingOrders[i]; LinkedElementCollection<RoleBase> roles = ord.RoleCollection; - if (!roles.Contains(addedRole) && !isUnaryFactType) + if (!roles.Contains(addedRole)) { - ord.RoleCollection.Add(addedRole); + if (!checkedContext) + { + checkedContext = true; + Dictionary<object, object> contextInfo = factType.Store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo; + object contextRole; + if (contextInfo.TryGetValue(FactType.InsertAfterRoleKey, out contextRole)) + { + insertBeside = contextRole as RoleBase; + insertAfter = true; + } + else if (contextInfo.TryGetValue(FactType.InsertBeforeRoleKey, out contextRole)) + { + insertBeside = contextRole as RoleBase; + } + } + int insertIndex = -1; + if (insertBeside != null) + { + insertIndex = roles.IndexOf(insertBeside); + } + + if (insertIndex != -1) + { + roles.Insert(insertIndex + (insertAfter ? 1 : 0), addedRole); + } + else + { + roles.Add(addedRole); + } LinkedElementCollection<Reading> readings = ord.ReadingCollection; int readingCount = readings.Count; if (readingCount != 0) { - string appendText = String.Concat(" {", (roles.Count - 1).ToString(CultureInfo.InvariantCulture), "}"); - for (int j = 0; j < readingCount; ++j) + if (insertIndex == -1) { - Reading reading = readings[j]; - reading.SetAutoText(reading.Text + appendText); + string appendText = string.Concat(" {", (roles.Count - 1).ToString(CultureInfo.InvariantCulture), "}"); + for (int j = 0; j < readingCount; ++j) + { + Reading reading = readings[j]; + reading.SetAutoText(reading.Text + appendText); + } } + else + { + for (int j = 0; j < readingCount; ++j) + { + Reading reading = readings[j]; + reading.SetAutoText(Reading.ReplaceFields( + reading.Text, + delegate(int replaceIndex) + { + // UNDONE: Respect leading/trailing hyphen binding and keep them associated + // with the corresponding role. Will require work well beyond the scope of this + // routine. + if (replaceIndex == insertIndex) + { + return string.Concat("{", insertIndex.ToString(formatProvider), "} {", (insertIndex + 1).ToString(formatProvider), "}"); + } + else if (replaceIndex > insertIndex) + { + return string.Concat("{", (replaceIndex + 1).ToString(formatProvider), "}"); + } + return null; // Leave as is + } + )); + } + } } } } Modified: trunk/ORMModel/ShapeModel/FactTypeShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/FactTypeShape.cs 2008-08-13 00:58:40 UTC (rev 1319) +++ trunk/ORMModel/ShapeModel/FactTypeShape.cs 2008-08-14 21:36:23 UTC (rev 1320) @@ -43,18 +43,6 @@ #region FactTypeShape class public partial class FactTypeShape : ICustomShapeFolding, IModelErrorActivation, IProvideConnectorShape { - #region Public token values - /// <summary> - /// A key to set in the top-level transaction context to indicate the role that - /// a newly added role should be added after. - /// </summary> - public static readonly object InsertAfterRoleKey = new object(); - /// <summary> - /// A key to set in the top-level transaction context to indicate the role that - /// a newly added role should be added before. - /// </summary> - public static readonly object InsertBeforeRoleKey = new object(); - #endregion // Public token values #region ConstraintBoxRoleActivity enum /// <summary> /// The activity of a role in a ConstraintBox @@ -2198,7 +2186,28 @@ /// <returns>The vertical slice for this role</returns> public sealed override RectangleD GetBounds(ShapeElement parentShape, ShapeField parentField) { - return parentField.GetBounds(parentShape); + RectangleD retVal = RectangleD.Empty; + IConstraint testConstraint = myAssociatedConstraint; + if (testConstraint != null) + { + ((FactTypeShape)parentShape).WalkConstraintBoxes( + parentField, + ((ConstraintShapeField)parentField).AttachPosition, + delegate(ref ConstraintBox constraintBox) + { + if (constraintBox.FactConstraint.Constraint == testConstraint) + { + retVal = constraintBox.Bounds; + return false; // Don't continue, we got our item + } + return true; + }); + } + if (retVal.IsEmpty) + { + retVal = parentField.GetBounds(parentShape); + } + return retVal; } #endregion // Required ShapeSubField #region Accessor functions @@ -2747,11 +2756,30 @@ RectangleD retVal = parentField.GetBounds(parentShape); FactTypeShape parentFactShape = parentShape as FactTypeShape; LinkedElementCollection<RoleBase> roles = parentFactShape.DisplayedRoleOrder; - retVal.Width /= roles.Count; + int roleCount = roles.Count; int roleIndex = roles.IndexOf(myAssociatedRole); - if (roleIndex > 0) + DisplayOrientation orientation = parentFactShape.DisplayOrientation; + switch (orientation) { - retVal.Offset(roleIndex * retVal.Width, 0); + case DisplayOrientation.Horizontal: + retVal.Width /= roleCount; + if (roleIndex > 0) + { + retVal.Offset(roleIndex * retVal.Width, 0); + } + break; + case DisplayOrientation.VerticalRotatedLeft: + case DisplayOrientation.VerticalRotatedRight: + retVal.Height /= roleCount; + if (orientation == DisplayOrientation.VerticalRotatedLeft) + { + roleIndex = roleCount - roleIndex - 1; + } + if (roleIndex > 0) + { + retVal.Offset(0, roleIndex * retVal.Height); + } + break; } return retVal; } Modified: trunk/ORMModel/ShapeModel/ModelNoteConnectAction.cs =================================================================== --- trunk/ORMModel/ShapeModel/ModelNoteConnectAction.cs 2008-08-13 00:58:40 UTC (rev 1319) +++ trunk/ORMModel/ShapeModel/ModelNoteConnectAction.cs 2008-08-14 21:36:23 UTC (rev 1320) @@ -250,6 +250,16 @@ } } /// <summary> + /// Allow dragging the source element onto the target + /// </summary> + protected override void OnDraggingBegun(MouseActionEventArgs e) + { + if (mySourceElement == null) + { + mySourceElement = ElementFromShape<ORMModelElement>(MouseDownHitShape); + } + base.OnDraggingBegun(e); + } /// <summary> /// If we're emulating a drag (occurs when we're chained from RoleDragPendingAction), /// then complete the action on mouse up /// </summary> Modified: trunk/ORMModel/ShapeModel/ORMDiagram.cs =================================================================== --- trunk/ORMModel/ShapeModel/ORMDiagram.cs 2008-08-13 00:58:40 UTC (rev 1319) +++ trunk/ORMModel/ShapeModel/ORMDiagram.cs 2008-08-14 21:36:23 UTC (rev 1320) @@ -930,7 +930,7 @@ return !objectifiedShape.ExpandRefMode; } } - return objectType.HasReferenceMode; + return false; // If a shape can't be found, then do not collapse, regardless of objectType.HasReferenceMode } #if SHOW_FACTSHAPE_FOR_SUBTYPE /// <summary>See <see cref="ORMDiagramBase.CreateChildShape"/>.</summary> @@ -1698,14 +1698,15 @@ /// <summary> /// Implements IProxyDisplayProvider.ElementDisplayedAs /// </summary> - protected ModelElement ElementDisplayedAs(ModelElement element) + protected ModelElement ElementDisplayedAs(ModelElement element, ModelError forError) { ObjectType objectElement; ExclusionConstraint exclusionConstraint; SetConstraint setConstraint; if (null != (objectElement = element as ObjectType)) { - if (!ShouldDisplayObjectType(objectElement)) + if (!ShouldDisplayObjectType(objectElement) && + !(forError is ObjectTypeDuplicateNameError)) { FactType nestedFact = objectElement.NestedFactType; if (nestedFact != null) @@ -1749,9 +1750,9 @@ } return null; } - ModelElement IProxyDisplayProvider.ElementDisplayedAs(ModelElement element) + ModelElement IProxyDisplayProvider.ElementDisplayedAs(ModelElement element, ModelError forError) { - return ElementDisplayedAs(element); + return ElementDisplayedAs(element, forError); } #endregion // IProxyDisplayProvider Implementation #region IMergeElements implementation Modified: trunk/ORMModel/ShapeModel/ORMShape.AttachRules.cs =================================================================== --- trunk/ORMModel/ShapeModel/ORMShape.AttachRules.cs 2008-08-13 00:58:40 UTC (rev 1319) +++ trunk/ORMModel/ShapeModel/ORMShape.AttachRules.cs 2008-08-14 21:36:23 UTC (rev 1320) @@ -105,6 +105,10 @@ typeof(ReadingShape).GetNestedType("ReadingTextChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic), typeof(ReadingShape).GetNestedType("RoleDisplayOrderAddedRuleClass", BindingFlags.Public | BindingFlags.NonPublic), typeof(ReadingShape).GetNestedType("RoleDisplayOrderPositionChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic), + typeof(ReadingShape).GetNestedType("RolePlayerAddedRuleClass", BindingFlags.Public | BindingFlags.NonPublic), + typeof(ReadingShape).GetNestedType("RolePlayerChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic), + typeof(ReadingShape).GetNestedType("RolePlayerDeletedRuleClass", BindingFlags.Public | BindingFlags.NonPublic), + typeof(ReadingShape).GetNestedType("RolePlayerRolePlayerChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic), typeof(RingConstraintShape).GetNestedType("RingConstraintPropertyChangeRuleClass", BindingFlags.Public | BindingFlags.NonPublic), typeof(ValueConstraintShape).GetNestedType("ValueConstraintTextChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic)}; ORMShapeDomainModel.myCustomDomainModelTypes = retVal; @@ -140,7 +144,7 @@ { Microsoft.VisualStudio.Modeling.RuleManager ruleManager = store.RuleManager; Type[] disabledRuleTypes = ORMShapeDomainModel.CustomDomainModelTypes; - for (int i = 0; i < 73; ++i) + for (int i = 0; i < 77; ++i) { ruleManager.EnableRule(disabledRuleTypes[i]); } @@ -2051,6 +2055,110 @@ Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.SourceElement.Store, "Neumont.Tools.ORM.ShapeModel.ReadingShape.RoleDisplayOrderPositionChangedRule"); } } + [Microsoft.VisualStudio.Modeling.RuleOn(typeof(Neumont.Tools.ORM.ObjectModel.ObjectTypePlaysRole), FireTime=Microsoft.VisualStudio.Modeling.TimeToFire.TopLevelCommit, Priority=Microsoft.VisualStudio.Modeling.Diagrams.DiagramFixupConstants.ResizeParentRulePriority)] + private sealed class RolePlayerAddedRuleClass : Microsoft.VisualStudio.Modeling.AddRule + { + [System.Diagnostics.DebuggerStepThrough()] + public RolePlayerAddedRuleClass() + { + base.IsEnabled = false; + } + /// <summary> + /// Provide the following method in class: + /// Neumont.Tools.ORM.ShapeModel.ReadingShape + /// /// <summary> + /// /// AddRule: typeof(Neumont.Tools.ORM.ObjectModel.ObjectTypePlaysRole), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.ResizeParentRulePriority; + /// /// </summary> + /// private static void RolePlayerAddedRule(ElementAddedEventArgs e) + /// { + /// } + /// </summary> + [System.Diagnostics.DebuggerStepThrough()] + public override void ElementAdded(Microsoft.VisualStudio.Modeling.ElementAddedEventArgs e) + { + Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleStart(e.ModelElement.Store, "Neumont.Tools.ORM.ShapeModel.ReadingShape.RolePlayerAddedRule"); + ReadingShape.RolePlayerAddedRule(e); + Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "Neumont.Tools.ORM.ShapeModel.ReadingShape.RolePlayerAddedRule"); + } + } + [Microsoft.VisualStudio.Modeling.RuleOn(typeof(Neumont.Tools.ORM.ObjectModel.ObjectType), FireTime=Microsoft.VisualStudio.Modeling.TimeToFire.TopLevelCommit, Priority=Microsoft.VisualStudio.Modeling.Diagrams.DiagramFixupConstants.ResizeParentRulePriority)] + private sealed class RolePlayerChangedRuleClass : Microsoft.VisualStudio.Modeling.ChangeRule + { + [System.Diagnostics.DebuggerStepThrough()] + public RolePlayerChangedRuleClass() + { + base.IsEnabled = false; + } + /// <summary> + /// Provide the following method in class: + /// Neumont.Tools.ORM.ShapeModel.ReadingShape + /// /// <summary> + /// /// ChangeRule: typeof(Neumont.Tools.ORM.ObjectModel.ObjectType), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.ResizeParentRulePriority; + /// /// </summary> + /// private static void RolePlayerChangedRule(ElementPropertyChangedEventArgs e) + /// { + /// } + /// </summary> + [System.Diagnostics.DebuggerStepThrough()] + public override void ElementPropertyChanged(Microsoft.VisualStudio.Modeling.ElementPropertyChangedEventArgs e) + { + Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleStart(e.ModelElement.Store, "Neumont.Tools.ORM.ShapeModel.ReadingShape.RolePlayerChangedRule"); + ReadingShape.RolePlayerChangedRule(e); + Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "Neumont.Tools.ORM.ShapeModel.ReadingShape.RolePlayerChangedRule"); + } + } + [Microsoft.VisualStudio.Modeling.RuleOn(typeof(Neumont.Tools.ORM.ObjectModel.ObjectTypePlaysRole), FireTime=Microsoft.VisualStudio.Modeling.TimeToFire.TopLevelCommit, Priority=Microsoft.VisualStudio.Modeling.Diagrams.DiagramFixupConstants.ResizeParentRulePriority)] + private sealed class RolePlayerDeletedRuleClass : Microsoft.VisualStudio.Modeling.DeleteRule + { + [System.Diagnostics.DebuggerStepThrough()] + public RolePlayerDeletedRuleClass() + { + base.IsEnabled = false; + } + /// <summary> + /// Provide the following method in class: + /// Neumont.Tools.ORM.ShapeModel.ReadingShape + /// /// <summary> + /// /// DeleteRule: typeof(Neumont.Tools.ORM.ObjectModel.ObjectTypePlaysRole), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.ResizeParentRulePriority; + /// /// </summary> + /// private static void RolePlayerDeletedRule(ElementDeletedEventArgs e) + /// { + /// } + /// </summary> + [System.Diagnostics.DebuggerStepThrough()] + public override void ElementDeleted(Microsoft.VisualStudio.Modeling.ElementDeletedEventArgs e) + { + Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleStart(e.ModelElement.Store, "Neumont.Tools.ORM.ShapeModel.ReadingShape.RolePlayerDeletedRule"); + ReadingShape.RolePlayerDeletedRule(e); + Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "Neumont.Tools.ORM.ShapeModel.ReadingShape.RolePlayerDeletedRule"); + } + } + [Microsoft.VisualStudio.Modeling.RuleOn(typeof(Neumont.Tools.ORM.ObjectModel.ObjectTypePlaysRole), FireTime=Microsoft.VisualStudio.Modeling.TimeToFire.TopLevelCommit, Priority=Microsoft.VisualStudio.Modeling.Diagrams.DiagramFixupConstants.ResizeParentRulePriority)] + private sealed class RolePlayerRolePlayerChangedRuleClass : Microsoft.VisualStudio.Modeling.RolePlayerChangeRule + { + [System.Diagnostics.DebuggerStepThrough()] + public RolePlayerRolePlayerChangedRuleClass() + { + base.IsEnabled = false; + } + /// <summary> + /// Provide the following method in class: + /// Neumont.Tools.ORM.ShapeModel.ReadingShape + /// /// <summary> + /// /// RolePlayerChangeRule: typeof(Neumont.Tools.ORM.ObjectModel.ObjectTypePlaysRole), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.ResizeParentRulePriority; + /// /// </summary> + /// private static void RolePlayerRolePlayerChangedRule(RolePlayerChangedEventArgs e) + /// { + /// } + /// </summary> + [System.Diagnostics.DebuggerStepThrough()] + public override void RolePlayerChanged(Microsoft.VisualStudio.Modeling.RolePlayerChangedEventArgs e) + { + Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleStart(e.ElementLink.Store, "Neumont.Tools.ORM.ShapeModel.ReadingShape.RolePlayerRolePlayerChangedRule"); + ReadingShape.RolePlayerRolePlayerChangedRule(e); + Neumont.Tools.Modeling.Diagnostics.TraceUtility.TraceRuleEnd(e.ElementLink.Store, "Neumont.Tools.ORM.ShapeModel.ReadingShape.RolePlayerRolePlayerChangedRule"); + } + } } #endregion // Rule classes for ReadingShape #region Rule classes for RingConstraintShape Modified: trunk/ORMModel/ShapeModel/ORMShape.AttachRules.xml =================================================================== --- trunk/ORMModel/ShapeModel/ORMShape.AttachRules.xml 2008-08-13 00:58:40 UTC (rev 1319) +++ trunk/ORMModel/ShapeModel/ORMShape.AttachRules.xml 2008-08-14 21:36:23 UTC (rev 1320) @@ -257,6 +257,18 @@ <arg:RolePlayerPositionChangeRule methodName="RoleDisplayOrderPositionChangedRule"> <arg:RuleOn targetType="FactTypeShapeHasRoleDisplayOrder" fireTime="TopLevelCommit" priority="DiagramFixupConstants.ResizeParentRulePriority"/> </arg:RolePlayerPositionChangeRule> + <arg:AddRule methodName="RolePlayerAddedRule"> + <arg:RuleOn targetType="ObjectTypePlaysRole" targetTypeQualifier="Neumont.Tools.ORM.ObjectModel" fireTime="TopLevelCommit" priority="DiagramFixupConstants.ResizeParentRulePriority"/> + </arg:AddRule> + <arg:ChangeRule methodName="RolePlayerChangedRule"> + <arg:RuleOn targetType="ObjectType" targetTypeQualifier="Neumont.Tools.ORM.ObjectModel" fireTime="TopLevelCommit" priority="DiagramFixupConstants.ResizeParentRulePriority"/> + </arg:ChangeRule> + <arg:DeleteRule methodName="RolePlayerDeletedRule"> + <arg:RuleOn targetType="ObjectTypePlaysRole" targetTypeQualifier="Neumont.Tools.ORM.ObjectModel" fireTime="TopLevelCommit" priority="DiagramFixupConstants.ResizeParentRulePriority"/> + </arg:DeleteRule> + <arg:RolePlayerChangeRule methodName="RolePlayerRolePlayerChangedRule"> + <arg:RuleOn targetType="ObjectTypePlaysRole" targetTypeQualifier="Neumont.Tools.ORM.ObjectModel" fireTime="TopLevelCommit" priority="DiagramFixupConstants.ResizeParentRulePriority"/> + </arg:RolePlayerChangeRule> </arg:RuleContainer> <arg:RuleContainer class="RingConstraintShape"> <arg:ChangeRule methodName="RingConstraintPropertyChangeRule"> Modified: trunk/ORMModel/ShapeModel/ReadingShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/ReadingShape.cs 2008-08-13 00:58:40 UTC (rev 1319) +++ trunk/ORMModel/ShapeModel/ReadingShape.cs 2008-08-14 21:36:23 UTC (rev 1320) @@ -440,25 +440,37 @@ } return retVal; } - /// <summary> + /// Cause the reading shape for a role to invalidate + /// </summary> + private static void InvalidateReadingShape(Role role) + { + FactType factType; + if (null != role && + null != (factType = role.FactType)) + { + InvalidateReadingShape(factType); + } + } + /// <summary> /// Causes the ReadingShape on a FactTypeShape to invalidate /// </summary> public static void InvalidateReadingShape(FactType factType) { - foreach (ShapeElement se in PresentationViewsSubject.GetPresentation(factType)) + if (factType != null) { - FactTypeShape factShape = se as FactTypeShape; - if (factShape != null) + foreach (ShapeElement se in PresentationViewsSubject.GetPresentation(factType)) { - foreach (ShapeElement se2 in se.RelativeChildShapes) + FactTypeShape factShape = se as FactTypeShape; + if (factShape != null) { - ReadingShape readShape = se2 as ReadingShape; - if (readShape != null) + foreach (ShapeElement se2 in se.RelativeChildShapes) { - readShape.myDisplayText = null; - readShape.InvalidateRequired(true); - readShape.AutoResize(); + ReadingShape readShape = se2 as ReadingShape; + if (readShape != null) + { + readShape.InvalidateDisplayText(); + } } } } @@ -1009,6 +1021,69 @@ } } /// <summary> + /// AddRule: typeof(Neumont.Tools.ORM.ObjectModel.ObjectTypePlaysRole), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.ResizeParentRulePriority; + /// Update readings when the set of role player names is modified + /// </summary> + private static void RolePlayerAddedRule(ElementAddedEventArgs e) + { + ObjectTypePlaysRole link = (ObjectTypePlaysRole)e.ModelElement; + if (!link.IsDeleted) + { + InvalidateReadingShape(link.PlayedRole); + } + } + /// <summary> + /// DeleteRule: typeof(Neumont.Tools.ORM.ObjectModel.ObjectTypePlaysRole), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.ResizeParentRulePriority; + /// Update readings when the set of role player names is modified + /// </summary> + private static void RolePlayerDeletedRule(ElementDeletedEventArgs e) + { + ObjectTypePlaysRole link = (ObjectTypePlaysRole)e.ModelElement; + Role role = link.PlayedRole; + if (!role.IsDeleted) + { + InvalidateReadingShape(role); + } + } + /// <summary> + /// RolePlayerChangeRule: typeof(Neumont.Tools.ORM.ObjectModel.ObjectTypePlaysRole), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.ResizeParentRulePriority; + /// Update readings when the set of role player names is modified + /// </summary> + private static void RolePlayerRolePlayerChangedRule(RolePlayerChangedEventArgs e) + { + ObjectTypePlaysRole link = (ObjectTypePlaysRole)e.ElementLink; + if (!link.IsDeleted) + { + if (e.DomainRole.Id == ObjectTypePlaysRole.RolePlayerDomainRoleId) + { + InvalidateReadingShape(link.PlayedRole); + } + else + { + InvalidateReadingShape((Role)e.OldRolePlayer); + InvalidateReadingShape((Role)e.NewRolePlayer); + } + } + } + /// <summary> + /// ChangeRule: typeof(Neumont.Tools.ORM.ObjectModel.ObjectType), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.ResizeParentRulePriority; + /// Update readings when the set of role player names is modified + /// </summary> + private static void RolePlayerChangedRule(ElementPropertyChangedEventArgs e) + { + if (e.DomainProperty.Id == ObjectType.NameDomainPropertyId) + { + ObjectType objectType = (ObjectType)e.ModelElement; + if (!objectType.IsDeleted) + { + foreach (Role role in ObjectTypePlaysRole.GetPlayedRoleCollection(objectType)) + { + InvalidateReadingShape(role); + } + } + } + } + /// <summary> /// ChangeRule: typeof(Neumont.Tools.ORM.ObjectModel.Reading), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.AddShapeRulePriority; /// Rule to notice changes to Reading.Text properties so that the /// reading shapes can have their display text invalidated. Modified: trunk/ORMModel/ShapeModel/ViewFixupRules.cs =================================================================== --- trunk/ORMModel/ShapeModel/ViewFixupRules.cs 2008-08-13 00:58:40 UTC (rev 1319) +++ trunk/ORMModel/ShapeModel/ViewFixupRules.cs 2008-08-14 21:36:23 UTC (rev 1320) @@ -452,20 +452,19 @@ { Store store = shape.Store; Dictionary<object, object> contextInfo = store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo; + object contextRole; int insertIndex = -1; - if (contextInfo.ContainsKey(FactTypeShape.InsertAfterRoleKey)) + if (contextInfo.TryGetValue(FactType.InsertAfterRoleKey, out contextRole)) { - RoleBase insertAfter = (RoleBase)contextInfo[FactTypeShape.InsertAfterRoleKey]; - insertIndex = roles.IndexOf(insertAfter); + insertIndex = roles.IndexOf(contextRole as RoleBase); if (insertIndex != -1) { ++insertIndex; } } - else if (contextInfo.ContainsKey(FactTypeShape.InsertBeforeRoleKey)) + else if (contextInfo.TryGetValue(FactType.InsertBeforeRoleKey, out contextRole)) { - RoleBase insertBefore = (RoleBase)contextInfo[FactTypeShape.InsertBeforeRoleKey]; - insertIndex = roles.IndexOf(insertBefore); + insertIndex = roles.IndexOf(contextRole as RoleBase); } if (insertIndex != -1) { Modified: trunk/ORMModel/Shell/FactEditor/FactEditorSaver.cs =================================================================== --- trunk/ORMModel/Shell/FactEditor/FactEditorSaver.cs 2008-08-13 00:58:40 UTC (rev 1319) +++ trunk/ORMModel/Shell/FactEditor/FactEditorSaver.cs 2008-08-14 21:36:23 UTC (rev 1320) @@ -440,8 +440,8 @@ { if (matchedRoles[i] == null) { - // UNDONE: Consider using the FactTypeShape.InsertAfterRoleKey - // and FactTypeShape.InsertBeforeRoleKey context information + // UNDONE: Consider using the FactType.InsertAfterRoleKey + // and FactType.InsertBeforeRoleKey context information // to modify display of inserted roles. // Use an existing role if we have it Modified: trunk/ORMModel/Shell/ORMDocDataServices.cs =================================================================== --- trunk/ORMModel/Shell/ORMDocDataServices.cs 2008-08-13 00:58:40 UTC (rev 1319) +++ trunk/ORMModel/Shell/ORMDocDataServices.cs 2008-08-14 21:36:23 UTC (rev 1320) @@ -1681,6 +1681,7 @@ } } ModelElement startElement = element; + ModelError modelError = locator as ModelError; IProxyDisplayProvider proxyProvider = null; bool useProxy = false; bool haveCurrentDesigner = false; @@ -1707,7 +1708,7 @@ if (useProxy) { // Second pass, we were unable to find a suitable shape for the first - selectElement = proxyProvider.ElementDisplayedAs(element); + selectElement = proxyProvider.ElementDisplayedAs(element, modelError); if (selectElement != null && selectElement == element) { selectElement = null; @@ -1791,12 +1792,11 @@ if (targetDocData.ActivateShapeHelper(shape, ref currentDocView, ref currentDesigner, ref haveCurrentDesigner)) { - ModelError error; IModelErrorActivation activator; - if (null != (error = locator as ModelError) & + if (null != modelError && null != (activator = shape as IModelErrorActivation)) { - activator.ActivateModelError(error); + activator.ActivateModelError(modelError); } return true; } Modified: trunk/ORMModel/Shell/ORMDocView.cs =================================================================== --- trunk/ORMModel/Shell/ORMDocView.cs 2008-08-13 00:58:40 UTC (rev 1319) +++ trunk/ORMModel/Shell/ORMDocView.cs 2008-08-14 21:36:23 UTC (rev 1320) @@ -854,13 +854,15 @@ checkedCommands = ORMDesignerCommands.None; toleratedCommands = ORMDesignerCommands.None; FactType factType; + ReadingOrder readingOrder = null; Role role; ObjectType objectType; NodeShape nodeShape; SetConstraint setConstraint; SetComparisonConstraint setComparisonConstraint = null; bool otherShape = false; - if (null != (factType = element as FactType)) + if (null != (factType = element as FactType) || + (null != (readingOrder = element as ReadingOrder) && null != (factType = readingOrder.FactType))) { visibleCommands = enabledCommands = ORMDesignerCommands.DeleteFactType | ORMDesignerCommands.DeleteAny | ORMDesignerCommands.DisplayReadingsWindow; Objectification objectification = factType.Objectification; @@ -874,11 +876,16 @@ visibleCommands |= ORMDesignerCommands.UnobjectifyFactType; enabledCommands |= ORMDesignerCommands.UnobjectifyFactType; } - FactTypeShape factShape; - if (null != (factShape = presentationElement as FactTypeShape)) + if (presentationElement is FactTypeShape || + (readingOrder != null && presentationElement is ReadingShape)) { - visibleCommands |= ORMDesignerCommands.DeleteFactShape | ORMDesignerCommands.DeleteAnyShape | ORMDesignerCommands.AutoLayout | ORMDesignerCommands.AlignShapes | ORMDesignerCommands.DisplayOrientation | ORMDesignerCommands.DisplayConstraintsPosition; - enabledCommands |= ORMDesignerCommands.DeleteFactShape | ORMDesignerCommands.DeleteAnyShape | ORMDesignerCommands.AutoLayout | ORMDesignerCommands.AlignShapes | ORMDesignerCommands.DisplayOrientation | ORMDesignerCommands.DisplayConstraintsPosition; + visibleCommands |= ORMDesignerCommands.DeleteFactShape | ORMDesignerCommands.DeleteAnyShape | ORMDesignerCommands.DisplayOrientation | ORMDesignerCommands.DisplayConstraintsPosition; + enabledCommands |= ORMDesignerCommands.DeleteFactShape | ORMDesignerCommands.DeleteAnyShape | ORMDesignerCommands.DisplayOrientation | ORMDesignerCommands.DisplayConstraintsPosition; + if (readingOrder == null) + { + visibleCommands |= ORMDesignerCommands.AutoLayout | ORMDesignerCommands.AlignShapes; + enabledCommands |= ORMDesignerCommands.AutoLayout | ORMDesignerCommands.AlignShapes; + } // Don't flag the DisplayOrientation or DisplayConstraintsPosition commands as checkable, multiselect check state mismatches handled dynamically in OnStatusCommand if (factType.RoleCollection.Count > 1) { @@ -1287,11 +1294,14 @@ bool isChecked = true; foreach (ModelElement mel in docView.SelectedElements) { - FactTypeShape shape = mel as FactTypeShape; - if (shape != null) + FactTypeShape factTypeShape; + ReadingShape readingShape; + if (null != (factTypeShape = mel as FactTypeShape) || + (null != (readingShape = mel as ReadingShape) && + null != (factTypeShape = readingShape.ParentShape as FactTypeShape))) { // The command is checked when all selected values match the expected orientation - if (shape.DisplayOrientation != expectedOrientation) + if (factTypeShape.DisplayOrientation != expectedOrientation) { isChecked = false; break; @@ -1316,11 +1326,14 @@ bool isChecked = true; foreach (ModelElement mel in docView.SelectedElements) { - FactTypeShape shape = mel as FactTypeShape; - if (shape != null) + FactTypeShape factTypeShape; + ReadingShape readingShape; + if (null != (factTypeShape = mel as FactTypeShape) || + (null != (readingShape = mel as ReadingShape) && + null != (factTypeShape = readingShape.ParentShape as FactTypeShape))) { // The command is checked when all selected values match the expected orientation - if (shape.ConstraintDisplayPosition != expectedPosition) + if (factTypeShape.ConstraintDisplayPosition != expectedPosition) { isChecked = false; break; @@ -1796,19 +1809,20 @@ mel = pel.ModelElement; // Remove the actual object in the model - if (mel != null && !mel.IsDeleted && !(mel is ReadingOrder)) + if (mel != null && !mel.IsDeleted) { Role role; if (null != (role = mel as Role) && pel is RoleNameShape) { role.Name = ""; } - else if (mel is ReadingOrder) - { - // Reading orders tolerate the delete command, but are not deleted directly - } else { + ReadingOrder readingOrder = mel as ReadingOrder; + if (readingOrder != null) + { + mel = readingOrder.FactType; + } // Check if the object shape was in expanded mode bool testRefModeCollapse = complexSelection || 0 != (enabledCommands & ORMDesignerCommands.DeleteObjectType); ObjectTypeShape objectShape; @@ -1890,15 +1904,24 @@ ModelElement mel = selectedElements[i] as ModelElement; PresentationElement pel = mel as ShapeElement; ObjectType backingObjectifiedType = null; - // ReadingShape and ValueConstraintShape tolerate deletion, but the - // shapes cannot be deleted individually if (pel != null && !pel.IsDeleted) { ObjectifiedFactTypeNameShape objectifiedObjectShape; - if (pel is ReadingShape || pel is ValueConstraintShape) + ReadingShape readingShape; + if (pel is ValueConstraintShape) { + // ValueConstraintShape tolerates deletion, but the + // shapes cannot be deleted individually continue; } + else if (null != (readingShape = pel as ReadingShape)) + { + pel = readingShape.ParentShape; + if (pel == null) + { + continue; + } + } else if (null != (objectifiedObjectShape = pel as ObjectifiedFactTypeNameShape)) { // The two parts of an objectification should always appear together, @@ -2279,11 +2302,11 @@ if (insertAfter) { ++insertIndex; - contextInfo[FactTypeShape.InsertAfterRoleKey] = role; + contextInfo[FactType.InsertAfterRoleKey] = role; } else { - contextInfo[FactTypeShape.InsertBeforeRoleKey] = role; + contextInfo[FactType.InsertBeforeRoleKey] = role; } //bool aggressivelyKillValueType = store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo.ContainsKey(DeleteReferenceModeValueType); @@ -3254,8 +3277,12 @@ IList selectedElements = SelectedElements; for (int i = selectedElements.Count - 1; i >= 0; i--) { - FactTypeShape factTypeShape = selectedElements[i] as FactTypeShape; - if (factTypeShape != null) + ModelElement element = selectedElements[i] as ModelElement; + FactTypeShape factTypeShape; + ReadingShape readingShape; + if (null != (factTypeShape = element as FactTypeShape) || + (null != (readingShape = element as ReadingShape) && + null != (factTypeShape = readingShape.ParentShape as FactTypeShape))) { factTypeShape.DisplayOrientation = orientation; } @@ -3287,8 +3314,12 @@ IList selectedElements = SelectedElements; for (int i = selectedElements.Count - 1; i >= 0; i--) { - FactTypeShape factTypeShape = selectedElements[i] as FactTypeShape; - if (factTypeShape != null) + ModelElement element = selectedElements[i] as ModelElement; + FactTypeShape factTypeShape; + ReadingShape readingShape; + if (null != (factTypeShape = element as FactTypeShape) || + (null != (readingShape = element as ReadingShape) && + null != (factTypeShape = readingShape.ParentShape as FactTypeShape))) { factTypeShape.ConstraintDisplayPosition = position; } @@ -3307,8 +3338,12 @@ IList selectedElements = SelectedElements; for (int i = selectedElements.Count - 1; i >= 0; i--) { - FactTypeShape factTypeShape = selectedElements[i] as FactTypeShape; - if (factTypeShape != null) + ModelElement element = selectedElements[i] as ModelElement; + FactTypeShape factTypeShape; + ReadingShape readingShape; + if (null != (factTypeShape = element as FactTypeShape) || + (null != (readingShape = element as ReadingShape) && + null != (factTypeShape = readingShape.ParentShape as FactTypeShape))) { factTypeShape.ReverseDisplayedRoleOrder(); break; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2008-11-14 03:28:41
|
Revision: 1329 http://orm.svn.sourceforge.net/orm/?rev=1329&view=rev Author: mcurland Date: 2008-11-14 03:28:31 +0000 (Fri, 14 Nov 2008) Log Message: ----------- Fix a couple of bugs from [1327]. Simple subtype fields activating a text editor, and initial new objectified FactType instances with a supertype identifier were not getting an identifier required error. refs #374 Modified Paths: -------------- trunk/ORMModel/ObjectModel/SamplePopulation.cs trunk/ORMModel/ShapeModel/ObjectTypeShape.cs trunk/ORMModel/Shell/SamplePopulationEditor.cs Modified: trunk/ORMModel/ObjectModel/SamplePopulation.cs =================================================================== --- trunk/ORMModel/ObjectModel/SamplePopulation.cs 2008-11-08 21:43:45 UTC (rev 1328) +++ trunk/ORMModel/ObjectModel/SamplePopulation.cs 2008-11-14 03:28:31 UTC (rev 1329) @@ -1074,13 +1074,14 @@ ObjectType entityType; UniquenessConstraint pid; if (null != (entityType = factType.NestingType) && - null != (pid = entityType.PreferredIdentifier)) + null != (pid = entityType.ResolvedPreferredIdentifier)) { LinkedElementCollection<FactType> pidFactTypes; FactType identifierFactType; Role unaryRole = null; ObjectifiedUnaryRole objectifiedUnaryRole = null; - if (pid.IsInternal && + if (pid.PreferredIdentifierFor == entityType && + pid.IsInternal && 1 == (pidFactTypes = pid.FactTypeCollection).Count && ((identifierFactType = pidFactTypes[0]) == factType || (null != (unaryRole = factType.UnaryRole) && Modified: trunk/ORMModel/ShapeModel/ObjectTypeShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/ObjectTypeShape.cs 2008-11-08 21:43:45 UTC (rev 1328) +++ trunk/ORMModel/ShapeModel/ObjectTypeShape.cs 2008-11-14 03:28:31 UTC (rev 1329) @@ -470,7 +470,7 @@ /// <param name="objectType">The associated model element</param> private static void ResizeAssociatedShapes(ObjectType objectType) { - if (!objectType.IsDeleted && objectType != null) + if (objectType != null && !objectType.IsDeleted) { LinkedElementCollection<PresentationElement> pels = PresentationViewsSubject.GetPresentation(objectType); int pelCount = pels.Count; Modified: trunk/ORMModel/Shell/SamplePopulationEditor.cs =================================================================== --- trunk/ORMModel/Shell/SamplePopulationEditor.cs 2008-11-08 21:43:45 UTC (rev 1328) +++ trunk/ORMModel/Shell/SamplePopulationEditor.cs 2008-11-14 03:28:31 UTC (rev 1329) @@ -2361,6 +2361,14 @@ { EntityTypeSubtypeInstance subtypeInstance = objectInstance as EntityTypeSubtypeInstance; EntityTypeInstance entityInstance = (subtypeInstance != null) ? subtypeInstance.SupertypeInstance : (EntityTypeInstance)objectInstance; + ObjectType entityTypeSubtype; + if (subtypeInstance == null && + null != (entityTypeSubtype = myEntityTypeSubtype)) + { + // Doing this simple sanity check means that we can call this + // update function for all subtype cases. + subtypeInstance = EntityTypeSubtypeInstance.GetSubtypeInstance(entityInstance, entityTypeSubtype, true, false); + } UpdateInstanceFields(entityInstance, subtypeInstance); } /// <summary> @@ -2476,7 +2484,7 @@ get { Role role = myRole; - return (role != null) ? role.RolePlayer : myIsEntityTypeEditor ? myEntityType : (myEntityTypeSubtype ?? myEntityType); + return (role != null && (!(role is SubtypeMetaRole) || myEntityType == null)) ? role.RolePlayer : myIsEntityTypeEditor ? myEntityType : (myEntityTypeSubtype ?? myEntityType); } } #endregion // Accessor Properties @@ -2488,8 +2496,9 @@ public IVirtualTreeInPlaceControl CreateInPlaceEditControl() { ObjectType rolePlayer; + Role role = myRole; bool blockEdits = - (null == (rolePlayer = ContextTargetObjectType)) || + (null == (rolePlayer = (role is SubtypeMetaRole) ? ContextTargetObjectType : ContextObjectType)) || (myRole != null && rolePlayer.NestedFactType != null) || HasComplexIdentifier(rolePlayer); TypeEditorHost host = EditContextTypeEditorHost.Create( @@ -2524,10 +2533,10 @@ Role role = instance.myRole; if (columnInstance == null) { - ObjectType objectifyingType = (role != null) ? role.RolePlayer : (instance.myEntityTypeSubtype ?? instance.myEntityType); + ObjectType objectifyingType = (role != null) ? ((role is SubtypeMetaRole) ? instance.myEntityType : role.RolePlayer) : (instance.myEntityTypeSubtype ?? instance.myEntityType); if (objectifyingType != null) { - return ObjectTypeInstance.GetDisplayString(null, instance.myEntityTypeSubtype ?? objectifyingType, role == null); + return ObjectTypeInstance.GetDisplayString(null, (role is SubtypeMetaRole) ? objectifyingType : (instance.myEntityTypeSubtype ?? objectifyingType), role == null); } } else if (role == null) @@ -5915,7 +5924,7 @@ editContext = new CellEditContext( (supertypeIdentifyingRole != null) ? supertypeIdentifyingRole.RolePlayer : rowType, (supertypeIdentifyingRole != null) ? rowType : null, - supertypeIdentifyingRole, + GetPreferredSubtypeRole(rowType), myEditInstance, myEditSubtypeInstance, this); break; @@ -7477,7 +7486,7 @@ EntityTypeInstance editInstance = myEditInstance; ObjectTypeInstance recurseConnectInstance = null; - if (identifierRole is SupertypeMetaRole && (factInstance == null || !(factInstance.FactType is SubtypeFact))) + if ((identifierRole is SupertypeMetaRole || identifierRole is SubtypeMetaRole) && (factInstance == null || !(factInstance.FactType is SubtypeFact))) { ObjectType subtype = ContextObjectType; EntityTypeInstance entityInstance = (EntityTypeInstance)instance; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2008-11-20 08:09:08
|
Revision: 1338 http://orm.svn.sourceforge.net/orm/?rev=1338&view=rev Author: mcurland Date: 2008-11-20 08:09:04 +0000 (Thu, 20 Nov 2008) Log Message: ----------- Modify the selection container tracking routines to allow a covered toolwindow that is an ORM selection container (currently this set is the model browser and diagram spy) to provide the selection for other toolwindows. Previously, the selection could jump back to the current document window when the tool window was deactivated, which made these containers unusable for toolwindow-based edits. refs #376 Modified Paths: -------------- trunk/ORMModel/Framework/Shell/ToolWindowActivator.cs trunk/ORMModel/Shell/ORMDiagramSpy.cs trunk/ORMModel/Shell/ORMModelBrowser.cs Modified: trunk/ORMModel/Framework/Shell/ToolWindowActivator.cs =================================================================== --- trunk/ORMModel/Framework/Shell/ToolWindowActivator.cs 2008-11-19 22:47:15 UTC (rev 1337) +++ trunk/ORMModel/Framework/Shell/ToolWindowActivator.cs 2008-11-20 08:09:04 UTC (rev 1338) @@ -85,6 +85,7 @@ ClearContentsOnSelectionChanged, } #endregion // CoveredFrameContentActions enum + #region INotifyToolWindowActivation interface /// <summary> /// Callback interface provided by consumers of the <see cref="T:ToolWindowActivationHelper"/> class. /// </summary> @@ -122,7 +123,21 @@ /// <param name="docData">The document to detach from</param> void ActivatorDetachEventHandlers(DocDataType docData); } - + #endregion // INotifyToolWindowActivation interface + #region ICurrentFrameVisibility interface + /// <summary> + /// Provide the current frame visibility. Implement this interface + /// on a selection container tool window to enable maintaining the tool + /// window as a selection container even when it is hidden. + /// </summary> + public interface IProvideFrameVisibility + { + /// <summary> + /// The current <see cref="FrameVisibility"/> for this container + /// </summary> + FrameVisibility CurrentFrameVisibility { get;} + } + #endregion // ICurrentFrameVisibility interface #region ToolWindowActivationHelper class /// <summary> /// Helper class to enable tool window implementations to track changes selection @@ -410,7 +425,7 @@ } } /// <summary> - /// Clear the contents of the tool window associated with thie <see cref="T:ToolWindowActivationHelper"/> + /// Clear the contents of the tool window associated with this <see cref="T:ToolWindowActivationHelper"/> /// </summary> protected virtual void ClearContents() { @@ -602,7 +617,16 @@ private void MonitorSelectionChanged(object sender, MonitorSelectionEventArgs e) { IMonitorSelectionService monitor = (IMonitorSelectionService)sender; - CurrentSelectionContainer = monitor.CurrentSelectionContainer as SelectionContainerType ?? monitor.CurrentDocumentView as SelectionContainerType; + SelectionContainerType newContainer = monitor.CurrentSelectionContainer as SelectionContainerType; + if (newContainer == null) + { + IProvideFrameVisibility visibility = myCurrentSelectionContainer as IProvideFrameVisibility; + if (visibility == null || visibility.CurrentFrameVisibility == FrameVisibility.Hidden) + { + newContainer = monitor.CurrentDocumentView as SelectionContainerType; + } + } + CurrentSelectionContainer = newContainer; } /// <summary> /// Handles the DocumentWindowChanged event on the IMonitorSelectionService Modified: trunk/ORMModel/Shell/ORMDiagramSpy.cs =================================================================== --- trunk/ORMModel/Shell/ORMDiagramSpy.cs 2008-11-19 22:47:15 UTC (rev 1337) +++ trunk/ORMModel/Shell/ORMDiagramSpy.cs 2008-11-20 08:09:04 UTC (rev 1338) @@ -41,7 +41,7 @@ /// </summary> [Guid("19A5C15D-14D4-4A88-9891-A3294077BE56")] [CLSCompliant(false)] - public class ORMDiagramSpyWindow : ORMToolWindow, IORMSelectionContainer, IORMDesignerView + public class ORMDiagramSpyWindow : ORMToolWindow, IORMSelectionContainer, IProvideFrameVisibility, IORMDesignerView { #region Member Variables private ToolWindowDiagramView myDiagramView; @@ -557,6 +557,15 @@ } } #endregion // IORMDesignerView Implementation + #region IProvideFrameVisibility Implementation + FrameVisibility IProvideFrameVisibility.CurrentFrameVisibility + { + get + { + return CurrentFrameVisibility; + } + } + #endregion // IProvideFrameVisibility Implementation #region ORMDiagramSpyToolWindow specific /// <summary> /// Loads the SurveyTreeControl from the current document Modified: trunk/ORMModel/Shell/ORMModelBrowser.cs =================================================================== --- trunk/ORMModel/Shell/ORMModelBrowser.cs 2008-11-19 22:47:15 UTC (rev 1337) +++ trunk/ORMModel/Shell/ORMModelBrowser.cs 2008-11-20 08:09:04 UTC (rev 1338) @@ -32,6 +32,7 @@ using System.Runtime.InteropServices; using Neumont.Tools.Modeling.Design; using Microsoft.VisualStudio.Modeling.Diagrams; +using Neumont.Tools.Modeling.Shell; using Neumont.Tools.ORM.ShapeModel; using MSOLE = Microsoft.VisualStudio.OLE.Interop; using Microsoft.VisualStudio; @@ -44,9 +45,17 @@ /// </summary> [Guid("DD2334C3-AFDB-4FC5-9E8A-17D19A8CC97A")] [CLSCompliant(false)] - public partial class ORMModelBrowserToolWindow : ORMToolWindow, IORMSelectionContainer + public partial class ORMModelBrowserToolWindow : ORMToolWindow, IORMSelectionContainer, IProvideFrameVisibility { + #region Member Variables private SurveyTreeContainer myTreeContainer; + private ORMDesignerCommands myVisibleCommands; + private ORMDesignerCommands myCheckedCommands; + private ORMDesignerCommands myCheckableCommands; + private ORMDesignerCommands myEnabledCommands; + private object myCommandSet; + #endregion // Member Variables + #region Constructor /// <summary> /// public constructor /// </summary> @@ -55,12 +64,7 @@ : base(serviceProvider) { } - private ORMDesignerCommands myVisibleCommands; - private ORMDesignerCommands myCheckedCommands; - private ORMDesignerCommands myCheckableCommands; - private ORMDesignerCommands myEnabledCommands; - private object myCommandSet; - + #endregion // Constructor #region MenuService, MonitorSelectionService, and SelectedNode properties private static bool myCommandsPopulated; /// <summary> @@ -477,5 +481,14 @@ } } #endregion //ORMToolWindow overrides + #region IProvideFrameVisibility Implementation + FrameVisibility IProvideFrameVisibility.CurrentFrameVisibility + { + get + { + return CurrentFrameVisibility; + } + } + #endregion // IProvideFrameVisibility Implementation } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2008-11-20 08:17:50
|
Revision: 1339 http://orm.svn.sourceforge.net/orm/?rev=1339&view=rev Author: mcurland Date: 2008-11-20 08:17:47 +0000 (Thu, 20 Nov 2008) Log Message: ----------- Reprioritize shapes for the context window so that entities are preferred over valuetypes (stops occasional reference mode value types from appearing in the context window with their respective entity types). Also returned attached FactTypes for objectification case, and cleaned up recursion in core context window routines. refs #283 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/Shell/ORMContextWindow.cs Modified: trunk/ORMModel/ObjectModel/Constraint.cs =================================================================== --- trunk/ORMModel/ObjectModel/Constraint.cs 2008-11-20 08:09:04 UTC (rev 1338) +++ trunk/ORMModel/ObjectModel/Constraint.cs 2008-11-20 08:17:47 UTC (rev 1339) @@ -1465,21 +1465,15 @@ } } /// <summary> - /// Implements <see cref="IHierarchyContextEnabled.ForcedHierarchyContextElementCollection"/> + /// Implements <see cref="IHierarchyContextEnabled.GetForcedHierarchyContextElements"/> /// </summary> - protected static IEnumerable<IHierarchyContextEnabled> ForcedHierarchyContextElementCollection + protected static IEnumerable<IHierarchyContextEnabled> GetForcedHierarchyContextElements(bool minimalElements) { - get - { - return null; - } + return null; } - IEnumerable<IHierarchyContextEnabled> IHierarchyContextEnabled.ForcedHierarchyContextElementCollection + IEnumerable<IHierarchyContextEnabled> IHierarchyContextEnabled.GetForcedHierarchyContextElements(bool minimalElements) { - get - { - return ForcedHierarchyContextElementCollection; - } + return GetForcedHierarchyContextElements(minimalElements); } /// <summary> /// Implements <see cref="IHierarchyContextEnabled.HierarchyContextPlacementPriority"/> @@ -2639,21 +2633,15 @@ } } /// <summary> - /// Implements <see cref="IHierarchyContextEnabled.ForcedHierarchyContextElementCollection"/> + /// Implements <see cref="IHierarchyContextEnabled.GetForcedHierarchyContextElements"/> /// </summary> - protected static IEnumerable<IHierarchyContextEnabled> ForcedHierarchyContextElementCollection + protected static IEnumerable<IHierarchyContextEnabled> GetForcedHierarchyContextElements(bool minimalElements) { - get - { - return null; - } + return null; } - IEnumerable<IHierarchyContextEnabled> IHierarchyContextEnabled.ForcedHierarchyContextElementCollection + IEnumerable<IHierarchyContextEnabled> IHierarchyContextEnabled.GetForcedHierarchyContextElements(bool minimalElements) { - get - { - return ForcedHierarchyContextElementCollection; - } + return GetForcedHierarchyContextElements(minimalElements); } /// <summary> /// Implements <see cref="IHierarchyContextEnabled.HierarchyContextPlacementPriority"/> Modified: trunk/ORMModel/ObjectModel/FactType.cs =================================================================== --- trunk/ORMModel/ObjectModel/FactType.cs 2008-11-20 08:09:04 UTC (rev 1338) +++ trunk/ORMModel/ObjectModel/FactType.cs 2008-11-20 08:17:47 UTC (rev 1339) @@ -2678,22 +2678,54 @@ } } /// <summary> - /// Gets the elements that the current instance is dependant on for display. - /// The returned elements will be forced to display in the context window. + /// Implements <see cref="IHierarchyContextEnabled.GetForcedHierarchyContextElements"/>. + /// Returns all role players if minimal elements are called for, otherwise returns all + /// related FactTypes, Subtypes, and Supertypes of an ObjectifiedFactType, plus the elements + /// needed for display of those elements. /// </summary> - /// <value>The dependant context elements.</value> - protected IEnumerable<IHierarchyContextEnabled> ForcedHierarchyContextElementCollection + protected IEnumerable<IHierarchyContextEnabled> GetForcedHierarchyContextElements(bool minimalElements) { - get + foreach (RoleBase roleBase in RoleCollection) { - LinkedElementCollection<RoleBase> collection = RoleCollection; - int collectionCount = collection.Count; - for (int i = 0; i < collectionCount; ++i) + ObjectType rolePlayer = roleBase.Role.RolePlayer; + if (!rolePlayer.IsImplicitBooleanValue) { - IHierarchyContextEnabled rolePlayer = collection[i].Role.RolePlayer as IHierarchyContextEnabled; - if (rolePlayer != null) + yield return roleBase.Role.RolePlayer; + } + } + if (!minimalElements) + { + ObjectType nestingType = NestingType; + if (nestingType != null) + { + // Make sure an objectified FactType picks up its supertypes, subtypes, and + // facttypes for directly played roles + foreach (Role role in nestingType.PlayedRoleCollection) { - yield return rolePlayer; + SubtypeMetaRole subtypeRole; + SupertypeMetaRole supertypeRole; + if (null != (subtypeRole = role as SubtypeMetaRole)) + { + yield return ((SubtypeFact)role.FactType).Supertype; + } + else if (null != (supertypeRole = role as SupertypeMetaRole)) + { + yield return ((SubtypeFact)role.FactType).Subtype; + } + else + { + FactType relatedFactType = role.FactType; + yield return relatedFactType; + foreach (RoleBase roleBase in relatedFactType.RoleCollection) + { + ObjectType rolePlayer = roleBase.Role.RolePlayer; + if (rolePlayer != nestingType && + !rolePlayer.IsImplicitBooleanValue) + { + yield return rolePlayer; + } + } + } } } } @@ -2713,7 +2745,7 @@ } else { - return HierarchyContextPlacementPriority.High; + return HierarchyContextPlacementPriority.Higher; } } } @@ -2754,9 +2786,9 @@ { get { return ForwardHierarchyContextTo; } } - IEnumerable<IHierarchyContextEnabled> IHierarchyContextEnabled.ForcedHierarchyContextElementCollection + IEnumerable<IHierarchyContextEnabled> IHierarchyContextEnabled.GetForcedHierarchyContextElements(bool minimalElements) { - get { return ForcedHierarchyContextElementCollection; } + return GetForcedHierarchyContextElements(minimalElements); } HierarchyContextPlacementPriority IHierarchyContextEnabled.HierarchyContextPlacementPriority { Modified: trunk/ORMModel/ObjectModel/HierarchyContext.cs =================================================================== --- trunk/ORMModel/ObjectModel/HierarchyContext.cs 2008-11-20 08:09:04 UTC (rev 1338) +++ trunk/ORMModel/ObjectModel/HierarchyContext.cs 2008-11-20 08:17:47 UTC (rev 1339) @@ -10,25 +10,49 @@ public enum HierarchyContextPlacementPriority { /// <summary> + /// Highest + /// </summary> + Highest = 100, + /// <summary> /// VeryHigh /// </summary> - VeryHigh = 100, // Object types + VeryHigh = 90, // Entity types /// <summary> + /// Higher + /// </summary> + Higher = 80, // Objectified Fact Types + /// <summary> /// High /// </summary> - High = 75, // Objectified Fact Types + High = 70, // Value types /// <summary> + /// MediumHigh + /// </summary> + MediumHigh = 60, + /// <summary> /// Medium /// </summary> Medium = 50, // Fact types /// <summary> + /// MediumLow + /// </summary> + MediumLow = 40, + /// <summary> /// Low /// </summary> - Low = 25, // roles + Low = 30, // roles /// <summary> + /// Lower + /// </summary> + Lower = 20, + /// <summary> /// VeryLow /// </summary> - VeryLow = 0, // Constraints + VeryLow = 10, // Constraints + /// <summary> + /// Lowest + /// </summary> + Lowest = 0, } /// <summary> /// Defines the methods and properties required for an object to display in the ORMContextWindow @@ -66,8 +90,10 @@ /// Gets the elements that the current instance is dependant on for display. /// The returned elements will be forced to display in the context window. /// </summary> - /// <value>The dependant context elements.</value> - IEnumerable<IHierarchyContextEnabled> ForcedHierarchyContextElementCollection { get;} + /// <param name="minimalElements">The final elements have been retrieved, + /// retrieve the minimal number of elements for display.</param> + /// <returns>Elements that always need to be shown with this element</returns> + IEnumerable<IHierarchyContextEnabled> GetForcedHierarchyContextElements(bool minimalElements); /// <summary> /// Gets the place priority. The place priority specifies the order in which the element will /// be placed on the context diagram. Modified: trunk/ORMModel/ObjectModel/ObjectType.cs =================================================================== --- trunk/ORMModel/ObjectModel/ObjectType.cs 2008-11-20 08:09:04 UTC (rev 1338) +++ trunk/ORMModel/ObjectModel/ObjectType.cs 2008-11-20 08:17:47 UTC (rev 1339) @@ -4133,26 +4133,24 @@ get { return ForwardHierarchyContextTo; } } /// <summary> - /// Gets the elements that the current instance is dependant on for display. - /// The returned elements will be forced to display in the context window. + /// Implements <see cref="IHierarchyContextEnabled.GetForcedHierarchyContextElements"/> /// </summary> - /// <value>The dependant context elements.</value> - protected static IEnumerable<IHierarchyContextEnabled> ForcedHierarchyContextElementCollection + protected static IEnumerable<IHierarchyContextEnabled> GetForcedHierarchyContextElements(bool minimalElements) { - get { return null; } + return null; } - IEnumerable<IHierarchyContextEnabled> IHierarchyContextEnabled.ForcedHierarchyContextElementCollection + IEnumerable<IHierarchyContextEnabled> IHierarchyContextEnabled.GetForcedHierarchyContextElements(bool minimalElements) { - get { return ForcedHierarchyContextElementCollection; } + return GetForcedHierarchyContextElements(minimalElements); } /// <summary> /// Gets the place priority. The place priority specifies the order in which the element will /// be placed on the context diagram. /// </summary> /// <value>The place priority.</value> - protected static HierarchyContextPlacementPriority HierarchyContextPlacementPriority + protected HierarchyContextPlacementPriority HierarchyContextPlacementPriority { - get { return HierarchyContextPlacementPriority.VeryHigh; } + get { return IsValueType ? HierarchyContextPlacementPriority.High : HierarchyContextPlacementPriority.VeryHigh; } } HierarchyContextPlacementPriority IHierarchyContextEnabled.HierarchyContextPlacementPriority { Modified: trunk/ORMModel/ObjectModel/Role.cs =================================================================== --- trunk/ORMModel/ObjectModel/Role.cs 2008-11-20 08:09:04 UTC (rev 1338) +++ trunk/ORMModel/ObjectModel/Role.cs 2008-11-20 08:17:47 UTC (rev 1339) @@ -1490,17 +1490,15 @@ get { return ForwardHierarchyContextTo; } } /// <summary> - /// Gets the elements that the current instance is dependant on for display. - /// The returned elements will be forced to display in the context window. + /// Implements <see cref="IHierarchyContextEnabled.GetForcedHierarchyContextElements"/> /// </summary> - /// <value>The dependant context elements.</value> - protected static IEnumerable<IHierarchyContextEnabled> ForcedHierarchyContextElementCollection + protected static IEnumerable<IHierarchyContextEnabled> GetForcedHierarchyContextElements(bool minimalElements) { - get { return null; } + return null; } - IEnumerable<IHierarchyContextEnabled> IHierarchyContextEnabled.ForcedHierarchyContextElementCollection + IEnumerable<IHierarchyContextEnabled> IHierarchyContextEnabled.GetForcedHierarchyContextElements(bool minimalElements) { - get { return ForcedHierarchyContextElementCollection; } + return GetForcedHierarchyContextElements(minimalElements); } /// <summary> /// Gets the place priority. The place priority specifies the order in which the element will Modified: trunk/ORMModel/Shell/ORMContextWindow.cs =================================================================== --- trunk/ORMModel/Shell/ORMContextWindow.cs 2008-11-20 08:09:04 UTC (rev 1338) +++ trunk/ORMModel/Shell/ORMContextWindow.cs 2008-11-20 08:17:47 UTC (rev 1339) @@ -347,9 +347,7 @@ /// <param name="element">The element.</param> private void PlaceObject(IHierarchyContextEnabled element) { - SortedList<IHierarchyContextEnabled, int> elementsToPlace = GetRelatedContextableElements(element, myGenerations); - IList<IHierarchyContextEnabled> elements = elementsToPlace.Keys; - foreach (IHierarchyContextEnabled elem in elements) + foreach (IHierarchyContextEnabled elem in GetRelatedContextableElements(element, myGenerations)) { if (elem.ForwardHierarchyContextTo != null) { @@ -363,34 +361,56 @@ /// </summary> /// <param name="element">The element.</param> /// <param name="generations">The numeber of generations out to go.</param> - /// <returns></returns> - private static SortedList<IHierarchyContextEnabled, int> GetRelatedContextableElements(IHierarchyContextEnabled element, int generations) + /// <returns>Sorted list of elements</returns> + private static IList<IHierarchyContextEnabled> GetRelatedContextableElements(IHierarchyContextEnabled element, int generations) { - SortedList<IHierarchyContextEnabled, int> relatedElementsCollection = new SortedList<IHierarchyContextEnabled, int>(HierarchyContextPlacePrioritySortComparer.Instance); - GetRelatedContextableElementsHelper(element, ref relatedElementsCollection, generations); - IList<IHierarchyContextEnabled> keys = relatedElementsCollection.Keys; - int relatedElementsCount = keys.Count; - for (int i = 0; i < relatedElementsCount; ++i) + Dictionary<IHierarchyContextEnabled, int> masterDictionary = new Dictionary<IHierarchyContextEnabled, int>(); + GetRelatedContextableElementsHelper(element, masterDictionary, ref masterDictionary, generations); + int nextPassCount = masterDictionary.Count; + IHierarchyContextEnabled[] firstPassElements = new IHierarchyContextEnabled[nextPassCount]; + masterDictionary.Keys.CopyTo(firstPassElements, 0); + ICollection<IHierarchyContextEnabled> nextPassElements = firstPassElements; + + while (nextPassCount != 0) { - IEnumerable<IHierarchyContextEnabled> forcedContextElements = keys[i].ForcedHierarchyContextElementCollection; - if (forcedContextElements != null) + Dictionary<IHierarchyContextEnabled, int> localDictionary = null; + bool requestMinimum = generations == 0; + generations = Math.Max(generations - 1, 0); + foreach (IHierarchyContextEnabled nextPassElement in nextPassElements) { - foreach (IHierarchyContextEnabled dependantContextableElement in forcedContextElements) + IEnumerable<IHierarchyContextEnabled> forcedContextElements = nextPassElement.GetForcedHierarchyContextElements(requestMinimum); + if (forcedContextElements != null) { - GetRelatedContextableElementsHelper(dependantContextableElement, ref relatedElementsCollection, 0); + foreach (IHierarchyContextEnabled dependantContextableElement in forcedContextElements) + { + GetRelatedContextableElementsHelper(dependantContextableElement, masterDictionary, ref localDictionary, generations); + } } } + if (localDictionary != null) + { + nextPassElements = localDictionary.Keys; + nextPassCount = nextPassElements.Count; + } + else + { + nextPassCount = 0; + } } - return relatedElementsCollection; + List<IHierarchyContextEnabled> retVal = new List<IHierarchyContextEnabled>(masterDictionary.Keys); + retVal.Sort(HierarchyContextPlacePrioritySortComparer.Instance); + return retVal; } /// <summary> /// Dont use this method. Use GetRelatedContextableElements instead. /// helper function for GetRelatedContextableElements. /// </summary> /// <param name="element">The element.</param> - /// <param name="relatedElementsCollection">The related elements collection.</param> + /// <param name="masterDictionary">A master dictionary of all elements</param> + /// <param name="localDictionary">A local dictionary for this pass through. + /// Allows us to track multiple passes while iterating through the elements of another dictionary.</param> /// <param name="generations">The generations.</param> - private static void GetRelatedContextableElementsHelper(IHierarchyContextEnabled element, ref SortedList<IHierarchyContextEnabled, int> relatedElementsCollection, int generations) + private static void GetRelatedContextableElementsHelper(IHierarchyContextEnabled element, Dictionary<IHierarchyContextEnabled, int> masterDictionary, ref Dictionary<IHierarchyContextEnabled, int> localDictionary, int generations) { if (element == null) { @@ -401,37 +421,55 @@ { return; } - if (!relatedElementsCollection.ContainsKey(contextableElement)) + int existingGenerations; + if (!masterDictionary.TryGetValue(contextableElement, out existingGenerations)) { - relatedElementsCollection.Add(contextableElement, generations); + masterDictionary.Add(contextableElement, generations); + if (localDictionary != masterDictionary) + { + (localDictionary ?? (localDictionary = new Dictionary<IHierarchyContextEnabled, int>())).Add(contextableElement, generations); + } } else { - if (relatedElementsCollection[contextableElement] >= generations) + if (existingGenerations >= generations) { return; } else { - relatedElementsCollection[contextableElement] = generations; + masterDictionary[contextableElement] = generations; + if (localDictionary == null) + { + (localDictionary = new Dictionary<IHierarchyContextEnabled,int>()).Add(contextableElement, generations); + } + else if (localDictionary != masterDictionary && !localDictionary.ContainsKey(contextableElement)) + { + // Note that we don't actually use the generations value from + // the local dictionary, there is no reason to update it. + localDictionary.Add(contextableElement, generations); + } } } - if (contextableElement.ForwardHierarchyContextTo != null) + IHierarchyContextEnabled forwardTo; + if (null != (forwardTo = contextableElement.ForwardHierarchyContextTo)) { - GetRelatedContextableElementsHelper(contextableElement.ForwardHierarchyContextTo, ref relatedElementsCollection, generations); + GetRelatedContextableElementsHelper(forwardTo, masterDictionary, ref localDictionary, generations); } - if (generations > 0 && (relatedElementsCollection.Count == 1 || contextableElement.ContinueWalkingHierarchyContext)) + if (generations > 0 && (masterDictionary.Count == 1 || contextableElement.ContinueWalkingHierarchyContext)) { - GetLinkedElements(contextableElement, ref relatedElementsCollection, generations); + GetLinkedElements(contextableElement, masterDictionary, ref localDictionary, generations); } } /// <summary> /// Gets the linked elements for the specified element. /// </summary> /// <param name="element">The element.</param> - /// <param name="relatedElementsCollection">The related elements collection.</param> + /// <param name="masterDictionary">A master dictionary of all elements</param> + /// <param name="localDictionary">A local dictionary for this pass through. + /// Allows us to track multiple passes while iterating through the elements of another dictionary.</param> /// <param name="generations">The generations.</param> - private static void GetLinkedElements(IHierarchyContextEnabled element, ref SortedList<IHierarchyContextEnabled, int> relatedElementsCollection, int generations) + private static void GetLinkedElements(IHierarchyContextEnabled element, Dictionary<IHierarchyContextEnabled, int> masterDictionary, ref Dictionary<IHierarchyContextEnabled, int> localDictionary, int generations) { ReadOnlyCollection<ElementLink> col = DomainRoleInfo.GetAllElementLinks((ModelElement)element); foreach (ElementLink link in col) @@ -444,11 +482,11 @@ continue; } int decrement = contextableElement.HierarchyContextDecrementCount; - if (relatedElementsCollection.Count == 1 && contextableElement.ForwardHierarchyContextTo != null) + if (masterDictionary.Count == 1 && contextableElement.ForwardHierarchyContextTo != null) { decrement = 0; } - GetRelatedContextableElementsHelper(contextableElement, ref relatedElementsCollection, generations - decrement); + GetRelatedContextableElementsHelper(contextableElement, masterDictionary, ref localDictionary, generations - decrement); } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2008-12-05 04:41:22
|
Revision: 1342 http://orm.svn.sourceforge.net/orm/?rev=1342&view=rev Author: mcurland Date: 2008-12-05 04:41:19 +0000 (Fri, 05 Dec 2008) Log Message: ----------- Fixed crash adding new diagram with [1341] when the 'Diagram Management' extension is not turned on. Also changed the display name of SaveDiagramPosition to SaveDiagramPositions to more accurately reflect its application to all diagrams, not just the selected one where the property is displayed. refs #379 Modified Paths: -------------- trunk/ORMModel/Framework/Shell/DiagramDisplay.dsl trunk/ORMModel/Framework/Shell/GeneratedCode/DomainModelResx.resx trunk/ORMModel/Framework/Shell/MultiDiagramDocView.cs trunk/ORMModel/Shell/ORMDocView.cs Modified: trunk/ORMModel/Framework/Shell/DiagramDisplay.dsl =================================================================== --- trunk/ORMModel/Framework/Shell/DiagramDisplay.dsl 2008-12-03 21:41:29 UTC (rev 1341) +++ trunk/ORMModel/Framework/Shell/DiagramDisplay.dsl 2008-12-05 04:41:19 UTC (rev 1342) @@ -35,7 +35,7 @@ <Classes> <DomainClass Name="DiagramDisplay" Namespace="Neumont.Tools.Modeling.Shell" Id="14A6B724-7849-4D7D-A5C2-29910FFBB516" DisplayName="DiagramDisplay" InheritanceModifier="Sealed" Description=""> <Properties> - <DomainProperty Name="SaveDiagramPosition" DisplayName="SaveDiagramPosition" IsBrowsable="true" DefaultValue="true" Id="17AA2B64-3328-4420-8C68-34157D10DB77" Description="Save the most recent position and zoom information for each diagram in addition to diagram order."> + <DomainProperty Name="SaveDiagramPosition" DisplayName="SaveDiagramPositions" IsBrowsable="true" DefaultValue="true" Id="17AA2B64-3328-4420-8C68-34157D10DB77" Description="Save the most recent position and zoom information for each diagram in addition to diagram order."> <Type> <ExternalTypeMoniker Name="/System/Boolean"/> </Type> Modified: trunk/ORMModel/Framework/Shell/GeneratedCode/DomainModelResx.resx =================================================================== --- trunk/ORMModel/Framework/Shell/GeneratedCode/DomainModelResx.resx 2008-12-03 21:41:29 UTC (rev 1341) +++ trunk/ORMModel/Framework/Shell/GeneratedCode/DomainModelResx.resx 2008-12-05 04:41:19 UTC (rev 1342) @@ -138,7 +138,7 @@ <comment>Description for DomainProperty 'SaveDiagramPosition' on DomainClass 'DiagramDisplay'</comment> </data> <data name="Neumont.Tools.Modeling.Shell.DiagramDisplay/SaveDiagramPosition.DisplayName" xml:space="preserve"> - <value>SaveDiagramPosition</value> + <value>SaveDiagramPositions</value> <comment>DisplayName for DomainProperty 'SaveDiagramPosition' on DomainClass 'DiagramDisplay'</comment> </data> <data name="Neumont.Tools.Modeling.Shell.DiagramPlaceHolder.Description" xml:space="preserve"> Modified: trunk/ORMModel/Framework/Shell/MultiDiagramDocView.cs =================================================================== --- trunk/ORMModel/Framework/Shell/MultiDiagramDocView.cs 2008-12-03 21:41:29 UTC (rev 1341) +++ trunk/ORMModel/Framework/Shell/MultiDiagramDocView.cs 2008-12-05 04:41:19 UTC (rev 1342) @@ -557,7 +557,7 @@ { DomainDataDirectory dataDirectory = store.DomainDataDirectory; DomainClassInfo classInfo; - classInfo = dataDirectory.FindDomainClass(DiagramDisplayHasDiagramOrder.DomainClassId); + classInfo = dataDirectory.FindDomainRelationship(DiagramDisplayHasDiagramOrder.DomainClassId); if (classInfo != null) { // DiagramDisplay is an optional domain model, it may not be loaded in the store Modified: trunk/ORMModel/Shell/ORMDocView.cs =================================================================== --- trunk/ORMModel/Shell/ORMDocView.cs 2008-12-03 21:41:29 UTC (rev 1341) +++ trunk/ORMModel/Shell/ORMDocView.cs 2008-12-05 04:41:19 UTC (rev 1342) @@ -413,6 +413,7 @@ LinkedElementCollection<Diagram> diagramOrder; int selectedDiagramIndex; if (null != (selectedDiagram = ContextMenuStrip.SelectedDiagram) && + null != store.FindDomainModel(DiagramDisplayDomainModel.DomainModelId) && null != (displayContainer = DiagramDisplayHasDiagramOrder.GetDiagramDisplay(selectedDiagram)) && (selectedDiagramIndex = (diagramOrder = displayContainer.OrderedDiagramCollection).IndexOf(selectedDiagram)) < (diagramOrder.Count - 1)) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2008-12-20 03:37:08
|
Revision: 1345 http://orm.svn.sourceforge.net/orm/?rev=1345&view=rev Author: mcurland Date: 2008-12-20 03:37:05 +0000 (Sat, 20 Dec 2008) Log Message: ----------- Modify the toolbox handling in the ORM Diagram Spy window to handle dynamic toolbox contents introduced with the shape extensions in [1344]. refs #376 refs #380 Modified Paths: -------------- trunk/ORMModel/Framework/Design/PropertyProvider.cs trunk/ORMModel/Framework/FrameworkServices.cs trunk/ORMModel/Framework/Shell/MultiDiagramDocView.cs trunk/ORMModel/Framework/Shell/MultiDiagramDocViewControl.cs trunk/ORMModel/ShapeModel/ORMDiagram.cs trunk/ORMModel/Shell/ORMDesignerCommandManager.cs trunk/ORMModel/Shell/ORMDiagramSpy.cs trunk/ORMModel/Shell/ORMDocData.cs trunk/ORMModel/Shell/ORMDocDataServices.cs trunk/ORMModel/Shell/ORMDocView.cs Modified: trunk/ORMModel/Framework/Design/PropertyProvider.cs =================================================================== --- trunk/ORMModel/Framework/Design/PropertyProvider.cs 2008-12-17 02:27:45 UTC (rev 1344) +++ trunk/ORMModel/Framework/Design/PropertyProvider.cs 2008-12-20 03:37:05 UTC (rev 1345) @@ -88,6 +88,18 @@ this.myProviderDictionary = new Dictionary<RuntimeTypeHandle, PropertyProvider>(RuntimeTypeHandleComparer.Instance); } #endregion // Constructor + #region Accessor Properties + /// <summary> + /// Get the context <see cref="Store"/> + /// </summary> + public Store Store + { + get + { + return myStore; + } + } + #endregion // Access Properties #region IPropertyProviderService implementation void IPropertyProviderService.AddOrRemovePropertyProvider<TExtendableElement>(PropertyProvider provider, bool includeSubtypes, EventHandlerAction action) { Modified: trunk/ORMModel/Framework/FrameworkServices.cs =================================================================== --- trunk/ORMModel/Framework/FrameworkServices.cs 2008-12-17 02:27:45 UTC (rev 1344) +++ trunk/ORMModel/Framework/FrameworkServices.cs 2008-12-20 03:37:05 UTC (rev 1345) @@ -83,6 +83,16 @@ myStore = store; } /// <summary> + /// The current <see cref="Store"/> + /// </summary> + public Store Store + { + get + { + return myStore; + } + } + /// <summary> /// Get an array of providers of the requested type, or null if the interface is not implemented /// </summary> public T[] GetTypedDomainModelProviders<T>() where T : class Modified: trunk/ORMModel/Framework/Shell/MultiDiagramDocView.cs =================================================================== --- trunk/ORMModel/Framework/Shell/MultiDiagramDocView.cs 2008-12-17 02:27:45 UTC (rev 1344) +++ trunk/ORMModel/Framework/Shell/MultiDiagramDocView.cs 2008-12-20 03:37:05 UTC (rev 1345) @@ -55,7 +55,7 @@ /// <summary> /// Determine when the toolbox should be refreshed /// </summary> - private Type myLastDiagramType; + private Type myLastToolboxDiagramType; private MultiDiagramDocViewControl DocViewControl { get @@ -86,19 +86,49 @@ protected override void OnSelectionChanged(EventArgs e) { base.OnSelectionChanged(e); - Diagram diagram = CurrentDiagram; + if (UpdateToolboxDiagram(CurrentDiagram)) + { + RefreshDiagramToolboxItems(); + } + } + /// <summary> + /// Update the type of diagram that sources the toolbox items for this document. If this + /// returns <see langword="true"/>, then it is the responsibility of the caller to call + /// <see cref="IToolboxService.Refresh"/> after updating the current toolbox filters. + /// </summary> + /// <param name="diagram">The <see cref="Diagram"/> to activate</param> + /// <returns><see langword="true"/> if the diagram type is changed</returns> + /// <remarks>The toolbox service always requests toolbox items from the document window, even + /// when the active selection container in a tool window supports the <see cref="Microsoft.VisualStudio.Shell.Interop.IVsToolboxUser"/> + /// interface. Derived classes can reimplement <see cref="Microsoft.VisualStudio.Shell.Interop.IVsToolboxUser"/> to redirect to the + /// implementation on an active toolwindow, but the document window needs to know the type of the + /// last diagram for which items were requested by both the document and tool windows. This enables + /// the items to be refreshed when the selection container is switched back and forth between the + /// document window and the tool window toolbox users.</remarks> + public bool UpdateToolboxDiagram(Diagram diagram) + { Type diagramType; if (diagram != null && - (diagramType = diagram.GetType()) != myLastDiagramType) + (diagramType = diagram.GetType()) != myLastToolboxDiagramType) { - myLastDiagramType = diagramType; - IToolboxService toolboxService; - if (this.UpdateToolboxFilters(ToolboxItemFilterType.Diagram, true) && (null != (toolboxService = base.ToolboxService))) - { - toolboxService.Refresh(); - } + myLastToolboxDiagramType = diagramType; + return true; } + return false; } + /// <summary> + /// Helper method to perform toolbox filter refresh. Should only call if <see cref="UpdateToolboxDiagram"/> returns true. + /// </summary> + private void RefreshDiagramToolboxItems() + { + IToolboxService toolboxService; + if (null != (toolboxService = base.ToolboxService)) + { + // We refresh on this request regardless of the response from UpdateToolboxFilters + UpdateToolboxFilters(ToolboxItemFilterType.Diagram, true); + toolboxService.Refresh(); + } + } #endregion // Base Overrides #region Public Properties #region Context Menu support @@ -328,6 +358,33 @@ } } #endregion // ReorderDiagrams method + #region DeactivateMouseActions method + /// <summary> + /// Verify that all mouse actions for the specified <see cref="DiagramView"/> + /// are canceled. Mouse actions are also canceled for the active view on the + /// associated <see cref="Diagram"/>. + /// </summary> + public static void DeactivateMouseActions(DiagramView diagramView) + { + if (diagramView != null) + { + MouseAction mouseAction; + if (null != (mouseAction = diagramView.ActiveMouseAction)) + { + diagramView.ActiveMouseAction = null; + } + Diagram diagram; + DiagramView activeView; + if (null != (diagram = diagramView.Diagram) && + null != (activeView = diagram.ActiveDiagramView) && + activeView != diagramView && + null != (mouseAction = activeView.ActiveMouseAction)) + { + diagramView.ActiveMouseAction = null; + } + } + } + #endregion // DeactivateMouseActions method #region Add methods /// <summary> /// Adds the <see cref="Diagram"/> specified by <paramref name="diagram"/> to this <see cref="MultiDiagramDocView"/>. @@ -573,7 +630,7 @@ if (0 != (reasons & EventSubscriberReasons.DocumentLoaded)) { // Force toolbox refresh on next selection change - myLastDiagramType = null; + myLastToolboxDiagramType = null; // Attach extra properties and events if we're tracking diagram order and position Store store = this.Store; Modified: trunk/ORMModel/Framework/Shell/MultiDiagramDocViewControl.cs =================================================================== --- trunk/ORMModel/Framework/Shell/MultiDiagramDocViewControl.cs 2008-12-17 02:27:45 UTC (rev 1344) +++ trunk/ORMModel/Framework/Shell/MultiDiagramDocViewControl.cs 2008-12-20 03:37:05 UTC (rev 1345) @@ -298,6 +298,10 @@ if (tabPage != null) { tabPage.Focus(); + if (DocView.UpdateToolboxDiagram(((DiagramTabPage)tabPage).Diagram)) + { + DocView.RefreshDiagramToolboxItems(); + } } } #endregion // OnGotFocus method @@ -416,6 +420,26 @@ DocView.SetSelectedComponents(null); } } + protected override void OnSelecting(TabControlCancelEventArgs e) + { + DiagramTabPage tabPage; + if (e.Action == TabControlAction.Selecting && + null != (tabPage = e.TabPage as DiagramTabPage)) + { + DeactivateMouseActions(tabPage.Designer); + } + base.OnSelecting(e); + } + protected override void OnDeselecting(TabControlCancelEventArgs e) + { + DiagramTabPage tabPage; + if (e.Action == TabControlAction.Deselecting && + null != (tabPage = e.TabPage as DiagramTabPage)) + { + DeactivateMouseActions(tabPage.Designer); + } + base.OnDeselecting(e); + } #endregion // OnSelectedIndexChanged method #region IndexOf methods public int IndexOf(DiagramView designer, int startingIndex) Modified: trunk/ORMModel/ShapeModel/ORMDiagram.cs =================================================================== --- trunk/ORMModel/ShapeModel/ORMDiagram.cs 2008-12-17 02:27:45 UTC (rev 1344) +++ trunk/ORMModel/ShapeModel/ORMDiagram.cs 2008-12-20 03:37:05 UTC (rev 1345) @@ -1319,7 +1319,7 @@ // during a chained mouse action cancels the action. // See corresponding code in ExternalConstraintConnectAction.ChainMouseAction and // InternalUniquenessConstraintConnectAction.ChainMouseAction. - (action != null || activeView.Toolbox.GetSelectedToolboxItem() != null)) + (action != null || (activeView != null && activeView.Toolbox.GetSelectedToolboxItem() != null))) { clientView.ActiveMouseAction = action; } Modified: trunk/ORMModel/Shell/ORMDesignerCommandManager.cs =================================================================== --- trunk/ORMModel/Shell/ORMDesignerCommandManager.cs 2008-12-17 02:27:45 UTC (rev 1344) +++ trunk/ORMModel/Shell/ORMDesignerCommandManager.cs 2008-12-20 03:37:05 UTC (rev 1345) @@ -41,6 +41,7 @@ namespace Neumont.Tools.ORM.Shell { + #region IORMDesignerView interface /// <summary> /// An interface representing a container that displays an ORM diagram. /// Abstracting the view enables commands to be handled/ the same for @@ -89,7 +90,246 @@ /// </summary> object PrimarySelection { get;} } + #endregion // IORMDesignerView interface + #region ToolboxFilterSet enum /// <summary> + /// The type of selection filter type to check. Used by <see cref="ToolboxFilterCache.UpdateFilters"/> + /// </summary> + [Flags] + public enum ToolboxFilterSet + { + /// <summary> + /// Update the filters for the currently selected item + /// </summary> + Selection = 1, + /// <summary> + /// Update the filters for the current diagram + /// </summary> + Diagram = 2, + /// <summary> + /// Udpate all filters + /// </summary> + All = Selection | Diagram, + } + #endregion // ToolboxFilterSet enum + #region ToolboxFilterCache class + /// <summary> + /// A class to manage toolbox filters as the selection in a <see cref="IORMDesignerView"/> implementation is modified + /// </summary> + [CLSCompliant(false)] + public class ToolboxFilterCache + { + // Use positive values for diagram items, negative for selection + private Dictionary<object, int> myFilterCache = new Dictionary<object, int>(); + private int myDiagramCookie; + private int mySelectionCookie; + private int myDiagramFilterCount; + private int mySelectionFilterCount; + private object[] myFilterCollection; + /// <summary> + /// Update the current toolbox filters to correspond to the current selection in <paramref name="designerView"/> + /// </summary> + /// <param name="designerView">The current <see cref="IORMDesignerView"/> to populate settings for</param> + /// <param name="filterType">The <see cref="ToolboxFilterSet"/> indicating the set of toolbox items to update</param> + /// <returns><see langword="true"/> if the filter set is changed.</returns> + public bool UpdateFilters(IORMDesignerView designerView, ToolboxFilterSet filterType) + { + Dictionary<object, int> filterCache = myFilterCache; + int diagramCookie = myDiagramCookie; + int selectionCookie = mySelectionCookie; + bool repopulate = false; + + // Check for first pass + if (diagramCookie == 0) + { + diagramCookie = NewDiagramCookie(); + filterType = ToolboxFilterSet.All; + } + if (selectionCookie == 0) + { + selectionCookie = NewSelectionCookie(); + filterType = ToolboxFilterSet.All; + } + + // Update the diagram information + if (0 != (filterType & ToolboxFilterSet.Diagram)) + { + Diagram diagram; + ICollection filters; + if (null != (diagram = designerView.CurrentDiagram) && + null != (filters = diagram.TargetToolboxItemFilterAttributes)) + { + int oldCount = myDiagramFilterCount; + int newCount = 0; + if (oldCount != 0) + { + int oldCookie = diagramCookie; + diagramCookie = NewDiagramCookie(); + foreach (object filter in filters) + { + int testCookie; + if (filterCache.TryGetValue(filter, out testCookie)) + { + filterCache[filter] = diagramCookie; + if (oldCookie != testCookie) + { + // Filter was not included in previous count + repopulate = true; + } + ++newCount; + } + else + { + filterCache[filter] = diagramCookie; + ++newCount; + repopulate = true; + } + } + if (!repopulate && newCount != oldCount) + { + repopulate = true; + } + } + else + { + foreach (object filter in filters) + { + // We updated the cookie when the count was set to zero, no reason to repeat + filterCache[filter] = diagramCookie; + ++newCount; + } + if (newCount != 0) + { + repopulate = true; + } + } + myDiagramFilterCount = newCount; + } + else if (myDiagramFilterCount != 0) + { + diagramCookie = NewDiagramCookie(); + myDiagramFilterCount = 0; + repopulate = true; + } + } + if (0 != (filterType & ToolboxFilterSet.Selection)) + { + IList selectedElements; + ShapeElement selectedShape; + ICollection filters; + if (null != (selectedElements = designerView.SelectedElements) && + 1 == selectedElements.Count && + null != (selectedShape = selectedElements[0] as ShapeElement) && + selectedShape != designerView.CurrentDiagram && + null != (filters = selectedShape.TargetToolboxItemFilterAttributes)) + { + int oldCount = mySelectionFilterCount; + int newCount = 0; + if (oldCount != 0) + { + int oldCookie = selectionCookie; + selectionCookie = NewSelectionCookie(); + foreach (object filter in filters) + { + int testCookie; + if (filterCache.TryGetValue(filter, out testCookie)) + { + filterCache[filter] = selectionCookie; + if (oldCookie != testCookie) + { + // Filter was not included in previous count + repopulate = true; + } + ++newCount; + } + else + { + filterCache[filter] = selectionCookie; + ++newCount; + repopulate = true; + } + } + if (!repopulate && newCount != oldCount) + { + repopulate = true; + } + } + else + { + foreach (object filter in filters) + { + // We updated the cookie when the count was set to zero, no reason to repeat + filterCache[filter] = selectionCookie; + ++newCount; + } + if (newCount != 0) + { + repopulate = true; + } + } + mySelectionFilterCount = newCount; + } + else if (mySelectionFilterCount != 0) + { + selectionCookie = NewSelectionCookie(); + mySelectionFilterCount = 0; + repopulate = true; + } + } + if (repopulate) + { + myFilterCollection = null; + } + return repopulate; + } + /// <summary> + /// Get a collection of all current toolbox filters + /// </summary> + public ICollection ToolboxFilters + { + get + { + object[] filters = myFilterCollection; + if (filters == null) + { + int totalCount = myDiagramFilterCount + mySelectionFilterCount; + myFilterCollection = filters = new object[totalCount]; + if (totalCount != 0) + { + int index = -1; + int diagramCookie = myDiagramCookie; + int selectionCookie = mySelectionCookie; + foreach (KeyValuePair<object, int> pair in myFilterCache) + { + int testValue = pair.Value; + if (testValue == diagramCookie || testValue == selectionCookie) + { + filters[++index] = pair.Key; + } + } + } + } + return filters; + } + } + private int NewDiagramCookie() + { + // Diagram cookies are positive + int cookie = myDiagramCookie; + myDiagramCookie = cookie = (cookie == int.MaxValue) ? 1 : (cookie + 1); + return cookie; + } + private int NewSelectionCookie() + { + // Selection cookies are negative + int cookie = mySelectionCookie; + mySelectionCookie = cookie = (cookie == int.MinValue) ? -11 : (cookie - 1); + return cookie; + } + } + #endregion // ToolboxFilterCache class + #region ORMDesignerCommandManager class + /// <summary> /// Handle command routing for views on the ORM designer /// </summary> [CLSCompliant(false)] @@ -3024,4 +3264,5 @@ } #endregion // Command Handlers } + #endregion // ORMDesignerCommandManager class } Modified: trunk/ORMModel/Shell/ORMDiagramSpy.cs =================================================================== --- trunk/ORMModel/Shell/ORMDiagramSpy.cs 2008-12-17 02:27:45 UTC (rev 1344) +++ trunk/ORMModel/Shell/ORMDiagramSpy.cs 2008-12-20 03:37:05 UTC (rev 1345) @@ -32,6 +32,8 @@ using Microsoft.VisualStudio.Shell.Interop; using Neumont.Tools.Modeling.Shell; using Neumont.Tools.Modeling; +using OLE = Microsoft.VisualStudio.OLE.Interop; +using System.Drawing.Design; namespace Neumont.Tools.ORM.Shell { @@ -41,7 +43,7 @@ /// </summary> [Guid("19A5C15D-14D4-4A88-9891-A3294077BE56")] [CLSCompliant(false)] - public class ORMDiagramSpyWindow : ORMToolWindow, IORMSelectionContainer, IProvideFrameVisibility, IORMDesignerView + public class ORMDiagramSpyWindow : ORMToolWindow, IORMSelectionContainer, IProvideFrameVisibility, IORMDesignerView, IVsToolboxUser { #region Member Variables private ToolWindowDiagramView myDiagramView; @@ -49,6 +51,8 @@ private LinkLabel myWatermarkLabel; private bool myDiagramSetChanged; private bool myDisassociating; + private IToolboxService myToolboxService; + private ToolboxFilterCache myToolboxFilterCache; private Store myStore; #endregion // Member Variables #region Constructor @@ -117,11 +121,13 @@ } if (!reselectOldDiagram) { + MultiDiagramDocView.DeactivateMouseActions(diagram.ActiveDiagramView); diagram.Associate(diagramView); } AdjustVisibility(true, false); if (!calledShow) { + calledShow = true; Show(); } if (reselectOldDiagram && diagramView.Selection.PrimaryItem != null) @@ -133,6 +139,12 @@ { SetSelectedComponents(new object[] { diagram }); } + DiagramClientView clientView; + if (calledShow && + !(clientView = diagramView.DiagramClientView).Focused) + { + clientView.Focus(); + } return true; } } @@ -236,7 +248,7 @@ myDiagramSetChanged = true; if (element == myDiagramView.Diagram) { - // Note that this is unlikely, the diagram will be disassociatin firts + // Note that this is unlikely, the diagram will be disassociated first AdjustVisibility(false, true); } } @@ -250,6 +262,7 @@ myDisassociating = true; try { + MultiDiagramDocView.DeactivateMouseActions(diagramView); diagram.Disassociate(diagramView); } finally @@ -288,16 +301,17 @@ } private void AdjustVisibility(bool diagramVisible, bool deferRebuildWatermark) { + DiagramView diagramView = myDiagramView; if (!diagramVisible) { - DiagramView view = myDiagramView; - Diagram diagram = view.Diagram; + Diagram diagram = diagramView.Diagram; if (diagram != null) { myDisassociating = true; try { - diagram.Disassociate(view); + MultiDiagramDocView.DeactivateMouseActions(diagramView); + diagram.Disassociate(diagramView); } finally { @@ -311,7 +325,7 @@ RebuildWatermark(); } } - myDiagramView.Visible = diagramVisible; + diagramView.Visible = diagramVisible; myWatermarkLabel.Visible = !diagramVisible; } private void RebuildWatermark() @@ -453,7 +467,32 @@ protected override void OnSelectionChanged(EventArgs e) { CommandManager.UpdateCommandStatus(); + UpdateToolbox(); } + /// <summary> + /// Update the toolbox when this window is activated + /// </summary> + protected override void OnORMSelectionContainerChanged() + { + if (CurrentORMSelectionContainer == this) + { + UpdateToolbox(); + } + } + private void UpdateToolbox() + { + MultiDiagramDocView docView; + if (null != (docView = CurrentDocumentView as MultiDiagramDocView) && + docView.UpdateToolboxDiagram(CurrentDiagram)) + { + IToolboxService toolboxService; + if (null != (toolboxService = ToolboxService)) + { + ToolboxFilterManager.UpdateFilters(this, ToolboxFilterSet.Diagram); + toolboxService.Refresh(); + } + } + } #endregion //ORMToolWindow overrides #region IORMDesignerView Implementation /// <summary> @@ -668,5 +707,68 @@ this.MenuService.ShowContextMenu(contextMenuId, pt.X, pt.Y); } #endregion // ContextMenu + #region IVsToolboxUser Implementation + /// <summary> + /// Get the <see cref="IToolboxService"/> for this object + /// </summary> + protected IToolboxService ToolboxService + { + get + { + return myToolboxService ?? (myToolboxService = (IToolboxService)ExternalServiceProvider.GetService(typeof(IToolboxService))); + } + } + /// <summary> + /// Get the <see cref="ToolboxFilterManager"/> for this window + /// </summary> + protected ToolboxFilterCache ToolboxFilterManager + { + get + { + ToolboxFilterCache retVal = myToolboxFilterCache; + if (retVal == null) + { + myToolboxFilterCache = retVal = new ToolboxFilterCache(); + retVal.UpdateFilters(this, ToolboxFilterSet.All); + } + return retVal; + } + } + /// <summary> + /// Implements <see cref="IVsToolboxUser.IsSupported"/> + /// </summary> + protected int IsSupported(OLE.IDataObject pDO) + { + IDataObject data = pDO as IDataObject; + if (data == null) + { + data = new DataObject(pDO); + } + IToolboxService toolboxService; + if (null != (toolboxService = ToolboxService)) + { + if (toolboxService.IsSupported(data, ToolboxFilterManager.ToolboxFilters)) + { + return VSConstants.S_OK; + } + } + return VSConstants.E_FAIL; + } + int IVsToolboxUser.IsSupported(OLE.IDataObject pDO) + { + return IsSupported(pDO); + } + /// <summary> + /// Implements <see cref="IVsToolboxUser.ItemPicked"/> + /// </summary> + protected static int ItemPicked(OLE.IDataObject pDO) + { + return VSConstants.S_OK; + } + int IVsToolboxUser.ItemPicked(OLE.IDataObject pDO) + { + return ItemPicked(pDO); + } + #endregion // IVsToolboxUser Implementation } } Modified: trunk/ORMModel/Shell/ORMDocData.cs =================================================================== --- trunk/ORMModel/Shell/ORMDocData.cs 2008-12-17 02:27:45 UTC (rev 1344) +++ trunk/ORMModel/Shell/ORMDocData.cs 2008-12-20 03:37:05 UTC (rev 1345) @@ -202,13 +202,13 @@ if (isReload) { - this.RemoveModelingEventHandlers(isReload); - // Null out the myPropertyProviderService and myTypedDomainModelProviderCache fields // so that a new instance will be created with the new Store next time it is needed this.myPropertyProviderService = null; this.myTypedDomainModelProviderCache = null; + this.RemoveModelingEventHandlers(isReload); + foreach (ModelingDocView view in DocViews) { MultiDiagramDocView multiDiagramDocView = view as MultiDiagramDocView; Modified: trunk/ORMModel/Shell/ORMDocDataServices.cs =================================================================== --- trunk/ORMModel/Shell/ORMDocDataServices.cs 2008-12-17 02:27:45 UTC (rev 1344) +++ trunk/ORMModel/Shell/ORMDocDataServices.cs 2008-12-20 03:37:05 UTC (rev 1345) @@ -1065,7 +1065,19 @@ { get { - return myPropertyProviderService ?? (myPropertyProviderService = new PropertyProviderService(Store)); + // Defensively verify store state + PropertyProviderService providers = myPropertyProviderService as PropertyProviderService; + Store store = Store; + if (providers == null || providers.Store != store) + { + if (store.ShuttingDown || store.Disposed) + { + myPropertyProviderService = null; + return null; + } + myPropertyProviderService = providers = new PropertyProviderService(store); + } + return providers; } } IPropertyProviderService IFrameworkServices.PropertyProviderService @@ -1081,10 +1093,17 @@ /// </summary> protected T[] GetTypedDomainModelProviders<T>() where T : class { + // Defensively verify store state TypedDomainModelProviderCache cache = myTypedDomainModelProviderCache; - if (cache == null) + Store store = Store; + if (cache == null || cache.Store != store) { - myTypedDomainModelProviderCache = cache = new TypedDomainModelProviderCache(Store); + if (store.ShuttingDown || store.Disposed) + { + myTypedDomainModelProviderCache = null; + return null; + } + myTypedDomainModelProviderCache = cache = new TypedDomainModelProviderCache(store); } return cache.GetTypedDomainModelProviders<T>(); } Modified: trunk/ORMModel/Shell/ORMDocView.cs =================================================================== --- trunk/ORMModel/Shell/ORMDocView.cs 2008-12-17 02:27:45 UTC (rev 1344) +++ trunk/ORMModel/Shell/ORMDocView.cs 2008-12-20 03:37:05 UTC (rev 1345) @@ -31,6 +31,7 @@ using Neumont.Tools.ORM.ObjectModel; using Neumont.Tools.ORM.ShapeModel; using Neumont.Tools.Modeling; +using Microsoft.VisualStudio.Shell.Interop; namespace Neumont.Tools.ORM.Shell { @@ -266,10 +267,11 @@ /// <see cref="DiagramDocView"/> designed to contain multiple <see cref="ORMDiagram"/>s. /// </summary> [CLSCompliant(false)] - public partial class ORMDesignerDocView : MultiDiagramDocView, IORMSelectionContainer, IORMDesignerView, IModelingEventSubscriber + public partial class ORMDesignerDocView : MultiDiagramDocView, IORMSelectionContainer, IORMDesignerView, IModelingEventSubscriber, IVsToolboxUser { #region Member variables private IServiceProvider myCtorServiceProvider; + private IMonitorSelectionService myMonitorSelectionService; private ORMDesignerCommandManager myCommandManager; #endregion // Member variables #region Construction/destruction @@ -819,6 +821,16 @@ } }); } + /// <summary> + /// Get the selection service for this designer + /// </summary> + protected IMonitorSelectionService MonitorSelection + { + get + { + return myMonitorSelectionService ?? (myMonitorSelectionService = (IMonitorSelectionService)myCtorServiceProvider.GetService(typeof(IMonitorSelectionService))); + } + } #endregion // ORMDesignerDocView Specific #region IORMDesignerView Implementation /// <summary> @@ -860,5 +872,39 @@ } } #endregion // IORMDesignerView Implementation + #region IVsToolboxUser Toolwindow Redirection + int IVsToolboxUser.IsSupported(Microsoft.VisualStudio.OLE.Interop.IDataObject pDO) + { + // Redirect toolbox queries to supporting tool windows if the document is not the + // active selection container. + object selectionContainer = MonitorSelection.CurrentSelectionContainer; + IVsToolboxUser redirectUser; + IORMDesignerView designerView; + if (selectionContainer != this && + null != (redirectUser = selectionContainer as IVsToolboxUser) && + null != (designerView = selectionContainer as IORMDesignerView) && + null != designerView.CurrentDiagram) + { + return redirectUser.IsSupported(pDO); + } + return IsSupported(pDO); + } + int IVsToolboxUser.ItemPicked(Microsoft.VisualStudio.OLE.Interop.IDataObject pDO) + { + // Redirect toolbox queries to supporting tool windows if the document is not the + // active selection container. + object selectionContainer = MonitorSelection.CurrentSelectionContainer; + IVsToolboxUser redirectUser; + IORMDesignerView designerView; + if (selectionContainer != this && + null != (redirectUser = selectionContainer as IVsToolboxUser) && + null != (designerView = selectionContainer as IORMDesignerView) && + null != designerView.CurrentDiagram) + { + return redirectUser.ItemPicked(pDO); + } + return ItemPicked(pDO); + } + #endregion // IVsToolboxUser Toolwindow Redirection } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2009-01-08 22:49:00
|
Revision: 1350 http://orm.svn.sourceforge.net/orm/?rev=1350&view=rev Author: mcurland Date: 2009-01-08 22:48:55 +0000 (Thu, 08 Jan 2009) Log Message: ----------- Duplicate constraint names are blocking file load with a null reference exception. This fixes a bug introduced in [1343]. Most duplicate constraint names can be fixed by double-clicking on them and clearing the name, which will regenerate. However, duplicate names for some implied constraints cannot be selected and require an XML edit to fix (find the name on an element, delete the contents of the Name attribute (leave Name=""), save, and reload). Duplicate generated names will be automatically fixed in a future changeset. refs #383 Modified Paths: -------------- trunk/ORMModel/ObjectModel/ORMModel.cs trunk/ORMModel/ObjectModel/ORMModel.resx trunk/ORMModel/Resources/ResourceStringsGenerator.cs trunk/ORMModel/Resources/ResourceStringsGenerator.xml Modified: trunk/ORMModel/ObjectModel/ORMModel.cs =================================================================== --- trunk/ORMModel/ObjectModel/ORMModel.cs 2009-01-01 04:29:35 UTC (rev 1349) +++ trunk/ORMModel/ObjectModel/ORMModel.cs 2009-01-08 22:48:55 UTC (rev 1350) @@ -2055,6 +2055,7 @@ [ModelErrorDisplayFilter(typeof(NameErrorCategory))] public partial class ConstraintDuplicateNameError : DuplicateNameError, IHasIndirectModelErrorOwner { + #region Base overrides /// <summary> /// Get the duplicate elements represented by this DuplicateNameError /// </summary> @@ -2063,7 +2064,7 @@ { get { - return ConstraintCollection as IList<ModelElement>; + return ConstraintCollection; } } /// <summary> @@ -2085,6 +2086,7 @@ return ResourceStrings.ModelErrorModelHasDuplicateConstraintNames; } } + #endregion // Base overrides #region ConstraintCollection Implementation [NonSerialized] private CompositeCollection myCompositeList; @@ -2093,14 +2095,14 @@ /// single column external, multi column external, internal constraints, and value constraints /// </summary> /// <value></value> - public IList<ORMNamedElement> ConstraintCollection + public IList<ModelElement> ConstraintCollection { get { return myCompositeList ?? (myCompositeList = new CompositeCollection(this)); } } - private sealed class CompositeCollection : IList<ORMNamedElement> + private sealed class CompositeCollection : IList<ModelElement> { #region Member Variables private readonly LinkedElementCollection<SetComparisonConstraint> myList1; @@ -2115,8 +2117,8 @@ myList3 = error.ValueConstraintCollection; } #endregion // Constructors - #region IList<ORMNamedElement> Implementation - int IList<ORMNamedElement>.IndexOf(ORMNamedElement value) + #region IList<ModelElement> Implementation + int IList<ModelElement>.IndexOf(ModelElement value) { SetComparisonConstraint setComparisonConstraint; SetConstraint setConstraint; @@ -2135,7 +2137,7 @@ } return -1; } - ORMNamedElement IList<ORMNamedElement>.this[int index] + ModelElement IList<ModelElement>.this[int index] { get { @@ -2144,7 +2146,7 @@ { index -= list1Count; int list2Count = myList2.Count; - return (index >= list2Count) ? (ORMNamedElement)myList3[index - list2Count] : myList2[index]; + return (index >= list2Count) ? (ModelElement)myList3[index - list2Count] : myList2[index]; } return myList1[index]; } @@ -2153,17 +2155,17 @@ throw new NotSupportedException(); // Not supported for readonly list } } - void IList<ORMNamedElement>.Insert(int index, ORMNamedElement value) + void IList<ModelElement>.Insert(int index, ModelElement value) { throw new NotSupportedException(); // Not supported for readonly list } - void IList<ORMNamedElement>.RemoveAt(int index) + void IList<ModelElement>.RemoveAt(int index) { throw new NotSupportedException(); // Not supported for readonly list } - #endregion // IList<ORMNamedElement> Implementation - #region ICollection<ORMNamedElement> Implementation - void ICollection<ORMNamedElement>.CopyTo(ORMNamedElement[] array, int index) + #endregion // IList<ModelElement> Implementation + #region ICollection<ModelElement> Implementation + void ICollection<ModelElement>.CopyTo(ModelElement[] array, int index) { int baseIndex = index; int nextCount = myList1.Count; @@ -2184,14 +2186,14 @@ ((ICollection)myList3).CopyTo(array, baseIndex); } } - int ICollection<ORMNamedElement>.Count + int ICollection<ModelElement>.Count { get { return myList1.Count + myList2.Count + myList3.Count; } } - bool ICollection<ORMNamedElement>.Contains(ORMNamedElement value) + bool ICollection<ModelElement>.Contains(ModelElement value) { SetComparisonConstraint setComparisonConstraint; SetConstraint setConstraint; @@ -2210,47 +2212,47 @@ } return false; } - bool ICollection<ORMNamedElement>.IsReadOnly + bool ICollection<ModelElement>.IsReadOnly { get { return true; } } - void ICollection<ORMNamedElement>.Add(ORMNamedElement value) + void ICollection<ModelElement>.Add(ModelElement value) { throw new NotSupportedException(); // Not supported for readonly list } - void ICollection<ORMNamedElement>.Clear() + void ICollection<ModelElement>.Clear() { throw new NotSupportedException(); // Not supported for readonly list } - bool ICollection<ORMNamedElement>.Remove(ORMNamedElement value) + bool ICollection<ModelElement>.Remove(ModelElement value) { throw new NotSupportedException(); // Not supported for readonly list } - #endregion // ICollection<ORMNamedElement> Implementation - #region IEnumerable<ORMNamedElement> Implementation - IEnumerator<ORMNamedElement> IEnumerable<ORMNamedElement>.GetEnumerator() + #endregion // ICollection<ModelElement> Implementation + #region IEnumerable<ModelElement> Implementation + IEnumerator<ModelElement> IEnumerable<ModelElement>.GetEnumerator() { - foreach (ORMNamedElement element in myList1) + foreach (ModelElement element in myList1) { yield return element; } - foreach (ORMNamedElement element in myList2) + foreach (ModelElement element in myList2) { yield return element; } - foreach (ORMNamedElement element in myList3) + foreach (ModelElement element in myList3) { yield return element; } } - #endregion // IEnumerable<ORMNamedElement> Implementation + #endregion // IEnumerable<ModelElement> Implementation #region IEnumerable Implementation IEnumerator IEnumerable.GetEnumerator() { - return ((IEnumerable<ORMNamedElement>)this).GetEnumerator(); + return ((IEnumerable<ModelElement>)this).GetEnumerator(); } #endregion // IEnumerable Implementation } @@ -2288,7 +2290,10 @@ /// </summary> protected override IList<ModelElement> DuplicateElements { - get { return RecognizedPhraseCollection.ToArray(); } + get + { + return RecognizedPhraseCollection.ToArray(); + } } /// <summary> /// Provide an efficient name lookup @@ -2300,12 +2305,13 @@ /// <summary> /// Text to be displayed when an error is thrown. ///</summary> - //TODO: Add this to the ResourceStrings collection protected override string ErrorFormatText { - get { return "Duplicate recognized word exists in the model."; } + get + { + return ResourceStrings.ModelErrorModelHasDuplicateRecognizedPhraseNames; + } } - #region IHasIndirectModelErrorOwner Implementation private static Guid[] myIndirectModelErrorOwnerLinkRoles; /// <summary> Modified: trunk/ORMModel/ObjectModel/ORMModel.resx =================================================================== --- trunk/ORMModel/ObjectModel/ORMModel.resx 2009-01-01 04:29:35 UTC (rev 1349) +++ trunk/ORMModel/ObjectModel/ORMModel.resx 2009-01-08 22:48:55 UTC (rev 1350) @@ -306,6 +306,10 @@ <value>Model '{0}' contains multiple object types named '{1}'. Type names must be unique across all entity and value types in a model.</value> <comment>Model validation error text used when multiple object types with the same name are loaded into a model.Field 0 is the model name, field 1 is the element name.This is an uncommon condition that should only occur with a hand edit to a model file.</comment> </data> + <data name="ModelError.Model.DuplicateRecognizedPhraseNames.Text" xml:space="preserve"> + <value>Model '{0}' contains multiple recognized phrases called '{1}'. Phrase names must be unique across all phrases in a model.</value> + <comment>Model validation error text used when multiple recognized phrases with the same name are loaded into a model.Field 0 is the model name, field 1 is the element name.This is an uncommon condition that should only occur with a hand edit to a model file.</comment> + </data> <data name="ModelError.Model.PopulationMandatoryError.Text" xml:space="preserve"> <value>'{0}' instance '{1}' in model '{2}' must participate in FactType '{3}'{4}.</value> <comment>Model validation error shown when a population violates a mandatory constraint. Field 0 is the name of the role player, field 1 is the derived name of the instance, field 2 is the model name, field 3 is the name of the first facttype name, field 4 is a placeholder for additional fact types.</comment> Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.cs =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2009-01-01 04:29:35 UTC (rev 1349) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2009-01-08 22:48:55 UTC (rev 1350) @@ -925,6 +925,14 @@ return ResourceStrings.GetString(ResourceManagers.Model, "ModelError.Model.DuplicateObjectTypeNames.Text"); } } + /// <summary>Model validation error text used when multiple recognized phrases with the same name are loaded into a model.Field 0 is the model name, field 1 is the element name.This is an uncommon condition that should only occur with a hand edit to a model file.</summary> + public static string ModelErrorModelHasDuplicateRecognizedPhraseNames + { + get + { + return ResourceStrings.GetString(ResourceManagers.Model, "ModelError.Model.DuplicateRecognizedPhraseNames.Text"); + } + } /// <summary>Model validation error shown when a population violates a uniqueness constraint and its role is named. Field 0 is the name of the object type, field 1 is the string representation of the instance, field 2 is the model name, field 3 is the role name.</summary> public static string ModelErrorModelHasPopulationUniquenessErrorWithNamedRole { Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.xml =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2009-01-01 04:29:35 UTC (rev 1349) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2009-01-08 22:48:55 UTC (rev 1350) @@ -163,6 +163,7 @@ <ResourceString name="ModelErrorConstraintExternalConstraintArityMismatch" model="Model" resourceName="ModelError.Constraint.ExternalConstraintArityMismatch.Text"/> <ResourceString name="ModelErrorModelHasDuplicateConstraintNames" model="Model" resourceName="ModelError.Model.DuplicateConstraintNames.Text"/> <ResourceString name="ModelErrorModelHasDuplicateObjectTypeNames" model="Model" resourceName="ModelError.Model.DuplicateObjectTypeNames.Text"/> + <ResourceString name="ModelErrorModelHasDuplicateRecognizedPhraseNames" model="Model" resourceName="ModelError.Model.DuplicateRecognizedPhraseNames.Text"/> <ResourceString name="ModelErrorModelHasPopulationUniquenessErrorWithNamedRole" model="Model" resourceName="ModelError.Model.PopulationUniquenessError.Role.Text"/> <ResourceString name="ModelErrorModelHasPopulationUniquenessErrorWithUnnamedRole" model="Model" resourceName="ModelError.Model.PopulationUniquenessError.FactType.Text"/> <ResourceString name="ModelErrorModelHasPopulationMandatoryError" model="Model" resourceName="ModelError.Model.PopulationMandatoryError.Text"/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2009-01-15 22:56:50
|
Revision: 1352 http://orm.svn.sourceforge.net/orm/?rev=1352&view=rev Author: mcurland Date: 2009-01-15 21:59:26 +0000 (Thu, 15 Jan 2009) Log Message: ----------- Restore objectified FactType name quotes inadvertently lost for some cases in [1328]. Apparently no one noticed they've been missing for the last two public drops. refs #375 Modified Paths: -------------- trunk/ORMModel/Resources/ResourceStringsGenerator.cs trunk/ORMModel/Resources/ResourceStringsGenerator.xml trunk/ORMModel/ShapeModel/FactTypeShape.cs trunk/ORMModel/ShapeModel/ORMDiagram.resx Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.cs =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2009-01-15 00:26:23 UTC (rev 1351) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2009-01-15 21:59:26 UTC (rev 1352) @@ -2365,6 +2365,22 @@ return ResourceStrings.GetString(ResourceManagers.Diagram, "ObjectTypeShape.ReferenceModeFormatString"); } } + /// <summary>The string used to display an objectified type that is a derived subtype.</summary> + public static string ObjectifiedFactTypeNameShapeDerivedSubtypeFormatString + { + get + { + return ResourceStrings.GetString(ResourceManagers.Diagram, "ObjectifiedFactTypeNameShape.DerivedSubtypeFormatString"); + } + } + /// <summary>The string used to display an objectified type name for an independent object.</summary> + public static string ObjectifiedFactTypeNameShapeIndependentFormatString + { + get + { + return ResourceStrings.GetString(ResourceManagers.Diagram, "ObjectifiedFactTypeNameShape.IndependentFormatString"); + } + } /// <summary>The string used to display an objectified type name for an derived subtype with a reference mode.</summary> public static string ObjectifiedFactTypeNameShapeRefModeDerivedSubtypeFormatString { @@ -2389,6 +2405,14 @@ return ResourceStrings.GetString(ResourceManagers.Diagram, "ObjectifiedFactTypeNameShape.RefModeFormatString"); } } + /// <summary>The string used to display an objectified type name.</summary> + public static string ObjectifiedFactTypeNameShapeStandardFormatString + { + get + { + return ResourceStrings.GetString(ResourceManagers.Diagram, "ObjectifiedFactTypeNameShape.StandardFormatString"); + } + } /// <summary>The string used to divide multiple readings shown in a ReadingShape.</summary> public static string ReadingShapeReadingSeparator { Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.xml =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2009-01-15 00:26:23 UTC (rev 1351) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2009-01-15 21:59:26 UTC (rev 1352) @@ -343,9 +343,12 @@ <ResourceString name="ObjectTypeShapeDerivedSubtypeFormatString" model="Diagram" resourceName="ObjectTypeShape.DerivedSubtypeFormatString"/> <ResourceString name="ObjectTypeShapeIndependentFormatString" model="Diagram" resourceName="ObjectTypeShape.IndependentFormatString"/> <ResourceString name="ObjectTypeShapeReferenceModeFormatString" model="Diagram" resourceName="ObjectTypeShape.ReferenceModeFormatString"/> + <ResourceString name="ObjectifiedFactTypeNameShapeDerivedSubtypeFormatString" model="Diagram" resourceName="ObjectifiedFactTypeNameShape.DerivedSubtypeFormatString"/> + <ResourceString name="ObjectifiedFactTypeNameShapeIndependentFormatString" model="Diagram" resourceName="ObjectifiedFactTypeNameShape.IndependentFormatString"/> <ResourceString name="ObjectifiedFactTypeNameShapeRefModeDerivedSubtypeFormatString" model="Diagram" resourceName="ObjectifiedFactTypeNameShape.RefModeDerivedSubtypeFormatString"/> <ResourceString name="ObjectifiedFactTypeNameShapeRefModeIndependentFormatString" model="Diagram" resourceName="ObjectifiedFactTypeNameShape.RefModeIndependentFormatString"/> <ResourceString name="ObjectifiedFactTypeNameShapeRefModeFormatString" model="Diagram" resourceName="ObjectifiedFactTypeNameShape.RefModeFormatString"/> + <ResourceString name="ObjectifiedFactTypeNameShapeStandardFormatString" model="Diagram" resourceName="ObjectifiedFactTypeNameShape.StandardFormatString"/> <ResourceString name="ReadingShapeReadingSeparator" model="Diagram" resourceName="ReadingShape.ReadingSeparator"/> <ResourceString name="ReadingShapeEllipsis" model="Diagram" resourceName="ReadingShape.Ellipsis"/> <ResourceString name="ReadingShapeAttachedRoleDisplay" model="Diagram" resourceName="ReadingShape.AttachedRoleDisplay"/> Modified: trunk/ORMModel/ShapeModel/FactTypeShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/FactTypeShape.cs 2009-01-15 00:26:23 UTC (rev 1351) +++ trunk/ORMModel/ShapeModel/FactTypeShape.cs 2009-01-15 21:59:26 UTC (rev 1352) @@ -5698,12 +5698,16 @@ } else if (independent) { - formatString = ResourceStrings.ObjectTypeShapeIndependentFormatString; + formatString = ResourceStrings.ObjectifiedFactTypeNameShapeIndependentFormatString; } else if (derived) { - formatString = ResourceStrings.ObjectTypeShapeIndependentFormatString; + formatString = ResourceStrings.ObjectifiedFactTypeNameShapeDerivedSubtypeFormatString; } + else + { + formatString = ResourceStrings.ObjectifiedFactTypeNameShapeStandardFormatString; + } } return (formatString == null) ? baseText : string.Format(CultureInfo.InvariantCulture, formatString, baseText, refModeString); } Modified: trunk/ORMModel/ShapeModel/ORMDiagram.resx =================================================================== --- trunk/ORMModel/ShapeModel/ORMDiagram.resx 2009-01-15 00:26:23 UTC (rev 1351) +++ trunk/ORMModel/ShapeModel/ORMDiagram.resx 2009-01-15 21:59:26 UTC (rev 1352) @@ -563,6 +563,14 @@ <value xml:space="preserve">({0})</value> <comment xml:space="preserve">The string used to display a reference mode.</comment> </data> + <data name="ObjectifiedFactTypeNameShape.DerivedSubtypeFormatString"> + <value xml:space="preserve">"{0} *"</value> + <comment xml:space="preserve">The string used to display an objectified type that is a derived subtype.</comment> + </data> + <data name="ObjectifiedFactTypeNameShape.IndependentFormatString"> + <value xml:space="preserve">"{0} !"</value> + <comment xml:space="preserve">The string used to display an objectified type name for an independent object.</comment> + </data> <data name="ObjectifiedFactTypeNameShape.RefModeDerivedSubtypeFormatString"> <value xml:space="preserve">"{0} ({1})*"</value> <comment xml:space="preserve">The string used to display an objectified type name for an derived subtype with a reference mode.</comment> @@ -575,6 +583,10 @@ <value xml:space="preserve">"{0} ({1})"</value> <comment xml:space="preserve">The string used to display an objectified type name for an object with a reference mode.</comment> </data> + <data name="ObjectifiedFactTypeNameShape.StandardFormatString"> + <value xml:space="preserve">"{0}"</value> + <comment xml:space="preserve">The string used to display an objectified type name.</comment> + </data> <data name="ObjectifyFactType.TransactionName"> <value xml:space="preserve">Objectify Fact Type</value> <comment xml:space="preserve">The name given to the transaction used when objectifying a fact type.</comment> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2009-03-04 00:10:36
|
Revision: 1363 http://orm.svn.sourceforge.net/orm/?rev=1363&view=rev Author: mcurland Date: 2009-03-04 00:10:35 +0000 (Wed, 04 Mar 2009) Log Message: ----------- A couple of fixes for [1162]. refs #387 * Deleting one reference from the model browser lost track of remaining reference nodes * Population of the 'delete from group' did not correctly break out of the inner loop Modified Paths: -------------- trunk/ORMModel/Framework/Shell/DynamicSurveyTreeGrid/SurveyClasses.cs trunk/ORMModel/Shell/ORMDesignerCommandManager.cs Modified: trunk/ORMModel/Framework/Shell/DynamicSurveyTreeGrid/SurveyClasses.cs =================================================================== --- trunk/ORMModel/Framework/Shell/DynamicSurveyTreeGrid/SurveyClasses.cs 2009-02-27 21:44:05 UTC (rev 1362) +++ trunk/ORMModel/Framework/Shell/DynamicSurveyTreeGrid/SurveyClasses.cs 2009-03-04 00:10:35 UTC (rev 1363) @@ -602,6 +602,7 @@ myReferenceDictionary.TryGetValue(element, out headLinkNode)) { LinkedNode<SurveyNodeReference> linkNode = headLinkNode; + LinkedNode<SurveyNodeReference> startHeadLinkNode = headLinkNode; while (linkNode != null) { SurveyNodeReference link = linkNode.Value; @@ -628,6 +629,10 @@ } } } + else if (startHeadLinkNode != headLinkNode) + { + myReferenceDictionary[element] = headLinkNode; + } } } void INotifySurveyElementChanged.ElementReferenceDeleted(object element, object referenceReason, object contextElement) Modified: trunk/ORMModel/Shell/ORMDesignerCommandManager.cs =================================================================== --- trunk/ORMModel/Shell/ORMDesignerCommandManager.cs 2009-02-27 21:44:05 UTC (rev 1362) +++ trunk/ORMModel/Shell/ORMDesignerCommandManager.cs 2009-03-04 00:10:35 UTC (rev 1363) @@ -1460,14 +1460,23 @@ ElementGrouping grouping = groupings[i]; for (int j = 0; j < selectedElementCount; ++j) { + bool allowGroupDeletion; switch (grouping.GetMembershipType(normalizedElements[j])) { case GroupingMembershipType.Inclusion: case GroupingMembershipType.Contradiction: - cachedGroupings[allowedGroupingCount] = grouping; - ++allowedGroupingCount; + allowGroupDeletion = true; break; + default: + allowGroupDeletion = false; + break; } + if (allowGroupDeletion) + { + cachedGroupings[allowedGroupingCount] = grouping; + ++allowedGroupingCount; + break; + } } } if (allowedGroupingCount < groupingCount) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2009-03-31 19:25:21
|
Revision: 1375 http://orm.svn.sourceforge.net/orm/?rev=1375&view=rev Author: mcurland Date: 2009-03-31 19:25:05 +0000 (Tue, 31 Mar 2009) Log Message: ----------- Name alias resolution choosing a less-refined name, depending on the alias entry order. refs #338 Also moved the 'Reverse Role Order' command to the top of the Orientation submenu, and gave the MoveRoleLeft/MoveRoleRight commands that display with a role selection the same dynamic 'Reverse Role Order' name instead of 'Swap Role Order' for a binary FactType. Modified Paths: -------------- trunk/ORMModel/ObjectModel/NameGenerator.cs trunk/ORMModel/ShapeModel/ORMDiagram.resx trunk/ORMModel/Shell/PackageResources/PkgCmd.vsct Modified: trunk/ORMModel/ObjectModel/NameGenerator.cs =================================================================== --- trunk/ORMModel/ObjectModel/NameGenerator.cs 2009-03-28 17:45:34 UTC (rev 1374) +++ trunk/ORMModel/ObjectModel/NameGenerator.cs 2009-03-31 19:25:05 UTC (rev 1375) @@ -398,32 +398,35 @@ /// <summary> /// Retrieve the best matching alias for the provided set of aliases /// </summary> + /// <remarks>If an exact type/usage match is not available, then this will + /// return the closest usage match over the closest type match. The closest + /// matches are determined by walking up the parent hierarchy of name generators.</remarks> /// <param name="aliases">A set of alias elements. The best match is returned.</param> /// <returns>A <see cref="NameAlias"/>, or <see langword="null"/> if none is available.</returns> public NameAlias FindMatchingAlias(IEnumerable<NameAlias> aliases) { - NameAlias bestMatch = null; + NameAlias bestUsageMatch = null; + NameAlias bestTypeMatch = null; Type usageType = NameUsageType; DomainClassInfo thisClassInfo = GetDomainClass(); - DomainClassInfo matchedClassInfo = null; - bool matchedUsageType = false; - int closestDistance = int.MaxValue; + int closestTypeDistance = int.MaxValue; + int closestUsageDistance = int.MaxValue; foreach (NameAlias alias in aliases) { DomainClassInfo testClassInfo = alias.NameConsumerDomainClass; Type testUsageType = alias.NameUsageType; if (testClassInfo == thisClassInfo) { - if (usageType == testUsageType) + if (usageType == testUsageType) // intentionally handles two null values { - bestMatch = alias; + bestUsageMatch = alias; break; } else if (usageType != null && testUsageType == null) { - matchedClassInfo = testClassInfo; - bestMatch = alias; - // Keep going to see if we get an exact usage match + closestTypeDistance = 0; // Matched self, can't get any closer + bestTypeMatch = alias; + // Keep going to see if we get a higher priority usage match } } else @@ -435,30 +438,21 @@ ++testDistance; if (iterateClassInfo == testClassInfo) { - if (testDistance <= closestDistance) + if (usageType == testUsageType) // intentionally handles two null values { - if (testClassInfo == matchedClassInfo) + if (testDistance < closestUsageDistance) { - if (!matchedUsageType) - { - bestMatch = alias; - matchedUsageType = usageType == testUsageType; - } + closestUsageDistance = testDistance; + bestUsageMatch = alias; } - else if (usageType == testUsageType) + } + else if (usageType != null && testUsageType == null) + { + if (testDistance < closestTypeDistance) { - closestDistance = testDistance; - matchedClassInfo = testClassInfo; - matchedUsageType = true; - bestMatch = alias; + closestTypeDistance = testDistance; + bestTypeMatch = alias; } - else if (usageType != null && testUsageType == null) - { - closestDistance = testDistance; - matchedClassInfo = testClassInfo; - matchedUsageType = false; - bestMatch = alias; - } } break; } @@ -466,7 +460,7 @@ } while (iterateClassInfo != null); } } - return bestMatch; + return bestUsageMatch ?? bestTypeMatch; } #endregion // GetGeneratorSettings } Modified: trunk/ORMModel/ShapeModel/ORMDiagram.resx =================================================================== --- trunk/ORMModel/ShapeModel/ORMDiagram.resx 2009-03-28 17:45:34 UTC (rev 1374) +++ trunk/ORMModel/ShapeModel/ORMDiagram.resx 2009-03-31 19:25:05 UTC (rev 1375) @@ -212,7 +212,7 @@ <comment xml:space="preserve">This text appears on the 'Select on Diagram' menu if there is more than one shape for the selected element on the current diagram.</comment> </data> <data name="Command.SwapRoleOrder.Text"> - <value xml:space="preserve">S&wap Role Order</value> + <value xml:space="preserve">Re&verse Role Order</value> <comment xml:space="preserve">This text appears on the move role left/right when the fact type is binary.</comment> </data> <data name="ConstraintDisplayPosition.Bottom" xml:space="preserve"> Modified: trunk/ORMModel/Shell/PackageResources/PkgCmd.vsct =================================================================== --- trunk/ORMModel/Shell/PackageResources/PkgCmd.vsct 2009-03-28 17:45:34 UTC (rev 1374) +++ trunk/ORMModel/Shell/PackageResources/PkgCmd.vsct 2009-03-31 19:25:05 UTC (rev 1375) @@ -207,13 +207,13 @@ <Parent guid="guidORMDesignerCommandSet" id="menuIdReportGeneratorList"/> </Group> - <Group guid="guidORMDesignerCommandSet" id="groupIdDisplayOrientation" priority="0x0010"> + <Group guid="guidORMDesignerCommandSet" id="groupIdDisplayReverseRoleOrder" priority="0x0010"> <Parent guid="guidORMDesignerCommandSet" id="menuIdDisplayOrientation"/> </Group> - <Group guid="guidORMDesignerCommandSet" id="groupIdDisplayConstraintPosition" priority="0x0020"> + <Group guid="guidORMDesignerCommandSet" id="groupIdDisplayOrientation" priority="0x0020"> <Parent guid="guidORMDesignerCommandSet" id="menuIdDisplayOrientation"/> </Group> - <Group guid="guidORMDesignerCommandSet" id="groupIdDisplayReverseRoleOrder" priority="0x0030"> + <Group guid="guidORMDesignerCommandSet" id="groupIdDisplayConstraintPosition" priority="0x0030"> <Parent guid="guidORMDesignerCommandSet" id="menuIdDisplayOrientation"/> </Group> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2009-04-03 17:21:44
|
Revision: 1377 http://orm.svn.sourceforge.net/orm/?rev=1377&view=rev Author: mcurland Date: 2009-04-03 17:21:34 +0000 (Fri, 03 Apr 2009) Log Message: ----------- * Enable conditional serialization of top-level link elements. refs #329 * Hyphen binding incorrectly bound a hyphen directly to a replacement field on its left. A reading of the form 'A- B' would lead to incorrect verbalization, and crashes or unsaveable files with the relational extension turned on. refs #263 * Fixed FactEditor activation issue (opening the window did not respect the current selection). Fixed by flagging a tool window as visible before setting the selection container during the activation sequence. Modified Paths: -------------- trunk/ORMModel/Framework/Shell/SerializationEngine.cs trunk/ORMModel/Framework/Shell/ToolWindowActivator.cs trunk/ORMModel/ObjectModel/Verbalization.cs trunk/ORMModel/Transforms/SerializationExtensions.xsd trunk/ORMModel/Transforms/SerializationExtensions.xslt Modified: trunk/ORMModel/Framework/Shell/SerializationEngine.cs =================================================================== --- trunk/ORMModel/Framework/Shell/SerializationEngine.cs 2009-04-01 01:49:40 UTC (rev 1376) +++ trunk/ORMModel/Framework/Shell/SerializationEngine.cs 2009-04-03 17:21:34 UTC (rev 1377) @@ -2884,26 +2884,41 @@ for (int k = 0; k < linkCount; ++k) { ElementLink link = relationshipElements[k] as ElementLink; - if (relationship.IsPrimaryLinkElement) + if (ns.ShouldSerializeRootElement(link)) { - SerializeElement(file, link, new SerializeExtraAttributesCallback(delegate(XmlWriter xmlFile) + int testSerialize = 0; + for (; testSerialize < customRelationshipRoles.Length; ++testSerialize) { + if (!ShouldSerializeElement(DomainRoleInfo.GetRolePlayer(link, customRelationshipRoles[testSerialize].DomainRoleId))) + { + break; + } + } + if (testSerialize != customRelationshipRoles.Length) + { + continue; + } + if (relationship.IsPrimaryLinkElement) + { + SerializeElement(file, link, new SerializeExtraAttributesCallback(delegate(XmlWriter xmlFile) + { + for (int l = 0; l < customRelationshipRoles.Length; ++l) + { + CustomSerializedStandaloneRelationshipRole role = customRelationshipRoles[l]; + xmlFile.WriteAttributeString(role.AttributeName, ToXml(DomainRoleInfo.GetRolePlayer(link, role.DomainRoleId).Id)); + } + })); + } + else + { + file.WriteStartElement(relationship.ElementPrefix, relationship.ElementName, relationship.ElementNamespace); for (int l = 0; l < customRelationshipRoles.Length; ++l) { CustomSerializedStandaloneRelationshipRole role = customRelationshipRoles[l]; - xmlFile.WriteAttributeString(role.AttributeName, ToXml(DomainRoleInfo.GetRolePlayer(link, role.DomainRoleId).Id)); + file.WriteAttributeString(role.AttributeName, ToXml(DomainRoleInfo.GetRolePlayer(link, role.DomainRoleId).Id)); } - })); - } - else - { - file.WriteStartElement(relationship.ElementPrefix, relationship.ElementName, relationship.ElementNamespace); - for (int l = 0; l < customRelationshipRoles.Length; ++l) - { - CustomSerializedStandaloneRelationshipRole role = customRelationshipRoles[l]; - file.WriteAttributeString(role.AttributeName, ToXml(DomainRoleInfo.GetRolePlayer(link, role.DomainRoleId).Id)); + file.WriteEndElement(); } - file.WriteEndElement(); } } } Modified: trunk/ORMModel/Framework/Shell/ToolWindowActivator.cs =================================================================== --- trunk/ORMModel/Framework/Shell/ToolWindowActivator.cs 2009-04-01 01:49:40 UTC (rev 1376) +++ trunk/ORMModel/Framework/Shell/ToolWindowActivator.cs 2009-04-03 17:21:34 UTC (rev 1377) @@ -479,8 +479,8 @@ monitor.SelectionChanged += new EventHandler<MonitorSelectionEventArgs>(MonitorSelectionChanged); monitor.DocumentWindowChanged += new EventHandler<MonitorSelectionEventArgs>(DocumentWindowChanged); SetCurrentDocument(SafeGetCurrentDocument(monitor) as DocDataType, monitor.CurrentDocumentView as DocViewType); + myFrameVisibility = FrameVisibilityFlags.Visible | (flags & FrameVisibilityFlags.PersistentFlagsMask) | FrameVisibilityFlags.HasBeenVisible; CurrentSelectionContainer = monitor.CurrentSelectionContainer as SelectionContainerType ?? monitor.CurrentDocumentView as SelectionContainerType; - myFrameVisibility = FrameVisibilityFlags.Visible | (flags & FrameVisibilityFlags.PersistentFlagsMask) | FrameVisibilityFlags.HasBeenVisible; break; } } Modified: trunk/ORMModel/ObjectModel/Verbalization.cs =================================================================== --- trunk/ORMModel/ObjectModel/Verbalization.cs 2009-04-01 01:49:40 UTC (rev 1376) +++ trunk/ORMModel/ObjectModel/Verbalization.cs 2009-04-03 17:21:34 UTC (rev 1377) @@ -1134,7 +1134,7 @@ //# Test if there is a hyphen binding match before the next format replacement field //(?(.*?\S-\s.*?(?<!\{)\{\d+\}(?!\})) // # If there is a hyphen bind before the next replacement field then use it - // ((?<BeforeLeftHyphenWord>.*?\s??)(?<LeftHyphenWord>\S+?)-(?<AfterLeftHyphen>\s.*?)) + // ((?<BeforeLeftHyphenWord>.*?\s??)(?<LeftHyphenWord>\S+?)(?<!(?<!\{)\{\d+\}(?!\}))-(?<AfterLeftHyphen>\s.*?)) // | // # Otherwise, pick up all text before the next format replacement field // ((?<BeforeLeftHyphenWord>.*?)) @@ -1163,7 +1163,7 @@ System.Threading.Interlocked.CompareExchange<Regex>( ref myMainRegex, new Regex( - @"(?n)\G(?(.*?\S-\s.*?(?<!\{)\{\d+\}(?!\}))((?<BeforeLeftHyphenWord>.*?\s??)(?<LeftHyphenWord>\S+?)-(?<AfterLeftHyphen>\s.*?))|((?<BeforeLeftHyphenWord>.*?)))((?<!\{)\{)(?<ReplaceIndex>\d+)(\}(?!\}))((?=(?(.+(?<!\{)\{\d+\}(?!\}))(((?!(?<!\{)\{\d+\}(?!\})).)*?\s-\S.*?(?<!\{)\{\d+\}(?!\}))|([^\-]*?\s-\S.*?)))(?<BeforeRightHyphen>.*?\s+?)-(?<RightHyphenWord>\S+))?", + @"(?n)\G(?(.*?\S-\s.*?(?<!\{)\{\d+\}(?!\}))((?<BeforeLeftHyphenWord>.*?\s??)(?<LeftHyphenWord>\S+?)(?<!(?<!\{)\{\d+\}(?!\}))-(?<AfterLeftHyphen>\s.*?))|((?<BeforeLeftHyphenWord>.*?)))((?<!\{)\{)(?<ReplaceIndex>\d+)(\}(?!\}))((?=(?(.+(?<!\{)\{\d+\}(?!\}))(((?!(?<!\{)\{\d+\}(?!\})).)*?\s-\S.*?(?<!\{)\{\d+\}(?!\}))|([^\-]*?\s-\S.*?)))(?<BeforeRightHyphen>.*?\s+?)-(?<RightHyphenWord>\S+))?", RegexOptions.Compiled), null); regexMain = myMainRegex; Modified: trunk/ORMModel/Transforms/SerializationExtensions.xsd =================================================================== --- trunk/ORMModel/Transforms/SerializationExtensions.xsd 2009-04-01 01:49:40 UTC (rev 1376) +++ trunk/ORMModel/Transforms/SerializationExtensions.xsd 2009-04-03 17:21:34 UTC (rev 1377) @@ -14,6 +14,7 @@ Natural Object-Role Modeling Architect for Visual Studio Copyright © Neumont University. All rights reserved. + Copyright © ORM Solutions, LLC. All rights reserved. The use and distribution terms for this software are covered by the Common Public License 1.0 (http://opensource.org/licenses/cpl) which @@ -320,7 +321,15 @@ <xs:element name="Container"> <xs:complexType> <xs:sequence minOccurs="1" maxOccurs="unbounded"> - <xs:element name="RootLink" type="StandaloneLinkType"/> + <xs:element name="RootLink"> + <xs:complexType> + <xs:sequence> + <xs:element ref="ConditionalSerialization" minOccurs="0"/> + <xs:group ref="StandaloneLinkRoleGroup"/> + </xs:sequence> + <xs:attributeGroup ref="StandaloneLinkAttributeGroup"/> + </xs:complexType> + </xs:element> </xs:sequence> <xs:attribute name="Name" type="xs:string" use="required"/> <xs:attribute name="Prefix" type="xs:string" use="optional"/> @@ -388,6 +397,10 @@ <xs:annotation> <xs:documentation>Represents a link that is created directly without being in the parent context of one of its role players.</xs:documentation> </xs:annotation> + <xs:group ref="StandaloneLinkRoleGroup"/> + <xs:attributeGroup ref="StandaloneLinkAttributeGroup"/> + </xs:complexType> + <xs:group name="StandaloneLinkRoleGroup"> <xs:sequence> <xs:element name="Role" minOccurs="2" maxOccurs="2"> <xs:complexType> @@ -404,6 +417,8 @@ </xs:complexType> </xs:element> </xs:sequence> + </xs:group> + <xs:attributeGroup name="StandaloneLinkAttributeGroup"> <xs:attribute name="Class" type="xs:string" use="required"> <xs:annotation> <xs:documentation>The name of the link class.</xs:documentation> @@ -424,7 +439,7 @@ <xs:documentation>If true, then an id attribute will be written out for this link and serialization will defer to the link treated as a class after the source and target role player elements are written.</xs:documentation> </xs:annotation> </xs:attribute> - </xs:complexType> + </xs:attributeGroup> <xs:complexType name="ElementType"> <xs:sequence> <xs:sequence> Modified: trunk/ORMModel/Transforms/SerializationExtensions.xslt =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2009-05-21 09:48:03
|
Revision: 1387 http://orm.svn.sourceforge.net/orm/?rev=1387&view=rev Author: mcurland Date: 2009-05-21 09:47:37 +0000 (Thu, 21 May 2009) Log Message: ----------- * Objectify fact type did not add name shape when fact type was already implicitly objectified. Broken in [1385] refs #321 * Fix reverse hyphen bind (reverse hyphen bind missed for reading '{0} -a r b- {1}') refs #263 * Automatically place the caret before the forward slash if a forward reading does not already exist. Tweak of [1355]. refs #331 * Fall back on ISurveyNode.SurveyName of an object for delete final shape message if a component name is not available. Modified Paths: -------------- trunk/ORMModel/ObjectModel/Verbalization.cs trunk/ORMModel/ShapeModel/FactTypeShape.cs trunk/ORMModel/Shell/FactEditor/FactEditorLanguageService.cs trunk/ORMModel/Shell/ORMDesignerCommandManager.cs Modified: trunk/ORMModel/ObjectModel/Verbalization.cs =================================================================== --- trunk/ORMModel/ObjectModel/Verbalization.cs 2009-05-21 01:04:05 UTC (rev 1386) +++ trunk/ORMModel/ObjectModel/Verbalization.cs 2009-05-21 09:47:37 UTC (rev 1387) @@ -1154,7 +1154,7 @@ // string mainPatternCommented = @"(?xn) //\G //# Test if there is a hyphen binding match before the next format replacement field - //(?(.*?\S-\s.*?(?<!\{)\{\d+\}(?!\})) + //(?((.(?!\s+-\S))*?\S-\s.*?(?<!\{)\{\d+\}(?!\})) // # If there is a hyphen bind before the next replacement field then use it // ((?<BeforeLeftHyphenWord>.*?\s??)(?<LeftHyphenWord>\S+?)(?<!(?<!\{)\{\d+\}(?!\}))-(?<AfterLeftHyphen>\s.*?)) // | @@ -1185,7 +1185,7 @@ System.Threading.Interlocked.CompareExchange<Regex>( ref myMainRegex, new Regex( - @"(?n)\G(?(.*?\S-\s.*?(?<!\{)\{\d+\}(?!\}))((?<BeforeLeftHyphenWord>.*?\s??)(?<LeftHyphenWord>\S+?)(?<!(?<!\{)\{\d+\}(?!\}))-(?<AfterLeftHyphen>\s.*?))|((?<BeforeLeftHyphenWord>.*?)))((?<!\{)\{)(?<ReplaceIndex>\d+)(\}(?!\}))((?=(?(.+(?<!\{)\{\d+\}(?!\}))(((?!(?<!\{)\{\d+\}(?!\})).)*?\s-\S.*?(?<!\{)\{\d+\}(?!\}))|([^\-]*?\s-\S.*?)))(?<BeforeRightHyphen>.*?\s+?)-(?<RightHyphenWord>\S+))?", + @"(?n)\G(?((.(?!\s+-\S))*?\S-\s.*?(?<!\{)\{\d+\}(?!\}))((?<BeforeLeftHyphenWord>.*?\s??)(?<LeftHyphenWord>\S+?)(?<!(?<!\{)\{\d+\}(?!\}))-(?<AfterLeftHyphen>\s.*?))|((?<BeforeLeftHyphenWord>.*?)))((?<!\{)\{)(?<ReplaceIndex>\d+)(\}(?!\}))((?=(?(.+(?<!\{)\{\d+\}(?!\}))(((?!(?<!\{)\{\d+\}(?!\})).)*?\s-\S.*?(?<!\{)\{\d+\}(?!\}))|([^\-]*?\s-\S.*?)))(?<BeforeRightHyphen>.*?\s+?)-(?<RightHyphenWord>\S+))?", RegexOptions.Compiled), null); regexMain = myMainRegex; Modified: trunk/ORMModel/ShapeModel/FactTypeShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/FactTypeShape.cs 2009-05-21 01:04:05 UTC (rev 1386) +++ trunk/ORMModel/ShapeModel/FactTypeShape.cs 2009-05-21 09:47:37 UTC (rev 1387) @@ -5061,12 +5061,29 @@ } // Part 1: Resize the existing fact shapes + bool missingNameShapes = false; foreach (PresentationElement pel in PresentationViewsSubject.GetPresentation(nestedFactType)) { FactTypeShape factShape = pel as FactTypeShape; if (factShape != null) { factShape.AutoResize(); + if (!missingNameShapes) + { + bool foundNameShape = false; + foreach (PresentationElement testNameShape in factShape.RelativeChildShapes) + { + if (testNameShape is ObjectifiedFactTypeNameShape) + { + foundNameShape = true; + break; + } + } + if (!foundNameShape) + { + missingNameShapes = true; + } + } } } @@ -5145,6 +5162,12 @@ } } #endif // TRACKNEWSHAPES + + // Make sure we have name shapes for all fact type shapes + if (missingNameShapes) + { + Diagram.FixUpDiagram(nestedFactType, nestingType); + } } /// <summary> /// DeleteRule: typeof(ORMSolutions.ORMArchitect.Core.ObjectModel.Objectification), FireTime=TopLevelCommit, Priority=DiagramFixupConstants.AddShapeRulePriority; Modified: trunk/ORMModel/Shell/FactEditor/FactEditorLanguageService.cs =================================================================== --- trunk/ORMModel/Shell/FactEditor/FactEditorLanguageService.cs 2009-05-21 01:04:05 UTC (rev 1386) +++ trunk/ORMModel/Shell/FactEditor/FactEditorLanguageService.cs 2009-05-21 09:47:37 UTC (rev 1387) @@ -1104,7 +1104,12 @@ // replace as if the opposite direction were selected. However, with the // added slash, the replacement fields are backwards, so we translate the // requested index against the known order. - return FormatReplacementField(reverseReadingOrderRoles[(replaceIndex + 1) % 2], reverseReadingOrderRoles, false); + string replacementField = FormatReplacementField(reverseReadingOrderRoles[(replaceIndex + 1) % 2], reverseReadingOrderRoles, false); + if (replaceIndex == 0) + { + newCaretPosition = replacementField.Length + insertAfter - 3; + } + return replacementField; } return null; }); Modified: trunk/ORMModel/Shell/ORMDesignerCommandManager.cs =================================================================== --- trunk/ORMModel/Shell/ORMDesignerCommandManager.cs 2009-05-21 01:04:05 UTC (rev 1386) +++ trunk/ORMModel/Shell/ORMDesignerCommandManager.cs 2009-05-21 09:47:37 UTC (rev 1387) @@ -40,6 +40,7 @@ using ORMSolutions.ORMArchitect.Core.ShapeModel; using ORMSolutions.ORMArchitect.Framework.Shell; using System.Collections.ObjectModel; +using ORMSolutions.ORMArchitect.Framework.Shell.DynamicSurveyTreeGrid; namespace ORMSolutions.ORMArchitect.Core.Shell { @@ -1887,12 +1888,21 @@ if (newPelCount == 0) { - if (finalDeleteBehavior == FinalShapeDeleteBehavior.Prompt && - (int)DialogResult.No == VsShellUtilities.ShowMessageBox(view.ServiceProvider, - string.Format(CultureInfo.CurrentCulture, ResourceStrings.FinalShapeDeletionMessage, TypeDescriptor.GetClassName(backingMel), TypeDescriptor.GetComponentName(backingMel)), + if (finalDeleteBehavior == FinalShapeDeleteBehavior.Prompt) + { + string componentName = TypeDescriptor.GetComponentName(backingMel); + ISurveyNode surveyNode; + if (string.IsNullOrEmpty(componentName) && + null != (surveyNode = backingMel as ISurveyNode)) + { + componentName = surveyNode.SurveyName; + } + if ((int)DialogResult.No == VsShellUtilities.ShowMessageBox(view.ServiceProvider, + string.Format(CultureInfo.CurrentCulture, ResourceStrings.FinalShapeDeletionMessage, TypeDescriptor.GetClassName(backingMel), componentName), string.Empty, OLEMSGICON.OLEMSGICON_QUERY, OLEMSGBUTTON.OLEMSGBUTTON_YESNO, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_SECOND)) - { - continue; + { + continue; + } } backingMel.Delete(); if (backingObjectifiedType != null && !backingObjectifiedType.IsDeleted && PresentationViewsSubject.GetPresentation(backingObjectifiedType).Count <= 1) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2009-08-07 18:29:08
|
Revision: 1400 http://orm.svn.sourceforge.net/orm/?rev=1400&view=rev Author: mcurland Date: 2009-08-07 18:29:00 +0000 (Fri, 07 Aug 2009) Log Message: ----------- Fixed initial object selection crash in some dropdown editors with VS2005 (non-service pack) versions. In original Dll, tree branches with PositionTracking but not InsertsAndDeletes fail to select. Modified Paths: -------------- trunk/ORMModel/Framework/Design/Editors/TreePicker.cs trunk/ORMModel/Shell/ReadingEditor.cs Modified: trunk/ORMModel/Framework/Design/Editors/TreePicker.cs =================================================================== --- trunk/ORMModel/Framework/Design/Editors/TreePicker.cs 2009-08-06 02:52:32 UTC (rev 1399) +++ trunk/ORMModel/Framework/Design/Editors/TreePicker.cs 2009-08-07 18:29:00 UTC (rev 1400) @@ -321,7 +321,7 @@ IBranch branch = control.Tree.Root; if (0 != (branch.Features & BranchFeatures.PositionTracking)) { - control.SelectObject(branch, value, (int)ObjectStyle.TrackingObject, 0); + control.SelectObject(null, value, (int)ObjectStyle.TrackingObject, 0); } } /// <summary> Modified: trunk/ORMModel/Shell/ReadingEditor.cs =================================================================== --- trunk/ORMModel/Shell/ReadingEditor.cs 2009-08-06 02:52:32 UTC (rev 1399) +++ trunk/ORMModel/Shell/ReadingEditor.cs 2009-08-07 18:29:00 UTC (rev 1400) @@ -844,7 +844,7 @@ && null != (factType = order.FactType) && (factType == myFact || factType == mySecondaryFact)) { - if (TreeControl.SelectObject(myMainBranch, reading, (int)ObjectStyle.TrackingObject, 0)) + if (TreeControl.SelectObject(null, reading, (int)ObjectStyle.TrackingObject, 0)) { TreeControl.BeginLabelEdit(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2009-09-05 17:25:27
|
Revision: 1406 http://orm.svn.sourceforge.net/orm/?rev=1406&view=rev Author: mcurland Date: 2009-09-05 17:25:17 +0000 (Sat, 05 Sep 2009) Log Message: ----------- * Fix selection issue when adding secondary readings in the same order in the reading editor. * Enable F2 activation of inplace editors for reading extension properties. refs #397 * Workaround tree control navigation issues with complex subitems (Right arrow not working correctly if no column permutation specified, fix previous workaround bug with down arrow) Modified Paths: -------------- trunk/ORMModel/Framework/Shell/StandardMultiColumnTree.cs trunk/ORMModel/Resources/ResourceStringsGenerator.cs trunk/ORMModel/Resources/ResourceStringsGenerator.xml trunk/ORMModel/ShapeModel/ORMDiagram.resx trunk/ORMModel/Shell/ORMReadingEditor.cs trunk/ORMModel/Shell/ReadingEditor.cs Modified: trunk/ORMModel/Framework/Shell/StandardMultiColumnTree.cs =================================================================== --- trunk/ORMModel/Framework/Shell/StandardMultiColumnTree.cs 2009-08-26 19:32:11 UTC (rev 1405) +++ trunk/ORMModel/Framework/Shell/StandardMultiColumnTree.cs 2009-09-05 17:25:17 UTC (rev 1406) @@ -68,10 +68,11 @@ // UNDONE: MSBUG GetNavigationTarget calls the internal method to get its blank expansion, not // the interface, so we have no way to override it. Duplicate the GetNavigationTarget fix here for // the 'Down' navigation target. + BlankExpansionData blankExpansion; switch (direction) { case TreeNavigation.Down: - BlankExpansionData blankExpansion = GetBlankExpansion(sourceRow, sourceColumn, columnPermutation); + blankExpansion = GetBlankExpansion(sourceRow, sourceColumn, columnPermutation); if (blankExpansion.Anchor.IsValid) { int lastRow = ((ITree)this).VisibleItemCount - 1; @@ -87,11 +88,30 @@ int topRow = blankExpansion.TopRow; if (sourceColumn == blankExpansion.AnchorColumn && topRow >= testRow) { - return new VirtualTreeCoordinate(topRow, (columnPermutation != null) ? columnPermutation.GetPermutedColumn(sourceColumn) : sourceColumn); + return new VirtualTreeCoordinate(topRow, sourceColumn); } } } return VirtualTreeCoordinate.Invalid; + case TreeNavigation.Right: + // If no column permutation is specified and we're on the first row in a complex + // subitem expansion, then the provided implementation does not go right. + // MSBUG: VirtualTree.GetNavigationTarget is looking at the column count of the + // ParentNode of a complex subitem. The column count in this case is always 1. + if (columnPermutation == null) + { + VirtualTreeCoordinate retVal = base.GetNavigationTarget(TreeNavigation.Right, sourceRow, sourceColumn, null); + int lastAllowedSourceColumn; + if (!retVal.IsValid && + sourceColumn < (lastAllowedSourceColumn = (ColumnCount - 1)) && + (blankExpansion = GetBlankExpansion(sourceRow, sourceColumn, null)).Anchor.IsValid && + blankExpansion.RightColumn < lastAllowedSourceColumn) + { + retVal = GetBlankExpansion(sourceRow, blankExpansion.RightColumn + 1, null).Anchor; + } + return retVal; + } + break; case TreeNavigation.LeftColumn: if (sourceColumn == 0) { Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.cs =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2009-08-26 19:32:11 UTC (rev 1405) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2009-09-05 17:25:17 UTC (rev 1406) @@ -1501,14 +1501,6 @@ return ResourceStrings.GetString(ResourceManagers.Diagram, "Command.DeleteReading.Text"); } } - /// <summary>This text appears on the undo/redo menu when a reading is edited.</summary> - public static string CommandEditReadingText - { - get - { - return ResourceStrings.GetString(ResourceManagers.Diagram, "Command.EditReading.Text"); - } - } /// <summary>This text appears on the move role left/right when the fact type is binary.</summary> public static string CommandSwapRoleOrderText { Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.xml =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2009-08-26 19:32:11 UTC (rev 1405) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2009-09-05 17:25:17 UTC (rev 1406) @@ -237,7 +237,6 @@ <ResourceString name="CommandDeleteMultipleShapeText" model="Diagram" resourceName="Command.DeleteMultipleShape.Text"/> <ResourceString name="CommandDeleteRoleText" model="Diagram" resourceName="Command.DeleteRole.Text"/> <ResourceString name="CommandDeleteReadingText" model="Diagram" resourceName="Command.DeleteReading.Text"/> - <ResourceString name="CommandEditReadingText" model="Diagram" resourceName="Command.EditReading.Text"/> <ResourceString name="CommandSwapRoleOrderText" model="Diagram" resourceName="Command.SwapRoleOrder.Text"/> <ResourceString name="CommandNextOnThisDiagramText" model="Diagram" resourceName="Command.NextOnThisDiagram.Text"/> <ResourceString name="DiagramSpyWindowTitle" model="Diagram" resourceName="DiagramSpy.WindowTitle"/> Modified: trunk/ORMModel/ShapeModel/ORMDiagram.resx =================================================================== --- trunk/ORMModel/ShapeModel/ORMDiagram.resx 2009-08-26 19:32:11 UTC (rev 1405) +++ trunk/ORMModel/ShapeModel/ORMDiagram.resx 2009-09-05 17:25:17 UTC (rev 1406) @@ -203,10 +203,6 @@ <value xml:space="preserve">Delete Reading</value> <comment xml:space="preserve">This text appears on the undo/redo menu when a reading is deleted.</comment> </data> - <data name="Command.EditReading.Text"> - <value xml:space="preserve">Edit Reading</value> - <comment xml:space="preserve">This text appears on the undo/redo menu when a reading is edited.</comment> - </data> <data name="Command.NextOnThisDiagram.Text"> <value xml:space="preserve">Next on this Dia&gram</value> <comment xml:space="preserve">This text appears on the 'Select on Diagram' menu if there is more than one shape for the selected element on the current diagram.</comment> Modified: trunk/ORMModel/Shell/ORMReadingEditor.cs =================================================================== --- trunk/ORMModel/Shell/ORMReadingEditor.cs 2009-08-26 19:32:11 UTC (rev 1405) +++ trunk/ORMModel/Shell/ORMReadingEditor.cs 2009-09-05 17:25:17 UTC (rev 1406) @@ -383,16 +383,6 @@ { myReadingEditor.ActivateReading(fact); } - - public void DeleteSelectedReading() - { - myReadingEditor.OnMenuDeleteSelectedReading(); - } - - public void EditSelectedReading() - { - myReadingEditor.EditSelectedReading(); - } #endregion // Reading activation helper } #endregion @@ -575,7 +565,7 @@ return QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText); } [DllImport("user32.dll", CharSet = CharSet.Auto)] - private static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam); + private static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, int lParam); /// <summary> /// Provides a first chance to handle any command that MSOLE.IOleCommandTarget.QueryStatus /// informed the shell to pass to this window. Implements IOleCommandTarget.Exec @@ -657,7 +647,7 @@ { if (editor.IsReadingPaneActive && editor.CurrentReading != null) { - form.DeleteSelectedReading(); + editor.OnMenuDeleteSelectedReading(); } } else @@ -665,7 +655,7 @@ Control editControl = editor.LabelEditControl; if (editControl != null) { - IntPtr editHandle = editControl.Handle; + HandleRef editHandle = new HandleRef(editControl, editControl.Handle); // WM_KEYDOWN == 0x100 SendMessage(editHandle, 0x100, (int)Keys.Delete, 1); // WM_KEYUP == 0x101 @@ -686,13 +676,25 @@ // VirtualTreeView control), handle the edit command and set the hresult to a handled status. if (!editor.EditingFactType.IsEmpty) { - if (editor.CurrentReading != null) + if (!editor.InLabelEdit) { if (editor.IsReadingPaneActive) { - form.EditSelectedReading(); + editor.EditSelection(); } } + else + { + Control editControl = editor.LabelEditControl; + if (editControl != null) + { + HandleRef editHandle = new HandleRef(editControl, editControl.Handle); + // WM_KEYDOWN == 0x100 + SendMessage(editHandle, 0x100, (int)Keys.F2, 1); + // WM_KEYUP == 0x101 + SendMessage(editHandle, 0x101, (int)Keys.F2, 0x40000001); + } + } } // We enabled the command, so we say we handled it regardless of the further conditions hr = VSConstants.S_OK; Modified: trunk/ORMModel/Shell/ReadingEditor.cs =================================================================== --- trunk/ORMModel/Shell/ReadingEditor.cs 2009-08-26 19:32:11 UTC (rev 1405) +++ trunk/ORMModel/Shell/ReadingEditor.cs 2009-09-05 17:25:17 UTC (rev 1406) @@ -665,7 +665,6 @@ private abstract class RootBranch : BaseBranch { #region Virtual and Abstract Methods - public abstract bool IsAdding { get; } public virtual ReadingEditorCommands SupportedSelectionCommands(int itemLocation) { return ReadingEditorCommands.None; @@ -1249,14 +1248,11 @@ } } /// <summary> - /// Puts the reading that is currently selected in the reading order into edit mode. + /// Puts the currently selected item into edit mode. /// </summary> - public void EditSelectedReading() + public void EditSelection() { - using (Transaction t = myFactType.Store.TransactionManager.BeginTransaction(ResourceStrings.CommandEditReadingText)) - { - vtrReadings.BeginLabelEdit(); - } + vtrReadings.BeginLabelEdit(); } #endregion // Reading activation helper @@ -1847,15 +1843,6 @@ } #endregion // Reading Methods #region ReadingOrder Methods - public override bool IsAdding - { - get - { - ReadingOrderBranch testBranch; - return (null != (testBranch = myReadingOrderBranch) && testBranch.IsAdding) || - (null != (testBranch = myImpliedFactTypeBranch) && testBranch.IsAdding); - } - } public override void EditReadingOrder(IList<RoleBase> collection) { FactType matchFactType = collection[0].FactType; @@ -1895,7 +1882,6 @@ private ReadingOrderInformationCollection myReadingOrderPermutations; private readonly IList<RoleBase> myRoleDisplayOrder; private string[] myRoleNames; - private int myInsertedRow = -1; private BranchModificationEventHandler myModify; private ReadingEditor myEditor; #endregion // Member Variables @@ -1988,25 +1974,15 @@ string newReadingText = editor.BuildReadingText(); if (newReadingText.Length != 0) { - Reading theNewReading; - try + using (Transaction t = store.TransactionManager.BeginTransaction(ResourceStrings.ModelReadingEditorNewReadingTransactionText)) { - myInsertedRow = row; - using (Transaction t = store.TransactionManager.BeginTransaction(ResourceStrings.ModelReadingEditorNewReadingTransactionText)) - { - ReadingOrder theOrder = myFactType.EnsureReadingOrder(myReadingOrderKeyedCollection[row].RoleOrder); - Debug.Assert(theOrder != null, "A ReadingOrder should have been found or created."); - theNewReading = new Reading(store); - LinkedElementCollection<Reading> readings = theOrder.ReadingCollection; - readings.Add(theNewReading); - theNewReading.Text = newReadingText; - t.Commit(); - } + ReadingOrder readingOrder = myFactType.EnsureReadingOrder(myReadingOrderKeyedCollection[row].RoleOrder); + Debug.Assert(readingOrder != null, "A ReadingOrder should have been found or created."); + Reading newReading = new Reading(store); + newReading.ReadingOrder = readingOrder; + newReading.Text = newReadingText; + t.Commit(); } - finally - { - myInsertedRow = -1; - } return LabelEditResult.AcceptEdit; } return LabelEditResult.CancelEdit; @@ -2307,16 +2283,6 @@ } #endregion // Reading Branch Methods #region ReadingOrder Branch Methods - /// <summary> - /// Used to find out if the branch is in the process of adding a new entry from input into the branch. - /// </summary> - public override bool IsAdding - { - get - { - return myInsertedRow != -1; - } - } public override void AddNewReadingOrder() { VirtualTreeControl control = ReadingEditor.Instance.TreeControl; @@ -3030,7 +2996,6 @@ private readonly ReadingEditor myEditor; private ExtensionPropertyBranch[] myPropertyBranches; private bool myShowNewRow; - private int myInsertedRow = -1; private BranchModificationEventHandler myModify; #endregion // Member Variables #region Constructor @@ -3085,23 +3050,23 @@ string newReadingText = editor.BuildReadingText(); if (newReadingText.Length != 0) { - try + Reading newReading = null; + using (Transaction t = store.TransactionManager.BeginTransaction(ResourceStrings.ModelReadingEditorNewReadingTransactionText)) { - myInsertedRow = row; - using (Transaction t = store.TransactionManager.BeginTransaction(ResourceStrings.ModelReadingEditorNewReadingTransactionText)) - { - Debug.Assert(myReadingOrder != null, "A ReadingOrder should have been found or created."); - this.ShowNewRow(false); - Reading theNewReading = new Reading(store); - LinkedElementCollection<Reading> readings = myReadingOrder.ReadingCollection; - readings.Add(theNewReading); - theNewReading.Text = newReadingText; - t.Commit(); - } + Debug.Assert(myReadingOrder != null, "A ReadingOrder should have been found or created."); + this.ShowNewRow(false); + newReading = new Reading(store); + newReading.ReadingOrder = myReadingOrder; + newReading.Text = newReadingText; + t.Commit(); } - finally + if (newReading != null) { - myInsertedRow = -1; + // Reselect the new reading. The option to this approach is to + // replace the new row with the reading before the transaction + // commits so that the row is not inserted/readded. For the same + // user experience, this isn't worth the additional complication. + myEditor.TreeControl.SelectObject(null, newReading, (int)ObjectStyle.TrackingObject, 0); } return LabelEditResult.AcceptEdit; } @@ -3216,17 +3181,6 @@ } } /// <summary> - /// Used to find out if the branch is in the process of adding a new entry from - /// input into the branch. - /// </summary> - public bool IsAdding - { - get - { - return myInsertedRow != -1; - } - } - /// <summary> /// Displays the new row for adding a reading to the reading order /// </summary> public void ShowNewRow(bool show) @@ -3241,10 +3195,6 @@ // Notify addition at the end int insertPosition = myReadings.Count - 2; modify(this, BranchModificationEventArgs.InsertItems(this, insertPosition, 1)); - foreach (ExtensionPropertyBranch propertyBranch in ExtensionPropertyBranches) - { - modify(propertyBranch, BranchModificationEventArgs.InsertItems(propertyBranch, insertPosition, 1)); - } } } else if (myShowNewRow && !show) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2009-09-16 07:46:00
|
Revision: 1410 http://orm.svn.sourceforge.net/orm/?rev=1410&view=rev Author: mcurland Date: 2009-09-16 07:45:45 +0000 (Wed, 16 Sep 2009) Log Message: ----------- * Modify grouping mechanism to integrate properties from group types directly in the group properties. Also added a category to all group properties and display the currently selected GroupTypes directly in the properties window. refs #387 * Added EditorUtility helpers to modify displayed information for a property without modifying its behavior. Enables properties from a base class (Name is a common example) to be explicitly named and categorized by a derived class. * Extensions can now be attached to the main properties section of an objectified FactTypeShape by attaching property providers to the Objectification type. * Relaxed sealed overrides on EnumConverter to enable context-based modification of enum values. The typical use allows a 'default' enum item to display the current default setting. Modified Paths: -------------- trunk/ORMModel/Framework/Design/Editors/EditorUtility.cs trunk/ORMModel/Framework/Design/EnumConverter.cs trunk/ORMModel/ObjectModel/Design/ElementGroupingTypeDescriptor.cs trunk/ORMModel/ObjectModel/GeneratedCode/DomainClasses.cs trunk/ORMModel/ObjectModel/GeneratedCode/DomainModelResx.resx trunk/ORMModel/ObjectModel/Grouping.cs trunk/ORMModel/ObjectModel/ORMCore.dsl trunk/ORMModel/Resources/ResourceStringsGenerator.cs trunk/ORMModel/Resources/ResourceStringsGenerator.xml trunk/ORMModel/ShapeModel/Design/FactTypeShapeTypeDescriptor.cs trunk/ORMModel/Shell/ORMDocDataServices.cs Modified: trunk/ORMModel/Framework/Design/Editors/EditorUtility.cs =================================================================== --- trunk/ORMModel/Framework/Design/Editors/EditorUtility.cs 2009-09-10 23:39:38 UTC (rev 1409) +++ trunk/ORMModel/Framework/Design/Editors/EditorUtility.cs 2009-09-16 07:45:45 UTC (rev 1410) @@ -3,6 +3,7 @@ * Natural Object-Role Modeling Architect for Visual Studio * * * * Copyright \xA9 Neumont University. All rights reserved. * +* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * * * * The use and distribution terms for this software are covered by the * * Common Public License 1.0 (http://opensource.org/licenses/cpl) which * @@ -131,6 +132,7 @@ /// </summary> public static class EditorUtility { + #region ResolveContextInstance /// <summary> /// Selection context is often based on a wrapper shape, such /// as a NodeShape or a tree node in a model browser. Use this @@ -166,6 +168,8 @@ } return instance; } + #endregion // ResolveContextInstance + #region ActivatePropertyEditor /// <summary> /// Helper method to recursively find a control of a given type /// </summary> @@ -333,5 +337,182 @@ } } } + #endregion // ActivatePropertyEditor + #region ModifyPropertyDescriptorDisplay + /// <summary> + /// Modify the display settings for a <see cref="PropertyDescriptor"/> by + /// wrapping the base descriptor with another property descriptor instance. + /// </summary> + /// <param name="basedOnDescriptor">The original descriptor.</param> + /// <param name="displayName">The modified display name. If this is <see langword="null"/>, then the original display name is used.</param> + /// <param name="description">The modified description. If this is <see langword="null"/>, then the original description is used.</param> + /// <param name="category">The modified category. If this is <see langword="null"/>, then the original category is used.</param> + /// <returns>A wrapper <see cref="PropertyDescriptor"/></returns> + public static PropertyDescriptor ModifyPropertyDescriptorDisplay(PropertyDescriptor basedOnDescriptor, string displayName, string description, string category) + { + return new DisplayModifiedPropertyDescriptor(basedOnDescriptor, displayName, description, category); + } + /// <summary> + /// Modify the display settings for a <see cref="PropertyDescriptor"/> by + /// wrapping the base descriptor with another property descriptor instance. + /// </summary> + /// <param name="descriptorCollection">A collection of descriptors.</param> + /// <param name="propertyName">The non-localized name of the property to modify.</param> + /// <param name="displayName">The modified display name. If this is <see langword="null"/>, then the original display name is used.</param> + /// <param name="description">The modified description. If this is <see langword="null"/>, then the original description is used.</param> + /// <param name="category">The modified category. If this is <see langword="null"/>, then the original category is used.</param> + /// <returns>A wrapper <see cref="PropertyDescriptor"/></returns> + public static void ModifyPropertyDescriptorDisplay(PropertyDescriptorCollection descriptorCollection, string propertyName, string displayName, string description, string category) + { + PropertyDescriptor descriptor; + if (descriptorCollection != null && + null != (descriptor = descriptorCollection[propertyName])) + { + descriptorCollection.Remove(descriptor); + descriptorCollection.Add(ModifyPropertyDescriptorDisplay(descriptor, displayName, description, category)); + } + } + /// <summary> + /// Wrapper <see cref="PropertyDescriptor"/> class to support display modification + /// </summary> + private sealed class DisplayModifiedPropertyDescriptor : PropertyDescriptor + { + #region Member Variables + private PropertyDescriptor myInner; + private string myDisplayName; + private string myDescription; + private string myCategory; + #endregion // Member Variables + #region Constructor + /// <summary> + /// Create a wrapped descriptor + /// </summary> + /// <param name="modifyDescriptor"></param> + /// <param name="displayName">The modified display name. If this is <see langword="null"/>, then the original display name is used.</param> + /// <param name="description">The modified description. If this is <see langword="null"/>, then the original description is used.</param> + /// <param name="category">The modified category. If this is <see langword="null"/>, then the original category is used.</param> + public DisplayModifiedPropertyDescriptor(PropertyDescriptor modifyDescriptor, string displayName, string description, string category) + : base(modifyDescriptor.Name, GetAttributeArray(modifyDescriptor.Attributes)) + { + myInner = modifyDescriptor; + myDisplayName = displayName; + myDescription = description; + myCategory = category; + } + private static Attribute[] GetAttributeArray(AttributeCollection attributes) + { + int attributeCount; + if (attributes == null || 0 == (attributeCount = attributes.Count)) + { + return null; + } + Attribute[] retVal = new Attribute[attributeCount]; + attributes.CopyTo(retVal, 0); + return retVal; + } + #endregion // Constructor + #region Display overrides + public override string Category + { + get + { + return myCategory ?? myInner.Category; + } + } + public override string DisplayName + { + get + { + return myDisplayName ?? myInner.DisplayName; + } + } + public override string Description + { + get + { + return myDescription ?? myInner.Description; + } + } + #endregion // Display overrides + #region Other overrides + public override bool CanResetValue(object component) + { + return myInner.CanResetValue(component); + } + public override Type ComponentType + { + get { return myInner.ComponentType; } + } + public override object GetValue(object component) + { + return myInner.GetValue(component); + } + public override bool IsReadOnly + { + get { return myInner.IsReadOnly; } + } + public override Type PropertyType + { + get { return myInner.PropertyType; } + } + public override void ResetValue(object component) + { + myInner.ResetValue(component); + } + public override void SetValue(object component, object value) + { + myInner.SetValue(component, value); + } + public override bool ShouldSerializeValue(object component) + { + return myInner.ShouldSerializeValue(component); + } + public override void AddValueChanged(object component, EventHandler handler) + { + myInner.AddValueChanged(component, handler); + } + public override AttributeCollection Attributes + { + get { return myInner.Attributes; } + } + public override TypeConverter Converter + { + get { return myInner.Converter; } + } + public override bool DesignTimeOnly + { + get { return myInner.DesignTimeOnly; } + } + public override PropertyDescriptorCollection GetChildProperties(object instance, Attribute[] filter) + { + return myInner.GetChildProperties(instance, filter); + } + public override object GetEditor(Type editorBaseType) + { + return myInner.GetEditor(editorBaseType); + } + public override bool IsBrowsable + { + get { return myInner.IsBrowsable; } + } + public override bool IsLocalizable + { + get { return myInner.IsLocalizable; } + } + public override void RemoveValueChanged(object component, EventHandler handler) + { + myInner.RemoveValueChanged(component, handler); + } + public override bool SupportsChangeEvents + { + get { return myInner.SupportsChangeEvents; } + } + public override string ToString() + { + return myInner.ToString(); + } + #endregion // Other overrides + } + #endregion // ModifyPropertyDescriptorDisplay } } Modified: trunk/ORMModel/Framework/Design/EnumConverter.cs =================================================================== --- trunk/ORMModel/Framework/Design/EnumConverter.cs 2009-09-10 23:39:38 UTC (rev 1409) +++ trunk/ORMModel/Framework/Design/EnumConverter.cs 2009-09-16 07:45:45 UTC (rev 1410) @@ -3,6 +3,7 @@ * Natural Object-Role Modeling Architect for Visual Studio * * * * Copyright \xA9 Neumont University. All rights reserved. * +* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * * * * The use and distribution terms for this software are covered by the * * Common Public License 1.0 (http://opensource.org/licenses/cpl) which * @@ -360,7 +361,7 @@ #region ConvertFrom method /// <summary>See <see cref="EnumConverter.ConvertFrom"/>.</summary> - public sealed override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { string stringValue = value as string; if ((object)stringValue != null && culture != null && !culture.Equals(CultureInfo.InvariantCulture)) @@ -377,7 +378,7 @@ #region ConvertTo method /// <summary>See <see cref="EnumConverter.ConvertTo"/>.</summary> - public sealed override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(string) && culture != null && !culture.Equals(CultureInfo.InvariantCulture) && (value is TEnum || Modified: trunk/ORMModel/ObjectModel/Design/ElementGroupingTypeDescriptor.cs =================================================================== --- trunk/ORMModel/ObjectModel/Design/ElementGroupingTypeDescriptor.cs 2009-09-10 23:39:38 UTC (rev 1409) +++ trunk/ORMModel/ObjectModel/Design/ElementGroupingTypeDescriptor.cs 2009-09-16 07:45:45 UTC (rev 1410) @@ -2,7 +2,7 @@ /**************************************************************************\ * Natural Object-Role Modeling Architect for Visual Studio * * * -* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * +* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * * * * The use and distribution terms for this software are covered by the * * Common Public License 1.0 (http://opensource.org/licenses/cpl) which * @@ -16,20 +16,21 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.ComponentModel; +using System.Drawing; +using System.Drawing.Design; using System.Globalization; using System.Security.Permissions; +using System.Text; +using System.Windows.Forms; +using System.Windows.Forms.Design; using Microsoft.VisualStudio.Modeling; using Microsoft.VisualStudio.Modeling.Design; +using Microsoft.VisualStudio.VirtualTreeGrid; +using ORMSolutions.ORMArchitect.Core.Shell; +using ORMSolutions.ORMArchitect.Core.ObjectModel; using ORMSolutions.ORMArchitect.Framework.Design; -using ORMSolutions.ORMArchitect.Core.ObjectModel; -using System.Drawing.Design; -using System.Windows.Forms.Design; -using ORMSolutions.ORMArchitect.Core.Shell; -using System.Windows.Forms; -using Microsoft.VisualStudio.VirtualTreeGrid; -using System.Collections.ObjectModel; -using System.Drawing; namespace ORMSolutions.ORMArchitect.Core.ObjectModel.Design { @@ -57,7 +58,15 @@ public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { PropertyDescriptorCollection retVal = base.GetProperties(attributes); + EditorUtility.ModifyPropertyDescriptorDisplay(retVal, "Name", null, null, ResourceStrings.ElementGroupingPropertyCategory); retVal.Add(GroupingTypesPropertyDescriptor.Instance); + foreach (ElementGroupingType groupingType in ModelElement.GroupingTypeCollection) + { + foreach (PropertyDescriptor groupTypeDescriptor in TypeDescriptor.GetProperties(groupingType, attributes)) + { + retVal.Add(groupTypeDescriptor); + } + } return retVal; } #endregion // Base overrides @@ -111,7 +120,7 @@ } public override bool ShouldSerializeValue(object component) { - return false; + return true; } public override string Description { @@ -127,6 +136,13 @@ return ResourceStrings.ElementGroupingTypesPropertyDescriptorDisplayName; } } + public override string Category + { + get + { + return ResourceStrings.ElementGroupingPropertyCategory; + } + } public override object GetEditor(Type editorBaseType) { if (editorBaseType == typeof(UITypeEditor)) @@ -135,6 +151,13 @@ } return base.GetEditor(editorBaseType); } + public override TypeConverter Converter + { + get + { + return GroupingTypesTypeConverter.Instance; + } + } #endregion // Base overrides #region GroupingTypesEditor class /// <summary> @@ -460,6 +483,58 @@ #endregion // GroupingTypesBranch class } #endregion // GroupingTypesEditor class + #region GroupingTypesTypeConverter class + /// <summary> + /// Provide display text for grouping types + /// </summary> + private class GroupingTypesTypeConverter : TypeConverter + { + #region Constructor and Instance + public static readonly TypeConverter Instance = new GroupingTypesTypeConverter(); + private GroupingTypesTypeConverter() + { + } + #endregion // Constructor and Instance + #region Base overrides + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + ElementGrouping grouping; + LinkedElementCollection<ElementGroupingType> groupingTypes; + int groupingTypeCount; + if (destinationType == typeof(string) && + null != context && + null != (grouping = context.Instance as ElementGrouping) && + 0 != (groupingTypeCount = (groupingTypes = grouping.GroupingTypeCollection).Count)) + { + if (groupingTypeCount == 1) + { + return DomainTypeDescriptor.GetDisplayName(groupingTypes[0].GetType()); + } + else + { + StringBuilder builder = new StringBuilder(); + TextInfo textInfo = culture.TextInfo; + string separator = textInfo.ListSeparator; + if (!char.IsWhiteSpace(separator, separator.Length - 1)) + { + separator += " "; + } + for (int i = 0; i < groupingTypeCount; ++i) + { + if (i != 0) + { + builder.Append(separator); + } + builder.Append(DomainTypeDescriptor.GetDisplayName(groupingTypes[i].GetType())); + } + return builder.ToString(); + } + } + return base.ConvertTo(context, culture, value, destinationType); + } + #endregion // Base overrides + } + #endregion // GroupingTypesTypeConverter class } #endregion // GroupingTypesPropertyDescriptor class } Modified: trunk/ORMModel/ObjectModel/GeneratedCode/DomainClasses.cs =================================================================== --- trunk/ORMModel/ObjectModel/GeneratedCode/DomainClasses.cs 2009-09-10 23:39:38 UTC (rev 1409) +++ trunk/ORMModel/ObjectModel/GeneratedCode/DomainClasses.cs 2009-09-16 07:45:45 UTC (rev 1410) @@ -1709,6 +1709,7 @@ [global::System.ComponentModel.Editor(typeof(global::ORMSolutions.ORMArchitect.Framework.Design.MultilineTextEditor<global::ORMSolutions.ORMArchitect.Core.ObjectModel.Definition>), typeof(global::System.Drawing.Design.UITypeEditor))] [global::System.ComponentModel.MergableProperty(false)] [DslDesign::DisplayNameResource("ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/DefinitionText.DisplayName", typeof(global::ORMSolutions.ORMArchitect.Core.ObjectModel.ORMCoreDomainModel), "ORMSolutions.ORMArchitect.Core.GeneratedCode.CoreDomainModelResx")] + [DslDesign::CategoryResource("ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/DefinitionText.Category", typeof(global::ORMSolutions.ORMArchitect.Core.ObjectModel.ORMCoreDomainModel), "ORMSolutions.ORMArchitect.Core.GeneratedCode.CoreDomainModelResx")] [DslDesign::DescriptionResource("ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/DefinitionText.Description", typeof(global::ORMSolutions.ORMArchitect.Core.ObjectModel.ORMCoreDomainModel), "ORMSolutions.ORMArchitect.Core.GeneratedCode.CoreDomainModelResx")] [DslModeling::DomainProperty(Kind = DslModeling::DomainPropertyKind.CustomStorage)] [DslModeling::DomainObjectId("d1539042-2a67-413b-8b3b-12d00775bb8d")] @@ -1803,6 +1804,7 @@ [global::System.ComponentModel.Editor(typeof(global::ORMSolutions.ORMArchitect.Framework.Design.MultilineTextEditor<global::ORMSolutions.ORMArchitect.Core.ObjectModel.Note>), typeof(global::System.Drawing.Design.UITypeEditor))] [global::System.ComponentModel.MergableProperty(false)] [DslDesign::DisplayNameResource("ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/NoteText.DisplayName", typeof(global::ORMSolutions.ORMArchitect.Core.ObjectModel.ORMCoreDomainModel), "ORMSolutions.ORMArchitect.Core.GeneratedCode.CoreDomainModelResx")] + [DslDesign::CategoryResource("ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/NoteText.Category", typeof(global::ORMSolutions.ORMArchitect.Core.ObjectModel.ORMCoreDomainModel), "ORMSolutions.ORMArchitect.Core.GeneratedCode.CoreDomainModelResx")] [DslDesign::DescriptionResource("ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/NoteText.Description", typeof(global::ORMSolutions.ORMArchitect.Core.ObjectModel.ORMCoreDomainModel), "ORMSolutions.ORMArchitect.Core.GeneratedCode.CoreDomainModelResx")] [DslModeling::DomainProperty(Kind = DslModeling::DomainPropertyKind.CustomStorage)] [DslModeling::DomainObjectId("39b0228b-8884-4e4e-b595-4f058f192b50")] @@ -1904,6 +1906,7 @@ /// GroupTypes. /// </summary> [DslDesign::DisplayNameResource("ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/TypeCompliance.DisplayName", typeof(global::ORMSolutions.ORMArchitect.Core.ObjectModel.ORMCoreDomainModel), "ORMSolutions.ORMArchitect.Core.GeneratedCode.CoreDomainModelResx")] + [DslDesign::CategoryResource("ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/TypeCompliance.Category", typeof(global::ORMSolutions.ORMArchitect.Core.ObjectModel.ORMCoreDomainModel), "ORMSolutions.ORMArchitect.Core.GeneratedCode.CoreDomainModelResx")] [DslDesign::DescriptionResource("ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/TypeCompliance.Description", typeof(global::ORMSolutions.ORMArchitect.Core.ObjectModel.ORMCoreDomainModel), "ORMSolutions.ORMArchitect.Core.GeneratedCode.CoreDomainModelResx")] [global::System.ComponentModel.DefaultValue(ORMSolutions.ORMArchitect.Core.ObjectModel.GroupingMembershipTypeCompliance.NotExcluded)] [DslModeling::DomainObjectId("16e7b546-46ce-4a46-aed5-1437edb5fa6c")] @@ -1994,6 +1997,7 @@ /// GroupPriority are given precedence. /// </summary> [DslDesign::DisplayNameResource("ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/Priority.DisplayName", typeof(global::ORMSolutions.ORMArchitect.Core.ObjectModel.ORMCoreDomainModel), "ORMSolutions.ORMArchitect.Core.GeneratedCode.CoreDomainModelResx")] + [DslDesign::CategoryResource("ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/Priority.Category", typeof(global::ORMSolutions.ORMArchitect.Core.ObjectModel.ORMCoreDomainModel), "ORMSolutions.ORMArchitect.Core.GeneratedCode.CoreDomainModelResx")] [DslDesign::DescriptionResource("ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/Priority.Description", typeof(global::ORMSolutions.ORMArchitect.Core.ObjectModel.ORMCoreDomainModel), "ORMSolutions.ORMArchitect.Core.GeneratedCode.CoreDomainModelResx")] [DslModeling::DomainObjectId("c290cb24-0f2c-4e67-a561-fcd25dda53e8")] public global::System.Int32 Priority Modified: trunk/ORMModel/ObjectModel/GeneratedCode/DomainModelResx.resx =================================================================== --- trunk/ORMModel/ObjectModel/GeneratedCode/DomainModelResx.resx 2009-09-10 23:39:38 UTC (rev 1409) +++ trunk/ORMModel/ObjectModel/GeneratedCode/DomainModelResx.resx 2009-09-16 07:45:45 UTC (rev 1410) @@ -350,6 +350,10 @@ <value>InformalDescription</value> <comment>DisplayName for DomainProperty 'DefinitionText' on DomainClass 'ElementGrouping'</comment> </data> + <data name="ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/DefinitionText.Category" xml:space="preserve"> + <value>Group</value> + <comment>Category for DomainProperty 'DefinitionText' on DomainClass 'ElementGrouping'</comment> + </data> <data name="ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/NoteText.Description" xml:space="preserve"> <value>A note to associate with this group. To insert new lines, use Control-Enter in the dropdown editor, or open the 'ORM Notes Editor' tool window.</value> @@ -359,6 +363,10 @@ <value>Note</value> <comment>DisplayName for DomainProperty 'NoteText' on DomainClass 'ElementGrouping'</comment> </data> + <data name="ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/NoteText.Category" xml:space="preserve"> + <value>Group</value> + <comment>Category for DomainProperty 'NoteText' on DomainClass 'ElementGrouping'</comment> + </data> <data name="ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/TypeCompliance.Description" xml:space="preserve"> <value>Specify the level of GroupType compliance for elements in this group. Not Excluded: Allow elements not explicitly excluded by a selected GroupType. @@ -370,6 +378,10 @@ <value>GroupTypeCompliance</value> <comment>DisplayName for DomainProperty 'TypeCompliance' on DomainClass 'ElementGrouping'</comment> </data> + <data name="ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/TypeCompliance.Category" xml:space="preserve"> + <value>Group</value> + <comment>Category for DomainProperty 'TypeCompliance' on DomainClass 'ElementGrouping'</comment> + </data> <data name="ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/Priority.Description" xml:space="preserve"> <value>Specify a priority relative to other Groups. If an element is included in two groups of the same type, the settings for the Group with the highest GroupPriority are given precedence.</value> <comment>Description for DomainProperty 'Priority' on DomainClass 'ElementGrouping'</comment> @@ -378,6 +390,10 @@ <value>GroupPriority</value> <comment>DisplayName for DomainProperty 'Priority' on DomainClass 'ElementGrouping'</comment> </data> + <data name="ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/Priority.Category" xml:space="preserve"> + <value>Group</value> + <comment>Category for DomainProperty 'Priority' on DomainClass 'ElementGrouping'</comment> + </data> <data name="ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGroupingType.Description" xml:space="preserve"> <value>A type for a group. Each Group is associated with a new instance of each of its GroupTypes, allowing individual settings per group.</value> <comment>Description for DomainClass 'ElementGroupingType'</comment> Modified: trunk/ORMModel/ObjectModel/Grouping.cs =================================================================== --- trunk/ORMModel/ObjectModel/Grouping.cs 2009-09-10 23:39:38 UTC (rev 1409) +++ trunk/ORMModel/ObjectModel/Grouping.cs 2009-09-16 07:45:45 UTC (rev 1410) @@ -2,7 +2,7 @@ /**************************************************************************\ * Natural Object-Role Modeling Architect for Visual Studio * * * -* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * +* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * * * * The use and distribution terms for this software are covered by the * * Common Public License 1.0 (http://opensource.org/licenses/cpl) which * @@ -522,6 +522,23 @@ } } } + /// <summary> + /// Get the <see cref="ElementGroupingType"/> instance associated with this <see cref="ElementGrouping"/> + /// </summary> + /// <typeparam name="T">The <see cref="ElementGroupingType"/> to retrieve.</typeparam> + /// <returns>The <see cref="ElementGroupingType"/> instance, or <see langword="null"/></returns> + public T GetGroupingType<T>() where T : ElementGroupingType + { + foreach (ElementGroupingType groupingType in GroupingTypeCollection) + { + T testGroupingType = groupingType as T; + if (testGroupingType != null) + { + return testGroupingType; + } + } + return null; + } #endregion // Public Helper Methods #region Rule methods /// <summary> Modified: trunk/ORMModel/ObjectModel/ORMCore.dsl =================================================================== --- trunk/ORMModel/ObjectModel/ORMCore.dsl 2009-09-10 23:39:38 UTC (rev 1409) +++ trunk/ORMModel/ObjectModel/ORMCore.dsl 2009-09-16 07:45:45 UTC (rev 1410) @@ -189,7 +189,7 @@ <DomainClassMoniker Name="ORMNamedElement"/> </BaseClass> <Properties> - <DomainProperty Name="DefinitionText" DefaultValue="" DisplayName="InformalDescription" Description="An informal description of this group.
 To insert new lines, use Control-Enter in the dropdown editor, or open the 'ORM Informal Description Editor' tool window." Id="D1539042-2A67-413B-8B3B-12D00775BB8D" Kind="CustomStorage"> + <DomainProperty Name="DefinitionText" DefaultValue="" DisplayName="InformalDescription" Category="Group" Description="An informal description of this group.
 To insert new lines, use Control-Enter in the dropdown editor, or open the 'ORM Informal Description Editor' tool window." Id="D1539042-2A67-413B-8B3B-12D00775BB8D" Kind="CustomStorage"> <Attributes> <ClrAttribute Name="global::System.ComponentModel.Editor"> <Parameters> @@ -207,7 +207,7 @@ <ExternalTypeMoniker Name="/System/String"/> </Type> </DomainProperty> - <DomainProperty Name="NoteText" DefaultValue="" DisplayName="Note" Description="A note to associate with this group.
 To insert new lines, use Control-Enter in the dropdown editor, or open the 'ORM Notes Editor' tool window." Id="39B0228B-8884-4E4E-B595-4F058F192B50" Kind="CustomStorage"> + <DomainProperty Name="NoteText" DefaultValue="" DisplayName="Note" Category="Group" Description="A note to associate with this group.
 To insert new lines, use Control-Enter in the dropdown editor, or open the 'ORM Notes Editor' tool window." Id="39B0228B-8884-4E4E-B595-4F058F192B50" Kind="CustomStorage"> <Attributes> <ClrAttribute Name="global::System.ComponentModel.Editor"> <Parameters> @@ -225,12 +225,12 @@ <ExternalTypeMoniker Name="/System/String"/> </Type> </DomainProperty> - <DomainProperty Name="TypeCompliance" DefaultValue="NotExcluded" DisplayName="GroupTypeCompliance" Id="16E7B546-46CE-4A46-AED5-1437EDB5FA6C" Description="Specify the level of GroupType compliance for elements in this group.
 Not Excluded: Allow elements not explicitly excluded by a selected GroupType.
 Approved by Some Type: Allow elements explicitly approved by at least one GroupType.
 Approved by All Types: Allow elements explicitly approved by all selected GroupTypes."> + <DomainProperty Name="TypeCompliance" DefaultValue="NotExcluded" DisplayName="GroupTypeCompliance" Category="Group" Id="16E7B546-46CE-4A46-AED5-1437EDB5FA6C" Description="Specify the level of GroupType compliance for elements in this group.
 Not Excluded: Allow elements not explicitly excluded by a selected GroupType.
 Approved by Some Type: Allow elements explicitly approved by at least one GroupType.
 Approved by All Types: Allow elements explicitly approved by all selected GroupTypes."> <Type> <DomainEnumerationMoniker Name="GroupingMembershipTypeCompliance"/> </Type> </DomainProperty> - <DomainProperty Name="Priority" DefaultValue="0" DisplayName="GroupPriority" Id="C290CB24-0F2C-4E67-A561-FCD25DDA53E8" Description="Specify a priority relative to other Groups. If an element is included in two groups of the same type, the settings for the Group with the highest GroupPriority are given precedence."> + <DomainProperty Name="Priority" DefaultValue="0" DisplayName="GroupPriority" Category="Group" Id="C290CB24-0F2C-4E67-A561-FCD25DDA53E8" Description="Specify a priority relative to other Groups. If an element is included in two groups of the same type, the settings for the Group with the highest GroupPriority are given precedence."> <Type> <ExternalTypeMoniker Name="/System/Int32"/> </Type> Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.cs =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2009-09-10 23:39:38 UTC (rev 1409) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2009-09-16 07:45:45 UTC (rev 1410) @@ -581,6 +581,13 @@ return ResourceStrings.GetString(ResourceManagers.Diagram, "DropShape.TransactionName"); } } + public static string ElementGroupingPropertyCategory + { + get + { + return ResourceStrings.GetString(ResourceManagers.ObjectModel, "ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/TypeCompliance.Category"); + } + } /// <summary>The base name used to create a name for a new ElementGrouping. This is a format string with {0} being the placeholder for the number placement.</summary> public static string ElementGroupingDefaultNamePattern { Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.xml =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2009-09-10 23:39:38 UTC (rev 1409) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2009-09-16 07:45:45 UTC (rev 1410) @@ -122,6 +122,7 @@ <ResourceString name="ExclusiveOrCouplerTransactionName" model="Diagram" resourceName="ExclusiveOrCoupler.TransactionName"/> <ResourceString name="ExclusiveOrDecouplerTransactionName" model="Diagram" resourceName="ExclusiveOrDecoupler.TransactionName"/> <ResourceString name="DropShapeTransactionName" model="Diagram" resourceName="DropShape.TransactionName"/> + <ResourceString name="ElementGroupingPropertyCategory" model="ObjectModel" resourceName="ORMSolutions.ORMArchitect.Core.ObjectModel.ElementGrouping/TypeCompliance.Category"/> <ResourceString name="ElementGroupingDefaultNamePattern" model="Model" resourceName="ElementGrouping.DefaultNamePattern"/> <ResourceString name="ElementGroupingAddElementTransactionName" model="Model" resourceName="ElementGrouping.AddElement.TransactionName"/> <ResourceString name="ElementGroupingAddGroupTransactionName" model="Model" resourceName="ElementGrouping.AddGroup.TransactionName"/> Modified: trunk/ORMModel/ShapeModel/Design/FactTypeShapeTypeDescriptor.cs =================================================================== --- trunk/ORMModel/ShapeModel/Design/FactTypeShapeTypeDescriptor.cs 2009-09-10 23:39:38 UTC (rev 1409) +++ trunk/ORMModel/ShapeModel/Design/FactTypeShapeTypeDescriptor.cs 2009-09-16 07:45:45 UTC (rev 1410) @@ -28,6 +28,7 @@ using ORMSolutions.ORMArchitect.Core.ObjectModel; using ORMSolutions.ORMArchitect.Core.ObjectModel.Design; using ORMSolutions.ORMArchitect.Core.ShapeModel; +using ORMSolutions.ORMArchitect.Framework; namespace ORMSolutions.ORMArchitect.Core.ShapeModel.Design { @@ -134,7 +135,8 @@ if (FactTypeShape.ShouldDrawObjectification(factType)) { FactTypeShape factTypeShape = PresentationElement; - ObjectType nestingType = factType.NestingType; + Objectification objectification = factType.Objectification; + ObjectType nestingType = objectification.NestingType; bool nestingTypeHasRelatedTypes = nestingType.IsSubtypeOrSupertype; DomainDataDirectory domainDataDirectory = factType.Store.DomainDataDirectory; EnsureDomainAttributesInitialized(domainDataDirectory); @@ -152,7 +154,13 @@ descriptors[7] = CreatePropertyDescriptor(factTypeShape, domainDataDirectory.FindDomainProperty(FactTypeShape.DisplayRelatedTypesDomainPropertyId), DisplayRelatedTypesDomainPropertyAttributes); } - return new PropertyDescriptorCollection(descriptors); + PropertyDescriptorCollection retVal = new PropertyDescriptorCollection(descriptors); + + // This mockup of important properties means that extension providers cannot add properties + // here by adding to the objecttype or facttype. Use an extension on the Objectification type + // itself to add extension properties. + ((IFrameworkServices)factType.Store).PropertyProviderService.GetProvidedProperties(objectification, retVal); + return retVal; } return base.GetProperties(attributes); } Modified: trunk/ORMModel/Shell/ORMDocDataServices.cs =================================================================== --- trunk/ORMModel/Shell/ORMDocDataServices.cs 2009-09-10 23:39:38 UTC (rev 1409) +++ trunk/ORMModel/Shell/ORMDocDataServices.cs 2009-09-16 07:45:45 UTC (rev 1410) @@ -3,7 +3,7 @@ * Natural Object-Role Modeling Architect for Visual Studio * * * * Copyright \xA9 Neumont University. All rights reserved. * -* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * +* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * * * * The use and distribution terms for this software are covered by the * * Common Public License 1.0 (http://opensource.org/licenses/cpl) which * @@ -2140,7 +2140,13 @@ if (null != modelError && null != (activator = shape as IModelErrorActivation)) { - activator.ActivateModelError(modelError); + if (!activator.ActivateModelError(modelError)) + { + // The shape itself could not activate this error. + // Attempt to activate using an activator that is tied to the + // backing element for the current shape. + ModelErrorActivationService.ActivateError(shape.ModelElement, modelError); + } } return true; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2009-09-24 18:47:32
|
Revision: 1411 http://orm.svn.sourceforge.net/orm/?rev=1411&view=rev Author: mcurland Date: 2009-09-24 18:47:24 +0000 (Thu, 24 Sep 2009) Log Message: ----------- * Handle extension load failure by removing unsupported extension, revert to previous state if the extension manager fails to load the new extension. refs #398 * Fix error with dynamic changes not producing an ObjectifyingInstanceRequiredError. Switching from an internal identifier to an external supertype identifier does not create an error present on reload. refs #374 Modified Paths: -------------- trunk/ORMModel/ObjectModel/SamplePopulation.cs trunk/ORMModel/Resources/ResourceStringsGenerator.cs trunk/ORMModel/Resources/ResourceStringsGenerator.xml trunk/ORMModel/ShapeModel/ORMDiagram.resx trunk/ORMModel/Shell/ExtensionManager.cs trunk/ORMModel/Shell/ORMDocData.cs trunk/ORMModel/Shell/ORMPackage.cs Modified: trunk/ORMModel/ObjectModel/SamplePopulation.cs =================================================================== --- trunk/ORMModel/ObjectModel/SamplePopulation.cs 2009-09-16 07:45:45 UTC (rev 1410) +++ trunk/ORMModel/ObjectModel/SamplePopulation.cs 2009-09-24 18:47:24 UTC (rev 1411) @@ -1670,7 +1670,8 @@ Role unaryRole = null; ObjectifiedUnaryRole objectifiedUnaryRole = null; if (!deletedLink && - null != (pid = entityType.PreferredIdentifier) && + null != (pid = entityType.ResolvedPreferredIdentifier) && + pid.PreferredIdentifierFor == entityType && pid.IsInternal && 1 == (pidFactTypes = pid.FactTypeCollection).Count && ((identifierFactType = pidFactTypes[0]) == factType || Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.cs =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2009-09-16 07:45:45 UTC (rev 1410) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2009-09-24 18:47:24 UTC (rev 1411) @@ -2660,6 +2660,22 @@ return ResourceStrings.GetString(ResourceManagers.Diagram, "MessageBox.FileFormatUpgrade.Message"); } } + /// <summary>The message shown when extensions are automatically removed from a file. Replacements: {0}=file name, {1}=list of unrecognized extensions.</summary> + public static string UnrecognizedExtensionsStrippedMessage + { + get + { + return ResourceStrings.GetString(ResourceManagers.Diagram, "MessageBox.UnrecognizedExtensionsStripped.Message"); + } + } + /// <summary>The header for the message displayed if a set of extensions fails to correctly reload.</summary> + public static string RevertExtensionsMessage + { + get + { + return ResourceStrings.GetString(ResourceManagers.Diagram, "MessageBox.RevertExtensions.Message"); + } + } /// <summary>The name of the transaction that auto-fixes implied and duplicate internal constraints.</summary> public static string RemoveImpliedInternalUniquenessConstraintsTransactionName { Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.xml =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2009-09-16 07:45:45 UTC (rev 1410) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2009-09-24 18:47:24 UTC (rev 1411) @@ -382,6 +382,8 @@ <ResourceString name="ImpliedInternalConstraintFixMessage" model="Diagram" resourceName="MessageBox.ImpliedInternalUniquenessConstraint.Message"/> <ResourceString name="FinalShapeDeletionMessage" model="Diagram" resourceName="MessageBox.FinalShapeDeletion.Message"/> <ResourceString name="FileFormatUpgradeMessage" model="Diagram" resourceName="MessageBox.FileFormatUpgrade.Message"/> + <ResourceString name="UnrecognizedExtensionsStrippedMessage" model="Diagram" resourceName="MessageBox.UnrecognizedExtensionsStripped.Message"/> + <ResourceString name="RevertExtensionsMessage" model="Diagram" resourceName="MessageBox.RevertExtensions.Message"/> <ResourceString name="RemoveImpliedInternalUniquenessConstraintsTransactionName" model="Model" resourceName="FactType.RemoveImpliedInternalUniquenessConstraints.TransactionName"/> <ResourceString name="AlignShapesTransactionName" model="Diagram" resourceName="AlignShapes.TransactionName"/> <ResourceString name="AutoLayoutTransactionName" model="Diagram" resourceName="AutoLayout.TransactionName"/> Modified: trunk/ORMModel/ShapeModel/ORMDiagram.resx =================================================================== --- trunk/ORMModel/ShapeModel/ORMDiagram.resx 2009-09-16 07:45:45 UTC (rev 1410) +++ trunk/ORMModel/ShapeModel/ORMDiagram.resx 2009-09-24 18:47:24 UTC (rev 1411) @@ -515,6 +515,10 @@ <value xml:space="preserve">Interpret Fact Editor Line</value> <comment xml:space="preserve">The transaction name used for changes made in response to committing a modified line in the fact editor. The text appears in the undo dropdown in the VS IDE.</comment> </data> + <data name="MessageBox.RevertExtensions.Message"> + <value xml:space="preserve">Restoring previous model state, loading new extensions faileds with exception:
</value> + <comment xml:space="preserve">The header for the message displayed if a set of extensions fails to correctly reload.</comment> + </data> <data name="MessageBox.ImpliedInternalUniquenessConstraint.Message"> <value xml:space="preserve">One or more of the internal uniqueness constraints are implied by other internal uniqueness constraints. Do you wish to remove the implied constraints?</value> <comment xml:space="preserve">The message for the auto-fix implied internal uniqueness constraint message box.</comment> @@ -527,7 +531,11 @@ <value xml:space="preserve">The final shape corresponding to this element is being deleted. Delete the underlying '{0}' element '{1}' as well?</value> <comment xml:space="preserve">The message for the prompt to delete an element from the model when the final shape representing it is delete. Replacement field 0 gets the class name and 1 the component name.</comment> </data> - <data name="ModelErrorDisplayFilterChange.TransactionName"> + <data name="MessageBox.UnrecognizedExtensionsStripped.Message"> + <value xml:space="preserve">The file format of '{0}' contains unsupported extensions.
Data associated with extension(s) '{1}' has been removed.
Should the 'Save' command be disabled to preserve the original file contents? The 'Save As' command will remain enabled.</value> + <comment xml:space="preserve">The message shown when extensions are automatically removed from a file. Replacements: {0}=file name, {1}=list of unrecognized extensions.</comment> + </data> + <data name="ModelErrorDisplayFilterChange.TransactionName"> <value xml:space="preserve">Change Error Display</value> <comment xml:space="preserve">The transaction name used by the model error display filter dialog when a filter is changed. The text appears in the undo dropdown in the VS IDE.</comment> </data> Modified: trunk/ORMModel/Shell/ExtensionManager.cs =================================================================== --- trunk/ORMModel/Shell/ExtensionManager.cs 2009-09-16 07:45:45 UTC (rev 1410) +++ trunk/ORMModel/Shell/ExtensionManager.cs 2009-09-24 18:47:24 UTC (rev 1411) @@ -3,7 +3,7 @@ * Natural Object-Role Modeling Architect for Visual Studio * * * * Copyright \xA9 Neumont University. All rights reserved. * -* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * +* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * * * * The use and distribution terms for this software are covered by the * * Common Public License 1.0 (http://opensource.org/licenses/cpl) which * @@ -70,7 +70,8 @@ public static void ShowDialog(IServiceProvider serviceProvider, ORMDesignerDocData docData) { ExtensionManager extensionManager = new ExtensionManager(docData.Store); - if (extensionManager.ShowDialog(Utility.GetDialogOwnerWindow(serviceProvider)) == DialogResult.OK) + IWin32Window dialogOwner = Utility.GetDialogOwnerWindow(serviceProvider); + if (extensionManager.ShowDialog(dialogOwner) == DialogResult.OK) { // TODO: Prompt the user to make sure they really want us to start deleting stuff... @@ -87,24 +88,29 @@ // secondary extensions back on. ORMDesignerPackage.VerifyRequiredExtensions(ref checkedTypes); - Stream stream = null; + Stream currentStream = null; + Stream newStream = null; try { Object streamObj; (docData as EnvDTE.IExtensibleObject).GetAutomationObject("ORMXmlStream", null, out streamObj); - stream = streamObj as Stream; + currentStream = streamObj as Stream; - Debug.Assert(stream != null); + Debug.Assert(currentStream != null); - stream = CleanupStream(stream, ORMDesignerPackage.StandardDomainModels, checkedTypes.Values); - docData.ReloadFromStream(stream); + newStream = CleanupStream(currentStream, ORMDesignerPackage.StandardDomainModels, checkedTypes.Values, null); + docData.ReloadFromStream(newStream, currentStream); } finally { - if (stream != null) + if (currentStream != null) { - stream.Dispose(); + currentStream.Dispose(); } + if (newStream != null) + { + newStream.Dispose(); + } } } } @@ -124,11 +130,11 @@ /// <summary> /// Default Constructor for the <see cref="ExtensionManagerUtility"/>. /// </summary> - /// <param name="namespaces">An array of available namespaces.</param> - public ExtensionManagerUtility(string[] namespaces) + /// <param name="sortedNamespaces">An array of available namespaces. The array should be sorted with the + /// default string sort.</param> + public ExtensionManagerUtility(string[] sortedNamespaces) { - myNamespaces = namespaces; - Array.Sort<string>(namespaces); + myNamespaces = sortedNamespaces; myLastIdRemovalPhase = -1; } /// <summary> @@ -243,8 +249,12 @@ /// <param name="stream">The file stream that contains the ORM file.</param> /// <param name="standardTypes">The standard models that are not loaded as extensions</param> /// <param name="extensionTypes">A collection of extension types.</param> + /// <param name="unrecognizedNamespaces">An editable list of unrecognized namespaces. If this is set, + /// the namespaces will be verified after secondary namespaces from the extension types are validated. + /// If no remaining unrecognized namespaces are left after validation, then the method will return null. + /// Recognized namespaces will be removed from the list.</param> /// <returns>The cleaned stream.</returns> - public static Stream CleanupStream(Stream stream, ICollection<Type> standardTypes, ICollection<ORMExtensionType> extensionTypes) + public static Stream CleanupStream(Stream stream, ICollection<Type> standardTypes, ICollection<ORMExtensionType> extensionTypes, IList<string> unrecognizedNamespaces) { MemoryStream outputStream = new MemoryStream((int)stream.Length); XsltArgumentList argList = new XsltArgumentList(); @@ -295,6 +305,21 @@ namespaces[++namespaceIndex] = currentAttribute[j]; } } + Array.Sort<string>(namespaces); + if (unrecognizedNamespaces != null) + { + for (int i = unrecognizedNamespaces.Count - 1; i >= 0; --i) + { + if (Array.BinarySearch<string>(namespaces, unrecognizedNamespaces[i]) >= 0) + { + unrecognizedNamespaces.RemoveAt(i); + } + } + if (unrecognizedNamespaces.Count == 0) + { + return null; + } + } argList.AddExtensionObject("urn:schemas-neumont-edu:ORM:ExtensionManagerUtility", new ExtensionManagerUtility(namespaces)); XslCompiledTransform transform = GetExtensionStripperTransform(); Modified: trunk/ORMModel/Shell/ORMDocData.cs =================================================================== --- trunk/ORMModel/Shell/ORMDocData.cs 2009-09-16 07:45:45 UTC (rev 1410) +++ trunk/ORMModel/Shell/ORMDocData.cs 2009-09-24 18:47:24 UTC (rev 1411) @@ -3,7 +3,7 @@ * Natural Object-Role Modeling Architect for Visual Studio * * * * Copyright \xA9 Neumont University. All rights reserved. * -* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * +* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * * * * The use and distribution terms for this software are covered by the * * Common Public License 1.0 (http://opensource.org/licenses/cpl) which * @@ -18,27 +18,28 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; using System.Xml; +using System.Xml.Schema; +using EnvDTE; using Microsoft.VisualStudio; using Microsoft.VisualStudio.Modeling; using Microsoft.VisualStudio.Modeling.Shell; using Microsoft.VisualStudio.Modeling.Diagrams; +using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; -using ORMSolutions.ORMArchitect.Framework.Shell; using ORMSolutions.ORMArchitect.Core.ObjectModel; using ORMSolutions.ORMArchitect.Core.ShapeModel; using ORMSolutions.ORMArchitect.Framework; -using EnvDTE; -using System.Xml.Schema; -using System.Collections.ObjectModel; +using ORMSolutions.ORMArchitect.Framework.Shell; using ORMSolutions.ORMArchitect.Framework.Shell.DynamicSurveyTreeGrid; -using System.Runtime.InteropServices; -using Microsoft.VisualStudio.Shell; -using System.Windows.Forms; namespace ORMSolutions.ORMArchitect.Core.Shell { @@ -60,6 +61,8 @@ SaveDisabled = 8, ErrorDisplayModified = 0x10, UndoStackRemoved = 0x20, + RethrowLoadDocDataException = 0x40, + IgnoreDocumentReloading = 0x80, // Other flags here, add instead of lots of bool variables } private PrivateFlags myFlags; @@ -160,16 +163,66 @@ /// <summary> /// Reload this document from a <see cref="Stream"/> instead of from a file. /// </summary> - /// <param name="stream">The <see cref="Stream"/> to load</param> - public void ReloadFromStream(Stream stream) + /// <param name="newStream">The <see cref="Stream"/> to load</param> + /// <param name="fallbackStream">If <paramref name="newStream"/> fails to load, then + /// reload this stream instead.</param> + public void ReloadFromStream(Stream newStream, Stream fallbackStream) { - myFileStream = stream; + myFileStream = newStream; // This calls into LoadDocData(string, bool) after doing necessary cleanup - ReloadDocData((uint)_VSRELOADDOCDATA.RDD_RemoveUndoStack); + IServiceProvider serviceProvider; + if (fallbackStream == null) + { + ReloadDocData((uint)_VSRELOADDOCDATA.RDD_RemoveUndoStack); + } + else + { + SetFlag(PrivateFlags.RethrowLoadDocDataException, true); + try + { + ReloadDocData((uint)_VSRELOADDOCDATA.RDD_RemoveUndoStack); + } + catch (Exception ex) + { + SetFlag(PrivateFlags.RethrowLoadDocDataException, false); + SetFlag(PrivateFlags.IgnoreDocumentReloading, true); + fallbackStream.Position = 0; + myFileStream = fallbackStream; + ReloadDocData((uint)_VSRELOADDOCDATA.RDD_RemoveUndoStack); + if (null != (serviceProvider = ServiceProvider)) + { + StringBuilder builder = new StringBuilder(ResourceStrings.RevertExtensionsMessage); + const string offset = "\r\n"; + Exception messageException = ex; + while (messageException != null) + { + string message = messageException.Message; + if (!string.IsNullOrEmpty(message)) + { + builder.Append(offset); + builder.Append(message); + } + messageException = messageException.InnerException; + } - // The document now has no undo stack, but we need it to display as dirty + VsShellUtilities.ShowMessageBox( + serviceProvider, + builder.ToString(), + ResourceStrings.PackageOfficialName, + OLEMSGICON.OLEMSGICON_INFO, + OLEMSGBUTTON.OLEMSGBUTTON_OK, + OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); + } + } + finally + { + SetFlag(PrivateFlags.RethrowLoadDocDataException, false); + SetFlag(PrivateFlags.IgnoreDocumentReloading, false); + } + } + + // The document now has no undo stack, but we need it to display it as dirty SetFlag(PrivateFlags.UndoStackRemoved, true); - IServiceProvider serviceProvider; uint cookie; IVsUIShell shell; if (null != (serviceProvider = base.ServiceProvider) && @@ -180,6 +233,29 @@ } } /// <summary> + /// Enable reloading of the original stream during a failed attempt + /// to modify extensions. + /// </summary> + protected override void OnDocumentReloading(EventArgs e) + { + if (!GetFlag(PrivateFlags.IgnoreDocumentReloading)) + { + base.OnDocumentReloading(e); + } + } + /// <summary> + /// Enable reloading of the original stream during a failed attempt + /// to modify extensions. + /// </summary> + protected override void HandleLoadDocDataException(string fileName, Exception exception, bool isReload) + { + if (GetFlag(PrivateFlags.RethrowLoadDocDataException)) + { + throw exception; + } + base.HandleLoadDocDataException(fileName, exception, isReload); + } + /// <summary> /// See the <see cref="LoadDocData"/> method. /// </summary> /// <param name="fileName">The file name that we pass to <see cref="ModelingDocData.LoadDocData"/>.</param> @@ -236,12 +312,14 @@ // Convert early so we can accurately check extension elements int retVal = 0; bool dontSave = false; + List<string> unrecognizedNamespaces = null; ORMDesignerSettings settings = ORMDesignerPackage.DesignerSettings; using (Stream convertedStream = settings.ConvertStream(inputStream, ServiceProvider)) { dontSave = convertedStream != null; Stream stream = dontSave ? convertedStream : inputStream; myFileStream = stream; + Stream namespaceStrippedStream = null; try { XmlReaderSettings readerSettings = new XmlReaderSettings(); @@ -272,6 +350,10 @@ } documentExtensions[URI] = extensionType.Value; } + else + { + (unrecognizedNamespaces ?? (unrecognizedNamespaces = new List<string>())).Add(URI); + } } } } while (reader.MoveToNextAttribute()); @@ -279,11 +361,74 @@ } } ORMDesignerPackage.VerifyRequiredExtensions(ref documentExtensions); + Stream unstrippedNamespaceStream = stream; + if (unrecognizedNamespaces != null) + { + stream.Position = 0; + namespaceStrippedStream = ExtensionManager.CleanupStream(stream, ORMDesignerPackage.StandardDomainModels, documentExtensions.Values, unrecognizedNamespaces); + if (namespaceStrippedStream != null) + { + dontSave = true; + stream = namespaceStrippedStream; + myFileStream = namespaceStrippedStream; + } + else + { + unrecognizedNamespaces = null; + } + } myExtensionDomainModels = documentExtensions; stream.Position = 0; - - retVal = base.LoadDocData(fileName, isReload); + try + { + retVal = base.LoadDocData(fileName, isReload); + } + catch (TypeInitializationException ex) + { + // If the type that failed to load is an extensions, then remove it from + // the list of available extensions and try again. + if (documentExtensions != null) + { + string typeName = ex.TypeName; + foreach (KeyValuePair<string, ORMExtensionType> pair in documentExtensions) + { + Type testType = pair.Value.Type; + if (testType.FullName == typeName) + { + if (ORMDesignerPackage.CustomExtensionUnavailable(testType)) + { + // If the unloadable type is a registered extensions, then + // we now have an additional namespace element that will not + // load correctly. Recurse on this function with the stream + // before any extensions namespace were stripped so that we can + // see all stripped namespaces in the final message. Obviously, + // this repeats some processing we've already done, but this is + // very much an exception case, and the additional minor performance + // hit is minimal compared with the user annoyance at potentially + // seeing multiple error displays. + Exception innerException = ex.InnerException; + string message; + if (innerException != null && + !string.IsNullOrEmpty(message = innerException.Message)) + { + VsShellUtilities.ShowMessageBox( + ServiceProvider, + message, + ResourceStrings.PackageOfficialName, + OLEMSGICON.OLEMSGICON_INFO, + OLEMSGBUTTON.OLEMSGBUTTON_OK, + OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); + } + unstrippedNamespaceStream.Position = 0; + return LoadDocDataFromStream(fileName, true, unstrippedNamespaceStream); + } + break; + } + } + } + throw; + } // HACK: After the file is loaded and the load transaction has committed, commit a new transaction. // For some reason this seems to fix various line routing issues (including the lines not showing up). @@ -300,6 +445,10 @@ finally { myFileStream = null; + if (namespaceStrippedStream != null) + { + namespaceStrippedStream.Dispose(); + } } } if (dontSave) @@ -317,10 +466,35 @@ } if (dontSave) { + string message; + CultureInfo culture = CultureInfo.CurrentCulture; + int unrecognizedCount; + if (unrecognizedNamespaces != null && + 0 != (unrecognizedCount = unrecognizedNamespaces.Count)) + { + string namespaceReplacement = unrecognizedNamespaces[0]; + if (unrecognizedCount > 1) + { + string separator = culture.TextInfo.ListSeparator; + if (!char.IsWhiteSpace(separator, separator.Length - 1)) + { + separator += " "; + } + for (int i = 1; i < unrecognizedCount; ++i) + { + namespaceReplacement += separator + unrecognizedNamespaces[i]; + } + } + message = string.Format(culture, ResourceStrings.UnrecognizedExtensionsStrippedMessage, fileName, namespaceReplacement); + } + else + { + message = string.Format(culture, ResourceStrings.FileFormatUpgradeMessage, fileName); + } // The disabled save is leading to data loss, prompt the user dontSave = (int)DialogResult.Yes == VsShellUtilities.ShowMessageBox( ServiceProvider, - string.Format(CultureInfo.CurrentCulture, ResourceStrings.FileFormatUpgradeMessage, fileName), + message, ResourceStrings.PackageOfficialName, OLEMSGICON.OLEMSGICON_QUERY, OLEMSGBUTTON.OLEMSGBUTTON_YESNO, @@ -883,19 +1057,34 @@ } Object streamObj; (myDocData as EnvDTE.IExtensibleObject).GetAutomationObject("ORMXmlStream", null, out streamObj); - Stream stream = streamObj as Stream; + Stream currentStream = streamObj as Stream; + Stream newStream = null; - Debug.Assert(stream != null); + Debug.Assert(currentStream != null); - ORMDesignerPackage.VerifyRequiredExtensions(ref requestedExtensions); - ICollection<ORMExtensionType> allExtensions = requestedExtensions.Values; - if (nonRequestedLoadedExtensions != null) + try { - nonRequestedLoadedExtensions.AddRange(allExtensions); - allExtensions = nonRequestedLoadedExtensions; + ORMDesignerPackage.VerifyRequiredExtensions(ref requestedExtensions); + ICollection<ORMExtensionType> allExtensions = requestedExtensions.Values; + if (nonRequestedLoadedExtensions != null) + { + nonRequestedLoadedExtensions.AddRange(allExtensions); + allExtensions = nonRequestedLoadedExtensions; + } + newStream = ExtensionManager.CleanupStream(currentStream, ORMDesignerPackage.StandardDomainModels, allExtensions, null); + myDocData.ReloadFromStream(newStream, currentStream); } - stream = ExtensionManager.CleanupStream(stream, ORMDesignerPackage.StandardDomainModels, allExtensions); - myDocData.ReloadFromStream(stream); + finally + { + if (currentStream != null) + { + currentStream.Dispose(); + } + if (newStream != null) + { + newStream.Dispose(); + } + } } } } Modified: trunk/ORMModel/Shell/ORMPackage.cs =================================================================== --- trunk/ORMModel/Shell/ORMPackage.cs 2009-09-16 07:45:45 UTC (rev 1410) +++ trunk/ORMModel/Shell/ORMPackage.cs 2009-09-24 18:47:24 UTC (rev 1411) @@ -1074,6 +1074,57 @@ return retVal; } /// <summary> + /// A custom extension has failed to load. Remove the extension from the list + /// of available extensions. + /// </summary> + /// <param name="unvailableExtensionType">The extension <see cref="Type"/>The + /// extension that has failed to load.</param> + /// <returns><see langword="true"/> if the extension was successfully removed.</returns> + public static bool CustomExtensionUnavailable(Type unvailableExtensionType) + { + IDictionary<string, ORMExtensionType> customExtensions = GetAvailableCustomExtensions(); + if (customExtensions != null) + { + foreach (KeyValuePair<string, ORMExtensionType> pair in customExtensions) + { + ORMExtensionType extensionType = pair.Value; + if (extensionType.Type == unvailableExtensionType) + { + customExtensions.Remove(pair.Key); + ORMDesignerPackage package = mySingleton; // Note that we must have a singleton, or we would have no custom extensions + IDictionary<Guid, string> extensionIdMap = package.myExtensionIdToExtensionNameMap; + if (extensionIdMap != null && extensionIdMap.ContainsKey(extensionType.DomainModelId)) + { + extensionIdMap.Remove(extensionType.DomainModelId); + } + string[] autoloadExtensions = package.myAutoLoadExtensions; + int autoloadExtensionLength; + int removeExtensionIndex; + if (autoloadExtensions != null && + 0 != (autoloadExtensionLength = autoloadExtensions.Length) && + -1 != (removeExtensionIndex = Array.IndexOf<string>(autoloadExtensions, extensionType.NamespaceUri))) + { + string[] newExtensions = new string[autoloadExtensionLength - 1]; + if (autoloadExtensionLength > 1) + { + for (int i = 0; i < removeExtensionIndex; ++i) + { + newExtensions[i] = autoloadExtensions[i]; + } + for (int i = removeExtensionIndex + 1; i < autoloadExtensionLength; ++i) + { + newExtensions[i - 1] = autoloadExtensions[i]; + } + } + package.myAutoLoadExtensions = newExtensions; + } + return true; + } + } + } + return false; + } + /// <summary> /// Helper method for <see cref="GetAvailableCustomExtensions"/> /// </summary> private static void LoadAvailableCustomExtensions(RegistryKey rootKey, IDictionary<string, ORMExtensionType> extensionMap) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2009-10-23 17:36:00
|
Revision: 1415 http://orm.svn.sourceforge.net/orm/?rev=1415&view=rev Author: mcurland Date: 2009-10-23 17:35:51 +0000 (Fri, 23 Oct 2009) Log Message: ----------- Add 'Select In Model Browser' command to complement other selection commands. fixes #400 * Switched DiagramSurvey nodes to use ISurveyNodeReference instead of IRepresentModelElements, allowing model browser to track DiagramNode/Diagram relationships. * ModelBrowser jumps to a reference if a primary location is not available. Modified Paths: -------------- trunk/ORMModel/Framework/Shell/DiagramSurvey.cs trunk/ORMModel/Framework/Shell/DynamicSurveyTreeGrid/MainList.cs trunk/ORMModel/Resources/ResourceStringsGenerator.cs trunk/ORMModel/Resources/ResourceStringsGenerator.xml trunk/ORMModel/ShapeModel/ORMDiagram.resx trunk/ORMModel/Shell/ORMCommandSet.cs trunk/ORMModel/Shell/ORMDesignerCommandManager.cs trunk/ORMModel/Shell/ORMDocDataServices.cs trunk/ORMModel/Shell/ORMDocView.cs trunk/ORMModel/Shell/PackageResources/PkgCmd.vsct Modified: trunk/ORMModel/Framework/Shell/DiagramSurvey.cs =================================================================== --- trunk/ORMModel/Framework/Shell/DiagramSurvey.cs 2009-10-17 01:56:46 UTC (rev 1414) +++ trunk/ORMModel/Framework/Shell/DiagramSurvey.cs 2009-10-23 17:35:51 UTC (rev 1415) @@ -2,7 +2,7 @@ /**************************************************************************\ * Natural Object-Role Modeling Architect for Visual Studio * * * -* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * +* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * * * * The use and distribution terms for this software are covered by the * * Common Public License 1.0 (http://opensource.org/licenses/cpl) which * @@ -43,9 +43,6 @@ /// </summary> public static readonly global::System.Guid DomainModelId = new global::System.Guid(0x52222B4A, 0x8155, 0x43E9, 0x8e, 0xc9, 0x66, 0xeb, 0x05, 0x60, 0x09, 0xf3); #endregion // Public constants - #region Member Variables - private Dictionary<Diagram, DiagramNode> myDiagramToNodeMap; - #endregion // Member Variables #region Constructor /// <summary> /// Required constructor for a domain model @@ -75,7 +72,7 @@ /// knowing about it, so we cannot implement anything directly on diagram. Use /// a thin wrapper class to put the diagram in the tree. /// </summary> - private sealed class DiagramNode : ISurveyNode, IAnswerSurveyQuestion<DiagramSurveyType>, IAnswerSurveyDynamicQuestion<DiagramGlyphSurveyType>, IRepresentModelElements + private sealed class DiagramNode : ISurveyNode, IAnswerSurveyQuestion<DiagramSurveyType>, IAnswerSurveyDynamicQuestion<DiagramGlyphSurveyType>, ISurveyNodeReference { #region Member variables and constructors private readonly Diagram myDiagram; @@ -156,12 +153,33 @@ } } #endregion // ISurveyNode Implementation - #region IRepresentModelElements Implementation - ModelElement[] IRepresentModelElements.GetRepresentedElements() + #region ISurveyNodeReference Implementation + object ISurveyNodeReference.SurveyNodeReferenceReason { - return new ModelElement[] { myDiagram }; + get + { + return typeof(DiagramNode); + } } - #endregion // IRepresentModelElements Implementation + SurveyNodeReferenceOptions ISurveyNodeReference.SurveyNodeReferenceOptions + { + get + { + return SurveyNodeReferenceOptions.BlockLinkDisplay | SurveyNodeReferenceOptions.BlockTargetNavigation; + } + } + bool ISurveyNodeReference.UseSurveyNodeReferenceAnswer(Type questionType, ISurveyDynamicValues dynamicValues, int answer) + { + return false; + } + object IElementReference.ReferencedElement + { + get + { + return myDiagram; + } + } + #endregion // ISurveyNodeReference implementation } #endregion // DiagramNode class #region ISurveyNodeProvider Implementation @@ -173,16 +191,13 @@ { if (expansionKey == null) { - Dictionary<Diagram, DiagramNode> diagramToNodeMap = myDiagramToNodeMap ?? (myDiagramToNodeMap = new Dictionary<Diagram, DiagramNode>()); Store store = Store; Partition defaultPartition = store.DefaultPartition; foreach (Diagram diagram in Store.ElementDirectory.FindElements<Diagram>(true)) { if (diagram.Partition == defaultPartition) { - DiagramNode node = new DiagramNode(diagram); - diagramToNodeMap.Add(diagram, node); - yield return node; + yield return new DiagramNode(diagram); } } } @@ -215,10 +230,6 @@ eventManager.AddOrRemoveHandler(classInfo, new EventHandler<ElementDeletedEventArgs>(DiagramRemovedEvent), action); DomainPropertyInfo propertyInfo = dataDirectory.FindDomainProperty(Diagram.NameDomainPropertyId); eventManager.AddOrRemoveHandler(propertyInfo, new EventHandler<ElementPropertyChangedEventArgs>(DiagramRenamedEvent), action); - if (action == EventHandlerAction.Remove) - { - myDiagramToNodeMap = null; - } } } #endregion // IModelingEventSubscriber Implementation @@ -232,43 +243,30 @@ (store = element.Store).DefaultPartition == element.Partition && null != (eventNotify = (store as IFrameworkServices).NotifySurveyElementChanged)) { - Diagram diagram = (Diagram)element; - DiagramNode node = new DiagramNode(diagram); - (myDiagramToNodeMap ?? (myDiagramToNodeMap = new Dictionary<Diagram, DiagramNode>())).Add(diagram, node); - eventNotify.ElementAdded(node, null); + eventNotify.ElementAdded(new DiagramNode((Diagram)element), null); } } private void DiagramRemovedEvent(object sender, ElementDeletedEventArgs e) { INotifySurveyElementChanged eventNotify; ModelElement element = e.ModelElement; - Dictionary<Diagram, DiagramNode> nodeMap; - DiagramNode node; - Diagram diagram; Store store; - if (null != (nodeMap = myDiagramToNodeMap) && - (store = element.Store).DefaultPartition == element.Partition && - null != (eventNotify = (store as IFrameworkServices).NotifySurveyElementChanged) && - nodeMap.TryGetValue(diagram = (Diagram)element, out node)) + if ((store = element.Store).DefaultPartition == element.Partition && + null != (eventNotify = (store as IFrameworkServices).NotifySurveyElementChanged)) { - nodeMap.Remove(diagram); - eventNotify.ElementDeleted(node); + eventNotify.ElementReferenceDeleted(element, typeof(DiagramNode), null); } } private void DiagramRenamedEvent(object sender, ElementPropertyChangedEventArgs e) { INotifySurveyElementChanged eventNotify; ModelElement element = e.ModelElement; - Dictionary<Diagram, DiagramNode> nodeMap; - DiagramNode node; Store store; if (!element.IsDeleted && - null != (nodeMap = myDiagramToNodeMap) && (store = element.Store).DefaultPartition == element.Partition && - null != (eventNotify = (store as IFrameworkServices).NotifySurveyElementChanged) && - nodeMap.TryGetValue((Diagram)element, out node)) + null != (eventNotify = (store as IFrameworkServices).NotifySurveyElementChanged)) { - eventNotify.ElementRenamed(node); + eventNotify.ElementReferenceRenamed(element, typeof(DiagramNode), null); } } #endregion // Event handlers Modified: trunk/ORMModel/Framework/Shell/DynamicSurveyTreeGrid/MainList.cs =================================================================== --- trunk/ORMModel/Framework/Shell/DynamicSurveyTreeGrid/MainList.cs 2009-10-17 01:56:46 UTC (rev 1414) +++ trunk/ORMModel/Framework/Shell/DynamicSurveyTreeGrid/MainList.cs 2009-10-23 17:35:51 UTC (rev 1415) @@ -3,7 +3,7 @@ * Natural Object-Role Modeling Architect for Visual Studio * * * * Copyright \xA9 Neumont University. All rights reserved. * -* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * +* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * * * * The use and distribution terms for this software are covered by the * * Common Public License 1.0 (http://opensource.org/licenses/cpl) which * @@ -658,8 +658,9 @@ ISurveyNodeContext nodeContext; object contextElement = null; MainList locatedList; - if (mySurveyTree.myNodeDictionary.TryGetValue(obj, out location) && - null != (locatedList = location.MainList)) + SurveyTree<SurveyContextType> surveyTree = mySurveyTree; + bool haveLocation = surveyTree.myNodeDictionary.TryGetValue(obj, out location); + if (haveLocation && null != (locatedList = location.MainList)) { if (locatedList == this) { @@ -677,6 +678,27 @@ { contextElement = nodeContext.SurveyNodeContext; } + else if (haveLocation) + { + // A reference to the element has been recorded, jump to it instead + LinkedNode<SurveyNodeReference> referenceNodeLink; + if (surveyTree.myReferenceDictionary.TryGetValue(obj, out referenceNodeLink)) + { + SurveyNodeReference referenceNode = referenceNodeLink.Value; + object referenceContext = referenceNode.ContextElement; + if (referenceContext == myContextElement) + { + if (0 <= (nodeIndex = myNodes.BinarySearch(referenceNode.Node, myNodeComparer))) + { + return new LocateObjectData(nodeIndex, 0, (int)TrackingObjectAction.ThisLevel); + } + } + else + { + contextElement = referenceContext; + } + } + } if (contextElement != null) { // This item is in an expansion, see if we can find the context element at this level Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.cs =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2009-10-17 01:56:46 UTC (rev 1414) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2009-10-23 17:35:51 UTC (rev 1415) @@ -2636,6 +2636,14 @@ return ResourceStrings.GetString(ResourceManagers.Model, "ModelError.FactType.ImpliedInternalUniquenessConstraintError.Text"); } } + /// <summary>The message displayed if a selected item cannot be located in the model browser.</summary> + public static string ElementNotInModelBrowserMessage + { + get + { + return ResourceStrings.GetString(ResourceManagers.Diagram, "MessageBox.ElementNotInModelBrowser.Message"); + } + } /// <summary>The message for the auto-fix implied internal uniqueness constraint message box.</summary> public static string ImpliedInternalConstraintFixMessage { Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.xml =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2009-10-17 01:56:46 UTC (rev 1414) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2009-10-23 17:35:51 UTC (rev 1415) @@ -379,6 +379,7 @@ <ResourceString name="ModelErrorFrequencyConstraintExactlyOneError" model="Model" resourceName="ModelError.Constraint.FrequencyConstraintExactlyOneError.Text"/> <ResourceString name="ModelVerbalizationWindowTitle" model="Model" resourceName="ModelVerbalization.WindowTitle"/> <ResourceString name="ModelErrorImpliedInternalUniquenessConstraintError" model="Model" resourceName="ModelError.FactType.ImpliedInternalUniquenessConstraintError.Text"/> + <ResourceString name="ElementNotInModelBrowserMessage" model="Diagram" resourceName="MessageBox.ElementNotInModelBrowser.Message"/> <ResourceString name="ImpliedInternalConstraintFixMessage" model="Diagram" resourceName="MessageBox.ImpliedInternalUniquenessConstraint.Message"/> <ResourceString name="FinalShapeDeletionMessage" model="Diagram" resourceName="MessageBox.FinalShapeDeletion.Message"/> <ResourceString name="FileFormatUpgradeMessage" model="Diagram" resourceName="MessageBox.FileFormatUpgrade.Message"/> Modified: trunk/ORMModel/ShapeModel/ORMDiagram.resx =================================================================== --- trunk/ORMModel/ShapeModel/ORMDiagram.resx 2009-10-17 01:56:46 UTC (rev 1414) +++ trunk/ORMModel/ShapeModel/ORMDiagram.resx 2009-10-23 17:35:51 UTC (rev 1415) @@ -386,17 +386,17 @@ AYABAQYAAYABAQYAAYABAQIAAYABAwIAAYABAQYAAYABAQoAAYABAw0AAQEBAAEBAQABAQGAAQEBgAED AcQBRwGAAQMBwAEDBv8B/AF/Cw== </value> - </data> - <data name="FactEditor.MissingRolePlayerFormatString"> - <value xml:space="preserve">[Missing_{0}]</value> - <comment xml:space="preserve">The format string for a missing role player in the FactEditor. The format string should not use parentheses, which are parsed by the FactEditor as reference modes.</comment> - </data> - <data name="FactEditor.UnqualifiedRolePlayerFormatString"> - <value xml:space="preserve">{0}</value> - <comment xml:space="preserve">The format string for a role player with no () qualifier in the FactEditor. Languages which should not rely on capitalization to delimit ObjectType names should put square braces around this format string.</comment> - </data> - <data name="FactEditor.QualifiedRolePlayerFormatString"> - <value xml:space="preserve">{0}({1})</value> + </data> + <data name="FactEditor.MissingRolePlayerFormatString"> + <value xml:space="preserve">[Missing_{0}]</value> + <comment xml:space="preserve">The format string for a missing role player in the FactEditor. The format string should not use parentheses, which are parsed by the FactEditor as reference modes.</comment> + </data> + <data name="FactEditor.UnqualifiedRolePlayerFormatString"> + <value xml:space="preserve">{0}</value> + <comment xml:space="preserve">The format string for a role player with no () qualifier in the FactEditor. Languages which should not rely on capitalization to delimit ObjectType names should put square braces around this format string.</comment> + </data> + <data name="FactEditor.QualifiedRolePlayerFormatString"> + <value xml:space="preserve">{0}({1})</value> <comment xml:space="preserve">The format string for a role player with a () qualifier in the FactEditor. The qualifier represents either a value type or a reference mode. Languages which should not rely on capitalization to delimit ObjectType names should put square braces around this format string.</comment> </data> <data name="FactEditorColors.Delimiter"> @@ -515,6 +515,10 @@ <value xml:space="preserve">Interpret Fact Editor Line</value> <comment xml:space="preserve">The transaction name used for changes made in response to committing a modified line in the fact editor. The text appears in the undo dropdown in the VS IDE.</comment> </data> + <data name="MessageBox.ElementNotInModelBrowser.Message"> + <value xml:space="preserve">The selected item is not represented in the ORM Model Browser.</value> + <comment xml:space="preserve">The message displayed if a selected item cannot be located in the model browser.</comment> + </data> <data name="MessageBox.RevertExtensions.Message"> <value xml:space="preserve">Restoring previous model state, loading new extensions faileds with exception:
</value> <comment xml:space="preserve">The header for the message displayed if a set of extensions fails to correctly reload.</comment> @@ -531,11 +535,11 @@ <value xml:space="preserve">The final shape corresponding to this element is being deleted. Delete the underlying '{0}' element '{1}' as well?</value> <comment xml:space="preserve">The message for the prompt to delete an element from the model when the final shape representing it is delete. Replacement field 0 gets the class name and 1 the component name.</comment> </data> - <data name="MessageBox.UnrecognizedExtensionsStripped.Message"> - <value xml:space="preserve">The file format of '{0}' contains unsupported extensions.
Data associated with extension(s) '{1}' has been removed.
Should the 'Save' command be disabled to preserve the original file contents? The 'Save As' command will remain enabled.</value> - <comment xml:space="preserve">The message shown when extensions are automatically removed from a file. Replacements: {0}=file name, {1}=list of unrecognized extensions.</comment> - </data> - <data name="ModelErrorDisplayFilterChange.TransactionName"> + <data name="MessageBox.UnrecognizedExtensionsStripped.Message"> + <value xml:space="preserve">The file format of '{0}' contains unsupported extensions.
Data associated with extension(s) '{1}' has been removed.
Should the 'Save' command be disabled to preserve the original file contents? The 'Save As' command will remain enabled.</value> + <comment xml:space="preserve">The message shown when extensions are automatically removed from a file. Replacements: {0}=file name, {1}=list of unrecognized extensions.</comment> + </data> + <data name="ModelErrorDisplayFilterChange.TransactionName"> <value xml:space="preserve">Change Error Display</value> <comment xml:space="preserve">The transaction name used by the model error display filter dialog when a filter is changed. The text appears in the undo dropdown in the VS IDE.</comment> </data> Modified: trunk/ORMModel/Shell/ORMCommandSet.cs =================================================================== --- trunk/ORMModel/Shell/ORMCommandSet.cs 2009-10-17 01:56:46 UTC (rev 1414) +++ trunk/ORMModel/Shell/ORMCommandSet.cs 2009-10-23 17:35:51 UTC (rev 1415) @@ -285,6 +285,10 @@ new EventHandler(OnMenuSelectInDiagramSpy), ORMDesignerCommandIds.SelectInDiagramSpy) ,new DynamicStatusMenuCommand( + new EventHandler(OnStatusSelectInModelBrowser), + new EventHandler(OnMenuSelectInModelBrowser), + ORMDesignerCommandIds.SelectInModelBrowser) + ,new DynamicStatusMenuCommand( new EventHandler(OnStatusSelectInDocumentWindow), new EventHandler(OnMenuSelectInDocumentWindow), ORMDesignerCommandIds.SelectInDocumentWindow) @@ -1109,6 +1113,24 @@ /// <summary> /// Status callback /// </summary> + protected void OnStatusSelectInModelBrowser(object sender, EventArgs e) + { + ORMDesignerCommandManager.OnStatusCommand(sender, CurrentORMView, ORMDesignerCommands.SelectInModelBrowser); + } + /// <summary> + /// Menu handler + /// </summary> + protected void OnMenuSelectInModelBrowser(object sender, EventArgs e) + { + IORMDesignerView designerView = CurrentORMView; + if (designerView != null) + { + designerView.CommandManager.OnMenuSelectInModelBrowser(); + } + } + /// <summary> + /// Status callback + /// </summary> protected void OnStatusSelectInDocumentWindow(object sender, EventArgs e) { ORMDesignerCommandManager.OnStatusCommand(sender, CurrentORMView, ORMDesignerCommands.SelectInDocumentWindow); @@ -1771,6 +1793,10 @@ /// </summary> public static readonly CommandID SelectInDocumentWindow = new CommandID(guidORMDesignerCommandSet, cmdIdSelectInDocumentWindow); /// <summary> + /// Activate the selected display element in the model browser. + /// </summary> + public static readonly CommandID SelectInModelBrowser = new CommandID(guidORMDesignerCommandSet, cmdIdSelectInModelBrowser); + /// <summary> /// Available if free form context commands are supported for the current selection /// </summary> public static readonly CommandID FreeFormCommandList = new CommandID(guidORMDesignerCommandSet, cmdIdFreeFormCommandList); @@ -2058,6 +2084,10 @@ /// </summary> private const int cmdIdIncludeInNewGroup = 0x2931; /// <summary> + /// Activate the selected display element in the model browser. + /// </summary> + private const int cmdIdSelectInModelBrowser = 0x2932; + /// <summary> /// The context menu item for related diagrams, targeted to the diagram spy /// </summary> private const int cmdIdDiagramSpyDiagramList = 0x2d00; Modified: trunk/ORMModel/Shell/ORMDesignerCommandManager.cs =================================================================== --- trunk/ORMModel/Shell/ORMDesignerCommandManager.cs 2009-10-17 01:56:46 UTC (rev 1414) +++ trunk/ORMModel/Shell/ORMDesignerCommandManager.cs 2009-10-23 17:35:51 UTC (rev 1415) @@ -3,7 +3,7 @@ * Natural Object-Role Modeling Architect for Visual Studio * * * * Copyright \xA9 Neumont University. All rights reserved. * -* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * +* Copyright \xA9 ORM Solutions, LLC. All rights reserved. * * * * The use and distribution terms for this software are covered by the * * Common Public License 1.0 (http://opensource.org/licenses/cpl) which * @@ -954,8 +954,8 @@ enabledCommands |= ORMDesignerCommands.IncludeInNewGroup | ORMDesignerCommands.IncludeInGroupList | ORMDesignerCommands.DeleteFromGroupList; } // Turn on standard commands for all selections - visibleCommands |= ORMDesignerCommands.DisplayStandardWindows | ORMDesignerCommands.CopyImage | ORMDesignerCommands.SelectAll | ORMDesignerCommands.ExtensionManager | ORMDesignerCommands.ErrorList | ORMDesignerCommands.ReportGeneratorList | ORMDesignerCommands.FreeFormCommandList; - enabledCommands |= ORMDesignerCommands.DisplayStandardWindows | ORMDesignerCommands.CopyImage | ORMDesignerCommands.SelectAll | ORMDesignerCommands.ExtensionManager | ORMDesignerCommands.ErrorList | ORMDesignerCommands.ReportGeneratorList | ORMDesignerCommands.FreeFormCommandList; + visibleCommands |= ORMDesignerCommands.DisplayStandardWindows | ORMDesignerCommands.CopyImage | ORMDesignerCommands.SelectAll | ORMDesignerCommands.ExtensionManager | ORMDesignerCommands.ErrorList | ORMDesignerCommands.ReportGeneratorList | ORMDesignerCommands.FreeFormCommandList | ORMDesignerCommands.SelectInModelBrowser; + enabledCommands |= ORMDesignerCommands.DisplayStandardWindows | ORMDesignerCommands.CopyImage | ORMDesignerCommands.SelectAll | ORMDesignerCommands.ExtensionManager | ORMDesignerCommands.ErrorList | ORMDesignerCommands.ReportGeneratorList | ORMDesignerCommands.FreeFormCommandList | ORMDesignerCommands.SelectInModelBrowser; } private static void UpdateMoveRoleCommandStatus(FactTypeShape factShape, Role role, ref ORMDesignerCommands visibleCommands, ref ORMDesignerCommands enabledCommands) { @@ -2582,6 +2582,41 @@ } } /// <summary> + /// Select the current item in the model browser window + /// </summary> + public virtual void OnMenuSelectInModelBrowser() + { + IORMToolServices toolServices; + DiagramView designer; + DiagramItem diagramItem; + if (null != (designer = myDesignerView.CurrentDesigner) && + null != (diagramItem = designer.DiagramClientView.Selection.PrimaryItem) && + null != (toolServices = myDesignerView.Store as IORMToolServices)) + { + object targetElement = null; + foreach (object element in diagramItem.RepresentedElements) + { + targetElement = element; + break; + } + if (targetElement != null) + { + if (!(targetElement is Diagram)) + { + targetElement = EditorUtility.ResolveContextInstance(targetElement, false); + } + if (!toolServices.NavigateTo(targetElement, NavigateToWindow.ModelBrowser)) + { + IServiceProvider provider; + if (null != (provider = toolServices.ServiceProvider)) + { + VsShellUtilities.ShowMessageBox(provider, ResourceStrings.ElementNotInModelBrowserMessage, ResourceStrings.PackageOfficialName, OLEMSGICON.OLEMSGICON_INFO, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); + } + } + } + } + } + /// <summary> /// Select the current item in a view of the current document window /// </summary> public virtual void OnMenuSelectInDocumentWindow() Modified: trunk/ORMModel/Shell/ORMDocDataServices.cs =================================================================== --- trunk/ORMModel/Shell/ORMDocDataServices.cs 2009-10-17 01:56:46 UTC (rev 1414) +++ trunk/ORMModel/Shell/ORMDocDataServices.cs 2009-10-23 17:35:51 UTC (rev 1415) @@ -2186,52 +2186,48 @@ VirtualTreeControl treeControl = null; while (element != null) { - if (element is ISurveyNode) + if (treeControl == null) { - // Assume if we're a SurveyNode that it is possible to select the item in the survey tree - if (treeControl == null) + // Make sure a docview associated with the current model is + // active. Otherwise, the model browser will not contain the + // correct tree. + if (!haveCurrentDesigner) { - // Make sure a docview associated with the current model is - // active. Otherwise, the model browser will not contain the - // correct tree. - if (!haveCurrentDesigner) + haveCurrentDesigner = true; + GetCurrentDesigner(ref currentDocView, ref currentDesigner); + } + if (currentDocView == null || currentDocView.DocData != this) + { + if (null == ActivateView(null)) { - haveCurrentDesigner = true; - GetCurrentDesigner(ref currentDocView, ref currentDesigner); - } - if (currentDocView == null || currentDocView.DocData != this) - { - if (null == ActivateView(null)) - { - return false; - } - } - // UNDONE: See if we can get the tree control without forcing the window to show - // This is safe, but gives weird results if the initial item cannot be found. - ORMModelBrowserToolWindow browserWindow; - SurveyTreeContainer treeContainer; - if (null != (browserWindow = ORMDesignerPackage.ORMModelBrowserWindow)) - { - browserWindow.Show(); - if (null != (treeContainer = browserWindow.Window as SurveyTreeContainer)) - { - treeControl = treeContainer.TreeControl; - } - } - if (null == treeControl) - { return false; } } - if (treeControl.SelectObject(null, element, (int)ObjectStyle.TrackingObject, 0)) + // UNDONE: See if we can get the tree control without forcing the window to show + // This is safe, but gives weird results if the initial item cannot be found. + ORMModelBrowserToolWindow browserWindow; + SurveyTreeContainer treeContainer; + if (null != (browserWindow = ORMDesignerPackage.ORMModelBrowserWindow)) { - if (modelError != null) + browserWindow.Show(); + if (null != (treeContainer = browserWindow.Window as SurveyTreeContainer)) { - ModelErrorActivationService.ActivateError(element, modelError); + treeControl = treeContainer.TreeControl; } - return true; } + if (null == treeControl) + { + return false; + } } + if (treeControl.SelectObject(null, element, (int)ObjectStyle.TrackingObject, 0)) + { + if (modelError != null) + { + ModelErrorActivationService.ActivateError(element, modelError); + } + return true; + } ModelElement currentElement = element; element = null; // If we could not select the current element, then go up the aggregation chain Modified: trunk/ORMModel/Shell/ORMDocView.cs =================================================================== --- trunk/ORMModel/Shell/ORMDocView.cs 2009-10-17 01:56:46 UTC (rev 1414) +++ trunk/ORMModel/Shell/ORMDocView.cs 2009-10-23 17:35:51 UTC (rev 1415) @@ -268,6 +268,10 @@ /// </summary> DeleteFromGroupList = 1L << 52, /// <summary> + /// Activate the current selection in the model browser window + /// </summary> + SelectInModelBrowser = 1L << 53, + /// <summary> /// Mask field representing individual delete commands /// </summary> Delete = DeleteObjectType | DeleteFactType | DeleteConstraint | DeleteRole | DeleteModelNote | DeleteModelNoteReference | DeleteGroup | RemoveFromGroup, Modified: trunk/ORMModel/Shell/PackageResources/PkgCmd.vsct =================================================================== --- trunk/ORMModel/Shell/PackageResources/PkgCmd.vsct 2009-10-17 01:56:46 UTC (rev 1414) +++ trunk/ORMModel/Shell/PackageResources/PkgCmd.vsct 2009-10-23 17:35:51 UTC (rev 1415) @@ -590,6 +590,16 @@ </Strings> </Button> + <Button guid="guidORMDesignerCommandSet" id="cmdIdSelectInModelBrowser" priority="0x0500" type="Button"> + <Parent guid="guidORMDesignerCommandSet" id="groupIdSelectCommands"/> + <Icon guid="guidORMToolWindowIcons" id="bmpIdToolWindowModelBrowser"/> + <CommandFlag>DefaultInvisible</CommandFlag> + <CommandFlag>DynamicVisibility</CommandFlag> + <Strings> + <ButtonText>Select in M&odel Browser</ButtonText> + </Strings> + </Button> + <Button guid="guidORMDesignerCommandSet" id="cmdIdCopyImage" priority="0x0200" type="Button"> <Parent guid="guidORMDesignerCommandSet" id="groupIdModelCommands"/> <Icon guid="guidOfficeIcon" id="msotcidCamera"/> @@ -1013,6 +1023,7 @@ <IDSymbol value="0x292F" name="cmdIdSelectInDocumentWindow"/> <IDSymbol value="0x2930" name="cmdIdIncludeInGroup"/> <IDSymbol value="0x2931" name="cmdIdIncludeInNewGroup"/> + <IDSymbol value="0x2932" name="cmdIdSelectInModelBrowser"/> <!-- Large ranges for dynamic commands, keep single commands in the 0x29__ range --> <IDSymbol value="0x2A00" name="cmdIdErrorList"/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2009-12-31 07:19:43
|
Revision: 1424 http://orm.svn.sourceforge.net/orm/?rev=1424&view=rev Author: mcurland Date: 2009-12-31 07:19:36 +0000 (Thu, 31 Dec 2009) Log Message: ----------- Miscellaneous fixes: * Changes in [1392] resulted in no object type name for an objectified fact type off the toolbox. refs #321 * FactEditor commit with object type name of objectified fact type selected repositioned the object type name shape to the default location. * Verbalize list separator 'and' and 'or' instances uses the logicalOperator style (bold blue) instead of the listSeparator style (non-bold window text (generally black)) * Added model browser support for 'Select on Diagram' and 'Select on Diagram Spy' with link elements. * Added defensive code to fix occasional model browser exception due to event order when a referenced element is deleted * Deserialization of duplicate non-empty objectified link elements caused end element mismatch, eliminated remainder of file (can't duplicated with NORMA-saved files, occurred with some externally generated .orm files). * Remove dead ReadingEditor command set code. Reading editor commands are handled by the designer command set. Modified Paths: -------------- trunk/ORMModel/Framework/Shell/DynamicSurveyTreeGrid/MainList.cs trunk/ORMModel/Framework/Shell/SerializationEngine.cs trunk/ORMModel/ObjectModel/VerbalizationCoreSnippets/VerbalizationCoreSnippets.xml trunk/ORMModel/ObjectModel/VerbalizationGenerator.cs trunk/ORMModel/ShapeModel/FactTypeShape.cs trunk/ORMModel/Shell/ORMModelBrowser.cs trunk/ORMModel/Shell/ORMReadingEditor.cs Modified: trunk/ORMModel/Framework/Shell/DynamicSurveyTreeGrid/MainList.cs =================================================================== --- trunk/ORMModel/Framework/Shell/DynamicSurveyTreeGrid/MainList.cs 2009-12-22 08:38:42 UTC (rev 1423) +++ trunk/ORMModel/Framework/Shell/DynamicSurveyTreeGrid/MainList.cs 2009-12-31 07:19:36 UTC (rev 1424) @@ -395,9 +395,15 @@ if (reference != null && null != (referencedElement = reference.ReferencedElement)) { + NodeLocation targetLocation; + if (!surveyTree.myNodeDictionary.TryGetValue(referencedElement, out targetLocation)) + { + // Defensive code to handle callbacks on partially removed references + // resulting from event side effects. + return retVal; + } referenceOptions = reference.SurveyNodeReferenceOptions; filterTargetQuestions = 0 != (referenceOptions & SurveyNodeReferenceOptions.FilterReferencedAnswers); - NodeLocation targetLocation = surveyTree.myNodeDictionary[referencedElement = reference.ReferencedElement]; referenceNode = targetLocation.ElementNode; referenceSurvey = targetLocation.Survey; } Modified: trunk/ORMModel/Framework/Shell/SerializationEngine.cs =================================================================== --- trunk/ORMModel/Framework/Shell/SerializationEngine.cs 2009-12-22 08:38:42 UTC (rev 1423) +++ trunk/ORMModel/Framework/Shell/SerializationEngine.cs 2009-12-31 07:19:36 UTC (rev 1424) @@ -4318,6 +4318,7 @@ if (element == oppositeRolePlayers[i]) { createLink = false; + PassEndElement(reader); break; } } Modified: trunk/ORMModel/ObjectModel/VerbalizationCoreSnippets/VerbalizationCoreSnippets.xml =================================================================== --- trunk/ORMModel/ObjectModel/VerbalizationCoreSnippets/VerbalizationCoreSnippets.xml 2009-12-22 08:38:42 UTC (rev 1423) +++ trunk/ORMModel/ObjectModel/VerbalizationCoreSnippets/VerbalizationCoreSnippets.xml 2009-12-31 07:19:36 UTC (rev 1424) @@ -111,9 +111,9 @@ <Snippet type="IndentedCompoundListFinalSeparator"><![CDATA[<span class="listSeparator">; </span>]]></Snippet> <Snippet type="IndentedCompoundListClose"><![CDATA[</span>]]></Snippet> <Snippet type="IndentedListOpen"><![CDATA[<br/><span class="smallIndent">]]></Snippet> - <Snippet type="IndentedListPairSeparator"><![CDATA[<span class="listSeparator"> and </span><br/>]]></Snippet> - <Snippet type="IndentedListSeparator"><![CDATA[<span class="listSeparator"> and </span><br/>]]></Snippet> - <Snippet type="IndentedListFinalSeparator"><![CDATA[<span class="listSeparator"> and </span><br/>]]></Snippet> + <Snippet type="IndentedListPairSeparator"><![CDATA[<span class="logicalOperator"> and </span><br/>]]></Snippet> + <Snippet type="IndentedListSeparator"><![CDATA[<span class="logicalOperator"> and </span><br/>]]></Snippet> + <Snippet type="IndentedListFinalSeparator"><![CDATA[<span class="logicalOperator"> and </span><br/>]]></Snippet> <Snippet type="IndentedListClose"><![CDATA[</span>]]></Snippet> <Snippet type="IndentedLogicalOrListOpen"><![CDATA[<br/><span class="smallIndent">]]></Snippet> <Snippet type="IndentedLogicalOrListPairSeparator"><![CDATA[<br/><span class="logicalOperator">or </span>]]></Snippet> @@ -155,9 +155,9 @@ <Snippet type="CompoundListClose"><![CDATA[]]></Snippet> <Snippet type="SimpleListOpen"><![CDATA[]]></Snippet> - <Snippet type="SimpleListPairSeparator"><![CDATA[<span class="listSeparator"> and </span>]]></Snippet> + <Snippet type="SimpleListPairSeparator"><![CDATA[<span class="logicalOperator"> and </span>]]></Snippet> <Snippet type="SimpleListSeparator"><![CDATA[<span class="listSeparator">, </span>]]></Snippet> - <Snippet type="SimpleListFinalSeparator"><![CDATA[<span class="listSeparator">, and </span>]]></Snippet> + <Snippet type="SimpleListFinalSeparator"><![CDATA[<span class="listSeparator">,</span><span class="logicalOperator"> and </span>]]></Snippet> <Snippet type="SimpleListClose"><![CDATA[]]></Snippet> <Snippet type="CompactSimpleListOpen"><![CDATA[]]></Snippet> <Snippet type="CompactSimpleListPairSeparator"><![CDATA[<span class="listSeparator">, </span>]]></Snippet> Modified: trunk/ORMModel/ObjectModel/VerbalizationGenerator.cs =================================================================== --- trunk/ORMModel/ObjectModel/VerbalizationGenerator.cs 2009-12-22 08:38:42 UTC (rev 1423) +++ trunk/ORMModel/ObjectModel/VerbalizationGenerator.cs 2009-12-31 07:19:36 UTC (rev 1424) @@ -458,10 +458,10 @@ @"<span class=""listSeparator"">; </span>", @"<span class=""listSeparator"">; </span>", "</span>", - @"<span class=""listSeparator""> and </span><br/>", + @"<span class=""logicalOperator""> and </span><br/>", @"<br/><span class=""smallIndent"">", - @"<span class=""listSeparator""> and </span><br/>", - @"<span class=""listSeparator""> and </span><br/>", + @"<span class=""logicalOperator""> and </span><br/>", + @"<span class=""logicalOperator""> and </span><br/>", "</span>", @"<br/><span class=""logicalOperator"">and that </span>", @"<br/><span class=""smallIndent"">", @@ -516,9 +516,9 @@ @"<span class=""smallIndent""><span class=""quantifier"">Reference Scheme:</span> {0}</span>", "{0}", "", - @"<span class=""listSeparator"">, and </span>", + @"<span class=""listSeparator"">,</span><span class=""logicalOperator""> and </span>", "", - @"<span class=""listSeparator""> and </span>", + @"<span class=""logicalOperator""> and </span>", @"<span class=""listSeparator"">, </span>", "", @"<span class=""logicalOperator""> and </span>", @@ -656,10 +656,10 @@ @"<span class=""listSeparator"">; </span>", @"<span class=""listSeparator"">; </span>", "</span>", - @"<span class=""listSeparator""> and </span><br/>", + @"<span class=""logicalOperator""> and </span><br/>", @"<br/><span class=""smallIndent"">", - @"<span class=""listSeparator""> and </span><br/>", - @"<span class=""listSeparator""> and </span><br/>", + @"<span class=""logicalOperator""> and </span><br/>", + @"<span class=""logicalOperator""> and </span><br/>", "</span>", @"<br/><span class=""logicalOperator"">and that </span>", @"<br/><span class=""smallIndent"">", @@ -714,9 +714,9 @@ @"<span class=""smallIndent""><span class=""quantifier"">Reference Scheme:</span> {0}</span>", "{0}", "", - @"<span class=""listSeparator"">, and </span>", + @"<span class=""listSeparator"">,</span><span class=""logicalOperator""> and </span>", "", - @"<span class=""listSeparator""> and </span>", + @"<span class=""logicalOperator""> and </span>", @"<span class=""listSeparator"">, </span>", "", @"<span class=""logicalOperator""> and </span>", @@ -854,10 +854,10 @@ @"<span class=""listSeparator"">; </span>", @"<span class=""listSeparator"">; </span>", "</span>", - @"<span class=""listSeparator""> and </span><br/>", + @"<span class=""logicalOperator""> and </span><br/>", @"<br/><span class=""smallIndent"">", - @"<span class=""listSeparator""> and </span><br/>", - @"<span class=""listSeparator""> and </span><br/>", + @"<span class=""logicalOperator""> and </span><br/>", + @"<span class=""logicalOperator""> and </span><br/>", "</span>", @"<br/><span class=""logicalOperator"">and that </span>", @"<br/><span class=""smallIndent"">", @@ -912,9 +912,9 @@ @"<span class=""smallIndent""><span class=""quantifier"">Reference Scheme:</span> {0}</span>", "{0}", "", - @"<span class=""listSeparator"">, and </span>", + @"<span class=""listSeparator"">,</span><span class=""logicalOperator""> and </span>", "", - @"<span class=""listSeparator""> and </span>", + @"<span class=""logicalOperator""> and </span>", @"<span class=""listSeparator"">, </span>", "", @"<span class=""logicalOperator""> and </span>", @@ -1052,10 +1052,10 @@ @"<span class=""listSeparator"">; </span>", @"<span class=""listSeparator"">; </span>", "</span>", - @"<span class=""listSeparator""> and </span><br/>", + @"<span class=""logicalOperator""> and </span><br/>", @"<br/><span class=""smallIndent"">", - @"<span class=""listSeparator""> and </span><br/>", - @"<span class=""listSeparator""> and </span><br/>", + @"<span class=""logicalOperator""> and </span><br/>", + @"<span class=""logicalOperator""> and </span><br/>", "</span>", @"<br/><span class=""logicalOperator"">and that </span>", @"<br/><span class=""smallIndent"">", @@ -1110,9 +1110,9 @@ @"<span class=""smallIndent""><span class=""quantifier"">Reference Scheme:</span> {0}</span>", "{0}", "", - @"<span class=""listSeparator"">, and </span>", + @"<span class=""listSeparator"">,</span><span class=""logicalOperator""> and </span>", "", - @"<span class=""listSeparator""> and </span>", + @"<span class=""logicalOperator""> and </span>", @"<span class=""listSeparator"">, </span>", "", @"<span class=""logicalOperator""> and </span>", Modified: trunk/ORMModel/ShapeModel/FactTypeShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/FactTypeShape.cs 2009-12-22 08:38:42 UTC (rev 1423) +++ trunk/ORMModel/ShapeModel/FactTypeShape.cs 2009-12-31 07:19:36 UTC (rev 1424) @@ -5100,11 +5100,13 @@ // Part 1: Resize the existing fact shapes bool missingNameShapes = false; + bool hasShape = false; foreach (PresentationElement pel in PresentationViewsSubject.GetPresentation(nestedFactType)) { FactTypeShape factShape = pel as FactTypeShape; if (factShape != null) { + hasShape = true; factShape.AutoResize(); if (!missingNameShapes) { @@ -5135,6 +5137,7 @@ ObjectTypeShape objectShape = pels[i] as ObjectTypeShape; if (objectShape != null) { + hasShape = true; ORMDiagram currentDiagram = (ORMDiagram)objectShape.Diagram; // Search the current diagram and see if we have a shape for the FactType @@ -5226,6 +5229,11 @@ #endif // TRACKNEWSHAPES // Make sure we have name shapes for all fact type shapes + if (!hasShape) + { + Diagram.FixUpDiagram(nestedFactType.Model, nestedFactType); + missingNameShapes = true; + } if (missingNameShapes) { Diagram.FixUpDiagram(nestedFactType, nestingType); @@ -5958,7 +5966,10 @@ { AutoResize(); SizeD size = Size; - Location = new PointD(0, -1.5 * size.Height); + if (createdDuringViewFixup) + { + Location = new PointD(0, -1.5 * size.Height); + } foreach (ShapeElement childShape in RelativeChildShapes) { ORMBaseShape shape = childShape as ORMBaseShape; Modified: trunk/ORMModel/Shell/ORMModelBrowser.cs =================================================================== --- trunk/ORMModel/Shell/ORMModelBrowser.cs 2009-12-22 08:38:42 UTC (rev 1423) +++ trunk/ORMModel/Shell/ORMModelBrowser.cs 2009-12-31 07:19:36 UTC (rev 1424) @@ -164,9 +164,13 @@ else if (0 != (commandFlags & (ORMDesignerCommands.DiagramList))) { OleMenuCommand cmd = command as OleMenuCommand; + object selectedNode = currentWindow.SelectedNode; + IElementReference elementReference; ModelElement element; string diagramName = null; - if (null != (element = currentWindow.SelectedNode as ModelElement)) + if (null != (elementReference = selectedNode as IElementReference) ? + null != (element = elementReference.ReferencedElement as ModelElement) : + null != (element = selectedNode as ModelElement)) { int diagramIndex = cmd.MatchedCommandId; ORMBaseShape.VisitAssociatedShapes( @@ -643,7 +647,11 @@ protected virtual void OnMenuDiagramList(int diagramIndex, NavigateToWindow targetWindow) { ModelElement element; - if (null != (element = SelectedNode as ModelElement)) + IElementReference elementReference; + object selectedNode = SelectedNode; + if (null != (elementReference = selectedNode as IElementReference) ? + null != (element = elementReference.ReferencedElement as ModelElement) : + null != (element = selectedNode as ModelElement)) { ORMBaseShape.VisitAssociatedShapes( element, Modified: trunk/ORMModel/Shell/ORMReadingEditor.cs =================================================================== --- trunk/ORMModel/Shell/ORMReadingEditor.cs 2009-12-22 08:38:42 UTC (rev 1423) +++ trunk/ORMModel/Shell/ORMReadingEditor.cs 2009-12-31 07:19:36 UTC (rev 1424) @@ -85,27 +85,7 @@ } } - - private object myCommandSet; - private bool myCommandsPopulated; /// <summary> - /// returns the menu service and instantiates a new command set if none exists - /// </summary> - public override IMenuCommandService MenuService - { - get - { - IMenuCommandService retVal = base.MenuService; - if (retVal != null && !myCommandsPopulated) - { - myCommandsPopulated = true; - myCommandSet = new ReadingEditorCommandSet(myCtorServiceProvider, retVal); - } - return retVal; - } - } - - /// <summary> /// Gets the title that will be displayed on the tool window. /// </summary> public override string WindowTitle @@ -753,120 +733,5 @@ } } #endregion - #region Nested Tool Window Class - private sealed class ReadingEditorCommandSet : MarshalByRefObject, IDisposable - { - private IMenuCommandService myMenuService; - private IMonitorSelectionService myMonitorSelection; - private IServiceProvider myServiceProvider; - private MenuCommand[] myCommands; - - public ReadingEditorCommandSet(IServiceProvider provider, IMenuCommandService menuService) - { - myServiceProvider = provider; - myMenuService = menuService; - #region command array - myCommands = new MenuCommand[]{ - new DynamicStatusMenuCommand( - new EventHandler(OnStatusDelete), - new EventHandler(OnMenuDelete), - StandardCommands.Delete)}; - #endregion //command array - AddCommands(myCommands); - } - - private void AddCommands(MenuCommand[] commands) - { - IMenuCommandService menuService = MenuService; //force creation of myMenuService - if (menuService != null) - { - int count = commands.Length; - for (int i = 0; i < count; ++i) - { - menuService.AddCommand(commands[i]); - } - } - } - - private void RemoveCommands(MenuCommand[] commands) - { - IMenuCommandService menuService = myMenuService; - if (menuService != null) - { - int count = commands.Length; - for (int i = 0; i < count; ++i) - { - menuService.RemoveCommand(commands[i]); - } - } - } - - private IMenuCommandService MenuService - { - get - { - Debug.Assert(myMenuService != null); // Should be passed into the constructor - return myMenuService; - } - } - private ORMReadingEditorToolWindow CurrentToolWindow - { - get - { - return MonitorSelection.CurrentWindow as ORMReadingEditorToolWindow; - } - } - /// <summary> - /// Load the monitor selection service - /// </summary> - private IMonitorSelectionService MonitorSelection - { - get - { - IMonitorSelectionService monitorSelect = myMonitorSelection; - if (monitorSelect == null) - { - myMonitorSelection = monitorSelect = (IMonitorSelectionService)myServiceProvider.GetService(typeof(IMonitorSelectionService)); - } - return monitorSelect; - } - } - - #region IDisposable Members - - public void Dispose() - { - if (myCommands != null) - { - RemoveCommands(myCommands); - } - myMenuService = null; - myMonitorSelection = null; - myServiceProvider = null; - myCommands = null; - } - - public void OnStatusDelete(Object sender, EventArgs e) - { - //IMonitorSelectionService service = MonitorSelection; - //ORMReadingEditorToolWindow.OnStatusCommand(sender, ORMDesignerCommands.Delete, service.CurrentWindow as ORMReadingEditorToolWindow); - } - public void OnMenuDelete(Object sender, EventArgs e) - { - //ORMReadingEditorToolWindow currentWindow = CurrentToolWindow; - //if (currentWindow != null) - //{ - // currentWindow.OnMenuDelete((sender as OleMenuCommand).Text); - //} - } - #endregion - } - - #region Nested Click Location Class - - #endregion //Nested Click Location Class - - - #endregion //Nested Tool Window Class } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2010-05-27 23:05:22
|
Revision: 1442 http://orm.svn.sourceforge.net/orm/?rev=1442&view=rev Author: mcurland Date: 2010-05-27 23:05:16 +0000 (Thu, 27 May 2010) Log Message: ----------- Add element-level custom deletion hooks to allow elements more flexibility in specifying how they are to be deleted. Handles role path scenario supporting ownership transfer of a path from one container to another. refs #395 Modified Paths: -------------- trunk/ORMModel/Framework/FrameworkServices.cs trunk/ORMModel/ShapeModel/ReadingShape.cs trunk/ORMModel/ShapeModel/RoleNameShape.cs trunk/ORMModel/Shell/ORMDesignerCommandManager.cs trunk/ORMModel/Shell/ORMModelBrowser.cs Modified: trunk/ORMModel/Framework/FrameworkServices.cs =================================================================== --- trunk/ORMModel/Framework/FrameworkServices.cs 2010-05-27 06:01:30 UTC (rev 1441) +++ trunk/ORMModel/Framework/FrameworkServices.cs 2010-05-27 23:05:16 UTC (rev 1442) @@ -197,14 +197,30 @@ bool MergeRelateIndirect(T mergeContext, ModelElement sourceElement, ElementGroup elementGroup); } #endregion // IMergeIndirectElements<T> interface - #region IAllowsStandardCommands interface + #region IAllowStandardCommands interface /// <summary> - /// Implement the <see cref="IAllowStandardCommands"/> to turn - /// on standard command handling for a shape or element. Standard - /// commands allow element and shape deletion, shape alignment, and layout. + /// Implement IAllowStandardCommands to enable standard command + /// handling for a shape or element. Standard commands allow + /// element and shape deletion, shape alignment, and layout. /// </summary> public interface IAllowStandardCommands { } - #endregion // IAllowsStandardCommands interface + #endregion // IAllowStandardCommands interface + #region ICustomElementDeletion interface + /// <summary> + /// Implement ICustomElementDeletion to replace the standard + /// <see cref="ModelElement.Delete()"/> to handle deletion of + /// the implementing element. ICustomElementDeletion can be + /// coupled with <see cref="IAllowStandardCommands"/> to + /// enable deletion on extension elements. + /// </summary> + public interface ICustomElementDeletion + { + /// <summary> + /// Delete the current element. + /// </summary> + void DeleteCustomElement(); + } + #endregion // ICustomElementDeletion interface } Modified: trunk/ORMModel/ShapeModel/ReadingShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/ReadingShape.cs 2010-05-27 06:01:30 UTC (rev 1441) +++ trunk/ORMModel/ShapeModel/ReadingShape.cs 2010-05-27 23:05:16 UTC (rev 1442) @@ -37,7 +37,7 @@ namespace ORMSolutions.ORMArchitect.Core.ShapeModel { - public partial class ReadingShape : IModelErrorActivation, ISelectionContainerFilter, IDynamicColorGeometryHost + public partial class ReadingShape : IModelErrorActivation, ISelectionContainerFilter, IDynamicColorGeometryHost, ICustomElementDeletion { #region IDynamicColorGeometryHost Implementation /// <summary> @@ -1231,6 +1231,26 @@ } } #endregion // ISelectionContainerFilter Implementation + #region ICustomElementDeletion Implementation + /// <summary> + /// Implements <see cref="ICustomElementDeletion.DeleteCustomElement"/> + /// A reading shape selection should delete the fact type. + /// </summary> + protected void DeleteCustomElement() + { + ReadingOrder readingOrder; + FactType factType; + if (null != (readingOrder = ModelElement as ReadingOrder) && + null != (factType = readingOrder.FactType)) + { + factType.Delete(); + } + } + void ICustomElementDeletion.DeleteCustomElement() + { + DeleteCustomElement(); + } + #endregion // ICustomElementDeletion Implementation #region Mouse handling /// <summary> /// Attempt model error activation Modified: trunk/ORMModel/ShapeModel/RoleNameShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/RoleNameShape.cs 2010-05-27 06:01:30 UTC (rev 1441) +++ trunk/ORMModel/ShapeModel/RoleNameShape.cs 2010-05-27 23:05:16 UTC (rev 1442) @@ -31,7 +31,7 @@ namespace ORMSolutions.ORMArchitect.Core.ShapeModel { - public partial class RoleNameShape : ISelectionContainerFilter, IProxyDisplayProvider, IDynamicColorGeometryHost + public partial class RoleNameShape : ISelectionContainerFilter, IProxyDisplayProvider, IDynamicColorGeometryHost, ICustomElementDeletion { #region Member Variables private static AutoSizeTextField myTextField; @@ -359,5 +359,23 @@ return ElementDisplayedAs(element, forError); } #endregion // IProxyDisplayProvider Implementation + #region ICustomElementDeletion Implementation + /// <summary> + /// Implements <see cref="ICustomElementDeletion.DeleteCustomElement"/> + /// Clear the role name on deletion instead of deleting the role itself. + /// </summary> + protected void DeleteCustomElement() + { + Role role = ModelElement as Role; + if (role != null) + { + role.Name = ""; + } + } + void ICustomElementDeletion.DeleteCustomElement() + { + DeleteCustomElement(); + } + #endregion // ICustomElementDeletion Implementation } } Modified: trunk/ORMModel/Shell/ORMDesignerCommandManager.cs =================================================================== --- trunk/ORMModel/Shell/ORMDesignerCommandManager.cs 2010-05-27 06:01:30 UTC (rev 1441) +++ trunk/ORMModel/Shell/ORMDesignerCommandManager.cs 2010-05-27 23:05:16 UTC (rev 1442) @@ -1733,7 +1733,7 @@ // up before committing. bool complexSelection = 0 == (enabledCommands & ORMDesignerCommands.Delete); - Diagram d = null; + Diagram diagram = null; // Use the localized text from the command for our transaction name using (Transaction t = store.TransactionManager.BeginTransaction(commandText.Replace("&", string.Empty))) { @@ -1746,6 +1746,7 @@ object selectedObject = selectedElements[i]; ShapeElement pel; // just the shape ModelElement mel; + ICustomElementDeletion customDeletion; bool deleteReferenceModeValueTypeInContext = false; if (null != (pel = selectedObject as ShapeElement)) { @@ -1759,11 +1760,17 @@ { continue; } - if (d == null) + if (diagram == null) { - d = pel.Diagram; + diagram = pel.Diagram; } + if (null != (customDeletion = pel as ICustomElementDeletion)) + { + customDeletion.DeleteCustomElement(); + continue; + } + // Get the actual object inside the pel before // removing the pel. mel = pel.ModelElement; @@ -1771,52 +1778,53 @@ // Remove the actual object in the model if (mel != null && !mel.IsDeleted) { - Role role; - if (null != (role = mel as Role) && pel is RoleNameShape) + // Check if the object shape was in expanded mode + bool testRefModeCollapse = complexSelection || 0 != (enabledCommands & ORMDesignerCommands.DeleteObjectType); + ObjectTypeShape objectShape; + ObjectifiedFactTypeNameShape objectifiedShape; + if (testRefModeCollapse && + ((null != (objectShape = pel as ObjectTypeShape) && + !objectShape.ExpandRefMode) || + (null != (objectifiedShape = pel as ObjectifiedFactTypeNameShape) && + !objectifiedShape.ExpandRefMode)) + ) { - role.Name = ""; + if (!deleteReferenceModeValueTypeInContext) + { + contextInfo[ObjectType.DeleteReferenceModeValueType] = null; + deleteReferenceModeValueTypeInContext = true; + } } + else if (deleteReferenceModeValueTypeInContext) + { + deleteReferenceModeValueTypeInContext = false; + contextInfo.Remove(ObjectType.DeleteReferenceModeValueType); + } + + // Get rid of the model element. Delete propagation on the PresentationViewsSubject + // relationship will automatically delete the pel. + if (null != (customDeletion = mel as ICustomElementDeletion)) + { + customDeletion.DeleteCustomElement(); + } else { - ReadingOrder readingOrder = mel as ReadingOrder; - if (readingOrder != null) - { - mel = readingOrder.FactType; - } - // Check if the object shape was in expanded mode - bool testRefModeCollapse = complexSelection || 0 != (enabledCommands & ORMDesignerCommands.DeleteObjectType); - ObjectTypeShape objectShape; - ObjectifiedFactTypeNameShape objectifiedShape; - if (testRefModeCollapse && - ((null != (objectShape = pel as ObjectTypeShape) && - !objectShape.ExpandRefMode) || - (null != (objectifiedShape = pel as ObjectifiedFactTypeNameShape) && - !objectifiedShape.ExpandRefMode)) - ) - { - if (!deleteReferenceModeValueTypeInContext) - { - contextInfo[ObjectType.DeleteReferenceModeValueType] = null; - deleteReferenceModeValueTypeInContext = true; - } - } - else if (deleteReferenceModeValueTypeInContext) - { - deleteReferenceModeValueTypeInContext = false; - contextInfo.Remove(ObjectType.DeleteReferenceModeValueType); - } - - // Get rid of the model element. Delete propagation on the PresentationViewsSubject - // relationship will automatically delete the pel. mel.Delete(); } } } else if (null != (mel = selectedObject as ModelElement) && !mel.IsDeleted) { - // Remove the item - mel.Delete(); + customDeletion = mel as ICustomElementDeletion; + if (customDeletion != null) + { + customDeletion.DeleteCustomElement(); + } + else + { + mel.Delete(); + } } } @@ -1826,7 +1834,7 @@ } } - if (d != null) + if (diagram != null) { // Clearing the selection selects the diagram view.CurrentDesigner.Selection.Clear(); Modified: trunk/ORMModel/Shell/ORMModelBrowser.cs =================================================================== --- trunk/ORMModel/Shell/ORMModelBrowser.cs 2010-05-27 06:01:30 UTC (rev 1441) +++ trunk/ORMModel/Shell/ORMModelBrowser.cs 2010-05-27 23:05:16 UTC (rev 1442) @@ -468,7 +468,15 @@ } if (executeDelete) { - deleteTarget.Delete(); + ICustomElementDeletion customDeletion = deleteTarget as ICustomElementDeletion; + if (customDeletion != null) + { + customDeletion.DeleteCustomElement(); + } + else + { + deleteTarget.Delete(); + } } } if (t.HasPendingChanges) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2010-09-15 08:17:35
|
Revision: 1456 http://orm.svn.sourceforge.net/orm/?rev=1456&view=rev Author: mcurland Date: 2010-09-15 08:17:28 +0000 (Wed, 15 Sep 2010) Log Message: ----------- Fixed some cross-model copy problems from [1455]. refs #403 * Element order in 'allows duplicates' relationships needs to be based on the link order, not the target element order. * Add matching for abbreviations * Improve sophistication of merge filter to enable both the toolbox and cross-model drag Modified Paths: -------------- trunk/ORMModel/Framework/CopyMergeServices.cs trunk/ORMModel/ObjectModel/NameAlias.cs trunk/ORMModel/ObjectModel/ORMCore.AttachRules.cs trunk/ORMModel/ObjectModel/ORMCore.AttachRules.xml trunk/ORMModel/ObjectModel/ORMCore.ElementEquivalence.cs trunk/ORMModel/ShapeModel/ReadingShape.cs trunk/ORMModel/ShapeModel/ViewFixupRules.cs Modified: trunk/ORMModel/Framework/CopyMergeServices.cs =================================================================== --- trunk/ORMModel/Framework/CopyMergeServices.cs 2010-09-14 21:30:56 UTC (rev 1455) +++ trunk/ORMModel/Framework/CopyMergeServices.cs 2010-09-15 08:17:28 UTC (rev 1456) @@ -16,7 +16,7 @@ // Temporarily uncomment this line to enable helper // routines useful during copy closure debugging. - #define DEBUGHELPERS +// #define DEBUGHELPERS using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -1485,31 +1485,82 @@ DomainRoleInfo sourceRoleInfo; DomainRoleInfo targetRoleInfo; LinkedElementCollection<ModelElement> targetLinkedElements; - LinkedElementCollection<ModelElement> sourceLinkedElements; + int targetLinkCount; if (null != (sourceRoleInfo = sourceDataDirectory.FindDomainRole(roleId)) && null != (targetRoleInfo = targetDataDirectory.FindDomainRole(roleId)) && - 1 < (targetLinkedElements = targetRoleInfo.GetLinkedElements(pair.Value)).Count && - 0 != (sourceLinkedElements = sourceRoleInfo.GetLinkedElements(key.Element)).Count) + 1 < (targetLinkCount = (targetLinkedElements = targetRoleInfo.GetLinkedElements(pair.Value)).Count)) { - // UNDONE: COPYMERGE Use MergeIntegrationOrder to more accurately - // place elements in an existing collection. This moves all merged - // elements to the front. - MergeIntegrationOrder order = orderedRoles[roleId]; - int resolvedIndex = 0; - foreach (ModelElement sourceLinkedElement in sourceLinkedElements) + if (sourceRoleInfo.DomainRelationship.AllowsDuplicates) { - CopiedElement copy; - int targetIndex; - if (resolvedElements.TryGetValue(sourceLinkedElement.Id, out copy) && - -1 != (targetIndex = targetLinkedElements.IndexOf(copy.Element))) + // We have to be very careful in this situation because we can + // based on the order on the location of the source links, but + // not the source elements (which can be duplicated). From the + // target side, we need the LinkedElementCollection for the Move + // method plus the ElementLink collection for order comparison. + ReadOnlyCollection<ElementLink> sourceLinks = sourceRoleInfo.GetElementLinks(key.Element); + if (0 != sourceLinks.Count) { - if (targetIndex != resolvedIndex) + ReadOnlyCollection<ElementLink> targetLinks = targetRoleInfo.GetElementLinks(pair.Value); + // Note that count and order directly correspond to the linked elements. + // Assert the count for minimal sanity, assume the order. + Debug.Assert(targetLinks.Count == targetLinkCount); + // Record the index in original collection now residing in a given slot + int[] originalIndexMap = new int[targetLinkCount]; + for (int i = 0; i < targetLinkCount; ++i) { - targetLinkedElements.Move(targetIndex, resolvedIndex); + originalIndexMap[i] = i; } - ++resolvedIndex; + int resolvedIndex = 0; + foreach (ElementLink sourceLink in sourceLinks) + { + CopiedElement copy; + int originalTargetIndex; + if (resolvedElements.TryGetValue(sourceLink.Id, out copy) && + -1 != (originalTargetIndex = targetLinks.IndexOf((ElementLink)copy.Element))) + { + int targetIndex = Array.IndexOf<int>(originalIndexMap, originalTargetIndex); + if (targetIndex != resolvedIndex) + { + Debug.Assert(targetIndex > resolvedIndex); // Otherwise the links do not form a set + targetLinkedElements.Move(targetIndex, resolvedIndex); + int keepTargetIndex = originalIndexMap[targetIndex]; + for (int i = targetIndex; i > resolvedIndex; --i) + { + originalIndexMap[i] = originalIndexMap[i - 1]; + } + originalIndexMap[resolvedIndex] = keepTargetIndex; + } + ++resolvedIndex; + } + } } } + else + { + LinkedElementCollection<ModelElement> sourceLinkedElements = sourceRoleInfo.GetLinkedElements(key.Element); + if (0 != sourceLinkedElements.Count) + { + // UNDONE: COPYMERGE Use MergeIntegrationOrder to more accurately + // place elements in an existing collection. This moves all merged + // elements to the front. Also apply to AllowsDuplicates case. + // MergeIntegrationOrder order = orderedRoles[roleId]; + int resolvedIndex = 0; + foreach (ModelElement sourceLinkedElement in sourceLinkedElements) + { + CopiedElement copy; + int targetIndex; + if (resolvedElements.TryGetValue(sourceLinkedElement.Id, out copy) && + -1 != (targetIndex = targetLinkedElements.IndexOf(copy.Element))) + { + if (targetIndex != resolvedIndex) + { + targetLinkedElements.Move(targetIndex, resolvedIndex); + } + ++resolvedIndex; + } + } + } + } } } } @@ -1853,34 +1904,26 @@ if (null != (embeddedRoles = myEmbeddedRoles) && embeddedRoles.TryGetValue(newElement.GetDomainClass().ImplementationClass, out roleNode)) { - DomainRoleInfo embeddedRoleInfo = null; - if (roleNode.Next == null) + // Get available embedding roles and verify that the basedOnElement is attached + // via that relationship. Note that we do this even if exactly one root embedding + // relationship is available because we do not know if there are other non-root + // embedding relationships in this code. + DomainRoleInfo sourceEmbeddedRoleInfo = null; + while (roleNode != null) { - // We have only one choice, short circuit tie breakers - // Use Find instead of Get to handle source/target situations - // where the extension models may be different. - embeddedRoleInfo = targetDataDirectory.FindDomainRole(roleNode.Value); - } - else - { - while (roleNode != null) + sourceEmbeddedRoleInfo = sourceDataDirectory.GetDomainRole(roleNode.Value); + if (sourceEmbeddedRoleInfo.GetElementLinks(basedOnElement).Count != 0) { - if (null != (embeddedRoleInfo = sourceDataDirectory.FindDomainRole(roleNode.Value))) { - if (embeddedRoleInfo.GetElementLinks(basedOnElement).Count != 0) - { - { - break; - } - } - embeddedRoleInfo = null; + break; } - roleNode = roleNode.Next; } + sourceEmbeddedRoleInfo = null; + roleNode = roleNode.Next; } - if (embeddedRoleInfo != null) + if (sourceEmbeddedRoleInfo != null) { - DomainRelationshipInfo sourceRelationshipInfo = embeddedRoleInfo.DomainRelationship; + DomainRelationshipInfo sourceRelationshipInfo = sourceEmbeddedRoleInfo.DomainRelationship; DomainRelationshipInfo targetRelationshipInfo = targetDataDirectory.FindDomainRelationship(sourceRelationshipInfo.Id); if (targetRelationshipInfo == null) { @@ -1888,7 +1931,7 @@ } else { - DomainRoleInfo embeddingRoleInfo = embeddedRoleInfo.OppositeDomainRole; + DomainRoleInfo embeddingRoleInfo = sourceEmbeddedRoleInfo.OppositeDomainRole; DomainClassInfo parentClassInfo = embeddingRoleInfo.RolePlayer; Type implementationClass = parentClassInfo.ImplementationClass; ModelElement rootElement = null; @@ -1926,7 +1969,7 @@ if (rootElement != null) { Guid embeddingRoleId = embeddingRoleInfo.Id; - Guid embeddedRoleId = embeddedRoleInfo.Id; + Guid embeddedRoleId = sourceEmbeddedRoleInfo.Id; targetElementFactory.CreateElementLink( targetRelationshipInfo, new RoleAssignment(embeddingRoleId, rootElement), @@ -1936,7 +1979,7 @@ { if (orderedRoles.ContainsKey(embeddingRoleId)) // Pre check so we don't fetch elements we don't need { - foreach (ModelElement basedOnRootElement in embeddedRoleInfo.GetLinkedElements(basedOnElement)) + foreach (ModelElement basedOnRootElement in sourceEmbeddedRoleInfo.GetLinkedElements(basedOnElement)) { TrackOrdering(orderedRoles, embeddingRoleId, basedOnRootElement, rootElement, ref requiresOrdering); break; Modified: trunk/ORMModel/ObjectModel/NameAlias.cs =================================================================== --- trunk/ORMModel/ObjectModel/NameAlias.cs 2010-09-14 21:30:56 UTC (rev 1455) +++ trunk/ORMModel/ObjectModel/NameAlias.cs 2010-09-15 08:17:28 UTC (rev 1456) @@ -110,32 +110,53 @@ /// <param name="notifyAdded">The listener to notify if elements are added during fixup</param> protected sealed override void ProcessElement(NameAlias element, Store store, INotifyElementAdded notifyAdded) { - Type consumer; - Type usage; - object[] attributes = null; - DomainClassInfo consumerDomainClass; - if (null == (consumerDomainClass = element.myConsumerDomainClass) || - null == (consumer = consumerDomainClass.ImplementationClass) || - (null != (usage = element.NameUsageType) && - null == (attributes = consumer.GetCustomAttributes(typeof(NameUsageAttribute), true)))) + element.DeleteIfTypeBindingFailed(); + } + } + /// <summary> + /// AddRule: typeof(NameAlias), FireTime=LocalCommit, Priority=FrameworkDomainModel.CopyClosureExpansionCompletedRulePriority; + /// </summary> + private static void AliasAddedClosureRule(ElementAddedEventArgs e) + { + ModelElement element = e.ModelElement; + if (!element.IsDeleted && + CopyMergeUtility.GetIntegrationPhase(element.Store) == CopyClosureIntegrationPhase.IntegrationComplete) + { + ((NameAlias)element).DeleteIfTypeBindingFailed(); + } + } + /// <summary> + /// Shared helper for merge integration and deserialization. Deletes + /// the element if the types referenced by the consumer and usage + /// are not loaded in the store. + /// </summary> + private void DeleteIfTypeBindingFailed() + { + Type consumer; + Type usage; + object[] attributes = null; + DomainClassInfo consumerDomainClass; + if (null == (consumerDomainClass = myConsumerDomainClass) || + null == (consumer = consumerDomainClass.ImplementationClass) || + (null != (usage = NameUsageType) && + null == (attributes = consumer.GetCustomAttributes(typeof(NameUsageAttribute), true)))) + { + Delete(); + } + else if (usage != null) + { + int i = 0; + for (; i < attributes.Length; ++i) { - element.Delete(); - } - else if (usage != null) - { - int i = 0; - for (; i < attributes.Length; ++i) + if (((NameUsageAttribute)attributes[i]).Type == usage) { - if (((NameUsageAttribute)attributes[i]).Type == usage) - { - break; - } + break; } - if (i == attributes.Length) - { - element.Delete(); - } } + if (i == attributes.Length) + { + Delete(); + } } } #endregion // Deserialization Fixup Modified: trunk/ORMModel/ObjectModel/ORMCore.AttachRules.cs =================================================================== --- trunk/ORMModel/ObjectModel/ORMCore.AttachRules.cs 2010-09-14 21:30:56 UTC (rev 1455) +++ trunk/ORMModel/ObjectModel/ORMCore.AttachRules.cs 2010-09-15 08:17:28 UTC (rev 1456) @@ -205,6 +205,7 @@ typeof(MandatoryConstraint).GetNestedType("MandatoryConstraintChangeRuleClass", BindingFlags.Public | BindingFlags.NonPublic), typeof(ModelError).GetNestedType("SynchronizeErrorTextForModelRuleClass", BindingFlags.Public | BindingFlags.NonPublic), typeof(ModelError).GetNestedType("SynchronizeErrorTextForOwnerRuleClass", BindingFlags.Public | BindingFlags.NonPublic), + typeof(NameAlias).GetNestedType("AliasAddedClosureRuleClass", BindingFlags.Public | BindingFlags.NonPublic), typeof(ORMSolutions.ORMArchitect.Framework.NamedElementDictionary).GetNestedType("ElementLinkAddedRuleClass", BindingFlags.Public | BindingFlags.NonPublic), typeof(ORMSolutions.ORMArchitect.Framework.NamedElementDictionary).GetNestedType("ElementLinkDeletingRuleClass", BindingFlags.Public | BindingFlags.NonPublic), typeof(ORMSolutions.ORMArchitect.Framework.NamedElementDictionary).GetNestedType("NamedElementChangedRuleClass", BindingFlags.Public | BindingFlags.NonPublic), @@ -489,7 +490,7 @@ { Microsoft.VisualStudio.Modeling.RuleManager ruleManager = store.RuleManager; Type[] disabledRuleTypes = ORMCoreDomainModel.CustomDomainModelTypes; - for (int i = 0; i < 421; ++i) + for (int i = 0; i < 422; ++i) { ruleManager.EnableRule(disabledRuleTypes[i]); } @@ -5030,6 +5031,37 @@ } } #endregion // Rule classes for ModelError + #region Rule classes for NameAlias + partial class NameAlias + { + [Microsoft.VisualStudio.Modeling.RuleOn(typeof(NameAlias), FireTime=Microsoft.VisualStudio.Modeling.TimeToFire.LocalCommit, Priority=ORMSolutions.ORMArchitect.Framework.FrameworkDomainModel.CopyClosureExpansionCompletedRulePriority)] + private sealed class AliasAddedClosureRuleClass : Microsoft.VisualStudio.Modeling.AddRule + { + [System.Diagnostics.DebuggerStepThrough()] + public AliasAddedClosureRuleClass() + { + base.IsEnabled = false; + } + /// <summary> + /// Provide the following method in class: + /// ORMSolutions.ORMArchitect.Core.ObjectModel.NameAlias + /// /// <summary> + /// /// AddRule: typeof(NameAlias), FireTime=LocalCommit, Priority=FrameworkDomainModel.CopyClosureExpansionCompletedRulePriority; + /// /// </summary> + /// private static void AliasAddedClosureRule(ElementAddedEventArgs e) + /// { + /// } + /// </summary> + [System.Diagnostics.DebuggerStepThrough()] + public override void ElementAdded(Microsoft.VisualStudio.Modeling.ElementAddedEventArgs e) + { + ORMSolutions.ORMArchitect.Framework.Diagnostics.TraceUtility.TraceRuleStart(e.ModelElement.Store, "ORMSolutions.ORMArchitect.Core.ObjectModel.NameAlias.AliasAddedClosureRule"); + NameAlias.AliasAddedClosureRule(e); + ORMSolutions.ORMArchitect.Framework.Diagnostics.TraceUtility.TraceRuleEnd(e.ModelElement.Store, "ORMSolutions.ORMArchitect.Core.ObjectModel.NameAlias.AliasAddedClosureRule"); + } + } + } + #endregion // Rule classes for NameAlias #region Rule classes for NameGenerator partial class NameGenerator { Modified: trunk/ORMModel/ObjectModel/ORMCore.AttachRules.xml =================================================================== --- trunk/ORMModel/ObjectModel/ORMCore.AttachRules.xml 2010-09-14 21:30:56 UTC (rev 1455) +++ trunk/ORMModel/ObjectModel/ORMCore.AttachRules.xml 2010-09-15 08:17:28 UTC (rev 1456) @@ -570,6 +570,11 @@ <arg:RuleOn targetType="ORMNamedElement"/> </arg:ChangeRule> </arg:RuleContainer> + <arg:RuleContainer class="NameAlias"> + <arg:AddRule methodName="AliasAddedClosureRule"> + <arg:RuleOn targetType="NameAlias" fireTime="LocalCommit" priority="CopyClosureExpansionCompletedRulePriority"/> + </arg:AddRule> + </arg:RuleContainer> <arg:RuleContainer class="NamedElementDictionary" namespace="ORMSolutions.ORMArchitect.Framework"> <arg:AddRule methodName="ElementLinkAddedRule"> <arg:RuleOn targetType="ElementLink" targetTypeQualifier="Microsoft.VisualStudio.Modeling"> Modified: trunk/ORMModel/ObjectModel/ORMCore.ElementEquivalence.cs =================================================================== --- trunk/ORMModel/ObjectModel/ORMCore.ElementEquivalence.cs 2010-09-14 21:30:56 UTC (rev 1455) +++ trunk/ORMModel/ObjectModel/ORMCore.ElementEquivalence.cs 2010-09-15 08:17:28 UTC (rev 1456) @@ -1799,4 +1799,75 @@ } } #endregion // CalculatedPathValue class + #region RecognizedPhrase class + partial class RecognizedPhrase : IElementEquivalence + { + /// <summary> + /// Implements <see cref="IElementEquivalence.MapEquivalentElements"/> + /// Match phrases by name. + /// </summary> + protected bool MapEquivalentElements(Store foreignStore, IEquivalentElementTracker elementTracker) + { + foreach (ORMModel otherModel in foreignStore.ElementDirectory.FindElements<ORMModel>(false)) + { + RecognizedPhrase otherPhrase = otherModel.RecognizedPhrasesDictionary.GetElement(Name).FirstElement as RecognizedPhrase; + if (otherPhrase != null) + { + elementTracker.AddEquivalentElement(this, otherPhrase); + return true; + } + break; + } + return false; + } + bool IElementEquivalence.MapEquivalentElements(Store foreignStore, IEquivalentElementTracker elementTracker) + { + return MapEquivalentElements(foreignStore, elementTracker); + } + } + #endregion // RecognizedPhrase class + #region NameAlias class + partial class NameAlias : IElementEquivalence + { + /// <summary> + /// Implements <see cref="IElementEquivalence.MapEquivalentElements"/> + /// </summary> + protected bool MapEquivalentElements(Store foreignStore, IEquivalentElementTracker elementTracker) + { + ModelElement aliasOwner; + ModelElement otherAliasOwner; + if (null != (aliasOwner = Element) && + null != (otherAliasOwner = CopyMergeUtility.GetEquivalentElement(aliasOwner, foreignStore, elementTracker))) + { + // Match by consumer and usage classes. Use the internal class information + // instead of the serialized string forms. If we end up copying one of these + // with no matching class information then we'll delete it at the end of + // the merge integration phase. Note that we match by id because the meta + // information is in a different store. + // UNDONE: COPYMERGE We need a way for an element to add domain model requirements + // without referencing elements in that model. + DomainClassInfo classInfo = myConsumerDomainClass; + bool hasConsumer = classInfo != null; + Guid consumerId = hasConsumer ? classInfo.Id : Guid.Empty; + classInfo = myUsageDomainClass; + bool hasUsage = classInfo != null; + Guid usageId = hasUsage ? classInfo.Id : Guid.Empty; + foreach (NameAlias otherAlias in ElementHasAlias.GetAliasCollection(otherAliasOwner)) + { + if (consumerId == (null != (classInfo = otherAlias.myConsumerDomainClass) ? classInfo.Id : Guid.Empty) && + usageId == (null != (classInfo = otherAlias.myUsageDomainClass) ? classInfo.Id : Guid.Empty)) + { + elementTracker.AddEquivalentElement(this, otherAlias); + return true; + } + } + } + return false; + } + bool IElementEquivalence.MapEquivalentElements(Store foreignStore, IEquivalentElementTracker elementTracker) + { + return MapEquivalentElements(foreignStore, elementTracker); + } + } + #endregion // NameAlias class } Modified: trunk/ORMModel/ShapeModel/ReadingShape.cs =================================================================== --- trunk/ORMModel/ShapeModel/ReadingShape.cs 2010-09-14 21:30:56 UTC (rev 1455) +++ trunk/ORMModel/ShapeModel/ReadingShape.cs 2010-09-15 08:17:28 UTC (rev 1456) @@ -895,11 +895,13 @@ private ArrowDirection GetDirection(ShapeElement parentShape) { ArrowDirection retVal = ArrowDirection.None; - FactTypeShape factTypeShape = (FactTypeShape)parentShape.ParentShape; - FactType factType = factTypeShape.AssociatedFactType; - LinkedElementCollection<RoleBase> roles = factType.RoleCollection; - int roleCount = roles.Count; - if (roleCount > 1) + FactTypeShape factTypeShape; + FactType factType; + LinkedElementCollection<RoleBase> roles; + int roleCount; + if (null != (factTypeShape = (FactTypeShape)parentShape.ParentShape) && + null != (factType = factTypeShape.AssociatedFactType) && + (roleCount = (roles = factType.RoleCollection).Count) > 1) { DisplayOrientation orientation = factTypeShape.DisplayOrientation; bool isVertical = orientation != DisplayOrientation.Horizontal; Modified: trunk/ORMModel/ShapeModel/ViewFixupRules.cs =================================================================== --- trunk/ORMModel/ShapeModel/ViewFixupRules.cs 2010-09-14 21:30:56 UTC (rev 1455) +++ trunk/ORMModel/ShapeModel/ViewFixupRules.cs 2010-09-15 08:17:28 UTC (rev 1456) @@ -43,8 +43,8 @@ ModelHasObjectType link = e.ModelElement as ModelHasObjectType; ObjectType objectType = link.ObjectType; if (!element.IsDeleted && - !MergeContext.HasContext(element.Store.TransactionManager.CurrentTransaction.TopLevelTransaction) && - (objectType = (link = (ModelHasObjectType)element).ObjectType).NestedFactType == null) // Otherwise, fix up with the fact type + (objectType = (link = (ModelHasObjectType)element).ObjectType).NestedFactType == null && // Otherwise, fix up with the fact type + ElementRequiresFixup(objectType)) { Diagram.FixUpDiagram(link.Model, objectType); } @@ -246,11 +246,14 @@ private static void FactTypedAddedRule(ElementAddedEventArgs e) { ModelElement element = e.ModelElement; - if (!element.IsDeleted && - !MergeContext.HasContext(element.Store.TransactionManager.CurrentTransaction.TopLevelTransaction)) + if (!element.IsDeleted) { ModelHasFactType link = (ModelHasFactType)e.ModelElement; - Diagram.FixUpDiagram(link.Model, link.FactType); + FactType factType = link.FactType; + if (ElementRequiresFixup(factType)) + { + Diagram.FixUpDiagram(link.Model, factType); + } } } #endregion // FactTypeAddedRule @@ -296,13 +299,13 @@ private static void SetConstraintAddedRule(ElementAddedEventArgs e) { ModelElement element = e.ModelElement; - if (!element.IsDeleted && - !MergeContext.HasContext(element.Store.TransactionManager.CurrentTransaction.TopLevelTransaction)) + if (!element.IsDeleted) { ModelHasSetConstraint link = (ModelHasSetConstraint)e.ModelElement; SetConstraint constraint = link.SetConstraint; // Shapes are never added for internal constraints, so there is no point in attempting a fixup - if (!((IConstraint)constraint).ConstraintIsInternal) + if (!((IConstraint)constraint).ConstraintIsInternal && + ElementRequiresFixup(constraint)) { Diagram.FixUpDiagram(link.Model, constraint); } @@ -605,22 +608,35 @@ ObjectType rolePlayer; ORMModel model; if (!link.IsDeleted && - !MergeContext.HasContext(link.Store.TransactionManager.CurrentTransaction.TopLevelTransaction) && null != (associatedFact = link.PlayedRole.FactType) && null == associatedFact.ImpliedByObjectification && null != (model = (rolePlayer = link.RolePlayer).Model)) { FactType nestedFact; + bool continueFixup = false; if (FactTypeShape.ShouldDrawObjectification(nestedFact = rolePlayer.NestedFactType)) { - Diagram.FixUpDiagram(model, nestedFact); - Diagram.FixUpDiagram(nestedFact, rolePlayer); + if (ElementRequiresFixup(nestedFact)) + { + Diagram.FixUpDiagram(model, nestedFact); + Diagram.FixUpDiagram(nestedFact, rolePlayer); + continueFixup = true; + } } - else + else if (ElementRequiresFixup(rolePlayer)) { Diagram.FixUpDiagram(model, rolePlayer); + continueFixup = true; } - Diagram.FixUpDiagram(model, associatedFact); + if (ElementRequiresFixup(associatedFact)) + { + Diagram.FixUpDiagram(model, associatedFact); + continueFixup = true; + } + if (!continueFixup) + { + return; + } object AllowMultipleShapes; Dictionary<object, object> topLevelContextInfo; @@ -1017,9 +1033,12 @@ ORMModel model; if (!link.IsDeleted && !((factType = link.FactType) is SubtypeFact) && - !MergeContext.HasContext(link.Store.TransactionManager.CurrentTransaction.TopLevelTransaction) && null != (model = factType.Model)) { + if (!ElementRequiresFixup(factType)) + { + return; + } Diagram.FixUpDiagram(model, factType); // Make sure the fact type is already there object AllowMultipleShapes; @@ -1107,11 +1126,14 @@ private static void ModelNoteAddedRule(ElementAddedEventArgs e) { ModelElement element = e.ModelElement; - if (!element.IsDeleted && - !MergeContext.HasContext(element.Store.TransactionManager.CurrentTransaction.TopLevelTransaction)) + if (!element.IsDeleted) { ModelHasModelNote link = (ModelHasModelNote)e.ModelElement; - Diagram.FixUpDiagram(link.Model, link.Note); + ModelNote note = link.Note; + if (ElementRequiresFixup(note)) + { + Diagram.FixUpDiagram(link.Model, note); + } } } #endregion // ModelNoteAddedRule @@ -1331,6 +1353,28 @@ } } #endregion // Shape Invalidation Routines + #region Merge context validation rules + /// <summary> + /// Helper method to determine if a fixup operation + /// should be attempted for an added element. Fixup + /// is not needed if presentation elements are dropped, + /// but it is needed if non-presentation elements are dropped + /// directly. + /// </summary> + /// <param name="element">An element that might require a shape.</param> + /// <returns><see langword="true"/> to continue with fixup.</returns> + public static bool ElementRequiresFixup(ModelElement element) + { + Transaction transaction = element.Store.TransactionManager.CurrentTransaction.TopLevelTransaction; + if (DesignSurfaceMergeContext.GetRootPresentationElements(transaction).Count == 0) + { + IList rootElements = DesignSurfaceMergeContext.GetRootModelElements(transaction); + // Merge if no context is given + return rootElements.Count == 0 || rootElements.Contains(element); + } + return false; + } + #endregion // Merge context validation rules #endregion // View Fixup Rules } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2010-09-15 22:04:55
|
Revision: 1457 http://orm.svn.sourceforge.net/orm/?rev=1457&view=rev Author: mcurland Date: 2010-09-15 22:04:48 +0000 (Wed, 15 Sep 2010) Log Message: ----------- More copy/merge targeted changes * Add matching for model notes and copy note links * Fix matching for value ranges with unspecified upper or lower bounds * Add automatic equivalence matching on request for non-duplicate relationships * Add optimization to request a match once per merge instead of continue to ask on failure * Make sure that lead role paths are matched one time only (two equivalent paths with different projections could match twice) * Fix missed calculation matches when a role path had calculations but no conditions Modified Paths: -------------- trunk/ORMModel/Framework/CopyMergeServices.cs trunk/ORMModel/ObjectModel/ORMCore.CopyMergeClosure.cs trunk/ORMModel/ObjectModel/ORMCore.CopyMergeClosure.xml trunk/ORMModel/ObjectModel/ORMCore.ElementEquivalence.cs trunk/ORMModel/ObjectModel/ValueRange.cs Modified: trunk/ORMModel/Framework/CopyMergeServices.cs =================================================================== --- trunk/ORMModel/Framework/CopyMergeServices.cs 2010-09-15 08:17:28 UTC (rev 1456) +++ trunk/ORMModel/Framework/CopyMergeServices.cs 2010-09-15 22:04:48 UTC (rev 1457) @@ -488,7 +488,7 @@ /// Add an element equivalence relationship. /// </summary> /// <param name="nativeElement">The native element, from the <see cref="Store"/> of - /// the instance called the the <see cref="IElementEquivalence"/> interface.</param> + /// the instance called via the <see cref="IElementEquivalence"/> interface.</param> /// <param name="equivalentElement">An equivalent element in the foreign store.</param> /// <remarks>An implementation of this interface should ignore any call with one or /// more values <see langword="null"/></remarks> @@ -496,9 +496,22 @@ /// <summary> /// Get an equivalent mapping previously added with <see cref="AddEquivalentElement"/> /// </summary> - /// <param name="element">The element to find a match for.</param> + /// <param name="nativeElement">The element to find a match for.</param> /// <returns>The equivalent element, if any.</returns> - ModelElement GetEquivalentElement(ModelElement element); + ModelElement GetEquivalentElement(ModelElement nativeElement); + /// <summary> + /// An equivalence test has been attempted for this element + /// but has failed. Track it so another attempt to test + /// equivalence is not made. + /// </summary> + /// <param name="nativeElement">The native element, from the <see cref="Store"/> of + /// the instance called via the <see cref="IElementEquivalence"/> interface.</param> + void AddFailedEquivalentElement(ModelElement nativeElement); + /// <summary> + /// Check if <see cref="AddFailedEquivalentElement"/> has been + /// called for this element. + /// </summary> + bool IsFailedEquivalentElement(ModelElement nativeElement); } #endregion // IElementEquivalence interface #region CopyClosureIntegrationPhase enum @@ -572,12 +585,66 @@ public static T GetEquivalentElement<T>(T element, Store foreignStore, IEquivalentElementTracker elementTracker) where T : ModelElement { T otherElement = elementTracker.GetEquivalentElement(element) as T; - IElementEquivalence testEquivalence; if (otherElement == null && - null != (testEquivalence = element as IElementEquivalence) && - testEquivalence.MapEquivalentElements(foreignStore, elementTracker)) + !elementTracker.IsFailedEquivalentElement(element)) { - otherElement = elementTracker.GetEquivalentElement(element) as T; + IElementEquivalence testEquivalence; + ElementLink link; + DomainRelationshipInfo relationshipInfo; + ReadOnlyCollection<DomainRoleInfo> domainRoles; + DomainRoleInfo firstRole; + DomainRoleInfo secondRole; + ModelElement otherFirstRolePlayer; + ModelElement otherSecondRolePlayer; + if (null != (testEquivalence = element as IElementEquivalence)) + { + if (testEquivalence.MapEquivalentElements(foreignStore, elementTracker)) + { + otherElement = elementTracker.GetEquivalentElement(element) as T; + } + } + else if (null != (link = element as ElementLink) && + !(relationshipInfo = link.GetDomainRelationship()).AllowsDuplicates && + null != (otherFirstRolePlayer = GetEquivalentElement((firstRole = (domainRoles = relationshipInfo.DomainRoles)[0]).GetRolePlayer(link), foreignStore, elementTracker)) && + null != (otherSecondRolePlayer = GetEquivalentElement((secondRole = domainRoles[1]).GetRolePlayer(link), foreignStore, elementTracker))) + { + // See notes on GetElementLinksToElement in ResolveExistingLink + DomainDataDirectory dataDirectory = foreignStore.DomainDataDirectory; + DomainRoleInfo fromOtherRoleInfo; + DomainRoleInfo toOtherRoleInfo; + ModelElement fromOtherElement; + ModelElement toOtherElement; + if (firstRole.IsOne || !secondRole.IsOne) + { + fromOtherRoleInfo = dataDirectory.FindDomainRole(firstRole.Id); + toOtherRoleInfo = dataDirectory.FindDomainRole(secondRole.Id); + fromOtherElement = otherFirstRolePlayer; + toOtherElement = otherSecondRolePlayer; + } + else + { + fromOtherRoleInfo = dataDirectory.FindDomainRole(secondRole.Id); + toOtherRoleInfo = dataDirectory.FindDomainRole(firstRole.Id); + fromOtherElement = otherSecondRolePlayer; + toOtherElement = otherFirstRolePlayer; + } + if (fromOtherRoleInfo != null) // These will be null together, checking one is sufficient + { + foreach (ElementLink otherLink in fromOtherRoleInfo.GetElementLinks(fromOtherElement)) + { + if (toOtherRoleInfo.GetRolePlayer(otherLink) == toOtherElement && + null != (otherElement = otherLink as T)) + { + elementTracker.AddEquivalentElement(element, otherElement); + break; + } + } + } + } + if (otherElement == null) + { + elementTracker.AddFailedEquivalentElement(element); + } } return otherElement; } @@ -597,10 +664,10 @@ } #endregion // Member Variables and Constructor #region IEquivalentElementTracker Implementation - ModelElement IEquivalentElementTracker.GetEquivalentElement(ModelElement element) + ModelElement IEquivalentElementTracker.GetEquivalentElement(ModelElement nativeElement) { ModelElement retVal; - return myElementDictionary.TryGetValue(element, out retVal) ? retVal : null; + return myElementDictionary.TryGetValue(nativeElement, out retVal) ? retVal : null; } void IEquivalentElementTracker.AddEquivalentElement(ModelElement nativeElement, ModelElement equivalentElement) { @@ -609,6 +676,15 @@ myElementDictionary[nativeElement] = equivalentElement; } } + void IEquivalentElementTracker.AddFailedEquivalentElement(ModelElement nativeElement) + { + myElementDictionary[nativeElement] = null; + } + bool IEquivalentElementTracker.IsFailedEquivalentElement(ModelElement nativeElement) + { + ModelElement checkForNull; + return myElementDictionary.TryGetValue(nativeElement, out checkForNull) && checkForNull == null; + } #endregion // IEquivalentElementTracker Implementation } #endregion // StockEquivalentElementTracker class @@ -1237,6 +1313,7 @@ private readonly Dictionary<Guid, MergeIntegrationOrder> myOrderedRoles; private readonly DomainDataDirectory myTargetDataDirectory; private Dictionary<RoleAndElement, ModelElement> myRequiresOrdering; + private Dictionary<Guid, object> myFailedEquivalence; public EquivalenceTracker(Dictionary<Guid, CopiedElement> equivalenceMap, Dictionary<Guid, MergeIntegrationOrder> orderedRoles, DomainDataDirectory targetDataDirectory, Dictionary<RoleAndElement, ModelElement> requiresOrdering) { myEquivalentElementMap = equivalenceMap; @@ -1246,6 +1323,9 @@ } #endregion // Member Variables and Constructor #region EquivalenceTracker specific + /// <summary> + /// Get back the original or on-demand-created ordering dictionary + /// </summary> public Dictionary<RoleAndElement, ModelElement> RequiresOrdering { get @@ -1253,12 +1333,22 @@ return myRequiresOrdering; } } + /// <summary> + /// Test if an identifier is tracked as either a successful + /// or failed equivalence mapping. + /// </summary> + public bool IsKnownIdentifier(Guid elementId) + { + Dictionary<Guid, object> failures; + return myEquivalentElementMap.ContainsKey(elementId) || + (null != (failures = myFailedEquivalence) && failures.ContainsKey(elementId)); + } #endregion // EquivalenceTracker specific #region IEquivalentElementTracker Implementation - ModelElement IEquivalentElementTracker.GetEquivalentElement(ModelElement element) + ModelElement IEquivalentElementTracker.GetEquivalentElement(ModelElement nativeElement) { CopiedElement copiedElement; - return myEquivalentElementMap.TryGetValue(element.Id, out copiedElement) ? copiedElement.Element : null; + return myEquivalentElementMap.TryGetValue(nativeElement.Id, out copiedElement) ? copiedElement.Element : null; } void IEquivalentElementTracker.AddEquivalentElement(ModelElement nativeElement, ModelElement equivalentElement) { @@ -1288,6 +1378,16 @@ } } } + void IEquivalentElementTracker.AddFailedEquivalentElement(ModelElement nativeElement) + { + (myFailedEquivalence ?? (myFailedEquivalence = new Dictionary<Guid, object>()))[nativeElement.Id] = null; + } + bool IEquivalentElementTracker.IsFailedEquivalentElement(ModelElement nativeElement) + { + Dictionary<Guid, object> failedElements; + return null != (failedElements = myFailedEquivalence) && + failedElements.ContainsKey(nativeElement.Id); + } #endregion // IEquivalentElementTracker Implementation } #endregion // EquivalenceTracker class @@ -1388,6 +1488,7 @@ DomainDataDirectory targetDataDirectory = targetStore.DomainDataDirectory; DomainDataDirectory sourceDataDirectory = sourceStore.DomainDataDirectory; EquivalenceTracker tracker = new EquivalenceTracker(resolvedElements, myOrderedRoles, targetDataDirectory, requiresOrdering); + IEquivalentElementTracker trackerAsInterface = tracker; foreach (KeyValuePair<Guid, IClosureElement> pair in copyClosure) { IClosureElement closureElement = pair.Value; @@ -1401,10 +1502,15 @@ break; // Do not attempt to merge duplicate elements case CopyMergeAction.Match: IElementEquivalence equivalence; - if (null != (equivalence = closureElement.Element as IElementEquivalence) && - !resolvedElements.ContainsKey(pair.Key)) + ModelElement element; + if (!tracker.IsKnownIdentifier(pair.Key) && + null != (equivalence = (element = closureElement.Element) as IElementEquivalence)) { - equivalence.MapEquivalentElements(targetStore, tracker); + if (!equivalence.MapEquivalentElements(targetStore, trackerAsInterface) || + null == trackerAsInterface.GetEquivalentElement(element)) + { + trackerAsInterface.AddFailedEquivalentElement(element); + } } break; case CopyMergeAction.Link: Modified: trunk/ORMModel/ObjectModel/ORMCore.CopyMergeClosure.cs =================================================================== --- trunk/ORMModel/ObjectModel/ORMCore.CopyMergeClosure.cs 2010-09-15 08:17:28 UTC (rev 1456) +++ trunk/ORMModel/ObjectModel/ORMCore.CopyMergeClosure.cs 2010-09-15 22:04:48 UTC (rev 1457) @@ -192,6 +192,7 @@ closureManager.AddCopyClosureDirective(new DomainRoleClosureRestriction(GroupingElementRelationship.ElementDomainRoleId), new DomainRoleClosureRestriction(GroupingElementRelationship.GroupingDomainRoleId), CopyClosureDirectiveOptions.None, CopyClosureBehavior.ExternalReferencedPart); closureManager.AddCopyClosureDirective(new DomainRoleClosureRestriction(LeadRolePathSatisfiesCalculatedCondition.LeadRolePathDomainRoleId), new DomainRoleClosureRestriction(LeadRolePathSatisfiesCalculatedCondition.CalculatedConditionDomainRoleId), CopyClosureDirectiveOptions.None, CopyClosureBehavior.InternalReferencedPart); closureManager.AddCopyClosureDirective(new DomainRoleClosureRestriction(LeadRolePathSatisfiesCalculatedCondition.LeadRolePathDomainRoleId), new DomainRoleClosureRestriction(LeadRolePathSatisfiesCalculatedCondition.CalculatedConditionDomainRoleId), CopyClosureDirectiveOptions.None, CopyClosureBehavior.InternalReferencedPart); + closureManager.AddCopyClosureDirective(new DomainRoleClosureRestriction(ModelNoteReferencesModelElement.ElementDomainRoleId), new DomainRoleClosureRestriction(ModelNoteReferencesModelElement.NoteDomainRoleId), CopyClosureDirectiveOptions.None, CopyClosureBehavior.ExternalReferencedPart); closureManager.AddCopyClosureDirective(new DomainRoleClosureRestriction(Objectification.NestingTypeDomainRoleId), new DomainRoleClosureRestriction(Objectification.NestedFactTypeDomainRoleId), CopyClosureDirectiveOptions.None, CopyClosureBehavior.ExternalCompositePart); closureManager.AddCopyClosureDirective(new DomainRoleClosureRestriction(Objectification.NestedFactTypeDomainRoleId), new DomainRoleClosureRestriction(Objectification.NestingTypeDomainRoleId), CopyClosureDirectiveOptions.None, CopyClosureBehavior.ExternalCompositePart); closureManager.AddCopyClosureDirective(new DomainRoleClosureRestriction(ObjectificationImpliesFactType.ImpliedFactTypeDomainRoleId), new DomainRoleClosureRestriction(ObjectificationImpliesFactType.ImpliedByObjectificationDomainRoleId), CopyClosureDirectiveOptions.None, CopyClosureBehavior.ExternalCompositePart); Modified: trunk/ORMModel/ObjectModel/ORMCore.CopyMergeClosure.xml =================================================================== --- trunk/ORMModel/ObjectModel/ORMCore.CopyMergeClosure.xml 2010-09-15 08:17:28 UTC (rev 1456) +++ trunk/ORMModel/ObjectModel/ORMCore.CopyMergeClosure.xml 2010-09-15 22:04:48 UTC (rev 1457) @@ -205,6 +205,10 @@ <cmc:ClosureRole relationship="ValueTypeHasDataType" role="DataType" closureBehavior="ExternalReferencedPart"/> <cmc:ClosureRole relationship="ReferenceModeHasReferenceModeKind" role="Kind" closureBehavior="ExternalReferencedPart"/> <cmc:ClosureRole relationship="ReadingOrderHasRole" role="Role" closureBehavior="InternalReferencedPart" order="From"/> + <!-- UNDONE: COPYMERGE This is temporary for notes (bring in the note with a referencing element). We actually + want a weak relationship, where the ModelNote reference is pulled in only if both role players are pulled in for other + reasons. We need a notion of a MatchOnly element (match, but do not create) and a non-propagating relationship. --> + <cmc:ClosureRole relationship="ModelNoteReferencesModelElement" role="Note" closureBehavior="ExternalReferencedPart"/> <!-- Role path closures --> <cmc:ClosureRole relationship="LeadRolePathSatisfiesCalculatedCondition" role="CalculatedCondition" closureBehavior="InternalReferencedPart"/> Modified: trunk/ORMModel/ObjectModel/ORMCore.ElementEquivalence.cs =================================================================== --- trunk/ORMModel/ObjectModel/ORMCore.ElementEquivalence.cs 2010-09-15 08:17:28 UTC (rev 1456) +++ trunk/ORMModel/ObjectModel/ORMCore.ElementEquivalence.cs 2010-09-15 22:04:48 UTC (rev 1457) @@ -1212,8 +1212,9 @@ /// </summary> protected bool MapEquivalentElements(Store foreignStore, IEquivalentElementTracker elementTracker) { + RolePathOwner pathOwner = PathOwner; RolePathOwner otherPathOwner; - if (null != (otherPathOwner = CopyMergeUtility.GetEquivalentElement(PathOwner, foreignStore, elementTracker))) + if (null != (otherPathOwner = CopyMergeUtility.GetEquivalentElement(pathOwner, foreignStore, elementTracker))) { LinkedElementCollection<PathObjectUnifier> unifiers = null; LinkedElementCollection<CalculatedPathValue> conditions = null; @@ -1225,8 +1226,37 @@ int[] matchingOtherUnifiers = null; // Array indexed into other unifiers (index +1, zero means empty) BitTracker matchedOthers = default(BitTracker); Dictionary<ModelElement, ModelElement> preMatchedElements = null; + LinkedElementCollection<LeadRolePath> allOwnedPaths = pathOwner.OwnedLeadRolePathCollection; + if (allOwnedPaths.Count == 1) + { + allOwnedPaths = null; + } foreach (LeadRolePath otherLeadRolePath in otherPathOwner.OwnedLeadRolePathCollection) { + if (allOwnedPaths != null) + { + bool previouslyMatched = false; + foreach (LeadRolePath ownedPath in allOwnedPaths) + { + if (ownedPath != this && + elementTracker.GetEquivalentElement(ownedPath) == otherLeadRolePath) + { + // Do a sanity check before we continue. It is possible for one owner + // to have two equivalent paths (possibly with alternate projections, etc). + // The merge framework does not track reverse elements, so we need to make + // sure that we don't match with two different things. Without this check, + // two projections can end up mapping the same lead role path. For the more + // common case of a relatively small number of different paths, this also + // avoids repetitions of the matching code below. + previouslyMatched = true; + break; + } + } + if (previouslyMatched) + { + continue; + } + } if (preMatchedElements == null) { preMatchedElements = new Dictionary<ModelElement,ModelElement>(); @@ -1392,6 +1422,11 @@ // All conditions match, the paths are equivalent. // Now try top pair up any remaining unmapped functions. + if (calculations == null) + { + calculations = CalculatedValueCollection; + calculationCount = calculations.Count; + } if (calculationCount != 0) { int otherCalculationCount; @@ -1799,6 +1834,33 @@ } } #endregion // CalculatedPathValue class + #region CalculatedPathValueInput class + partial class CalculatedPathValueInput : IElementEquivalence + { + /// <summary> + /// Implements <see cref="IElementEquivalence.MapEquivalentElements"/> + /// Match the calculation input based on the associated lead role path. + /// IElementEquivalence is implemented on path components that are referenced from + /// outside the path structure or nest 1-1 mapped elements. + /// </summary> + protected bool MapEquivalentElements(Store foreignStore, IEquivalentElementTracker elementTracker) + { + CalculatedPathValue calculation; + LeadRolePath rolePath; + if (null != (calculation = CalculatedValue) && + null != (rolePath = calculation.LeadRolePath) && + CopyMergeUtility.GetEquivalentElement(rolePath, foreignStore, elementTracker) != null) + { + return elementTracker.GetEquivalentElement(this) != null; + } + return false; + } + bool IElementEquivalence.MapEquivalentElements(Store foreignStore, IEquivalentElementTracker elementTracker) + { + return MapEquivalentElements(foreignStore, elementTracker); + } + } + #endregion // CalculatedPathValueInput class #region RecognizedPhrase class partial class RecognizedPhrase : IElementEquivalence { @@ -1870,4 +1932,33 @@ } } #endregion // NameAlias class + #region ModelNote class + partial class ModelNote : IElementEquivalence + { + /// <summary> + /// Implements <see cref="IElementEquivalence.MapEquivalentElements"/> + /// </summary> + protected new bool MapEquivalentElements(Store foreignStore, IEquivalentElementTracker elementTracker) + { + foreach (ORMModel otherModel in foreignStore.ElementDirectory.FindElements<ORMModel>(false)) + { + string matchText = Text; + foreach (ModelNote otherNote in otherModel.NoteCollection) + { + if (otherNote.Text == matchText) + { + elementTracker.AddEquivalentElement(this, otherNote); + return true; + } + } + break; + } + return false; + } + bool IElementEquivalence.MapEquivalentElements(Store foreignStore, IEquivalentElementTracker elementTracker) + { + return MapEquivalentElements(foreignStore, elementTracker); + } + } + #endregion // ModelNote class } Modified: trunk/ORMModel/ObjectModel/ValueRange.cs =================================================================== --- trunk/ORMModel/ObjectModel/ValueRange.cs 2010-09-15 08:17:28 UTC (rev 1456) +++ trunk/ORMModel/ObjectModel/ValueRange.cs 2010-09-15 22:04:48 UTC (rev 1457) @@ -1707,6 +1707,28 @@ for (int i = 0; i < rangeCount; ++i) { ValueRange range = ranges[i]; + string rangeMin = range.MinValue; + bool minParsed; + if (string.IsNullOrEmpty(rangeMin)) + { + rangeMin = null; + minParsed = false; + } + else + { + minParsed = dataType.ParseNormalizeValue(rangeMin, range.InvariantMinValue, out rangeMin); + } + string rangeMax = range.MaxValue; + bool maxParsed; + if (string.IsNullOrEmpty(rangeMax)) + { + rangeMax = null; + maxParsed = false; + } + else + { + maxParsed = dataType.ParseNormalizeValue(rangeMax, range.InvariantMaxValue, out rangeMax); + } for (int j = 0; j < otherRangeCount; ++j) { if (!otherMatches[j]) @@ -1718,20 +1740,43 @@ // integration is complete. We use the current data type to // compare values, and leave it up to rules to sort out the // remaining issues after data type information is complete. - string normalizedValue; - string otherNormalizedValue; - if (dataType.ParseNormalizeValue(range.MinValue, range.InvariantMinValue, out normalizedValue) && - dataType.ParseNormalizeValue(otherRange.MinValue, otherRange.InvariantMinValue, out otherNormalizedValue) && - (canCompare ? (dataType.Compare(normalizedValue, otherNormalizedValue) == 0) : (normalizedValue == otherNormalizedValue)) && - dataType.ParseNormalizeValue(range.MaxValue, range.InvariantMaxValue, out normalizedValue) && - dataType.ParseNormalizeValue(otherRange.MaxValue, otherRange.InvariantMaxValue, out otherNormalizedValue) && - (canCompare ? (dataType.Compare(normalizedValue, otherNormalizedValue) == 0) : (normalizedValue == otherNormalizedValue))) + string otherRangeBound = otherRange.MinValue; + if (string.IsNullOrEmpty(otherRangeBound)) { - // Ignore endpoint inclusion properties for merging, consider these sufficient equivalent ranges to match. - elementTracker.AddEquivalentElement(range, otherRange); - otherMatches[j] = true; - break; + if (rangeMin != null) + { + continue; + } } + else if (minParsed != dataType.ParseNormalizeValue(otherRangeBound, otherRange.InvariantMinValue, out otherRangeBound)) + { + continue; + } + else if (!((canCompare && minParsed) ? (dataType.Compare(rangeMin, otherRangeBound) == 0) : (rangeMin == otherRangeBound))) + { + continue; + } + otherRangeBound = otherRange.MaxValue; + if (string.IsNullOrEmpty(otherRangeBound)) + { + if (rangeMax != null) + { + continue; + } + } + else if (maxParsed != dataType.ParseNormalizeValue(otherRangeBound, otherRange.InvariantMaxValue, out otherRangeBound)) + { + continue; + } + else if (!((canCompare && maxParsed) ? (dataType.Compare(rangeMax, otherRangeBound) == 0) : (rangeMax == otherRangeBound))) + { + continue; + } + + // Ignore endpoint inclusion properties for merging, consider these sufficient equivalent ranges to match. + elementTracker.AddEquivalentElement(range, otherRange); + otherMatches[j] = true; + break; } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2010-10-26 07:45:42
|
Revision: 1463 http://orm.svn.sourceforge.net/orm/?rev=1463&view=rev Author: mcurland Date: 2010-10-26 07:45:34 +0000 (Tue, 26 Oct 2010) Log Message: ----------- * Unguarded cross-model merge rule was creating two link fact types on unary objectification, model would not reload. refs #403 * Automatic join paths failing with constrained roles on the same role player of fully symmetric binary fact types (both role players the same). Favor the role away from the join. Adjustment of [1460]. refs #395 * Shape placement of automatically-created shapes during cross-model merge is not respecting the specified element creation. Modified Paths: -------------- trunk/ORMModel/Framework/CopyMergeServices.cs trunk/ORMModel/ObjectModel/Constraint.cs trunk/ORMModel/ObjectModel/Objectification.cs trunk/ORMModel/ShapeModel/ORMDiagram.cs Modified: trunk/ORMModel/Framework/CopyMergeServices.cs =================================================================== --- trunk/ORMModel/Framework/CopyMergeServices.cs 2010-10-22 20:52:58 UTC (rev 1462) +++ trunk/ORMModel/Framework/CopyMergeServices.cs 2010-10-26 07:45:34 UTC (rev 1463) @@ -1678,14 +1678,17 @@ if (copy.CopyType == CopiedElementType.Existing) { ModelElement copyElement = copy.Element; - PropertyAssignment[] propertyAssignments = GetCopiedPropertyAssignments(copyClosure[pair.Key].Element, copyElement); - if (propertyAssignments != null) + if (!copyElement.IsDeleted) { - // Update the element with new property assignments - for (int i = 0; i < propertyAssignments.Length; ++i) + PropertyAssignment[] propertyAssignments = GetCopiedPropertyAssignments(copyClosure[pair.Key].Element, copyElement); + if (propertyAssignments != null) { - PropertyAssignment assignment = propertyAssignments[i]; - targetDataDirectory.GetDomainProperty(assignment.PropertyId).SetValue(copyElement, assignment.Value); + // Update the element with new property assignments + for (int i = 0; i < propertyAssignments.Length; ++i) + { + PropertyAssignment assignment = propertyAssignments[i]; + targetDataDirectory.GetDomainProperty(assignment.PropertyId).SetValue(copyElement, assignment.Value); + } } } } Modified: trunk/ORMModel/ObjectModel/Constraint.cs =================================================================== --- trunk/ORMModel/ObjectModel/Constraint.cs 2010-10-22 20:52:58 UTC (rev 1462) +++ trunk/ORMModel/ObjectModel/Constraint.cs 2010-10-26 07:45:34 UTC (rev 1463) @@ -5370,8 +5370,14 @@ matchedRightRole = testRightRole; matchedRightRoleAlternateEntryConstraintRoleIndex = testRightRoleAlternateEntryConstraintRoleIndex; } - else + else if (matchedRightRoleAlternateEntryConstraintRoleIndex != -1 && matchedLeftRole == null) { + // Prefer the opposite role over the alternate entry through the constraint role + matchedRightRole = testRightRole; + matchedRightRoleAlternateEntryConstraintRoleIndex = -1; + } + else if (testRightRoleAlternateEntryConstraintRoleIndex == -1) + { incompleteOrAmbiguousPath = true; break; } @@ -5520,8 +5526,15 @@ matchedRightRole = testRightRole; matchedRightRoleAlternateEntryConstraintRoleIndex = testRightRoleAlternateEntryConstraintRoleIndex; } - else + else if (matchedRightRoleAlternateEntryConstraintRoleIndex != -1) { + // Always prefer the opposite role over the near role + matchedLeftRole = testLeftRole; + matchedRightRole = testRightRole; + matchedRightRoleAlternateEntryConstraintRoleIndex = -1; + } + else if (testRightRoleAlternateEntryConstraintRoleIndex == -1) + { incompleteOrAmbiguousPath = true; break; } Modified: trunk/ORMModel/ObjectModel/Objectification.cs =================================================================== --- trunk/ORMModel/ObjectModel/Objectification.cs 2010-10-22 20:52:58 UTC (rev 1462) +++ trunk/ORMModel/ObjectModel/Objectification.cs 2010-10-26 07:45:34 UTC (rev 1463) @@ -334,14 +334,25 @@ /// </summary> private static void ObjectificationAddedRule(ElementAddedEventArgs e) { - ProcessObjectificationAdded((Objectification)e.ModelElement, null, null); + ModelElement element = e.ModelElement; + if (CopyMergeUtility.GetIntegrationPhase(element.Store) == CopyClosureIntegrationPhase.Integrating) + { + return; + } + ProcessObjectificationAdded((Objectification)element, null, null); } /// <summary> /// AddRule: typeof(Objectification), FireTime=LocalCommit, Priority=FrameworkDomainModel.CopyClosureExpansionCompletedRulePriority; /// </summary> private static void ObjectificationAddedClosureRule(ElementAddedEventArgs e) { - ProcessObjectificationAdded((Objectification)e.ModelElement, null, null); + ModelElement element = e.ModelElement; + if (element.IsDeleted || + CopyMergeUtility.GetIntegrationPhase(element.Store) != CopyClosureIntegrationPhase.IntegrationComplete) + { + return; + } + ProcessObjectificationAdded((Objectification)element, null, null); } /// <summary> /// Create implied facts and constraints as needed @@ -352,11 +363,6 @@ private static void ProcessObjectificationAdded(Objectification objectification, FactType nestedFactType, ObjectType nestingType) { Store store = objectification.Store; - if (objectification.IsDeleted || - CopyMergeUtility.GetIntegrationPhase(store) == CopyClosureIntegrationPhase.Integrating) - { - return; - } if (nestedFactType == null) { nestedFactType = objectification.NestedFactType; @@ -400,19 +406,31 @@ for (int i = 0; i < roleCount; ++i) { Role role = roles[i].Role; - RoleProxy proxy = role.Proxy; - if (proxy == null) + RoleProxy proxy; + ObjectifiedUnaryRole objectifiedUnaryRole; + if (unaryRole == null) { - if (unaryRole == null || role == unaryRole) + objectifiedUnaryRole = null; + proxy = role.Proxy; + } + else + { + if (unaryRole != role) { - CreateImpliedFactTypeForRole(model, nestingType, role, objectification, unaryRole != null); + continue; } + objectifiedUnaryRole = unaryRole.ObjectifiedUnaryRole; + proxy = null; } + if (proxy == null && objectifiedUnaryRole == null) + { + CreateImpliedFactTypeForRole(model, nestingType, role, objectification, unaryRole != null); + } else { RoleBase oppositeRoleBase; Role oppositeRole; - if (null != (oppositeRoleBase = proxy.OppositeRole) && + if (null != (oppositeRoleBase = ((RoleBase)proxy ?? objectifiedUnaryRole).OppositeRole) && null != (oppositeRole = oppositeRoleBase as Role) && (nestingType != oppositeRole.RolePlayer)) { @@ -538,7 +556,8 @@ { oldFactType = (FactType)e.OldRolePlayer; } - RuleManager ruleManager = link.Store.RuleManager; + Store store = link.Store; + RuleManager ruleManager = store.RuleManager; try { ruleManager.DisableRule(typeof(RoleDeletingRuleClass)); @@ -549,6 +568,11 @@ ruleManager.EnableRule(typeof(RoleDeletingRuleClass)); } ProcessObjectificationDeleting(link, oldFactType, oldObjectType); + // UNDONE: COPYMERGE Element equivalence does not produce an + // objectification role player change, it just equates the old + // object type with the new one. If this changes (as it probably + // should to handle objectification change scenarios) then we will + // need to check merge state here. ProcessObjectificationAdded(link, null, null); } #endregion // ObjectificationRolePlayerChangedRule Modified: trunk/ORMModel/ShapeModel/ORMDiagram.cs =================================================================== --- trunk/ORMModel/ShapeModel/ORMDiagram.cs 2010-10-22 20:52:58 UTC (rev 1462) +++ trunk/ORMModel/ShapeModel/ORMDiagram.cs 2010-10-26 07:45:34 UTC (rev 1463) @@ -380,6 +380,19 @@ if (clearContext) { DropTargetContext.Remove(transaction.TopLevelTransaction); + NodeShape nodeShape; + if (null != (nodeShape = shapeElement as NodeShape) && + nodeShape.Location.IsEmpty) + { + // Backup plan if the location doesn't take. This can + // happen if an element is being automatically created + // during the drop of another shape element, such as + // during cross-model drops. In this case, the design + // surface merge context is set, this shape is not + // considered root element, and the drop target context + // location is ignored by ShapeElement.PlaceChildShapeUsingContext + nodeShape.Location = elementPosition; + } } if (shapeElement != null) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mcu...@us...> - 2011-07-27 17:35:06
|
Revision: 1474 http://orm.svn.sourceforge.net/orm/?rev=1474&view=rev Author: mcurland Date: 2011-07-27 17:34:59 +0000 (Wed, 27 Jul 2011) Log Message: ----------- * FactTypeShape displayed as object type does not reconnect role players on file reload. refs #406 * Eliminate some allowed ring type combinations from ring type picker display (Irreflexive+Symmetric disallows Transitive because Transitive+Symmetric implies Reflexive, similarly for Irreflexive+Transitive disallows Symmetric) refs #407 * Added descriptive tooltips to ring type picker glyphs Modified Paths: -------------- trunk/ORMModel/ObjectModel/Design/Editors/RingConstraintTypePicker.cs trunk/ORMModel/ObjectModel/ORMModel.resx trunk/ORMModel/Resources/ResourceStringsGenerator.cs trunk/ORMModel/Resources/ResourceStringsGenerator.xml trunk/ORMModel/ShapeModel/ORMDiagram.cs Modified: trunk/ORMModel/ObjectModel/Design/Editors/RingConstraintTypePicker.cs =================================================================== --- trunk/ORMModel/ObjectModel/Design/Editors/RingConstraintTypePicker.cs 2011-06-30 02:39:04 UTC (rev 1473) +++ trunk/ORMModel/ObjectModel/Design/Editors/RingConstraintTypePicker.cs 2011-07-27 17:34:59 UTC (rev 1474) @@ -104,6 +104,7 @@ public readonly RingConstraintType[] ImpliedByCombination; // Theoretically [][], but doesn't actually happen public readonly RingConstraintType[] UsedInCombinationBy; public readonly string DisplayName; + public readonly string Description; public readonly SurveyQuestionGlyph Glyph; public SingleRingTypeInfo( RingConstraintType nodeType, @@ -113,6 +114,7 @@ RingConstraintType[] impliedByCombination, RingConstraintType[] usedInCombinationBy, string displayName, + string description, SurveyQuestionGlyph glyph) { NodeType = nodeType; @@ -122,6 +124,7 @@ ImpliedByCombination = impliedByCombination; UsedInCombinationBy = usedInCombinationBy; DisplayName = displayName; + Description = description; Glyph = glyph; } } @@ -155,6 +158,7 @@ null, null, enumNames[(int)RingConstraintType.Irreflexive], + ResourceStrings.RingConstraintTypeDescriptionIrreflexive, SurveyQuestionGlyph.RingIrreflexive) , new SingleRingTypeInfo( RingConstraintType.Antisymmetric, @@ -164,6 +168,7 @@ null, null, enumNames[(int)RingConstraintType.Antisymmetric], + ResourceStrings.RingConstraintTypeDescriptionAntisymmetric, SurveyQuestionGlyph.RingAntisymmetric) , new SingleRingTypeInfo( RingConstraintType.Asymmetric, @@ -173,6 +178,7 @@ null, null, enumNames[(int)RingConstraintType.Asymmetric], + ResourceStrings.RingConstraintTypeDescriptionAsymmetric, SurveyQuestionGlyph.RingAsymmetric) , new SingleRingTypeInfo( RingConstraintType.Intransitive, @@ -182,6 +188,7 @@ null, null, enumNames[(int)RingConstraintType.Intransitive], + ResourceStrings.RingConstraintTypeDescriptionIntransitive, SurveyQuestionGlyph.RingIntransitive) , new SingleRingTypeInfo( RingConstraintType.StronglyIntransitive, @@ -191,6 +198,7 @@ null, null, enumNames[(int)RingConstraintType.StronglyIntransitive], + ResourceStrings.RingConstraintTypeDescriptionStronglyIntransitive, SurveyQuestionGlyph.RingStronglyIntransitive) , new SingleRingTypeInfo( RingConstraintType.Acyclic, @@ -200,6 +208,7 @@ null, null, enumNames[(int)RingConstraintType.Acyclic], + ResourceStrings.RingConstraintTypeDescriptionAcyclic, SurveyQuestionGlyph.RingAcyclic) , new SingleRingTypeInfo( RingConstraintType.PurelyReflexive, @@ -209,7 +218,13 @@ null, null, enumNames[(int)RingConstraintType.PurelyReflexive], + ResourceStrings.RingConstraintTypeDescriptionPurelyReflexive, SurveyQuestionGlyph.RingPurelyReflexive) + // Note that if any two of Reflexive/Symmetric/Transitive are selected then the + // third remains bold (or implied if Symmetric/Transitive is selected). This is + // slightly inconsistent with the other selections, but is reasonable from a + // usability perspective as selecting the third positive ring type will simply + // make reflexive implied, not turn it off. , new SingleRingTypeInfo( RingConstraintType.Reflexive, new RingConstraintType[]{RingConstraintType.Irreflexive, RingConstraintType.Asymmetric, RingConstraintType.Intransitive, RingConstraintType.StronglyIntransitive, RingConstraintType.Acyclic}, @@ -218,24 +233,27 @@ new RingConstraintType[]{RingConstraintType.Symmetric, RingConstraintType.Transitive}, null, enumNames[(int)RingConstraintType.Reflexive], + ResourceStrings.RingConstraintTypeDescriptionReflexive, SurveyQuestionGlyph.RingReflexive) , new SingleRingTypeInfo( RingConstraintType.Symmetric, new RingConstraintType[]{RingConstraintType.Antisymmetric, RingConstraintType.Asymmetric, RingConstraintType.Acyclic}, - null, + new RingConstraintType[]{RingConstraintType.Irreflexive, RingConstraintType.Transitive}, new RingConstraintType[]{RingConstraintType.PurelyReflexive}, null, - new RingConstraintType[]{RingConstraintType.Reflexive, RingConstraintType.Irreflexive}, + new RingConstraintType[]{RingConstraintType.Reflexive, RingConstraintType.Irreflexive, RingConstraintType.Transitive}, enumNames[(int)RingConstraintType.Symmetric], + ResourceStrings.RingConstraintTypeDescriptionSymmetric, SurveyQuestionGlyph.RingSymmetric) , new SingleRingTypeInfo( RingConstraintType.Transitive, new RingConstraintType[]{RingConstraintType.Intransitive, RingConstraintType.StronglyIntransitive, RingConstraintType.PurelyReflexive}, + new RingConstraintType[]{RingConstraintType.Irreflexive, RingConstraintType.Symmetric}, null, null, - null, - new RingConstraintType[]{RingConstraintType.Reflexive, RingConstraintType.Irreflexive}, + new RingConstraintType[]{RingConstraintType.Reflexive, RingConstraintType.Irreflexive, RingConstraintType.Symmetric}, enumNames[(int)RingConstraintType.Transitive], + ResourceStrings.RingConstraintTypeDescriptionTransitive, SurveyQuestionGlyph.RingTransitive) }; int[] enumToPositionMap = new int[SingleRingTypeCount + 1]; // Note that undefined is at 0, so real values start at 1 @@ -644,6 +662,17 @@ { return mySingleNodes[row].DisplayName; } + string IBranch.GetTipText(int row, int column, ToolTipType tipType) + { + switch (tipType) + { + case ToolTipType.Icon: + return mySingleNodes[row].Description; + case ToolTipType.StateIcon: + return ""; + } + return null; + } int IBranch.VisibleItemCount { get @@ -808,10 +837,6 @@ { return null; } - string IBranch.GetTipText(int row, int column, ToolTipType tipType) - { - return null; - } bool IBranch.IsExpandable(int row, int column) { return false; Modified: trunk/ORMModel/ObjectModel/ORMModel.resx =================================================================== --- trunk/ORMModel/ObjectModel/ORMModel.resx 2011-06-30 02:39:04 UTC (rev 1473) +++ trunk/ORMModel/ObjectModel/ORMModel.resx 2011-07-27 17:34:59 UTC (rev 1474) @@ -1070,6 +1070,36 @@ <data name="RingConstraintType.AsymmetricStronglyIntransitive" xml:space="preserve"> <value>Asymmetric and Strongly Intransitive</value> </data> + <data name="RingConstraintType.Description.Acyclic" xml:space="preserve"> + <value>Acyclic:
No A may cycle back to itself via one or more traversals through “A relates to A”.</value> + </data> + <data name="RingConstraintType.Description.Antisymmetric" xml:space="preserve"> + <value>Antisymmetric:
If A1 relates to A2 and A1 is not A2
 then it is impossible that A2 relates to A1.</value> + </data> + <data name="RingConstraintType.Description.Asymmetric" xml:space="preserve"> + <value>Asymmetric:
If A1 relates to A2
 then it is impossible that A2 relates to A1.</value> + </data> + <data name="RingConstraintType.Description.Intransitive" xml:space="preserve"> + <value>Intransitive:
If A1 relates to A2 and A2 relates to A3
 then it is impossible that A2 relates to A3.</value> + </data> + <data name="RingConstraintType.Description.Irreflexive" xml:space="preserve"> + <value>Irreflexive:
No A relates to itself.</value> + </data> + <data name="RingConstraintType.Description.PurelyReflexive" xml:space="preserve"> + <value>Purely Reflexive:
If A1 relates to some A2
 then A1 = A2.</value> + </data> + <data name="RingConstraintType.Description.Reflexive" xml:space="preserve"> + <value>Reflexive:
If A1 relates to some A2
 then A1 relates to itself.</value> + </data> + <data name="RingConstraintType.Description.StronglyIntransitive" xml:space="preserve"> + <value>Strongly Intransitive:
If A1 relates to some A2
 then it is not true that A1 is indirectly related to A2 by repeatedly applying this fact type.</value> + </data> + <data name="RingConstraintType.Description.Symmetric" xml:space="preserve"> + <value>Symmetric:
If A1 relates to A2
 then A2 relates to A1.</value> + </data> + <data name="RingConstraintType.Description.Transitive" xml:space="preserve"> + <value>Transitive:
If A1 relates to A2 and A2 relates to A3
 then A1 relates to A3.</value> + </data> <data name="RingConstraintType.Intransitive" xml:space="preserve"> <value>Intransitive</value> </data> Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.cs =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2011-06-30 02:39:04 UTC (rev 1473) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.cs 2011-07-27 17:34:59 UTC (rev 1474) @@ -1612,6 +1612,76 @@ return ResourceStrings.GetString(ResourceManagers.Model, "ModelException.ValueTypeInstance.InvalidValueTypeParent"); } } + public static string RingConstraintTypeDescriptionAcyclic + { + get + { + return ResourceStrings.GetString(ResourceManagers.Model, "RingConstraintType.Description.Acyclic"); + } + } + public static string RingConstraintTypeDescriptionAntisymmetric + { + get + { + return ResourceStrings.GetString(ResourceManagers.Model, "RingConstraintType.Description.Antisymmetric"); + } + } + public static string RingConstraintTypeDescriptionAsymmetric + { + get + { + return ResourceStrings.GetString(ResourceManagers.Model, "RingConstraintType.Description.Asymmetric"); + } + } + public static string RingConstraintTypeDescriptionIntransitive + { + get + { + return ResourceStrings.GetString(ResourceManagers.Model, "RingConstraintType.Description.Intransitive"); + } + } + public static string RingConstraintTypeDescriptionIrreflexive + { + get + { + return ResourceStrings.GetString(ResourceManagers.Model, "RingConstraintType.Description.Irreflexive"); + } + } + public static string RingConstraintTypeDescriptionPurelyReflexive + { + get + { + return ResourceStrings.GetString(ResourceManagers.Model, "RingConstraintType.Description.PurelyReflexive"); + } + } + public static string RingConstraintTypeDescriptionReflexive + { + get + { + return ResourceStrings.GetString(ResourceManagers.Model, "RingConstraintType.Description.Reflexive"); + } + } + public static string RingConstraintTypeDescriptionStronglyIntransitive + { + get + { + return ResourceStrings.GetString(ResourceManagers.Model, "RingConstraintType.Description.StronglyIntransitive"); + } + } + public static string RingConstraintTypeDescriptionSymmetric + { + get + { + return ResourceStrings.GetString(ResourceManagers.Model, "RingConstraintType.Description.Symmetric"); + } + } + public static string RingConstraintTypeDescriptionTransitive + { + get + { + return ResourceStrings.GetString(ResourceManagers.Model, "RingConstraintType.Description.Transitive"); + } + } /// <summary>This text appears in the edit menu when fact types are selected in the diagram.</summary> public static string CommandDeleteFactTypeText { Modified: trunk/ORMModel/Resources/ResourceStringsGenerator.xml =================================================================== --- trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2011-06-30 02:39:04 UTC (rev 1473) +++ trunk/ORMModel/Resources/ResourceStringsGenerator.xml 2011-07-27 17:34:59 UTC (rev 1474) @@ -251,6 +251,16 @@ <ResourceString name="ModelExceptionEntityTypeSubtypeInstanceDuplicateSupertypeInstance" model="Model" resourceName="ModelException.EntityTypeSubtypeInstance.DuplicateSupertypeInstance"/> <ResourceString name="ModelExceptionEntityTypeSubtypeInstanceEnforceInitialSubtypeInstance" model="Model" resourceName="ModelException.EntityTypeSubtypeInstance.EnforceInitialSubtypeInstance"/> <ResourceString name="ModelExceptionValueTypeInstanceInvalidValueTypeParent" model="Model" resourceName="ModelException.ValueTypeInstance.InvalidValueTypeParent"/> + <ResourceString name="RingConstraintTypeDescriptionAcyclic" model="Model" resourceName="RingConstraintType.Description.Acyclic"/> + <ResourceString name="RingConstraintTypeDescriptionAntisymmetric" model="Model" resourceName="RingConstraintType.Description.Antisymmetric"/> + <ResourceString name="RingConstraintTypeDescriptionAsymmetric" model="Model" resourceName="RingConstraintType.Description.Asymmetric"/> + <ResourceString name="RingConstraintTypeDescriptionIntransitive" model="Model" resourceName="RingConstraintType.Description.Intransitive"/> + <ResourceString name="RingConstraintTypeDescriptionIrreflexive" model="Model" resourceName="RingConstraintType.Description.Irreflexive"/> + <ResourceString name="RingConstraintTypeDescriptionPurelyReflexive" model="Model" resourceName="RingConstraintType.Description.PurelyReflexive"/> + <ResourceString name="RingConstraintTypeDescriptionReflexive" model="Model" resourceName="RingConstraintType.Description.Reflexive"/> + <ResourceString name="RingConstraintTypeDescriptionStronglyIntransitive" model="Model" resourceName="RingConstraintType.Description.StronglyIntransitive"/> + <ResourceString name="RingConstraintTypeDescriptionSymmetric" model="Model" resourceName="RingConstraintType.Description.Symmetric"/> + <ResourceString name="RingConstraintTypeDescriptionTransitive" model="Model" resourceName="RingConstraintType.Description.Transitive"/> <ResourceString name="CommandDeleteFactTypeText" model="Diagram" resourceName="Command.DeleteFactType.Text"/> <ResourceString name="CommandDeleteObjectTypeText" model="Diagram" resourceName="Command.DeleteObjectType.Text"/> <ResourceString name="CommandDeleteConstraintText" model="Diagram" resourceName="Command.DeleteConstraint.Text"/> Modified: trunk/ORMModel/ShapeModel/ORMDiagram.cs =================================================================== --- trunk/ORMModel/ShapeModel/ORMDiagram.cs 2011-06-30 02:39:04 UTC (rev 1473) +++ trunk/ORMModel/ShapeModel/ORMDiagram.cs 2011-07-27 17:34:59 UTC (rev 1474) @@ -1002,6 +1002,31 @@ #endregion //StickyEditObject #region View Fixup Methods /// <summary> + /// Used by <see cref="ShouldAddShapeForElement"/> to map an + /// element that is not directly displayed shaped one with displayed + /// elements. The default representation maps a <see cref="Role"/> to + /// its parent <see cref="FactType"/> and an objectified <see cref="ObjectType"/> + /// to the objectifying <see cref="FactType"/>. + /// </summary> + /// <param name="element">The element to be displayed or redirected.</param> + /// <returns>The input element, or displayed element.</returns> + protected virtual ModelElement RedirectToDisplayedElement(ModelElement element) + { + Role role; + ObjectType objectType; + Objectification objectification; + if (null != (role = element as Role)) + { + element = role.FactType; + } + else if (null != (objectType = element as ObjectType) && + null != (objectification = objectType.Objectification)) + { + element = objectification.NestedFactType; + } + return element; + } + /// <summary> /// Called as a result of the FixUpDiagram calls /// with the diagram as the first element /// </summary> @@ -1016,18 +1041,8 @@ ModelElement element2 = null; if (link != null) { - element1 = DomainRoleInfo.GetSourceRolePlayer(link); - Role role1 = element1 as Role; - if (role1 != null) - { - element1 = role1.FactType; - } - element2 = DomainRoleInfo.GetTargetRolePlayer(link); - Role role2 = element2 as Role; - if (role2 != null) - { - element2 = role2.FactType; - } + element1 = RedirectToDisplayedElement(DomainRoleInfo.GetSourceRolePlayer(link)); + element2 = RedirectToDisplayedElement(DomainRoleInfo.GetTargetRolePlayer(link)); } else if ((subtypeFact = element as SubtypeFact) != null) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |