// /// ------------------------------------------------------------------------------------ // /// <summary> // /// Given a spec that might be some sort of element, or might be something wrapping a flow object // /// around that element, return the element. Or, it might be a "frag" element wrapping all of that. // /// </summary> // /// <param name="viewSpec">The view spec.</param> // /// <returns></returns> // /// ------------------------------------------------------------------------------------ // XmlNode ExtractFromFlow(XmlNode viewSpec) // { // if (viewSpec == null) // return null; // if (viewSpec.Name == "frag") // viewSpec = viewSpec.FirstChild; // if (viewSpec.Name == "para" || viewSpec.Name == "div") // { // if (viewSpec.ChildNodes.Count == 2 && viewSpec.FirstChild.Name == "properties") // return viewSpec.ChildNodes[1]; // else if (viewSpec.ChildNodes.Count == 1) // return viewSpec.FirstChild; // } // return viewSpec; // None of the special flow object cases, use the node itself. // } #region StringFinder Members /// ------------------------------------------------------------------------------------ /// <summary> /// Stringses the specified hvo. /// </summary> /// <param name="hvo">The hvo.</param> /// <returns></returns> /// ------------------------------------------------------------------------------------ public string[] Strings(int hvo) { try { string[] result = null; if (m_layoutName == null) { result = StringsFor(hvo, m_colSpec, m_vc.WsForce); } if (result == null) { XmlNode layout = XmlVc.GetNodeForPart(hvo, m_layoutName, true, m_sda, m_layouts); if (layout == null) { return(new string[0]); // cell will be empty. } result = StringsFor(hvo, layout, m_vc.WsForce); } if (result == null) { return(new string[0]); } else { return(result); } } catch (Exception e) { throw new Exception("Failed to get strings for object " + hvo, e); } }
private string[] GetChildObjKey(XmlNode layout, int hvo, IManyOnePathSortItem item, int pathIndex, bool sortedFromEnd) { ICmObject childObj = m_cache.ServiceLocator.ObjectRepository.GetObject(hvo); string layoutName = XmlUtils.GetOptionalAttributeValue(layout, "layout"); XmlNode part = XmlVc.GetNodeForPart(hvo, layoutName, true, m_sda, m_layouts); var key = GetKey(part, childObj, item, pathIndex, sortedFromEnd); if (key != null) { return(key); } return(CallSortMethod(childObj, sortedFromEnd)); }
private string GetChildObjKey(XmlNode layout, int hvo, ManyOnePathSortItem item, int pathIndex, bool sortedFromEnd) { ICmObject childObj = CmObject.CreateFromDBObject(m_cache, hvo); string layoutName = XmlUtils.GetManditoryAttributeValue(layout, "layout"); XmlNode part = XmlVc.GetNodeForPart(hvo, layoutName, true, m_sda, m_layouts); string key = GetKey(part, childObj, item, pathIndex, sortedFromEnd); if (key != null) { return(key); } return(CallSortMethod(childObj, sortedFromEnd)); }
// Display the first child (item in the vector) in a special mode which suppresses everything except the child // marked singlegraminfofirst, to show the POS. private void DisplayFirstChildPOS(int firstChildHvo, int childFrag) { var dispCommand = (MainCallerDisplayCommand)m_viewConstructor.m_idToDisplayCommand[childFrag]; string layoutName; var parent = dispCommand.GetNodeForChild(out layoutName, childFrag, m_viewConstructor, firstChildHvo); foreach (XmlNode gramInfoPartRef in parent.ChildNodes) { if (XmlUtils.GetOptionalBooleanAttributeValue(gramInfoPartRef, "singlegraminfofirst", false)) { // It really is the gram info part ref we want. //m_viewConstructor.ProcessPartRef(gramInfoPartRef, firstChildHvo, m_vwEnv); no! the sense is not on the stack. var sVisibility = XmlUtils.GetOptionalAttributeValue(gramInfoPartRef, "visibility", "always"); if (sVisibility == "never") { return; // user has configured gram info first, but turned off gram info. } string morphLayoutName = XmlUtils.GetManditoryAttributeValue(gramInfoPartRef, "ref"); var part = m_viewConstructor.GetNodeForPart(firstChildHvo, morphLayoutName, false); if (part == null) { throw new ArgumentException("Attempt to display gram info of first child, but part for " + morphLayoutName + " does not exist"); } var objNode = XmlUtils.GetFirstNonCommentChild(part); if (objNode == null || objNode.Name != "obj") { throw new ArgumentException("Attempt to display gram info of first child, but part for " + morphLayoutName + " does not hav a single <obj> child"); } int flid = XmlVc.GetFlid(objNode, firstChildHvo, m_viewConstructor.DataAccess); int hvoTarget = m_viewConstructor.DataAccess.get_ObjectProp(firstChildHvo, flid); if (hvoTarget == 0) { return; // first sense has no category. } int fragId = m_viewConstructor.GetSubFragId(objNode, gramInfoPartRef); if (m_vwEnv is ConfiguredExport) { (m_vwEnv as ConfiguredExport).BeginCssClassIfNeeded(gramInfoPartRef); } m_vwEnv.AddObj(hvoTarget, m_viewConstructor, fragId); if (m_vwEnv is ConfiguredExport) { (m_vwEnv as ConfiguredExport).EndCssClassIfNeeded(gramInfoPartRef); } return; } } throw new ArgumentException("Attempt to display gram info of first child, but template has no singlegraminfofirst"); }
/// <summary> /// Get a key from the item. /// </summary> /// <param name="item">The item.</param> /// <param name="sortedFromEnd">if set to <c>true</c> [sorted from end].</param> /// <returns></returns> public override string[] SortStrings(IManyOnePathSortItem item, bool sortedFromEnd) { if (item.KeyObject == 0) { return(new string[0]); } // traverse the part tree from the root, the root object and the root layout node should // be compatible XmlNode layout = XmlVc.GetNodeForPart(item.RootObjectHvo, m_layoutName, true, m_sda, m_layouts); var rootObject = item.RootObjectUsing(m_cache); var key = GetKey(layout, rootObject, item, 0, sortedFromEnd); if (key == null) { // the root object sort method is not tried in GetKey key = CallSortMethod(rootObject, sortedFromEnd); if (key == null) { // try calling the sort method on the key object var keyCmObjectUsing = item.KeyObjectUsing(m_cache); key = CallSortMethod(keyCmObjectUsing, sortedFromEnd); if (key == null) { // Try the default fallback if we can't find the method. var firstKey = keyCmObjectUsing.SortKey ?? ""; if (sortedFromEnd) { firstKey = TsStringUtils.ReverseString(firstKey); } return(new [] { firstKey, keyCmObjectUsing.SortKey2Alpha }); } } } return(key); }
/// <summary> /// Get a key from the item. /// </summary> /// <param name="item">The item.</param> /// <param name="sortedFromEnd">if set to <c>true</c> [sorted from end].</param> /// <returns></returns> public override string[] SortStrings(ManyOnePathSortItem item, bool sortedFromEnd) { CheckDisposed(); if (item.KeyCmObject == null) { return(new string[0]); } // traverse the part tree from the root, the root object and the root layout node should // be compatible XmlNode layout = XmlVc.GetNodeForPart(item.RootObject.Hvo, m_layoutName, true, m_sda, m_layouts); string key = GetKey(layout, item.RootObject, item, 0, sortedFromEnd); if (key == null) { // the root object sort method is not tried in GetKey key = CallSortMethod(item.RootObject, sortedFromEnd); if (key == null) { // try calling the sort method on the key object key = CallSortMethod(item.KeyCmObject, sortedFromEnd); if (key == null) { // Try the default fallback if we can't find the method. key = item.KeyCmObject.SortKey ?? ""; if (sortedFromEnd) { key = StringUtils.ReverseString(key); } key = key + " " + item.KeyCmObject.SortKey2Alpha; } } } return(new string[] { key }); }
/// <summary> /// make sure we can get a PartNode for this child, if not, /// try to (recursively) generate parts refering to the parent(s) until we can find the owner of the layout. /// /// clone this (generic) part: /// /// <code> /// <part id="{className}-Jt-$fieldName" type="jtview"> /// <obj class="{className}" field="{OwnerOfClassVirtualProperty}" layout="$fieldName"/> /// </part> /// </code> /// /// into this (specific) part: /// /// <code> /// <part id="{className}-Jt-{layoutName}" type="jtview"> /// <obj class="{className}" field="{OwnerOfClassVirtualProperty}" layout="{layoutName}"/> /// </part> /// </code> /// </summary> /// <param name="layoutClass"></param> /// <param name="fieldNameForReplace"></param> /// <param name="fieldIdForWs"></param> /// <param name="layoutNode"></param> /// <returns>list of part nodes generated</returns> protected List <XmlNode> GeneratePartsFromLayouts(int layoutClass, string fieldNameForReplace, int fieldIdForWs, ref XmlNode layoutNode) { if (m_vc == null || layoutClass == 0) { return(null); } string layout = XmlUtils.GetOptionalAttributeValue(layoutNode, "layout"); if (layout == null) { return(null); } string className = m_mdc.GetClassName(layoutClass); string layoutGeneric = ""; string layoutSpecific = ""; if (layout.Contains("$fieldName") && !fieldNameForReplace.Contains("$fieldName")) { // this is generic layout name that requires further specification. layoutGeneric = layout; // first try to substitute the field name to see if we can get an existing part. XmlNode layoutNodeForCustomField = layoutNode.CloneNode(true); ReplaceParamsInAttributes(layoutNodeForCustomField, "", fieldNameForReplace, fieldIdForWs, className); layoutSpecific = XmlUtils.GetOptionalAttributeValue(layoutNodeForCustomField, "layout"); } else { // possibly need to look for the most generic layout name by default. layoutGeneric = "$fieldName"; layoutSpecific = layout; } XmlNode partNode = m_vc.GetNodeForPart(layoutSpecific, false, layoutClass); if (partNode != null) { // Enhance: Validate existing part! // specific part already exists, just keep it. return(null); } // couldn't find a specific part, so get the generic part in order to generate the specific part partNode = m_vc.GetNodeForPart(layoutGeneric, false, layoutClass); if (partNode == null) #if !__MonoCS__ { throw new ApplicationException("Couldn't find generic Part (" + className + "-Jt-" + layout + ")"); } #else { // TODO-Linux: Fix this in the correct way. return(null); } #endif if (partNode != null) { var generatedParts = new List <XmlNode>(); // clone the generic node so we can substitute any attributes that need to be substituted. XmlNode generatedPartNode = partNode.CloneNode(true); ReplaceParamsInAttributes(generatedPartNode, "", fieldNameForReplace, fieldIdForWs, className); Inventory.GetInventory("parts", m_vc.Cache.ProjectId.Name).AddNodeToInventory(generatedPartNode); generatedParts.Add(generatedPartNode); // now see if we need to create other parts from further generic layouts. if (fieldNameForReplace.Contains("$fieldName")) { // use the generated part, since it contains a template reference. partNode = generatedPartNode; } XmlNode nextLayoutNode = null; XmlAttribute layoutAttr = partNode.Attributes["layout"]; if (layoutAttr != null && layoutAttr.Value.Contains("$fieldName")) { nextLayoutNode = partNode; } else if (partNode.ChildNodes.Count > 0) { nextLayoutNode = partNode.SelectSingleNode(".//*[contains(@layout, '$fieldName')]"); } if (nextLayoutNode != null) { // now build the new node from its layouts string fieldName = XmlUtils.GetManditoryAttributeValue(nextLayoutNode, "field"); int field = m_vc.Cache.DomainDataByFlid.MetaDataCache.GetFieldId(className, fieldName, true); int nextLayoutClass = m_vc.Cache.GetDestinationClass(field); List <XmlNode> furtherGeneratedParts = GeneratePartsFromLayouts(nextLayoutClass, fieldNameForReplace, fieldIdForWs, ref nextLayoutNode); if (furtherGeneratedParts != null) { generatedParts.AddRange(furtherGeneratedParts); } } return(generatedParts); } return(null); }
/// <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, IManyOnePathSortItem 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.MainCacheAccessor.get_ObjectProp(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.MainCacheAccessor.get_VecSize(cmo.Hvo, flid); StringBuilder sb = null; for (int i = 0; i < size; i++) { int objHvo = m_cache.MainCacheAccessor.get_VecItem(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 var childObjKey = GetChildObjKey(layout, objHvo, item, -1, sortedFromEnd); if (childObjKey != null) { if (sb == null) { sb = new StringBuilder(); } foreach (var subKey in childObjKey) { sb.Append(subKey); } } } if (sb != null) { return new [] { 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; } var key = GetKey(child, cmo, item, pathIndex, sortedFromEnd); if (key != null) { return(key); } } } break; } return(null); }