コード例 #1
0
        int GetProp(int hvo, XmlNode elt)
        {
            string propName = XmlUtils.GetMandatoryAttributeValue(elt, "prop");
            int    clsid    = m_sda.get_IntProp(hvo, (int)CmObjectFields.kflidCmObject_Class);

            return((int)m_mdc.GetFieldId2(clsid, propName, true));
        }
コード例 #2
0
        static internal int GetCustomFieldFlid(XmlNode caller, IFwMetaDataCache mdc, ICmObject obj)
        {
            string fieldName = XmlUtils.GetManditoryAttributeValue(caller, "param");
            int    flid      = (int)mdc.GetFieldId2((uint)obj.ClassID, fieldName, true);

            return(flid);
        }
コード例 #3
0
        public override void Init(FdoCache cache, Mediator mediator, XmlNode recordListNode)
        {
            CheckDisposed();

            // <recordList class="WfiWordform" field="Occurrences"/>
            BaseInit(cache, mediator, recordListNode);
            IFwMetaDataCache mdc = VirtualListPublisher.MetaDataCache;

            m_flid = mdc.GetFieldId2(WfiWordformTags.kClassId, "Occurrences", false);
            Sorter = new OccurrenceSorter
            {
                Cache = cache, SpecialDataAccess = VirtualListPublisher
            };
        }
コード例 #4
0
        static internal int GetCustomFieldFlid(XmlNode caller, IFwMetaDataCache mdc, ICmObject obj)
        {
            string fieldName = XmlUtils.GetManditoryAttributeValue(caller, "param");

            // It would be nice to avoid all the possible throws for invalid fields, but hard
            // to achieve in a static method.
            try
            {
                int flid = mdc.GetFieldId2(obj.ClassID, fieldName, true);
                return(flid);
            }
            catch
            {
                return(0);
            }
        }
コード例 #5
0
        const int ktagMinVp = 0x7f000000;         // copied from VwCacheDa.h, mimimum value for assigned virtual props.
        /// <summary>
        /// We implement this to record modify times.
        /// </summary>
        /// <param name="hvo"></param>
        /// <param name="tag"></param>
        /// <param name="ivMin"></param>
        /// <param name="cvIns"></param>
        /// <param name="cvDel"></param>
        public void PropChanged(int hvo, int tag, int ivMin, int cvIns, int cvDel)
        {
            CheckDisposed();
            if (m_fModifyChangeInProgress)             // ignore PropChanged on the DateModified property!
            {
                return;
            }
            // Typically an Undo will restore the modify time to what it was before the
            // main change. We don't want to reverse that by recording the time of the Undo!
            // Note that there is one pathological scenario:
            // t1: make a change.
            // t2: undo the change.
            // t3: export all changed records (since before t1).
            // t4: redo the change. Record appears to have been modified at time t2.
            // t5: export all changed records (since t3).
            // If this was the only change to the record, it is not part of either export,
            // and the change might be lost.
            // To prevent this, I think the 'export changed records' function should clear
            // the Undo stack.
            if (m_cache.ActionHandlerAccessor != null && m_cache.ActionHandlerAccessor.IsUndoOrRedoInProgress)
            {
                return;
            }
            if (tag < 0 || tag >= ktagMinVp)
            {
                return;                 // phony or virtual properties, not real changes (e.g., different filter applied, or selection moving in browse).
            }
            try
            {
                DateTime dtNow    = DateTime.Now;
                int      hvoMajor = 0;            // hvo of the 'major' object that has the DateModified property.
                if (SameMinute(dtNow, m_currentMinute))
                {
                    // We can use our Dictionary
                    if (m_recentMods.ContainsKey(hvo))
                    {
                        hvoMajor = m_recentMods[hvo];
                    }
                }
                else
                {
                    ResetDelay();
                }
                int flidModify = 0;
                if (hvoMajor == 0)
                {
                    for (int hvoCandidate = hvo; hvoCandidate != 0;
                         hvoCandidate = m_cache.GetOwnerOfObject(hvoCandidate))
                    {
                        // We assume that this is a dummy object at this point and GetClassOfObject
                        // only accepts real objects. Since it's a dummy object, changes should never
                        // affect the modify time of a real object. Maybe at some point we can get an
                        // interface method to check for dummy objects.
                        if (hvoCandidate < 0)
                        {
                            return;
                        }
                        int clid = m_cache.GetClassOfObject(hvoCandidate);
                        if (clid == 0)
                        {
                            return;                             // maybe a deleted object, no good to us, we can't record modify time.
                        }
                        flidModify = (int)m_mdc.GetFieldId2((uint)clid, "DateModified", true);
                        if (flidModify != 0)
                        {
                            hvoMajor = hvoCandidate;
                            break;
                        }
                    }
                    if (hvoMajor == 0)
                    {
                        return;                         // found no owner with DateCreated property.
                    }
                    m_recentMods[hvo] = hvoMajor;       // lets us find it fast if modified again soon.
                }
                else
                {
                    // We need to set flidModify!
                    int clid = m_cache.GetClassOfObject(hvoMajor);
                    if (clid != 0)
                    {
                        flidModify = (int)m_mdc.GetFieldId2((uint)clid, "DateModified", true);
                    }
                }
                if (flidModify == 0)
                {
                    return;                     // can't set the time prop without a field...
                }
                DateTime oldModifyTime = m_cache.GetTimeProperty(hvoMajor, flidModify);
                // If we already noted a modify time in the current minute, don't do it again.
                // This is intended to keep down the overhead of recording modify times for frequently
                // modified objects.
                if (SameMinute(oldModifyTime, dtNow))
                {
                    //Trace.TraceInformation("New Modify Time ({0}) for {1} is same minute as the old ({2}).\n",
                    //    dtNow, hvoMajor, oldModifyTime);
                    return;
                }
                //				if (m_currentMinute != null &&
                //					m_currentMinute.Date == dtNow.Date && m_currentMinute.Hour = dtNow.Hour && m_currentMinute.Minute == dtNow.Minute)
                //					return;

                // Set the modify time. If possible tack this on to the last Undo task (or the current one, if a
                // transaction is open).
                if (m_cache.ActionHandlerAccessor != null && m_cache.VwOleDbDaAccessor != null &&
                    ((m_cache.DatabaseAccessor != null && m_cache.DatabaseAccessor.IsTransactionOpen()) ||
                     m_cache.CanUndo))
                {
                    m_cache.ContinueUndoTask();
                    m_cache.SetTimeProperty(hvoMajor, flidModify, dtNow);
                    m_cache.EndUndoTask();
                }
                else
                {
                    // We don't have an Undo task to append to, so somehow a Save has occurred
                    // in the midst of the operation that caused the time stamp modification.
                    // If we make an empty undo task, the user will typically have no idea what
                    // could be undone, and will be confused. Best to make it impossible to
                    // undo the timestamp change also.
                    using (new SuppressSubTasks(m_cache))
                    {
                        m_cache.SetTimeProperty(hvoMajor, flidModify, dtNow);
                    }
                }
                //Trace.TraceInformation("Setting new Modify Time ({0}) for {1}\n",
                //        dtNow, hvoMajor);
            }
            finally
            {
                m_fModifyChangeInProgress = false;
            }
        }
コード例 #6
0
ファイル: SliceFactory.cs プロジェクト: sillsdev/FieldWorks
		static internal int GetCustomFieldFlid(XmlNode caller, IFwMetaDataCache mdc, ICmObject obj)
		{
			string fieldName = XmlUtils.GetManditoryAttributeValue(caller, "param");
			// It would be nice to avoid all the possible throws for invalid fields, but hard
			// to achieve in a static method.
			try
			{
				int flid = mdc.GetFieldId2(obj.ClassID, fieldName, true);
				return flid;
			}
			catch
			{
				return 0;
			}
		}
コード例 #7
0
        private void LoadObject(XmlNode objectNode, int hvo, int clid, IDictionary <int, int> objects)
        {
            // Optimize by looping over the child nodes,
            // and dealing with relevant flid.
            // The idea is that most objects will only have a subset of fields filled in.
            var nodeList = objectNode.ChildNodes;

            for (var i = 0; i < nodeList.Count; ++i)
            {
                var fieldNode = nodeList[i];                 // Item(i);
                var fieldName = fieldNode.Name;
                var idx       = fieldName.IndexOfAny(new[] { '1', '2', '3', '4', '5', '6', '7', '8', '9' });
                fieldName = fieldName.Substring(0, idx);
                var cfk = new ClidFieldnameKey(clid, fieldName);
                int flid;
                if (m_cachedFlids.ContainsKey(cfk))
                {
                    flid = m_cachedFlids[cfk];
                }
                else
                {
                    flid = m_metaDataCache.GetFieldId2(clid, fieldName, true);
                    m_cachedFlids[cfk] = flid;
                }

                var flidType = (CellarPropertyType)m_metaDataCache.GetFieldType(flid);
                int ownedClid;
                int ownedHvo;
                switch (flidType)
                {
                case CellarPropertyType.Boolean:
                    // <System18><Boolean val="true"/></System18>
                    m_realDataCache.CacheBooleanProp(hvo, flid, bool.Parse(fieldNode.FirstChild.Attributes["val"].Value));
                    break;

                case CellarPropertyType.Integer:
                    // <Type18><Integer val="1"/></Type18>
                    m_realDataCache.CacheIntProp(hvo, flid, Int32.Parse(fieldNode.FirstChild.Attributes["val"].Value));
                    break;

                case CellarPropertyType.Numeric:
                    break;

                case CellarPropertyType.Float:
                    break;

                case CellarPropertyType.Time:
                    // <LastModified24><Time val="2005-11-18 02:48:33.000"/></LastModified24>
                    var valTime = DateTime.Parse(fieldNode.FirstChild.Attributes["val"].Value);
                    m_realDataCache.CacheTimeProp(hvo, flid, valTime.Ticks);
                    break;

                case CellarPropertyType.Guid:
                    if (flid != (int)CmObjectFields.kflidCmObject_Guid)
                    {
                        // <App18><Guid val="5EA62D01-7A78-11D4-8078-0000C0FB81B5"/></App18>
                        var id = fieldNode.FirstChild.Attributes["val"].Value;
                        m_realDataCache.CacheGuidProp(hvo, flid, new Guid(id));
                    }
                    break;

                case CellarPropertyType.Image:
                    break;

                case CellarPropertyType.GenDate:
                    // <DateOfEvent4006><GenDate val=\"193112111\" /></DateOfEvent4006>
                    break;

                case CellarPropertyType.Binary:
                    // <Details18><Binary>03000000</Binary></Details18>
                    // <Details18><Binary>05000000\r\n</Binary></Details18>
                    break;

                case CellarPropertyType.String:
                    // "<Str><Run ws=\"eZPI\">Te mgyeey ne la Benit nuu Pwert. Za men gun men inbitar xmig men ne la Jasint nuu San José. Za Benit. Weey Benit mël. Weey Benit mëlbyuu ne ygued Benit lo xmig Benit, Jasint. Chene wdxiin Benit ruxyuu Jasint, re Benit:</Run></Str>"
                    foreach (XmlNode strNode in fieldNode.ChildNodes)
                    {
                        var tssStr = m_tsf.CreateFromStr(strNode);
                        m_realDataCache.CacheStringProp(hvo, flid, tssStr);
                    }
                    // CacheStringProp(hvo, tag, tss);
                    break;

                case CellarPropertyType.MultiString:                         // <AStr>
                    foreach (XmlNode aStrAlt in fieldNode.ChildNodes)
                    {
                        int wsAStr;
                        var tssAlt = m_tsf.CreateFromAStr(aStrAlt, out wsAStr);
                        m_realDataCache.CacheStringAlt(hvo, flid, wsAStr, tssAlt);
                    }
                    break;

                case CellarPropertyType.Unicode:
                    string unicodeText = fieldNode.FirstChild.InnerText;
                    m_realDataCache.CacheUnicodeProp(hvo, flid, unicodeText, unicodeText.Length);
                    break;

                case CellarPropertyType.MultiUnicode:                         // <AUni>
                    foreach (XmlNode uniNode in fieldNode.ChildNodes)
                    {
                        var ws      = m_wsCache[uniNode.Attributes["ws"].Value];
                        var uniText = uniNode.InnerText;
                        m_realDataCache.CacheStringAlt(hvo, flid, ws, TsStringUtils.MakeString(uniText, ws));
                    }
                    break;

                // Cases for regular objects.
                case CellarPropertyType.OwningAtomic:
                    XmlNode atomicOwnedObject = fieldNode.FirstChild;
                    ownedHvo = LoadCmObjectProperties(atomicOwnedObject, hvo, flid, 0, out ownedClid, objects);
                    LoadObject(atomicOwnedObject, ownedHvo, ownedClid, objects);
                    m_realDataCache.CacheObjProp(hvo, flid, ownedHvo);
                    break;

                case CellarPropertyType.ReferenceAtomic:
                    /* Some are simple Guid links, but others contain more info.
                     * <Category5059>
                     *      <Link target="I751B8DE1-089B-42B1-A35E-62CF838A27A3" ws="en" abbr="N" name="noun"/>
                     * </Category5059>
                     * <Morph5112>
                     *      <Link target="I9370DD7D-978D-484D-B304-B5D4700BAA30"/>
                     * </Morph5112>
                     */
                    // Defer caching references, until all objects are loaded.
                    m_delayedAtomicReferences[new HvoFlidKey(hvo, flid)] = fieldNode.FirstChild;
                    break;

                case CellarPropertyType.OwningCollection:                         // Fall through.
                case CellarPropertyType.OwningSequence:
                    var hvos   = new List <int>();
                    var newOrd = 0;
                    foreach (XmlNode obj in fieldNode.ChildNodes)
                    {
                        ownedHvo = LoadCmObjectProperties(obj, hvo, flid, newOrd, out ownedClid, objects);
                        LoadObject(obj, ownedHvo, ownedClid, objects);
                        hvos.Add(ownedHvo);
                        if (flidType == CellarPropertyType.OwningSequence)
                        {
                            newOrd++;
                        }
                    }
                    m_realDataCache.CacheVecProp(hvo, flid, hvos.ToArray(), hvos.Count);
                    break;

                case CellarPropertyType.ReferenceCollection:                         // Fall through.
                case CellarPropertyType.ReferenceSequence:
                    // <Link target="ID75F7FB5-BABD-4D60-B57F-E188BEF264B7" />
                    // Defer caching references, until all objects are loaded.
                    var list = new List <XmlNode>();
                    m_delayedVecterReferences[new HvoFlidKey(hvo, flid)] = list;
                    foreach (XmlNode linkNode in fieldNode.ChildNodes)
                    {
                        list.Add(linkNode);
                    }
                    break;
                }
            }
        }
コード例 #8
0
 public static int GetFlid(IFwMetaDataCache mdc, int classId, string fieldName)
 {
     return((int)mdc.GetFieldId2(classId, fieldName, true));
 }
コード例 #9
0
ファイル: XmlViewsUtils.cs プロジェクト: bbriggs/FieldWorks
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Main (recursive) part of CollectBrowseItems. Given that hvo is to be displayed using node,
		/// figure what objects to put in the list.
		/// </summary>
		/// <param name="hvo">The hvo.</param>
		/// <param name="node">The node.</param>
		/// <param name="collector">The collector.</param>
		/// <param name="mdc">The MDC.</param>
		/// <param name="sda">The sda.</param>
		/// <param name="layouts">The layouts.</param>
		/// <param name="caller">The caller.</param>
		/// <param name="hvos">The hvos.</param>
		/// <param name="flids">The flids.</param>
		/// ------------------------------------------------------------------------------------
		static void CollectBrowseItems(int hvo, XmlNode node, ArrayList collector,
			IFwMetaDataCache mdc, ISilDataAccess sda, LayoutCache layouts, XmlNode caller, int[] hvos, int[] flids)
		{
			switch(node.Name)
			{
			case "obj":
			{
				int clsid = sda.get_IntProp(hvo, CmObjectTags.kflidClass);
				int flid = mdc.GetFieldId2(clsid, XmlUtils.GetManditoryAttributeValue(node, "field"), true);
				int hvoDst = sda.get_ObjectProp(hvo, flid);
				if (hvoDst == 0)
				{
					// We want a row, even though it's blank for this column.
					collector.Add(new ManyOnePathSortItem(hvo, hvos, flids));
					return;
				}
				// At this point we have to mimic the process that XmlVc uses to come up with the
				// node that will be used to process the destination item.
				XmlNode dstNode = GetNodeForRelatedObject(hvoDst, caller, node, layouts, sda);
				if (dstNode == null)
				{
					// maybe an old-style "frag" element? Anyway, we can't do anything smart,
					// so just insert the original object.
					collector.Add(new ManyOnePathSortItem(hvo, hvos, flids));
					return;
				}
				CollectBrowseItems(hvoDst, dstNode, collector, mdc, sda, layouts, null, AppendInt(hvos, hvo), AppendInt(flids, flid));
			}
				break;
			case "seq":
			{
				// very like "obj" except for the loop. How could we capture this?
				int clsid = sda.get_IntProp(hvo, CmObjectTags.kflidClass);
				int flid = mdc.GetFieldId2(clsid, XmlUtils.GetManditoryAttributeValue(node, "field"), true);
				int chvo = sda.get_VecSize(hvo, flid);
				if (chvo == 0)
				{
					// We want a row, even though it's blank for this column.
					collector.Add(new ManyOnePathSortItem(hvo, hvos, flids));
					return;
				}
				for (int ihvo = 0; ihvo < chvo; ihvo++)
				{
					int hvoDst = sda.get_VecItem(hvo, flid, ihvo);
					// At this point we have to mimic the process that XmlVc uses to come up with the
					// node that will be used to process the destination item.
					XmlNode dstNode = GetNodeForRelatedObject(hvoDst, caller, node, layouts, sda);
					if (dstNode == null)
					{
						if (ihvo == 0)
						{
							// maybe an old-style "frag" element? Anyway, we can't do anything smart,
							// so just insert the original object.
							collector.Add(new ManyOnePathSortItem(hvo, hvos, flids));
							return;
						}
						// if this happens and it's not the first object, we have a funny mixture of modes.
						// As a fall-back, skip this object.
						continue;
					}
					CollectBrowseItems(hvoDst, dstNode, collector, mdc, sda, layouts, null, AppendInt(hvos, hvo), AppendInt(flids, flid));
				}
			}
				break;
			case "span":
			case "para":
			case "div":
			case "concpara":
			case "innerpile":
			case "column":
				// Review JohnT: In XmlVc, "part" is the one thing that calls ProcessChildren with non-null caller.
				// this should make some difference here, but I can't figure what yet, or come up with a test that fails.
			case "part":
			case "layout":
				// These are grouping nodes. In general this terminates things. However, if there is only
				// one thing embedded apart from comments and properties, we can proceed.
				XmlNode mainChild = FindMainChild(node);
				if (mainChild == null)
				{
					// no single non-trivial child, keep our current object
					collector.Add(new ManyOnePathSortItem(hvo, hvos, flids));
					return;
				}
				// Recurse with same object, but process the 'main child'.
				CollectBrowseItems(hvo, mainChild, collector, mdc, sda, layouts, caller, hvos, flids);
				break;

			default:
				collector.Add(new ManyOnePathSortItem(hvo, hvos, flids));
				break;
			}
		}
コード例 #10
0
ファイル: XmlViewsUtils.cs プロジェクト: bbriggs/FieldWorks
		/// <summary>
		/// Recursive implementation method for GetDisplayCommandForColumn.
		/// </summary>
		/// <param name="bvi"></param>
		/// <param name="node"></param>
		/// <param name="mdc"></param>
		/// <param name="sda"></param>
		/// <param name="layouts"></param>
		/// <param name="depth"></param>
		/// <param name="hvo"></param>
		/// <param name="collectOuterStructParts"></param>
		/// <returns></returns>
		static NodeDisplayCommand GetDisplayCommandForColumn1(IManyOnePathSortItem bvi, XmlNode node,
			IFwMetaDataCache mdc, ISilDataAccess sda, LayoutCache layouts, int depth,
			out int hvo, List<XmlNode> collectOuterStructParts)
		{
			hvo = bvi.PathObject(depth); // default
			switch(node.Name)
			{
			case "obj":
			case "seq":
			{
				// These two cases are the same here, because if the field matches, the object
				// that determines the next step comes from the bvi, not from one or many items
				// in the property.

				if (bvi.PathLength == depth)
				{
					// No more path, we display the final object using the node we've deduced is
					// appropriate for it.
					// (We could put this test outside the switch. But then we don't dig into
					// layout, para, span, etc elements at the end of the chain. It's more
					// consistent if we always dig as deep as we can.
					hvo = bvi.KeyObject;
					return new NodeDisplayCommand(node);
				}

				int clsid = sda.get_IntProp(bvi.PathObject(depth), CmObjectTags.kflidClass);
				int flid = mdc.GetFieldId2(clsid, XmlUtils.GetManditoryAttributeValue(node, "field"), true);
				if (flid != bvi.PathFlid(depth))
					return new NodeDisplayCommand(node); // different field, can't dig deeper.
				int hvoDst = bvi.PathObject(depth + 1);
				// If the path object has been deleted, fall back to displaying whatever the property currently holds.
				if (sda.get_IntProp(hvoDst, CmObjectTags.kflidClass) == 0)
					return new NodeDisplayCommand(node); // different field, can't dig deeper.
				// At this point we have to mimic the process that XmlVc uses to come up with the
				// node that will be used to process the destination item.
				XmlNode dstNode = GetNodeForRelatedObject(hvoDst, null, node, layouts, sda);
				return GetDisplayCommandForColumn1(bvi, dstNode, mdc, sda, layouts, depth + 1, out hvo, collectOuterStructParts);
			}
			case "para":
			case "span":
			case "div":
			case "concpara":
			case "innerpile":
			{
				XmlNode mainChild = FindMainChild(node);
				if (mainChild == null)
					return new NodeDisplayCommand(node); // can't usefully go further.
				if (collectOuterStructParts != null)
					collectOuterStructParts.Add(node);
				return GetDisplayCommandForColumn1(bvi, mainChild, mdc, sda, layouts, depth, out hvo, collectOuterStructParts);
			}
				// Review JohnT: In XmlVc, "part" is the one thing that calls ProcessChildren with non-null caller.
				// this should make some difference here, but I can't figure what yet, or come up with a test that fails.
				// We may need a "caller" argument to pass this down so it can be used in GetNodeForRelatedObject.
			case "part":
			{
				string layoutName = XmlUtils.GetOptionalAttributeValue(node, "ref");
				if (layoutName != null)
				{
					// It's actually a part ref, in a layout, not a part looked up by one!
					// Get the node it refers to, and make a command to process its children.
					XmlNode part = XmlVc.GetNodeForPart(hvo, layoutName, false, sda, layouts);
					if (part != null)
						return new NodeChildrenDisplayCommand(part); // display this object using the children of the part referenced.
					else
						return new NodeDisplayCommand(node); // no matching part, do default.
				}

				// These are almost the same, but are never added to collectOuterStructParts.
				// Also, expecially in the case of 'layout', they may result from unification, and be meaningless
				// except for their children; in any case, the children are all we want to process.
				// This is the main reason we return a command, not just a node: this case has to return the subclass.
				XmlNode mainChild = FindMainChild(node);
				if (mainChild == null)
					return new NodeChildrenDisplayCommand(node); // can't usefully go further.
				return GetDisplayCommandForColumn1(bvi, mainChild, mdc, sda, layouts, depth, out hvo, collectOuterStructParts);
			}
			case "column":
			case "layout":
			{

				// These are almost the same as para, span, etc, but are never added to collectOuterStructParts.
				// Also, expecially in the case of 'layout', they may result from unification, and be meaningless
				// except for their children; in any case, the children are all we want to process.
				// This is the main reason we return a command, not just a node: this case has to return the subclass.
				XmlNode mainChild = FindMainChild(node);
				if (mainChild == null)
					return new NodeChildrenDisplayCommand(node); // can't usefully go further.
				return GetDisplayCommandForColumn1(bvi, mainChild, mdc, sda, layouts, depth, out hvo, collectOuterStructParts);
			}
			default:
				// If we can't find anything clever to do, we display the object at the
				// current level using the current node.
				return new NodeDisplayCommand(node);
			}
		}
コード例 #11
0
ファイル: AutoMenuHandler.cs プロジェクト: sillsdev/WorldPad
			public static int GetFlid(IFwMetaDataCache mdc, int classId, string fieldName)
			{
				return (int)mdc.GetFieldId2((uint) classId, fieldName, true);
			}
コード例 #12
0
ファイル: SliceFactory.cs プロジェクト: sillsdev/WorldPad
		static internal int GetCustomFieldFlid(XmlNode caller, IFwMetaDataCache mdc, ICmObject obj)
		{
			string fieldName = XmlUtils.GetManditoryAttributeValue(caller, "param");
			int flid = (int)mdc.GetFieldId2((uint)obj.ClassID, fieldName, true);
			return flid;
		}