///// <summary> ///// Return the WfiMorphBundleDefaultSenseHandler for the supplied cache, creating it if needed. ///// </summary> ///// <param name="cda"></param> ///// <returns></returns> //public static WfiMorphBundleDefaultSenseHandler InstallHandler(IVwCacheDa cda) //{ // WfiMorphBundleDefaultSenseHandler vh = (WfiMorphBundleDefaultSenseHandler)cda.GetVirtualHandlerName(kClassName, kFieldName); // if (vh == null) // { // vh = new WfiMorphBundleDefaultSenseHandler(); // vh.Type = (int)CellarModuleDefns.kcptReferenceAtom; // vh.ClassName = kClassName; // vh.FieldName = kFieldName; // cda.InstallVirtual(vh); // } // return vh; //} public override void Load(int hvo, int tag, int ws, IVwCacheDa cda) { ISilDataAccess sda = cda as ISilDataAccess; int hvoSense = sda.get_ObjectProp(hvo, (int)WfiMorphBundle.WfiMorphBundleTags.kflidSense); if (hvoSense == 0) { // Try for a default. int hvoMsa = sda.get_ObjectProp(hvo, (int)WfiMorphBundle.WfiMorphBundleTags.kflidMsa); if (hvoMsa != 0) { int hvoEntry = sda.get_ObjectProp(hvoMsa, (int)CmObjectFields.kflidCmObject_Owner); if (hvoEntry != 0) { hvoSense = SenseWithMsa(sda, hvoEntry, (int)LexEntry.LexEntryTags.kflidSenses, hvoMsa); if (hvoSense == 0) { // no sense has right MSA...go for the first sense of any kind. int csense = sda.get_VecSize(hvoEntry, (int)LexEntry.LexEntryTags.kflidSenses); if (csense > 0) { hvoSense = sda.get_VecItem(hvoEntry, (int)LexEntry.LexEntryTags.kflidSenses, 0); } } } } } cda.CacheObjProp(hvo, tag, hvoSense); }
private bool SetAllMsaSameFlag(int chvo, int[] rghvo) { int hvoMsa = m_sda.get_ObjectProp(rghvo[0], kflidSenseMsa); var fAllMsaSame = SubsenseMsasMatch(rghvo[0], hvoMsa); for (var i = 1; fAllMsaSame && i < chvo; ++i) { int hvoMsa2 = m_sda.get_ObjectProp(rghvo[i], kflidSenseMsa); fAllMsaSame = hvoMsa == hvoMsa2 && SubsenseMsasMatch(rghvo[i], hvoMsa); } return(fAllMsaSame); }
public void ObjectProp() { int hvo = m_ISilDataAccess.get_ObjectProp(1000, 2000); Assert.AreEqual(0, hvo); m_IVwCacheDa.CacheObjProp(1000, 2000, 7777); hvo = m_ISilDataAccess.get_ObjectProp(1000, 2000); Assert.AreEqual(7777, hvo); m_IVwCacheDa.CacheObjProp(1000, 2000, 8888); hvo = m_ISilDataAccess.get_ObjectProp(1000, 2000); Assert.AreEqual(8888, hvo); }
/// <summary> /// Select the word indicated by the text-wordform-in-context (twfic) annotation. /// This ignores the Sandbox! This is 'public' because it overrides a public method. /// </summary> /// <param name="hvoAnn"></param> public override void SelectAnnotation(int hvoAnn) { ISilDataAccess sda = Cache.MainCacheAccessor; // We should assert that ann is Twfic int twficType = CmAnnotationDefn.Twfic(Cache).Hvo; int annoType = sda.get_ObjectProp(hvoAnn, (int)CmAnnotation.CmAnnotationTags.kflidAnnotationType); Debug.Assert(annoType == twficType, "Given annotation type should be twfic(" + twficType + ") but was " + annoType + "."); // The following will select the Twfic, ... I hope! // Scroll to selection into view IVwSelection sel = SelectWficInIText(hvoAnn); if (sel == null) { return; } if (!this.Focused) { this.Focus(); } this.ScrollSelectionIntoView(sel, VwScrollSelOpts.kssoTop); Update(); }
/// <summary> /// Get the Hvo of the LangProject by tracing up the ownership chain from a known /// CmPossibility with a fixed guid that exists in all FieldWorks projects. /// </summary> private int GetHvoOfProject(ISilDataAccess sda) { // fixed guid of a possibility eventually owned by LangProject Guid guid = new Guid("d7f713e4-e8cf-11d3-9764-00c04f186933"); // MoMorphType: bound root int hvoPoss = GetIdFromGuid(sda, ref guid); int flidOwner = sda.MetaDataCache.GetFieldId("CmObject", "Owner", false); int hvoNewOwner = sda.get_ObjectProp(hvoPoss, flidOwner); int hvoOwner = 0; while (hvoNewOwner != 0) { hvoOwner = hvoNewOwner; hvoNewOwner = sda.get_ObjectProp(hvoOwner, flidOwner); } return(hvoOwner); }
private void SetReferencesForReferenceFlid(int thisFlid, int flidType, int hvoSrc, int hvoCopy) { switch (flidType) { case (int)CellarPropertyType.ReferenceAtomic: int hvoAtomic = m_sda.get_ObjectProp(hvoSrc, thisFlid); if (hvoAtomic > 0) { // If we find the object referred to by the RA property in our copy map, // put a reference to its copy in our copied object. Otherwise, use the same // reference as our source object. ICmObject copiedAtomic; if (m_sourceToCopyMap.TryGetValue(hvoAtomic, out copiedAtomic)) { m_sda.SetObjProp(hvoCopy, thisFlid, copiedAtomic.Hvo); } else { m_sda.SetObjProp(hvoCopy, thisFlid, hvoAtomic); } } break; case (int)CellarPropertyType.ReferenceCollection: case (int)CellarPropertyType.ReferenceSequence: // Handle Reference Vectors int cVec = m_sda.get_VecSize(hvoSrc, thisFlid); for (int i = 0; i < cVec; i++) { int hvoVecItem = m_sda.get_VecItem(hvoSrc, thisFlid, i); ICmObject copiedVecItem; if (m_sourceToCopyMap.TryGetValue(hvoVecItem, out copiedVecItem)) { m_sda.Replace(hvoCopy, thisFlid, i, i, new[] { copiedVecItem.Hvo }, 1); } else { m_sda.Replace(hvoCopy, thisFlid, i, i, new[] { hvoVecItem }, 1); } } break; default: throw new ArgumentException("Non-reference Field in wrong method!", "flidType"); } }
private void PreviewCurrentSelection(int hvoOccurrence) { if (m_hvoSelectedOccurrence == hvoOccurrence) { return; } m_hvoSelectedOccurrence = hvoOccurrence; m_previewPane.RootObjectHvo = m_decoratedSda.get_ObjectProp(m_hvoSelectedOccurrence, ConcDecorator.kflidSegment); }
private static void AddHvoPOStoResults(ISilDataAccess sda, List <int> results, int hvoMsa, int flidPos) { int hvoPOS; hvoPOS = sda.get_ObjectProp(hvoMsa, flidPos); if (hvoPOS != 0) { results.Add(hvoPOS); } }
public void ObjectProp() { CheckDisposed(); int hvo = m_ISilDataAccess.get_ObjectProp(1000, 2000); Assert.AreEqual(0, hvo); Assert.IsFalse(m_ISilDataAccess.IsDirty()); m_ISilDataAccess.SetObjProp(1000, 2000, 7777); hvo = m_ISilDataAccess.get_ObjectProp(1000, 2000); Assert.AreEqual(7777, hvo); Assert.IsTrue(m_ISilDataAccess.IsDirty()); m_ISilDataAccess.SetObjProp(1000, 2000, 8888); hvo = m_ISilDataAccess.get_ObjectProp(1000, 2000); Assert.AreEqual(8888, hvo); Assert.IsTrue(m_ISilDataAccess.IsDirty()); CheckProp(1000, 2000, 8888, CellarModuleDefns.kcptOwningAtom); }
public override void Load(int hvo, int tag, int ws, IVwCacheDa cda) { ISilDataAccess sda = cda as ISilDataAccess; m_hvo = sda.get_ObjectProp(hvo, m_tagReal); if (m_hvo == 0) { // Empty: need a fake object. m_hvo = TypeAheadSupportVc.kBaseFakeObj; } cda.CacheObjProp(hvo, tag, m_hvo); }
private bool IsItemEligible(ISilDataAccess sda, int hvo, HashSet <int> possiblePOS) { bool fEnable = false; int hvoMsa = sda.get_ObjectProp(hvo, LexSenseTags.kflidMorphoSyntaxAnalysis); if (hvoMsa != 0) { int clsid = m_cache.ServiceLocator.GetInstance <ICmObjectRepository>().GetObject(hvoMsa).ClassID; if (clsid == MoStemMsaTags.kClassId) { int pos = sda.get_ObjectProp(hvoMsa, MoStemMsaTags.kflidPartOfSpeech); if (pos != 0 && possiblePOS.Contains(pos)) { // Only show it as a change if it is different int hvoFeature = sda.get_ObjectProp(hvoMsa, MoStemMsaTags.kflidMsFeatures); fEnable = hvoFeature != m_selectedHvo; } } } return(fEnable); }
private bool IsItemEligible(ISilDataAccess sda, int hvo, Set <int> possiblePOS) { bool fEnable = false; int hvoMsa = sda.get_ObjectProp(hvo, (int)LexSense.LexSenseTags.kflidMorphoSyntaxAnalysis); if (hvoMsa != 0) { int clsid = m_cache.GetClassOfObject(hvoMsa); if (clsid == MoStemMsa.kClassId) { int pos = sda.get_ObjectProp(hvoMsa, (int)MoStemMsa.MoStemMsaTags.kflidPartOfSpeech); if (pos != 0 && possiblePOS.Contains(pos)) { // Only show it as a change if it is different int hvoClass = sda.get_ObjectProp(hvoMsa, (int)MoStemMsa.MoStemMsaTags.kflidInflectionClass); fEnable = hvoClass != m_selectedHvo; } } } return(fEnable); }
public override void DisplayEmbeddedObject(IVwEnv vwenv, int hvo) { // See if it is a CmPicture. ISilDataAccess sda = vwenv.DataAccess; int clsid = sda.get_IntProp(hvo, (int)CmObjectFields.kflidCmObject_Class); if (clsid != CmPictureTags.kClassId) { // don't know how to deal with it. Maybe the base implementation does. base.DisplayEmbeddedObject(vwenv, hvo); return; } int hvoFile = sda.get_ObjectProp(hvo, CmPictureTags.kflidPictureFile); if (hvoFile == 0) { return; } string path; string fileName = sda.get_UnicodeProp(hvoFile, CmFileTags.kflidInternalPath); if (Path.IsPathRooted(fileName)) { path = fileName; } else { if (m_hvoLangProject == 0) { // REVIEW (TimS/TomB): Hvo is for a CmPicture which means it might not be owned. // If it's not owned, there will be no way to walk up the owner tree to find the // Language Project. Review all clients to see if they have embedded objects. // If so, they need to set the cache. TryToSetLangProjectHvo(sda, hvo); } string linkedFilesRoot = sda.get_UnicodeProp(m_hvoLangProject, LangProjectTags.kflidLinkedFilesRootDir); if (String.IsNullOrEmpty(linkedFilesRoot)) { path = Path.Combine(DirectoryFinder.FWDataDirectory, fileName); } else { path = Path.Combine(linkedFilesRoot, fileName); } } vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalCenter); IPicture picture = new PictureWrapper(path); // -1 is ktagNotAnAttr. 0 width & height mean use natural width/height. vwenv.AddPictureWithCaption(picture, -1, CaptionProps, hvoFile, m_wsDefault, 0, 0, this); }
/// <summary> /// Make one AND make the change to the cache. /// </summary> /// <param name="sda"></param> /// <param name="hvo"></param> /// <param name="flid"></param> /// <param name="newValue"></param> public CacheObjPropUndoAction(ISilDataAccess sda, int hvo, int flid, int newValue) { m_sda = sda; m_hvo = hvo; m_flid = flid; m_newValue = newValue; m_oldValue = 0; // Since this is used for fake props, if it isn't already cached, it doesn't have an old value. if (sda.get_IsPropInCache(hvo, flid, (int)CellarModuleDefns.kcptReferenceAtom, 0)) { m_oldValue = sda.get_ObjectProp(hvo, flid); } DoIt(m_newValue); }
internal void SelectAnnotation(int hvoStText, int hvoPara, int hvoAnn) { CheckDisposed(); // get the annotation properties ISilDataAccess sda = Cache.MainCacheAccessor; int annBeginOffset = sda.get_IntProp(hvoAnn, (int)CmBaseAnnotation.CmBaseAnnotationTags.kflidBeginOffset); int annEndOffset = sda.get_IntProp(hvoAnn, (int)CmBaseAnnotation.CmBaseAnnotationTags.kflidEndOffset); int annWSid = sda.get_ObjectProp(hvoAnn, (int)CmBaseAnnotation.CmBaseAnnotationTags.kflidWritingSystem); // Now select the annotated word. int ihvoPara = GetParagraphIndexForPara(Cache, hvoStText, hvoPara); MakeTextSelectionAndScrollToView(annBeginOffset, annEndOffset, annWSid, ihvoPara); }
/// <summary> /// Get the items to be compared against the filter. /// </summary> /// <param name="item"></param> /// <returns></returns> protected override int[] GetItems(IManyOnePathSortItem item) { ISilDataAccess sda = m_cache.DomainDataByFlid; List <int> results = new List <int>(); if (item.PathLength > 0 && item.PathFlid(0) == kflidMsas) { // sorted by MSA, match just the one MSA. // I don't think this path can occur with the current XML spec where this is used. int hvoMsa; if (item.PathLength > 1) { hvoMsa = item.PathObject(1); } else { hvoMsa = item.KeyObject; } GetItemsForMsaType(sda, ref results, hvoMsa); } else if (item.PathLength >= 1 && item.PathFlid(0) == kflidEntrySenses) { // sorted in a way that shows one sense per row, test that sense's MSA. int hvoSense; if (item.PathLength > 1) { hvoSense = item.PathObject(1); } else { hvoSense = item.KeyObject; } int hvoMsa = sda.get_ObjectProp(hvoSense, LexSenseTags.kflidMorphoSyntaxAnalysis); GetItemsForMsaType(sda, ref results, hvoMsa); } else { int hvoEntry = item.RootObjectHvo; int cmsa = sda.get_VecSize(hvoEntry, kflidMsas); for (int imsa = 0; imsa < cmsa; imsa++) { int hvoMsa = sda.get_VecItem(hvoEntry, kflidMsas, imsa); GetItemsForMsaType(sda, ref results, hvoMsa); } } return(results.ToArray()); }
/// ----------------------------------------------------------------------------------- /// <summary> /// Attempts to look up the ownership hierarchy to find the HVO of the language project /// to set the m_hvoLangProject member variable. /// </summary> /// ----------------------------------------------------------------------------------- private void TryToSetLangProjectHvo(ISilDataAccess sda, int hvo) { int hvoOwner = sda.get_ObjectProp(hvo, (int)CmObjectFields.kflidCmObject_Owner); while (hvoOwner != 0) { int clsid = sda.get_IntProp(hvoOwner, (int)CmObjectFields.kflidCmObject_Class); if (clsid == LangProjectTags.kClassId) { m_hvoLangProject = hvoOwner; return; } hvoOwner = sda.get_IntProp(hvoOwner, (int)CmObjectFields.kflidCmObject_Owner); } // Not particularly true in the new architecture, since the WSes are loaded first, so get HVO 1. // m_hvoLangProject = 1; // true 99.999% of the time as of 11/24/2008 throw new ArgumentException("Probably an ownerless object", "hvo"); }
/// ------------------------------------------------------------------------------------- /// <summary> /// If the object specified by the HVO is one of the reference targets for this /// subordinate view, return a 'path' for locating the object in the view. /// The path works like the VwSelLevInfo objects passed to IVwRootBox.MakeTextSelection: /// that is, the LAST one specifies a property of the root object and an index within /// that property. /// /// If the object specified by the HVO is not a reference target for this view at all /// (perhaps it is a different kind of note), return null. /// </summary> /// <param name="hvo">The id of the object whose path is needed</param> /// <returns>Selection level info identifying where the object is in the subordinate /// stream</returns> /// ------------------------------------------------------------------------------------- public SelLevInfo[] GetPathToObject(int hvo) { List <SelLevInfo> rgSelLevInfo = new List <SelLevInfo>(m_maxLevels); // Loop over multiple owners up to m_hvoRoot and create a VwLevInfo for each level. int hvoCurr = hvo; for (int iLev = 0; iLev < m_maxLevels; iLev++) { int hvoOwner = m_sda.get_ObjectProp(hvoCurr, (int)CmObjectFields.kflidCmObject_Owner); int tag = m_sda.get_IntProp(hvoCurr, (int)CmObjectFields.kflidCmObject_OwnFlid); // use filtered tag if one has been provided. if (m_tagMap.ContainsKey(tag)) { tag = m_tagMap[tag]; } // Search for hvoCurr in the owning property to determine its index. // Todo: handle non-sequence property case. int chvo = m_sda.get_VecSize(hvoOwner, tag); int i; for (i = 0; i < chvo; i++) { if (m_sda.get_VecItem(hvoOwner, tag, i) == hvoCurr) { break; } } Debug.Assert(i < chvo); SelLevInfo selLevInfo = new SelLevInfo(); selLevInfo.ihvo = i; selLevInfo.tag = tag; selLevInfo.cpropPrevious = 0; rgSelLevInfo.Add(selLevInfo); if (hvoOwner == m_hvoRoot) { return(rgSelLevInfo.ToArray()); } hvoCurr = hvoOwner; } return(null); // Didn't find the root within the maximum number of levels, so give up. }
/// <summary> /// Starting from hvoBase, which may be a LexEntry or LexSense, find the most desirable sense that has /// the requested MSA. flidSense should be LexEntry.kflidSenses or LexSense.kflidSenses as /// appropriate. /// First tries all the top-level senses, if none matches, try children of each sense recursively. /// Note: arguably, should try all level-two senses before trying level 3. But level-3 senses are /// vanishingly rare; a level 3 sense with a different msa from its parent is so rare that it isn't /// worth the effort to be more precise. /// </summary> /// <param name="sda"></param> /// <param name="hvoBase"></param> /// <param name="flidSenses"></param> /// <param name="hvoMsa"></param> /// <returns></returns> int SenseWithMsa(ISilDataAccess sda, int hvoBase, int flidSenses, int hvoMsa) { int csense = sda.get_VecSize(hvoBase, flidSenses); for (int i = 0; i < csense; i++) { int hvoSense = sda.get_VecItem(hvoBase, flidSenses, i); int hvoThisMsa = sda.get_ObjectProp(hvoSense, (int)LexSense.LexSenseTags.kflidMorphoSyntaxAnalysis); if (hvoThisMsa == hvoMsa) { return(hvoSense); } } for (int i = 0; i < csense; i++) { int hvoSense = sda.get_VecItem(hvoBase, flidSenses, i); int hvoSubSense = SenseWithMsa(sda, hvoSense, (int)LexSense.LexSenseTags.kflidSenses, hvoMsa); if (hvoSubSense != 0) { return(hvoSubSense); } } return(0); // no suitable sense found. }
private bool IsItemEligible(ISilDataAccess sda, int hvo, Set<int> possiblePOS) { bool fEnable = false; int hvoMsa = sda.get_ObjectProp(hvo, (int)LexSense.LexSenseTags.kflidMorphoSyntaxAnalysis); if (hvoMsa != 0) { int clsid = m_cache.GetClassOfObject(hvoMsa); if (clsid == MoStemMsa.kClassId) { int pos = sda.get_ObjectProp(hvoMsa, (int)MoStemMsa.MoStemMsaTags.kflidPartOfSpeech); if (pos != 0 && possiblePOS.Contains(pos)) { // Only show it as a change if it is different int hvoFeature = sda.get_ObjectProp(hvoMsa, (int)MoStemMsa.MoStemMsaTags.kflidMsFeatures); fEnable = hvoFeature != m_selectedHvo; } } } return fEnable; }
public void Setup() { // Create the following: // - part and layout inventories // - metadata cache // - DataAccess cache // - collection of columns to display. // We want a MetaDataCache that knows about // - LexEntry.Senses, Msas, CitationForm, Bibliography, Etymology // - LexSense.SemanticDomains, SenseType, Status, gloss // - CmPossibility Name, abbr // - MoMorphSynAnalysis // - MoStemMsa // - MoDerivationalMsa string m_sTestPath = Path.Combine(DirectoryFinder.FwSourceDirectory, Path.Combine("Common", Path.Combine("Controls", Path.Combine("XMLViews", Path.Combine("XMLViewsTests", "SampleCm.xml"))))); m_mdc = MetaDataCache.CreateMetaDataCache(m_sTestPath); // We want ISilDataAccess with: // - LexEntry (1) with no senses and one MSA (2) // - LexEntry (4) with one sense (5) and no MSA // - LexEntry (6) with three senses (7, 8, 9) and two MSAs (10, 11) // - sense(5) with no semantic domains // - senses with one SD (7->30, 8->31) // - sense with three SDs, one the same as the first (9->30, 31, 32) // - MoStemMsa (2, 11) // - MoDerivationalMsa (10) m_cda = VwCacheDaClass.Create(); m_sda = m_cda as ISilDataAccess; m_wsManager = new PalasoWritingSystemManager(); m_sda.WritingSystemFactory = m_wsManager; var parser = new SimpleDataParser(m_mdc, m_cda); parser.Parse(Path.Combine(DirectoryFinder.FwSourceDirectory, Path.Combine("Common", Path.Combine("Controls", Path.Combine("XMLViews", Path.Combine("XMLViewsTests", "SampleData.xml")))))); int wsEn = m_wsManager.GetWsFromStr("en"); // These are mainly to check out the parser. Assert.AreEqual(3, m_sda.get_ObjectProp(2, 23011), "part of speech of an MoStemMsa"); Assert.AreEqual(2, m_sda.get_VecItem(1, 2009, 0), "owned msa"); Assert.AreEqual("noun", m_sda.get_MultiStringAlt(3, 7003, wsEn).Text, "got ms property"); Assert.AreEqual(9, m_sda.get_VecItem(6, 2010, 2), "3rd sense"); Assert.AreEqual(31, m_sda.get_VecItem(9, 21016, 1), "2nd semantic domain"); // Columns includes // - CitationForm (string inside span) // - Bibliography (string not in span) // - Sense glosses (string in para in seq, nested in column element) // - Semantic domains (pair of strings in para in seq in seq, using layout refs) // - MSAs (simplified, but polymorphic with one having <choice> and one <obj> to CmPossibility XmlDocument docColumns = new XmlDocument(); docColumns.Load(Path.Combine(DirectoryFinder.FwSourceDirectory, Path.Combine("Common", Path.Combine("Controls", Path.Combine("XMLViews", Path.Combine("XMLViewsTests", "TestColumns.xml")))))); m_columnList = docColumns.DocumentElement.ChildNodes; // Parts just has what those columns need. string partDirectory = Path.Combine(DirectoryFinder.FwSourceDirectory, Path.Combine("Common", Path.Combine("Controls", Path.Combine("XMLViews", "XMLViewsTests")))); Dictionary <string, string[]> keyAttrs = new Dictionary <string, string[]>(); keyAttrs["layout"] = new string[] { "class", "type", "name" }; keyAttrs["group"] = new string[] { "label" }; keyAttrs["part"] = new string[] { "ref" }; // Currently there are no specialized layout files that match. m_layoutInventory = new Inventory(new string[] { partDirectory }, "*.fwlayout", "/LayoutInventory/*", keyAttrs, "TestManyOneBrowse", "ProjectPath"); keyAttrs = new Dictionary <string, string[]>(); keyAttrs["part"] = new string[] { "id" }; m_partInventory = new Inventory(new string[] { partDirectory }, "TestParts.xml", "/PartInventory/bin/*", keyAttrs, "TestManyOneBrowse", "ProjectPath"); m_layouts = new LayoutCache(m_mdc, m_layoutInventory, m_partInventory); }
/// <summary> /// Returns an array of string values (keys) for the objects under this layout node. /// </summary> /// <param name="fdoCache">The fdo cache.</param> /// <param name="sda">The sda.</param> /// <param name="layout">The layout.</param> /// <param name="hvo">The hvo.</param> /// <param name="layoutCache">The layout cache.</param> /// <param name="caller">where layout is a component of a 'part' element, caller /// is the 'part ref' that invoked it.</param> /// <param name="stringTbl">The string TBL.</param> /// <param name="wsForce">if non-zero, "string" elements are forced to use that writing system for multistrings.</param> /// <returns></returns> static public string[] StringsFor(FdoCache fdoCache, ISilDataAccess sda, XmlNode layout, int hvo, LayoutCache layoutCache, XmlNode caller, StringTable stringTbl, int wsForce) { // Some nodes are known to be uninteresting. if (XmlVc.CanSkipNode(layout)) return new string[0]; // don't know how to sort, treat as empty key. switch (layout.Name) { case "string": { int hvoTarget = hvo; XmlVc.GetActualTarget(layout, ref hvoTarget, sda); // modify the hvo if needed if (hvo != hvoTarget) { return AddStringFromOtherObj(layout, hvoTarget, fdoCache, sda); } int flid = GetFlid(sda, layout, hvo); if (wsForce != 0) { // If we are forcing a writing system, and it's a multistring, get the forced alternative. int itype = sda.MetaDataCache.GetFieldType(flid); itype = itype & (int)CellarPropertyTypeFilter.VirtualMask; switch (itype) { case (int) CellarPropertyType.MultiUnicode: case (int) CellarPropertyType.MultiString: if (wsForce < 0) { int wsActual; var tss = WritingSystemServices.GetMagicStringAlt(fdoCache, sda, wsForce, hvo, flid, true, out wsActual); return new[] {tss == null ? "" : tss.Text }; } return new[] {sda.get_MultiStringAlt(hvo, flid, wsForce).Text}; } } bool fFoundType; var strValue = fdoCache.GetText(hvo, flid, layout, out fFoundType); if (fFoundType) return new[] {strValue}; throw new Exception("Bad property type (" + strValue + " for hvo " + hvo + " found for string property " + flid + " in " + layout.OuterXml); } case "configureMlString": { int flid = GetFlid(sda, layout, hvo); // The Ws info specified in the part ref node HashSet<int> wsIds = WritingSystemServices.GetAllWritingSystems(fdoCache, caller, null, hvo, flid); if (wsIds.Count == 1) { var strValue = sda.get_MultiStringAlt(hvo, flid, wsIds.First()).Text; return new[] {strValue}; } return new[] {AddMultipleAlternatives(fdoCache, sda, wsIds, hvo, flid, caller)}; } case "multiling": return ProcessMultiLingualChildren(fdoCache, sda, layout, hvo, layoutCache, caller, stringTbl, wsForce); case "layout": // "layout" can occur when GetNodeToUseForColumn returns a phony 'layout' // formed by unifying a layout with child nodes. Assemble its children. // (arguably, we should treat that like div if current flow is a pile. // but we can't tell that and it rarely makes a difference.) case "para": case "span": { return AssembleChildKeys(fdoCache, sda, layout, hvo, layoutCache, caller, stringTbl, wsForce); } case "column": // top-level node for whole column; concatenate children as for "para" // if multipara is false, otherwise as for "div" if (XmlUtils.GetOptionalBooleanAttributeValue(layout, "multipara", false)) return ChildKeys(fdoCache, sda, layout, hvo, layoutCache, caller, stringTbl, wsForce); else return AssembleChildKeys(fdoCache, sda, layout, hvo, layoutCache, caller, stringTbl, wsForce); case "part": { string partref = XmlUtils.GetOptionalAttributeValue(layout, "ref"); if (partref == null) return ChildKeys(fdoCache, sda, layout, hvo, layoutCache, caller, stringTbl, wsForce); // an actual part, made up of its pieces XmlNode part = XmlVc.GetNodeForPart(hvo, partref, false, sda, layoutCache); // This is the critical place where we introduce a caller. The 'layout' is really a 'part ref' which is the // 'caller' for all embedded nodes in the called part. return StringsFor(fdoCache, sda, part, hvo, layoutCache, layout, stringTbl, wsForce); } case "div": case "innerpile": { // Concatenate keys for child nodes (as distinct strings) return ChildKeys(fdoCache, sda, layout, hvo, layoutCache, caller, stringTbl, wsForce); } case "obj": { // Follow the property, get the object, look up the layout to use, // invoke recursively. int flid = GetFlid(sda, layout, hvo); int hvoTarget = sda.get_ObjectProp(hvo, flid); if (hvoTarget == 0) break; // return empty key string targetLayoutName = XmlUtils.GetOptionalAttributeValue(layout, "layout"); // uses 'default' if missing. XmlNode layoutTarget = GetLayoutNodeForChild(sda, hvoTarget, flid, targetLayoutName, layout, layoutCache); if (layoutTarget == null) break; return ChildKeys(fdoCache, sda, layoutTarget, hvoTarget, layoutCache, caller, stringTbl, wsForce); } case "seq": { // Follow the property. For each object, look up the layout to use, // invoke recursively, concatenate int flid = GetFlid(sda, layout, hvo); int[] contents; int ctarget = sda.get_VecSize(hvo, flid); using (ArrayPtr arrayPtr = MarshalEx.ArrayToNative<int>(ctarget)) { int chvo; sda.VecProp(hvo, flid, ctarget, out chvo, arrayPtr); contents = MarshalEx.NativeToArray<int>(arrayPtr, chvo); } string[] result = null; string targetLayoutName = XmlVc.GetLayoutName(layout, caller); // also allows for finding "param" attr in caller, if not null int i = 0; foreach (int hvoTarget in contents) { int prevResultLength = GetArrayLength(result); XmlNode layoutTarget = GetLayoutNodeForChild(sda, hvoTarget, flid, targetLayoutName, layout, layoutCache); if (layoutTarget == null) continue; // should not happen, but best recovery we can make result = Concatenate(result, ChildKeys(fdoCache, sda, layoutTarget, hvoTarget, layoutCache, caller, stringTbl, wsForce)); // add a separator between the new childkey group and the previous childkey group if (i > 0 && prevResultLength != GetArrayLength(result) && prevResultLength > 0) { int ichIns = 0; if (result[prevResultLength - 1] != null) ichIns = result[prevResultLength - 1].Length; AddSeparator(ref result[prevResultLength - 1], ichIns, layout); } ++i; } return result; } case "choice": { foreach(XmlNode whereNode in layout.ChildNodes) { if (whereNode.Name != "where") { if (whereNode.Name == "otherwise") return StringsFor(fdoCache, sda, XmlUtils.GetFirstNonCommentChild(whereNode), hvo, layoutCache, caller, stringTbl, wsForce); continue; // ignore any other nodes,typically comments } // OK, it's a where node. if (XmlVc.ConditionPasses(whereNode, hvo, fdoCache, sda, caller)) return StringsFor(fdoCache, sda, XmlUtils.GetFirstNonCommentChild(whereNode), hvo, layoutCache, caller, stringTbl, wsForce); } break; // if no condition passes and no otherwise, return null. } case "if": { if (XmlVc.ConditionPasses(layout, hvo, fdoCache, sda, caller)) return StringsFor(fdoCache, sda, XmlUtils.GetFirstNonCommentChild(layout), hvo, layoutCache, caller, stringTbl, wsForce); break; } case "ifnot": { if (!XmlVc.ConditionPasses(layout, hvo, fdoCache, sda, caller)) return StringsFor(fdoCache, sda, XmlUtils.GetFirstNonCommentChild(layout), hvo, layoutCache, caller, stringTbl, wsForce); break; } case "lit": { string literal = layout.InnerText; if (stringTbl != null) { string sTranslate = XmlUtils.GetOptionalAttributeValue(layout, "translate", ""); if (sTranslate.Trim().ToLower() != "do not translate") literal = stringTbl.LocalizeLiteralValue(literal); } return new[] { literal }; } case "int": { int flid = GetFlid(sda, layout, hvo); int val = sda.get_IntProp(hvo, flid); return new[] {AlphaCompNumberString(val)}; } case "datetime": { int flid = GetFlid(sda, layout, hvo); CellarPropertyType itype = (CellarPropertyType)sda.MetaDataCache.GetFieldType(flid); if (itype == CellarPropertyType.Time) { DateTime dt = SilTime.GetTimeProperty(sda, hvo, flid); return new[] {DateTimeCompString(dt)}; } else { string stFieldName = XmlUtils.GetManditoryAttributeValue(layout, "field"); throw new Exception("Bad field type (" + stFieldName + " for hvo " + hvo + " found for " + layout.Name + " property " + flid + " in " + layout.OuterXml); } } case "picture": // Treat a picture as a non-empty string for purposes of deciding whether something is empty. // This string seems as good as anything for other purposes. return new[] {"a picture"}; default: // unknown or comment node, adds nothing Debug.Assert(false, "unrecognized XML node."); break; } return new string[0]; // don't know how to sort, treat as empty key. }
public override void DoIt(Set <int> itemsToChange, ProgressState state) { CheckDisposed(); ISilDataAccess sda = m_cache.MainCacheAccessor; // Make a hashtable from HVO of entry to list of modified senses. Dictionary <int, List <int> > sensesByEntry = new Dictionary <int, List <int> >(); int tagOwningEntry = m_cache.VwCacheDaAccessor.GetVirtualHandlerName("LexSense", "OwningEntry").Tag; int i = 0; // Report progress 50 times or every 100 items, whichever is more (but no more than once per item!) int interval = Math.Min(100, Math.Max(itemsToChange.Count / 50, 1)); foreach (int hvoSense in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 20 / itemsToChange.Count; state.Breath(); } int hvoMsa = sda.get_ObjectProp(hvoSense, (int)LexSense.LexSenseTags.kflidMorphoSyntaxAnalysis); if (hvoMsa != 0 && m_cache.GetClassOfObject(hvoMsa) != MoStemMsa.kclsidMoStemMsa) { continue; // can't fix this one, not a stem. } int hvoEntry = sda.get_ObjectProp(hvoSense, tagOwningEntry); List <int> senses = null; if (!sensesByEntry.TryGetValue(hvoEntry, out senses)) { senses = new List <int>(); sensesByEntry[hvoEntry] = senses; } senses.Add(hvoSense); } m_cache.BeginUndoTask(FdoUiStrings.ksUndoBulkEditPOS, FdoUiStrings.ksRedoBulkEditPOS); BulkEditBar.ForceRefreshOnUndoRedo(sda); i = 0; interval = Math.Min(100, Math.Max(sensesByEntry.Count / 50, 1)); foreach (KeyValuePair <int, List <int> > kvp in sensesByEntry) { i++; if (i % interval == 0) { state.PercentDone = i * 80 / sensesByEntry.Count + 20; state.Breath(); } int hvoEntry = kvp.Key; List <int> sensesToChange = kvp.Value; int hvoMsmTarget = 0; int cmsa = sda.get_VecSize(hvoEntry, (int)LexEntry.LexEntryTags.kflidMorphoSyntaxAnalyses); bool fAssumeSurvives = true; // true if we know all old MSAs will survive. for (int imsa = 0; imsa < cmsa; imsa++) { int hvoMsa = sda.get_VecItem(hvoEntry, (int)LexEntry.LexEntryTags.kflidMorphoSyntaxAnalyses, imsa); if (m_cache.GetClassOfObject(hvoMsa) == MoStemMsa.kclsidMoStemMsa && sda.get_ObjectProp(hvoMsa, (int)MoStemMsa.MoStemMsaTags.kflidPartOfSpeech) == m_selectedHvo) { // Can reuse this one! hvoMsmTarget = hvoMsa; fAssumeSurvives = false; // old MSA may be redundant. break; } } if (hvoMsmTarget == 0) { // See if we can reuse an existing MoStemMsa by changing it. // This is possible if it is used only by senses in the list, or not used at all. List <int> otherSenses = new List <int>(); AddExcludedSenses(sda, hvoEntry, (int)LexEntry.LexEntryTags.kflidSenses, otherSenses, sensesToChange); for (int imsa = 0; imsa < cmsa; imsa++) { int hvoMsa = sda.get_VecItem(hvoEntry, (int)LexEntry.LexEntryTags.kflidMorphoSyntaxAnalyses, imsa); if (m_cache.GetClassOfObject(hvoMsa) != MoStemMsa.kclsidMoStemMsa) { continue; } bool fOk = true; foreach (int hvoOtherSense in otherSenses) { if (sda.get_ObjectProp(hvoOtherSense, (int)LexSense.LexSenseTags.kflidMorphoSyntaxAnalysis) == hvoMsa) { fOk = false; // we can't change it, one of the unchanged senses uses it break; } } if (fOk) { // Can reuse this one! Nothing we don't want to change uses it. Go ahead and set it to the // required POS. hvoMsmTarget = hvoMsa; int hvoOld = sda.get_ObjectProp(hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidPartOfSpeech); sda.SetObjProp(hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidPartOfSpeech, m_selectedHvo); sda.PropChanged(null, (int)PropChangeType.kpctNotifyAll, hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidPartOfSpeech, 0, 1, hvoOld == 0 ? 1 : 0); // compare MoStemMsa.ResetInflectionClass: changing POS requires us to clear inflection class, // if it is set. if (hvoOld != 0 && sda.get_ObjectProp(hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidInflectionClass) != 0) { sda.SetObjProp(hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidInflectionClass, 0); sda.PropChanged(null, (int)PropChangeType.kpctNotifyAll, hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidInflectionClass, 0, 0, 1); } break; } } } if (hvoMsmTarget == 0) { // Nothing we can reuse...make a new one. hvoMsmTarget = sda.MakeNewObject((int)MoStemMsa.kclsidMoStemMsa, hvoEntry, (int)LexEntry.LexEntryTags.kflidMorphoSyntaxAnalyses, -1); sda.SetObjProp(hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidPartOfSpeech, m_selectedHvo); sda.PropChanged(null, (int)PropChangeType.kpctNotifyAll, hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidInflectionClass, m_cache.GetObjIndex(hvoEntry, (int)LexEntry.LexEntryTags.kflidMorphoSyntaxAnalyses, hvoMsmTarget), 1, 0); } // Finally! Make the senses we want to change use it. foreach (int hvoSense in sensesToChange) { int hvoOld = sda.get_ObjectProp(hvoSense, (int)LexSense.LexSenseTags.kflidMorphoSyntaxAnalysis); if (hvoOld == hvoMsmTarget) { continue; // reusing a modified msa. } LexSense.HandleOldMSA(m_cache, hvoSense, hvoMsmTarget, fAssumeSurvives); sda.SetObjProp(hvoSense, (int)LexSense.LexSenseTags.kflidMorphoSyntaxAnalysis, hvoMsmTarget); sda.PropChanged(null, (int)PropChangeType.kpctNotifyAll, hvoSense, (int)LexSense.LexSenseTags.kflidMorphoSyntaxAnalysis, 0, 1, hvoOld == 0 ? 1 : 0); } } m_cache.EndUndoTask(); }
/// <summary> /// Get the Hvo of the LangProject by tracing up the ownership chain from a known /// CmPossibility with a fixed guid that exists in all FieldWorks projects. /// </summary> private int GetHvoOfProject(ISilDataAccess sda) { // fixed guid of a possibility eventually owned by LangProject Guid guid = new Guid("d7f713e4-e8cf-11d3-9764-00c04f186933"); // MoMorphType: bound root int hvoPoss = GetIdFromGuid(sda, ref guid); int flidOwner = sda.MetaDataCache.GetFieldId("CmObject", "Owner", false); int hvoNewOwner = sda.get_ObjectProp(hvoPoss, flidOwner); int hvoOwner = 0; while (hvoNewOwner != 0) { hvoOwner = hvoNewOwner; hvoNewOwner = sda.get_ObjectProp(hvoOwner, flidOwner); } return hvoOwner; }
public UpdateMorphEntryAction(SandboxBase sandbox, int hvoMorph) { m_oldVals = new int[m_tags.Length]; m_newVals = new int[m_tags.Length]; m_sandbox = sandbox; m_sda = m_sandbox.Caches.DataAccess; m_originalAnalysis = m_sandbox.Analysis; m_hvoMorph = hvoMorph; for (int i = 0; i < m_tags.Length; i++ ) m_oldVals[i] = m_sda.get_ObjectProp(m_hvoMorph, m_tags[i]); }
public bool Test(int hvo, ISilDataAccess sda, Set <int> validHvos) { return(validHvos.Contains(sda.get_ObjectProp(hvo, m_flid))); }
public bool Test(int hvo, ISilDataAccess sda, Set<int> validHvos) { return validHvos.Contains(sda.get_ObjectProp(hvo, m_flid)); }
/// <summary> /// Starting from hvoBase, which may be a LexEntry or LexSense, find the most desirable sense that has /// the requested MSA. flidSense should be LexEntry.kflidSenses or LexSense.kflidSenses as /// appropriate. /// First tries all the top-level senses, if none matches, try children of each sense recursively. /// Note: arguably, should try all level-two senses before trying level 3. But level-3 senses are /// vanishingly rare; a level 3 sense with a different msa from its parent is so rare that it isn't /// worth the effort to be more precise. /// </summary> /// <param name="sda"></param> /// <param name="hvoBase"></param> /// <param name="flidSenses"></param> /// <param name="hvoMsa"></param> /// <returns></returns> int SenseWithMsa(ISilDataAccess sda, int hvoBase, int flidSenses, int hvoMsa) { int csense = sda.get_VecSize(hvoBase, flidSenses); for (int i = 0; i < csense; i++) { int hvoSense = sda.get_VecItem(hvoBase, flidSenses, i); int hvoThisMsa = sda.get_ObjectProp(hvoSense, (int)LexSense.LexSenseTags.kflidMorphoSyntaxAnalysis); if (hvoThisMsa == hvoMsa) return hvoSense; } for (int i = 0; i < csense; i++) { int hvoSense = sda.get_VecItem(hvoBase, flidSenses, i); int hvoSubSense = SenseWithMsa(sda, hvoSense, (int)LexSense.LexSenseTags.kflidSenses, hvoMsa); if (hvoSubSense != 0) return hvoSubSense; } return 0; // no suitable sense found. }
public void Setup() { // Create the following: // - part and layout inventories // - metadata cache // - DataAccess cache // - collection of columns to display. // We want a MetaDataCache that knows about // - LexEntry.Senses, Msas, CitationForm, Bibliography, Etymology // - LexSense.SemanticDomains, SenseType, Status, gloss // - CmPossibility Name, abbr // - MoMorphSynAnalysis // - MoStemMsa // - MoDerivationalMsa m_mdc = FwMetaDataCacheClass.Create(); string m_sTestPath = Path.Combine(DirectoryFinder.FwSourceDirectory, @"Common\Controls\XmlViews\XmlViewsTests\SampleCm.xml"); m_mdc.InitXml(m_sTestPath, true); // We want ISilDataAccess with: // - LexEntry (1) with no senses and one MSA (2) // - LexEntry (4) with one sense (5) and no MSA // - LexEntry (6) with three senses (7, 8, 9) and two MSAs (10, 11) // - sense(5) with no semantic domains // - senses with one SD (7->30, 8->31) // - sense with three SDs, one the same as the first (9->30, 31, 32) // - MoStemMsa (2, 11) // - MoDerivationalMsa (10) m_cda = VwCacheDaClass.Create(); m_sda = m_cda as ISilDataAccess; m_wsf = LgWritingSystemFactoryClass.Create(); m_sda.WritingSystemFactory = m_wsf; SimpleDataParser parser = new SimpleDataParser(m_mdc, m_cda); parser.Parse(Path.Combine(DirectoryFinder.FwSourceDirectory, @"Common\Controls\XmlViews\XmlViewsTests\SampleData.xml")); int wsEn = m_wsf.GetWsFromStr("en"); // These are mainly to check out the parser. Assert.AreEqual(3, m_sda.get_ObjectProp(2, 23011), "part of speech of an MoStemMsa"); Assert.AreEqual(2, m_sda.get_VecItem(1, 2009, 0), "owned msa"); Assert.AreEqual("noun", m_sda.get_MultiStringAlt(3, 7003, wsEn).Text, "got ms property"); Assert.AreEqual(9, m_sda.get_VecItem(6, 2010, 2), "3rd sense"); Assert.AreEqual(31, m_sda.get_VecItem(9, 21016, 1), "2nd semantic domain"); // Columns includes // - CitationForm (string inside span) // - Bibliography (string not in span) // - Sense glosses (string in para in seq, nested in column element) // - Semantic domains (pair of strings in para in seq in seq, using layout refs) // - MSAs (simplified, but polymorphic with one having <choice> and one <obj> to CmPossibility XmlDocument docColumns = new XmlDocument(); docColumns.Load(Path.Combine(DirectoryFinder.FwSourceDirectory, @"Common\Controls\XmlViews\XmlViewsTests\TestColumns.xml")); m_columnList = docColumns.DocumentElement.ChildNodes; // Parts just has what those columns need. string partDirectory = Path.Combine(DirectoryFinder.FwSourceDirectory, @"Common\Controls\XmlViews\XmlViewsTests"); Dictionary<string, string[]> keyAttrs = new Dictionary<string, string[]>(); keyAttrs["layout"] = new string[] {"class", "type", "name" }; keyAttrs["group"] = new string[] {"label"}; keyAttrs["part"] = new string[] {"ref"}; // Currently there are no specialized layout files that match. m_layoutInventory = new Inventory(new string[] {partDirectory}, "*Layouts.xml", "/LayoutInventory/*", keyAttrs); keyAttrs = new Dictionary<string, string[]>(); keyAttrs["part"] = new string[] {"id"}; m_partInventory = new Inventory(new string[] {partDirectory}, "TestParts.xml", "/PartInventory/bin/*", keyAttrs); if (m_layouts != null) m_layouts.Dispose(); m_layouts = new LayoutCache(m_mdc, m_layoutInventory, m_partInventory); }
/// <summary> /// It's possible that hvoItem will be an owner of a ghost (ie. an absent source object for m_flidAtomicProp). /// In that case, the cache should return 0. /// </summary> /// <param name="sda"></param> /// <param name="hvoItem"></param> /// <returns></returns> private int GetOriginalListValue(ISilDataAccess sda, int hvoItem) { return sda.get_ObjectProp(hvoItem, m_flidAtomicProp); }
public static void UpdateMainTransFromSegmented(StTxtPara para, int[] wss) { if (!para.IsValidObject()) { return; // in merge, paragraph may be modified then deleted. } FdoCache cache = para.Cache; BtConverter.EnsureMainParaSegments(para, wss[0]); ISilDataAccess sda = cache.MainCacheAccessor; List <int> segments = para.Segments; int kflidFT = StTxtPara.SegmentFreeTranslationFlid(cache); ITsString tssContents = para.Contents.UnderlyingTsString; IScripture scr = para.Cache.LangProject.TranslatedScriptureOA; ICmTranslation originalBT = para.GetBT(); // Can be null string sUnfinished = BackTranslationStatus.Unfinished.ToString(); foreach (int ws in wss) { ITsStrBldr bldr = TsStrBldrClass.Create(); bool wantNextSpace = false; // suppresses space before the first thing we add. bool haveBtText = false; // Text that isn't segment label text foreach (int hvoSeg in segments) { // If it's a label, insert it directly. Suppress following space. int beginOffset = sda.get_IntProp(hvoSeg, (int)CmBaseAnnotation.CmBaseAnnotationTags.kflidBeginOffset); int endOffset = sda.get_IntProp(hvoSeg, (int)CmBaseAnnotation.CmBaseAnnotationTags.kflidEndOffset); ITsString tssFt; // Whether we want to insert a space before the current segment is determined by the previous one. // Save that value so we can set wantSpace appropriately for the following one. bool wantSpace = wantNextSpace; if (SegmentBreaker.HasLabelText(tssContents, beginOffset, endOffset)) { tssFt = (new CmBaseAnnotation(cache, hvoSeg)).TextAnnotated; tssFt = scr.ConvertCVNumbersInStringForBT(CorrectFootnotes(tssFt), ws); wantNextSpace = false; } else { int hvoFt = sda.get_ObjectProp(hvoSeg, kflidFT); tssFt = sda.get_MultiStringAlt(hvoFt, (int)CmAnnotation.CmAnnotationTags.kflidComment, ws); haveBtText |= (tssFt.Length > 0); wantNextSpace = EndsWithNonSpace(tssFt); } if (tssFt.Length > 0) { if (wantSpace) { // The preceding segment should typically be followed by a space. if (!StartsWithSpaceOrOrc(tssFt)) { bldr.Replace(bldr.Length, bldr.Length, " ", null); } } bldr.ReplaceTsString(bldr.Length, bldr.Length, tssFt); } } // If the back translation doesn't have text, we don't want to create verse // segment labels. This prevents the problem where the book thinks it has a // back translation because of automatically generated verse labels (TE-8283). if (!haveBtText) { // This check might not be needed, but it shouldn't hurt anything. if (originalBT != null) { if (originalBT.Translation.GetAlternative(ws).Length > 0) { string origStatus = originalBT.Status.GetAlternative(ws); if (!String.IsNullOrEmpty(origStatus) && origStatus != sUnfinished) { originalBT.Status.SetAlternative(sUnfinished, ws); } } } continue; } ITsString newFt = bldr.GetString(); ICmTranslation trans; if (newFt.Length == 0) { trans = para.GetBT(); if (trans == null) { return; // don't bother creating one to store an empty translation! } } else { trans = para.GetOrCreateBT(); } // Don't write unless it changed...PropChanged can be expensive. if (!trans.Translation.GetAlternative(ws).UnderlyingTsString.Equals(newFt)) { trans.Translation.SetAlternative(newFt, ws); trans.Status.SetAlternative(sUnfinished, ws); } } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Main (recursive) part of CollectBrowseItems. Given that hvo is to be displayed using node, /// figure what objects to put in the list. /// </summary> /// <param name="hvo">The hvo.</param> /// <param name="node">The node.</param> /// <param name="collector">The collector.</param> /// <param name="mdc">The MDC.</param> /// <param name="sda">The sda.</param> /// <param name="layouts">The layouts.</param> /// <param name="caller">The caller.</param> /// <param name="hvos">The hvos.</param> /// <param name="flids">The flids.</param> /// ------------------------------------------------------------------------------------ static void CollectBrowseItems(int hvo, XmlNode node, ArrayList collector, IFwMetaDataCache mdc, ISilDataAccess sda, LayoutCache layouts, XmlNode caller, int[] hvos, int[] flids) { switch(node.Name) { case "obj": { int clsid = sda.get_IntProp(hvo, CmObjectTags.kflidClass); int flid = mdc.GetFieldId2(clsid, XmlUtils.GetManditoryAttributeValue(node, "field"), true); int hvoDst = sda.get_ObjectProp(hvo, flid); if (hvoDst == 0) { // We want a row, even though it's blank for this column. collector.Add(new ManyOnePathSortItem(hvo, hvos, flids)); return; } // At this point we have to mimic the process that XmlVc uses to come up with the // node that will be used to process the destination item. XmlNode dstNode = GetNodeForRelatedObject(hvoDst, caller, node, layouts, sda); if (dstNode == null) { // maybe an old-style "frag" element? Anyway, we can't do anything smart, // so just insert the original object. collector.Add(new ManyOnePathSortItem(hvo, hvos, flids)); return; } CollectBrowseItems(hvoDst, dstNode, collector, mdc, sda, layouts, null, AppendInt(hvos, hvo), AppendInt(flids, flid)); } break; case "seq": { // very like "obj" except for the loop. How could we capture this? int clsid = sda.get_IntProp(hvo, CmObjectTags.kflidClass); int flid = mdc.GetFieldId2(clsid, XmlUtils.GetManditoryAttributeValue(node, "field"), true); int chvo = sda.get_VecSize(hvo, flid); if (chvo == 0) { // We want a row, even though it's blank for this column. collector.Add(new ManyOnePathSortItem(hvo, hvos, flids)); return; } for (int ihvo = 0; ihvo < chvo; ihvo++) { int hvoDst = sda.get_VecItem(hvo, flid, ihvo); // At this point we have to mimic the process that XmlVc uses to come up with the // node that will be used to process the destination item. XmlNode dstNode = GetNodeForRelatedObject(hvoDst, caller, node, layouts, sda); if (dstNode == null) { if (ihvo == 0) { // maybe an old-style "frag" element? Anyway, we can't do anything smart, // so just insert the original object. collector.Add(new ManyOnePathSortItem(hvo, hvos, flids)); return; } // if this happens and it's not the first object, we have a funny mixture of modes. // As a fall-back, skip this object. continue; } CollectBrowseItems(hvoDst, dstNode, collector, mdc, sda, layouts, null, AppendInt(hvos, hvo), AppendInt(flids, flid)); } } break; case "span": case "para": case "div": case "concpara": case "innerpile": case "column": // Review JohnT: In XmlVc, "part" is the one thing that calls ProcessChildren with non-null caller. // this should make some difference here, but I can't figure what yet, or come up with a test that fails. case "part": case "layout": // These are grouping nodes. In general this terminates things. However, if there is only // one thing embedded apart from comments and properties, we can proceed. XmlNode mainChild = FindMainChild(node); if (mainChild == null) { // no single non-trivial child, keep our current object collector.Add(new ManyOnePathSortItem(hvo, hvos, flids)); return; } // Recurse with same object, but process the 'main child'. CollectBrowseItems(hvo, mainChild, collector, mdc, sda, layouts, caller, hvos, flids); break; default: collector.Add(new ManyOnePathSortItem(hvo, hvos, flids)); break; } }
/// <summary> /// /// </summary> /// <param name="hvo"></param> /// <param name="tag"></param> /// <returns></returns> public int get_ObjectProp(int hvo, int tag) { return(m_sda.get_ObjectProp(hvo, tag)); }
/// <summary> /// Make one AND make the change to the cache. /// </summary> /// <param name="sda"></param> /// <param name="hvo"></param> /// <param name="flid"></param> /// <param name="newValue"></param> public CacheObjPropUndoAction(ISilDataAccess sda, int hvo, int flid, int newValue) { m_sda = sda; m_hvo = hvo; m_flid = flid; m_newValue = newValue; m_oldValue = 0; // Since this is used for fake props, if it isn't already cached, it doesn't have an old value. if (sda.get_IsPropInCache(hvo, flid, (int)CellarModuleDefns.kcptReferenceAtom, 0)) m_oldValue = sda.get_ObjectProp(hvo, flid); DoIt(m_newValue); }
/// <summary> /// If object hvo has no cached value for the property flidVirtual, do nothing. /// Otherwise, compute a new value for the property, and issue a PropChanged. (Currently only string type supported) /// If it has owning properties of type clidVirtual, do the same for all their items. /// </summary> /// <param name="hvo"></param> /// <param name="flidVirtual"></param> /// <param name="mdc"></param> /// <param name="sda"></param> private void RecomputeVirtuals(int hvo, uint clidVirtual, int flidVirtual, int typeVirtual, IFwMetaDataCache mdc, ISilDataAccess sda, IVwVirtualHandler vh) { if (Cache.GetClassOfObject(hvo) != clidVirtual) return; // Unless it's a computeEveryTime property, we don't need to worry if it's not already cached. if (vh.ComputeEveryTime || sda.get_IsPropInCache(hvo, flidVirtual, typeVirtual, 0)) { vh.Load(hvo, flidVirtual, 0, Cache.VwCacheDaAccessor); switch (typeVirtual) { case (int)CellarModuleDefns.kcptString: sda.PropChanged(null, (int)PropChangeType.kpctNotifyAll, hvo, flidVirtual, 0, 0, 0); break; default: Debug.WriteLine("RecomputeVirtuals: unimplemented prop type"); break; } } uint[] flids = DbOps.GetFieldsInClassOfType(mdc, (int)clidVirtual, FieldType.kgrfcptOwning); foreach (uint flid in flids) { int type = mdc.GetFieldType(flid); if (type == (int)CellarModuleDefns.kfcptOwningAtom) { RecomputeVirtuals(sda.get_ObjectProp(hvo, (int)flid), clidVirtual, flidVirtual, typeVirtual, mdc, sda, vh); } else { // must be owning sequence or collection; do them all. int chvo = sda.get_VecSize(hvo, (int)flid); for (int i = 0; i < chvo; i++) RecomputeVirtuals(sda.get_VecItem(hvo, (int)flid, i), clidVirtual, flidVirtual, typeVirtual, mdc, sda, vh); } } }
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); var hc = m_cache.ServiceLocator.GetInstance <HomographConfiguration>(); StringServices.InsertHomographNumber(tsBldr, nHomograph, hc, HomographConfiguration.HeadwordVariant.Main, m_cache); vwenv.AddString(tsBldr.GetString()); } }
private void TrySelectAnnotation(ISilDataAccess sda, InterlinDocChild pane, int annHvo) { // Try our best not to select an annotation we know won't work. int annoType = sda.get_ObjectProp(annHvo, kflidAnnotationType); int annInstanceOfRAHvo = sda.get_ObjectProp(annHvo, kflidInstanceOf); if (annInstanceOfRAHvo == 0 || annoType != CmAnnotationDefn.Twfic(Cache).Hvo) { // if we didn't set annHvo by our marker or Clerk.CurrentObject, // then we must have already tried the first word. if (m_bookmark.IndexOfParagraph < 0 && Clerk.CurrentObject.Hvo == 0) return; // reset our marker and return to avoid trying to reuse an "orphan annotation" // resulting from an Undo(). (cf. LT-2663). m_bookmark.Reset(); return; // Can't select nothing, so return. } pane.SelectAnnotation(annHvo); }
/// <summary> /// Obtain the value of an atomic reference property, including owner. ///</summary>S /// <param name='hvo'> </param> /// <param name='tag'> </param> /// <returns></returns> public virtual int get_ObjectProp(int hvo, int tag) { return(m_baseSda.get_ObjectProp(hvo, tag)); }
private void ApplyAnalysisToInstancesOfWordform(ISilDataAccess sda, int hvoNewAnalysis, int hvoOldWordform, int hvoNewWordform, bool fIsSentenceInitialCaseChange) { foreach (int hvoAnn in GetNextXfic()) { if (hvoAnn == m_hvoAnnotation) continue; // already processed. int hvoInstance = sda.get_ObjectProp(hvoAnn, (int)CmAnnotation.CmAnnotationTags.kflidInstanceOf); if (hvoInstance == 0) continue; // skip punctuation. if (CheckOkToConfirm(fIsSentenceInitialCaseChange, hvoOldWordform, hvoNewWordform, hvoAnn, hvoInstance)) { int hvoAnnNew = CacheAnalysisForAnnotation(hvoAnn, hvoNewAnalysis, sda); if (hvoAnnNew != 0) SimulateReplaceAnnotation(hvoAnnNew); } } }
private void LoadSecDataForEntry(ILexEntry entryReal, ILexSense senseReal, int hvoSbWord, IVwCacheDa cda, int wsVern, int hvoMbSec, int fGuessing, ISilDataAccess sdaMain, ITsStrFactory tsf) { int hvoEntry = m_caches.FindOrCreateSec(entryReal.Hvo, kclsidSbNamedObj, hvoSbWord, ktagSbWordDummy); // try to determine if the given entry is a variant of the sense we passed in (ie. not an owner) ILexEntryRef ler = null; int hvoEntryToDisplay = entryReal.Hvo; if (senseReal != null) { if ((entryReal as ILexEntry).IsVariantOfSenseOrOwnerEntry(senseReal, out ler)) hvoEntryToDisplay = senseReal.EntryID; } ITsString tssLexEntry = LexEntryVc.GetLexEntryTss(Cache, hvoEntryToDisplay, wsVern, ler); cda.CacheStringAlt(hvoEntry, ktagSbNamedObjName, wsVern, tssLexEntry); cda.CacheObjProp(hvoMbSec, ktagSbMorphEntry, hvoEntry); cda.CacheIntProp(hvoEntry, ktagSbNamedObjGuess, fGuessing); List<int> writingSystems = m_choices.OtherWritingSystemsForFlid(InterlinLineChoices.kflidLexEntries, 0); if (writingSystems.Count > 0) { // Sigh. We're trying for some reason to display other alternatives of the entry. int hvoLf = sdaMain.get_ObjectProp(hvoEntryToDisplay, LexEntryTags.kflidLexemeForm); if (hvoLf != 0) CopyStringsToSecondary(writingSystems, sdaMain, hvoLf, MoFormTags.kflidForm, cda, hvoEntry, ktagSbNamedObjName, tsf); else CopyStringsToSecondary(writingSystems, sdaMain, hvoEntryToDisplay, LexEntryTags.kflidCitationForm, cda, hvoEntry, ktagSbNamedObjName, tsf); } }
private bool IsItemEligible(ISilDataAccess sda, int hvo, ICmObject selectedObject, string labelToShow) { bool fEnable = false; if (string.IsNullOrEmpty(labelToShow)) return fEnable; int hvoFeats = sda.get_ObjectProp(hvo, PhPhonemeTags.kflidFeatures); if (hvoFeats == 0) return true; // phoneme does not have any features yet, so it is eligible var feats = m_cache.ServiceLocator.GetInstance<ICmObjectRepository>().GetObject(hvoFeats); int clsid = feats.ClassID; if (clsid == FsFeatStrucTags.kClassId) { // Only show it as a change if it is different var features = feats as IFsFeatStruc; switch (selectedObject.ClassID) { case FsSymFeatValTags.kClassId: // user has chosen a value for the targeted feature var symFeatVal = selectedObject as IFsSymFeatVal; if (symFeatVal != null && features != null) { var closedValue = from s in features.FeatureSpecsOC where s.ClassID == FsClosedValueTags.kClassId && ((IFsClosedValue) s).ValueRA == symFeatVal select s; fEnable = !closedValue.Any(); } break; case FsFeatStrucTags.kClassId: // user has specified one or more feature/value pairs var fs = selectedObject as IFsFeatStruc; if (fs != null) { var closedValue = from s in features.FeatureSpecsOC where s.ClassID == FsClosedValueTags.kClassId && s.FeatureRA.Abbreviation.BestAnalysisAlternative.Text == m_featDefnAbbr && ((IFsClosedValue) s).ValueRA.Abbreviation.BestAnalysisAlternative.Text == labelToShow select s; fEnable = !closedValue.Any(); } break; case FsClosedFeatureTags.kClassId: // user has chosen the remove targeted feature option var closedFeature = selectedObject as IFsClosedFeature; if (closedFeature != null) { var closedFeatures = from s in features.FeatureSpecsOC where s.FeatureRA == closedFeature select s; fEnable = closedFeatures.Any(); } break; default: fEnable = hvoFeats != SelectedHvo; break; } } return fEnable; }
// Check that the specified WfiAnalysis includes at least one morpheme bundle, and that all morpheme // bundles have the specified property set. Return true if all is well. private static bool CheckPropSetForAllMorphs(ISilDataAccess sda, int hvoWfiAnalysis, int flid) { int cbundle = sda.get_VecSize(hvoWfiAnalysis, (int)WfiAnalysis.WfiAnalysisTags.kflidMorphBundles); if (cbundle == 0) return false; for (int ibundle = 0; ibundle < cbundle; ibundle++) { int hvoBundle = sda.get_VecItem(hvoWfiAnalysis, (int)WfiAnalysis.WfiAnalysisTags.kflidMorphBundles, ibundle); if (sda.get_ObjectProp(hvoBundle, flid) == 0) return false; } return true; }
public void AutoLoad() { // Get the language project as an FDO object ILangProject lp = m_fdoCache.LangProject; // Use it to get the HVO of the data notebook, but without making an FDO object // and thus loading data. Assert.IsTrue(m_sda.get_IsPropInCache(lp.Hvo, (int)LangProject.LangProjectTags.kflidResearchNotebook, (int)CellarModuleDefns.kcptOwningAtom, 0), "LP notebook loaded by FDO"); int hvoNotebook = m_fdoCache.GetObjProperty(lp.Hvo, (int)LangProject.LangProjectTags.kflidResearchNotebook); // Owning atomic Assert.IsFalse(m_sda.get_IsPropInCache(hvoNotebook, (int)RnResearchNbk.RnResearchNbkTags.kflidEventTypes, (int)CellarModuleDefns.kcptOwningAtom, 0), "Notebook event types not preloaded"); int hvoEventTypes = m_sda.get_ObjectProp(hvoNotebook, (int)RnResearchNbk.RnResearchNbkTags.kflidEventTypes); Assert.IsTrue(m_sda.get_IsPropInCache(hvoNotebook, (int)RnResearchNbk.RnResearchNbkTags.kflidEventTypes, (int)CellarModuleDefns.kcptOwningAtom, 0), "Notebook event types autoloaded"); Assert.IsTrue(hvoEventTypes != 0, "got real event types"); int flidET = m_sda.get_IntProp(hvoEventTypes, (int)CmObjectFields.kflidCmObject_OwnFlid); Assert.AreEqual((int)RnResearchNbk.RnResearchNbkTags.kflidEventTypes, flidET, "owning flid loaded correctly"); int clsidET = m_sda.get_IntProp(hvoEventTypes, (int)CmObjectFields.kflidCmObject_Class); Assert.AreEqual((int)CmPossibilityList.kClassId, clsidET, "class autoloaded"); int ownerET = m_sda.get_ObjectProp(hvoEventTypes, (int)CmObjectFields.kflidCmObject_Owner); Assert.AreEqual(hvoNotebook, ownerET, "owner auto-loaded"); // Todo: test ref atomic. // Owning collection. Assert.IsFalse(m_sda.get_IsPropInCache(hvoNotebook, (int)RnResearchNbk.RnResearchNbkTags.kflidRecords, (int)CellarModuleDefns.kcptOwningCollection, 0), "Nb records not preloaded"); // Forces a load int chvoRecs = m_sda.get_VecSize(hvoNotebook, (int)RnResearchNbk.RnResearchNbkTags.kflidRecords); Assert.IsTrue(m_sda.get_IsPropInCache(hvoNotebook, (int)RnResearchNbk.RnResearchNbkTags.kflidRecords, (int)CellarModuleDefns.kcptOwningCollection, 0), "Nb records autoloaded"); // Be careful what we assert...don't want it too dependent on the exact data. // Should be OK to assume at least a few records. Assert.IsTrue(chvoRecs > 4, "at least 4 recs"); int hvoRec3 = m_sda.get_VecItem(hvoNotebook, (int)RnResearchNbk.RnResearchNbkTags.kflidRecords, 3); int clsIDR3 = m_sda.get_IntProp(hvoRec3, (int)CmObjectFields.kflidCmObject_Class); Assert.IsTrue((int)RnEvent.kClassId == clsIDR3 || (int)RnAnalysis.kClassId == clsIDR3, "class of rec 3 valid"); Assert.IsFalse(m_sda.get_IsPropInCache(hvoRec3, (int)RnGenericRec.RnGenericRecTags.kflidResearchers, (int)CellarModuleDefns.kcptReferenceCollection, 0), "R3 researchers not preloaded"); int chvoR3Researchers = m_sda.get_VecSize(hvoRec3, (int)RnGenericRec.RnGenericRecTags.kflidResearchers); Assert.IsTrue(m_sda.get_IsPropInCache(hvoRec3, (int)RnGenericRec.RnGenericRecTags.kflidResearchers, (int)CellarModuleDefns.kcptReferenceCollection, 0), "R3 researchers autoloaded"); // We can't assume anything about any one record, but we should be able to find // at least one where researchers is non-empty. Along the way we do at least // some testing of VecProp and also make sure we can load a string that is a // BigString bool fGotEmpty = false; bool fGotNonEmpty = false; bool fGotEvent = false; int hvoEvent = 0; // some record will be an event... int hvoText = 0; // that has a non-empty structured text... int hvoPara = 0; // that has a non-empty paragraph with a label. for (int ihvo = 0; ihvo < chvoRecs && ((!fGotEmpty) || (!fGotNonEmpty) || (!fGotEvent) || hvoText == 0); ihvo++) { int hvoRec = m_sda.get_VecItem(hvoNotebook, (int)RnResearchNbk.RnResearchNbkTags.kflidRecords, ihvo); int chvoResearchers = m_sda.get_VecSize(hvoRec, (int)RnGenericRec.RnGenericRecTags.kflidResearchers); if (chvoResearchers > 0) { if (!fGotNonEmpty) { fGotNonEmpty = true; // Try this on the first non-empty list. int hvoResearcher = m_sda.get_VecItem(hvoRec, (int)RnGenericRec.RnGenericRecTags.kflidResearchers, 0); int clsidResearcher = m_sda.get_IntProp(hvoResearcher, (int)CmObjectFields.kflidCmObject_Class); Assert.AreEqual(CmPerson.kClassId, clsidResearcher, "class of researcher"); } } else { fGotEmpty = true; // should now be considered cached anyway. Assert.IsTrue(m_sda.get_IsPropInCache(hvoRec, (int)RnGenericRec.RnGenericRecTags.kflidResearchers, (int)CellarModuleDefns.kcptReferenceCollection, 0), "empty researchers autoloaded"); } int clsIDRec = m_sda.get_IntProp(hvoRec, (int)CmObjectFields.kflidCmObject_Class); if (clsIDRec == (int)RnEvent.kClassId && !fGotEvent) { hvoEvent = hvoRec; hvoText = m_sda.get_ObjectProp(hvoEvent, (int)RnEvent.RnEventTags.kflidDescription); if (hvoText != 0) { int chvo; using (ArrayPtr arrayPtr = MarshalEx.ArrayToNative(1000, typeof(int))) { // if there's a description with more than 1000 paragraphs this will break and // we'll fix it then. m_sda.VecProp(hvoText, (int)StText.StTextTags.kflidParagraphs, 1000, out chvo, arrayPtr); int[] rgHvo = (int[])MarshalEx.NativeToArray(arrayPtr, chvo, typeof(int)); // search for the paragraph that has non-empty label (there are a couple). for (int ihvoPara = 0; ihvoPara < chvo; ++ihvoPara) { hvoPara = rgHvo[ihvoPara]; // BigString ITsString tssPara = m_sda.get_StringProp(hvoPara, (int)StTxtPara.StTxtParaTags.kflidContents); if (tssPara.Length > 0) { string sname = m_sda.get_UnicodeProp(hvoPara, (int)StPara.StParaTags.kflidStyleName); if (sname != null && sname.Length > 0) { fGotEvent = true; } // Todo: it would be nice to test UnicodePropRgch, but we can't test // on the same prop because it's already loaded. Also, the modification // for data loading is shared code. We could make another cache instance // to test from, maybe? Or keep searching till we find another instance? // Could also look for a kcptBigUnicode, but implementation is identical. } } } } } } Assert.IsTrue(fGotEmpty && fGotNonEmpty, "found both empty and non-empty researcher lists"); Assert.IsTrue(hvoEvent != 0, "got at least one event"); // todo: test sequence (somehow verify order). // todo: test ref seq/collection (verify it does NOT set the owner to the referring obj). // Ref atomic Assert.IsFalse(m_sda.get_IsPropInCache(hvoRec3, (int)RnGenericRec.RnGenericRecTags.kflidConfidence, (int)CellarModuleDefns.kcptReferenceAtom, 0), "R3 confidence not preloaded"); int hvoConfidence = m_sda.get_ObjectProp(hvoRec3, (int)RnGenericRec.RnGenericRecTags.kflidConfidence); Assert.IsTrue(m_sda.get_IsPropInCache(hvoRec3, (int)RnGenericRec.RnGenericRecTags.kflidConfidence, (int)CellarModuleDefns.kcptReferenceAtom, 0), "R3 confidence autoloaded"); if (hvoConfidence != 0) { int clsidConfidence = m_sda.get_IntProp(hvoConfidence, (int)CmObjectFields.kflidCmObject_Class); Assert.AreEqual(CmPossibility.kClassId, clsidConfidence, "class of confidence"); } // TsString. Assert.IsFalse(m_sda.get_IsPropInCache(hvoRec3, (int)RnGenericRec.RnGenericRecTags.kflidTitle, (int)CellarModuleDefns.kcptString, 0), "title of rec 3 not preloaded"); ITsString qtssRec3Title = m_sda.get_StringProp(hvoRec3, (int)RnGenericRec.RnGenericRecTags.kflidTitle); Assert.IsTrue(m_sda.get_IsPropInCache(hvoRec3, (int)RnGenericRec.RnGenericRecTags.kflidTitle, (int)CellarModuleDefns.kcptString, 0), "autoloaded title of rec 3"); // Int (e.g., gendate) Assert.IsFalse(m_sda.get_IsPropInCache(hvoEvent, (int)RnEvent.RnEventTags.kflidDateOfEvent, (int)CellarModuleDefns.kcptInteger, 0), "date of event not preloaded"); int nDateEvent = m_sda.get_IntProp(hvoEvent, (int)RnEvent.RnEventTags.kflidDateOfEvent); Assert.IsTrue(m_sda.get_IsPropInCache(hvoEvent, (int)RnEvent.RnEventTags.kflidDateOfEvent, (int)CellarModuleDefns.kcptInteger, 0), "autoloaded date of event"); // Todo: find example of int64 prop and test. // Test loading of binary data (into a TsTextProps). object obj = m_sda.get_UnknownProp(hvoPara, (int)StPara.StParaTags.kflidStyleRules); Assert.IsNotNull(obj as ITsTextProps); // Also loading of raw binary data, using the same prop. using (ArrayPtr rgbData = MarshalEx.ArrayToNative(10000, typeof(byte))) { int cb = -1; m_sda.BinaryPropRgb(hvoPara, (int)StPara.StParaTags.kflidStyleRules, rgbData, 10000, out cb); Assert.IsTrue(cb > 0, "got some bytes using BinaryPropRgb"); // Enhance JohnT: wish I could figure what they ought to be and test... // Get a UserView object (they have no owner, so go direct) SqlConnection con = new SqlConnection(string.Format("Server={0}; Database={1}; User ID = fwdeveloper;" + "Password=careful; Pooling=false;", m_fdoCache.ServerName, m_fdoCache.DatabaseName)); con.Open(); SqlCommand cmd = con.CreateCommand(); cmd.CommandText = "select top 2 id from UserView"; SqlDataReader reader = cmd.ExecuteReader(); reader.Read(); int hvoUv = reader.GetInt32(0); reader.Close(); con.Close(); // Guid prop Guid guidUv = m_sda.get_GuidProp(hvoUv, (int)UserView.UserViewTags.kflidApp); Assert.IsFalse(guidUv == Guid.Empty, "got non-empty guid"); // Time prop long lEventTime = m_sda.get_TimeProp(hvoEvent, (int)RnGenericRec.RnGenericRecTags.kflidDateCreated); Assert.IsFalse(lEventTime == 0, "got meaningful time"); // Enhance JohnT: really verify. // Int prop int viewSubtype = m_sda.get_IntProp(hvoUv, (int)UserView.UserViewTags.kflidSubType); // Enhance JohnT: think of a way to verify... // get_Prop: Time object objMod = m_sda.get_Prop(hvoRec3, (int)RnGenericRec.RnGenericRecTags.kflidDateModified); Assert.IsTrue(objMod is long); // get_Prop: String int hvoRec0 = m_sda.get_VecItem(hvoNotebook, (int)RnResearchNbk.RnResearchNbkTags.kflidRecords, 0); object objTitle = m_sda.get_Prop(hvoRec0, (int)RnGenericRec.RnGenericRecTags.kflidTitle); Assert.IsTrue(objTitle is ITsString, "get_Prop title is string"); // get_Prop: Int object objType = m_sda.get_Prop(hvoUv, (int)UserView.UserViewTags.kflidType); Assert.IsTrue(objType is int, "get_Prop type is integer"); // Confirm some more results by loading through FDO ICmObject objRec3 = CmObject.CreateFromDBObject(m_fdoCache, hvoRec3); Assert.IsTrue(objRec3 is IRnGenericRec, "object of correct type"); IRnGenericRec grRec3 = (IRnGenericRec)objRec3; // I'd prefer to use full ITsString equality test, but not sure how to get // a regular ITsString from FDO obj. Assert.AreEqual(qtssRec3Title.Text, grRec3.Title.Text, "two ways to retrieve R3 title match"); // Can't try this yet because FDO GenDate not yet implemented. The data type might not // be right anyway. // CmObject objEvent = CmObject.CreateFromDBObject(m_fdoCache, hvoEvent); // Assert.IsTrue(objEvent is RnEvent, "type of event"); // RnEvent ev1 = (RnEvent) objEvent; // Assert.AreEqual(ev1.DateOfEvent, nDateEvent, "date of event matches"); } }
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); } // Show homograph number if non-zero. int defUserWs = m_cache.WritingSystemFactory.UserWs; int nHomograph = sda.get_IntProp(hvo, LexEntryTags.kflidHomographNumber); var hc = m_cache.ServiceLocator.GetInstance <HomographConfiguration>(); //Insert HomographNumber when position is Before if (hc.HomographNumberBefore) { InsertHomographNumber(vwenv, hc, nHomograph, defUserWs); } // 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.MakeString(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.MakeString(sPrefix, wsActual)); } vwenv.AddStringAltMember(LexEntryTags.kflidCitationForm, wsActual, this); fGotLabel = true; } } if (!fGotLabel) { // If that fails just show two questions marks. if (sPrefix != null) { vwenv.AddString(TsStringUtils.MakeString(sPrefix, wsActual)); } vwenv.AddString(TsStringUtils.MakeString(FdoUiStrings.ksQuestions, defUserWs)); // was "??", not "???" } // If we have a lexeme form type show the appropriate postfix. if (hvoType != 0) { vwenv.AddString(TsStringUtils.MakeString( sda.get_UnicodeProp(hvoType, MoMorphTypeTags.kflidPostfix), wsActual)); } vwenv.NoteDependency(new[] { hvo }, new[] { LexEntryTags.kflidHomographNumber }, 1); //Insert HomographNumber when position is After if (!hc.HomographNumberBefore) { InsertHomographNumber(vwenv, hc, nHomograph, defUserWs); } }
protected virtual int HvoOfObjectToDisplay(IVwEnv vwenv, int hvo) { ISilDataAccess sda = vwenv.DataAccess; return(sda.get_ObjectProp(hvo, m_flid)); }
/// ----------------------------------------------------------------------------------- /// <summary> /// Display the specified object (from an ORC embedded in a string). The default /// here knows how to display IPictures. /// </summary> /// <param name="vwenv"></param> /// <param name="hvo"></param> /// ----------------------------------------------------------------------------------- public virtual void DisplayEmbeddedObject(IVwEnv vwenv, int hvo) { CheckDisposed(); // See if it is a CmPicture. ISilDataAccess sda = vwenv.DataAccess; int clsid = sda.get_IntProp(hvo, (int)CmObjectFields.kflidCmObject_Class); if (clsid != CmPicture.kclsidCmPicture) { return; // don't know how to deal with it. } int hvoFile = sda.get_ObjectProp(hvo, (int)CmPicture.CmPictureTags.kflidPictureFile); if (hvoFile == 0) { return; } string path; string fileName = sda.get_UnicodeProp(hvoFile, (int)CmFile.CmFileTags.kflidInternalPath); if (Path.IsPathRooted(fileName)) { path = fileName; } else { if (m_hvoLangProject == 0) { TryToSetLangProjectHvo(sda, hvo); } string externalRoot = sda.get_UnicodeProp(m_hvoLangProject, (int)LangProject.LangProjectTags.kflidExtLinkRootDir); if (String.IsNullOrEmpty(externalRoot)) { path = Path.Combine(DirectoryFinder.FWDataDirectory, fileName); } else { path = Path.Combine(externalRoot, fileName); } } vwenv.set_IntProperty((int)FwTextPropType.ktptAlign, (int)FwTextPropVar.ktpvEnum, (int)FwTextAlign.ktalCenter); Image image; try { image = Image.FromFile(FileUtils.ActualFilePath(path)); } catch { // unable to read image. set to default image that indicates an invalid image. image = ResourceHelper.ImageNotFoundX; } stdole.IPicture picture; try { picture = (stdole.IPicture)OLECvt.ToOLE_IPictureDisp(image); } catch { // conversion to OLE format from current image format is not supported (e.g. WMF file) // try to convert it to a bitmap and convert it to OLE format again. // TODO: deal with transparency // We could just do the following line (creating a new bitmap) instead of going // through a memory stream, but then we end up with an image that is too big. //image = new Bitmap(image, image.Size); using (MemoryStream imageStream = new MemoryStream()) { image.Save(imageStream, ImageFormat.Png); image = Image.FromStream(imageStream, true); } picture = (stdole.IPicture)OLECvt.ToOLE_IPictureDisp(image); } // -1 is ktagNotAnAttr. 0 width & height mean use natural width/height. vwenv.AddPictureWithCaption(picture, -1, CaptionProps, hvoFile, m_wsDefault, 0, 0, this); image.Dispose(); }
private static void AddHvoPOStoResults(ISilDataAccess sda, List<int> results, int hvoMsa, int flidPos) { int hvoPOS; hvoPOS = sda.get_ObjectProp(hvoMsa, flidPos); if (hvoPOS != 0) results.Add(hvoPOS); }
int OwnerOf(int hvo, ISilDataAccess sda) { return sda.get_ObjectProp(hvo, (int)CmObjectFields.kflidCmObject_Owner); }