internal void AddField(int flid, string fieldName, CellarPropertyType cpt, int destClsid)
        {
            var clsid = flid / 1000;
            var mfi   = new MockFieldInfo
            {
                m_flid          = flid,
                m_name          = fieldName,
                m_cpt           = cpt,
                m_destClsid     = destClsid,
                m_fCustom       = false,
                m_fieldHelp     = null,
                m_fieldWs       = WritingSystemServices.kwsAnal,
                m_fieldListRoot = Guid.Empty
            };

            m_fieldsById.Add(flid, mfi);
            List <MockFieldInfo> list;

            if (!m_fieldsByClassId.TryGetValue(clsid, out list))
            {
                list = new List <MockFieldInfo>();
                m_fieldsByClassId.Add(clsid, list);
            }
            list.Add(mfi);
        }
Beispiel #2
0
        public void AddVirtualPropTest()
        {
            const int flid = 2000000001;
            const CellarPropertyType type      = CellarPropertyType.Image;
            const string             className = "ClassB";
            const string             fieldName = "NewImageVP";

            m_metaDataCache.AddVirtualProp(className, fieldName, flid, (int)type);
            // Check its flid.
            var newFlid = m_metaDataCache.GetFieldId(className, fieldName, false);

            Assert.AreEqual(flid, newFlid, "Wrong field Id.");
            // Check its data type.
            Assert.AreEqual(type, (CellarPropertyType)m_metaDataCache.GetFieldType(flid), "Wrong field type.");
            // Check to see it is virtual.
            var isVirtual = m_metaDataCache.get_IsVirtual(flid);

            Assert.IsTrue(isVirtual, "Wrong field virtual setting.");
            // Check the clid it was supposed to be placed in.
            var clid = m_metaDataCache.GetClassId(className);

            Assert.AreEqual(clid, m_metaDataCache.GetOwnClsId(flid),
                            "Wrong clid for new virtual field.");
            Assert.AreEqual(fieldName, m_metaDataCache.GetFieldName(flid),
                            "Wrong field name for new virtual field.");
        }
Beispiel #3
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Export a collection/sequence list reference field.
        /// </summary>
        /// ------------------------------------------------------------------------------------
        private void ExportReferenceList(TextWriter writer, List <ICmPossibility> collection,
                                         string fieldName, string targetType, CellarPropertyType cpt)
        {
            if (collection == null || collection.Count == 0)
            {
                return;
            }
            if (cpt == CellarPropertyType.ReferenceCollection)
            {
                writer.WriteLine("<Field name=\"{0}\" type=\"{1}\" card=\"collection\">", fieldName, targetType);
            }
            else
            {
                writer.WriteLine("<Field name=\"{0}\" type=\"{1}\" card=\"sequence\">", fieldName, targetType);
            }
            int ws;

            foreach (var item in collection)
            {
                ITsString tss = item.Name.GetAlternativeOrBestTss(m_cache.DefaultAnalWs, out ws);
                writer.WriteLine("<Item ws=\"{0}\">{1}</Item>",
                                 m_cache.WritingSystemFactory.GetStrFromWs(ws), XmlUtils.MakeSafeXml(tss.Text));
            }
            writer.WriteLine("</Field>");
        }
		/// <summary>
		/// Constructor.
		/// </summary>
		/// <param name="flidType">Type of property.</param>
		/// <param name="flid">Field ID</param>
		/// <param name="signature">return value signature</param>
		public ModelPropertyAttribute(CellarPropertyType flidType, int flid, string signature)
		{
			if (string.IsNullOrEmpty(signature)) throw new ArgumentNullException("signature");

			m_flidType = flidType;
			m_flid = flid;
			m_signature = signature;
		}
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="flidType">Type of property.</param>
        /// <param name="flid">Field ID</param>
        /// <param name="signature">return value signature</param>
        public ModelPropertyAttribute(CellarPropertyType flidType, int flid, string signature)
        {
            if (string.IsNullOrEmpty(signature))
            {
                throw new ArgumentNullException("signature");
            }

            m_flidType  = flidType;
            m_flid      = flid;
            m_signature = signature;
        }
Beispiel #6
0
 public MetaFieldRec()
 {
     m_fieldType  = 0;
     m_ownClsid   = 0;
     m_dstClsid   = 0;
     m_fieldWs    = 0;
     m_fieldName  = null;
     m_fieldLabel = null;
     m_fieldHelp  = null;
     m_fieldXml   = null;
 }
Beispiel #7
0
        bool m_fGotFocus = false;         // True if we have focus.

        public TypeAheadSupportVc(int tag, LcmCache cache)
        {
            m_tag = tag;
            IFwMetaDataCache mdc = cache.DomainDataByFlid.MetaDataCache;

            m_clid      = mdc.GetOwnClsId(m_tag);
            m_className = mdc.GetClassName(m_clid);
            m_fieldName = mdc.GetFieldName(m_tag);
            m_type      = (CellarPropertyType)(mdc.GetFieldType(m_tag) & (int)CellarPropertyTypeFilter.VirtualMask);
            m_sda       = cache.DomainDataByFlid;
            Cache       = cache;
        }
Beispiel #8
0
 /// <summary>
 /// Constructs a custom field using the given arguments and adds it into the Cache.
 /// </summary>
 public CustomFieldForTest(LcmCache cache, string customFieldLabel, string customFieldName, int classId, int destClass, int ws,
                           CellarPropertyType fieldType, Guid listGuid)
 {
     m_customField = new FieldDescription(cache)
     {
         Userlabel  = customFieldLabel,
         Name       = customFieldName,
         HelpString = String.Empty,
         Class      = classId,
         ListRootId = listGuid,
         Type       = fieldType,
         DstCls     = destClass,
         WsSelector = ws
     };
     m_customField.UpdateCustomField();
 }
 private bool IsSupportedFieldType(CellarPropertyType fieldType)
 {
     switch (fieldType)
     {
     case CellarPropertyType.OwningAtomic:
     case CellarPropertyType.ReferenceAtomic:
     case CellarPropertyType.Boolean:
     //case CellarPropertyType.Float: // Not yet supported (as of 23 march 2013)
     case CellarPropertyType.GenDate:
     case CellarPropertyType.Guid:
     case CellarPropertyType.Integer:
     //case CellarPropertyType.Numeric: // Not yet supported (as of 23 march 2013)
     case CellarPropertyType.Time:
         return(true);
     }
     return(false);
 }
        internal void Initialize(FdoCache cache, XCore.IHelpTopicProvider helpTopicProvider, IApp app, IVwStylesheet stylesheet,
                                 NotebookImportWiz.RnSfMarker rsfm, CellarPropertyType cpt)
        {
            m_cache             = cache;
            m_helpTopicProvider = helpTopicProvider;
            m_btnAddWritingSystem.Initialize(m_cache, helpTopicProvider, app, stylesheet);
            NotebookImportWiz.InitializeWritingSystemCombo(rsfm.m_tlo.m_wsId, cache,
                                                           m_cbWritingSystem);

            bool fNotAtomic = (cpt != CellarPropertyType.ReferenceAtomic);

            m_tbDefaultValue.Text = rsfm.m_tlo.m_sEmptyDefault;

            m_chkDelimMultiEnable.Checked = rsfm.m_tlo.m_fHaveMulti && fNotAtomic;
            m_chkDelimMultiEnable.Enabled = fNotAtomic;
            m_tbDelimMulti.Text           = rsfm.m_tlo.m_sDelimMulti;
            m_tbDelimMulti.Enabled        = rsfm.m_tlo.m_fHaveMulti && fNotAtomic;

            m_chkDelimSubEnable.Checked = rsfm.m_tlo.m_fHaveSub;
            m_tbDelimSub.Text           = rsfm.m_tlo.m_sDelimSub;
            m_tbDelimSub.Enabled        = rsfm.m_tlo.m_fHaveSub;

            m_chkBetweenEnable.Checked = rsfm.m_tlo.m_fHaveBetween;
            m_tbBetweenBefore.Text     = rsfm.m_tlo.m_sMarkStart;
            m_tbBetweenAfter.Text      = rsfm.m_tlo.m_sMarkEnd;
            m_tbBetweenBefore.Enabled  = rsfm.m_tlo.m_fHaveBetween;
            m_tbBetweenAfter.Enabled   = rsfm.m_tlo.m_fHaveBetween;

            m_chkOnlyBeforeEnable.Checked = rsfm.m_tlo.m_fHaveBefore;
            m_tbOnlyBefore.Text           = rsfm.m_tlo.m_sBefore;
            m_tbOnlyBefore.Enabled        = rsfm.m_tlo.m_fHaveBefore;

            m_chkDiscardNewStuff.Checked = rsfm.m_tlo.m_fIgnoreNewStuff;

            m_rbMatchName.Checked = rsfm.m_tlo.m_pnt == PossNameType.kpntName;
            m_rbMatchAbbr.Checked = rsfm.m_tlo.m_pnt != PossNameType.kpntName;

            Debug.Assert(rsfm.m_tlo.m_rgsMatch.Count == rsfm.m_tlo.m_rgsReplace.Count);
            m_lvSubstitutions.Items.Clear();
            for (int i = 0; i < rsfm.m_tlo.m_rgsMatch.Count; ++i)
            {
                var lvi = new ListViewItem(new[] { rsfm.m_tlo.m_rgsMatch[i], rsfm.m_tlo.m_rgsReplace[i] });
                m_lvSubstitutions.Items.Add(lvi);
            }
        }
Beispiel #11
0
		private static bool IsObjectFieldType(CellarPropertyType type)
		{
			var isObjectFT = false;

			switch (type)
			{
				case CellarPropertyType.OwningAtomic:
				case CellarPropertyType.OwningCollection:
				case CellarPropertyType.OwningSequence:
				case CellarPropertyType.ReferenceAtomic:
				case CellarPropertyType.ReferenceCollection:
				case CellarPropertyType.ReferenceSequence:
					isObjectFT = true;
					break;
			}

			return isObjectFT;
		}
Beispiel #12
0
        private static bool IsObjectFieldType(CellarPropertyType type)
        {
            var isObjectFT = false;

            switch (type)
            {
            case CellarPropertyType.OwningAtomic:
            case CellarPropertyType.OwningCollection:
            case CellarPropertyType.OwningSequence:
            case CellarPropertyType.ReferenceAtomic:
            case CellarPropertyType.ReferenceCollection:
            case CellarPropertyType.ReferenceSequence:
                isObjectFT = true;
                break;
            }

            return(isObjectFT);
        }
        public int AddCustomField(string className, string fieldName, CellarPropertyType fieldType,
                                  int destinationClass, string fieldHelp, int fieldWs, Guid fieldListRoot)
        {
            int clid;

            if (m_classesByName.TryGetValue(className, out clid))
            {
                List <MockFieldInfo> list;
                var flid = (clid * 1000) + 500;
                if (m_fieldsByClassId.TryGetValue(clid, out list))
                {
                    var flidMax = flid - 1;
                    foreach (MockFieldInfo mfi in list)
                    {
                        if (mfi.m_fCustom && mfi.m_flid > flid)
                        {
                            flidMax = mfi.m_flid;
                        }
                    }
                    flid = flidMax + 1;
                }
                else
                {
                    list = new List <MockFieldInfo>();
                    m_fieldsByClassId.Add(clid, list);
                }
                var mfiNew = new MockFieldInfo
                {
                    m_flid          = flid,
                    m_name          = fieldName,
                    m_cpt           = fieldType,
                    m_destClsid     = destinationClass,
                    m_fCustom       = true,
                    m_fieldHelp     = fieldHelp,
                    m_fieldWs       = fieldWs,
                    m_fieldListRoot = fieldListRoot
                };
                list.Add(mfiNew);
                m_fieldsById.Add(flid, mfiNew);
                return(flid);
            }

            return(0);
        }
Beispiel #14
0
        private static string GetDefaultValueForPropertyType(CellarPropertyType propertyType)
        {
            switch (propertyType)
            {
            case CellarPropertyType.Boolean:
                return("False");

            case CellarPropertyType.GenDate:
                var genDate = new GenDate();
                return(string.Format("{0}{1:0000}{2:00}{3:00}{4}",
                                     genDate.IsAD ? "" : "-",
                                     genDate.Year,
                                     genDate.Month,
                                     genDate.Day,
                                     (int)genDate.Precision));

            case CellarPropertyType.Guid:
                return(Guid.Empty.ToString());

            case CellarPropertyType.Float:
                throw new NotSupportedException("The 'Float' data type is not supported in the FW data model yet (as of 23 March 2013).");

            case CellarPropertyType.Integer:
                return("0");

            case CellarPropertyType.Time:
                var datetime = new DateTime();
                datetime = datetime.ToUniversalTime();                         // Store it as UTC.
                return(String.Format("{0}-{1}-{2} {3}:{4}:{5}.{6}",
                                     datetime.Year,
                                     datetime.Month,
                                     datetime.Day,
                                     datetime.Hour,
                                     datetime.Minute,
                                     datetime.Second,
                                     datetime.Millisecond));

            case CellarPropertyType.Numeric:
                throw new NotSupportedException("The 'Numeric' data type is not supported in the FW data model yet (as of 23 March 2013).");

            default:
                throw new InvalidOperationException("The given 'propertyType' is not a basic data type.");
            }
        }
Beispiel #15
0
            public override void MakeRoot()
            {
                CheckDisposed();
                base.MakeRoot();

                if (m_fdoCache == null || DesignMode)
                {
                    return;
                }

                // A crude way of making sure the property we want is loaded into the cache.
                m_obj = m_fdoCache.ServiceLocator.GetInstance <ICmObjectRepository>().GetObject(m_hvoObj);

                CellarPropertyType type = (CellarPropertyType)m_fdoCache.DomainDataByFlid.MetaDataCache.GetFieldType(m_flid);

                if (type == CellarPropertyType.Unicode)
                {
                    m_vc = new UnicodeStringSliceVc(m_flid, m_ws, m_fdoCache);
                }
                else if (type == CellarPropertyType.String)
                {
                    // Even if we were given a writing system, we must not use it if not a multistring,
                    // otherwise the VC crashes when it tries to read the property as multilingual.
                    m_vc = new StringSliceVc(m_flid, m_fdoCache, m_mediator);
                    (m_vc as StringSliceVc).ShowWsLabel = m_fShowWsLabel;
                }
                else
                {
                    m_vc = new StringSliceVc(m_flid, m_ws, m_fdoCache, m_mediator);
                    (m_vc as StringSliceVc).ShowWsLabel = m_fShowWsLabel;
                }

                // Review JohnT: why doesn't the base class do this??
                m_rootb = VwRootBoxClass.Create();
                m_rootb.SetSite(this);

                // And maybe this too, at least by default?
                m_rootb.DataAccess = m_fdoCache.DomainDataByFlid;

                // arg3 is a meaningless initial fragment, since this VC only displays one thing.
                // arg4 could be used to supply a stylesheet.
                m_rootb.SetRootObject(m_hvoObj, m_vc, 1, m_styleSheet);
            }
		internal void AddField(int flid, string fieldName, CellarPropertyType cpt, int destClsid)
		{
			var clsid = flid / 1000;
			var mfi = new MockFieldInfo
				{
					m_flid = flid,
					m_name = fieldName,
					m_cpt = cpt,
					m_destClsid = destClsid,
					m_fCustom = false,
					m_isVirtual = false,
					m_fieldHelp = null,
					m_fieldWs = WritingSystemServices.kwsAnal,
					m_fieldListRoot = Guid.Empty
				};
			m_fieldsById.Add(flid, mfi);
			List<MockFieldInfo> list;
			if (!m_fieldsByClassId.TryGetValue(clsid, out list))
			{
				list = new List<MockFieldInfo>();
				m_fieldsByClassId.Add(clsid, list);
			}
			list.Add(mfi);
		}
Beispiel #17
0
        // extracted from the CellarPropertyType enum
        protected static string GetFlidTypeAsString(CellarPropertyType flidType)
        {
            string retval;

            switch (flidType)
            {
            default:
                throw new ArgumentException("Property element name not recognized.");

            case CellarPropertyType.Boolean:
                retval = "Boolean";
                break;

            case CellarPropertyType.Integer:
                retval = "Integer";
                break;

            case CellarPropertyType.Time:
                retval = "Time";
                break;

            case CellarPropertyType.String:
                retval = "String";
                break;

            case CellarPropertyType.MultiString:
                retval = "MultiString";
                break;

            case CellarPropertyType.Unicode:
                retval = "Unicode";
                break;

            case CellarPropertyType.MultiUnicode:
                retval = "MultiUnicode";
                break;

            case CellarPropertyType.Guid:
                retval = "Guid";
                break;

            case CellarPropertyType.Image:
                retval = "Image";
                break;

            case CellarPropertyType.GenDate:
                retval = "GenDate";
                break;

            case CellarPropertyType.Binary:
                retval = "Binary";
                break;

            case CellarPropertyType.Numeric:
                retval = "Numeric";
                break;

            case CellarPropertyType.Float:
                retval = "Float";
                break;

            case CellarPropertyType.OwningAtomic:
                retval = "OA";
                break;

            case CellarPropertyType.OwningCollection:
                retval = "OC";
                break;

            case CellarPropertyType.OwningSequence:
                retval = "OS";
                break;

            case CellarPropertyType.ReferenceAtomic:
                retval = "RA";
                break;

            case CellarPropertyType.ReferenceCollection:
                retval = "RC";
                break;

            case CellarPropertyType.ReferenceSequence:
                retval = "RS";
                break;
            }
            return(retval);
        }
		public virtual int AddCustomField(string className, string fieldName, CellarPropertyType fieldType, int destinationClass)
		{
			return m_metaDataCache.AddCustomField(className, fieldName, fieldType, destinationClass);
		}
		/// <summary>
		/// This overload allows the label to be specified separately.
		/// </summary>
		public int AddCustomField(string className, string fieldName, string label, CellarPropertyType fieldType,
			int destinationClass, string fieldHelp, int fieldWs, Guid fieldListRoot)
		{
			var flid = AddCustomField(className, fieldName, fieldType, destinationClass);
			m_metaFieldRecords[flid].m_fieldHelp = fieldHelp;
			m_metaFieldRecords[flid].m_fieldWs = fieldWs;
			m_metaFieldRecords[flid].m_fieldLabel = label;	// user label same as field name now.
			m_metaFieldRecords[flid].m_fieldListRoot = fieldListRoot;
			return flid;
		}
Beispiel #20
0
		private void AddToLongCache(int obj, int tag, long val, CellarPropertyType flidType)
		{
			CheckBasics(obj);

			// Make sure the hvo has the given tag.
			CheckHvoTagMatch(obj, tag);
			// Make sure a long is legal for the given tag.
			CellarPropertyType tagType = (CellarPropertyType)MetaDataCache.GetFieldType(tag);
			if (tagType != flidType)
				throw new ArgumentException(String.Format("Can only put long integers in the tag/flid '{0}'.", tag));
			m_longCache[new HvoFlidKey(obj, tag)] = val;
		}
        /// <summary>
        /// Set custom field data for one field (specified by owner HVO and field ID).
        /// </summary>
        /// <returns><c>true</c>, if custom field data was set, <c>false</c> otherwise (e.g., if value hadn't changed,
        /// or value was null, or field type was one not implemented in LCM, such as CellarPropertyType.Float).</returns>
        /// <param name="hvo">HVO of object whose field we're setting.</param>
        /// <param name="flid">Field ID of custom field to set.</param>
        /// <param name="value">Field's new value (as returned by GetCustomFieldData).</param>
        /// <param name="guidOrGuids">GUID or guids associated with new value (as returned by GetCustomFieldData).
        /// May be null or BsonNull.Value if no GUIDs associated with this value.</param>
        public bool SetCustomFieldData(int hvo, int flid, BsonValue value, BsonValue guidOrGuids)
        {
            if ((value == null) || (value == BsonNull.Value) ||
                ((value.BsonType == BsonType.Array) && (value.AsBsonArray.Count == 0)))
            {
                return(false);
            }
            List <Guid> fieldGuids = new List <Guid>();

            if (guidOrGuids == null || guidOrGuids == BsonNull.Value)
            {
                // Leave fieldGuids as an empty list
            }
            else
            {
                if (guidOrGuids is BsonArray)
                {
                    fieldGuids.AddRange(guidOrGuids.AsBsonArray.Select(bsonValue => ParseGuidOrDefault(bsonValue.AsString)));
                }
                else
                {
                    fieldGuids.Add(ParseGuidOrDefault(guidOrGuids.AsString));
                }
            }
            ISilDataAccessManaged data      = (ISilDataAccessManaged)cache.DomainDataByFlid;
            CellarPropertyType    fieldType = (CellarPropertyType)lcmMetaData.GetFieldType(flid);
            string fieldName = lcmMetaData.GetFieldNameOrNull(flid);

//			logger.Debug("Custom field named {0} has type {1}", fieldName, fieldType.ToString());
            if (fieldName == null)
            {
                return(false);
            }

            // Valid field types in LCM are GenDate, Integer, String, OwningAtomic, ReferenceAtomic, and ReferenceCollection, so that's all we implement.
            switch (fieldType)
            {
            case CellarPropertyType.GenDate:
            {
                var    valueAsMultiText = BsonSerializer.Deserialize <LfMultiText>(value.AsBsonDocument);
                string valueAsString    = valueAsMultiText.BestString(new string[] { MagicStrings.LanguageCodeForGenDateFields });
                if (string.IsNullOrEmpty(valueAsString))
                {
                    return(false);
                }
                GenDate valueAsGenDate;
                if (GenDate.TryParse(valueAsString, out valueAsGenDate))
                {
                    GenDate oldValue = data.get_GenDateProp(hvo, flid);
                    if (oldValue == valueAsGenDate)
                    {
                        return(false);
                    }
                    else
                    {
                        data.SetGenDate(hvo, flid, valueAsGenDate);
                        return(true);
                    }
                }
                return(false);
            }

            case CellarPropertyType.Integer:
            {
                var    valueAsMultiText = BsonSerializer.Deserialize <LfMultiText>(value.AsBsonDocument);
                string valueAsString    = valueAsMultiText.BestString(new string[] { MagicStrings.LanguageCodeForIntFields });
                if (string.IsNullOrEmpty(valueAsString))
                {
                    return(false);
                }
                int valueAsInt;
                if (int.TryParse(valueAsString, out valueAsInt))
                {
                    int oldValue = data.get_IntProp(hvo, flid);
                    if (oldValue == valueAsInt)
                    {
                        return(false);
                    }
                    else
                    {
                        data.SetInt(hvo, flid, valueAsInt);
                        return(true);
                    }
                }
                return(false);
            }

            case CellarPropertyType.OwningAtomic:
            {
                // Custom field is a MultiparagraphText, which is an IStText object in LCM
                IStTextRepository textRepo = servLoc.GetInstance <IStTextRepository>();
                Guid    fieldGuid          = fieldGuids.FirstOrDefault();
                IStText text;
                if (!textRepo.TryGetObject(fieldGuid, out text))
                {
                    int currentFieldContentsHvo = data.get_ObjectProp(hvo, flid);
                    if (currentFieldContentsHvo != LcmCache.kNullHvo)
                    {
                        text = (IStText)cache.GetAtomicPropObject(currentFieldContentsHvo);
                    }
                    else
                    {
                        // NOTE: I don't like the "magic" -2 number below, but LCM doesn't seem to have an enum for this. 2015-11 RM
                        int newStTextHvo = data.MakeNewObject(cache.GetDestinationClass(flid), hvo, flid, -2);
                        text = (IStText)cache.GetAtomicPropObject(newStTextHvo);
                    }
                }
                // Shortcut: if text contents haven't changed, we don't want to change anything at all
                BsonValue currentLcmTextContents = ConvertUtilities.GetCustomStTextValues(text, flid,
                                                                                          servLoc.WritingSystemManager, lcmMetaData, cache.DefaultUserWs);
                if ((currentLcmTextContents == BsonNull.Value || currentLcmTextContents == null) &&
                    (value == BsonNull.Value || value == null))
                {
                    return(false);
                }
                if (currentLcmTextContents != null && currentLcmTextContents.Equals(value))
                {
                    // No changes needed.
                    return(false);
                }
                // BsonDocument passed in contains "paragraphs". ParseCustomStTextValuesFromBson wants only a "value" element
                // inside the doc, so we'll need to construct a new doc for the StTextValues.
                BsonDocument     doc       = value.AsBsonDocument;
                LfMultiParagraph multiPara = BsonSerializer.Deserialize <LfMultiParagraph>(doc);
                // Now we have another way to check for "old value and new value were the same": if the LCM multiparagraph was empty,
                // GetCustomStTextValues will have returned null -- so if this multiPara has no paragraphs, that's also an unchanged situation
                if ((multiPara.Paragraphs == null || multiPara.Paragraphs.Count <= 0) &&
                    (currentLcmTextContents == BsonNull.Value || currentLcmTextContents == null))
                {
                    return(false);
                }
                int wsId;
                if (multiPara.InputSystem == null)
                {
                    wsId = lcmMetaData.GetFieldWs(flid);
                }
                else
                {
                    wsId = servLoc.WritingSystemFactory.GetWsFromStr(multiPara.InputSystem);
                }
                ConvertUtilities.SetCustomStTextValues(text, multiPara.Paragraphs, wsId);

                return(true);
            }

            case CellarPropertyType.ReferenceAtomic:
                if (fieldGuids.FirstOrDefault() != Guid.Empty)
                {
                    int referencedHvo = data.get_ObjFromGuid(fieldGuids.FirstOrDefault());
                    int oldHvo        = data.get_ObjectProp(hvo, flid);
                    if (referencedHvo == oldHvo)
                    {
                        return(false);
                    }
                    else
                    {
                        data.SetObjProp(hvo, flid, referencedHvo);
                        // TODO: What if the value of the referenced object has changed in LanguageForge? (E.g., change that possibility's text from "foo" to "bar")
                        // Need to implement that scenario.
                        return(true);
                    }
                }
                else
                {
                    // It's a reference to an ICmPossibility instance: create a new entry in appropriate PossibilityList
                    LfStringField valueAsLfStringField = BsonSerializer.Deserialize <LfStringField>(value.AsBsonDocument);
                    string        nameHierarchy        = valueAsLfStringField.Value;
                    if (nameHierarchy == null)
                    {
                        return(false);
                    }
                    int fieldWs = lcmMetaData.GetFieldWs(flid);
                    // Oddly, this can return 0 for some custom fields. TODO: Find out why: that seems like it would be an error.
                    if (fieldWs == 0)
                    {
                        fieldWs = cache.DefaultUserWs;                         // TODO: Investigate, because this should probably be wsEn instead so that we can create correct keys.
                    }
                    if (fieldWs < 0)
                    {
                        // FindOrCreatePossibility has a bug where it doesn't handle "magic" writing systems (e.g., -1 for default analysis, etc) and
                        // throws an exception instead. So we need to get a real ws here.
                        fieldWs = WritingSystemServices.ActualWs(cache, fieldWs, hvo, flid);
                    }
                    ICmPossibilityList parentList = GetParentListForField(flid);
                    ICmPossibility     newPoss    = parentList.FindOrCreatePossibility(nameHierarchy, fieldWs);

                    int oldHvo = data.get_ObjectProp(hvo, flid);
                    if (newPoss.Hvo == oldHvo)
                    {
                        return(false);
                    }
                    else
                    {
                        data.SetObjProp(hvo, flid, newPoss.Hvo);
                        return(true);
                    }
                }

            case CellarPropertyType.ReferenceCollection:
            case CellarPropertyType.ReferenceSequence:
            {
                if (value == null || value == BsonNull.Value)
                {
                    // Can't write null to a collection or sequence in LCM; it's forbidden. So data.SetObjProp(hvo, flid, LcmCache.kNullHvo) will not work.
                    // Instead, we delete all items from the existing collection or sequence, and thus store an empty coll/seq in LCM.
                    int oldSize = data.get_VecSize(hvo, flid);
                    if (oldSize == 0)
                    {
                        // It was already empty, so leave it unchanged so we don't cause unnecessary changes in the .fwdata XML (and unnecessary Mercurial commits).
                        return(false);
                    }
                    else
                    {
                        data.Replace(hvo, flid, 0, oldSize, null, 0);                                 // This is how you set an empty array
                        return(true);
                    }
                }
                int fieldWs = lcmMetaData.GetFieldWs(flid);
                // TODO: Investigate why this is sometimes coming back as 0 instead of as a real writing system ID
                if (fieldWs == 0)
                {
                    fieldWs = cache.DefaultUserWs;
                }
                ICmPossibilityList parentList = GetParentListForField(flid);

                LfStringArrayField valueAsStringArray = BsonSerializer.Deserialize <LfStringArrayField>(value.AsBsonDocument);

                // Step 1: Get ICmPossibility instances from the string keys that LF gave us

                // First go through all the GUIDs we have and match them up to the keys. If they match up,
                // then remove the keys from the list. Any remaining keys get looked up with FindOrCreatePossibility(), so now we
                // have a complete set of GUIDs (or ICmPossibility objects, which works out to the same thing).

                // TODO: This is all kind of ugly, and WAY too long for one screen. I could put it in its own function,
                // but there's really no real gain from that, as it simply moves the logic even further away from where
                // it needs to be. There's not really a *good* way to achieve simplicity with this code design, unfortunately.
                // The only thing that would be close to simple would be to call some functions from the LcmToMongo option list
                // converters, and that's pulling in code from the "wrong" direction, which has its own ugliness. Ugh.

                HashSet <string> keysFromLF = new HashSet <string>(valueAsStringArray.Values);
                var fieldObjs = new List <ICmPossibility>();
                foreach (Guid guid in fieldGuids)
                {
                    ICmPossibility poss;
                    string         key = "";
                    if (guid != default(Guid))
                    {
                        poss = servLoc.GetInstance <ICmPossibilityRepository>().GetObject(guid);
                        if (poss == null)
                        {
                            // TODO: Decide what to do with possibilities deleted from LCM
                            key = "";
                        }
                        else
                        {
                            if (poss.Abbreviation == null)
                            {
                                key = "";
                            }
                            else
                            {
                                ITsString keyTss = poss.Abbreviation.get_String(wsEn);
                                key = keyTss == null ? "" : keyTss.Text ?? "";
                            }
                            fieldObjs.Add(poss);
                        }
                    }
                    keysFromLF.Remove(key);
                    // Ignoring return value (HashSet.Remove returns false if the key wasn't present), because false could mean one of two things:
                    // 1. The CmPossibility had its English abbreviation changed in LCM, but LF doesn't know this yet.
                    //    If this is the case, the LF key won't match, but the GUID will still match. So we might end up creating
                    //    duplicate entries below with the FindOrCreatePossibility. TODO: Need to verify that LCM->LF possibility lists
                    //    get updated correctly if renames happen! (... Or use the OptionList converters, that's what they were for.)
                    // 2. The CmPossibility was just created in LF and isn't in LCM yet. In which case we should have been using the
                    //    OptionList converters, which would hopefully have handled creating the ICmPossibility instane in LCM.
                    // Either way, we can't really use that fact later, since we can't be certain if the possibility was renamed or created.
                }
                // Any remaining keysFromLF strings did not have corresponding GUIDs in Mongo.
                // This is most likely because they were added by LF, which doesn't write to the customFieldGuids field.
                // So we assume they exist in FW, and just look them up.
                foreach (string key in keysFromLF)
                {
                    ICmPossibility poss = parentList.FindOrCreatePossibility(key, wsEn);
                    // TODO: If this is a new possibility, then we need to populate it with ALL the corresponding data from LF,
                    // which we don't necessarily have at this point. Need to make that a separate step in the Send/Receive: converting option lists first.
                    fieldObjs.Add(poss);
                }
                // logger.Debug("Custom field {0} for CmObject {1}: BSON list was [{2}] and customFieldGuids was [{3}]. This was translated to keysFromLF = [{4}] and fieldObjs = [{5}]",
                //  fieldName,
                //  hvo,
                //  String.Join(", ", valueAsStringArray.Values),
                //  String.Join(", ", fieldGuids.Select(g => g.ToString())),
                //  String.Join(", ", keysFromLF.AsEnumerable()),
                //  String.Join(", ", fieldObjs.Select(poss => poss.AbbrAndName))
                // );
                // Step 2: Remove any objects from the "old" list that weren't in the "new" list
                // We have to look them up by HVO because that's the only public API available in LCM
                // Following logic inspired by XmlImportData.CopyCustomFieldData in FieldWorks source
                int[] oldHvosArray = data.VecProp(hvo, flid);
                int[] newHvosArray = fieldObjs.Select(poss => poss.Hvo).ToArray();
                // Shortcut check
                if (oldHvosArray.SequenceEqual(newHvosArray))
                {
                    // Nothing to do, so return now so that we don't cause unnecessary changes and commits in Mercurial
                    return(false);
                }
                HashSet <int> newHvos      = new HashSet <int>(newHvosArray);
                HashSet <int> combinedHvos = new HashSet <int>();
                // Loop backwards so deleting items won't mess up indices of subsequent deletions
                for (int idx = oldHvosArray.Length - 1; idx >= 0; idx--)
                {
                    int oldHvo = oldHvosArray[idx];
                    if (newHvos.Contains(oldHvo))
                    {
                        combinedHvos.Add(oldHvo);
                    }
                    else
                    {
                        data.Replace(hvo, flid, idx, idx + 1, null, 0);                                 // Important to pass *both* null *and* 0 here to remove items
                    }
                }

                // Step 3: Add any objects from the "new" list that weren't in the "old" list
                foreach (int newHvo in newHvosArray)
                {
                    if (combinedHvos.Contains(newHvo))
                    {
                        continue;
                    }
                    // This item was added in the new list
                    data.Replace(hvo, flid, combinedHvos.Count, combinedHvos.Count, new int[] { newHvo }, 1);
                    combinedHvos.Add(newHvo);
                }
                return(true);
            }

            case CellarPropertyType.String:
            {
                var    valueAsMultiText          = BsonSerializer.Deserialize <LfMultiText>(value.AsBsonDocument);
                int    wsIdForField              = lcmMetaData.GetFieldWs(flid);
                string wsStrForField             = servLoc.WritingSystemFactory.GetStrFromWs(wsIdForField);
                KeyValuePair <string, string> kv = valueAsMultiText.BestStringAndWs(new string[] { wsStrForField });
                string foundWs   = kv.Key ?? string.Empty;
                string foundData = kv.Value ?? string.Empty;
                int    foundWsId = servLoc.WritingSystemFactory.GetWsFromStr(foundWs);
                if (foundWsId == 0)
                {
                    return(false);                            // Skip any unidentified writing systems
                }
                ITsString oldValue = data.get_StringProp(hvo, flid);
                ITsString newValue = ConvertMongoToLcmTsStrings.SpanStrToTsString(foundData, foundWsId, servLoc.WritingSystemFactory);
                if (oldValue != null && TsStringUtils.GetDiffsInTsStrings(oldValue, newValue) == null)                         // GetDiffsInTsStrings() returns null when there are no changes
                {
                    return(false);
                }
                else
                {
                    data.SetString(hvo, flid, newValue);
                    return(true);
                }
            }

            default:
                return(false);
                // TODO: Maybe issue a proper warning (or error) log message for "field type not recognized"?
            }
        }
Beispiel #22
0
		private void VerifyCustomListToPossList(int flid, CellarPropertyType type, string possListName)
		{
			var custFieldType = (CellarPropertyType)m_mdc.GetFieldType(flid);
			var custFieldListGuid = m_mdc.GetFieldListRoot(flid);
			Assert.AreEqual(type, custFieldType);
			Guid lstGuid = Guid.Empty;
			m_customListNamesAndGuids.TryGetValue(possListName, out lstGuid);
			Assert.AreEqual(custFieldListGuid, lstGuid);
		}
Beispiel #23
0
 /// <summary>
 /// Create a custom field using the given values.
 /// </summary>
 public void CreateCustomField(string className, string fieldName, CellarPropertyType cpt,
                               int destClid, string helpString, int wsSelector, Guid listRoot)
 {
     m_mdc.AddCustomField(className, fieldName, cpt, destClid, helpString, wsSelector, listRoot);
 }
 /// <summary>
 /// Constructor for non-object properties.
 /// </summary>
 public VirtualPropertyAttribute(CellarPropertyType flidType)
     : this(flidType, "")
 {
 }
		public int AddCustomField(string className, string fieldName, CellarPropertyType fieldType, int destinationClass)
		{
			CheckClid(className);
			var clid = m_nameToClid[className];

			if (string.IsNullOrEmpty(fieldName)) throw new ArgumentNullException("fieldName");
			int flid;

			// Don't allow custom field with same name as non-custom field
			if (m_nameToFlid.TryGetValue(MakeFlidKey(clid, fieldName), out flid) && !IsCustom(flid))
				throw new FDOInvalidFieldException("Field already exists: " + fieldName, fieldName);

			// FWR-2804 - in case a custom field already exists that originally had this name,
			// make sure we use a unique name this time.
			var uniqueName = AssureUniqueFieldName(clid, fieldName);

			// Get custom flid for clid.
			if (m_clidToNextCustomFlid.TryGetValue(clid, out flid))
			{
				// Bump it up by 1.
				flid += 1;
				m_clidToNextCustomFlid[clid] = flid;
			}
			else
			{
				// Start with 500.
				flid = (clid*1000) + 500;
				m_clidToNextCustomFlid.Add(clid, flid);
			}
			string fieldSig = null;
			MetaClassRec mcrSig;
			if (m_metaClassRecords.TryGetValue(destinationClass, out mcrSig))
				fieldSig = mcrSig.m_className;
			AddField(className,
					 flid, uniqueName,
					 null, null, null,
					 fieldSig,
					 fieldType, FieldSource.kCustom, Guid.Empty, 0);

			var mfr = m_metaFieldRecords[flid];
			mfr.m_fieldLabel = fieldName;		// user label is original proposed name.
			m_customFields.Add(mfr);
			ConnectMetaFieldRec(mfr);

			return flid;
		}
Beispiel #26
0
        private void VerifyCustomFieldPresent(string customFieldLabel, int classWithCustomField, int expectedType, CellarPropertyType ownerType = CellarPropertyType.Nil)
        {
            var mdc  = Cache.MetaDataCacheAccessor as IFwMetaDataCacheManaged;
            var flid = mdc.GetFieldId2(classWithCustomField, customFieldLabel, false);

            Assert.IsTrue(mdc.IsCustom(flid));
            Assert.AreEqual(mdc.GetDstClsId(flid), expectedType, "The {0} custom field was not the correct type.", customFieldLabel);
        }
 /// <summary>
 /// Constructor for object properties. Signature is the name (unqualified) of the class, e.g., "LexEntry".
 /// </summary>
 public VirtualPropertyAttribute(CellarPropertyType flidType, string signature)
 {
     m_flidType    = flidType;
     m_virtualFlid = GetNextFlid();
     m_signature   = signature;
 }
		private static XAttribute CreateValAttribute(CellarPropertyType propertyType)
		{
			return new XAttribute("val", GetDefaultValueForPropertyType(propertyType));
		}
		/// <summary>
		/// Constructor for non-object properties.
		/// </summary>
		public VirtualPropertyAttribute(CellarPropertyType flidType)
			:this(flidType, "")
		{
		}
		/// <summary>
		/// Constructor for object properties. Signature is the name (unqualified) of the class, e.g., "LexEntry".
		/// </summary>
		public VirtualPropertyAttribute(CellarPropertyType flidType, string signature)
		{
			m_flidType = flidType;
			m_virtualFlid = GetNextFlid();
			m_signature = signature;
		}
		/// <summary>
		/// Create a custom field using the given values.
		/// </summary>
		public void CreateCustomField(string className, string fieldName, CellarPropertyType cpt,
			int destClid, string helpString, int wsSelector, Guid listRoot)
		{
			m_mdc.AddCustomField(className, fieldName, cpt, destClid, helpString, wsSelector, listRoot);
		}
Beispiel #32
0
		public VectorReferenceUi(FdoCache cache, ICmObject rootObj, int referenceFlid, int targetHvo)
			: base(cache, rootObj, referenceFlid, targetHvo)
		{
			m_iType = (CellarPropertyType)cache.DomainDataByFlid.MetaDataCache.GetFieldType(m_flid);
			Debug.Assert(m_iType == CellarPropertyType.ReferenceSequence ||
					m_iType == CellarPropertyType.ReferenceCollection);
		}
Beispiel #33
0
        public void WriteCustomFieldConfigForOneFieldSourceType(
            int classId,
            string fieldSourceType,              // Can be either "entry", "senses", or "examples"
            Dictionary <string, LfConfigFieldBase> lfCustomFieldConfig,
            Dictionary <string, string> lfCustomFieldTypes
            )
        {
            IEnumerable <int> customFieldIds =
                LcmMetaData.GetFields(classId, false, (int)CellarPropertyTypeFilter.All)
                .Where(flid => cache.GetIsCustomField(flid));

            foreach (int flid in customFieldIds)
            {
                string label = LcmMetaData.GetFieldNameOrNull(flid);
                if (label == null)
                {
                    continue;
                }
                string             lfCustomFieldName = ConvertUtilities.NormalizedFieldName(label, fieldSourceType);
                CellarPropertyType LcmFieldType      = (CellarPropertyType)LcmMetaData.GetFieldType(flid);
                lfCustomFieldTypes[lfCustomFieldName] = LcmFieldType.ToString();
                string lfCustomFieldType;
                if (CellarPropertyTypeToLfCustomFieldType.TryGetValue(LcmFieldType, out lfCustomFieldType))
                {
                    // Get custom field configuration info
                    LfConfigFieldBase fieldConfig = null;

                    if (lfCustomFieldType.EndsWith("ListRef"))
                    {
                        // List references, whether single or multi, need a list code
                        string listCode = GetParentListCode(flid);
                        fieldConfig = GetLfCustomFieldOptionListConfig(label, lfCustomFieldType, listCode);
                    }
                    else if (lfCustomFieldType == CellarPropertyTypeToLfCustomFieldType[CellarPropertyType.OwningAtomic])
                    {
                        // Multiparagraphs don't need writing systems
                        fieldConfig = GetLfCustomFieldMultiParagraphConfig(label, lfCustomFieldType);
                    }
                    else
                    {
                        // Single line or MultiText fields need writing systems
                        int fieldWs = LcmMetaData.GetFieldWs(flid);
                        // That's a "magic" ws, which we need to expand into a (list of) real writing system(s).
#if FW8_COMPAT
                        var wsesForThisField = new List <IWritingSystem>();
#else
                        var wsesForThisField = new List <CoreWritingSystemDefinition>();
#endif
                        // GetWritingSystemList() in FW 8.3 is buggy and doesn't properly handle the kwsAnal and kwsVern cases, so we handle them here instead.
                        switch (fieldWs)
                        {
                        case WritingSystemServices.kwsAnal:
                            wsesForThisField.Add(servLoc.LanguageProject.DefaultAnalysisWritingSystem);
                            break;

                        case WritingSystemServices.kwsVern:
                            wsesForThisField.Add(servLoc.LanguageProject.DefaultVernacularWritingSystem);
                            break;

                        default:
                            wsesForThisField = WritingSystemServices.GetWritingSystemList(cache, fieldWs, forceIncludeEnglish: false);
                            break;
                        }
#if FW8_COMPAT
                        IEnumerable <string> inputSystems = wsesForThisField.Select(LcmWs => LcmWs.Id);
#else
                        IEnumerable <string> inputSystems = wsesForThisField.Select(LcmWs => LcmWs.LanguageTag);
#endif
                        // GetWritingSystemList returns all analysis WSes even when asked for just one, so if this
                        // is a single-line custom field, trim the WSes down to just the first one
                        if (lfCustomFieldType.StartsWith("Single"))
                        {
                            inputSystems = inputSystems.Take(1);
                        }
                        fieldConfig = GetLfCustomFieldMultiTextConfig(label, lfCustomFieldType, inputSystems.ToList());
                    }

                    if (fieldConfig != null)
                    {
                        lfCustomFieldConfig[lfCustomFieldName] = fieldConfig;
                    }
                }
            }
        }
Beispiel #34
0
        public bool OkToMove(int hvoDstOwner, int flidDst, int ihvoDstStart, ObjectDragInfo odi)
        {
            CheckDisposed();

            FDO.FdoCache        cache = Slice.ContainingDataTree.Cache;
            ICmObjectRepository repo  = cache.ServiceLocator.GetInstance <ICmObjectRepository>();

            if (flidDst == odi.FlidSrc)
            {
                // Verify that it is not a no-operation.
                if (hvoDstOwner == odi.HvoSrcOwner)
                {
                    // Same property of same object. If it's a collection, disable.
                    CellarPropertyType fieldType = (CellarPropertyType)cache.DomainDataByFlid.MetaDataCache.GetFieldType((int)flidDst);
                    // We can't drag it to the position it's already at; that's no change. We also can't drag it
                    // to the position one greater: that amounts to trying to place it after itself, which (after
                    // removing it from before itself) amounts to a no-operation.
                    if (fieldType == CellarPropertyType.OwningSequence &&
                        ihvoDstStart != odi.IhvoSrcStart && ihvoDstStart != odi.IhvoSrcStart + 1)
                    {
                        // It's a sequence and the target and source positions are different, so we can do it.
                        return(true);
                    }
                }
                else
                {
                    // Different objects; need to verify no circular ownership involved.
                    for (int ihvo = odi.IhvoSrcStart; ihvo <= odi.IhvoSrcEnd; ihvo++)
                    {
                        int hvo = cache.DomainDataByFlid.get_VecItem(odi.HvoSrcOwner, odi.FlidSrc, ihvo);
                        // See if hvoDstOwner is owned by hvo
                        ICmObject obj2 = repo.GetObject(hvoDstOwner);
                        // loop from hvo2 to root owner of hvo2. If hvo2 or any of its owners is hvo,
                        // we have a problem.
                        while (obj2 != null)
                        {
                            if (hvo == obj2.Hvo)
                            {
                                return(false);                                // circular ownership, can't drop.
                            }
                            obj2 = obj2.Owner;
                        }
                    }
                    return(true);
                }
            }
            else
            {
                // Different property, check signature.
                IFwMetaDataCache mdc = cache.DomainDataByFlid.MetaDataCache;
                int luclid           = mdc.GetDstClsId((int)flidDst);
                for (int ihvo = odi.IhvoSrcStart; ihvo <= odi.IhvoSrcEnd; ihvo++)
                {
                    int hvo = cache.DomainDataByFlid.get_VecItem(odi.HvoSrcOwner, odi.FlidSrc, ihvo);
                    int cls = repo.GetObject(hvo).ClassID;
                    while (cls != 0 && cls != luclid)
                    {
                        cls = mdc.GetBaseClsId(cls);
                    }
                    if (cls == 0)
                    {
                        return(false);                        // wrong signature, can't drop.
                    }
                }
                // All sigs OK, allow drop.
                return(true);
            }
            // If none of those cases is OK, can't do it.
            return(false);
        }
Beispiel #35
0
        private void ExportCustomFields(TextWriter writer, IRnGenericRec record)
        {
            ISilDataAccessManaged sda = m_cache.DomainDataByFlid as ISilDataAccessManaged;

            Debug.Assert(sda != null);
            foreach (int flid in m_customFlids)
            {
                string             fieldName = m_mdc.GetFieldName(flid);
                bool               fHandled  = false;
                ITsString          tss;
                string             s;
                CellarPropertyType cpt = (CellarPropertyType)m_mdc.GetFieldType(flid);
                switch (cpt)
                {
                case CellarPropertyType.Boolean:
                    break;

                case CellarPropertyType.Integer:
                    break;

                case CellarPropertyType.Numeric:
                    break;

                case CellarPropertyType.Float:
                    break;

                case CellarPropertyType.Time:
                    break;

                case CellarPropertyType.Guid:
                    break;

                case CellarPropertyType.Image:
                case CellarPropertyType.Binary:
                    break;

                case CellarPropertyType.GenDate:
                    break;

                case CellarPropertyType.String:
                    tss = sda.get_StringProp(record.Hvo, flid);
                    if (tss != null && tss.Text != null)
                    {
                        ExportString(writer, tss, fieldName);
                    }
                    fHandled = true;
                    break;

                case CellarPropertyType.MultiString:
                case CellarPropertyType.MultiUnicode:
                    ITsMultiString tms = sda.get_MultiStringProp(record.Hvo, flid);
                    int            cch = 0;
                    for (int i = 0; i < tms.StringCount; ++i)
                    {
                        int ws;
                        tss  = tms.GetStringFromIndex(i, out ws);
                        cch += tss.Length;
                        if (cch > 0)
                        {
                            break;
                        }
                    }
                    if (cch > 0)
                    {
                        writer.WriteLine("<Field name=\"{0}\" type=\"MultiString\">", fieldName);
                        for (int i = 0; i < tms.StringCount; ++i)
                        {
                            int ws;
                            tss = tms.GetStringFromIndex(i, out ws);
                            if (tss != null && tss.Length > 0)
                            {
                                if (cpt == CellarPropertyType.MultiString)
                                {
                                    writer.WriteLine(TsStringUtils.GetXmlRep(tss,
                                                                             m_cache.WritingSystemFactory, ws, true));
                                }
                                else
                                {
                                    writer.WriteLine("<AUni ws=\"{0}\">{1}</AUni>",
                                                     m_cache.WritingSystemFactory.GetStrFromWs(ws),
                                                     XmlUtils.MakeSafeXml(tss.Text));
                                }
                            }
                        }
                        writer.WriteLine("</Field>");
                    }
                    fHandled = true;
                    break;

                case CellarPropertyType.Unicode:
                    break;

                case CellarPropertyType.ReferenceAtomic:
                case CellarPropertyType.ReferenceCollection:
                case CellarPropertyType.ReferenceSequence:
                {
                    int        destClid  = m_mdc.GetDstClsId(flid);
                    List <int> rghvoDest = new List <int>();
                    if (cpt == CellarPropertyType.ReferenceAtomic)
                    {
                        int hvo = sda.get_ObjectProp(record.Hvo, flid);
                        if (hvo != 0)
                        {
                            if (destClid == CmPossibilityTags.kClassId)
                            {
                                ICmPossibility poss = PossibilityRepository.GetObject(hvo);
                                ExportAtomicReference(writer, poss, fieldName, "CmPossibility");
                                fHandled = true;
                            }
                            else
                            {
                                rghvoDest.Add(hvo);
                            }
                        }
                        else
                        {
                            fHandled = true;
                        }
                    }
                    else
                    {
                        int[] hvos = sda.VecProp(record.Hvo, flid);
                        if (hvos.Length > 0)
                        {
                            if (destClid == CmPossibilityTags.kClassId)
                            {
                                List <ICmPossibility> collection = new List <ICmPossibility>();
                                foreach (int hvo in hvos)
                                {
                                    collection.Add(PossibilityRepository.GetObject(hvo));
                                }
                                ExportReferenceList(writer, collection, fieldName, "CmPossibility", cpt);
                                fHandled = true;
                            }
                            else
                            {
                                rghvoDest.AddRange(hvos);
                            }
                        }
                        else
                        {
                            fHandled = true;
                        }
                    }
                    if (rghvoDest.Count > 0)
                    {
                    }
                }
                break;

                case CellarPropertyType.OwningAtomic:
                case CellarPropertyType.OwningCollection:
                case CellarPropertyType.OwningSequence:
                {
                    int        destClid  = m_mdc.GetDstClsId(flid);
                    List <int> rghvoDest = new List <int>();
                    if (cpt == CellarPropertyType.OwningAtomic)
                    {
                        int hvo = sda.get_ObjectProp(record.Hvo, flid);
                        if (hvo != 0)
                        {
                            if (destClid == StTextTags.kClassId)
                            {
                                IStText text = StTextRepository.GetObject(hvo);
                                ExportStText(writer, text, fieldName);
                                fHandled = true;
                            }
                            else
                            {
                                rghvoDest.Add(hvo);
                            }
                        }
                        else
                        {
                            fHandled = true;
                        }
                    }
                    else
                    {
                    }
                }
                break;
                }
                if (!fHandled)
                {
                }
            }
        }
Beispiel #36
0
		private void ReadPossibilityMarker(XmlNode xnMarker, RnSfMarker sfm, CellarPropertyType cpt)
		{
			foreach (XmlNode xn in xnMarker.ChildNodes)
			{
				switch (xn.Name)
				{
					case "Match":
						string sMatch = XmlUtils.GetManditoryAttributeValue(xn, "value");
						switch (sMatch)
						{
							case "abbr":
								sfm.m_tlo.m_pnt = PossNameType.kpntAbbreviation;
								break;
							case "name":
								sfm.m_tlo.m_pnt = PossNameType.kpntName;
								break;
							default:
								sfm.m_tlo.m_pnt = PossNameType.kpntAbbreviation;
								break;
						}
						break;
					case "Multiple":
						if (cpt == CellarPropertyType.ReferenceCollection ||
							cpt == CellarPropertyType.ReferenceSequence ||
							cpt == CellarPropertyType.OwningCollection ||
							cpt == CellarPropertyType.OwningSequence)
						{
							sfm.m_tlo.m_fHaveMulti = true;
							sfm.m_tlo.m_sDelimMulti = XmlUtils.GetManditoryAttributeValue(xn, "sep");
						}
						break;
					case "Subchoice":
						sfm.m_tlo.m_fHaveSub = true;
						sfm.m_tlo.m_sDelimSub = XmlUtils.GetManditoryAttributeValue(xn, "sep");
						break;
					case "Default":
						sfm.m_tlo.m_sEmptyDefault = XmlUtils.GetManditoryAttributeValue(xn, "value");
						sfm.m_tlo.m_default = null;
						break;
					case "DelimitChoice":
						sfm.m_tlo.m_fHaveBetween = true;
						sfm.m_tlo.m_sMarkStart = XmlUtils.GetManditoryAttributeValue(xn, "start");
						sfm.m_tlo.m_sMarkEnd = XmlUtils.GetManditoryAttributeValue(xn, "end");
						break;
					case "StopChoices":
						sfm.m_tlo.m_fHaveBefore = true;
						sfm.m_tlo.m_sBefore = XmlUtils.GetManditoryAttributeValue(xn, "value");
						break;
					case "IgnoreNewChoices":
						sfm.m_tlo.m_fIgnoreNewStuff = XmlUtils.GetBooleanAttributeValue(xn, "value");
						break;
					case "MatchReplaceChoice":
						sfm.m_tlo.m_rgsMatch.Add(XmlUtils.GetManditoryAttributeValue(xn, "match"));
						sfm.m_tlo.m_rgsReplace.Add(XmlUtils.GetOptionalAttributeValue(xn, "replace", String.Empty));
						break;
					case "ItemWrtSys":
						sfm.m_tlo.m_wsId = XmlUtils.GetManditoryAttributeValue(xn, "ws");
						break;
				}
			}
		}
Beispiel #37
0
		public MetaFieldRec()
		{
			m_fieldType = 0;
			m_ownClsid = 0;
			m_dstClsid = 0;
			m_fieldWs = 0;
			m_fieldName = null;
			m_fieldLabel = null;
			m_fieldHelp = null;
			m_fieldXml = null;
		}
        private void SetSubControl()
        {
            m_groupOptions.Controls.Clear();
            if (m_rsfm.m_flid == 0)
            {
                m_groupOptions.Text = LexTextControls.ksDiscardedField;
                m_groupOptions.Controls.Add(m_discardOpt);
                m_discardOpt.Location = m_locSubCtrl;
                return;
            }
            CellarPropertyType cpt = (CellarPropertyType)m_mdc.GetFieldType(m_rsfm.m_flid);
            int clidDst            = -1;

            switch (cpt)
            {
            case CellarPropertyType.ReferenceAtomic:
            case CellarPropertyType.ReferenceCollection:
            case CellarPropertyType.ReferenceSequence:
                clidDst = m_mdc.GetDstClsId(m_rsfm.m_flid);
                switch (clidDst)
                {
                case RnGenericRecTags.kClassId:
                    m_groupOptions.Text = LexTextControls.ksRnLinkFieldOptions;
                    m_groupOptions.Controls.Add(m_linkOpt);
                    m_linkOpt.Location = m_locSubCtrl;
                    break;

                case CrossReferenceTags.kClassId:
                case ReminderTags.kClassId:
                    throw new NotImplementedException(LexTextControls.ksUnimplementedField);

                default:
                    int clidBase = clidDst;
                    while (clidBase != 0 && clidBase != CmPossibilityTags.kClassId)
                    {
                        clidBase = m_mdc.GetBaseClsId(clidBase);
                    }
                    if (clidBase == CmPossibilityTags.kClassId)
                    {
                        m_groupOptions.Text = LexTextControls.ksListRefImportOptions;
                        m_groupOptions.Controls.Add(m_listOpt);
                        m_listOpt.Location = m_locSubCtrl;
                        m_listOpt.Initialize(m_cache, m_helpTopicProvider, m_app, m_stylesheet, m_rsfm, cpt);
                        break;
                    }
                    throw new ArgumentException(LexTextControls.ksInvalidField);
                }
                break;

            case CellarPropertyType.OwningAtomic:
            case CellarPropertyType.OwningCollection:
            case CellarPropertyType.OwningSequence:
                clidDst = m_mdc.GetDstClsId(m_rsfm.m_flid);
                switch (clidDst)
                {
                case StTextTags.kClassId:
                    Debug.Assert(cpt == CellarPropertyType.OwningAtomic);
                    m_groupOptions.Text = LexTextControls.ksTextImportOptions;
                    m_groupOptions.Controls.Add(m_textOpt);
                    m_textOpt.Location = m_locSubCtrl;
                    m_textOpt.Initialize(m_cache, m_helpTopicProvider, m_app, m_stylesheet, m_rsfm);
                    break;

                case RnRoledParticTags.kClassId:
                    m_groupOptions.Text = LexTextControls.ksListRefImportOptions;
                    m_groupOptions.Controls.Add(m_listOpt);
                    m_listOpt.Location = m_locSubCtrl;
                    m_listOpt.Initialize(m_cache, m_helpTopicProvider, m_app, m_stylesheet, m_rsfm, cpt);
                    break;

                case RnGenericRecTags.kClassId:
                    throw new NotImplementedException(LexTextControls.ksUnimplementedField);

                default:
                    throw new ArgumentException(LexTextControls.ksInvalidField);
                }
                break;

            case CellarPropertyType.MultiString:
            case CellarPropertyType.MultiUnicode:
                m_groupOptions.Text = LexTextControls.ksMultiStringImportOptions;
                m_groupOptions.Controls.Add(m_stringOpt);
                m_stringOpt.Location = m_locSubCtrl;
                m_stringOpt.Initialize(m_cache, m_helpTopicProvider, m_app, m_stylesheet, m_rsfm);
                break;

            case CellarPropertyType.String:
                m_groupOptions.Text = LexTextControls.ksStringImportOptions;
                m_groupOptions.Controls.Add(m_stringOpt);
                m_stringOpt.Location = m_locSubCtrl;
                m_stringOpt.Initialize(m_cache, m_helpTopicProvider, m_app, m_stylesheet, m_rsfm);
                break;

            case CellarPropertyType.GenDate:
                m_groupOptions.Text = LexTextControls.ksGenDateImportOptions;
                m_groupOptions.Controls.Add(m_dateOpt);
                m_dateOpt.Location = m_locSubCtrl;
                m_dateOpt.Initialize(m_cache, m_helpTopicProvider, m_rsfm, true);
                break;

            case CellarPropertyType.Time:
                m_groupOptions.Text = LexTextControls.ksDateTimeImportOptions;
                m_groupOptions.Controls.Add(m_dateOpt);
                m_dateOpt.Location = m_locSubCtrl;
                m_dateOpt.Initialize(m_cache, m_helpTopicProvider, m_rsfm, false);
                break;

            case CellarPropertyType.Unicode:
            case CellarPropertyType.Binary:
            case CellarPropertyType.Image:
            case CellarPropertyType.Boolean:
            case CellarPropertyType.Float:
            case CellarPropertyType.Guid:
            case CellarPropertyType.Integer:
            case CellarPropertyType.Numeric:
                throw new ArgumentException(LexTextControls.ksInvalidField);
            }
        }
Beispiel #39
0
            int MakeRealObject(ITsString tssTyped)
            {
                // Figure whether owning atomic or owning collection or owning sequence. Throw if none.
                // Unless we're making an unowned IText for a Notebook Record.
                ISilDataAccess     sdaReal    = m_fdoCache.DomainDataByFlid;
                IFwMetaDataCache   mdc        = sdaReal.MetaDataCache;
                CellarPropertyType typeOwning =
                    (CellarPropertyType)(mdc.GetFieldType(m_flidEmptyProp) & (int)CellarPropertyTypeFilter.VirtualMask);
                // Make a new object of the specified class in the specified property.
                int ord = 0;

                switch (typeOwning)
                {
                default:
                    if (m_flidEmptyProp != RnGenericRecTags.kflidText)
                    {
                        throw new Exception("ghost string property must be owning object property");
                    }
                    break;

                case CellarPropertyType.OwningAtomic:
                    ord = -2;
                    break;

                case CellarPropertyType.OwningCollection:
                    ord = -1;
                    break;

                case CellarPropertyType.OwningSequence:
                    // ord = 0 set above (inserting the first and only object at position 0).
                    break;
                }
                string sClassRaw    = mdc.GetClassName(m_clidDst);
                string sClass       = m_mediator.StringTbl.GetString(sClassRaw, "ClassNames");
                string sUndo        = String.Format(DetailControlsStrings.ksUndoCreate0, sClass);
                string sRedo        = String.Format(DetailControlsStrings.ksRedoCreate0, sClass);
                int    hvoNewObj    = 0;
                int    hvoStringObj = 0;

                UndoableUnitOfWorkHelper.DoUsingNewOrCurrentUOW(sUndo, sRedo, m_fdoCache.ServiceLocator.GetInstance <IActionHandler>(), () =>
                {
                    // Special case: if we just created a Text in RnGenericRecord, and we want to show the contents
                    // of an StTxtPara, make the intermediate objects
                    if (m_flidEmptyProp == RnGenericRecTags.kflidText)
                    {
                        var servLoc     = Cache.ServiceLocator;
                        var text        = servLoc.GetInstance <ITextFactory>().Create();
                        var stText      = servLoc.GetInstance <IStTextFactory>().Create();
                        text.ContentsOA = stText;
                        var para        = servLoc.GetInstance <IStTxtParaFactory>().Create();
                        stText.ParagraphsOS.Add(para);
                        hvoNewObj    = text.Hvo;
                        hvoStringObj = para.Hvo;
                        // Set the RnGenericRec's Text property to reference the new text
                        sdaReal.SetObjProp(m_hvoObj, m_flidEmptyProp, hvoNewObj);
                    }
                    else
                    {
                        hvoNewObj = hvoStringObj = sdaReal.MakeNewObject(m_clidDst, m_hvoObj, m_flidEmptyProp, ord);
                    }

                    // Set its property m_flidStringProp to tssTyped. If it is multilingual, choose based on ghostWs.
                    var typeString = (CellarPropertyType)(mdc.GetFieldType(m_flidStringProp) &
                                                          (int)CellarPropertyTypeFilter.VirtualMask);
                    switch (typeString)
                    {
                    default:
                        throw new Exception("ghost property must store strings!");

                    case CellarPropertyType.MultiString:
                    case CellarPropertyType.MultiUnicode:
                        sdaReal.SetMultiStringAlt(hvoStringObj, m_flidStringProp, m_wsToCreate, tssTyped);
                        break;

                    case CellarPropertyType.String:
                        sdaReal.SetString(hvoStringObj, m_flidStringProp, tssTyped);
                        break;
                    }

                    string ghostInitMethod = XmlUtils.GetOptionalAttributeValue(m_nodeObjProp, "ghostInitMethod");
                    if (ghostInitMethod != null)
                    {
                        var obj      = m_fdoCache.ServiceLocator.GetInstance <ICmObjectRepository>().GetObject(hvoNewObj);
                        Type objType = obj.GetType();
                        System.Reflection.MethodInfo mi = objType.GetMethod(ghostInitMethod);
                        mi.Invoke(obj, null);
                    }
                });
                return(hvoNewObj);
            }
Beispiel #40
0
 public virtual int AddCustomField(string className, string fieldName, CellarPropertyType fieldType, int destinationClass)
 {
     return(m_metaDataCache.AddCustomField(className, fieldName, fieldType, destinationClass));
 }
		/// <summary>
		/// Returns true for Binary, Boolean, GenDate, Integer and Time
		/// </summary>
		/// <param name="type"></param>
		/// <returns></returns>
		public bool IsValueType(CellarPropertyType type)
		{
			return m_metaDataCache.IsValueType(type);
		}
Beispiel #42
0
		private XmlNode GetFxtNodeAndFxtItemLabel(string sClassName, int flid, string sFieldName,
			CellarPropertyType fieldType, out string sResultOwningElementName,
			out bool fIsRefVector, out string sFxtItemLabel)
		{
			const string ksObjVector = "objVector";
			string sObjFieldType = "OS";
			if (fieldType == CellarPropertyType.OwningCollection)
				sObjFieldType = "OC";

			string[] asAttributeValues = new string[1];
			asAttributeValues[0] = sFieldName + sObjFieldType;
			FXTElementSearchProperties searchProps =
				new FXTElementSearchProperties(ksObjVector, "objProperty", asAttributeValues);
			List<FXTElementSearchProperties> searchPropsList = new List<FXTElementSearchProperties>(2);
			searchPropsList.Add(searchProps);
			string[] asAttributeValues2 = new string[1];
			asAttributeValues2[0] = sFieldName;
			FXTElementSearchProperties searchProps2 = new FXTElementSearchProperties(ksRefVector, ksField, asAttributeValues2);
			searchPropsList.Add(searchProps2);

			string sAttrValueFound;
			FXTElementSearchProperties searchPropsFound;
			XmlNode fxtFieldNode =
				GetFxtFieldNode(sClassName, searchPropsList, out sResultOwningElementName, out searchPropsFound,
								out sAttrValueFound);
			if (fxtFieldNode == null)
			{
				sResultOwningElementName = "";
				fIsRefVector = false;
				sFxtItemLabel = "";
				return null; // Not all fields are addressed in the FXT description
			}

			if (searchPropsFound.ElementName == ksObjVector)
			{
				fIsRefVector = false;
				// want the signature of the field
				int destClassId = m_cache.GetDestinationClass((int) flid);

				if (m_cache.DomainDataByFlid.MetaDataCache.GetAbstract(destClassId))
				{
					int iCount = 0;
					StringBuilder sbSubClasses = new StringBuilder();
					GetNamesOfSubClasses(destClassId, sbSubClasses, iCount);
					sFxtItemLabel = sbSubClasses.ToString();
				}
				else
					sFxtItemLabel = m_cache.DomainDataByFlid.MetaDataCache.GetClassName(destClassId);
			}
			else
			{
				fIsRefVector = true;
				XmlNode fxtItemLabelAttr = fxtFieldNode.SelectSingleNode("@itemLabel");
				sFxtItemLabel = fxtItemLabelAttr.InnerText;
			}
			return fxtFieldNode;
		}
		public int AddCustomField(string className, string fieldName, CellarPropertyType fieldType,
			int destinationClass, string fieldHelp, int fieldWs, Guid fieldListRoot)
		{
			return m_metaDataCache.AddCustomField(className, fieldName, fieldType, destinationClass,
				fieldHelp, fieldWs, fieldListRoot);
		}
		private bool IsSupportedFieldType(CellarPropertyType fieldType)
		{
			switch (fieldType)
			{
				case CellarPropertyType.OwningAtomic:
				case CellarPropertyType.ReferenceAtomic:
				case CellarPropertyType.Boolean:
				//case CellarPropertyType.Float: // Not yet supported (as of 23 march 2013)
				case CellarPropertyType.GenDate:
				case CellarPropertyType.Guid:
				case CellarPropertyType.Integer:
				//case CellarPropertyType.Numeric: // Not yet supported (as of 23 march 2013)
				case CellarPropertyType.Time:
					return true;
			}
			return false;
		}
		internal void Initialize(FdoCache cache, XCore.IHelpTopicProvider helpTopicProvider, IApp app, IVwStylesheet stylesheet,
			NotebookImportWiz.RnSfMarker rsfm, CellarPropertyType cpt)
		{
			m_cache = cache;
			m_helpTopicProvider = helpTopicProvider;
			m_btnAddWritingSystem.Initialize(m_cache, helpTopicProvider, app, stylesheet);
			NotebookImportWiz.InitializeWritingSystemCombo(rsfm.m_tlo.m_wsId, cache,
				m_cbWritingSystem);

			bool fNotAtomic = (cpt != CellarPropertyType.ReferenceAtomic);
			m_tbDefaultValue.Text = rsfm.m_tlo.m_sEmptyDefault;

			m_chkDelimMultiEnable.Checked = rsfm.m_tlo.m_fHaveMulti && fNotAtomic;
			m_chkDelimMultiEnable.Enabled = fNotAtomic;
			m_tbDelimMulti.Text = rsfm.m_tlo.m_sDelimMulti;
			m_tbDelimMulti.Enabled = rsfm.m_tlo.m_fHaveMulti && fNotAtomic;

			m_chkDelimSubEnable.Checked = rsfm.m_tlo.m_fHaveSub;
			m_tbDelimSub.Text = rsfm.m_tlo.m_sDelimSub;
			m_tbDelimSub.Enabled = rsfm.m_tlo.m_fHaveSub;

			m_chkBetweenEnable.Checked = rsfm.m_tlo.m_fHaveBetween;
			m_tbBetweenBefore.Text = rsfm.m_tlo.m_sMarkStart;
			m_tbBetweenAfter.Text = rsfm.m_tlo.m_sMarkEnd;
			m_tbBetweenBefore.Enabled = rsfm.m_tlo.m_fHaveBetween;
			m_tbBetweenAfter.Enabled = rsfm.m_tlo.m_fHaveBetween;

			m_chkOnlyBeforeEnable.Checked = rsfm.m_tlo.m_fHaveBefore;
			m_tbOnlyBefore.Text = rsfm.m_tlo.m_sBefore;
			m_tbOnlyBefore.Enabled = rsfm.m_tlo.m_fHaveBefore;

			m_chkDiscardNewStuff.Checked = rsfm.m_tlo.m_fIgnoreNewStuff;

			m_rbMatchName.Checked = rsfm.m_tlo.m_pnt == PossNameType.kpntName;
			m_rbMatchAbbr.Checked = rsfm.m_tlo.m_pnt != PossNameType.kpntName;

			Debug.Assert(rsfm.m_tlo.m_rgsMatch.Count == rsfm.m_tlo.m_rgsReplace.Count);
			m_lvSubstitutions.Items.Clear();
			for (int i = 0; i < rsfm.m_tlo.m_rgsMatch.Count; ++i)
			{
				var lvi = new ListViewItem(new[] { rsfm.m_tlo.m_rgsMatch[i], rsfm.m_tlo.m_rgsReplace[i] });
				m_lvSubstitutions.Items.Add(lvi);
			}
		}
		/// <summary>
		/// Add a user-defined custom field.
		/// </summary>
		/// <param name="className">Class that gets the new custom field.</param>
		/// <param name="fieldName">Field name for the custom field.</param>
		/// <param name="fieldType">Data type for the custom field.</param>
		/// <param name="destinationClass">Class Id for object type custom properties</param>
		/// <returns>The Id for the new custom field.</returns>
		/// <exception cref="KeyNotFoundException">
		/// Thrown if 'fieldType' is an object type (owning/reference and atomic/collection/sequence) property,
		/// but 'destinationClass' does not match a class in the model.
		/// </exception>
		/// <exception cref="ArgumentNullException">
		/// Thrown if 'className' or 'fieldName' are null or empty.
		/// </exception>
		/// <exception cref="KeyNotFoundException">
		/// Thrown if class is not defined.
		/// </exception>
		/// <remarks>
		/// If 'fieldType' is a basic property type, then 'destinationClass' is ignored.
		///
		/// If 'fieldType' is an object type (owning/reference and atomic/collection/sequence) property,
		/// then 'destinationClass' must match a class in the model.
		/// </remarks>
		public int AddCustomField(string className, string fieldName, CellarPropertyType fieldType, int destinationClass)
		{
			return AddCustomField(className, fieldName, fieldType, destinationClass, null, 0, Guid.Empty);
		}
Beispiel #47
0
		// extracted from the CellarPropertyType enum
		protected static string GetFlidTypeAsString(CellarPropertyType flidType)
		{
			string retval;
			switch (flidType)
			{
				default:
					throw new ArgumentException("Property element name not recognized.");
				case CellarPropertyType.Boolean:
					retval = "Boolean";
					break;
				case CellarPropertyType.Integer:
					retval = "Integer";
					break;
				case CellarPropertyType.Time:
					retval = "Time";
					break;
				case CellarPropertyType.String:
					retval = "String";
					break;
				case CellarPropertyType.MultiString:
					retval = "MultiString";
					break;
				case CellarPropertyType.Unicode:
					retval = "Unicode";
					break;
				case CellarPropertyType.MultiUnicode:
					retval = "MultiUnicode";
					break;
				case CellarPropertyType.Guid:
					retval = "Guid";
					break;
				case CellarPropertyType.Image:
					retval = "Image";
					break;
				case CellarPropertyType.GenDate:
					retval = "GenDate";
					break;
				case CellarPropertyType.Binary:
					retval = "Binary";
					break;
				case CellarPropertyType.Numeric:
					retval = "Numeric";
					break;
				case CellarPropertyType.Float:
					retval = "Float";
					break;
				case CellarPropertyType.OwningAtomic:
					retval = "OA";
					break;
				case CellarPropertyType.OwningCollection:
					retval = "OC";
					break;
				case CellarPropertyType.OwningSequence:
					retval = "OS";
					break;
				case CellarPropertyType.ReferenceAtomic:
					retval = "RA";
					break;
				case CellarPropertyType.ReferenceCollection:
					retval = "RC";
					break;
				case CellarPropertyType.ReferenceSequence:
					retval = "RS";
					break;
			}
			return retval;
		}
		public int AddCustomField(string className, string fieldName, CellarPropertyType fieldType,
			int destinationClass, string fieldHelp, int fieldWs, Guid fieldListRoot)
		{
			int clid;
			if (m_classesByName.TryGetValue(className, out clid))
			{
				List<MockFieldInfo> list;
				var flid = (clid * 1000) + 500;
				if (m_fieldsByClassId.TryGetValue(clid, out list))
				{
					var flidMax = flid - 1;
					foreach (MockFieldInfo mfi in list)
					{
						if (mfi.m_fCustom && mfi.m_flid >= flid)
							flidMax = mfi.m_flid;
					}
					flid = flidMax + 1;
				}
				else
				{
					list = new List<MockFieldInfo>();
					m_fieldsByClassId.Add(clid, list);
				}
				var mfiNew = new MockFieldInfo
					{
						m_flid = flid,
						m_name = fieldName,
						m_cpt = fieldType,
						m_destClsid = destinationClass,
						m_fCustom = true,
						m_fieldHelp = fieldHelp,
						m_fieldWs = fieldWs,
						m_fieldListRoot = fieldListRoot
					};
				list.Add(mfiNew);
				m_fieldsById.Add(flid, mfiNew);
				return flid;
			}

			return 0;
		}
Beispiel #49
0
        /// <summary>Add a virtual property (field) to a class.</summary>
        /// <param name='className'>Name of the class that gets the new virtual property</param>
        /// <param name='fieldName'>Name of the new virtual Field.</param>
        /// <param name='virtualFlid'>Field identifier for the enw virtual field</param>
        /// <param name='iFieldType'>
        /// This type value indicates if the field is a primitive data type
        /// or a MultiStr/MultiTxt value or describes the relationship
        /// between two classes (i.e. owning/reference and atomic/collection/sequence).
        /// These numeric values are defined in CoreImpl\CellarPropertyType.cs.
        /// It must NOT have the virtual bit OR'd in.
        /// </param>
        public void AddVirtualProp(string className, string fieldName, int virtualFlid, int iFieldType)
        {
            CellarPropertyType fieldType = (CellarPropertyType)iFieldType;

            // Do various tests to make sure:
            // 1. The given className exists,
            // 2. The given fieldName does NOT exist for the given class,
            // 3. The given virtualFlid does NOT exist, and finally
            // 4. The fieldType is a legal value.
            // Will throw, if the classname doesn't exist,
            // dealing with #1, above.
            if (!m_nameToClid.ContainsKey(className))
            {
                throw new ArgumentException("Class not found.");
            }
            var clid = m_nameToClid[className];

            // Check condition #2, above.
            // JohnT changed the last argument to 'false'. MDC should allow override virtual handlers.
            var flid = GetFieldId2(clid, fieldName, false);

            if (flid > 0)
            {
                throw new ArgumentException("Field name already exists.", "fieldName");
            }

            // Check condition #3, above.
            MetaFieldRec mfr;

            if (m_metaFieldRecords.ContainsKey(virtualFlid))
            {
                throw new ArgumentException("Field number already in use.", "virtualFlid");
            }

            // Test condition #4, above.
            // May throw if fieldType isn't valid.
            switch (fieldType)
            {
            default:
                throw new ArgumentException("Invalid field type.", "fieldType");

            case CellarPropertyType.Boolean:
            case CellarPropertyType.Integer:
            case CellarPropertyType.Numeric:
            case CellarPropertyType.Float:
            case CellarPropertyType.Time:
            case CellarPropertyType.Guid:
            case CellarPropertyType.Image:
            case CellarPropertyType.GenDate:
            case CellarPropertyType.Binary:
            case CellarPropertyType.String:
            case CellarPropertyType.MultiString:
            case CellarPropertyType.Unicode:
            case CellarPropertyType.MultiUnicode:
            case CellarPropertyType.OwningAtomic:
            case CellarPropertyType.ReferenceAtomic:
            case CellarPropertyType.OwningCollection:
            case CellarPropertyType.ReferenceCollection:
            case CellarPropertyType.OwningSequence:
            case CellarPropertyType.ReferenceSequence:
                mfr = new MetaFieldRec
                {
                    m_fieldType = fieldType,
                    m_fieldName = fieldName,
                    m_ownClsid  = clid,
                    m_fType     = FieldType.virt
                };
                MetaClassRec mcr = m_metaClassRecords[clid];
                InstallField(mcr, clid, mfr.m_fieldName, virtualFlid, mfr);
                break;
            }
        }
		/// <summary>
		/// Returns true for Boolean, GenDate, Guid, Integer, Float, Numeric, and Time
		/// </summary>
		/// <param name="type"></param>
		/// <remarks>
		/// Float and Numeric are not used in the model, as of 23 March 2013.
		/// </remarks>
		/// <returns></returns>
		public bool IsValueType(CellarPropertyType type)
		{
			return PropertyTypesForValueTypeData.Contains(type);
		}
Beispiel #51
0
        /// <summary>
        /// Gets the data for one custom field, and any relevant GUIDs.
        /// </summary>
        /// <param name="hvo">Hvo of object we're getting the field for.</param>
        /// <param name="flid">Flid for this field.</param>
        /// <param name="fieldSourceType">Either "entry", "senses" or "examples". Could also be "allomorphs", eventually.</param>
        /// <param name="bsonForThisField">Output of a BsonDocument with the following structure: <br />
        /// { fieldName: { "value": BsonValue, "guid": "some-guid-as-a-string" } } <br />
        /// -OR- <br />
        /// { fieldName: { "value": BsonValue, "guid": ["guid1", "guid2", "guid3"] } } <br />
        /// The format of the fieldName key will be "customField_FOO_field_name_with_underscores",
        /// where FOO is one of "entry", "senses", or "examples". <br />
        /// The type of the "guid" value (array or string) will determine whether there is a single GUID,
        /// or a list of GUIDs that happens to contain only one entry.
        /// If there is no "guid" key, that field has no need for a GUID. (E.g., a number).
        /// </param>
        /// <param name="listConverters">Dictionary of ConvertLcmToMongoOptionList instances, keyed by list code</param>
        private BsonDocument GetCustomFieldData(int hvo, int flid, string fieldSourceType,
                                                IDictionary <string, ConvertLcmToMongoOptionList> listConverters)
        {
            BsonValue             fieldValue   = null;
            BsonValue             fieldGuid    = null; // Might be a single value, might be a list (as a BsonArray)
            ISilDataAccessManaged data         = (ISilDataAccessManaged)cache.DomainDataByFlid;
            CellarPropertyType    LcmFieldType = (CellarPropertyType)LcmMetaData.GetFieldType(flid);
            var dataGuids = new List <Guid>();

            // Valid field types in Lcm are GenDate, Integer, String, OwningAtomic, ReferenceAtomic, and ReferenceCollection, so that's all we implement.
            switch (LcmFieldType)
            {
            case CellarPropertyType.GenDate:
                GenDate genDate    = data.get_GenDateProp(hvo, flid);
                string  genDateStr = genDate.ToLongString();
                // LF wants single-string fields in the format { "ws": { "value": "contents" } }
                fieldValue = String.IsNullOrEmpty(genDateStr) ? null :
                             LfMultiText.FromSingleStringMapping(
                    MagicStrings.LanguageCodeForGenDateFields, genDateStr).AsBsonDocument();
                break;
            // When parsing, will use GenDate.TryParse(str, out genDate)

            case CellarPropertyType.Integer:
                fieldValue = new BsonInt32(data.get_IntProp(hvo, flid));
                if (fieldValue.AsInt32 == default(Int32))
                {
                    fieldValue = null;                     // Suppress int fields with 0 in them, to save Mongo DB space
                }
                else
                {
                    // LF wants single-string fields in the format { "ws": { "value": "contents" } }
                    fieldValue = LfMultiText.FromSingleStringMapping(
                        MagicStrings.LanguageCodeForIntFields, fieldValue.AsInt32.ToString()).AsBsonDocument();
                }
                break;

            case CellarPropertyType.OwningAtomic:
            case CellarPropertyType.ReferenceAtomic:
                int ownedHvo = data.get_ObjectProp(hvo, flid);
                fieldValue = GetCustomReferencedObject(ownedHvo, flid, listConverters, ref dataGuids);
                if (fieldValue != null && LcmFieldType == CellarPropertyType.ReferenceAtomic)
                {
                    // Single CmPossiblity reference - LF expects format like { "value": "key of possibility" }
                    fieldValue = new BsonDocument("value", fieldValue);
                }
                fieldGuid = new BsonString(dataGuids.FirstOrDefault().ToString());
                break;

            case CellarPropertyType.MultiUnicode:
                ITsMultiString tss = data.get_MultiStringProp(hvo, flid);
                if (tss != null && tss.StringCount > 0)
                {
                    fieldValue = LfMultiText.FromMultiITsString(tss, servLoc.WritingSystemManager).AsBsonDocument();
                }
                break;

            case CellarPropertyType.OwningCollection:
            case CellarPropertyType.OwningSequence:
            case CellarPropertyType.ReferenceCollection:
            case CellarPropertyType.ReferenceSequence:
                int[] listHvos    = data.VecProp(hvo, flid);
                var   innerValues = new BsonArray(listHvos.Select(listHvo => GetCustomReferencedObject(listHvo, flid, listConverters, ref dataGuids)).Where(x => x != null));
                if (innerValues.Count == 0)
                {
                    fieldValue = null;
                }
                else
                {
                    fieldValue = new BsonDocument("values", innerValues);
                    fieldGuid  = new BsonArray(dataGuids.Select(guid => guid.ToString()));
                }
                break;

            case CellarPropertyType.String:
                ITsString iTsValue = data.get_StringProp(hvo, flid);
                if (iTsValue == null || String.IsNullOrEmpty(iTsValue.Text))
                {
                    fieldValue = null;
                }
                else
                {
                    fieldValue = LfMultiText.FromSingleITsString(iTsValue, servLoc.WritingSystemManager).AsBsonDocument();
                }
                break;

            default:
                fieldValue = null;
                if (logger != null)
                {
                    logger.Warning("Lcm CellarPropertyType.{0} not recognized for LF custom field", LcmFieldType.ToString());
                }
                break;
            }

            if (fieldValue == null)
            {
                return(null);
            }
            else
            {
                var result = new BsonDocument();
                result.Add("value", fieldValue ?? BsonNull.Value);                 // BsonValues aren't allowed to have C# nulls; they have their own null representation
                if (fieldGuid is BsonArray)
                {
                    result.Add("guid", fieldGuid, ((BsonArray)fieldGuid).Count > 0);
                }
                else
                {
                    result.Add("guid", fieldGuid, fieldGuid != null);
                }
                return(result);
            }
        }
Beispiel #52
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Check the IsPropInCache method.
        /// </summary>
        /// <param name="hvo">HVO part of the key</param>
        /// <param name="tag">tag part of the key</param>
        /// <param name="expValues">Expected values</param>
        /// ------------------------------------------------------------------------------------
        private void CheckIsPropInCache(int hvo, int tag, object[] expValues)
        {
            for (CellarPropertyType cpt = CellarPropertyType.Nil;
                 cpt <= CellarPropertyType.ReferenceSequence; cpt++)
            {
                bool flag = false;
                switch (cpt)
                {
                case CellarPropertyType.Nil:
                    try
                    {
                        Assert.IsFalse(m_ISilDataAccess.get_IsPropInCache(hvo, tag,
                                                                          (int)cpt, 0));
                    }
                    catch (ArgumentException)
                    {
                    }
                    continue;

                case CellarPropertyType.Boolean:
                case CellarPropertyType.Integer:
                case CellarPropertyType.Numeric:
                    flag = ((int)expValues[5] != 0);
                    break;

                case CellarPropertyType.Float:
                    // Never cached so far
                    // TODO: We expect this to fail the test for VwCacheDa because the existing
                    // implementation fails to set the return value to false. Need to fix this
                    // at line 520 of VwCacheDa.cpp.
                    break;

                case CellarPropertyType.Time:
                    flag = (expValues[4] is long || (int)expValues[4] != 0);
                    break;

                case CellarPropertyType.Guid:
                    flag = ((Guid)expValues[3] != Guid.Empty);
                    break;

                case CellarPropertyType.Image:
                case CellarPropertyType.GenDate:
                    // Never cached so far
                    // TODO: We expect this to fail the test for VwCacheDa because the existing
                    // implementation fails to set the return value to false. Need to fix this
                    // at line 535 of VwCacheDa.cpp.
                    break;

                case CellarPropertyType.Binary:
                    flag = (expValues[2] is byte[]);
                    break;

                case CellarPropertyType.MultiString:
                case CellarPropertyType.MultiUnicode:
                    flag = (expValues[6] != null);
                    break;

                case CellarPropertyType.String:
                    flag = (expValues[7] != null);
                    break;

                case CellarPropertyType.Unicode:
                    flag = (expValues[8] != null);
                    break;

                case CellarPropertyType.OwningAtomic:
                case CellarPropertyType.ReferenceAtomic:
                    flag = ((int)expValues[0] != 0);
                    break;

                case CellarPropertyType.OwningCollection:
                case CellarPropertyType.ReferenceCollection:
                case CellarPropertyType.OwningSequence:
                case CellarPropertyType.ReferenceSequence:
                    flag = (expValues[1] is int[]);
                    break;

                default:
                    continue;
                }
                Assert.AreEqual(flag, m_ISilDataAccess.get_IsPropInCache(hvo, tag, (int)cpt, 12345),
                                string.Format("IsPropInCache for property type '{0}' failed;", cpt));
            }
        }
		bool m_fGotFocus = false; // True if we have focus.

		public TypeAheadSupportVc(int tag, FdoCache cache)
		{
			m_tag = tag;
			IFwMetaDataCache mdc = cache.DomainDataByFlid.MetaDataCache;
			m_clid = mdc.GetOwnClsId(m_tag);
			m_className = mdc.GetClassName(m_clid);
			m_fieldName = mdc.GetFieldName(m_tag);
			m_type = (CellarPropertyType)(mdc.GetFieldType(m_tag) & (int)CellarPropertyTypeFilter.VirtualMask);
			m_sda = cache.DomainDataByFlid;
			Cache = cache;
		}
		/// --------------------------------------------------------------------------------
		/// <summary>
		/// Add a field to the MetaDataCache.
		/// </summary>
		/// <param name="className">Name of the class.</param>
		/// <param name="flid">The flid.</param>
		/// <param name="fieldName">Name of the field.</param>
		/// <param name="fieldLabel">The field label.</param>
		/// <param name="fieldHelp">The field help.</param>
		/// <param name="fieldXml">The field XML.</param>
		/// <param name="fieldSignature">The field signature.</param>
		/// <param name="type">The type.</param>
		/// <param name="fsSource">The fs source.</param>
		/// <param name="fieldListRoot">The field list root.</param>
		/// <param name="fieldWs">The field ws.</param>
		/// --------------------------------------------------------------------------------
		private void AddField(string className, int flid, string fieldName, string fieldLabel,
			string fieldHelp, string fieldXml, string fieldSignature, CellarPropertyType type,
			FieldSource fsSource, Guid fieldListRoot, int fieldWs)
		{
			// Will throw if class is not in one or the other Dictionaries.
			var clid = m_nameToClid[className];
			var mcr = m_metaClassRecords[clid];
			var mfr = new MetaFieldRec
						{
							m_flid = flid,
							m_fieldLabel = fieldLabel,
							m_fieldHelp = fieldHelp,
							m_fieldXml = fieldXml,
							m_fieldListRoot = fieldListRoot,
							m_fieldWs = fieldWs,
							m_sig = null,
							m_fieldSource = fsSource
						};
			switch (type)
			{
				default:
					break;
				case CellarPropertyType.OwningAtomic: // Fall through
				case CellarPropertyType.OwningCollection: // Fall through
				case CellarPropertyType.OwningSequence: // Fall through
				case CellarPropertyType.ReferenceAtomic: // Fall through
				case CellarPropertyType.ReferenceCollection: // Fall through
				case CellarPropertyType.ReferenceSequence:
					mfr.m_sig = fieldSignature;
					// It may not be present yet when the whole MDC is being initialized via 'Init',
					// or the Constructor, as the case may be.
					// Only mess with setting this after intitialization of the main model.
					// Once all those model classes are in, a client can take his lumps
					// if this throws an exception.
					if (m_initialized)
					{
						if (string.IsNullOrEmpty(fieldSignature))
							throw new KeyNotFoundException("'bstrFieldSignature' is a null or empty key.");
						// Note that m_fieldSource must be set before calling this.
						SetDestClass(mfr, m_nameToClid[fieldSignature]);
					}
					break;
			}
			mfr.m_fieldType = type;
			mfr.m_fieldName = fieldName;
			mfr.m_ownClsid = clid;
			mcr.AddField(mfr);
			m_metaFieldRecords[flid] = mfr;
			m_nameToFlid[MakeFlidKey(clid, fieldName)] = flid;
		}
Beispiel #55
0
		/// <summary>
		/// Store a value for either a simple formatted string or a multilingual string.
		/// </summary>
		private void SetStringValue(IRnGenericRec rec, RnSfMarker rsf, Sfm2Xml.SfmField field,
			CellarPropertyType cpt)
		{
			// REVIEW: SHOULD WE WORRY ABOUT EMBEDDED CHAR MAPPINGS THAT CHANGE THE WRITING SYSTEM
			// WHEN IT COMES TO ENCODING CONVERSION???
			ReconvertEncodedDataIfNeeded(field, rsf.m_sto.m_wsId);
			ITsString tss = MakeTsString(field.Data, rsf.m_sto.m_ws.Handle);
			switch (rsf.m_flid)
			{
				case RnGenericRecTags.kflidTitle:
					rec.Title = tss;
					break;
				default:
					// must be a custom field.
					Debug.Assert(rsf.m_flid >= (RnGenericRecTags.kClassId * 1000) + 500);
					switch (cpt)
					{
						case CellarPropertyType.MultiString:
						case CellarPropertyType.MultiUnicode:
							m_cache.DomainDataByFlid.SetMultiStringAlt(rec.Hvo, rsf.m_flid, rsf.m_sto.m_ws.Handle, tss);
							break;
						case CellarPropertyType.String:
							m_cache.DomainDataByFlid.SetString(rec.Hvo, rsf.m_flid, tss);
							break;
					}
					break;
			}
		}
		private static string GetDefaultValueForPropertyType(CellarPropertyType propertyType)
		{
			switch (propertyType)
			{
				case CellarPropertyType.Boolean:
					return "False";
				case CellarPropertyType.GenDate:
					var genDate = new GenDate();
					return string.Format("{0}{1:0000}{2:00}{3:00}{4}",
						genDate.IsAD ? "" : "-",
						genDate.Year,
						genDate.Month,
						genDate.Day,
						(int)genDate.Precision);
				case CellarPropertyType.Guid:
					return Guid.Empty.ToString();
				case CellarPropertyType.Float:
					throw new NotSupportedException("The 'Float' data type is not supported in the FW data model yet (as of 23 March 2013).");
				case CellarPropertyType.Integer:
					return "0";
				case CellarPropertyType.Time:
					var datetime = new DateTime();
					datetime = datetime.ToUniversalTime(); // Store it as UTC.
					return String.Format("{0}-{1}-{2} {3}:{4}:{5}.{6}",
						datetime.Year,
						datetime.Month,
						datetime.Day,
						datetime.Hour,
						datetime.Minute,
						datetime.Second,
						datetime.Millisecond);
				case CellarPropertyType.Numeric:
					throw new NotSupportedException("The 'Numeric' data type is not supported in the FW data model yet (as of 23 March 2013).");
				default:
					throw new InvalidOperationException("The given 'propertyType' is not a basic data type.");
			}
		}
Beispiel #57
0
 /// <summary>
 /// Returns true for Binary, Boolean, GenDate, Integer and Time
 /// </summary>
 /// <param name="type"></param>
 /// <returns></returns>
 public bool IsValueType(CellarPropertyType type)
 {
     return(m_metaDataCache.IsValueType(type));
 }
		/// <summary>
		/// Should return true for value types; but not implemented
		/// </summary>
		/// <param name="type"></param>
		/// <returns></returns>
		public bool IsValueType(CellarPropertyType type)
		{
			throw new NotSupportedException();
		}
Beispiel #59
0
 public int AddCustomField(string className, string fieldName, CellarPropertyType fieldType,
                           int destinationClass, string fieldHelp, int fieldWs, Guid fieldListRoot)
 {
     return(m_metaDataCache.AddCustomField(className, fieldName, fieldType, destinationClass,
                                           fieldHelp, fieldWs, fieldListRoot));
 }
Beispiel #60
0
		private void UpdateOwningVector(string sClassName, int flid, string sFieldName, int hvoItem,
			CellarPropertyType fieldType, XmlDocument fxtResult)
		{
			// hvoItem is the owner and something inside the owning sequence field has changed
			// so we want to find the owner object in the result file and then look for the field items within it.
			// Note: some use refVector when put real items elsewhere
			// Note: others use objVector for when the items are stored right here
			//   Parents (i.e. the owner)
			//      some have <element name=""> ;
			//      others have just an (output) element;
			//      some have just the <class>
			XmlNode resultNode;

			// figure out the name of the element that corresponds to the field
			bool fIsRefVector;
			string sFxtItemLabel;
			string sResultOwningElementName;
			XmlNode fxtFieldNode = GetFxtNodeAndFxtItemLabel(sClassName, flid, sFieldName, fieldType, out sResultOwningElementName, out fIsRefVector, out sFxtItemLabel);
			if (fxtFieldNode == null)
				return;  // Not all fields are addressed in the FXT description file
			string sXPath = "//" + sResultOwningElementName + "[ancestor-or-self::*[@Id='" + hvoItem + "']]";
			resultNode = fxtResult.SelectSingleNode(sXPath); // is the owner
			if (resultNode == null)
			{
				XmlNode objResultNode = FindOrInsertAllElementObject(hvoItem, fxtResult);
				if (objResultNode != null)
				{
					resultNode = objResultNode.SelectSingleNode("descendant-or-self::" + sResultOwningElementName);
				}
				else
				{
					// the item does not have an Id; it's just the parent element
				resultNode = fxtResult.SelectSingleNode("//" + sResultOwningElementName);
				if (resultNode == null)
						// The object has not been added to the result yet, most likely it is being initialized, so wait for owner to add it
						return;
				}
			}

			// get set of field items in the database
			List<int> hvosDatabase = GetHvosInDatabase(hvoItem, flid);

			// get set of field items in the FXT result file
			List<int> hvosResult = GetHvosInFxtResult(resultNode, sFxtItemLabel, fxtFieldNode);

			HandleOwningVectorDeletions(fxtResult, resultNode, hvosResult, hvosDatabase, flid);

			HandleVectorAdditions(fxtResult, resultNode, sFxtItemLabel, hvosResult, hvosDatabase, sResultOwningElementName, fIsRefVector);

			UpdateVectorOrds(resultNode, hvosDatabase);
		}