/// ------------------------------------------------------------------------------------ /// <summary> /// This is the main interesting method of displaying objects and fragments of them. /// A Scripture is displayed by displaying its Books; /// and a Book is displayed by displaying its Title and Sections; /// and a Section is diplayed by displaying its Heading and Content; /// which are displayed by using the standard view constructor for StText. /// </summary> /// <param name="vwenv"></param> /// <param name="hvo"></param> /// <param name="frag"></param> /// ------------------------------------------------------------------------------------ public override void Display(IVwEnv vwenv, int hvo, int frag) { CheckDisposed(); if (hvo == 0) return; // not much we can display without a valid object switch (frag) { case (int)ScrFrags.kfrBook: vwenv.OpenDiv(); vwenv.AddObjProp((int)ScrBook.ScrBookTags.kflidTitle, this, (int)StTextFrags.kfrText); vwenv.NoteDependency(new int[] { m_cache.LangProject.TranslatedScriptureOAHvo }, new int[] { (int)Scripture.ScriptureTags.kflidScriptureBooks }, 1); vwenv.NoteDependency(new int[] { hvo }, new int[] { (int)ScrBook.ScrBookTags.kflidSections }, 1); vwenv.AddLazyVecItems(m_sectionTag, this, (int)ScrFrags.kfrSection); // TODO (EberhardB): The gap between the intro division and the text // division probably needs to be configurable somewhere... // Add a 24 point gap at the bottom of the intro section vwenv.AddSimpleRect(ColorUtil.ConvertColorToBGR(BackColor), -1, 24000, 0); vwenv.CloseDiv(); break; default: base.Display(vwenv, hvo, frag); break; } }
/// ------------------------------------------------------------------------------------ /// <summary> /// This is the main interesting method of displaying objects and fragments of them. /// A Scripture is displayed by displaying its Books; /// and a Book is displayed by displaying its Title and Sections; /// and a Section is diplayed by displaying its Heading and Content; /// which are displayed by using the standard view constructor for StText. /// </summary> /// <param name="vwenv"></param> /// <param name="hvo"></param> /// <param name="frag"></param> /// ------------------------------------------------------------------------------------ public override void Display(IVwEnv vwenv, int hvo, int frag) { CheckDisposed(); if (hvo == 0) return; // not much we can display without a valid object switch (frag) { case (int)ScrFrags.kfrBook: vwenv.OpenDiv(); vwenv.NoteDependency(new int[] { m_cache.LanguageProject.TranslatedScriptureOA.Hvo }, new int[] { ScriptureTags.kflidScriptureBooks }, 1); vwenv.NoteDependency(new int[] { hvo }, new int[] { ScrBookTags.kflidSections }, 1); vwenv.AddLazyVecItems(ScrBookTags.kflidSections, this, (int)ScrFrags.kfrSection); vwenv.CloseDiv(); break; default: base.Display(vwenv, hvo, frag); break; } }
public override void Display(IVwEnv vwenv, int hvo, int frag) { switch (frag) { case kfragRHS: m_rhs = m_cache.ServiceLocator.GetInstance<IPhSegRuleRHSRepository>().GetObject(hvo); var rule = m_rhs.OwningRule; if (rule.Disabled) { vwenv.set_StringProperty((int)FwTextPropType.ktptNamedStyle, "Disabled Text"); } int arrowWidth, slashWidth, underscoreWidth, charHeight; vwenv.get_StringWidth(m_arrow, m_charProps, out arrowWidth, out charHeight); int maxCharHeight = charHeight; vwenv.get_StringWidth(m_slash, m_charProps, out slashWidth, out charHeight); maxCharHeight = Math.Max(charHeight, maxCharHeight); vwenv.get_StringWidth(m_underscore, m_charProps, out underscoreWidth, out charHeight); maxCharHeight = Math.Max(charHeight, maxCharHeight); int dmpx, spaceHeight; vwenv.get_StringWidth(m_zwSpace, m_bracketProps, out dmpx, out spaceHeight); int maxNumLines = GetMaxNumLines(); int maxCtxtHeight = maxNumLines * spaceHeight; int maxHeight = Math.Max(maxCharHeight, maxCtxtHeight); int charOffset = maxHeight; int ctxtPadding = maxHeight - maxCtxtHeight; VwLength tableLen; tableLen.nVal = 10000; tableLen.unit = VwUnit.kunPercent100; vwenv.OpenTable(7, tableLen, 0, VwAlignment.kvaCenter, VwFramePosition.kvfpVoid, VwRule.kvrlNone, 0, 0, false); VwLength ctxtLen; ctxtLen.nVal = 1; ctxtLen.unit = VwUnit.kunRelative; VwLength charLen; charLen.unit = VwUnit.kunPoint1000; vwenv.MakeColumns(1, ctxtLen); charLen.nVal = arrowWidth + 4000; vwenv.MakeColumns(1, charLen); vwenv.MakeColumns(1, ctxtLen); charLen.nVal = slashWidth + 4000; vwenv.MakeColumns(1, charLen); vwenv.MakeColumns(1, ctxtLen); charLen.nVal = underscoreWidth + 4000; vwenv.MakeColumns(1, charLen); vwenv.MakeColumns(1, ctxtLen); vwenv.OpenTableBody(); vwenv.OpenTableRow(); // LHS cell vwenv.Props = m_ctxtProps; vwenv.set_IntProperty((int)FwTextPropType.ktptPadTop, (int)FwTextPropVar.ktpvMilliPoint, ctxtPadding); vwenv.OpenTableCell(1, 1); vwenv.OpenParagraph(); vwenv.AddObjProp(m_cache.MetaDataCacheAccessor.GetFieldId2(PhSegRuleRHSTags.kClassId, "OwningRule", false), this, kfragRule); vwenv.CloseParagraph(); vwenv.CloseTableCell(); // arrow cell vwenv.Props = m_charProps; vwenv.set_IntProperty((int)FwTextPropType.ktptOffset, (int)FwTextPropVar.ktpvMilliPoint, -charOffset); vwenv.OpenTableCell(1, 1); vwenv.AddString(m_arrow); vwenv.CloseTableCell(); // RHS cell vwenv.Props = m_ctxtProps; vwenv.set_IntProperty((int)FwTextPropType.ktptPadTop, (int)FwTextPropVar.ktpvMilliPoint, ctxtPadding); vwenv.OpenTableCell(1, 1); vwenv.OpenParagraph(); if (m_rhs.StrucChangeOS.Count > 0) { vwenv.AddObjVecItems(PhSegRuleRHSTags.kflidStrucChange, this, kfragContext); } else { vwenv.NoteDependency(new[] {hvo}, new[] {PhSegRuleRHSTags.kflidStrucChange}, 1); OpenSingleLinePile(vwenv, maxNumLines, false); vwenv.Props = m_bracketProps; vwenv.AddProp(PhSegRuleRHSTags.kflidStrucChange, this, kfragEmpty); CloseSingleLinePile(vwenv, false); } vwenv.CloseParagraph(); vwenv.CloseTableCell(); // slash cell vwenv.Props = m_charProps; vwenv.set_IntProperty((int)FwTextPropType.ktptOffset, (int)FwTextPropVar.ktpvMilliPoint, -charOffset); vwenv.OpenTableCell(1, 1); vwenv.AddString(m_slash); vwenv.CloseTableCell(); // left context cell vwenv.Props = m_ctxtProps; vwenv.set_IntProperty((int)FwTextPropType.ktptPadTop, (int)FwTextPropVar.ktpvMilliPoint, ctxtPadding); vwenv.OpenTableCell(1, 1); vwenv.OpenParagraph(); if (m_rhs.LeftContextOA != null) { vwenv.AddObjProp(PhSegRuleRHSTags.kflidLeftContext, this, kfragContext); } else { vwenv.NoteDependency(new[] { hvo }, new[] { PhSegRuleRHSTags.kflidLeftContext }, 1); OpenSingleLinePile(vwenv, maxNumLines, false); vwenv.Props = m_bracketProps; vwenv.AddProp(PhSegRuleRHSTags.kflidLeftContext, this, kfragEmpty); CloseSingleLinePile(vwenv, false); } vwenv.CloseParagraph(); vwenv.CloseTableCell(); // underscore cell vwenv.Props = m_charProps; vwenv.set_IntProperty((int)FwTextPropType.ktptOffset, (int)FwTextPropVar.ktpvMilliPoint, -charOffset); vwenv.OpenTableCell(1, 1); vwenv.AddString(m_underscore); vwenv.CloseTableCell(); // right context cell vwenv.Props = m_ctxtProps; vwenv.set_IntProperty((int)FwTextPropType.ktptPadTop, (int)FwTextPropVar.ktpvMilliPoint, ctxtPadding); vwenv.OpenTableCell(1, 1); vwenv.OpenParagraph(); if (m_rhs.RightContextOA != null) { vwenv.AddObjProp(PhSegRuleRHSTags.kflidRightContext, this, kfragContext); } else { vwenv.NoteDependency(new[] { hvo }, new[] { PhSegRuleRHSTags.kflidRightContext }, 1); OpenSingleLinePile(vwenv, maxNumLines, false); vwenv.Props = m_bracketProps; vwenv.AddProp(PhSegRuleRHSTags.kflidRightContext, this, kfragEmpty); CloseSingleLinePile(vwenv, false); } vwenv.CloseParagraph(); vwenv.CloseTableCell(); vwenv.CloseTableRow(); vwenv.CloseTableBody(); vwenv.CloseTable(); break; case kfragRule: if (m_rhs.OwningRule.StrucDescOS.Count > 0) { vwenv.AddObjVecItems(PhSegmentRuleTags.kflidStrucDesc, this, kfragContext); } else { OpenSingleLinePile(vwenv, GetMaxNumLines(), false); vwenv.Props = m_bracketProps; vwenv.AddProp(PhSegmentRuleTags.kflidStrucDesc, this, kfragEmpty); CloseSingleLinePile(vwenv, false); } break; default: base.Display(vwenv, hvo, frag); break; } }
public override void Display(IVwEnv vwenv, int hvo, int frag) { switch (frag) { case AudioVisualView.kfragPathname: // Display the filename. ILgWritingSystemFactory wsf = m_cache.WritingSystemFactory; vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvDefault, (int)TptEditable.ktptNotEditable); ITsString tss; ITsStrFactory tsf = m_cache.TsStrFactory; Debug.Assert(hvo != 0); Debug.Assert(m_cache != null); var file = m_cache.ServiceLocator.GetInstance<ICmFileRepository>().GetObject(hvo); Debug.Assert(file != null); string path = file.AbsoluteInternalPath; tss = tsf.MakeString(path, m_cache.WritingSystemFactory.UserWs); vwenv.OpenParagraph(); vwenv.NoteDependency( new [] { m_cache.LangProject.Hvo, file.Hvo}, new [] {LangProjectTags.kflidLinkedFilesRootDir, CmFileTags.kflidInternalPath}, 2); vwenv.AddString(tss); vwenv.CloseParagraph(); break; default: throw new ArgumentException( "Don't know what to do with the given frag.", "frag"); } }
/// ----------------------------------------------------------------------------------- /// <summary> /// In certain contexts, check the given paragraph to see if it is empty. If so, /// insert a user prompt. /// </summary> /// <param name="vwenv">view environment</param> /// <param name="paraHvo">HVO of the paragraph to be displayed</param> /// <returns>true if an empty string was substituted for missing/empty StText</returns> /// ----------------------------------------------------------------------------------- protected override bool InsertParaContentsUserPrompt(IVwEnv vwenv, int paraHvo) { Debug.Assert(!DisplayTranslation); // No user prompt in any of these conditions IStTxtPara para = m_cache.ServiceLocator.GetInstance<IStTxtParaRepository>().GetObject(paraHvo); if (!(para is IScrTxtPara) || !Options.ShowEmptyParagraphPromptsSetting // tools options setting || m_target == LayoutViewTarget.targetPrint // any print layout view || m_updatedPrompts.Contains(para.Hvo)) // user interaction has updated prompt { return false; } // User prompt is only for title & heading paras IStText text = (IStText)para.Owner; // para owner if (text.OwningFlid != ScrBookTags.kflidTitle && text.OwningFlid != ScrSectionTags.kflidHeading) return false; int paraCount = text.ParagraphsOS.Count; Debug.Assert(paraCount != 0, "We shouldn't come here if StText doesn't contain any paragraphs"); // By design, if there is more than one para, don't display the user prompt. if (paraCount != 1) return false; // If first para is empty, insert user prompt for paragraph content if (text[0].Contents.Text == null) { vwenv.NoteDependency(new int[] { para.Hvo }, new int[] { StTxtParaTags.kflidContents}, 1); vwenv.AddProp(SimpleRootSite.kTagUserPrompt, this, text.OwningFlid); return true; } return false; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Display the footnote marker. /// </summary> /// <param name="vwenv">View environment</param> /// <param name="footnote">The footnote.</param> /// ------------------------------------------------------------------------------------ private void DisplayFootnoteMarker(IVwEnv vwenv, ScrFootnote footnote) { vwenv.NoteDependency(new int[] { footnote.Hvo }, new int[] { (int)StFootnote.StFootnoteTags.kflidFootnoteMarker }, 1); // The footnote marker is not editable. vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvEnum, (int)TptEditable.ktptNotEditable); ITsStrBldr strBldr = footnote.MakeFootnoteMarker(DefaultWs); strBldr.Replace(strBldr.Length, strBldr.Length, " ", null); vwenv.AddString(strBldr.GetString()); }
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 }
/// <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; }
/// <summary> /// Add to the vwenv a display of property tag of object hvo, which stores an /// SbNamedObj. If the property is non-null, display the name of the SbNamedObj. /// If not, display the dummyTag 'property' using the dummyFrag. /// </summary> /// <param name="vwenv"></param> /// <param name="hvo"></param> /// <param name="tag"></param> /// <param name="dummyTag"></param> /// <param name="dummyFrag"></param> /// <param name="tagIcon">If non-zero, display a pull-down icon before the item, marked with this tag.</param> /// <param name="ws">which alternative of the name to display</param> /// <param name="choiceIndex">which item in m_choices this comes from. The icon is displayed /// only if it is the first one for its flid.</param> protected void AddOptionalNamedObj(IVwEnv vwenv, int hvo, int tag, int dummyTag, int dummyFrag, int tagIcon, int ws, int choiceIndex) { int hvoNo = vwenv.DataAccess.get_ObjectProp(hvo, tag); SetColor(vwenv, m_choices.LabelRGBFor(choiceIndex)); bool fWantIcon = false; fWantIcon = tagIcon != 0 && m_choices.IsFirstOccurrenceOfFlid(choiceIndex); if (m_fIconsForAnalysisChoices && !fWantIcon) { // This line does not have one, but add some white space to line things up. vwenv.set_IntProperty((int)FwTextPropType.ktptLeadingIndent, (int)FwTextPropVar.ktpvMilliPoint, m_dxmpArrowPicWidth + kmpIconMargin); } vwenv.OpenParagraph(); if (fWantIcon) AddPullDownIcon(vwenv, tagIcon); // The NoteDependency is needed whether or not hvoNo is set, in case we update // to a sense which has a null MSA. See LT-4246. vwenv.NoteDependency(new int[] { hvo }, new int[] { tag }, 1); if (hvoNo == 0) vwenv.AddProp(dummyTag, this, dummyFrag); else vwenv.AddObjProp(tag, this, kfragNamedObjectNameChoices + choiceIndex); vwenv.CloseParagraph(); }
private void DisplayLexGloss(IVwEnv vwenv, int hvo, int ws, int choiceIndex) { int hvoNo = vwenv.DataAccess.get_ObjectProp(hvo, ktagSbMorphGloss); SetColor(vwenv, m_choices.LabelRGBFor(choiceIndex)); if (m_fIconsForAnalysisChoices) { // This line does not have one, but add some white space to line things up. vwenv.set_IntProperty((int)FwTextPropType.ktptLeadingIndent, (int)FwTextPropVar.ktpvMilliPoint, m_dxmpArrowPicWidth + kmpIconMargin); } if (hvoNo == 0) { // One of these is enough, the regeneration will redo an outer object and get // all the alternatives. vwenv.NoteDependency(new int[] { hvo }, new int[] { ktagSbMorphGloss }, 1); vwenv.AddProp(ktagMissingMorphGloss, this, kfragMissingMorphGloss); } else { vwenv.AddObjProp(ktagSbMorphGloss, this, kfragNamedObjectNameChoices + choiceIndex); } }
public override void Display(IVwEnv vwenv, int hvo, int frag) { switch (frag) { case AtomicReferenceView.kFragAtomicRef: // Display a paragraph with a single item. int hvoProp = HvoOfObjectToDisplay(vwenv, hvo); if (hvoProp == 0) { vwenv.set_IntProperty((int)FwTextPropType.ktptForeColor, (int)FwTextPropVar.ktpvDefault, (int)ColorUtil.ConvertColorToBGR(Color.Gray)); vwenv.set_IntProperty((int)FwTextPropType.ktptLeadingIndent, (int)FwTextPropVar.ktpvMilliPoint, 18000); vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalRight); //vwenv.AddString(m_cache.MakeUserTss("Click to select -->")); vwenv.NoteDependency(new int[] {hvo}, new int[] {m_flid}, 1); } else { vwenv.OpenParagraph(); // vwenv.OpenMappedPara(); DisplayObjectProperty(vwenv, hvoProp); vwenv.CloseParagraph(); } break; case AtomicReferenceView.kFragObjName: // Display one reference. { ILgWritingSystemFactory wsf = m_cache.WritingSystemFactory; vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvDefault, (int)TptEditable.ktptNotEditable); ITsString tss; ITsStrFactory tsf = m_cache.TsStrFactory; Debug.Assert(hvo != 0); // Use reflection to get a prebuilt name if we can. Otherwise // settle for piecing together a string. Debug.Assert(m_cache != null); var obj = m_cache.ServiceLocator.GetInstance<ICmObjectRepository>().GetObject(hvo); Debug.Assert(obj != null); System.Type type = obj.GetType(); System.Reflection.PropertyInfo pi = type.GetProperty("TsName", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy); if (pi != null) { tss = (ITsString)pi.GetValue(obj, null); } else { if (!string.IsNullOrEmpty(m_displayNameProperty)) { pi = type.GetProperty(m_displayNameProperty, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy); } int ws = wsf.GetWsFromStr(obj.SortKeyWs); if (ws == 0) ws = m_cache.ServiceLocator.WritingSystems.DefaultAnalysisWritingSystem.Handle; if (pi != null) { object info = pi.GetValue(obj, null); // handle the object type if (info is String) tss = tsf.MakeString((string)info, ws); else if (info is IMultiUnicode) { var accessor = info as IMultiUnicode; tss = accessor.get_String(ws); // try the requested one (or default analysis) if (tss == null || tss.Length == 0) tss = accessor.BestAnalysisVernacularAlternative; // get something } else if (info is ITsString) tss = (ITsString)info; else tss = null; } else { tss = obj.ShortNameTSS; // prefer this, which is hopefully smart about wss. if (tss == null || tss.Length == 0) { tss = tsf.MakeString(obj.ShortName, ws); } } } if (!string.IsNullOrEmpty(TextStyle)) { vwenv.set_StringProperty((int)FwTextPropType.ktptNamedStyle, TextStyle); } vwenv.AddString(tss); } break; default: throw new ArgumentException( "Don't know what to do with the given frag.", "frag"); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// This is the main interesting method of displaying objects and fragments of them. /// Scripture Footnotes are displayed by displaying each footnote's reference and text. /// The text is displayed using the standard view constructor for StText. /// </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)StTextFrags.kfrFootnote: { // FWR-1640: Make the sequence of footnote paragraphs non-editable // since we only allow one para per footnote. This will cause // pasting multiple paragraphs to work correctly. vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvEnum, (int)TptEditable.ktptNotEditable); base.Display(vwenv, hvo, frag); break; } case (int)FootnoteFrags.kfrScripture: { vwenv.NoteDependency(new int[] { m_cache.LanguageProject.TranslatedScriptureOA.Hvo }, new int[] { (int)ScriptureTags.kflidScriptureBooks }, 1); vwenv.AddLazyVecItems(BooksTag, this, (int)FootnoteFrags.kfrBook); break; } case (int)FootnoteFrags.kfrRootInPageSeq: { vwenv.AddObjVec(ScrBookTags.kflidFootnotes, this, (int)FootnoteFrags.kfrAllFootnotesWithinPagePara); break; } case (int)FootnoteFrags.kfrFootnoteWithinPagePara: { // Insert the marker and reference vwenv.AddObj(hvo, this, (int)StTextFrags.kfrFootnoteMarker); vwenv.AddObj(hvo, this,(int)StTextFrags.kfrFootnoteReference); // Insert (we hope only one) paragraph contents. vwenv.AddObjVecItems(StTextTags.kflidParagraphs, this, (int)FootnoteFrags.kfrFootnoteParaWithinPagePara); break; } case (int) FootnoteFrags.kfrFootnoteParaWithinPagePara: { if (!InsertParaContentsUserPrompt(vwenv, hvo)) { // Display the text paragraph contents, or its user prompt. vwenv.AddStringProp(StTxtParaTags.kflidContents, null); } break; } case (int)FootnoteFrags.kfrBook: { vwenv.OpenDiv(); vwenv.AddObjVecItems(ScrBookTags.kflidFootnotes, this, (int)StTextFrags.kfrFootnote); vwenv.CloseDiv(); break; } case (int)StTextFrags.kfrFootnoteReference: { DisplayFootnoteReference(vwenv, hvo); break; } default: base.Display(vwenv, hvo, frag); break; } }
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> /// This is for an IAnalysis object at a particular index of a Segment. /// </summary> internal override void AddExtraBundleRows(IVwEnv vwenv, AnalysisOccurrence analysis) { ITsString tss; var key = GetDictKey(analysis); if (m_tagStrings.TryGetValue(key, out tss)) { var stText = analysis.Segment.Owner.Owner; // If either the Segment's analyses sequence or the tags on the text change, we want to redraw this vwenv.NoteDependency(new [] { analysis.Segment.Hvo, stText.Hvo }, new [] { SegmentTags.kflidAnalyses, StTextTags.kflidTags }, 2); SetTrailingAlignmentIfNeeded(vwenv, tss); vwenv.AddString(tss); } }
// If the expected reference property is null, insert "??" and return false; // otherwise return true. private bool HandleObjMissing(IVwEnv vwenv, int hvo) { if (m_cache.GetObjProperty(hvo, m_flidRef) == 0) { int wsUi = vwenv.DataAccess.WritingSystemFactory.UserWs; ITsStrFactory tsf = TsStrFactoryClass.Create(); vwenv.AddString(tsf.MakeString(FdoUiStrings.ksQuestions, wsUi)); // was "??", not "???" vwenv.NoteDependency(new int[] {hvo}, new int[] {m_flidRef}, 1); return false; } return true; }
private void AddFreeformComment(IVwEnv vwenv, int hvo, int ws, int flidTarget) { if (flidTarget != ActiveFreeformFlid || hvo != m_hvoActiveFreeform || ws != ActiveFreeformWs) { vwenv.AddStringAltMember(flidTarget, ws, this); // display normally, not the current prop return; } ITsString tssVal = vwenv.DataAccess.get_MultiStringAlt(hvo, flidTarget, ws); if (tssVal.Length != 0) { // Display normally, length is not zero. This is probably redundant, we don't set m_hvoActiveFreeform etc // if the length is zero. For that reason, putting in the following note dependency doesn't help. // Even if we did set them for a non-empty string, we'd have to // do a lot of other work to get the selection restored appropriately when the length goes to zero. // vwenv.NoteStringValDependency(hvo, CmAnnotationTags.kflidComment, ws, tsf.MakeString("", ws)); vwenv.AddStringAltMember(flidTarget, ws, this); return; } // If anything causes the comment to change, get rid of the prompt. vwenv.NoteDependency(new [] { hvo }, new [] { flidTarget }, 1); // Passing the ws where we normally pass a tag, but DisplayVariant doesn't need the tag and does need to // know which writing system. vwenv.AddProp(SimpleRootSite.kTagUserPrompt, this, ws); }
/// <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(); }
// If the expected reference property is null, insert "??" and return false; // otherwise return true. private bool HandleObjMissing(IVwEnv vwenv, int hvo) { if (m_cache.DomainDataByFlid.get_ObjectProp(hvo, m_flidRef) == 0) { int wsUi = vwenv.DataAccess.WritingSystemFactory.UserWs; ITsStrFactory tsf = m_cache.TsStrFactory; vwenv.AddString(tsf.MakeString(FdoUiStrings.ksQuestions, wsUi)); // was "??", not "???" vwenv.NoteDependency(new[] { hvo }, new[] { m_flidRef }, 1); return false; } return true; }
/// <summary> /// Add a display of the category of hvoAnalysis. /// If choiceOffset is -1, display the current analysis writing systems, otherwise, /// display the one indicated (choiceIndex is an index into line choices). /// When choice index is not -1, hvoAnalysis may not be the current object. /// In that case, we invoke AddObj with a special flid which results in a recursive /// call to this, but with the correct current object. /// </summary> /// <param name="vwenv"></param> /// <param name="hvoAnalysis"></param> protected void AddAnalysisPos(IVwEnv vwenv, int hvoAnalysis, int hvoCurrent, int choiceIndex) { IWfiAnalysis wa = m_coRepository.GetObject(hvoAnalysis) as IWfiAnalysis; int hvoPos = wa.CategoryRA != null ? wa.CategoryRA.Hvo : 0; SetColor(vwenv, LabelRGBFor(choiceIndex)); if (hvoPos == 0) { vwenv.OpenParagraph(); vwenv.NoteDependency(new int[] {hvoAnalysis}, new int[] {WfiAnalysisTags.kflidCategory}, 1); vwenv.AddString(m_tssMissingAnalysisPos); vwenv.CloseParagraph(); } else if (choiceIndex < 0) { vwenv.AddObjProp(WfiAnalysisTags.kflidCategory, this, kfragCategory); } else { if (hvoCurrent == hvoAnalysis) vwenv.AddObjProp(WfiAnalysisTags.kflidCategory, this, kfragLineChoices + choiceIndex); else vwenv.AddObj(hvoAnalysis, this, kfragAnalysisCategoryChoices + choiceIndex); // causes recursive call with right hvoCurrent } }
/// <summary> /// This is the basic method needed for the view constructor. /// </summary> public override void Display(IVwEnv vwenv, int hvo, int frag) { switch (frag) { case VectorReferenceView.kfragTargetVector: // Check for an empty vector. if (hvo == 0 || m_cache.DomainDataByFlid.get_VecSize(hvo, m_flid) == 0) { vwenv.set_IntProperty((int)FwTextPropType.ktptForeColor, (int)FwTextPropVar.ktpvDefault, (int)ColorUtil.ConvertColorToBGR(Color.Gray)); vwenv.set_IntProperty((int)FwTextPropType.ktptLeadingIndent, (int)FwTextPropVar.ktpvMilliPoint, 18000); vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvDefault, (int)TptEditable.ktptNotEditable); vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalRight); //vwenv.AddString(m_cache.MakeUserTss("Click to select -->")); if (hvo != 0) vwenv.NoteDependency(new[] { hvo }, new[] { m_flid }, 1); } else { if (!string.IsNullOrEmpty(TextStyle)) { vwenv.set_StringProperty((int)FwTextPropType.ktptNamedStyle, TextStyle); } vwenv.OpenParagraph(); vwenv.AddObjVec(m_flid, this, frag); vwenv.CloseParagraph(); } break; case VectorReferenceView.kfragTargetObj: // Display one object from the vector. { ILgWritingSystemFactory wsf = m_cache.WritingSystemFactory; vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvDefault, (int)TptEditable.ktptNotEditable); ITsString tss; ITsStrFactory tsf = m_cache.TsStrFactory; Debug.Assert(hvo != 0); #if USEBESTWS if (m_displayWs != null && m_displayWs.StartsWith("best")) { // The flid can be a variety of types, so deal with those. Debug.WriteLine("Using 'best ws': " + m_displayWs); int magicWsId = LgWritingSystem.GetMagicWsIdFromName(m_displayWs); int actualWS = m_cache.LanguageProject.ActualWs(magicWsId, hvo, m_flid); Debug.WriteLine("Actual ws: " + actualWS.ToString()); } else { #endif // Use reflection to get a prebuilt name if we can. Otherwise // settle for piecing together a string. Debug.Assert(m_cache != null); var obj = m_cache.ServiceLocator.GetInstance<ICmObjectRepository>().GetObject(hvo); Debug.Assert(obj != null); Type type = obj.GetType(); System.Reflection.PropertyInfo pi = type.GetProperty("TsName", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy); if (pi != null) { tss = (ITsString)pi.GetValue(obj, null); } else { if (!string.IsNullOrEmpty(m_displayNameProperty)) { pi = type.GetProperty(m_displayNameProperty, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy); } int ws = wsf.GetWsFromStr(obj.SortKeyWs); if (ws == 0) ws = m_cache.ServiceLocator.WritingSystems.DefaultAnalysisWritingSystem.Handle; if (pi != null) { object s = pi.GetValue(obj, null); if (s is ITsString) tss = (ITsString)s; else tss = tsf.MakeString((string)s, ws); } else { // ShortNameTss sometimes gets PropChanged, so worth letting the view know that's // what we're inserting. var flid = Cache.MetaDataCacheAccessor.GetFieldId2(obj.ClassID, "ShortNameTSS", true); vwenv.AddStringProp(flid, this); break; } #if USEBESTWS } #endif } if (!string.IsNullOrEmpty(TextStyle)) { vwenv.set_StringProperty((int)FwTextPropType.ktptNamedStyle, TextStyle); } vwenv.AddString(tss); } break; default: throw new ArgumentException( "Don't know what to do with the given frag.", "frag"); } }
private void AddHeadwordWithHomograph(IVwEnv vwenv, int hvo) { ISilDataAccess sda = vwenv.DataAccess; int hvoLf = sda.get_ObjectProp(hvo, LexEntryTags.kflidLexemeForm); int hvoType = 0; if (hvoLf != 0) { hvoType = sda.get_ObjectProp(hvoLf, MoFormTags.kflidMorphType); } // If we have a type of morpheme, show the appropriate prefix that indicates it. // We want vernacular so it will match the point size of any aligned vernacular text. // (The danger is that the vernacular font doesn't have these characters...not sure what // we can do about that, but most do, and it looks awful in analysis if that is a // much different size from vernacular.) string sPrefix = null; if (hvoType != 0) { sPrefix = sda.get_UnicodeProp(hvoType, MoMorphTypeTags.kflidPrefix); } // LexEntry.ShortName1; basically tries for form of the lexeme form, then the citation form. bool fGotLabel = false; int wsActual = 0; if (hvoLf != 0) { // if we have a lexeme form and its label is non-empty, use it. if (TryMultiStringAlt(sda, hvoLf, MoFormTags.kflidForm, out wsActual)) { m_wsActual = wsActual; fGotLabel = true; if (sPrefix != null) vwenv.AddString(TsStringUtils.MakeTss(sPrefix, wsActual)); vwenv.AddObjProp(LexEntryTags.kflidLexemeForm, this, kfragFormForm); } } if (!fGotLabel) { // If we didn't get a useful form from the lexeme form try the citation form. if (TryMultiStringAlt(sda, hvo, LexEntryTags.kflidCitationForm, out wsActual)) { m_wsActual = wsActual; if (sPrefix != null) vwenv.AddString(TsStringUtils.MakeTss(sPrefix, wsActual)); vwenv.AddStringAltMember(LexEntryTags.kflidCitationForm, wsActual, this); fGotLabel = true; } } int defUserWs = m_cache.WritingSystemFactory.UserWs; if (!fGotLabel) { // If that fails just show two questions marks. if (sPrefix != null) vwenv.AddString(TsStringUtils.MakeTss(sPrefix, wsActual)); vwenv.AddString(m_cache.TsStrFactory.MakeString(FdoUiStrings.ksQuestions, defUserWs)); // was "??", not "???" } // If we have a lexeme form type show the appropriate postfix. if (hvoType != 0) { vwenv.AddString(TsStringUtils.MakeTss( sda.get_UnicodeProp(hvoType, MoMorphTypeTags.kflidPostfix), wsActual)); } // Show homograph number if non-zero. int nHomograph = sda.get_IntProp(hvo, LexEntryTags.kflidHomographNumber); vwenv.NoteDependency(new[] { hvo }, new[] { LexEntryTags.kflidHomographNumber }, 1); if (nHomograph > 0) { // Use a string builder to embed the properties in with the TsString. // this allows our TsStringCollectorEnv to properly encode the superscript. // ideally, TsStringCollectorEnv could be made smarter to handle SetIntPropValues // since AppendTss treats the given Tss as atomic. ITsIncStrBldr tsBldr = TsIncStrBldrClass.Create(); tsBldr.SetIntPropValues((int)FwTextPropType.ktptSuperscript, (int)FwTextPropVar.ktpvEnum, (int)FwSuperscriptVal.kssvSub); tsBldr.SetIntPropValues((int)FwTextPropType.ktptBold, (int)FwTextPropVar.ktpvEnum, (int)FwTextToggleVal.kttvForceOn); tsBldr.SetIntPropValues((int)FwTextPropType.ktptWs, (int)FwTextPropVar.ktpvDefault, defUserWs); tsBldr.Append(nHomograph.ToString()); vwenv.AddString(tsBldr.GetString()); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Displays the annotation fragment. /// </summary> /// ------------------------------------------------------------------------------------ private void DisplayAnnotationFragment(IVwEnv vwenv, int hvo) { IScrScriptureNote ann = m_cache.ServiceLocator.GetInstance<IScrScriptureNoteRepository>().GetObject(hvo); bool isExpanded = (m_expandTable.ContainsKey(hvo) && m_expandTable[hvo]); int hvoFirstResponse = ann.ResponsesOS.Count > 0 ? ann.ResponsesOS[0].Hvo : 0; bool responseExpanded = m_expandTable.ContainsKey(hvoFirstResponse) && m_expandTable[hvoFirstResponse]; // put the separator at the top of the note InsertNoteSeparator(vwenv); // Open a table to display the first line of the annotation. VwLength vlTable; // we use this to specify that the table takes 100% of the width. vlTable.nVal = 10000; vlTable.unit = VwUnit.kunPercent100; int borderThickness = 2000; int columnCount = 9; VwFramePosition framePos = VwFramePosition.kvfpVoid; if (ann.Hvo == SelectedNoteHvo) { columnCount = 7; framePos = (ann.ResponsesOS.Count == 0 || !isExpanded || !responseExpanded) ? VwFramePosition.kvfpBox : (VwFramePosition.kvfpAbove | VwFramePosition.kvfpVsides); } vwenv.OpenTable(columnCount, vlTable, // Table uses 100% of available width. borderThickness, VwAlignment.kvaLeft, // Default alignment. framePos, //VwFramePosition.kvfpBox, //VwRule.kvrlAll, // rule lines between cells VwRule.kvrlNone, 0, //No space between cells. 0, //No padding inside cells. false); vwenv.NoteDependency(new int[] { hvo, hvo }, new int[]{m_expansionTag, ScrScriptureNoteTags.kflidResponses}, 2); // Specify column widths. The first argument is the number of columns, // not a column index. VwLength vlColumn; if (ann.Hvo != SelectedNoteHvo) { vlColumn.nVal = borderThickness; vlColumn.unit = VwUnit.kunPoint1000; vwenv.MakeColumns(1, vlColumn); } vlColumn.nVal = 13000; vlColumn.unit = VwUnit.kunPoint1000; vwenv.MakeColumns(2, vlColumn); vlColumn.nVal = 60000; vlColumn.unit = VwUnit.kunPoint1000; vwenv.MakeColumns(1, vlColumn); vlColumn.nVal = 2; vlColumn.unit = VwUnit.kunRelative; vwenv.MakeColumns(1, vlColumn); // Column for the CONNOT categories vlColumn.nVal = 12000; vlColumn.unit = VwUnit.kunPoint1000; vwenv.MakeColumns(1, vlColumn); // Column for the chooser button when showing quote vlColumn.nVal = 3; vlColumn.unit = VwUnit.kunRelative; vwenv.MakeColumns(1, vlColumn); // Column for the quote when collapsed vlColumn.nVal = 12000; vlColumn.unit = VwUnit.kunPoint1000; vwenv.MakeColumns(1, vlColumn); // Column for the chooser button when not showing quote if (ann.Hvo != SelectedNoteHvo) { vlColumn.nVal = borderThickness; vlColumn.unit = VwUnit.kunPoint1000; vwenv.MakeColumns(1, vlColumn); } vwenv.OpenTableBody(); DisplayAnnotation(vwenv, ann, isExpanded); // Only display the responses if this note is expanded and has responses. if (!isExpanded || ann.ResponsesOS.Count == 0) { // Close table vwenv.CloseTableBody(); vwenv.CloseTable(); return; } vwenv.NoteDependency(new int[] { ann.ResponsesOS.ToHvoArray()[0] }, new int[] { m_expansionTag }, 1); OpenTableRow(vwenv, ann); // Display empty first cell vwenv.OpenTableCell(1, 1); vwenv.CloseTableCell(); // Display expand box (+/-) in the second cell vwenv.OpenTableCell(1, 1); vwenv.AddObj(ann.ResponsesOS.ToHvoArray()[0], this, (int)NotesFrags.kfrExpansion); vwenv.CloseTableCell(); // Display response label in the remaining cells vwenv.OpenTableCell(1, 5); vwenv.OpenConcPara(0, 0, 0, 0); vwenv.AddString(m_responseLabel); vwenv.CloseParagraph(); vwenv.CloseTableCell(); CloseTableRow(vwenv, ann); // Close table vwenv.CloseTableBody(); vwenv.CloseTable(); if (responseExpanded) { vwenv.AddObjVecItems((int)ScrScriptureNoteTags.kflidResponses, this, (int)NotesFrags.kfrResponse); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// This is the main interesting method of displaying objects and fragments of them. /// Scripture Footnotes are displayed by displaying each footnote's reference and text. /// The text is displayed using the standard view constructor for StText. /// </summary> /// <param name="vwenv"></param> /// <param name="hvo"></param> /// <param name="frag"></param> /// ------------------------------------------------------------------------------------ public override void Display(IVwEnv vwenv, int hvo, int frag) { CheckDisposed(); switch (frag) { case (int)FootnoteFrags.kfrScripture: { vwenv.NoteDependency(new int[] { m_cache.LangProject.TranslatedScriptureOAHvo }, new int[] { (int)Scripture.ScriptureTags.kflidScriptureBooks }, 1); vwenv.AddLazyVecItems(BooksTag, this, (int)FootnoteFrags.kfrBook); break; } case (int)FootnoteFrags.kfrRootInPageSeq: { int tag = DummyVirtualHandler.InstallDummyHandler(m_cache.VwCacheDaAccessor, "Scripture", "FootnotesOnPage", (int)CellarModuleDefns.kcptReferenceSequence).Tag; // Get the list of footnotes to display int[] hvos = m_cache.GetVectorProperty(hvo, tag, true); if (hvos.Length > 0) { int ownerHvo = m_cache.GetOwnerOfObject(hvos[0]); // The ownerHvo should be the HVO of the book vwenv.NoteDependency(new int[] { ownerHvo }, new int[] { (int)ScrBook.ScrBookTags.kflidFootnotes }, 1); } vwenv.AddObjVec(tag, this, (int)FootnoteFrags.kfrAllFootnotesWithinPagePara); break; } case (int)FootnoteFrags.kfrFootnoteWithinPagePara: { // Note a dependency on the footnote options so that the footnote will // be refreshed when these are changed. int[] depHvos = { hvo }; int[] depTags = { StFootnote.ktagFootnoteOptions }; vwenv.NoteDependency(depHvos, depTags, 1); // Insert the marker and reference vwenv.AddObj(hvo, this, (int)StTextFrags.kfrFootnoteMarker); vwenv.AddObj(hvo, this,(int)StTextFrags.kfrFootnoteReference); // Insert (we hope only one) paragraph contents. vwenv.AddObjVecItems((int)StText.StTextTags.kflidParagraphs, this, (int)FootnoteFrags.kfrFootnoteParaWithinPagePara); break; } case (int) FootnoteFrags.kfrFootnoteParaWithinPagePara: { if (!InsertParaContentsUserPrompt(vwenv, hvo)) { // Display the text paragraph contents, or its user prompt. vwenv.AddStringProp((int)StTxtPara.StTxtParaTags.kflidContents, null); } break; } case (int)FootnoteFrags.kfrBook: { vwenv.OpenDiv(); vwenv.AddObjVecItems((int)ScrBook.ScrBookTags.kflidFootnotes, this, (int)StTextFrags.kfrFootnote); vwenv.CloseDiv(); break; } case (int)StTextFrags.kfrFootnoteMarker: { ScrFootnote footnote = new ScrFootnote(Cache, hvo); if (footnote.DisplayFootnoteMarker) DisplayFootnoteMarker(vwenv, footnote); break; } case (int)StTextFrags.kfrFootnoteReference: { ITsStrFactory tsStrFactory = TsStrFactoryClass.Create(); ITsPropsFactory tpf = TsPropsFactoryClass.Create(); ITsTextProps ttp = tpf.MakeProps(ScrStyleNames.FootnoteTargetRef, m_wsDefault, 0); ScrFootnote footnote = new ScrFootnote(m_cache, hvo); string footnoteRef = footnote.GetReference(m_wsDefault); ITsString tssRef = tsStrFactory.MakeStringWithPropsRgch(footnoteRef, footnoteRef.Length, ttp); vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvEnum, (int)TptEditable.ktptNotEditable); vwenv.AddString(tssRef); break; } default: base.Display(vwenv, hvo, frag); break; } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Displays an expandable annotation of the specified type. /// </summary> /// ------------------------------------------------------------------------------------ private void DisplayExpandableAnnotation(IVwEnv vwenv, IScrScriptureNote ann, int tag, int hvo, IStJournalText paras, ITsString label, bool readOnly) { vwenv.NoteDependency(new int[] { hvo }, new int[] { m_expansionTag }, 1); SetBackgroundColorForNote(ann, vwenv); OpenTableRow(vwenv, ann); // Display empty first cell vwenv.OpenTableCell(1, 1); vwenv.CloseTableCell(); // Display +/- in the second cell, unless this is read-only vwenv.OpenTableCell(1, 1); if (!readOnly) vwenv.AddObjProp(tag, this, (int)NotesFrags.kfrExpansion); vwenv.CloseTableCell(); // Display text in the remaining cells vwenv.OpenTableCell(1, 5); vwenv.OpenConcPara(0, 0, 0, 0); vwenv.AddString(label); if (!m_expandTable.ContainsKey(hvo)) vwenv.AddString(paras[0].Contents); vwenv.CloseParagraph(); vwenv.CloseTableCell(); CloseTableRow(vwenv, ann); if (!m_expandTable.ContainsKey(hvo)) return; SetBackgroundColorForNote(ann, vwenv); OpenTableRow(vwenv, ann); // Display empty first and second cell vwenv.OpenTableCell(1, 2); vwenv.CloseTableCell(); // Display text in cells 3-7 vwenv.OpenTableCell(1, 5); if (!readOnly) SetEditBackground(vwenv); vwenv.AddObjProp(tag, this, (int)StTextFrags.kfrText); vwenv.CloseTableCell(); CloseTableRow(vwenv, ann); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Insert end of paragraph marks if needed. /// </summary> /// <param name="vwenv"></param> /// <param name="paraHvo"></param> /// ------------------------------------------------------------------------------------ protected override void InsertEndOfParaMarks(IVwEnv vwenv, int paraHvo) { if (Options.ShowFormatMarksSetting && m_target == LayoutViewTarget.targetDraft) { IStPara para = m_cache.ServiceLocator.GetInstance<IStParaRepository>().GetObject(paraHvo); // If this is the last paragraph of a section then insert an // end of section mark, otherwise insert a paragraph mark. VwBoundaryMark boundaryMark = (para.IsFinalParaInText) ? VwBoundaryMark.endOfSection : VwBoundaryMark.endOfParagraph; vwenv.SetParagraphMark(boundaryMark); int flid = m_cache.ServiceLocator.GetInstance<Virtuals>().StParaIsFinalParaInText; vwenv.NoteDependency(new [] { paraHvo}, new [] { flid}, 1); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// This is the main interesting method of displaying objects and fragments of them. /// A Scripture is displayed by displaying its Books; /// and a Book is displayed by displaying its Title and Sections; /// and a Section is diplayed by displaying its Heading and Content; /// which are displayed by using the standard view constructor for StText. /// </summary> /// <param name="vwenv"></param> /// <param name="hvo"></param> /// <param name="frag"></param> /// ------------------------------------------------------------------------------------ public override void Display(IVwEnv vwenv, int hvo, int frag) { CheckDisposed(); switch(frag) { case (int)FootnoteFrags.kfrScripture: case (int)ScrFrags.kfrScripture: { vwenv.NoteDependency(new[] { hvo }, new[] { ScrBookTags.kflidFootnotes }, 1); // This fragment should only be used on full refresh - clear the user prompt // flags so they will be shown again. ClearUserPromptUpdates(); // We add this lazy - we will expand some of it immediately, but the non- // visible parts will remain lazy! vwenv.NoteDependency(new[]{m_cache.LanguageProject.TranslatedScriptureOA.Hvo}, new[]{ScriptureTags.kflidScriptureBooks}, 1); vwenv.AddLazyVecItems(BooksTag, this, frag == (int)ScrFrags.kfrScripture ? (int)ScrFrags.kfrBook : (int)FootnoteFrags.kfrBook); // Add a 48 point gap at the bottom of the view if (!PrintLayout && (frag != (int)FootnoteFrags.kfrScripture)) vwenv.AddSimpleRect((int)ColorUtil.ConvertColorToBGR(BackColor), -1, 48000, 0); break; } case (int)ScrFrags.kfrBook: { vwenv.OpenDiv(); vwenv.AddObjProp(ScrBookTags.kflidTitle, this, (int)StTextFrags.kfrText); vwenv.AddLazyVecItems(ScrBookTags.kflidSections, this, (int)ScrFrags.kfrSection); // Add a 48 point gap at the bottom of the view if (!PrintLayout && m_fShowTailingSpace) vwenv.AddSimpleRect((int)ColorUtil.ConvertColorToBGR(BackColor), -1, 48000, 0); if (!PrintLayout) InsertBookSeparator(hvo, vwenv); vwenv.CloseDiv(); break; } case (int)ScrFrags.kfrSection: { vwenv.OpenDiv(); vwenv.AddObjProp(ScrSectionTags.kflidHeading, this, (int)StTextFrags.kfrText); vwenv.AddObjProp(ScrSectionTags.kflidContent, this, (int)StTextFrags.kfrText); vwenv.CloseDiv(); break; } case (int)StTextFrags.kfrPara: if (PrintLayout || !m_fDisplayInTable) { // We are displaying Scripture or a print layout view base.Display(vwenv, hvo, frag); } else { // We are displaying a back translation or Scripture in draftview in a table // Open a table to display the BT para in column 1, and the icon in column 2. VwLength vlTable; // we use this to specify that the table takes 100% of the width. vlTable.nVal = 10000; vlTable.unit = VwUnit.kunPercent100; VwLength vlColumn; // and this one to specify 90% for the text vlColumn.nVal = DisplayTranslation ? 9000 : 10000; vlColumn.unit = VwUnit.kunPercent100; int nColumns = DisplayTranslation ? 2 : 1; vwenv.OpenTable(nColumns, // One or two columns. vlTable, // Table uses 100% of available width. 0, // Border thickness. VwAlignment.kvaLeft, // Default alignment. VwFramePosition.kvfpVoid, // No border. //VwFramePosition.kvfpBox, //VwRule.kvrlAll, // rule lines between cells VwRule.kvrlNone, 0, //No space between cells. 0, //No padding inside cells. false); // Specify column widths. The first argument is the number of columns, // not a column index. vwenv.MakeColumns(nColumns, vlColumn); vwenv.OpenTableBody(); vwenv.OpenTableRow(); // Display paragraph in the first cell vwenv.OpenTableCell(1, 1); InsertParagraphBody(vwenv, hvo, frag, true, ContentType, this); vwenv.CloseTableCell(); if (DisplayTranslation) { // Stylesheet should never be null for a VC that displays BTs, but to be safe... Debug.Assert (m_stylesheet != null); if (m_stylesheet != null) { IStPara para = m_cache.ServiceLocator.GetInstance<IStParaRepository>().GetObject(hvo); ITsTextProps styleRules = para.StyleRules; if (styleRules == null) { Debug.Fail("Style Rules should not be null"); styleRules = NormalStyle; } string paraStyleName = styleRules.GetStrPropValue((int)FwTextPropType.ktptNamedStyle); ITsTextProps ttp = m_stylesheet.GetStyleRgch(0, paraStyleName); Debug.Assert(ttp != null); if (ttp != null) { int var; int spaceBefore = ttp.GetIntPropValues((int)FwTextPropType.ktptSpaceBefore, out var); if (spaceBefore > 0) vwenv.set_IntProperty((int)FwTextPropType.ktptPadTop, var, spaceBefore); } } // BT status icon in the next cell, not editable vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvEnum, (int)TptEditable.ktptNotEditable); vwenv.OpenTableCell(1, 1); vwenv.AddObjVec(StTxtParaTags.kflidTranslations, this, (int)ScrFrags.kfrBtTranslationStatus); vwenv.CloseTableCell(); } // Close table vwenv.CloseTableRow(); vwenv.CloseTableBody(); vwenv.CloseTable(); } break; case (int)ScrFrags.kfrBtTranslationStatus: { ICmTranslation trans = m_cache.ServiceLocator.GetInstance<ICmTranslationRepository>().GetObject(hvo); if (trans != null) { string status = trans.Status.get_String(m_wsDefault).Text; IPicture picture; if (status == BackTranslationStatus.Checked.ToString()) picture = m_CheckedPic; else if (status == BackTranslationStatus.Finished.ToString()) picture = m_FinishedPic; else picture = m_UnfinishedPic; vwenv.OpenDiv(); vwenv.AddPicture(picture, -1, 0, 0); vwenv.NoteDependency(new [] {hvo}, new [] {CmTranslationTags.kflidStatus}, 1); vwenv.CloseDiv(); } } break; default: base.Display(vwenv, hvo, frag); break; } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Check the given translation to see if the text is empty. If so, then insert a /// user prompt. /// </summary> /// <param name="vwenv">view environment</param> /// <param name="trans">translation to be displayed</param> /// <returns>true if an empty string was substituted for missing/empty StText</returns> /// ------------------------------------------------------------------------------------ protected override bool InsertTranslationUserPrompt(IVwEnv vwenv, ICmTranslation trans) { // No user prompt in any of these conditions if (trans == null || m_updatedPrompts.Contains(trans.Hvo)) // user interaction has updated prompt return false; // If there is text in the translation then do not add a prompt. if (trans.Translation.get_String(m_wsDefault).Length > 0) return false; // If there is no text in the parent paragraph then do not place a prompt in the // back translation. if (((IStTxtPara)trans.Owner).Contents.Length == 0) return false; // Insert the prompt. vwenv.NoteDependency(new int[] { trans.Hvo }, new int[] { CmTranslationTags.kflidTranslation}, 1); vwenv.AddProp(SimpleRootSite.kTagUserPrompt, this, (int)CmTranslationTags.kflidTranslation); return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// This is the main interesting method of displaying objects and fragments of them. /// A Scripture is displayed by displaying its Books; /// and a Book is displayed by displaying its Title and Sections; /// and a Section is diplayed by displaying its Heading and Content; /// which are displayed by showing the style for each paragraph in the StText. /// </summary> /// <param name="vwenv"></param> /// <param name="hvo"></param> /// <param name="frag"></param> /// ------------------------------------------------------------------------------------ public override void Display(IVwEnv vwenv, int hvo, int frag) { CheckDisposed(); ISilDataAccess silDataAccess = vwenv.DataAccess; int wsUser = Cache.WritingSystemFactory.UserWs; switch(frag) { case (int)FootnoteFrags.kfrBook: case (int)ScrFrags.kfrBook: { vwenv.OpenDiv(); if (m_displayForFootnotes) { vwenv.AddObjVecItems(ScrBookTags.kflidFootnotes, this, (int)FootnoteFrags.kfrFootnoteStyles); } else { vwenv.AddObjProp(ScrBookTags.kflidTitle, this, (int)ScrFrags.kfrTextStyles); vwenv.AddLazyVecItems(ScrBookTags.kflidSections, this, (int)ScrFrags.kfrSection); InsertBookSeparator(hvo, vwenv); } vwenv.CloseDiv(); break; } case (int)ScrFrags.kfrSection: { vwenv.OpenDiv(); vwenv.AddObjProp(ScrSectionTags.kflidHeading, this, (int)ScrFrags.kfrTextStyles); vwenv.AddObjProp(ScrSectionTags.kflidContent, this, (int)ScrFrags.kfrTextStyles); vwenv.CloseDiv(); break; } case (int)ScrFrags.kfrTextStyles: { // We need to show something, since the current view code can't handle a property // containing no boxes. if (HandleEmptyText(vwenv, hvo)) break; if (m_fLazy) { vwenv.AddLazyVecItems(StTextTags.kflidParagraphs, this, (int)ScrFrags.kfrParaStyles); } else { vwenv.AddObjVecItems(StTextTags.kflidParagraphs, this, (int)ScrFrags.kfrParaStyles); } break; } case (int)FootnoteFrags.kfrFootnoteStyles: { if (HandleEmptyText(vwenv, hvo)) break; vwenv.AddObjVecItems(StTextTags.kflidParagraphs, this, (int)ScrFrags.kfrParaStyles); break; } case (int)ScrFrags.kfrParaStyles: { var tsTextProps = silDataAccess.get_UnknownProp(hvo, StParaTags.kflidStyleRules) as ITsTextProps; string styleName = ScrStyleNames.Normal; if (tsTextProps != null) styleName = tsTextProps.GetStrPropValue((int)FwTextPropType.ktptNamedStyle); // To insert it into the view it has to be an ITsString ITsStrFactory tsStrFactory = TsStrFactoryClass.Create(); // Last arg is writing system. Should we use English? UI writing system? // Note that when we support localization of style names this code will need // to be enhanced as the stylename from the TsTextProps will be a raw name or // GUID that the user shouldn't see. ITsString tssStyle = tsStrFactory.MakeStringRgch(styleName, styleName.Length, wsUser); // To make the pile align things properly, top and bottom margins for the // matching boxes must be the same as the original. // A 'concordance' paragraph is a way of preventing wrapping. vwenv.OpenConcPara(0, 0, 0, 0); vwenv.AddString(tssStyle); // Since we looked up this property directly rather than going through the vwenv (which // there seems to be no way to do for Unknown-type properties as yet), we need to tell // the view to update this paragraph if the properties of the paragraph are changed. vwenv.NoteDependency(new[] {hvo}, new[] {StParaTags.kflidStyleRules}, 1); vwenv.CloseParagraph(); break; } default: base.Display(vwenv, hvo, frag); break; } }
protected override void DisplayObjectProperty(IVwEnv vwenv, int hvo) { vwenv.NoteDependency(new int[] {m_hvoOwner}, new int[] {m_flid}, 1); vwenv.AddObj(hvo, this, AtomicReferenceView.kFragObjName); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Check the given translation to see if the text is empty. If so, then insert a /// user prompt. /// </summary> /// <param name="vwenv">view environment</param> /// <param name="hvo">id of translation to be displayed</param> /// <returns>true if an empty string was substituted for missing/empty StText</returns> /// ------------------------------------------------------------------------------------ protected override bool InsertTranslationUserPrompt(IVwEnv vwenv, int hvo) { // No user prompt in any of these conditions if (hvo == 0 || Cache.GetClassOfObject(hvo) != (int)CmTranslation.kClassId || m_updatedPrompts.Contains(hvo)) // user interaction has updated prompt { return false; } // If there is text in the translation then do not add a prompt. CmTranslation trans = new CmTranslation(Cache, hvo); if (trans.Translation.GetAlternative(m_wsDefault).Text != null) return false; // If there is no text in the parent paragraph then do not place a prompt in the // back translation. StTxtPara parentPara = new StTxtPara(Cache, trans.OwnerHVO); if (parentPara.Contents.Text == null) return false; // Insert the prompt. vwenv.NoteDependency(new int[] { hvo }, new int[] { (int)CmTranslation.CmTranslationTags.kflidTranslation}, 1); vwenv.AddProp(SimpleRootSite.kTagUserPrompt, this, (int)CmTranslation.CmTranslationTags.kflidTranslation); return true; }