void DisplayIterCtxt(IPhIterationContext iterCtxt, int numLines, IVwEnv vwenv) { int superOffset = 0; if (numLines == 1) { // if the inner context is a single line, then make the min value a subscript and the max value a superscript. // I tried to use the Views subscript and superscript properties, but they added extra space so that it would // have the same line height of a normal character, which is not what I wanted, so I compute the size myself int fontHeight = GetFontHeight(m_cache.DefaultUserWs); int superSubHeight = (fontHeight * 2) / 3; vwenv.set_IntProperty((int)FwTextPropType.ktptFontSize, (int)FwTextPropVar.ktpvMilliPoint, superSubHeight); vwenv.set_IntProperty((int)FwTextPropType.ktptLineHeight, (int)FwTextPropVar.ktpvMilliPoint, -superSubHeight); superOffset = superSubHeight / 2; } else { vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, PILE_MARGIN); } vwenv.OpenInnerPile(); if (numLines == 1) { vwenv.set_IntProperty((int)FwTextPropType.ktptOffset, (int)FwTextPropVar.ktpvMilliPoint, superOffset); } vwenv.OpenParagraph(); vwenv.AddProp((int)PhIterationContext.PhIterationContextTags.kflidMaximum, this, kfragIterCtxtMax); vwenv.CloseParagraph(); AddExtraLines(numLines - 2, vwenv); vwenv.set_IntProperty((int)FwTextPropType.ktptOffset, (int)FwTextPropVar.ktpvMilliPoint, 0); vwenv.OpenParagraph(); vwenv.AddIntProp((int)PhIterationContext.PhIterationContextTags.kflidMinimum); vwenv.CloseParagraph(); vwenv.CloseInnerPile(); }
int GetIterCtxtWidth(IPhIterationContext ctxt, IVwEnv vwenv) { if (ctxt.MemberRAHvo != 0) { int len = GetSimpleCtxtWidth(ctxt.MemberRA as IPhSimpleContext, vwenv); int numLines = GetNumLines(ctxt.MemberRA); if (numLines > 1) { len += GetMinMaxWidth(ctxt, null, vwenv); } else { if (ctxt.MemberRA.ClassID != PhSimpleContextNC.kclsidPhSimpleContextNC) { len += GetStrWidth(m_leftParen, null, vwenv); len += GetStrWidth(m_rightParen, null, vwenv); } int fontHeight = GetFontHeight(m_cache.DefaultUserWs); int superSubHeight = (fontHeight * 2) / 3; ITsPropsBldr tpb = TsPropsBldrClass.Create(); tpb.SetIntPropValues((int)FwTextPropType.ktptFontSize, (int)FwTextPropVar.ktpvMilliPoint, superSubHeight); len += GetMinMaxWidth(ctxt, tpb.GetTextProps(), vwenv); } return(len); } else { return(GetStrWidth(m_questions, null, vwenv)); } }
int GetMinMaxWidth(IPhIterationContext ctxt, ITsTextProps props, IVwEnv vwenv) { int minWidth = GetStrWidth(m_cache.MakeUserTss(Convert.ToString(ctxt.Minimum)), props, vwenv); ITsString maxStr = ctxt.Maximum == -1 ? m_infinity : m_cache.MakeUserTss(Convert.ToString(ctxt.Maximum)); int maxWidth = GetStrWidth(maxStr, props, vwenv); return(Math.Max(minWidth, maxWidth)); }
int GetMinMaxWidth(IPhIterationContext ctxt, ITsTextProps props, IVwEnv vwenv) { var userWs = m_cache.DefaultUserWs; int minWidth = GetStrWidth(TsStringUtils.MakeString(Convert.ToString(ctxt.Minimum), userWs), props, vwenv); ITsString maxStr = ctxt.Maximum == -1 ? m_infinity : TsStringUtils.MakeString(Convert.ToString(ctxt.Maximum), userWs); int maxWidth = GetStrWidth(maxStr, props, vwenv); return(Math.Max(minWidth, maxWidth)); }
/// <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); ICmObject obj = GetCmObject(sel, SelectionHelper.SelLimitType.Anchor); var ctxt = (IPhPhonContext)obj; int index = -1; UndoableUnitOfWorkHelper.Do(MEStrings.ksRegRuleUndoSetOccurrence, MEStrings.ksRegRuleRedoSetOccurrence, ctxt, () => { if (ctxt.ClassID == PhIterationContextTags.kClassId) { // if there is an existing iteration context, just update it or remove it if it can occur only once var iterCtxt = (IPhIterationContext)ctxt; if (min == 1 && max == 1) { // We want to replace the iteration context with the original (simple?) context which it // specifies repeat counts for. That is, we will replace the iterCtxt with its own MemberRA. // Then we will delete the iteration context (false argument). // We have to do this carefully, however, because when a PhIterationContext is deleted, // it also deletes its MemberRA. So if the MemberRA is still linked to the simple context, // both get deleted, and the replace unexpectedly fails (LT-13566). // So, we must break the link before we do the replacement. IPhPhonContext temp = iterCtxt.MemberRA; iterCtxt.MemberRA = null; index = OverwriteContext(temp, iterCtxt, cellId == PhSegRuleRHSTags.kflidLeftContext, false); } else { iterCtxt.Minimum = min; iterCtxt.Maximum = max; } } else if (min != 1 || max != 1) { // create a new iteration context IPhIterationContext iterCtxt = m_cache.ServiceLocator.GetInstance <IPhIterationContextFactory>().Create(); index = OverwriteContext(iterCtxt, ctxt, cellId == PhSegRuleRHSTags.kflidLeftContext, true); iterCtxt.MemberRA = ctxt; iterCtxt.Minimum = min; iterCtxt.Maximum = max; } }); if (index == -1) { IPhPhonContext envCtxt = cellId == PhSegRuleRHSTags.kflidLeftContext ? Rhs.LeftContextOA : Rhs.RightContextOA; IPhSequenceContext seqCtxt; index = GetIndex(ctxt, envCtxt, out seqCtxt); } ReconstructView(cellId, index, true); }
/// <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> /// Gets the number of occurrences of the currently selected context. /// </summary> /// <param name="min">The min.</param> /// <param name="max">The max.</param> public void GetContextOccurrence(out int min, out int max) { CheckDisposed(); SelectionHelper sel = SelectionHelper.Create(m_view); int hvo = GetItemHvo(sel, SelectionHelper.SelLimitType.Anchor); IPhPhonContext ctxt = PhPhonContext.CreateFromDBObject(m_cache, hvo); if (ctxt.ClassID == PhIterationContext.kclsidPhIterationContext) { IPhIterationContext iterCtxt = ctxt as IPhIterationContext; min = iterCtxt.Minimum; max = iterCtxt.Maximum; } else { min = 1; max = 1; } }
/// <summary> /// Gets the number of lines needed to display the specified context or variable. /// </summary> /// <param name="ctxtOrVar">The context or variable.</param> /// <returns></returns> protected int GetNumLines(IPhContextOrVar ctxtOrVar) { if (ctxtOrVar == null) { return(1); } switch (ctxtOrVar.ClassID) { case PhSequenceContext.kclsidPhSequenceContext: IPhSequenceContext seqCtxt = ctxtOrVar as IPhSequenceContext; int maxNumLines = 1; foreach (IPhPhonContext cur in seqCtxt.MembersRS) { int numLines = GetNumLines(cur); if (numLines > maxNumLines) { maxNumLines = numLines; } } return(maxNumLines); case PhIterationContext.kclsidPhIterationContext: IPhIterationContext iterCtxt = ctxtOrVar as IPhIterationContext; return(GetNumLines(iterCtxt.MemberRA)); case PhSimpleContextNC.kclsidPhSimpleContextNC: int numFeats = 0; IPhSimpleContextNC ncCtxt = ctxtOrVar as IPhSimpleContextNC; if (ncCtxt.FeatureStructureRAHvo != 0 && ncCtxt.FeatureStructureRA.ClassID == PhNCFeatures.kclsidPhNCFeatures) { IPhNCFeatures natClass = ncCtxt.FeatureStructureRA as IPhNCFeatures; if (natClass.FeaturesOAHvo != 0) { numFeats = natClass.FeaturesOA.FeatureSpecsOC.Count; } } return(ncCtxt.PlusConstrRS.Count + ncCtxt.MinusConstrRS.Count + numFeats); } return(1); }
public override void Display(IVwEnv vwenv, int hvo, int frag) { CheckDisposed(); switch (frag) { case kfragContext: IPhContextOrVar ctxtOrVar = PhContextOrVar.CreateFromDBObject(m_cache, hvo); bool isOuterIterCtxt = false; // are we inside an iteration context? this is important since we only open a context pile if we are not // in an iteration context, since an iteration context does it for us if (vwenv.EmbeddingLevel > 0) { int outerHvo, outerTag, outerIndex; vwenv.GetOuterObject(vwenv.EmbeddingLevel - 1, out outerHvo, out outerTag, out outerIndex); isOuterIterCtxt = m_cache.GetClassOfObject(outerHvo) == PhIterationContext.kclsidPhIterationContext; } switch (ctxtOrVar.ClassID) { case PhSequenceContext.kclsidPhSequenceContext: if (m_cache.GetVectorSize(hvo, (int)PhSequenceContext.PhSequenceContextTags.kflidMembers) > 0) { vwenv.AddObjVecItems((int)PhSequenceContext.PhSequenceContextTags.kflidMembers, this, kfragContext); } else { OpenContextPile(vwenv, false); vwenv.Props = m_bracketProps; vwenv.AddProp((int)PhSequenceContext.PhSequenceContextTags.kflidMembers, this, kfragEmpty); CloseContextPile(vwenv, false); } break; case PhSimpleContextNC.kclsidPhSimpleContextNC: IPhSimpleContextNC ncCtxt = ctxtOrVar as IPhSimpleContextNC; if (ncCtxt.FeatureStructureRAHvo != 0 && ncCtxt.FeatureStructureRA.ClassID == PhNCFeatures.kclsidPhNCFeatures) { // Natural class simple context with a feature-based natural class IPhNCFeatures natClass = ncCtxt.FeatureStructureRA as IPhNCFeatures; int numLines = GetNumLines(ncCtxt); if (numLines == 0) { if (!isOuterIterCtxt) { OpenContextPile(vwenv); } vwenv.AddProp(ktagInnerNonBoundary, this, kfragLeftBracket); vwenv.AddProp((int)PhSimpleContextNC.PhSimpleContextNCTags.kflidFeatureStructure, this, kfragQuestions); vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightBracket); if (!isOuterIterCtxt) { CloseContextPile(vwenv); } } else if (numLines == 1) { if (!isOuterIterCtxt) { OpenContextPile(vwenv); } // use normal brackets for a single line context vwenv.AddProp(ktagInnerNonBoundary, this, kfragLeftBracket); // special consonant and vowel natural classes only display the abbreviation if (natClass.Abbreviation.AnalysisDefaultWritingSystem == "C" || natClass.Abbreviation.AnalysisDefaultWritingSystem == "V") { vwenv.AddObjProp((int)PhSimpleContextNC.PhSimpleContextNCTags.kflidFeatureStructure, this, kfragNC); } else { if (natClass.FeaturesOAHvo != 0 && natClass.FeaturesOA.FeatureSpecsOC.Count > 0) { vwenv.AddObjProp((int)PhSimpleContextNC.PhSimpleContextNCTags.kflidFeatureStructure, this, kfragFeatNC); } else if (ncCtxt.PlusConstrRS.Count > 0) { vwenv.AddObjVecItems((int)PhSimpleContextNC.PhSimpleContextNCTags.kflidPlusConstr, this, kfragPlusVariable); } else { vwenv.AddObjVecItems((int)PhSimpleContextNC.PhSimpleContextNCTags.kflidMinusConstr, this, kfragMinusVariable); } } vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightBracket); if (!isOuterIterCtxt) { CloseContextPile(vwenv); } } else { // multiline context // left bracket pile int maxNumLines = MaxNumLines; vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int)FwTextPropType.ktptMarginLeading, (int)FwTextPropVar.ktpvMilliPoint, PILE_MARGIN); vwenv.OpenInnerPile(); AddExtraLines(maxNumLines - numLines, ktagLeftNonBoundary, vwenv); vwenv.AddProp(ktagLeftNonBoundary, this, kfragLeftBracketUpHook); for (int i = 1; i < numLines - 1; i++) { vwenv.AddProp(ktagLeftNonBoundary, this, kfragLeftBracketExt); } vwenv.AddProp(ktagLeftBoundary, this, kfragLeftBracketLowHook); vwenv.CloseInnerPile(); // feature and variable pile vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalLeft); vwenv.OpenInnerPile(); AddExtraLines(maxNumLines - numLines, vwenv); vwenv.AddObjProp((int)PhSimpleContextNC.PhSimpleContextNCTags.kflidFeatureStructure, this, kfragFeatNC); vwenv.AddObjVecItems((int)PhSimpleContextNC.PhSimpleContextNCTags.kflidPlusConstr, this, kfragPlusVariable); vwenv.AddObjVecItems((int)PhSimpleContextNC.PhSimpleContextNCTags.kflidMinusConstr, this, kfragMinusVariable); vwenv.CloseInnerPile(); // right bracket pile vwenv.Props = m_bracketProps; if (!isOuterIterCtxt) { vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, PILE_MARGIN); } vwenv.OpenInnerPile(); AddExtraLines(maxNumLines - numLines, ktagRightNonBoundary, vwenv); vwenv.AddProp(ktagRightNonBoundary, this, kfragRightBracketUpHook); for (int i = 1; i < numLines - 1; i++) { vwenv.AddProp(ktagRightNonBoundary, this, kfragRightBracketExt); } vwenv.AddProp(ktagRightBoundary, this, kfragRightBracketLowHook); vwenv.CloseInnerPile(); } } else { // natural class context with segment-based natural class if (!isOuterIterCtxt) { OpenContextPile(vwenv); } vwenv.AddProp(ktagInnerNonBoundary, this, kfragLeftBracket); if (ncCtxt.FeatureStructureRAHvo != 0) { vwenv.AddObjProp((int)PhSimpleContextNC.PhSimpleContextNCTags.kflidFeatureStructure, this, kfragNC); } else { vwenv.AddProp((int)PhSimpleContextNC.PhSimpleContextNCTags.kflidFeatureStructure, this, kfragQuestions); } vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightBracket); if (!isOuterIterCtxt) { CloseContextPile(vwenv); } } break; case PhIterationContext.kclsidPhIterationContext: IPhIterationContext iterCtxt = ctxtOrVar as IPhIterationContext; if (iterCtxt.MemberRAHvo != 0) { int numLines = GetNumLines(iterCtxt.MemberRA as IPhSimpleContext); if (numLines > 1) { vwenv.AddObjProp((int)PhIterationContext.PhIterationContextTags.kflidMember, this, kfragContext); DisplayIterCtxt(iterCtxt, numLines, vwenv); } else { OpenContextPile(vwenv); if (iterCtxt.MemberRA.ClassID == PhSimpleContextNC.kclsidPhSimpleContextNC) { vwenv.AddObjProp((int)PhIterationContext.PhIterationContextTags.kflidMember, this, kfragContext); } else { vwenv.AddProp(ktagInnerNonBoundary, this, kfragLeftParen); vwenv.AddObjProp((int)PhIterationContext.PhIterationContextTags.kflidMember, this, kfragContext); vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightParen); } DisplayIterCtxt(iterCtxt, 1, vwenv); // Views doesn't handle selection properly when we have an inner pile with strings on either side, // so we don't add a zero-width space at the end CloseContextPile(vwenv, false); } } else { OpenContextPile(vwenv); vwenv.AddProp((int)PhIterationContext.PhIterationContextTags.kflidMember, this, kfragQuestions); CloseContextPile(vwenv); } break; case PhSimpleContextSeg.kclsidPhSimpleContextSeg: if (!isOuterIterCtxt) { OpenContextPile(vwenv); } if (m_cache.GetObjProperty(hvo, (int)PhSimpleContextSeg.PhSimpleContextSegTags.kflidFeatureStructure) != 0) { vwenv.AddObjProp((int)PhSimpleContextSeg.PhSimpleContextSegTags.kflidFeatureStructure, this, kfragTerminalUnit); } else { vwenv.AddProp((int)PhSimpleContextSeg.PhSimpleContextSegTags.kflidFeatureStructure, this, kfragQuestions); } if (!isOuterIterCtxt) { CloseContextPile(vwenv); } break; case PhSimpleContextBdry.kclsidPhSimpleContextBdry: if (!isOuterIterCtxt) { OpenContextPile(vwenv); } if (m_cache.GetObjProperty(hvo, (int)PhSimpleContextBdry.PhSimpleContextBdryTags.kflidFeatureStructure) != 0) { vwenv.AddObjProp((int)PhSimpleContextBdry.PhSimpleContextBdryTags.kflidFeatureStructure, this, kfragTerminalUnit); } else { vwenv.AddProp((int)PhSimpleContextBdry.PhSimpleContextBdryTags.kflidFeatureStructure, this, kfragQuestions); } if (!isOuterIterCtxt) { CloseContextPile(vwenv); } break; case PhVariable.kclsidPhVariable: OpenContextPile(vwenv); vwenv.AddProp(ktagXVariable, this, kfragXVariable); CloseContextPile(vwenv); break; } break; case kfragNC: int ncWs = m_cache.LangProject.ActualWs(LangProject.kwsFirstAnal, hvo, (int)PhNaturalClass.PhNaturalClassTags.kflidAbbreviation); if (ncWs != 0) { vwenv.AddStringAltMember((int)PhNaturalClass.PhNaturalClassTags.kflidAbbreviation, ncWs, this); } else { ncWs = m_cache.LangProject.ActualWs(LangProject.kwsFirstAnal, hvo, (int)PhNaturalClass.PhNaturalClassTags.kflidName); if (ncWs != 0) { vwenv.AddStringAltMember((int)PhNaturalClass.PhNaturalClassTags.kflidName, ncWs, this); } else { vwenv.AddProp((int)PhNaturalClass.PhNaturalClassTags.kflidAbbreviation, this, kfragQuestions); } } break; case kfragTerminalUnit: int tuWs = m_cache.LangProject.ActualWs(LangProject.kwsFirstVern, hvo, (int)PhTerminalUnit.PhTerminalUnitTags.kflidName); if (tuWs != 0) { vwenv.AddStringAltMember((int)PhTerminalUnit.PhTerminalUnitTags.kflidName, tuWs, this); } else { vwenv.AddProp((int)PhTerminalUnit.PhTerminalUnitTags.kflidName, this, kfragQuestions); } break; case kfragFeatNC: vwenv.AddObjProp((int)PhNCFeatures.PhNCFeaturesTags.kflidFeatures, this, kfragFeats); break; case kfragFeats: vwenv.AddObjVecItems((int)FsFeatStruc.FsFeatStrucTags.kflidFeatureSpecs, this, kfragFeature); break; case kfragFeature: vwenv.AddProp(ktagFeature, this, kfragFeatureLine); break; case kfragPlusVariable: vwenv.AddProp(ktagVariable, this, kfragPlusVariableLine); break; case kfragMinusVariable: vwenv.AddProp(ktagVariable, this, kfragMinusVariableLine); break; } }
int GetMinMaxWidth(IPhIterationContext ctxt, ITsTextProps props, IVwEnv vwenv) { var tsf = m_cache.TsStrFactory; var userWs = m_cache.DefaultUserWs; int minWidth = GetStrWidth(tsf.MakeString(Convert.ToString(ctxt.Minimum), userWs), props, vwenv); ITsString maxStr = ctxt.Maximum == -1 ? m_infinity : tsf.MakeString(Convert.ToString(ctxt.Maximum), userWs); int maxWidth = GetStrWidth(maxStr, props, vwenv); return Math.Max(minWidth, maxWidth); }
int GetIterCtxtWidth(IPhIterationContext ctxt, IVwEnv vwenv) { if (ctxt.MemberRA != null) { int len = GetSimpleCtxtWidth(ctxt.MemberRA as IPhSimpleContext, vwenv); int numLines = GetNumLines(ctxt.MemberRA); if (numLines > 1) { len += GetMinMaxWidth(ctxt, null, vwenv); } else { if (ctxt.MemberRA.ClassID != PhSimpleContextNCTags.kClassId) { len += GetStrWidth(m_leftParen, null, vwenv); len += GetStrWidth(m_rightParen, null, vwenv); } int fontHeight = GetFontHeight(m_cache.DefaultUserWs); int superSubHeight = (fontHeight * 2) / 3; ITsPropsBldr tpb = TsPropsBldrClass.Create(); tpb.SetIntPropValues((int)FwTextPropType.ktptFontSize, (int)FwTextPropVar.ktpvMilliPoint, superSubHeight); len += GetMinMaxWidth(ctxt, tpb.GetTextProps(), vwenv); } return len; } else { return GetStrWidth(m_questions, null, vwenv); } }
/// <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; } } }
/// <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="flid"></param> /// <param name="iterCtxt">The iteration context to insert into.</param> private void InsertContextsFromEnv(string envStr, int flid, IPhIterationContext iterCtxt) { int i = 0; while (i < envStr.Length) { switch (envStr[i]) { case '#': var bdryCtxt = m_cache.ServiceLocator.GetInstance <IPhSimpleContextBdryFactory>().Create(); AppendToEnv(bdryCtxt, flid); bdryCtxt.FeatureStructureRA = m_cache.ServiceLocator.GetInstance <IPhBdryMarkerRepository>().GetObject(LangProjectTags.kguidPhRuleWordBdry); 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) { var ncCtxt = m_cache.ServiceLocator.GetInstance <IPhSimpleContextNCFactory>().Create(); if (iterCtxt != null) { m_cache.LangProject.PhonologicalDataOA.ContextsOS.Add(ncCtxt); iterCtxt.MemberRA = ncCtxt; } else { AppendToEnv(ncCtxt, flid); } ncCtxt.FeatureStructureRA = nc; break; } } i = closeBracket + 1; break; case '(': int closeParen = envStr.IndexOf(')', i + 1); string str = envStr.Substring(i + 1, closeParen - (i + 1)); var newIterCtxt = m_cache.ServiceLocator.GetInstance <IPhIterationContextFactory>().Create(); AppendToEnv(newIterCtxt, flid); newIterCtxt.Minimum = 0; newIterCtxt.Maximum = 1; InsertContextsFromEnv(str, flid, newIterCtxt); i = closeParen + 1; break; case ' ': i++; break; default: int nextIndex = envStr.IndexOfAny(new[] { '[', ' ', '#', '(' }, 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) { var segCtxt = m_cache.ServiceLocator.GetInstance <IPhSimpleContextSegFactory>().Create(); if (iterCtxt != null) { m_cache.LangProject.PhonologicalDataOA.ContextsOS.Add(segCtxt); iterCtxt.MemberRA = segCtxt; } else { AppendToEnv(segCtxt, flid); } segCtxt.FeatureStructureRA = phoneme; goto Found; } } } len--; } Found: if (len == 0) { i++; } else { i += len; } break; } } }
/// <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; } } }
int GetMinMaxWidth(IPhIterationContext ctxt, ITsTextProps props, IVwEnv vwenv) { int minWidth = GetStrWidth(m_cache.MakeUserTss(Convert.ToString(ctxt.Minimum)), props, vwenv); ITsString maxStr = ctxt.Maximum == -1 ? m_infinity : m_cache.MakeUserTss(Convert.ToString(ctxt.Maximum)); int maxWidth = GetStrWidth(maxStr, props, vwenv); return Math.Max(minWidth, maxWidth); }
void DisplayIterCtxt(IPhIterationContext iterCtxt, int numLines, IVwEnv vwenv) { int superOffset = 0; if (numLines == 1) { // if the inner context is a single line, then make the min value a subscript and the max value a superscript. // I tried to use the Views subscript and superscript properties, but they added extra space so that it would // have the same line height of a normal character, which is not what I wanted, so I compute the size myself int fontHeight = GetFontHeight(m_cache.DefaultUserWs); int superSubHeight = (fontHeight * 2) / 3; vwenv.set_IntProperty((int)FwTextPropType.ktptFontSize, (int)FwTextPropVar.ktpvMilliPoint, superSubHeight); vwenv.set_IntProperty((int)FwTextPropType.ktptLineHeight, (int)FwTextPropVar.ktpvMilliPoint, -superSubHeight); superOffset = superSubHeight / 2; } else { vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, PILE_MARGIN); } vwenv.OpenInnerPile(); if (numLines == 1) vwenv.set_IntProperty((int)FwTextPropType.ktptOffset, (int)FwTextPropVar.ktpvMilliPoint, superOffset); vwenv.OpenParagraph(); vwenv.AddProp(PhIterationContextTags.kflidMaximum, this, kfragIterCtxtMax); vwenv.CloseParagraph(); AddExtraLines(numLines - 2, vwenv); vwenv.set_IntProperty((int)FwTextPropType.ktptOffset, (int)FwTextPropVar.ktpvMilliPoint, 0); vwenv.OpenParagraph(); vwenv.AddIntProp(PhIterationContextTags.kflidMinimum); vwenv.CloseParagraph(); vwenv.CloseInnerPile(); }
/// <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="flid"></param> /// <param name="iterCtxt">The iteration context to insert into.</param> private void InsertContextsFromEnv(string envStr, int flid, IPhIterationContext iterCtxt) { int i = 0; while (i < envStr.Length) { switch (envStr[i]) { case '#': var bdryCtxt = m_cache.ServiceLocator.GetInstance<IPhSimpleContextBdryFactory>().Create(); AppendToEnv(bdryCtxt, flid); bdryCtxt.FeatureStructureRA = m_cache.ServiceLocator.GetInstance<IPhBdryMarkerRepository>().GetObject(LangProjectTags.kguidPhRuleWordBdry); 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) { var ncCtxt = m_cache.ServiceLocator.GetInstance<IPhSimpleContextNCFactory>().Create(); if (iterCtxt != null) { m_cache.LangProject.PhonologicalDataOA.ContextsOS.Add(ncCtxt); iterCtxt.MemberRA = ncCtxt; } else { AppendToEnv(ncCtxt, flid); } ncCtxt.FeatureStructureRA = nc; break; } } i = closeBracket + 1; break; case '(': int closeParen = envStr.IndexOf(')', i + 1); string str = envStr.Substring(i + 1, closeParen - (i + 1)); var newIterCtxt = m_cache.ServiceLocator.GetInstance<IPhIterationContextFactory>().Create(); AppendToEnv(newIterCtxt, flid); newIterCtxt.Minimum = 0; newIterCtxt.Maximum = 1; InsertContextsFromEnv(str, flid, newIterCtxt); i = closeParen + 1; break; case ' ': i++; break; default: int nextIndex = envStr.IndexOfAny(new[] { '[', ' ', '#', '(' }, 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) { var segCtxt = m_cache.ServiceLocator.GetInstance<IPhSimpleContextSegFactory>().Create(); if (iterCtxt != null) { m_cache.LangProject.PhonologicalDataOA.ContextsOS.Add(segCtxt); iterCtxt.MemberRA = segCtxt; } else { AppendToEnv(segCtxt, flid); } segCtxt.FeatureStructureRA = phoneme; goto Found; } } } len--; } Found: if (len == 0) i++; else i += len; break; } } }