SIL.FieldWorks.Common.Framework.DetailControls.Slice.Slice.InsertObject C# (CSharp) Méthode

InsertObject() private méthode

Insert a new object of the specified class into the specified property of your object.
private InsertObject ( int flid, int newObjectClassId ) : int
flid int
newObjectClassId int
Résultat int
		int InsertObject(int flid, int newObjectClassId)
		{
			CheckDisposed();

			bool fAbstract = m_cache.DomainDataByFlid.MetaDataCache.GetAbstract(newObjectClassId);
			if (fAbstract)
			{
				// We've been handed an abstract class to insert.  Try to determine the desired
				// concrete from the context.
				if (newObjectClassId == MoFormTags.kClassId && Object is ILexEntry)
				{
					var entry = (Object as ILexEntry);
					newObjectClassId = entry.GetDefaultClassForNewAllomorph();
				}
				else
				{
					return -1;
				}
			}
			// OK, we can add to property flid of the object of slice slice.
			int insertionPosition = 0;//leave it at 0 if it does not matter
			int hvoOwner = Object.Hvo;
			int clidOwner = Object.ClassID;
			int clidOfFlid = flid / 1000;
			if (clidOwner != clidOfFlid && clidOfFlid == Object.Owner.ClassID)
			{
				hvoOwner = Object.Owner.Hvo;
			}
			int type = GetFieldType(flid);
			if (type == (int)CellarPropertyType.OwningSequence)
			{
				try
				{
					// We might not be on the right slice to insert this item.  See FWR-898.
					insertionPosition = Cache.DomainDataByFlid.get_VecSize(hvoOwner, flid);
				}
				catch
				{
					return -1;
				}
				if (ContainingDataTree != null && ContainingDataTree.CurrentSlice != null)
				{
					ISilDataAccess sda = m_cache.DomainDataByFlid;
					int chvo = insertionPosition;
					// See if the current slice in any way indicates a position in that property.
					object[] key = ContainingDataTree.CurrentSlice.Key;
					bool fGotIt = false;
					for (int ikey = key.Length - 1; ikey >= 0 && !fGotIt; ikey--)
					{
						if (!(key[ikey] is int))
							continue;
						var hvoTarget = (int)key[ikey];
						for (int i = 0; i < chvo; i++)
						{
							if (hvoTarget == sda.get_VecItem(hvoOwner, flid, i))
							{
								insertionPosition = i + 1; // insert after current object.
								fGotIt = true; // break outer loop
								break;
							}
						}
					}
				}
			}
			var slices = new Set<Slice>(ContainingDataTree.Slices);

			// Save DataTree for the finally block.  Note premature return below due to IsDisposed.  See LT-9005.
			DataTree dtContainer = ContainingDataTree;
			try
			{
				dtContainer.SetCurrentObjectFlids(hvoOwner, flid);
				var fieldType = (CellarPropertyType) m_cache.MetaDataCacheAccessor.GetFieldType(flid);
				switch (fieldType)
				{
					case CellarPropertyType.OwningCollection:
						insertionPosition = -1;
						break;

					case CellarPropertyType.OwningAtomic:
						insertionPosition = -2;
						break;
				}
				using (CmObjectUi uiObj = CmObjectUi.CreateNewUiObject(m_mediator, newObjectClassId, hvoOwner, flid, insertionPosition))
				{
					// If uiObj is null, typically CreateNewUiObject displayed a dialog and the user cancelled.
					// We return -1 to make the caller give up trying to insert, so we don't get another dialog if
					// there is another slice that could insert this kind of object.
					// If 'this' isDisposed, typically the inserted object occupies a place in the record list for
					// this view, and inserting an object caused the list to be refreshed and all slices for this
					// record to be disposed. In that case, we won't be able to find a child of this to activate,
					// so we'll just settle for having created the object.
					// Enhance JohnT: possibly we could load information from the slice into local variables before
					// calling CreateNewUiObject so that we could do a better job of picking the slice to focus
					// after an insert which disposes 'this'. Or perhaps we could improve the refresh list process
					// so that it more successfully restores the current item without disposing of all the slices.
					if (IsDisposed)
						return -1;
					if (uiObj == null)
						return -2; // Nothing created.

					switch (fieldType)
					{
						case CellarPropertyType.OwningCollection:
							// order is not fully predicatable, figure where it DID show up.
							insertionPosition = m_cache.DomainDataByFlid.GetObjIndex(hvoOwner, flid, uiObj.Object.Hvo);
							break;

						case CellarPropertyType.OwningAtomic:
							insertionPosition = 0;
							break;
					}

					//			if (ihvoPosition == ClassAndPropInfo.kposNotSet && cpi.fieldType == DataTree.kcptOwningSequence)
					//			{
					//				// insert at end of sequence.
					//				ihvoPosition = cache.DomainDataByFlid.get_VecSize(hvoOwner, (int)cpi.flid);
					//			} // otherwise we already worked out the position or it doesn't matter
					//			// Note: ihvoPosition ignored if sequence(?) or atomic.
					//			int hvoNew = cache.CreateObject((int)(cpi.signatureClsid), hvoOwner, (int)(cpi.flid), ihvoPosition);
					//			cache.DomainDataByFlid.PropChanged(null, (int)PropChangeType.kpctNotifyAll, hvoOwner, (int)(cpi.flid), ihvoPosition, 1, 0);
					if (hvoOwner == Object.Hvo && Expansion == DataTree.TreeItemState.ktisCollapsed)
					{
						// We added something to the object of the current slice...almost certainly it
						// will be something that will display under this node...if it is still collapsed,
						// expand it to show the thing inserted.
						TreeNode.ToggleExpansion(IndexInContainer);
					}
					Slice child = ExpandSubItem(uiObj.Object.Hvo);
					if (child != null)
						child.FocusSliceOrChild();
					else
					{
						// If possible, jump to the newly inserted sub item.
						if (m_mediator.BroadcastMessageUntilHandled("JumpToRecord", uiObj.Object.Hvo))
							return insertionPosition;
						// If we haven't found a slice...common now, because there's rarely a need to expand anything...
						// and some slice was added, focus it.
						foreach (Slice slice in Parent.Controls)
						{
							if (!slices.Contains(slice))
							{
								slice.FocusSliceOrChild();
								break;
							}
						}
					}
				}
			}
			finally
			{
				dtContainer.ClearCurrentObjectFlids();
			}
			return insertionPosition;
		}