/// <summary> /// Returns a dictionary of custom fields at the LexEntry, LexSense, and LexExampleSentence levels /// From Lcm to LF. If the dictionary doesn't exist, create one. /// </summary> /// <returns>Dictionary of custom fields where the keys are the parent listCode</returns> public Dictionary <string, ICmPossibilityList> GetCustomFieldParentLists() { // Generate the dictionary of custom fields var lfCustomFieldLists = new Dictionary <string, ICmPossibilityList>(); // The three classes that are allowed to have custom fields in them are LexEntry, LexSense, and LexExampleSentence List <int> customFieldIds = new List <int>( LcmMetaData.GetFields(LexEntryTags.kClassId, false, (int)CellarPropertyTypeFilter.AllReference) .Where(flid => cache.GetIsCustomField(flid) && LcmMetaData.GetFieldListRoot(flid) != Guid.Empty)); customFieldIds.AddRange( LcmMetaData.GetFields(LexSenseTags.kClassId, false, (int)CellarPropertyTypeFilter.AllReference) .Where(flid => cache.GetIsCustomField(flid) && LcmMetaData.GetFieldListRoot(flid) != Guid.Empty)); customFieldIds.AddRange( LcmMetaData.GetFields(LexExampleSentenceTags.kClassId, false, (int)CellarPropertyTypeFilter.AllReference) .Where(flid => cache.GetIsCustomField(flid) && LcmMetaData.GetFieldListRoot(flid) != Guid.Empty)); var listRepo = servLoc.GetInstance <ICmPossibilityListRepository>(); foreach (int flid in customFieldIds) { Guid parentListGuid = LcmMetaData.GetFieldListRoot(flid); string listCode = GetParentListCode(flid); lfCustomFieldLists[listCode] = listRepo.GetObject(parentListGuid); } return(lfCustomFieldLists); }
private static Dictionary <string, List <PropertyInfo> > CacheBasicProperties(IFwMetaDataCacheManaged mdc) { var cachedBasicProperties = new Dictionary <string, List <PropertyInfo> >(); foreach (var classId in mdc.GetClassIds()) { var className = mdc.GetClassName(classId); List <PropertyInfo> basicProps; if (!cachedBasicProperties.TryGetValue(className, out basicProps)) { basicProps = new List <PropertyInfo>(); cachedBasicProperties.Add(className, basicProps); } basicProps.AddRange(mdc.GetFields(classId, className != "CmObject", (int)CellarPropertyTypeFilter.AllBasic).Select(propId => new PropertyInfo { m_propertyName = mdc.GetFieldName(propId), m_propertyType = (CellarPropertyType)mdc.GetFieldType(propId), m_isCustom = mdc.IsCustom(propId), m_isVirtual = mdc.get_IsVirtual(propId) })); if (basicProps.Count == 0) { cachedBasicProperties.Remove(className); } } return(cachedBasicProperties); }
private void m_btnAddCustom_Click(object sender, EventArgs e) { // What we'd like to do is the following bit of code, but we can't due to // circular dependencies that would be introduced. We could possibly move // the dialog to another assembly/dll, but that would require reworking a // fair number of strings that have been converted to resources. //using (var dlg = new AddCustomFieldDlg(m_mediator, AddCustomFieldDlg.LocationType.Notebook)) // dlg.ShowDialog(); System.Type typeFound; MethodInfo mi = XmlUtils.GetStaticMethod("xWorks.dll", "SIL.FieldWorks.XWorks.AddCustomFieldDlg", "ShowNotebookCustomFieldDlg", "AnthroFieldMappingDlg.m_btnAddCustom_Click()", out typeFound); if (mi != null) { var parameters = new object[2]; parameters[0] = m_mediator; parameters[1] = m_propertyTable; mi.Invoke(typeFound, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, null, parameters, null); // Now, clean up our map of possible field targets and reload the field combo list. List <int> delFields = new List <int>(); foreach (int key in m_mapFlidName.Keys) { if (!m_mdc.FieldExists(key)) { delFields.Add(key); } } foreach (int flid in delFields) { m_mapFlidName.Remove(flid); } foreach (int flid in m_mdc.GetFields(RnGenericRecTags.kClassId, false, (int)CellarPropertyTypeFilter.All)) { if (m_mapFlidName.ContainsKey(flid)) { continue; } if (m_mdc.IsCustom(flid)) { string name = m_mdc.GetFieldName(flid); m_mapFlidName.Add(flid, name); } } FillInFieldList(); } else { } }
public void SetCustomFieldsForThisCmObject(ICmObject cmObj, string objectType, BsonDocument customFieldValues, BsonDocument customFieldGuids) { if (customFieldValues == null) { return; } IEnumerable <int> customFieldIds = lcmMetaData.GetFields(cmObj.ClassID, false, (int)CellarPropertyTypeFilter.All) .Where(flid => cache.GetIsCustomField(flid)); var remainingFieldNames = new HashSet <string>(customFieldValues.Select(elem => elem.Name)); foreach (int flid in customFieldIds) { string fieldName = lcmMetaData.GetFieldNameOrNull(flid); if (fieldName == null) { return; } fieldName = ConvertUtilities.NormalizedFieldName(fieldName, objectType); BsonValue fieldValue = customFieldValues.GetValue(fieldName, BsonNull.Value); BsonValue fieldGuidOrGuids = (customFieldGuids == null) ? BsonNull.Value : customFieldGuids.GetValue(fieldName, BsonNull.Value); // Persist Guid.Empty as null to save space if (fieldGuidOrGuids.BsonType == BsonType.String && fieldGuidOrGuids.AsString == "00000000-0000-0000-0000-000000000000") { fieldGuidOrGuids = BsonNull.Value; } remainingFieldNames.Remove(fieldName); if (fieldValue != BsonNull.Value) { SetCustomFieldData(cmObj.Hvo, flid, fieldValue, fieldGuidOrGuids); } } foreach (string fieldName in remainingFieldNames) { // TODO: These are NEW CUSTOM FIELDS! Will need to create them in LCM, then do: // BsonValue fieldValue = customFieldValues.GetValue(fieldName, BsonNull.Value); // BsonValue fieldGuidOrGuids = customFieldGuids.GetValue(fieldName, BsonNull.Value); // SetCustomFieldData(cmObj.Hvo, flid, fieldValue, fieldGuidOrGuids); // Above lines commented out until we can create new custom fields correctly. 2015-11 RM logger.Warning("Custom field {0} from LF skipped, because we're not yet creating new custom fields in LCM", fieldName); } }
private void ExportRecords(TextWriter writer, IProgress progress) { m_mdc = m_cache.ServiceLocator.GetInstance <IFwMetaDataCacheManaged>(); foreach (int flid in m_mdc.GetFields(RnGenericRecTags.kClassId, true, (int)CellarPropertyTypeFilter.All)) { if (m_mdc.IsCustom(flid)) { m_customFlids.Add(flid); } } writer.WriteLine("<Entries docRightToLeft=\"{0}\">", m_fRightToLeft ? "true" : "false"); foreach (var record in m_cache.LangProject.ResearchNotebookOA.RecordsOC) { ExportRecord(writer, record, 0); progress.Step(1); } writer.WriteLine("</Entries>"); }
/// <summary> /// Get the field values as a dict, keyed by field ID, for any CmObject. /// </summary> /// <returns>A dictionary with integer field ID mapped to values.</returns> /// <param name="cache">LCM cache the object lives in.</param> /// <param name="obj">Object whose fields we're getting.</param> protected IDictionary <int, object> GetFieldValues(LcmCache cache, ICmObject obj) { IFwMetaDataCacheManaged mdc = cache.ServiceLocator.MetaDataCache; ISilDataAccess data = cache.DomainDataByFlid; int[] fieldIds = mdc.GetFields(obj.ClassID, false, (int)CellarPropertyTypeFilter.All); var fieldValues = new Dictionary <int, object>(); foreach (int flid in fieldIds) { if (mdc.IsCustom(flid)) { continue; // Custom fields get processed differently } string fieldName = mdc.GetFieldNameOrNull(flid); if (String.IsNullOrEmpty(fieldName)) { continue; } object value = data.get_Prop(obj.Hvo, flid); fieldValues[flid] = value; } return(fieldValues); }
/// <summary> /// Gets a list of the fields for the specified class. /// Gets all fields whose types match the specified argument, which should be a combination /// of the fcpt values defined in CmTypes.h, e.g., to get all owning properties /// pass kfcptOwningCollection | kfcptOwningAtom | kfcptOwningSequence. /// Returns E_FAIL if the array is too small. cflidMax 0 may be passed to obtain the required /// size. /// Fields of superclasses are also returned, if the relevant flag is true. /// [Note: The special CmObject fields are not returned, for now, /// but the plan to include them before too long.] ///</summary> /// <param name='luClid'> </param> /// <param name='fIncludeSuperclasses'> </param> /// <param name='grfcpt'> </param> /// <param name='cflidMax'> </param> /// <param name='_rgflid'> </param> /// <returns></returns> public virtual int GetFields(int luClid, bool fIncludeSuperclasses, int grfcpt, int cflidMax, ArrayPtr _rgflid) { return(m_metaDataCache.GetFields(luClid, fIncludeSuperclasses, grfcpt, cflidMax, _rgflid)); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Refresh the lv (list view) control based on the tv (tree view) control. /// </summary> /// ------------------------------------------------------------------------------------ public void AfterSelectMethod() { string holdType = "", holdSig = ""; int clid = (int)m_tvModel.SelectedNode.Tag; // Get flids. int[] uFlids = m_mdc.GetFields(clid, true, (int)CellarPropertyTypeFilter.All); List <ListViewItem> list = new List <ListViewItem>(); for (int i = uFlids.Length - 1; i >= 0; --i) { int flid = uFlids[i]; if (flid == 0) { continue; // Keep looking for suitable flids lower in the array. } else { if (FDOBrowserForm.m_virtualFlag == false && (flid >= 20000000 && flid < 30000000)) { continue; } else { string className = m_mdc.GetOwnClsName(flid); ListViewItem lvi = new ListViewItem(className); list.Add(lvi); // flid lvi.SubItems.Add(flid.ToString()); // field name string fieldname = m_mdc.GetFieldName(flid); lvi.SubItems.Add(fieldname); int flidType = m_mdc.GetFieldType(flid); string type = "Not recognized"; string signature = "Not recognized"; int dstClid; switch (flidType) { // Basic data types. case (int)CellarPropertyType.Boolean: type = "Basic"; signature = "Boolean"; break; case (int)CellarPropertyType.Integer: type = "Basic"; signature = "Integer"; break; case (int)CellarPropertyType.Numeric: type = "Basic"; signature = "Numeric"; break; case (int)CellarPropertyType.Float: type = "Basic"; signature = "Float"; break; case (int)CellarPropertyType.Time: type = "Basic"; signature = "Time"; break; case (int)CellarPropertyType.Guid: type = "Basic"; signature = "Guid"; break; case (int)CellarPropertyType.Image: type = "Basic"; signature = "Image"; break; case (int)CellarPropertyType.GenDate: type = "Basic"; signature = "GenDate"; break; case (int)CellarPropertyType.Binary: type = "Basic"; signature = "Binary"; break; case (int)CellarPropertyType.String: type = "Basic"; signature = "String"; break; case (int)CellarPropertyType.MultiString: type = "Basic"; signature = "MultiString"; break; case (int)CellarPropertyType.Unicode: type = "Basic"; signature = "Unicode"; break; case (int)CellarPropertyType.MultiUnicode: type = "Basic"; signature = "MultiUnicode"; break; // CmObjects. case (int)CellarPropertyType.OwningAtomic: type = "OA"; dstClid = m_mdc.GetDstClsId(flid); signature = m_mdc.GetClassName(dstClid); break; case (int)CellarPropertyType.ReferenceAtomic: type = "RA"; dstClid = m_mdc.GetDstClsId(flid); signature = m_mdc.GetClassName(dstClid); break; case (int)CellarPropertyType.OwningCollection: type = "OC"; dstClid = m_mdc.GetDstClsId(flid); signature = m_mdc.GetClassName(dstClid); break; case (int)CellarPropertyType.ReferenceCollection: type = "RC"; dstClid = m_mdc.GetDstClsId(flid); signature = m_mdc.GetClassName(dstClid); break; case (int)CellarPropertyType.OwningSequence: type = "OS"; dstClid = m_mdc.GetDstClsId(flid); signature = m_mdc.GetClassName(dstClid); break; case (int)CellarPropertyType.ReferenceSequence: type = "RS"; dstClid = m_mdc.GetDstClsId(flid); signature = m_mdc.GetClassName(dstClid); break; } if (flid >= 20000000 && flid < 30000000) { type += " (Virt)"; } else if (flid > 10000000) { type += " (BackRef)"; } lvi.SubItems.Add(type); lvi.SubItems.Add(signature); } } } // Add custom fields if (FDOBrowserForm.CFields != null && FDOBrowserForm.CFields.Count > 0) { foreach (CustomFields cf in FDOBrowserForm.CFields) { if (clid == cf.ClassID) { string clasName = m_mdc.GetClassName(cf.ClassID); ListViewItem lv = new ListViewItem(clasName); list.Add(lv); // classname //lv.SubItems.Add(clasName); // flid lv.SubItems.Add(cf.FieldID.ToString()); // field name lv.SubItems.Add(cf.Name); // Type switch (cf.Type) { case "ICmPossibility": holdType = "Custom - RA"; break; case "FdoReferenceCollection<ICmPossibility>": holdType = "Custom - RC"; break; case "IStText": holdType = "Custom - OA"; break; default: holdType = "Custom"; break; } lv.SubItems.Add(holdType); // Signature switch (cf.Type) { case "ITsString": holdSig = "String"; break; case "System.Int32": holdSig = "Integer"; break; case "SIL.FieldWorks.Common.FwUtils.GenDate": holdSig = "GenDate"; break; case "ICmPossibility": holdSig = "CmPossibility"; break; case "FdoReferenceCollection<ICmPossibility>": holdSig = "CmPossibility"; break; case "IStText": holdSig = "StText"; break; default: MessageBox.Show(String.Format("Type not recognized for signature for custom model fields. Type: {0}", cf.Type)); break; } lv.SubItems.Add(holdSig); } } } LoadListView(list); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Returns an array of all the Field tags (flids) for the specified class. /// NB. Must run Init method at least once before using this method. /// </summary> /// <param name="clsid">The CLSID.</param> /// <returns></returns> /// ------------------------------------------------------------------------------------ private int[] GetAllFieldsFromClassId(int clsid) { return(m_mdc.GetFields(clsid, true, (int)CellarPropertyTypeFilter.All)); }
private static Dictionary<string, List<PropertyInfo>> CacheBasicProperties(IFwMetaDataCacheManaged mdc) { var cachedBasicProperties = new Dictionary<string, List<PropertyInfo>>(); foreach (var classId in mdc.GetClassIds()) { var className = mdc.GetClassName(classId); List<PropertyInfo> basicProps; if (!cachedBasicProperties.TryGetValue(className, out basicProps)) { basicProps = new List<PropertyInfo>(); cachedBasicProperties.Add(className, basicProps); } basicProps.AddRange(mdc.GetFields(classId, className != "CmObject", (int)CellarPropertyTypeFilter.AllBasic).Select(propId => new PropertyInfo { m_propertyName = mdc.GetFieldName(propId), m_propertyType = (CellarPropertyType)mdc.GetFieldType(propId), m_isCustom = mdc.IsCustom(propId), m_isVirtual = mdc.get_IsVirtual(propId) })); if (basicProps.Count == 0) cachedBasicProperties.Remove(className); } return cachedBasicProperties; }
private void VerifyCmPossibilityCustomFields(ILexEntry entry) { m_mdc = Cache.MetaDataCacheAccessor as IFwMetaDataCacheManaged; var repo = Cache.ServiceLocator.GetInstance<ICmPossibilityListRepository>(); //Store mapping between Possibility List names and their guids. This is used to verify that //the custom list has stored the correct guid for the list when imported. m_customListNamesAndGuids.Add(RangeNames.sSemanticDomainListOA, Cache.LanguageProject.SemanticDomainListOA.Guid); foreach (ICmPossibilityList list in repo.AllInstances()) { if (list.OwningFlid == 0) //then it is a custom list { if (!m_customListNamesAndGuids.ContainsKey(list.Name.BestAnalysisVernacularAlternative.Text)) { m_customListNamesAndGuids.Add(list.Name.BestAnalysisVernacularAlternative.Text, list.Guid); } } } //Verify each custom field foreach (var flid in m_mdc.GetFields(entry.ClassID, true, (int)CellarPropertyTypeFilter.All)) { if (!m_mdc.IsCustom(flid)) continue; var fieldName = m_mdc.GetFieldName(flid); if (fieldName == "CustomFld ListSingle") { VerifyCustomListToPossList(flid, CellarPropertyType.ReferenceAtomic, RangeNames.sSemanticDomainListOA); } else if (fieldName == "CustomFld ListMulti") { VerifyCustomListToPossList(flid, CellarPropertyType.ReferenceCollection, RangeNames.sSemanticDomainListOA); } else if (fieldName == "CustomFld CmPossibilityCustomList") { VerifyCustomListToPossList(flid, CellarPropertyType.ReferenceAtomic, "CustomCmPossibiltyList"); } else if (fieldName == "CustomFld CustomList2") { VerifyCustomListToPossList(flid, CellarPropertyType.ReferenceAtomic, "CustomList Number2 "); } } }
private void ExportRecords(TextWriter writer, IProgress progress) { m_mdc = m_cache.ServiceLocator.GetInstance<IFwMetaDataCacheManaged>(); foreach (int flid in m_mdc.GetFields(RnGenericRecTags.kClassId, true, (int)CellarPropertyTypeFilter.All)) { if (m_mdc.IsCustom(flid)) m_customFlids.Add(flid); } writer.WriteLine("<Entries docRightToLeft=\"{0}\">", m_fRightToLeft ? "true" : "false"); foreach (var record in m_cache.LangProject.ResearchNotebookOA.RecordsOC) { ExportRecord(writer, record, 0); progress.Step(1); } writer.WriteLine("</Entries>"); }