예제 #1
0
		/// <summary>
		/// Get the items to be compared against the filter.
		/// </summary>
		/// <param name="item"></param>
		/// <returns></returns>
		protected override int[] GetItems(ManyOnePathSortItem item)
		{
			ISilDataAccess sda = m_cache.MainCacheAccessor;
			List<int> results = new List<int>();
			if (item.PathLength > 0 && item.PathFlid(0) == kflidMsas)
			{
				// sorted by MSA, match just the one MSA.
				// I don't think this path can occur with the current XML spec where this is used.
				int hvoMsa;
				if (item.PathLength > 1)
					hvoMsa = item.PathObject(1);
				else
					hvoMsa = item.KeyObject;
				GetItemsForMsaType(sda, ref results, hvoMsa);
			}
			else if (item.PathLength >= 1 && item.PathFlid(0) == kflidEntrySenses)
			{
				// sorted in a way that shows one sense per row, test that sense's MSA.
				int hvoSense;
				if (item.PathLength > 1)
					hvoSense = item.PathObject(1);
				else
					hvoSense = item.KeyObject;
				int hvoMsa = sda.get_ObjectProp(hvoSense, (int)LexSense.LexSenseTags.kflidMorphoSyntaxAnalysis);
				GetItemsForMsaType(sda, ref results, hvoMsa);
			}
			else
			{
				int hvoEntry = item.RootObject.Hvo;
				int cmsa = sda.get_VecSize(hvoEntry, kflidMsas);
				for (int imsa = 0; imsa < cmsa; imsa++)
				{
					int hvoMsa = sda.get_VecItem(hvoEntry, kflidMsas, imsa);
					GetItemsForMsaType(sda, ref results, hvoMsa);
				}
			}
			return results.ToArray();
		}
예제 #2
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Checks if we are sorted by column of the given flid, and if so returns the hvo for that item.
		/// </summary>
		/// <param name="flid">The flid.</param>
		/// <param name="iPathFlid">The i path flid.</param>
		/// <param name="item">The item.</param>
		/// <param name="hvo">The hvo.</param>
		/// <returns>
		/// 	<c>true</c> if [is sorted by field] [the specified flid]; otherwise, <c>false</c>.
		/// </returns>
		/// ------------------------------------------------------------------------------------
		static internal bool IsSortedByField(int flid, int iPathFlid, ManyOnePathSortItem item, out int hvo)
		{
			hvo = 0;
			if (item.PathLength > iPathFlid && item.PathFlid(iPathFlid) == flid)
			{
				if ((item.PathLength > 1) && (item.PathLength != (iPathFlid + 1)))
					hvo = item.PathObject(1);
				else
					hvo = item.KeyObject;
				return true;
			}
			return false;
		}
예제 #3
0
		/// <summary>
		/// Gets the sort key by traversing the part tree, calling the sort method at the leaves.
		/// </summary>
		/// <param name="layout">The layout.</param>
		/// <param name="cmo">The object.</param>
		/// <param name="item">The item.</param>
		/// <param name="pathIndex">Index of the path.</param>
		/// <param name="sortedFromEnd">if set to <c>true</c> [sorted from end].</param>
		/// <returns></returns>
		private string GetKey(XmlNode layout, ICmObject cmo, ManyOnePathSortItem item, int pathIndex, bool sortedFromEnd)
		{
			if (layout == null)
				return null;

			switch (layout.Name)
			{
				case "obj":
					{
						int flid = GetFlid(layout, cmo.Hvo);
						if (pathIndex != -1 && (pathIndex == item.PathLength || flid != item.PathFlid(pathIndex)))
							// we are now off of the path
							pathIndex = -1;

						int objHvo = m_cache.GetObjProperty(cmo.Hvo, flid);
						if (objHvo != 0)
						{
							if (pathIndex != -1
								&& (pathIndex < item.PathLength - 1 && objHvo == item.PathObject(pathIndex + 1))
								 || (pathIndex == item.PathLength - 1 && objHvo == item.KeyObject))
							{
								return GetChildObjKey(layout, objHvo, item, pathIndex + 1, sortedFromEnd);
							}

							// we are off of the path
							return GetChildObjKey(layout, objHvo, item, -1, sortedFromEnd);
						}
					}
					break;

				case "seq":
					{
						int flid = GetFlid(layout, cmo.Hvo);
						if (pathIndex != -1 && (pathIndex == item.PathLength || flid != item.PathFlid(pathIndex)))
							// we are now off of the path
							pathIndex = -1;

						int size = m_cache.GetVectorSize(cmo.Hvo, flid);
						StringBuilder sb = null;
						for (int i = 0; i < size; i++)
						{
							int objHvo = m_cache.GetVectorItem(cmo.Hvo, flid, i);
							if (pathIndex != -1
								&& (pathIndex < item.PathLength - 1 && objHvo == item.PathObject(pathIndex + 1))
								|| (pathIndex == item.PathLength - 1 && objHvo == item.KeyObject))
							{
								return GetChildObjKey(layout, objHvo, item, pathIndex + 1, sortedFromEnd);
							}

							// if we are off of the path, we concatenate all vector keys to create an
							// aggregate key
							string childObjKey = GetChildObjKey(layout, objHvo, item, -1, sortedFromEnd);
							if (childObjKey != null)
							{
								if (sb == null)
									sb = new StringBuilder();
								sb.Append(childObjKey);
							}
						}
						if (sb != null)
							return sb.ToString();
					}
					break;

				case "layout":
				case "part":
					{
						string partref = XmlUtils.GetOptionalAttributeValue(layout, "ref");
						if (partref != null)
						{
							XmlNode part = XmlVc.GetNodeForPart(cmo.Hvo, partref, true, m_sda, m_layouts);
							return GetKey(part, cmo, item, pathIndex, sortedFromEnd);
						}

						foreach (XmlNode child in layout.ChildNodes)
						{
							if (child is XmlComment)
								continue;

							string key = GetKey(child, cmo, item, pathIndex, sortedFromEnd);
							if (key != null)
								return key;
						}
					}
					break;
			}
			return null;
		}
예제 #4
0
		/// <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(ManyOnePathSortItem 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), (int)CmObjectFields.kflidCmObject_Class);
				int flid = (int)mdc.GetFieldId2((uint)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, (int)CmObjectFields.kflidCmObject_Class) == 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);
			}
		}