/// <summary> /// Setup DependencyPaths property /// </summary> /// <param name="configuration"></param> /// <param name="cache"></param> protected void SetupDependencies(XmlNode configuration, FdoCache cache) { if (DependencyPaths.Count > 0) { return; // already setup. } string dependsStr = XmlUtils.GetOptionalAttributeValue(configuration, "depends"); if (dependsStr == null || cache == null) { return; } string[] depends = dependsStr.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string fieldPath in depends) { string[] fieldtree = fieldPath.Split(new char[] { '.' }); List <int> tags = new List <int>(fieldtree.Length); string srcClassName = this.ClassName; foreach (string field in fieldtree) { int tag = cache.GetFlid(0, srcClassName, field); Debug.Assert(tag > 0, String.Format("Invalid dependency field {0} in field path {1}.", field, fieldPath)); if (tag <= 0) { break; } tags.Add(tag); if (tags.Count < fieldtree.Length) { string nextFieldName = fieldtree[tags.Count]; // make dst class the source class of next field uint clsidDst = 0; if (field == "OwnerHVO") { // handle the special case where we need the owning class // this is only possible if srcClassName is has a unique owner. // find the first class that owns the given 'classId' and the given fieldName. clsidDst = GetClassOwningClassAndFieldName(cache, srcClassName, nextFieldName); } else { ClassAndPropInfo cpi = cache.GetClassAndPropInfo((uint)tag); if (ClassHasField(cache, cache.GetClassName(cpi.signatureClsid), nextFieldName)) { clsidDst = cpi.signatureClsid; } else if (cpi.isAbstract) { // find a subclasses that could refer to the nextFieldName. clsidDst = GetSubclassOwningNextField(cache, tag, nextFieldName); } } srcClassName = cache.GetClassName(clsidDst); } } m_fieldPaths.Add(tags); } }
/// <summary> /// /// </summary> /// <param name="cache"></param> /// <param name="tbl"></param> /// <param name="clsId"></param> /// <param name="titleStr">*{dstClass}* if couldn't find result.</param> /// <returns>true if we found an alternate form. false if titleStr is null or in *{ClassName}* format.</returns> public static bool TryFindPluralFormFromClassId(FdoCache cache, StringTable tbl, uint clsId, out string titleStr) { titleStr = null; if (clsId != 0) { string className = cache.GetClassName(clsId); return TryFindString(tbl, "AlternativeTitles", String.Format("{0}-Plural", className), out titleStr); } return false; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets virtual property handler corresponding to filter instance. /// </summary> /// <param name="cache">The FDO Cache</param> /// <param name="owningClassId">The ID of the class which will own this virtual /// property</param> /// <param name="filter">The filter whose virtual handler we want</param> /// <param name="filterInstance">Number used to make filters unique for each main /// window</param> /// <returns>The existing virtual handler for this filter and instance, if any; /// otherwise <c>null</c></returns> /// <remarks>TODO (TE-3941): pass sort method also (and use it)</remarks> /// ------------------------------------------------------------------------------------ public static FilteredSequenceHandler GetFilterInstance(FdoCache cache, int owningClassId, IFilter filter, int filterInstance) { if (cache == null) { return(null); } return(cache.GetVirtualProperty(cache.GetClassName((uint)owningClassId), GetVirtualPropertyName(filter, null, filterInstance)) as FilteredSequenceHandler); }
/// <summary> /// handle the special case where we need the owning class /// this is only possible if srcClassName is has a unique owner. /// find the first class that owns the given 'classId' and the given fieldName. /// </summary> /// <param name="cache"></param> /// <param name="ownedClassName"></param> /// <param name="nextFieldName"></param> /// <returns></returns> private static uint GetClassOwningClassAndFieldName(FdoCache cache, string ownedClassName, string nextFieldName) { uint clsidDst = 0; uint clsidOwned = cache.MetaDataCacheAccessor.GetClassId(ownedClassName); foreach (ClassAndPropInfo cpi in cache.GetFieldsOwningClass(clsidOwned)) { if (ClassHasField(cache, cache.GetClassName(cpi.sourceClsid), nextFieldName)) { clsidDst = cpi.sourceClsid; break; } } return(clsidDst); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="FilteredSequenceHandler"/> class. /// </summary> /// <param name="cache">The FDO cache</param> /// <param name="owningClassId">The ID of the class which will own this virtual /// property</param> /// <param name="filterInstance">Number used to make filters unique for each main /// window</param> /// <param name="filter">A CmFilter that specifies the details of how to filter the /// notes (can be null)</param> /// <param name="sortMethod">TODO (TE-3941): use this. A CmSortSpec that specifies the /// details of how to sort the notes (can be null)</param> /// <param name="flidProvider">The method that provides the flid that is used to /// retrieve all records.</param> /// ------------------------------------------------------------------------------------ public FilteredSequenceHandler(FdoCache cache, int owningClassId, int filterInstance, IFilter filter, ISortSpec sortMethod, IFlidProvider flidProvider) { m_cache = cache; m_filter = filter; m_flidProvider = flidProvider; if (m_filter != null) { m_filter.InitCriteria(); } m_sortMethod = sortMethod; ClassName = m_cache.GetClassName((uint)owningClassId); FieldName = GetVirtualPropertyName(filter, sortMethod, filterInstance); Type = (int)CellarModuleDefns.kcptReferenceSequence; ComputeEveryTime = false; cache.InstallVirtualProperty(this); }
/// <summary> /// Create the ordered vector of writing sytems to try for displaying names. /// </summary> protected void EstablishWritingSystemsToTry(string sDisplayWs) { if (m_cache == null || m_writingSystemIds != null) { return; } if (sDisplayWs == null || sDisplayWs == String.Empty) { sDisplayWs = "analysis vernacular"; // very general default. } int flid = 0; if (!string.IsNullOrEmpty(m_displayNameProperty)) { string className = m_cache.GetClassName((uint)m_cache.GetClassOfObject(Hvo)); IVwVirtualHandler vh = m_cache.VwCacheDaAccessor.GetVirtualHandlerName(className, m_displayNameProperty); if (vh != null) { flid = vh.Tag; } } m_writingSystemIds = LangProject.GetWritingSystemIdsFromLabel(m_cache, sDisplayWs, m_cache.DefaultUserWs, m_hvo, flid, null); }
/// <summary> /// Setup DependencyPaths property /// </summary> /// <param name="configuration"></param> /// <param name="cache"></param> protected void SetupDependencies(XmlNode configuration, FdoCache cache) { if (DependencyPaths.Count > 0) return; // already setup. string dependsStr = XmlUtils.GetOptionalAttributeValue(configuration, "depends"); if (dependsStr == null || cache == null) return; string[] depends = dependsStr.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string fieldPath in depends) { string[] fieldtree = fieldPath.Split(new char[] { '.' }); List<int> tags = new List<int>(fieldtree.Length); string srcClassName = this.ClassName; foreach (string field in fieldtree) { int tag = cache.GetFlid(0, srcClassName, field); Debug.Assert(tag > 0, String.Format("Invalid dependency field {0} in field path {1}.", field, fieldPath)); if (tag <= 0) break; tags.Add(tag); if (tags.Count < fieldtree.Length) { string nextFieldName = fieldtree[tags.Count]; // make dst class the source class of next field uint clsidDst = 0; if (field == "OwnerHVO") { // handle the special case where we need the owning class // this is only possible if srcClassName is has a unique owner. // find the first class that owns the given 'classId' and the given fieldName. clsidDst = GetClassOwningClassAndFieldName(cache, srcClassName, nextFieldName); } else { ClassAndPropInfo cpi = cache.GetClassAndPropInfo((uint)tag); if (ClassHasField(cache, cache.GetClassName(cpi.signatureClsid), nextFieldName)) { clsidDst = cpi.signatureClsid; } else if (cpi.isAbstract) { // find a subclasses that could refer to the nextFieldName. clsidDst = GetSubclassOwningNextField(cache, tag, nextFieldName); } } srcClassName = cache.GetClassName(clsidDst); } } m_fieldPaths.Add(tags); } }
/// <summary> /// handle the special case where we need the owning class /// this is only possible if srcClassName is has a unique owner. /// find the first class that owns the given 'classId' and the given fieldName. /// </summary> /// <param name="cache"></param> /// <param name="ownedClassName"></param> /// <param name="nextFieldName"></param> /// <returns></returns> private static uint GetClassOwningClassAndFieldName(FdoCache cache, string ownedClassName, string nextFieldName) { uint clsidDst = 0; uint clsidOwned = cache.MetaDataCacheAccessor.GetClassId(ownedClassName); foreach (ClassAndPropInfo cpi in cache.GetFieldsOwningClass(clsidOwned)) { if (ClassHasField(cache, cache.GetClassName(cpi.sourceClsid), nextFieldName)) { clsidDst = cpi.sourceClsid; break; } } return clsidDst; }
/// ------------------------------------------------------------------------------------ /// <summary> /// gives the CSharp type corresponding to the given the fieldworks class ID /// </summary> /// <param name="fcCache"></param> /// <param name="iClassId"></param> /// <returns></returns> /// ------------------------------------------------------------------------------------ public static Type GetTypeFromFWClassID(FdoCache fcCache, int iClassId) { //CmObject is a special case because it is not part of a module. if (iClassId == CmObject.kClassId) return typeof(CmObject); // if the class ID is cached then return the type now. if (s_classIdToType.ContainsKey(iClassId)) return s_classIdToType[iClassId]; Type t = null; // Find the class name of this object string sClassName = fcCache.GetClassName((uint)iClassId); // find the Type for this class, which is painful 'cause we don't know the namespace string[] modules = new string[]{"Cellar", "Ling", "Scripture", "FeatSys", "LangProj", "Notebk"}; foreach(string moduleName in modules) { string fullTypeName = string.Format("SIL.FieldWorks.FDO.{0}.{1}", moduleName, sClassName); t = fcCache.GetTypeInAssembly(fullTypeName); //t = Assembly.GetExecutingAssembly().GetType(fullTypeName, false, false); if (t != null) break; } Debug.Assert(t != null); // cache the type info and return it. s_classIdToType.Add(iClassId, t); return t; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets virtual property handler corresponding to filter instance. /// </summary> /// <param name="cache">The FDO Cache</param> /// <param name="owningClassId">The ID of the class which will own this virtual /// property</param> /// <param name="filter">The filter whose virtual handler we want</param> /// <param name="filterInstance">Number used to make filters unique for each main /// window</param> /// <returns>The existing virtual handler for this filter and instance, if any; /// otherwise <c>null</c></returns> /// <remarks>TODO (TE-3941): pass sort method also (and use it)</remarks> /// ------------------------------------------------------------------------------------ public static FilteredSequenceHandler GetFilterInstance(FdoCache cache, int owningClassId, IFilter filter, int filterInstance) { if (cache == null) return null; return cache.GetVirtualProperty(cache.GetClassName((uint)owningClassId), GetVirtualPropertyName(filter, null, filterInstance)) as FilteredSequenceHandler; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="FilteredSequenceHandler"/> class. /// </summary> /// <param name="cache">The FDO cache</param> /// <param name="owningClassId">The ID of the class which will own this virtual /// property</param> /// <param name="filterInstance">Number used to make filters unique for each main /// window</param> /// <param name="filter">A CmFilter that specifies the details of how to filter the /// notes (can be null)</param> /// <param name="sortMethod">TODO (TE-3941): use this. A CmSortSpec that specifies the /// details of how to sort the notes (can be null)</param> /// <param name="flidProvider">The method that provides the flid that is used to /// retrieve all records.</param> /// ------------------------------------------------------------------------------------ public FilteredSequenceHandler(FdoCache cache, int owningClassId, int filterInstance, IFilter filter, ISortSpec sortMethod, IFlidProvider flidProvider) { m_cache = cache; m_filter = filter; m_flidProvider = flidProvider; if (m_filter != null) m_filter.InitCriteria(); m_sortMethod = sortMethod; ClassName = m_cache.GetClassName((uint)owningClassId); FieldName = GetVirtualPropertyName(filter, sortMethod, filterInstance); Type = (int) CellarModuleDefns.kcptReferenceSequence; ComputeEveryTime = false; cache.InstallVirtualProperty(this); }