/// <summary> /// Sets the number of occurrences of a context. /// </summary> /// <param name="min">The min.</param> /// <param name="max">The max.</param> public void SetContextOccurrence(int min, int max) { CheckDisposed(); SelectionHelper sel = SelectionHelper.Create(m_view); int cellId = GetCell(sel); int hvo = GetItemHvo(sel, SelectionHelper.SelLimitType.Anchor); IPhPhonContext ctxt = PhPhonContext.CreateFromDBObject(m_cache, hvo); int index = -1; using (new UndoRedoTaskHelper(m_cache, MEStrings.ksRegRuleUndoSetOccurrence, MEStrings.ksRegRuleRedoSetOccurrence)) { if (ctxt.ClassID == PhIterationContext.kclsidPhIterationContext) { // if there is an existing iteration context, just update it or remove it if it can occur only once IPhIterationContext iterCtxt = ctxt as IPhIterationContext; if (min == 1 && max == 1) { index = OverwriteContext(iterCtxt.MemberRA, iterCtxt, cellId == (int)PhSegRuleRHS.PhSegRuleRHSTags.kflidLeftContext, false); } else { iterCtxt.Minimum = min; iterCtxt.Maximum = max; } } else if (min != 1 || max != 1) { // create a new iteration context IPhIterationContext iterCtxt = new PhIterationContext(); index = OverwriteContext(iterCtxt, ctxt, cellId == (int)PhSegRuleRHS.PhSegRuleRHSTags.kflidLeftContext, true); iterCtxt.MemberRAHvo = ctxt.Hvo; iterCtxt.Minimum = min; iterCtxt.Maximum = max; iterCtxt.NotifyNew(); } } if (index == -1) { IPhPhonContext envCtxt = cellId == (int)PhSegRuleRHS.PhSegRuleRHSTags.kflidLeftContext ? RHS.LeftContextOA : RHS.RightContextOA; IPhSequenceContext seqCtxt; index = GetIndex(ctxt, envCtxt, out seqCtxt); } ReconstructView(cellId, index, true); }
/// <summary> /// This method is the one to override if you need side effects when DeleteUnderlyingObject /// is called. If other objects should be deleted also, do NOT delete them directly; this /// tends to produce abysmal performance. Rather, add them to objectsToDeleteAlso, and the /// whole lot (including this) will be deleted in one relatively efficient operation. /// You should not modify objectsToDeleteAlso except to add HVOs to it. /// You must not use the FDO object after calling this, it has been put into the deleted state. /// </summary> /// <param name="objectsToDeleteAlso">hashtable of HVOs (value typically just true, it's really a set).</param> /// <param name="state"></param> public override void DeleteObjectSideEffects(Set<int> objectsToDeleteAlso, ProgressState state) { switch (Owner.ClassID) { case MoAffixProcess.kclsidMoAffixProcess: // if this is owned by a MoAffixProcess we must remove all of the associated output mappings IMoAffixProcess rule = Owner as IMoAffixProcess; foreach (int mappingHvo in rule.OutputOS.HvoArray) { switch (m_cache.GetClassOfObject(mappingHvo)) { case MoCopyFromInput.kclsidMoCopyFromInput: IMoCopyFromInput copy = new MoCopyFromInput(m_cache, mappingHvo); if (copy.ContentRAHvo == Hvo) objectsToDeleteAlso.Add(mappingHvo); break; case MoModifyFromInput.kclsidMoModifyFromInput: IMoModifyFromInput modify = new MoModifyFromInput(m_cache, mappingHvo); if (modify.ContentRAHvo == Hvo) objectsToDeleteAlso.Add(mappingHvo); break; } } break; case PhPhonData.kclsidPhPhonData: List<LinkedObjectInfo> linkedObjs = LinkedObjects; foreach (LinkedObjectInfo loi in linkedObjs) { if (loi.RelObjClass == PhIterationContext.kclsidPhIterationContext && loi.RelObjField == (int)PhIterationContext.PhIterationContextTags.kflidMember) { IPhIterationContext ctxt = new PhIterationContext(m_cache, loi.RelObjId); ctxt.DeleteObjectSideEffects(objectsToDeleteAlso, state); objectsToDeleteAlso.Add(loi.RelObjId); } else if (loi.RelObjClass == PhSequenceContext.kclsidPhSequenceContext && loi.RelObjField == (int)PhSequenceContext.PhSequenceContextTags.kflidMembers && m_cache.GetVectorSize(loi.RelObjId, (int)PhSequenceContext.PhSequenceContextTags.kflidMembers) == 1) { IPhSequenceContext ctxt = new PhSequenceContext(m_cache, loi.RelObjId); ctxt.DeleteObjectSideEffects(objectsToDeleteAlso, state); objectsToDeleteAlso.Add(loi.RelObjId); } } break; } base.DeleteObjectSideEffects(objectsToDeleteAlso, state); }
/// <summary> /// Parses the string representation of the specified environment and creates contexts /// based off of the environment. This is called recursively. /// </summary> /// <param name="envStr">The environment string.</param> /// <param name="leftEnv">if <c>true</c> insert in the left context, otherwise the right context.</param> /// <param name="iterCtxt">The iteration context to insert into.</param> void InsertContextsFromEnv(string envStr, int flid, IPhIterationContext iterCtxt) { int i = 0; while (i < envStr.Length) { switch (envStr[i]) { case '#': IPhSimpleContextBdry bdryCtxt = new PhSimpleContextBdry(); AppendToEnv(bdryCtxt, flid); bdryCtxt.FeatureStructureRAHvo = m_cache.GetIdFromGuid(LangProject.kguidPhRuleWordBdry); bdryCtxt.NotifyNew(); i++; break; case '[': int closeBracket = envStr.IndexOf(']', i + 1); string ncAbbr = envStr.Substring(i + 1, closeBracket - (i + 1)); int redupIndex = ncAbbr.IndexOf('^'); if (redupIndex != -1) ncAbbr = ncAbbr.Substring(0, redupIndex); foreach (IPhNaturalClass nc in m_cache.LangProject.PhonologicalDataOA.NaturalClassesOS) { if (nc.Abbreviation.BestAnalysisAlternative.Text == ncAbbr) { IPhSimpleContextNC ncCtxt = new PhSimpleContextNC(); if (iterCtxt != null) { m_cache.LangProject.PhonologicalDataOA.ContextsOS.Append(ncCtxt); iterCtxt.MemberRAHvo = ncCtxt.Hvo; } else { AppendToEnv(ncCtxt, flid); } ncCtxt.FeatureStructureRAHvo = nc.Hvo; ncCtxt.NotifyNew(); break; } } i = closeBracket + 1; break; case '(': int closeParen = envStr.IndexOf(')', i + 1); string str = envStr.Substring(i + 1, closeParen - (i + 1)); IPhIterationContext newIterCtxt = new PhIterationContext(); AppendToEnv(newIterCtxt, flid); newIterCtxt.Minimum = 0; newIterCtxt.Maximum = 1; InsertContextsFromEnv(str, flid, newIterCtxt); newIterCtxt.NotifyNew(); i = closeParen + 1; break; case ' ': i++; break; default: int nextIndex = envStr.IndexOfAny(new char[] { '[', ' ', '#', '(' }, i + 1); if (nextIndex == -1) nextIndex = envStr.Length; int len = nextIndex - i; while (len > 0) { string phonemeStr = envStr.Substring(i, len); foreach (IPhPhoneme phoneme in m_cache.LangProject.PhonologicalDataOA.PhonemeSetsOS[0].PhonemesOC) { foreach (IPhCode code in phoneme.CodesOS) { if (code.Representation.BestVernacularAlternative.Text == phonemeStr) { IPhSimpleContextSeg segCtxt = new PhSimpleContextSeg(); if (iterCtxt != null) { m_cache.LangProject.PhonologicalDataOA.ContextsOS.Append(segCtxt); iterCtxt.MemberRAHvo = segCtxt.Hvo; } else { AppendToEnv(segCtxt, flid); } segCtxt.FeatureStructureRAHvo = phoneme.Hvo; segCtxt.NotifyNew(); goto Found; } } } len--; } Found: if (len == 0) i++; else i += len; break; } } }