private void DisplayMinMax(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, PileMargin); } vwenv.OpenInnerPile(); if (numLines == 1) { vwenv.set_IntProperty((int)FwTextPropType.ktptOffset, (int)FwTextPropVar.ktpvMilliPoint, superOffset); } vwenv.OpenParagraph(); vwenv.AddProp(ktagRightNonBoundary, this, kfragNodeMax); vwenv.CloseParagraph(); AddExtraLines(numLines - 2, ktagRightNonBoundary, vwenv); vwenv.set_IntProperty((int)FwTextPropType.ktptOffset, (int)FwTextPropVar.ktpvMilliPoint, 0); vwenv.OpenParagraph(); vwenv.AddProp(ktagRightBoundary, this, kfragNodeMin); vwenv.CloseParagraph(); vwenv.CloseInnerPile(); }
private void DisplayInflFeatures(IVwEnv vwenv, IDictionary <IFsFeatDefn, object> inflFeatures) { int numLines = GetNumLines(inflFeatures); if (numLines == 1) { // use normal brackets for a single line constraint vwenv.AddProp(ktagInnerNonBoundary, this, kfragLeftBracket); DisplayInflFeatureLines(vwenv, inflFeatures, false); vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightBracket); } else { // left bracket pile vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int)FwTextPropType.ktptMarginLeading, (int)FwTextPropVar.ktpvMilliPoint, PileMargin); vwenv.OpenInnerPile(); 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 pile vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalLeft); vwenv.OpenInnerPile(); DisplayInflFeatureLines(vwenv, inflFeatures, true); vwenv.CloseInnerPile(); // right bracket pile vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, PileMargin); vwenv.OpenInnerPile(); vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightBracketUpHook); for (int i = 1; i < numLines - 1; i++) { vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightBracketExt); } vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightBracketLowHook); vwenv.CloseInnerPile(); } }
/// <summary/> protected virtual void Dispose(bool fDisposing) { System.Diagnostics.Debug.WriteLineIf(!fDisposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** "); if (fDisposing && !IsDisposed) { // dispose managed and unmanaged objects m_vwenv.CloseInnerPile(); } IsDisposed = true; }
public virtual void CloseInnerPile() { if (!IsRtL) { m_vwEnv.CloseInnerPile(); return; } m_calledMethods.Add(new StoredMethod(DecoratorMethodTypes.CloseInnerPile, new object[] { })); m_numOfCalls++; }
protected void CloseContextPile(IVwEnv vwenv, bool addBoundary) { if (addBoundary) { vwenv.Props = m_bracketProps; vwenv.AddProp(ktagRightBoundary, this, kfragZeroWidthSpace); } vwenv.CloseParagraph(); vwenv.CloseInnerPile(); }
public override void Display(IVwEnv vwenv, int hvo, int frag) { switch (frag) { default: break; case InterlinearView.kfrText: vwenv.OpenParagraph(); vwenv.AddObjVecItems(InterlinearView.ktagText_Words, this, InterlinearView.kfrWord); vwenv.CloseParagraph(); break; case InterlinearView.kfrWord: vwenv.set_IntProperty((int)FwKernelLib.FwTextPropType.ktptMarginTrailing, (int)FwKernelLib.FwTextPropVar.ktpvMilliPoint, 10000); vwenv.OpenInnerPile(); vwenv.AddStringProp(InterlinearView.ktagWord_Form, this); vwenv.AddStringProp(InterlinearView.ktagWord_Type, this); vwenv.CloseInnerPile(); break; } }
private void DisplayWordform(IVwEnv vwenv, int ws, int choiceIndex) { // For the wordform line we only want an icon on the first line (which is always wordform). bool fWantIcon = m_sandbox.ShowAnalysisCombo && choiceIndex == 0; // This has to be BEFORE we open the paragraph, so the indent applies to the whole // paragraph, and not some string box inside it. if (!fWantIcon) { SetIndentForMissingIcon(vwenv); } vwenv.OpenParagraph(); // The actual icon, if present, has to be INSIDE the paragraph. if (fWantIcon) { AddPullDownIcon(vwenv, ktagAnalysisIcon); } //Set the background of the wordform to the 'WordFormBGColor' which is set when ChangeOrCreateSandbox //is called SetBGColor(vwenv, MultipleOptionBGColor); if (ws != m_sandbox.RawWordformWs) { // Any other Ws we can edit. MakeNextFlowObjectEditable(vwenv); vwenv.OpenInnerPile(); // So white background occupies full width vwenv.AddStringAltMember(ktagSbWordForm, ws, this); vwenv.CloseInnerPile(); } else { MakeNextFlowObjectReadOnly(vwenv); //vwenv.AddString(m_sandbox.RawWordform); vwenv.AddStringAltMember(ktagSbWordForm, ws, this); } vwenv.CloseParagraph(); }
private void CloseSingleLinePile(IVwEnv vwenv) { vwenv.CloseParagraph(); vwenv.CloseInnerPile(); }
private void AddPreviewPiles(IVwEnv vwenv, XmlNode node) { // add padding to separate PreviewArrow from other cell contents. vwenv.set_IntProperty((int)FwTextPropType.ktptPadTrailing, (int)FwTextPropVar.ktpvMilliPoint, 2500); vwenv.set_IntProperty((int)FwTextPropType.ktptPadLeading, (int)FwTextPropVar.ktpvMilliPoint, 2500); vwenv.OpenInnerPile(); { AddPreviewArrow(vwenv, node); } vwenv.CloseInnerPile(); vwenv.OpenInnerPile(); { AddAlternateCellContents(vwenv); } vwenv.CloseInnerPile(); }
public override void Display(IVwEnv vwenv, int hvo, int frag) { CheckDisposed(); try { switch (frag) { case kfragBundle: // One annotated word bundle, in this case, the whole view. if (hvo == 0) { return; } vwenv.set_IntProperty((int)FwTextPropType.ktptSpellCheck, (int)FwTextPropVar.ktpvEnum, (int)SpellingModes.ksmDoNotCheck); vwenv.set_IntProperty((int)FwTextPropType.ktptBackColor, (int)FwTextPropVar.ktpvDefault, krgbBackground); vwenv.OpenDiv(); vwenv.OpenParagraph(); // Since embedded in a pile with context, we need another layer of pile here,. // It's an overlay sandbox: draw a box around it. vwenv.OpenInnerPile(); // Inside that division we need a paragraph which does not have any border // or background. This suppresses the 'infinite width' behavior for the // nested paragraphs that may have grey border. vwenv.OpenParagraph(); // This makes a little separation between left border and arrows. vwenv.set_IntProperty((int)FwTextPropType.ktptPadLeading, (int)FwTextPropVar.ktpvMilliPoint, 1000); if (m_fRtl) { // This must not be on the outer paragraph or we get infinite width behavior. vwenv.set_IntProperty((int)FwTextPropType.ktptRightToLeft, (int)FwTextPropVar.ktpvEnum, (int)FwTextToggleVal.kttvForceOn); vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalRight); } vwenv.OpenInnerPile(); for (int ispec = 0; ispec < m_choices.Count;) { InterlinLineSpec spec = m_choices[ispec]; if (!spec.WordLevel) { break; } if (spec.MorphemeLevel) { DisplayMorphBundles(vwenv, hvo); ispec = m_choices.LastMorphemeIndex + 1; continue; } switch (spec.Flid) { case InterlinLineChoices.kflidWord: int ws = GetActualWs(hvo, spec.StringFlid, spec.WritingSystem); DisplayWordform(vwenv, ws, ispec); break; case InterlinLineChoices.kflidWordGloss: DisplayWordGloss(vwenv, hvo, spec.WritingSystem, ispec); break; case InterlinLineChoices.kflidWordPos: DisplayWordPOS(vwenv, hvo, spec.WritingSystem, ispec); break; } ispec++; } vwenv.CloseInnerPile(); vwenv.CloseParagraph(); vwenv.CloseInnerPile(); vwenv.CloseParagraph(); vwenv.CloseDiv(); break; case kfragFirstMorph: // first morpheme in word case kfragMorph: // The bundle of 4 lines representing a morpheme. vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, 10000); vwenv.OpenInnerPile(); for (int ispec = m_choices.FirstMorphemeIndex; ispec <= m_choices.LastMorphemeIndex; ispec++) { int tagLexEntryIcon = 0; if (m_choices.FirstLexEntryIndex == ispec) { tagLexEntryIcon = ktagMorphEntryIcon; } InterlinLineSpec spec = m_choices[ispec]; switch (spec.Flid) { case InterlinLineChoices.kflidMorphemes: DisplayMorphForm(vwenv, hvo, frag, spec.WritingSystem, ispec); break; case InterlinLineChoices.kflidLexEntries: AddOptionalNamedObj(vwenv, hvo, ktagSbMorphEntry, ktagMissingEntry, kfragMissingEntry, tagLexEntryIcon, spec.WritingSystem, ispec); break; case InterlinLineChoices.kflidLexGloss: AddOptionalNamedObj(vwenv, hvo, ktagSbMorphGloss, ktagMissingMorphGloss, kfragMissingMorphGloss, tagLexEntryIcon, spec.WritingSystem, ispec); break; case InterlinLineChoices.kflidLexPos: AddOptionalNamedObj(vwenv, hvo, ktagSbMorphPos, ktagMissingMorphPos, kfragMissingMorphPos, tagLexEntryIcon, spec.WritingSystem, ispec); break; } } vwenv.CloseInnerPile(); break; default: if (frag >= kfragNamedObjectNameChoices && frag < kfragNamedObjectNameChoices + m_choices.Count) { InterlinLineSpec spec = m_choices[frag - kfragNamedObjectNameChoices]; int wsActual = GetActualWs(hvo, ktagSbNamedObjName, spec.WritingSystem); vwenv.AddStringAltMember(ktagSbNamedObjName, wsActual, this); } else { throw new Exception("Bad fragment ID in SandboxVc.Display"); } break; } } catch { Debug.Assert(false, "Exception thrown in the display of the SandboxVc (About to be eaten)"); } }
private void DisplayWordGloss(IVwEnv vwenv, int hvo, int ws, int choiceIndex) { // Count how many glosses there are for the current analysis: int cGlosses = 0; // Find a wfi analysis (existing or guess) to determine whether to provide an icon for selecting // multiple word glosses for IhWordGloss.SetupCombo (cf. LT-1428) IWfiAnalysis wa = m_sandbox.GetWfiAnalysisInUse(); if (wa != null) { cGlosses = wa.MeaningsOC.Count; } SetColor(vwenv, m_choices.LabelRGBFor(choiceIndex)); // Icon only if we want icons at all (currently always true) and there is at least one WfiGloss to choose // and this is the first word gloss line. bool fWantIcon = m_fIconsForAnalysisChoices && (cGlosses > 0 || m_sandbox.ShouldAddWordGlossToLexicon) && m_choices.IsFirstOccurrenceOfFlid(choiceIndex); // If there isn't going to be an icon, add an indent. if (!fWantIcon) { SetIndentForMissingIcon(vwenv); } vwenv.OpenParagraph(); if (fWantIcon) { AddPullDownIcon(vwenv, ktagWordGlossIcon); m_fIconForWordGloss = true; } else if (m_fIconForWordGloss == true && cGlosses == 0) { // reset m_fIconForWordGloss = false; } //if there is more than one gloss set the background color to give visual indication if (cGlosses > 1) { //set directly to the MultipleApproved color rather than the stored one //the state of the two could be different. SetBGColor(vwenv, InterlinVc.MultipleApprovedGuessColor); ITsStrFactory fact = TsStrFactoryClass.Create(); ITsString count = TsStringUtils.MakeTss(fact, Cache.DefaultUserWs, "" + cGlosses); //make the number black. SetColor(vwenv, 0); vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, kmpIconMargin); vwenv.AddString(count); } //Set the margin and padding values vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, kmpIconMargin); vwenv.set_IntProperty((int)FwTextPropType.ktptPadTrailing, (int)FwTextPropVar.ktpvMilliPoint, 2000); vwenv.set_IntProperty((int)FwTextPropType.ktptPadLeading, (int)FwTextPropVar.ktpvMilliPoint, 2000); SetBGColor(vwenv, krgbEditable); vwenv.set_IntProperty((int)FwTextPropType.ktptSpellCheck, (int)FwTextPropVar.ktpvEnum, (int)SpellingModes.ksmNormalCheck); vwenv.OpenInnerPile(); // Set the appropriate paragraph direction for the writing system. bool fWsRtl = m_caches.MainCache.ServiceLocator.WritingSystemManager.Get(ws).RightToLeftScript; if (fWsRtl != RightToLeft) { vwenv.set_IntProperty((int)FwTextPropType.ktptRightToLeft, (int)FwTextPropVar.ktpvEnum, fWsRtl ? (int)FwTextToggleVal.kttvForceOn : (int)FwTextToggleVal.kttvOff); } vwenv.AddStringAltMember(ktagSbWordGloss, ws, this); vwenv.CloseInnerPile(); vwenv.CloseParagraph(); }
/// <summary> /// NOTE: this routine is ignorant of calling context, so caller must provide NoteDependency to the possibleVariant and the sense /// (e.g. vwenv.NoteDependency(new[] { wfiMorphBundle.Hvo }, new[] { WfiMorphBundleTags.kflidSense }, 1); /// vwenv.NoteDependency(new[] { wfiMorphBundle.Hvo }, new[] { WfiMorphBundleTags.kflidInflType }, 1); /// </summary> /// <param name="vwenv"></param> /// <param name="possibleVariant"></param> /// <param name="sense"></param> /// <param name="spec"></param> /// <param name="inflType"></param> /// <returns>true if there was anything to display </returns> internal bool DisplayLexGlossWithInflType(IVwEnv vwenv, ILexEntry possibleVariant, ILexSense sense, InterlinLineSpec spec, ILexEntryInflType inflType) { int iLineChoice = m_lineChoices.IndexOf(spec); ILexEntryRef ler; if (possibleVariant.IsVariantOfSenseOrOwnerEntry(sense, out ler)) { var wsPreferred = GetRealWsOrBestWsForContext(sense.Hvo, spec); var wsGloss = Cache.ServiceLocator.WritingSystemManager.Get(wsPreferred); var wsUser = Cache.ServiceLocator.WritingSystemManager.UserWritingSystem; var testGloss = sense.Gloss.get_String(wsPreferred); // don't bother adding anything for an empty gloss. if (testGloss.Text != null && testGloss.Text.Length >= 0) { vwenv.OpenParagraph(); // see if we have an irregularly inflected form type reference var leitFirst = ler.VariantEntryTypesRS.Where( let => let.ClassID == LexEntryInflTypeTags.kClassId).FirstOrDefault(); // add any GlossPrepend info if (leitFirst != null) { vwenv.OpenInnerPile(); // TODO: add dependency to VariantType GlossPrepend/Append names vwenv.NoteDependency(new[] { ler.Hvo }, new[] { LexEntryRefTags.kflidVariantEntryTypes }, 1); vwenv.OpenParagraph(); ITsString tssPrepend = null; if (inflType != null) { tssPrepend = MorphServices.AddTssGlossAffix(null, inflType.GlossPrepend, wsGloss, wsUser); } else { ITsIncStrBldr sbPrepend; ITsIncStrBldr sbAppend; JoinGlossAffixesOfInflVariantTypes(ler, wsPreferred, out sbPrepend, out sbAppend); if (sbPrepend.Text != null) tssPrepend = sbPrepend.GetString(); } if (tssPrepend != null) vwenv.AddString(tssPrepend); vwenv.CloseParagraph(); vwenv.CloseInnerPile(); } // add gloss of main entry or sense { vwenv.OpenInnerPile(); // NOTE: remember to NoteDependency from OuterObject vwenv.AddObj(sense.Hvo, this, kfragLineChoices + iLineChoice); vwenv.CloseInnerPile(); } // now add variant type info if (leitFirst != null) { vwenv.OpenInnerPile(); // TODO: add dependency to VariantType GlossPrepend/Append names vwenv.NoteDependency(new[] { ler.Hvo }, new[] { LexEntryRefTags.kflidVariantEntryTypes }, 1); vwenv.OpenParagraph(); ITsString tssAppend = null; if (inflType != null) { tssAppend = MorphServices.AddTssGlossAffix(null, inflType.GlossAppend, wsGloss, wsUser); } else { ITsIncStrBldr sbPrepend; ITsIncStrBldr sbAppend; JoinGlossAffixesOfInflVariantTypes(ler, wsPreferred, out sbPrepend, out sbAppend); if (sbAppend.Text != null) tssAppend = sbAppend.GetString(); } { // Use AddProp/DisplayVariant to store GlossAppend with m_tssPendingGlossAffix // this allows InterlinearExporter to know to export a glsAppend item try { if (tssAppend != null) m_tssPendingGlossAffix = tssAppend; else m_tssPendingGlossAffix = m_tssMissingGlossAppend; vwenv.AddProp(ktagGlossAppend, this, 0); } finally { m_tssPendingGlossAffix = null; } } vwenv.CloseParagraph(); vwenv.CloseInnerPile(); } vwenv.CloseParagraph(); return true; } } return false; }
public override void Display(IVwEnv vwenv, int hvo, int frag) { #if __MonoCS__ // TODO-Linux: Randomly m_tsf seem to have been Release. // eg Marshal.ReleaseComObject(m_tsf); // However the Dispose method isn't called (which calls the Release) // Currently unsure what is doing this need to find out - very concerning // Hack - just recreate a new TsStrFactory each time... for now // seems to stop the problem. m_tsf = TsStrFactoryClass.Create(); #endif CheckDisposed(); if (hvo == 0) return; // Can't do anything without an hvo (except crash -- see LT-9348). #if DEBUG //TimeRecorder.Begin("Display"); #endif switch (frag) { case kfragStText: // new root object for InterlinDocChild. SetupRealVernWsForDisplay(WritingSystemServices.ActualWs(m_cache, WritingSystemServices.kwsVernInParagraph, hvo, StTextTags.kflidParagraphs)); vwenv.AddLazyVecItems(StTextTags.kflidParagraphs, this, kfragInterlinPara); break; case kfragInterlinPara: // Whole StTxtPara. This can be the root fragment in DE view. if (vwenv.DataAccess.get_VecSize(hvo, StTxtParaTags.kflidSegments) == 0) { vwenv.NoteDependency(new int[] { hvo }, new int[] { StTxtParaTags.kflidSegments }, 1); vwenv.AddString(m_tssEmptyPara); } else { PreferredVernWs = WritingSystemServices.ActualWs(m_cache, WritingSystemServices.kwsVernInParagraph, hvo, StTxtParaTags.kflidSegments); // Include the plain text version of the paragraph? vwenv.AddLazyVecItems(StTxtParaTags.kflidSegments, this, kfragParaSegment); } break; case kfragParaSegment: // Don't put anything in this segment if it is a 'label' segment (typically containing a verse // number for TE). var seg = m_segRepository.GetObject(hvo); if (seg.IsLabel) break; // This puts ten points between segments. There's always 5 points below each line of interlinear; // if there are no freeform annotations another 5 points makes 10 between segments. // If there are freeforms, we need the full 10 points after the last of them. var haveFreeform = seg.FreeTranslation != null || seg.LiteralTranslation != null || seg.NotesOS.Count > 0; vwenv.set_IntProperty((int)FwTextPropType.ktptMarginBottom, (int)FwTextPropVar.ktpvMilliPoint, !haveFreeform ? 5000 : 10000); vwenv.OpenDiv(); // Enhance JohnT: determine what the overall direction of the paragraph should // be and set it. if (m_mpBundleHeight == 0) { // First time...figure it out. int dmpx, dmpyAnal, dmpyVern; vwenv.get_StringWidth(m_tssEmptyAnalysis, null, out dmpx, out dmpyAnal); vwenv.get_StringWidth(m_tssEmptyVern, null, out dmpx, out dmpyVern); m_mpBundleHeight = dmpyAnal * 4 + dmpyVern * 3; } // The interlinear bundles are not editable. vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvEnum, (int)TptEditable.ktptNotEditable); if (m_fRtl) { vwenv.set_IntProperty((int)FwTextPropType.ktptRightToLeft, (int)FwTextPropVar.ktpvEnum, (int)FwTextToggleVal.kttvForceOn); vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int) FwTextAlign.ktalRight); } vwenv.set_IntProperty((int)FwTextPropType.ktptSpellCheck, (int)FwTextPropVar.ktpvEnum, (int)SpellingModes.ksmDoNotCheck); vwenv.OpenParagraph(); AddSegmentReference(vwenv, hvo); // Calculate and display the segment reference. AddLabelPile(vwenv, m_tsf, m_cache, true, m_fShowMorphBundles); vwenv.AddObjVecItems(SegmentTags.kflidAnalyses, this, kfragBundle); // JohnT, 1 Feb 2008. Took this out as I can see no reason for it; AddObjVecItems handles // the dependency already. Adding it just means that any change to the forms list // regenerates a higher level than needed, which contributes to a great deal of scrolling // and flashing (LT-7470). // Originally added by Eric in revision 72 on the trunk as part of handling phrases. // Eric can't see any reason we need it now, either. If you find a need to re-insert it, // please document carefully the reasons it is needed and what bad consequences follow // from removing it. //vwenv.NoteDependency(new int[] { hvo }, new int[] { ktagSegmentForms }, 1); vwenv.CloseParagraph(); // We'd get the same visual effect from just calling AddFreeformAnnotations here. But then a regenerate // such as happens when hiding or showing a prompt has to redisplay the whole segment. This initially // makes it lazy, then the lazy stuff gets expanded. In the process we may get undesired scrolling (LT-12248). // So we insert another layer of object, allowing just the freeforms to be regenerated. var flidSelf = Cache.MetaDataCacheAccessor.GetFieldId2(CmObjectTags.kClassId, "Self", false); vwenv.AddObjProp(flidSelf, this, kfragFreeformBundle); vwenv.CloseDiv(); break; case kfragFreeformBundle: AddFreeformAnnotations(vwenv, hvo); break; case kfragBundle: // One annotated word bundle; hvo is the IAnalysis object. // checking AllowLayout (especially in context of Undo/Redo make/break phrase) // helps prevent us from rebuilding the display until we've finished // reconstructing the data and cache. Otherwise we can crash. if (m_rootsite != null && !m_rootsite.AllowLayout) return; AddWordBundleInternal(hvo, vwenv); break; case kfragIsolatedAnalysis: // This one is used for an isolated HVO that is surely an analysis. { var wa = m_analRepository.GetObject(hvo); vwenv.AddObj(wa.Owner.Hvo, this, kfragWordformForm); if (m_fShowMorphBundles) vwenv.AddObj(hvo, this, kfragAnalysisMorphs); int chvoGlosses = wa.MeaningsOC.Count; for (int i = 0; i < m_WsList.AnalysisWsIds.Length; ++i) { SetColor(vwenv, LabelRGBFor(m_lineChoices.IndexOf(InterlinLineChoices.kflidWordGloss, m_WsList.AnalysisWsIds[i]))); if (chvoGlosses == 0) { // There are no glosses, display something indicating it is missing. vwenv.AddProp(ktagAnalysisMissingGloss, this, kfragAnalysisMissingGloss); } else { vwenv.AddObjVec(WfiAnalysisTags.kflidMeanings, this, kfragWordGlossWs + i); } } AddAnalysisPos(vwenv, hvo, hvo, -1); } break; case kfragAnalysisMorphs: int cmorphs = 0; ICmObject co = m_coRepository.GetObject(hvo); if (co is IWfiAnalysis) cmorphs = (co as IWfiAnalysis).MorphBundlesOS.Count; // We really want a variable for this...there have been pathological cases where // m_fHaveOpenedParagraph changed during the construction of the paragraph, and we want to be // sure to close the paragraph if we opened it. var openedParagraph = !m_fHaveOpenedParagraph; if (openedParagraph) vwenv.OpenParagraph(); if (cmorphs == 0) { DisplayMorphBundle(vwenv, 0); } else { vwenv.AddObjVecItems(WfiAnalysisTags.kflidMorphBundles, this, kfragMorphBundle); } if (openedParagraph) vwenv.CloseParagraph(); break; case kfragMorphType: // for export only at present, display the vwenv.AddObjProp(MoFormTags.kflidMorphType, this, kfragPossibiltyAnalysisName); break; case kfragPossibiltyAnalysisName: vwenv.AddStringAltMember(CmPossibilityTags.kflidName, m_cache.DefaultAnalWs, this); break; case kfragMorphBundle: // the lines of morpheme information (hvo is a WfiMorphBundle) // Make an 'inner pile' to contain the bundle of morph information. // Give it 10 points of separation from whatever follows. DisplayMorphBundle(vwenv, hvo); break; case kfragSingleInterlinearAnalysisWithLabels: /* // This puts ten points between segments. There's always 5 points below each line of interlinear; // if there are no freeform annotations another 5 points makes 10 between segments. // If there are freeforms, we need the full 10 points after the last of them. int cfreeform = vwenv.get_DataAccess().get_VecSize(hvo, ktagSegFF); vwenv.set_IntProperty((int)FwTextPropType.ktptMarginBottom, (int)FwTextPropVar.ktpvMilliPoint, cfreeform == 0 ? 5000 : 10000); */ vwenv.OpenDiv(); DisplaySingleInterlinearAnalysisWithLabels(vwenv, hvo); vwenv.CloseDiv(); break; // This frag is used to display a single interlin analysis that is always left-aligned, even for RTL languages case kfragSingleInterlinearAnalysisWithLabelsLeftAlign: vwenv.OpenDiv(); vwenv.set_IntProperty((int)FwTextPropType.ktptPadLeading, (int)FwTextPropVar.ktpvMilliPoint, m_leftPadding); vwenv.OpenParagraph(); vwenv.OpenInnerPile(); DisplaySingleInterlinearAnalysisWithLabels(vwenv, hvo); vwenv.CloseInnerPile(); vwenv.CloseParagraph(); vwenv.CloseDiv(); break; //case kfragDefaultSense: // Some default sense // // NB: If the hvo is zero, then we need to go back to the normal missing sense display, after all. // // (hvo isn't zero, even for cases where there isn't even a default value.) // if (hvo > 0) // { // // Show default sense, in some other 'guess' color. // SetGuessing(vwenv, false); // foreach (int wsId in m_WsList.AnalysisWsIds) // vwenv.AddStringAltMember(LexSenseTags.kflidGloss, // wsId, this); // } // else // { // // Give up and show the missing sense row. // vwenv.AddString(m_tssMissingSense); // } // break; case kfragWordformForm: // The form of a WviWordform. vwenv.AddStringAltMember(WfiWordformTags.kflidForm, m_wsVernForDisplay, this); break; case kfragPrefix: vwenv.AddUnicodeProp(MoMorphTypeTags.kflidPrefix, m_wsVernForDisplay, this); break; case kfragPostfix: vwenv.AddUnicodeProp(MoMorphTypeTags.kflidPostfix, m_wsVernForDisplay, this); break; case kfragSenseName: // The name (gloss) of a LexSense. foreach (int wsId in m_WsList.AnalysisWsIds) vwenv.AddStringAltMember(LexSenseTags.kflidGloss, wsId, this); break; case kfragCategory: // the category of a WfiAnalysis, a part of speech; // display the Abbreviation property inherited from CmPossibility. foreach(var wsId in m_WsList.AnalysisWsIds) { vwenv.AddStringAltMember(CmPossibilityTags.kflidAbbreviation, wsId, this); } break; default: if (frag >= kfragWordGlossWs && frag < kfragWordGlossWs + m_WsList.AnalysisWsIds.Length) { // Displaying one ws of the form of a WfiGloss. int ws = m_WsList.AnalysisWsIds[frag - kfragWordGlossWs]; vwenv.AddStringAltMember(WfiGlossTags.kflidForm, ws, this); } else if (frag >= kfragLineChoices && frag < kfragLineChoices + m_lineChoices.Count) { var spec = m_lineChoices[frag - kfragLineChoices]; var ws = GetRealWsOrBestWsForContext(hvo, spec); vwenv.AddStringAltMember(spec.StringFlid, ws, this); } else if (frag >= kfragAnalysisCategoryChoices && frag < kfragAnalysisCategoryChoices + m_lineChoices.Count) { AddAnalysisPos(vwenv, hvo, hvo, frag - kfragAnalysisCategoryChoices); } else if (frag >= kfragMorphFormChoices && frag < kfragMorphFormChoices + m_lineChoices.Count) { InterlinLineSpec spec = m_lineChoices[frag - kfragMorphFormChoices]; int wsActual = GetRealWsOrBestWsForContext(hvo, spec); DisplayMorphForm(vwenv, hvo, wsActual); } else if (frag >= kfragSegFfChoices && frag < kfragSegFfChoices + m_lineChoices.Count) { AddFreeformComment(vwenv, hvo, frag - kfragSegFfChoices); } else { throw new Exception("Bad fragment ID in InterlinVc.Display"); } break; } #if DEBUG //TimeRecorder.End("Display"); #endif }
public override void Display(IVwEnv vwenv, int hvo, int frag) { CheckDisposed(); try { switch (frag) { case kfragBundle: // One annotated word bundle, in this case, the whole view. if (hvo == 0) return; vwenv.set_IntProperty((int)FwTextPropType.ktptSpellCheck, (int)FwTextPropVar.ktpvEnum, (int)SpellingModes.ksmDoNotCheck); vwenv.set_IntProperty((int)FwTextPropType.ktptBackColor, (int)FwTextPropVar.ktpvDefault, krgbBackground); vwenv.OpenDiv(); vwenv.OpenParagraph(); // Since embedded in a pile with context, we need another layer of pile here,. // It's an overlay sandbox: draw a box around it. vwenv.OpenInnerPile(); // Inside that division we need a paragraph which does not have any border // or background. This suppresses the 'infinite width' behavior for the // nested paragraphs that may have grey border. vwenv.OpenParagraph(); // This makes a little separation between left border and arrows. vwenv.set_IntProperty((int)FwTextPropType.ktptPadLeading, (int)FwTextPropVar.ktpvMilliPoint, 1000); if (m_fRtl) { // This must not be on the outer paragraph or we get infinite width behavior. vwenv.set_IntProperty((int)FwTextPropType.ktptRightToLeft, (int)FwTextPropVar.ktpvEnum, (int)FwTextToggleVal.kttvForceOn); vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalRight); } vwenv.OpenInnerPile(); for (int ispec = 0; ispec < m_choices.Count; ) { InterlinLineSpec spec = m_choices[ispec]; if (!spec.WordLevel) break; if (spec.MorphemeLevel) { DisplayMorphBundles(vwenv, hvo); ispec = m_choices.LastMorphemeIndex + 1; continue; } switch (spec.Flid) { case InterlinLineChoices.kflidWord: int ws = GetActualWs(hvo, spec.StringFlid, spec.WritingSystem); DisplayWordform(vwenv, ws, ispec); break; case InterlinLineChoices.kflidWordGloss: DisplayWordGloss(vwenv, hvo, spec.WritingSystem, ispec); break; case InterlinLineChoices.kflidWordPos: DisplayWordPOS(vwenv, hvo, spec.WritingSystem, ispec); break; } ispec++; } vwenv.CloseInnerPile(); vwenv.CloseParagraph(); vwenv.CloseInnerPile(); vwenv.CloseParagraph(); vwenv.CloseDiv(); break; case kfragFirstMorph: // first morpheme in word case kfragMorph: // The bundle of 4 lines representing a morpheme. vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, 10000); vwenv.OpenInnerPile(); for (int ispec = m_choices.FirstMorphemeIndex; ispec <= m_choices.LastMorphemeIndex; ispec++) { int tagLexEntryIcon = 0; if (m_choices.FirstLexEntryIndex == ispec) tagLexEntryIcon = ktagMorphEntryIcon; InterlinLineSpec spec = m_choices[ispec]; switch (spec.Flid) { case InterlinLineChoices.kflidMorphemes: DisplayMorphForm(vwenv, hvo, frag, spec.WritingSystem, ispec); break; case InterlinLineChoices.kflidLexEntries: AddOptionalNamedObj(vwenv, hvo, ktagSbMorphEntry, ktagMissingEntry, kfragMissingEntry, tagLexEntryIcon, spec.WritingSystem, ispec); break; case InterlinLineChoices.kflidLexGloss: AddOptionalNamedObj(vwenv, hvo, ktagSbMorphGloss, ktagMissingMorphGloss, kfragMissingMorphGloss, tagLexEntryIcon, spec.WritingSystem, ispec); break; case InterlinLineChoices.kflidLexPos: AddOptionalNamedObj(vwenv, hvo, ktagSbMorphPos, ktagMissingMorphPos, kfragMissingMorphPos, tagLexEntryIcon, spec.WritingSystem, ispec); break; } } vwenv.CloseInnerPile(); break; default: if (frag >= kfragNamedObjectNameChoices && frag < kfragNamedObjectNameChoices + m_choices.Count) { InterlinLineSpec spec = m_choices[frag - kfragNamedObjectNameChoices]; int wsActual = GetActualWs(hvo, ktagSbNamedObjName, spec.WritingSystem); vwenv.AddStringAltMember(ktagSbNamedObjName, wsActual, this); } else { throw new Exception("Bad fragment ID in SandboxVc.Display"); } break; } } catch { Debug.Assert(false, "Exception thrown in the display of the SandboxVc (About to be eaten)"); } }
/// <summary> /// Add a segment number appropriate to the current segment being displayed. /// (See LT-1236.) /// </summary> /// <param name="vwenv"></param> /// <param name="hvo"></param> private void AddSegmentReference(IVwEnv vwenv, int hvo) { ITsString tssSegNum; StringBuilder sbSegNum = new StringBuilder(); int flid = 0; var seg = m_segRepository.GetObject(hvo); var para = seg.Paragraph; if (para != null) { ISilDataAccess sda = vwenv.DataAccess; int cseg = para.SegmentsOS.Count; int idxSeg = para.SegmentsOS.IndexOf(seg); // sda.GetObjIndex(hvoStPara, ktagParaSegments, hvo); IStText stText = para.Owner as IStText; if (stText != null) flid = stText.OwningFlid; if (flid == ScrSectionTags.kflidContent) { var scrPara = para as IScrTxtPara; // With null book name and trimmed it should have just chapter:v{a,b}. // The {a,b} above would not be the segment identifiers we add for multiple segments in // a verse, but the letters indicating that the verse label is for only part of the verse. // There is therefore a pathological case where, say, verse 4a as labeled in the main text // gets another letter because 4a has multiple segments 4aa, 4ab, etc. string chapRef = ScriptureServices.FullScrRef(scrPara, seg.BeginOffset, "").Trim(); sbSegNum.Append(chapRef + ScriptureServices.VerseSegLabel(scrPara, idxSeg)); } else { int idxPara = para.OwnOrd; if (idxPara >= 0) { sbSegNum.AppendFormat("{0}", idxPara + 1); if (idxSeg >= 0 && cseg > 1) sbSegNum.AppendFormat(".{0}", idxSeg + 1); } } } ITsStrBldr tsbSegNum = m_tsf.GetBldr(); tsbSegNum.ReplaceTsString(0, tsbSegNum.Length, TsStringUtils.MakeTss(sbSegNum.ToString(), m_cache.DefaultUserWs)); tsbSegNum.SetIntPropValues(0, tsbSegNum.Length, (int)FwTextPropType.ktptBold, (int)FwTextPropVar.ktpvEnum, (int)FwTextToggleVal.kttvForceOn); tssSegNum = tsbSegNum.GetString(); vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, 10000); vwenv.set_IntProperty((int)FwTextPropType.ktptForeColor, (int)FwTextPropVar.ktpvDefault, (int)CmObjectUi.RGB(SystemColors.ControlText)); try { m_fIsAddingSegmentReference = true; vwenv.OpenInnerPile(); vwenv.AddString(tssSegNum); vwenv.CloseInnerPile(); } finally { m_fIsAddingSegmentReference = false; } }
void CloseIndexPile(IVwEnv vwenv) { vwenv.Props = m_bracketProps; vwenv.AddProp(ktagRightBoundary, this, kfragZeroWidthSpace); vwenv.CloseParagraph(); vwenv.CloseInnerPile(); }
public override void Display(IVwEnv vwenv, int hvo, int frag) { var tsf = m_cache.TsStrFactory; var userWs = m_cache.DefaultUserWs; switch (frag) { case kfragRule: m_rule = m_cache.ServiceLocator.GetInstance<IMoAffixProcessRepository>().GetObject(hvo); VwLength tableLen; tableLen.nVal = 10000; tableLen.unit = VwUnit.kunPercent100; vwenv.OpenTable(3, tableLen, 0, VwAlignment.kvaLeft, VwFramePosition.kvfpVoid, VwRule.kvrlNone, 0, 0, false); VwLength inputLen; inputLen.nVal = 0; inputLen.unit = VwUnit.kunPoint1000; int indexWidth = GetStrWidth(m_indexStr, m_headerProps, vwenv); int inputWidth = GetStrWidth(m_inputStr, m_headerProps, vwenv); VwLength headerLen; headerLen.nVal = Math.Max(indexWidth, inputWidth) + 8000; headerLen.unit = VwUnit.kunPoint1000; inputLen.nVal += headerLen.nVal; VwLength leftEmptyLen; leftEmptyLen.nVal = 8000 + (PILE_MARGIN * 2) + 2000; leftEmptyLen.unit = VwUnit.kunPoint1000; inputLen.nVal += leftEmptyLen.nVal; var ctxtLens = new VwLength[m_rule.InputOS.Count]; vwenv.NoteDependency(new[] {m_rule.Hvo}, new[] {MoAffixProcessTags.kflidInput}, 1 ); for (int i = 0; i < m_rule.InputOS.Count; i++) { int idxWidth = GetStrWidth(tsf.MakeString(Convert.ToString(i + 1), userWs), m_indexProps, vwenv); int ctxtWidth = GetWidth(m_rule.InputOS[i], vwenv); ctxtLens[i].nVal = Math.Max(idxWidth, ctxtWidth) + 8000 + 1000; ctxtLens[i].unit = VwUnit.kunPoint1000; inputLen.nVal += ctxtLens[i].nVal; } VwLength rightEmptyLen; rightEmptyLen.nVal = 8000 + (PILE_MARGIN * 2) + 1000; rightEmptyLen.unit = VwUnit.kunPoint1000; inputLen.nVal += rightEmptyLen.nVal; vwenv.MakeColumns(1, inputLen); VwLength arrowLen; arrowLen.nVal = GetStrWidth(m_doubleArrow, m_arrowProps, vwenv) + 8000; arrowLen.unit = VwUnit.kunPoint1000; vwenv.MakeColumns(1, arrowLen); VwLength outputLen; outputLen.nVal = 1; outputLen.unit = VwUnit.kunRelative; vwenv.MakeColumns(1, outputLen); vwenv.OpenTableBody(); vwenv.OpenTableRow(); // input table cell vwenv.OpenTableCell(1, 1); vwenv.OpenTable(m_rule.InputOS.Count + 3, tableLen, 0, VwAlignment.kvaCenter, VwFramePosition.kvfpVoid, VwRule.kvrlNone, 0, 4000, false); vwenv.MakeColumns(1, headerLen); vwenv.MakeColumns(1, leftEmptyLen); foreach (VwLength ctxtLen in ctxtLens) vwenv.MakeColumns(1, ctxtLen); vwenv.MakeColumns(1, rightEmptyLen); vwenv.OpenTableBody(); vwenv.OpenTableRow(); // input header cell vwenv.Props = m_headerProps; vwenv.OpenTableCell(1, 1); vwenv.AddString(m_inputStr); vwenv.CloseTableCell(); // input left empty cell vwenv.Props = m_ctxtProps; vwenv.set_IntProperty((int)FwTextPropType.ktptBorderLeading, (int)FwTextPropVar.ktpvMilliPoint, 1000); vwenv.OpenTableCell(1, 1); vwenv.OpenParagraph(); OpenContextPile(vwenv, false); vwenv.Props = m_bracketProps; vwenv.AddProp(ktagLeftEmpty, this, kfragEmpty); CloseContextPile(vwenv, false); vwenv.CloseParagraph(); vwenv.CloseTableCell(); // input context cells vwenv.AddObjVec(MoAffixProcessTags.kflidInput, this, kfragInput); // input right empty cell vwenv.Props = m_ctxtProps; vwenv.OpenTableCell(1, 1); vwenv.OpenParagraph(); OpenContextPile(vwenv, false); vwenv.Props = m_bracketProps; vwenv.AddProp(ktagRightEmpty, this, kfragEmpty); CloseContextPile(vwenv, false); vwenv.CloseParagraph(); vwenv.CloseTableCell(); vwenv.CloseTableRow(); vwenv.OpenTableRow(); // index header cell vwenv.Props = m_headerProps; vwenv.OpenTableCell(1, 1); vwenv.AddString(m_indexStr); vwenv.CloseTableCell(); // index left empty cell vwenv.Props = m_indexProps; vwenv.set_IntProperty((int)FwTextPropType.ktptBorderLeading, (int)FwTextPropVar.ktpvMilliPoint, 1000); vwenv.OpenTableCell(1, 1); vwenv.CloseTableCell(); // index cells for (int i = 0; i < m_rule.InputOS.Count; i++) { vwenv.Props = m_indexProps; vwenv.OpenTableCell(1, 1); vwenv.AddString(tsf.MakeString(Convert.ToString(i + 1), userWs)); vwenv.CloseTableCell(); } // index right empty cell vwenv.Props = m_indexProps; vwenv.OpenTableCell(1, 1); vwenv.CloseTableCell(); vwenv.CloseTableRow(); vwenv.CloseTableBody(); vwenv.CloseTable(); vwenv.CloseTableCell(); // double arrow cell vwenv.Props = m_arrowProps; vwenv.OpenTableCell(1, 1); vwenv.AddString(m_doubleArrow); vwenv.CloseTableCell(); // result table cell vwenv.OpenTableCell(1, 1); vwenv.OpenTable(1, tableLen, 0, VwAlignment.kvaLeft, VwFramePosition.kvfpVoid, VwRule.kvrlNone, 0, 4000, false); vwenv.MakeColumns(1, outputLen); vwenv.OpenTableBody(); vwenv.OpenTableRow(); // result header cell vwenv.Props = m_headerProps; vwenv.OpenTableCell(1, 1); vwenv.AddString(m_resultStr); vwenv.CloseTableCell(); vwenv.CloseTableRow(); vwenv.OpenTableRow(); // result cell vwenv.Props = m_resultProps; vwenv.OpenTableCell(1, 1); vwenv.OpenParagraph(); if (m_rule.OutputOS.Count == 0) vwenv.AddProp(MoAffixProcessTags.kflidOutput, this, kfragEmpty); else vwenv.AddObjVecItems(MoAffixProcessTags.kflidOutput, this, kfragRuleMapping); vwenv.CloseParagraph(); vwenv.CloseTableCell(); vwenv.CloseTableRow(); vwenv.CloseTableBody(); vwenv.CloseTable(); vwenv.CloseTableCell(); vwenv.CloseTableRow(); vwenv.CloseTableBody(); vwenv.CloseTable(); break; case kfragRuleMapping: var mapping = m_cache.ServiceLocator.GetInstance<IMoRuleMappingRepository>().GetObject(hvo); switch (mapping.ClassID) { case MoCopyFromInputTags.kClassId: var copy = (IMoCopyFromInput) mapping; OpenIndexPile(vwenv); if (copy.ContentRA == null) vwenv.AddProp(ktagIndex, this, 0); else vwenv.AddProp(ktagIndex, this, copy.ContentRA.IndexInOwner + 1); CloseIndexPile(vwenv); break; case MoInsertPhonesTags.kClassId: OpenIndexPile(vwenv); vwenv.AddObjVecItems(MoInsertPhonesTags.kflidContent, this, kfragTerminalUnit); CloseIndexPile(vwenv); break; case MoModifyFromInputTags.kClassId: var modify = (IMoModifyFromInput) mapping; var numLines = modify.ModificationRA.FeaturesOA.FeatureSpecsOC.Count; // left bracket pile vwenv.set_IntProperty((int)FwTextPropType.ktptMarginLeading, (int)FwTextPropVar.ktpvMilliPoint, PILE_MARGIN); vwenv.OpenInnerPile(); vwenv.Props = m_bracketProps; vwenv.AddProp(ktagLeftBoundary, this, kfragZeroWidthSpace); // put index in the left bracket pile if (modify.ContentRA == null) vwenv.AddProp(ktagIndex, this, 0); else vwenv.AddProp(ktagIndex, this, modify.ContentRA.IndexInOwner + 1); // right align brackets in left bracket pile, since the index could have a greater width, then the bracket if (numLines > 1) { vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalRight); vwenv.AddProp(ktagLeftNonBoundary, this, kfragLeftBracketUpHook); for (int i = 1; i < numLines - 1; i++) { vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalRight); vwenv.AddProp(ktagLeftNonBoundary, this, kfragLeftBracketExt); } vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalRight); vwenv.AddProp(ktagLeftNonBoundary, this, kfragLeftBracketLowHook); } else { vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalRight); vwenv.AddProp(ktagLeftNonBoundary, this, kfragLeftBracket); } vwenv.CloseInnerPile(); // feature pile vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalLeft); vwenv.OpenInnerPile(); AddExtraLines(1, vwenv); if (numLines == 0) vwenv.AddProp(MoModifyFromInputTags.kflidModification, this, kfragQuestions); else vwenv.AddObjProp(MoModifyFromInputTags.kflidModification, this, kfragFeatNC); vwenv.CloseInnerPile(); // right bracket pile vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, PILE_MARGIN); vwenv.OpenInnerPile(); vwenv.Props = m_bracketProps; vwenv.AddProp(ktagRightBoundary, this, kfragSpace); if (numLines > 1) { vwenv.Props = m_bracketProps; vwenv.AddProp(ktagRightNonBoundary, this, kfragRightBracketUpHook); for (int i = 1; i < numLines - 1; i++) { vwenv.Props = m_bracketProps; vwenv.AddProp(ktagRightNonBoundary, this, kfragRightBracketExt); } vwenv.Props = m_bracketProps; vwenv.AddProp(ktagRightNonBoundary, this, kfragRightBracketLowHook); } else { vwenv.AddProp(ktagRightNonBoundary, this, kfragRightBracket); } vwenv.CloseInnerPile(); break; } break; default: base.Display(vwenv, hvo, frag); break; } }
/// <summary> /// /// </summary> /// <param name="vwenv"></param> /// <param name="hvo">WfiMorphBundle</param> private void DisplayMorphBundle(IVwEnv vwenv, int hvo) { vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, 10000); vwenv.OpenInnerPile(); int first = m_lineChoices.FirstMorphemeIndex; int last = m_lineChoices.LastMorphemeIndex; int hvoMf = 0; if (hvo != 0) { hvoMf = m_cache.GetObjProperty(hvo, (int)WfiMorphBundle.WfiMorphBundleTags.kflidMorph); } if (vwenv is CollectorEnv && hvoMf != 0) { // Collectors are given an extra initial chance to 'collect' the morph type, if any. vwenv.AddObjProp((int)WfiMorphBundle.WfiMorphBundleTags.kflidMorph, this, kfragMorphType); } for (int i = first; i <= last; i++) { InterlinLineSpec spec = m_lineChoices[i]; int ws = 0; if (hvo != 0) { ws = GetRealWs(hvo, spec); } SetColor(vwenv, LabelRGBFor(spec)); switch (spec.Flid) { case InterlinLineChoices.kflidMorphemes: if (hvo == 0) { vwenv.AddString(m_tssMissingMorph); } else if (hvoMf == 0) { // If no morph, use the form of the morph bundle (and the entry is of // course missing) if (ws == 0) { ws = m_cache.LangProject.ActualWs(spec.WritingSystem, hvo, (int)WfiMorphBundle.WfiMorphBundleTags.kflidForm); } vwenv.AddStringAltMember( (int)WfiMorphBundle.WfiMorphBundleTags.kflidForm, ws, this); } else { // Got a morph, show it. vwenv.AddObjProp((int)WfiMorphBundle.WfiMorphBundleTags.kflidMorph, this, kfragMorphFormChoices + i); // And the LexEntry line. } break; case InterlinLineChoices.kflidLexEntries: if (hvoMf == 0) { if (hvo != 0) vwenv.NoteDependency(new int[] { hvo }, new int[] { (int)WfiMorphBundle.WfiMorphBundleTags.kflidMorph }, 1); vwenv.AddString(m_tssMissingEntry); } else { if (ws == 0) ws = spec.WritingSystem; LexEntryVc vcEntry = new LexEntryVc(m_cache); vcEntry.WritingSystemCode = ws; vwenv.AddObj(hvo, vcEntry, LexEntryVc.kfragEntryAndVariant); } break; case InterlinLineChoices.kflidLexGloss: int hvoSense = 0; if (hvo != 0) { hvoSense = m_cache.GetObjProperty(hvo, (int)WfiMorphBundle.WfiMorphBundleTags.kflidSense); } if (hvoSense == 0) { int virtFlid = 0; if (hvo != 0) { vwenv.NoteDependency(new int[] { hvo }, new int[] { (int)WfiMorphBundle.WfiMorphBundleTags.kflidSense }, 1); virtFlid = BaseVirtualHandler.GetInstalledHandlerTag(m_cache, "WfiMorphBundle", "DefaultSense"); } if (hvo != 0 && ShowDefaultSense && m_cache.GetObjProperty(hvo, virtFlid) > 0) { // Switch values when using the default sense, rather than the missing row '***'. SetGuessing(vwenv, false); vwenv.AddObjProp(virtFlid, this, kfragLineChoices + i); } else { vwenv.AddProp(ktagBundleMissingSense, this, kfragBundleMissingSense); } } else { vwenv.AddObjProp((int)WfiMorphBundle.WfiMorphBundleTags.kflidSense, this, kfragLineChoices + i); } break; case InterlinLineChoices.kflidLexPos: // LexPOS line: int hvoMsa = 0; if (hvo != 0) hvoMsa = m_cache.GetObjProperty(hvo, (int)WfiMorphBundle.WfiMorphBundleTags.kflidMsa); if (hvoMsa == 0) { if (hvo != 0) vwenv.NoteDependency(new int[] { hvo }, new int[] { (int)WfiMorphBundle.WfiMorphBundleTags.kflidMsa }, 1); vwenv.AddString(m_tssMissingMsa); } else { // Use a special view constructor that knows how to display the // interlinear view of whatever kind of MSA it is. // Enhance JohnT: ideally we would have one of these VCs for each writing system, // perhaps stored in the InterlinLineSpec. Currently displaying multiple Wss of LexPos // is not useful, though it is possible. // Enhancement RickM: we set the m_msaVc.WritingSystemCode to the selected writing system // of each LexPos line in interlinear. This is used extract the LexPos abbreviation // for the specific writing system. m_msaVc.WritingSystemCode = spec.WritingSystem; vwenv.AddObjProp((int)WfiMorphBundle.WfiMorphBundleTags.kflidMsa, m_msaVc, (int)VcFrags.kfragInterlinearAbbr); } break; } } vwenv.CloseInnerPile(); }
public override void Display(IVwEnv vwenv, int hvo, int frag) { int userWs = m_cache.DefaultUserWs; switch (frag) { case kfragRule: m_rule = m_cache.ServiceLocator.GetInstance <IMoAffixProcessRepository>().GetObject(hvo); int maxNumLines = GetMaxNumLines(); VwLength tableLen; tableLen.nVal = 10000; tableLen.unit = VwUnit.kunPercent100; vwenv.OpenTable(3, tableLen, 0, VwAlignment.kvaLeft, VwFramePosition.kvfpVoid, VwRule.kvrlNone, 0, 0, false); VwLength inputLen; inputLen.nVal = 0; inputLen.unit = VwUnit.kunPoint1000; int indexWidth = GetStrWidth(m_indexStr, m_headerProps, vwenv); int inputWidth = GetStrWidth(m_inputStr, m_headerProps, vwenv); VwLength headerLen; headerLen.nVal = Math.Max(indexWidth, inputWidth) + 8000; headerLen.unit = VwUnit.kunPoint1000; inputLen.nVal += headerLen.nVal; VwLength leftEmptyLen; leftEmptyLen.nVal = 8000 + (PileMargin * 2) + 2000; leftEmptyLen.unit = VwUnit.kunPoint1000; inputLen.nVal += leftEmptyLen.nVal; var ctxtLens = new VwLength[m_rule.InputOS.Count]; vwenv.NoteDependency(new[] { m_rule.Hvo }, new[] { MoAffixProcessTags.kflidInput }, 1); for (int i = 0; i < m_rule.InputOS.Count; i++) { int idxWidth = GetStrWidth(TsStringUtils.MakeString(Convert.ToString(i + 1), userWs), m_indexProps, vwenv); int ctxtWidth = GetWidth(m_rule.InputOS[i], vwenv); ctxtLens[i].nVal = Math.Max(idxWidth, ctxtWidth) + 8000 + 1000; ctxtLens[i].unit = VwUnit.kunPoint1000; inputLen.nVal += ctxtLens[i].nVal; } VwLength rightEmptyLen; rightEmptyLen.nVal = 8000 + (PileMargin * 2) + 1000; rightEmptyLen.unit = VwUnit.kunPoint1000; inputLen.nVal += rightEmptyLen.nVal; vwenv.MakeColumns(1, inputLen); VwLength arrowLen; arrowLen.nVal = GetStrWidth(m_doubleArrow, m_arrowProps, vwenv) + 8000; arrowLen.unit = VwUnit.kunPoint1000; vwenv.MakeColumns(1, arrowLen); VwLength outputLen; outputLen.nVal = 1; outputLen.unit = VwUnit.kunRelative; vwenv.MakeColumns(1, outputLen); vwenv.OpenTableBody(); vwenv.OpenTableRow(); // input table cell vwenv.OpenTableCell(1, 1); vwenv.OpenTable(m_rule.InputOS.Count + 3, tableLen, 0, VwAlignment.kvaCenter, VwFramePosition.kvfpVoid, VwRule.kvrlNone, 0, 4000, false); vwenv.MakeColumns(1, headerLen); vwenv.MakeColumns(1, leftEmptyLen); foreach (VwLength ctxtLen in ctxtLens) { vwenv.MakeColumns(1, ctxtLen); } vwenv.MakeColumns(1, rightEmptyLen); vwenv.OpenTableBody(); vwenv.OpenTableRow(); // input header cell vwenv.Props = m_headerProps; vwenv.OpenTableCell(1, 1); vwenv.AddString(m_inputStr); vwenv.CloseTableCell(); // input left empty cell vwenv.Props = m_ctxtProps; vwenv.set_IntProperty((int)FwTextPropType.ktptBorderLeading, (int)FwTextPropVar.ktpvMilliPoint, 1000); vwenv.OpenTableCell(1, 1); vwenv.OpenParagraph(); OpenSingleLinePile(vwenv, maxNumLines, false); vwenv.Props = m_bracketProps; vwenv.AddProp(ktagLeftEmpty, this, kfragEmpty); CloseSingleLinePile(vwenv, false); vwenv.CloseParagraph(); vwenv.CloseTableCell(); // input context cells vwenv.AddObjVec(MoAffixProcessTags.kflidInput, this, kfragInput); // input right empty cell vwenv.Props = m_ctxtProps; vwenv.OpenTableCell(1, 1); vwenv.OpenParagraph(); OpenSingleLinePile(vwenv, maxNumLines, false); vwenv.Props = m_bracketProps; vwenv.AddProp(ktagRightEmpty, this, kfragEmpty); CloseSingleLinePile(vwenv, false); vwenv.CloseParagraph(); vwenv.CloseTableCell(); vwenv.CloseTableRow(); vwenv.OpenTableRow(); // index header cell vwenv.Props = m_headerProps; vwenv.OpenTableCell(1, 1); vwenv.AddString(m_indexStr); vwenv.CloseTableCell(); // index left empty cell vwenv.Props = m_indexProps; vwenv.set_IntProperty((int)FwTextPropType.ktptBorderLeading, (int)FwTextPropVar.ktpvMilliPoint, 1000); vwenv.OpenTableCell(1, 1); vwenv.CloseTableCell(); // index cells for (int i = 0; i < m_rule.InputOS.Count; i++) { vwenv.Props = m_indexProps; vwenv.OpenTableCell(1, 1); vwenv.AddString(TsStringUtils.MakeString(Convert.ToString(i + 1), userWs)); vwenv.CloseTableCell(); } // index right empty cell vwenv.Props = m_indexProps; vwenv.OpenTableCell(1, 1); vwenv.CloseTableCell(); vwenv.CloseTableRow(); vwenv.CloseTableBody(); vwenv.CloseTable(); vwenv.CloseTableCell(); // double arrow cell vwenv.Props = m_arrowProps; vwenv.OpenTableCell(1, 1); vwenv.AddString(m_doubleArrow); vwenv.CloseTableCell(); // result table cell vwenv.OpenTableCell(1, 1); vwenv.OpenTable(1, tableLen, 0, VwAlignment.kvaLeft, VwFramePosition.kvfpVoid, VwRule.kvrlNone, 0, 4000, false); vwenv.MakeColumns(1, outputLen); vwenv.OpenTableBody(); vwenv.OpenTableRow(); // result header cell vwenv.Props = m_headerProps; vwenv.OpenTableCell(1, 1); vwenv.AddString(m_resultStr); vwenv.CloseTableCell(); vwenv.CloseTableRow(); vwenv.OpenTableRow(); // result cell vwenv.Props = m_resultProps; vwenv.OpenTableCell(1, 1); vwenv.OpenParagraph(); if (m_rule.OutputOS.Count == 0) { vwenv.AddProp(MoAffixProcessTags.kflidOutput, this, kfragEmpty); } else { vwenv.AddObjVecItems(MoAffixProcessTags.kflidOutput, this, kfragRuleMapping); } vwenv.CloseParagraph(); vwenv.CloseTableCell(); vwenv.CloseTableRow(); vwenv.CloseTableBody(); vwenv.CloseTable(); vwenv.CloseTableCell(); vwenv.CloseTableRow(); vwenv.CloseTableBody(); vwenv.CloseTable(); break; case kfragRuleMapping: var mapping = m_cache.ServiceLocator.GetInstance <IMoRuleMappingRepository>().GetObject(hvo); switch (mapping.ClassID) { case MoCopyFromInputTags.kClassId: var copy = (IMoCopyFromInput)mapping; OpenSingleLinePile(vwenv, GetOutputMaxNumLines()); if (copy.ContentRA == null) { vwenv.AddProp(ktagIndex, this, 0); } else { vwenv.AddProp(ktagIndex, this, copy.ContentRA.IndexInOwner + 1); } CloseSingleLinePile(vwenv); break; case MoInsertPhonesTags.kClassId: OpenSingleLinePile(vwenv, GetOutputMaxNumLines()); vwenv.AddObjVecItems(MoInsertPhonesTags.kflidContent, this, kfragTerminalUnit); CloseSingleLinePile(vwenv); break; case MoModifyFromInputTags.kClassId: var modify = (IMoModifyFromInput)mapping; int outputMaxNumLines = GetOutputMaxNumLines(); int numLines = modify.ModificationRA.FeaturesOA.FeatureSpecsOC.Count; // index pile vwenv.set_IntProperty((int)FwTextPropType.ktptMarginLeading, (int)FwTextPropVar.ktpvMilliPoint, PileMargin); vwenv.OpenInnerPile(); AddExtraLines(outputMaxNumLines - 1, vwenv); vwenv.OpenParagraph(); vwenv.Props = m_bracketProps; vwenv.AddProp(ktagLeftBoundary, this, kfragZeroWidthSpace); if (modify.ContentRA == null) { vwenv.AddProp(ktagIndex, this, 0); } else { vwenv.AddProp(ktagIndex, this, modify.ContentRA.IndexInOwner + 1); } vwenv.CloseParagraph(); vwenv.CloseInnerPile(); // left bracket pile // right align brackets in left bracket pile, since the index could have a greater width, then the bracket if (numLines == 1) { vwenv.OpenInnerPile(); AddExtraLines(outputMaxNumLines - 1, vwenv); vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalRight); vwenv.AddProp(ktagLeftNonBoundary, this, kfragLeftBracket); vwenv.CloseInnerPile(); } else { vwenv.OpenInnerPile(); vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalRight); vwenv.AddProp(ktagLeftNonBoundary, this, kfragLeftBracketUpHook); for (int i = 1; i < numLines - 1; i++) { vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalRight); vwenv.AddProp(ktagLeftNonBoundary, this, kfragLeftBracketExt); } vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalRight); vwenv.AddProp(ktagLeftNonBoundary, this, kfragLeftBracketLowHook); vwenv.CloseInnerPile(); } // feature pile vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalLeft); vwenv.OpenInnerPile(); AddExtraLines(outputMaxNumLines - numLines, vwenv); if (numLines == 0) { vwenv.AddProp(MoModifyFromInputTags.kflidModification, this, kfragQuestions); } else { vwenv.AddObjProp(MoModifyFromInputTags.kflidModification, this, kfragFeatNC); } vwenv.CloseInnerPile(); // right bracket pile if (numLines == 1) { vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, PileMargin); AddExtraLines(outputMaxNumLines - 1, vwenv); vwenv.OpenInnerPile(); vwenv.AddProp(ktagRightBoundary, this, kfragRightBracket); vwenv.CloseInnerPile(); } else { vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, PileMargin); vwenv.OpenInnerPile(); AddExtraLines(outputMaxNumLines - numLines, vwenv); vwenv.Props = m_bracketProps; vwenv.AddProp(ktagRightNonBoundary, this, kfragRightBracketUpHook); for (int i = 1; i < numLines - 1; i++) { vwenv.Props = m_bracketProps; vwenv.AddProp(ktagRightNonBoundary, this, kfragRightBracketExt); } vwenv.Props = m_bracketProps; vwenv.AddProp(ktagRightBoundary, this, kfragRightBracketLowHook); vwenv.CloseInnerPile(); } break; } break; default: base.Display(vwenv, hvo, frag); break; } }
public override void Display(IVwEnv vwenv, int hvo, int frag) { switch (frag) { case kfragPrintChart: // the whole chart with headings for printing. if (hvo == 0) return; PrintColumnGroupHeaders(hvo, vwenv); PrintIndividualColumnHeaders(hvo, vwenv); // Rest is same as kfragChart DisplayChartBody(vwenv); break; case kfragTemplateHeader: // Display the template as group headers. vwenv.AddObjVecItems((int)CmPossibility.CmPossibilityTags.kflidSubPossibilities, this, kfragColumnGroupHeader); break; // This is only used for printing, the headers in the screen version are a separate control. case kfragColumnGroupHeader: int ccols = vwenv.DataAccess.get_VecSize(hvo, (int)CmPossibility.CmPossibilityTags.kflidSubPossibilities); // If there are no subitems, we still want a blank cell as a placeholder. MakeCellsMethod.OpenStandardCell(vwenv, Math.Max(ccols, 1), true); if (ccols > 0) { // It's a group, include its name vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalCenter); vwenv.OpenParagraph(); vwenv.AddString(CmPossibility.BestAnalysisName(m_cache, hvo)); vwenv.CloseParagraph(); } vwenv.CloseTableCell(); break; case kfragChart: // the whole chart, a DsConstChart. if (hvo == 0) return; DisplayChartBody(vwenv); break; case kfragChartRow: // one row, a CmIndirectAnnotation { MakeTableAndRowWithStdWidths(vwenv, hvo, false); MakeCells(vwenv, hvo); vwenv.CloseTableRow(); vwenv.CloseTable(); } break; case kfragCca: // a single group of words, the contents of one cell. if (ConstituentChartLogic.IsWficGroup(m_cache, hvo)) vwenv.AddObjVec(kflidAppliesTo, this, kfragBundleVec); else { // it's a moved text or missing-item placeholder. int hvoClause; if (m_chart.Logic.IsClausePlaceholder(hvo, out hvoClause)) DisplayClausePlaceholder(vwenv, hvoClause); else if (vwenv.DataAccess.get_VecSize(hvo, kflidAppliesTo) == 0) DisplayMissingMarker(vwenv); else DisplayMovedTextTag(hvo, vwenv); } break; case kfragCcaMoved: // a single group of words, the contents of one cell, which is considered moved-within-line. // can't be a placeholder. string formatTag = m_chart.Logic.MovedTextTag(hvo); ApplyFormatting(vwenv, formatTag); vwenv.OpenSpan(); InsertOpenBracket(vwenv, formatTag); vwenv.AddObjVec(kflidAppliesTo, this, kfragBundleVec); InsertCloseBracket(vwenv, formatTag); vwenv.CloseSpan(); break; case kfragCcaListItem: // a single CCA, referring to a list item. // can't be a placeholder. ApplyFormatting(vwenv, "marker"); vwenv.OpenSpan(); InsertOpenBracket(vwenv, "marker"); vwenv.AddObjProp((int)CmBaseAnnotation.CmBaseAnnotationTags.kflidBeginObject, this, kfragPossibility); InsertCloseBracket(vwenv, "marker"); vwenv.CloseSpan(); break; case kfragPossibility: // A CmPossibility, show it's abbreviation int flid = (int)CmPossibility.CmPossibilityTags.kflidAbbreviation; int retWs; m_cache.LangProject.GetMagicStringAlt(LangProject.kwsFirstAnal, hvo, flid, false, out retWs); // If we didn't find an abbreviation try for the name ITsString tss = null; if (retWs != 0) tss = m_cache.GetMultiStringAlt(hvo, flid, retWs); if (tss == null || string.IsNullOrEmpty(tss.Text)) { flid = (int)CmPossibility.CmPossibilityTags.kflidName; m_cache.LangProject.GetMagicStringAlt(LangProject.kwsFirstAnal, hvo, flid, false, out retWs); } // Unless we didn't get anything, go ahead and insert the best option we found. if (retWs != 0) vwenv.AddStringAltMember(flid, retWs, this); // retWS was m_cache.DefaultAnalWs, this fixes LT-7838 break; case kfragBundle: // One annotated word bundle; hvo is CmBaseAnnotation. Overrides behavior of InterlinVc { SetupForTwfic(hvo); // Make an 'inner pile' to contain the wordform and annotations. // 10 points below also helps space out the paragraph. vwenv.set_IntProperty((int)FwTextPropType.ktptMarginBottom, (int)FwTextPropVar.ktpvMilliPoint, 5000); vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalLeading); vwenv.OpenInnerPile(); // Get the instanceOf property of the annotation and see whether it exists. If not it is // just a punctuation annotation, and we just insert the form. vwenv.NoteDependency(new int[] { hvo }, new int[] { InterlinDocChild.TagAnalysis }, 1); int hvoInstanceOf = vwenv.DataAccess.get_ObjectProp(hvo, InterlinDocChild.TagAnalysis); if (hvoInstanceOf == 0) { vwenv.AddStringProp(m_flidStringValue, this); } else { // It's a full Twfic annotation, display the full bundle. vwenv.AddObjProp(InterlinDocChild.TagAnalysis, this, kfragTwficAnalysis); } //vwenv.AddObjProp(ktagTwficDefault, this, kfragTwficAnalysis); vwenv.CloseInnerPile(); // revert back to the paragraph vernWs. SetupForTwfic(0); } break; case kfragNotesText: // notes structured text vwenv.AddObjVecItems((int)StText.StTextTags.kflidParagraphs, this, kfragNotesPara); break; case kfragNotesPara: vwenv.AddStringProp((int)StTxtPara.StTxtParaTags.kflidContents, this); break; case kfragComment: // hvo is a CmAnnotation, a row vwenv.AddStringAltMember((int)CmAnnotation.CmAnnotationTags.kflidComment, m_chart.Logic.WsLineNumber, this); break; default: base.Display(vwenv, hvo, frag); break; } }
private void AddTableCell(IVwEnv vwenv, int hvo, int index, int hvoRoot, int icolActive, int cAdjCol, int icol) { XmlNode node = m_columns[icol - 1]; // Figure out the underlying Right-To-Left value. bool fRightToLeft = false; // Figure out if this column's writing system is audio. bool fVoice = false; m_wsBest = GetBestWsForNode(node, hvo); if (m_wsBest != 0) { var ws = m_cache.ServiceLocator.WritingSystemManager.Get(m_wsBest); if (ws != null) { fRightToLeft = ws.RightToLeftScript; var wsDef = ws as WritingSystemDefinition; fVoice = wsDef == null ? false : wsDef.IsVoice; } } bool fSortedFromEnd = m_xbv.ColumnSortedFromEnd(icol - cAdjCol); int tal; if (fRightToLeft) { if (fSortedFromEnd) tal = (int)FwTextAlign.ktalLeft; else tal = (int)FwTextAlign.ktalRight; } else { if (fSortedFromEnd) tal = (int)FwTextAlign.ktalRight; else tal = (int)FwTextAlign.ktalLeft; } vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, tal); // If this cell is audio, don't allow editing. if (fVoice) SetCellEditability(vwenv, false); bool fIsCellActive = false; if (icolActive != 0 && m_PreviewArrowPic != null) { // The display depends on which column is active and whether the current row is selected. vwenv.NoteDependency(new int[] { hvoRoot, hvo, hvo }, new int[] { XMLViewsDataCache.ktagActiveColumn, XMLViewsDataCache.ktagItemSelected, XMLViewsDataCache.ktagItemEnabled }, 3); // We're doing the active column thing. if (MultiColumnPreview) { fIsCellActive = vwenv.DataAccess.get_IntProp(hvo, XMLViewsDataCache.ktagItemSelected) != 0 && vwenv.DataAccess.get_StringProp(hvo, XMLViewsDataCache.ktagAlternateValueMultiBase + icol).Length > 0; } else if (icol == icolActive) { fIsCellActive = vwenv.DataAccess.get_IntProp(hvo, XMLViewsDataCache.ktagItemSelected) != 0 && vwenv.DataAccess.get_IntProp(hvo, XMLViewsDataCache.ktagItemEnabled) != 0; } } // Make a cell and embed the contents of the column node. ProcessProperties(node, vwenv); SetCellProperties(index, icol, node, hvo, vwenv, fIsCellActive); vwenv.set_IntProperty((int)FwTextPropType.ktptPadTop, (int)FwTextPropVar.ktpvMilliPoint, 1607); vwenv.OpenTableCell(1, 1); vwenv.set_IntProperty((int)FwTextPropType.ktptPadTrailing, (int)FwTextPropVar.ktpvMilliPoint, 1607); vwenv.set_IntProperty((int)FwTextPropType.ktptPadLeading, (int)FwTextPropVar.ktpvMilliPoint, 1607); if (node.Name == "column") { // Paragraph directionality must be set before the paragraph is opened. vwenv.set_IntProperty((int)FwTextPropType.ktptRightToLeft, (int)FwTextPropVar.ktpvEnum, IsWritingSystemRTL(node) ? -1 : 0); } // According to LT-8947, in bulk edit preview mode, we want to try to show the // original cell contents on the same line with the preview arrow and the new cell contents. // to accomplish this, we use 3 InnerPiles in a paragraph // to try to keep them on the same line (or wrap otherwise). // NOTE: the bottom two inner piles will only be present if fIsCellActive is true. // // <Paragraph> // <InnerPile> // <paragraph> Original cell contents </paragraph> // </InnerPile> // <InnerPile> // <paragraph> Arrow Picture </paragraph> // </InnerPile> // <InnerPile> // <paragraph> Alternate cell contents </paragraph> // </InnerPile> // </Paragraph> // vwenv.OpenParagraph(); // <Paragraph> bool multiPara = XmlUtils.GetOptionalBooleanAttributeValue(node, "multipara", false); vwenv.OpenInnerPile(); // <InnerPile> // if the multi-para attribute is not specified, create a paragraph to wrap the cell contents. bool fParaOpened = false; if (!multiPara) { vwenv.OpenParagraph(); // <paragraph> fParaOpened = true; } if (m_sortItemProvider == null) { try { if (node.Name == "column") { SetForcedWs(node); } XmlNode nodeToProcess = GetColumnNode(node, hvo, m_sda, m_layouts); ProcessChildren(nodeToProcess, vwenv, hvo, null); } finally { // reset the ws for next column in the row. WsForce = 0; } } else { int level = vwenv.EmbeddingLevel; int hvoDum, tag, ihvo; vwenv.GetOuterObject(level - 2, out hvoDum, out tag, out ihvo); Debug.Assert(tag == m_fakeFlid); IManyOnePathSortItem item = m_sortItemProvider.SortItemAt(ihvo); if (item != null) DisplayCell(item, node, hvo, vwenv); // (Original) cell contents } if (fParaOpened) { vwenv.CloseParagraph(); // (Original) cell contents </paragraph> fParaOpened = false; } vwenv.CloseInnerPile(); // </InnerPile> if (fIsCellActive) AddPreviewPiles(vwenv, node, icol); vwenv.CloseParagraph(); // </Paragraph> vwenv.CloseTableCell(); m_wsBest = 0; }
private void DisplayMorphForm(IVwEnv vwenv, int hvo, int frag, int ws, int choiceIndex) { int hvoMorphForm = vwenv.DataAccess.get_ObjectProp(hvo, ktagSbMorphForm); // Allow editing of the morpheme breakdown line. SetColor(vwenv, m_choices.LabelRGBFor(choiceIndex)); // On this line we want an icon only for the first column (and only if it is the first // occurrence of the flid). bool fWantIcon = m_fIsMorphemeFormEditable && (frag == kfragFirstMorph) && m_choices.IsFirstOccurrenceOfFlid(choiceIndex); if (!fWantIcon) SetIndentForMissingIcon(vwenv); vwenv.OpenParagraph(); bool fFirstMorphLine = (m_choices.IndexOf(InterlinLineChoices.kflidMorphemes) == choiceIndex); if (fWantIcon) // Review JohnT: should we do the 'edit box' for all first columns? { AddPullDownIcon(vwenv, ktagMorphFormIcon); // Create an edit box that stays visible when the user deletes // the first morpheme (like the WordGloss box). // This is especially useful if the user wants to // delete the entire MorphForm line (cf. LT-1621). vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, kmpIconMargin); vwenv.set_IntProperty((int)FwTextPropType.ktptPadTrailing, (int)FwTextPropVar.ktpvMilliPoint, 2000); vwenv.set_IntProperty((int)FwTextPropType.ktptPadLeading, (int)FwTextPropVar.ktpvMilliPoint, 2000); vwenv.set_IntProperty((int)FwTextPropType.ktptBackColor, (int)FwTextPropVar.ktpvDefault, krgbEditable); } // Per LT-14891, morpheme form is not editable except for the default vernacular. if (m_fIsMorphemeFormEditable && m_choices.IsFirstOccurrenceOfFlid(choiceIndex)) MakeNextFlowObjectEditable(vwenv); else MakeNextFlowObjectReadOnly(vwenv); vwenv.OpenInnerPile(); vwenv.OpenParagraph(); if (fFirstMorphLine) vwenv.AddStringProp(ktagSbMorphPrefix, this); // This is never missing, but may, or may not, be editable. vwenv.AddObjProp(ktagSbMorphForm, this, kfragNamedObjectNameChoices + choiceIndex); if (fFirstMorphLine) vwenv.AddStringProp(ktagSbMorphPostfix, this); // close the special edit box we opened for the first morpheme. vwenv.CloseParagraph(); vwenv.CloseInnerPile(); vwenv.CloseParagraph(); }
/// <summary> /// The main entry point to do the work of the original method. /// </summary> internal void Display(ref ITsString tssDelayedNumber) { MainCallerDisplayCommand dispInfo; if (!m_viewConstructor.CanGetMainCallerDisplayCommand(m_frag, out dispInfo)) { // Shouldn't be possible, but just in case... Debug.Assert(true, "No MainCallerDisplayCommand!"); return; } XmlNode listDelimitNode; // has the list seps attrs like 'sep' XmlNode specialAttrsNode; // has the more exotic ones like 'excludeHvo' listDelimitNode = specialAttrsNode = dispInfo.MainNode; // 'inheritSeps' attr means to use the 'caller' (the part ref node) // to get the separator information. if (XmlUtils.GetOptionalBooleanAttributeValue(listDelimitNode, "inheritSeps", false)) { listDelimitNode = dispInfo.Caller; } // // 1. get number of items in vector // var chvo = m_sda.get_VecSize(m_hvo, m_flid); if (chvo == 0) { // We may want to do something special for empty vectors. See LT-9687. ProcessEmptyVector(m_vwEnv, m_hvo, m_flid); return; } // // 2. for each item in the vector, // a) print leading number if desired. // b) call AddObj // c) print separator if desired and needed // int[] rghvo = GetVector(m_sda, m_hvo, m_flid); Debug.Assert(chvo == rghvo.Length); // // Define some special boolean flags. // // Note that we deliberately don't use the listDelimitNode here. // These three props are not currently configurable, and they belong on the 'seq' element, // not the part ref. var fCheckForEmptyItems = XmlUtils.GetOptionalBooleanAttributeValue(specialAttrsNode, "checkForEmptyItems", false); string exclude = XmlUtils.GetOptionalAttributeValue(specialAttrsNode, "excludeHvo", null); var fFirstOnly = XmlUtils.GetOptionalBooleanAttributeValue(specialAttrsNode, "firstOnly", false); XmlAttribute xaNum; var fNumber = SetNumberFlagIncludingSingleOption(listDelimitNode, chvo, out xaNum); ApplySortingIfSpecified(rghvo, specialAttrsNode); // Determine if sequence should be filtered by a stored list of Guids. // Note that if we filter, we replace rghvo with the filtered list. if (m_viewConstructor.ShouldFilterByGuid) { // order by vector item type guids // Don't reorder LexEntry VisibleComplexFormBackRefs vector if the user overrode it manually. var obj = m_cache.ServiceLocator.GetObject(m_hvo); if (obj is ILexEntry) { var lexEntry = obj as ILexEntry; if (m_flid == m_cache.MetaDataCacheAccessor.GetFieldId("LexEntry", "VisibleComplexFormBackRefs", false)) { if (!VirtualOrderingServices.HasVirtualOrdering(lexEntry, "VisibleComplexFormBackRefs")) { chvo = ApplyFilterToSequence(ref rghvo); } } else { chvo = ApplyFilterToSequence(ref rghvo); } } else { chvo = ApplyFilterToSequence(ref rghvo); } } // Check whether the user wants the grammatical information to appear only once, preceding any // sense numbers, if there is only one set of grammatical information, and all senses refer to // it. See LT-9663. var childFrag = m_frag; var fSingleGramInfoFirst = false; if (m_flid == LexEntryTags.kflidSenses) { fSingleGramInfoFirst = XmlUtils.GetOptionalBooleanAttributeValue(listDelimitNode, "singlegraminfofirst", false); } // This groups senses by placing graminfo before the number, and omitting it if the same as the // previous sense in the entry. This isn't yet supported by the UI, but may well be requested in // the future. (See LT-9663.) //bool fGramInfoBeforeNumber = XmlUtils.GetOptionalBooleanAttributeValue(listDelimitNode, "graminfobeforenumber", false); // Setup text properties for any numbering int wsEng = m_cache.WritingSystemFactory.GetWsFromStr(strEng); ITsTextProps ttpNum = null; var fDelayNumber = false; if (fNumber) { ttpNum = SetNumberTextProperties(wsEng, listDelimitNode); fDelayNumber = XmlUtils.GetOptionalBooleanAttributeValue(specialAttrsNode, "numdelay", false); } // A vector may be conditionally configured to display its objects as separate paragraphs // in dictionary (document) configuration. See LT-9667. var fShowAsParagraphsInInnerPile = XmlUtils.GetOptionalBooleanAttributeValue(listDelimitNode, "showasindentedpara", false); // We have (this is probably bad) two ways to do this. The better one is setting the flowType to divInPara. // When we do this for a vector, and configure properties that require us to insert numbering and so forth, // we currently force a paragraph for each item. It's too hard otherwise to get the numbers etc. into the paragraph. // This means that the X_AsPara layout which the configure dialog causes to be invoked when setting up sense-as-para // has to be configured NOT to make a paragraph. It also means we can't readily configure a view that has more than one // paragraph, except when doing another layer of inserting paragraphs into what is usually a single one. I don't like // this much but it does what we need for now and making it better looks very messy. var fShowAsParagraphsInDivInPara = XmlUtils.GetOptionalAttributeValue(listDelimitNode, "flowType", null) == "divInPara"; ITsString tssBefore = null; string sParaStyle = null; if (fShowAsParagraphsInInnerPile && chvo > 0) { sParaStyle = XmlUtils.GetOptionalAttributeValue(listDelimitNode, "style"); tssBefore = SetBeforeString(specialAttrsNode, listDelimitNode); // We need a line break here to force the inner pile of paragraphs to begin at // the margin, rather than somewhere in the middle of the line. m_vwEnv.AddString(m_cache.TsStrFactory.MakeString(StringUtils.kChHardLB.ToString(), m_cache.ServiceLocator.WritingSystems.DefaultAnalysisWritingSystem.Handle)); m_vwEnv.OpenInnerPile(); } else if (fShowAsParagraphsInDivInPara) { sParaStyle = XmlUtils.GetOptionalAttributeValue(listDelimitNode, "parastyle", ""); } // Setup and run actual internal vector loop var tsf = m_cache.TsStrFactory; var xattrSeparator = listDelimitNode.Attributes["sep"]; var fFirst = true; // May actually mean first non-empty. for (var ihvo = 0; ihvo < chvo; ++ihvo) { if (IsExcluded(exclude, ihvo, rghvo)) { continue; } if (fCheckForEmptyItems && IsItemEmpty(rghvo[ihvo], childFrag)) { continue; } if (fShowAsParagraphsInInnerPile || fShowAsParagraphsInDivInPara) { SetupParagraph(sParaStyle, (fFirst ? tssBefore : null), listDelimitNode); } // This needs to happen AFTER we wet up the paragraph that we want it to be part of // and any 'before' stuff that goes ahead of the whole sequence, but BEFORE we add any other stuff to the para. if (fFirst && fNumber && fSingleGramInfoFirst) { var fAllMsaSame = SetAllMsaSameFlag(chvo, rghvo); if (fAllMsaSame) { DisplayFirstChildPOS(rghvo[0], childFrag); } // Exactly if we put out the grammatical info at the start, we need to NOT put it out // as part of each item. Note that we must not set this flag before we put out the one-and-only // gram info, or that will be suppressed too! m_viewConstructor.ShouldIgnoreGramInfo = fAllMsaSame; } if (!fShowAsParagraphsInInnerPile && !fShowAsParagraphsInDivInPara) { AddSeparatorIfNeeded(fFirst, xattrSeparator, listDelimitNode, wsEng); } // add the numbering if needed. if (fNumber) { var sTag = CalculateAndFormatSenseLabel(rghvo, ihvo, xaNum); ITsStrBldr tsb = tsf.GetBldr(); tsb.Replace(0, 0, sTag, ttpNum); ITsString tss = tsb.GetString(); m_numberPartRef = listDelimitNode; AddNumberingNowOrDelayed(fDelayNumber, tss, out tssDelayedNumber); } // add the object. Debug.Assert(ihvo < rghvo.Length); m_vwEnv.AddObj(rghvo[ihvo], m_viewConstructor, childFrag); // Close Paragraph if displaying paragraphs if (fShowAsParagraphsInInnerPile || fShowAsParagraphsInDivInPara) { m_vwEnv.CloseParagraph(); } fFirst = false; if (fFirstOnly) { break; } } // end of sequence 'for' loop // Close Inner Pile if displaying paragraphs if (fShowAsParagraphsInInnerPile && chvo > 0) { m_vwEnv.CloseInnerPile(); } // Reset the flag for ignoring grammatical information after the first if it was set // earlier in this method. if (fSingleGramInfoFirst) { m_viewConstructor.ShouldIgnoreGramInfo = false; } // Reset the flag for delaying displaying a number. if (m_viewConstructor.DelayNumFlag && m_hvo == m_hvoDelayedNumber) { m_viewConstructor.DelayNumFlag = false; tssDelayedNumber = null; } // end of Display method }
public override void Display(IVwEnv vwenv, int hvo, int frag) { switch (frag) { case kfragContext: var ctxtOrVar = m_cache.ServiceLocator.GetInstance<IPhContextOrVarRepository>().GetObject(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); var outerObj = m_cache.ServiceLocator.GetObject(outerHvo); isOuterIterCtxt = outerObj.ClassID == PhIterationContextTags.kClassId; } switch (ctxtOrVar.ClassID) { case PhSequenceContextTags.kClassId: var seqCtxt = ctxtOrVar as IPhSequenceContext; if (seqCtxt.MembersRS.Count > 0) { vwenv.AddObjVecItems(PhSequenceContextTags.kflidMembers, this, kfragContext); } else { OpenContextPile(vwenv, false); vwenv.Props = m_bracketProps; vwenv.AddProp(PhSequenceContextTags.kflidMembers, this, kfragEmpty); CloseContextPile(vwenv, false); } break; case PhSimpleContextNCTags.kClassId: var ncCtxt = ctxtOrVar as IPhSimpleContextNC; if (ncCtxt.FeatureStructureRA != null && ncCtxt.FeatureStructureRA.ClassID == PhNCFeaturesTags.kClassId) { // Natural class simple context with a feature-based natural class var natClass = ncCtxt.FeatureStructureRA as IPhNCFeatures; int numLines = GetNumLines(ncCtxt); if (numLines == 0) { if (!isOuterIterCtxt) OpenContextPile(vwenv); vwenv.AddProp(ktagInnerNonBoundary, this, kfragLeftBracket); vwenv.AddProp(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.Text == "C" || natClass.Abbreviation.AnalysisDefaultWritingSystem.Text == "V") { vwenv.AddObjProp(PhSimpleContextNCTags.kflidFeatureStructure, this, kfragNC); } else { if (natClass.FeaturesOA != null && natClass.FeaturesOA.FeatureSpecsOC.Count > 0) vwenv.AddObjProp(PhSimpleContextNCTags.kflidFeatureStructure, this, kfragFeatNC); else if (ncCtxt.PlusConstrRS.Count > 0) vwenv.AddObjVecItems(PhSimpleContextNCTags.kflidPlusConstr, this, kfragPlusVariable); else vwenv.AddObjVecItems(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(PhSimpleContextNCTags.kflidFeatureStructure, this, kfragFeatNC); vwenv.AddObjVecItems(PhSimpleContextNCTags.kflidPlusConstr, this, kfragPlusVariable); vwenv.AddObjVecItems(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.FeatureStructureRA != null) vwenv.AddObjProp(PhSimpleContextNCTags.kflidFeatureStructure, this, kfragNC); else vwenv.AddProp(PhSimpleContextNCTags.kflidFeatureStructure, this, kfragQuestions); vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightBracket); if (!isOuterIterCtxt) CloseContextPile(vwenv); } break; case PhIterationContextTags.kClassId: IPhIterationContext iterCtxt = ctxtOrVar as IPhIterationContext; if (iterCtxt.MemberRA != null) { int numLines = GetNumLines(iterCtxt.MemberRA as IPhSimpleContext); if (numLines > 1) { vwenv.AddObjProp(PhIterationContextTags.kflidMember, this, kfragContext); DisplayIterCtxt(iterCtxt, numLines, vwenv); } else { OpenContextPile(vwenv); if (iterCtxt.MemberRA.ClassID == PhSimpleContextNCTags.kClassId) { vwenv.AddObjProp(PhIterationContextTags.kflidMember, this, kfragContext); } else { vwenv.AddProp(ktagInnerNonBoundary, this, kfragLeftParen); vwenv.AddObjProp(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(PhIterationContextTags.kflidMember, this, kfragQuestions); CloseContextPile(vwenv); } break; case PhSimpleContextSegTags.kClassId: if (!isOuterIterCtxt) OpenContextPile(vwenv); var segCtxt = ctxtOrVar as IPhSimpleContextSeg; if (segCtxt.FeatureStructureRA != null) vwenv.AddObjProp(PhSimpleContextSegTags.kflidFeatureStructure, this, kfragTerminalUnit); else vwenv.AddProp(PhSimpleContextSegTags.kflidFeatureStructure, this, kfragQuestions); if (!isOuterIterCtxt) CloseContextPile(vwenv); break; case PhSimpleContextBdryTags.kClassId: if (!isOuterIterCtxt) OpenContextPile(vwenv); var bdryCtxt = ctxtOrVar as IPhSimpleContextBdry; if (bdryCtxt.FeatureStructureRA != null) vwenv.AddObjProp(PhSimpleContextBdryTags.kflidFeatureStructure, this, kfragTerminalUnit); else vwenv.AddProp(PhSimpleContextBdryTags.kflidFeatureStructure, this, kfragQuestions); if (!isOuterIterCtxt) CloseContextPile(vwenv); break; case PhVariableTags.kClassId: OpenContextPile(vwenv); vwenv.AddProp(ktagXVariable, this, kfragXVariable); CloseContextPile(vwenv); break; } break; case kfragNC: int ncWs = WritingSystemServices.ActualWs(m_cache, WritingSystemServices.kwsFirstAnal, hvo, PhNaturalClassTags.kflidAbbreviation); if (ncWs != 0) { vwenv.AddStringAltMember(PhNaturalClassTags.kflidAbbreviation, ncWs, this); } else { ncWs = WritingSystemServices.ActualWs(m_cache, WritingSystemServices.kwsFirstAnal, hvo, PhNaturalClassTags.kflidName); if (ncWs != 0) vwenv.AddStringAltMember(PhNaturalClassTags.kflidName, ncWs, this); else vwenv.AddProp(PhNaturalClassTags.kflidAbbreviation, this, kfragQuestions); } break; case kfragTerminalUnit: int tuWs = WritingSystemServices.ActualWs(m_cache, WritingSystemServices.kwsFirstVern, hvo, PhTerminalUnitTags.kflidName); if (tuWs != 0) vwenv.AddStringAltMember(PhTerminalUnitTags.kflidName, tuWs, this); else vwenv.AddProp(PhTerminalUnitTags.kflidName, this, kfragQuestions); break; case kfragFeatNC: vwenv.AddObjProp(PhNCFeaturesTags.kflidFeatures, this, kfragFeats); break; case kfragFeats: vwenv.AddObjVecItems(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; } }
/// <summary> /// Displays a MorphBundle, setting the colors of its parts. /// </summary> /// <param name="vwenv"></param> /// <param name="hvo">WfiMorphBundle</param> private void DisplayMorphBundle(IVwEnv vwenv, int hvo) { IWfiMorphBundle wmb = null; if (hvo != 0) wmb = m_wmbRepository.GetObject(hvo); vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, 10000); vwenv.OpenInnerPile(); int first = m_lineChoices.FirstMorphemeIndex; int last = m_lineChoices.LastMorphemeIndex; IMoForm mf = null; if (wmb != null) mf = wmb.MorphRA; if (vwenv is CollectorEnv && mf != null) { // Collectors are given an extra initial chance to 'collect' the morph type, if any. vwenv.AddObjProp(WfiMorphBundleTags.kflidMorph, this, kfragMorphType); } for (int i = first; i <= last; i++) { InterlinLineSpec spec = m_lineChoices[i]; SetColor(vwenv, LabelRGBFor(spec)); switch (spec.Flid) { case InterlinLineChoices.kflidMorphemes: if (wmb == null) { vwenv.AddString(m_tssMissingMorph); } else if (mf == null) { // displaying morphemes should be int ws = 0; if (wmb.MorphRA != null) { Debug.Assert(spec.StringFlid == MoFormTags.kflidForm); ws = GetRealWsOrBestWsForContext(wmb.MorphRA.Hvo, spec); } // If no morph, use the form of the morph bundle (and the entry is of // course missing) if (ws == 0) { ws = WritingSystemServices.ActualWs(m_cache, spec.WritingSystem, wmb.Hvo, WfiMorphBundleTags.kflidForm); } vwenv.AddStringAltMember( WfiMorphBundleTags.kflidForm, ws, this); } else { // Got a morph, show it. vwenv.AddObjProp(WfiMorphBundleTags.kflidMorph, this, kfragMorphFormChoices + i); // And the LexEntry line. } break; case InterlinLineChoices.kflidLexEntries: if (mf == null) { if (hvo != 0) vwenv.NoteDependency(new int[] { hvo }, new int[] { WfiMorphBundleTags.kflidMorph }, 1); vwenv.AddString(m_tssMissingEntry); } else { int ws = GetRealWsOrBestWsForContext(mf.Hvo, spec); if (ws == 0) ws = spec.WritingSystem; LexEntryVc vcEntry = new LexEntryVc(m_cache); vcEntry.WritingSystemCode = ws; vwenv.AddObj(hvo, vcEntry, LexEntryVc.kfragEntryAndVariant); } break; case InterlinLineChoices.kflidLexGloss: int flid = 0; if (wmb != null) { vwenv.NoteDependency(new[] { wmb.Hvo }, new[] { WfiMorphBundleTags.kflidMorph }, 1); vwenv.NoteDependency(new[] { wmb.Hvo }, new[] { WfiMorphBundleTags.kflidInflType }, 1); vwenv.NoteDependency(new[] { hvo }, new[] { WfiMorphBundleTags.kflidSense }, 1); if (wmb.SenseRA == null) { if (ShowDefaultSense && wmb.DefaultSense != null && UsingGuess) { flid = wmb.Cache.MetaDataCacheAccessor.GetFieldId2(WfiMorphBundleTags.kClassId, "DefaultSense", false); } } else { flid = WfiMorphBundleTags.kflidSense; if (wmb.MorphRA != null && DisplayLexGlossWithInflType(vwenv, wmb.MorphRA.Owner as ILexEntry, wmb.SenseRA, spec, wmb.InflTypeRA)) { break; } } } if (flid == 0) vwenv.AddString(m_tssMissingSense); else vwenv.AddObjProp(flid, this, kfragLineChoices + i); break; case InterlinLineChoices.kflidLexPos: // LexPOS line: int hvoMsa = 0; if (wmb != null && wmb.MsaRA != null) hvoMsa = wmb.MsaRA.Hvo; if (hvoMsa == 0) { if (hvo != 0) vwenv.NoteDependency(new int[] { hvo }, new int[] { WfiMorphBundleTags.kflidMsa }, 1); vwenv.AddString(m_tssMissingMsa); } else { // Use a special view constructor that knows how to display the // interlinear view of whatever kind of MSA it is. // Enhance JohnT: ideally we would have one of these VCs for each writing system, // perhaps stored in the InterlinLineSpec. Currently displaying multiple Wss of LexPos // is not useful, though it is possible. // Enhancement RickM: we set the m_msaVc.DefaultWs to the selected writing system // of each LexPos line in interlinear. This is used extract the LexPos abbreviation // for the specific writing system. m_msaVc.DefaultWs = spec.WritingSystem; vwenv.AddObjProp(WfiMorphBundleTags.kflidMsa, m_msaVc, (int)VcFrags.kfragInterlinearAbbr); } break; } } vwenv.CloseInnerPile(); }
/// <summary> /// Add a segment number appropriate to the current segment being displayed. /// (See LT-1236.) /// </summary> /// <param name="vwenv"></param> /// <param name="hvo"></param> private void AddSegmentReference(IVwEnv vwenv, int hvo) { ITsString tssSegNum; StringBuilder sbSegNum = new StringBuilder(); int flid = 0; int hvoStPara = m_cache.GetObjProperty(hvo, (int)CmBaseAnnotation.CmBaseAnnotationTags.kflidBeginObject); if (hvoStPara != 0) { ISilDataAccess sda = vwenv.DataAccess; int cseg = sda.get_VecSize(hvoStPara, ktagParaSegments); int idxSeg = sda.GetObjIndex(hvoStPara, ktagParaSegments, hvo); int hvoStText = m_cache.GetOwnerOfObject(hvoStPara); if (hvoStText != 0) flid = m_cache.GetOwningFlidOfObject(hvoStText); if (flid == (int)ScrSection.ScrSectionTags.kflidContent) { if (m_scrPara == null || m_scrPara.Hvo != hvoStPara) m_scrPara = new ScrTxtPara(m_cache, hvoStPara); // With null book name and trimmed it should have just chapter:v{a,b}. // The {a,b} above would not be the segment identifiers we add for multiple segments in // a verse, but the letters indicating that the verse label is for only part of the verse. // There is therefore a pathological case where, say, verse 4a as labeled in the main text // gets another letter because 4a has multiple segments 4aa, 4ab, etc. string chapRef = AnnotationRefHandler.FullScrRef(m_scrPara, hvo, "").Trim(); sbSegNum.Append(chapRef + AnnotationRefHandler.VerseSegLabel(m_scrPara, idxSeg, ktagParaSegments)); } else { int idxPara = m_cache.GetObjIndex(hvoStText, (int)StText.StTextTags.kflidParagraphs, hvoStPara); if (idxPara >= 0) { sbSegNum.AppendFormat("{0}", idxPara + 1); if (idxSeg >= 0 && cseg > 1) sbSegNum.AppendFormat(".{0}", idxSeg + 1); } } } ITsStrBldr tsbSegNum = m_tsf.GetBldr(); tsbSegNum.ReplaceTsString(0, tsbSegNum.Length, m_cache.MakeUserTss(sbSegNum.ToString())); tsbSegNum.SetIntPropValues(0, tsbSegNum.Length, (int)FwTextPropType.ktptBold, (int)FwTextPropVar.ktpvEnum, (int)FwTextToggleVal.kttvForceOn); tssSegNum = tsbSegNum.GetString(); vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, 10000); vwenv.set_IntProperty((int)FwTextPropType.ktptForeColor, (int)FwTextPropVar.ktpvDefault, (int)CmObjectUi.RGB(SystemColors.ControlText)); try { m_fIsAddingSegmentReference = true; vwenv.OpenInnerPile(); vwenv.AddString(tssSegNum); vwenv.CloseInnerPile(); } finally { m_fIsAddingSegmentReference = false; } }
/// <summary> /// Add the pile of labels used to identify the lines in interlinear text. /// </summary> /// <param name="vwenv"></param> /// <param name="tsf"></param> /// <param name="cache"></param> /// <param name="wsList">Null if don't want multiple writing systems.</param> /// <param name="fShowMutlilingGlosses"></param> public void AddLabelPile(IVwEnv vwenv, ITsStrFactory tsf, FdoCache cache, bool fWantMultipleSenseGloss, bool fShowMorphemes) { CheckDisposed(); int wsUI = cache.DefaultUserWs; var spaceStr = TsStringUtils.MakeTss(" ", wsUI); vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, 10000); vwenv.set_IntProperty((int)FwTextPropType.ktptBold, (int)FwTextPropVar.ktpvEnum, (int)FwTextToggleVal.kttvForceOn); vwenv.set_IntProperty((int)FwTextPropType.ktptMarginBottom, (int)FwTextPropVar.ktpvMilliPoint, 5000); // default spacing is fine for all embedded paragraphs. vwenv.OpenInnerPile(); for (var i = 0; i < m_lineChoices.Count; i++) { InterlinLineSpec spec = m_lineChoices[i]; if (!spec.WordLevel) break; SetColor(vwenv, LabelRGBFor(spec)); ITsString tss = MakeUiElementString(m_lineChoices.LabelFor(spec.Flid), wsUI, null); var bldr = tss.GetBldr(); if (m_lineChoices.RepetitionsOfFlid(spec.Flid) > 1) { bldr.Append(spaceStr); bldr.Append(spec.WsLabel(cache)); AddLineIndexProperty(bldr, i); // Enhance GJM: Might be able to do without paragraph now? vwenv.OpenParagraph(); vwenv.AddString(bldr.GetString()); vwenv.CloseParagraph(); } else { AddLineIndexProperty(bldr, i); vwenv.AddString(bldr.GetString()); } } vwenv.CloseInnerPile(); }
protected void CloseSingleLinePile(IVwEnv vwenv, bool addBoundary) { if (addBoundary) { vwenv.Props = m_bracketProps; vwenv.AddProp(ktagRightBoundary, this, kfragZeroWidthSpace); } vwenv.CloseParagraph(); vwenv.CloseInnerPile(); }
/// <summary> /// Displays Analysis using DisplayWordBundleMethod and closes the views Inner Pile. /// </summary> /// <param name="vwenv"></param> /// <param name="analysisOccurrence"></param> /// <param name="showMultipleAnalyses">Tells DisplayWordBundleMethod whether or not to show /// the colored highlighting if a word has multiple analyses</param> protected void DisplayAnalysisAndCloseInnerPile(IVwEnv vwenv, AnalysisOccurrence analysisOccurrence, bool showMultipleAnalyses) { // if it is just a punctuation annotation, we just insert the form. var analysis = analysisOccurrence.Analysis; if (analysis is IPunctuationForm) { vwenv.AddStringProp(PunctuationFormTags.kflidForm, this); } else { // It's a full wordform-possessing annotation, display the full bundle. new DisplayWordBundleMethod(vwenv, analysisOccurrence, this).Run(showMultipleAnalyses); } AddExtraBundleRows(vwenv, analysisOccurrence); vwenv.CloseInnerPile(); }
public override void Display(IVwEnv vwenv, int hvo, int frag) { CheckDisposed(); if (hvo == 0) return; // Can't do anything without an hvo (except crash -- see LT-9348). #if DEBUG //TimeRecorder.Begin("Display"); #endif switch (frag) { case kfragText: // The whole text, root object for the InterlinDocChild. vwenv.AddObjProp((int)Text.TextTags.kflidContents, this, kfragStText); break; // case kfragTxtSection: // obsolete // // Enhance JohnT: possibly some extra space, bold the heading, or whatever? // vwenv.AddObjProp((int)TxtSection.TxtSectionTags.kflidHeading, this, kfragStText); // vwenv.AddObjProp((int)TxtSection.TxtSectionTags.kflidContents, this, kfragStText); // vwenv.AddLazyVecItems((int)TxtSection.TxtSectionTags.kflidSubsections, this, kfragTxtSection); // break; case kfragStText: // new root object for InterlinDocChild. SetupRealVernWsForDisplay(m_cache.LangProject.ActualWs(LangProject.kwsVernInParagraph, hvo, (int)StText.StTextTags.kflidParagraphs)); vwenv.AddLazyVecItems((int)StText.StTextTags.kflidParagraphs, this, kfragInterlinPara); break; case kfragInterlinPara: // Whole StTxtPara. This can be the root fragment in DE view. if (vwenv.DataAccess.get_VecSize(hvo, ktagParaSegments) == 0) { vwenv.NoteDependency(new int[] {hvo}, new int[] {ktagParaSegments}, 1); vwenv.AddString(m_tssEmptyPara); } else { PreferredVernWs = m_cache.LangProject.ActualWs(LangProject.kwsVernInParagraph, hvo, ktagParaSegments); // Include the plain text version of the paragraph? vwenv.AddLazyVecItems(ktagParaSegments, this, kfragParaSegment); } break; case kfragParaSegment: // Don't put anything in this segment if it is a 'label' segment (typically containing a verse // number for TE). CmBaseAnnotation seg = CmObject.CreateFromDBObject(m_cache, hvo, false) as CmBaseAnnotation; StTxtPara para = seg.BeginObjectRA as StTxtPara; if (SegmentBreaker.HasLabelText(para.Contents.UnderlyingTsString, seg.BeginOffset, seg.EndOffset)) break; // This puts ten points between segments. There's always 5 points below each line of interlinear; // if there are no freeform annotations another 5 points makes 10 between segments. // If there are freeforms, we need the full 10 points after the last of them. int cfreeform = vwenv.DataAccess.get_VecSize(hvo, ktagSegFF); vwenv.set_IntProperty((int)FwTextPropType.ktptMarginBottom, (int)FwTextPropVar.ktpvMilliPoint, cfreeform == 0 ? 5000 : 10000); vwenv.OpenDiv(); // Enhance JohnT: determine what the overall direction of the paragraph should // be and set it. if (m_mpBundleHeight == 0) { // First time...figure it out. int dmpx, dmpyAnal, dmpyVern; vwenv.get_StringWidth(m_tssEmptyAnalysis, null, out dmpx, out dmpyAnal); vwenv.get_StringWidth(m_tssEmptyVern, null, out dmpx, out dmpyVern); m_mpBundleHeight = dmpyAnal * 4 + dmpyVern * 3; } // The interlinear bundles are not editable. vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvEnum, (int)TptEditable.ktptNotEditable); if (m_fRtl) { vwenv.set_IntProperty((int)FwTextPropType.ktptRightToLeft, (int)FwTextPropVar.ktpvEnum, (int)FwTextToggleVal.kttvForceOn); vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int) FwTextAlign.ktalRight); } vwenv.set_IntProperty((int)FwTextPropType.ktptSpellCheck, (int)FwTextPropVar.ktpvEnum, (int)SpellingModes.ksmDoNotCheck); vwenv.OpenParagraph(); AddSegmentReference(vwenv, hvo); // Calculate and display the segment reference. AddLabelPile(vwenv, m_tsf, m_cache, true, m_fShowMorphBundles); vwenv.AddObjVecItems(ktagSegmentForms, this, kfragBundle); // JohnT, 1 Feb 2008. Took this out as I can see no reason for it; AddObjVecItems handles // the dependency already. Adding it just means that any change to the forms list // regenerates a higher level than needed, which contributes to a great deal of scrolling // and flashing (LT-7470). // Originally added by Eric in revision 72 on the trunk as part of handling phrases. // Eric can't see any reason we need it now, either. If you find a need to re-insert it, // please document carefully the reasons it is needed and what bad consequences follow // from removing it. //vwenv.NoteDependency(new int[] { hvo }, new int[] { ktagSegmentForms }, 1); vwenv.CloseParagraph(); // This puts 3 points of margin on the first FF annotation, if any. vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTop, (int)FwTextPropVar.ktpvMilliPoint, 0); // 3000 vwenv.AddObjVec(ktagSegFF, this, kfragSegFf); vwenv.CloseDiv(); break; case kfragBundle: // One annotated word bundle; hvo is CmBaseAnnotation. // checking AllowLayout (especially in context of Undo/Redo make/break phrase) // helps prevent us from rebuilding the display until we've finished // reconstructing the data and cache. Otherwise we can crash. if (m_rootsite != null && !m_rootsite.AllowLayout) return; // set the display WS here even though it is set in the paragraph frag, since this frag might // get called on its own during a prop update int paraHvo = m_cache.GetObjProperty(hvo, (int)CmBaseAnnotation.CmBaseAnnotationTags.kflidBeginObject); if (paraHvo != 0) PreferredVernWs = m_cache.LangProject.ActualWs(LangProject.kwsVernInParagraph, paraHvo, ktagParaSegments); SetupForTwfic(hvo); // Give whatever box we make 10 points of separation from whatever follows. vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, 10000); if (hvo == m_hvoSandboxAnnotation) { // Leave room for the Sandbox instead of displaying the internlinear data. // The first argument makes it invisible in case a little bit of it shows around // the sandbox. // The last argument puts the 'Baseline' of the sandbox (which aligns with the base of the // first line of text) an appropriate distance from the top of the Sandbox. This aligns it's // top line of text properly. // Enhance JohnT: 90% of font height is not always exactly right, but it's the closest // I can get wihtout a new API to get the exact ascent of the font. int dympBaseline = SIL.FieldWorks.Common.Widgets.FontHeightAdjuster.GetFontHeightForStyle("Normal", m_stylesheet, m_wsCurrentTwfic, m_cache.LanguageWritingSystemFactoryAccessor) * 9 / 10; vwenv.AddSimpleRect(0xC0000000, // FwTextColor.kclrTransparent won't convert to uint SandboxSize.Width, SandboxSize.Height, -(SandboxSize.Height - dympBaseline)); SetupForTwfic(0); break; } // Make an 'inner pile' to contain the wordform and annotations. // 10 points below also helps space out the paragraph. vwenv.set_IntProperty((int)FwTextPropType.ktptMarginBottom, (int)FwTextPropVar.ktpvMilliPoint, 5000); vwenv.OpenInnerPile(); // Get the instanceOf property of the annotation and see whether it exists. If not it is // just a punctuation annotation, and we just insert the form. vwenv.NoteDependency(new int[] { hvo }, new int[] { InterlinDocChild.TagAnalysis }, 1); int hvoInstanceOf = vwenv.DataAccess.get_ObjectProp(hvo, InterlinDocChild.TagAnalysis); // Treat a non-vernacular word as unconnected to any kind of analysis. if (m_wsCurrentTwfic != m_wsVernForDisplay || !m_vernWss.Contains(m_wsCurrentTwfic)) { // Cf CanBeAnalyzed method. hvoInstanceOf = 0; } if (hvoInstanceOf == 0) { vwenv.AddStringProp(m_flidStringValue, this); } else { // It's a full Twfic annotation, display the full bundle. vwenv.AddObjProp(InterlinDocChild.TagAnalysis, this, kfragTwficAnalysis); } AddExtraTwficRows(vwenv, hvo); //vwenv.AddObjProp(ktagTwficDefault, this, kfragTwficAnalysis); vwenv.CloseInnerPile(); // revert back to the paragraph vernWs. SetupForTwfic(0); break; case kfragTwficAnalysis: new DisplayWordBundleMethod(vwenv, hvo, this, tagRealForm).Run(); break; case kfragIsolatedAnalysis: // This one is used for an isolated HVO that is surely an analyis. { // In some ways this is a simplified kfragTwficAnalysis. vwenv.AddObj(m_cache.GetOwnerOfObject(hvo), this, kfragWordformForm); if (m_fShowMorphBundles) vwenv.AddObj(hvo, this, kfragAnalysisMorphs); int chvoGlosses = m_cache.GetVectorSize(hvo, (int)WfiAnalysis.WfiAnalysisTags.kflidMeanings); for (int i = 0; i < m_WsList.AnalysisWsIds.Length; ++i) { SetColor(vwenv, LabelRGBFor(m_lineChoices.IndexOf(InterlinLineChoices.kflidWordGloss, m_WsList.AnalysisWsIds[i]))); if (chvoGlosses == 0) { // There are no glosses, display something indicating it is missing. vwenv.AddProp(ktagAnalysisMissingGloss, this, kfragAnalysisMissingGloss); } else { vwenv.AddObjVec((int)WfiAnalysis.WfiAnalysisTags.kflidMeanings, this, kfragWordGlossWs + i); } } AddAnalysisPos(vwenv, hvo, -1); } break; case kfragAnalysisMorphs: int cmorphs = m_cache.GetVectorSize(hvo, (int)WfiAnalysis.WfiAnalysisTags.kflidMorphBundles); if (!m_fHaveOpenedParagraph) vwenv.OpenParagraph(); if (cmorphs == 0) { DisplayMorphBundle(vwenv, 0); } else { vwenv.AddObjVecItems((int)WfiAnalysis.WfiAnalysisTags.kflidMorphBundles, this, kfragMorphBundle); } if (!m_fHaveOpenedParagraph) vwenv.CloseParagraph(); break; case kfragWordGloss: // displaying forms of a known WfiGloss. foreach (int wsId in m_WsList.AnalysisWsIds) { SetColor(vwenv, LabelRGBFor(m_lineChoices.IndexOf(InterlinLineChoices.kflidWordGloss, wsId))); vwenv.AddStringAltMember((int)WfiGloss.WfiGlossTags.kflidForm, wsId, this); } break; case kfragMorphType: // for export only at present, display the vwenv.AddObjProp((int)MoForm.MoFormTags.kflidMorphType, this, kfragPossibiltyAnalysisName); break; case kfragPossibiltyAnalysisName: vwenv.AddStringAltMember((int)CmPossibility.CmPossibilityTags.kflidName, m_cache.DefaultAnalWs, this); break; case kfragMorphBundle: // the lines of morpheme information (hvo is a WfiMorphBundle) // Make an 'inner pile' to contain the bundle of morph information. // Give it 10 points of separation from whatever follows. DisplayMorphBundle(vwenv, hvo); break; case kfragSingleInterlinearAnalysisWithLabels: /* // This puts ten points between segments. There's always 5 points below each line of interlinear; // if there are no freeform annotations another 5 points makes 10 between segments. // If there are freeforms, we need the full 10 points after the last of them. int cfreeform = vwenv.get_DataAccess().get_VecSize(hvo, ktagSegFF); vwenv.set_IntProperty((int)FwTextPropType.ktptMarginBottom, (int)FwTextPropVar.ktpvMilliPoint, cfreeform == 0 ? 5000 : 10000); */ vwenv.OpenDiv(); DisplaySingleInterlinearAnalysisWithLabels(vwenv, hvo); vwenv.CloseDiv(); break; // This frag is used to display a single interlin analysis that is always left-aligned, even for RTL languages case kfragSingleInterlinearAnalysisWithLabelsLeftAlign: vwenv.OpenDiv(); vwenv.set_IntProperty((int)FwTextPropType.ktptPadLeading, (int)FwTextPropVar.ktpvMilliPoint, m_leftPadding); vwenv.OpenParagraph(); vwenv.OpenInnerPile(); DisplaySingleInterlinearAnalysisWithLabels(vwenv, hvo); vwenv.CloseInnerPile(); vwenv.CloseParagraph(); vwenv.CloseDiv(); break; //case kfragDefaultSense: // Some default sense // // NB: If the hvo is zero, then we need to go back to the normal missing sense display, after all. // // (hvo isn't zero, even for cases where there isn't even a default value.) // if (hvo > 0) // { // // Show default sense, in some other 'guess' color. // SetGuessing(vwenv, false); // foreach (int wsId in m_WsList.AnalysisWsIds) // vwenv.AddStringAltMember((int)LexSense.LexSenseTags.kflidGloss, // wsId, this); // } // else // { // // Give up and show the missing sense row. // vwenv.AddString(m_tssMissingSense); // } // break; case kfragWordformForm: // The form of a WviWordform. vwenv.AddStringAltMember((int)WfiWordform.WfiWordformTags.kflidForm, m_wsCurrentWordBundleVern, this); break; case kfragPrefix: vwenv.AddUnicodeProp((int)MoMorphType.MoMorphTypeTags.kflidPrefix, m_wsCurrentWordBundleVern, this); break; case kfragPostfix: vwenv.AddUnicodeProp((int)MoMorphType.MoMorphTypeTags.kflidPostfix, m_wsCurrentWordBundleVern, this); break; case kfragSenseName: // The name (gloss) of a LexSense. foreach (int wsId in m_WsList.AnalysisWsIds) vwenv.AddStringAltMember((int)LexSense.LexSenseTags.kflidGloss, wsId, this); break; case kfragCategory: // the category of a WfiAnalysis, a part of speech; // display the Abbreviation property inherited from CmPossibility. foreach(int wsId in m_WsList.AnalysisWsIds) { vwenv.AddStringAltMember( (int)CmPossibility.CmPossibilityTags.kflidAbbreviation, wsId, this); } break; default: if (frag >= kfragWordGlossWs && frag < kfragWordGlossWs + m_WsList.AnalysisWsIds.Length) { // Displaying one ws of the form of a WfiGloss. int ws = m_WsList.AnalysisWsIds[frag - kfragWordGlossWs]; vwenv.AddStringAltMember((int)WfiGloss.WfiGlossTags.kflidForm, ws, this); } else if (frag >= kfragLineChoices && frag < kfragLineChoices + m_lineChoices.Count) { InterlinLineSpec spec = m_lineChoices[frag - kfragLineChoices]; int ws = GetRealWs(hvo, spec); // The wrong value can be displayed in at least the LexGloss and WordCat fields, // both of which are analysis fields (at least if vern and anal ws are the same). // See LT-8682. bool fVernWs = IsVernWs(ws, spec.WritingSystem); if (m_wsCurrentTwfic != 0 && ws == m_wsCurrentTwfic && fVernWs) { if (m_cache.MainCacheAccessor.get_IsPropInCache(m_hvoCurrentTwfic, tagRealForm, (int)CellarModuleDefns.kcptString, 0)) { // overridden. vwenv.AddString(m_cache.MainCacheAccessor.get_StringProp(m_hvoCurrentTwfic, tagRealForm)); break; } } vwenv.AddStringAltMember(spec.StringFlid, ws, this); } else if (frag >= kfragAnalysisCategoryChoices && frag < kfragAnalysisCategoryChoices + m_lineChoices.Count) { AddAnalysisPos(vwenv, hvo, frag - kfragAnalysisCategoryChoices); } else if (frag >= kfragMorphFormChoices && frag < kfragMorphFormChoices + m_lineChoices.Count) { InterlinLineSpec spec = m_lineChoices[frag - kfragMorphFormChoices]; int wsActual = GetRealWs(hvo, spec); DisplayMorphForm(vwenv, hvo, wsActual); } else if (frag >= kfragSegFfChoices && frag < kfragSegFfChoices + m_lineChoices.Count) { int[] wssAnalysis = m_lineChoices.AdjacentWssAtIndex(frag - kfragSegFfChoices); if (wssAnalysis.Length == 0) break; // This is bizarre, but for the sake of paranoia... vwenv.OpenDiv(); SetParaDirectionAndAlignment(vwenv, wssAnalysis[0]); vwenv.OpenParagraph(); int hvoType = m_cache.MainCacheAccessor.get_ObjectProp(hvo, (int) CmAnnotation.CmAnnotationTags. kflidAnnotationType); string label = ""; if (hvoType == NoteSegmentDefn) label = ITextStrings.ksNote_; else if (hvoType == FtSegmentDefn) label = ITextStrings.ksFree_; else if (hvoType == LtSegmentDefn) label = ITextStrings.ksLit_; else throw new Exception("Unexpected FF annotation type"); InterlinearExporter exporter = vwenv as InterlinearExporter; if (exporter != null) { if (hvoType == NoteSegmentDefn) exporter.FreeAnnotationType = "note"; else if (hvoType == FtSegmentDefn) exporter.FreeAnnotationType = "gls"; else if (hvoType == LtSegmentDefn) exporter.FreeAnnotationType = "lit"; } SetNoteLabelProps(vwenv); ITsStrBldr tsbLabel = m_tsf.GetBldr(); tsbLabel.ReplaceTsString(0, tsbLabel.Length, m_cache.MakeUserTss(label)); tsbLabel.SetIntPropValues(0, tsbLabel.Length, (int) FwTextPropType.ktptBold, (int) FwTextPropVar.ktpvEnum, (int) FwTextToggleVal.kttvForceOn); // REVIEW: Should we set the label to a special color as well? ITsString tssLabel = tsbLabel.GetString(); int labelWidth = 0; int labelHeight; // unused if (wssAnalysis.Length > 1) vwenv.get_StringWidth(tssLabel, null, out labelWidth, out labelHeight); if (IsWsRtl(wssAnalysis[0]) != m_fRtl) { ITsStrBldr bldr = tssLabel.GetBldr(); bldr.Replace(bldr.Length - 1, bldr.Length, null, null); ITsString tssLabelNoSpace = bldr.GetString(); // (First) analysis language is upstream; insert label at end. vwenv.AddString(GetTssDirForWs(wssAnalysis[0])); AddFreeformComment(vwenv, hvo, wssAnalysis[0], hvoType); vwenv.AddString(GetTssDirForWs(wssAnalysis[0])); if (wssAnalysis.Length != 1) { // Insert WS label for first line vwenv.AddString(m_tssDir); vwenv.AddString(m_tssSpace); vwenv.AddString(m_tssDir); SetNoteLabelProps(vwenv); vwenv.AddString(WsListManager.WsLabel(m_cache, wssAnalysis[0])); } vwenv.AddString(m_tssDir); vwenv.AddString(m_tssSpace); vwenv.AddString(m_tssDir); vwenv.AddString(tssLabelNoSpace); vwenv.AddString(m_tssDir); } else { vwenv.AddString(m_tssDir); vwenv.AddString(tssLabel); vwenv.AddString(m_tssDir); if (wssAnalysis.Length == 1) { vwenv.AddString(GetTssDirForWs(wssAnalysis[0])); AddFreeformComment(vwenv, hvo, wssAnalysis[0], hvoType); } else { SetNoteLabelProps(vwenv); vwenv.AddString(WsListManager.WsLabel(m_cache, wssAnalysis[0])); vwenv.AddString(m_tssDir); vwenv.AddString(m_tssSpace); // label width unfortunately does not include trailing space. vwenv.AddString(m_tssDir); vwenv.AddString(GetTssDirForWs(wssAnalysis[0])); AddFreeformComment(vwenv, hvo, wssAnalysis[0], hvoType); } } // Add any other lines, each in its appropriate direction. for (int i = 1; i < wssAnalysis.Length; i++) { vwenv.CloseParagraph(); // Indent subsequent paragraphs by the width of the main label. if (IsWsRtl(wssAnalysis[i]) != m_fRtl) { vwenv.set_IntProperty((int)FwTextPropType.ktptTrailingIndent, (int)FwTextPropVar.ktpvMilliPoint, labelWidth); } else { vwenv.set_IntProperty((int) FwTextPropType.ktptLeadingIndent, (int) FwTextPropVar.ktpvMilliPoint, labelWidth); } SetParaDirectionAndAlignment(vwenv, wssAnalysis[i]); vwenv.OpenParagraph(); if (IsWsRtl(wssAnalysis[i]) != m_fRtl) { // upstream...reverse everything. vwenv.AddString(GetTssDirForWs(wssAnalysis[i])); AddFreeformComment(vwenv, hvo, wssAnalysis[i], hvoType); vwenv.AddString(GetTssDirForWs(wssAnalysis[i])); vwenv.AddString(m_tssDir); vwenv.AddString(m_tssSpace); vwenv.AddString(m_tssDir); vwenv.AddString(m_tssDir); SetNoteLabelProps(vwenv); vwenv.AddString(WsListManager.WsLabel(m_cache, wssAnalysis[i])); vwenv.AddString(m_tssDir); vwenv.AddString(m_tssSpace); vwenv.AddString(m_tssDir); } else { vwenv.AddString(m_tssDir); vwenv.AddString(m_tssSpace); vwenv.AddString(m_tssDir); SetNoteLabelProps(vwenv); vwenv.AddString(WsListManager.WsLabel(m_cache, wssAnalysis[i])); vwenv.AddString(m_tssDir); vwenv.AddString(m_tssSpace); vwenv.AddString(m_tssDir); vwenv.AddString(GetTssDirForWs(wssAnalysis[i])); AddFreeformComment(vwenv, hvo, wssAnalysis[i], hvoType); } } vwenv.CloseParagraph(); vwenv.CloseDiv(); } else { throw new Exception("Bad fragment ID in InterlinVc.Display"); } break; } #if DEBUG //TimeRecorder.End("Display"); #endif }
private void DisplayMorphForm(IVwEnv vwenv, int hvo, int frag, int ws, int choiceIndex) { int hvoMorphForm = vwenv.DataAccess.get_ObjectProp(hvo, ktagSbMorphForm); // Allow editing of the morpheme breakdown line. SetColor(vwenv, m_choices.LabelRGBFor(choiceIndex)); // On this line we want an icon only for the first column (and only if it is the first // occurrence of the flid). bool fWantIcon = m_fIsMorphemeFormEditable && (frag == kfragFirstMorph) && m_choices.IsFirstOccurrenceOfFlid(choiceIndex); if (!fWantIcon) { SetIndentForMissingIcon(vwenv); } vwenv.OpenParagraph(); bool fFirstMorphLine = (m_choices.IndexOf(InterlinLineChoices.kflidMorphemes) == choiceIndex); if (fWantIcon) // Review JohnT: should we do the 'edit box' for all first columns? { AddPullDownIcon(vwenv, ktagMorphFormIcon); // Create an edit box that stays visible when the user deletes // the first morpheme (like the WordGloss box). // This is especially useful if the user wants to // delete the entire MorphForm line (cf. LT-1621). vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, kmpIconMargin); vwenv.set_IntProperty((int)FwTextPropType.ktptPadTrailing, (int)FwTextPropVar.ktpvMilliPoint, 2000); vwenv.set_IntProperty((int)FwTextPropType.ktptPadLeading, (int)FwTextPropVar.ktpvMilliPoint, 2000); vwenv.set_IntProperty((int)FwTextPropType.ktptBackColor, (int)FwTextPropVar.ktpvDefault, krgbEditable); } if (m_fIsMorphemeFormEditable) { MakeNextFlowObjectEditable(vwenv); } else { MakeNextFlowObjectReadOnly(vwenv); } vwenv.OpenInnerPile(); vwenv.OpenParagraph(); if (fFirstMorphLine) { vwenv.AddStringProp(ktagSbMorphPrefix, this); } // This is never missing, but may, or may not, be editable. vwenv.AddObjProp(ktagSbMorphForm, this, kfragNamedObjectNameChoices + choiceIndex); if (fFirstMorphLine) { vwenv.AddStringProp(ktagSbMorphPostfix, this); } // close the special edit box we opened for the first morpheme. vwenv.CloseParagraph(); vwenv.CloseInnerPile(); vwenv.CloseParagraph(); }
private void AddTableCell(IVwEnv vwenv, int hvo, int index, int hvoRoot, int icolActive, int cAdjCol, int icol) { XmlNode node = m_columns[icol - 1]; // Figure out the underlying Right-To-Left value. bool fRightToLeft = false; // look for a writing system ID. XmlAttribute xa = node.Attributes["ws"]; XmlNode xn = node; if (xa == null) xn = XmlUtils.FindNode(node, "string"); m_wsBest = 0; if (xn != null) { int hvoBest = 0; int flidBest = 0; if (LangProject.GetWsRequiresObject(xn)) { // The 'best' ws series needs the hvo and flid in order to work. // Some others (e.g., 'reversal' which require the hvo don't need a flid. hvoBest = hvo; // Wonder it isn't really the hvoRoot that is to be used. string flidname = XmlUtils.GetOptionalAttributeValue(xn, "field"); if (flidname != null) { string classname; xa = xn.Attributes["class"]; if (xa == null) { // Get it from the meta data cache. classname = m_cache.GetClassName((uint)m_cache.GetClassOfObject(hvo)); } else { classname = xa.Value; } flidBest = (int)m_mdc.GetFieldId(classname, flidname, true); } } m_wsBest = LangProject.GetWritingSystem(xn, m_cache, null, hvoBest, flidBest, m_cache.DefaultAnalWs); IWritingSystem lgWs = m_cache.LanguageWritingSystemFactoryAccessor.get_EngineOrNull(m_wsBest); if (lgWs != null) fRightToLeft = lgWs.RightToLeft; } bool fSortedFromEnd = m_xbv.ColumnSortedFromEnd(icol - cAdjCol); int tal; if (fRightToLeft) { if (fSortedFromEnd) tal = (int)FwTextAlign.ktalLeft; else tal = (int)FwTextAlign.ktalRight; } else { if (fSortedFromEnd) tal = (int)FwTextAlign.ktalRight; else tal = (int)FwTextAlign.ktalLeft; } vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, tal); bool fIsCellActive = false; if (icolActive != 0 && m_PreviewArrowPic != null) { // The display depends on which column is active and whether the current row is selected. vwenv.NoteDependency(new int[] { hvoRoot, hvo, hvo }, new int[] { ktagActiveColumn, ktagItemSelected, ktagItemEnabled }, 3); // We're doing the active column thing. if (icol == icolActive) { fIsCellActive = vwenv.DataAccess.get_IntProp(hvo, ktagItemSelected) != 0 && vwenv.DataAccess.get_IntProp(hvo, ktagItemEnabled) != 0; } } // Make a cell and embed the contents of the column node. ProcessProperties(node, vwenv); SetCellProperties(index, icol, node, hvo, vwenv, fIsCellActive); vwenv.set_IntProperty((int)FwTextPropType.ktptPadTop, (int)FwTextPropVar.ktpvMilliPoint, 1607); vwenv.OpenTableCell(1, 1); vwenv.set_IntProperty((int)FwTextPropType.ktptPadTrailing, (int)FwTextPropVar.ktpvMilliPoint, 1607); vwenv.set_IntProperty((int)FwTextPropType.ktptPadLeading, (int)FwTextPropVar.ktpvMilliPoint, 1607); if (node.Name == "column") { // Paragraph directionality must be set before the paragraph is opened. vwenv.set_IntProperty((int)FwTextPropType.ktptRightToLeft, (int)FwTextPropVar.ktpvEnum, IsWritingSystemRTL(node) ? -1 : 0); } // According to LT-8947, in bulk edit preview mode, we want to try to show the // original cell contents on the same line with the preview arrow and the new cell contents. // to accomplish this, we use 3 InnerPiles in a paragraph // to try to keep them on the same line (or wrap otherwise). // NOTE: the bottom two inner piles will only be present if fIsCellActive is true. // // <Paragraph> // <InnerPile> // <paragraph> Original cell contents </paragraph> // </InnerPile> // <InnerPile> // <paragraph> Arrow Picture </paragraph> // </InnerPile> // <InnerPile> // <paragraph> Alternate cell contents </paragraph> // </InnerPile> // </Paragraph> // vwenv.OpenParagraph(); // <Paragraph> bool multiPara = XmlUtils.GetOptionalBooleanAttributeValue(node, "multipara", false); vwenv.OpenInnerPile(); // <InnerPile> // if the multi-para attribute is not specified, create a paragraph to wrap the cell contents. bool fParaOpened = false; if (!multiPara) { vwenv.OpenParagraph(); // <paragraph> fParaOpened = true; } if (m_sortItemProvider == null) { try { if (node.Name == "column") { SetForcedWs(node); } XmlNode nodeToProcess = GetColumnNode(node, hvo, m_cache.MainCacheAccessor, m_layouts); ProcessChildren(nodeToProcess, vwenv, hvo, null); } finally { // reset the ws for next column in the row. WsForce = 0; } } else { int level = vwenv.EmbeddingLevel; int hvoDum, tag, ihvo; vwenv.GetOuterObject(level - 2, out hvoDum, out tag, out ihvo); Debug.Assert(tag == m_fakeFlid); ManyOnePathSortItem item = m_sortItemProvider.SortItemAt(ihvo); if (item != null) DisplayCell(item, node, hvo, vwenv); // (Original) cell contents } if (fParaOpened) { vwenv.CloseParagraph(); // (Original) cell contents </paragraph> fParaOpened = false; } vwenv.CloseInnerPile(); // </InnerPile> if (fIsCellActive) AddPreviewPiles(vwenv, node); vwenv.CloseParagraph(); // </Paragraph> vwenv.CloseTableCell(); m_wsBest = 0; }
private void DisplayWordGloss(IVwEnv vwenv, int hvo, int ws, int choiceIndex) { // Count how many glosses there are for the current analysis: int cGlosses = 0; // Find a wfi analysis (existing or guess) to determine whether to provide an icon for selecting // multiple word glosses for IhWordGloss.SetupCombo (cf. LT-1428) IWfiAnalysis wa = m_sandbox.GetWfiAnalysisInUse(); if (wa != null) cGlosses = wa.MeaningsOC.Count; SetColor(vwenv, m_choices.LabelRGBFor(choiceIndex)); // Icon only if we want icons at all (currently always true) and there is at least one WfiGloss to choose // and this is the first word gloss line. bool fWantIcon = m_fIconsForAnalysisChoices && (cGlosses > 0 || m_sandbox.ShouldAddWordGlossToLexicon) && m_choices.IsFirstOccurrenceOfFlid(choiceIndex); // If there isn't going to be an icon, add an indent. if (!fWantIcon) { SetIndentForMissingIcon(vwenv); } vwenv.OpenParagraph(); if (fWantIcon) { AddPullDownIcon(vwenv, ktagWordGlossIcon); m_fIconForWordGloss = true; } else if (m_fIconForWordGloss == true && cGlosses == 0) { // reset m_fIconForWordGloss = false; } //if there is more than one gloss set the background color to give visual indication if (cGlosses > 1) { //set directly to the MultipleApproved color rather than the stored one //the state of the two could be different. SetBGColor(vwenv, InterlinVc.MultipleApprovedGuessColor); ITsStrFactory fact = TsStrFactoryClass.Create(); ITsString count = TsStringUtils.MakeTss(fact, Cache.DefaultUserWs, "" + cGlosses); //make the number black. SetColor(vwenv, 0); vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, kmpIconMargin); vwenv.AddString(count); } //Set the margin and padding values vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, kmpIconMargin); vwenv.set_IntProperty((int)FwTextPropType.ktptPadTrailing, (int)FwTextPropVar.ktpvMilliPoint, 2000); vwenv.set_IntProperty((int)FwTextPropType.ktptPadLeading, (int)FwTextPropVar.ktpvMilliPoint, 2000); SetBGColor(vwenv, krgbEditable); vwenv.set_IntProperty((int)FwTextPropType.ktptSpellCheck, (int)FwTextPropVar.ktpvEnum, (int)SpellingModes.ksmNormalCheck); vwenv.OpenInnerPile(); // Set the appropriate paragraph direction for the writing system. bool fWsRtl = m_caches.MainCache.ServiceLocator.WritingSystemManager.Get(ws).RightToLeftScript; if (fWsRtl != RightToLeft) vwenv.set_IntProperty((int)FwTextPropType.ktptRightToLeft, (int)FwTextPropVar.ktpvEnum, fWsRtl ? (int)FwTextToggleVal.kttvForceOn : (int)FwTextToggleVal.kttvOff); vwenv.AddStringAltMember(ktagSbWordGloss, ws, this); vwenv.CloseInnerPile(); vwenv.CloseParagraph(); }
/// <summary> /// Add the pile of labels used to identify the lines in interlinear text. /// </summary> /// <param name="vwenv"></param> /// <param name="tsf"></param> /// <param name="cache"></param> /// <param name="wsList">Null if don't want multiple writing systems.</param> /// <param name="fShowMutlilingGlosses"></param> public void AddLabelPile(IVwEnv vwenv, ITsStrFactory tsf, FdoCache cache, bool fWantMultipleSenseGloss, bool fShowMorphemes) { CheckDisposed(); int wsUI = cache.DefaultUserWs; int wsAnalysis = cache.DefaultAnalWs; vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, 10000); vwenv.set_IntProperty((int)FwTextPropType.ktptBold, (int)FwTextPropVar.ktpvEnum, (int)FwTextToggleVal.kttvForceOn); vwenv.set_IntProperty((int)FwTextPropType.ktptMarginBottom, (int)FwTextPropVar.ktpvMilliPoint, 5000); // default spacing is fine for all embedded paragraphs. vwenv.OpenInnerPile(); foreach (InterlinLineSpec spec in m_lineChoices) { if (!spec.WordLevel) break; SetColor(vwenv, LabelRGBFor(spec)); ITsString tss = tsf.MakeString(m_lineChoices.LabelFor(spec.Flid), wsUI); if (m_lineChoices.RepetitionsOfFlid(spec.Flid) > 1) { vwenv.OpenParagraph(); vwenv.AddString(tss); vwenv.AddString(m_cache.MakeUserTss(" ")); vwenv.AddString(spec.WsLabel(m_cache)); vwenv.CloseParagraph(); } else { vwenv.AddString(tss); } } vwenv.CloseInnerPile(); }
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(); }
private void DisplayWordform(IVwEnv vwenv, int ws, int choiceIndex) { // For the wordform line we only want an icon on the first line (which is always wordform). bool fWantIcon = m_sandbox.ShowAnalysisCombo && choiceIndex == 0; // This has to be BEFORE we open the paragraph, so the indent applies to the whole // paragraph, and not some string box inside it. if (!fWantIcon) SetIndentForMissingIcon(vwenv); vwenv.OpenParagraph(); // The actual icon, if present, has to be INSIDE the paragraph. if (fWantIcon) AddPullDownIcon(vwenv, ktagAnalysisIcon); //Set the background of the wordform to the 'WordFormBGColor' which is set when ChangeOrCreateSandbox //is called SetBGColor(vwenv, MultipleOptionBGColor); if (ws != m_sandbox.RawWordformWs) { // Any other Ws we can edit. MakeNextFlowObjectEditable(vwenv); vwenv.OpenInnerPile(); // So white background occupies full width vwenv.AddStringAltMember(ktagSbWordForm, ws, this); vwenv.CloseInnerPile(); } else { MakeNextFlowObjectReadOnly(vwenv); //vwenv.AddString(m_sandbox.RawWordform); vwenv.AddStringAltMember(ktagSbWordForm, ws, this); } vwenv.CloseParagraph(); }
public override void Display(IVwEnv vwenv, int hvo, int frag) { switch (frag) { case kfragContext: var ctxtOrVar = m_cache.ServiceLocator.GetInstance <IPhContextOrVarRepository>().GetObject(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); var outerObj = m_cache.ServiceLocator.GetObject(outerHvo); isOuterIterCtxt = outerObj.ClassID == PhIterationContextTags.kClassId; } switch (ctxtOrVar.ClassID) { case PhSequenceContextTags.kClassId: var seqCtxt = (IPhSequenceContext)ctxtOrVar; if (seqCtxt.MembersRS.Count > 0) { vwenv.AddObjVecItems(PhSequenceContextTags.kflidMembers, this, kfragContext); } else { OpenSingleLinePile(vwenv, GetMaxNumLines(), false); vwenv.Props = m_bracketProps; vwenv.AddProp(PhSequenceContextTags.kflidMembers, this, kfragEmpty); CloseSingleLinePile(vwenv, false); } break; case PhSimpleContextNCTags.kClassId: var ncCtxt = (IPhSimpleContextNC)ctxtOrVar; if (ncCtxt.FeatureStructureRA != null && ncCtxt.FeatureStructureRA.ClassID == PhNCFeaturesTags.kClassId) { // Natural class simple context with a feature-based natural class var natClass = (IPhNCFeatures)ncCtxt.FeatureStructureRA; int numLines = GetNumLines(ncCtxt); if (numLines == 0) { if (!isOuterIterCtxt) { OpenSingleLinePile(vwenv, GetMaxNumLines()); } vwenv.AddProp(ktagInnerNonBoundary, this, kfragLeftBracket); vwenv.AddProp(PhSimpleContextNCTags.kflidFeatureStructure, this, kfragQuestions); vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightBracket); if (!isOuterIterCtxt) { CloseSingleLinePile(vwenv); } } else if (numLines == 1) { if (!isOuterIterCtxt) { OpenSingleLinePile(vwenv, GetMaxNumLines()); } // 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.Text == "C" || natClass.Abbreviation.AnalysisDefaultWritingSystem.Text == "V") { vwenv.AddObjProp(PhSimpleContextNCTags.kflidFeatureStructure, this, kfragNC); } else { if (natClass.FeaturesOA != null && natClass.FeaturesOA.FeatureSpecsOC.Count > 0) { vwenv.AddObjProp(PhSimpleContextNCTags.kflidFeatureStructure, this, kfragFeatNC); } else if (ncCtxt.PlusConstrRS.Count > 0) { vwenv.AddObjVecItems(PhSimpleContextNCTags.kflidPlusConstr, this, kfragPlusVariable); } else { vwenv.AddObjVecItems(PhSimpleContextNCTags.kflidMinusConstr, this, kfragMinusVariable); } } vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightBracket); if (!isOuterIterCtxt) { CloseSingleLinePile(vwenv); } } else { // multiline context // left bracket pile int maxNumLines = GetMaxNumLines(); vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int)FwTextPropType.ktptMarginLeading, (int)FwTextPropVar.ktpvMilliPoint, PileMargin); 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(PhSimpleContextNCTags.kflidFeatureStructure, this, kfragFeatNC); vwenv.AddObjVecItems(PhSimpleContextNCTags.kflidPlusConstr, this, kfragPlusVariable); vwenv.AddObjVecItems(PhSimpleContextNCTags.kflidMinusConstr, this, kfragMinusVariable); vwenv.CloseInnerPile(); // right bracket pile vwenv.Props = m_bracketProps; if (!isOuterIterCtxt) { vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, PileMargin); } 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) { OpenSingleLinePile(vwenv, GetMaxNumLines()); } vwenv.AddProp(ktagInnerNonBoundary, this, kfragLeftBracket); if (ncCtxt.FeatureStructureRA != null) { vwenv.AddObjProp(PhSimpleContextNCTags.kflidFeatureStructure, this, kfragNC); } else { vwenv.AddProp(PhSimpleContextNCTags.kflidFeatureStructure, this, kfragQuestions); } vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightBracket); if (!isOuterIterCtxt) { CloseSingleLinePile(vwenv); } } break; case PhIterationContextTags.kClassId: var iterCtxt = (IPhIterationContext)ctxtOrVar; if (iterCtxt.MemberRA != null) { int numLines = GetNumLines(iterCtxt.MemberRA as IPhSimpleContext); if (numLines > 1) { vwenv.AddObjProp(PhIterationContextTags.kflidMember, this, kfragContext); DisplayIterCtxt(numLines, vwenv); } else { OpenSingleLinePile(vwenv, GetMaxNumLines()); if (iterCtxt.MemberRA.ClassID == PhSimpleContextNCTags.kClassId) { vwenv.AddObjProp(PhIterationContextTags.kflidMember, this, kfragContext); } else { vwenv.AddProp(ktagInnerNonBoundary, this, kfragLeftParen); vwenv.AddObjProp(PhIterationContextTags.kflidMember, this, kfragContext); vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightParen); } DisplayIterCtxt(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 CloseSingleLinePile(vwenv, false); } } else { OpenSingleLinePile(vwenv, GetMaxNumLines()); vwenv.AddProp(PhIterationContextTags.kflidMember, this, kfragQuestions); CloseSingleLinePile(vwenv); } break; case PhSimpleContextSegTags.kClassId: if (!isOuterIterCtxt) { OpenSingleLinePile(vwenv, GetMaxNumLines()); } var segCtxt = (IPhSimpleContextSeg)ctxtOrVar; if (segCtxt.FeatureStructureRA != null) { vwenv.AddObjProp(PhSimpleContextSegTags.kflidFeatureStructure, this, kfragTerminalUnit); } else { vwenv.AddProp(PhSimpleContextSegTags.kflidFeatureStructure, this, kfragQuestions); } if (!isOuterIterCtxt) { CloseSingleLinePile(vwenv); } break; case PhSimpleContextBdryTags.kClassId: if (!isOuterIterCtxt) { OpenSingleLinePile(vwenv, GetMaxNumLines()); } var bdryCtxt = (IPhSimpleContextBdry)ctxtOrVar; if (bdryCtxt.FeatureStructureRA != null) { vwenv.AddObjProp(PhSimpleContextBdryTags.kflidFeatureStructure, this, kfragTerminalUnit); } else { vwenv.AddProp(PhSimpleContextBdryTags.kflidFeatureStructure, this, kfragQuestions); } if (!isOuterIterCtxt) { CloseSingleLinePile(vwenv); } break; case PhVariableTags.kClassId: OpenSingleLinePile(vwenv, GetMaxNumLines()); vwenv.AddProp(ktagXVariable, this, kfragXVariable); CloseSingleLinePile(vwenv); break; } break; case kfragNC: int ncWs = WritingSystemServices.ActualWs(m_cache, WritingSystemServices.kwsFirstAnal, hvo, PhNaturalClassTags.kflidAbbreviation); if (ncWs != 0) { vwenv.AddStringAltMember(PhNaturalClassTags.kflidAbbreviation, ncWs, this); } else { ncWs = WritingSystemServices.ActualWs(m_cache, WritingSystemServices.kwsFirstAnal, hvo, PhNaturalClassTags.kflidName); if (ncWs != 0) { vwenv.AddStringAltMember(PhNaturalClassTags.kflidName, ncWs, this); } else { vwenv.AddProp(PhNaturalClassTags.kflidAbbreviation, this, kfragQuestions); } } break; case kfragTerminalUnit: int tuWs = WritingSystemServices.ActualWs(m_cache, WritingSystemServices.kwsFirstVern, hvo, PhTerminalUnitTags.kflidName); if (tuWs != 0) { vwenv.AddStringAltMember(PhTerminalUnitTags.kflidName, tuWs, this); } else { vwenv.AddProp(PhTerminalUnitTags.kflidName, this, kfragQuestions); } break; case kfragFeatNC: vwenv.AddObjProp(PhNCFeaturesTags.kflidFeatures, this, kfragFeats); break; case kfragFeats: vwenv.AddObjVecItems(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; } }
private void DisplayInflFeatures(IVwEnv vwenv, IDictionary<IFsFeatDefn, object> inflFeatures) { int numLines = GetNumLines(inflFeatures); if (numLines == 1) { // use normal brackets for a single line constraint vwenv.AddProp(ktagInnerNonBoundary, this, kfragLeftBracket); DisplayInflFeatureLines(vwenv, inflFeatures, false); vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightBracket); } else { // left bracket pile vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int) FwTextPropType.ktptMarginLeading, (int) FwTextPropVar.ktpvMilliPoint, PileMargin); vwenv.OpenInnerPile(); 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 pile vwenv.set_IntProperty((int) FwTextPropType.ktptAlign, (int) FwTextPropVar.ktpvEnum, (int) FwTextAlign.ktalLeft); vwenv.OpenInnerPile(); DisplayInflFeatureLines(vwenv, inflFeatures, true); vwenv.CloseInnerPile(); // right bracket pile vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int) FwTextPropType.ktptMarginTrailing, (int) FwTextPropVar.ktpvMilliPoint, PileMargin); vwenv.OpenInnerPile(); vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightBracketUpHook); for (int i = 1; i < numLines - 1; i++) vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightBracketExt); vwenv.AddProp(ktagInnerNonBoundary, this, kfragRightBracketLowHook); vwenv.CloseInnerPile(); } }
public override void Display(IVwEnv vwenv, int hvo, int frag) { switch (frag) { default: break; case kfrBook: vwenv.set_IntProperty((int)FwKernelLib.FwTextPropType.ktptFontSize, (int)FwKernelLib.FwTextPropVar.ktpvMilliPoint, 24000); vwenv.set_IntProperty((int)FwKernelLib.FwTextPropType.ktptBold, (int)FwKernelLib.FwTextPropVar.ktpvEnum, (int)FwKernelLib.FwTextToggleVal.kttvOn); vwenv.set_IntProperty((int)FwKernelLib.FwTextPropType.ktptAlign, (int)FwKernelLib.FwTextPropVar.ktpvEnum, (int)FwKernelLib.FwTextAlign.ktalCenter); vwenv.AddStringProp(ktagBookName, this); vwenv.AddLazyVecItems(ktagBookSections, this, kfrSection); break; case kfrSection: vwenv.set_IntProperty((int)FwKernelLib.FwTextPropType.ktptItalic, (int)FwKernelLib.FwTextPropVar.ktpvEnum, (int)FwKernelLib.FwTextToggleVal.kttvOn); vwenv.OpenParagraph(); vwenv.AddStringProp(ktagSectionTitle, this); vwenv.AddString(m_tssLeftParen); vwenv.AddStringProp(ktagSectionRefs, this); vwenv.AddString(m_tssRightParen); vwenv.CloseParagraph(); vwenv.AddLazyVecItems(ktagSectionParas, this, kfrDoublePara); break; case kfrDoublePara: AddDoublePara(vwenv, hvo); // Now insert an interlinear version of the paragraph. This is basically editable. vwenv.set_IntProperty((int)FwKernelLib.FwTextPropType.ktptBackColor, (int)FwKernelLib.FwTextPropVar.ktpvDefault, m_colorEditable); vwenv.OpenParagraph(); vwenv.AddObjVecItems(ktagParaBundles, this, kfrBundle); vwenv.CloseParagraph(); break; case kfrBundle: // Put a little space after each bundle to separate them. vwenv.set_IntProperty((int)FwKernelLib.FwTextPropType.ktptMarginTrailing, (int)FwKernelLib.FwTextPropVar.ktpvMilliPoint, 5000); vwenv.OpenInnerPile(); vwenv.AddStringProp(ktagBundleBase, this); vwenv.set_IntProperty((int)FwKernelLib.FwTextPropType.ktptBold, (int)FwKernelLib.FwTextPropVar.ktpvEnum, (int)FwKernelLib.FwTextToggleVal.kttvOn); vwenv.set_IntProperty((int)FwKernelLib.FwTextPropType.ktptFontSize, (int)FwKernelLib.FwTextPropVar.ktpvMilliPoint, 13000); vwenv.AddStringProp(ktagBundleIdiom, this); vwenv.set_IntProperty((int)FwKernelLib.FwTextPropType.ktptFontSize, (int)FwKernelLib.FwTextPropVar.ktpvMilliPoint, 8000); vwenv.AddStringProp(ktagBundleLing, this); vwenv.CloseInnerPile(); break; } }
public override void Display(IVwEnv vwenv, int hvo, int frag) { switch (frag) { case kfragPattern: VwLength tableLen; tableLen.nVal = 10000; tableLen.unit = VwUnit.kunPercent100; vwenv.OpenTable(1, tableLen, 0, VwAlignment.kvaCenter, VwFramePosition.kvfpVoid, VwRule.kvrlNone, 0, 0, false); VwLength patternLen; patternLen.nVal = 1; patternLen.unit = VwUnit.kunRelative; vwenv.MakeColumns(1, patternLen); vwenv.OpenTableBody(); vwenv.OpenTableRow(); vwenv.set_IntProperty((int)FwTextPropType.ktptBorderBottom, (int)FwTextPropVar.ktpvMilliPoint, 1000); vwenv.set_IntProperty((int)FwTextPropType.ktptBorderColor, (int)FwTextPropVar.ktpvDefault, (int)ColorUtil.ConvertColorToBGR(Color.Gray)); vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalCenter); vwenv.set_IntProperty((int)FwTextPropType.ktptPadBottom, (int)FwTextPropVar.ktpvMilliPoint, 2000); vwenv.OpenTableCell(1, 1); vwenv.OpenParagraph(); if (((ComplexConcPatternSda) vwenv.DataAccess).Root.IsLeaf) { OpenSingleLinePile(vwenv, GetMaxNumLines(vwenv), false); vwenv.Props = m_bracketProps; vwenv.AddProp(ComplexConcPatternSda.ktagChildren, this, kfragEmpty); CloseSingleLinePile(vwenv, false); } else { vwenv.AddObjVecItems(ComplexConcPatternSda.ktagChildren, this, kfragNode); } vwenv.CloseParagraph(); vwenv.CloseTableCell(); vwenv.CloseTableRow(); vwenv.CloseTableBody(); vwenv.CloseTable(); break; case kfragNode: ComplexConcPatternNode node = ((ComplexConcPatternSda) vwenv.DataAccess).Nodes[hvo]; int maxNumLines = GetMaxNumLines(vwenv); if (node is ComplexConcOrNode) { OpenSingleLinePile(vwenv, maxNumLines); vwenv.AddProp(ktagInnerNonBoundary, this, kfragOR); CloseSingleLinePile(vwenv, false); } else if (node is ComplexConcWordBdryNode) { OpenSingleLinePile(vwenv, maxNumLines); vwenv.AddProp(ktagInnerNonBoundary, this, kfragHash); CloseSingleLinePile(vwenv); } else if (node is ComplexConcGroupNode) { int numLines = GetNumLines(node); bool hasMinMax = node.Maximum != 1 || node.Minimum != 1; if (numLines == 1) { OpenSingleLinePile(vwenv, maxNumLines, false); // use normal parentheses for a single line group vwenv.AddProp(ktagLeftBoundary, this, kfragLeftParen); vwenv.AddObjVecItems(ComplexConcPatternSda.ktagChildren, this, kfragNode); vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightBoundary, this, kfragRightParen); if (hasMinMax) DisplayMinMax(numLines, vwenv); CloseSingleLinePile(vwenv, false); } else { vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int) FwTextPropType.ktptMarginLeading, (int) FwTextPropVar.ktpvMilliPoint, PileMargin); vwenv.OpenInnerPile(); AddExtraLines(maxNumLines - numLines, ktagLeftNonBoundary, vwenv); vwenv.AddProp(ktagLeftNonBoundary, this, kfragLeftParenUpHook); for (int i = 1; i < numLines - 1; i++) vwenv.AddProp(ktagLeftNonBoundary, this, kfragLeftParenExt); vwenv.AddProp(ktagLeftBoundary, this, kfragLeftParenLowHook); vwenv.CloseInnerPile(); vwenv.AddObjVecItems(ComplexConcPatternSda.ktagChildren, this, kfragNode); vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int) FwTextPropType.ktptMarginTrailing, (int) FwTextPropVar.ktpvMilliPoint, PileMargin); vwenv.OpenInnerPile(); AddExtraLines(maxNumLines - numLines, hasMinMax ? ktagInnerNonBoundary : ktagRightNonBoundary, vwenv); vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightNonBoundary, this, kfragRightParenUpHook); for (int i = 1; i < numLines - 1; i++) vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightNonBoundary, this, kfragRightParenExt); vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightBoundary, this, kfragRightParenLowHook); vwenv.CloseInnerPile(); if (hasMinMax) DisplayMinMax(numLines, vwenv); } } else { bool hasMinMax = node.Maximum != 1 || node.Minimum != 1; int numLines = GetNumLines(node); if (numLines == 1) { OpenSingleLinePile(vwenv, maxNumLines, false); // use normal brackets for a single line constraint vwenv.AddProp(ktagLeftBoundary, this, kfragLeftBracket); DisplayFeatures(vwenv, node); vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightBoundary, this, kfragRightBracket); if (hasMinMax) DisplayMinMax(numLines, vwenv); CloseSingleLinePile(vwenv, false); } else { // left bracket pile vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int) FwTextPropType.ktptMarginLeading, (int) FwTextPropVar.ktpvMilliPoint, PileMargin); 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 pile vwenv.set_IntProperty((int) FwTextPropType.ktptAlign, (int) FwTextPropVar.ktpvEnum, (int) FwTextAlign.ktalLeft); vwenv.OpenInnerPile(); AddExtraLines(maxNumLines - numLines, ktagInnerNonBoundary, vwenv); DisplayFeatures(vwenv, node); vwenv.CloseInnerPile(); // right bracket pile vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int) FwTextPropType.ktptMarginTrailing, (int) FwTextPropVar.ktpvMilliPoint, PileMargin); vwenv.OpenInnerPile(); AddExtraLines(maxNumLines - numLines, hasMinMax ? ktagInnerNonBoundary : ktagRightNonBoundary, vwenv); vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightNonBoundary, this, kfragRightBracketUpHook); for (int i = 1; i < numLines - 1; i++) vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightNonBoundary, this, kfragRightBracketExt); vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightBoundary, this, kfragRightBracketLowHook); vwenv.CloseInnerPile(); if (hasMinMax) DisplayMinMax(numLines, vwenv); } } break; } }
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; } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Display a view of the LexEntry (or fragment thereof). /// </summary> /// <param name="vwenv"></param> /// <param name="hvo"></param> /// <param name="frag"></param> /// ------------------------------------------------------------------------------------ public override void Display(IVwEnv vwenv, int hvo, int frag) { switch (frag) { case (int)VcFrags.kfragHeadWord: // This case should stay in sync with // LexEntry.LexemeFormMorphTypeAndHomographStatic vwenv.OpenParagraph(); AddHeadwordWithHomograph(vwenv, hvo); vwenv.CloseParagraph(); break; case kfragEntryAndVariant: var wfb = m_cache.ServiceLocator.GetInstance <IWfiMorphBundleRepository>().GetObject(hvo); //int hvoMf = wfb.MorphRA.Hvo; //int hvoLexEntry = m_cache.GetOwnerOfObject(hvoMf); // if morphbundle morph (entry) is in a variant relationship to the morph bundle sense // display its entry headword and variant type information (LT-4053) ILexEntryRef ler; var variant = wfb.MorphRA.Owner as ILexEntry; if (variant.IsVariantOfSenseOrOwnerEntry(wfb.SenseRA, out ler)) { // build Headword from sense's entry vwenv.OpenParagraph(); vwenv.OpenInnerPile(); vwenv.AddObj(wfb.SenseRA.EntryID, this, (int)VcFrags.kfragHeadWord); vwenv.CloseInnerPile(); vwenv.OpenInnerPile(); // now add variant type info vwenv.AddObj(ler.Hvo, this, kfragVariantTypes); vwenv.CloseInnerPile(); vwenv.CloseParagraph(); break; } // build Headword even though we aren't in a variant relationship. vwenv.AddObj(variant.Hvo, this, (int)VcFrags.kfragHeadWord); break; case kfragVariantTypes: ler = m_cache.ServiceLocator.GetInstance <ILexEntryRefRepository>().GetObject(hvo); bool fNeedInitialPlus = true; vwenv.OpenParagraph(); foreach (var let in ler.VariantEntryTypesRS.Where(let => let.ClassID == LexEntryTypeTags.kClassId)) { // just concatenate them together separated by comma. ITsString tssVariantTypeRevAbbr = let.ReverseAbbr.BestAnalysisAlternative; if (tssVariantTypeRevAbbr != null && tssVariantTypeRevAbbr.Length > 0) { if (fNeedInitialPlus) { vwenv.AddString(TsStringUtils.MakeString("+", m_cache.DefaultUserWs)); } else { vwenv.AddString(TsStringUtils.MakeString(",", m_cache.DefaultUserWs)); } vwenv.AddString(tssVariantTypeRevAbbr); fNeedInitialPlus = false; } } vwenv.CloseParagraph(); break; case kfragFormForm: // form of MoForm vwenv.AddStringAltMember(MoFormTags.kflidForm, m_wsActual, this); break; default: base.Display(vwenv, hvo, frag); break; } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Display a view of the LexEntry (or fragment thereof). /// </summary> /// <param name="vwenv"></param> /// <param name="hvo"></param> /// <param name="frag"></param> /// ------------------------------------------------------------------------------------ public override void Display(IVwEnv vwenv, int hvo, int frag) { switch (frag) { case (int)VcFrags.kfragHeadWord: // This case should stay in sync with // LexEntry.LexemeFormMorphTypeAndHomographStatic vwenv.OpenParagraph(); AddHeadwordWithHomograph(vwenv, hvo); vwenv.CloseParagraph(); break; case kfragEntryAndVariant: var wfb = m_cache.ServiceLocator.GetInstance<IWfiMorphBundleRepository>().GetObject(hvo); //int hvoMf = wfb.MorphRA.Hvo; //int hvoLexEntry = m_cache.GetOwnerOfObject(hvoMf); // if morphbundle morph (entry) is in a variant relationship to the morph bundle sense // display its entry headword and variant type information (LT-4053) ILexEntryRef ler; var variant = wfb.MorphRA.Owner as ILexEntry; if (variant.IsVariantOfSenseOrOwnerEntry(wfb.SenseRA, out ler)) { // build Headword from sense's entry vwenv.OpenParagraph(); vwenv.OpenInnerPile(); vwenv.AddObj(wfb.SenseRA.EntryID, this, (int)VcFrags.kfragHeadWord); vwenv.CloseInnerPile(); vwenv.OpenInnerPile(); // now add variant type info vwenv.AddObj(ler.Hvo, this, kfragVariantTypes); vwenv.CloseInnerPile(); vwenv.CloseParagraph(); break; } // build Headword even though we aren't in a variant relationship. vwenv.AddObj(variant.Hvo, this, (int)VcFrags.kfragHeadWord); break; case kfragVariantTypes: ler = m_cache.ServiceLocator.GetInstance<ILexEntryRefRepository>().GetObject(hvo); bool fNeedInitialPlus = true; vwenv.OpenParagraph(); foreach (var let in ler.VariantEntryTypesRS.Where(let => let.ClassID == LexEntryTypeTags.kClassId)) { // just concatenate them together separated by comma. ITsString tssVariantTypeRevAbbr = let.ReverseAbbr.BestAnalysisAlternative; if (tssVariantTypeRevAbbr != null && tssVariantTypeRevAbbr.Length > 0) { if (fNeedInitialPlus) vwenv.AddString(TsStringUtils.MakeTss("+", m_cache.DefaultUserWs)); else vwenv.AddString(TsStringUtils.MakeTss(",", m_cache.DefaultUserWs)); vwenv.AddString(tssVariantTypeRevAbbr); fNeedInitialPlus = false; } } vwenv.CloseParagraph(); break; case kfragFormForm: // form of MoForm vwenv.AddStringAltMember(MoFormTags.kflidForm, m_wsActual, this); break; default: base.Display(vwenv, hvo, frag); break; } }
public override void Display(IVwEnv vwenv, int hvo, int frag) { switch (frag) { case kfragPattern: VwLength tableLen; tableLen.nVal = 10000; tableLen.unit = VwUnit.kunPercent100; vwenv.OpenTable(1, tableLen, 0, VwAlignment.kvaCenter, VwFramePosition.kvfpVoid, VwRule.kvrlNone, 0, 0, false); VwLength patternLen; patternLen.nVal = 1; patternLen.unit = VwUnit.kunRelative; vwenv.MakeColumns(1, patternLen); vwenv.OpenTableBody(); vwenv.OpenTableRow(); vwenv.set_IntProperty((int)FwTextPropType.ktptBorderBottom, (int)FwTextPropVar.ktpvMilliPoint, 1000); vwenv.set_IntProperty((int)FwTextPropType.ktptBorderColor, (int)FwTextPropVar.ktpvDefault, (int)ColorUtil.ConvertColorToBGR(Color.Gray)); vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalCenter); vwenv.set_IntProperty((int)FwTextPropType.ktptPadBottom, (int)FwTextPropVar.ktpvMilliPoint, 2000); vwenv.OpenTableCell(1, 1); vwenv.OpenParagraph(); if (((ComplexConcPatternSda)vwenv.DataAccess).Root.IsLeaf) { OpenSingleLinePile(vwenv, GetMaxNumLines(vwenv), false); vwenv.Props = m_bracketProps; vwenv.AddProp(ComplexConcPatternSda.ktagChildren, this, kfragEmpty); CloseSingleLinePile(vwenv, false); } else { vwenv.AddObjVecItems(ComplexConcPatternSda.ktagChildren, this, kfragNode); } vwenv.CloseParagraph(); vwenv.CloseTableCell(); vwenv.CloseTableRow(); vwenv.CloseTableBody(); vwenv.CloseTable(); break; case kfragNode: ComplexConcPatternNode node = ((ComplexConcPatternSda)vwenv.DataAccess).Nodes[hvo]; int maxNumLines = GetMaxNumLines(vwenv); if (node is ComplexConcOrNode) { OpenSingleLinePile(vwenv, maxNumLines); vwenv.AddProp(ktagInnerNonBoundary, this, kfragOR); CloseSingleLinePile(vwenv, false); } else if (node is ComplexConcWordBdryNode) { OpenSingleLinePile(vwenv, maxNumLines); vwenv.AddProp(ktagInnerNonBoundary, this, kfragHash); CloseSingleLinePile(vwenv); } else if (node is ComplexConcGroupNode) { int numLines = GetNumLines(node); bool hasMinMax = node.Maximum != 1 || node.Minimum != 1; if (numLines == 1) { OpenSingleLinePile(vwenv, maxNumLines, false); // use normal parentheses for a single line group vwenv.AddProp(ktagLeftBoundary, this, kfragLeftParen); vwenv.AddObjVecItems(ComplexConcPatternSda.ktagChildren, this, kfragNode); vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightBoundary, this, kfragRightParen); if (hasMinMax) { DisplayMinMax(numLines, vwenv); } CloseSingleLinePile(vwenv, false); } else { vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int)FwTextPropType.ktptMarginLeading, (int)FwTextPropVar.ktpvMilliPoint, PileMargin); vwenv.OpenInnerPile(); AddExtraLines(maxNumLines - numLines, ktagLeftNonBoundary, vwenv); vwenv.AddProp(ktagLeftNonBoundary, this, kfragLeftParenUpHook); for (int i = 1; i < numLines - 1; i++) { vwenv.AddProp(ktagLeftNonBoundary, this, kfragLeftParenExt); } vwenv.AddProp(ktagLeftBoundary, this, kfragLeftParenLowHook); vwenv.CloseInnerPile(); vwenv.AddObjVecItems(ComplexConcPatternSda.ktagChildren, this, kfragNode); vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, PileMargin); vwenv.OpenInnerPile(); AddExtraLines(maxNumLines - numLines, hasMinMax ? ktagInnerNonBoundary : ktagRightNonBoundary, vwenv); vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightNonBoundary, this, kfragRightParenUpHook); for (int i = 1; i < numLines - 1; i++) { vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightNonBoundary, this, kfragRightParenExt); } vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightBoundary, this, kfragRightParenLowHook); vwenv.CloseInnerPile(); if (hasMinMax) { DisplayMinMax(numLines, vwenv); } } } else { bool hasMinMax = node.Maximum != 1 || node.Minimum != 1; int numLines = GetNumLines(node); if (numLines == 1) { OpenSingleLinePile(vwenv, maxNumLines, false); // use normal brackets for a single line constraint vwenv.AddProp(ktagLeftBoundary, this, kfragLeftBracket); DisplayFeatures(vwenv, node); vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightBoundary, this, kfragRightBracket); if (hasMinMax) { DisplayMinMax(numLines, vwenv); } CloseSingleLinePile(vwenv, false); } else { // left bracket pile vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int)FwTextPropType.ktptMarginLeading, (int)FwTextPropVar.ktpvMilliPoint, PileMargin); 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 pile vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalLeft); vwenv.OpenInnerPile(); AddExtraLines(maxNumLines - numLines, ktagInnerNonBoundary, vwenv); DisplayFeatures(vwenv, node); vwenv.CloseInnerPile(); // right bracket pile vwenv.Props = m_bracketProps; vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, PileMargin); vwenv.OpenInnerPile(); AddExtraLines(maxNumLines - numLines, hasMinMax ? ktagInnerNonBoundary : ktagRightNonBoundary, vwenv); vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightNonBoundary, this, kfragRightBracketUpHook); for (int i = 1; i < numLines - 1; i++) { vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightNonBoundary, this, kfragRightBracketExt); } vwenv.AddProp(hasMinMax ? ktagInnerNonBoundary : ktagRightBoundary, this, kfragRightBracketLowHook); vwenv.CloseInnerPile(); if (hasMinMax) { DisplayMinMax(numLines, vwenv); } } } break; } }
private void DisplayWordGloss(IVwEnv vwenv, int hvo, int ws, int choiceIndex) { // Count how many glosses there are for the current analysis: int cGlosses = 0; // Find a wfi analysis (existing or guess) to determine whether to provide an icon for selecting // multiple word glosses for IhWordGloss.SetupCombo (cf. LT-1428) int hvoWa = m_sandbox.GetWfiAnalysisHvoInUse(); if (hvoWa != 0) { IWfiAnalysis wa = WfiAnalysis.CreateFromDBObject(m_caches.MainCache, hvoWa); cGlosses = wa.MeaningsOC.Count; } SetColor(vwenv, m_choices.LabelRGBFor(choiceIndex)); SetGuessing(vwenv, hvo, ktagSbWordGlossGuess); // Icon only if we want icons at all (currently always true) and there is at least one WfiGloss to choose // and this is the first word gloss line. bool fWantIcon = m_fIconsForAnalysisChoices && (cGlosses > 0 || m_sandbox.ShouldAddWordGlossToLexicon) && m_choices.IsFirstOccurrenceOfFlid(choiceIndex); // If there isn't going to be an icon, add an indent. if (!fWantIcon) { SetIndentForMissingIcon(vwenv); } vwenv.OpenParagraph(); if (fWantIcon) { AddPullDownIcon(vwenv, ktagWordGlossIcon); m_fIconForWordGloss = true; } else if (m_fIconForWordGloss == true && cGlosses == 0) { // reset m_fIconForWordGloss = false; } // vwenv.set_IntProperty((int)FwTextPropType.ktptBorderTop, // (int)FwTextPropVar.ktpvMilliPoint, // 1000); // vwenv.set_IntProperty((int)FwTextPropType.ktptBorderBottom, // (int)FwTextPropVar.ktpvMilliPoint, // 1000); // vwenv.set_IntProperty((int)FwTextPropType.ktptBorderLeading, // (int)FwTextPropVar.ktpvMilliPoint, // 1000); // vwenv.set_IntProperty((int)FwTextPropType.ktptBorderTrailing, // (int)FwTextPropVar.ktpvMilliPoint, // 1000); vwenv.set_IntProperty((int)FwTextPropType.ktptMarginTrailing, (int)FwTextPropVar.ktpvMilliPoint, kmpIconMargin); vwenv.set_IntProperty((int)FwTextPropType.ktptPadTrailing, (int)FwTextPropVar.ktpvMilliPoint, 2000); vwenv.set_IntProperty((int)FwTextPropType.ktptPadLeading, (int)FwTextPropVar.ktpvMilliPoint, 2000); vwenv.set_IntProperty((int)FwTextPropType.ktptBackColor, (int)FwTextPropVar.ktpvDefault, krgbEditable); vwenv.set_IntProperty((int)FwTextPropType.ktptSpellCheck, (int)FwTextPropVar.ktpvEnum, (int)SpellingModes.ksmNormalCheck); vwenv.OpenInnerPile(); // Set the appropriate paragraph direction for the writing system. bool fWsRtl = m_caches.MainCache.LanguageWritingSystemFactoryAccessor.get_EngineOrNull(ws).RightToLeft; if (fWsRtl != RightToLeft) vwenv.set_IntProperty((int)FwTextPropType.ktptRightToLeft, (int)FwTextPropVar.ktpvEnum, fWsRtl ? (int)FwTextToggleVal.kttvForceOn : (int)FwTextToggleVal.kttvOff); vwenv.AddStringAltMember(ktagSbWordGloss, ws, this); vwenv.CloseInnerPile(); vwenv.CloseParagraph(); }