Ejemplo n.º 1
0
		private NodeTestResult AddSeqNode(ArrayList path, XmlNode node, ObjSeqHashMap reuseMap, string editor,
			int flid, ICmObject obj, int indent, ref int insertPosition, bool fTestOnly,
			string layoutName, bool fVisIfData, XmlNode caller)
		{
			if (flid == 0)
				throw new ApplicationException("field attribute required for seq properties " + node.OuterXml);
			int cobj = m_cache.GetVectorSize(obj.Hvo, flid);
			// monitor it even if we're testing: result may change.
			m_monitoredProps.Add(new KeyValuePair<int, int>(obj.Hvo, flid));
			if (fVisIfData && cobj == 0)
				return NodeTestResult.kntrNothing;
			if (fTestOnly)
			{
				if (cobj > 0 || XmlUtils.GetOptionalAttributeValue(node, "ghost") != null)
					return NodeTestResult.kntrSomething;
				else
					return NodeTestResult.kntrPossible;
			}
			path.Add(node);
			string layoutOverride = XmlUtils.GetOptionalAttributeValue(node, "layout", layoutName);
			if (cobj == 0)
			{
				// Nothing in seq....do we want a ghost slice?
				if (XmlUtils.GetOptionalAttributeValue(node, "ghost") != null)
				{
					MakeGhostSlice(path, node, reuseMap, obj, flid, caller, indent, ref insertPosition);
				}
			}
			else if (cobj < 15 ||	// This may be a little on the small side
				m_currentObjectFlids.Contains(flid) ||
				(!String.IsNullOrEmpty(m_currentSlicePartName) && m_currentSliceObjHvo != 0 && m_currentSliceNew == null))
			{
				// Create slices immediately
				foreach (int hvo in m_cache.GetVectorProperty(obj.Hvo, flid, false))
				{
					path.Add(hvo);
					insertPosition = CreateSlicesFor(CmObject.CreateFromDBObject(m_cache, hvo),
						layoutOverride, indent, insertPosition, path, reuseMap, caller);
					path.RemoveAt(path.Count - 1);
				}
			}
			else
			{
				// Create unique DummyObjectSlices for each slice.  This may reduce the initial
				// preceived benefit, but this way doesn't crash now that the slices are being
				// disposed of.
				int cnt = 0;
				foreach (int hvo in m_cache.GetVectorProperty(obj.Hvo, flid, false))
				{
					path.Add(hvo);
					DummyObjectSlice dos = new DummyObjectSlice(this, indent, node, (ArrayList)(path.Clone()),
						obj, flid, cnt, layoutOverride, caller);
					dos.Cache = m_cache;
					InsertSlice(insertPosition++, dos);
					////InstallSlice(dos, -1);
					////ResetTabIndices(insertPosition);
					////insertPosition++;
					path.RemoveAt(path.Count - 1);
					cnt++;
				}
			}
			path.RemoveAt(path.Count - 1);
			return NodeTestResult.kntrNothing;
		}
Ejemplo n.º 2
0
		/// <summary>
		/// Turn this dummy slice into whatever it stands for, replacing itself in the data tree's
		/// slices (where it occupies slot index) with whatever is appropriate.
		/// </summary>
		/// <param name="index"></param>
		/// <returns></returns>
		public override Slice BecomeReal(int index)
		{
			CheckDisposed();

			// We stand in for the slice at 'index', and that is to be replaced. But we might stand for earlier
			// slices too: how many indicates what we have to add to m_ihvoMin.

			// Note: I (RandyR) don't think the same one can stand in for multiple dummies now.
			// We don't use a dummy slice in more than one place.
			// Each are created individually, if more than one is needed.
			int ihvo = m_ihvoMin;
			for (int islice = index - 1; islice >= 0 && Parent.Controls[islice] == this; islice--)
				ihvo++;
			string mode = XmlUtils.GetOptionalAttributeValue(m_node, "mode");
			int hvo = m_cache.GetVectorItem(m_obj.Hvo, m_flid, ihvo);
			// In the course of becoming real, we may get disposed. That clears m_path, which
			// has various bad effects on called objects that are trying to use it, as well as
			// causing failure here when we try to remove the thing we added temporarily.
			// Work with a copy, so Dispose can't get at it.
			ArrayList path = new ArrayList(m_path);
			if (ihvo == m_ihvoMin)
			{
				// made the first element real. Increment start ihvo: the first thing we are a
				// dummy for got one greater
				m_ihvoMin++;
			}
			else if (index < Parent.Controls.Count && Parent.Controls[index + 1] == this)
			{
				// Any occurrences after index get replaced by a new one with suitable ihvoMin.
				// Note this must be done before we insert an unknown number of extra slices
				// by calling CreateSlicesFor.
				DummyObjectSlice dosRep = new DummyObjectSlice(ContainingDataTree, m_indent, m_node, path,
					m_obj, m_flid, ihvo + 1, m_layoutName, m_caller);
				dosRep.Cache = this.Cache;
				for (int islice = index + 1;
					islice < Parent.Controls.Count && Parent.Controls[islice] == this;
					islice++)
				{
					ContainingDataTree.RawSetSlice(islice, dosRep);
				}
			}

			// Save these, we may get disposed soon, can't get them from member data any more.
			DataTree containingTree = ContainingDataTree;
			Control parent = Parent;

			path.Add(hvo);
			ICmObject objItem = CmObject.CreateFromDBObject(ContainingDataTree.Cache, hvo);
			Point oldPos = ContainingDataTree.AutoScrollPosition;
			int insertPosition = ContainingDataTree.CreateSlicesFor(objItem, m_layoutName, m_indent, index + 1, path,
				new ObjSeqHashMap(), m_caller);
			// If inserting slices somehow altered the scroll position, for example as the
			// silly Panel tries to make the selected control visible, put it back!
			if (containingTree.AutoScrollPosition != oldPos)
				containingTree.AutoScrollPosition = new Point(-oldPos.X, -oldPos.Y);
			// No need to remove, we added to copy.
			//m_path.RemoveAt(m_path.Count - 1);
			if (parent.Controls.Count > index + 1)
				return parent.Controls[index + 1] as Slice;
			else
				return null;
		}
Ejemplo n.º 3
0
		private NodeTestResult AddSeqNode(ArrayList path, XmlNode node, ObjSeqHashMap reuseMap, int flid,
			ICmObject obj, Slice parentSlice, int indent, ref int insertPosition, bool fTestOnly, string layoutName,
			bool fVisIfData, XmlNode caller)
		{
			if (flid == 0)
				throw new ApplicationException("field attribute required for seq properties " + node.OuterXml);
			int cobj = m_cache.DomainDataByFlid.get_VecSize(obj.Hvo, flid);
			// monitor it even if we're testing: result may change.
			m_monitoredProps.Add(Tuple.Create(obj.Hvo, flid));
			if (fVisIfData && cobj == 0)
				return NodeTestResult.kntrNothing;
			if (fTestOnly)
			{
				if (cobj > 0 || XmlUtils.GetOptionalAttributeValue(node, "ghost") != null)
					return NodeTestResult.kntrSomething;

				return NodeTestResult.kntrPossible;
			}
			path.Add(node);
			string layoutOverride = XmlUtils.GetOptionalAttributeValue(node, "layout", layoutName);
			string layoutChoiceField = XmlUtils.GetOptionalAttributeValue(node, "layoutChoiceField");
			if (cobj == 0)
			{
				// Nothing in seq....do we want a ghost slice?
				if (XmlUtils.GetOptionalAttributeValue(node, "ghost") != null)
				{
					MakeGhostSlice(path, node, reuseMap, obj, parentSlice, flid, caller, indent, ref insertPosition);
				}
			}
			else if (cobj < kInstantSliceMax ||	// This may be a little on the small side
				m_currentObjectFlids.Contains(flid) ||
				(!String.IsNullOrEmpty(m_currentSlicePartName) && m_currentSliceObjGuid != Guid.Empty && m_currentSliceNew == null))
			{
				//Create slices immediately
				var contents = SetupContents(flid, obj);
				foreach (int hvo in contents)
				{
					path.Add(hvo);
					insertPosition = CreateSlicesFor(m_cache.ServiceLocator.GetInstance<ICmObjectRepository>().GetObject(hvo),
						parentSlice, layoutOverride, layoutChoiceField, indent, insertPosition, path, reuseMap, caller);
					path.RemoveAt(path.Count - 1);
				}
			}
			else
			{
				// Create unique DummyObjectSlices for each slice.  This may reduce the initial
				// preceived benefit, but this way doesn't crash now that the slices are being
				// disposed of.
				int cnt = 0;
				var contents = SetupContents(flid, obj);
				foreach (int hvo in contents)
				{
					// TODO (DamienD): do we need to add the layout choice field to the monitored props for a dummy slice?
					// LT-12302 exposed a path through here that was messed up when hvo was added before Dummy slices
					//path.Add(hvo); // try putting this AFTER the dos creation
					var dos = new DummyObjectSlice(indent, node, (ArrayList)(path.Clone()),
						obj, flid, cnt, layoutOverride, layoutChoiceField, caller) {Cache = m_cache, ParentSlice = parentSlice};
					path.Add(hvo);
					// This is really important. Since some slices are invisible, all must be,
					// or Show() will reorder them.
					dos.Visible = false;
					InsertSlice(insertPosition++, dos);
					path.RemoveAt(path.Count - 1);
					cnt++;
				}
			}
			path.RemoveAt(path.Count - 1);
			return NodeTestResult.kntrNothing;
		}