/// <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);
		}
Exemple #2
0
		/// <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;
				}
			}
		}