void VerifyLabel(int iseg, string label) { int hvoSeg = Cache.GetVectorItem(m_para.Hvo, kflidSegments, iseg); CmBaseAnnotation seg = CmObject.CreateFromDBObject(Cache, hvoSeg, false) as CmBaseAnnotation; Assert.IsTrue(SegmentBreaker.HasLabelText(m_para.Contents.UnderlyingTsString, seg.BeginOffset, seg.EndOffset), label); }
public void AnnotationStringValue() { // Use old-style creation to support in-memory testing; cf CmBaseAnnotation.CreateUnownedCba. CmBaseAnnotation ann = new CmBaseAnnotation(); Cache.LangProject.AnnotationsOC.Add(ann); ann.BeginOffset = 4; ann.EndOffset = 10; // The below is a non-standard usage of the TextOA field. It works for this test as a place // to store the text we're testing, but normally it's purpose is for a (possibly) multi-paragraph // commentary on the target of the annotation (pointed to by BeginObject). This would be similar to // how a ScriptureNote.Discussion points to a JournalText (subclass of StText). ann.TextOA = new StText(); StTxtPara para = new StTxtPara(); ann.TextOA.ParagraphsOS.Append(para); para.Contents.Text = "pus yalola nihimbilira. nihimbilira pus yalola. hesyla nihimbilira."; ann.BeginObjectRA = para; ann.EndObjectRA = para; ann.Flid = (int)StTxtPara.StTxtParaTags.kflidContents; // Install the virtual property and get its id. int flid = CmBaseAnnotation.StringValuePropId(Cache); // The text of the annotation should be 'yalola'. Assert.AreEqual("yalola", Cache.MainCacheAccessor.get_StringProp(ann.Hvo, flid).Text, "Wrong StringValue for 'yalola' annotation"); }
protected InterlinearExporter(FdoCache cache, XmlWriter writer, int hvoRoot, InterlinLineChoices lineChoices, InterlinVc vc, ITsString tssTextName, ITsString tssTextAbbreviation) : base(null, cache.MainCacheAccessor, hvoRoot) { m_cache = cache; m_writer = writer; ktagParaSegments = InterlinVc.ParaSegmentTag(cache); ktagSegmentForms = InterlinVc.SegmentFormsTag(cache); m_flidStringValue = CmBaseAnnotation.StringValuePropId(cache); m_lineChoices = lineChoices; m_defaultGlossVirtFlid = BaseVirtualHandler.GetInstalledHandlerTag(m_cache, "WfiMorphBundle", "DefaultSense"); m_vc = vc; m_tssPendingTitle = tssTextName; m_tssTitleAbbreviation = tssTextAbbreviation; // Get morphtype information that we need later. (plus stuff we don't...) See LT-8288. IMoMorphType mmtStem; IMoMorphType mmtPrefix; IMoMorphType mmtSuffix; IMoMorphType mmtInfix; IMoMorphType mmtBoundStem; IMoMorphType mmtSimulfix; IMoMorphType mmtSuprafix; MoMorphType.GetMajorMorphTypes(cache, out mmtStem, out mmtPrefix, out mmtSuffix, out mmtInfix, out mmtBoundStem, out m_mmtProclitic, out m_mmtEnclitic, out mmtSimulfix, out mmtSuprafix); }
private ICmBaseAnnotation MakeSegment(IStTxtPara para, int beginOffset, int length) { ICmBaseAnnotation seg = CmBaseAnnotation.CreateUnownedCba(Cache); seg.BeginObjectRA = para; seg.BeginOffset = beginOffset; seg.EndOffset = beginOffset + length; seg.AnnotationTypeRAHvo = m_hvoSegDefn; ISilDataAccess sda = para.Cache.MainCacheAccessor; int[] segments; if (sda.get_IsPropInCache(para.Hvo, kflidSegments, (int)CellarModuleDefns.kcptReferenceSequence, 0)) { int[] segmentsT = Cache.GetVectorProperty(para.Hvo, kflidSegments, true); segments = new int[segmentsT.Length]; Array.Copy(segmentsT, segments, segmentsT.Length); segments[segments.Length - 1] = seg.Hvo; } else { segments = new int[] { seg.Hvo }; } para.Cache.VwCacheDaAccessor.CacheVecProp(seg.Hvo, kflidSegments, segments, segments.Length); return(seg); }
/// <summary> /// Here we have a reference to IText, which can reference ScrFdo, so unlike the base class /// we can give a meaningful definition to label segment. /// </summary> /// <param name="hvo"></param> /// <returns></returns> protected override bool IsLabelSegment(int hvo) { CmBaseAnnotation seg = (CmBaseAnnotation)CmObject.CreateFromDBObject(Cache, hvo); StTxtPara para = seg.BeginObjectRA as StTxtPara; return(SegmentBreaker.HasLabelText(para.Contents.UnderlyingTsString, seg.BeginOffset, seg.EndOffset)); }
public void ValidatePhEnvironment_StringRepresentation() { CheckDisposed(); ConstraintFailure failure = null; FdoObjectSet <ICmBaseAnnotation> os = null; int strRepFlid = (int)PhEnvironment.PhEnvironmentTags.kflidStringRepresentation; PhEnvironment env = (PhEnvironment)m_fdoCache.LangProject.PhonologicalDataOA.EnvironmentsOS.Append(new PhEnvironment()); os = CmBaseAnnotation.AnnotationsForObject(m_fdoCache, env.Hvo); Assert.AreEqual(0, os.Count, "Wrong starting count of annotations."); env.StringRepresentation.Text = @"/ [BADCLASS] _"; Assert.IsFalse(env.CheckConstraints(strRepFlid, out failure)); Assert.IsNotNull(failure, "Didn't get an object back from the CheckConstraints method."); //Assert.IsTrue(obj is CmBaseAnnotation, "Didn't get a CmBaseAnnotation back from the Validate call."); os = CmBaseAnnotation.AnnotationsForObject(m_fdoCache, env.Hvo); Assert.AreEqual(1, os.Count, "Wrong invalid count of annotations."); env.StringRepresentation.Text = @"/ d _"; Assert.IsTrue(env.CheckConstraints(strRepFlid, out failure)); Assert.IsNull(failure, "Got an object back from the CheckConstraints method."); os = CmBaseAnnotation.AnnotationsForObject(m_fdoCache, env.Hvo); Assert.AreEqual(0, os.Count, "Wrong valid count of annotations."); }
private void VerifySegment(int hvoSeg, int beginOffset, int endOffset, int hvoPara, string label) { CmBaseAnnotation cba = new CmBaseAnnotation(Cache, hvoSeg); Assert.AreEqual(beginOffset, cba.BeginOffset, label + " - begin"); Assert.AreEqual(endOffset, cba.EndOffset, label + " - end"); Assert.AreEqual(hvoPara, cba.BeginObjectRAHvo, label + " - para"); }
internal ICmBaseAnnotation MakeMarkerAnnotation(int icol, ICmIndirectAnnotation row, ICmPossibility marker) { CmBaseAnnotation cba = MakeBaseAnnotation(); cba.BeginObjectRA = marker; InitializeCca(cba, icol, row); return(cba); }
private void EnsureCbaIsReal(ref int hvo) { ICmBaseAnnotation cba = CmBaseAnnotation.CreateFromDBObject(m_cache, hvo); if (cba != null && cba.IsDummyObject) { hvo = CmBaseAnnotation.ConvertBaseAnnotationToReal(m_cache, hvo).Hvo; } }
protected override void WriteStartWord(int hvo) { base.WriteStartWord(hvo); ICmBaseAnnotation cba = CmBaseAnnotation.CreateFromDBObject(m_cache, hvo); // avoid writing guids for punctuations, since some may be dummy annotations. if (cba.AnnotationTypeRAHvo != kPunctuationAnnType) { WriteGuidAttributeForObj(hvo); } }
protected override void EnsureXficCbaIsRealIfNeeded(ref int hvo) { ICmBaseAnnotation cba = CmBaseAnnotation.CreateFromDBObject(m_cache, hvo); // avoid converting dummy punctuations, since we don't always have guids for those // because our dummy conversion process does not update the cache for punctuation types. if (cba.AnnotationTypeRAHvo != kPunctuationAnnType) { EnsureCbaIsReal(ref hvo); } base.EnsureXficCbaIsRealIfNeeded(ref hvo); }
/// <summary> /// It's safer to save the paragraph here...the segment might get deleted by one of the edits /// we're monitoring. /// </summary> /// <param name="newMonitorObject"></param> protected override void SetMonitorObject(CmObject newMonitorObject) { base.SetMonitorObject(newMonitorObject); if (m_objectToMonitor != null) { CmBaseAnnotation seg = (m_objectToMonitor as CmIndirectAnnotation).AppliesToRS[0] as CmBaseAnnotation; m_para = new ScrTxtPara(m_cache, seg.BeginObjectRAHvo); } else { m_para = null; } }
public void ConstraintErrors() { CheckDisposed(); IMoMorphData target = m_fdoCache.LangProject.MorphologicalDataOA; CmBaseAnnotation.RemoveErrorAnnotationsForObject(m_fdoCache, target.Hvo); Assert.AreEqual(0, CmBaseAnnotation.ErrorAnnotationsForObject(m_fdoCache, target.Hvo).Count); ConstraintFailure failure = new ConstraintFailure(target, 0, "testing"); Assert.AreEqual(1, CmBaseAnnotation.ErrorAnnotationsForObject(m_fdoCache, target.Hvo).Count); CmBaseAnnotation.RemoveErrorAnnotationsForObject(m_fdoCache, target.Hvo); Assert.AreEqual(0, CmBaseAnnotation.ErrorAnnotationsForObject(m_fdoCache, target.Hvo).Count); }
// Make some sort of wfics for the text of the specified paragraph. Assumes no double spaces! // Caches results and does not repeat on same para internal int[] MakeAnnotations(StTxtPara para) { int[] previous; if (m_annotations.TryGetValue(para.Hvo, out previous)) { return(previous); } string contents = para.Contents.Text; string[] words = contents.Split(new char[] { ' ', '.' }); int ich = 0; List <int> results = new List <int>(); ICmAnnotationDefn WficType = CmAnnotationDefn.Twfic(Cache); foreach (string word in words) { if (word == "") { ich++; continue; } WfiWordform wordform = new WfiWordform(); Cache.LangProject.WordformInventoryOA.WordformsOC.Add(wordform); wordform.Form.SetAlternative(word, Cache.DefaultVernWs); // JohnT: This should ideally use CmBaseAnnotation.CreateUnownedCba. But most or all uses of this // method are memory-only tests, and that method requires a database. CmBaseAnnotation cba = new CmBaseAnnotation(); Cache.LangProject.AnnotationsOC.Add(cba); cba.BeginOffset = ich; ich += word.Length; cba.EndOffset = ich; ich++; // past space or dot cba.BeginObjectRA = para; cba.AnnotationTypeRA = WficType; //cba.AnnotationTypeRA = ?? can we get CmAnnotationDefn.Twfic(Cache) with a non-database cache? WfiAnalysis analysis = new WfiAnalysis(); wordform.AnalysesOC.Add(analysis); WfiGloss gloss = new WfiGloss(); analysis.MeaningsOC.Add(gloss); gloss.Form.SetAlternative(word + "Gloss" + ich, Cache.DefaultAnalWs); cba.InstanceOfRA = gloss; results.Add(cba.Hvo); } int[] result = results.ToArray(); m_annotations[para.Hvo] = result; return(result); }
/// <summary> /// Get the segments of the paragraph. This is public static to allow others to use /// the same code. This will actually parse the text of the paragraph, create any /// segments that do not yet exist, and create any needed free translation annotations /// to go with them. It also sets the kflidSegments (virtual) property of the paragraph, /// and the kflidFT (virtual) property of the segments. /// </summary> /// <returns>array of ICmBaseAnnotation objects for the segments</returns> public static ICmBaseAnnotation[] GetMainParaSegments(IStTxtPara para, int wsBt, out int[] paraSegs) { FdoCache cache = EnsureMainParaSegments(para, wsBt); int kflidSegments = StTxtPara.SegmentsFlid(cache); paraSegs = cache.GetVectorProperty(para.Hvo, kflidSegments, true); ICmBaseAnnotation[] segments = new ICmBaseAnnotation[paraSegs.Length]; for (int i = 0; i < paraSegs.Length; i++) { // This prevents trying to really load it from the database, which is typically not // useful and actully causes failures of some tests when using a memory cache that considers all // objects to be non-dummies. cache.VwCacheDaAccessor.CacheIntProp(paraSegs[i], (int)CmObjectFields.kflidCmObject_Class, (int)CmBaseAnnotation.kclsidCmBaseAnnotation); segments[i] = new CmBaseAnnotation(cache, paraSegs[i]); } return(segments); }
private void btnAssign_Click(object sender, System.EventArgs e) { using (new SIL.FieldWorks.Common.Utils.WaitCursor(this, false)) { int newTargetHvo = (int)(tvTarget.SelectedNode.Tag); List <int> checkedItems = m_currentBrowseView.CheckedItems; int virtFlid = m_currentBrowseView.Clerk.VirtualFlid; int srcHvo = (int)tvSource.SelectedNode.Tag; if (checkedItems.Count > 0) { m_toolStripProgressBar.Minimum = 0; m_toolStripProgressBar.Maximum = checkedItems.Count; m_toolStripProgressBar.Step = 1; m_toolStripProgressBar.Value = 0; } foreach (int annHvo in checkedItems) { ICmBaseAnnotation ann = null; if (m_cache.IsDummyObject(annHvo)) { ann = ConvertDummyToReal(srcHvo, virtFlid, annHvo) as ICmBaseAnnotation; Debug.Assert(ann != null); } else { ann = CmBaseAnnotation.CreateFromDBObject(m_cache, annHvo); } ann.InstanceOfRAHvo = newTargetHvo; m_cache.SetIntProperty(ann.Hvo, XmlBrowseViewVc.ktagItemSelected, 0); m_toolStripProgressBar.PerformStep(); } // After these changes, we need to refresh the display. PropChanged() redraws the // list, but incorrect (and inconsistent) items are then displayed. See LT-8703. // Refreshing the clerk reloads the list and then redraws it. m_cache.PropChanged(null, PropChangeType.kpctNotifyAll, srcHvo, virtFlid, 0, 0, checkedItems.Count); m_currentBrowseView.Clerk.OnRefresh(null); CheckAssignBtnEnabling(); m_toolStripProgressBar.Value = 0; SetRecordStatus(); } }
protected override void ValidateSegFormOuterElements(object expectedSegForm, object actualSegForm, string segFormContext) { // First validate the twfic guid. ICmBaseAnnotation cbaExpected = CmBaseAnnotation.CreateFromDBObject(m_cache, (int)expectedSegForm); if (cbaExpected.AnnotationTypeRAHvo == PunctuationAnnotationType) { // we are not exporting punctuation guids, since some are dummys without guids. ValidateMissingGuidForNode(actualSegForm as XmlNode, segFormContext); } else { Assert.IsFalse(cbaExpected.IsDummyObject, String.Format("We expected our paragraph segform ({0}) in context {1} to be real.", cbaExpected.Hvo, segFormContext)); string guidActual; ValidateCmObjectGuidForNode((int)expectedSegForm, actualSegForm as XmlNode, segFormContext, out guidActual); ValidateGuidIsNonrepeating(guidActual, segFormContext); } base.ValidateSegFormOuterElements(expectedSegForm, actualSegForm, segFormContext); }
// If hvo is an CmIndirectAnnotation that is the free translation of a segment of Scripture, return the // annotation; otherwise return null. CmIndirectAnnotation GetAnnotation(int hvo) { if (m_cache.GetClassOfObject(hvo) != CmIndirectAnnotation.kclsidCmIndirectAnnotation) { return(null); } // Return result unless it is disqualified somehow. CmIndirectAnnotation result = CmObject.CreateFromDBObject(m_cache, hvo) as CmIndirectAnnotation; if (result.AnnotationTypeRAHvo != m_hvoFtDefn) { return(null); // not a free translation } if (result.AppliesToRS.Count == 0) { return(null); // huh? all FTs should applyTo their segment. } CmBaseAnnotation cbaSeg = result.AppliesToRS[0] as CmBaseAnnotation; if (cbaSeg == null) { return(null); // huh? again for same reason } StTxtPara para = cbaSeg.BeginObjectRA as StTxtPara; if (para == null) { return(null); // also unlikely, a segment should link to a paragraph } // Make sure the paragraph belongs to Scripture. if (!ScrTxtPara.IsScripturePara(para.Hvo, m_cache)) { return(null); // not Scripture } return(result); // finally! }
protected void CreateTestData() { // Create required virtual properties XmlDocument doc = new XmlDocument(); // Subset of Flex virtuals required for parsing paragraphs etc. doc.LoadXml( "<virtuals>" + "<virtual modelclass=\"StTxtPara\" virtualfield=\"Segments\">" + "<dynamicloaderinfo assemblyPath=\"ITextDll.dll\" class=\"SIL.FieldWorks.IText.ParagraphSegmentsVirtualHandler\"/>" + "</virtual>" + "<virtual modelclass=\"WfiWordform\" virtualfield=\"OccurrencesInTexts\" destinationClass=\"CmBaseAnnotation\">" + "<dynamicloaderinfo assemblyPath=\"ITextDll.dll\" class=\"SIL.FieldWorks.IText.OccurrencesInTextsVirtualHandler\"/>" + "</virtual>" + "<virtual modelclass=\"WfiWordform\" virtualfield=\"HumanApprovedAnalyses\" computeeverytime=\"true\">" + "<dynamicloaderinfo assemblyPath=\"FDO.dll\" class=\"SIL.FieldWorks.FDO.FDOSequencePropertyVirtualHandler\"/>" + "</virtual>" + "<virtual modelclass=\"WfiWordform\" virtualfield=\"HumanNoOpinionParses\" computeeverytime=\"true\" requiresRealParserGeneratedData=\"true\">" + "<dynamicloaderinfo assemblyPath=\"FDO.dll\" class=\"SIL.FieldWorks.FDO.FDOSequencePropertyVirtualHandler\"/>" + "</virtual>" + "<virtual modelclass=\"WfiWordform\" virtualfield=\"HumanDisapprovedParses\" computeeverytime=\"true\">" + "<dynamicloaderinfo assemblyPath=\"FDO.dll\" class=\"SIL.FieldWorks.FDO.FDOSequencePropertyVirtualHandler\"/>" + "</virtual>" + "<virtual modelclass=\"WfiWordform\" virtualfield=\"FullConcordanceCount\" depends=\"OccurrencesInTexts\" computeeverytime=\"true\">" + "<dynamicloaderinfo assemblyPath=\"FDO.dll\" class=\"SIL.FieldWorks.FDO.IntegerPropertyVirtualHandler\"/>" + "</virtual>" + "<virtual modelclass=\"WfiWordform\" virtualfield=\"UserCount\" bulkLoadMethod=\"LoadAllUserCounts\" computeeverytime=\"true\">" + "<dynamicloaderinfo assemblyPath=\"FDO.dll\" class=\"SIL.FieldWorks.FDO.IntegerPropertyVirtualHandler\"/>" + "</virtual>" + "<virtual modelclass=\"WfiWordform\" virtualfield=\"ParserCount\" bulkLoadMethod=\"LoadAllParserCounts\" computeeverytime=\"true\" requiresRealParserGeneratedData=\"true\">" + "<dynamicloaderinfo assemblyPath=\"FDO.dll\" class=\"SIL.FieldWorks.FDO.IntegerPropertyVirtualHandler\"/>" + "</virtual>" + "<virtual modelclass=\"WfiWordform\" virtualfield=\"ConflictCount\" computeeverytime=\"true\" requiresRealParserGeneratedData=\"true\">" + "<dynamicloaderinfo assemblyPath=\"FDO.dll\" class=\"SIL.FieldWorks.FDO.IntegerPropertyVirtualHandler\"/>" + "</virtual>" + "<virtual modelclass=\"WordformInventory\" virtualfield=\"ConcordanceWords\" destinationClass=\"WfiWordform\">" + "<dynamicloaderinfo assemblyPath=\"ITextDll.dll\" class=\"SIL.FieldWorks.IText.ConcordanceWordsVirtualHandler\"/>" + "</virtual>" + "</virtuals>"); BaseVirtualHandler.InstallVirtuals(doc.DocumentElement, Cache); m_text = new Text(); Cache.LangProject.TextsOC.Add(m_text); string para1 = "Axx simplexx testxx withxx axx lotxx ofxx wordsxx endingxx inxx xx"; string para2 = "axx sentencexx axx havingxx axx lotxx ofxx axx"; m_para1 = new StTxtPara(); m_stText = new StText(); m_text.ContentsOA = m_stText; m_para1 = MakePara(para1); m_para2 = MakePara(para2); m_wfAxx = WfiWordform.CreateFromDBObject(Cache, WfiWordform.FindOrCreateWordform(Cache, "axx", Cache.DefaultVernWs, true)); // Make one real annotation, which also serves to link the Axx to this. m_cbaAxx = CmBaseAnnotation.CreateUnownedCba(Cache); m_cbaAxx.InstanceOfRA = m_wfAxx; m_cbaAxx.BeginObjectRA = m_para1; m_cbaAxx.BeginOffset = 0; m_cbaAxx.EndOffset = 3; m_cbaAxx.Flid = (int)StTxtPara.StTxtParaTags.kflidContents; m_cbaAxx.AnnotationTypeRA = CmAnnotationDefn.Twfic(Cache); // Make another real annotation, which should get updated during Apply. IWfiWordform wf2 = WfiWordform.CreateFromDBObject(Cache, WfiWordform.FindOrCreateWordform(Cache, "lotxx", Cache.DefaultVernWs, true)); m_cba2 = CmBaseAnnotation.CreateUnownedCba(Cache); m_cba2.InstanceOfRA = wf2; m_cba2.BeginObjectRA = m_para2; m_cba2.BeginOffset = "axx sentencexx axx havingxx axx ".Length; m_cba2.EndOffset = m_cba2.BeginOffset + "lotxx".Length; m_cba2.AnnotationTypeRA = CmAnnotationDefn.Twfic(Cache); m_cba2.Flid = (int)StTxtPara.StTxtParaTags.kflidContents; ParagraphParser.ConcordTexts(Cache, new int[] { m_stText.Hvo }, new NullProgressState()); m_axxOccurrences = m_wfAxx.ConcordanceIds; m_para1Occurrences = OccurrencesInPara(m_para1.Hvo, m_axxOccurrences); m_para2Occurrences = OccurrencesInPara(m_para2.Hvo, m_axxOccurrences); // to improve test isolation, be sure to null things not always initialized. m_wfaAxe = m_wfaCut = m_wfaCutIt = m_wfaNotRude = null; m_cAnalyses = 0; }
private int MakeWfic(int hvoObj, int iBegCh, int iEndCh) { return(CmBaseAnnotation.CreateRealAnnotation(Cache, s_kTwficAnnType, 0, hvoObj, 0, iBegCh, iEndCh).Hvo); }
internal void Run(bool fMakeSelectionInNewFreeformAnnotation) { IVwSelection sel = null; if (m_site is InterlinDocChild) { sel = (m_site as InterlinDocChild).MakeSandboxSel(); } // If there's no sandbox selection, there may be one in the site itself, perhaps in another // free translation. if (sel == null) { sel = m_site.RootBox.Selection; } if (sel == null) { return; // Enhance JohnT: give an error, or disable the command. } int cvsli = sel.CLevels(false); cvsli--; // CLevels includes the string property itself, but AllTextSelInfo doesn't need it. // Out variables for AllTextSelInfo. int ihvoRoot; int tagTextProp; int cpropPrevious; int ichAnchor; int ichEnd; int ws; bool fAssocPrev; int ihvoEnd; ITsTextProps ttpBogus; // Main array of information retrived from sel that made combo. SelLevInfo[] rgvsli = SelLevInfo.AllTextSelInfo(sel, cvsli, out ihvoRoot, out tagTextProp, out cpropPrevious, out ichAnchor, out ichEnd, out ws, out fAssocPrev, out ihvoEnd, out ttpBogus); // Identify the segment. // This is important because although we are currently displaying just an StTxtPara, // eventually it might be part of a higher level structure. We want this to work // no matter how much higher level structure there is. int itagSegments = -1; for (int i = rgvsli.Length; --i >= 0;) { if (rgvsli[i].tag == m_vc.ktagParaSegments) { itagSegments = i; break; } } if (itagSegments == -1) { return; // Enhance JohnT: throw? disable command? Give an error? } int hvoSeg = rgvsli[itagSegments].hvo; if (m_fdoCache.IsDummyObject(hvoSeg)) { // we need to convert this into a real segment before proceeding. ICmBaseAnnotation cbaReal = CmBaseAnnotation.ConvertBaseAnnotationToReal(m_fdoCache, hvoSeg); hvoSeg = cbaReal != null ? cbaReal.Hvo : 0; rgvsli[itagSegments].hvo = hvoSeg; } ICmIndirectAnnotation ann = AddFreeformAnnotation(hvoSeg, m_hvoType); // If necessary (e.g., we just added a previously invisible FF annotation), // Reconstruct the root box. Otherwise, a simple PropChanged will do. if (m_fNeedReconstruct) { m_site.RootBox.Reconstruct(); // m_site.Invalidate(); // m_site.Update(); // necessary to get a lazy } if (!fMakeSelectionInNewFreeformAnnotation) { return; } // Now try to make a new selection in the FF we just made. // The elements of rgvsli from itagSegments onwards form a path to the segment. // In the segment we want the freeform propery, specifically the new one we just made. // We want to select at the start of it. SelLevInfo[] rgvsliNew = new SelLevInfo[rgvsli.Length - itagSegments + 1]; for (int i = 1; i < rgvsliNew.Length; i++) { rgvsliNew[i] = rgvsli[i + itagSegments - 1]; } // Work out how many freeforms are DISPLAYED before the (first occurrence of the) one we want to select. int ihvo = 0; Dictionary <int, List <int> > dict = m_vc.OrganizeFfAnnotations(hvoSeg); for (int i = m_choices.FirstFreeformIndex; i < m_choices.Count;) { int hvoAnnType = m_vc.SegDefnFromFfFlid(m_choices[i].Flid); List <int> annotations = null; if (dict.ContainsKey(hvoAnnType)) { annotations = dict[hvoAnnType]; } if (hvoAnnType == m_hvoType) { ihvo += annotations.IndexOf(ann.Hvo); break; // And that's where we want our selection!! } // Adjacent WSS of the same annotation count as only ONE object in the display. // So we advance i over as many items in m_choices as there are adjacent Wss // of the same flid. i += m_choices.AdjacentWssAtIndex(i).Length; // But each time we display this flid, we display ALL the objects, // so advance ihvo by the number of annotations of the type. int chvoAnn = annotations == null ? 0 : annotations.Count; ihvo += chvoAnn; } rgvsliNew[0].ihvo = ihvo; rgvsliNew[0].tag = m_vc.ktagSegFF; rgvsliNew[0].cpropPrevious = 0; m_site.RootBox.MakeTextSelInObj(0, rgvsliNew.Length, rgvsliNew, 0, null, true, true, false, false, true); }
/// <summary> /// Given that segment is a 'label' segment (typically an embedded identifying number), /// figure out what to display as the corresponding label in a back translation view. /// This is made separate so that TeStVc can override to use a different numbering scheme /// in the BT. /// </summary> /// <param name="segment"></param> /// <returns></returns> protected virtual ITsString GetBackTransLabelText(CmBaseAnnotation segment) { return(segment.TextAnnotated); }
/// ----------------------------------------------------------------------------------- /// <summary> /// This is the main interesting method of displaying objects and fragments of them. /// Here a text is displayed by displaying its paragraphs; /// and a paragraph is displayed by invoking its style rule, making a paragraph, /// and displaying its contents. /// </summary> /// <param name="vwenv">view environment</param> /// <param name="hvo">id of object to be displayed</param> /// <param name="frag">fragment of data</param> /// ----------------------------------------------------------------------------------- public override void Display(IVwEnv vwenv, int hvo, int frag) { CheckDisposed(); switch (frag) { case (int)StTextFrags.kfrFootnote: { if (HandleEmptyText(vwenv, hvo)) { break; } vwenv.AddObjVecItems((int)StText.StTextTags.kflidParagraphs, this, (int)StTextFrags.kfrFootnotePara); break; } case (int)StTextFrags.kfrText: { if (HandleEmptyText(vwenv, hvo)) { break; } if (m_fLazy) { vwenv.AddLazyVecItems((int)StText.StTextTags.kflidParagraphs, this, (int)StTextFrags.kfrPara); } else { vwenv.AddObjVecItems((int)StText.StTextTags.kflidParagraphs, this, (int)StTextFrags.kfrPara); } break; } case (int)StTextFrags.kfrFootnoteMarker: { StFootnote footnote = new StFootnote(Cache, hvo); if (footnote.DisplayFootnoteMarker) { DisplayFootnoteMarker(vwenv); } break; } case (int)StTextFrags.kfrLabel: { // The label is not editable. vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvEnum, (int)TptEditable.ktptNotEditable); vwenv.AddString(m_tssLabel); break; } case (int)StTextFrags.kfrPara: case (int)StTextFrags.kfrFootnotePara: { InsertParagraphBody(vwenv, hvo, frag, true, ContentType, this); break; } case (int)StTextFrags.kfrTranslation: { vwenv.set_IntProperty((int)FwTextPropType.ktptEditable, (int)FwTextPropVar.ktpvEnum, Editable ? (int)TptEditable.ktptIsEditable : (int)TptEditable.ktptNotEditable); // Display the translation, or its user prompt if (!InsertTranslationUserPrompt(vwenv, hvo)) { vwenv.AddStringAltMember((int)CmTranslation.CmTranslationTags.kflidTranslation, m_wsDefault, this); } break; } case (int)StTextFrags.kfrSegmentFreeTranslations: // Hvo is a CmBaseAnnotation of one segment of an StTxtPara. if (IsLabelSegment(hvo)) { CmBaseAnnotation segment = (CmBaseAnnotation)CmBaseAnnotation.CreateFromDBObject(Cache, hvo, false); vwenv.AddString(GetBackTransLabelText(segment)); vwenv.AddSimpleRect(ColorUtil.ConvertColorToBGR(this.BackColor), 1200, 0, 0); // a narrow space, font-neutral } else { vwenv.AddObjProp(StTxtPara.SegmentFreeTranslationFlid(Cache), this, (int)StTextFrags.kfrFreeTrans); vwenv.AddString(OneSpaceString); } break; case (int)StTextFrags.kfrFreeTrans: // Hvo is a CmIndirectAnnotation whose Contents are the free/back translation. vwenv.set_IntProperty((int)FwTextPropType.ktptBackColor, (int)FwTextPropVar.ktpvDefault, (int)ColorUtil.ConvertColorToBGR(SystemColors.Window)); ITsString tssVal = vwenv.DataAccess.get_MultiStringAlt(hvo, (int)CmAnnotation.CmAnnotationTags.kflidComment, BackTranslationWS); if (tssVal.Length == 0 && !SuppressPrompt(hvo, (int)CmAnnotation.CmAnnotationTags.kflidComment)) { vwenv.NoteDependency(new int[] { hvo }, new int[] { (int)CmAnnotation.CmAnnotationTags.kflidComment }, 1); vwenv.AddProp(SimpleRootSite.kTagUserPrompt, this, (int)CmAnnotation.CmAnnotationTags.kflidComment); // Almost invisibly narrow, but the Views code doesn't know it is invisible so it should prevent the prompts collapsing // into the margin. vwenv.AddSimpleRect(ColorUtil.ConvertColorToBGR(this.BackColor), 100, 0, 0); } else { ITsStrBldr bldr = tssVal.GetBldr(); bldr.Replace(0, bldr.Length, "", null); // reduce to empty string in ws. // We want it to change back to the prompt if all is deleted. vwenv.NoteStringValDependency(hvo, (int)CmAnnotation.CmAnnotationTags.kflidComment, BackTranslationWS, bldr.GetString()); vwenv.AddStringAltMember((int)CmAnnotation.CmAnnotationTags.kflidComment, BackTranslationWS, this); // This little separator is useful here, too. Temporarily the comment may be displayed this way even when empty, // and if there is ordinary text following, it is difficult to get an IP displayed in an empty run. vwenv.AddSimpleRect(ColorUtil.ConvertColorToBGR(this.BackColor), 100, 0, 0); } break; } }
protected override void ValidateSegForms(object expectedSegForm, object actualSegForm, string segFormContext) { string msg = "Mismatched {0} in {1}."; // Get the paragraph string corresponding to the annotation. ICmBaseAnnotation cbaExpected = CmBaseAnnotation.CreateFromDBObject(m_cache, (int)expectedSegForm); // first make sure we have a txt item. if (IsLineEnabled(InterlinLineChoices.kflidWord)) { ITsString tssExpectedForm = m_para.Contents.UnderlyingTsString.GetSubstring(cbaExpected.BeginOffset, cbaExpected.EndOffset); string lang = "xkal"; // Review: get WsLabel from tssExpectedForm. string actualForm = ""; if (cbaExpected.AnnotationTypeRAHvo == TwficAnnotationType) { actualForm = m_reader.GetItemInnerText(actualSegForm as XmlNode, "txt", lang); } else if (cbaExpected.AnnotationTypeRAHvo == PunctuationAnnotationType) { actualForm = m_reader.GetItemInnerText(actualSegForm as XmlNode, "punct", lang); } Assert.AreEqual(tssExpectedForm.Text, actualForm, String.Format(msg, "word", segFormContext)); } // if WordGloss is enabled, verify it. if (IsLineEnabled(InterlinLineChoices.kflidWordGloss)) { string lang = "en"; string actualWordGloss = m_reader.GetItemInnerText(actualSegForm as XmlNode, "gls", lang); if (cbaExpected.AnnotationTypeRAHvo == PunctuationAnnotationType) { // must be a punctuation (non-wfic) Assert.AreEqual("", actualWordGloss); } else { WfiGloss expectedGloss = null; int clsId = m_cache.GetClassOfObject(cbaExpected.InstanceOfRAHvo); if (clsId == WfiGloss.kclsidWfiGloss) { expectedGloss = new WfiGloss(m_cache, cbaExpected.InstanceOfRAHvo); } else if (clsId == WfiWordform.kclsidWfiWordform) { // should be a twfic so get its guess. StTxtPara.TwficInfo cbaInfo = new StTxtPara.TwficInfo(m_cache, cbaExpected.Hvo); int hvoExpectedGloss = cbaInfo.GetGuess(); if (hvoExpectedGloss != 0) { expectedGloss = new WfiGloss(m_cache, hvoExpectedGloss); } } // TODO: There are cases for other classes (e.g. WfiAnalysis) but // the tests do not generate those right now, so we won't worry about them right now. if (expectedGloss != null) { Assert.AreEqual(expectedGloss.Form.AnalysisDefaultWritingSystem, actualWordGloss); } else { Assert.AreEqual("", actualWordGloss); } } } // validate morph bundle lines. if (IsLineEnabled(InterlinLineChoices.kflidMorphemes) || IsLineEnabled(InterlinLineChoices.kflidLexEntries) || IsLineEnabled(InterlinLineChoices.kflidLexGloss) || IsLineEnabled(InterlinLineChoices.kflidLexPos)) { // compare exported document to the LexEntries information in the WfiAnalysis int hvoWfiAnalysis = 0; if (cbaExpected.AnnotationTypeRAHvo != PunctuationAnnotationType) { hvoWfiAnalysis = WfiAnalysis.GetWfiAnalysisFromInstanceOf(m_cache, cbaExpected.Hvo); } List <XmlNode> morphNodes = m_reader.GetMorphNodes(actualSegForm as XmlNode); if (hvoWfiAnalysis == 0) { // make sure we don't have any morphs. Assert.IsEmpty(morphNodes); } else { IWfiAnalysis wfiAnalysis = WfiAnalysis.CreateFromDBObject(m_cache, hvoWfiAnalysis); foreach (WfiMorphBundle morphBundle in wfiAnalysis.MorphBundlesOS) { int iMorph = morphBundle.OwnOrd - 1; string morphContext = segFormContext + "/Morph(" + iMorph + ")"; XmlNode actualMorphNode = iMorph < morphNodes.Count ? morphNodes[iMorph] : null; if (actualMorphNode == null) { Assert.Fail(String.Format(msg, "missing morph", morphContext)); } ITsString tssLexEntry = null; int hvoMorph = morphBundle.MorphRAHvo; if (hvoMorph != 0) { // first test the morph form if (IsLineEnabled(InterlinLineChoices.kflidMorphemes)) { string actualMorphForm = m_reader.GetItemInnerText(actualMorphNode as XmlNode, "txt", "xkal"); Assert.AreEqual(morphBundle.MorphRA.Form.VernacularDefaultWritingSystem, actualMorphForm, String.Format(msg, "morph/txt", morphContext)); } // next test the lex entry if (IsLineEnabled(InterlinLineChoices.kflidLexEntries)) { string actualLexEntry = m_reader.GetItemInnerText(actualMorphNode as XmlNode, "cf", "xkal"); string actualHomograph = m_reader.GetItemInnerText(actualMorphNode as XmlNode, "hn", "en"); string actualVariantTypes = m_reader.GetItemInnerText(actualMorphNode as XmlNode, "variantTypes", "en"); tssLexEntry = InterlinDocChild.GetLexEntryTss(m_cache, morphBundle, m_cache.DefaultVernWs); Assert.AreEqual(tssLexEntry.Text, actualLexEntry + actualHomograph + actualVariantTypes, String.Format(msg, "morph/cf[hn|variantTypes]", morphContext)); } if (IsLineEnabled(InterlinLineChoices.kflidLexGloss)) { string actualLexGloss = m_reader.GetItemInnerText(actualMorphNode as XmlNode, "gls", "en"); string expectedGloss = ""; if (morphBundle.SenseRA != null && morphBundle.SenseRA.Gloss != null) { expectedGloss = morphBundle.SenseRA.Gloss.AnalysisDefaultWritingSystem; } Assert.AreEqual(expectedGloss, actualLexGloss, String.Format(msg, "morph/gls", morphContext)); } if (IsLineEnabled(InterlinLineChoices.kflidLexPos)) { string actualLexMsa = m_reader.GetItemInnerText(actualMorphNode as XmlNode, "msa", "en"); string expectedMsa = ""; if (morphBundle.SenseRA != null && morphBundle.SenseRA.MorphoSyntaxAnalysisRA != null) { expectedMsa = morphBundle.SenseRA.MorphoSyntaxAnalysisRA.InterlinearAbbr; } Assert.AreEqual(expectedMsa, actualLexMsa, String.Format(msg, "morph/msa", morphContext)); } } } Assert.AreEqual(wfiAnalysis.MorphBundlesOS.Count, morphNodes.Count); } } }