/// <summary> /// DeletingRule: typeof(ReadingOrderHasRole) /// Handles the clean up of the readings that the role is involved in by replacing /// the place holder with the text DELETED /// </summary> private static void ReadingOrderHasRoleDeletingRule(ElementDeletingEventArgs e) { ReadingOrderHasRole link = e.ModelElement as ReadingOrderHasRole; RoleBase linkRole = link.Role; ReadingOrder linkReadingOrder = link.ReadingOrder; if (linkReadingOrder.IsDeleting || linkReadingOrder.IsDeleted) { // Don't validate if we're removing the reading order return; } FactType factType = linkReadingOrder.FactType; if (factType != null) { FrameworkDomainModel.DelayValidateElement(factType, DelayValidateReadingOrderCollation); } int pos = linkReadingOrder.RoleCollection.IndexOf(linkRole); if (pos >= 0) { bool isUnaryFactType = factType.UnaryRole != null; LinkedElementCollection <Reading> readings = linkReadingOrder.ReadingCollection; int numReadings = readings.Count; int roleCount = linkReadingOrder.RoleCollection.Count; for (int iReading = 0; iReading < numReadings; ++iReading) { Reading linkReading = readings[iReading]; if (!linkReading.IsDeleting) { Debug.Assert(!linkReading.IsDeleted); string text = linkReading.Text; IFormatProvider formatProvider = CultureInfo.InvariantCulture; linkReading.SetAutoText(Reading.ReplaceFields( linkReading.Text, delegate(int replaceIndex) { if (replaceIndex == pos) { return(isUnaryFactType ? "" : ResourceStrings.ModelReadingRoleDeletedRoleText); } else if (replaceIndex > pos) { return("{" + (replaceIndex - 1).ToString(formatProvider) + "}"); } return(null); } )); } } } }
/// <summary> /// Common place for code to deal with roles that exist in a fact /// but do not exist in the ReadingOrder objects that it contains. /// 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 factType, RoleBase addedRole) { LinkedElementCollection <ReadingOrder> readingOrders; int orderCount; if (null == factType.UnaryRole && 0 != (orderCount = (readingOrders = factType.ReadingOrderCollection).Count)) { 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)) { 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) { if (insertIndex == -1) { 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 } )); } } } } } } }